Commit Graph

264 Commits (main)

Author SHA1 Message Date
Council 9603ab42f6 refactor(vr_ticket): Admin.php root pattern → Hook-based goods save
- DELETE old Admin.php root controller (Vrticket.php)
- DELETE old Layui view files (seat_template/ticket/venue/verification/verifier)
- ADD hook/AdminGoodsSave.php: plugins_view_admin_goods_save hook (Vue3 form injection)
- ADD hook/AdminGoodsSaveHandle.php: handle save flow (save_handle + save_thing_end)
- UPDATE config.json: register 3 new hooks
- UPDATE SeatSkuService.php: refactored BatchGenerate
- ADD data.db: SQLite venue data
- UPDATE venue/save.html: venue editing form
- docs: add GOODS_ADD_HOOK_RESEARCH.md + update plan.md
2026-04-19 05:46:37 +08:00
Council 111063d785 docs: add 13_GOODS_ADD_HOOK_RESEARCH.md - goods add hook survey
- Code-verified: vr_seat_templates full field list + seat_map v3 JSON structure
- Confirmed: no goods_save hook exists yet, no vr_goods_config table
- Critical bug found: SeatSkuService.php has corrupted \t\think\xacade strings (P0 fix)
- Two-hook design: plugins_view_admin_goods_save + plugins_service_goods_save_handle
- goods.vr_goods_config JSON field (no new table needed)
- BatchGenerate extension: room/section filtering
2026-04-17 21:49:21 +08:00
Council 207f49839b docs: add 12_UNIAPP_FRONTEND_RESEARCH.md - shopxo-uniapp frontend architecture survey
- ShopXO DIY designer limitations (cannot import custom Vue components)
- shopxo-diy vs shopxo-uniapp architecture relationship
- Recommended path: fork shopxo-uniapp, modify Vue source directly
- H5/mini-program CSS consistency via rpx + uni-app WebView
- Full evidence archive and pending deep-dive items for 美在
2026-04-17 13:54:13 +08:00
Council 2452fde466 refactor(vr_ticket): full plugin restructure - Admin.php root pattern + Hook.php
Phase 2 completion - complete backend management rebuild:

Plugin architecture change (旧 → 新):
- 删: admin/controller/ 子目录多控制器 → 留: admin/Admin.php 单控制器
- 删: admin/view/ → 留: view/{module}/
- 删: EventListener.php, app.php, plugin.json → 留: Hook.php, config.json

New files:
- Hook.php: 插件钩子入口(侧边栏菜单 + 订单支付处理)
- config.json: 插件配置(is_enable 等)
- install.sql / uninstall.sql: 安装卸载脚本
- view/venue/list.html, save.html: 场馆管理视图(AmazeUI)
- view/admin/setup.html: 插件设置页

Modified files:
- service/AuditService.php, BaseService.php, SeatSkuService.php, TicketService.php
- admin/Admin.php: 全新 Admin.php 根目录控制器

ShopXO core changes:
- app/index/controller/Goods.php: ticket 类型商品详情页路由
- app/service/AdminPowerService.php: 权限系统适配
- config/shopxo.php: 配置

AmazeUI frontend migration:
- All views migrated from LayUI to AmazeUI
- Vue 3 editor for venue/seat configuration
- CDN: unpkg.com → cdn.staticfile.net

Fixes included:
- Infinite loading (missing footer include)
- Vue3 textarea interpolation bug
- Template path resolution (../../../plugins/...)
- Hook return fields (id/url/is_show)
- DB field names verified from source
2026-04-17 00:46:00 +08:00
Council e7730170f3 docs: add EXPERIENCES.md - 16 critical lessons from refactoring session
- docs/EXPERIENCES.md: Cleaned experience document with P0/P1/P2 classification
  - P0: footer missing → infinite loading, Vue3 textarea interpolation, field names from source
  - P1: plugin view paths, Hook.php return fields, CDN blocking, PHP comment pollution
  - P2: AmazeUI classes, Base64 URL encoding, search field consistency
