diff --git a/changelogs/2026-05/18_feat_product_v2_snapshot_p23_loosen_save_group_batch.md b/changelogs/2026-05/18_feat_product_v2_snapshot_p23_loosen_save_group_batch.md new file mode 100644 index 0000000..711be27 --- /dev/null +++ b/changelogs/2026-05/18_feat_product_v2_snapshot_p23_loosen_save_group_batch.md @@ -0,0 +1,161 @@ +# product-v2: 产品快照 P2.3 — 保存放宽 + GROUP 班期完整 + 弹窗交互(mmg 必看) + +> **服务**: hl-product-service-v2 (端口 8083) +> **PR**: #2478 +> **Issue**: #2470 +> **日期**: 2026-05-18 +> **影响范围**: 产品快照保存权限/状态放宽 + GROUP 类产品班期完整保存 + 提交上架/完成设计 UI 加保存版本弹窗 + +--- + +## ⚠️ 关键变化(前端 mmg 必看) + +### 1. 保存版本权限放宽 — 所有 admin 都能保存 +- **旧**:只有 SUPER_ADMIN 或 CUSTOMIZER+owner 能调 `POST /admin/product/item/{id}/snapshots` +- **新**:**所有 admin 登录态都能保存**自己看到的产品版本(OPERATOR / CUSTOMER_SERVICE / 等等都能存) +- 还原/删除/标记永久**仍严格校验**(这些是改业务数据的危险动作) + +### 2. 可保存状态扩到 3 种 +- **旧**:`DRAFT / COMPLETED` +- **新**:**`DRAFT / UNPUBLISHED / COMPLETED`**(**下架的产品现在也能保存**) +- PUBLISHED / 审批中仍拒绝(数据不稳定) + +### 3. GROUP 小蒙马班期完整保存(修复缺陷) +- **旧版 P2.2 漏存** `group_tour_batch` 表 → GROUP 还原后班期数据丢失 +- **新版** ProductSnapshotPayload 加 `productType` + `groupTourBatches` 两字段,GROUP 产品快照含完整班期,还原可恢复 + +### 4. 还原时类型一致性校验 +- 还原前校验 `payload.productType == 当前 product.productType` +- 跨类型还原(如 CORE 快照试图还原到 GROUP 产品)返 `SNAPSHOT_TYPE_MISMATCH (410128)` +- 老快照 `productType=null` 兼容放行(不强制) + +--- + +## 🎨 前端弹窗交互(mmg 必做) + +P2.3 用户体验目标:用户在「提交上架」或「完成设计」前,前端弹窗提示「是否保存当前版本」,避免上架后想还原但没快照。 + +### 交互流程 + +``` +┌────────────────────────────────────┐ +│ [提交上架] 按钮 / [完成设计] 按钮 │ +└─────────────────┬──────────────────┘ + │ 点击 + ▼ +┌────────────────────────────────────┐ +│ 弹窗 "是否保存当前版本?" │ +│ │ +│ 上架/完成设计后想要恢复到此版本 │ +│ 必须先保存。 │ +│ │ +│ [保存并提交] [直接提交] [取消] │ +└──┬──────────────┬──────────────┬───┘ + │ │ │ + │ 选保存并提交 │ 选直接提交 │ 选取消 + ▼ ▼ ▼ +1. POST /admin/product/item/{id}/snapshots + body: { name: "上架前自动备份-2026-05-18 14:30", + description: "提交上架前自动保存", + keepForever: false } +2. POST /admin/product/item/{id}/toggle-publish → 直接 POST /toggle-publish + 或 /complete 或 /complete 无操作 +``` + +### 实现建议 +- 弹窗组件可以**默认勾选「保存并提交」**(鼓励保存) +- 版本名可让用户填,也可前端自动生成(如 `"上架前自动备份-${yyyy-MM-dd HH:mm}"`) +- 描述选填,留空自动填触发动作(如 `"提交上架前自动保存"` / `"完成设计前自动保存"`) +- 用户选「直接提交」时也可以记录到操作日志,便于审计 + +### 触发时机的接口 +| 触发动作 | URL | Method | +|---|---|---| +| 提交上架 | `/admin/product/item/{id}/toggle-publish` | POST | +| 完成设计(仅 CUSTOM) | `/admin/product/item/{id}/complete` | POST | +| 保存快照 | `/admin/product/item/{id}/snapshots` | POST | + +--- + +## 一、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更 | +|---|------|------|------|------| +| 1 | 保存快照 | POST | `/admin/product/item/{id}/snapshots` | **权限放宽** + **状态扩** + **GROUP 含班期** | +| 2 | 还原快照 | POST | `/admin/product/item/{id}/snapshots/{snapshotId}/restore` | **加类型一致性校验** | + +--- + +## 二、接口详情 + +### 1. 保存快照(权限+状态放宽) + +**入参 VO**(无变化):name + description + keepForever,详见 PR #2431 changelog。 + +**校验变化**: +| 校验项 | 旧 | 新 | +|---|---|---| +| 角色 | SUPER_ADMIN 或 CUSTOMIZER+owner | **所有 admin 登录态** | +| 状态 | DRAFT / COMPLETED | **DRAFT / UNPUBLISHED / COMPLETED** | +| 同名 | 拒绝 | 同 | +| 大小 | >1MB 拒绝 | 同 | +| keep_forever 上限 | 3 个/产品 | 同 | + +**出参**:`Result` (snapshotId) 无变化 + +### 2. 还原快照(加类型一致性校验) + +**新校验**:快照保存时记的 `productType` 必须等于当前产品的 `productType` + +**新错误码**:`410128 SNAPSHOT_TYPE_MISMATCH` — `"快照类型与当前产品不一致, 快照=CORE, 当前=GROUP"` + +**老快照兼容**:PR #2431 时代保存的快照 `productType=null`,还原时**放行**(不强制校验) + +--- + +## 三、新增字段(payload 结构变化) + +`ProductSnapshotPayload` JSON 结构新增 2 字段: + +```json +{ + "schemaVersion": 1, + "productType": "GROUP", // ⬅ 新增, 用于还原时一致性校验 + "product": { ... }, + "basic": { ... }, + "supplement": { ... }, + ... + "groupTourBatches": [ // ⬅ 新增, GROUP 才有非空, CORE/CUSTOM 为 [] + { "batchId": "...", "departureDate": "2026-07-15", "adultSellPrice": 3800.00, ... } + ] +} +``` + +前端**不需要解析这个 JSON**(在 OSS 上 + 后端透明处理),仅需知道: +- 新版 GROUP 快照含完整班期信息 +- 还原可能返 `410128` 类型不一致错误 + +--- + +## 四、向后兼容 + +- ✅ 接口路径、入参、HTTP 方法、原有出参字段全部不变 +- ✅ 老 payload(productType=null)反序列化兼容(已加 @JsonIgnoreProperties(ignoreUnknown=true)) +- ✅ 老快照还原时不强制类型校验 +- ✅ 前端不实施弹窗也不影响(只是少了 UX 改进) + +--- + +## 五、部署 + +- 测试服:自动同步 dev 部署 +- 正式服:等 Deploy Panel /prod 触发 +- nacos: 无需配置(OSS 配置 PR #2435 已对齐全局 oss.*) + +--- + +## 六、不在本期范围 + +- 集合深 diff(P2.1 #2428 单独跟) +- 调价告警(用户已决策不做) +- 跨产品聚合可视化页(P2-4 #2426,mmg 前端工作)