支持关闭采购参考价倍率保护并保留绝对单价上限 #180

Open
opened 2026-08-31 20:50:38 +08:00 by ila · 1 comment
Owner

原始需求摘要

  • 来源:用户于 2026-08-31 在分析 CG46~CG49 的价格越界失败后,要求增加“取消价格保护”设置,并明确执行“建工单并做”。
  • 目的:允许管理员对新采购任务关闭“相对参考价倍率保护”,同时保留强制的单件绝对最高价,避免错误参考价长期阻断采购,也不得形成无金额边界下单。
  • Gitea 交互回退:当前会话未提供项目 Gitea MCP,按仓库规则使用 Gitea API;凭据仅从 gitea.env 读取,未写入工单、代码或日志。

当前事实

  • 代码基线:55ded8b,核验日期:2026-08-31。
  • 当前 priceGuard 仅支持 minRatio=0.1..1.0、maxRatio=1.0..3.0;缺省时使用 0.2~1.5,无法关闭。
  • 服务端按 PDD 档案颜色价格计算并固化 minUnitPriceCent / maxUnitPriceCent;Android 只执行任务固化边界,不自行重算倍率。
  • CG47~CG49 已使用 maxRatio=3,参考价 ¥0.68、最高价 ¥2.04,仍报 PURCHASE_PRICE_OUT_OF_RANGE。任务没有保存本次实际观察价格,无法从服务端复核越界方向和金额。
  • 用户已确认本次高风险契约与采购安全边界变更;本工单不授权创建或重试真实采购任务。

目标

  1. 采购规则支持关闭参考价倍率保护。
  2. 关闭倍率保护时强制配置单件绝对最高价,服务端固化为任务价格上限,Android 下单前继续 fail-closed 校验。
  3. 新旧规则快照兼容;规则修改只影响新任务以及既有安全重试的规则快照,既有任务业务价格快照不变。
  4. Android 价格越界失败携带实际观察单价,服务端按现有可选字段保存,便于诊断。
  5. Admin 清晰展示高风险状态并在保存关闭保护的规则前人工确认。

非目标

  • 不允许无上限采购,不取消绝对金额检查。
  • 不提高数量上限,不新增支付、自动付款、取消订单或修改既有订单。
  • 不修复 PDD 价格节点/SKU 识别算法;该相邻根因另行处理。
  • 不修改或重试 CG46~CG49,不创建真实任务、订单或付款。
  • 不做数据库迁移;继续复用任务的最小/最大单价快照字段。

方案与契约

priceGuard 采用以下两种互斥形态:

{"enabled":true,"minRatio":0.2,"maxRatio":1.5}
{"enabled":false,"absoluteMaxUnitPriceCent":5000}
  • enabled 缺省视为 true,兼容既有快照。
  • 启用时只允许倍率字段,范围维持 0.1~1.0 / 1.0~3.0。
  • 关闭时禁止倍率字段,必须提供整数分 absoluteMaxUnitPriceCent,范围 1~100000(¥0.01~¥1000.00)。
  • 缺省整个 priceGuard 时继续使用既有默认倍率,不视为关闭。
  • 关闭时服务端仍要求精确映射颜色存在可用参考价用于预检/任务审计;任务固化 referenceUnitPriceCent、minUnitPriceCent=0、maxUnitPriceCent=absoluteMaxUnitPriceCent。
  • Android 严格解析两种形态,但执行仍只以任务固化价格边界为准;未知字段、混用字段、缺少绝对上限或越界均拒绝。

Admin 设计证据

属于现有“采购规则”编辑弹窗的小范围扩展,明确复用当前 Element Plus 表单规范,不新增页面或导航,无需完整原型:

  • 增加“参考价倍率保护”开关,默认开启。
  • 开启时显示现有最低/最高倍率输入;关闭时隐藏倍率输入,显示“单件绝对最高价(元)”输入和红色风险提示。
  • 保存关闭保护的规则前弹出二次确认,明确“仅取消参考价倍率校验、仍受绝对上限约束、只影响新任务”。
  • 列表摘要显示“倍率保护关闭 · 单件上限 ¥xx.xx”;设为当前时继续使用既有切换确认,并补充关闭状态和绝对上限。
  • JSON 预览/编辑与表单保存结果保持一致。

