vr-shopxo-plugin/docs/ALIGNMENT.md

12 KiB
Raw Blame History

架构对齐文档 — 用户需求 vs 文档现状

PM Agent 输出 | 2026-04-14 状态:草稿,待确认


一、用户需求摘要

以下需求从对话记录中提取,已确认:

# 需求 来源
U1 spec = 场次规格spec直接作为场次不需要独立的 vr_sessions 表 "规格spec就是场次"
U2 每个商品 = 一个场馆的演唱会:用户在一个商品内完成选座购买全流程 "每一个商品就是一个物理意义上的电影院或者演出地址"
U3 场次作为分类值:场次加载为 ShopXO 的分类category后台通过分类名关联 "场次这个东西我们直接加载成一个分类值就好了"
U4 座位模板 → 绑定分类 → 商品关联:后台创建座位模板 → 绑定特定分类 → 创建商品时关联 "后端管理页:创建座位模板 → 绑定特定的分类信息 → 创建商品时关联"
U5 前端判断 item_type 替换模板:商品详情页加载时判断传入值,如果是 VR 票则替换为专用前端 "前端商品详情页加载时判断传入的值得出这是不是VR演唱会票如果是就替换成专用前端"
U6 购买走 ShopXO 原生流程:最终提交购买按钮走 ShopXO 原生订单流程,不另建独立下单 "最终提交购买按钮时走 ShopXO 原生订单流程"
U7 核销端独立页面:核销是单独的页面,不在购票流程内 "核销端是另外的独立页面"
U8 扩展字段注入模式:插件新增数据表 → 绑定 spec_value全局可复用→ 写入 goods.extension_data → 前端按数据渲染自定义 UI。这是通用模式可套用到票务/实物/套票等所有自定义类型商品 通用扩展方法论确认

Q4新增待确认问题

ShopXO spec_value 是「全局可复用」还是「商品级私有」?

  • 全局复用:插件初始化时自动检测/创建 spec商家直接选
  • 商品级私有:每个商品的 spec_value 独立,插件需要引导用户正确填写 影响:插件初始化策略 + 绑定方案

Q4 的两个选项:

  • Option A全局可复用推荐插件可以一键初始化
  • Option B商品级私有需要引导流程

二、冲突点列表

冲突 1vr_sessions 独立表 vs spec = 场次

维度 文档现状 用户想法
场次存储 vr_sessions 独立表,存日期/时间/价格覆盖/库存 ShopXO spec 系统即为场次载体,每个 spec 选项 = 一个场次
座位布局 sxo_goods.venue_data 存完整 venue + sessions[] + spec_base_id_map 座位模板seat_map绑定分类通过分类关联到商品
多场次复用 vr_sessions 共用 venue.seat_map多场次同一座位图 每个商品 = 单一商品内嵌多个 spec场次选项

分析

  • 用户明确说"规格spec就是场次",意味着不需要独立的 vr_sessions 表
  • 多个场次 = 商品的多个 spec 选项(如"2026-06-01 19:30"、"2026-06-02 14:00"
  • 座位图/座位布局是商品属性,通过分类绑定关联

建议方案

废弃 vr_sessions 独立表,改为:

  • 商品的每个 spec 选项 = 一个场次spec_value = 日期时间)
  • sxo_goods.venue_data 仅存座位图配置seat_map不存 sessions[]
  • 座位图与分类绑定,商品通过分类继承座位图配置

冲突 2venue_data 存完整配置 vs 座位模板绑定分类

维度 文档现状 用户想法
座位配置存储 sxo_goods.venue_data 存完整 venue + seat_map + sessions[] + spec_base_id_map 座位模板单独管理,绑定到分类,商品通过分类关联
绑定机制 每个商品直接存完整配置 商品关联分类 → 分类关联座位模板 → 座位模板提供 seat_map

分析

  • 用户强调"创建座位模板 → 绑定特定的分类信息 → 创建商品时关联"
  • 这是解耦思路:座位模板可复用,多个商品(同一场馆不同演出)共用同一模板
  • 分类在这里是"座位模板 ID"的载体

