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

View File

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

View File

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

View File

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

View File

@@ -2,6 +2,7 @@
namespace App\Admin\Controllers\Coupon;
use App\Admin\Actions\Coupon\RefreshPAOrder;
use App\Models\ActivityRule;
use App\Models\Coupon;
use App\Models\User;
@@ -15,6 +16,7 @@ class IndexController extends AdminController
/**
* Notes:
*
* @Author: <C.Jason>
* @Date : 2019/9/18 14:50
* @return Grid
@@ -26,6 +28,10 @@ class IndexController extends AdminController
$grid->disableBatchActions();
$grid->disableActions();
$grid->tools(function (Grid\Tools $tools) {
$tools->append(new refreshPAOrder());//刷新平安订单id
});
$grid->model()
->with(['outlet.province', 'outlet.city', 'outlet.district', 'user', 'user.info'])
->whereIn('status', [2, 3])
@@ -44,6 +50,7 @@ class IndexController extends AdminController
$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', '卡券编号');
@@ -56,6 +63,8 @@ class IndexController extends AdminController
}, '网点名称');
$filter->equal('type', '类型')->select(Coupon::TYPES);
$filter->like('pa_order_id', '平安主订单号');
$filter->like('pa_sub_order_id', '平安子订单号');
});
});
@@ -79,19 +88,21 @@ class IndexController extends AdminController
$grid->column('price', '核销金额');
$grid->column('total', '订单金额');
$grid->column('orderid', '订单id');
$grid->column('pa_order_id', '平安主订单号');
$grid->column('pa_sub_order_id', '平安子订单号')->hide();
$grid->column('资金通道结算')->display(function () {
$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 () {
switch ($this->status) {
case 2:
return '<span style="color:green">' . $this->status_text . '</span>';
return '<span style="color:green">'.$this->status_text.'</span>';
break;
case 3:
return '<span style="color:red">' . $this->status_text . '</span>';
return '<span style="color:red">'.$this->status_text.'</span>';
break;
default:
return $this->status_text;
@@ -119,17 +130,17 @@ class IndexController extends AdminController
// $all = $query->get();
// $pass = $all->where('status', 2)->all();
// $pass = collect($pass);
$total = $query->count();
$success = $query->where('status', 2)->count();
$total = (clone $query)->count();
$success = (clone $query)->where('status', 2)->count();
$faield = $total - $success;
return '<label class="label label-success">全部:' . $total . '张</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">核销金额:' . $query->sum('price') . '元</label>&nbsp;&nbsp;'
. '<label class="label label-success">资金通道结算:' . $query->sum('profit') . '元</label>&nbsp;&nbsp;'
. '<label class="label label-success">打款金额:' . $query->where('is_profit', 1)
->sum('profit') . '元</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">失败:'.$faield.'张</label>&nbsp;&nbsp;'
.'<label class="label label-success">核销金额:'.(clone $query)->sum('price').'元</label>&nbsp;&nbsp;'
.'<label class="label label-success">资金通道结算:'.(clone $query)->sum('profit').'元</label>&nbsp;&nbsp;'
.'<label class="label label-success">打款金额:'.(clone $query)->where('is_profit', 1)
->sum('profit').'元</label>&nbsp;&nbsp;';
});
$grid->disableExport(false);
@@ -141,13 +152,13 @@ class IndexController extends AdminController
return strip_tags($value);
});
$export->column('redemptionCode', function ($value, $original) {
return $value . "\t";
return $value."\t";
});
// $export->column('price', function ($value, $original) {
// return $value . "\t";
// });
$export->column('orderid', function ($value, $original) {
return $value . "\t";
return $value."\t";
});
// $export->column('total', function ($value, $original) {
// return $value . "\t";
@@ -155,7 +166,7 @@ class IndexController extends AdminController
$export->column('资金通道结算', function ($value, $original) {
return strip_tags($value);
});
$export->filename('卡券列表' . date("YmdHis"));
$export->filename('卡券列表'.date("YmdHis"));
});
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,16 +2,24 @@
namespace App\Admin\Controllers;
use App\Jobs\CheckCouponByLog;
use App\Jobs\CheckCouponLog;
use App\Models\Coupon;
use App\Models\Log;
use Carbon\Carbon;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;
use XuanChen\Coupon\Action\pingan\Verification;
class TestController
{
public function index(Request $request)
{
$str = Str::uuid();
$date = $request->date ?? date('Y-m-d');
$time = Carbon::parse($date);
@@ -55,12 +63,12 @@ class TestController
->get();
$data = [
' 日期为:' . $time->format('Y-m-d'),
' 核销总数为:' . $all,
' 自有卡券总数为:' . $self,
' 平安卡券总数为:' . $pingan,
' 核销错误总数为:' . $error,
' 核销重复数据数为:' . $lists->count(),
' 日期为:'.$time->format('Y-m-d'),
' 核销总数为:'.$all,
' 自有卡券总数为:'.$self,
' 平安卡券总数为:'.$pingan,
' 核销错误总数为:'.$error,
' 核销重复数据数为:'.$lists->count(),
];
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
* @return Grid
*/
protected function grid()
protected function grid(): Grid
{
$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,
];
});
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;
//Form::forget(['map', 'editor']);
Form::extend('editor', WangEditor::class);
//Form::extend('editor', WangEditor::class);
Form::init(function (Form $form) {
$form->disableEditingCheck();

View File

@@ -12,6 +12,9 @@ Route::group([
$router->get('/', 'HomeController@index')->name('admin.home');
$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');
@@ -35,6 +38,8 @@ Route::group([
*/
$router->resource('logs', 'Log\IndexController');
$router->resource('coupons', 'Coupon\IndexController'); //平安卡券
$router->resource('settle_coupons', 'Coupon\SettleCouponController'); //平安结算数据
$router->resource('pa_coupons', 'Coupon\PaCouponController'); //平安未找到数据
$router->resource('wos', 'Wo\IndexController'); //沃钱包业务
/**

View File

@@ -23,7 +23,7 @@ class UserController extends Controller
public function check(Request $request)
{
$res = $this->checkSign($request);
if (!is_array($res)) {
if (! is_array($res)) {
return $this->error($res);
}
$user_id = $res['user_id'];
@@ -34,6 +34,7 @@ class UserController extends Controller
/**
* Notes: 发券
*
* @Author: 玄尘
* @Date : 2020/6/29 13:57
*/
@@ -75,6 +76,7 @@ class UserController extends Controller
/**
* Notes: 查询
*
* @Author: 玄尘
* @Date : 2020/7/22 11:23
* @param \Illuminate\Http\Request $request
@@ -106,13 +108,43 @@ class UserController extends Controller
$redemptionCode = $res['redemptionCode'];
$outletId = $res['outletId'];
try {
$res = Coupon::Query($redemptionCode, $outletId);
if (is_string($res)) {
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);
}
}
//作废
@@ -160,7 +192,7 @@ class UserController extends Controller
//插入日志表
$log = $this->createLog($request->url(), 'POST', $inputdata, 'freezecoupon'); //添加日志
if (!is_array($res)) {
if (! is_array($res)) {
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/cancel', 'WoController@cancel'); //退业务
Route::post('ticket/query', 'WoController@query'); //退业务
});

View File

@@ -23,6 +23,7 @@ class ToolsController extends Controller
/**
* Notes: 发券
*
* @Author: 玄尘
* @Date : 2020/6/29 13:57
* @param \Illuminate\Http\Request $request
@@ -52,7 +53,7 @@ class ToolsController extends Controller
'activityId' => $request->activityId,
'mobile' => $request->mobile,
];
$url = $this->baseUrl . 'user/grant';
$url = $this->baseUrl.'user/grant';
return $this->getResult($input_data, $url);
@@ -60,6 +61,7 @@ class ToolsController extends Controller
/**
* Notes: 查询
*
* @Author: 玄尘
* @Date : 2021/4/25 9:57
* @param \Illuminate\Http\Request $request
@@ -87,7 +89,7 @@ class ToolsController extends Controller
'redemptionCode' => $request->redemptionCode,
];
$url = $this->baseUrl . 'user/query';
$url = $this->baseUrl.'user/query';
return $this->getResult($input_data, $url);
@@ -95,6 +97,7 @@ class ToolsController extends Controller
/**
* Notes: 卡券作废
*
* @Author: 玄尘
* @Date : 2021/4/25 10:08
* @param \Illuminate\Http\Request $request
@@ -121,13 +124,14 @@ class ToolsController extends Controller
'redemptionCode' => $request->redemptionCode,
];
$url = $this->baseUrl . 'user/destroy';
$url = $this->baseUrl.'user/destroy';
return $this->getResult($input_data, $url);
}
/**
* Notes: 核销
*
* @Author: 玄尘
* @Date : 2020/6/29 14:01
*/
@@ -162,7 +166,7 @@ class ToolsController extends Controller
'from' => $request->from ?? '',
];
$url = $this->baseUrl . 'user/freezecoupon';
$url = $this->baseUrl.'user/freezecoupon';
return $this->getResult($input_data, $url);
@@ -170,6 +174,7 @@ class ToolsController extends Controller
/**
* Notes: 总执行
*
* @Author: 玄尘
* @Date : 2021/4/25 10:00
* @param $data
@@ -186,6 +191,7 @@ class ToolsController extends Controller
'getElapsedTime' => $this->getElapsedTime(),
'getMemoryUsage' => $this->getMemoryUsage(),
'ret' => $res,
'api_input_data' => $this->api_input_data,
'raw_data' => $this->decode($res),
];
@@ -210,6 +216,7 @@ class ToolsController extends Controller
/**
* Notes: 加密
*
* @Author: 玄尘
* @Date : 2021/4/25 9:46
* @param $input
@@ -229,12 +236,13 @@ class ToolsController extends Controller
'sign' => $sign,
'data' => $ascdata,
];
$this->api_input_data = $data;
return $data;
}
/**
* Notes: 解密
*
* @Author: 玄尘
* @Date : 2021/4/25 10:07
* @param $res
@@ -254,6 +262,7 @@ class ToolsController extends Controller
/***
* Notes: 使用的内存
*
* @Author: 玄尘
* @Date : 2021/4/25 9:45
* @param int $precision
@@ -265,11 +274,12 @@ class ToolsController extends Controller
$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: 代码执行时间
*
* @Author: 玄尘
* @Date : 2021/4/25 9:45
* @param int $decimals
@@ -277,7 +287,7 @@ class ToolsController extends Controller
*/
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,24 +6,26 @@ use App\Merchant\Controllers\Controller;
use App\Models\ActivityRule;
use App\Models\Coupon;
use Auth;
use Carbon\Carbon;
use Illuminate\Http\Request;
class IndexController extends Controller
{
protected $query;
public function index(Request $request)
{
$user = Auth::guard('merchant')->user();
$action = $request->action ?? 'search';
if ($action == 'search') {
$rules = ActivityRule::get();
if ($request->start) {
$request->start = $request->start . ' 00:00:00';
$request->start = $request->start.' 00:00:00';
}
if ($request->end) {
$request->end = $request->end . ' 23:59:59';
$request->end = $request->end.' 23:59:59';
}
$outlet = $request->outlet;
@@ -32,8 +34,11 @@ class IndexController extends Controller
$start = $request->start;
$end = $request->end;
$thirdPartyGoodsId = $request->thirdPartyGoodsId;
$pa_order_id = $request->pa_order_id;
$type = $request->type;
$coupons = Coupon::where('user_id', $user->id)
$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) {
@@ -44,37 +49,41 @@ class IndexController extends Controller
->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) {
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) {
->when($start && ! $end, function ($query) use ($start) {
$query->where('created_at', '>', $start);
})
->when(!$start && $end, function ($query) use ($end) {
->when(! $start && $end, function ($query) use ($end) {
$query->where('created_at', '<', $end);
})
->orderBy('created_at', 'desc')->orderBy('id', 'desc')->paginate();
->orderBy('created_at', 'desc')
->orderBy('id', 'desc');
if ($action == 'search') {
$data = [
'all' => $this->getData($request, 'all', $user),
'pass' => $this->getData($request, 'pass', $user),
'reject' => $this->getData($request, 'reject', $user),
];
$coupons = (clone $this->query)->paginate();
return view('Merchant::coupon.index', compact('coupons', 'data', 'rules'));
} else {
@@ -84,9 +93,10 @@ class IndexController extends Controller
/**
* 按照日期分润
* @author 玄尘 2020-03-11
*
* @param Request $request [description]
* @return array|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @author 玄尘 2020-03-11
*/
public function profits(Request $request)
{
@@ -115,9 +125,10 @@ class IndexController extends Controller
/**
* 分润
* @author 玄尘 2020-03-11
*
* @param Coupon $coupon [description]
* @return [type] [description]
* @author 玄尘 2020-03-11
*/
public function profit(Coupon $coupon)
{
@@ -137,95 +148,13 @@ class IndexController extends Controller
switch ($type) {
case 'all':
return Coupon::where('user_id', $user->id)
->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();
return (clone $this->query)->count();
break;
case 'pass':
return Coupon::where('user_id', $user->id)
->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();
return (clone $this->query)->where('status', 2)->count();
break;
case 'reject':
return Coupon::where('user_id', $user->id)
->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();
return (clone $this->query)->where('status', 3)->count();
break;
default:
return 0;
@@ -238,55 +167,28 @@ class IndexController extends Controller
//导出数据
public function excel($request, $user)
{
if (!$request->end) {
if (! $request->end) {
$request->end = now()->toDateTimeString();
}
set_time_limit(0);
ini_set('memory_limit', '1024M');
$filename = '卡券记录' . date('YmdHis') . '.csv';
$filename = '卡券记录'.date('YmdHis').'.csv';
$response = function () use ($user, $request) {
$handle = fopen('php://output', 'w');
$titles = ['ID', '网点名称', '平安券编号', '优惠政策', '核销金额', '订单id', '状态', '处理结果', '核销时间'];
$titles = ['id', '网点名称', '平安券编号', '优惠政策', '核销金额', '平安主订单号', '状态', '处理结果', '核销时间'];
fputcsv($handle, $titles);
Coupon::where('user_id', $user->id)
->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('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);
})
$this->query
->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->outlet ? $info->outlet->nickname : 'Id:'.$info->outletId,
$info->redemptionCode."\t",
' '.$info->couponName,
$info->price."\t",
$info->pa_order_id,
$info->status_text,
$info->remark,
$info->created_at,

View File

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

View File

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

View File

@@ -11,6 +11,7 @@ class Coupon extends Model
use BelongsToUser, BelongsToOutlet;
protected $dates = [
'paid_at',
];
@@ -22,6 +23,13 @@ class Coupon extends Model
self::TYPE_YSD => '自有券',
];
const SETTLE_YES = 1;
const SETTLE_NO = 0;
const SETTLES = [
self::SETTLE_YES => '是',
self::SETTLE_NO => '否',
];
//状态
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 Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Schema\Blueprint;
use Schema;
@@ -33,11 +35,11 @@ class Log extends Model
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
if (!$this->table) {
$this->table = 'api_log_' . date('Ym');
if (! $this->table) {
$this->table = 'api_log_'.date('Ym');
}
if (!Schema::hasTable($this->table)) {
if (! Schema::hasTable($this->table)) {
Schema::create($this->table, function (Blueprint $table) {
$table->increments('id');
$table->string('path', 255);
@@ -62,6 +64,7 @@ class Log extends Model
/**
* 为数组 / JSON 序列化准备日期。
*
* @param \DateTimeInterface $date
* @return string
*/
@@ -70,4 +73,27 @@ class Log extends Model
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\Listeners\ConponCallbackListener;
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\Listeners\UnionpayConponCallbackListener;
@@ -13,6 +15,7 @@ class EventServiceProvider extends ServiceProvider
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
@@ -22,11 +25,14 @@ class EventServiceProvider extends ServiceProvider
UnionpayConponCallback::class => [
UnionpayConponCallbackListener::class,
],
CouponNotice::class => [
PetroConponNoticeListener::class,
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()

View File

@@ -9,14 +9,17 @@
"license": "MIT",
"require": {
"php": "^7.3|^8.0",
"encore/laravel-admin": "1.*",
"encore/laravel-admin": "^1.8",
"fideloper/proxy": "^4.4",
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",
"laravel/framework": "^8.12",
"laravel/tinker": "^2.5",
"maatwebsite/excel": "^3.1",
"predis/predis": "^1.1",
"xuanchen/coupon": "^1.0",
"xuanchen/petro": "^1.0",
"xuanchen/petro-ysd": "^1.0",
"xuanchen/unionpay": "^3.0.0"
},
"require-dev": {
@@ -25,7 +28,8 @@
"laravel/sail": "^1.0.1",
"mockery/mockery": "^1.4.2",
"nunomaduro/collision": "^5.0",
"phpunit/phpunit": "^9.3.3"
"phpunit/phpunit": "^9.3.3",
"wulfheart/pretty_routes": "^0.3.0"
},
"config": {
"optimize-autoloader": true,

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",
"This file is @generated automatically"
],
<<<<<<< HEAD
"content-hash": "1fde4d1d7b4ed4a586277a4f6a0f0d95",
=======
"content-hash": "4afa3c4ba7aca22c3ee390667768e41a",
>>>>>>> a7719d7038809738262e66c70e301947845f680d
"packages": [
{
"name": "asm89/stack-cors",
@@ -7332,6 +7336,7 @@
},
{
"name": "xuanchen/petro-ysd",
<<<<<<< HEAD
"version": "dev-main",
"source": {
"type": "git",
@@ -7410,6 +7415,79 @@
"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": {
"laravel/framework": "*",
@@ -10137,6 +10215,7 @@
"time": "2020-09-28T06:39:44+00:00"
},
{
<<<<<<< HEAD
"name": "theseer/tokenizer",
"version": "1.2.1",
"source": {
@@ -10146,6 +10225,76 @@
},
"dist": {
"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",
"reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
"shasum": "",
@@ -10191,6 +10340,78 @@
}
],
"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": [],
@@ -10204,5 +10425,9 @@
"php": "^7.3|^8.0"
},
"platform-dev": [],
<<<<<<< HEAD
"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