Browse Source

订单列表、推送记录

master
yangrz 5 months ago
parent
commit
935704fb97
  1. 4
      app/Admin/Controllers/MchAppController.php
  2. 135
      app/Admin/Controllers/OrderController.php
  3. 97
      app/Admin/Controllers/OrderNotifyController.php
  4. 6
      app/Admin/routes.php
  5. 13
      app/Models/Merchant.php
  6. 11
      app/Models/Order.php
  7. 13
      app/Models/OrderNotify.php
  8. 48
      database/migrations/2025_08_27_163509_create_orders_table.php
  9. 36
      database/migrations/2025_08_27_170155_create_order_notifies_table.php
  10. 21
      lang/zh_CN/order-notify.php
  11. 38
      lang/zh_CN/order.php
  12. 39
      resources/views/dcat/filter/between-datetime.blade.php

4
app/Admin/Controllers/MchAppController.php

@ -36,7 +36,7 @@ class MchAppController extends AdminController
$grid->disableEditButton(); $grid->disableEditButton();
$grid->filter(function (Grid\Filter $filter) { $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('app_id')->width(3);
$filter->equal('alipay_account')->width(3); $filter->equal('alipay_account')->width(3);
$filter->like('company_name')->width(3); $filter->like('company_name')->width(3);
@ -79,7 +79,7 @@ class MchAppController extends AdminController
if ($form->isCreating()) { if ($form->isCreating()) {
$form->select('mch_no') $form->select('mch_no')
->options(Merchant::pluck('mch_name', 'mch_no'))
->options(Merchant::getAllMerchant())
->required(); ->required();
$form->hidden('app_id'); $form->hidden('app_id');
$form->hidden('secret_key'); $form->hidden('secret_key');

135
app/Admin/Controllers/OrderController.php

@ -0,0 +1,135 @@
<?php
namespace App\Admin\Controllers;
use App\Models\Merchant;
use App\Models\Order;
use Dcat\Admin\Form;
use Dcat\Admin\Grid;
use Dcat\Admin\Show;
use Dcat\Admin\Http\Controllers\AdminController;
class OrderController extends AdminController
{
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
return Grid::make(new Order(), function (Grid $grid) {
$grid->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');
});
}
}

97
app/Admin/Controllers/OrderNotifyController.php

@ -0,0 +1,97 @@
<?php
namespace App\Admin\Controllers;
use App\Models\OrderNotify;
use Dcat\Admin\Form;
use Dcat\Admin\Grid;
use Dcat\Admin\Show;
use Dcat\Admin\Http\Controllers\AdminController;
class OrderNotifyController extends AdminController
{
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
return Grid::make(new OrderNotify(), function (Grid $grid) {
$grid->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) => '<pre>' . e($v) . '</pre>');
$show->field('push_time');
$show->field('push_body')->unescape()->as(fn ($v) => '<pre>' . e($v) . '</pre>');
$show->field('push_duration');
$show->field('response_time');
$show->field('response_code');
$show->field('response_body')->unescape()->as(fn ($v) => '<pre>' . e($v) . '</pre>');
});
}
/**
* 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');
});
}
}

6
app/Admin/routes.php

@ -2,6 +2,8 @@
use App\Admin\Controllers\MchAppController; use App\Admin\Controllers\MchAppController;
use App\Admin\Controllers\MerchantController; use App\Admin\Controllers\MerchantController;
use App\Admin\Controllers\OrderController;
use App\Admin\Controllers\OrderNotifyController;
use Illuminate\Routing\Router; use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use Dcat\Admin\Admin; use Dcat\Admin\Admin;
@ -19,4 +21,8 @@ Route::group([
$router->resource('merchant', MerchantController::class); $router->resource('merchant', MerchantController::class);
$router->resource('mch-app', MchAppController::class); $router->resource('mch-app', MchAppController::class);
$router->resource('order', OrderController::class)->only(['index', 'show']);
$router->resource('order-notify', OrderNotifyController::class)->only(['index', 'show']);
}); });

13
app/Models/Merchant.php

@ -8,4 +8,17 @@ use Illuminate\Database\Eloquent\Model;
class Merchant extends Model class Merchant extends Model
{ {
use HasDateTimeFormatter; 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;
}
} }

11
app/Models/Order.php

@ -0,0 +1,11 @@
<?php
namespace App\Models;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
use HasDateTimeFormatter;
}

13
app/Models/OrderNotify.php

@ -0,0 +1,13 @@
<?php
namespace App\Models;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Model;
class OrderNotify extends Model
{
use HasDateTimeFormatter;
public $timestamps = false;
}

48
database/migrations/2025_08_27_163509_create_orders_table.php

@ -0,0 +1,48 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('orders', function (Blueprint $table) {
$table->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');
}
};

36
database/migrations/2025_08_27_170155_create_order_notifies_table.php

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('order_notifies', function (Blueprint $table) {
$table->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');
}
};

21
lang/zh_CN/order-notify.php

@ -0,0 +1,21 @@
<?php
return [
'labels' => [
'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' => [
],
];

38
lang/zh_CN/order.php

@ -0,0 +1,38 @@
<?php
return [
'labels' => [
'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 => '转账关闭',
],
],
];

39
resources/views/dcat/filter/between-datetime.blade.php

@ -0,0 +1,39 @@
<div class="filter-input col-sm-{{ $width }}" style="{!! $style !!}">
<div class="form-group">
<div class="input-group input-group-sm">
<div class="input-group-prepend">
<span class="input-group-text bg-white text-capitalize"><b>{!! $label !!}</b>&nbsp;<i class="feather icon-calendar"></i></span>
</div>
<input autocomplete="off" type="text" class="form-control" id="{{$id['start']}}" placeholder="{{$label}}" name="{{$name['start']}}" value="{{ request($name['start'], \Illuminate\Support\Arr::get($value, 'start')) }}">
<span class="input-group-addon" style="border-left: 0; border-right: 0;">To</span>
<input autocomplete="off" type="text" class="form-control" id="{{$id['end']}}" placeholder="{{$label}}" name="{{$name['end']}}" value="{{ request($name['end'], \Illuminate\Support\Arr::get($value, 'end')) }}">
</div>
</div>
</div>
<script require="@moment,@bootstrap-datetimepicker">
var options = {!! admin_javascript_json($dateOptions) !!};
$('#{{ $id['start'] }}').datetimepicker(options);
$('#{{ $id['end'] }}').datetimepicker($.extend(options, {useCurrent: false}));
$("#{{ $id['start'] }}").on("dp.change", function (e) {
if (e.oldDate === null && options.format === 'YYYY-MM-DD HH:mm:ss') {
$(this).data("DateTimePicker").date(e.date.format('YYYY-MM-DD') + ' 00:00:00');
}
if ($(this).val() > $("#{{ $id['end'] }}").val()) {
$("#{{ $id['end'] }}").val('');
}
//$('#{{ $id['end'] }}').data("DateTimePicker").minDate(e.date);
});
$("#{{ $id['end'] }}").on("dp.change", function (e) {
if (e.oldDate === null && options.format === 'YYYY-MM-DD HH:mm:ss') {
$(this).data("DateTimePicker").date(e.date.format('YYYY-MM-DD') + ' 23:59:59');
}
if ($(this).val() < $("#{{ $id['start'] }}").val()) {
$("#{{ $id['start'] }}").val('');
}
//$('#{{ $id['start'] }}').data("DateTimePicker").maxDate(e.date);
});
</script>
Loading…
Cancel
Save