shopeeproduct/service.go:389-391(SetMapping)文档注释明确:"An exact-name match or an AI suggestion is always written as pending regardless of what the caller sends; only a manual mapping may start confirmed"——AI 来源的映射结果无论置信度多高,写入时一律 pending,没有例外。match_worker.go 里达到 AutoConfirmMinConfidence 阈值即采用的 AI 结果,只写入对应采购任务自己的快照字段(mapped_color_snapshot 等),从未写入或影响过 shopee_product.specs_json 里的 Mapping,因此不构成"AI 结果可以免人工直接持久化为 confirmed"的先例。本单如果要让批量 AI 匹配的结果直接可用,必须遵守 SetMapping 现有规则写成 pending,再走既有 ConfirmMapping 完成人工确认,不能绕过。
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
原始需求摘要
来源:用户于 2026-09-01 提出,在 SYB 商品页「创建采购」按钮左边加一个「AI 匹配」按钮,批量匹配当前勾选的 SYB 货运单商品各自需要的单个规格(不是虾皮商品的全部规格表)与 PDD 商品规格。讨论后确认:
SetMapping规则写成pending(不新增"AI 结果可免人工直接生效"的例外),需要人工确认后才能被「创建采购」识别为可用;本单不实现自动确认,是否放宽为高置信度自动确认是需要用户单独决定的选项,本单不默认采用。创建 PDD 采集(N)、创建采购(N)的括号计数改为更轻量的角标样式(不是直接删除计数——用户确认计数含义与页面已有的「已选择 N 条」不同,需要保留,只是不再用突出的括号正文形式);创建 PDD 采集简化为创建采集(去掉 "PDD" 前缀,与相邻的"创建采购"已经能区分含义)。目标是让查询相关控件和这些按钮尽量在同一行,不占两行。目的:解决 #164 之前讨论中发现的真实缺口——批量「创建采购」内部只做确定性匹配(
previewOneDeterministic),需要 AI 才能判定的 SYB 订单会被直接跳过标成"颜色待匹配",此前唯一的解决路径是逐条进虾皮商品详情页用 #172 的 AI 匹配按钮处理,跟批量采购的操作节奏脱节。基线与已核实事实
代码基线:
6ab2f62(2026-09-01,含 #186 抽屉内联改动)。核验日期 2026-09-01。purchase/batch.go:233-266(BatchCreate)对每个待创建的 SYB 订单先跑previewOneDeterministic(仅确定性匹配,不含 AI),!preview.Eligible时直接continue,不会调用到s.Create()——意味着match_worker.go里那套"创建任务后自动排队 AI 匹配"的机制,对批量创建路径里需要 AI 才能解决的订单从未被触发。syb-products/index.vue:186(purchaseCandidates)在客户端就已经把processStage !== 'purchase_ready'的行排除在「创建采购」按钮计数之外,处于color_mapping阶段的行目前唯一的处理入口是单行「去匹配」链接(processNextAction === 'open_mapping',runPurchaseNextAction里openShopeeDetail),跳到虾皮商品详情页走 #172 的人工/AI 匹配流程。shopeeproduct/service.go:389-391(SetMapping)文档注释明确:"An exact-name match or an AI suggestion is always written as pending regardless of what the caller sends; only a manual mapping may start confirmed"——AI 来源的映射结果无论置信度多高,写入时一律pending,没有例外。match_worker.go里达到AutoConfirmMinConfidence阈值即采用的 AI 结果,只写入对应采购任务自己的快照字段(mapped_color_snapshot等),从未写入或影响过shopee_product.specs_json里的Mapping,因此不构成"AI 结果可以免人工直接持久化为confirmed"的先例。本单如果要让批量 AI 匹配的结果直接可用,必须遵守SetMapping现有规则写成pending,再走既有ConfirmMapping完成人工确认,不能绕过。purchase/service.go:127-138(confirmedMappings)判定"是否已解决",只认Mapping.Status == confirmed;pending状态的映射不会让previewOneDeterministic/confirmedMappings判定为已解决,因此仅仅写入pending还不足以让「创建采购」通过,必须补一步人工确认。syb-products/index.vue:6-15)已经很拥挤:已选择 N 条、店铺 autocomplete、订单号多行输入框、解析状态/处理阶段两个下拉、查询、重置、创建采购(N)、创建 PDD 采集(N),共 8 个控件挤在同一el-form :inline="true"行内,再加一个「AI 匹配」按钮会更紧张,实际能否不换行取决于目标浏览器宽度,无法仅凭代码静态判断,需要在标注截图/实测中确认。aimatching.SuggestBatch(#172,server/app/goauto/aimatching/suggest.go)是"短编号绑定、批量单次调用"的通用批量建议能力,但其设计对象是一个虾皮商品的全部规格值;本单需要的是多个虾皮商品各自一个规格值,语义不同,不能直接套用同一个函数签名,需要新的服务方法组织输入(每个 SYB 订单贡献一个来源短编号,候选集合是各自关联 PDD 商品的对应维度规格),但可以复用aimatching.Resolve(server/app/goauto/aimatching/service.go,确定性优先、AI 兜底,即match_worker.go已经在用的同一逻辑)按订单逐个调用,不必新增批量 prompt。判断边界
confirmed"的例外,通过独立写入路径实现,不改变SetMapping通用接口的既有强制pending规则;未达阈值的结果不享受此例外,仍需人工处理。此为用户在明确了解"当前SetMapping从未允许 AI 来源直接confirmed"这一事实后做出的决定。创建 PDD 采集简化为创建采集。目标
color_mapping阶段的行,批量解析各自需要的单个颜色/尺码规格。AutoConfirmMinConfidence阈值时,通过独立写入路径直接落成confirmed(不经过通用SetMapping的强制pending规则,SetMapping本身及其现有调用方——包括 #172——不受影响、不修改);未达阈值时仍按SetMapping现有语义写成pending,留给人工在虾皮商品详情页用 #172 处理。confirmed)、多少条置信度不足留给人工处理(pending)、多少条解析失败及原因;一个「关闭」按钮,不需要勾选或点击确认。confirmed的映射,能让previewOneDeterministic/confirmedMappings立即判定为已解决;关闭结果弹窗后自动刷新purchaseReadiness,「创建采购」按钮的候选数与可用性立刻反映最新状态,用户可以直接点「创建采购」,无需额外操作。创建 PDD 采集(N)→创建采集+ 轻量角标 N;创建采购(N)→创建采购+ 轻量角标 N;为「AI 匹配」按钮腾出位置,尽量让查询控件与这些按钮保持同一行。非目标
SetMapping本身的通用接口行为;本单新增的自动确认能力必须走独立的写入路径,不能让SetMapping对其余调用方(含 #172)也开始允许 AI 来源直接confirmed。ConfirmMapping)以及匹配引擎(aimatching.Resolve)。BatchCreate/previewOneDeterministic的既有判定逻辑,本单让更多订单"提前具备confirmed映射",从而自然通过既有检查,不改检查本身。前置依赖与并行性
ConfirmMapping、aimatching.Resolve、置信度阈值配置,均已存在,无需等待。6ab2f62),本单在其基础上继续,不冲突。固定实施方案
1. 服务端
purchase.Service.SuggestSpecMatches或放在shopeeproduct包):接收 SYB 订单 id 列表,逐个查出各自关联的虾皮商品、目标颜色/尺码、关联 PDD 商品的候选规格值,跳过已经是confirmed的(无需重复解析),对其余的调用aimatching.Resolve。SetMapping,而是本单新增的独立写入路径:matched.Decision.Confidence >= AutoConfirmMinConfidence(aimatching设置里已有的同一个阈值,与 #172、match_worker.go共用同一字段)时,直接写入Mapping{PDDValue, Source: matched.Source, Status: confirmed, Confidence, Reason};SetMapping既有语义写pending(或不写,留给人工从头处理),不享受自动确认。SetMapping函数本身及其"AI/exact_match 来源强制pending"的规则不做任何修改,本单的独立写入路径是新代码,不是放宽SetMapping的参数或分支。confirmed)、自动确认成功(附来源、置信度、理由)、留待人工(置信度不足,附理由)、解析失败(无候选/AI 不可用等,附原因)。2. 前端
syb-products/index.vue工具栏新增「AI 匹配」按钮,禁用条件参考"当前勾选中是否存在color_mapping阶段的行"。purchaseReadiness(复用loadPurchaseReadiness),让"创建采购"按钮的候选数与处理阶段标签立刻反映刚刚自动确认的结果,用户可以直接继续点「创建采购」。创建 PDD 采集简化为创建采集。设计证据
新增按钮与结果确认弹窗,交互模式复用现有批量操作弹窗(
purchaseDialog/collectionBatch),不引入新的交互范式。2026-09-01 用户确认:工具栏文案与视觉精简改动范围小、交互不变,用户已认可上方文字方案描述,不要求标注截图,可直接据此实施;单行布局的实际效果在实施后如与预期不符,再另行调整,不作为阻塞实施的前置条件。验收标准
color_mapping阶段的 SYB 订单,点击「AI 匹配」,能正确解析各自需要的单个规格并展示结果(自动确认/留待人工/失败/已跳过)。AutoConfirmMinConfidence阈值的结果,直接写入对应虾皮商品规格表为confirmed,无需任何人工点击确认。pending,不会被本单的入口自动确认,仍需走 #172 人工处理。shopeeproduct.SetMapping函数本身未被修改,其在 #172 及其余调用方的行为(AI 来源强制pending)保持不变;本单的自动确认逻辑证明为独立写入路径,未复用/修改SetMapping的分支判断。ConfirmMapping、BatchCreate、previewOneDeterministic的既有判定逻辑。必测场景
confirmed(应跳过重复解析)、color_mapping(应解析)、其他阶段(不参与)三种混合情况。pending,两者互不影响,各自状态正确。purchaseReady(row)结果与预期一致,被自动确认的订单可以直接点击创建采购成功。风险与安全门禁
confirmed——这是本单唯一放开人工确认要求的场景。SetMapping通用接口及 #172 等其余调用方必须继续保持"AI/exact_match 来源强制pending",不得被本单的改动波及。match_worker.go现有的"只影响单条采购任务快照"的自动匹配机制影响范围更大、更持久。这是用户在明确该差异后仍然要求简化流程所接受的取舍,工单如实记录,不代表该风险不存在。文档影响
无长期文档影响。 未新增持久化数据结构(复用既有
Mapping字段与既有确认接口),未改变已有业务规则;仅新增一个批量触发入口和对应的前端交互。若实施后发现需要新增独立接口且改变共享契约,届时在实施过程中重新判断并回写本工单。状态
已确认,可以实施(2026-09-01 创建;同日修订为"达到置信度阈值免人工自动确认",用户在了解风险后重申并采纳;同日用户明确"不用截图,方案文字描述我认可了",设计证据门槛以文字方案确认放行,不再要求界面标注截图)。
实施完成,待验收
实现
POST /api/admin/v1/purchase-tasks/batch-spec-match(1~100 条,管理员/采购员可用),仅处理当前处于color_mapping的 SYB 明细并逐条返回auto_confirmed/pending/failed/skipped。autoConfirmMinConfidence;只有source=ai_match、置信度存在且达到阈值、候选和理由完整时,才通过独立写入路径原子保存为confirmed。SetMapping、ConfirmMapping、BatchCreate、previewOneDeterministic行为未改变。验证
go test ./app/goauto/purchase ./app/goauto/shopeeproduct ./app/goauto/access:通过。go test ./...:通过(因系统盘空间不足,将 Go 临时目录切换到D:\Temp\goauto-188后执行)。pnpm run build:prod:通过;仅有既存 lightningcss/大 chunk 警告。tests/e2e/syb-product-layout.spec.ts:8 passed。python dev_scripts/harness.py check --strict:通过。sync+sync --check:通过。git diff --check/ 提交差异检查:通过。web/src/views/goauto/purchase-tasks/index.vue混合缩进问题阻塞(24 errors,41 warnings),该文件不在 #188 范围,本次未修改。文档
Business-Rules-and-Glossary:revision084dae8190b765758cc77a59732215bd8a9ca6fe。Android-Agent-API-Contract:revision44f936706dfd36b0281215a239b790bbe50aaf77。提交与上线
3ef0f72(已推送main)。/home/goauto/releases/20260901-121758-3ef0f72。/home/goauto/releases/20260901-112853-6ab2f62。8b3420d9b04704cd59f0acb61ee4e011ac9c267fe153238a5093d321dfefa9d8。goauto.service:active;Nginx 配置检查通过。code=401,说明新路由已加载且鉴权生效。工单保持打开,等待用户验收。
需求变更:批量 AI 匹配资格改为显式业务判定(待用户重新确认)
变更来源
用户在 #188 上线后进一步澄清业务含义:批量 AI 匹配的对象是“每条 SYB 货运单商品已经解析出的采购规格”,候选是“该蝦皮商品所关联 PDD 商品的全部当前可选规格”。满足前置条件并匹配成功后,该 SYB 明细应变为“可创建采购”,但不自动创建采购任务、订单或支付。
线上复核发现:当前第一页勾选 17 条时显示“AI 匹配 0”,原因是现实现仅以
processStage === color_mapping作为候选条件;第一页 20 条实际为 15 条“可创建采购”、2 条“PDD 待采集”、3 条“未关联 PDD”,没有color_mapping。计数符合原 #188 固定方案,但“候选资格”表达过度依赖处理阶段字符串,不能直接说明两端规格是否真的具备匹配条件。修订目标
aiMatchEligible:当前明细是否可以运行批量 AI 规格匹配;aiMatchDisabledReason:不可运行时的明确原因;aiMatchEligible=true的明细,不再自行使用processStage === color_mapping推导资格。processStage继续作为页面流程展示;color_mapping应是服务端资格和当前映射状态计算后的结果,而不是前端候选资格的唯一事实来源。AI 匹配资格(修订草案)
一条 SYB 明细仅在同时满足以下条件时为
aiMatchEligible=true:confirmed映射或唯一确定性结果;不可匹配时至少区分:采购规格未完整解析、解析存疑、未关联蝦皮/PDD、PDD 待采集或采集中、PDD 采集失败、PDD 无可选规格、已有有效映射无需 AI、已有采购任务。
需要重新确认的安全边界
建议口径:
parse_status=uncertain(解析存疑)不进入高置信自动确认。 即使目标颜色/尺码字段非空,也先人工修正解析结果,再进入批量 AI 匹配,避免错误的 SYB 来源规格被永久保存为共享的蝦皮→PDDconfirmed映射。如果用户要求“解析存疑但字段非空也允许 AI”,需要单独明确接受其误确认风险,并决定是否只允许生成
pending、禁止自动confirmed。匹配输入、写入与结果
confirmed映射重复调用 AI 或覆盖。confirmed,刷新批量预检后变为“可创建采购”。非目标与不变项
SetMapping的 AI 强制pending语义;高置信自动确认继续限定在 #188 独立入口。修订验收与必测场景
aiMatchEligible与禁用原因,前端按钮计数与服务端一致。SetMapping、BatchCreate、采购安全边界及订单/支付禁令没有变化。当前状态
#188 已上线但尚未验收。本变更属于候选资格/API/UI 行为调整,现标记为待用户重新确认;确认前不修改生产代码、不再次发布。确认后继续在 #188 内实施、测试、更新共享 API/Wiki、提交推送,并在单独取得线上发布授权后再部署。
修订方案已确认,待实施
实施完成,待验收
已按 2026-09-01 确认的 #188 修订方案完成并推送,提交:
5446ebe。实现
batch-preview新增显式aiMatchEligible/aiMatchDisabledReason;Admin 候选数和勾选资格只认服务端字段,不再以processStage=color_mapping推断。parse_status=success、蝦皮/PDD 关联完整、PDD 当前规格可用且最近成功/部分成功采集存在完整可售 SKU 组合证据的明细可进入批量 AI 匹配;uncertain必须先人工修正。验证
go test ./app/goauto/purchase -count=1:通过。go build:通过。pnpm exec eslint src/views/goauto/syb-products/index.vue:通过。pnpm run build:prod:通过(仅既有 CSS/chunk size 警告)。pnpm exec playwright test tests/e2e/syb-product-layout.spec.ts:8/8 通过。python dev_scripts/harness.py check --strict:通过。git diff --cached --check:通过(提交前)。已知的非本工单阻断
go test ./...:app/goauto/apprelease.TestParseBuiltAgentAPKWhenAvailable读取到工作区既有 APK0.9.37(versionCode 50),与测试绑定期望不一致;#188 的 purchase 包已单独全通过。pnpm run lint:被未修改的web/src/views/goauto/purchase-tasks/index.vue既有 Tab/空格混排阻断;本工单修改页面单文件 lint 已通过。sync --check串行逐页访问 Gitea 很慢,最终仅报告用户原有docs/12-syb-erp-interface.md重复镜像头且 revision/正文不一致;未覆盖该无关改动。#188 两页已在线回读并同步:Business-Rules-and-Glossary@b9d13a3576f331091687bca1d6407f9d41901fad、Android-Agent-API-Contract@5afa14ea875e38dc08718a19d4646147a56d829f。请按修订后的 SYB 商品页 AI 候选数、禁用原因、混合批次结果和可采购状态进行验收;工单保持开启。
需求再次修订并确认(2026-09-01)
用户确认:AI 匹配的业务含义是,把一条 SYB 货运单商品已解析出的目标颜色、目标尺码,与其关联 PDD 商品的可售规格组合进行匹配。
本次以以下规则替换此前“可在创建采购时临时确定性匹配”的口径:
exact_match + confirmed保存;其余候选再调用 AI。ai_match + confirmed保存。追加验收:
实施完成,待验收(2026-09-01)
已按评论 6917 的修订规则完成并推送。
实现结果
batch-preview仅在已保存确认映射且该颜色+尺码共同命中最近一次成功/部分成功采集的完整可售 SKU 组合时返回eligible=true。batch-spec-match遇到唯一确定性结果时不调用外部 AI,直接以exact_match + confirmed保存;非确定性结果仍需 AI 高置信度、理由和可售组合校验后才保存。batch创建入口重新执行上述持久化映射门禁,未保存确认映射时返回PURCHASE_SPEC_MAPPING_REQUIRED,不会创建后再进入人工规格匹配。提交
776db13 fix: require saved spec match before purchase (#188)origin/main。验证
通过:
go test ./app/goauto/purchase ./app/goauto/shopeeproductscripts/verify.ps1 -Component server:go test ./...与go build均通过pnpm exec eslint src/views/goauto/syb-products/index.vuesyb-product-layout.spec.ts+pdd-related-products.spec.ts,9/9 通过pnpm run build:prod通过(仅有仓库既有 CSS/分包告警)python dev_scripts/harness.py check --strict通过sync+sync --check通过全量 Web
scripts/verify.ps1 -Component web停在既有文件web/src/views/goauto/purchase-tasks/index.vue的 Tab/空格 ESLint 错误;本次未修改该文件,SYB 页面定向 ESLint 与生产构建均通过。Wiki
687439543630832db26d2c73f6ada980e34eea10b3d7656c10bb3ec93894f69dbe078c5aa3037ef7未验证/未执行
工单保持打开,等待用户验收。
资格判断修订确认(2026-09-01)
根据本地订单
260901TA39HMUY验证结果,#188 对 SYB 规格可信度的实现遗漏了既有“人工修正与解析成功同等可信”规则。本次继续在 #188 内修订:
parse_status=success或manually_confirmed=true均视为可信的 SYB 目标规格。exact_match + confirmed,再进入“可创建采购”。uncertain/failed仍明确阻断。回归验收:人工已确认但保留原解析状态为
uncertain的明细,可以进入规格匹配;映射未保存前不能创建采购,保存后才可创建。修订实施完成,待验收(2026-09-01)
已按评论 6920 完成:
parse_status=success || manually_confirmed=true。uncertain/failed仍被阻断。uncertain + manuallyConfirmed从“规格待匹配”到唯一精确匹配保存,再进入“可创建采购”的完整过程。提交:
4a1b4af fix: trust manually confirmed SYB specs (#188),已推送origin/main。验证通过:
go test ./app/goauto/purchasescripts/verify.ps1 -Component server(go test ./...、go build)python dev_scripts/harness.py check --strictsync+sync --checkWiki revisions:
3e4f463cfa026a09ba125f2eb376bd42ef41c880c214791a0b055e5b56c0ad05e73829a1f141dd46未执行线上发布、真实采购或订单创建。本地已运行的 8010 进程需要重启后才会加载该提交。工单继续保持待验收。