From 1d7f6006751700716b33081622cbbb74e3f5a415 Mon Sep 17 00:00:00 2001 From: Council Date: Wed, 15 Apr 2026 19:52:03 +0800 Subject: [PATCH] council(round4): FrontendDev - Issue #9 execution plan (P0/P1 task breakdown) Co-Authored-By: Claude Opus 4.6 --- plan.md | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/plan.md b/plan.md index 139b60b..cab820b 100644 --- a/plan.md +++ b/plan.md @@ -303,6 +303,90 @@ this.selectedSeats.forEach(function(seat) { --- +## Issue #9 执行计划 — Round 4(P0 修复) + +> 执行日期:2026-04-15 | 目标:方案 A 全量落地 + +### 任务清单 + +- [ ] **P0-A**: `BaseService::initGoodsSpecs()` — 修复商品 112 broken state `[Claimed: BackendArchitect]` +- [ ] **P0-B**: `SeatSkuService::BatchGenerate()` — 批量生成座位级 SKU `[Claimed: BackendArchitect]` +- [ ] **P1**: `ticket_detail.html` submit() 重构 — seat-level goods_params `[Claimed: FrontendDev]` +- [ ] **P1-Verification**: 前端实测验证(商品 112 购买流程) `[Claimed: FrontendDev]` + +### 阶段划分 + +| 阶段 | 内容 | 负责 | +|------|------|------| +| **Draft** | BackendArchitect: P0-A + P0-B 实现;FrontendDev: submit() 重构 | 双线并行 | +| **Review** | 互相 review对方代码,确认接口对齐 | 双线并行 | +| **Finalize** | 合并到 main,实测验证 | 共同 | + +### 依赖关系 + +- P0-A 完成后,P0-B 才能验证 spec_type 维度是否存在 +- P0-A + P0-B 完成后,前端 submit() 重构才有正确的 spec_base_id 可用 +- 前端实测依赖后端 SKU 已生成 + +### P1 详细执行计划 + +**当前状态(ticket_detail.html 第 413-418 行)**: +```javascript +var goodsParams = JSON.stringify([{ + goods_id: this.goodsId, + spec_base_id: this.sessionSpecId, // ← Zone 级别,只有 1 个 + stock: this.selectedSeats.length, // ← 数量,但 ShopXO 不知道具体是哪些座位 + extension_data: extensionData +}]); +``` + +**重构目标**:每座一行 goods_params: +```javascript +// 每座一行,逐座提交 +var goodsParamsList = []; +this.selectedSeats.forEach(function(seat) { + var seatKey = seat.row + '_' + seat.col; + var specBaseId = app.specBaseIdMap[seatKey]?.spec_base_id || app.sessionSpecId; + goodsParamsList.push({ + goods_id: app.goodsId, + spec_base_id: specBaseId, + stock: 1, + extension_data: JSON.stringify({ + attendee: attendees.find(function(a) { return a._seat === seatKey; }), + seat: seat + }) + }); +}); +var goodsParams = JSON.stringify(goodsParamsList); +``` + +**关键改动点**: +1. `submit()` 改为遍历 `selectedSeats`,每座一行 goods_params +2. `spec_base_id` 从 `specBaseIdMap[seatKey]` 获取(Plan A:座位级 SKU) +3. `stock` 固定为 1(每个 SKU 对应一个座位) +4. `extension_data` 改为 seat-level,每座携带自己的信息 +5. 保留 `sessionSpecId` 作为 fallback(Plan B 回退) + +### P0-B 返回值接口约定 + +BackendArchitect 的 `BatchGenerate()` 返回值需包含: +```php +[ + 'total' => 100, // 生成数量 + 'spec_base_id_map' => [ // seatKey → spec_base_id 映射 + 'A_1' => ['spec_base_id' => 2001, 'zone_id' => 'zone1', 'row' => 'A', 'col' => 1], + 'B_2' => ['spec_base_id' => 2002, 'zone_id' => 'zone1', 'row' => 'B', 'col' => 2], + ... + ] +] +``` + +前端期望 `specBaseIdMap` 格式: +- Key: `row_col`(如 `"A_1"`) +- Value: `{spec_base_id: number, zone_id: string, row: string, col: number}` + +--- + ## Round 3 安全审计结果(保留,仅供参考) ### Task S1 — Admin 鉴权覆盖完整性审查 ✅ 验证通过