This commit is contained in:
youda 2025-05-18 12:45:06 +08:00
parent a67dd65a97
commit ee7bd2958f
4 changed files with 335 additions and 111 deletions

View File

@ -582,11 +582,7 @@ class Order extends Base
$whe[] = ['addtime', 'BETWEEN', [$time[0], $time[1]]];
}
$data = OrderModel::where($whe)->append(['user_info'])->order('id desc')->select()->toArray();
if (!$data) {
return $this->renderError('未找到数据');
}
// 创建新的Spreadsheet对象
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
@ -606,34 +602,55 @@ class Order extends Base
$sheet->getColumnDimension($col)->setWidth($widths[$i]);
}
// 填充数据
// 分批处理数据
$page = 1;
$limit = 1000; // 每批处理1000条
$line = 2;
foreach ($data as $value) {
try {
$sheet->setCellValue('A' . $line, $value['order_num']);
if ($value['user_info']) {
$sheet->setCellValue('B' . $line, 'ID' . $value['user_id'] . ' UID' . ($value['user_info']['uid'] ?: $value['user_id']) . ' 昵称:' . $value['user_info']['nickname'] . ' 手机号:' . $value['user_info']['mobile']);
} else {
$sheet->setCellValue('B' . $line, 'ID' . $value['user_id'] . ' UID' . $value['user_id'] . ' 昵称: 手机号:');
}
$sheet->setCellValue('C' . $line, '盒子名称:' . $value['goods_title'] . ($value['num'] ? ' 箱号:' . $value['num'] : ''));
$sheet->setCellValue('D' . $line, ['1' => '一番赏', '2' => '无限赏', '3' => '擂台赏', '4' => '抽卡机', '5' => '积分赏'][$value['order_type']] ?? '');
$sheet->setCellValue('E' . $line, $value['order_total']);
$sheet->setCellValue('F' . $line, $value['zhe']);
$sheet->setCellValue('G' . $line, $value['order_zhe_total']);
$sheet->setCellValue('H' . $line, $value['price']);
$sheet->setCellValue('I' . $line, $value['use_money']);
$sheet->setCellValue('J' . $line, $value['use_integral']);
$sheet->setCellValue('K' . $line, $value['use_score']);
$sheet->setCellValue('L' . $line, date('Y-m-d H:i:s', $value['addtime']));
} catch (\Throwable $th) {
//throw $th;
$c = $value;
while (true) {
$data = OrderModel::where($whe)
->append(['user_info'])
->order('id desc')
->page($page, $limit)
->select()
->toArray();
if (empty($data)) {
break;
}
$line++;
foreach ($data as $value) {
try {
$sheet->setCellValue('A' . $line, $value['order_num']);
if ($value['user_info']) {
$sheet->setCellValue('B' . $line, 'ID' . $value['user_id'] . ' UID' . ($value['user_info']['uid'] ?: $value['user_id']) . ' 昵称:' . $value['user_info']['nickname'] . ' 手机号:' . $value['user_info']['mobile']);
} else {
$sheet->setCellValue('B' . $line, 'ID' . $value['user_id'] . ' UID' . $value['user_id'] . ' 昵称: 手机号:');
}
$sheet->setCellValue('C' . $line, '盒子名称:' . $value['goods_title'] . ($value['num'] ? ' 箱号:' . $value['num'] : ''));
$sheet->setCellValue('D' . $line, ['1' => '一番赏', '2' => '无限赏', '3' => '擂台赏', '4' => '抽卡机', '5' => '积分赏'][$value['order_type']] ?? '');
$sheet->setCellValue('E' . $line, $value['order_total']);
$sheet->setCellValue('F' . $line, $value['zhe']);
$sheet->setCellValue('G' . $line, $value['order_zhe_total']);
$sheet->setCellValue('H' . $line, $value['price']);
$sheet->setCellValue('I' . $line, $value['use_money']);
$sheet->setCellValue('J' . $line, $value['use_integral']);
$sheet->setCellValue('K' . $line, $value['use_score']);
$sheet->setCellValue('L' . $line, date('Y-m-d H:i:s', $value['addtime']));
} catch (\Throwable $th) {
continue;
}
$line++;
}
// 清理内存
unset($data);
gc_collect_cycles();
$page++;
}
// 输出 Excel
// 输出Excel文件
$filename = '购买列表信息_' . date('Y-m-d_H-i-s') . '.xls';
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="' . $filename . '"');
@ -1008,18 +1025,215 @@ class Order extends Base
*/
public function get_order_list()
{
$page = input('page', 1);
$limit = input('limit', 10);
$user_id = input('user_id', '');
$mobile = input('mobile', '');
$order_num = input('order_num', '');
$status = input('status', '');
$start_time = input('start_time', '');
$end_time = input('end_time', '');
$params = [
'page' => input('page', 1),
'limit' => input('limit', 10),
'user_id' => input('user_id', ''),
'mobile' => input('mobile', ''),
'order_num' => input('order_num', ''),
'status' => input('status', ''),
'start_time' => input('start_time', ''),
'end_time' => input('end_time', ''),
'istest' => input('istest', '0'),
'u_status' => input('u_status', '1')
];
$result = $this->getOrderDataSource($params);
// 格式化数据
foreach ($result['list'] as &$item) {
$item = $this->formatOrderData($item);
}
return json([
'code' => 0,
'msg' => '获取成功',
'count' => $result['count'],
'data' => $result['list']
]);
}
/**
* 格式化订单数据
* @param array $item 订单数据
* @param bool $isExport 是否为导出模式
* @return array
*/
private function formatOrderData($item, $isExport = false)
{
// 格式化时间
$addtime = date('Y-m-d H:i:s', $item['addtime']);
$pay_time = $item['pay_time'] ? date('Y-m-d H:i:s', $item['pay_time']) : '';
// 支付状态格式化
switch ($item['status']) {
case 0:
$status_text = '未支付';
break;
case 1:
$status_text = '已支付';
break;
case 2:
$status_text = '已失效';
break;
default:
$status_text = '未知状态';
}
// 支付类型格式化 - 根据订单号前缀判断
$order_prefix = substr($item['order_num'], 3, 3);
switch ($order_prefix) {
case 'MON':
$pay_type_text = '货币支付';
break;
case 'ZFA':
$pay_type_text = '支付宝';
break;
default:
$pay_type_text = '微信支付';
}
if ($isExport) {
return [
$item['id'],
$item['order_num'],
$item['uid'],
$item['nickname'],
$item['mobile'],
$item['goods_title'],
$item['goods_price'],
$item['num'],
$item['order_zhe_total'],
$item['price'],
$item['use_money'],
$item['use_integral'],
$item['use_money2'],
$item['use_coupon'],
$item['prize_num'],
$item['sc_money'],
$status_text,
$pay_type_text,
$addtime,
$pay_time
];
}
$item['addtime'] = $addtime;
$item['pay_time'] = $pay_time;
$item['status_text'] = $status_text;
$item['pay_type_text'] = $pay_type_text;
return $item;
}
/**
* 导出订单列表数据
*/
public function export_order_list()
{
$params = [
'user_id' => input('user_id', ''),
'mobile' => input('mobile', ''),
'order_num' => input('order_num', ''),
'status' => input('status', ''),
'start_time' => input('start_time', ''),
'end_time' => input('end_time', ''),
'istest' => input('istest', '0'),
'u_status' => input('u_status', '1')
];
// 创建新的Spreadsheet对象
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
// 设置表头
$headers = [
'订单ID', '订单号', '用户UID', '用户昵称', '手机号',
'商品标题', '商品价格', '购买数量', '订单金额',
'RMB支付', '钻石支付', 'UU币支付', '达达券支付', '优惠券抵扣',
'抽奖数量', '出货金额', '支付状态', '支付类型', '购买时间', '支付时间'
];
// 写入表头
foreach ($headers as $col => $header) {
$sheet->setCellValueByColumnAndRow($col + 1, 1, $header);
}
// 设置样式
$sheet->getStyle('A1:T1')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
$sheet->getStyle('A1:T1')->getFont()->setBold(true);
// 设置列宽
$widths = [10, 40, 15, 20, 15, 40, 15, 10, 15, 15, 15, 15, 15, 15, 10, 15, 15, 15, 20, 20];
foreach (range('A', 'T') as $i => $col) {
$sheet->getColumnDimension($col)->setWidth($widths[$i]);
}
// 分批处理数据
$page = 1;
$limit = 1000; // 每批处理1000条
$line = 2;
while (true) {
$query = $this->getOrderDataSource($params, true);
$data = $query->page($page, $limit)->select()->toArray();
if (empty($data)) {
break;
}
foreach ($data as $item) {
// 写入数据
$sheet->fromArray($this->formatOrderData($item, true), null, "A{$line}");
$line++;
}
// 清理内存
unset($data);
gc_collect_cycles();
$page++;
}
// 输出Excel文件
$filename = '订单列表_' . date('Y-m-d_H-i-s') . '.xlsx';
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="' . $filename . '"');
header('Cache-Control: max-age=0');
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save('php://output');
exit;
}
/**
* 获取订单数据源
* @param array $params 查询参数
* @param bool $isExport 是否为导出模式
* @return array|object
*/
private function getOrderDataSource($params = [], $isExport = false)
{
$user_id = $params['user_id'] ?? '';
$mobile = $params['mobile'] ?? '';
$order_num = $params['order_num'] ?? '';
$status = $params['status'] ?? '';
$start_time = $params['start_time'] ?? '';
$end_time = $params['end_time'] ?? '';
$istest = $params['istest'] ?? '0';
$u_status = $params['u_status'] ?? '1';
$page = $params['page'] ?? 1;
$limit = $params['limit'] ?? 10;
$where = [];
// $where[] = ['u.status', '=', 1];
// $where[] = ['u.istest', '=', 0];
// 转换时间格式
if ($start_time) {
$start_time = strtotime($start_time);
}
if ($end_time) {
$end_time = strtotime($end_time);
}
if ($user_id) {
$user_id = $this->convertUidToUserId($user_id);
@ -1037,6 +1251,16 @@ class Order extends Base
if ($status !== '') {
$where[] = ['o.status', '=', $status];
}
// 添加账号类型查询条件
if ($istest !== '') {
$where[] = ['u.istest', '=', $istest];
}
// 添加用户状态查询条件
if ($u_status !== '') {
$where[] = ['u.status', '=', $u_status];
}
if ($start_time && $end_time) {
$where[] = ['o.addtime', 'between', [$start_time, $end_time]];
@ -1059,54 +1283,18 @@ class Order extends Base
END as sc_money,u.status u_status,u.istest,u.uid')
->where($where)
->order('o.id desc');
if ($isExport) {
return $query;
}
$count = $query->count();
$list = $query->page($page, $limit)->select()->toArray();
// 格式化数据
foreach ($list as &$item) {
$item['addtime'] = date('Y-m-d H:i:s', $item['addtime']);
$item['pay_time'] = $item['pay_time'] ? date('Y-m-d H:i:s', $item['pay_time']) : '';
// 支付状态格式化
switch ($item['status']) {
case 0:
$item['status_text'] = '未支付';
break;
case 1:
$item['status_text'] = '已支付';
break;
case 2:
$item['status_text'] = '已失效';
break;
default:
$item['status_text'] = '未知状态';
}
// 支付类型格式化
switch ($item['pay_type']) {
case 1:
$item['pay_type_text'] = '微信支付';
break;
case 2:
$item['pay_type_text'] = '支付宝';
break;
case 3:
$item['pay_type_text'] = '钻石支付';
break;
default:
$item['pay_type_text'] = '其他';
}
}
return json([
'code' => 0,
'msg' => '获取成功',
return [
'count' => $count,
'data' => $list
]);
'list' => $list
];
}
}

View File

@ -229,6 +229,8 @@ Route::rule('unpaid_order', 'Order/unpaid_order');
Route::rule('delete_order_item', 'Order/delete_order_item');
Route::rule('order_list', 'Order/order_list', 'GET|POST');
Route::rule('order/get_order_list', 'Order/get_order_list', 'GET|POST');
Route::get('get_order_list', 'Order/get_order_list');
Route::get('order/export_order_list', 'Order/export_order_list');
#============================

View File

@ -3,54 +3,60 @@
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-body">
<div class="layui-card-body" >
<!-- 搜索条件 -->
<div id="order-list-body">
<form class="layui-form layui-form-pane">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">用户ID</label>
<div class="layui-input-inline">
<input type="text" name="user_id" placeholder="请输入用户ID" autocomplete="off"
class="layui-input">
<div class="layui-input-inline" style="width: 120px;">
<input type="text" name="user_id" placeholder="用户ID" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">手机号</label>
<div class="layui-input-inline">
<input type="text" name="mobile" placeholder="请输入手机号" autocomplete="off"
class="layui-input">
<div class="layui-input-inline" style="width: 120px;">
<input type="text" name="mobile" placeholder="手机号" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">订单号</label>
<div class="layui-input-inline">
<input type="text" name="order_num" placeholder="请输入订单号" autocomplete="off"
class="layui-input">
<div class="layui-input-inline" style="width: 180px;">
<input type="text" name="order_num" placeholder="订单号" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">支付状态</label>
<div class="layui-input-inline">
<div class="layui-input-inline" style="width: 100px;">
<select name="status">
<option value="">全部</option>
<option value="">支付状态</option>
<option value="0">未支付</option>
<option value="1">已支付</option>
<option value="2">已失效</option>
</select>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">购买时间</label>
<div class="layui-input-inline">
<input type="text" name="start_time" id="start_time" placeholder="开始时间" autocomplete="off"
class="layui-input">
<div class="layui-input-inline" style="width: 100px;">
<select name="istest">
<option value="0">账号类型</option>
<option value="1">推广</option>
<option value="2">测试</option>
</select>
</div>
</div>
<div class="layui-inline">
<div class="layui-input-inline" style="width: 100px;">
<select name="u_status">
<option value="1">用户状态</option>
<option value="2">封号</option>
</select>
</div>
</div>
<div class="layui-inline">
<div class="layui-input-inline" style="width: 160px;">
<input type="text" name="start_time" id="start_time" placeholder="开始时间" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid">-</div>
<div class="layui-input-inline">
<input type="text" name="end_time" id="end_time" placeholder="结束时间" autocomplete="off"
class="layui-input">
<div class="layui-input-inline" style="width: 160px;">
<input type="text" name="end_time" id="end_time" placeholder="结束时间" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
@ -58,9 +64,13 @@
<i class="layui-icon layui-icon-search"></i> 搜索
</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<button type="button" class="layui-btn layui-btn-normal" id="export-order">
<i class="layui-icon layui-icon-export"></i> 导出Excel
</button>
</div>
</div>
</form>
</div>
<!-- 数据表格 -->
<table id="order-table" lay-filter="order-table"></table>
@ -82,6 +92,7 @@
<script type="text/html" id="order-num-tpl">
<div>
<p>{{d.order_num}}</p>
<p><b>订单Id{{d.id}}</b></p>
<p><b>支付商户:{{appConfigManager.getWxPayConfigByType(d.order_num)?.name}}</b></p>
<p><b>商户Id{{appConfigManager.getWxPayConfigByType(d.order_num)?.mch_id}}</b></p>
</div>
@ -123,8 +134,8 @@
<!-- 用户信息模板 -->
<script type="text/html" id="user-info-tpl">
<div>
<p style="margin: 2px 0; line-height: 1.4;"><b>ID</b>{{d.user_id}}</p>
<p style="margin: 2px 0; line-height: 1.4;"><b>真实ID</b>{{d.id}}</p>
<p style="margin: 2px 0; line-height: 1.4;"><b>UID</b>{{d.uid}}</p>
<p style="margin: 2px 0; line-height: 1.4;"><b>真实ID</b>{{d.user_id}}</p>
<p style="margin: 2px 0; line-height: 1.4;"><b>昵称:</b>{{d.nickname}}</p>
<p style="margin: 2px 0; line-height: 1.4;"><b>手机:</b>{{d.mobile}}</p>
<p style="margin: 2px 0; line-height: 1.4;"><b>账号状态:</b>
@ -202,7 +213,7 @@
elem: '#order-table',
url: "{:url('get_order_list')}",
page: true,
height: 'full-140',
height: 'full-'+($("#order-list-body").height()+40),
lineStyle: 'height:170px',
limit: 10,
limits: [10, 20, 50, 100],
@ -265,5 +276,11 @@
});
}
});
// 导出Excel
$('#export-order').on('click', function() {
var formData = $('.layui-form').serialize();
window.location.href = "{:url('export_order_list')}?" + formData;
});
});
</script>

View File

@ -65,7 +65,24 @@ class AppConfigManager {
// 取第 3~6 位字符作为前缀DEA、DEC、DED...
const order_key = order_num.substr(3, 3);
// console.log('订单号:', order_num, '订单前缀:', order_key);
if(order_key=="MON"){
return {
name: '货币支付',
mch_id: '无',
order_prefix: 'MON',
appid: '',
appsecret: ''
}
}
if(order_key=="ZFA"){
return {
name: '支付宝支付',
mch_id: '',
order_prefix: 'ZFA',
appid: '',
appsecret: ''
}
}
const wxPayConfigList = this.getWxPayConfig();
if (!Array.isArray(wxPayConfigList)) {
console.warn('微信支付配置无效');