覆盖状态:开启、关闭、字段校验失败、保存确认取消、保存成功、历史规则兼容;权限仍仅管理员。

验收标准

  • 服务端和 Android 均接受两种合法形态,且保持未知字段严格拒绝。
  • 既有不含 enabled 的倍率规则及完全缺省 priceGuard 的旧快照继续兼容。
  • 关闭形态缺绝对上限、混入倍率、非整数、0、负数或超过 ¥1000 均被拒绝。
  • 服务端预检对关闭形态生成最小价 0、最大价为绝对上限,新建任务固化该边界。
  • Android 在核价、订单摘要和创建订单前仍校验固化边界;越界失败结果包含实际单价。
  • Admin 能编辑、摘要展示和二次确认关闭状态,生产构建通过。
  • 不执行真机正式采购、不创建订单、不支付。

验证计划

  • cd server && go test ./app/goauto/purchasecontract ./app/goauto/purchaserule ./app/goauto/purchase
  • cd web && pnpm lint(若仓库脚本支持)与 pnpm build:prod
  • android\gradlew.bat -p android testDebugUnitTest
  • android\gradlew.bat -p android assembleDebug
  • git diff --check

风险与安全边界

  • 关闭倍率保护会放宽采购价格门禁,因此绝对上限不可省略、不可由 Agent 覆盖,并随任务快照固化。
  • 永久禁止支付;本工单测试不得创建真实采购任务或订单。
  • 旧任务保持自身业务价格快照,不能通过规则编辑悄悄扩大已经失败任务的价格范围。
  • 共享契约、服务端和 Android 必须同一提交交付,避免再次出现跨端规则不兼容。

子项目影响

  • 共享契约:扩展 priceGuard 互斥形态。
  • Server:严格校验、价格边界计算、测试。
  • Web:采购规则编辑/摘要/确认。
  • Android:严格解析、失败实际价格回传、测试与 APK。
  • 数据库、权限、并发和状态机:无结构变化。

文档影响

  • 有长期文档影响:采购价格安全规则和 Agent 共享规则契约发生变化。实施完成后更新 Gitea Wiki Business-Rules-and-Glossary 与 Android-Agent-API-Contract,在线回读 revision,再同步本地镜像并检查一致性。
