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
b4078d1cfc
docs: Phase 4 plan - 发票·核销·票夹(QR签名+Feistel短码+出票链路)
2026-04-22 17:58:39 +08:00
Council
ffeda44ddc
feat(Phase 3): 演播室选择器+层级售罄灰化+短码Feistel架构规划
2026-04-22 16:39:39 +08:00
Council
de7c25c6b9
docs: Phase 3 P0 - 5维Spec重构文档(演播室层补全)
2026-04-22 01:36:39 +08:00
Council
8c38484c58
Merge origin/main into fix/venue-hard-delete-p0 (resolve plan.md + reviews conflict with origin/main)
2026-04-22 01:06:11 +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
a97e5fd0d3
docs: 添加 AntiGravity 会话报告 SESSION_REPORT_20260421_PHASE2_FIX.md
...
记录 AntiGravity 在 2026-04-21 的完整工作:
- 移除 GoodsSpecValue.type 字段,改为通过值匹配确定维度
- buildSeatSpecMap() 按值匹配重建 seatSpecMap
- GetGoodsViewData() 返回 specTypeList(4维规格类型列表)
- 前端新增场馆/分区选择器 + filterSeats() 联动过滤
- CSS 同步到 public/plugins/ 目录
⚠️ CHECKPOINT - 存在已知问题:
- submit() POST 到 Buy::Index 报'非法访问'(疑似登录/CSRF 拦截)
- 扩展字段(观演人信息)存储方案待确认
- Phase 3 前需修复并合并回 main
2026-04-21 14:25:31 +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
c4a35ca258
chore: 删除不再需要的 SQL 修复文件
2026-04-21 12:54:37 +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
c134351c82
fix: 修复 spec 选择区 + GoodsSpecType encoding
...
- 清理重复的 GoodsSpecType 记录
- 重新生成正确的 GoodsSpecType 数据(场次信息)
2026-04-21 12:32:16 +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
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
671b0359ad
council(finalize): BackendArchitect - merge report + resolve plan.md conflict, all tasks done
2026-04-20 19:21:04 +08:00
Council
ccf0fbb309
council(review): BackendArchitect - ghost spec root cause analysis report
2026-04-20 19:18:08 +08:00
Council
11fdf0309f
Merge branch 'council/FrontendDev' into main
...
council(review): FrontendDev - ghost spec research report with verified findings
- All 7 FrontendDev tasks completed and verified against actual code
- Summary updated with correct file references and commit hashes
- Conflicting plan.md resolved: keep FrontendDev version
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 19:16:18 +08:00
Council
cba9c64eb9
council(draft): BackendArchitect - merge fix branch, resolve conflict, all tasks complete
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 19:16:11 +08:00
Council
c9105f7eb3
council(review): FrontendDev - fix summary file references and verified research
...
- Remove non-existent SecurityEngineer report file references
- Fix commit hashes to match actual fix/venue-hard-delete-p0 history
- Add BackendArchitect-on-FrontendDev-P1.md to index
- Verify all findings against actual code (AdminGoodsSaveHandle.php,
SeatSkuService.php, ticket_detail.html)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 19:15:47 +08:00
Council
1803262bbd
council(finalize): SecurityEngineer - mark all tasks complete in plan.md
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 19:15:41 +08:00
Council
d52bf31b55
council(finalize): SecurityEngineer - resolve plan.md merge conflict, finalize ghost spec summary
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 19:14:57 +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
ff30e79d0b
council(review): SecurityEngineer - ghost spec security audit + summary
...
Security audit findings:
- 0 P1 vulnerabilities found
- 3 P2 issues: error messages, DB auto-modification, sold seats detection
- 1 P3 issue: field size limit
Reports:
- reviews/SecurityEngineer-GHOST_SPEC_SECURITY.md
- reviews/council-ghost-spec-summary.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 19:06:29 +08:00
Council
dbacd36230
council(review): FrontendDev - ghost spec research report
...
- ticket_detail.html is customer-facing (not admin edit page)
- "spec不允许重复" triggers in GoodsService.php, not in the frontend
- GetGoodsViewData() correctly clears template_id/snapshot on hard delete
- loadSoldSeats() is unimplemented (TODO only)
- BackendArchitect should evaluate removing stale config blocks on hard delete
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 19:05:32 +08:00
Council
f84f95b569
Merge branch 'council/FrontendDev'
2026-04-20 18:49:57 +08:00
Council
a96a3c00ba
council(draft): FrontendDev - update plan.md for ghost spec research
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 18:49:54 +08:00
Council
f441deaa61
Merge branch 'council/FrontendDev'
...
# Conflicts:
# plan.md
2026-04-20 18:49:13 +08:00
Council
f27a32dc3d
council(draft): FrontendDev - plan.md: ghost spec research Round 1
2026-04-20 18:48:09 +08:00
Council
795126cd55
council(draft): SecurityEngineer - resolve plan.md merge conflict, ghost spec audit
2026-04-20 18:47:55 +08:00
Council
aa6651e963
council(draft): BackendArchitect - create plan for ghost spec investigation
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 18:47:38 +08:00
Council
98dfbbd943
council(draft): SecurityEngineer - Round 1 plan for ghost spec security audit
2026-04-20 18:47:31 +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