Files
2026-07-13 19:57:46 +08:00

167 lines
5.0 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict';
const BUSINESS_SOURCE = 'LTJT_MOCK_BUSINESS';
const EXTENSION_SOURCE = 'LTJT_ORDER_ASSISTANT_EXTENSION';
const $ = (selector) => document.querySelector(selector);
function setText(selector, text) {
const el = $(selector);
if (el) el.textContent = text;
}
function setBadge(text, mode = '') {
const badge = $('#stateBadge');
if (!badge) return;
badge.textContent = text;
badge.classList.toggle('bad', mode === 'bad');
badge.classList.toggle('paused', mode === 'paused');
}
function isBusinessSystemUrl(url) {
return /^http:\/\/(localhost|127\.0\.0\.1)(?::(?:8765|8786))?\//i.test(url || '');
}
function friendlyError(error) {
const message = error?.message || String(error || '');
if (/Extension context invalidated/i.test(message)) {
return '插件刚重新加载,旧页面桥接已失效。请刷新业务系统页面后重新打开本面板。';
}
return message;
}
async function findBusinessTab() {
const tabs = await chrome.tabs.query({});
return tabs.find((tab) => isBusinessSystemUrl(tab.url)) || null;
}
async function pingBusinessBridge(tabId) {
await chrome.scripting.executeScript({
target: { tabId },
files: ['business-bridge.js']
});
const [probe] = await chrome.scripting.executeScript({
target: { tabId },
func: async (businessSource, extensionSource) => {
const requestId = `POPUP-PING-${Date.now()}-${Math.random().toString(16).slice(2)}`;
return new Promise((resolve) => {
const timer = window.setTimeout(() => {
window.removeEventListener('message', onMessage);
resolve({
ok: false,
message: '业务系统页面未收到插件桥接响应。'
});
}, 1500);
function onMessage(event) {
if (event.source !== window) return;
const message = event.data || {};
if (message.source !== extensionSource || message.requestId !== requestId) return;
window.clearTimeout(timer);
window.removeEventListener('message', onMessage);
resolve(message.payload || { ok: false, message: '插件桥接返回为空。' });
}
window.addEventListener('message', onMessage);
window.postMessage({
source: businessSource,
requestId,
type: 'PING',
payload: {}
}, window.location.origin);
});
},
args: [BUSINESS_SOURCE, EXTENSION_SOURCE]
});
return probe?.result || {
ok: false,
message: '无法读取业务系统桥接检测结果。'
};
}
async function detectBusinessConnection() {
const tab = await findBusinessTab();
if (!tab?.id) {
return {
connected: false,
bridge: null,
text: '未打开业务系统页面',
hint: '请打开生产控制平面或 http://127.0.0.1:8786/,然后刷新本面板。'
};
}
try {
const bridge = await pingBusinessBridge(tab.id);
if (!bridge.ok) {
return {
connected: false,
bridge,
text: '业务系统未联通',
hint: bridge.message || '插件桥接未响应。'
};
}
return {
connected: true,
bridge,
text: '已联通',
hint: '业务系统页面已收到插件桥接响应。'
};
} catch (error) {
return {
connected: false,
bridge: null,
text: '业务系统未联通',
hint: friendlyError(error)
};
}
}
async function readAutomationEnabled() {
const saved = await chrome.storage.local.get('erpAutomationEnabled');
return saved.erpAutomationEnabled !== false;
}
async function updateStatusPanel() {
setBadge('检测中');
setText('#versionLabel', `v${chrome.runtime.getManifest().version}`);
const [enabled, connection] = await Promise.all([
readAutomationEnabled(),
detectBusinessConnection()
]);
const toggle = $('#erpAutomationToggle');
if (toggle) toggle.checked = enabled;
if (!enabled) {
setBadge('已关闭', 'paused');
setText('#connectionText', connection.connected ? '已联通ERP 操作已关闭' : '未联通ERP 操作已关闭');
setText('#connectionHint', connection.connected
? '业务系统已连接;插件不会打开、填写或提交 ERP。'
: connection.hint);
return;
}
setBadge(connection.connected ? '已联通' : '未联通', connection.connected ? '' : 'bad');
setText('#connectionText', connection.connected ? '已联通ERP 操作已开启' : connection.text);
setText('#connectionHint', connection.connected
? '插件允许操作 ERP。任务创建和进度跟踪请在业务系统中完成。'
: connection.hint);
}
document.addEventListener('DOMContentLoaded', async () => {
const toggle = $('#erpAutomationToggle');
if (toggle) {
toggle.checked = await readAutomationEnabled();
toggle.addEventListener('change', async (event) => {
await chrome.storage.local.set({ erpAutomationEnabled: event.currentTarget.checked });
await updateStatusPanel();
});
}
await updateStatusPanel();
window.setTimeout(() => updateStatusPanel().catch(() => {}), 800);
});