- README.md: Add prominent link in top section + update project status
- docs/refactoring_learnings.md: Granular 24-round extraction from raw log
2026-04-17 00:43:34 +08:00
Council f6bcad6bfb fix: 表名前缀修复 + 创建缺失的audit_log表
- BaseService::table() 从 'plugins_vr_' 改为 'vr_'
  (原名 plugins_vr_seat_templates → ShopXO前缀后变成 vrt_plugins_vr_seat_templates,实际表名是 vrt_vr_seat_templates)
- Admin.php 所有硬编码 Db::name('plugins_vr_xxx') 改为 Db::name('vr_xxx')
- 在数据库创建缺失的 vrt_vr_audit_log 表
2026-04-16 17:23:40 +08:00
Council e9480b6866 docs: add VR plugin refactor briefing 2026-04-16 16:10:37 +08:00
Council 28103e7d9b docs: 补充自定义侧边栏快速入口机制说明 2026-04-16 15:59:37 +08:00
Council 4593c96119 docs: 更新部署配置(admin文件名/数据库名/源码路径/表前缀) 2026-04-16 15:50:55 +08:00
Council 35c10a7f66 council(security): SecurityEngineer - add missing VenueList methods + security audit
Security findings:
- SQL injection: LOW (query builder + parameter binding)
- XSS: LOW (ThinkPHP auto-escape, no |raw detected)
- Path traversal: LOW (all view paths hardcoded)
- CSRF: MEDIUM (ShopXO framework-level gap, out of scope for plugin)

Critical fix: admin/Admin.php was missing VenueList(), VenueSave(),
VenueDelete() — sidebar URL "/plugins/vr_ticket/admin/venueList" would
return 500 error. Added all three methods with v3.0 seat_map support.

P1 garbled name: documented DB fix SQL for shx_plugins + vrt_power tables.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:53:41 +08:00
Council 000a0990e7 council(round3): merge main (BackendArchitect Phase 2 fixes) + FrontendDev Admin.php routing
BackendArchitect 贡献:
- Vrticket.php (app/admin/controller/) - 独立后台控制器
- 视图复制到 app/admin/view/default/plugins/view/vr_ticket/admin/view/
- admin/controller/Plugins.php - 插件路由入口
- admin/controller/Venue.php + view/venue/ - 场馆管理
- app.php - 插件主文件

FrontendDev 贡献(本次):
- admin/Admin.php - 统一入口控制器(admin/ 子目录模式)
- plugin.json - sidebar URL 改为 camelCase 格式匹配 ucfirst()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:35:26 +08:00
Council b41e268a77 council(round3): FrontendDev - fix admin/Admin.php routing + camelCase sidebar URLs
路由分析结论:
- PluginsService::PluginsControlCall 使用 ucfirst() 转换类名
- sidebar URL /plugins/vr_ticket/admin/seatTemplateList
- → class=\app\plugins\vr_ticket\admin\Admin, method=SeatTemplateList()
- admin/Admin.php 方法名使用 camelCase 与 URL 匹配

修改内容:
- admin/Admin.php: 更新注释,方法名已使用 camelCase ✓
- plugin.json: sidebar URL 从 snake_case 改为 camelCase 格式

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:34:50 +08:00
Council 06a22c6a18 council(plan): FrontendDev - Phase 2 bugfix plan: routing + encoding issues
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:11:57 +08:00
Council d75eaa80a1 council(draft): SecurityEngineer - create plan.md for Phase 2 security audit
Analyzes two critical issues:
1. Sidebar garbled text (UTF-8/Latin1 encoding corruption in vrt_power/plugins tables)
2. Plugin controller routing failure (wrong directory structure vs freightfee Admin.php pattern)

