4.2 KiB
4.2 KiB
vr-shopxo-plugin P0 修复执行计划 — plan.md
版本:v1.0 | 日期:2026-04-15 | Agent:BackendArchitect + FrontendDev 关联:Issue #9 | 状态:执行中
任务背景
方案 A 已全票通过(见 council-output/ARCHITECTURE_DECISION.md)。现在进入执行阶段,按优先级实施三个任务。
任务清单
- P0-A:
BaseService::initGoodsSpecs()— 商品 112 最小修复集[Claimed: BackendArchitect] - P0-B:
SeatSkuService::BatchGenerate()— 批量生成座位级 SKU[Claimed: BackendArchitect] - P1:
ticket_detail.htmlsubmit() 重构 — seat-level 逐座提交[Claimed: FrontendDev]
阶段划分
| 阶段 | 内容 | 负责 |
|---|---|---|
| Draft | 各成员编写执行代码 | BackendArchitect (P0-A/P0-B), FrontendDev (P1) |
| Review | 代码互审,验证 SQL 正确性 | BackendArchitect 审 P1, FrontendDev 审 P0-A/P0-B |
| Finalize | 合并到 main,实测验证 | 所有成员 |
P0-A 详细设计
文件: plugins/vr_ticket/service/BaseService.php
方法: public static function initGoodsSpecs(int $goodsId): bool
逻辑:
- UPDATE
is_exist_many_spec=1WHEREid=$goodsId(幂等) - 检查
$vr-场馆/$vr-分区/$vr-时段是否存在(按 name 查goods_spec_type),不存在则 INSERT - 使用
INSERT IGNORE或ON DUPLICATE KEY防止重复
关键 SQL:
UPDATE sxo_goods SET is_exist_many_spec = 1 WHERE id = $goodsId;
INSERT IGNORE INTO sxo_goods_spec_type (goods_id, name, value, add_time) VALUES
($goodsId, '$vr-场馆', '[{"name":"国家体育馆","images":""}]', UNIX_TIMESTAMP()),
($goodsId, '$vr-分区', '[{"name":"A区","images":""},{"name":"B区","images":""},{"name":"C区","images":""}]', UNIX_TIMESTAMP()),
($goodsId, '$vr-时段', '[{"name":"2026-05-01 19:00","images":""}]', UNIX_TIMESTAMP());
验证: 执行后 SELECT * FROM sxo_goods_spec_type WHERE goods_id=112 确认 3 条 spec_type 记录。
P0-B 详细设计
文件: plugins/vr_ticket/service/SeatSkuService.php(新建)
方法: public static function BatchGenerate(int $goodsId, int $seatTemplateId): array
返回值:
[
'total' => 100, // 生成的 SKU 总数
'batch' => 1, // 批次数
'spec_base_id_map' => ['A1_1' => 2001, 'A1_2' => 2002, ...] // seatId => spec_base_id
]
核心逻辑:
- 从
vr_seat_template读取 seat_map(zones → rows → seats) - 从 zone 配置获取 price
- 遍历每个座位,生成
goods_spec_base行(inventory=1,price 从 zone.price 获取) - 同时写入
goods_spec_value(spec_type_id × 4 维度 = 4 行/座位) - 必须旁路
GoodsSpecificationsInsert()— 直接 SQL INSERT - 分批:500 条/批,10000 座位约 20 批
关键表结构:
sxo_goods_spec_base: id (PK auto), goods_id, spec_base, price, inventory, color, images, weight, stocksxo_goods_spec_value: id (PK auto), goods_id, spec_base_id (FK), spec_type_id (FK),spec_value(JSON)
幂等: 先 DELETE 已存在的座位级 SKU(spec_type_id IN (venue,zone,time,seat_num)),再重建。
P1 详细设计(FrontendDev)
文件: plugins/vr_ticket/view/goods/ticket_detail.html
逻辑:
submit()改为遍历this.selectedSeats- 每个座位从
app.specBaseIdMap[seatId]获取spec_base_id - 构造
goods_params数组,每个座位一行 - 降级策略:
spec_base_id不存在时走原 Plan B 逻辑
依赖关系
- P0-A 和 P0-B 可并行开发
- P1 依赖 P0-B 完成后注入
specBaseIdMap数据 - P0-A 完成后需在 ShopXO 容器实测验证
Claim 状态
| 任务 | Claim 状态 |
|---|---|
| P0-A | [Claimed: BackendArchitect] |
| P0-B | [Claimed: BackendArchitect] |
| P1 | [Claimed: FrontendDev] |
执行顺序
- BackendArchitect: P0-A 代码 + SQL 验证
- BackendArchitect: P0-B SeatSkuService::BatchGenerate()
- FrontendDev: P1 submit() 重构
- BackendArchitect: 合并到 main
- 容器实测:商品 112
initGoodsSpecs(112)→ 验证 is_exist_many_spec=1 + 3条spec_type - 容器实测:
BatchGenerate(112, $templateId)→ 验证座位级 SKU 生成