This commit is contained in:
2023-05-16 11:24:14 +08:00
43 changed files with 2317 additions and 380 deletions

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Admin\Actions\Coupon;
use App\Jobs\CheckCouponByLog;
use App\Jobs\CheckCouponLog;
use Carbon\Carbon;
use Encore\Admin\Actions\Action;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
class RefreshPAOrder extends Action
{
public $name = '刷新平安订单id';
protected $selector = '.refresh-order';
public function handle(Request $request): \Encore\Admin\Actions\Response
{
$month = $request->month;
$month = Carbon::parse($month)->format('Ym');
$table = 'api_log_'.$month;
if (! Schema::hasColumn($table, 'coupon_no')) {
Schema::table($table, function (Blueprint $table) {
$table->string('coupon_no')->after('out_source')->nullable();
});
}
CheckCouponLog::dispatch($table);
CheckCouponByLog::dispatch($table, 10);
return $this->response()->success('正在获取数据,请等待片刻后刷新页面查看!')->refresh();
}
public function form()
{
$this->date('month', '月份')->format('YYYY-MM');
}
public function html()
{
return <<<HTML
<a class="btn btn-sm btn-default refresh-order "><i class="fa fa-refresh"></i> 刷新平安订单id</a>
HTML;
}
}

View File

@@ -0,0 +1,115 @@
<?php
namespace App\Admin\Actions\Coupon;
use App\Admin\Imports\SettleCouponImport;
use Encore\Admin\Actions\Action;
use Encore\Admin\Admin;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
class SettleCoupon extends Action
{
public $name = '结算数据';
protected $selector = '.check-coupon';
public function handle(Request $request): \Encore\Admin\Actions\Response
{
try {
Excel::import(new SettleCouponImport(), request()->file('file'));
} catch (\Exception $exception) {
return $this->response()->swal()->error($exception->getMessage());
}
return $this->response()->swal()->success('上传成功')->refresh();
}
public function form()
{
$this->file('file', '请选择文件')
->options([
'showPreview' => false,
'allowedFileExtensions' => ['xlsx', 'xls', 'csv'],
'showUpload' => true,
])
->required();
}
public function html(): string
{
return <<<HTML
<a class="btn btn-sm btn-default import-action check-coupon">导入已结算数据</a>
HTML;
}
/**
* 上传等待
*
* @return string
*/
public function handleActionPromise(): string
{
$resolve = <<<SCRIPT
var actionResolverss = function (data) {
$('.modal-footer').show()
$('.tips').remove()
var response = data[0];
var target = data[1];
if (typeof response !== 'object') {
return $.admin.swal({type: 'error', title: 'Oops!'});
}
var then = function (then) {
if (then.action == 'refresh') {
$.admin.reload();
}
if (then.action == 'download') {
window.open(then.value, '_blank');
}
if (then.action == 'redirect') {
$.admin.redirect(then.value);
}
};
if (typeof response.html === 'string') {
target.html(response.html);
}
if (typeof response.swal === 'object') {
$.admin.swal(response.swal);
}
if (typeof response.toastr === 'object') {
$.admin.toastr[response.toastr.type](response.toastr.content, '', response.toastr.options);
}
if (response.then) {
then(response.then);
}
};
var actionCatcherss = function (request) {
$('.modal-footer').show()
$('.tips').remove()
if (request && typeof request.responseJSON === 'object') {
$.admin.toastr.error(request.responseJSON.message, '', {positionClass:"toast-bottom-center", timeOut: 10000}).css("width","500px")
}
};
SCRIPT;
Admin::script($resolve);
return <<<SCRIPT
$('.modal-footer').hide()
let html = `<div class='tips' style='color: red;font-size: 18px;'>导入时间取决于数据量,请耐心等待结果不要关闭窗口!<img src="data:image/gif;base64,R0lGODlhEAAQAPQAAP///1VVVfr6+np6eqysrFhYWG5ubuPj48TExGNjY6Ojo5iYmOzs7Lq6utjY2ISEhI6OjgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAAFUCAgjmRpnqUwFGwhKoRgqq2YFMaRGjWA8AbZiIBbjQQ8AmmFUJEQhQGJhaKOrCksgEla+KIkYvC6SJKQOISoNSYdeIk1ayA8ExTyeR3F749CACH5BAkKAAAALAAAAAAQABAAAAVoICCKR9KMaCoaxeCoqEAkRX3AwMHWxQIIjJSAZWgUEgzBwCBAEQpMwIDwY1FHgwJCtOW2UDWYIDyqNVVkUbYr6CK+o2eUMKgWrqKhj0FrEM8jQQALPFA3MAc8CQSAMA5ZBjgqDQmHIyEAIfkECQoAAAAsAAAAABAAEAAABWAgII4j85Ao2hRIKgrEUBQJLaSHMe8zgQo6Q8sxS7RIhILhBkgumCTZsXkACBC+0cwF2GoLLoFXREDcDlkAojBICRaFLDCOQtQKjmsQSubtDFU/NXcDBHwkaw1cKQ8MiyEAIfkECQoAAAAsAAAAABAAEAAABVIgII5kaZ6AIJQCMRTFQKiDQx4GrBfGa4uCnAEhQuRgPwCBtwK+kCNFgjh6QlFYgGO7baJ2CxIioSDpwqNggWCGDVVGphly3BkOpXDrKfNm/4AhACH5BAkKAAAALAAAAAAQABAAAAVgICCOZGmeqEAMRTEQwskYbV0Yx7kYSIzQhtgoBxCKBDQCIOcoLBimRiFhSABYU5gIgW01pLUBYkRItAYAqrlhYiwKjiWAcDMWY8QjsCf4DewiBzQ2N1AmKlgvgCiMjSQhACH5BAkKAAAALAAAAAAQABAAAAVfICCOZGmeqEgUxUAIpkA0AMKyxkEiSZEIsJqhYAg+boUFSTAkiBiNHks3sg1ILAfBiS10gyqCg0UaFBCkwy3RYKiIYMAC+RAxiQgYsJdAjw5DN2gILzEEZgVcKYuMJiEAOwAAAAAAAAAAAA=="><\/div>`
$('.modal-header').append(html)
process.then(actionResolverss).catch(actionCatcherss);
SCRIPT;
}
}

View File

