Files
LWLT-AIBOT/chrome-extension/ltjt-order-assistant/hotel-batch.js
T
2026-09-24 14:43:08 +08:00

73 lines
4.6 KiB
JavaScript
Raw 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.
(function (root, factory) {
const api = factory();
if (typeof module === 'object' && module.exports) module.exports = api;
root.LTJTHotelBatch = api;
})(typeof self !== 'undefined' ? self : globalThis, function () {
'use strict';
const object = value => value && typeof value === 'object' && !Array.isArray(value) ? value : {};
const group = value => String(value || '').normalize('NFKC').replace(/\s+/gu, '').toUpperCase();
function verified(result, identifier) {
const report = object(result?.report), refs = object(report.resolved_refs);
return result?.status === 'completed' && report.status === 'lifecycle_completed' && report.server_response?.completed === true
&& report.requery?.matched === true && report.requery?.skipped !== true
&& !result.uncertain && !result.manual_review_required && !report.manual_review_required
&& ![result.blockers, report.blockers].some(value => Array.isArray(value) && value.length)
&& refs.kind !== 'shared_child_order' && group(refs.identifier || refs.group_no) === group(identifier);
}
function inspect(value) {
const batch = object(value), items = batch.items;
if (batch.version !== 1 || !group(batch.group_number) || !Array.isArray(items)
|| items.length < 2 || items.length > 10) return null;
let stopped = false, pending = false, completed = 0, failed = 0, uncertain = 0;
const rowIds = new Set();
for (let index = 0; index < items.length; index++) {
const item = object(items[index]);
if (item.index !== index || item.arrangement?.mode !== 'create') return null;
if (item.status === 'completed') {
if (stopped || pending || !verified(item.result, batch.group_number)) return null;
const subpage = object(item.result.report.requery.subpage), target = object(subpage.arrangement_target);
const rowId = String(target.row_id || '');
if (!rowId || rowId === '0' || rowIds.has(rowId)) return null;
rowIds.add(rowId);
const normalizeDate = value => String(value || '').replace(/^(\d{4})-(\d{1,2})-(\d{1,2})$/, (_, y, m, d) => `${y}-${m.padStart(2, '0')}-${d.padStart(2, '0')}`);
const checks = Array.isArray(subpage.checks) ? subpage.checks : [];
const actual = pattern => checks.filter(check => check.matched === true && pattern.test(check.field));
for (const [pattern, expected] of [[/^riqi\d+$/, item.arrangement.start_date], [/^riqis\d+$/, item.arrangement.end_date]]) {
const matches = actual(pattern);
if (matches.length !== 1 || normalizeDate(matches[0].actual) !== expected) return null;
}
if (Number(target.quantity_value) !== item.arrangement.room_count) return null;
completed++;
} else if (item.status === 'failed') {
if (stopped || pending || item.result?.no_erp_write !== true || item.result?.write_attempted === true) return null;
stopped = true; failed++;
} else if (item.status === 'uncertain') {
if (stopped || pending) return null;
stopped = true; uncertain++;
} else if (item.status === 'running') {
if (stopped || pending) return null;
pending = true;
} else if (item.status === 'not_started') pending = true;
else return null;
}
return { completed, failed, uncertain, total: items.length,
not_started: items.filter(item => item.status === 'not_started').length,
allCompleted: completed === items.length, knownStopped: (failed === 1 || (batch.stopped === true && completed > 0 && !items.some(item => item.status === 'running'))) && uncertain === 0 };
}
function resultText(batch) {
const stats = inspect(batch);
if (!stats) return '';
const lines = [`共 ${stats.total} 条:成功 ${stats.completed} 条,失败 ${stats.failed} 条,待核验 ${stats.uncertain} 条,未执行 ${stats.not_started} 条`];
const labels = { completed: '已完成', failed: '失败', uncertain: '结果不确定,待只读回查', not_started: '未执行', running: '处理中' };
batch.items.forEach(item => {
const a = item.arrangement;
lines.push('', `${item.index + 1}. ${String(a.start_date).replaceAll('-', '/')}—${String(a.end_date).replaceAll('-', '/')}`,
` 酒店搜索:${a.resource?.keyword || a.resource?.name || ''};${a.room_count} 间`, ` ${labels[item.status]}`);
if (item.status === 'failed') lines.push(` 原因:${String(item.result?.failure_message || item.result?.message || '执行阻断').slice(0, 250)}`);
});
if (!stats.allCompleted) lines.push('', '已完成的安排已保留,请勿整批重复提交。');
return lines.join('\n');
}
return { verified, inspect, resultText };
});