修复匹配的问题
This commit is contained in:
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,
|
||||
|
||||
Reference in new issue
Block a user