@@ -13,7 +13,7 @@ class CouponController extends AdminController
protected $title = '卡券列表管理'; protected $title = '卡券列表管理';
protected function grid() protected function grid(): Grid
{ {
$grid = new Grid(new ActivityCoupon); $grid = new Grid(new ActivityCoupon);
$grid->model()->with(['outlet'])->latest(); $grid->model()->with(['outlet'])->latest();
@@ -24,6 +24,11 @@ class CouponController extends AdminController
$filter->column(1 / 2, function ($filter) { $filter->column(1 / 2, function ($filter) {
$filter->equal('status', '状态')->select(ActivityCoupon::STATUS); $filter->equal('status', '状态')->select(ActivityCoupon::STATUS);
$filter->between('used_at', '核销时间')->datetime(); $filter->between('used_at', '核销时间')->datetime();
<<<<<<< HEAD
=======
>>>>>>> a7719d7038809738262e66c70e301947845f680d
$filter->where(function ($query) { $filter->where(function ($query) {
$query->whereHas('outlet', function ($query) { $query->whereHas('outlet', function ($query) {
$query->whereHas('info', function ($query) { $query->whereHas('info', function ($query) {
@@ -52,7 +57,11 @@ class CouponController extends AdminController
}) })
->get() ->get()
->pluck('nickname', 'id'); ->pluck('nickname', 'id');
<<<<<<< HEAD
=======
>>>>>>> a7719d7038809738262e66c70e301947845f680d
$filter->where(function ($query) { $filter->where(function ($query) {
$query->whereHas('outlet', function ($query) { $query->whereHas('outlet', function ($query) {
$query->whereHas('parent', function ($query) { $query->whereHas('parent', function ($query) {

View File

@@ -2,6 +2,8 @@
namespace App\Admin\Controllers\Activity; namespace App\Admin\Controllers\Activity;
use App\Admin\Renderable\Activity\Grants;
use App\Admin\Renderable\Activity\Verifications;
use App\Models\Activity; use App\Models\Activity;
use App\Models\ActivityRule; use App\Models\ActivityRule;
use App\Models\User; use App\Models\User;
@@ -18,7 +20,7 @@ class IndexController extends AdminController
protected function grid(): Grid protected function grid(): Grid
{ {
$grid = new Grid(new Activity); $grid = new Grid(new Activity);
$grid->model()->withCount('coupons'); $grid->model()->with(['rule', 'grants', 'verifications'])->withCount('coupons');
$grid->actions(function ($actions) { $grid->actions(function ($actions) {
$actions->disableView(); $actions->disableView();
@@ -28,15 +30,14 @@ class IndexController extends AdminController
$filter->column(1 / 2, function ($filter) { $filter->column(1 / 2, function ($filter) {
$filter->equal('status', '状态')->select(Activity::STATUS); $filter->equal('status', '状态')->select(Activity::STATUS);
$filter->equal('type', '类型')->select(Activity::TYPES); $filter->equal('type', '类型')->select(Activity::TYPES);
$filter->equal('code', '活动编号');
}); });
$filter->column(1 / 2, function ($filter) { $filter->column(1 / 2, function ($filter) {
$filter->between('start_at', '开始时间')->datetime(); $filter->between('start_at', '开始时间')->datetime();
$filter->between('end_at', '结束时间')->datetime(); $filter->between('end_at', '结束时间')->datetime();
$filter->equal('channel', '核销途径')->select(Activity::CHANNELS); $filter->equal('channel', '核销途径')->select(Activity::CHANNELS);
}); });
}); });
$grid->column('id', '#ID#'); $grid->column('id', '#ID#');
@@ -48,13 +49,13 @@ class IndexController extends AdminController
$grid->column('类型')->display(function () { $grid->column('类型')->display(function () {
return $this->type_text; return $this->type_text;
}); });
$grid->column('channel', '核销途径') $grid->column('channel', '核销途径')
->using(Activity::CHANNELS) ->using(Activity::CHANNELS)
->label([ ->label([
Activity::CHANNEL_YSD => 'info', Activity::CHANNEL_YSD => 'info',
Activity::CHANNEL_UNION => 'success', Activity::CHANNEL_UNION => 'success',
]); ]);
<<<<<<< HEAD
$grid->column('days', '延期(天)'); $grid->column('days', '延期(天)');
$grid->column('rule.full', '满足金额'); $grid->column('rule.full', '满足金额');
@@ -74,6 +75,17 @@ class IndexController extends AdminController
->label() ->label()
->width(350) ->width(350)
->hide(); ->hide();
=======
$grid->column('days', '延期(天)');
$grid->column('rule.full', '满足金额');
$grid->column('rule.take', '扣除金额');
$grid->column('发券渠道')->display(function ($title, $column) {
return '查看';
})->modal(Grants::class);
$grid->column('核券渠道')->display(function ($title, $column) {
return '查看';
})->modal(Verifications::class);
>>>>>>> a7719d7038809738262e66c70e301947845f680d
$grid->column('开始时间')->display(function () { $grid->column('开始时间')->display(function () {
return $this->type == Activity::TYPE_SCOPE ? $this->start_at->format('Y-m-d') : '---'; return $this->type == Activity::TYPE_SCOPE ? $this->start_at->format('Y-m-d') : '---';
@@ -123,7 +135,10 @@ class IndexController extends AdminController
->when(Activity::TYPE_SCOPE, function (Form $form) { ->when(Activity::TYPE_SCOPE, function (Form $form) {
$form->dateRange('start_at', 'end_at', '有效时间'); $form->dateRange('start_at', 'end_at', '有效时间');
}) })
<<<<<<< HEAD
->help('当月券,领取的月底到期') ->help('当月券,领取的月底到期')
=======
>>>>>>> a7719d7038809738262e66c70e301947845f680d
->required(); ->required();
$form->radio('channel', '核销途径') $form->radio('channel', '核销途径')
@@ -131,8 +146,11 @@ class IndexController extends AdminController
->default(Activity::CHANNEL_YSD) ->default(Activity::CHANNEL_YSD)
->help('券码核销的途径亿时代是自己核销银联是银联pos核销') ->help('券码核销的途径亿时代是自己核销银联是银联pos核销')
->required(); ->required();
<<<<<<< HEAD
$form->number('day_times','每天可用次数')->default(0)->help('每天可用次数0未不限制'); $form->number('day_times','每天可用次数')->default(0)->help('每天可用次数0未不限制');
=======
>>>>>>> a7719d7038809738262e66c70e301947845f680d
$form->switch('status', '状态')->default(1); $form->switch('status', '状态')->default(1);
$form->switch('need_check', '多次校验') $form->switch('need_check', '多次校验')

View File

@@ -2,7 +2,6 @@
namespace App\Admin\Controllers\Activity; namespace App\Admin\Controllers\Activity;
use App\Admin\Renderable\Activity\Grants;
use App\Models\ActivityCouponLog; use App\Models\ActivityCouponLog;
use Encore\Admin\Controllers\HasResourceActions; use Encore\Admin\Controllers\HasResourceActions;
use Encore\Admin\Grid; use Encore\Admin\Grid;
@@ -18,19 +17,21 @@ class LogController extends AdminController
/** /**
* Get content title. * Get content title.
*
* @return string * @return string
*/ */
protected function title() protected function title(): string
{ {
return $this->title; return $this->title;
} }
/** /**
* Index interface. * Index interface.
*
* @param Content $content * @param Content $content
* @return Content * @return Content
*/ */
public function index(Content $content) public function index(Content $content): Content
{ {
return $content return $content
->title($this->title()) ->title($this->title())
@@ -38,7 +39,7 @@ class LogController extends AdminController
->body($this->grid()); ->body($this->grid());
} }
protected function grid() protected function grid(): Grid
{ {
$grid = new Grid(new ActivityCouponLog); $grid = new Grid(new ActivityCouponLog);
@@ -54,35 +55,30 @@ class LogController extends AdminController
$filter->column(1 / 2, function ($filter) { $filter->column(1 / 2, function ($filter) {
$filter->equal('status', '状态')->select(ActivityCouponLog::STATUS); $filter->equal('status', '状态')->select(ActivityCouponLog::STATUS);
$filter->between('created_at', '开始时间')->datetime(); $filter->between('created_at', '开始时间')->datetime();
}); });
}); });
$grid->column('id', '#ID#'); $grid->column('id', '#ID#');
$grid->column('code', '卡券编号'); $grid->column('code', '卡券编号');
$grid->column('type', '分类') $grid->column('type', '分类')
->using(ActivityCouponLog::TYPES) ->using(ActivityCouponLog::TYPES)
->label([ ->label([
1 => 'default', 1 => 'default',
2 => 'warning', 2 => 'warning',
3 => 'info', 3 => 'info',
]); ]);
$grid->column('status', '状态') $grid->column('status', '状态')
->using(ActivityCouponLog::STATUS) ->using(ActivityCouponLog::STATUS)
->label([ ->label([
1 => 'default', 1 => 'default',
2 => 'warning', 2 => 'warning',
3 => 'info', 3 => 'info',
]); ]);
$grid->column('remark', '处理结果'); $grid->column('remark', '处理结果');
$grid->column('created_at', '操作时间'); $grid->column('created_at', '操作时间');
return $grid; return $grid;
} }
} }

View File

@@ -12,10 +12,9 @@ use RuLong\Identity\Models\Identity;
class RuleController extends AdminController class RuleController extends AdminController
{ {
protected $title = '规则管理'; protected $title = '规则管理';
protected function grid() protected function grid(): Grid
{ {
$grid = new Grid(new ActivityRule); $grid = new Grid(new ActivityRule);
@@ -34,15 +33,15 @@ class RuleController extends AdminController
]); ]);
$grid->column('created_at', '创建时间'); $grid->column('created_at', '创建时间');
return $grid; return $grid;
} }
/** /**
* Make a form builder. * Make a form builder.
*
* @return Form * @return Form
*/ */
protected function form() protected function form(): Form
{ {
$form = new Form(new ActivityRule); $form = new Form(new ActivityRule);
@@ -58,7 +57,7 @@ class RuleController extends AdminController
$code = $form->code; $code = $form->code;
$ticket = explode('-', $code); $ticket = explode('-', $code);
if (!is_array($ticket) || count($ticket) != 3) { if (! is_array($ticket) || count($ticket) != 3) {
$error = new MessageBag([ $error = new MessageBag([
'title' => '错误', 'title' => '错误',
'message' => '规则编号格式错误', 'message' => '规则编号格式错误',
@@ -79,5 +78,4 @@ class RuleController extends AdminController
return $form; return $form;
} }
} }

View File

@@ -2,6 +2,7 @@
namespace App\Admin\Controllers\Coupon; namespace App\Admin\Controllers\Coupon;
use App\Admin\Actions\Coupon\RefreshPAOrder;
use App\Models\ActivityRule; use App\Models\ActivityRule;
use App\Models\Coupon; use App\Models\Coupon;
use App\Models\User; use App\Models\User;
@@ -15,6 +16,7 @@ class IndexController extends AdminController
/** /**
* Notes: * Notes:
*
* @Author: <C.Jason> * @Author: <C.Jason>
* @Date : 2019/9/18 14:50 * @Date : 2019/9/18 14:50
* @return Grid * @return Grid
@@ -26,10 +28,14 @@ class IndexController extends AdminController
$grid->disableBatchActions(); $grid->disableBatchActions();
$grid->disableActions(); $grid->disableActions();
$grid->tools(function (Grid\Tools $tools) {
$tools->append(new refreshPAOrder());//刷新平安订单id
});
$grid->model() $grid->model()
->with(['outlet.province', 'outlet.city', 'outlet.district', 'user', 'user.info']) ->with(['outlet.province', 'outlet.city', 'outlet.district', 'user', 'user.info'])
->whereIn('status', [2, 3]) ->whereIn('status', [2, 3])
->orderBy('id', 'desc'); ->orderBy('id', 'desc');
$grid->filter(function ($filter) { $grid->filter(function ($filter) {
$filter->column(1 / 2, function ($filter) { $filter->column(1 / 2, function ($filter) {
@@ -44,6 +50,7 @@ class IndexController extends AdminController
$filter->equal('user_id', '渠道')->select($users); $filter->equal('user_id', '渠道')->select($users);
$filter->equal('thirdPartyGoodsId', '优惠政策')->select(ActivityRule::pluck('title', 'code')); $filter->equal('thirdPartyGoodsId', '优惠政策')->select(ActivityRule::pluck('title', 'code'));
$filter->like('couponName', '优惠政策名');
}); });
$filter->column(1 / 2, function ($filter) { $filter->column(1 / 2, function ($filter) {
$filter->like('redemptionCode', '卡券编号'); $filter->like('redemptionCode', '卡券编号');
@@ -56,6 +63,8 @@ class IndexController extends AdminController
}, '网点名称'); }, '网点名称');
$filter->equal('type', '类型')->select(Coupon::TYPES); $filter->equal('type', '类型')->select(Coupon::TYPES);
$filter->like('pa_order_id', '平安主订单号');
$filter->like('pa_sub_order_id', '平安子订单号');
}); });
}); });
@@ -64,11 +73,11 @@ class IndexController extends AdminController
return $this->user->nickname; return $this->user->nickname;
}); });
$grid->column('type', '类型') $grid->column('type', '类型')
->using(Coupon::TYPES) ->using(Coupon::TYPES)
->label([ ->label([
'1' => 'info', '1' => 'info',
'2' => 'success', '2' => 'success',
]); ]);
$grid->column('网点名称/编号')->display(function () { $grid->column('网点名称/编号')->display(function () {
return $this->outlet ? $this->outlet->nickname : $this->outletId; return $this->outlet ? $this->outlet->nickname : $this->outletId;
@@ -79,19 +88,21 @@ class IndexController extends AdminController
$grid->column('price', '核销金额'); $grid->column('price', '核销金额');
$grid->column('total', '订单金额'); $grid->column('total', '订单金额');
$grid->column('orderid', '订单id'); $grid->column('orderid', '订单id');
$grid->column('pa_order_id', '平安主订单号');
$grid->column('pa_sub_order_id', '平安子订单号')->hide();
$grid->column('资金通道结算')->display(function () { $grid->column('资金通道结算')->display(function () {
$profit = $this->status == 2 ? $this->profit : '0.00'; $profit = $this->status == 2 ? $this->profit : '0.00';
return '<span style="color:red">' . $profit . '</span>'; return '<span style="color:red">'.$profit.'</span>';
}); });
$grid->column('状态')->display(function () { $grid->column('状态')->display(function () {
switch ($this->status) { switch ($this->status) {
case 2: case 2:
return '<span style="color:green">' . $this->status_text . '</span>'; return '<span style="color:green">'.$this->status_text.'</span>';
break; break;
case 3: case 3:
return '<span style="color:red">' . $this->status_text . '</span>'; return '<span style="color:red">'.$this->status_text.'</span>';
break; break;
default: default:
return $this->status_text; return $this->status_text;
@@ -119,17 +130,17 @@ class IndexController extends AdminController
// $all = $query->get(); // $all = $query->get();
// $pass = $all->where('status', 2)->all(); // $pass = $all->where('status', 2)->all();
// $pass = collect($pass); // $pass = collect($pass);
$total = $query->count(); $total = (clone $query)->count();
$success = $query->where('status', 2)->count(); $success = (clone $query)->where('status', 2)->count();
$faield = $total - $success; $faield = $total - $success;
return '<label class="label label-success">全部:' . $total . '张</label>&nbsp;&nbsp;' return '<label class="label label-success">全部:'.$total.'张</label>&nbsp;&nbsp;'
. '<label class="label label-success">成功:' . $success . '张</label>&nbsp;&nbsp;' .'<label class="label label-success">成功:'.$success.'张</label>&nbsp;&nbsp;'
. '<label class="label label-success">失败:' . $faield . '张</label>&nbsp;&nbsp;' .'<label class="label label-success">失败:'.$faield.'张</label>&nbsp;&nbsp;'
. '<label class="label label-success">核销金额:' . $query->sum('price') . '元</label>&nbsp;&nbsp;' .'<label class="label label-success">核销金额:'.(clone $query)->sum('price').'元</label>&nbsp;&nbsp;'
. '<label class="label label-success">资金通道结算:' . $query->sum('profit') . '元</label>&nbsp;&nbsp;' .'<label class="label label-success">资金通道结算:'.(clone $query)->sum('profit').'元</label>&nbsp;&nbsp;'
. '<label class="label label-success">打款金额:' . $query->where('is_profit', 1) .'<label class="label label-success">打款金额:'.(clone $query)->where('is_profit', 1)
->sum('profit') . '元</label>&nbsp;&nbsp;'; ->sum('profit').'元</label>&nbsp;&nbsp;';
}); });
$grid->disableExport(false); $grid->disableExport(false);
@@ -141,13 +152,13 @@ class IndexController extends AdminController
return strip_tags($value); return strip_tags($value);
}); });
$export->column('redemptionCode', function ($value, $original) { $export->column('redemptionCode', function ($value, $original) {
return $value . "\t"; return $value."\t";
}); });
// $export->column('price', function ($value, $original) { // $export->column('price', function ($value, $original) {
// return $value . "\t"; // return $value . "\t";
// }); // });
$export->column('orderid', function ($value, $original) { $export->column('orderid', function ($value, $original) {
return $value . "\t"; return $value."\t";
}); });
// $export->column('total', function ($value, $original) { // $export->column('total', function ($value, $original) {
// return $value . "\t"; // return $value . "\t";
@@ -155,7 +166,7 @@ class IndexController extends AdminController
$export->column('资金通道结算', function ($value, $original) { $export->column('资金通道结算', function ($value, $original) {
return strip_tags($value); return strip_tags($value);
}); });
$export->filename('卡券列表' . date("YmdHis")); $export->filename('卡券列表'.date("YmdHis"));
}); });
return $grid; return $grid;

View File

@@ -0,0 +1,55 @@
<?php
namespace App\Admin\Controllers\Coupon;
use App\Admin\Actions\Coupon\SettleCoupon;
use App\Models\ActivityRule;
use App\Models\Coupon;
use App\Models\CouponPaCheck;
use App\Models\User;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Grid;
class PaCouponController extends AdminController
{
protected $title = '未找到数据';
/**
* Notes:
*
* @Author: <C.Jason>
* @Date : 2019/9/18 14:50
* @return Grid
*/
protected function grid(): Grid
{
$grid = new Grid(new CouponPaCheck());
$grid->disableCreateButton();
$grid->disableBatchActions();
$grid->disableActions();
$grid->model()->oldest('id');
$grid->filter(function ($filter) {
$filter->column(1 / 2, function ($filter) {
$filter->equal('pa_order_id', '平安主订单号');
});
});
$grid->column('id', '#ID#');
$grid->column('pa_order_id', '平安主订单号');
$grid->disableExport(false);
$grid->export(function ($export) {
$export->filename($this->title.date("YmdHis"));
});
return $grid;
}
}

View File

@@ -0,0 +1,145 @@
<?php
namespace App\Admin\Controllers\Coupon;
use App\Admin\Actions\Coupon\SettleCoupon;
use App\Models\ActivityRule;
use App\Models\Coupon;
use App\Models\User;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Grid;
class SettleCouponController extends AdminController
{
protected $title = '平安券核销列表';
/**
* Notes:
*
* @Author: <C.Jason>
* @Date : 2019/9/18 14:50
* @return Grid
*/
protected function grid(): Grid
{
$grid = new Grid(new Coupon);
$grid->disableCreateButton();
$grid->disableBatchActions();
$grid->disableActions();
$grid->tools(function (Grid\Tools $tools) {
$tools->append(new SettleCoupon());//上传等待校验数据
});
$grid->model()
->where('type', 1)
->with(['outlet.province', 'outlet.city', 'outlet.district', 'user', 'user.info'])
->where('status', 2)
->orderBy('id', 'desc');
$grid->filter(function ($filter) {
$filter->column(1 / 2, function ($filter) {
$filter->between('created_at', '核销时间')->datetime();
$users = User::whereHas('identity', function ($query) {
$query->where('identity_id', 1);
})->get()->pluck('nickname', 'id');
$filter->equal('user_id', '渠道')->select($users);
$filter->equal('thirdPartyGoodsId', '优惠政策')->select(ActivityRule::pluck('title', 'code'));
$filter->like('couponName', '优惠政策名');
});
$filter->column(1 / 2, function ($filter) {
$filter->like('redemptionCode', '卡券编号');
$filter->where(function ($query) {
$query->whereHas('outlet', function ($query) {
$query->whereHas('info', function ($query) {
$query->where('nickname', 'like', "%{$this->input}%");
});
});
}, '网点名称');
$filter->like('pa_order_id', '平安主订单号');
$filter->equal('is_settle', '是否结算')->select(Coupon::SETTLES);
});
});
$grid->column('id', '#ID#');
$grid->column('渠道')->display(function () {
return $this->user->nickname;
});
$grid->column('type', '类型')
->using(Coupon::TYPES)
->label([
'1' => 'info',
'2' => 'success',
]);
$grid->column('网点名称/编号')->display(function () {
return $this->outlet ? $this->outlet->nickname : $this->outletId;
});
$grid->column('redemptionCode', '卡券编号');
$grid->column('couponName', '优惠政策');
$grid->column('price', '核销金额');
$grid->column('total', '订单金额');
$grid->column('orderid', '订单id');
$grid->column('pa_order_id', '平安主订单号');
$grid->column('pa_sub_order_id', '平安子订单号')->hide();
$grid->column('is_settle', '是否结算')->bool();
$grid->column('资金通道结算')->display(function () {
$profit = $this->status == 2 ? $this->profit : '0.00';
return '<span style="color:red">'.$profit.'</span>';
});
$grid->column('startTime', '起始时间')->hide();
$grid->column('endTime', '到期时间')->hide();
$grid->column('created_at', '核销时间');
$grid->column('省')->display(function () {
return ($this->outlet && $this->outlet->province) ? $this->outlet->province->name : '';
});
$grid->column('市')->display(function () {
return ($this->outlet && $this->outlet->province) ? $this->outlet->city->name : '';
});
$grid->column('区')->display(function () {
return ($this->outlet && $this->outlet->province) ? $this->outlet->district->name : '';
});
$grid->footer(function ($query) {
$total = (clone $query)->count();
$no = (clone $query)->where('is_settle', 0)->count();
$yes = $total - $no;
return '<label class="label label-success">全部:'.$total.'张</label>&nbsp;&nbsp;'
.'<label class="label label-success">已结算:'.$yes.'张</label>&nbsp;&nbsp;'
.'<label class="label label-success">未结算:'.$no.'张</label>&nbsp;&nbsp;';
});
$grid->disableExport(false);
$grid->export(function ($export) {
$export->column('type', function ($value, $original) {
return strip_tags($value);
});
$export->column('redemptionCode', function ($value, $original) {
return $value."\t";
});
$export->column('orderid', function ($value, $original) {
return $value."\t";
});
$export->column('资金通道结算', function ($value, $original) {
return strip_tags($value);
});
$export->filename($this->title.date("YmdHis"));
});
return $grid;
}
}

View File

@@ -0,0 +1,111 @@
<?php
namespace App\Admin\Controllers;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use XuanChen\Petro;
use XuanChen\PetroYsd;
use XuanChen\PetroYsd\Kernel\Event\CouponNotice;
class PetroController
{
public function index(Request $request)
{
try {
$coupon = PetroYsd\Kernel\Models\PetroYsdCoupon::find($request->coupon_id);
dump($coupon);
event(new CouponNotice($coupon));
dd(1);
// dd(
// base64_decode('6buR6b6Z5rGfNuWFg+ayueWTgea1i+ivleWIuA==')
// );
// $res = PetroYsd::Invalid()
// ->setParams([
// 'requestId' => Str::random(32),
// 'couponId' => '2830025247791780434',
// 'couponType' => 0,
// ])->start();
//
// dd($res);
// $res = PetroYsd::Query()
// ->setParams([
// 'requestId' => Str::random(32),
// 'thirdOrderId' => 'B6Q1rzCITRretxUFkIlFUtEciW7kNnq5',
// ])->start();
//
// dd($res);
// $res = PetroYsd::Detail()
// ->setParams([
// 'requestId' => Str::random(32),
// 'couponId' => '2830025247791780426',
// 'couponType' => 0,
// ])->start();
//
// dd($res);
$res = PetroYsd::Grant()->setParams([
'requestId' => Str::random(32),
'productNo' => 'hljlt_hlj6yypcs',
'mobile' => '15663876870',
'num' => 1,
'notifyUrl' => route('petro_new.grant_notice'),
'thirdOrderId' => Str::random(32),
])->start();
dd($res);
dd('老板程序');
//获取动态码
// $res = Petro::Check()->setParams([
// 'ticketNum' => '61578832475977235',
// 'random' => Str::random(6),
// ])->start();
//
// dd($res);
// $res = Petro::Bill()->setParams([
// 'matchDate' => Carbon::now()->format('Ymd'),
// 'pageNo' => 1,
// 'dzmaxResult' => 1000,
// 'random' => Str::random(6),
// ])->start();
// dd($res);
// dd('作废');
// $res = Petro::Invalid()->setParams([
// 'cxcouponNo' => '61578832475977235',
// 'random' => Str::random(6),
// ])->start();
// dd($res);
// dd('查询');
$res = Petro::Detail()->setParams([
'couponNo' => '61578832475977235',
'random' => Str::random(6),
])->start();
//
dd($res);
// $grant = [
// 'requestCode' => 'Z591xRQ9fv1u',
// 'tradeId' => 111222,
// 'ticketSum' => 1,
// 'amount' => 10,
// 'random' => Str::random(6),
// ];
//
// $res = Petro::Grant()->setParams($grant)->start();
// dd($res);
} catch (\Exception $exception) {
dd('error'.$exception->getMessage());
}
}
}

View File

@@ -2,65 +2,73 @@
namespace App\Admin\Controllers; namespace App\Admin\Controllers;
use App\Jobs\CheckCouponByLog;
use App\Jobs\CheckCouponLog;
use App\Models\Coupon; use App\Models\Coupon;
use App\Models\Log;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;
use XuanChen\Coupon\Action\pingan\Verification;
class TestController class TestController
{ {
public function index(Request $request) public function index(Request $request)
{ {
$str = Str::uuid();
$date = $request->date ?? date('Y-m-d'); $date = $request->date ?? date('Y-m-d');
$time = Carbon::parse($date); $time = Carbon::parse($date);
$all = Coupon::where('status', 2) $all = Coupon::where('status', 2)
->whereBetween('created_at', [ ->whereBetween('created_at', [
$time->startOfDay()->toDateTimeString(), $time->startOfDay()->toDateTimeString(),
$time->endOfDay()->toDateTimeString(), $time->endOfDay()->toDateTimeString(),
]) ])
->count(); ->count();
$self = Coupon::where('status', 2) $self = Coupon::where('status', 2)
->where('type', Coupon::TYPE_YSD) ->where('type', Coupon::TYPE_YSD)
->whereBetween('created_at', [ ->whereBetween('created_at', [
$time->startOfDay()->toDateTimeString(), $time->startOfDay()->toDateTimeString(),
$time->endOfDay()->toDateTimeString(), $time->endOfDay()->toDateTimeString(),
]) ])
->count(); ->count();
$pingan = Coupon::where('status', 2) $pingan = Coupon::where('status', 2)
->where('type', Coupon::TYPE_PINGAN) ->where('type', Coupon::TYPE_PINGAN)
->whereBetween('created_at', [ ->whereBetween('created_at', [
$time->startOfDay()->toDateTimeString(), $time->startOfDay()->toDateTimeString(),
$time->endOfDay()->toDateTimeString(), $time->endOfDay()->toDateTimeString(),
]) ])
->count(); ->count();
$error = Coupon::where('status', 3) $error = Coupon::where('status', 3)
->whereBetween('created_at', [ ->whereBetween('created_at', [
$time->startOfDay()->toDateTimeString(), $time->startOfDay()->toDateTimeString(),
$time->endOfDay()->toDateTimeString(), $time->endOfDay()->toDateTimeString(),
]) ])
->count(); ->count();
$lists = DB::table('coupons') $lists = DB::table('coupons')
->where('status', 2) ->where('status', 2)
->whereBetween('created_at', [ ->whereBetween('created_at', [
$time->startOfDay()->toDateTimeString(), $time->startOfDay()->toDateTimeString(),
$time->endOfDay()->toDateTimeString(), $time->endOfDay()->toDateTimeString(),
]) ])
->select('redemptionCode', DB::raw('COUNT(*) as code_count')) ->select('redemptionCode', DB::raw('COUNT(*) as code_count'))
->groupBy('redemptionCode') ->groupBy('redemptionCode')
->having('code_count', '>', 1) ->having('code_count', '>', 1)
->get(); ->get();
$data = [ $data = [
' 日期为:' . $time->format('Y-m-d'), ' 日期为:'.$time->format('Y-m-d'),
' 核销总数为:' . $all, ' 核销总数为:'.$all,
' 自有卡券总数为:' . $self, ' 自有卡券总数为:'.$self,
' 平安卡券总数为:' . $pingan, ' 平安卡券总数为:'.$pingan,
' 核销错误总数为:' . $error, ' 核销错误总数为:'.$error,
' 核销重复数据数为:' . $lists->count(), ' 核销重复数据数为:'.$lists->count(),
]; ];
foreach ($data as $info) { foreach ($data as $info) {
@@ -69,4 +77,122 @@ class TestController
} }
/**
* Notes: 设置日志关联
*
* @Author: 玄尘
* @Date: 2022/1/19 11:12
* @param \Illuminate\Http\Request $request
*/
public function coupon(Request $request)
{
$type = $request->type ?? '';
$date = $request->date ?? '';
if (! $type) {
dd('type 错误');
}
if (! $date) {
dd('date 错误');
}
$name = 'api_log_'.$date;//表名
if (! Schema::hasTable($name)) {
dd('数据表不存在');
}
if (! Schema::hasColumn($name, 'coupon_no')) {
Schema::table($name, function (Blueprint $table) {
$table->string('coupon_no')->after('out_source')->nullable();
});
}
/**
* 设置日志
*/
if ($type == 'log') {
(new Log())->setTable($name)
->whereNull('coupon_no')
->where('path', 'http://api.pingan.com.cn/open/vassPartner/appsvr/property/api/new/partner/redemption')
->where('out_source->code', 200)
->chunkById(1000, function ($logs) use ($name) {
foreach ($logs as $log) {
$data = (new Verification())->decrypt($log->in_source['json']['data']);
$data = json_decode($data, true);
$log->update([
'coupon_no' => $data['couponNo']
]);
}
});
dd($name.' 表日志设置完成');
}
if ($type == 'coupon') {
(new Log())->setTable($name)
->whereHas('coupon', function ($q) {
$q->whereNull('pa_order_id');
})
->where('path', 'http://api.pingan.com.cn/open/vassPartner/appsvr/property/api/new/partner/redemption')
->where('out_source->code', 200)
->chunkById(1000, function ($logs) use ($name) {
foreach ($logs as $log) {
$log->coupon->update([
'pa_order_id' => $log->out_source['data']['orderId'],
'pa_sub_order_id' => $log->out_source['data']['subOrderId'],
]);
}
});
dd($name.' 表关联的优惠券设置完成');
}
dd(1);
}
/**
* Notes: 设置数据
*
* @Author: 玄尘
* @Date: 2022/1/19 13:29
*/
public function checkCouponLog(Request $request)
{
$type = $request->type ?? '';
if (! $type) {
dd('type 错误');
}
$tables = DB::connection()->getDoctrineSchemaManager()->listTableNames();
foreach ($tables as $table) {
if (Str::contains($table, 'api_log_')) {
echo " 开始处理 ".$table." <br>";
if (! Schema::hasColumn($table, 'coupon_no')) {
Schema::table($table, function (Blueprint $table) {
$table->string('coupon_no')->after('out_source')->nullable();
});
}
if ($type == 'log') {
CheckCouponLog::dispatch($table);
}
if ($type == 'coupon') {
CheckCouponByLog::dispatch($table);
}
}
}
}
} }

View File

@@ -29,7 +29,7 @@ class IndexController extends AdminController
* @Date : 2019/9/18 14:50 * @Date : 2019/9/18 14:50
* @return Grid * @return Grid
*/ */
protected function grid() protected function grid(): Grid
{ {
$user = Auth::guard('admin')->user(); $user = Auth::guard('admin')->user();

View File

@@ -0,0 +1,288 @@
<?php
namespace App\Admin\Exporters;
use Encore\Admin\Grid\Exporters\ExcelExporter;
class NewCouponExport extends ExcelExporter
{
protected $fileName = null;
protected $debug = false;
protected $dealColumnList = [];
protected $columnCallback = null;
protected $addColumnList = [];
protected $appendColumn = [];
protected $perLimit = 1500;
/**
* 导出
*
* @return mixed|void
*/
public function export()
{
$model = $this;
$grid = $this->grid;
$columns = $this->getColumns();
$columns = $this->addingColumn($columns);
$call_back = function ($page, $limit) use ($model, $grid, $columns) {
$model->page = $page;
$grid->paginate($limit);
$model->setGrid($grid);
request()->offsetSet('per_page', $limit);
$list = $model->getQuery()->get()->toArray();
$list = $this->dealColumn($columns, $list);
if ($this->columnCallback) {
$list = call_user_func($this->columnCallback, $columns, $list);
}
return $list;
};
if ($this->debug) {
dd($columns, call_user_func($call_back, 1, 20));
}
$file_name = $this->fileName ? $this->fileName : $this->getTable().date('YmdHis');
$data_count = $this->getQuery()->count();
$perPage = request()->get('per_page', $this->perLimit);
$this->exportCsv($file_name, $columns, $call_back, $data_count, $perPage);
}
/**
* 设置文件名
*
* @param null $file_name
*/
public function setName($file_name = null)
{
if ($file_name) {
$this->fileName = $file_name;
}
}
/**
* Notes: 设置处理字段值的规则
*
* @Author: 玄尘
* @Date: 2023/2/1 15:42
* @param $column
* @param \Closure $call_back
*/
public function setColumn($column, \Closure $call_back)
{
$this->dealColumnList[$column] = $call_back;
}
/**
* 添加字段
*
* @param $column
* @param $name
* @param null|string|\Closure $after_column
* @param null|\Closure $call_back
*/
public function addColumn($column, $name, $after_column = null, $call_back = null)
{
if ($after_column instanceof \Closure) {
$this->addColumnList[$column] = $after_column;
$this->appendColumn[$column] = [$name, null];
} else {
if ($call_back instanceof \Closure) {
$this->addColumnList[$column] = $call_back;
$this->appendColumn[$column] = [$name, $after_column];
} else {
$this->appendColumn[$column] = [$name, $after_column];
}
}
}
/**
* 正式追加字段
*
* @param $columns
* @return array
*/
protected function addingColumn($columns): array
{
if (! $this->appendColumn) {
return $columns;
}
$keys = array_keys($columns);
foreach ($this->appendColumn as $column => $item) {
list ($name, $after_column) = $item;
if (! empty($after_column) && in_array($after_column, $keys)) {
$index = array_search($after_column, $keys);
array_splice($keys, $index + 1, 0, $column);
} else {
array_push($keys, $column);
}
$columns[$column] = $name;
}
$result = [];
foreach ($keys as $column) {
$result[$column] = $columns[$column] ?? $column;
}
return $result;
}
/**
* 字段值重新处理 回调函数
*
* @param \Closure $call_back
*/
public function setList(\Closure $call_back)
{
$this->columnCallback = $call_back;
}
/**
* 处理有共同特征的字段值
*
* @param $columns
* @param $list
* @return mixed
*/
protected function dealColumn($columns, $list)
{
if (! $list) {
return $list;
}
$deal = array_keys($this->dealColumnList);
$add = array_keys($this->addColumnList);
foreach ($list as $index => $data) {
foreach ($columns as $column => $name) {
switch ($column) {
case strpos($column, '.') !== false :
$keys = explode('.', $column);
$value = $data;
for ($i = 0; $i < count($keys); $i++) {
$value = $value[$keys[$i]] ?? [];
}
if (is_array($value)) {
$value = empty($value) ? '' : json_encode($value, JSON_UNESCAPED_UNICODE);
}
$data[$column] = $value;
break;
}
if ($this->dealColumnList && in_array($column, $deal)) {
$data[$column] = call_user_func_array($this->dealColumnList[$column],
[$data[$column] ?? '', $data]);
}
if ($this->addColumnList && in_array($column, $add)) {
$data[$column] = call_user_func($this->addColumnList[$column], $data);
}
}
$list[$index] = $data;
}
return $list;
}
/**
* 获取选中的导出字段
*
* @return array
*/
protected function getColumns(): array
{
$columns = [];
foreach ($this->grid->getColumns() as $column) {
$columns[$column->getName()] = $column->getLabel();
}
$column_string = request()->get('_columns_', '');
if (! $column_string) {
return $columns;
}
$column_array = explode(',', $column_string);
$column_list = [];
foreach ($columns as $column => $name) {
if (in_array($column, $column_array)) {
$column_list[$column] = $name;
}
}
return $column_list;
}
/**
* 打印
*/
public function dd()
{
$this->debug = true;
}
/**
* 导出CSV
*
* @param string $file_name 文件名
* @param array $head_list 表头
* @param int $data_count 总数
* @param int $page_limit 每页数量
* @param \Closure $call_back 获取分页数据的回调函数
*/
function exportCsv(
string $file_name,
array $head_list,
\Closure $call_back,
int $data_count,
int $page_limit = 0
) {
set_time_limit(0);
ini_set('memory_limit', -1);
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="'.$file_name.'.csv"');
header('Cache-Control: max-age=0');
//打开PHP文件句柄,php://output 表示直接输出到浏览器
$fp = fopen('php://output', 'a');
$head = [];
//输出Excel列名信息
foreach ($head_list as $name) {
//CSV的Excel支持GBK编码一定要转换否则乱码
$head[] = iconv('utf-8', 'gbk', $name);
}
//将数据通过fputcsv写到文件句柄
fputcsv($fp, $head);
$page_limit = $data_count > $page_limit ? $page_limit : $data_count;
$page_count = ceil($data_count / $page_limit);
for ($page = 1; $page <= $page_count; $page++) {
//逐页取出数据,不浪费内存
$data_list = call_user_func($call_back, $page, $page_limit);
if (! $data_list) {
continue;
}
foreach ($data_list as $data) {
$row = [];
foreach ($head_list as $key => $name) {
$value = $data[$key] ?? '';
$row[] = iconv('utf-8', 'gbk', $value);
}
fputcsv($fp, $row);
unset($row);
}
//刷新一下输出buffer防止由于数据过多内存不足
ob_flush();
flush();
info($page.'/'.$page_count.' time= '.$this->getElapsedTime().' memory= '.$this->getMemoryUsage());
}
fclose($fp);
exit();
}
public function getElapsedTime(int $decimals = 2): string
{
return number_format(microtime(true) - request()->server('REQUEST_TIME_FLOAT'), $decimals).' s';
}
public function getMemoryUsage($precision = 2): string
{
$size = memory_get_usage(true);
$unit = ['b', 'kb', 'mb', 'gb', 'tb', 'pb'];
return round($size / pow(1024, ($i = floor(log($size, 1024)))), $precision).' '.$unit[$i];
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace App\Admin\Imports;
use App\Models\Coupon;
use App\Models\CouponPaCheck;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\SkipsErrors;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithStartRow;
class SettleCouponImport implements ToModel, WithStartRow, WithChunkReading, WithBatchInserts
{
use Importable, SkipsErrors;
public $chunk = 5000;
/**
* @param array $row
* @return \Illuminate\Database\Eloquent\Model|null
* @throws \Exception
*/
public function model(array $row)
{
try {
$order_id = trim($row[0]);
$exists = Coupon::query()->where('pa_order_id', $order_id)->exists();
if ($exists) {
Coupon::query()->where('pa_order_id', $order_id)->update([
'is_settle' => 1
]);
} else {
$exists = CouponPaCheck::query()->where('pa_order_id', $order_id)->exists();
if (! $exists) {
CouponPaCheck::create([
'pa_order_id' => $order_id
]);
}
}
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
/**
* 从第几行开始处理数据 就是不处理标题
*
* @return int
*/
public function startRow(): int
{
return 2;
}
/**
* Notes: 批量导入1000条
*
* @Author: 玄尘
* @Date : 2020/11/23 13:40
* @return int
*/
public function chunkSize(): int
{
return $this->chunk;
}
/**
* Notes: 以1000条数据基准切割数据
*
* @Author: 玄尘
* @Date : 2020/11/23 13:41
* @return int
*/
public function batchSize(): int
{
return $this->chunk;
}
}

View File

@@ -18,9 +18,11 @@ class Grants implements Renderable
'nickname' => $info->user_nickname, 'nickname' => $info->user_nickname,
]; ];
}); });
dd($items->toArray());
return new Table(['Id', '渠道'], $items->toArray()); $table = new Table(['Id', '渠道'], $items->toArray());
return $table->render();
} }
} }

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Admin\Renderable\Activity;
use App\Models\Activity;
use Encore\Admin\Widgets\Table;
use Illuminate\Contracts\Support\Renderable;
class Verifications implements Renderable
{
public function render($key = null)
{
$activity = Activity::find($key);
$items = $activity->verifications->map(function ($info) {
return [
'id' => $info->id,
'nickname' => $info->user_nickname,
];
});
$table = new Table(['Id', '渠道'], $items->toArray());
return $table->render();
}
}

View File

@@ -5,7 +5,7 @@ use Encore\Admin\Form;
use Encore\Admin\Grid; use Encore\Admin\Grid;
//Form::forget(['map', 'editor']); //Form::forget(['map', 'editor']);
Form::extend('editor', WangEditor::class); //Form::extend('editor', WangEditor::class);
Form::init(function (Form $form) { Form::init(function (Form $form) {
$form->disableEditingCheck(); $form->disableEditingCheck();

View File

@@ -12,6 +12,9 @@ Route::group([
$router->get('/', 'HomeController@index')->name('admin.home'); $router->get('/', 'HomeController@index')->name('admin.home');
$router->get('test', 'TestController@index')->name('test.index'); $router->get('test', 'TestController@index')->name('test.index');
$router->get('test/coupon', 'TestController@coupon');
$router->get('test/check_coupon_log', 'TestController@checkCouponLog');
$router->get('petro', 'PetroController@index');
$router->post('uploads/editor', 'UploadController@editor')->name('uploads.editor'); $router->post('uploads/editor', 'UploadController@editor')->name('uploads.editor');
@@ -35,6 +38,8 @@ Route::group([
*/ */
$router->resource('logs', 'Log\IndexController'); $router->resource('logs', 'Log\IndexController');
$router->resource('coupons', 'Coupon\IndexController'); //平安卡券 $router->resource('coupons', 'Coupon\IndexController'); //平安卡券
$router->resource('settle_coupons', 'Coupon\SettleCouponController'); //平安结算数据
$router->resource('pa_coupons', 'Coupon\PaCouponController'); //平安未找到数据
$router->resource('wos', 'Wo\IndexController'); //沃钱包业务 $router->resource('wos', 'Wo\IndexController'); //沃钱包业务
/** /**

View File

@@ -23,7 +23,7 @@ class UserController extends Controller
public function check(Request $request) public function check(Request $request)
{ {
$res = $this->checkSign($request); $res = $this->checkSign($request);
if (!is_array($res)) { if (! is_array($res)) {
return $this->error($res); return $this->error($res);
} }
$user_id = $res['user_id']; $user_id = $res['user_id'];
@@ -34,6 +34,7 @@ class UserController extends Controller
/** /**
* Notes: 发券 * Notes: 发券
*
* @Author: 玄尘 * @Author: 玄尘
* @Date : 2020/6/29 13:57 * @Date : 2020/6/29 13:57
*/ */
@@ -75,9 +76,10 @@ class UserController extends Controller
/** /**
* Notes: 查询 * Notes: 查询
*
* @Author: 玄尘 * @Author: 玄尘
* @Date : 2020/7/22 11:23 * @Date : 2020/7/22 11:23
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
*/ */
public function query(Request $request) public function query(Request $request)
{ {
@@ -106,13 +108,43 @@ class UserController extends Controller
$redemptionCode = $res['redemptionCode']; $redemptionCode = $res['redemptionCode'];
$outletId = $res['outletId']; $outletId = $res['outletId'];
$res = Coupon::Query($redemptionCode, $outletId); try {
$res = Coupon::Query($redemptionCode, $outletId);
if (is_string($res)) { if (is_string($res)) {
return $this->error($res, $log); return $this->error($res, $log);
}
if (isset($res['productItemList'])) {
$ticket = explode('-', $res['productItemList'][0]['thirdPartyGoodsId']);
$full = $ticket[1]; //full100
$price = $ticket[2];
preg_match('/\d+/', $full, $result);
$status = [
0 => 1,
1 => 2,
2 => 2,
3 => 3,
4 => 3,
][$res['status']];
$res = [
'name' => $res['couponName'],
'code' => $res['redemptionCode'],
'full' => $result[0],
'price' => $price,
'status' => $status,
'used_at' => $res['issueDate'],
'startTime' => $res['startTime'],
'endTime' => $res['endTime'],
];
}
return $this->success($res, $log);
} catch (\Exception $exception) {
return $this->error($exception->getMessage(), $log);
} }
return $this->success($res, $log);
} }
//作废 //作废
@@ -160,7 +192,7 @@ class UserController extends Controller
//插入日志表 //插入日志表
$log = $this->createLog($request->url(), 'POST', $inputdata, 'freezecoupon'); //添加日志 $log = $this->createLog($request->url(), 'POST', $inputdata, 'freezecoupon'); //添加日志
if (!is_array($res)) { if (! is_array($res)) {
return $this->error($res, $log); return $this->error($res, $log);
} }

View File

@@ -19,5 +19,4 @@ Route::group(['prefix' => 'V1'], function () {
Route::post('ticket/grant180', 'WoController@grant180'); //发券 Route::post('ticket/grant180', 'WoController@grant180'); //发券
Route::post('ticket/cancel', 'WoController@cancel'); //退业务 Route::post('ticket/cancel', 'WoController@cancel'); //退业务
Route::post('ticket/query', 'WoController@query'); //退业务 Route::post('ticket/query', 'WoController@query'); //退业务
}); });

View File

@@ -23,6 +23,7 @@ class ToolsController extends Controller
/** /**
* Notes: 发券 * Notes: 发券
*
* @Author: 玄尘 * @Author: 玄尘
* @Date : 2020/6/29 13:57 * @Date : 2020/6/29 13:57
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
@@ -52,7 +53,7 @@ class ToolsController extends Controller
'activityId' => $request->activityId, 'activityId' => $request->activityId,
'mobile' => $request->mobile, 'mobile' => $request->mobile,
]; ];
$url = $this->baseUrl . 'user/grant'; $url = $this->baseUrl.'user/grant';
return $this->getResult($input_data, $url); return $this->getResult($input_data, $url);
@@ -60,6 +61,7 @@ class ToolsController extends Controller
/** /**
* Notes: 查询 * Notes: 查询
*
* @Author: 玄尘 * @Author: 玄尘
* @Date : 2021/4/25 9:57 * @Date : 2021/4/25 9:57
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
@@ -87,7 +89,7 @@ class ToolsController extends Controller
'redemptionCode' => $request->redemptionCode, 'redemptionCode' => $request->redemptionCode,
]; ];
$url = $this->baseUrl . 'user/query'; $url = $this->baseUrl.'user/query';
return $this->getResult($input_data, $url); return $this->getResult($input_data, $url);
@@ -95,6 +97,7 @@ class ToolsController extends Controller
/** /**
* Notes: 卡券作废 * Notes: 卡券作废
*
* @Author: 玄尘 * @Author: 玄尘
* @Date : 2021/4/25 10:08 * @Date : 2021/4/25 10:08
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
@@ -121,13 +124,14 @@ class ToolsController extends Controller
'redemptionCode' => $request->redemptionCode, 'redemptionCode' => $request->redemptionCode,
]; ];
$url = $this->baseUrl . 'user/destroy'; $url = $this->baseUrl.'user/destroy';
return $this->getResult($input_data, $url); return $this->getResult($input_data, $url);
} }
/** /**
* Notes: 核销 * Notes: 核销
*
* @Author: 玄尘 * @Author: 玄尘
* @Date : 2020/6/29 14:01 * @Date : 2020/6/29 14:01
*/ */
@@ -162,7 +166,7 @@ class ToolsController extends Controller
'from' => $request->from ?? '', 'from' => $request->from ?? '',
]; ];
$url = $this->baseUrl . 'user/freezecoupon'; $url = $this->baseUrl.'user/freezecoupon';
return $this->getResult($input_data, $url); return $this->getResult($input_data, $url);
@@ -170,6 +174,7 @@ class ToolsController extends Controller
/** /**
* Notes: 总执行 * Notes: 总执行
*
* @Author: 玄尘 * @Author: 玄尘
* @Date : 2021/4/25 10:00 * @Date : 2021/4/25 10:00
* @param $data * @param $data
@@ -186,6 +191,7 @@ class ToolsController extends Controller
'getElapsedTime' => $this->getElapsedTime(), 'getElapsedTime' => $this->getElapsedTime(),
'getMemoryUsage' => $this->getMemoryUsage(), 'getMemoryUsage' => $this->getMemoryUsage(),
'ret' => $res, 'ret' => $res,
'api_input_data' => $this->api_input_data,
'raw_data' => $this->decode($res), 'raw_data' => $this->decode($res),
]; ];
@@ -210,6 +216,7 @@ class ToolsController extends Controller
/** /**
* Notes: 加密 * Notes: 加密
*
* @Author: 玄尘 * @Author: 玄尘
* @Date : 2021/4/25 9:46 * @Date : 2021/4/25 9:46
* @param $input * @param $input
@@ -222,19 +229,20 @@ class ToolsController extends Controller
$addcode = sprintf("%08d", mt_rand(0, 99999999)); //随机code 验证签名用 $addcode = sprintf("%08d", mt_rand(0, 99999999)); //随机code 验证签名用
$sign = $this->keysign($ascdata, $addcode); $sign = $this->keysign($ascdata, $addcode);
$data = [ $data = [
'server_id' => $this->user->server_id, 'server_id' => $this->user->server_id,
'key' => $this->user->server_key, 'key' => $this->user->server_key,
'addcode' => $addcode, 'addcode' => $addcode,
'sign' => $sign, 'sign' => $sign,
'data' => $ascdata, 'data' => $ascdata,
]; ];
$this->api_input_data = $data;
return $data; return $data;
} }
/** /**
* Notes: 解密 * Notes: 解密
*
* @Author: 玄尘 * @Author: 玄尘
* @Date : 2021/4/25 10:07 * @Date : 2021/4/25 10:07
* @param $res * @param $res
@@ -254,6 +262,7 @@ class ToolsController extends Controller
/*** /***
* Notes: 使用的内存 * Notes: 使用的内存
*
* @Author: 玄尘 * @Author: 玄尘
* @Date : 2021/4/25 9:45 * @Date : 2021/4/25 9:45
* @param int $precision * @param int $precision
@@ -265,11 +274,12 @@ class ToolsController extends Controller
$unit = ['b', 'kb', 'mb', 'gb', 'tb', 'pb']; $unit = ['b', 'kb', 'mb', 'gb', 'tb', 'pb'];
return round($size / pow(1024, ($i = floor(log($size, 1024)))), $precision) . ' ' . $unit[$i]; return round($size / pow(1024, ($i = floor(log($size, 1024)))), $precision).' '.$unit[$i];
} }
/** /**
* Notes: 代码执行时间 * Notes: 代码执行时间
*
* @Author: 玄尘 * @Author: 玄尘
* @Date : 2021/4/25 9:45 * @Date : 2021/4/25 9:45
* @param int $decimals * @param int $decimals
@@ -277,7 +287,7 @@ class ToolsController extends Controller
*/ */
public function getElapsedTime(int $decimals = 2): string public function getElapsedTime(int $decimals = 2): string
{ {
return number_format(microtime(true) - request()->server('REQUEST_TIME_FLOAT'), $decimals) . ' s'; return number_format(microtime(true) - request()->server('REQUEST_TIME_FLOAT'), $decimals).' s';
} }
} }

View File

@@ -0,0 +1,68 @@
<?php
namespace App\Jobs;
use App\Models\Log;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
class CheckCouponByLog implements ShouldQueue
{
use Dispatchable, InteractsWithQueue;
public $queue = 'LISTENER';
public $delay = 0;
public $tries = 1;
public $timeout = 30;
protected $table;
public function __construct(string $table, int $delay = 0)
{
$this->table = $table;
$this->delay = $delay;
}
public function handle()
{
info(__CLASS__.' 开始处理 '.$this->table);
$count = (new Log())->setTable($this->table)
->whereHas('coupon', function ($q) {
$q->whereNull('pa_order_id');
})
->where('path',
'http://api.pingan.com.cn/open/vassPartner/appsvr/property/api/new/partner/redemption')
->where('out_source->code', 200)
->count();
if ($count > 0) {
(new Log())->setTable($this->table)
->whereHas('coupon', function ($q) {
$q->whereNull('pa_order_id');
})
->where('path',
'http://api.pingan.com.cn/open/vassPartner/appsvr/property/api/new/partner/redemption')
->where('out_source->code', 200)
->chunkById(1000, function ($logs) {
foreach ($logs as $log) {
$log->coupon->update([
'pa_order_id' => $log->out_source['data']['orderId'],
'pa_sub_order_id' => $log->out_source['data']['subOrderId'],
]);
}
});
}
info(__CLASS__.' '.$this->table.' 成功处理 '.$count);
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace App\Jobs;
use App\Models\Log;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use XuanChen\Coupon\Action\pingan\Verification;
class CheckCouponLog implements ShouldQueue
{
use Dispatchable, InteractsWithQueue;
public $queue = 'LISTENER';
public $delay = 0;
public $tries = 1;
public $timeout = 30;
protected $table;
public function __construct(string $table)
{
$this->table = $table;
}
public function handle()
{
info(__CLASS__.' 开始处理 '.$this->table);
$count = (new Log())->setTable($this->table)
->whereNull('coupon_no')
->where('path',
'http://api.pingan.com.cn/open/vassPartner/appsvr/property/api/new/partner/redemption')
->where('out_source->code', 200)
->count();
if ($count > 0) {
(new Log())->setTable($this->table)
->whereNull('coupon_no')
->where('path',
'http://api.pingan.com.cn/open/vassPartner/appsvr/property/api/new/partner/redemption')
->where('out_source->code', 200)
->chunkById(1000, function ($logs) {
foreach ($logs as $log) {
$data = (new Verification())->decrypt($log->in_source['json']['data']);
$data = json_decode($data, true);
$log->update([
'coupon_no' => $data['couponNo']
]);
}
});
}
info(__CLASS__.' '.$this->table.' 成功处理 '.$count);
}
}

View File

@@ -6,75 +6,84 @@ use App\Merchant\Controllers\Controller;
use App\Models\ActivityRule; use App\Models\ActivityRule;
use App\Models\Coupon; use App\Models\Coupon;
use Auth; use Auth;
use Carbon\Carbon;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class IndexController extends Controller class IndexController extends Controller
{ {
protected $query;
public function index(Request $request) public function index(Request $request)
{ {
$user = Auth::guard('merchant')->user(); $user = Auth::guard('merchant')->user();
$action = $request->action ?? 'search'; $action = $request->action ?? 'search';
$rules = ActivityRule::get();
if ($request->start) {
$request->start = $request->start.' 00:00:00';
}
if ($request->end) {
$request->end = $request->end.' 23:59:59';
}
$outlet = $request->outlet;
$status = $request->status;
$redemptionCode = $request->redemptionCode;
$start = $request->start;
$end = $request->end;
$thirdPartyGoodsId = $request->thirdPartyGoodsId;
$pa_order_id = $request->pa_order_id;
$type = $request->type;
$this->query = Coupon::where('user_id', $user->id)
->when($outlet, function ($q) use ($outlet) {
$q->whereHas('outlet', function ($q) use ($outlet) {
$q->whereHas('info', function ($q) use ($outlet) {
$q->where('nickname', 'like', "%{$outlet}%");
});
});
})
->when($redemptionCode, function ($q) use ($redemptionCode) {
$q->where('redemptionCode', $redemptionCode);
})
->when($type == 'pingan', function ($q) {
$q->where('type', 1);
})
->when($thirdPartyGoodsId, function ($q) use ($thirdPartyGoodsId) {
$q->where('thirdPartyGoodsId', $thirdPartyGoodsId);
})
->when($pa_order_id, function ($q) use ($pa_order_id) {
$q->where('pa_order_id', $pa_order_id);
})
->when(is_numeric($status), function ($query) use ($status) {
$query->where('status', $status);
}, function ($query) {
$query->whereIn('status', [2, 3]);
})
->when($start && $end, function ($query) use ($start, $end) {
$query->whereBetween('created_at', [$start, $end]);
})
->when($start && ! $end, function ($query) use ($start) {
$query->where('created_at', '>', $start);
})
->when(! $start && $end, function ($query) use ($end) {
$query->where('created_at', '<', $end);
})
->orderBy('created_at', 'desc')
->orderBy('id', 'desc');
if ($action == 'search') { if ($action == 'search') {
$rules = ActivityRule::get();
if ($request->start) {
$request->start = $request->start . ' 00:00:00';
}
if ($request->end) {
$request->end = $request->end . ' 23:59:59';
}
$outlet = $request->outlet;
$status = $request->status;
$redemptionCode = $request->redemptionCode;
$start = $request->start;
$end = $request->end;
$thirdPartyGoodsId = $request->thirdPartyGoodsId;
$coupons = Coupon::where('user_id', $user->id)
->when($outlet, function ($q) use ($outlet) {
$q->whereHas('outlet', function ($q) use ($outlet) {
$q->whereHas('info', function ($q) use ($outlet) {
$q->where('nickname', 'like', "%{$outlet}%");
});
});
})
->when($redemptionCode, function ($q) use ($redemptionCode) {
$q->where('redemptionCode', $redemptionCode);
})
->when($thirdPartyGoodsId, function ($q) use ($thirdPartyGoodsId) {
$q->where('thirdPartyGoodsId', $thirdPartyGoodsId);
})
->when(is_numeric($status), function ($query) use ($status) {
if ($status == 4) {
$query->where('is_profit', 1);
} else {
$query->where('status', $status);
}
}, function ($query) {
$query->whereIn('status', [2, 3]);
})
->when($start && $end, function ($query) use ($start, $end) {
$query->whereBetween('created_at', [$start, $end]);
})
->when($start && !$end, function ($query) use ($start) {
$query->where('created_at', '>', $start);
})
->when(!$start && $end, function ($query) use ($end) {
$query->where('created_at', '<', $end);
})
->orderBy('created_at', 'desc')->orderBy('id', 'desc')->paginate();
$data = [ $data = [
'all' => $this->getData($request, 'all', $user), 'all' => $this->getData($request, 'all', $user),
'pass' => $this->getData($request, 'pass', $user), 'pass' => $this->getData($request, 'pass', $user),
'reject' => $this->getData($request, 'reject', $user), 'reject' => $this->getData($request, 'reject', $user),
]; ];
$coupons = (clone $this->query)->paginate();
return view('Merchant::coupon.index', compact('coupons', 'data', 'rules')); return view('Merchant::coupon.index', compact('coupons', 'data', 'rules'));
} else { } else {
@@ -84,9 +93,10 @@ class IndexController extends Controller
/** /**
* 按照日期分润 * 按照日期分润
* @author 玄尘 2020-03-11 *
* @param Request $request [description] * @param Request $request [description]
* @return array|\Illuminate\Contracts\View\Factory|\Illuminate\View\View * @return array|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @author 玄尘 2020-03-11
*/ */
public function profits(Request $request) public function profits(Request $request)
{ {
@@ -100,9 +110,9 @@ class IndexController extends Controller
return $this->error('分润失败!没有可处理的数据'); return $this->error('分润失败!没有可处理的数据');
} }
if (Coupon::where('user_id', $user->id) if (Coupon::where('user_id', $user->id)
->whereDate('created_at', $date) ->whereDate('created_at', $date)
->where('status', 2) ->where('status', 2)
->update(['status' => 4])) { ->update(['status' => 4])) {
return $this->success('分润成功!'); return $this->success('分润成功!');
} else { } else {
return $this->error('分润失败!'); return $this->error('分润失败!');
@@ -115,9 +125,10 @@ class IndexController extends Controller
/** /**
* 分润 * 分润
* @author 玄尘 2020-03-11 *
* @param Coupon $coupon [description] * @param Coupon $coupon [description]
* @return [type] [description] * @return [type] [description]
* @author 玄尘 2020-03-11
*/ */
public function profit(Coupon $coupon) public function profit(Coupon $coupon)
{ {
@@ -137,95 +148,13 @@ class IndexController extends Controller
switch ($type) { switch ($type) {
case 'all': case 'all':
return Coupon::where('user_id', $user->id) return (clone $this->query)->count();
->when($request->outlet, function ($q) use ($request) {
$q->whereHas('outlet', function ($q) use ($request) {
$q->whereHas('info', function ($q) use ($request) {
$q->where('nickname', 'like', "%{$request->outlet}%");
});
});
})
->when($request->redemptionCode, function ($q) use ($request) {
$q->where('redemptionCode', $request->redemptionCode);
})
->when($request->thirdPartyGoodsId, function ($q) use ($request) {
$q->where('thirdPartyGoodsId', $request->thirdPartyGoodsId);
})
->when(is_numeric($request->status), function ($query) use ($request) {
$query->where('status', $request->status);
}, function ($query) {
$query->whereIn('status', [2, 3]);
})
->when($request->start && $request->end, function ($query) use ($request) {
$query->whereBetween('created_at', [$request->start, $request->end]);
})
->when($request->start, function ($query) use ($request) {
$query->where('created_at', '>', $request->start);
})
->when($request->end, function ($query) use ($request) {
$query->where('created_at', '<', $request->end);
})
->count();
break; break;
case 'pass': case 'pass':
return Coupon::where('user_id', $user->id) return (clone $this->query)->where('status', 2)->count();
->when($request->outlet, function ($q) use ($request) {
$q->whereHas('outlet', function ($q) use ($request) {
$q->whereHas('info', function ($q) use ($request) {
$q->where('nickname', 'like', "%{$request->outlet}%");
});
});
})
->when($request->redemptionCode, function ($q) use ($request) {
$q->where('redemptionCode', $request->redemptionCode);
})
->when($request->thirdPartyGoodsId, function ($q) use ($request) {
$q->where('thirdPartyGoodsId', $request->thirdPartyGoodsId);
})
->when(is_numeric($request->status), function ($query) use ($request) {
$query->where('status', $request->status);
})
->where('status', 2)
->when($request->start && $request->end, function ($query) use ($request) {
$query->whereBetween('created_at', [$request->start, $request->end]);
})
->when($request->start, function ($query) use ($request) {
$query->where('created_at', '>', $request->start);
})
->when($request->end, function ($query) use ($request) {
$query->where('created_at', '<', $request->end);
})
->count();
break; break;
case 'reject': case 'reject':
return Coupon::where('user_id', $user->id) return (clone $this->query)->where('status', 3)->count();
->when($request->outlet, function ($q) use ($request) {
$q->whereHas('outlet', function ($q) use ($request) {
$q->whereHas('info', function ($q) use ($request) {
$q->where('nickname', 'like', "%{$request->outlet}%");
});
});
})
->when($request->redemptionCode, function ($q) use ($request) {
$q->where('redemptionCode', $request->redemptionCode);
})
->when($request->thirdPartyGoodsId, function ($q) use ($request) {
$q->where('thirdPartyGoodsId', $request->thirdPartyGoodsId);
})
->when(is_numeric($request->status), function ($query) use ($request) {
$query->where('status', $request->status);
})
->where('status', 3)
->when($request->start && $request->end, function ($query) use ($request) {
$query->whereBetween('updated_at', [$request->start, $request->end]);
})
->when($request->start, function ($query) use ($request) {
$query->where('updated_at', '>', $request->start);
})
->when($request->end, function ($query) use ($request) {
$query->where('updated_at', '<', $request->end);
})
->count();
break; break;
default: default:
return 0; return 0;
@@ -238,61 +167,34 @@ class IndexController extends Controller
//导出数据 //导出数据
public function excel($request, $user) public function excel($request, $user)
{ {
if (!$request->end) { if (! $request->end) {
$request->end = now()->toDateTimeString(); $request->end = now()->toDateTimeString();
} }
set_time_limit(0); set_time_limit(0);
ini_set('memory_limit', '1024M'); ini_set('memory_limit', '1024M');
$filename = '卡券记录' . date('YmdHis') . '.csv'; $filename = '卡券记录'.date('YmdHis').'.csv';
$response = function () use ($user, $request) { $response = function () use ($user, $request) {
$handle = fopen('php://output', 'w'); $handle = fopen('php://output', 'w');
$titles = ['ID', '网点名称', '平安券编号', '优惠政策', '核销金额', '订单id', '状态', '处理结果', '核销时间']; $titles = ['id', '网点名称', '平安券编号', '优惠政策', '核销金额', '平安主订单号', '状态', '处理结果', '核销时间'];
fputcsv($handle, $titles); fputcsv($handle, $titles);
Coupon::where('user_id', $user->id) $this->query
->when($request->outlet, function ($q) use ($request) { ->latest()
$q->whereHas('outlet', function ($q) use ($request) { ->chunk(5000, function ($coupons) use ($handle) {
$q->whereHas('info', function ($q) use ($request) { foreach ($coupons as $index => $info) {
$q->where('nickname', 'like', "%{$request->outlet}%"); fputcsv($handle, [
}); $info->id,
}); $info->outlet ? $info->outlet->nickname : 'Id:'.$info->outletId,
}) $info->redemptionCode."\t",
->when($request->redemptionCode, function ($q) use ($request) { ' '.$info->couponName,
$q->where('redemptionCode', $request->redemptionCode); $info->price."\t",
}) $info->pa_order_id,
->when($request->thirdPartyGoodsId, function ($q) use ($request) { $info->status_text,
$q->where('thirdPartyGoodsId', $request->thirdPartyGoodsId); $info->remark,
}) $info->created_at,
->when(is_numeric($request->status), function ($query) use ($request) { ]);
$query->where('status', $request->status); }
}, function ($query) { });
$query->whereIn('status', [2, 3]);
})
->when($request->start && $request->end, function ($query) use ($request) {
$query->whereBetween('updated_at', [$request->start, $request->end]);
})
->when($request->start, function ($query) use ($request) {
$query->where('updated_at', '>', $request->start);
})
->when($request->end, function ($query) use ($request) {
$query->where('updated_at', '<', $request->end);
})
->latest()
->chunk(5000, function ($coupons) use ($handle) {
foreach ($coupons as $index => $info) {
fputcsv($handle, [
$info->id,
$info->outlet ? $info->outlet->nickname : 'Id:' . $info->outletId,
$info->redemptionCode . "\t",
' ' . $info->couponName,
$info->price . "\t",
$info->orderid,
$info->status_text,
$info->remark,
$info->created_at,
]);
}
});
fclose($handle); fclose($handle);
}; };

View File

@@ -45,6 +45,11 @@
class="input-sm form-control" value="{{ Request::input('redemptionCode') }}"> class="input-sm form-control" value="{{ Request::input('redemptionCode') }}">
</div> </div>
<div class="form-group">
<input type="text" placeholder="平安主订单号" name="pa_order_id"
class="input-sm form-control" value="{{ Request::input('pa_order_id') }}">
</div>
<div class="form-group"> <div class="form-group">
<select class="form-control m-b" name="status"> <select class="form-control m-b" name="status">
<option value="">状态</option> <option value="">状态</option>
@@ -53,6 +58,16 @@
{{-- <option value="4" @if(request()->status==4) selected="" @endif >已分润</option> --}} {{-- <option value="4" @if(request()->status==4) selected="" @endif >已分润</option> --}}
</select> </select>
</div> </div>
<div class="form-group">
<select class="form-control m-b" name="type">
<option value="">类型</option>
<option value="all" @if(request()->type=='all') selected="" @endif >全部</option>
<option value="pingan" @if(request()->type=='pingan') selected="" @endif >平安
</option>
</select>
</div>
<div class="form-group"> <div class="form-group">
<select class="form-control m-b" name="thirdPartyGoodsId"> <select class="form-control m-b" name="thirdPartyGoodsId">
<option value="">政策</option> <option value="">政策</option>
@@ -105,7 +120,7 @@
<th>平安券编号</th> <th>平安券编号</th>
<th>优惠政策</th> <th>优惠政策</th>
<th>核销金额</th> <th>核销金额</th>
<th>订单id</th> <th>平安主订单号</th>
<th>状态</th> <th>状态</th>
<th>处理结果</th> <th>处理结果</th>
<th>核销时间</th> <th>核销时间</th>
@@ -121,7 +136,8 @@
<td>{{ $coupon->redemptionCode }}</td> <td>{{ $coupon->redemptionCode }}</td>
<td>{{ $coupon->couponName }}</td> <td>{{ $coupon->couponName }}</td>
<td>{{ $coupon->price }}</td> <td>{{ $coupon->price }}</td>
<td>{{ $coupon->orderid }}</td> {{-- <td>{{ $coupon->orderid }}</td>--}}
<td>{{ $coupon->pa_order_id }}</td>
<td>{{ $coupon->status_text }}</td> <td>{{ $coupon->status_text }}</td>
<td>{{ $coupon->remark }}</td> <td>{{ $coupon->remark }}</td>
<td>{{ $coupon->created_at }}</td> <td>{{ $coupon->created_at }}</td>
@@ -143,13 +159,7 @@
</div> </div>
<div class="text-right"> <div class="text-right">
{{ {{
$coupons->appends([ $coupons->appends(Request::all())->links('Merchant::common.pagination')
'outlet'=>Request::input('outlet'),
'status'=>Request::input('status'),
'redemptionCode'=>Request::input('redemptionCode'),
'start'=>Request::input('start'),
'end'=>Request::input('end'),
])->links('Merchant::common.pagination')
}} }}
</div> </div>
</div> </div>

View File

@@ -229,7 +229,6 @@ class Activity extends Model
return $coupon; return $coupon;
} catch (\Exception $e) { } catch (\Exception $e) {
DB::rollback(); DB::rollback();
return $e->getMessage(); return $e->getMessage();
} }
} }

View File

@@ -11,6 +11,7 @@ class Coupon extends Model
use BelongsToUser, BelongsToOutlet; use BelongsToUser, BelongsToOutlet;
protected $dates = [ protected $dates = [
'paid_at', 'paid_at',
]; ];
@@ -22,6 +23,13 @@ class Coupon extends Model
self::TYPE_YSD => '自有券', self::TYPE_YSD => '自有券',
]; ];
const SETTLE_YES = 1;
const SETTLE_NO = 0;
const SETTLES = [
self::SETTLE_YES => '是',
self::SETTLE_NO => '否',
];
//状态 //状态
public function getStatusTextAttribute(): string public function getStatusTextAttribute(): string
{ {

View File

@@ -0,0 +1,11 @@
<?php
namespace App\Models;
class CouponPaCheck extends Model
{
protected $casts = [
'pa_order_ids' => 'json'
];
}

View File

@@ -4,6 +4,8 @@ namespace App\Models;
use DateTimeInterface; use DateTimeInterface;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Schema; use Schema;
@@ -33,11 +35,11 @@ class Log extends Model
public function __construct(array $attributes = []) public function __construct(array $attributes = [])
{ {
parent::__construct($attributes); parent::__construct($attributes);
if (!$this->table) { if (! $this->table) {
$this->table = 'api_log_' . date('Ym'); $this->table = 'api_log_'.date('Ym');
} }
if (!Schema::hasTable($this->table)) { if (! Schema::hasTable($this->table)) {
Schema::create($this->table, function (Blueprint $table) { Schema::create($this->table, function (Blueprint $table) {
$table->increments('id'); $table->increments('id');
$table->string('path', 255); $table->string('path', 255);
@@ -62,6 +64,7 @@ class Log extends Model
/** /**
* 为数组 / JSON 序列化准备日期。 * 为数组 / JSON 序列化准备日期。
*
* @param \DateTimeInterface $date * @param \DateTimeInterface $date
* @return string * @return string
*/ */
@@ -70,4 +73,27 @@ class Log extends Model
return $date->format($this->dateFormat ?: 'Y-m-d H:i:s'); return $date->format($this->dateFormat ?: 'Y-m-d H:i:s');
} }
/**
* Notes: 关联优惠券-成功
*
* @Author: 玄尘
* @Date: 2022/1/19 11:24
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function coupon(): HasOne
{
return $this->hasOne(Coupon::class, 'redemptionCode', 'coupon_no')->where('status', 2);
}
/**
* Notes: 关联优惠券
*
* @Author: 玄尘
* @Date: 2022/1/19 13:12
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function coupons(): HasMany
{
return $this->hasMany(Coupon::class, 'redemptionCode', 'coupon_no');
}
} }

View File

@@ -5,6 +5,8 @@ namespace App\Providers;
use App\Events\ConponCallback; use App\Events\ConponCallback;
use App\Listeners\ConponCallbackListener; use App\Listeners\ConponCallbackListener;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use XuanChen\Petro\Kernel\Event\CouponNotice;
use XuanChen\Petro\Kernel\Listeners\PetroConponNoticeListener;
use XuanChen\UnionPay\Event\UnionpayConponCallback; use XuanChen\UnionPay\Event\UnionpayConponCallback;
use XuanChen\UnionPay\Listeners\UnionpayConponCallbackListener; use XuanChen\UnionPay\Listeners\UnionpayConponCallbackListener;
@@ -13,6 +15,7 @@ class EventServiceProvider extends ServiceProvider
/** /**
* The event listener mappings for the application. * The event listener mappings for the application.
*
* @var array * @var array
*/ */
protected $listen = [ protected $listen = [
@@ -22,11 +25,14 @@ class EventServiceProvider extends ServiceProvider
UnionpayConponCallback::class => [ UnionpayConponCallback::class => [
UnionpayConponCallbackListener::class, UnionpayConponCallbackListener::class,
], ],
CouponNotice::class => [
PetroConponNoticeListener::class,
],
]; ];
/** /**
* Register any events for your application. * Register any events for your application.
*
* @return void * @return void
*/ */
public function boot() public function boot()

View File

@@ -1,67 +1,71 @@
{ {
"name": "laravel/laravel", "name": "laravel/laravel",
"type": "project", "type": "project",
"description": "The Laravel Framework.", "description": "The Laravel Framework.",
"keywords": [ "keywords": [
"framework", "framework",
"laravel" "laravel"
], ],
"license": "MIT", "license": "MIT",
"require": { "require": {
"php": "^7.3|^8.0", "php": "^7.3|^8.0",
"encore/laravel-admin": "1.*", "encore/laravel-admin": "^1.8",
"fideloper/proxy": "^4.4", "fideloper/proxy": "^4.4",
"fruitcake/laravel-cors": "^2.0", "fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1", "guzzlehttp/guzzle": "^7.0.1",
"laravel/framework": "^8.12", "laravel/framework": "^8.12",
"laravel/tinker": "^2.5", "laravel/tinker": "^2.5",
"predis/predis": "^1.1", "maatwebsite/excel": "^3.1",
"xuanchen/coupon": "^1.0", "predis/predis": "^1.1",
"xuanchen/unionpay": "^3.0.0" "xuanchen/coupon": "^1.0",
}, "xuanchen/petro": "^1.0",
"require-dev": { "xuanchen/petro-ysd": "^1.0",
"facade/ignition": "^2.5", "xuanchen/unionpay": "^3.0.0"
"fakerphp/faker": "^1.9.1", },
"laravel/sail": "^1.0.1", "require-dev": {
"mockery/mockery": "^1.4.2", "facade/ignition": "^2.5",
"nunomaduro/collision": "^5.0", "fakerphp/faker": "^1.9.1",
"phpunit/phpunit": "^9.3.3" "laravel/sail": "^1.0.1",
}, "mockery/mockery": "^1.4.2",
"config": { "nunomaduro/collision": "^5.0",
"optimize-autoloader": true, "phpunit/phpunit": "^9.3.3",
"preferred-install": "dist", "wulfheart/pretty_routes": "^0.3.0"
"sort-packages": true },
}, "config": {
"extra": { "optimize-autoloader": true,
"laravel": { "preferred-install": "dist",
"dont-discover": [] "sort-packages": true
} },
}, "extra": {
"autoload": { "laravel": {
"psr-4": { "dont-discover": []
"App\\": "app/",
"RuLong\\Identity\\": "packages/identity/src/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
]
} }
},
"autoload": {
"psr-4": {
"App\\": "app/",
"RuLong\\Identity\\": "packages/identity/src/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
]
}
} }

225
composer.lock generated
View File

@@ -4,7 +4,11 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
<<<<<<< HEAD
"content-hash": "1fde4d1d7b4ed4a586277a4f6a0f0d95", "content-hash": "1fde4d1d7b4ed4a586277a4f6a0f0d95",
=======
"content-hash": "4afa3c4ba7aca22c3ee390667768e41a",
>>>>>>> a7719d7038809738262e66c70e301947845f680d
"packages": [ "packages": [
{ {
"name": "asm89/stack-cors", "name": "asm89/stack-cors",
@@ -7332,6 +7336,7 @@
}, },
{ {
"name": "xuanchen/petro-ysd", "name": "xuanchen/petro-ysd",
<<<<<<< HEAD
"version": "dev-main", "version": "dev-main",
"source": { "source": {
"type": "git", "type": "git",
@@ -7410,6 +7415,79 @@
"preferred": true "preferred": true
} }
] ]
=======
"version": "1.2",
"source": {
"type": "git",
"url": "https://github.com/xuanchen120/petroYsd.git",
"reference": "f38e2f38a331741a165b70bbaa0f9ad1cea8673e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/xuanchen120/petroYsd/zipball/f38e2f38a331741a165b70bbaa0f9ad1cea8673e",
"reference": "f38e2f38a331741a165b70bbaa0f9ad1cea8673e",
"shasum": ""
>>>>>>> a7719d7038809738262e66c70e301947845f680d
},
"require": {
"guzzlehttp/guzzle": "^7.0.0",
"illuminate/support": "^7.0|^8.0",
"laravel/framework": "*",
"php": ">=7.1.3",
"pimple/pimple": "^3.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"XuanChen\\PetroYsd\\ServiceProvider"
],
"aliases": {
"Petro": "XuanChen\\PetroYsd"
}
}
},
"autoload": {
"psr-4": {
"XuanChen\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "玄尘",
"email": "122383162@qq.com"
}
],
"description": "优惠券",
"support": {
"issues": "https://github.com/xuanchen120/petroYsd/issues",
"source": "https://github.com/xuanchen120/petroYsd/tree/1.2"
},
"time": "2022-05-26T05:32:19+00:00"
},
{
"name": "xuanchen/unionpay",
"version": "3.4.0",
"source": {
"type": "git",
"url": "https://github.com/xuanchen120/unionpay.git",
"reference": "a2eabfc7786e9087a16bcf65f7a707a6967aa456"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/xuanchen120/unionpay/zipball/a2eabfc7786e9087a16bcf65f7a707a6967aa456",
"reference": "a2eabfc7786e9087a16bcf65f7a707a6967aa456",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
}, },
"require": { "require": {
"laravel/framework": "*", "laravel/framework": "*",
@@ -10137,6 +10215,7 @@
"time": "2020-09-28T06:39:44+00:00" "time": "2020-09-28T06:39:44+00:00"
}, },
{ {
<<<<<<< HEAD
"name": "theseer/tokenizer", "name": "theseer/tokenizer",
"version": "1.2.1", "version": "1.2.1",
"source": { "source": {
@@ -10146,6 +10225,76 @@
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
=======
"name": "spatie/laravel-package-tools",
"version": "1.11.3",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-package-tools.git",
"reference": "baeb3df0ebb3a541394fdaf8cbe6115bf4034a59"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/baeb3df0ebb3a541394fdaf8cbe6115bf4034a59",
"reference": "baeb3df0ebb3a541394fdaf8cbe6115bf4034a59",
"shasum": ""
},
"require": {
"illuminate/contracts": "^7.0|^8.0|^9.0",
"php": "^7.4|^8.0"
},
"require-dev": {
"mockery/mockery": "^1.4",
"orchestra/testbench": "^5.0|^6.23|^7.0",
"phpunit/phpunit": "^9.4",
"spatie/test-time": "^1.2"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\LaravelPackageTools\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"role": "Developer"
}
],
"description": "Tools for creating Laravel packages",
"homepage": "https://github.com/spatie/laravel-package-tools",
"keywords": [
"laravel-package-tools",
"spatie"
],
"support": {
"issues": "https://github.com/spatie/laravel-package-tools/issues",
"source": "https://github.com/spatie/laravel-package-tools/tree/1.11.3"
},
"funding": [
{
"url": "https://github.com/spatie",
"type": "github"
}
],
"time": "2022-03-15T20:01:36+00:00"
},
{
"name": "theseer/tokenizer",
"version": "1.2.1",
"source": {
"type": "git",
"url": "https://github.com/theseer/tokenizer.git",
"reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
},
"dist": {
"type": "zip",
>>>>>>> a7719d7038809738262e66c70e301947845f680d
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
"reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
"shasum": "", "shasum": "",
@@ -10191,6 +10340,78 @@
} }
], ],
"time": "2021-07-28T10:34:58+00:00" "time": "2021-07-28T10:34:58+00:00"
<<<<<<< HEAD
=======
},
{
"name": "wulfheart/pretty_routes",
"version": "0.3.0",
"source": {
"type": "git",
"url": "https://github.com/Wulfheart/pretty-routes.git",
"reference": "e257fac400db2c696ddaec197e634b1fc7c40d22"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Wulfheart/pretty-routes/zipball/e257fac400db2c696ddaec197e634b1fc7c40d22",
"reference": "e257fac400db2c696ddaec197e634b1fc7c40d22",
"shasum": ""
},
"require": {
"illuminate/contracts": "^8.0",
"php": "^7.4|^8.0",
"spatie/laravel-package-tools": "^1.4.3"
},
"require-dev": {
"brianium/paratest": "^6.2",
"nunomaduro/collision": "^5.3",
"orchestra/testbench": "^6.15",
"phpunit/phpunit": "^9.3",
"spatie/laravel-ray": "^1.9",
"spatie/phpunit-snapshot-assertions": "^4.2",
"vimeo/psalm": "^4.4"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Wulfheart\\PrettyRoutes\\PrettyRoutesServiceProvider"
],
"aliases": {
"PrettyRoutes": "Wulfheart\\PrettyRoutes\\PrettyRoutesFacade"
}
}
},
"autoload": {
"psr-4": {
"Wulfheart\\PrettyRoutes\\": "src",
"Wulfheart\\PrettyRoutes\\Database\\Factories\\": "database/factories"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Alexander Wulf",
"email": "dev@alexfwulf.de",
"role": "Developer"
}
],
"description": "Display your Laravel routes in the console, but make it pretty. 😎",
"homepage": "https://github.com/wulfheart/pretty_routes",
"keywords": [
"laravel",
"pretty_routes",
"wulfheart"
],
"support": {
"issues": "https://github.com/Wulfheart/pretty-routes/issues",
"source": "https://github.com/Wulfheart/pretty-routes/tree/0.3.0"
},
"time": "2021-05-03T09:19:08+00:00"
>>>>>>> a7719d7038809738262e66c70e301947845f680d
} }
], ],
"aliases": [], "aliases": [],
@@ -10204,5 +10425,9 @@
"php": "^7.3|^8.0" "php": "^7.3|^8.0"
}, },
"platform-dev": [], "platform-dev": [],
<<<<<<< HEAD
"plugin-api-version": "2.0.0" "plugin-api-version": "2.0.0"
=======
"plugin-api-version": "2.2.0"
>>>>>>> a7719d7038809738262e66c70e301947845f680d
} }

202
config/excel.php Normal file
View File

@@ -0,0 +1,202 @@
<?php
use Maatwebsite\Excel\Excel;
return [
'exports' => [
/*
|--------------------------------------------------------------------------
| Chunk size
|--------------------------------------------------------------------------
|
| When using FromQuery, the query is automatically chunked.
| Here you can specify how big the chunk should be.
|
*/
'chunk_size' => 1000,
/*
|--------------------------------------------------------------------------
| Pre-calculate formulas during export
|--------------------------------------------------------------------------
*/
'pre_calculate_formulas' => false,
/*
|--------------------------------------------------------------------------
| CSV Settings
|--------------------------------------------------------------------------
|
| Configure e.g. delimiter, enclosure and line ending for CSV exports.
|
*/
'csv' => [
'delimiter' => ',',
'enclosure' => '"',
'line_ending' => PHP_EOL,
'use_bom' => false,
'include_separator_line' => false,
'excel_compatibility' => false,
],
],
'imports' => [
'read_only' => true,
'heading_row' => [
/*
|--------------------------------------------------------------------------
| Heading Row Formatter
|--------------------------------------------------------------------------
|
| Configure the heading row formatter.
| Available options: none|slug|custom
|
*/
'formatter' => 'slug',
],
/*
|--------------------------------------------------------------------------
| CSV Settings
|--------------------------------------------------------------------------
|
| Configure e.g. delimiter, enclosure and line ending for CSV imports.
|
*/
'csv' => [
'delimiter' => ',',
'enclosure' => '"',
'escape_character' => '\\',
'contiguous' => false,
'input_encoding' => 'UTF-8',
],
],
/*
|--------------------------------------------------------------------------
| Extension detector
|--------------------------------------------------------------------------
|
| Configure here which writer type should be used when
| the package needs to guess the correct type
| based on the extension alone.
|
*/
'extension_detector' => [
'xlsx' => Excel::XLSX,
'xlsm' => Excel::XLSX,
'xltx' => Excel::XLSX,
'xltm' => Excel::XLSX,
'xls' => Excel::XLS,
'xlt' => Excel::XLS,
'ods' => Excel::ODS,
'ots' => Excel::ODS,
'slk' => Excel::SLK,
'xml' => Excel::XML,
'gnumeric' => Excel::GNUMERIC,
'htm' => Excel::HTML,
'html' => Excel::HTML,
'csv' => Excel::CSV,
'tsv' => Excel::TSV,
/*
|--------------------------------------------------------------------------
| PDF Extension
|--------------------------------------------------------------------------
|
| Configure here which Pdf driver should be used by default.
| Available options: Excel::MPDF | Excel::TCPDF | Excel::DOMPDF
|
*/
'pdf' => Excel::DOMPDF,
],
'value_binder' => [
/*
|--------------------------------------------------------------------------
| Default Value Binder
|--------------------------------------------------------------------------
|
| PhpSpreadsheet offers a way to hook into the process of a value being
| written to a cell. In there some assumptions are made on how the
| value should be formatted. If you want to change those defaults,
| you can implement your own default value binder.
|
*/
'default' => Maatwebsite\Excel\DefaultValueBinder::class,
],
'transactions' => [
/*
|--------------------------------------------------------------------------
| Transaction Handler
|--------------------------------------------------------------------------
|
| By default the import is wrapped in a transaction. This is useful
| for when an import may fail and you want to retry it. With the
| transactions, the previous import gets rolled-back.
|
| You can disable the transaction handler by setting this to null.
| Or you can choose a custom made transaction handler here.
|
| Supported handlers: null|db
|
*/
'handler' => 'db',
],
'temporary_files' => [
/*
|--------------------------------------------------------------------------
| Local Temporary Path
|--------------------------------------------------------------------------
|
| When exporting and importing files, we use a temporary file, before
| storing reading or downloading. Here you can customize that path.
|
*/
'local_path' => sys_get_temp_dir(),
/*
|--------------------------------------------------------------------------
| Remote Temporary Disk
|--------------------------------------------------------------------------
|
| When dealing with a multi server setup with queues in which you
| cannot rely on having a shared local temporary path, you might
| want to store the temporary file on a shared disk. During the
| queue executing, we'll retrieve the temporary file from that
| location instead. When left to null, it will always use
| the local path. This setting only has effect when using
| in conjunction with queued imports and exports.
|
*/
'remote_disk' => null,
'remote_prefix' => null,
/*
|--------------------------------------------------------------------------
| Force Resync
|--------------------------------------------------------------------------
|
| When dealing with a multi server setup as above, it's possible
| for the clean up that occurs after entire queue has been run to only
| cleanup the server that the last AfterImportJob runs on. The rest of the server
| would still have the local temporary file stored on it. In this case your
| local storage limits can be exceeded and future imports won't be processed.
| To mitigate this you can set this config value to be true, so that after every
| queued chunk is processed the local temporary file is deleted on the server that
| processed it.
|
*/
'force_resync_remote' => null,
],
];

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCouponPaChecksTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('coupon_pa_checks', function (Blueprint $table) {
$table->id();
$table->string('pa_order_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('coupon_pa_checks');
}
}

74
docs/券码介绍.md Normal file
View File

@@ -0,0 +1,74 @@
## 功能介绍
> 所有优惠券操作的集合系统,开始是查看平安券核销情况后来陆续增加了自有券、银联券、中石油券等。
### 券码种类
#### 自有券
> 自己开发的优惠券系统,想发什么券就发什么券
##### 活动管理
> 设置发券的参数,优惠券的有效期,满减条件等
##### 规则管理
> 优惠券满减规则
##### 卡券列表
> 自有券列表,优惠券的相关数据,
#### 平安券
> 最开始对接的系统,平安券可查询和核销。
#### 银联券
> 银联pos使用
##### 002025 聚合营销优惠查询接口
##### 002100 销账交易接口
##### 002101 销账冲正通知接口
##### 002102 销账撤销通知接口
##### 106040 领取优惠券
##### 012100 优惠券核销通知
#### 中石油
> 发券 查询 作废 回调
#### 中石油(和悦)
~~~
卡券下发接口
卡券使用通知接口
卡券包列表查询接口
卡券状态查询接口
卡券退款接口
查询卡券库存接口
查询发券结果接口
发券结果通知接口
~~~
### 用户管理
#### 用户身份
###### 渠道
> 渠道的顶级账号,配置回调地址,分润规则,可核销优惠券的规则,配置优惠券核销相关的参数。
###### 网点
> 渠道下的网点,就是门店
>
> 平安网点id和平安系统匹配
>
> 门店号匹配银联pos里的门店号

119
docs/功能介绍.md Normal file
View File

@@ -0,0 +1,119 @@
## 功能介绍
### 看板
> 数据看版,查看卡券核销的情况
### 自有卡券
#### 活动列表
> 发券的汇总类型,可查看发券总数、卡券规则、发券渠道、核券渠道、类型等
> 活动编号:本时生活权益配置,唯一。
>
> 卡券规则:配置满减条件
>
> 发券渠道:可申请发券的渠道
>
> 核券渠道:可核销优惠券的渠道
>
> 卡券类型:延期券(领取优惠券后多少天失效),固定期限(设置好卡券的有效期)
>
> 网点校验:校验网点是否存在和是否可以核销
>
> 优惠券可叠加使用:同一门店 相同金额 3分钟之内看作是一笔订单
#### 规则管理
> 创建优惠券使用规则,满多少减多少 YSD-full100-10
#### 卡券列表管理
> 自有券发放使用记录
### 用户管理
> 渠道和门店列表
>
> 渠道可设置回调地址服务秘钥DES3秘钥分润规则未使用
### 卡券核销管理
> 平安券和自有券核销记录
#### 平安结算相关
> 所有已核销的平安券记录
#### 未找到订单数据
> 平安券未匹配上的核销数据
### 沃钱包相关
> 沃钱包业务数据
### 银联相关
> 银联pos相关数据
#### 对账单列表
> 对账单详细数据
#### 对账单
> 对账单数据
#### 优惠券列表
> 银联优惠券记录
#### 操作日志
> 银联券所有操作日志
### 中石油(最初)
> 对接中石油接口
#### 优惠券
> 中石油优惠券列表
#### 日志
> 中石油优惠券操作日志
### 中石油(和悦)
#### 优惠券
> 中石油(和悦)优惠券列表
#### 日志
> 中石油(和悦)优惠券操作日志
### 系统设置
#### 用户
#### 角色
#### 权限
#### 菜单
#### 操作日志
> 后台操作详情
#### api日志
> 所有对接核销系统的api日志
#### 自由券回调日志
> 自由券回调详细日志

19
docs/渠道商后台.md Normal file
View File

@@ -0,0 +1,19 @@
## 渠道商后台
### 平安券管理
> 平安券核销记录
#### 核销记录
> 平安券核销记录:查询,导出
#### 核销统计
> 平安券核销统计:所有规则的统计
### 银联券管理
> 银联券记录
#### 银联券核销记录

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,68 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.zh = {}));
}(this, (function (exports) { 'use strict';
var fp = typeof window !== "undefined" && window.flatpickr !== undefined
? window.flatpickr
: {
l10ns: {},
};
var Mandarin = {
weekdays: {
shorthand: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
longhand: [
"星期日",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
],
},
months: {
shorthand: [
"一月",
"二月",
"三月",
"四月",
"五月",
"六月",
"七月",
"八月",
"九月",
"十月",
"十一月",
"十二月",
],
longhand: [
"一月",
"二月",
"三月",
"四月",
"五月",
"六月",
"七月",
"八月",
"九月",
"十月",
"十一月",
"十二月",
],
},
rangeSeparator: " 至 ",
weekAbbreviation: "周",
scrollTitle: "滚动切换",
toggleTitle: "点击切换 12/24 小时时制",
};
fp.l10ns.zh = Mandarin;
var zh = fp.l10ns;
exports.Mandarin = Mandarin;
exports.default = zh;
Object.defineProperty(exports, '__esModule', { value: true });
})));

View File

@@ -0,0 +1,2 @@
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ShortcutButtonsPlugin=e():t.ShortcutButtonsPlugin=e()}(window,function(){return function(t){var e={};function n(o){if(e[o])return e[o].exports;var r=e[o]={i:o,l:!1,exports:{}};return t[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=t,n.c=e,n.d=function(t,e,o){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:o})},n.r=function(t){Object.defineProperty(t,"__esModule",{value:!0})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});const o={theme:"light"};e.ShortcutButtonsPlugin=function(t){const e=Object.assign({},o,t);return t=>{let n;function o(n){n.stopPropagation(),n.preventDefault();const o=n.target;if("button"!==o.tagName.toLowerCase()||void 0===e.onClick)return;const r=parseInt(o.dataset.index,10),c=Array.isArray(e.onClick)?e.onClick:[e.onClick];for(const e of c)"function"==typeof e&&e(r,t)}return{onReady:()=>{if((n=document.createElement("div")).classList.add("shortcut-buttons-flatpickr-wrapper",e.theme),void 0!==e.label&&e.label.length){const t=document.createElement("div");t.classList.add("shortcut-buttons-flatpickr-label"),t.textContent=e.label,n.appendChild(t)}const r=document.createElement("div");r.classList.add("shortcut-buttons-flatpickr-buttons"),(Array.isArray(e.button)?e.button:[e.button]).forEach((t,e)=>{const n=document.createElement("button");n.classList.add("shortcut-buttons-flatpickr-button"),n.textContent=t.label,n.dataset.index=String(e),r.appendChild(n)}),n.appendChild(r),t.calendarContainer.appendChild(n),n.addEventListener("click",o)},onDestroy:()=>{n.removeEventListener("click",o),n=void 0}}}}}]).ShortcutButtonsPlugin});
//# sourceMappingURL=shortcut-buttons-flatpickr.min.js.map

View File

@@ -0,0 +1 @@
.shortcut-buttons-flatpickr-wrapper{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;padding:5px}.shortcut-buttons-flatpickr-wrapper>.shortcut-buttons-flatpickr-label{-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:0 5px}.shortcut-buttons-flatpickr-wrapper>.shortcut-buttons-flatpickr-buttons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap}.shortcut-buttons-flatpickr-buttons>.shortcut-buttons-flatpickr-button{margin:2px}.light.shortcut-buttons-flatpickr-wrapper{background-color:#eceef1;color:#5a6171}

File diff suppressed because one or more lines are too long