## 原始需求摘要 - 来源:用户于 2026-08-31 在分析 CG46~CG49 的价格越界失败后,要求增加“取消价格保护”设置,并明确执行“建工单并做”。 - 目的:允许管理员对新采购任务关闭“相对参考价倍率保护”,同时保留强制的单件绝对最高价,避免错误参考价长期阻断采购,也不得形成无金额边界下单。 - Gitea 交互回退:当前会话未提供项目 Gitea MCP,按仓库规则使用 Gitea API;凭据仅从 `gitea.env` 读取,未写入工单、代码或日志。 ## 当前事实 - 代码基线:`55ded8b`,核验日期:2026-08-31。 - 当前 `priceGuard` 仅支持 `minRatio=0.1..1.0`、`maxRatio=1.0..3.0`;缺省时使用 0.2~1.5,无法关闭。 - 服务端按 PDD 档案颜色价格计算并固化 `minUnitPriceCent` / `maxUnitPriceCent`;Android 只执行任务固化边界,不自行重算倍率。 - CG47~CG49 已使用 `maxRatio=3`,参考价 ¥0.68、最高价 ¥2.04,仍报 `PURCHASE_PRICE_OUT_OF_RANGE`。任务没有保存本次实际观察价格,无法从服务端复核越界方向和金额。 - 用户已确认本次高风险契约与采购安全边界变更;本工单不授权创建或重试真实采购任务。 ## 目标 1. 采购规则支持关闭参考价倍率保护。 2. 关闭倍率保护时强制配置单件绝对最高价,服务端固化为任务价格上限,Android 下单前继续 fail-closed 校验。 3. 新旧规则快照兼容;规则修改只影响新任务以及既有安全重试的规则快照,既有任务业务价格快照不变。 4. Android 价格越界失败携带实际观察单价,服务端按现有可选字段保存,便于诊断。 5. Admin 清晰展示高风险状态并在保存关闭保护的规则前人工确认。 ## 非目标 - 不允许无上限采购,不取消绝对金额检查。 - 不提高数量上限,不新增支付、自动付款、取消订单或修改既有订单。 - 不修复 PDD 价格节点/SKU 识别算法;该相邻根因另行处理。 - 不修改或重试 CG46~CG49,不创建真实任务、订单或付款。 - 不做数据库迁移;继续复用任务的最小/最大单价快照字段。 ## 方案与契约 `priceGuard` 采用以下两种互斥形态: ```json {"enabled":true,"minRatio":0.2,"maxRatio":1.5} ``` ```json {"enabled":false,"absoluteMaxUnitPriceCent":5000} ``` - `enabled` 缺省视为 `true`,兼容既有快照。 - 启用时只允许倍率字段,范围维持 0.1~1.0 / 1.0~3.0。 - 关闭时禁止倍率字段,必须提供整数分 `absoluteMaxUnitPriceCent`,范围 1~100000(¥0.01~¥1000.00)。 - 缺省整个 `priceGuard` 时继续使用既有默认倍率,不视为关闭。 - 关闭时服务端仍要求精确映射颜色存在可用参考价用于预检/任务审计;任务固化 `referenceUnitPriceCent`、`minUnitPriceCent=0`、`maxUnitPriceCent=absoluteMaxUnitPriceCent`。 - Android 严格解析两种形态,但执行仍只以任务固化价格边界为准;未知字段、混用字段、缺少绝对上限或越界均拒绝。 ## Admin 设计证据 属于现有“采购规则”编辑弹窗的小范围扩展,明确复用当前 Element Plus 表单规范,不新增页面或导航,无需完整原型: - 增加“参考价倍率保护”开关,默认开启。 - 开启时显示现有最低/最高倍率输入;关闭时隐藏倍率输入,显示“单件绝对最高价(元)”输入和红色风险提示。 - 保存关闭保护的规则前弹出二次确认,明确“仅取消参考价倍率校验、仍受绝对上限约束、只影响新任务”。 - 列表摘要显示“倍率保护关闭 · 单件上限 ¥xx.xx”;设为当前时继续使用既有切换确认,并补充关闭状态和绝对上限。 - JSON 预览/编辑与表单保存结果保持一致。 覆盖状态:开启、关闭、字段校验失败、保存确认取消、保存成功、历史规则兼容;权限仍仅管理员。 ## 验收标准 - 服务端和 Android 均接受两种合法形态,且保持未知字段严格拒绝。 - 既有不含 `enabled` 的倍率规则及完全缺省 `priceGuard` 的旧快照继续兼容。 - 关闭形态缺绝对上限、混入倍率、非整数、0、负数或超过 ¥1000 均被拒绝。 - 服务端预检对关闭形态生成最小价 0、最大价为绝对上限,新建任务固化该边界。 - Android 在核价、订单摘要和创建订单前仍校验固化边界;越界失败结果包含实际单价。 - Admin 能编辑、摘要展示和二次确认关闭状态,生产构建通过。 - 不执行真机正式采购、不创建订单、不支付。 ## 验证计划 - `cd server && go test ./app/goauto/purchasecontract ./app/goauto/purchaserule ./app/goauto/purchase` - `cd web && pnpm lint`(若仓库脚本支持)与 `pnpm build:prod` - `android\gradlew.bat -p android testDebugUnitTest` - `android\gradlew.bat -p android assembleDebug` - `git diff --check` ## 风险与安全边界 - 关闭倍率保护会放宽采购价格门禁,因此绝对上限不可省略、不可由 Agent 覆盖,并随任务快照固化。 - 永久禁止支付;本工单测试不得创建真实采购任务或订单。 - 旧任务保持自身业务价格快照,不能通过规则编辑悄悄扩大已经失败任务的价格范围。 - 共享契约、服务端和 Android 必须同一提交交付,避免再次出现跨端规则不兼容。 ## 子项目影响 - 共享契约:扩展 `priceGuard` 互斥形态。 - Server:严格校验、价格边界计算、测试。 - Web:采购规则编辑/摘要/确认。 - Android:严格解析、失败实际价格回传、测试与 APK。 - 数据库、权限、并发和状态机:无结构变化。 ## 文档影响 - 有长期文档影响:采购价格安全规则和 Agent 共享规则契约发生变化。实施完成后更新 Gitea Wiki `Business-Rules-and-Glossary` 与 `Android-Agent-API-Contract`,在线回读 revision,再同步本地镜像并检查一致性。
Author
Owner

