# 后端 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` 供产品列表批量计算 canEdit, 一次 GROUP BY 替代 N+1 调用。仅 product-v2 通过 Feign 调用, 外部访问会被 `X-Internal-Token` 过滤器拦截。 --- ## 降级保护 订单服务异常时, `canEdit` 保留原数据权限计算结果 (不强翻 false) — 订单服务抖动不会连带产品列表/详情不可用。日志关键字: `查 CUSTOM 产品活跃订单数失败` / `批量查 CUSTOM 产品活跃订单数失败`。