Proposes root cause hypotheses and step-by-step investigation + fix plan.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:11:43 +08:00
Council 5749edf6ad fix(Phase 2): 修复后台路由+视图路径,Vrticket控制器上线
- 新增 Vrticket.php(ThinkPHP小写路由约定,类名Vrticket)
- 修复视图标签:{include} → {{include}}(ShopXO使用{{}}分隔符)
- 视图文件同步到 app/admin/view/default/plugins/view/vr_ticket/
- 插件控制器类名 Seattemplate(ThinkPHP路由适配)
- plugin.json 新增场馆配置菜单项
- 删除废弃的 plugins/index.html 符号链接
- 自动载入:app.php 注册 app\plugins\ 命名空间映射
2026-04-16 07:59:27 +08:00
Council f1f061a8d7 docs: Phase 3-1 测试数据迁移完成(vr_seat_templates id=1 → v3.0 格式) 2026-04-15 22:16:42 +08:00
Council 9d8992ff41 docs: Phase 3-1 checklist 更新(Venue.php / list.html / save.html 已完成) 2026-04-15 22:06:42 +08:00
Council 49e256a9ab feat(Phase 3-1): Vue3 交互式场馆配置表单编辑器 save.html
- admin/view/venue/save.html:Vue3 CDN 嵌入
  - 实时彩色座位预览(每格 30x30px,背景色=zone.color,悬浮显示座位号/分区/价格)
  - 动态增删分区(char/name/price/color + 预设色板)
  - 每排座位行编辑器(动态 input)
  - 双向同步:改 zone char/color → 预览即时刷新
  - 初始默认值:3 区(VIP区/看台区/普通区),6座/排
  - mounted() 回填:zones_json / map_json / venue_json
  - computed 序列化:zonesJson / seatMapRowsJson / venueJson → 隐藏字段

- Venue.php 补充:新增 venue_json 字段供 Vue3 回填
  - venue_json = {name, address, image}

关联:docs/11_EDITOR_AND_INJECTION_DESIGN.md v3.0
2026-04-15 22:06:21 +08:00
Council 136efb9b92 feat(Phase 3-1): Venue.php CRUD + list.html + BatchGenerate venue.name 动态读取
- 新增 admin/controller/Venue.php:场馆配置 CRUD
  - list(): 解析 seat_map.venue.name 展示,zone_count / seat_count
  - save(): 构建 v3.0 seat_map JSON(venue + map + seats + sections)
  - delete(): 软删除 + 审计日志
  - preview(): 调试接口,返回 seat_map JSON + seat_count

- 新增 admin/view/venue/list.html:场馆列表页

- 改造 SeatSkuService.php BatchGenerate:
  - ensureVrSpecTypes() 增加 $venueName 参数
  - $vr-场馆 spec 值从 seat_map.venue.name 读取,不再硬编码
  - 降级:取模板 name 或 '未命名场馆'

关联:docs/11_EDITOR_AND_INJECTION_DESIGN.md v3.0
2026-04-15 22:02:03 +08:00
Council cd5160793d docs(v3): 大头确认3决策+v3.0更新:venue入seat_map/BatchGenerate按分区过滤/vr_ticket_config新增+美化JSON示例 2026-04-15 21:49:07 +08:00
Council 219b35aded docs(v2): PM Auditor 核查修正 — 10处关键错误,含seat_map字段名/钩子注册格式/BatchGenerate签名/表前缀等 2026-04-15 21:39:56 +08:00
Council b44f2232db docs: 追加完整状态流转图+时序图(商户发布流程/用户下单流程/编辑解析方案) 2026-04-15 21:22:22 +08:00
Council 7dd288a4dc docs: 后台编辑器+商品发布注入完整方案设计(Phase 3 详细规划) 2026-04-15 21:15:45 +08:00
Council 6571967c23 council(finalize): FrontendDev - Complete Q1 editor research + final recommendation
Q1 Findings:
- ShopXO DIY editor is commercial closed-source (no readable source in repo)
- Nested depth is 3 levels (not 4) — venue > seat_map > seats/sections
- Vue3 form visual editor: ~500 lines, 1-1.5 person-days
- JSON single-table is 50%+ cheaper than split-table approach
- Final recommendation: hook injection + form visual editor

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:54:18 +08:00
Council 58fc579822 council(round2): BackendArchitect - Update plan.md: Q2 Done, Round 2 findings
- Q2 marked as Done: plugins_view_admin_goods_save is injection not replacement
- Save() accepts standard POST; hook injection + JSON editor recommended
- Added BackendArchitect Round 2 findings section
- Final report blocked on FrontendDev Q1 completion

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:49:45 +08:00
Council f55ba36e7b council(draft): BackendArchitect - Q2 editor research findings
Plugins_view_admin_goods_save is an injection point, not a replacement point.
Save() accepts standard POST. Hook can intercept save flow.
Final recommendation: hook injection + JSON editor.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:45:09 +08:00
Council 283076f5f2 council(merge): FrontendDev - Round 1 plan (accept FrontendDev editor research plan) 2026-04-15 20:40:56 +08:00
Council c01e14ee70 council(plan): FrontendDev - Round 1 plan for editor solution research
Q1: JSON editor complexity assessment + ShopXO DIY components
Q2: BackendArchitect investigates page replacement feasibility
Final output: council-output/EDITOR_RESEARCH.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:40:39 +08:00
Council 4e5fda72a2 council(draft): BackendArchitect - plan for editor research Q2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:40:03 +08:00
Council d411073885 council(fix): BackendArchitect - Fix regex bug in getExistingSpecBaseIds()
Bug: regex '^([A-Za-z]+)(\d+)排(\d)座$' with $m[3] misparsed seat labels
like "A排10座" → colNum=1 (wrong). Fixed to '^([A-Za-z]+)排(\d+)座$' with $m[2].

