Commit Graph

228 Commits (461dd6b1011cb0add1ff43f5410916263c2f4b35)

Author SHA1 Message Date
Council 461dd6b101 fix: 修复 seat map 数据结构 + selected seats UI + encoding + submit button
1. renderSeatMap: 修复 map.seat_map 数据结构访问
2. updateSelectedUI: 渲染 selectedList + 启用 submit button
3. 修复 GoodsSpecValue 中文编码问题
4. 添加 barCount/barPrice 更新
2026-04-21 12:30:09 +08:00
Council 82a5b2129d fix: 修复 seatMap 数据结构错误 - vr_seat_template 已经是解码后的 seat_map 2026-04-21 12:08:48 +08:00
Council fb300e00fc feat(Phase2): 修复 seatSpecMap 生成 + room ID 硬编码问题
关键修复:
1. BatchGenerate(): 新增 extends.seat_key 字段写入 GoodsSpecBase
2. BatchGenerate(): 新增 type 字段写入 GoodsSpecValue(4维spec类型)
3. ticket_detail.html: renderSeatMap() 不再用 room_001_ 硬编码,改用模板实际 roomId
4. Goods.php: seatSpecMap 注入(已在上次提交)

数据库修复:
- 为 vrt_goods_spec_value 新增 type 字段
- 重新生成商品 118 的规格数据(含 seat_key 和 type)
2026-04-21 12:03:56 +08:00
Council c581395a9c feat(Phase2): Issue 1 修复购买提交流程
- Goods.php: 注入 seatSpecMap 到票务模板
- ticket_detail.html: submit() 改 POST + 4维spec数组