实施完成,等待验收

实现

  • 共享 priceGuard 新增严格互斥形态:
    • 开启:enabled=true + minRatio + maxRatio;enabled 缺省兼容旧快照。
    • 关闭:enabled=false + absoluteMaxUnitPriceCent,绝对上限为 1~100000 分;倍率字段不得混入。
  • 服务端关闭倍率时仍读取精确映射颜色参考价用于预检/审计,新任务固化 minUnitPriceCent=0、maxUnitPriceCent=absoluteMaxUnitPriceCent;无数据库迁移。
  • Android 严格解析新旧契约,执行仍只信任任务固化价格边界;核价、订单摘要和创建订单前继续 fail-closed。
  • Android 价格越界失败现在回传观察单价;服务端在 failed 结果中保存 actualUnitPriceCent。
  • Admin 采购规则弹窗增加开关、¥0.01~¥1000.00 绝对上限、红色风险提示、保存二次确认、列表摘要和切换当前规则风险说明。
  • 增加跨端共享关闭形态样例 contracts/purchase-rule-live-price-guard-disabled-v1.json。

验证

  • go test ./app/goauto/...:通过(最终提交后复跑)。
  • android\gradlew.bat testDebugUnitTest:通过。
  • android\gradlew.bat assembleDebug:通过。
  • pnpm exec eslint src/views/goauto/purchase-rules/index.vue:通过。
  • pnpm build:prod:通过;仅有仓库既有 CSS/大 chunk 警告。
  • pnpm lint:未通过,失败全部位于本工单未修改的 web/src/views/goauto/purchase-tasks/index.vue 用户现有 Tab/空格改动;未越界修复。目标页面 lint 已单独通过。
  • 浏览器只读验收:旧规则显示开启;切换关闭后显示 ¥50.00 绝对上限和红色提示;保存出现“确认关闭并保存”二次确认。已取消并关闭,未保存数据库规则。
  • git diff --check / staged diff check:通过。
  • Debug APK:android/app/build/outputs/apk/debug/app-debug.apk,6,443,003 bytes,SHA-256 B0CBCE449055574D2F88E63E38C1EE571BC9B5D19D868220D9EB21F2F2724481;版本仍为 versionCode=48、versionName=0.9.35,未安装到手机。

文档

  • Wiki Business-Rules-and-Glossary:revision 85e881bd4fd1ebffb6af24d0f2f7512dfeda2a16。
  • Wiki Android-Agent-API-Contract:revision bf61d3493fc4cd16649c0564b87580a5b78704aa。
  • 已执行唯一一轮 harness.py sync 和一轮 sync --check,一致性通过。
  • 同步期间 docs/12-syb-erp-interface.md 同时存在用户改动与线上更新;已按内容哈希 a8f859399c624a7d12c1fd444174ded59d9736ad 原样恢复用户版本,并排除在提交外。

