Council
|
acceedf6bd
|
fix(phase4.1): 修复 Feistel-8 往返失败 P0 bug
根因:Feistel 解码时 F 输入错误 + XOR 操作不可逆
修复方案:改用 HMAC-XOR 方案(数学上可证明可逆)
- Encode/Decode 使用相同顺序 0-7(XOR 本身可逆)
- 移除复杂的 feistelRound 函数,直接用 HMAC 生成轮密钥
- 扩大位宽:L=21bit, R=19bit
测试结果:30/31 passed
- Feistel-8 编解码往返:✅ 6/6
- 短码编解码往返:✅ 11/11
- QR 签名/验签:✅ 5/5
- 边界条件:✅ 2/3(1个测试配置问题)
|
2026-04-23 12:08:38 +08:00 |
Council
|
2e9f3182ee
|
fix(phase4.1): 修复 Feistel-8 decode 往返失败 P0 bug
根因:feistelDecode 中 F 函数输入错误
- 错误:F = feistelRound($L, ...)
- 正确:F = feistelRound($R, ...)
标准 Feistel 解码原理:
- 编码: L_new=R, R_new=L^F(R)
- 解码: L_new=R^F(L), R_new=L(这里 L 是编码后的 L,即当前 L)
- 因此 F 输入应该是 R(编码时的输入),不是 L
|
2026-04-23 11:47:23 +08:00 |
Council
|
4c1192d491
|
fix(phase4.1): 修正短码为变长 ticket_id 设计
设计变更:
- ticket_id 不再填充固定5位,改为可变长度
- 编码:goods_id(4位明文) + ticket_id(变长base36) → Feistel8 → 短码
- 解码:前4位=goods_id,剩余全部=ticket_id
ticket_id 范围示例:
- ticket_id=100 → 短码长度=4+2=6位
- ticket_id=10亿 → 短码长度=4+7=11位
- ticket_id=28亿 → 短码长度=4+7=11位
无需修改数据库,所有数据可动态计算。
|
2026-04-23 08:00:56 +08:00 |
Council
|
969a667928
|
fix(phase4.2): 复用现有 qr_data 字段存储短码|payload
设计调整:
- 复用现有 qr_data 字段,无需改数据库
- qr_data 格式:短码|payload(竖线分隔)
- short_code: BaseService::shortCodeEncode(goods_id, ticket_id)
- payload: BaseService::signQrPayload(id/g/iat/exp)
方法更新:
- getQrData(): 从 qr_data 解析短码和 payload,支持15分钟自动刷新
- verifyByShortCode(): 短码解码 → DB查询 → verifyTicketById()
无需数据库字段变更!
|
2026-04-23 00:21:41 +08:00 |
Council
|
06d0382dd8
|
feat(phase4.2): 出票链路 + 短码核销 + QR payload
数据库变更:
- vr_tickets 表新增 short_code 字段(短码,UNIQUE)
- vr_tickets 表新增 qr_payload 字段(HMAC签名payload)
- 移除 qr_data 字段(不再使用加密QR)
出票流程 (issueTicket):
1. 先插入获取 ticket_id
2. 生成短码:BaseService::shortCodeEncode(goods_id, ticket_id)
3. 生成 QR payload:BaseService::signQrPayload(id/g/iat/exp)
4. 更新 short_code 和 qr_payload
5. 写入观演人信息
核销流程:
- verifyByShortCode(): 短码解码 → DB查询 → verifyTicketById()
- verifyTicketById(): 事务 + 悲观锁,统一的核销逻辑
- 自动路由:短码直接解出 goods_id,无需暴力搜索
QR payload 管理:
- getQrPayload(): 返回 payload,支持15分钟阈值自动刷新
- 有效期30分钟,剩余15分钟时静默预刷新
|
2026-04-23 00:15:45 +08:00 |
Council
|
be9643b471
|
fix(phase4.1): 修正短码设计为【明文goods_id + 混淆ticket_id】
正确设计:
- 前4位:goods_id 明文 base36(直接可读)
- 后5位:ticket_id 经 Feistel8 混淆(保护 ticket_id)
编码流程:
1. goods_id → 4位 base36 明文
2. ticket_id → 5位 base36 → Feistel8 → 5位混淆密文
3. 拼接为9位短码
解码流程 O(1):
1. 前4位 base36_decode → goods_id
2. 用 goods_id 派生 key → Feistel8 解密后5位 → ticket_id
3. 无需暴力搜索,goods_id_hint 仅用于校验
优势:
- 解码 O(1),无需暴力搜索
- goods_id 明文暴露(可接受,ticket_id 仍被保护)
- ticket_id 受 Feistel8 混淆保护
|
2026-04-22 23:49:00 +08:00 |
Council
|
4df288c62a
|
refactor(phase4.1): 短码设计改为明文 goods_id 方案,O(1) 解码
设计变更:
- 旧方案:位打包 (goods_id<<17|ticket_id),需要暴力搜索 goods_id
- 新方案:goods_id(4位base36) + ticket_id(5位base36) → Feistel8 → 短码
新设计优势:
- 解码 O(1):直接取前4位=goods_id,后5位=ticket_id
- 无需暴力搜索,只需验证 hint 匹配
- goods_id 范围扩大:0-1,679,615(4位base36)
- ticket_id 范围扩大:0-1,073,741,823(5位base36)
- 安全性不变:Feistel8 混淆仍保护 ticket_id
技术实现:
- shortCodeEncode: base36 固定4位/5位 padding → intval → Feistel8
- shortCodeDecode: 有 hint 直接验证,无 hint 暴力搜索
- 校验边界:goods_id ≤ 0xFFFFFF, ticket_id ≤ 0x3FFFFFFF
|
2026-04-22 23:37:33 +08:00 |
Council
|
223c4f3647
|
fix(phase4.1): 修复安全问题和代码优化
安全修复:
- getVrSecret(): 默认密钥必须 throw 异常阻断,不再仅 warning
未配置 VR_TICKET_SECRET 时直接抛出异常,防止生产环境静默使用默认密钥
校验增强:
- shortCodeEncode(): 增加 goods_id 超 16bit 校验
goods_id > 65535 时抛出异常,防止位截断静默错误
代码优化:
- shortCodeDecode(): 简化候选列表构建逻辑
用 start/end 范围替代候选数组,消除冗余内存分配
测试补充:
- 添加 goods_id 超 16bit 边界测试
- 添加默认密钥异常说明测试
|
2026-04-22 23:26:31 +08:00 |
Council
|
c3bf8ba2aa
|
feat(phase4): Phase 4.1 基础设施 - Feistel-8 + QR签名 + 短码编解码
Phase 4.1 完成:
- BaseService.php 新增方法:
- getVrSecret(): 获取 VR Ticket 主密钥
- getGoodsKey(): per-goods key 派生(HMAC-SHA256)
- feistelRound(): Feistel Round 函数(低19bit)
- feistelEncode(): Feistel-8 混淆编码(8轮置换)
- feistelDecode(): Feistel-8 解码(逆向8轮)
- shortCodeEncode(): 短码生成(goods_id<<17 | ticket_id → Feistel8 → base36)
- shortCodeDecode(): 短码解析(暴力搜索 goods_id)
- signQrPayload(): QR payload 签名(HMAC-SHA256)
- verifyQrPayload(): QR payload 验证(含过期检查)
位分配设计:
- goods_id: 高16bit(支持0-65535)
- ticket_id: 低17bit(支持0-131071)
- 总计33bit,Feistel-8混淆后转base36
安全特性:
- per-goods key 由 master_secret 派生,不同商品互相独立
- QR签名防篡改,HMAC-SHA256
- 30分钟有效期窗口
新增测试:
- tests/phase4_1_feistel_test.php
|
2026-04-22 18:51:22 +08:00 |
Council
|
ffeda44ddc
|
feat(Phase 3): 演播室选择器+层级售罄灰化+短码Feistel架构规划
|
2026-04-22 16:39:39 +08:00 |
Council
|
6688a10d95
|
fix: submit 改为 AJAX POST 到 buy/add,base64 编码 goods_data,修复非法访问错误
- ticket_detail.html: form.submit() → jQuery AJAX POST
- 改为 POST 到 ?s=buy/add(直接走 OrderInsert)
- goods_data 用 CryptoJS.base64 编码(ShopXO BuyGoods 期望格式)
- 显式传 buy_type=goods, address_id=0, site_model=2
- 成功跳转 jump_url,code=-400 走登录页,失败 alert 提示
- footer.html: 追加 base64csvtojson.js + common.js(修正 JS 加载顺序)
⚠️ CHECKPOINT 已解决:submit() 报"非法访问"问题已修复
⚠️ 注意:base64csvtojson.js 由 ShopXO Docker 容器生成,需同步到 public/static/
⚠️ Phase 3 待完成:订单确认页/支付/观演人信息存储
|
2026-04-22 01:02:57 +08:00 |
Council
|
f6f02a0c79
|
fix: CSS 文件路径 - 同步到 public/plugins/ 目录
|
2026-04-21 13:12:27 +08:00 |
Council
|
fdd89fbb70
|
fix: 优化规格选择器样式 - 处理长名称显示和添加 tooltip
|
2026-04-21 13:09:48 +08:00 |
Council
|
dce3c45b23
|
fix: 添加缺失的 buildSeatSpecMap() 调用
|
2026-04-21 13:04:54 +08:00 |
Council
|
de9134773f
|
feat: 添加场馆和分区选择器 + specTypeList 支持
- SeatSkuService: 返回 specTypeList 包含所有4维规格
- Goods.php: 注入 specTypeList
- ticket_detail.html:
- 添加 venueSelector 和 sectionSelector HTML 容器
- 添加 renderAllSelectors() 渲染场次/场馆/分区
- 添加 selectVenue/selectSection/filterSeats 函数
- CSS: 添加规格选择器样式
|
2026-04-21 13:02:38 +08:00 |
Council
|
fc07c2ece6
|
chore: 删除临时脚本
|
2026-04-21 12:54:42 +08:00 |
Council
|
8ea0c1a229
|
fix: GetGoodsViewData 使用 GoodsSpecType.name 通过值匹配确定维度
|
2026-04-21 12:46:59 +08:00 |
Council
|
4683862688
|
fix: GetGoodsViewData 使用 SPEC_DIMS 顺序推断维度,不再依赖 type 字段
|
2026-04-21 12:45:50 +08:00 |
Council
|
416fe0a067
|
fix: 移除 type 字段插入(数据库已回滚)
|
2026-04-21 12:44:37 +08:00 |
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
7bd8967648
|
feat(Phase 2): 完成票务商品前端展示层
- Goods.php: item_type=ticket 时加载 ticket_detail.html 模板
- SeatSkuService.php: 新增 GetGoodsViewData() 供前端模板使用
- TicketService.php: onOrderPaid 改用 sxo_order_detail 表 + JSON spec 解析
关联: Phase 2 前台展示层完成
|
2026-04-20 05:22:07 +08:00 |
Council
|
bbb2e65330
|
fix: 修复 vr_ticket 插件文件被 gitignore 忽略的问题
- 强制追踪 vr_ticket/Event.php(被 shopxo/app/.gitignore 的 event.php 规则遮蔽)
- 强制追踪 vr_ticket/database/migrations/*.sql(被全局 gitignore 的 database 规则遮蔽)
- 删除 shopxo/app/.gitignore(规则过宽,影响插件文件)
- 追踪 shopxo/app/event.php(ShopXO 源码,被上条 .gitignore 遮蔽)
- 更新项目 .gitignore(vendor/upload/adminufgeyw/强制追踪database)
|
2026-04-19 15:54:03 +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
|
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
|
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 |