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
1b0ac3276d
fix: 替换为票务专用精简 footer
...
移除 ShopXO 默认导航(关于我们/招聘/客户服务等)
保留:返回首页 + 版权 + ICP备案
2026-04-20 06:35:24 +08:00
Council
c894e70188
fix: 复制 ShopXO public 模板 + 修复 footer_page 不存在问题
...
- 将 ShopXO 默认主题 public/ 目录完整复制到插件 goods/public/
- ticket_detail.html 中 footer_page → footer(footer_page.html 不存在于 ShopXO)
- ModuleInclude() 现在可以正确解析:view_path(goods/) + public/header.html ✅
2026-04-20 06:29:37 +08:00
Council
349ec063c1
fix: 替换 ThinkTemplate 标签为 PHP ModuleInclude
...
路线 B:票务模板不依赖 ThinkTemplate 解析引擎
- {include file=...} → <?php echo ModuleInclude(...) ?>
- {:Config()} / {:IsMobileLogin()} → <?php echo Config() ?> / <?php echo IsMobileLogin() ?>
- {$var|default=...} → <?php echo $var ?? 'default' ?>
- {$var|json_encode|raw} → <?php echo json_encode($var ?? []) ?>
绕过 ThinkTemplate parseTemplateFile() 路径拼接 bug(Linux view_depr=/ 导致 include 路径解析错误)
2026-04-20 06:23:29 +08:00
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
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
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
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
098bcfe780
fix(P0): P0-1 idempotent ticket issuance, P0-3 XSS, P0-4 QR secret exception
...
P0-1: issueTicket() now checks for existing tickets by (order_id, spec_base_id)
before inserting. Prevents duplicate tickets on HTTP retry/multi-instance.
P0-3: Removed |raw from simple_desc and content in ticket_detail.html.
Prevents stored XSS via malicious admin content injection.
P0-4: getQrSecret() now throws exception if VR_TICKET_QR_SECRET is unset,
instead of falling back to insecure default key.
2026-04-15 16:59:22 +08:00
Council
1afd547444
feat: import ShopXO v6.8.0 sourcecode (vendor/runtime excluded)
...
- ShopXO core + plugins/vr_ticket
- Goods.php item_type=ticket routing (Phase 1)
- vr_ticket plugin skeleton (Phase 0/1)
- Admin auth Base controller (Phase 2)
- All Phase 0/1/2 code included
Closes: tracks all ShopXO core modifications in monorepo
2026-04-15 13:09:44 +08:00