Merge branch 'council/FrontendDev'
commit
b4a94f832a
84
plan.md
84
plan.md
|
|
@ -222,6 +222,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 鉴权覆盖完整性审查 ✅ 验证通过
|
||||
|
|
|
|||
Loading…
Reference in New Issue