diff --git a/changelogs/2026-05/07_feat_product_publish_relax_validation_and_team_independent_api.md b/changelogs/2026-05/07_feat_product_publish_relax_validation_and_team_independent_api.md new file mode 100644 index 0000000..43ffe69 --- /dev/null +++ b/changelogs/2026-05/07_feat_product_publish_relax_validation_and_team_independent_api.md @@ -0,0 +1,120 @@ +# 产品上架放宽校验 + 已上架可独立管理团期/团队 + +**日期**: 2026-05-07 +**类型**: 后端 API 增强 + 前端调整建议 +**模块**: 产品(hl-product-service-v2) +**通知**: @mmg +**关联工单**: #1775 +**关联 PR**: #1779 + #1781(hotfix) + +--- + +## 业务变更 + +用户翻盘业务规则:**产品(尤其 GROUP/小蒙马)上架时不再硬校验团队/团期,可以「先上架后补」**。已上架(PUBLISHED)后通过现有/新增独立接口管理班期和团队成员。 + +--- + +## 后端改动 + +### 1. 上架校验放宽(`POST /admin/product/item/{id}/toggle-publish`) + +GROUP 产品上架时**不再强校验**: +- ~~至少 1 个班期~~(已删除) +- ~~每个班期至少 1 个 LEADER 角色成员~~(已删除) +- ~~至少 1 个未来出发、成人价 > 0 的班期~~(已删除) + +**保留校验**: +- 基础字段(名称/天数/封面/标签) +- 行程完整性(至少 1 天) +- 餐饮配置 +- CORE/CUSTOM 价格日历未来有效价 ≥ 1(GROUP 不要求) + +### 2. 已上架可独立管理班期 + +**`POST /admin/product/item/{id}/schedule`** — saveSchedule +- 新增/修改单个班期 +- **PUBLISHED 状态可调用**(之前会被 checkEditable 拒) +- 调用成功后产品 `priceVersion++` 并触发 mp 缓存失效 + +**`POST /admin/product/item/{id}/schedule/batch-create`** — batchCreateSchedule +- 按重复模式批量生成班期(≤52个) +- **PUBLISHED 状态可调用** +- 整批调用 priceVersion 只 +1(不会膨胀) + +**`DELETE /admin/product/item/{id}/schedule/{scheduleId}`** — deleteSchedule +- 删除班期 +- **PUBLISHED 状态可调用** +- 已有报名订单的班期仍拒删(业务保护,返回剩余订单数) +- 删除后 `priceVersion++` 触发缓存失效 + +### 3. 已上架可独立管理团队(**新增独立接口**) + +**`POST /admin/product/item/{id}/schedule/team`** — saveScheduleTeam ⭐ 本次新增 +- request body 同既有 `ScheduleTeamSaveReqVO`: + ```json + { + "productId": "", + "batchId": "", + "staffList": [ + {"staffId": "", "staffRole": "LEADER", "staffName": "...", "staffPhone": "...", "sortOrder": 1} + ] + } + ``` +- 全删全插策略:传完整列表覆盖该 batchId 的全部成员 +- **PUBLISHED 状态可直接调用**(绕过 supplement 接口的整体 checkEditable 拦截) +- staffId / staffRole / staffName / staffPhone 这些字段如果数据库 NOT NULL 必传 + +> 之前: 团队只能通过 `PUT /supplement` 嵌套保存,但 supplement 接口 PUBLISHED 整体被拒 +> 现在: 独立 `POST /schedule/team` 直调 saveTeam,不受 supplement 状态拦截影响 +> 与既有 `GET /schedule/team` 路径对称 + +### 4. 缓存一致性 + +修改班期/团队后通过 `registerAfterCommit('product' source)` 触发 D3 反向缓存失效,mp 端详情/列表/起步价自动同步(≤ 几秒)。 + +--- + +## 前端调整建议(@mmg) + +### 1. 「上架向导第 4 步 → 补充信息 → 团队配置」 + +当前页面对每个班期显示「N 人已配」+ 必填校验「至少 1 个领队」。 + +**建议调整**: +- 去掉「至少 1 个领队」的必填星号 + 提交拦截 +- 可保留业务建议文案(如「建议每期配置 1 个领队,确保订单详情显示完整」),但**不阻塞上架** +- 前端「上架」按钮在团队/团期为空时不再 disable 或弹错误提示 + +### 2. 「已上架后管理团期/团队」入口(**新交互**) + +业务诉求:用户希望产品上架后能独立加新团期、补领队等。 + +**建议交互**(仅供参考,最终方案 mmg 决定): +- 在产品列表「已上架」状态的产品行加「管理团期/团队」入口(侧边栏 / 浮层 / 跳转新页面均可) +- 已上架产品调用以下接口(参数 / response 与上架前一致): + - 加新团期: `POST /admin/product/item/{id}/schedule` + - 删团期: `DELETE /admin/product/item/{id}/schedule/{scheduleId}` + - 改团队: `POST /admin/product/item/{id}/schedule/team` ⭐ 新接口 +- **不再需要先把产品下架再修改** + +--- + +## round-trip 验收(已通过) + +测试服 9443 网关 + admin / Admin@123456 token 实测: + +| 验收项 | 接口 | 结果 | +|---|---|---| +| GROUP DRAFT toggle-publish message 不再含「班期/LEADER/领队」字样 | POST `/admin/product/item/{id}/toggle-publish` | ✅ message="行程未完整填写..." 不含班期相关字样 | +| PUBLISHED 加新班期 | POST `/admin/product/item/{id}/schedule` | ✅ code:200, batchId 落库 | +| PUBLISHED 删班期 | DELETE `/admin/product/item/{id}/schedule/{batchId}` | ✅ code:200 msg=班期删除成功 | +| PUBLISHED 调独立 saveTeam | POST `/admin/product/item/{id}/schedule/team` | ✅ code:200 msg=团队保存成功 | + +--- + +## 风险与兼容性 + +- **订单价格 snapshot 模式不变**:已下单订单不受班期价格变化影响 +- **既有 `PUT /admin/product/item/{id}/supplement` 接口不变**:仍可在草稿态批量保存团队(DRAFT/REJECTED/UNPUBLISHED 流程不受影响) +- **新接口与 GET 同路径不冲突**:`GET /schedule/team` (查询) + `POST /schedule/team` (保存) 共存