diff --git a/app/Admin/Controllers/MchAppController.php b/app/Admin/Controllers/MchAppController.php index f1557aa..909dbef 100644 --- a/app/Admin/Controllers/MchAppController.php +++ b/app/Admin/Controllers/MchAppController.php @@ -36,7 +36,7 @@ class MchAppController extends AdminController $grid->disableEditButton(); $grid->filter(function (Grid\Filter $filter) { - $filter->equal('mch_no')->width(3); + $filter->equal('mch_no')->width(3)->select(Merchant::getAllMerchant()); $filter->equal('app_id')->width(3); $filter->equal('alipay_account')->width(3); $filter->like('company_name')->width(3); @@ -79,7 +79,7 @@ class MchAppController extends AdminController if ($form->isCreating()) { $form->select('mch_no') - ->options(Merchant::pluck('mch_name', 'mch_no')) + ->options(Merchant::getAllMerchant()) ->required(); $form->hidden('app_id'); $form->hidden('secret_key'); diff --git a/app/Admin/Controllers/OrderController.php b/app/Admin/Controllers/OrderController.php new file mode 100644 index 0000000..cff14e5 --- /dev/null +++ b/app/Admin/Controllers/OrderController.php @@ -0,0 +1,135 @@ +model()->orderBy('id', 'desc'); + + $grid->column('id')->sortable(); + $grid->column('if_code'); + $grid->column('mch_no'); + $grid->column('app_id'); + $grid->column('mch_order_no'); + $grid->column('entry_type'); + $grid->column('amount')->display(fn ($v) => bcdiv($v, 100, 2)); + $grid->column('currency'); + $grid->column('account_no'); + $grid->column('account_name'); + $grid->column('bank_name'); + $grid->column('bank_code'); + $grid->column('client_ip'); + $grid->column('transfer_desc'); + $grid->column('notify_url'); + $grid->column('ext_param'); + $grid->column('channel_extra'); + $grid->column('state') + ->using(admin_trans('order.options.state')) + ->dot([ + 0 => 'primary', + 1 => 'warning', + 2 => 'success', + 3 => 'danger', + 4 => 'gray', + ]); + $grid->column('transfer_id'); + $grid->column('channel_order_no'); + $grid->column('success_time'); + $grid->column('created_at'); + $grid->column('updated_at')->sortable(); + + $grid->disableCreateButton(); + $grid->disableEditButton(); + $grid->disableDeleteButton(); + $grid->disableBatchDelete(); + + $grid->showColumnSelector(); + $grid->hideColumns(['if_code', 'currency', 'bank_name', 'bank_code', 'client_ip', 'transfer_desc', 'notify_url', 'ext_param', 'channel_extra', 'channel_order_no']); + + $grid->filter(function (Grid\Filter $filter) { + $filter->equal('id')->width(3); + $filter->equal('mch_no')->width(3)->select(Merchant::getAllMerchant()); + $filter->equal('app_id')->width(3); + $filter->equal('mch_order_no')->width(3); + $filter->equal('account_no')->width(3); + $filter->equal('state')->width(3)->select(admin_trans('order.options.state')); + $filter->between('success_time')->width(3)->datetime(['timeZone' => config('app.timezone')]); + $filter->between('created_at')->width(3)->datetime(); + }); + }); + } + + /** + * Make a show builder. + * + * @param mixed $id + * + * @return Show + */ + protected function detail($id) + { + return Show::make($id, new Order(), function (Show $show) { + $show->disableEditButton(); + $show->disableDeleteButton(); + $show->field('id'); + $show->field('if_code'); + $show->field('mch_no'); + $show->field('app_id'); + $show->field('mch_order_no'); + $show->field('entry_type'); + $show->field('amount')->as(fn ($v) => bcdiv($v, 100, 2)); + $show->field('currency'); + $show->field('account_no'); + $show->field('account_name'); + $show->field('bank_name'); + $show->field('bank_code'); + $show->field('client_ip'); + $show->field('transfer_desc'); + $show->field('notify_url'); + $show->field('ext_param'); + $show->field('channel_extra'); + $show->field('state') + ->using(admin_trans('order.options.state')) + ->dot([ + 0 => 'primary', + 1 => 'warning', + 2 => 'success', + 3 => 'danger', + 4 => 'gray', + ]); + $show->field('transfer_id'); + $show->field('channel_order_no'); + $show->field('success_time'); + $show->field('created_at'); + $show->field('updated_at'); + }); + } + + /** + * Make a form builder. + * + * @return Form + */ + protected function form() + { + return Form::make(new Order(), function (Form $form) { + $form->disableViewButton(); + $form->display('id'); + }); + } +} diff --git a/app/Admin/Controllers/OrderNotifyController.php b/app/Admin/Controllers/OrderNotifyController.php new file mode 100644 index 0000000..6c5b572 --- /dev/null +++ b/app/Admin/Controllers/OrderNotifyController.php @@ -0,0 +1,97 @@ +model()->orderBy('id', 'desc'); + + $grid->column('id')->sortable(); + $grid->column('order_id'); + $grid->column('state') + ->using(admin_trans('order.options.state')) + ->label([ + 0 => 'primary', + 1 => 'warning', + 2 => 'success', + 3 => 'danger', + 4 => 'gray', + ]); + $grid->column('receive_time'); + $grid->column('push_time'); + $grid->column('push_duration'); + $grid->column('response_time'); + $grid->column('response_code'); + + $grid->disableCreateButton(); + $grid->disableEditButton(); + $grid->disableDeleteButton(); + $grid->disableBatchDelete(); + + $grid->filter(function (Grid\Filter $filter) { + $filter->equal('order_id')->width(3); + + }); + }); + } + + /** + * Make a show builder. + * + * @param mixed $id + * + * @return Show + */ + protected function detail($id) + { + return Show::make($id, new OrderNotify(), function (Show $show) { + $show->field('id'); + $show->field('order_id'); + $show->field('state')->using(admin_trans('order.options.state')); + $show->field('receive_time'); + $show->field('receive_body')->unescape()->as(fn ($v) => '
' . e($v) . '
'); + $show->field('push_time'); + $show->field('push_body')->unescape()->as(fn ($v) => '
' . e($v) . '
'); + $show->field('push_duration'); + $show->field('response_time'); + $show->field('response_code'); + $show->field('response_body')->unescape()->as(fn ($v) => '
' . e($v) . '
'); + }); + } + + /** + * Make a form builder. + * + * @return Form + */ + protected function form() + { + return Form::make(new OrderNotify(), function (Form $form) { + $form->display('id'); + $form->text('order_id'); + $form->text('state'); + $form->text('receive_time'); + $form->text('receive_body'); + $form->text('push_time'); + $form->text('push_body'); + $form->text('push_duration'); + $form->text('response_time'); + $form->text('response_code'); + $form->text('response_body'); + }); + } +} diff --git a/app/Admin/routes.php b/app/Admin/routes.php index 47afaa9..858b8b9 100644 --- a/app/Admin/routes.php +++ b/app/Admin/routes.php @@ -2,6 +2,8 @@ use App\Admin\Controllers\MchAppController; use App\Admin\Controllers\MerchantController; +use App\Admin\Controllers\OrderController; +use App\Admin\Controllers\OrderNotifyController; use Illuminate\Routing\Router; use Illuminate\Support\Facades\Route; use Dcat\Admin\Admin; @@ -19,4 +21,8 @@ Route::group([ $router->resource('merchant', MerchantController::class); $router->resource('mch-app', MchAppController::class); + + $router->resource('order', OrderController::class)->only(['index', 'show']); + + $router->resource('order-notify', OrderNotifyController::class)->only(['index', 'show']); }); diff --git a/app/Models/Merchant.php b/app/Models/Merchant.php index aabec4d..f63686f 100644 --- a/app/Models/Merchant.php +++ b/app/Models/Merchant.php @@ -8,4 +8,17 @@ use Illuminate\Database\Eloquent\Model; class Merchant extends Model { use HasDateTimeFormatter; + + public static function getAllMerchant(): array + { + $merchants = self::all(); + + $list = []; + + foreach ($merchants as $merchant) { + $list[$merchant->mch_no] = "[$merchant->mch_no]$merchant->mch_name"; + } + + return $list; + } } diff --git a/app/Models/Order.php b/app/Models/Order.php new file mode 100644 index 0000000..e22f2f9 --- /dev/null +++ b/app/Models/Order.php @@ -0,0 +1,11 @@ +id(); + $table->string('if_code')->comment('渠道码'); + $table->string('mch_no')->comment('商户号'); + $table->string('app_id')->comment('应用ID')->index(); + $table->string('mch_order_no')->comment('商户订单号')->index(); + $table->string('entry_type')->comment('入账方式'); + $table->integer('amount')->comment('代付金额'); + $table->string('currency')->comment('货币代码'); + $table->string('account_no')->comment('收款账号'); + $table->string('account_name')->nullable()->comment('收款人姓名'); + $table->string('bank_name')->nullable()->comment('收款账户开户行名称'); + $table->string('bank_code')->nullable()->comment('收款账户开户行编码'); + $table->string('client_ip')->nullable()->comment('客户端IP'); + $table->string('transfer_desc')->comment('转账备注信息'); + $table->string('notify_url')->nullable()->comment('异步通知地址'); + $table->string('ext_param', 512)->nullable()->comment('扩展参数'); + $table->string('channel_extra')->nullable()->comment('渠道特殊参数'); + $table->tinyInteger('state')->default(0)->comment('转账状态'); + $table->string('transfer_id')->nullable()->unique()->comment('转账订单号'); + $table->string('channel_order_no')->nullable()->comment('渠道转账单号'); + $table->timestamp('success_time')->nullable()->comment('成功时间'); + $table->timestamps(); + $table->unique(['mch_no', 'mch_order_no']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('orders'); + } +}; diff --git a/database/migrations/2025_08_27_170155_create_order_notifies_table.php b/database/migrations/2025_08_27_170155_create_order_notifies_table.php new file mode 100644 index 0000000..7f18743 --- /dev/null +++ b/database/migrations/2025_08_27_170155_create_order_notifies_table.php @@ -0,0 +1,36 @@ +id(); + $table->unsignedBigInteger('order_id')->index()->comment('订单ID'); + $table->tinyInteger('state')->comment('订单状态'); + $table->timestamp('receive_time')->comment('接收通知的时间'); + $table->text('receive_body')->comment('接收通知的内容'); + $table->timestamp('push_time')->nullable()->comment('推给客户的时间'); + $table->text('push_body')->nullable()->comment('推给客户的内容'); + $table->integer('push_duration')->nullable()->comment('推送用时'); + $table->timestamp('response_time')->nullable()->comment('客户响应的时间'); + $table->integer('response_code')->nullable()->comment('客户响应的状态码'); + $table->text('response_body')->nullable()->comment('客户响应的内容'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('order_notifies'); + } +}; diff --git a/lang/zh_CN/order-notify.php b/lang/zh_CN/order-notify.php new file mode 100644 index 0000000..9e38a54 --- /dev/null +++ b/lang/zh_CN/order-notify.php @@ -0,0 +1,21 @@ + [ + 'OrderNotify' => '推送记录', + 'order-notify' => '推送记录', + ], + 'fields' => [ + 'order_id' => '订单ID', + 'state' => '订单状态', + 'receive_time' => '接收通知的时间', + 'receive_body' => '接收通知的内容', + 'push_time' => '推给客户的时间', + 'push_body' => '推给客户的内容', + 'push_duration' => '推送用时', + 'response_time' => '客户响应的时间', + 'response_code' => '客户响应的状态码', + 'response_body' => '客户响应的内容', + ], + 'options' => [ + ], +]; diff --git a/lang/zh_CN/order.php b/lang/zh_CN/order.php new file mode 100644 index 0000000..25cfc8f --- /dev/null +++ b/lang/zh_CN/order.php @@ -0,0 +1,38 @@ + [ + 'Order' => '代付订单', + 'order' => '代付订单', + ], + 'fields' => [ + 'if_code' => '渠道码', + 'mch_no' => '商户号', + 'app_id' => '应用ID', + 'mch_order_no' => '商户订单号', + 'entry_type' => '入账方式', + 'amount' => '代付金额', + 'currency' => '货币代码', + 'account_no' => '收款账号', + 'account_name' => '收款人姓名', + 'bank_name' => '收款账户开户行名称', + 'bank_code' => '收款账户开户行编码', + 'client_ip' => '客户端IP', + 'transfer_desc' => '转账备注信息', + 'notify_url' => '异步通知地址', + 'ext_param' => '扩展参数', + 'channel_extra' => '渠道特殊参数', + 'state' => '转账状态', + 'transfer_id' => '转账订单号', + 'channel_order_no' => '渠道转账单号', + 'success_time' => '成功时间', + ], + 'options' => [ + 'state' => [ + 0 => '订单生成', + 1 => '转账中', + 2 => '转账成功', + 3 => '转账失败', + 4 => '转账关闭', + ], + ], +]; diff --git a/resources/views/dcat/filter/between-datetime.blade.php b/resources/views/dcat/filter/between-datetime.blade.php new file mode 100644 index 0000000..25184f6 --- /dev/null +++ b/resources/views/dcat/filter/between-datetime.blade.php @@ -0,0 +1,39 @@ +
+
+
+ +
+ {!! $label !!}  +
+ + + To + +
+
+
+ +