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

217 lines
6.8 KiB
JavaScript

(() => {
'use strict';
try {
if (window.__LTJT_ORDER_ASSISTANT_BRIDGE_HANDLER__) {
window.removeEventListener('message', window.__LTJT_ORDER_ASSISTANT_BRIDGE_HANDLER__);
}
} catch (error) {
// Old handlers can belong to an invalidated extension context after reload.
}
try {
if (window.__LTJT_ORDER_ASSISTANT_STORAGE_HANDLER__) {
chrome.storage.onChanged.removeListener(window.__LTJT_ORDER_ASSISTANT_STORAGE_HANDLER__);
}
} catch (error) {
// Re-injection must keep going even when Chrome has invalidated the old context.
}
window.__LTJT_ORDER_ASSISTANT_BRIDGE_INSTALLED_AT__ = new Date().toISOString();
const BUSINESS_SOURCE = 'LTJT_MOCK_BUSINESS';
const EXTENSION_SOURCE = 'LTJT_ORDER_ASSISTANT_EXTENSION';
function nowIso() {
return new Date().toISOString();
}
function postReply(requestId, type, payload = {}) {
window.postMessage({
source: EXTENSION_SOURCE,
requestId,
type,
payload
}, window.location.origin);
}
async function getAutomationState() {
const saved = await chrome.storage.local.get('erpAutomationEnabled');
const enabled = saved.erpAutomationEnabled !== false;
return {
erp_automation_enabled: enabled,
erp_automation_status: enabled ? 'enabled' : 'disabled'
};
}
async function bridgePayload(extra = {}) {
return {
ok: true,
extension: 'ltjt-order-assistant',
version: chrome.runtime.getManifest().version,
bridge_installed_at: window.__LTJT_ORDER_ASSISTANT_BRIDGE_INSTALLED_AT__ || '',
...(await getAutomationState()),
...extra
};
}
async function postBridgeReady() {
window.postMessage({
source: EXTENSION_SOURCE,
type: 'BRIDGE_READY',
payload: await bridgePayload()
}, window.location.origin);
}
async function getResultMap() {
const saved = await chrome.storage.local.get('businessTaskResults');
return saved.businessTaskResults || {};
}
async function removeStoredBusinessTask(taskId) {
const saved = await chrome.storage.local.get([
'businessTasks',
'businessTaskResults',
'currentBusinessTask',
'currentBusinessTaskId'
]);
const belongsToTask = (candidateId) => candidateId === taskId || candidateId.startsWith(`${taskId}#`);
const businessTasks = saved.businessTasks || {};
const businessTaskResults = saved.businessTaskResults || {};
Object.keys(businessTasks).filter(belongsToTask).forEach((candidateId) => delete businessTasks[candidateId]);
Object.keys(businessTaskResults).filter(belongsToTask).forEach((candidateId) => delete businessTaskResults[candidateId]);
await chrome.storage.local.set({ businessTasks, businessTaskResults });
if (saved.currentBusinessTaskId === taskId || saved.currentBusinessTask?.task_id === taskId) {
await chrome.storage.local.remove([
'currentBusinessTask',
'currentBusinessTaskId',
'lastOperation',
'lastRawText'
]);
}
}
async function cancelAndRemoveTask(taskId) {
const cancellation = await chrome.runtime.sendMessage({
type: 'LTJT_CANCEL_TASK',
task_id: taskId
});
if (cancellation?.ok === false) {
throw new Error(cancellation.message || '插件未确认任务已取消。');
}
await removeStoredBusinessTask(taskId);
return {
ok: true,
task_id: taskId,
status: 'cancelled',
cancelled: cancellation?.cancelled !== false
};
}
async function createTask(payload) {
const task = payload?.task || {};
const operation = task.operation || payload?.operation;
const taskId = task.task_id || operation?.source?.task_id || `MOCK-${Date.now()}`;
const executionId = String(payload?.execution_id || '').trim();
if (!operation) throw new Error('Missing task.operation');
if (!executionId) throw new Error('Missing execution_id');
operation.source = {
...(operation.source || {}),
task_id: taskId,
execution_id: executionId,
origin: 'mock-business-system',
handed_to_extension_at: nowIso()
};
const currentBusinessTask = {
task_id: taskId,
operation,
raw_text: task.raw_text || '',
created_at: task.created_at || nowIso(),
received_at: nowIso(),
execution_id: executionId,
status: 'queued'
};
const acceptance = await chrome.runtime.sendMessage({
type: 'LTJT_AUTO_EXECUTE_TASK',
task_id: taskId,
execution_id: executionId,
task: currentBusinessTask
});
return { ...currentBusinessTask, acceptance };
}
const bridgeHandler = async (event) => {
if (event.source !== window) return;
const message = event.data || {};
if (message.source !== BUSINESS_SOURCE) return;
const requestId = message.requestId || '';
try {
if (message.type === 'PING') {
postReply(requestId, 'PONG', await bridgePayload());
return;
}
if (message.type === 'CREATE_TASK') {
const task = await createTask(message.payload || {});
postReply(requestId, 'TASK_CREATED', {
ok: true,
task_id: task.task_id,
execution_id: task.execution_id,
accepted: task.acceptance?.accepted === true,
status: task.acceptance?.status || 'not_accepted',
message: task.acceptance?.message || ''
});
return;
}
if (message.type === 'GET_TASK_RESULT') {
const taskId = message.payload?.task_id || '';
const resultMap = await getResultMap();
postReply(requestId, 'TASK_RESULT', {
ok: true,
task_id: taskId,
result: resultMap[taskId] || null
});
return;
}
if (message.type === 'GET_CURRENT_TASK') {
const saved = await chrome.storage.local.get('currentBusinessTask');
postReply(requestId, 'CURRENT_TASK', {
ok: true,
task: saved.currentBusinessTask || null
});
return;
}
if (message.type === 'DELETE_TASK') {
const taskId = message.payload?.task_id || '';
if (!taskId) throw new Error('Missing task_id');
const result = await cancelAndRemoveTask(taskId);
postReply(requestId, 'TASK_DELETED', result);
return;
}
if (message.type === 'CLEAR_TASKS') {
await chrome.storage.local.remove(['currentBusinessTask', 'currentBusinessTaskId', 'businessTasks', 'businessTaskResults']);
postReply(requestId, 'TASKS_CLEARED', { ok: true });
return;
}
postReply(requestId, 'ERROR', {
ok: false,
message: `Unknown bridge message type: ${message.type || '<missing>'}`
});
} catch (error) {
postReply(requestId, 'ERROR', {
ok: false,
message: error.message || String(error)
});
}
};
window.__LTJT_ORDER_ASSISTANT_BRIDGE_HANDLER__ = bridgeHandler;
window.addEventListener('message', bridgeHandler);
window.__LTJT_ORDER_ASSISTANT_STORAGE_HANDLER__ = (changes, areaName) => {
if (areaName !== 'local' || !changes.erpAutomationEnabled) return;
postBridgeReady().catch(() => {});
};
chrome.storage.onChanged.addListener(window.__LTJT_ORDER_ASSISTANT_STORAGE_HANDLER__);
postBridgeReady().catch(() => {});
})();