Files
tkPage/src/utils/pythonBridge.js
2026-01-07 21:36:52 +08:00

192 lines
4.7 KiB
JavaScript

// pythonBridge.js
// 适配 pywebview API (替代原有的 QWebChannel)
import { ref, onMounted } from 'vue';
const bridge = ref(null);
const isReady = ref(false);
/**
* 等待 pywebview API 准备就绪
* @returns {Promise<void>}
*/
const waitForPywebview = () => {
return new Promise((resolve) => {
// 如果已经存在,直接返回
if (window.pywebview && window.pywebview.api) {
resolve();
return;
}
// 监听 pywebviewready 事件
window.addEventListener('pywebviewready', () => {
resolve();
}, { once: true });
});
};
/**
* 统一安全调用 pywebview API
* pywebview 的方法调用会返回 Promise
*/
const callBridge = async (method, ...args) => {
if (!bridge.value || typeof bridge.value[method] !== 'function') {
console.warn(`[pythonBridge] 方法不存在: ${method}`);
return null;
}
try {
const result = await bridge.value[method](...args);
return result;
} catch (error) {
console.error(`[pythonBridge] 调用 ${method} 失败:`, error);
return null;
}
};
/**
* 初始化 pywebview 桥接
*/
const initBridge = async () => {
// 监听 DevTools 快捷键 (Ctrl + Shift + P)
window.addEventListener('keydown', (e) => {
// 1. 自定义快捷键: Ctrl + Shift + P -> 调用后端
if (e.ctrlKey && e.shiftKey && (e.key === 'p' || e.key === 'P')) {
e.preventDefault();
callBridge('openDevTools');
return;
}
// 2. 屏蔽 F12 (防止用户按下 F12 打开)
if (e.key === 'F12') {
e.preventDefault();
return;
}
});
// 开发环境 (localhost) 不初始化
if (/localhost/.test(window.location.href)) {
console.log('[pythonBridge] 开发环境,跳过初始化');
return;
}
await waitForPywebview();
if (window.pywebview && window.pywebview.api) {
bridge.value = window.pywebview.api;
isReady.value = true;
console.log('[pythonBridge] 初始化成功');
} else {
console.error('[pythonBridge] pywebview API 初始化失败');
}
};
export function usePythonBridge() {
// 调用 Python 方法
const fetchDataConfig = async (data) => {
if (!bridge.value) return null;
return await callBridge('fetchDataConfig', data);
};
// 查询获取主播的数据
const fetchDataCount = async () => {
if (!bridge.value) return null;
const result = await callBridge('fetchDataCount');
// pywebview 返回的是字符串,需要解析
try {
return typeof result === 'string' ? JSON.parse(result) : result;
} catch {
return result;
}
};
// 打开 tk 后台
const loginTikTok = () => {
callBridge('loginTikTok');
};
// 登录 tk 后台
const loginBackStage = (data) => {
if (data.index == 0) {
callBridge('loginBackStage', JSON.stringify(data));
} else if (data.index == 1) {
callBridge('loginBackStageCopy', JSON.stringify(data));
}
};
// 跳转到主播页面
const givePyAnchorId = (id) => {
callBridge('givePyAnchorId', id);
};
// 查询登录状态
const backStageloginStatus = async () => {
if (!bridge.value) return null;
const result = await callBridge('backStageloginStatus');
try {
return typeof result === 'string' ? JSON.parse(result) : result;
} catch {
return result;
}
};
// 查询登录状态(副账号)
const backStageloginStatusCopy = async () => {
if (!bridge.value) return null;
const result = await callBridge('backStageloginStatusCopy');
try {
return typeof result === 'string' ? JSON.parse(result) : result;
} catch {
return result;
}
};
// 导出表格
const exportToExcel = (data) => {
callBridge('exportToExcel', JSON.stringify(data));
};
const stopScript = () => {
callBridge('stopScript');
};
// 获取版本号
const getVersion = async () => {
if (!bridge.value) return null;
return await callBridge('currentVersion');
};
// 存储账号信息
const storageAccountInfo = async (key, data) => {
if (!bridge.value) return false;
return await callBridge('storageAccountInfo', key, JSON.stringify(data));
};
// 读取账号信息
const readAccountInfo = async (key) => {
if (!bridge.value) return null;
const result = await callBridge('readAccountInfo', key);
try {
return typeof result === 'string' ? JSON.parse(result) : result;
} catch {
return result;
}
};
// 在组件挂载时初始化桥接
onMounted(initBridge);
return {
isReady,
fetchDataConfig,
fetchDataCount,
loginBackStage,
loginTikTok,
givePyAnchorId,
backStageloginStatus,
backStageloginStatusCopy,
exportToExcel,
stopScript,
getVersion,
storageAccountInfo,
readAccountInfo,
};
}