vr-shopxo-plugin/plan.md

4.2 KiB
Raw Blame History

vr-shopxo-plugin P0 修复执行计划 — plan.md

版本v1.0 | 日期2026-04-15 | AgentBackendArchitect + 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.html submit() 重构 — 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

逻辑:

  1. UPDATE is_exist_many_spec=1 WHERE id=$goodsId(幂等)
  2. 检查 $vr-场馆/$vr-分区/$vr-时段 是否存在(按 name 查 goods_spec_type),不存在则 INSERT
  3. 使用 INSERT IGNOREON 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
]

核心逻辑:

  1. vr_seat_template 读取 seat_mapzones → rows → seats
  2. 从 zone 配置获取 price
  3. 遍历每个座位,生成 goods_spec_baseinventory=1price 从 zone.price 获取)
  4. 同时写入 goods_spec_valuespec_type_id × 4 维度 = 4 行/座位)
  5. 必须旁路 GoodsSpecificationsInsert() — 直接 SQL INSERT
  6. 分批500 条/批10000 座位约 20 批

关键表结构:

  • sxo_goods_spec_base: id (PK auto), goods_id, spec_base, price, inventory, color, images, weight, stock
  • sxo_goods_spec_value: id (PK auto), goods_id, spec_base_id (FK), spec_type_id (FK), spec_value (JSON)

幂等: 先 DELETE 已存在的座位级 SKUspec_type_id IN (venue,zone,time,seat_num)),再重建。


P1 详细设计FrontendDev

文件: plugins/vr_ticket/view/goods/ticket_detail.html

逻辑:

  1. submit() 改为遍历 this.selectedSeats
  2. 每个座位从 app.specBaseIdMap[seatId] 获取 spec_base_id
  3. 构造 goods_params 数组,每个座位一行
  4. 降级策略: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]

执行顺序

  1. BackendArchitect: P0-A 代码 + SQL 验证
  2. BackendArchitect: P0-B SeatSkuService::BatchGenerate()
  3. FrontendDev: P1 submit() 重构
  4. BackendArchitect: 合并到 main
  5. 容器实测:商品 112 initGoodsSpecs(112) → 验证 is_exist_many_spec=1 + 3条spec_type
  6. 容器实测:BatchGenerate(112, $templateId) → 验证座位级 SKU 生成