fix(admin): visitor_name→real_name, verify_status, TicketVerify GET handler, input filter null→s

- list.html: visitor_name→real_name, status→verify_status, 修复搜索字段名
- verify.html: visitor_name→real_name in JS showResult(), 移除form-validation class
- Admin.php TicketList: 搜索字段从keywords改为逐字段搜索(real_name/phone/order_no/ticket_code)
- Admin.php TicketVerify: 添加GET分支显示核销页面,POST分支保持原逻辑
- Admin.php TicketVerify: input() filter null→'s' 避免variable type error
feat/b-verification-clean
Council 2026-04-25 20:02:36 +08:00
parent 6fae406982
commit a5b2d00c8e
3 changed files with 62 additions and 43 deletions

View File

@ -316,20 +316,36 @@ class Admin extends Common
{
$where = [];
$keywords = input('keywords', '', null, 'trim');
if (!empty($keywords)) {
$where[] = ['order_no|ticket_code|real_name|phone', 'like', "%{$keywords}%"];
// 逐字段精确搜索(对应视图的独立搜索框)
$order_no = input('order_no', '', null, 'trim');
if ($order_no !== '') {
$where[] = ['order_no', 'like', "%{$order_no}%"];
}
$ticket_code = input('ticket_code', '', 's', 'trim');
if ($ticket_code !== '') {
$where[] = ['ticket_code', 'like', "%{$ticket_code}%"];
}
$real_name = input('real_name', '', null, 'trim');
if ($real_name !== '') {
$where[] = ['real_name', 'like', "%{$real_name}%"];
}
$phone = input('phone', '', null, 'trim');
if ($phone !== '') {
$where[] = ['phone', 'like', "%{$phone}%"];
}
$verify_status = input('verify_status', '', null);
if ($verify_status !== '' && $verify_status !== null) {
$where[] = ['verify_status', '=', intval($verify_status)];
}
$goods_id = input('goods_id', 0, 'intval');
if ($goods_id > 0) {
$where[] = ['goods_id', '=', $goods_id];
}
// 搜索参数回传(用于表单值保持)
$params = [
'order_no' => $order_no,
'ticket_code' => $ticket_code,
'real_name' => $real_name,
'phone' => $phone,
'verify_status' => $verify_status,
];
$list = \think\facade\Db::name('vr_tickets')
->where($where)
@ -350,17 +366,11 @@ class Admin extends Common
unset($item);
}
$status_map = [
0 => ['text' => '未核销', 'color' => 'blue'],
1 => ['text' => '已核销', 'color' => 'green'],
2 => ['text' => '已退款', 'color' => 'red'],
];
return MyView('../../../plugins/vr_ticket/view/admin/ticket/list', [
'list' => $list_data['data'],
'page' => $list->render() ?: '',
'count' => $list_data['total'],
'status_map' => $status_map,
'list' => $list_data['data'],
'page' => $list->render() ?: '',
'count' => $list_data['total'],
'params'=> $params,
]);
}
@ -404,13 +414,24 @@ class Admin extends Common
/**
* 手动核销票JSON API
*/
/**
* 扫码核销页面GET和核销处理AJAX POST
* GET: 显示核销表单
* POST: 处理核销 AJAX 请求
*/
public function TicketVerify()
{
if (!(request()->isAjax() && request()->isPost())) {
return DataReturn('非法请求', -1);
// GET 请求 — 显示核销表单页面
if (!request()->isAjax()) {
return MyView('../../../plugins/vr_ticket/view/admin/ticket/verify', []);
}
$ticket_code = input('ticket_code', '', null, 'trim');
// AJAX POST — 处理核销
if (!request()->isPost()) {
return json(['code' => -1, 'msg' => '非法请求']);
}
$ticket_code = input('ticket_code', '', 's', 'trim');
// M-05: verifier_id 从 session 获取,禁止客户端伪造
// $this->admin 来自父类构造函数AdminService::LoginInfo()

View File

@ -11,7 +11,7 @@
<!-- 搜索栏 -->
<div class="am-panel am-panel-default am-margin-bottom">
<div class="am-panel-bd">
<form class="am-form form-validation" action="{{:PluginsAdminUrl('vr_ticket', 'admin', 'ticketlist')}}" method="POST" request-type="ajax-url">
<form class="am-form" action="{{:PluginsAdminUrl('vr_ticket', 'admin', 'ticketlist')}}" method="GET">
<div class="am-g">
<div class="am-u-sm-3 am-u-end">
<div class="am-input-group am-input-group-sm">
@ -28,26 +28,26 @@
<div class="am-u-sm-3 am-u-end">
<div class="am-input-group am-input-group-sm">
<span class="am-input-group-label">观演人</span>
<input type="text" name="visitor_name" value="{{if !empty($params.visitor_name)}}{{$params.visitor_name}}{{/if}}" placeholder="请输入观演人姓名" class="am-radius" />
<input type="text" name="real_name" value="{{if !empty($params.real_name)}}{{$params.real_name}}{{/if}}" placeholder="请输入观演人姓名" class="am-radius" />
</div>
</div>
<div class="am-u-sm-3 am-u-end">
<div class="am-input-group am-input-group-sm">
<span class="am-input-group-label">手机号</span>
<input type="text" name="mobile" value="{{if !empty($params.mobile)}}{{$params.mobile}}{{/if}}" placeholder="请输入手机号" class="am-radius" />
<input type="text" name="phone" value="{{if !empty($params.phone)}}{{$params.phone}}{{/if}}" placeholder="请输入手机号" class="am-radius" />
</div>
</div>
</div>
<div class="am-g am-margin-top">
<div class="am-u-sm-3 am-u-end">
<div class="am-input-group am-input-group-sm">
<span class="am-input-group-label">状态</span>
<select name="status" class="am-radius">
<select name="verify_status" class="am-radius">
<option value="">全部</option>
<option value="0" {{if isset($params.status) && $params.status === '0'}}selected{{/if}}>未核销</option>
<option value="1" {{if isset($params.status) && $params.status == '1'}}selected{{/if}}>已核销</option>
<option value="2" {{if isset($params.status) && $params.status == '2'}}selected{{/if}}>已退款</option>
<option value="0" {{if isset($params.verify_status) && $params.verify_status === '0'}}selected{{/if}}>未核销</option>
<option value="1" {{if isset($params.verify_status) && $params.verify_status == '1'}}selected{{/if}}>已核销</option>
<option value="2" {{if isset($params.verify_status) && $params.verify_status == '2'}}selected{{/if}}>已退款</option>
</select>
</div>
</div>
@ -66,7 +66,7 @@
<!-- 票列表 -->
<div class="am-panel am-panel-default">
<div class="am-panel-hd">电子票列表</div>
<div class="am-panel-hd">电子票列表 <span class="am-text-xs am-padding-left">共 {{$count|default=0}} 条</span></div>
<div class="am-panel-bd">
<table class="am-table am-table-striped am-table-hover am-text-middle">
<thead>
@ -85,19 +85,19 @@
{{volist name="list" id="ticket"}}
<tr>
<td>{{$ticket.ticket_code}}</td>
<td>{{$ticket.visitor_name}}</td>
<td>{{$ticket.real_name|default='—'}}</td>
<td>{{if !empty($ticket.seat_info)}}{{$ticket.seat_info}}{{else}}无{{/if}}</td>
<td>{{$ticket.goods_name}}</td>
<td>{{$ticket.goods_title|default='已删除商品'}}</td>
<td>
{{if $ticket.status == 0}}
{{if $ticket.verify_status == 0}}
<span class="am-badge am-badge-warning">未核销</span>
{{elseif $ticket.status == 1}}
{{elseif $ticket.verify_status == 1}}
<span class="am-badge am-badge-success">已核销</span>
{{elseif $ticket.status == 2}}
{{elseif $ticket.verify_status == 2}}
<span class="am-badge am-badge-danger">已退款</span>
{{/if}}
</td>
<td>{{$ticket.create_time}}</td>
<td>{{if !empty($ticket.issued_at)}}{{:date('Y-m-d H:i', $ticket.issued_at)}}{{else}}—{{/if}}</td>
<td>
<a href="{{:PluginsAdminUrl('vr_ticket', 'admin', 'ticketdetail')}}?id={{$ticket.id}}" class="am-btn am-btn-default am-btn-xs am-radius">
<i class="am-icon-eye"></i> 查看详情
@ -112,7 +112,7 @@
{{/if}}
</tbody>
</table>
<!-- 分页 -->
{{if !empty($page)}}
<div class="am-margin-top">
@ -123,4 +123,4 @@
</div>
</div>
{{:ModuleInclude('public/footer')}}
{{:ModuleInclude('public/footer')}}

View File

@ -34,7 +34,7 @@
<div class="am-panel am-panel-default am-margin-top">
<div class="am-panel-hd">扫码/输入核销</div>
<div class="am-panel-bd">
<form class="am-form form-validation" id="verify-form">
<form class="am-form" id="verify-form">
<div class="am-form-group">
<label>票码/短码</label>
<div class="am-input-group">
@ -126,11 +126,9 @@ function showResult(res) {
var ticket = res.data;
html = '<div class="am-alert am-alert-success am-margin-top">' +
'<h4><i class="am-icon-check-circle"></i> 核销成功</h4>' +
'<p><strong>票码:</strong>' + ticket.ticket_code + '</p>' +
'<p><strong>观演人:</strong>' + ticket.visitor_name + '</p>' +
'<p><strong>观演人:</strong>' + (ticket.real_name || '—') + '</p>' +
'<p><strong>座位:</strong>' + (ticket.seat_info || '无') + '</p>' +
'<p><strong>商品名:</strong>' + ticket.goods_name + '</p>' +
'<p><strong>核销时间:</strong>' + ticket.verify_time + '</p>' +
'<p><strong>商品名:</strong>' + (ticket.goods_name || '—') + '</p>' +
'</div>';
// 清空输入框