建议方案

保留座位模板表 vr_seat_templates

  • 存储 seat_map JSON座位图布局
  • 绑定到一个特定分类(如 category_id = 场馆分类 ID
  • 商品创建时选择该分类 → 自动继承 seat_map → 商品的 spec 展示座位选择

冲突 3item_type 字段写入机制

维度 文档现状 用户想法
item_type 来源 文档提到 Goods.php 修改来识别 ticket 类型 前端商品详情页加载时判断"传入的值",识别 VR 票类型
谁来写 item_type 未明确(后台手动设置?插件自动?) 用户认为商品数据中有某个值可以用来判断类型

分析

  • 用户说"判断传入的值" → 说明商品数据里有某个字段可区分票务商品
  • 这个字段可能是:item_typegoods_type、或者自定义的 venue_data 是否存在
  • 最简单方案:商品有 venue_data 就认为是票务商品,不需要额外字段

建议方案

item_type 不作为独立字段,用 sxo_goods.venue_data IS NOT NULL 作为票务商品标识:

  • 创建商品时勾选"票务商品"或选择座位模板 → 插件写入 venue_data
  • 前端判断 $goods.venue_data 是否有值 → 有值则加载票务专用前端
  • 无需修改 ShopXO 核心或新增字段

冲突 4Goods.php 修改 vs 纯 Hook 方案

维度 文档现状 用户想法
模板替换方式 文档记录了 Goods.php Index() 加判断的方案MIT 允许范围内最小改动) 用户说"前端商品详情页加载时判断传入的值得出这是不是VR演唱会票如果是就替换成专用前端"
是否改核心文件 文档认为改 1 行可接受,保留为备案 用户想法中没有提到需要改核心 PHP 文件

分析

  • 用户的前端判断逻辑可以完全在 Hook + Vue 前端实现
  • 不需要修改 Goods.php

建议方案

废弃 Goods.php 修改方案,完全用 Hook

  • plugins_view_goods_detail_base_sku_top 注入票务选座 UI覆盖原有规格选择区
  • 前端 Vue 判断 goods.venue_data 是否有值 → 决定是否跳转到票务页面
  • 保留 Goods.php 方案作为备案(如 Hook 注入不够时)

冲突 5vr_venues 场馆表是否还需要?

维度 文档现状 用户想法
场馆概念 vr_venues 表存场馆名称/地址/座位图,多 session 共用一个 venue 用户说"每一个商品就是一个物理意义上的电影院或者演出地址"
粒度 venue 是复用层session 是时间层 商品 = 场馆 + 演出,座位模板是绑定到分类的

分析

  • 用户思路里"商品 = 场馆的一个演出",不需要跨商品的 venue 复用
  • 座位模板seat_map是绑定分类的不是绑定 venue 的
  • vr_venues 表在用户思路里没有明确位置

建议方案

废弃 vr_venues 表,改用 vr_seat_templates(座位模板)表:

  • 模板存储 seat_map JSON + 分类绑定
  • 商品通过分类关联模板
  • 不需要独立的场馆表(场馆名称可存商品信息里)

三、确认方案(无争议部分)

以下结论可以直接落地:

3.1 spec = 场次(已确认)

每个 ShopXO spec 选项 = 一个演出场次(如"2026-06-01 晚场"、"2026-06-02 下午场")。

  • 不需要 vr_sessions
  • 商品的多个 spec 值 = 多个场次
  • spec_base_id_map 绑定 seat_id → spec_base_id → 购买流程

3.2 座位模板绑定分类(已确认)

座位模板 vr_seat_templates 表:

CREATE TABLE vr_seat_templates (
  id           BIGINT PRIMARY KEY AUTO_INCREMENT,
  name         VARCHAR(180) NOT NULL COMMENT '模板名称(如:鸟巢-A区',
  category_id  BIGINT UNSIGNED NOT NULL COMMENT '绑定的分类ID',
  seat_map     LONGTEXT NOT NULL COMMENT '座位地图JSON',
  status       TINYINT UNSIGNED DEFAULT 1,
  add_time     INT UNSIGNED DEFAULT 0,
  upd_time     INT UNSIGNED DEFAULT 0,
  UNIQUE KEY category_id (category_id)
);