提交与安全边界

  • 提交:9cdb6bb(已推送 main)。
  • Gitea MCP 当前会话不可用,工单和 Wiki 按规则回退 Gitea API。
  • 未修改本机当前采购规则,未创建/重试采购任务,未打开 PDD,未修改地址,未创建订单,未支付。
  • docs/12-syb-erp-interface.md、server/config/settings.yml、%TEMP%/、gitea.zip、nul、prototypes/130/ 均为用户既有改动/文件,未提交。

工单保持打开,等待用户验收。

## 实施完成,等待验收 ### 实现 - 共享 `priceGuard` 新增严格互斥形态: - 开启:`enabled=true + minRatio + maxRatio`;`enabled` 缺省兼容旧快照。 - 关闭:`enabled=false + absoluteMaxUnitPriceCent`,绝对上限为 1~100000 分;倍率字段不得混入。 - 服务端关闭倍率时仍读取精确映射颜色参考价用于预检/审计,新任务固化 `minUnitPriceCent=0`、`maxUnitPriceCent=absoluteMaxUnitPriceCent`;无数据库迁移。 - Android 严格解析新旧契约,执行仍只信任任务固化价格边界;核价、订单摘要和创建订单前继续 fail-closed。 - Android 价格越界失败现在回传观察单价;服务端在 `failed` 结果中保存 `actualUnitPriceCent`。 - Admin 采购规则弹窗增加开关、¥0.01~¥1000.00 绝对上限、红色风险提示、保存二次确认、列表摘要和切换当前规则风险说明。 - 增加跨端共享关闭形态样例 `contracts/purchase-rule-live-price-guard-disabled-v1.json`。 ### 验证 - `go test ./app/goauto/...`:通过(最终提交后复跑)。 - `android\gradlew.bat testDebugUnitTest`:通过。 - `android\gradlew.bat assembleDebug`:通过。 - `pnpm exec eslint src/views/goauto/purchase-rules/index.vue`:通过。 - `pnpm build:prod`:通过;仅有仓库既有 CSS/大 chunk 警告。 - `pnpm lint`:未通过,失败全部位于本工单未修改的 `web/src/views/goauto/purchase-tasks/index.vue` 用户现有 Tab/空格改动;未越界修复。目标页面 lint 已单独通过。 - 浏览器只读验收:旧规则显示开启;切换关闭后显示 ¥50.00 绝对上限和红色提示;保存出现“确认关闭并保存”二次确认。已取消并关闭,未保存数据库规则。 - `git diff --check` / staged diff check:通过。 - Debug APK:`android/app/build/outputs/apk/debug/app-debug.apk`,6,443,003 bytes,SHA-256 `B0CBCE449055574D2F88E63E38C1EE571BC9B5D19D868220D9EB21F2F2724481`;版本仍为 `versionCode=48`、`versionName=0.9.35`,未安装到手机。 ### 文档 - Wiki `Business-Rules-and-Glossary`:revision `85e881bd4fd1ebffb6af24d0f2f7512dfeda2a16`。 - Wiki `Android-Agent-API-Contract`:revision `bf61d3493fc4cd16649c0564b87580a5b78704aa`。 - 已执行唯一一轮 `harness.py sync` 和一轮 `sync --check`,一致性通过。 - 同步期间 `docs/12-syb-erp-interface.md` 同时存在用户改动与线上更新;已按内容哈希 `a8f859399c624a7d12c1fd444174ded59d9736ad` 原样恢复用户版本,并排除在提交外。 ### 提交与安全边界 - 提交:`9cdb6bb`(已推送 `main`)。 - Gitea MCP 当前会话不可用,工单和 Wiki 按规则回退 Gitea API。 - 未修改本机当前采购规则,未创建/重试采购任务,未打开 PDD,未修改地址,未创建订单,未支付。 - `docs/12-syb-erp-interface.md`、`server/config/settings.yml`、`%TEMP%/`、`gitea.zip`、`nul`、`prototypes/130/` 均为用户既有改动/文件,未提交。 工单保持打开,等待用户验收。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#180