diff --git a/plan.md b/plan.md index 3e87e7c..fd6f9ed 100644 --- a/plan.md +++ b/plan.md @@ -31,31 +31,31 @@ Phase 2 目标:完成后台管理页面开发,涵盖座位模板管理、电 ## 任务清单 ### 座位模板管理 -- [ ] 座位模板列表页(seat_template_list.html) -- [ ] 座位模板新增/编辑页(seat_template_save.html) +- [x] 座位模板列表页(seat_template/list.html)— 已完成 +- [x] 座位模板新增/编辑页(seat_template/save.html)— 已完成 - [ ] 座位图可视化编辑器集成 -- [ ] 分类绑定功能 +- [x] 分类绑定功能 — 已完成 ### 电子票管理 -- [ ] 电子票列表页(ticket_list.html) -- [ ] 票详情页(ticket_detail.html) -- [ ] 批量导出功能(CSV/Excel) -- [ ] 票状态筛选(未核销/已核销/已退款) +- [x] 电子票列表页(ticket/list.html)— 已完成 +- [x] 票详情页(ticket/detail.html)— 已完成 +- [x] 批量导出功能(CSV/Excel)— 已完成 +- [x] 票状态筛选(未核销/已核销/已退款)— 已完成 ### 核销员管理 -- [ ] 核销员列表页 -- [ ] 核销员新增/编辑/删除 +- [x] 核销员列表页(verifier/list.html)— 已完成 +- [x] 核销员新增/编辑/删除(verifier/save.html)— 已完成 - [ ] 核销员绑定店铺/场次 ### 核销记录 -- [ ] 核销记录列表页 -- [ ] 多条件查询(时间/核销员/场次) +- [x] 核销记录列表页(verification/list.html)— 已完成 +- [x] 多条件查询(时间/核销员/场次)— 已完成 - [ ] 核销统计看板 ### Admin 鉴权(P1 安全) -- [ ] 所有 Admin 控制器继承 Base controller -- [ ] 鉴权中间件验证 -- [ ] 敏感操作日志审计 +- [x] 所有 Admin 控制器继承 Base controller — 已完成(Base extends Common) +- [ ] 鉴权中间件验证 — `[Claimed: council/SecurityEngineer]` +- [ ] 敏感操作日志审计 — `[Pending]` ### 安全任务 - [ ] **Task S1** — 审查 ShopXO 后台鉴权机制,确认 Phase 2 Base 控制器鉴权覆盖完整性 `[Pending]` @@ -224,14 +224,37 @@ admin.php → http->name('admin') → Common::__construct() (获取$admin, $left ### 已认领任务 -- [ ] **Task B1** — 座位模板管理 CRUD — `[Claimed: council/BackendArchitect]` -- [ ] **Task B2** — 电子票列表/详情/导出 — `[Claimed: council/BackendArchitect]` -- [ ] **Task B3** — 核销员管理(增删改查)— `[Claimed: council/BackendArchitect]` -- [ ] **Task B4** — 核销记录查询 — `[Pending]` -- [ ] **Task B5** — Base 控制器鉴权修复 — `[Claimed: council/BackendArchitect]` +- [x] **Task B1** — 座位模板管理 CRUD — `[Done: council/BackendArchitect]` +- [x] **Task B2** — 电子票列表/详情/导出 — `[Done: council/BackendArchitect]` +- [x] **Task B3** — 核销员管理(增删改查)— `[Done: council/BackendArchitect]` +- [x] **Task B4** — 核销记录查询 — `[Done: council/BackendArchitect]` +- [x] **Task B5** — Base 控制器鉴权修复 — `[Done: council/BackendArchitect]` + +--- + +## Round 3 执行结果(BackendArchitect) + +### 本轮完成内容 + +| # | 文件 | 操作 | 说明 | +|---|------|------|------| +| 1 | `admin/view/verifier/list.html` | 新建 | 核销员列表页(Layui table + 搜索栏 + 编辑/禁用按钮) | +| 2 | `admin/view/verifier/save.html` | 新建 | 核销员新增/编辑页(用户选择 + 名称 + 状态) | +| 3 | `admin/view/ticket/detail.html` | 新建 | 票详情页(基本信息 + QR码 + 手动核销表单) | +| 4 | `admin/controller/Verifier.php` | 修复 | `column(CONCAT(...))` 语法错误 → 改为先 select 再 PHP 拼接 | +| 5 | `admin/controller/Ticket.php` | 修复 | `detail()` 补充 `verifiers` 变量传给 detail.html | + +### 遗留 P0/P1 阻塞(需 SecurityEngineer 处理) + +| # | 问题 | 严重度 | 备注 | +|---|------|--------|------| +| S1 | Admin 控制器鉴权覆盖完整性 | P0 | `[Pending: council/SecurityEngineer]` | +| S2 | SQL 注入风险审计 | P1 | `[Pending: council/SecurityEngineer]` | +| S3 | XSS / CSRF 防护检查 | P1 | `[Pending: council/SecurityEngineer]` | +| S5 | IDOR 越权测试 | P1 | `[Pending: council/SecurityEngineer]` | --- ## 共识投票 -[CONSENSUS: NO] — 本轮仅完成研究讨论,实际执行待后续阶段 +[CONSENSUS: NO] — 等待 SecurityEngineer 完成 Task S1~S5 后可结束 Phase 2 diff --git a/shopxo/app/plugins/vr_ticket/admin/controller/Ticket.php b/shopxo/app/plugins/vr_ticket/admin/controller/Ticket.php index 4bd766e..e8f2ec8 100644 --- a/shopxo/app/plugins/vr_ticket/admin/controller/Ticket.php +++ b/shopxo/app/plugins/vr_ticket/admin/controller/Ticket.php @@ -102,10 +102,17 @@ class Ticket extends Base // QR 码图片 $ticket['qr_code_url'] = \app\plugins\vr_ticket\service\TicketService::getQrCodeUrl($ticket['ticket_code']); + // 核销员列表(用于手动核销) + $verifiers = \Db::name('plugins_vr_verifiers') + ->where('status', 1) + ->order('id', 'asc') + ->select(); + return view('', [ - 'ticket' => $ticket, - 'goods' => $goods, - 'verifier' => $verifier, + 'ticket' => $ticket, + 'goods' => $goods, + 'verifier' => $verifier, + 'verifiers' => $verifiers, ]); } diff --git a/shopxo/app/plugins/vr_ticket/admin/controller/Verifier.php b/shopxo/app/plugins/vr_ticket/admin/controller/Verifier.php index 083adfc..210cca7 100644 --- a/shopxo/app/plugins/vr_ticket/admin/controller/Verifier.php +++ b/shopxo/app/plugins/vr_ticket/admin/controller/Verifier.php @@ -37,14 +37,20 @@ class Verifier extends Base ->paginate(20) ->toArray(); - // 关联 ShopXO 用户信息 + // 关联 ShopXO 用户信息(先查再 PHP 拼接,避免 column() 不支持 CONCAT 表达式) $user_ids = array_filter(array_column($list['data'], 'user_id')); if (!empty($user_ids)) { $users = \Db::name('User') ->where('id', 'in', $user_ids) - ->column('CONCAT(COALESCE(nickname,""), "/", COALESCE(username,""))', 'id'); + ->select(); + $user_map = []; + foreach ($users as $u) { + $nickname = $u['nickname'] ?? ''; + $username = $u['username'] ?? ''; + $user_map[$u['id']] = ($nickname ?: '') . ($username ? '/' . $username : ''); + } foreach ($list['data'] as &$item) { - $item['user_name'] = $users[$item['user_id']] ?? '已删除用户'; + $item['user_name'] = $user_map[$item['user_id']] ?? '已删除用户'; } unset($item); } diff --git a/shopxo/app/plugins/vr_ticket/admin/view/ticket/detail.html b/shopxo/app/plugins/vr_ticket/admin/view/ticket/detail.html new file mode 100644 index 0000000..30ee4d7 --- /dev/null +++ b/shopxo/app/plugins/vr_ticket/admin/view/ticket/detail.html @@ -0,0 +1,130 @@ + + + + + 票详情 - VR票务 + {include file="public/head" /} + + + +
+
+
+ 票详情 + + {{$ticket['verify_status']==1 ? '已核销' : ($ticket['verify_status']==2 ? '已退款' : '未核销')}} + + 返回 +
+
+ +
+
票码
+
{$ticket.ticket_code}
+
+ + +
+
二维码
+
+ 票二维码 +
扫描核销
+
+
+ + +
+
关联商品
+
{$goods['title']|default='已删除商品'}
+
+
+
订单号
+
{$ticket.order_no}
+
+
+
座位信息
+
{$ticket.seat_info|default='无'}
+
+ + +
+
观演人
+
{$ticket.real_name|default='-'}
+
+
+
手机号
+
{$ticket.phone|default='-'}
+
+
+
身份证
+
{$ticket.id_card|default='-'}
+
+ + +
+
发放时间
+
{$ticket.issued_at > 0 ? date('Y-m-d H:i:s', $ticket.issued_at) : '-'}
+
+ {if $ticket['verify_status'] == 1} +
+
核销时间
+
{$ticket.verify_time > 0 ? date('Y-m-d H:i:s', $ticket.verify_time) : '-'}
+
+
+
核销员
+
{$verifier['name']|default='-'}
+
+ {/if} + + + {if $ticket['verify_status'] == 0} +
+
手动核销
+
+
+ + +
+
+
+ {/if} +
+
+
+{include file="public/footer" /} + + + diff --git a/shopxo/app/plugins/vr_ticket/admin/view/verifier/list.html b/shopxo/app/plugins/vr_ticket/admin/view/verifier/list.html new file mode 100644 index 0000000..7d55ba4 --- /dev/null +++ b/shopxo/app/plugins/vr_ticket/admin/view/verifier/list.html @@ -0,0 +1,102 @@ + + + + + 核销员管理 - VR票务 + {include file="public/head" /} + + +
+
+
核销员管理
+
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ + 添加核销员 +
+
+
+ + +
+ + + + +
+
+
+ +{include file="public/footer" /} + + + diff --git a/shopxo/app/plugins/vr_ticket/admin/view/verifier/save.html b/shopxo/app/plugins/vr_ticket/admin/view/verifier/save.html new file mode 100644 index 0000000..05c55fc --- /dev/null +++ b/shopxo/app/plugins/vr_ticket/admin/view/verifier/save.html @@ -0,0 +1,73 @@ + + + + + {$info ? '编辑' : '添加'}核销员 - VR票务 + {include file="public/head" /} + + +
+
+
{$info ? '编辑' : '添加'}核销员
+
+
+
+ +
+ +
+ {if isset($info.id) && $info.id > 0} + +
用户关联后不可修改
+ {/if} +
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + + 返回 +
+
+
+
+
+
+{include file="public/footer" /} + + +