Files
tkPage/src/utils/pythonBridge.js

192 lines
4.7 KiB
JavaScript
Raw Normal View History

2025-07-01 21:02:39 +08:00
// pythonBridge.js
2026-01-07 21:36:52 +08:00
// 适配 pywebview API (替代原有的 QWebChannel)
2025-07-01 21:02:39 +08:00
import { ref, onMounted } from 'vue';
2026-01-07 18:57:30 +08:00
2025-07-01 21:02:39 +08:00
const bridge = ref(null);
2026-01-07 21:36:52 +08:00
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 });
});
};
2026-01-07 18:57:30 +08:00
2026-01-07 21:36:52 +08:00
/**
* 统一安全调用 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;
}
2026-01-07 18:57:30 +08:00
};
2026-01-07 21:36:52 +08:00
/**
* 初始化 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');
2026-01-07 18:57:30 +08:00
return;
}
2026-01-07 21:36:52 +08:00
// 2. 屏蔽 F12 (防止用户按下 F12 打开)
if (e.key === 'F12') {
e.preventDefault();
return;
}
2025-07-01 21:02:39 +08:00
});
2026-01-07 21:36:52 +08:00
// 开发环境 (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 初始化失败');
}
2025-07-01 21:02:39 +08:00
};
2026-01-07 18:57:30 +08:00
export function usePythonBridge() {
2025-07-01 21:02:39 +08:00
// 调用 Python 方法
2026-01-07 21:36:52 +08:00
const fetchDataConfig = async (data) => {
if (!bridge.value) return null;
return await callBridge('fetchDataConfig', data);
2025-07-01 21:02:39 +08:00
};
// 查询获取主播的数据
2026-01-07 21:36:52 +08:00
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;
}
2025-07-01 21:02:39 +08:00
};
2026-01-07 18:57:30 +08:00
// 打开 tk 后台
2025-07-01 21:02:39 +08:00
const loginTikTok = () => {
2026-01-07 18:57:30 +08:00
callBridge('loginTikTok');
2025-07-01 21:02:39 +08:00
};
2026-01-07 18:57:30 +08:00
// 登录 tk 后台
2025-07-01 21:02:39 +08:00
const loginBackStage = (data) => {
2026-01-07 18:57:30 +08:00
if (data.index == 0) {
callBridge('loginBackStage', JSON.stringify(data));
} else if (data.index == 1) {
callBridge('loginBackStageCopy', JSON.stringify(data));
2025-07-01 21:02:39 +08:00
}
};
2026-01-07 18:57:30 +08:00
// 跳转到主播页面
2025-07-01 21:02:39 +08:00
const givePyAnchorId = (id) => {
2026-01-07 18:57:30 +08:00
callBridge('givePyAnchorId', id);
2025-07-01 21:02:39 +08:00
};
2026-01-07 18:57:30 +08:00
// 查询登录状态
2026-01-07 21:36:52 +08:00
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;
}
2025-07-01 21:02:39 +08:00
};
2026-01-07 18:57:30 +08:00
// 查询登录状态(副账号)
2026-01-07 21:36:52 +08:00
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;
}
2025-07-01 21:02:39 +08:00
};
2026-01-07 18:57:30 +08:00
// 导出表格
2025-07-01 21:02:39 +08:00
const exportToExcel = (data) => {
2026-01-07 18:57:30 +08:00
callBridge('exportToExcel', JSON.stringify(data));
2025-07-01 21:02:39 +08:00
};
2026-01-07 18:57:30 +08:00
const stopScript = () => {
callBridge('stopScript');
2025-07-01 21:02:39 +08:00
};
2026-01-07 18:57:30 +08:00
// 获取版本号
2026-01-07 21:36:52 +08:00
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;
}
2025-07-01 21:02:39 +08:00
};
2026-01-07 18:57:30 +08:00
2025-07-01 21:02:39 +08:00
// 在组件挂载时初始化桥接
onMounted(initBridge);
return {
2026-01-07 21:36:52 +08:00
isReady,
2025-07-01 21:02:39 +08:00
fetchDataConfig,
fetchDataCount,
loginBackStage,
loginTikTok,
givePyAnchorId,
backStageloginStatus,
backStageloginStatusCopy,
exportToExcel,
stopScript,
2026-01-07 18:57:30 +08:00
getVersion,
2026-01-07 21:36:52 +08:00
storageAccountInfo,
readAccountInfo,
2025-07-01 21:02:39 +08:00
};
2026-01-07 18:57:30 +08:00
}