2025-07-01 21:02:39 +08:00
|
|
|
|
// pythonBridge.js
|
|
|
|
|
|
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 18:57:30 +08:00
|
|
|
|
|
|
|
|
|
|
// 统一安全调用,确保 Qt 响应有回调可执行
|
|
|
|
|
|
const callBridge = (method, ...args) => {
|
|
|
|
|
|
if (!bridge.value || typeof bridge.value[method] !== 'function') return;
|
|
|
|
|
|
const last = args[args.length - 1];
|
|
|
|
|
|
const hasCallback = typeof last === 'function';
|
|
|
|
|
|
const callback = hasCallback ? args.pop() : () => { };
|
|
|
|
|
|
bridge.value[method](...args, callback);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 防御:若 Qt 返回了未知 id,忽略以免 execCallbacks 报错
|
|
|
|
|
|
const patchQWebChannel = () => {
|
|
|
|
|
|
if (!window.QWebChannel || QWebChannel.__patchedIgnoreMissing) return;
|
|
|
|
|
|
const originalHandleResponse = QWebChannel.prototype.handleResponse;
|
|
|
|
|
|
QWebChannel.__patchedIgnoreMissing = true;
|
|
|
|
|
|
QWebChannel.prototype.handleResponse = function (message) {
|
|
|
|
|
|
const cb = this.execCallbacks && this.execCallbacks[message.id];
|
|
|
|
|
|
if (message.id && typeof cb !== 'function') {
|
|
|
|
|
|
console.warn('忽略未知的 WebChannel 响应', message);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
return originalHandleResponse.call(this, message);
|
|
|
|
|
|
};
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-07-01 21:02:39 +08:00
|
|
|
|
// 初始化 QWebChannel
|
|
|
|
|
|
const initBridge = () => {
|
2026-01-07 18:57:30 +08:00
|
|
|
|
if (/localhost/.test(window.location.href)) return;
|
|
|
|
|
|
patchQWebChannel();
|
2025-07-01 21:02:39 +08:00
|
|
|
|
new QWebChannel(qt.webChannelTransport, (channel) => {
|
2026-01-07 18:57:30 +08:00
|
|
|
|
// 兜底:任何缺失的回调都返回空函数,避免 execCallbacks 报错
|
|
|
|
|
|
channel.execCallbacks = new Proxy(channel.execCallbacks || {}, {
|
|
|
|
|
|
get(target, prop) {
|
|
|
|
|
|
const val = target[prop];
|
|
|
|
|
|
if (typeof val === 'function') return val;
|
|
|
|
|
|
// 返回空函数,确保 handleResponse 可调用
|
|
|
|
|
|
return () => {};
|
|
|
|
|
|
},
|
|
|
|
|
|
set(target, prop, value) {
|
|
|
|
|
|
target[prop] = value;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-07-01 21:02:39 +08:00
|
|
|
|
bridge.value = channel.objects.bridge;
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-01-07 18:57:30 +08:00
|
|
|
|
export function usePythonBridge() {
|
2025-07-01 21:02:39 +08:00
|
|
|
|
// 调用 Python 方法
|
|
|
|
|
|
const fetchDataConfig = (data) => {
|
2026-01-07 18:57:30 +08:00
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
|
if (!bridge.value) return resolve(null);
|
|
|
|
|
|
callBridge('fetchDataConfig', data, (result) => {
|
|
|
|
|
|
resolve(result);
|
|
|
|
|
|
});
|
2025-07-01 21:02:39 +08:00
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 查询获取主播的数据
|
|
|
|
|
|
const fetchDataCount = () => {
|
2026-01-07 18:57:30 +08:00
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
|
if (!bridge.value) return resolve(null);
|
|
|
|
|
|
callBridge('fetchDataCount', (result) => {
|
|
|
|
|
|
resolve(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
|
|
|
|
// 查询登录状态
|
2025-07-01 21:02:39 +08:00
|
|
|
|
const backStageloginStatus = () => {
|
2026-01-07 18:57:30 +08:00
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
|
if (!bridge.value) return resolve(null);
|
|
|
|
|
|
callBridge('backStageloginStatus', (result) => {
|
|
|
|
|
|
resolve(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 backStageloginStatusCopy = () => {
|
2026-01-07 18:57:30 +08:00
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
|
if (!bridge.value) return resolve(null);
|
|
|
|
|
|
callBridge('backStageloginStatusCopy', (result) => {
|
|
|
|
|
|
resolve(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
|
|
|
|
// 获取版本号
|
2025-07-01 21:02:39 +08:00
|
|
|
|
const getVersion = () => {
|
2026-01-07 18:57:30 +08:00
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
|
if (!bridge.value) return resolve(null);
|
|
|
|
|
|
callBridge('currentVersion', (result) => {
|
|
|
|
|
|
resolve(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 {
|
|
|
|
|
|
fetchDataConfig,
|
|
|
|
|
|
fetchDataCount,
|
|
|
|
|
|
loginBackStage,
|
|
|
|
|
|
loginTikTok,
|
|
|
|
|
|
givePyAnchorId,
|
|
|
|
|
|
backStageloginStatus,
|
|
|
|
|
|
backStageloginStatusCopy,
|
|
|
|
|
|
exportToExcel,
|
|
|
|
|
|
stopScript,
|
2026-01-07 18:57:30 +08:00
|
|
|
|
getVersion,
|
2025-07-01 21:02:39 +08:00
|
|
|
|
};
|
2026-01-07 18:57:30 +08:00
|
|
|
|
}
|