vr-shopxo-plugin/reviews/FrontendDev-Issue3-SpecLoad...

3.0 KiB
Raw Permalink Blame History

FrontendDev — Issue 3 Findings: Spec 加载问题(前端视角)

当前状态

loadSoldSeats() 函数ticket_detail.html:375-383完全是 TODO stub

loadSoldSeats: function() {
    // TODO: 从后端加载已售座位
    // $.get(this.requestUrl + '?s=plugins/vr_ticket/index/sold_seats', {
    //     goods_id: this.goodsId,
    //     spec_base_id: this.sessionSpecId
    // }, function(res) {
    //     // 标记已售座位
    // });
},

没有任何网络请求soldSeats 永远是空对象 {}

真实库存加载

GetGoodsViewData 返回的数据SeatSkuService.php:358-464

$goods_spec_data 只包含场次维度的 spec_base_id(非座位级):

[
    'spec_id'   => $specValue['goods_spec_base_id'] ?? 0,  // 场次级 ID
    'spec_name' => $timeRange,                               // "08:00-23:59"
    'price'     => floatval($sv['price']),
]

前端通过 selectSession() 选择场次后,this.sessionSpecId 被设置为场次级 spec_base_id。但座位级的 spec_base_id_map每个座位的 SKU ID需要从后端接口查询

specBaseIdMap 的局限性

ticket_detail.html:187 注入的 specBaseIdMap 来自 seatTemplate['spec_base_id_map']。这个 map 的 key 格式是 rowLabel_colNum(如 "A_1"value 是座位级 GoodsSpecBase ID。

问题:前端无法仅凭前端数据知道哪些座位已售。需要后端接口:

  1. 根据 goods_id + sessionSpecId 查询所有已售 GoodsSpecBaseinventory = 0
  2. 返回已售座位 key 列表
  3. 前端在 loadSoldSeats() 中标记 .sold class

修复方案(前端部分)

需要实现一个 AJAX 接口 plugins/vr_ticket/index/sold_seats,前端调用:

loadSoldSeats: function() {
    if (!this.sessionSpecId) return;
    var self = this;
    $.get(this.requestUrl + '?s=plugins/vr_ticket/index/sold_seats', {
        goods_id: this.goodsId,
        spec_base_id: this.sessionSpecId  // 场次级 ID
    }, function(res) {
        if (res.code === 0 && res.data) {
            // res.data: [{row_col: "A_1", row_label: "A", col_num: 1}, ...]
            res.data.forEach(function(sold) {
                self.soldSeats[sold.row_label + '_' + sold.col_num] = true;
            });
            self.markSoldSeats();
        }
    });
},

markSoldSeats: function() {
    var self = this;
    document.querySelectorAll('.vr-seat-row .vr-seat:not(.aisle):not(.space)').forEach(function(el) {
        var key = el.dataset.rowLabel + '_' + el.dataset.colNum;
        if (self.soldSeats[key]) {
            el.classList.add('sold');
        }
    });
}

API 设计建议

后端需要新增一个控制器方法(可能是 plugins/vr_ticket/index/Index 中的 sold_seats action查询 GoodsSpecBaseinventory = 0 的座位记录,按场次 ID 过滤。

依赖

  • BackendArchitect 提供 sold_seats 接口的准确路径和返回格式
  • BackendArchitect 确认 GoodsSpecBase 的 inventory 字段在购票后是否被正确扣减