Also clarified spec_base_id_map docblock: frontend expects flat integer,
not nested object.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:16:49 +08:00
Council f003606ee6 council(finalize): BackendArchitect - Add review result to plan.md
Verdict: [APPROVE] on FrontendDev P1 submit() refactor.
All P0/P1 code on main. Pending: container verification + FrontendDev consensus.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:12:42 +08:00
Council 1a2b028822 Merge branch 'council/BackendArchitect' into main
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:12:20 +08:00
Council bcd7954cf8 council(review): BackendArchitect - Review FrontendDev P1 submit() refactor
[PASS] Interface contract: specBaseIdMap['A_1'] = int ✓
[PASS] goods_params: stock=1, seat-level spec_base_id ✓
[PASS] Fallback strategy for Plan B transition ✓
[PASS] Seat label format matches backend regex ✓
[PASS] Price sources align between frontend and backend ✓

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:12:17 +08:00
Council 5b80e775bb council(review): BackendArchitect - Review FrontendDev P1 submit() refactor
[PASS] Interface contract: specBaseIdMap['A_1'] = int ✓
[PASS] goods_params: stock=1, seat-level spec_base_id ✓
[PASS] Fallback strategy for Plan B transition ✓
[PASS] Seat label format matches backend regex ✓
[PASS] Price sources align between frontend and backend ✓

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:12:12 +08:00
Council a0690fdd58 Merge branch 'council/BackendArchitect' into main
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:10:28 +08:00
Council e4703b6fb4 council(finalize): BackendArchitect - Update plan.md: all P0/P1 done, merge complete
Commit 96337bc84 merged all bug fixes to main.
Next steps: container verification on ShopXO.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:10:24 +08:00
Council 96337bc840 council(execute): BackendArchitect - Fix 2 bugs in P0-A/B/P1 implementations
Bug 1: SeatSkuService.php:381 - regex has syntax error
  '/^([A-Za-z]+)(\d+)排(\d+)座$/' → '/^([A-Za-z]+)(\d+)排(\d)座$/'
  The third capture group only needs single digit (col number 1-9).

Bug 2: ticket_detail.html:416 - frontend accesses specBaseIdMap as object
  but PHP returns flat integer: specBaseIdMap['A_1'] = 2001 (int), not {spec_base_id: 2001}.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:09:22 +08:00
Council d7d7b33c96 council(review): BackendArchitect - Fix 2 bugs in P0-A/B/P1 implementations
1. SeatSkuService: Fix regex in getExistingSpecBaseIds()
   (\d+)排(\d+)座 → (\d+)排(\d)座
   The original regex incorrectly captures 2 digit groups in "A排10座",
   causing seatId parse failure for column >= 10.

