From 04b6e75eb968624f076efe22d26bfcd2e7c2e79f Mon Sep 17 00:00:00 2001 From: QiuSW <105186638@qq.com> Date: Thu, 10 Sep 2026 16:30:51 +0800 Subject: [PATCH] docs: record purchase panel and address readiness fixes #260 #261 --- docs/02-architecture-and-code-map.md | 67 +++++++++++++++++++++++++- docs/03-business-rules-and-glossary.md | 36 +++++++++++++- 2 files changed, 99 insertions(+), 4 deletions(-) diff --git a/docs/02-architecture-and-code-map.md b/docs/02-architecture-and-code-map.md index 7072cc3..c7e173d 100644 --- a/docs/02-architecture-and-code-map.md +++ b/docs/02-architecture-and-code-map.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Architecture-and-Code-Map wiki_url: https://git.ilapage.cn/OPC/goauto/wiki/Architecture-and-Code-Map.- -wiki_revision: 223cb9035a6b6e63072aa6b075889fcd0d6c2f23 -synchronized_at: 2026-09-09T08:18:24Z +wiki_revision: 7e3f0e2f6b358affdc876a3849f54cf7d37c71f1 +synchronized_at: 2026-09-10T08:29:16Z # 架构与代码地图 @@ -377,3 +377,66 @@ Web 唯一展示位置为“采集采购 → SYB 同步记录”:列表状态 - 删除 `PddCollectionHomeNavigator` 和专属首页/搜索层判据。新导航器仅使用 capture/back、当前包名、openAgentPreservingTab;1~5 次 Back,每次后 500ms,前台离开 PDD 终止剩余 Back;保留风险场景停止。最后打开 Agent 并等待 500ms 验证包名,不验证 PDD 首页。仍在原任务互斥与唤醒锁范围内完成,结束后原 finally 释放。 - `GoAutoCollector` 日志关联 taskId、attemptNumber、deviceId、规则快照 SHA-256;记录 continuousReturn、configuredBacks、固定 reason 和 actions。原因含 count_completed、left_pdd、back_failed、unsafe_page、agent_launch_failed、agent_not_confirmed、navigation_exception、invalid_count;actions 为 Back 尝试数,不代表最终页面。无节点文字、树、截图或个人数据落盘;不扩大采购诊断存储。 - `ContinuousCollectionTest` 覆盖范围/终态、1~5 次、无变化仍按次数、前台变化、风险、动作/启动失败、包名确认和异常;`ContinuousCollectionSettingsTest` 覆盖开关与次数持久化、默认/越界/写入失败。`:app:testDebugUnitTest :app:assembleDebug` 376 项通过。旧首页专属测试随旧行为替换,新版未安装,UI 大字体/横屏、多设备和完整采集真机链路尚未验证。 + +## SYB 存疑规格候选解析(#251) + +实现绑定 `64b4205`,仅 Server `app/goauto/sybimport`;无 API 字段、数据库迁移、权限、并发模式或 UI 变化。 + +- `parse_candidates.go: ParseWithCandidates` 先运行原 `Parse`,仅 uncertain 时解码并校验已存 SpecsJSON;复用 `closedShopeeCandidates` 提取颜色/尺码封闭候选,拒绝未知有值角色/重复角色。完整候选组合与原文归一比较唯一时确认,其他情况返回原 ParseResult。 +- `ApplyDetail` 在加载既有蝦皮商品后、写入规格前调用;`Reparse` 在保留人工/AI 确认保护后加载关联候选调用。新增 ParseResult 私有 matchedCandidates 标记,使 `mergeParsedSpec` 对已经存在的候选直接返回,避免按维度名重复合并或改变映射。 +- #198 `ProcessSpecAIParseRun → Reparse` 自然接入确定性优化,仍需 AI 的记录沿用原后续步骤,不新增异步任务/Provider 调用/接口。 +- 验证 `go test ./app/goauto/sybimport ./app/goauto/aimatching ./app/goauto/shopeeproduct ./app/goauto/purchase` 和 `go build ./...` 通过;新增候选正反/格式/组合色/单维度、歧义/空值、同步重解析一致、人工保护及无需调用 AI 测试。AI 原有置信度/失败重试测试改用仍需语义理解的合成输入,继续验证原分支。 +- 本轮只使用本地测试数据与 httptest AI,未触发真实 SYB 同步、外部 AI、采购、数据库迁移或服务重启;线上及历史数据效果尚待授权验证。 + + +## 蝦皮详情匹配等待与回读(#254) + +实现绑定 `9088e6b`(2026-09-10,分支 fix/254-match-loading);已通过合成数据测试,尚未合并 main 或发布线上。 + +- Server `shopeeproduct.Service.DetailWithAutoMatchBudget` 为详情 GET 附加派生的整次匹配预算,不返回 Provider、Key 等配置。`AutoMatchMappings` 读取 AI 设置 T,使用 2T+10 秒的单个父 context;颜色、尺码、保存及结果回读共用剩余时间。初始配置读取也受有界 context 约束,读取耗时从后续预算扣除。 +- 批量定时匹配调用内部 `autoMatchMappings` 并继续使用原 MaxProviderTimeout=600 秒,不随本次详情入口调整;候选建议与其他 AI 功能不改。 +- Web `ShopeeProductDetailDrawer` 在提交前以普通 GET 刷新商品与预算,仅 auto-match POST 使用 (2T+20) 秒超时。准备失败/缺少预算时不发 POST;旧 Server 必须先更新,不能只发布新版 Web。 +- 加载状态同时绑定商品加载代次和操作序号。关闭/切换立即结束该页面等待状态;同商品重开读取详情,旧响应/旧 finally 不得污染新操作。匹配期间禁止在当前抽屉编辑映射,原人工草稿放弃确认保留。 +- POST 未正常返回时只回读详情及关联 PDD,不自动重发 POST;回读失败结束转圈并保留刷新入口。GET 沿用单请求10秒超时,完整结果回读最多两次串行 GET,不是无限等待。 +- 验证:Go shopeeproduct/aimatching/clientapi 测试与 go build;Web `node --test tests/unit/shopee-match-lifecycle.test.cjs`,Playwright shopee-match-lifecycle 与 shopee-pdd-picker,受影响 ESLint 与 build:prod。 + + +## SYB 行内一键关联最近采集(#253) + +实现绑定 `b1594dc`,2026-09-10;分支 feat/253-one-click-link,包含 #254 依赖。已完成合成数据测试及构建,未合并 main、未部署,不代表当前线上已具备此能力。 + +- Web `syb-products/index.vue` 在“去关联”旁增加“一键关联+下拉箭头”,共享 `quick-link.js` 页面级状态。`quick-link-device-preference.js` 按当前浏览器来源、API环境、用户ID保存设备ID,独立于批量采购偏好;不存密钥或商品数据。首次主动作选机继续原行,箭头选机只保存偏好。 +- Server `shopeeproduct/latest_collection.go` 复用 LinkPDD 的可选 Admin 模式。短事务核对 SYB→Shopee、未关联/规格版本、设备状态,选择并锁定最新 completed/completed_partial 的 agent_current_page 任务及其 PDD;仅完整采集、active且有可用颜色或尺码时更新,WHERE pdd_product_id IS NULL 不覆盖其他操作者的关联。响应保留该事务产生的规格版本及来源task/device/PDD,不能用后续GET替换冻结上下文再自动匹配。 +- 不新增表、迁移、路由或权限对账。原手动关联/替换请求不变;共享 Handler 明确拒绝 Client API 使用此跨模块模式,不能借 Shopee-only write grant 读取 SYB/设备上下文。来源任务原规则快照不改,taskId 可回溯既有采集证据。 +- 关联后读取现有采购准备;需要人工确认或不具备AI资格时停止自动链路并保留关联,其他情况调用原 AutoMatchMappings,沿用 #254 动态预算及原事务保存/上下文冲突保护。最后刷新实际处理阶段,不调用创建采购/订单接口。 +- 运行期间冻结行、商品、手机;前端重复主动作禁用,切换偏好仍只影响未来操作。卸载或 keep-alive deactivated 令旧操作失效,禁止旧回调继续下一步;不声称已经取消服务端在途写入。异常仅有限GET回读和刷新,不自动重发POST。 +- 验证命令:Server `go test -p 1 ./...`、`go build ./...`;Web `node --test tests/unit/syb-quick-link.test.cjs tests/unit/shopee-match-lifecycle.test.cjs`、`pnpm exec playwright test tests/e2e/syb-quick-link.spec.ts tests/e2e/shopee-match-lifecycle.spec.ts --workers=1`、受影响文件 ESLint、`pnpm build:prod`。SQLite 单连接并发测试不代替生产 MySQL 行锁验收;真实AI、生产数据、跨设备人工闭环待验证。 + +## SYB 行内一键替换(#258) + +实现绑定 `2b01974`;部署与验收见 #258 发布证据。本节补充 #253,不改变原未关联入口。 + +- `syb-products/quick-link.js` 复用分体按钮、设备偏好和匹配/回读流程;已关联且允许处理阶段时同位置显示一键替换。先只读预览,固定任务、目标商品及规格版本;不同商品一次确认,同商品不重绑。 +- `shopeeproduct/latest_collection.go` 在原 latestCollection 增加可选 replacement 模式。预览和提交均短事务锁定 SYB、Shopee、原PDD、设备、来源采集与目标PDD,核对旧关联及上下文。提交按预览 taskId 读取,不重新挑选后来采集的商品。 +- Admin 路由注入 `purchase.ValidateQuickReplacement`,在事务内复用采购准备数据集及处理阶段计算,不调用 AI。缺少校验函数拒绝替换;客户端密钥不注入且仍拒绝 latestCollection。无新路由、权限、表或迁移。 +- 关联完成后才执行现有 AI 匹配,不在数据库事务中等待 Provider;同一 SYB 正式采购创建与替换共用 SYB 行锁。历史采购快照不变。SQLite 合成测试覆盖冲突与串行并发请求,不能替代生产 MySQL 多连接锁验收。 + +## 辅助信息缺失的采集关联(#259) + +实现绑定 `e467706`,仅 Server;部署/验收见 #259。替代 #253/#258 中“部分完成一律拒绝”的限制,不改变 completed 原有路径。 + +- completed_partial 的 missing 必须是非空合法列表且仅包含 salesText、shopName、reviewCount,才进入辅助信息兼容检查;title、规格/价格缺失、遍历截断、SKU数量上限及未知原因仍拒绝。 +- `shopeeproduct/partial_collection.go` 核对本次 task 的维度和值、可售SKU的完整标记/规格引用/非负价格、本次颜色价格,以及当前档案可选值由本次有效SKU覆盖,不能借旧档案合并残留的规格或价格通过。真实单维度允许,不虚构另一维度;本次明确报告缺少规格仍拒绝。 +- 一键关联、替换预览及确认提交共用验证。失败沿用409 LATEST_COLLECTION_UNAVAILABLE及现有提示,不回退更早采集、不换手机。状态 completed_partial 和 missing 原样保留;辅助字段缺失仍可在任务详情查看。 +- 无接口字段、数据库迁移、Android/Web或权限变更;普通人工关联与采购/AI资格不变。不将“允许关联”视为“已匹配或已采购”。 + +## 采购单标题面板与地址就绪等待(#260、#261) + +实现绑定 #260 `3c1ffa4`(执行器回归测试 `7de4318`)、#261 `5ea07f1`,Android 0.9.74 / versionCode87,基于0.9.73。安装及真实采购验收以工单证据为准;不代表 main 的 Android 已整合这些分支。 + +- 采购仅在安全规格入口点击返回SUCCESS后,记录本次页面包名/Activity作为内存上下文;开始新执行或页面身份改变时清除。`PddScreenParser` 的新增 purchaseEntryContext 默认关闭,仅该采购执行器传入;普通解析和采集原判定保留。 +- 当前仍为同一PDD Activity、商品ID非空、没有页面风险、没有选中摘要,且唯一有标题规格滚动区、一个维度有值,同时具有关闭、数量、支付展示区域与下单操作证据时,单标题可识别为NORMAL_SCROLLABLE。只是允许进入既有精确规格探测/选择,不执行下单或付款,不全局认可UNKNOWN,不增加入口重复点击或滑动。 +- 地址入口点击原有1000ms保留;地址列表等待增加唯一修改目标要求。点击修改和保存由500ms改为1000ms,其他通用动作间隔不变,无新配置项。 +- 修改后不再只见“详细地址”文字就立即写入。最多50次、每次间隔200ms读取(不含读取耗时),检查PDD页面风险;唯一可见启用有内容的详细地址EditText,连续两次路径、边界、内容及Activity相同才继续原输入流程。始终零个/多个或不稳定时失败,不取第一个候选。 +- 输入内容生成、输入后回读、保存后退出及返回规格面板、最终复核和单次下单边界不变。新增本机脱敏诊断 addressEditorCandidates / addressEditorPolls 两个整数,与task/attempt/device/ruleHash关联;不记录地址内容、原始树或整屏截图。 +- 仅Android;无Server/Web、共享API字段、数据库迁移或权限变化。真实采购、地址写入及订单创建不作为自动安装验证,不执行付款。 diff --git a/docs/03-business-rules-and-glossary.md b/docs/03-business-rules-and-glossary.md index 9c8622a..f2c51ce 100644 --- a/docs/03-business-rules-and-glossary.md +++ b/docs/03-business-rules-and-glossary.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Business-Rules-and-Glossary wiki_url: https://git.ilapage.cn/OPC/goauto/wiki/Business-Rules-and-Glossary.- -wiki_revision: 232757b70c87203d6270020fdc912720b98696c8 -synchronized_at: 2026-09-10T06:42:20Z +wiki_revision: c1bde95dfbd3f539ef9f2fc8dd94849cbf3751d7 +synchronized_at: 2026-09-10T08:29:19Z # 业务规则与术语 @@ -37,6 +37,8 @@ synchronized_at: 2026-09-10T06:42:20Z - PDD 重新采集或更换关联后,目标规格仍存在则映射继续有效;目标规格消失时详情标记“已失效”,服务端拒绝保存不存在的目标,采购预检和创建也拒绝使用失效映射并提示重新选择。 - 批量软删除逐条校验引用(虾皮商品被 SYB 明细或采购任务引用时不可删除)并逐条返回结果;已删除商品默认不出现在列表,可筛选查看并恢复。 +- #257:蝦皮颜色与尺码建议/一键匹配先保留仍有效的已确认映射,再复用相同标准化比较:简体、空白、全半角与大小写统一。颜色标准化后仅命中一个当前可选 PDD 候选时,不调用 AI,建议标为 matched,一键匹配按既有流程保存 exact_match + confirmed;未命中或多个不同候选标准化后相同,仍走原 AI 与置信度/候选校验。只转换比较键,蝦皮/PDD 原规格名不改,映射目标保存 PDD 原始候选名称;不引入颜色同义词猜测、不自动重算历史映射。 + ## SYB 商品明细 - 一行对应 SYB 一条明确的商品/颜色/尺码/数量明细;唯一键为「蝦皮订单号 `code` + 来源明细 `id`」组合,不是全局唯一 ID(未在多货运单样本中验证过全局唯一性)。 @@ -558,3 +560,33 @@ Web 唯一展示位置为“采集采购 → SYB 同步记录”:列表状态 - 先保存关联,再复用现有颜色/尺码自动匹配及保存。有效已确认映射保留;普通部分匹配保存合格结果,AI故障不提交本轮新映射,但已保存关联保留。后续可从“去匹配”或详情人工继续。failed 且无人工/AI确认时不能自动跳过人工解析;uncertain 不统一拦截,仍以原采购准备规则为准。 - 操作完成不保证立即可采购,必须刷新现有处理阶段;缺规格、缺映射、解析需确认或其他原资格不满足时继续显示真实待处理阶段。不自动创建采购任务、不下单、不支付。 - 请求超时/网络中断只做有限回读,不重复提交;读回失败明确结果未确认,避免无限转圈。离开页面不代表后端停止或回滚。普通用户沿用现有采购员权限,无新管理员专属开关。 + +## SYB 已关联商品的一键替换(#258) + +实现绑定 `2b01974`;部署与验收见 #258 发布证据。 + +- 复用一键关联及小箭头的位置,保留原查看 PDD 商品。PDD 待采集、采集失败、停用或缺价格的对应处理阶段可替换;采集中、已创建/运行采购、成功或结果未知不开放。服务端提交时再次检查,不能只相信按钮。 +- 复用每用户/浏览器/API环境的手机偏好;首次选择继续当前行,小箭头仅切换偏好。预览仅选所选手机最新 completed/completed_partial 临时采集,部分成功或不可用不回退旧商品。确认后固定来源任务和目标,不改用新采集;来源状态、设备、目标规格或旧关联改变时拒绝。 +- 不同商品显示一次确认,包含旧/新商品、手机和共享蝦皮档案影响;取消不写入。同商品不弹替换确认且不重写关联,只继续匹配。共享该蝦皮档案的 SYB 明细使用新关联,历史采购任务快照不改。 +- 沿用既有更换关联和有效映射检查,再复用自动匹配保存。部分匹配、AI失败或解析需人工处理时保留已保存关联,显示真实处理阶段,不保证立即可采购、不自动创建采购。 +- 网络异常只有限回读,区分目标商品、仍为原商品和其他关联,不把“已有某个关联”误报为本次替换成功;不自动重发写请求。没有新增后台作业、订单或付款操作。 + +## 辅助信息缺失的采集关联(#259) + +实现绑定 `e467706`,仅 Server;部署/验收见 #259。替代 #253/#258 中“部分完成一律拒绝”的限制,不改变 completed 原有路径。 + +- completed_partial 的 missing 必须是非空合法列表且仅包含 salesText、shopName、reviewCount,才进入辅助信息兼容检查;title、规格/价格缺失、遍历截断、SKU数量上限及未知原因仍拒绝。 +- `shopeeproduct/partial_collection.go` 核对本次 task 的维度和值、可售SKU的完整标记/规格引用/非负价格、本次颜色价格,以及当前档案可选值由本次有效SKU覆盖,不能借旧档案合并残留的规格或价格通过。真实单维度允许,不虚构另一维度;本次明确报告缺少规格仍拒绝。 +- 一键关联、替换预览及确认提交共用验证。失败沿用409 LATEST_COLLECTION_UNAVAILABLE及现有提示,不回退更早采集、不换手机。状态 completed_partial 和 missing 原样保留;辅助字段缺失仍可在任务详情查看。 +- 无接口字段、数据库迁移、Android/Web或权限变更;普通人工关联与采购/AI资格不变。不将“允许关联”视为“已匹配或已采购”。 + +## 采购单标题面板与地址就绪等待(#260、#261) + +实现绑定 #260 `3c1ffa4`(执行器回归测试 `7de4318`)、#261 `5ea07f1`,Android 0.9.74 / versionCode87,基于0.9.73。安装及真实采购验收以工单证据为准;不代表 main 的 Android 已整合这些分支。 + +- 采购仅在安全规格入口点击返回SUCCESS后,记录本次页面包名/Activity作为内存上下文;开始新执行或页面身份改变时清除。`PddScreenParser` 的新增 purchaseEntryContext 默认关闭,仅该采购执行器传入;普通解析和采集原判定保留。 +- 当前仍为同一PDD Activity、商品ID非空、没有页面风险、没有选中摘要,且唯一有标题规格滚动区、一个维度有值,同时具有关闭、数量、支付展示区域与下单操作证据时,单标题可识别为NORMAL_SCROLLABLE。只是允许进入既有精确规格探测/选择,不执行下单或付款,不全局认可UNKNOWN,不增加入口重复点击或滑动。 +- 地址入口点击原有1000ms保留;地址列表等待增加唯一修改目标要求。点击修改和保存由500ms改为1000ms,其他通用动作间隔不变,无新配置项。 +- 修改后不再只见“详细地址”文字就立即写入。最多50次、每次间隔200ms读取(不含读取耗时),检查PDD页面风险;唯一可见启用有内容的详细地址EditText,连续两次路径、边界、内容及Activity相同才继续原输入流程。始终零个/多个或不稳定时失败,不取第一个候选。 +- 输入内容生成、输入后回读、保存后退出及返回规格面板、最终复核和单次下单边界不变。新增本机脱敏诊断 addressEditorCandidates / addressEditorPolls 两个整数,与task/attempt/device/ruleHash关联;不记录地址内容、原始树或整屏截图。 +- 仅Android;无Server/Web、共享API字段、数据库迁移或权限变化。真实采购、地址写入及订单创建不作为自动安装验证,不执行付款。