|
|
@@ -0,0 +1,283 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Module\Transfer\AdminControllers\Helper;
|
|
|
+
|
|
|
+use App\Module\Transfer\Models\TransferOrder;
|
|
|
+use App\Module\Transfer\Enums\TransferStatus;
|
|
|
+use App\Module\Transfer\Enums\TransferType;
|
|
|
+use Dcat\Admin\Grid;
|
|
|
+use Dcat\Admin\Show;
|
|
|
+use Dcat\Admin\Form;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 划转订单管理辅助类
|
|
|
+ */
|
|
|
+class TransferOrderHelper
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * 配置Grid表格
|
|
|
+ */
|
|
|
+ public static function grid(Grid $grid): void
|
|
|
+ {
|
|
|
+ $grid->column('id', 'ID')->sortable();
|
|
|
+
|
|
|
+ $grid->column('transfer_app.title', '应用名称')->limit(15);
|
|
|
+
|
|
|
+ $grid->column('out_order_id', '外部订单ID')->copyable()->limit(20);
|
|
|
+
|
|
|
+ $grid->column('user_id', '用户ID')->link(function ($value) {
|
|
|
+ return admin_url("users/{$value}");
|
|
|
+ });
|
|
|
+
|
|
|
+ $grid->column('out_user_id', '外部用户ID')->limit(15);
|
|
|
+
|
|
|
+ $grid->column('type', '类型')->using([
|
|
|
+ 1 => '转入',
|
|
|
+ 2 => '转出',
|
|
|
+ ])->label([
|
|
|
+ 1 => 'success',
|
|
|
+ 2 => 'warning',
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $grid->column('status', '状态')->using([
|
|
|
+ 1 => '已创建',
|
|
|
+ 20 => '处理中',
|
|
|
+ 30 => '已回调',
|
|
|
+ 100 => '已完成',
|
|
|
+ -1 => '失败',
|
|
|
+ ])->label([
|
|
|
+ 1 => 'info',
|
|
|
+ 20 => 'warning',
|
|
|
+ 30 => 'primary',
|
|
|
+ 100 => 'success',
|
|
|
+ -1 => 'danger',
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $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('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->diffInSeconds($this->created_at);
|
|
|
+ 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('<a href="javascript:void(0)" class="btn btn-xs btn-outline-warning retry-order" data-id="'.$this->id.'">重试</a>');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 手动完成按钮(仅转出订单)
|
|
|
+ if ($this->isTransferOut() && !$this->isFinalStatus()) {
|
|
|
+ $actions->append('<a href="javascript:void(0)" class="btn btn-xs btn-outline-success manual-complete" data-id="'.$this->id.'">手动完成</a>');
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 批量操作
|
|
|
+ $grid->batchActions(function (Grid\Tools\BatchActions $batch) {
|
|
|
+ $batch->add('批量重试', new \App\Module\Transfer\AdminControllers\Tools\RetryOrderTool());
|
|
|
+ $batch->add('导出订单', new \App\Module\Transfer\AdminControllers\Tools\ExportOrderTool());
|
|
|
+ });
|
|
|
+
|
|
|
+ // 工具栏
|
|
|
+ $grid->tools(function (Grid\Tools $tools) {
|
|
|
+ $tools->append('<a href="javascript:void(0)" class="btn btn-sm btn-primary" onclick="showStats()">统计信息</a>');
|
|
|
+ });
|
|
|
+
|
|
|
+ // 默认排序
|
|
|
+ $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->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');
|
|
|
+
|
|
|
+ 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),
|
|
|
+ ];
|
|
|
+ }
|
|
|
+}
|