vr-shopxo-plugin/docs/council-eval-backendarchite...

8.0 KiB
Raw Blame History

Council 评估报告 — BackendArchitectRound 4 现场核查)

评估日期2026-05-26 | 角色:后端架构师 | Git: 0d6d20062 → 提交中


一、现状评估Round 4 现场核查)

1.1 Phase 4 Tree API 设计

状态:📋 设计文档存在,代码为零

组件 状态 说明
docs/PHASE_4_API.md 存在 Tree API 设计文档
docs/PLAN_TREE_API_IMPLEMENTATION.md 存在 实现计划
SeatMapService.php(服务类) 存在且完整 333行GetSeatMap() + buildSeatSpecMap() + buildGoodsSpecData()
api/Goods.php::seatmap() 存在且正确 第241行调用 SeatMapService::GetSeatMap($goodsId)
SeatSkuService.php 存在 独立服务,含 BatchGenerate() + GetGoodsViewData() + buildSeatSpecMap()
Tree API buildTree() 代码为零 Phase 4 设计中的核心方法未实现

Round 4 修正:设计文档中提到的 SeatMapService在父仓库已存在且完整api/Goods.php::seatmap() 路由已正确调用它。Round 1-3 的"P0 崩溃"分析是误判。

1.2 SeatMapService + seatmap API

状态: 已完整实现

组件 状态 位置
SeatMapService.php 完整 333行GetSeatMap() + 缓存 + buildSeatSpecMap() + buildGoodsSpecData()
api/Goods.php::seatmap() 正确 第233-246行路由注册正常调用 SeatMapService::GetSeatMap()
SeatSkuService::buildSeatSpecMap() 存在 第533行私有方法
SeatSkuService::GetGoodsViewData() 存在 第370行H5 模板专用)
SeatSkuService::getSoldSeats() ⚠️ 方法不存在 GetSeatMap() 已含库存信息,可替代
index/Index.php::soldSeats 不存在 Index.php 只有 wallet() 方法,无 soldSeats

Round 4 修正

  • Round 3 报告称"Index.php:43 调用 getSoldSeats()"——这是误判Index.php 只有 wallet() 方法,无 soldSeats action。
  • SeatMapService::GetSeatMap() 已完整实现,含实时 inventory 字段0=已售),可替代 getSoldSeats()
  • 无运行时崩溃seatmap API 工作正常。

1.3 seatSpecMap 注入商品详情 API

状态:⚠️ Gap 1 成立,但有变通方案

组件 状态 说明
SeatSkuService::GetGoodsViewData() 存在 第370行H5 模板专用
Hook.php::plugins_service_goods_data 未注册 Hook.php 无此 case
api/Goods.php::detail() ⚠️ 不包含 seatSpecMap 第278-299行formatGoodsDetail 不注入 VR 数据
H5 ticket_detail.html 工作正常 直接调用 GetGoodsViewData()
UniApp api/goods/detail Gap 1 成立 无 Hook 注入,无 VR 数据

Gap 1 分析修正

  • Gap 1 对 UniApp 仍然成立Hooks 未注册)
  • api/Goods.php::seatmap()第233行已完整提供 seatSpecMap + goods_spec_data
  • UniApp 可以绕过 Gap 1:先调用 /seatmap API 获取座位图,再调用标准 /detail API 获取商品基础信息
  • 最优解仍为 Hook 注册:减少前端调用次数(一次 /detail 获取所有数据)

1.4 CartSave extension_data 多座位链路

状态: H5 已验证,后端无需改动

组件 状态 说明
ticket_detail.html:762 订单提交 已实现 extension_data 嵌套在 order_base
TicketService::onOrderPaid() 已实现 逐行生成票(多座位支持)
Gap 2 状态 已消除 后端链路完整UniApp 复刻 JSON 格式即可

二、发现问题Round 4 修正)

P0重新评估

# 问题 严重度 Round 3 对比
P0-1 getSoldSeats() 方法缺失 已消除 SeatMapService::GetSeatMap() 已含库存,Index.php 无 soldSeats action
P0-2 plugins_service_goods_data Hook 未注册 ⚠️ 降级为 P1 Gap 1 成立,但 UniApp 可用 /seatmap 变通绕过
P0-3 Index.php:soldSeats 触发 Fatal Error 已消除 Index.php 无 soldSeats action无崩溃

