column('id', 'ID')->sortable(); $grid->column('transfer_app.title', '应用名称')->limit(15); $grid->column('out_order_id', '外部订单ID')->copyable(); $grid->column('user_id', '用户ID')->link(function ($value) { return admin_url("users/{$value}"); }); $grid->column('out_user_id', '外部用户ID')->limit(15); $grid->column('type', '类型')->display(function ($value) { $typeMap = [ 1 => '转入', 2 => '转出', ]; $labelMap = [ 1 => 'success', 2 => 'warning', ]; // 处理枚举对象 $typeValue = is_object($value) ? $value->value : $value; $text = $typeMap[$typeValue] ?? '未知'; $label = $labelMap[$typeValue] ?? 'default'; return "{$text}"; }); $grid->column('status', '状态')->display(function ($value) { $statusMap = [ 1 => '已创建', 20 => '处理中', 30 => '已回调', 100 => '已完成', -1 => '失败', ]; $labelMap = [ 1 => 'info', 20 => 'warning', 30 => 'primary', 100 => 'success', -1 => 'danger', ]; // 处理枚举对象 $statusValue = is_object($value) ? $value->value : $value; $text = $statusMap[$statusValue] ?? '未知'; $label = $labelMap[$statusValue] ?? 'default'; return "{$text}"; }); $grid->column('out_amount', '外部金额')->display(function ($value) { return number_format($value, 4); }); $grid->column('amount', '内部金额')->display(function ($value) { return number_format($value, 4); }); // 手续费信息 $grid->column('fee_info', '手续费信息')->display(function () { if ($this->fee_amount > 0) { $feeRate = number_format($this->fee_rate * 100, 2) . '%'; $feeAmount = number_format($this->fee_amount, 4); $actualAmount = number_format($this->actual_amount, 4); return "费率: {$feeRate}
手续费: {$feeAmount}
实际: {$actualAmount}"; } return '无手续费'; }); $grid->column('exchange_rate', '汇率')->display(function ($value) { return number_format($value, 4); }); $grid->column('created_at', '创建时间')->sortable(); $grid->column('completed_at', '完成时间'); // 处理时长 $grid->column('duration', '处理时长')->display(function () { if ($this->completed_at && $this->created_at) { // 确保计算正确的时间差(完成时间 - 创建时间) $seconds = $this->completed_at->getTimestamp() - $this->created_at->getTimestamp(); // 如果时间差为负数或0,显示为0秒 if ($seconds <= 0) { return '0秒'; } if ($seconds < 60) { return $seconds . '秒'; } elseif ($seconds < 3600) { return round($seconds / 60, 1) . '分钟'; } else { return round($seconds / 3600, 1) . '小时'; } } return '-'; }); // 筛选器 $grid->filter(function (Grid\Filter $filter) { $filter->equal('transfer_app_id', '应用')->select( \App\Module\Transfer\Models\TransferApp::pluck('title', 'id') ); $filter->equal('type', '类型')->select([ 1 => '转入', 2 => '转出', ]); $filter->equal('status', '状态')->select([ 1 => '已创建', 20 => '处理中', 30 => '已回调', 100 => '已完成', -1 => '失败', ]); $filter->equal('user_id', '用户ID'); $filter->like('out_order_id', '外部订单ID'); $filter->like('out_user_id', '外部用户ID'); $filter->between('amount', '内部金额'); $filter->between('created_at', '创建时间')->datetime(); }); // 操作按钮 $grid->actions(function (Grid\Displayers\Actions $actions) { $actions->disableDelete(); // 禁用删除 $actions->disableEdit(); // 禁用编辑 // 重试按钮 if ($this->canRetry()) { $actions->append('重试'); } // 手动完成按钮(仅转出订单) if ($this->isTransferOut() && !$this->isFinalStatus()) { $actions->append('手动完成'); } }); // 批量操作 $grid->batchActions(function (Grid\Tools\BatchActions $batch) { $batch->add(new \App\Module\Transfer\AdminControllers\Tools\RetryOrderTool()); }); // 工具栏 $grid->tools(function (Grid\Tools $tools) { $tools->append('统计信息'); $tools->append(new \App\Module\Transfer\AdminControllers\Tools\ExportOrderTool()); }); // 默认排序 $grid->model()->orderBy('created_at', 'desc'); } /** * 配置Show详情 */ public static function show(Show $show): void { $show->field('id', 'ID'); $show->divider(); $show->field('transfer_app.title', '应用名称'); $show->field('out_order_id', '外部订单ID'); $show->field('out_user_id', '外部用户ID'); $show->field('user_id', '内部用户ID'); $show->field('type', '订单类型')->using([ 1 => '转入', 2 => '转出', ]); $show->field('status', '订单状态')->using([ 1 => '已创建', 20 => '处理中', 30 => '已回调', 100 => '已完成', -1 => '失败', ]); $show->divider(); $show->field('out_amount', '外部金额')->as(function ($value) { return number_format($value, 10); }); $show->field('amount', '内部金额')->as(function ($value) { return number_format($value, 10); }); $show->field('exchange_rate', '使用汇率')->as(function ($value) { return number_format($value, 4); }); // 手续费信息 $show->field('fee_rate', '手续费率')->as(function ($value) { return number_format($value * 100, 2) . '%'; }); $show->field('fee_amount', '手续费金额')->as(function ($value) { return number_format($value, 4); }); $show->field('actual_amount', '实际到账金额')->as(function ($value) { return number_format($value, 4); }); $show->field('has_fee', '是否收取手续费')->as(function () { return $this->fee_amount > 0 ? '是' : '否'; }); $show->divider(); $show->field('currency_id', '货币类型')->using([ 1 => '金币', 2 => '钻石', 3 => '人民币', 4 => '美元', ]); $show->field('fund_id', '资金账户类型'); $show->divider(); $show->field('callback_data', '回调数据')->json(); $show->divider(); $show->field('error_message', '错误信息'); $show->field('remark', '备注信息'); $show->divider(); $show->field('created_at', '创建时间'); $show->field('processed_at', '处理时间'); $show->field('callback_at', '回调时间'); $show->field('completed_at', '完成时间'); $show->field('updated_at', '更新时间'); // 处理时长 $show->field('processing_duration', '处理时长')->as(function () { if ($this->completed_at && $this->created_at) { return $this->completed_at->diffForHumans($this->created_at, true); } return '未完成'; }); } /** * 获取状态统计 */ public static function getStatusStats(): array { $stats = TransferOrder::selectRaw('status, COUNT(*) as count, SUM(amount) as amount') ->groupBy('status') ->get() ->keyBy('status'); $result = []; foreach (TransferStatus::cases() as $status) { $stat = $stats->get($status->value); $result[] = [ 'status' => $status->getDescription(), 'count' => $stat ? number_format($stat->count) : 0, 'amount' => $stat ? number_format($stat->amount, 2) : '0.00', 'color' => $status->getColor(), ]; } return $result; } /** * 获取类型统计 */ public static function getTypeStats(): array { $stats = TransferOrder::selectRaw('type, COUNT(*) as count, SUM(amount) as amount') ->groupBy('type') ->get() ->keyBy('type'); $result = []; foreach (TransferType::cases() as $type) { $stat = $stats->get($type->value); $result[] = [ 'type' => $type->getDescription(), 'count' => $stat ? number_format($stat->count) : 0, 'amount' => $stat ? number_format($stat->amount, 2) : '0.00', 'color' => $type->getColor(), ]; } return $result; } /** * 获取今日统计 */ public static function getTodayStats(): array { $today = now()->startOfDay(); $total = TransferOrder::where('created_at', '>=', $today)->count(); $completed = TransferOrder::where('created_at', '>=', $today) ->where('status', TransferStatus::COMPLETED)->count(); $failed = TransferOrder::where('created_at', '>=', $today) ->where('status', TransferStatus::FAILED)->count(); $amount = TransferOrder::where('created_at', '>=', $today)->sum('amount'); $feeAmount = TransferOrder::where('created_at', '>=', $today)->sum('fee_amount'); return [ 'total' => number_format($total), 'completed' => number_format($completed), 'failed' => number_format($failed), 'success_rate' => $total > 0 ? number_format($completed / $total * 100, 1) . '%' : '0%', 'amount' => number_format($amount, 2), 'fee_amount' => number_format($feeAmount, 2), ]; } /** * 获取手续费统计 */ public static function getFeeStats(): array { $stats = TransferOrder::selectRaw(' COUNT(*) as total_orders, SUM(fee_amount) as total_fee, AVG(fee_rate) as avg_fee_rate, SUM(CASE WHEN type = 1 THEN fee_amount ELSE 0 END) as in_fee, SUM(CASE WHEN type = 2 THEN fee_amount ELSE 0 END) as out_fee, COUNT(CASE WHEN type = 1 THEN 1 END) as in_orders, COUNT(CASE WHEN type = 2 THEN 1 END) as out_orders ') ->where('status', TransferStatus::COMPLETED) ->where('fee_amount', '>', 0) ->first(); return [ 'total_orders' => number_format($stats->total_orders ?? 0), 'total_fee' => number_format($stats->total_fee ?? 0, 4), 'avg_fee_rate' => number_format(($stats->avg_fee_rate ?? 0) * 100, 2) . '%', 'in_fee' => number_format($stats->in_fee ?? 0, 4), 'out_fee' => number_format($stats->out_fee ?? 0, 4), 'in_orders' => number_format($stats->in_orders ?? 0), 'out_orders' => number_format($stats->out_orders ?? 0), ]; } }