绑定流程:

  1. 后台创建座位模板 → 选择绑定分类(如"VR演唱会-A区"
  2. 创建商品 → 选择该分类
  3. 插件自动将模板 seat_map 写入商品 venue_data

3.3 venue_data 精简为仅座位配置

sxo_goods.venue_data JSON 结构简化:

{
  "seat_map": { /* 座位图配置 */ },
  "spec_base_id_map": { /* seat_id  spec_base_id */ }
}

sessions 信息不再存在 venue_data 里,由 ShopXO spec 系统提供。

3.4 item_type 判断用 venue_data 非空

  • 不新增 item_type 字段
  • 判断逻辑:!empty($goods['venue_data']) → 票务商品
  • 前端 Vue 同理:goods.venue_data 是否有值

3.5 完全通过 Hook 实现,不改 Goods.php

  • plugins_view_goods_detail_base_sku_top 注入票务选座 UI
  • 保留 Goods.php 修改方案为备案(如 Hook 注入范围不够时启用)

3.6 核销端独立页面

  • B 端核销页:pages/plugins/vr-ticket-verify/check/check.vueFork 自 realstore/check.vue
  • 不在购票主流程内

四、待确认问题(需要 Council 判断)

以下问题无法从对话记录中确认解决方案,打上 pending-council 标签:

Q1: 座位模板与分类的绑定粒度

背景:用户说"绑定特定的分类信息"但一个演出可能有多个座位区A区/B区/C区每个区是不同的座位图。

选项

  • A每个分类 = 一个座位区(多个分类绑定同一个演出)
  • B一个分类 = 一个完整场馆(座位图内分区)
  • C一个商品可以绑定多个座位模板

待验证:用户的"分类"是指 ShopXO 商品分类,还是自定义的"场馆座位分类"?需要明确。

Q2: spec_base_id_map 的生成时机

背景spec = 场次时,座位选择是跨 spec场次还是每个 spec场次有独立的座位

选项

  • A每个 spec场次有独立的座位配置不同日期同一座位区
  • B所有 spec 共用同一座位配置(日期不同,座位相同)

待验证:用户说"只要用户想要买某一个场馆的演唱会,他就在这一个商品里面操作就行" → 倾向于 B同一座位图日期不同

Q4: spec_value 复用粒度 — 全局还是商品级?

背景用户在确认通用扩展方法论时提出spec_value 的复用粒度直接影响插件初始化策略。

选项

  • Option A全局可复用推荐插件可以一键初始化— 插件初始化时自动检测/创建 spec_value商家创建商品时直接选
  • Option B商品级私有需要引导流程— 每个商品的 spec_value 独立,插件需要引导用户正确填写

影响:插件初始化策略 + 绑定方案。


Q3: 观演人信息的存储位置

背景:用户说"走 ShopXO 原生订单流程",但票务需要观演人信息。

选项

  • A观演人信息存 sxo_order.extension_dataShopXO 扩展字段)
  • B观演人信息存 vr_tickets
  • C观演人信息作为 spec 选项的一部分

待验证ShopXO 原生订单的 extension_data 是否足够存观演人信息?是否有更优雅的方式?


五、ARCHITECTURE.md 更新计划

根据以上对齐结论ARCHITECTURE.md 需要做以下更新:

  1. 删除 vr_sessions 表,改为 spec = 场次
  2. 删除 vr_venues 表,改为 vr_seat_templates 表(座位模板绑定分类)
  3. 简化 venue_data JSON 结构,只保留 seat_map + spec_base_id_map
  4. 明确 item_type 判断机制venue_data 非空
  5. 删除 Goods.php 修改方案,改为纯 Hook 方案
  6. 更新购票流程,反映 spec = 场次的设计
  7. 更新目录结构,反映 vr_seat_templates 替代 vr_venues/vr_sessions