'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); });