修复匹配的问题

This commit is contained in:
andy committed 2026-09-19 11:06:02 +08:00
1 parent 6eeaee07d4
commit ea9c4b34c6
23 files changed
+470 -31

No files matched your search

@@ -11,9 +11,13 @@ Chrome Manifest V3 扩展,在用户已登录的 LTJT ERP 页面内执行经过
## 当前版本
当前源码版本为 `0.5.187`。版本化 ZIP、文件哈希和 Skill/DOCX 基线见 [`../../dist/release-manifest.json`](../../dist/release-manifest.json)。旧版本实现流水已冻结在 [`../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md`](../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md)。
当前源码版本为 `0.5.188`。版本化 ZIP、文件哈希和 Skill/DOCX 基线见 [`../../dist/release-manifest.json`](../../dist/release-manifest.json)。旧版本实现流水已冻结在 [`../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md`](../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md)。
0.5.187 当前重点:
0.5.188 当前重点:
- 独立团单个下单的产品名比较统一输入与 ERP 候选的 NFKC 和空白格式,精确优先、唯一包含兜底,保留其他标点及业务限定词;归一后多候选仍阻断。选中后以 ERP 原名填写及触发原生联动。初始匹配/校验失败保持表单未填写,后续阶段标记跳过,产品零/多候选分别给出中文原因。程序解析器 v1.0.14 保留 keyword 的原始格式,name 沿用既有归一化。需同步更新服务端、插件和平台最低版本,无迁移;本地合成验证通过,真实 ERP 验收待部署方完成。
继续保留 0.5.187 的房型修改:
- 独立团修改新增 DBL 大床房到 frenshu3 的字段映射,与 SGL/TWN 一样按明确目标值填写,重新计算房间合计,并通过保存后 fresh GET 核对大床房和合计。程序解析器 v1.0.13 兼容“房间数更改为 12 标+2 大”;未指定房型保持原值,其他未实现字段继续整体阻断。需同步更新服务端、插件和平台最低版本,无数据库迁移;本地合成验证通过,真实 ERP 实写待验收。
@@ -388,6 +388,38 @@
};
}
function selectUniqueProductOption(text, expected) {
// Normalize both sides for comparison only. Preserve punctuation and
// business qualifiers; the selected row still carries ERP's original
// name for Find_product/GetProduct and subsequent exact form checks.
const normalize = (value) => String(value || '').normalize('NFKC').replace(/\s+/gu, '');
const target = normalize(expected);
const candidates = rows(text);
const exact = target ? candidates.filter((row) => normalize(row.columns[1]) === target) : [];
const contains = target ? candidates.filter((row) => normalize(row.columns[1]).includes(target)) : [];
const matches = exact.length ? exact : contains;
if (matches.length === 1) {
return {
match: matches[0],
rule: exact.length ? 'exact_normalized' : 'unique_contains_normalized',
exact_count: exact.length,
contains_count: contains.length,
blocker: ''
};
}
return {
match: null,
rule: !target ? 'missing_keyword' : (matches.length ? 'ambiguous_normalized' : 'not_found'),
exact_count: exact.length,
contains_count: contains.length,
blocker: !target
? '产品搜索不能为空。'
: matches.length
? `产品搜索匹配到 ${matches.length} 个产品,无法唯一选择,请补充更完整的产品名称。`
: '未找到匹配的产品,请核对产品名称或搜索关键词。'
};
}
async function sha256(text) {
const buffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(text));
return Array.from(new Uint8Array(buffer)).map((byte) => byte.toString(16).padStart(2, '0')).join('');
@@ -5675,7 +5707,7 @@
summary: summarizeText(fetched.customer?.text || '')
};
const productSelection = selectUniqueExistingOption(fetched.product?.text || '', data.product?.name, 1, 'product');
const productSelection = selectUniqueProductOption(fetched.product?.text || '', data.product?.name);
if (!productSelection.match) blockers.push(productSelection.blocker);
const productInitialCheck = {
name: 'product_initial_selection',
@@ -5687,6 +5719,32 @@
summary: summarizeText(fetched.product?.text || '')
};
// Nothing has been applied yet. A failed lookup/contract must not be
// reported again as failures of linkage, restoration or blank fields in
// the untouched form. Keep the initial evidence and stop before mutation.
if (blockers.length) {
const skippedStages = ['preflight_product_linkage', 'preflight_customer_restore', 'preflight_final_form_validation', 'preflight_submit_intercept'];
return {
ok: true,
status: 'raw_instruction_preflight_blocked',
page: { url: location.href, title: document.title, form_element_count: form.elements.length },
lookup_checks: [customerInitialCheck, productInitialCheck],
product_side_effect: { status: 'skipped', ajax_records: [], changed_field_count: 0, changed_field_groups: {}, changed_field_names: [] },
set_summary: { set_field_count: 0, set_field_names: [], set_results: [] },
skipped_stages: skippedStages,
submit_intercept: null,
submit_safety: { live_submit_attempted: false, DoInfoJH_network_prevented: false, note: 'Initial preflight failed; form mutation and submission were not attempted.' },
no_erp_write: true,
write_attempted: false,
blockers,
warnings,
__ltjt_page_action_details: [
...timingDetails,
...skippedStages.map((step) => ({ step, status: 'skipped', duration_ms: 0 }))
]
};
}
const jq = window.jQuery || window.$;
const originalAjax = jq?.ajax;
let resolveProductEffectCompletion = null;
@@ -6619,7 +6677,7 @@
}
window.LTJTOrderAssistant = {
version: '0.5.187',
version: '0.5.188',
resolveNativeListSearchValues,
lookupKeywordMatchesText,
inspectLifecycleSearchCriteria: lifecycleSearchCriteria,
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "联泰下单助手",
"version": "0.5.187",
"version": "0.5.188",
"description": "在已登录 LTJT ERP 页面内规划并受控执行联泰 ERP 业务操作。",
"permissions": [
"activeTab",
@@ -944,7 +944,7 @@
window.LTJTOrderAssistant = {
...(window.LTJTOrderAssistant || {}),
version: '0.5.187',
version: '0.5.188',
openTeamBatchForm,
pingTeamBatchFrame,
preflightTeamBatchNative,