2. ticket_detail.html: Fix specBaseIdMap access in submit()
   (obj||{}).spec_base_id → direct numeric value
   PHP returns integers (not objects), so drop the .spec_base_id accessor.

关联:Issue #9

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:05:08 +08:00
Council f76a9d5462 council(merge): merge BackendArchitect P0 into FrontendDev worktree 2026-04-15 20:04:36 +08:00
Council 5e9c111370 council(draft): BackendArchitect - P0-A initGoodsSpecs + P0-B BatchGenerate
P0-A: BaseService::initGoodsSpecs() — 启用 is_exist_many_spec=1,
      插入 $vr-场馆/$vr-分区/$vr-时段/$vr-座位号 四维规格类型,幂等保护

P0-B: 新建 SeatSkuService.php,含:
      - BatchGenerate(): 批量生成座位级 SKU(500条/批,直接 SQL INSERT)
      - UpdateSessionSku(): 按场次更新 $vr-时段 维度
      - 幂等:已存在座位不重复生成

关联:Issue #9

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 20:00:29 +08:00
Council 93b70d4d50 council(execute): FrontendDev - Issue #9 P1 submit() refactor (seat-level goods_params)
- renderSeatMap(): add data-row-label + data-col-num attrs for specBaseIdMap key format
- toggleSeat(): change seatKey from "0_0" (numeric) to "A_1" (label_colNum) to match specBaseIdMap
- removeSeat(): use [data-row-label][data-col-num] selector
- submit(): refactor from 1 goods_params (zone-level) to N entries (seat-level, stock=1)
- Plan B fallback: if specBaseIdMap[key] missing, use sessionSpecId

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 19:56:25 +08:00
Council a2fb70d216 council(merge): resolve conflict — adopt execution plan (Round 1 P0 fix)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 19:52:54 +08:00
Council 22afafa1e1 council(draft): BackendArchitect - Round 1 execution plan: P0-A/B + P1 tasks
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 19:52:21 +08:00
Council b4a94f832a Merge branch 'council/FrontendDev' 2026-04-15 19:52:08 +08:00
Council 1d7f600675 council(round4): FrontendDev - Issue #9 execution plan (P0/P1 task breakdown)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 19:52:03 +08:00
Council a3ef16034e docs: 甲方新需求文档(多座位单订单/核销码卡夹/ext必填字段/手机号订单级) 2026-04-15 19:40:44 +08:00
Council 78b699eab4 council(merge): FrontendDev - Round 3 final decision (方案A)
Round 3 合并:
- council-output/ARCHITECTURE_DECISION.md: 汇总 Q1-Q4 三方分析 + 最终推荐
- plan.md v1.2: 全部 Q1-Q4 完成标记,consensus=YES

最终推荐: 方案A (每个座位一个ShopXO SKU)
- Q1: 直接 SQL INSERT 批量生成(旁路 GoodsSpecificationsInsert)
- Q2: 最小修复集 (UPDATE is_exist_many_spec + INSERT $vr- spec_type)
- Q3: $vr- 前缀低风险(ThinkPHP {$var} 默认转义)
- Q4: 三方一致推荐方案A

全票通过。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 19:29:08 +08:00
Council e5814c3bd4 council(merge): resolve conflicts — accept BackendArchitect final versions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 19:27:21 +08:00
Council 62553ab9f7 council(finalize): plan.md update — all tasks done, Plan A unanimous
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 19:27:05 +08:00
Council 0eb8adbf71 council(finalize): Issue #9 final ARCHITECTURE_DECISION.md — Plan A adopted unanimously
- Q1: Batch SKU via direct SQL INSERT (bypass GoodsSpecificationsInsert)
- Q2: Minimal fix (UPDATE is_exist_many_spec + INSERT \$vr- spec_type + idempotency)
- Q3: \$vr- prefix LOW risk confirmed
- Q4: All 3 members recommend Plan A (one SKU per seat)
- Action items assigned: P0 BatchGenerate, P0 Q2 fix, P1 idempotency, P2 isolation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 19:26:45 +08:00