重新分类

# 问题 严重度 说明
P1-A api/Goods.php::detail() 不包含 seatSpecMap UniApp /detail API 缺少 VR 数据注入
P1-B plugins_service_goods_data Hook 未注册 UniApp detail API 最佳入口缺失
P2-A Phase 4 Tree API buildTree() 未实现 设计完整,代码为零
P2-B api/Goods.php::seatmap() 命名不一致 seatmap vs seatMap大小写

三、技术方案建议

方案 A推荐Hook 注册(最小改动)

文件Hook.php 追加 case

case 'plugins_service_goods_data':
    $goodsId = $params['goods_id'] ?? 0;
    if ($goodsId > 0) {
        TicketService::InjectGoodsDetailData($params['data'], $goodsId);
    }
    break;

新增方法TicketService.php

public static function InjectGoodsDetailData(array &$data, int $goodsId): void
{
    if ($goodsId <= 0) return;
    $vrConfig = \think\facade\Db::name('goods')
        ->where('id', $goodsId)
        ->value('vr_goods_config');
    if (empty($vrConfig)) return;
    $viewData = SeatSkuService::GetGoodsViewData($goodsId);
    if (empty($viewData['seatSpecMap'])) return;
    $data['seatSpecMap']     = $viewData['seatSpecMap'];
    $data['goods_spec_data'] = $viewData['goods_spec_data'];
    $data['specTypeList']   = $viewData['specTypeList'] ?? [];
    $data['seatMap']         = $viewData['vr_seat_template']['seat_map'] ?? null;
    $data['goods_config']    = $viewData['goods_config'] ?? null;
}

代码量:约 30 行。效果UniApp 调用 ShopXO 标准 /goods/detail API 时自动获得 VR 数据。

方案 B备选UniApp 变通绕过(无需后端改动)

UniApp 端可在调用商品详情后,再调用 /seatmap API 补充 VR 数据。

  • 优点:无需后端改动,立即可用
  • 缺点:前端多一次 API 调用(可接受)

方案 CPhase 4 完整实现(独立任务)

buildTree() 实现 + Tree VR 体验,作为 Phase 4 独立里程碑。


四、优先级建议

优先级 任务 预计工时 收益
P1-A Hook 注册 + InjectGoodsDetailData() 30min 解锁 UniApp 完整票务链路
P1-B api/Goods.php::detail() 命名规范化 10min API 契约一致性
P2 Phase 4 Tree API 实现 待定 Tree VR 体验
P3 Phase 4 完整 Tree 体验 待定 VR 差异化功能

五、投票Round 4

议题:下一步主攻方向

投票A — 后端优先

理由

  1. Hook 注册是最低成本最高收益:约 30 行代码,一次性解决 UniApp 商品详情 API 的 VR 数据注入问题。无需前端变通,减少 API 调用次数。

  2. Round 4 重新评估确认:后端 seatmap API 已完整实现P0-1/P0-3 误判已消除),核心剩余问题是 Hook 注入这一处。

  3. Gap 2 已消除后端票务链路CartSave → onOrderPaid → 票生成)已完整,多座位支持已验证。

  4. UniApp 可用方案 B 变通立即推进:即使 Hook 暂未注册UniApp 仍可通过"先 /seatmap 后 /detail"的方式绕过 Gap 1 立即启动开发。

  5. Phase 4 不应前置Tree API 是体验增强在核心票务链路P1稳定前启动 Phase 4 资源浪费。

补充:对其他提案的评估

  • B前端优先可接受——UniApp 确实可以先用方案 B 变通绕过 Gap 1 立即开发。但变通方案不如 Hook 注册简洁。
  • C双线并行:可接受,但需明确分工。后端修 Hook前端用方案 B 变通同时推进。
  • DPhase 4 优先)不建议。Phase 4 是锦上添花,不是票务购买的基础设施。

报告人BackendArchitect | 2026-05-26 | Round 4