关键修复:
- submit() 使用隐藏表单 POST 到 Buy 链路(不再用 location.href)
- spec 从 seatSpecMap[seatKey].spec 读取完整4维数组
- extension_data 嵌套在 order_base 内
- 直接 JSON.stringify,不需要 base64
2026-04-21 11:41:59 +08:00
Council 919c5cfd4e council(draft): FirstPrinciples - create plan.md for ShopXO frontend research (Q1-Q4) 2026-04-20 23:10:51 +08:00
Council 752fc9e969 council(draft): ProductManager - create plan.md for frontend template research round 2026-04-20 23:10:35 +08:00
Council dbd62f5658 docs: 追加幽灵 spec 修复记录 (DEVELOPMENT_LOG.md 更新) 2026-04-20 22:43:01 +08:00
Council 2311f17b90 fix(vr_ticket): 修复幽灵 spec 问题 (Issue #15 + #16)
Issue #15 — AdminGoodsSaveHandle.php:
1. 读取优先级调换:data['vr_goods_config'] 优先,DB 兜底(从源头避免脏数据)
2. 模板不存在时 unset($configs[$i]) 移除无效 config 块(防御层)
3. array_values 重排索引 + 写回前判空(防御层)

Issue #16 — SeatSkuService.php GetGoodsViewData:
1. 多模板模式:遍历所有配置块过滤有效块
2. 模板不存在时清理无效块并写回有效配置(而非覆盖)

参考:reports/GHOST_SPEC_INVESTIGATION_REPORT.md
参考:docs/PLAN_GHOST_SPEC_FIX.md
2026-04-20 22:42:41 +08:00
Council 44120a7e2c council(finalize): resolve plan.md merge conflict, integrate BackendArchitect report
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 19:21:45 +08:00
Council f493d06d41 council(draft): BackendArchitect - mark all BackendArchitect tasks as done
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 19:14:37 +08:00
Council f1173e3c85 docs: 补充硬删除修复记录 + Issue #13 关闭说明
- docs/DEVELOPMENT_LOG.md: 追加 2026-04-20 下午记录(含教训)
- docs/Fixing Plugin Venue Deletion.md: 大头手动修复对话记录(新建)
- docs/VenueDelete_Bug_Fix.md: 审查报告(新建)
2026-04-20 18:07:51 +08:00
Council 9f3a46e5a1 fix(vr_ticket): 修复硬删除按钮 + 清理残留代码
1. Admin.php SeatTemplateDelete/VenueDelete:
   - is_delete → is_delete_time(ShopXO Goods 表软删除字段)
   - VenueDelete 新增 value='hard' 参数支持(兼容 submit-ajax)

2. list.html:
   - 删除按钮从 btn-open-delete-confirm 改为 submit-ajax
   - 删除按钮移出条件判断,始终可见
   - 移除残留的 old modal + custom JS handler

3. 清理 shopxo/app/event.php 变动(还原)
2026-04-20 18:06:23 +08:00
Council 95346206dc fix: 移除不存在的座位模板菜单 + 调整删除提示文案 + 取消阻塞式商品关联检查
1. Hook.php:移除 'plugins-vr_ticket-seat' 菜单项(对应 view 文件已删除)
2. Admin.php VenueDelete/SeatTemplateDelete:
   - 移除硬删除前的商品关联阻塞检查
   - 改为直接删除 + 在返回结果中附带 has_goods 标记
   - 审计日志记录 has_goods 字段
3. view/venue/list.html:删除确认弹窗文案改为
   '删除后,关联商品的场馆信息将被自动清除'
2026-04-20 15:48:11 +08:00
Council df8353a697 feat: 真删除功能 + 三按钮布局 + seat_template 视图补全
后端(Admin.php):
- SeatTemplateDelete/VenueDelete:新增 hard_delete 参数
  - hard_delete=0(默认):软删除(status→0),返回'已禁用'
  - hard_delete=1:真删除,先检查商品关联再 DELETE
- SeatTemplateEnable/VenueEnable:新增启用 API,含审计日志

前端(view/venue/list.html):
- 按钮改为三按钮布局:编辑 / 禁用/启用 / 删除
- 删除按钮点击后弹出警告弹窗
  - 警告:删除记录不会导致已上架商品内容变动
  - 若需同步,请编辑对应商品并保存
- 禁用/启用按钮使用 submit-ajax,data-view=reload 自动刷新

新增(admin/view/seat_template/):
- list.html:座位模板列表(三按钮布局,与 venue/list.html 相同)
- save.html:座位模板编辑页(基础版,seat_map 由 venue 编辑器管理)
2026-04-20 15:08:27 +08:00
Council 168d85e61d docs: 追加方案 C 决策记录和最终实现说明 2026-04-20 14:33:16 +08:00
Council 5675bb679f fix: 模板硬删除场景下优雅降级 + snapshot 同步清空
方案逻辑(用户提出):
- 模板被硬删除后,GetGoodsViewData() 将 template_id + template_snapshot 同时置 null
- 前端看到选单为空,用户可重新选择或清空配置
- AdminGoodsSaveHandle() 跳过不存在模板的 snapshot 重建(continue)

修改文件:
- SeatSkuService.php: GetGoodsViewData() 加硬删除检测,空模板时清空 config
- AdminGoodsSaveHandle.php: 模板不存在时 continue,不触发 json_decode(null) Fatal Error
2026-04-20 14:32:38 +08:00
Council fa35d785a9 docs: add venue hard-delete evaluation report 2026-04-20 13:53:35 +08:00
Council 79f2fe2bd3 docs: 记录 Issue #13 根因修复 + room.id UUID 生成逻辑 2026-04-20 13:32:08 +08:00
Council 05b69588f5 chore: remove debug logging from AdminGoodsSaveHandle
All debugging code (vr_debug.log writes) removed.
Template snapshot rebuild is now stable and verified.
2026-04-20 13:31:17 +08:00
Council c03737308b fix(Admin): 改用 random_int() CSPRNG,修正 UUID v4 版本/变体位
mt_rand() → random_int()(防种子预测)
版本号 nibble: 8 → 4(符合 RFC 4122 UUID v4)
变体位保持 10xx 格式不变
2026-04-20 13:21:44 +08:00
Council 1244adfaae feat(Admin): SeatTemplateSave 时为无 id 的 room 生成 UUID
兜底逻辑:在保存场馆模板时,遍历 rooms,
若 room.id 为空则用 time()+mt_rand 生成唯一 UUID。
不修改已有数据的读取逻辑(读取端已有 room_N 兼容兜底)。
2026-04-20 12:58:19 +08:00
Council 8a33e7fa29 fix(AdminGoodsSaveHandle): 空id房间用数组索引匹配 room_0/room_1
DB 中模板5的room[0].id为空,selected_rooms发来room_0。
filter无法匹配空id导致selectedRoomIds=[],rooms为空。

修复:空id时用数组索引作为room_N(N从0开始)进行匹配。
PHP 7.x兼容,无str_starts_with。
2026-04-20 12:42:46 +08:00
Council 5dc9a98420 fix: Db::find() 全量查询 + fallback 到 params[data];同时加调试日志 2026-04-20 12:25:02 +08:00
Council 0a2fd29d7c debug: add temp logging to trace template_snapshot rebuild 2026-04-20 12:23:58 +08:00
Council da001797ab fix(vr_ticket): template_snapshot 重建逻辑重写 + 幽灵配置过滤
=== 问题 1: template_snapshot.rooms 为空 ===

根因:前端 outputBase64 根本不包含 template_snapshot,导致:
- template_snapshot 永远是空的
- 无论 v1/v3 格式,rooms 信息都丢失

修复(AdminGoodsSaveHandle.php):
- 条件从「template_snapshot 为空才读 DB」改为「selected_rooms 有值就永远从 DB 重建」
- 读 DB 时同时做 v1→v3 迁移(sections+map → rooms 数组)
- ID 匹配支持前端标准化的 "room_0" 格式和 DB 原始 "0" 格式双向兼容
- PHP 7.x 兼容(strpos 而非 str_starts_with)

=== 问题 2: 幽灵配置(软删除场馆仍出现在表单)===

根因:AdminGoodsSave.php 查询模板时用 where('status', 1),软删除模板不加载,
但 configs.value 里还保留着旧配置 → 场馆 checkbox 选中但无法操作。

修复(AdminGoodsSave.php):
- 加载时用 Set 过滤掉 status=0 模板的配置
- 幽灵配置在编辑表单加载时直接排除,不出现在 UI
2026-04-20 12:16:31 +08:00
Council ca7bee5494 fix(AdminGoodsSaveHandle): save_thing_end 改为直接读 DB 而非 值拷贝
确保 template_snapshot 兜底逻辑在正确的数据上执行:
1. ShopXO save_thing_end 传入的 $data 是值拷贝,改用 Db::find() 直接从DB读
2. 加 json_last_error() 检查,防止损坏的 JSON 静默失败
2026-04-20 11:28:34 +08:00
Council 3f06f36e50 fix(AdminGoodsSaveHandle): template_snapshot rooms为空时DB兜底 + v1→v3迁移
修复 Issue #13:
1. 条件从 empty(template_snapshot) 改为 empty(rooms),解决前端发送空rooms对象时跳过兜底的问题
2. 新增 v1 旧格式兼容:sections+map 扁平结构自动升級为 v3 rooms 数组
2026-04-20 10:40:26 +08:00
Council effe522ebf Merge branch 'council/BackendArchitect'
# Conflicts:
#	plan.md
2026-04-20 10:00:59 +08:00
Council 20830abbc0 docs(plan): 记录 P1+P2 修复已合并到 main
Commit: 804d465d0 → main: 49930844f

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 10:00:05 +08:00
Council 49930844fa Merge branch 'council/BackendArchitect' 2026-04-20 09:59:41 +08:00
Council 804d465d09 fix(AdminGoodsSaveHandle): P1+P2 空安全修复 — 解决 "Undefined array key 'id'" 错误
P1 (line 80): array_filter 回调内 $r['id'] 前加 isset() 空安全
P2 (line 71-73): find() 返回 null 时 continue 跳过,避免访问 $template['seat_map']

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:59:31 +08:00
Council 7ddfed55c1 council(review): SecurityEngineer - merge Task 13 audit report into main plan
Task 13 complete: reviews/SecurityEngineer-AUDIT.md
- Confirms BackendArchitect root cause findings (P0: Line 77, P1: Line 71)
- Adds PHP 8 compatibility note on null[key] TypeError
- Provides complete fix code

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:57:43 +08:00
Council 41c8fda398 council(review): BackendArchitect - add Task 12, all reviews complete
All tasks done:
- Tasks 1-8: BackendArchitect root cause analysis
- Tasks 9-11: DebugAgent static analysis + ROOT_CAUSE report
- Task 12: BackendArchitect cross-review of DebugAgent report

Issue #13 root cause fully documented and cross-verified.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:57:01 +08:00
Council 7a14acf6bc council(review): SecurityEngineer - Round 2 安全审计完成:根因定位 + 修复建议
根因:AdminGoodsSaveHandle.php:77 - \$r['id'] 无空安全
Secondary:Line 71 - find() 返回 null 后直接访问 \$template['seat_map']
报告:reviews/SecurityEngineer-AUDIT.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:56:52 +08:00
Council 6c35ac5c0f Merge branch 'council/BackendArchitect' 2026-04-20 09:56:20 +08:00
Council 8211419400 council(review): BackendArchitect - approve DebugAgent ROOT_CAUSE report
- Confirms Primary/Secondary/Tertiary root causes
- Notes array_column(null) PHP 8.0+ warning finding
- No conflicts with BackendArchitect findings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:56:16 +08:00
Council 4b48e4648e council(review): DebugAgent - Task 10-11 complete, ROOT_CAUSE report
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:54:31 +08:00
Council 30a7663b16 council(review): DebugAgent - Task 10-11 complete, ROOT_CAUSE report
- 验证 ShopXO prefix = 'vrt_', 两者等价(已排除)
- 确认 P1=77行$riid, P2=71行template null, P3=类型不匹配
- 输出 reports/DebugAgent-ROOT_CAUSE.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:53:20 +08:00
Council 56b291f2f8 council(draft): DebugAgent - resolve plan.md conflict, sync with main
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:51:57 +08:00
Council 9d111541af council(draft): DebugAgent - Round 1 静态分析 + 补充 plan.md + Task 9-11
- 补充 PHP 8+ ?? 行为分析
- 新增 reviews/DebugAgent-PRELIMINARY.md
- plan.md 新增 Task 9-11(DebugAgent Round 2)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:51:04 +08:00
Council 3799b2bc92 council(review): BackendArchitect - Issue #13 根因已定位:AdminGoodsSaveHandle.php:77
- Primary: $r['id'] 无空安全(array_filter 回调内)→ "Undefined array key 'id'"
- Secondary: find() 返回 null 后直接访问 $template['seat_map']
- Tertiary: selected_rooms 类型不匹配静默失败
- 已排除:表前缀问题(Db::name 和 BaseService::table 均查询 vrt_vr_seat_templates)
- 已排除:SeatSkuService::BatchGenerate 有正确的空安全处理

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:48:53 +08:00
Council 04766c2424 council(draft): BackendArchitect - create debug plan for "Undefined array key 'id'" error
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:46:29 +08:00
Council 0385f79106 council(draft): DebugAgent - plan.md: debug "Undefined array key id" error
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:46:20 +08:00
Council 98bd6a52cf docs: 补充 template_snapshot 前端vs后端职责说明 + 更新 Issue #13 进度 2026-04-20 09:43:29 +08:00
Council bbea35d837 feat(AdminGoodsSaveHandle): 保存时自动填充 template_snapshot
Issue #13 Step 1:
- save_thing_end 时机:遍历 vr_goods_config[],检测 template_snapshot 是否缺失
- 若缺失:从 vr_seat_templates 读最新 seat_map,按 selected_rooms 过滤 rooms
- 将填充后的完整 config JSON 写回 goods 表,再执行 BatchGenerate
- 前端已传 template_snapshot 时:直接透传,无需后端处理
2026-04-20 09:36:06 +08:00
Council 7f32ad87c2 docs: README 重构 + VR_GOODS_CONFIG_SPEC.md 加目录 + 追加开发日志第十三章
- README: 新增清晰文档索引(必读/实现参考/调研存档/历史存档四分类)
- VR_GOODS_CONFIG_SPEC.md: 加 Markdown TOC
- DEVELOPMENT_LOG.md: 追加第十三章(模板渲染修复 + v3.0 格式确认)
2026-04-20 09:25:01 +08:00
Council 741f25451c docs: v3.0 最终规格 - template_snapshot 字段 + selected_sections 对象格式
核心变更:
- 新增 template_snapshot 字段(发布时从 vr_seat_templates 读取并存储)
- selected_sections 确认为对象格式 { room_id: ["A","B"] }
- spec_base_id_map 使用 goods_spec_base.extends 动态构建
- 现有前端编辑体验完全不受影响
- Issue #13 已同步更新
2026-04-20 09:04:23 +08:00
Council 6daa332323 docs: v3.0 vr_goods_config spec + Phase2 plan v3.0
v3.0 核心变更:
- selected_sections 改为数组格式 [A,B]
- spec_base_id_map 使用 goods_spec_base.extends 动态构建
- seat_key 格式: roomId_rowLabel_colNum(无 MD5)
- 完整规格文档: docs/VR_GOODS_CONFIG_SPEC.md
2026-04-20 08:30:00 +08:00
Council 977cc57aef docs: new vr_goods_config spec + Phase 2 v2.0 plan 2026-04-20 07:24:57 +08:00
Council 1b0ac3276d fix: 替换为票务专用精简 footer
移除 ShopXO 默认导航(关于我们/招聘/客户服务等)
保留:返回首页 + 版权 + ICP备案
2026-04-20 06:35:24 +08:00