# 181 采购价格上限按数量计算总价 - 类型:缺陷 - 父级大工单:#96 - 所属 MVP / 版本:#97 真实采购首单闭环(不支付) - 状态:已完成,用户验收通过 - 日期:2026-08-12 - Gitea 工单: ## 背景与目标 数量大于 1 的采购任务曾把 PDD SKU 单价直接保存到 `max_price_cent`,而 Client 设置数量后读取并比较的是页面订单总价,导致总价与单价错误比较。生产任务 `cg6` 的数量为 2、采集单价为 ¥11.80,却只下发了 1180 分上限。 本任务把 Admin、Client 和接口契约统一为“`max_price_cent` 是人民币订单总价上限”,并让 Admin 按采购数量自动计算,继续保留严格价格保护。 ## 最终方案 - Admin 采购确认弹窗输入选定规格的人民币单价上限,同时显示数量和只读订单总价上限;修改单价时即时更新总价。 - JavaScript 只提供交互反馈。Admin 后端把单价精确解析为整数分,在事务内读取顺运宝最新数量,执行 `单价上限 × 数量` 并检查整数溢出后写入 `tasks.max_price_cent`。 - Client 明确把 `max_price_cent` 解释为订单总价上限。商品页或规格面板的金额可能是单价或小计,因此只在最终订单确认页执行总价超限判断。 - 不修改数据库结构,不回写历史任务,不重试 `cg6`,不增加涨价容差。 - 实现与建单方案一致。 ## 改了哪些 - `admin/templates/syb/list.html`、`admin/static/js/app.js`:增加单价标签、数量、即时总价输出和辅助说明。 - `admin/handler/web/others.go`、`admin/service/purchase_workflow.go`:接收单价并在事务内安全计算订单总价上限。 - `admin/service/syb.go`、`admin/service/task.go`、任务详情模板:生成默认单价/总价并明确总价展示语义。 - `client/src/purchase_task_service.py`、采购适配和网关边界:只在最终确认页比较订单总价,统一错误信息和字段说明。 - Admin/Client 测试:覆盖数量乘法、溢出、模板反馈以及确认页总价超限。 - Admin/Client 基线文档:统一 `max_price_cent` 契约。 ## 验收结果 | 验收标准 | 结果 | |---|---| | 数量 2、单价 ¥11.80 显示订单总价上限 ¥23.60 | 通过 | | 单价输入具有可见标签、辅助说明和可访问的即时总价输出 | 通过 | | 后端按最新数量计算并保存总价,数量 1 保持原值 | 通过 | | 后端拒绝零值、负值和整数乘法溢出 | 通过 | | Client 只在最终确认页按订单总价执行价格保护 | 通过 | | Admin 与 Client 契约文档定义一致 | 通过 | | Go 1.23 静态检查、构建、全量测试通过 | 通过 | | Client 全量测试和语法检查通过 | 通过 | ## 测试 - 执行的命令: - `GOTOOLCHAIN=go1.23.0 go test ./service -run 'Test(CreatePurchaseTasks_安全字段和重复保护|CalculateOrderPriceLimitCent_按数量计算且拒绝溢出)' -count=1`(临时 MySQL 8 `_test` 基础库) - `GOTOOLCHAIN=go1.23.0 go vet ./...` - `GOTOOLCHAIN=go1.23.0 go build ./...` - `GOTOOLCHAIN=go1.23.0 go test ./... -count=1` - `C:/Python310/python.exe -m py_compile src/purchase_task_service.py src/pdd_purchase_adapter.py src/pdd_u2_purchase_adapter.py src/task_dispatcher.py src/http_admin_gateway.py` - `C:/Python310/python.exe -m unittest discover -s test -p "test_*.py"` - `git diff --check` - 结果:MySQL 8 实库目标测试通过;Admin 全量检查通过;Client 共 456 个测试通过。临时数据库和授权已清理。 - **没验证到的部分**:未在生产创建新采购任务,也未操作 Android 真机或执行真实下单;生产只执行部署和服务健康检查。 ## 遗留问题 - 历史任务保持创建时的原始金额语义,`cg6` 不自动修改或重试。部署后新建任务使用订单总价上限。 - 本任务不加入自动涨价容差;实际订单总价超过计算上限时仍会停止采购。 ## 相关提交 - `253be7c` 采购价格上限按数量计算总价