2.5 KiB
后端 fix 通知 — CUSTOM 私人定制产品已下单时 canEdit 强制 false
日期: 2026-05-12
类型: 后端修复 (PR #2085, merge commit 72ef5693)
模块: 产品 V2 管理端列表/详情 → canEdit 字段语义增强
通知: @mmg
前端是否需改动: 不需要 — 前端继续按 canEdit 决定"修改/删除"按钮显示, 后端语义自动收紧
严重性: P2(防数据不一致)
背景
私人定制 (CUSTOM) 产品本质上是为单一客户量身设计的方案, 一旦客户下单付费即代表方案已被接受。继续允许编辑产品本身会导致订单 productSnapshot 与产品现状失配, 客户拿到的合同/小程序回显 ≠ 实际购买的方案。
改动
canEdit 新规则
| 场景 | 旧 canEdit | 新 canEdit |
|---|---|---|
| 未认证 | false | false (不变) |
| CUSTOM + 有活跃订单 (status NOT IN CANCELLED/REFUNDED) | 超管=true / 创建人=true | false (强制覆盖) |
| CUSTOM + 0 活跃订单 (或仅 CANCELLED/REFUNDED) | 超管=true / 创建人=true | 不变 |
| CORE / GROUP | 超管=true / 创建人=true | 不变 (此规则不适用) |
受影响接口
GET /admin/product/item/{id}(产品详情)GET /admin/product/item/list(产品分页列表)
返回的 VO 中 canEdit 字段会按上述新规则计算。isOwner 字段不受影响 (仍按 created_by == 当前 adminId 判定)。
Swagger 文档已更新
ProductDetailRespVO.canEdit / ProductListRespVO.canEdit 的 ApiModelProperty 已写明完整规则, 前端可从 swagger UI 直接看到。
前端 mmg 无需改动
前端继续按当前逻辑读 canEdit 决定"修改/删除"按钮 disabled / 隐藏即可。CUSTOM 产品被锁的场景下:
- 按钮自动 disabled (符合现有交互)
- 鼠标 hover 提示可考虑加一句"产品已被订单引用, 不可修改" — 但不是必须, 现有提示也可继续用
内部新增端点 (前端无关, 仅记录)
GET /internal/order/count-active-by-products?productIds=... → Map<productId, 活跃订单数>
供产品列表批量计算 canEdit, 一次 GROUP BY 替代 N+1 调用。仅 product-v2 通过 Feign 调用, 外部访问会被 X-Internal-Token 过滤器拦截。
降级保护
订单服务异常时, canEdit 保留原数据权限计算结果 (不强翻 false) — 订单服务抖动不会连带产品列表/详情不可用。日志关键字: 查 CUSTOM 产品活跃订单数失败 / 批量查 CUSTOM 产品活跃订单数失败。