12 changed files with 459 additions and 2 deletions
-
4app/Admin/Controllers/MchAppController.php
-
135app/Admin/Controllers/OrderController.php
-
97app/Admin/Controllers/OrderNotifyController.php
-
6app/Admin/routes.php
-
13app/Models/Merchant.php
-
11app/Models/Order.php
-
13app/Models/OrderNotify.php
-
48database/migrations/2025_08_27_163509_create_orders_table.php
-
36database/migrations/2025_08_27_170155_create_order_notifies_table.php
-
21lang/zh_CN/order-notify.php
-
38lang/zh_CN/order.php
-
39resources/views/dcat/filter/between-datetime.blade.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'); |
|||
}); |
|||
} |
|||
} |
|||
@ -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'); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
<?php |
|||
|
|||
namespace App\Models; |
|||
|
|||
use Dcat\Admin\Traits\HasDateTimeFormatter; |
|||
use Illuminate\Database\Eloquent\Model; |
|||
|
|||
class Order extends Model |
|||
{ |
|||
use HasDateTimeFormatter; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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'); |
|||
} |
|||
}; |
|||
@ -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'); |
|||
} |
|||
}; |
|||
@ -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' => [ |
|||
], |
|||
]; |
|||
@ -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 => '转账关闭', |
|||
], |
|||
], |
|||
]; |
|||
@ -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> <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> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue