commit
33236ef9ba
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Actions\Show;
|
||||
|
||||
use App\Admin\Forms\BargainOrderRemark as BargainOrderRemarkForm;
|
||||
use Dcat\Admin\Show\AbstractTool;
|
||||
use Dcat\Admin\Widgets\Modal;
|
||||
|
||||
class BargainOrderRemark extends AbstractTool
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected $title = '<i class="feather icon-file-text"></i> 备注';
|
||||
|
||||
/**
|
||||
* 按钮样式定义,默认 btn btn-white waves-effect
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $style = 'btn-success';
|
||||
|
||||
public function render()
|
||||
{
|
||||
$form = BargainOrderRemarkForm::make()->payload(['id'=>$this->getKey()]);
|
||||
return Modal::make()
|
||||
->lg()
|
||||
->title($this->title)
|
||||
->body($form)
|
||||
->button("<a href=\"javascript:void(0)\" class=\"btn btn-sm {$this->style}\">{$this->title}</a> ");
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ class DealerWalletPay extends AbstractTool
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $style = 'btn-danger';
|
||||
protected $style = 'btn-danger mr-1';
|
||||
|
||||
public function render()
|
||||
{
|
||||
|
|
@ -27,6 +27,6 @@ class DealerWalletPay extends AbstractTool
|
|||
->lg()
|
||||
->title($this->title)
|
||||
->body($form)
|
||||
->button("<a href=\"javascript:void(0)\" class=\"btn btn-sm {$this->style}\">{$this->title}</a> ");
|
||||
->button("<a href=\"javascript:void(0)\" class=\"btn btn-sm {$this->style}\">{$this->title}</a>");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class DealerWalletRefuse extends AbstractTool
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $style = 'btn-warning';
|
||||
protected $style = 'btn-warning mr-1';
|
||||
|
||||
public function render()
|
||||
{
|
||||
|
|
@ -27,6 +27,6 @@ class DealerWalletRefuse extends AbstractTool
|
|||
->lg()
|
||||
->title($this->title)
|
||||
->body($form)
|
||||
->button("<a href=\"javascript:void(0)\" class=\"btn btn-sm {$this->style}\">{$this->title}</a> ");
|
||||
->button("<a href=\"javascript:void(0)\" class=\"btn btn-sm {$this->style}\">{$this->title}</a>");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use App\Admin\Repositories\ArticleCategory;
|
|||
use App\Exceptions\BizException;
|
||||
use App\Models\Article;
|
||||
use App\Models\ArticleCategory as ArticleCategoryModel;
|
||||
use Carbon\Carbon;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
|
|
@ -26,6 +27,7 @@ class ArticleCategoryController extends AdminController
|
|||
return Grid::make(new ArticleCategoryModel(), function (Grid $grid) {
|
||||
$grid->column('id')->sortable();
|
||||
$grid->column('name')->tree();
|
||||
$grid->column('cover')->image(100, 100);
|
||||
$grid->column('is_show')
|
||||
->if(function () {
|
||||
return Admin::user()->can('dcat.admin.article_categories.edit');
|
||||
|
|
@ -110,6 +112,11 @@ class ArticleCategoryController extends AdminController
|
|||
$form->display('id');
|
||||
$form->select('parent_id')->options(ArticleCategoryModel::selectOptions());
|
||||
$form->text('name')->required();
|
||||
$form->image('cover')
|
||||
->move('article-category/'.Carbon::now()->toDateString())
|
||||
->saveFullUrl()
|
||||
->removable(false)
|
||||
->autoUpload()->retainable();
|
||||
$form->switch('is_show');
|
||||
$form->switch('is_recommend');
|
||||
$form->number('sort')->min(0)->default(0);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,218 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Admin\Renderable\ProductSkuSimpleTable;
|
||||
use App\Admin\Repositories\BargainActivity;
|
||||
use App\Models\BargainActivity as BargainActivityModel;
|
||||
use App\Models\BargainOrder;
|
||||
use App\Models\ProductSku;
|
||||
use Carbon\Carbon;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Grid\Column;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Layout\Row;
|
||||
use Dcat\Admin\Show;
|
||||
use Dcat\Admin\Widgets\Box;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BargainActivityController extends AdminController
|
||||
{
|
||||
/**
|
||||
* Make a grid builder.
|
||||
*
|
||||
* @return Grid
|
||||
*/
|
||||
protected function grid()
|
||||
{
|
||||
return Grid::make(new BargainActivity(), function (Grid $grid) {
|
||||
$grid->column('id')->sortable();
|
||||
$grid->column('name');
|
||||
// $grid->column('description');
|
||||
$grid->column('is_enable')
|
||||
->if(function () {
|
||||
return Admin::user()->can('dcat.admin.bargain_activities.edit');
|
||||
})
|
||||
->then(function (Column $column) {
|
||||
$column->switch();
|
||||
})
|
||||
->else(function (Column $column) {
|
||||
$column->bool();
|
||||
});
|
||||
// $grid->column('rules');
|
||||
$grid->column('times');
|
||||
// $grid->column('expire_hours');
|
||||
$grid->column('start_at');
|
||||
$grid->column('end_at');
|
||||
$grid->column('created_at');
|
||||
$grid->column('updated_at')->sortable();
|
||||
|
||||
//新增
|
||||
if (Admin::user()->can('dcat.admin.bargain_activities.create')) {
|
||||
$grid->disableCreateButton(false);
|
||||
// $grid->enableDialogCreate();
|
||||
}
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableView(Admin::user()->cannot('dcat.admin.bargain_activities.show'));
|
||||
$actions->disableDelete(Admin::user()->cannot('dcat.admin.bargain_activities.destroy'));
|
||||
//修改
|
||||
$actions->disableEdit(Admin::user()->cannot('dcat.admin.bargain_activities.edit'));
|
||||
});
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->like('name')->width(3);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a show builder.
|
||||
*
|
||||
* @param mixed $id
|
||||
*
|
||||
* @return Show
|
||||
*/
|
||||
protected function detail($id)
|
||||
{
|
||||
return function (Row $row) use ($id) {
|
||||
$activity = BargainActivityModel::with(['skus'])->findOrFail($id);
|
||||
$row->column(6, function ($column) use ($activity) {
|
||||
$column->row(Show::make($activity, function (Show $show) use ($activity) {
|
||||
$show->panel()
|
||||
->tools(function ($tools) {
|
||||
$tools->disableEdit(Admin::user()->cannot('dcat.admin.bargain_activities.edit'));
|
||||
// $tools->disableList();
|
||||
$tools->disableDelete(Admin::user()->cannot('dcat.admin.bargain_activities.destroy'));
|
||||
});
|
||||
$show->row(function (Show\Row $show) use ($activity) {
|
||||
$show->field('id')->width(10, 1);
|
||||
$show->field('name')->width(10, 1);
|
||||
$show->field('is_enable')->using([0=>'未开启', '已开启'])->dot([
|
||||
'0'=>'#b3b9bf',
|
||||
'1'=>'success',
|
||||
])->width(10, 1);
|
||||
$show->width(6)->field('start_at');
|
||||
$show->width(6)->field('end_at');
|
||||
$show->width(6)->field('times')->append('刀');
|
||||
$show->width(6)->field('expire_hours')->append('h');
|
||||
|
||||
$show->width(12)->field('skus')->width(10, 1)->as(function ($value) {
|
||||
return array_column($value, 'name');
|
||||
})->label();
|
||||
|
||||
$show->field('images')->image()->width(10, 1);
|
||||
$show->field('description')->unescape()->width(10, 1);
|
||||
|
||||
$show->width(6)->field('created_at');
|
||||
$show->width(6)->field('updated_at');
|
||||
});
|
||||
}));
|
||||
});
|
||||
$row->column(6, function ($column) use ($activity) {
|
||||
//砍价记录
|
||||
$builder = BargainOrder::where('activity_id', $activity->id)->with(['userInfo']);
|
||||
$bargainOrderGrid = Grid::make($builder, function (Grid $grid) {
|
||||
$grid->column('id', '序号');
|
||||
$grid->column('infos', '明细')->display(function () {
|
||||
return '【'.$this->userInfo->nickname.'】'.$this->created_at->format('Y-m-d H:i:s').'发起了砍价';
|
||||
})->link(function () {
|
||||
return admin_route('bargain_orders.show', ['bargain_order' =>$this->id]);
|
||||
});
|
||||
|
||||
$grid->model()->orderBy('created_at', 'desc');
|
||||
|
||||
$grid->disableActions();
|
||||
$grid->disableRefreshButton();
|
||||
});
|
||||
$bargainOrderBox = Box::make('砍价记录', $bargainOrderGrid);
|
||||
$column->row($bargainOrderBox->collapsable());
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a form builder.
|
||||
*
|
||||
* @return Form
|
||||
*/
|
||||
protected function form()
|
||||
{
|
||||
$builder = BargainActivity::with(['skus']);
|
||||
return Form::make($builder, function (Form $form) {
|
||||
$form->display('id');
|
||||
$form->display('created_at');
|
||||
$form->display('updated_at');
|
||||
$form->block(6, function (Form\BlockForm $form) {
|
||||
$form->text('name')->required();
|
||||
$form->switch('is_enable');
|
||||
$form->datetimeRange('start_at', 'end_at', '活动时间')->required();
|
||||
$form->multipleSelectTable('skus')
|
||||
->from(ProductSkuSimpleTable::make())
|
||||
->model(ProductSku::class, 'id', 'name')
|
||||
->customFormat(function ($v) {
|
||||
if (!$v) {
|
||||
return [];
|
||||
}
|
||||
// 这一步非常重要,需要把数据库中查出来的二维数组转化成一维数组
|
||||
return array_column($v, 'id');
|
||||
})->required();
|
||||
$form->number('times')->min(0);
|
||||
$form->number('expire_hours')->min(0);
|
||||
$form->textarea('rules')->customFormat(function ($value) {
|
||||
return implode(',', json_decode($value));
|
||||
})->saving(function ($value) {
|
||||
// dd($value, explode(',', $value));
|
||||
return json_encode(explode(',', $value));
|
||||
});
|
||||
$form->text('share_title', '分享文案')->placeholder('默认使用活动名称');
|
||||
$form->image('share_image', '分享图')
|
||||
->move('bargain/share/'.Carbon::now()->toDateString())
|
||||
->saveFullUrl()
|
||||
->autoUpload()
|
||||
->retainable()
|
||||
->removable(false)->required();
|
||||
$form->showFooter();
|
||||
});
|
||||
$form->block(6, function (Form\BlockForm $form) {
|
||||
$form->multipleImage('images')
|
||||
->move('bargain/images/'.Carbon::now()->toDateString())
|
||||
->saveFullUrl()
|
||||
->removable(false)
|
||||
->autoUpload()->retainable()->sortable();
|
||||
$form->editor('description')->height('600');
|
||||
});
|
||||
$form->saving(function ($form) {
|
||||
if ($form->is_enable) {
|
||||
//查询是否有除了自己以外开启的活动
|
||||
if ($form->model()->id) {
|
||||
if (BargainActivityModel::where('id', '<>', $form->model()->id)->isEnable()->exists()) {
|
||||
return $form->response()->error('当前已有开启的活动');
|
||||
}
|
||||
} else {
|
||||
if (BargainActivityModel::isEnable()->exists()) {
|
||||
return $form->response()->error('当前已有开启的活动');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public function activities(Request $request)
|
||||
{
|
||||
$name = $request->input('q');
|
||||
|
||||
$query = BargainActivityModel::select('id', 'name as text');
|
||||
|
||||
if ($name) {
|
||||
$query->where('name', 'like', "%$name%");
|
||||
return $query->paginate(null);
|
||||
}
|
||||
|
||||
return response()->json($query->get());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Admin\Actions\Show\BargainOrderRemark;
|
||||
use App\Admin\Renderable\Grid\Filter\BargainOrderSnIn;
|
||||
use App\Admin\Repositories\BargainOrder;
|
||||
use App\Models\BargainOrder as BargainOrderModel;
|
||||
use App\Models\BargainOrderLog;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Layout\Row;
|
||||
use Dcat\Admin\Show;
|
||||
use Dcat\Admin\Widgets\Box;
|
||||
|
||||
class BargainOrderController extends AdminController
|
||||
{
|
||||
/**
|
||||
* Make a grid builder.
|
||||
*
|
||||
* @return Grid
|
||||
*/
|
||||
protected function grid()
|
||||
{
|
||||
$builder = BargainOrder::with(['activity', 'user', 'userInfo', 'mallOrder', 'sku']);
|
||||
return Grid::make($builder, function (Grid $grid) {
|
||||
$grid->column('id')->sortable();
|
||||
$grid->column('activity.name');
|
||||
$grid->column('user.phone');
|
||||
$grid->column('userInfo.nickname');
|
||||
$grid->column('sku.name');
|
||||
$grid->column('sku_price')->display(function ($v) {
|
||||
return bcdiv($v, 100, 2);
|
||||
})->prepend('¥');
|
||||
$grid->column('bargain_price')->display(function ($v) {
|
||||
return bcdiv($v, 100, 2);
|
||||
})->prepend('¥');
|
||||
$grid->column('status')->using([
|
||||
0=>'未开始',
|
||||
1=>'砍价中',
|
||||
2=>'已砍完',
|
||||
])->dot([
|
||||
0=>'primary',
|
||||
1=>'warning',
|
||||
2=>'success',
|
||||
]);
|
||||
$grid->column('expire_at');
|
||||
$grid->column('mallOrder.sn')->filter(BargainOrderSnIn::make([
|
||||
0 => '未下单',
|
||||
1 => '已下单',
|
||||
]));
|
||||
// $grid->column('remark');
|
||||
$grid->column('created_at');
|
||||
$grid->column('updated_at')->sortable();
|
||||
|
||||
$grid->model()->orderBy('id', 'desc');
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
if (Admin::user()->can('dcat.admin.bargain_orders.show')) {
|
||||
$actions->append('<a style="cursor: pointer;" target="_blank" href="'.admin_route('bargain_orders.show', ['bargain_order'=>$actions->row]).'"><i class="feather icon-eye"></i> 显示 </a>');
|
||||
}
|
||||
});
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->equal('activity_id')->select()->ajax(admin_route('api.bargain_activities'))->width(3);
|
||||
$filter->equal('sku_id')->select()->ajax(admin_route('api.product_skus'))->width(3);
|
||||
$filter->like('mallOrder.sn')->width(3);
|
||||
$filter->between('created_at')->dateTime()->width(7);
|
||||
$filter->like('user.phone')->width(3);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a show builder.
|
||||
*
|
||||
* @param mixed $id
|
||||
*
|
||||
* @return Show
|
||||
*/
|
||||
protected function detail($id)
|
||||
{
|
||||
return function (Row $row) use ($id) {
|
||||
$order = BargainOrderModel::with(['activity', 'user', 'userInfo', 'mallOrder', 'sku'])->find($id);
|
||||
$row->column(6, function ($column) use ($order) {
|
||||
$column->row(Show::make($order, function (Show $show) {
|
||||
$show->row(function (Show\Row $show) {
|
||||
$show->field('id')->width(10, 1);
|
||||
$show->width(6)->field('user.phone');
|
||||
$show->field('user_info.nickname', '昵称');
|
||||
$show->field('activity.name');
|
||||
$show->field('sku.name');
|
||||
$show->field('sku_price')->as(function ($v) {
|
||||
return bcdiv($v, 100, 2);
|
||||
})->prepend('¥');
|
||||
$show->field('bargain_price')->as(function ($v) {
|
||||
return bcdiv($v, 100, 2);
|
||||
})->prepend('¥');
|
||||
$show->field('status')->using([
|
||||
0=>'未开始',
|
||||
1=>'砍价中',
|
||||
2=>'已砍完',
|
||||
])->dot([
|
||||
0=>'primary',
|
||||
1=>'warning',
|
||||
2=>'success',
|
||||
]);
|
||||
|
||||
$show->field('mall_order.sn', '关联订单编号')->unescape()->as(function ($value) {
|
||||
if (Admin::user()->can('dcat.admin.orders.show') && !empty($value)) {
|
||||
return '<a href="'.admin_route('orders.show', ['order'=>$this->mallOrder]).'" target="_blank">'.$value.'</a>';
|
||||
}
|
||||
return $value;
|
||||
});
|
||||
|
||||
$show->field('expire_at');
|
||||
$show->field('created_at');
|
||||
$show->width(12)->field('remark')->width(10, 1);
|
||||
});
|
||||
$show->panel()
|
||||
->tools(function (Show\Tools $tools) {
|
||||
$tools->disableEdit();
|
||||
$tools->disableDelete();
|
||||
|
||||
$tools->prepend(new BargainOrderRemark());
|
||||
});
|
||||
}));
|
||||
});
|
||||
$row->column(6, function ($column) use ($id) {
|
||||
// 砍价日志列表
|
||||
$builder = BargainOrderLog::where('order_id', $id)->with(['user', 'userInfo']);
|
||||
$logGrid = Grid::make($builder, function (Grid $grid) {
|
||||
// $grid->column('id', '序号');
|
||||
$grid->column('user.phone');
|
||||
$grid->column('userInfo.nickname');
|
||||
// $grid->column('userInfo.avatar');
|
||||
$grid->column('bargain_amount', '砍一刀')->display(function ($v) {
|
||||
return bcdiv($v, 100, 2);
|
||||
})->prepend('¥');
|
||||
$grid->column('created_at');
|
||||
|
||||
$grid->model()->orderBy('created_at', 'desc');
|
||||
|
||||
$grid->disablePagination();
|
||||
$grid->disableActions();
|
||||
$grid->disableRefreshButton();
|
||||
});
|
||||
$logBox = Box::make('砍价记录', $logGrid);
|
||||
$column->row($logBox->collapsable());
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a form builder.
|
||||
*
|
||||
* @return Form
|
||||
*/
|
||||
protected function form()
|
||||
{
|
||||
return Form::make(new BargainOrder(), function (Form $form) {
|
||||
$form->display('id');
|
||||
$form->text('activity_id');
|
||||
$form->text('user_id');
|
||||
$form->text('sku_id');
|
||||
$form->text('sku_price');
|
||||
$form->text('bargain_price');
|
||||
$form->text('status');
|
||||
$form->text('expire_at');
|
||||
$form->text('order_id');
|
||||
$form->text('remark');
|
||||
|
||||
$form->display('created_at');
|
||||
$form->display('updated_at');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -40,6 +40,9 @@ class DealerPurchaseLogController extends AdminController
|
|||
$user = User::where('phone', $phone)->first();
|
||||
if ($user) {
|
||||
$grid->model()->where('path', 'like', '%-'.$user->id.'-%');
|
||||
} else {
|
||||
//不存的手机号查询数据置为空
|
||||
$grid->model()->where('id', 0);
|
||||
}
|
||||
}
|
||||
$grid->model()->orderBy('id', 'desc');//默认ID倒叙
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use App\Admin\Actions\Grid\Exports\DealerWalletWithdraw;
|
|||
use App\Admin\Actions\Show\DealerWalletPay;
|
||||
use App\Admin\Actions\Show\DealerWalletRefuse;
|
||||
use App\Admin\Repositories\DealerWalletToBankLog;
|
||||
use App\Enums\DealerWalletToBankLogStatus;
|
||||
use App\Models\DealerWalletToBankLog as DealerWalletToBankLogModel;
|
||||
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
|
||||
use Dcat\Admin\Admin;
|
||||
|
|
@ -14,6 +15,7 @@ use Dcat\Admin\Grid;
|
|||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Show;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class DealerWalletToBankLogController extends AdminController
|
||||
{
|
||||
|
|
@ -35,19 +37,16 @@ class DealerWalletToBankLogController extends AdminController
|
|||
$grid->column('rate')->append('%');
|
||||
$grid->column('service_amount')->prepend('¥');
|
||||
$grid->column('account_amount')->prepend('¥');
|
||||
$grid->column('status')->using([
|
||||
DealerWalletToBankLogModel::STATUS_PENDING=>'待处理',
|
||||
DealerWalletToBankLogModel::STATUS_AGREE=>'同意',
|
||||
DealerWalletToBankLogModel::STATUS_REFUSE=>'拒绝',
|
||||
])->dot([
|
||||
0=>'primary',
|
||||
1=>'success',
|
||||
2=>'danger',
|
||||
])->filter(Grid\Column\Filter\In::make([
|
||||
DealerWalletToBankLogModel::STATUS_PENDING=>'待处理',
|
||||
DealerWalletToBankLogModel::STATUS_AGREE=>'同意',
|
||||
DealerWalletToBankLogModel::STATUS_REFUSE=>'拒绝',
|
||||
]));
|
||||
$grid->column('status')->display(function ($v) {
|
||||
$text = $v->text();
|
||||
$background = $v->color();
|
||||
|
||||
return "<i class='fa fa-circle' style='font-size: 13px;color: {$background}'></i> {$text}";
|
||||
})->filter(Grid\Column\Filter\In::make(Arr::except(DealerWalletToBankLogStatus::texts(), [
|
||||
DealerWalletToBankLogStatus::Failed->value,
|
||||
DealerWalletToBankLogStatus::Passed->value,
|
||||
DealerWalletToBankLogStatus::Paying->value,
|
||||
])));
|
||||
$grid->column('remarks');
|
||||
$grid->column('created_at')->sortable();
|
||||
// $grid->column('updated_at')
|
||||
|
|
@ -62,11 +61,6 @@ class DealerWalletToBankLogController extends AdminController
|
|||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
// $filter->equal('status')->select([
|
||||
// DealerWalletToBankLogModel::STATUS_PENDING=>'待处理',
|
||||
// DealerWalletToBankLogModel::STATUS_AGREE=>'已同意',
|
||||
// DealerWalletToBankLogModel::STATUS_REFUSE=>'已拒绝',
|
||||
// ])->width(3);
|
||||
$filter->equal('user.phone')->width(3);
|
||||
$filter->between('created_at')->dateTime()->width(7);
|
||||
});
|
||||
|
|
@ -90,17 +84,17 @@ class DealerWalletToBankLogController extends AdminController
|
|||
$show->field('rate')->append('%');
|
||||
$show->field('service_amount')->prepend('¥');
|
||||
$show->field('account_amount')->prepend('¥');
|
||||
$show->field('status')->using([
|
||||
DealerWalletToBankLogModel::STATUS_PENDING=>'待处理',
|
||||
DealerWalletToBankLogModel::STATUS_AGREE=>'同意',
|
||||
DealerWalletToBankLogModel::STATUS_REFUSE=>'拒绝',
|
||||
])->dot([
|
||||
0=>'primary',
|
||||
1=>'success',
|
||||
2=>'danger',
|
||||
]);
|
||||
$show->field('status')->unescape()->as(function ($v) {
|
||||
$text = $this->status->text();
|
||||
$background = $this->status->color();
|
||||
|
||||
return "<i class='fa fa-circle' style='font-size: 13px;color: {$background}'></i> {$text}";
|
||||
});
|
||||
$show->field('pay_image')->image();
|
||||
$show->field('remarks');
|
||||
if ($show->model()->isFailed()) {
|
||||
$show->field('failed_reason');
|
||||
}
|
||||
$show->divider('收款信息-银行');
|
||||
$show->field('bank_user_name', '银行-收款人')->as(function () {
|
||||
$payInfo = $this->getPayInfo();
|
||||
|
|
@ -150,7 +144,8 @@ class DealerWalletToBankLogController extends AdminController
|
|||
->tools(function (Show\Tools $tools) use ($show) {
|
||||
$tools->disableEdit();
|
||||
$tools->disableDelete();
|
||||
if ($show->model()->isPending() && Admin::user()->can('dcat.admin.dealer_wallet_to_bank_logs.verify')) {
|
||||
|
||||
if (in_array($show->model()->status, [DealerWalletToBankLogStatus::Pending, DealerWalletToBankLogStatus::Failed]) && Admin::user()->can('dcat.admin.dealer_wallet_to_bank_logs.verify')) {
|
||||
$tools->append(new DealerWalletRefuse());
|
||||
$tools->append(new DealerWalletPay());
|
||||
}
|
||||
|
|
@ -214,17 +209,13 @@ class DealerWalletToBankLogController extends AdminController
|
|||
break;
|
||||
}
|
||||
}
|
||||
$statusArr = [
|
||||
DealerWalletToBankLogModel::STATUS_PENDING=>'待处理',
|
||||
DealerWalletToBankLogModel::STATUS_AGREE=>'同意',
|
||||
DealerWalletToBankLogModel::STATUS_REFUSE=>'拒绝',
|
||||
];
|
||||
|
||||
foreach ($query->cursor() as $log) {
|
||||
$payInfo = $log->getPayInfo();
|
||||
$writer->addRow(WriterEntityFactory::createRowFromArray([
|
||||
$log->user->phone,
|
||||
$log->account_amount,
|
||||
$statusArr[$log->status],
|
||||
$log->status->text(),
|
||||
$payInfo ? $payInfo['bank']['user_name'] : '',
|
||||
$payInfo ? $payInfo['bank']['bank_name'] : '',
|
||||
$payInfo ? $payInfo['bank']['bank_number'] : '',
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace App\Admin\Controllers;
|
|||
|
||||
use App\Admin\Widgets\InfoBox;
|
||||
use App\Enums\PayWay;
|
||||
use App\Enums\WalletToBankLogStatus;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Order;
|
||||
use App\Models\WalletLog;
|
||||
|
|
@ -65,7 +66,7 @@ class MonthlyStatisticsController extends Controller
|
|||
->sum('change_balance');
|
||||
|
||||
// 提现总额
|
||||
$withdrawAmount = WalletToBankLog::where('status', WalletToBankLog::STATUS_AGREE)
|
||||
$withdrawAmount = WalletToBankLog::where('status', WalletToBankLogStatus::Success)
|
||||
->whereBetween('updated_at', [$start, $end])
|
||||
->sum('amount');
|
||||
|
||||
|
|
|
|||
|
|
@ -281,6 +281,9 @@ class OrderController extends AdminController
|
|||
$show->field('reduced_amount')->as(function ($v) {
|
||||
return bcdiv($v, 100, 2);
|
||||
})->prepend('- ¥');
|
||||
$show->field('bargain_amount')->as(function ($v) {
|
||||
return bcdiv($v, 100, 2);
|
||||
})->prepend('- ¥');
|
||||
$show->field('total_amount')->as(function ($v) {
|
||||
return bcdiv($v, 100, 2);
|
||||
})->prepend('¥');
|
||||
|
|
@ -342,6 +345,12 @@ class OrderController extends AdminController
|
|||
$grid->column('coupon_discount_amount', '优惠券折扣')->display(function ($value) {
|
||||
return bcdiv($value, 100, 2);
|
||||
})->prepend('¥');
|
||||
$grid->column('reduced_amount', '减免金额')->display(function ($value) {
|
||||
return bcdiv($value, 100, 2);
|
||||
})->prepend('¥');
|
||||
$grid->column('bargain_amount', '砍价优惠')->display(function ($value) {
|
||||
return bcdiv($value, 100, 2);
|
||||
})->prepend('¥');
|
||||
$grid->column('sales_value', '销售值');
|
||||
$grid->column('remain_quantity');
|
||||
|
||||
|
|
|
|||
|
|
@ -4,12 +4,13 @@ namespace App\Admin\Controllers;
|
|||
|
||||
use App\Admin\Actions\Grid\WalletToBankLogVerify;
|
||||
use App\Admin\Repositories\WalletToBankLog;
|
||||
use App\Models\WalletToBankLog as WalletToBankLogModel;
|
||||
use App\Enums\WalletToBankLogStatus;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Show;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class WalletToBankLogController extends AdminController
|
||||
{
|
||||
|
|
@ -37,15 +38,12 @@ class WalletToBankLogController extends AdminController
|
|||
$grid->column('account_amount')->display(function ($v) {
|
||||
return bcdiv($v, 100, 2);
|
||||
})->prepend('¥');
|
||||
$grid->column('status')->using([
|
||||
WalletToBankLogModel::STATUS_PENDING=>'待处理',
|
||||
WalletToBankLogModel::STATUS_AGREE=>'同意',
|
||||
WalletToBankLogModel::STATUS_REFUSE=>'拒绝',
|
||||
])->dot([
|
||||
0=>'primary',
|
||||
1=>'success',
|
||||
2=>'danger',
|
||||
]);
|
||||
$grid->column('status')->display(function ($v) {
|
||||
$text = $v->text();
|
||||
$background = $v->color();
|
||||
|
||||
return "<i class='fa fa-circle' style='font-size: 13px;color: {$background}'></i> {$text}";
|
||||
});
|
||||
$grid->column('remarks');
|
||||
$grid->column('created_at')->sortable();
|
||||
|
||||
|
|
@ -54,18 +52,20 @@ class WalletToBankLogController extends AdminController
|
|||
$grid->model()->orderBy('created_at', 'desc');
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
if ($actions->row->status == 0 && Admin::user()->can('dcat.admin.wallet_to_bank_logs.verify')) {
|
||||
if (in_array($actions->row->status, [WalletToBankLogStatus::Pending, WalletToBankLogStatus::Failed]) && Admin::user()->can('dcat.admin.wallet_to_bank_logs.verify')) {
|
||||
$actions->append(new WalletToBankLogVerify());
|
||||
}
|
||||
});
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->equal('status')->select([
|
||||
WalletToBankLogModel::STATUS_PENDING=>'待处理',
|
||||
WalletToBankLogModel::STATUS_AGREE=>'已同意',
|
||||
WalletToBankLogModel::STATUS_REFUSE=>'已拒绝',
|
||||
])->width(3);
|
||||
$filter->equal('status')
|
||||
->select(Arr::except(WalletToBankLogStatus::texts(), [
|
||||
WalletToBankLogStatus::Passed->value,
|
||||
WalletToBankLogStatus::Paying->value,
|
||||
WalletToBankLogStatus::Failed->value,
|
||||
]))
|
||||
->width(3);
|
||||
$filter->equal('user.phone')->width(3);
|
||||
$filter->equal('username')->width(3);
|
||||
$filter->between('created_at')->dateTime()->width(7);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Forms;
|
||||
|
||||
use App\Models\BargainOrder;
|
||||
use Dcat\Admin\Contracts\LazyRenderable;
|
||||
use Dcat\Admin\Traits\LazyWidget;
|
||||
use Dcat\Admin\Widgets\Form;
|
||||
|
||||
class BargainOrderRemark extends Form implements LazyRenderable
|
||||
{
|
||||
use LazyWidget;
|
||||
|
||||
/**
|
||||
* 权限判断,如不需要可以删除此方法
|
||||
*
|
||||
* @param Model|Authenticatable|HasPermissions|null $user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.bargain_orders.remark');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the form request.
|
||||
*
|
||||
* @param array $input
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(array $input)
|
||||
{
|
||||
$orderId = $this->payload['id'] ?? 0;
|
||||
$order = BargainOrder::findOrFail($orderId);
|
||||
|
||||
$remark = $input['remark'] ?? '';
|
||||
|
||||
$order->update([
|
||||
'remark'=>$remark,
|
||||
]);
|
||||
|
||||
return $this->response()
|
||||
->success(__('admin.update_succeeded'))
|
||||
->refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a form here.
|
||||
*/
|
||||
public function form()
|
||||
{
|
||||
$orderId = $this->payload['id'] ?? 0;
|
||||
$order = BargainOrder::findOrFail($orderId);
|
||||
|
||||
$this->text('remark')->value($order->remark);
|
||||
|
||||
$this->disableResetButton();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
namespace App\Admin\Forms;
|
||||
|
||||
use App\Enums\DealerWalletToBankLogPayWay;
|
||||
use App\Enums\DealerWalletToBankLogStatus;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Models\DealerWalletToBankLog;
|
||||
use Carbon\Carbon;
|
||||
use Dcat\Admin\Contracts\LazyRenderable;
|
||||
|
|
@ -37,12 +40,25 @@ class DealerWalletPay extends Form implements LazyRenderable
|
|||
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$log = DealerWalletToBankLog::findOrFail($id);
|
||||
$log->update([
|
||||
'pay_info' => $log->getPayInfo(),
|
||||
'pay_image' => $input['pay_image']??null,
|
||||
'status' => DealerWalletToBankLog::STATUS_AGREE,
|
||||
]);
|
||||
|
||||
$log = DealerWalletToBankLog::lockForUpdate()->findOrFail($id);
|
||||
|
||||
if (! in_array($log->status, [DealerWalletToBankLogStatus::Pending, DealerWalletToBankLogStatus::Failed])) {
|
||||
throw new BizException('提现记录状态异常');
|
||||
}
|
||||
|
||||
$log->pay_info = $log->user->dealer->pay_info;
|
||||
$log->pay_image = $input['pay_image'] ?? null;
|
||||
$log->pay_way = $input['pay_way'];
|
||||
if ($log->pay_way == DealerWalletToBankLogPayWay::Offline) {
|
||||
$log->pay_at = now();
|
||||
$log->status = DealerWalletToBankLogStatus::Success;
|
||||
} else {
|
||||
$log->pay_sn = serial_number();
|
||||
$log->status = DealerWalletToBankLogStatus::Passed;
|
||||
}
|
||||
$log->save();
|
||||
|
||||
DB::commit();
|
||||
} catch (Throwable $th) {
|
||||
DB::rollBack();
|
||||
|
|
@ -60,6 +76,10 @@ class DealerWalletPay extends Form implements LazyRenderable
|
|||
*/
|
||||
public function form()
|
||||
{
|
||||
$this->hidden('pay_way')->value(DealerWalletToBankLogPayWay::Offline->value);
|
||||
// $this->select('pay_way')
|
||||
// ->options(DealerWalletToBankLogPayWay::texts())
|
||||
// ->required();
|
||||
$this->image('pay_image')
|
||||
->move('dealer-pay/'.Carbon::now()->toDateString())
|
||||
->saveFullUrl()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Admin\Forms;
|
||||
|
||||
use App\Enums\DealerWalletAction;
|
||||
use App\Enums\DealerWalletToBankLogStatus;
|
||||
use App\Models\DealerWalletToBankLog;
|
||||
use App\Services\Dealer\WalletService;
|
||||
use Dcat\Admin\Contracts\LazyRenderable;
|
||||
|
|
@ -40,8 +41,8 @@ class DealerWalletRefuse extends Form implements LazyRenderable
|
|||
DB::beginTransaction();
|
||||
$log = DealerWalletToBankLog::findOrFail($id);
|
||||
$log->update([
|
||||
'remark' => $input['remark']??'',
|
||||
'status' => DealerWalletToBankLog::STATUS_REFUSE,
|
||||
'remark' => $input['remark'] ?? '',
|
||||
'status' => DealerWalletToBankLogStatus::Refused,
|
||||
]);
|
||||
//打回余额
|
||||
$walletService = new WalletService();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
namespace App\Admin\Forms;
|
||||
|
||||
use App\Enums\WalletToBankLogPayWay;
|
||||
use App\Enums\WalletToBankLogStatus;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Models\WalletLog;
|
||||
use App\Models\WalletToBankLog;
|
||||
use App\Services\WalletService;
|
||||
|
|
@ -34,15 +37,37 @@ class WalletToBankLogVerify extends Form implements LazyRenderable
|
|||
*/
|
||||
public function handle(array $input)
|
||||
{
|
||||
$id = $this->payload['id'] ?? 0;
|
||||
$log = WalletToBankLog::findOrFail($id);
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$log->update($input);
|
||||
//如果拒绝,重新添加对应可提金额
|
||||
if ($log->status == 2) {
|
||||
$walletService = new WalletService();
|
||||
$walletService->changeBalance($log->user, $log->amount, WalletLog::ACTION_WITHDRAW_FAILED, '提现-失败', $log);
|
||||
|
||||
$log = WalletToBankLog::lockForUpdate()->findOrFail($this->payload['id']);
|
||||
|
||||
if (! in_array($log->status, [WalletToBankLogStatus::Pending, WalletToBankLogStatus::Failed])) {
|
||||
throw new BizException('提现记录状态异常');
|
||||
}
|
||||
|
||||
if ($input['status'] == 1) {
|
||||
$log->pay_way = $input['pay_way'];
|
||||
|
||||
if ($log->pay_way === WalletToBankLogPayWay::Offline) {
|
||||
$log->status = WalletToBankLogStatus::Success;
|
||||
$log->pay_at = now();
|
||||
} else {
|
||||
$log->pay_sn = serial_number();
|
||||
$log->status = WalletToBankLogStatus::Passed;
|
||||
}
|
||||
|
||||
$log->failed_reason = null;
|
||||
} else {
|
||||
$log->status = WalletToBankLogStatus::Refused;
|
||||
}
|
||||
|
||||
$log->remarks = $input['remarks'];
|
||||
$log->save();
|
||||
|
||||
// 如果拒绝,退换扣除金额
|
||||
if ($log->status === WalletToBankLogStatus::Refused) {
|
||||
(new WalletService())->changeBalance($log->user, $log->amount, WalletLog::ACTION_WITHDRAW_FAILED, '提现-失败', $log);
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
|
@ -65,7 +90,6 @@ class WalletToBankLogVerify extends Form implements LazyRenderable
|
|||
$id = $this->payload['id'] ?? 0;
|
||||
$log = WalletToBankLog::findOrFail($id);
|
||||
|
||||
|
||||
$this->text('bank_name')->value($log->bank_name)->disable();
|
||||
$this->text('bank_number')->value($log->bank_number)->disable();
|
||||
$this->text('username')->value($log->username)->disable();
|
||||
|
|
@ -75,10 +99,20 @@ class WalletToBankLogVerify extends Form implements LazyRenderable
|
|||
$this->currency('service_amount')->symbol('¥')->value(bcdiv($log->service_amount, 100, 2))->disable();
|
||||
$this->currency('account_amount')->symbol('¥')->value(bcdiv($log->account_amount, 100, 2))->disable();
|
||||
|
||||
$this->radio('status')->options([
|
||||
1 => '成功',
|
||||
2 => '拒绝',
|
||||
])->default(1);
|
||||
if ($log->status === WalletToBankLogStatus::Failed) {
|
||||
$this->textarea('failed_reason')->value($log->failed_reason ?: '')->disable();
|
||||
}
|
||||
|
||||
$this->radio('status')
|
||||
->options([
|
||||
1 => '通过',
|
||||
2 => '拒绝',
|
||||
])
|
||||
->default(1);
|
||||
$this->hidden('pay_way')->value(WalletToBankLogPayWay::Offline->value);
|
||||
// $this->select('pay_way')
|
||||
// ->options(WalletToBankLogPayWay::texts())
|
||||
// ->rules('required_if:status,1', ['required_if'=>'请选择支付方式']);
|
||||
$this->text('remarks')->rules('required_if:status,2', ['required_if'=>'拒绝时需要填写备注']);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Renderable\Grid\Filter;
|
||||
|
||||
use Dcat\Admin\Grid\Column\Filter;
|
||||
use Dcat\Admin\Grid\Column\Filter\Checkbox;
|
||||
use Dcat\Admin\Grid\Model;
|
||||
|
||||
class BargainOrderSnIn extends Filter
|
||||
{
|
||||
use Checkbox;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* CheckFilter constructor.
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(array $options)
|
||||
{
|
||||
$this->options = $options;
|
||||
|
||||
$this->class = [
|
||||
'all' => uniqid('column-filter-all-'),
|
||||
'item' => uniqid('column-filter-item-'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a binding to the query.
|
||||
*
|
||||
* @param array $value
|
||||
* @param Model $model
|
||||
*/
|
||||
public function addBinding($value, Model $model)
|
||||
{
|
||||
if (empty($value)) {
|
||||
return;
|
||||
}
|
||||
$all = [0, 1];
|
||||
|
||||
if (array_diff($all, $value)) {//无差别则直接跳过
|
||||
//判断查询的状态有哪些;
|
||||
$model->where(function ($query) use ($value) {
|
||||
foreach ($value as $status) {
|
||||
switch ($status) {
|
||||
case 0:
|
||||
$query->orWhere(function ($q) {
|
||||
return $q->whereNull('order_id')->orWhere('order_id', 0);
|
||||
});
|
||||
break;
|
||||
case 1:
|
||||
$query->orWhereNotNull('order_id');
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render this filter.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return $this->renderCheckbox();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Repositories;
|
||||
|
||||
use App\Models\BargainActivity as Model;
|
||||
use Dcat\Admin\Repositories\EloquentRepository;
|
||||
|
||||
class BargainActivity extends EloquentRepository
|
||||
{
|
||||
/**
|
||||
* Model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eloquentClass = Model::class;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Repositories;
|
||||
|
||||
use App\Models\BargainOrder as Model;
|
||||
use Dcat\Admin\Repositories\EloquentRepository;
|
||||
|
||||
class BargainOrder extends EloquentRepository
|
||||
{
|
||||
/**
|
||||
* Model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eloquentClass = Model::class;
|
||||
}
|
||||
|
|
@ -19,13 +19,48 @@ class OrderService
|
|||
public function adminReduceOrder(Order $order, int $reduceAmount)
|
||||
{
|
||||
if ($order->isPending()) {
|
||||
$needReduceAmount = $order->total_amount - $reduceAmount + $order->reduced_amount;
|
||||
$res = $order->where('updated_at', $order->updated_at)->update([
|
||||
'reduced_amount' => $order->total_amount - $reduceAmount + $order->reduced_amount,
|
||||
'reduced_amount' => $needReduceAmount,
|
||||
'total_amount' => $reduceAmount,
|
||||
]);
|
||||
if ($res === 0) {
|
||||
throw new BizException('订单已发生改变');
|
||||
}
|
||||
|
||||
//更新订单商品优惠金额
|
||||
//分解到订单中除赠品外的商品
|
||||
$orderProducts = $order->products;
|
||||
$needReduceOrderProducts = [];
|
||||
$totalAmount = 0;
|
||||
foreach ($orderProducts as $orderProduct) {
|
||||
if (!$orderProduct->isGift()) {
|
||||
$needReduceOrderProducts[] = $orderProduct;
|
||||
$totalAmount += $orderProduct->total_amount;
|
||||
}
|
||||
}
|
||||
|
||||
$i = count($needReduceOrderProducts);
|
||||
foreach ($needReduceOrderProducts as $reduceOrderProduct) {
|
||||
$i --;
|
||||
|
||||
if ($i > 0) {
|
||||
$amount = (int) bcdiv(bcmul($needReduceAmount, $reduceOrderProduct->total_amount, 0), $totalAmount, 2);
|
||||
$needReduceAmount -= $amount;
|
||||
$totalAmount -= $reduceOrderProduct->total_amount;
|
||||
} else {
|
||||
$amount = $needReduceAmount;
|
||||
}
|
||||
|
||||
$newTotalAmount = $reduceOrderProduct->total_amount + $reduceOrderProduct->reduced_amount - $amount;
|
||||
|
||||
//更新订单商品的金额
|
||||
$reduceOrderProduct->update([
|
||||
'reduced_amount' => $amount,
|
||||
'total_amount'=> $newTotalAmount,
|
||||
]);
|
||||
}
|
||||
|
||||
OrderLog::create([
|
||||
'order_id'=>$order->id,
|
||||
'content'=> '调整订单支付价格为:¥'.bcdiv($reduceAmount, 100, 2),
|
||||
|
|
|
|||
|
|
@ -214,6 +214,11 @@ Route::group([
|
|||
$router->get('dealer-delivery-bills', 'DealerDeliveryBillController@index')->name('dealer_delivery_bills.index');
|
||||
$router->get('dealer-delivery-bills/{dealer_delivery_bill}', 'DealerDeliveryBillController@show')->name('dealer_delivery_bills.show');
|
||||
|
||||
//商城端-砍价活动
|
||||
$router->resource('bargain-activities', 'BargainActivityController')->names('bargain_activities');
|
||||
$router->resource('bargain-orders', 'BargainOrderController')->only(['index', 'show'])->names('bargain_orders');
|
||||
|
||||
|
||||
/** api接口 **/
|
||||
$router->get('api/product-categories', 'ProductCategoryController@categories')->name('api.product_categories');
|
||||
$router->get('api/product-group-details', 'ProductGroupController@details')->name('api.product_group_details');
|
||||
|
|
@ -224,6 +229,7 @@ Route::group([
|
|||
$router->get('api/orders', 'OrderController@orders')->name('api.orders');
|
||||
$router->get('api/order-products', 'OrderController@orderProducts')->name('api.order_products');
|
||||
$router->get('api/users', 'UserController@users')->name('api.users');
|
||||
$router->get('api/bargain-activities', 'BargainActivityController@activities')->name('api.bargain_activities');
|
||||
|
||||
/** 调试接口 **/
|
||||
// $router->get('test', 'HomeController@test');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands\Dealer;
|
||||
|
||||
use App\Enums\Bank;
|
||||
use App\Enums\DealerWalletToBankLogStatus;
|
||||
use App\Exceptions\YeePayException;
|
||||
use App\Models\DealerWalletToBankLog;
|
||||
use App\Services\YeePayService;
|
||||
use Illuminate\Console\Command;
|
||||
use Throwable;
|
||||
|
||||
class WalletToBankCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'dealer:wallet-to-bank';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '批零提现';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$yeePayService = new YeePayService(config('services.yeepay'));
|
||||
|
||||
while (true) {
|
||||
DealerWalletToBankLog::where('status', DealerWalletToBankLogStatus::Passed)->chunkById(1, function ($logs) use ($yeePayService) {
|
||||
foreach ($logs as $log) {
|
||||
try {
|
||||
$result = $yeePayService->request('accountpay.behalf.Pay', [
|
||||
'payerOutUserId' => '21102510220227100003' ?: config('services.yeepay.partner_id'),
|
||||
'merchOrderNo' => $log->pay_sn,
|
||||
'tradeName' => '批零提现',
|
||||
'payeeUserName' => data_get($log->pay_info, 'bank.user_name'),
|
||||
'bankCardNo' => data_get($log->pay_info, 'bank.bank_number'),
|
||||
'bankCode' => Bank::tryFromBankName(data_get($log->pay_info, 'bank.bank_name'))?->name,
|
||||
'bankCardType' => 'DEBIT_CARD',
|
||||
'amount' => $log->account_amount,
|
||||
'feeRole' => 'PAYER',
|
||||
'tradeMemo' => '批零提现',
|
||||
'context' => json_encode(['type' => 'dealer_wallet_to_bank']),
|
||||
]);
|
||||
|
||||
// 如果交易超时,重新发起支付
|
||||
if ($result['resultCode'] === 'TIME_OUT') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($result['orderStatus'] === 'SUCCESS') {
|
||||
$log->update([
|
||||
'status' => DealerWalletToBankLogStatus::Success,
|
||||
'pay_at' => now(),
|
||||
'failed_reason' => null,
|
||||
]);
|
||||
} elseif ($result['orderStatus'] === 'FAIL') {
|
||||
$log->update([
|
||||
'status' => DealerWalletToBankLogStatus::Failed,
|
||||
'failed_reason' => '交易失败',
|
||||
]);
|
||||
} else {
|
||||
$log->update([
|
||||
'status' => DealerWalletToBankLogStatus::Paying,
|
||||
'failed_reason' => null,
|
||||
]);
|
||||
}
|
||||
} catch (YeePayException $e) {
|
||||
$log->update([
|
||||
'status' => DealerWalletToBankLogStatus::Failed,
|
||||
'failed_reason' => $e->getMessage(),
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
sleep(60);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Enums\Bank;
|
||||
use App\Enums\WalletToBankLogStatus;
|
||||
use App\Exceptions\YeePayException;
|
||||
use App\Models\WalletToBankLog;
|
||||
use App\Services\YeePayService;
|
||||
use Illuminate\Console\Command;
|
||||
use Throwable;
|
||||
|
||||
class WalletToBankCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'wallet-to-bank';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '可提提现';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$yeePayService = new YeePayService(config('services.yeepay'));
|
||||
|
||||
while (true) {
|
||||
WalletToBankLog::where('status', WalletToBankLogStatus::Passed)->chunkById(1, function ($logs) use ($yeePayService) {
|
||||
foreach ($logs as $log) {
|
||||
try {
|
||||
$result = $yeePayService->request('accountpay.behalf.Pay', [
|
||||
'payerOutUserId' => '21102510220227100003' ?: config('services.yeepay.partner_id'),
|
||||
'merchOrderNo' => $log->pay_sn,
|
||||
'tradeName' => '余额提现',
|
||||
'payeeUserName' => $log->username,
|
||||
'bankCardNo' => $log->bank_number,
|
||||
'bankCode' => Bank::tryFromBankName($log->bank_name)?->name,
|
||||
'bankCardType' => 'DEBIT_CARD',
|
||||
'amount' => bcdiv($log->account_amount, 100, 2),
|
||||
'feeRole' => 'PAYER',
|
||||
'tradeMemo' => '商城余额提现',
|
||||
'context' => json_encode(['type' => 'wallet_to_bank']),
|
||||
]);
|
||||
|
||||
// 如果交易超时,重新发起支付
|
||||
if ($result['resultCode'] === 'TIME_OUT') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($result['orderStatus'] === 'SUCCESS') {
|
||||
$log->update([
|
||||
'status' => WalletToBankLogStatus::Success,
|
||||
'pay_at' => now(),
|
||||
'failed_reason' => null,
|
||||
]);
|
||||
} elseif ($result['orderStatus'] === 'FAIL') {
|
||||
$log->update([
|
||||
'status' => WalletToBankLogStatus::Failed,
|
||||
'failed_reason' => '交易失败',
|
||||
]);
|
||||
} else {
|
||||
$log->update([
|
||||
'status' => WalletToBankLogStatus::Paying,
|
||||
'failed_reason' => null,
|
||||
]);
|
||||
}
|
||||
} catch (YeePayException $e) {
|
||||
$log->update([
|
||||
'status' => WalletToBankLogStatus::Failed,
|
||||
'failed_reason' => $e->getMessage(),
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
sleep(60);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,11 +2,13 @@
|
|||
|
||||
namespace App\Endpoint\Api\Http\Controllers;
|
||||
|
||||
use App\Endpoint\Api\Http\Resources\ArticleCategoryResource;
|
||||
use App\Endpoint\Api\Http\Resources\ArticleResource;
|
||||
use App\Endpoint\Api\Http\Resources\ArticleSimpleResource;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Helpers\Paginator as PaginatorHelper;
|
||||
use App\Models\Article;
|
||||
use App\Models\ArticleCategory;
|
||||
use App\Models\ArticleLikesLog;
|
||||
use App\Models\ArticlePointsLog;
|
||||
use App\Models\PointsLog;
|
||||
|
|
@ -50,7 +52,49 @@ class ArticleController extends Controller
|
|||
], $cate);
|
||||
$query = Article::query()->with(['likesInfo'=>function ($q) use ($request) {
|
||||
$user_id = $request->user()?->id;
|
||||
return $q->where('user_id', $user_id??0);
|
||||
return $q->where('user_id', $user_id ?? 0);
|
||||
}])->where('is_show', 1);
|
||||
if ($categoryId) {
|
||||
$query->where('category_id', $categoryId);
|
||||
}
|
||||
if ($key) {
|
||||
$query->where('title', 'like', '%'.$key.'%');
|
||||
}
|
||||
|
||||
$query->orderBy('is_recommend', 'desc');
|
||||
$query->orderBy('sort', 'desc');
|
||||
$query->orderBy('created_at', 'desc');
|
||||
|
||||
$list = $query->simplePaginate(PaginatorHelper::resolvePerPage('per_page', 20, 50));
|
||||
return ArticleSimpleResource::collection($list);
|
||||
}
|
||||
|
||||
public function healthCategory(Request $request)
|
||||
{
|
||||
$key = (string) $request->query('key');
|
||||
$categoryId = app_settings('app.article_health');
|
||||
$query = ArticleCategory::query()->where('parent_id', $categoryId)->where('is_show', 1);
|
||||
|
||||
if ($key) {
|
||||
$query->where('name', 'like', '%'.$key.'%');
|
||||
}
|
||||
|
||||
$query->orderBy('is_recommend', 'desc');
|
||||
$query->orderBy('sort', 'desc');
|
||||
$query->orderBy('created_at', 'desc');
|
||||
|
||||
$categories = $query->get();
|
||||
|
||||
return ArticleCategoryResource::collection($categories);
|
||||
}
|
||||
|
||||
public function articleList($id, Request $request)
|
||||
{
|
||||
$key = (string) $request->query('key');
|
||||
$categoryId = $id;
|
||||
$query = Article::query()->with(['likesInfo'=>function ($q) use ($request) {
|
||||
$user_id = $request->user()?->id;
|
||||
return $q->where('user_id', $user_id ?? 0);
|
||||
}])->where('is_show', 1);
|
||||
if ($categoryId) {
|
||||
$query->where('category_id', $categoryId);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,250 @@
|
|||
<?php
|
||||
|
||||
namespace App\Endpoint\Api\Http\Controllers;
|
||||
|
||||
use App\Endpoint\Api\Http\Resources\BargainActivityResource;
|
||||
use App\Endpoint\Api\Http\Resources\BargainOrderResource;
|
||||
use App\Endpoint\Api\Http\Resources\OrderResource;
|
||||
use App\Events\OrderPaid;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Models\BargainActivity;
|
||||
use App\Models\BargainOrder;
|
||||
use App\Models\BargainSku;
|
||||
use App\Models\ProductSku;
|
||||
use App\Services\BargainService;
|
||||
use App\Services\OrderService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Throwable;
|
||||
|
||||
class BargainController extends Controller
|
||||
{
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function activityDetail($id)
|
||||
{
|
||||
$activity = BargainActivity::with('skus')->findOrFail($id);
|
||||
if (!$activity->is_enable) {
|
||||
throw new BizException('砍价活动暂未开始');
|
||||
}
|
||||
if ($activity->start_at > now() || $activity->end_at < now()) {
|
||||
throw new BizException('不在活动时间范围');
|
||||
}
|
||||
|
||||
return BargainActivityResource::make($activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过砍价商品查看当前砍价记录
|
||||
*
|
||||
* @param [type] $id
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function bargainSku($id)
|
||||
{
|
||||
//判断商品是否参与砍价
|
||||
$bargainSku = BargainSku::with(['activity'=>function ($query) {
|
||||
return $query->where('is_enable', true)->where('start_at', '<=', now())->where('end_at', '>=', now());
|
||||
}, 'sku'])->where('sku_id', $id)->first();
|
||||
|
||||
if (!($bargainSku && $bargainSku->activity)) {
|
||||
throw new BizException('该商品未参与砍价活动,或者活动已结束');
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'sku' => [
|
||||
'name' => (string) $bargainSku->sku->name,
|
||||
'subtitle' => (string) $bargainSku->sku->subtitle,
|
||||
'cover' => (string) $bargainSku->sku->cover,
|
||||
'sell_price' => (string) $bargainSku->sku->sell_price_format,
|
||||
'vip_price' => (string) $bargainSku->sku->vip_price_format,
|
||||
],
|
||||
'max_bargain_price'=> array_sum(json_decode($bargainSku->activity->rules)),
|
||||
'activity_id' => $bargainSku->activity->id,
|
||||
'activity_images' => $bargainSku->activity->images,
|
||||
'activity_share_image'=> $bargainSku->activity->share_image,
|
||||
'activity_share_title'=> $bargainSku->activity->share_title,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过商品获取当前砍价进度(看自己的)
|
||||
*
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function barginaOrderBySku($id, Request $request)
|
||||
{
|
||||
// $order = [];
|
||||
$user = $request->user();
|
||||
$userId = $user?->id ?? 0;
|
||||
$order = BargainOrder::with(['logs', 'logs.userInfo'])
|
||||
->where([
|
||||
'sku_id' => $id,
|
||||
'user_id'=> $userId,
|
||||
])->where('status', '>', 0)
|
||||
->where('expire_at', '>', now())
|
||||
->whereNull('order_id')
|
||||
->orderBy('created_at', 'desc')->first();
|
||||
if ($order) {
|
||||
return BargainOrderResource::make($order);
|
||||
}
|
||||
return response()->noContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过订单ID获取当前砍价进度(看别人的)
|
||||
*
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function bargainOrderById($id, Request $request)
|
||||
{
|
||||
$order = BargainOrder::with(['logs', 'logs.userInfo'])
|
||||
->where([
|
||||
'id' => $id,
|
||||
])->where('status', '>', 0)
|
||||
->where('expire_at', '>', now())
|
||||
->whereNull('order_id')
|
||||
->orderBy('created_at', 'desc')->first();
|
||||
if ($order) {
|
||||
return BargainOrderResource::make($order);
|
||||
}
|
||||
return response()->noContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起砍价
|
||||
*
|
||||
* @param [type] $id
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function createBargainOrder(ProductSku $sku, Request $request)
|
||||
{
|
||||
if (!$sku->isBargaing()) {
|
||||
throw new BizException('活动已结束');
|
||||
}
|
||||
//判断是否已经有正在进行的砍价单, 直接返回
|
||||
$order = BargainOrder::where([
|
||||
'sku_id' => $sku->id,
|
||||
'user_id'=> $request->user()->id,
|
||||
])->where('status', '>', 0)
|
||||
->where('expire_at', '>', now())
|
||||
->whereNull('order_id')
|
||||
->orderBy('created_at', 'desc')->first();
|
||||
|
||||
if (!$order) {
|
||||
//创建新的砍价单
|
||||
$bargainService = new BargainService();
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$order = $bargainService->createBargainOrder($request->user(), $sku);
|
||||
DB::commit();
|
||||
} catch (Throwable $th) {
|
||||
DB::rollBack();
|
||||
report($th);
|
||||
throw new BizException($th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$order->load(['logs', 'logs.userInfo']);
|
||||
return BargainOrderResource::make($order);
|
||||
}
|
||||
|
||||
/**
|
||||
* 帮人砍价
|
||||
*
|
||||
* @param BargainOrder $order
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function bargain(BargainOrder $order, Request $request)
|
||||
{
|
||||
$bargainService = new BargainService();
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$bargainService->bargain($request->user(), $order);
|
||||
DB::commit();
|
||||
} catch (Throwable $th) {
|
||||
DB::rollBack();
|
||||
report($th);
|
||||
throw new BizException($th->getMessage());
|
||||
}
|
||||
|
||||
$order->load(['logs', 'logs.userInfo']);
|
||||
return BargainOrderResource::make($order);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过砍价订单创建待支付商城订单
|
||||
*
|
||||
* @param BargainOrder $bargainOrder
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function createMallOrderByBargainOrder(BargainOrder $bargainOrder, Request $request)
|
||||
{
|
||||
$rules = [
|
||||
'shipping_address_id' => ['bail', 'required', 'int'],
|
||||
'note' => ['bail', 'nullable', 'string', 'max:255'],
|
||||
];
|
||||
$input = $request->validate($rules, [], [
|
||||
'shipping_address_id' => '收货地址',
|
||||
'note' => '订单备注',
|
||||
]);
|
||||
$user = $request->user();
|
||||
if ($user->id != $bargainOrder->user_id) {
|
||||
throw new BizException('您不能替别人下单');
|
||||
}
|
||||
|
||||
$orderService = new OrderService();
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$bargainOrder->lockForUpdate();//下单的时候不允许砍价了
|
||||
|
||||
//已下单
|
||||
if ($bargainOrder->order_id > 0) {
|
||||
throw new BizException('您已下单,无需重复下单');
|
||||
}
|
||||
|
||||
//砍价超时
|
||||
if ($bargainOrder->expire_at < now()) {
|
||||
throw new BizException('当前砍价已结束,无法下单');
|
||||
}
|
||||
|
||||
//如果砍价活动结束了,也不能砍了
|
||||
$activity = $bargainOrder->sku->isBargaing();
|
||||
if (!$activity) {
|
||||
throw new BizException('当前砍价已结束,无法下单');
|
||||
}
|
||||
|
||||
$order = $orderService->createQuickOrder(
|
||||
$user,
|
||||
$bargainOrder->sku_id,
|
||||
1,
|
||||
$input['shipping_address_id'],
|
||||
null,
|
||||
$input['note'] ?? null,
|
||||
$bargainOrder
|
||||
);
|
||||
$bargainOrder->update([
|
||||
'order_id' => $order->id,
|
||||
]);
|
||||
DB::commit();
|
||||
} catch (Throwable $th) {
|
||||
DB::rollBack();
|
||||
report($th);
|
||||
throw new BizException($th->getMessage());
|
||||
}
|
||||
|
||||
OrderPaid::dispatchIf($order->isPaid(), $order);
|
||||
|
||||
return OrderResource::make($order);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ class OrderVerifyController extends Controller
|
|||
$rules = [
|
||||
'coupon_id' => ['bail', 'nullable', 'int'],
|
||||
'shipping_address_id' => ['bail', 'nullable', 'int'],
|
||||
'baragain_order_id' => ['bail', 'nullable', 'int'],
|
||||
];
|
||||
|
||||
// 快速下单
|
||||
|
|
@ -40,6 +41,7 @@ class OrderVerifyController extends Controller
|
|||
'product.quantity' => '数量',
|
||||
'coupon_id' => '优惠券',
|
||||
'shipping_address_id' => '收货地址',
|
||||
'bargain_order_id'=> '砍价',
|
||||
]);
|
||||
|
||||
$user = $request->user();
|
||||
|
|
@ -52,6 +54,7 @@ class OrderVerifyController extends Controller
|
|||
$request->input('product.quantity'),
|
||||
$request->input('shipping_address_id'),
|
||||
$request->input('coupon_id'),
|
||||
$request->input('bargain_order_id'),
|
||||
) : $orderService->verifyShoppingCartOrder(
|
||||
$user,
|
||||
$request->input('shopping_cart'),
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Endpoint\Api\Http\Controllers;
|
||||
|
||||
use App\Endpoint\Api\Http\Resources\UserBankResource;
|
||||
use App\Enums\Bank;
|
||||
use App\Models\UserBank;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
|
|
@ -11,21 +12,7 @@ class UserBankController extends Controller
|
|||
public function options(Request $request)
|
||||
{
|
||||
return response()->json([
|
||||
'banks' => [
|
||||
'中国建设银行',
|
||||
'中国农业银行',
|
||||
'中国工商银行',
|
||||
'中国银行',
|
||||
'交通银行',
|
||||
'招商银行',
|
||||
'民生银行',
|
||||
'兴业银行',
|
||||
'中信实业银行',
|
||||
'上海浦东发展银行',
|
||||
'光大银行',
|
||||
'邮政储蓄银行',
|
||||
'平安银行',
|
||||
],
|
||||
'banks' => array_values(Bank::banks()),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Endpoint\Api\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class ArticleCategoryResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'cover' => $this->cover ?? '',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Endpoint\Api\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class BargainActivityResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'name' => $this->name,
|
||||
'images' => $this->images,
|
||||
'description' => $this->description,
|
||||
'skus' => ProductSkuSimpleResource::collection($this->whenLoaded('skus')),
|
||||
'share_image'=> $this->share_image ?? '',
|
||||
'share_title'=> $this->share_title ?? '',
|
||||
'start_at' => $this->start_at->rawFormat('Y-m-d H:i:s'),
|
||||
'end_at' => $this->end_at->rawFormat('Y-m-d H:i:s'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Endpoint\Api\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class BargainOrderLogResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'nickname'=> (string) $this->whenLoaded('userInfo', function () {
|
||||
return $this->userInfo->nickname;
|
||||
}, ''),
|
||||
'avatar'=> (string) $this->whenLoaded('userInfo', function () {
|
||||
return $this->userInfo->avatar;
|
||||
}, ''),
|
||||
'bargain_amount' => $this->bargain_amount_format,
|
||||
'created_at' => $this->created_at->format('Y-m-d H:i:s'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Endpoint\Api\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class BargainOrderResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
$user = $request->user();
|
||||
$userId = $user?->id ?? 0;
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'logs' => BargainOrderLogResource::collection($this->whenLoaded('logs')),
|
||||
'expire_at'=> $this->expire_at->format('Y-m-d H:i:s'),
|
||||
'status' => $this->status,
|
||||
'user_nickname'=> $this->user->userInfo->nickname ?? '',
|
||||
'user_avatar'=> $this->user->userInfo->avatar ?? '',
|
||||
'is_owner' => $this->user_id == $userId ? true : false,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ class OrderResource extends JsonResource
|
|||
'coupon_discount_amount' => $this->coupon_discount_amount_format,
|
||||
'vip_discount_amount' => $this->vip_discount_amount_format,
|
||||
'reduced_amount' => $this->reduced_amount_format,
|
||||
'bargain_amount' => $this->bargain_amount_format,
|
||||
'shipping_fee' => $this->shipping_fee_format,
|
||||
'products_total_amount' => $this->products_total_amount_format,
|
||||
'total_amount' => $this->total_amount_format,
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ class ProduckSkuResource extends JsonResource
|
|||
}),
|
||||
'growth_value' => (int) $this->growth_value,
|
||||
'sales_value' => (int) $this->sales_value,
|
||||
'is_bargaing' => $this->isBargaing() ? true : false,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,8 @@ Route::group([
|
|||
Route::get('product/search-hot-keys', [ProductSkuController::class, 'searchHotKeys']);
|
||||
//文章列表
|
||||
Route::get('articles', [ArticleController::class, 'index']);
|
||||
Route::get('articles/health-category', [ArticleController::class, 'healthCategory']);
|
||||
Route::get('articles/by-category/{category}', [ArticleController::class, 'articleList']);
|
||||
|
||||
//指定文章配置
|
||||
Route::get('article-config', [ArticleController::class, 'config']);
|
||||
|
|
@ -87,6 +89,13 @@ Route::group([
|
|||
Route::get('configs', [SettingController::class, 'index']);
|
||||
Route::get('configs-custom', [SettingController::class, 'custom']);
|
||||
|
||||
//砍价
|
||||
Route::get('bargains/{activity}', [\App\Endpoint\Api\Http\Controllers\BargainController::class, 'activityDetail']);
|
||||
Route::get('bargain-sku/{sku}', [\App\Endpoint\Api\Http\Controllers\BargainController::class, 'bargainSku']);
|
||||
Route::get('bargain-order/sku/{sku}', [\App\Endpoint\Api\Http\Controllers\BargainController::class, 'barginaOrderBySku']);
|
||||
Route::get('bargain-order/order/{order}', [\App\Endpoint\Api\Http\Controllers\BargainController::class, 'bargainOrderById']);
|
||||
|
||||
|
||||
//三方登录聚合
|
||||
Route::group([
|
||||
'prefix' =>'socialite',
|
||||
|
|
@ -193,6 +202,11 @@ Route::group([
|
|||
Route::get('order/orders/{package}/shipping-info', [OrderController::class, 'shippingInfo']);
|
||||
|
||||
Route::get('users/{phone}', [\App\Endpoint\Api\Http\Controllers\UserController::class, 'show']);
|
||||
|
||||
//砍价
|
||||
Route::post('bargains/create-order/{sku}', [\App\Endpoint\Api\Http\Controllers\BargainController::class, 'createBargainOrder']);
|
||||
Route::post('bargains/bargain/{order}', [\App\Endpoint\Api\Http\Controllers\BargainController::class, 'bargain']);
|
||||
Route::post('bargains/create-mall-order/{bargainOrder}', [\App\Endpoint\Api\Http\Controllers\BargainController::class, 'createMallOrderByBargainOrder']);
|
||||
});
|
||||
|
||||
Route::group([
|
||||
|
|
|
|||
|
|
@ -0,0 +1,129 @@
|
|||
<?php
|
||||
|
||||
namespace App\Endpoint\Callback\Http\Controllers;
|
||||
|
||||
use App\Enums\DealerWalletToBankLogStatus;
|
||||
use App\Enums\WalletToBankLogStatus;
|
||||
use App\Models\DealerWalletToBankLog;
|
||||
use App\Models\WalletToBankLog;
|
||||
use App\Services\YeePayService;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class YeePayNotifyController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
$this->info('request parameters', $request->input());
|
||||
|
||||
$this->validateSign($request);
|
||||
|
||||
switch ($request->input('service')) {
|
||||
case 'accountpay.behalf.Pay':
|
||||
$this->handleBehalfPayNotify($request);
|
||||
break;
|
||||
}
|
||||
|
||||
return 'success';
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理代付回调
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return void
|
||||
*
|
||||
* @throws \App\Exceptions\BizException
|
||||
*/
|
||||
protected function handleBehalfPayNotify(Request $request)
|
||||
{
|
||||
$resultCode = $request->input('resultCode');
|
||||
|
||||
if ($resultCode === 'EXECUTE_PROCESSING') {
|
||||
return;
|
||||
}
|
||||
|
||||
$orderNo = $request->input('merchOrderNo');
|
||||
$orderStatus = $request->input('orderStatus');
|
||||
|
||||
$context = (array) json_decode($request->input('context'), true);
|
||||
$contextType = Arr::get($context, 'type');
|
||||
|
||||
if ($contextType === 'wallet_to_bank') {
|
||||
$log = WalletToBankLog::where('pay_sn', $orderNo)->first();
|
||||
|
||||
if ($log === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($log->status !== WalletToBankLogStatus::Paying) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($orderStatus === 'SUCCESS') {
|
||||
$log->update([
|
||||
'status' => WalletToBankLogStatus::Success,
|
||||
'pay_at' => Carbon::parse($request->input('finishTime')),
|
||||
'failed_reason' => null,
|
||||
]);
|
||||
} elseif ($orderStatus === 'FAIL') {
|
||||
$log->update([
|
||||
'status' => WalletToBankLogStatus::Failed,
|
||||
'failed_reason' => $request->input('resultMessage').'#'.$resultCode,
|
||||
]);
|
||||
}
|
||||
} elseif ($contextType === 'dealer_wallet_to_bank') {
|
||||
$log = DealerWalletToBankLog::where('pay_sn', $orderNo)->first();
|
||||
|
||||
if ($log === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($log->status !== DealerWalletToBankLogStatus::Paying) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($orderStatus === 'SUCCESS') {
|
||||
$log->update([
|
||||
'status' => DealerWalletToBankLogStatus::Success,
|
||||
'pay_at' => Carbon::parse($request->input('finishTime')),
|
||||
'failed_reason' => null,
|
||||
]);
|
||||
} elseif ($orderStatus === 'FAIL') {
|
||||
$log->update([
|
||||
'status' => DealerWalletToBankLogStatus::Failed,
|
||||
'failed_reason' => $request->input('resultMessage').'#'.$resultCode,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验签名
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return void
|
||||
*
|
||||
* @throws \App\Exceptions\BizException
|
||||
*/
|
||||
protected function validateSign(Request $request)
|
||||
{
|
||||
$yeePayService = new YeePayService(config('services.yeepay'));
|
||||
|
||||
if ($request->input('sign') === $yeePayService->sign($request->input())) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception('签名错误');
|
||||
}
|
||||
|
||||
protected function info($message, array $context = [])
|
||||
{
|
||||
logger()->build([
|
||||
'driver' => 'daily',
|
||||
'path' => storage_path('logs/yeepay-notify.log'),
|
||||
])->info('yeepay notify', $context);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
use App\Endpoint\Callback\Http\Controllers\AlipayController;
|
||||
use App\Endpoint\Callback\Http\Controllers\Kuaidi100Controller;
|
||||
use App\Endpoint\Callback\Http\Controllers\WxpayController;
|
||||
use App\Endpoint\Callback\Http\Controllers\YeePayNotifyController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
//快递100物流推送
|
||||
|
|
@ -13,3 +14,5 @@ Route::post('wxpay/{payment}/paid-notify', [WxpayController::class, 'paidNotify'
|
|||
Route::post('wxpay/{payment}/order-refund-notify', [WxpayController::class, 'orderRefundedNotify'])->name('wxpay.order_refund_notify');
|
||||
|
||||
Route::post('alipay', AlipayController::class)->name('alipay.notify');
|
||||
|
||||
Route::post('yeepay-notify', YeePayNotifyController::class)->name('yeepay.notify');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum Bank {
|
||||
case CCB;
|
||||
case ABC;
|
||||
case ICBC;
|
||||
case BOC;
|
||||
case BOCO;
|
||||
case CMBCHINA;
|
||||
case CMBC;
|
||||
case CIB;
|
||||
case CITIC;
|
||||
case SPDB;
|
||||
case CEB;
|
||||
case PSBC;
|
||||
case SDB;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function bankName(): string
|
||||
{
|
||||
return static::banks()[$this->name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $bankName
|
||||
* @return static
|
||||
*/
|
||||
public static function tryFromBankName(string $bankName): ?static
|
||||
{
|
||||
foreach (static::cases() as $enum) {
|
||||
if ($enum->bankName() === $bankName) {
|
||||
return $enum;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function banks(): array
|
||||
{
|
||||
return [
|
||||
static::CCB->name => '中国建设银行',
|
||||
static::ABC->name => '中国农业银行',
|
||||
static::ICBC->name => '中国工商银行',
|
||||
static::BOC->name => '中国银行',
|
||||
static::BOCO->name => '交通银行',
|
||||
static::CMBCHINA->name => '招商银行',
|
||||
static::CMBC->name => '民生银行',
|
||||
static::CIB->name => '兴业银行',
|
||||
static::CITIC->name => '中信实业银行',
|
||||
static::SPDB->name => '上海浦东发展银行',
|
||||
static::CEB->name => '光大银行',
|
||||
static::PSBC->name => '邮政储蓄银行',
|
||||
static::SDB->name => '平安银行',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum DealerWalletToBankLogPayWay: int {
|
||||
case Offline = 1;
|
||||
case Behalf = 2;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function color(): string
|
||||
{
|
||||
return match ($this) {
|
||||
static::Offline => '#5b69bc',
|
||||
static::Behalf => '#21b978',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function text(): string
|
||||
{
|
||||
return static::texts()[$this->value];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function texts(): array
|
||||
{
|
||||
return [
|
||||
static::Offline->value => '线下',
|
||||
static::Behalf->value => '代付',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum DealerWalletToBankLogStatus: int {
|
||||
case Pending = 0;
|
||||
case Success = 1;
|
||||
case Refused = 2;
|
||||
case Passed = 3; // 审核通过 - 等待付款
|
||||
case Paying = 4; // 审核通过 - 付款中
|
||||
case Failed = 9;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function color(): string
|
||||
{
|
||||
return match ($this) {
|
||||
static::Pending => '#5b69bc',
|
||||
static::Passed => '#dda451',
|
||||
static::Paying => '#3085d6',
|
||||
static::Success => '#21b978',
|
||||
static::Failed => '#ea5455',
|
||||
static::Refused => '#b3b9bf',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function text(): string
|
||||
{
|
||||
return static::texts()[$this->value];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function texts(): array
|
||||
{
|
||||
return [
|
||||
static::Pending->value => '待处理',
|
||||
static::Passed->value => '待付款',
|
||||
static::Paying->value => '付款中',
|
||||
static::Success->value => '成功',
|
||||
static::Failed->value => '失败',
|
||||
static::Refused->value => '拒绝',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum WalletToBankLogPayWay: int {
|
||||
case Offline = 1;
|
||||
case Behalf = 2;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function color(): string
|
||||
{
|
||||
return match ($this) {
|
||||
static::Offline => '#5b69bc',
|
||||
static::Behalf => '#21b978',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function text(): string
|
||||
{
|
||||
return static::texts()[$this->value];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function texts(): array
|
||||
{
|
||||
return [
|
||||
static::Offline->value => '线下',
|
||||
static::Behalf->value => '代付',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum WalletToBankLogStatus: int {
|
||||
case Pending = 0;
|
||||
case Success = 1;
|
||||
case Refused = 2;
|
||||
case Passed = 3; // 审核通过 - 等待付款
|
||||
case Paying = 4; // 审核通过 - 付款中
|
||||
case Failed = 9;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function color(): string
|
||||
{
|
||||
return match ($this) {
|
||||
static::Pending => '#5b69bc',
|
||||
static::Passed => '#dda451',
|
||||
static::Paying => '#3085d6',
|
||||
static::Success => '#21b978',
|
||||
static::Failed => '#ea5455',
|
||||
static::Refused => '#b3b9bf',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function text(): string
|
||||
{
|
||||
return static::texts()[$this->value];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function texts(): array
|
||||
{
|
||||
return [
|
||||
static::Pending->value => '待处理',
|
||||
static::Passed->value => '待付款',
|
||||
static::Paying->value => '付款中',
|
||||
static::Success->value => '成功',
|
||||
static::Failed->value => '失败',
|
||||
static::Refused->value => '拒绝',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class YeePayException extends Exception
|
||||
{
|
||||
}
|
||||
|
|
@ -42,6 +42,9 @@ class SendCoupons
|
|||
$products = $order->products()->where('is_gift', false)->get()->toArray();
|
||||
$_products = array_column($products, 'total_amount', 'sku_id');
|
||||
$partSkus = ProductPartSku::with('part')->whereIn('sku_id', array_keys($_products))->get();
|
||||
|
||||
$inValidParts = [];
|
||||
|
||||
foreach ($partSkus as $partSku) {
|
||||
if ($partSku->part?->is_show) {
|
||||
$inValidParts[$partSku->part_id][$partSku->sku_id] = $_products[$partSku->sku_id] ?? 0;
|
||||
|
|
@ -52,49 +55,51 @@ class SendCoupons
|
|||
// }
|
||||
}
|
||||
}
|
||||
// dd($inValidParts);
|
||||
//根据分区获取活动
|
||||
$partActivities = ActivityProductPart::with(['activity', 'activity.coupons'])->whereHas('activity', function (Builder $query) {
|
||||
return $query->where('is_use', true)->where('started_at', '<', now())->where('ended_at', '>=', now());
|
||||
})->whereIn('part_id', array_keys($inValidParts))->get();
|
||||
$activityArr = [];
|
||||
$partActivities->each(function ($item) use (&$activityArr) {
|
||||
$activityArr[$item->activity_id][] = $item->part_id;
|
||||
});
|
||||
$sendedActivities = [];
|
||||
foreach ($partActivities as $partActivity) {
|
||||
//判断该活动是否已处理
|
||||
if (in_array($partActivity->activity_id, $sendedActivities)) {
|
||||
continue;
|
||||
}
|
||||
$sendedActivities[] = $partActivity->activity_id;
|
||||
//获取活动的赠品赠送规则
|
||||
$_couponsRule = $partActivity->activity?->coupons_rule;
|
||||
//判断是否首单:times=0为仅首单赠送, 1为不限
|
||||
if ($_couponsRule['times'] == 0 && UserCoupon::where([
|
||||
'activity_id' => $partActivity->activity_id,
|
||||
'user_id' => $order->user_id,
|
||||
])->exists()) {
|
||||
continue;//提前结束本次循环
|
||||
}
|
||||
//判断是否满足门槛
|
||||
$inValidGoods = [];
|
||||
foreach ($inValidParts as $key => $part) {
|
||||
if (in_array($key, $activityArr[$partActivity->activity_id])) {
|
||||
$inValidGoods = array_merge($inValidGoods, $part);
|
||||
//存在有效分区时
|
||||
if ($inValidParts) {
|
||||
//根据分区获取活动
|
||||
$partActivities = ActivityProductPart::with(['activity', 'activity.coupons'])->whereHas('activity', function (Builder $query) {
|
||||
return $query->where('is_use', true)->where('started_at', '<', now())->where('ended_at', '>=', now());
|
||||
})->whereIn('part_id', array_keys($inValidParts))->get();
|
||||
$activityArr = [];
|
||||
$partActivities->each(function ($item) use (&$activityArr) {
|
||||
$activityArr[$item->activity_id][] = $item->part_id;
|
||||
});
|
||||
$sendedActivities = [];
|
||||
foreach ($partActivities as $partActivity) {
|
||||
//判断该活动是否已处理
|
||||
if (in_array($partActivity->activity_id, $sendedActivities)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (bcmul($_couponsRule['value'], 100) > array_sum($inValidGoods)) {
|
||||
continue;//提前结束本次循环
|
||||
}
|
||||
//赠券
|
||||
(new CouponService())->receiveActivityCoupons($partActivity->activity, $order->user);
|
||||
$sendedActivities[] = $partActivity->activity_id;
|
||||
//获取活动的赠品赠送规则
|
||||
$_couponsRule = $partActivity->activity?->coupons_rule;
|
||||
//判断是否首单:times=0为仅首单赠送, 1为不限
|
||||
if ($_couponsRule['times'] == 0 && UserCoupon::where([
|
||||
'activity_id' => $partActivity->activity_id,
|
||||
'user_id' => $order->user_id,
|
||||
])->exists()) {
|
||||
continue;//提前结束本次循环
|
||||
}
|
||||
//判断是否满足门槛
|
||||
$inValidGoods = [];
|
||||
foreach ($inValidParts as $key => $part) {
|
||||
if (in_array($key, $activityArr[$partActivity->activity_id])) {
|
||||
$inValidGoods = array_merge($inValidGoods, $part);
|
||||
}
|
||||
}
|
||||
if (bcmul($_couponsRule['value'], 100) > array_sum($inValidGoods)) {
|
||||
continue;//提前结束本次循环
|
||||
}
|
||||
//赠券
|
||||
(new CouponService())->receiveActivityCoupons($partActivity->activity, $order->user);
|
||||
|
||||
//记录订单参与活动信息
|
||||
OrderActivity::firstOrCreate([
|
||||
'order_id'=>$order->id,
|
||||
'activity_id'=>$partActivity->activity_id,
|
||||
]);
|
||||
//记录订单参与活动信息
|
||||
OrderActivity::firstOrCreate([
|
||||
'order_id'=>$order->id,
|
||||
'activity_id'=>$partActivity->activity_id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Casts\JsonArray;
|
||||
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class BargainActivity extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasDateTimeFormatter;
|
||||
|
||||
protected $casts = [
|
||||
'images' => JsonArray::class,
|
||||
'start_at' => 'datetime',
|
||||
'end_at' => 'datetime',
|
||||
];
|
||||
|
||||
public static $enabledText = [
|
||||
0=>'禁用',
|
||||
1=>'启用',
|
||||
];
|
||||
|
||||
public static $enabledColor = [
|
||||
0=>'#b3b9bf',
|
||||
1=>'success',
|
||||
];
|
||||
|
||||
public function skus()
|
||||
{
|
||||
return $this->belongsToMany(ProductSku::class, 'bargain_skus', 'activity_id', 'sku_id');
|
||||
}
|
||||
|
||||
public function scopeIsEnable($query)
|
||||
{
|
||||
return $query->where('is_enable', true);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class BargainOrder extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasDateTimeFormatter;
|
||||
|
||||
protected $casts = [
|
||||
'expire_at'=> 'datetime',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'order_id', 'remark',
|
||||
];
|
||||
|
||||
public const ORDER_STATUS_WAIT = 0;
|
||||
public const ORDER_STATUS_START = 1;
|
||||
public const ORDER_STATUS_FINISHED = 2;
|
||||
|
||||
public function activity()
|
||||
{
|
||||
return $this->belongsTo(BargainActivity::class, 'activity_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function userInfo()
|
||||
{
|
||||
return $this->belongsTo(UserInfo::class, 'user_id', 'user_id');
|
||||
}
|
||||
|
||||
public function logs()
|
||||
{
|
||||
return $this->hasMany(BargainOrderLog::class, 'order_id');
|
||||
}
|
||||
|
||||
public function sku()
|
||||
{
|
||||
return $this->hasOne(ProductSku::class, 'id', 'sku_id');
|
||||
}
|
||||
|
||||
public function mallOrder()
|
||||
{
|
||||
return $this->belongsTo(Order::class, 'order_id');
|
||||
}
|
||||
|
||||
public function isFinished()
|
||||
{
|
||||
return $this->status == static::ORDER_STATUS_FINISHED;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class BargainOrderLog extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasDateTimeFormatter;
|
||||
|
||||
protected $fillable = [
|
||||
'user_id', 'bargain_amount',
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function userInfo()
|
||||
{
|
||||
return $this->belongsTo(UserInfo::class, 'user_id', 'user_id');
|
||||
}
|
||||
|
||||
public function getBargainAmountFormatAttribute()
|
||||
{
|
||||
return bcdiv($this->attributes['bargain_amount'], 100, 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class BargainSku extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $timestamp = false;
|
||||
|
||||
public function activity()
|
||||
{
|
||||
return $this->belongsTo(BargainActivity::class, 'activity_id');
|
||||
}
|
||||
|
||||
public function sku()
|
||||
{
|
||||
return $this->belongsTo(ProductSku::class, 'sku_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Casts\JsonArray;
|
||||
use App\Enums\DealerWalletToBankLogPayWay;
|
||||
use App\Enums\DealerWalletToBankLogStatus;
|
||||
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
|
@ -11,9 +14,17 @@ class DealerWalletToBankLog extends Model
|
|||
use HasFactory;
|
||||
use HasDateTimeFormatter;
|
||||
|
||||
public const STATUS_PENDING = 0;//'待处理'
|
||||
public const STATUS_AGREE = 1;//'已同意'
|
||||
public const STATUS_REFUSE = 2;//'已拒绝'
|
||||
protected $attributes = [
|
||||
'pay_way' => DealerWalletToBankLogPayWay::Offline,
|
||||
'status' => DealerWalletToBankLogStatus::Pending,
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'pay_info' => JsonArray::class,
|
||||
'pay_at' => 'datetime',
|
||||
'pay_way' => DealerWalletToBankLogPayWay::class,
|
||||
'status' => DealerWalletToBankLogStatus::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
|
|
@ -26,6 +37,12 @@ class DealerWalletToBankLog extends Model
|
|||
'rate',
|
||||
'service_amount',
|
||||
'account_amount',
|
||||
'pay_info',
|
||||
'pay_image',
|
||||
'pay_sn',
|
||||
'pay_way',
|
||||
'pay_at',
|
||||
'failed_reason',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -49,7 +66,12 @@ class DealerWalletToBankLog extends Model
|
|||
*/
|
||||
public function isPending()
|
||||
{
|
||||
return $this->status == self::STATUS_PENDING;
|
||||
return $this->status === DealerWalletToBankLogStatus::Pending;
|
||||
}
|
||||
|
||||
public function isFailed()
|
||||
{
|
||||
return $this->status === DealerWalletToBankLogStatus::Failed;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -59,7 +81,7 @@ class DealerWalletToBankLog extends Model
|
|||
*/
|
||||
public function getPayInfo()
|
||||
{
|
||||
if ($this->isPending()) {//待打款订单显示发货人收款信息
|
||||
if ($this->isPending() || $this->isFailed()) {//待打款订单显示发货人收款信息
|
||||
$payInfo = $this->user->dealer->pay_info;
|
||||
} else {
|
||||
$payInfo = $this->pay_info;
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ class Order extends Model
|
|||
'is_settle',
|
||||
'sales_value',
|
||||
'is_settlable',
|
||||
'bargain_amount',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -427,4 +428,14 @@ class Order extends Model
|
|||
{
|
||||
return OrderStatus::$statusTexts[$this->order_status] ?? OrderStatus::$statusTexts[OrderStatus::UNKNOWN];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单砍价优惠
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBargainAmountFormatAttribute()
|
||||
{
|
||||
return trim_trailing_zeros(bcdiv($this->attributes['bargain_amount'], 100, 2));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ class OrderProduct extends Model
|
|||
'remain_quantity',
|
||||
'is_gift',
|
||||
'activity_id',
|
||||
'bargain_amount',
|
||||
];
|
||||
|
||||
public function packageProducts()
|
||||
|
|
|
|||
|
|
@ -195,4 +195,21 @@ class ProductSku extends Model
|
|||
|
||||
return bcdiv($price, 100, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否正在进行砍价
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isBargaing()
|
||||
{
|
||||
$bargainSku = BargainSku::with(['activity'=>function ($query) {
|
||||
return $query->where('is_enable', true)->where('start_at', '<=', now())->where('end_at', '>=', now());
|
||||
}])->where('sku_id', $this->id)->first();
|
||||
|
||||
if ($bargainSku && $bargainSku->activity) {
|
||||
return $bargainSku->activity;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -410,6 +410,14 @@ class User extends Model implements AuthorizableContract, AuthenticatableContrac
|
|||
return $this->belongsToMany(User::class, 'user_infos', 'inviter_id', 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户的砍价单
|
||||
*/
|
||||
public function bargainOrders()
|
||||
{
|
||||
return $this->hasMany(BargainOrder::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取我的粉丝总数
|
||||
*
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\WalletToBankLogPayWay;
|
||||
use App\Enums\WalletToBankLogStatus;
|
||||
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
|
@ -11,9 +13,11 @@ class WalletToBankLog extends Model
|
|||
use HasFactory;
|
||||
use HasDateTimeFormatter;
|
||||
|
||||
public const STATUS_PENDING = 0;//'待处理'
|
||||
public const STATUS_AGREE = 1;//'已同意'
|
||||
public const STATUS_REFUSE = 2;//'已拒绝'
|
||||
protected $casts = [
|
||||
'status' => WalletToBankLogStatus::class,
|
||||
'pay_way' => WalletToBankLogPayWay::class,
|
||||
'pay_at' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
|
|
@ -30,6 +34,10 @@ class WalletToBankLog extends Model
|
|||
'rate',
|
||||
'service_amount',
|
||||
'account_amount',
|
||||
'pay_sn',
|
||||
'pay_way',
|
||||
'pay_at',
|
||||
'failed_reason',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Exceptions\BizException;
|
||||
use App\Models\BargainOrder;
|
||||
use App\Models\BargainOrderLog;
|
||||
use App\Models\BargainSku;
|
||||
use App\Models\ProductSku;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class BargainService
|
||||
{
|
||||
/**
|
||||
* 创建砍价单
|
||||
*
|
||||
* @param User $user
|
||||
* @param ProductSku $productSku
|
||||
* @return void
|
||||
*/
|
||||
public function createBargainOrder(User $user, ProductSku $productSku)
|
||||
{
|
||||
$bargainSku = BargainSku::with(['activity'=>function ($query) {
|
||||
return $query->where('is_enable', true)->where('start_at', '<=', now())->where('end_at', '>=', now());
|
||||
}])->where('sku_id', $productSku->id)->first();
|
||||
if (!($bargainSku && $bargainSku->activity)) {
|
||||
throw new BizException('砍价商品活动已结束');
|
||||
}
|
||||
|
||||
$order = new BargainOrder();
|
||||
$order->activity_id = $bargainSku->activity_id;
|
||||
$order->user_id = $user->id;
|
||||
$order->sku_id = $productSku->id;
|
||||
$order->sku_price = $productSku->getRealPrice($user);
|
||||
$order->status = BargainOrder::ORDER_STATUS_START;
|
||||
$order->expire_at = now()->addHours($bargainSku->activity->expire_hours);
|
||||
$order->save();
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户砍价
|
||||
*
|
||||
* @param User $user
|
||||
* @param BargainOrder $order
|
||||
* @return void
|
||||
*/
|
||||
public function bargain(User $user, BargainOrder $order)
|
||||
{
|
||||
$order->lockForUpdate();
|
||||
$order->load('sku');
|
||||
|
||||
//不能给自己砍
|
||||
if ($user->id == $order->user_id) {
|
||||
throw new BizException('不能帮自己砍价');
|
||||
}
|
||||
|
||||
//已砍完
|
||||
if ($order->isFinished()) {
|
||||
throw new BizException('当前砍价单已完成,无法再砍');
|
||||
}
|
||||
|
||||
//已下单
|
||||
if ($order->order_id > 0) {
|
||||
throw new BizException('当前砍价单已下单,无法再砍');
|
||||
}
|
||||
|
||||
//砍价超时
|
||||
if ($order->expire_at < now()) {
|
||||
throw new BizException('当前砍价已结束,无法再砍');
|
||||
}
|
||||
|
||||
//如果砍价活动结束了,也不能砍了
|
||||
$activity = $order->sku->isBargaing();
|
||||
if (!$activity) {
|
||||
throw new BizException('当前砍价已结束,无法再砍');
|
||||
}
|
||||
|
||||
//如果已经砍过了,不能再砍了
|
||||
if ($order->logs()->where('user_id', $user->id)->exists()) {
|
||||
throw new BizException('您已砍价');
|
||||
}
|
||||
|
||||
//执行砍价动作;
|
||||
//计算第几次砍价,并获得当前砍价金额
|
||||
$nowBargainCount = $order->logs->count();
|
||||
|
||||
$bargainRules = json_decode($activity->rules, true);
|
||||
|
||||
$log = new BargainOrderLog([
|
||||
'user_id'=>$user->id,
|
||||
'bargain_amount'=> bcmul(Arr::get($bargainRules, $nowBargainCount, 0), 100),
|
||||
]);
|
||||
|
||||
$order->logs()->save($log);
|
||||
$order->bargain_price += $log->bargain_amount;
|
||||
$nowBargainCount ++;
|
||||
|
||||
if ($activity->times > 0 && $nowBargainCount >= $activity->times) {
|
||||
$order->status = BargainOrder::ORDER_STATUS_FINISHED;
|
||||
}
|
||||
$order->save();
|
||||
|
||||
return $order;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ use App\Enums\WxpayTradeType;
|
|||
use App\Exceptions\BizException;
|
||||
use App\Exceptions\ShippingNotSupportedException;
|
||||
use App\Models\ActivityProductPart;
|
||||
use App\Models\BargainOrder;
|
||||
use App\Models\DistributionPreIncomeJob;
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderActivity;
|
||||
|
|
@ -38,6 +39,7 @@ class OrderService
|
|||
* @param int $shippingAddressId
|
||||
* @param int|null $couponId
|
||||
* @param string|null $note
|
||||
* @param BargainOrder|null $bargainOrder
|
||||
* @return \App\Models\Order
|
||||
*/
|
||||
public function createQuickOrder(
|
||||
|
|
@ -46,7 +48,8 @@ class OrderService
|
|||
int $quantity,
|
||||
int $shippingAddressId,
|
||||
?int $couponId = null,
|
||||
?string $note = null
|
||||
?string $note = null,
|
||||
?BargainOrder $bargainOrder = null,
|
||||
): Order {
|
||||
$sku = ProductSku::online()->findOrFail($skuId);
|
||||
|
||||
|
|
@ -55,7 +58,7 @@ class OrderService
|
|||
'quantity' => $quantity,
|
||||
];
|
||||
|
||||
return $this->createOrder($user, [$product], $shippingAddressId, $couponId, $note);
|
||||
return $this->createOrder($user, [$product], $shippingAddressId, $couponId, $note, $bargainOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -97,6 +100,7 @@ class OrderService
|
|||
* @param int $shippingAddressId
|
||||
* @param int|null $couponId
|
||||
* @param string|null $note
|
||||
* @param BargainOrder|null $bargainOrder
|
||||
* @return \App\Models\Order
|
||||
*/
|
||||
protected function createOrder(
|
||||
|
|
@ -105,6 +109,7 @@ class OrderService
|
|||
int $shippingAddressId,
|
||||
?int $couponId = null,
|
||||
?string $note = null,
|
||||
?BargainOrder $bargainOrder = null,
|
||||
): Order {
|
||||
foreach ($products as $product) {
|
||||
$sku = $product['sku'];
|
||||
|
|
@ -123,7 +128,7 @@ class OrderService
|
|||
$coupon = $user->coupons()->onlyAvailable()->lockForUpdate()->findOrFail($couponId);
|
||||
}
|
||||
|
||||
$mapProducts = $this->mapProducts($user, $products, $coupon);
|
||||
$mapProducts = $this->mapProducts($user, $products, $coupon, $bargainOrder);
|
||||
|
||||
// 计算运费
|
||||
$shippingFee = $this->calculateShippingFee($mapProducts, $shippingAddress);
|
||||
|
|
@ -144,7 +149,8 @@ class OrderService
|
|||
$shippingFee,
|
||||
$salesValue,
|
||||
$note,
|
||||
$coupon
|
||||
$coupon,
|
||||
$bargainOrder,//添加砍价订单逻辑
|
||||
);
|
||||
|
||||
$this->storeOrderProducts($order, $mapProducts);
|
||||
|
|
@ -185,10 +191,16 @@ class OrderService
|
|||
$salesValue,
|
||||
?string $note = null,
|
||||
?UserCoupon $coupon = null,
|
||||
?BargainOrder $bargainOrder = null,
|
||||
): Order {
|
||||
// 订单支付金额=商品总额-券折扣金额-会员折扣金额+邮费
|
||||
// 订单支付金额=商品总额-券折扣金额-会员折扣金额+邮费-砍价金额
|
||||
$totalAmount = $productsTotalAmount - $couponDiscountAmount - $vipDiscountAmount;
|
||||
|
||||
//如果有砍价优惠
|
||||
if ($bargainOrder) {
|
||||
$totalAmount -= $bargainOrder->bargain_price;
|
||||
}
|
||||
|
||||
if ($totalAmount < 0) {
|
||||
$totalAmount = 0;
|
||||
}
|
||||
|
|
@ -213,6 +225,8 @@ class OrderService
|
|||
'consignee_telephone' => $shippingAddress->telephone,
|
||||
'consignee_zone' => $shippingAddress->zone,
|
||||
'consignee_address' => $shippingAddress->address,
|
||||
//砍价订单金额
|
||||
'bargain_amount'=>$bargainOrder?->bargain_price ?? 0,
|
||||
];
|
||||
|
||||
return $user->orders()->create($attrs);
|
||||
|
|
@ -239,8 +253,8 @@ class OrderService
|
|||
$sku = $product['sku'];
|
||||
$qty = $product['quantity'];
|
||||
|
||||
// 支付金额 = 商品总额 - 优惠券折扣金额- 会员折扣金额
|
||||
$totalAmount = $product['total_amount'] - $product['coupon_discount_amount'] - $product['vip_discount_amount'];
|
||||
// 支付金额 = 商品总额 - 优惠券折扣金额- 会员折扣金额 - 砍价金额
|
||||
$totalAmount = $product['total_amount'] - $product['coupon_discount_amount'] - $product['vip_discount_amount'] - $product['bargain_amount'];
|
||||
|
||||
$orderProducts[] = [
|
||||
'gift_for_sku_id' => null,
|
||||
|
|
@ -263,6 +277,7 @@ class OrderService
|
|||
'coupon_discount_amount' => $product['coupon_discount_amount'],
|
||||
'vip_discount_amount' => $product['vip_discount_amount'],
|
||||
'total_amount' => $totalAmount,
|
||||
'bargain_amount'=> $product['bargain_amount'],
|
||||
'created_at' => $order->created_at,
|
||||
'updated_at' => $order->updated_at,
|
||||
];
|
||||
|
|
@ -452,6 +467,7 @@ class OrderService
|
|||
'coupon_discount_amount' => 0,
|
||||
'vip_discount_amount' => 0,
|
||||
'total_amount' => 0,
|
||||
'bargain_amount'=> 0,
|
||||
'created_at' => $order->created_at,
|
||||
'updated_at' => $order->updated_at,
|
||||
'is_gift'=> true,
|
||||
|
|
@ -481,9 +497,10 @@ class OrderService
|
|||
* @param int $quantity
|
||||
* @param int|null $shippingAddressId
|
||||
* @param int|null $couponId
|
||||
* @param int|null $bargainOrderId
|
||||
* @return array
|
||||
*/
|
||||
public function verifyQuickOrder(User $user, int $skuId, int $quantity, ?int $shippingAddressId = null, ?int $couponId = null)
|
||||
public function verifyQuickOrder(User $user, int $skuId, int $quantity, ?int $shippingAddressId = null, ?int $couponId = null, ?int $bargainOrderId = null)
|
||||
{
|
||||
$sku = ProductSku::online()->findOrFail($skuId);
|
||||
|
||||
|
|
@ -492,7 +509,7 @@ class OrderService
|
|||
'quantity' => $quantity,
|
||||
];
|
||||
|
||||
return $this->verifyOrder($user, [$product], $shippingAddressId, $couponId);
|
||||
return $this->verifyOrder($user, [$product], $shippingAddressId, $couponId, $bargainOrderId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -519,9 +536,10 @@ class OrderService
|
|||
* @param array $products
|
||||
* @param int|null $shippingAddressId
|
||||
* @param int|null $couponId
|
||||
* @param int|null $bargainOrderId
|
||||
* @return array
|
||||
*/
|
||||
protected function verifyOrder(User $user, array $products, ?int $shippingAddressId = null, ?int $couponId = null): array
|
||||
protected function verifyOrder(User $user, array $products, ?int $shippingAddressId = null, ?int $couponId = null, ?int $bargainOrderId = null): array
|
||||
{
|
||||
// 获取收货地址
|
||||
$shippingAddress = $this->getShippingAddress($user, $shippingAddressId);
|
||||
|
|
@ -533,7 +551,12 @@ class OrderService
|
|||
$coupon = $user->coupons()->onlyAvailable()->findOrFail($couponId);
|
||||
}
|
||||
|
||||
$mapProducts = $this->mapProducts($user, $products, $coupon);
|
||||
$bargainOrder = null;
|
||||
if ($bargainOrderId) {
|
||||
$bargainOrder = $user->bargainOrders()->findOrFail($bargainOrderId);
|
||||
}
|
||||
|
||||
$mapProducts = $this->mapProducts($user, $products, $coupon, $bargainOrder);
|
||||
|
||||
// 是否支持配送
|
||||
$shippingSupported = true;
|
||||
|
|
@ -554,9 +577,10 @@ class OrderService
|
|||
$vipDiscountAmount,
|
||||
$couponDiscountAmount,
|
||||
$salesValue,
|
||||
$bargainAmount,
|
||||
) = $this->calculateFees($mapProducts);
|
||||
|
||||
$totalAmount = $productsTotalAmount - $couponDiscountAmount - $vipDiscountAmount;
|
||||
$totalAmount = $productsTotalAmount - $couponDiscountAmount - $vipDiscountAmount - $bargainAmount;
|
||||
|
||||
if ($totalAmount < 0) {
|
||||
$totalAmount = 0;
|
||||
|
|
@ -579,6 +603,7 @@ class OrderService
|
|||
'vip_discount_amount' => trim_trailing_zeros(bcdiv($vipDiscountAmount, 100, 2)), // 会员折扣金额
|
||||
'coupon_discount_amount' => trim_trailing_zeros(bcdiv($couponDiscountAmount, 100, 2)), // 优惠券折扣金额
|
||||
'total_amount' => trim_trailing_zeros(bcdiv($totalAmount, 100, 2)), // 实付金额
|
||||
'bargain_amount' => trim_trailing_zeros(bcdiv($bargainAmount, 100, 2)), //砍价金额
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -594,12 +619,14 @@ class OrderService
|
|||
$vipDiscountAmount = 0;
|
||||
$couponDiscountAmount = 0;
|
||||
$salesValue = 0;
|
||||
$bargainAmount = 0;
|
||||
|
||||
foreach ($products as $product) {
|
||||
$productsTotalAmount += $product['total_amount'];
|
||||
$vipDiscountAmount += $product['vip_discount_amount'];
|
||||
$couponDiscountAmount += $product['coupon_discount_amount'];
|
||||
$salesValue = bcadd($salesValue, $product['total_sales_value']);
|
||||
$bargainAmount += $product['bargain_amount'];
|
||||
}
|
||||
|
||||
return [
|
||||
|
|
@ -607,6 +634,7 @@ class OrderService
|
|||
$vipDiscountAmount,
|
||||
$couponDiscountAmount,
|
||||
$salesValue,
|
||||
$bargainAmount,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -665,7 +693,7 @@ class OrderService
|
|||
*
|
||||
* @throws \App\Exceptions\BizException
|
||||
*/
|
||||
protected function mapProducts(User $user, array $products, ?UserCoupon $coupon): array
|
||||
protected function mapProducts(User $user, array $products, ?UserCoupon $coupon, ?BargainOrder $bargainOrder = null): array
|
||||
{
|
||||
$_products = collect($products)->map(function ($item) use ($user) {
|
||||
$sku = $item['sku'];
|
||||
|
|
@ -681,9 +709,20 @@ class OrderService
|
|||
'total_amount' => $sku->sell_price * $item['quantity'],
|
||||
// 总销售值
|
||||
'total_sales_value' => bcmul($sku->sales_value, $item['quantity'], 2),
|
||||
//砍价金额
|
||||
'bargain_amount' => 0,
|
||||
]);
|
||||
});
|
||||
|
||||
//处理砍价金额
|
||||
if ($bargainOrder) {
|
||||
$bargainDiscountAmount = $this->getBargainDiscountAmount($bargainOrder, $_products->all());
|
||||
$_products = $_products->map(function ($item) use ($bargainDiscountAmount) {
|
||||
$item['bargain_amount'] = $bargainDiscountAmount[$item['sku']->id] ?? 0;
|
||||
return $item;
|
||||
});
|
||||
}
|
||||
|
||||
if ($coupon === null) {
|
||||
return $_products->all();
|
||||
}
|
||||
|
|
@ -778,9 +817,12 @@ class OrderService
|
|||
foreach ($amounts as &$amount) {
|
||||
$i--;
|
||||
|
||||
$originalAmount = $amount;
|
||||
|
||||
if ($i > 0) {
|
||||
$amount = (int) bcdiv(bcmul($couponAmount, $amount, 0), $totalAmount, 2);
|
||||
$couponAmount -= $amount;
|
||||
$totalAmount -= $originalAmount;
|
||||
} else {
|
||||
$amount = $couponAmount;
|
||||
}
|
||||
|
|
@ -791,6 +833,52 @@ class OrderService
|
|||
return $amounts;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function getBargainDiscountAmount(BargainOrder $bargainOrder, array $products): array
|
||||
{
|
||||
// 砍价的商品
|
||||
$amounts = [];
|
||||
foreach ($products as $item) {
|
||||
$sku = $item['sku'];
|
||||
|
||||
$amount = $item['total_amount'] - $item['vip_discount_amount'];
|
||||
|
||||
// 仅保留商品真实总额大于0的商品
|
||||
if ($amount > 0) {
|
||||
$amounts[$sku->id] = $amount;
|
||||
}
|
||||
}
|
||||
|
||||
// 全部商品总额
|
||||
$totalAmount = array_sum($amounts);
|
||||
|
||||
|
||||
$bargainAmount = $bargainOrder->bargain_price ?? 0;
|
||||
|
||||
// 待计算优惠的商品总数
|
||||
$i = count($amounts);
|
||||
|
||||
foreach ($amounts as &$amount) {
|
||||
$i--;
|
||||
|
||||
$originalAmount = $amount;
|
||||
|
||||
if ($i > 0) {
|
||||
$amount = (int) bcdiv(bcmul($bargainAmount, $amount, 0), $totalAmount, 2);
|
||||
$bargainAmount -= $amount;
|
||||
$totalAmount -= $originalAmount;
|
||||
} else {
|
||||
$amount = $bargainAmount;
|
||||
}
|
||||
|
||||
unset($amount);
|
||||
}
|
||||
|
||||
return $amounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据购物车获取商品
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Exceptions\YeePayException;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class YeePayService
|
||||
{
|
||||
public function __construct(
|
||||
protected array $config,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $service
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function request(string $service, array $data = []): array
|
||||
{
|
||||
$data = array_merge([
|
||||
'requestNo' => Str::uuid()->getHex()->toString(),
|
||||
'service' => $service,
|
||||
'partnerId' => $this->config['partner_id'],
|
||||
'signType' => 'MD5',
|
||||
'notifyUrl' => route('yeepay.notify'),
|
||||
], $data);
|
||||
|
||||
$data['sign'] = $this->sign($data);
|
||||
|
||||
$response = Http::asForm()->post($this->config['gateway_url'], $data);
|
||||
|
||||
$response->throw();
|
||||
|
||||
$result = $response->json();
|
||||
|
||||
if ($result['success'] && in_array($result['resultCode'], ['EXECUTE_SUCCESS', 'EXECUTE_PROCESSING', 'TIME_OUT'])) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$message = $result['resultDetail'] ?? $result['resultMessage'];
|
||||
|
||||
throw new YeePayException($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签名
|
||||
*
|
||||
* @param array $params
|
||||
* @return string
|
||||
*/
|
||||
public function sign(array $params): string
|
||||
{
|
||||
unset($params['sign']);
|
||||
|
||||
ksort($params);
|
||||
|
||||
$str = '';
|
||||
|
||||
foreach ($params as $key => $value) {
|
||||
if (blank($value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($str !== '') {
|
||||
$str .= '&';
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
$value = json_encode($value);
|
||||
}
|
||||
|
||||
$str .= "{$key}={$value}";
|
||||
}
|
||||
|
||||
$str .= $this->config['secret_key'];
|
||||
|
||||
return md5($str);
|
||||
}
|
||||
}
|
||||
|
|
@ -30,4 +30,10 @@ return [
|
|||
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
||||
],
|
||||
|
||||
'yeepay' => [
|
||||
'partner_id' => env('YEEPAY_PARTNER_ID'),
|
||||
'secret_key' => env('YEEPAY_SECRET_KEY'),
|
||||
'gateway_url' => env('YEEPAY_GATEWAY_URL'),
|
||||
],
|
||||
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateBargainActivitiesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('bargain_activities', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name')->comment('活动名称');
|
||||
$table->text('images')->nullable()->comment('活动图');
|
||||
$table->text('share_image')->nullable()->comment('分享图');
|
||||
$table->text('share_title')->nullable()->comment('分享文案');
|
||||
$table->text('description')->nullable()->comment('活动描述');
|
||||
$table->boolean('is_enable')->nullable()->comment('是否开启');
|
||||
$table->text('rules')->nullable()->comment('砍价规则');
|
||||
$table->unsignedInteger('times')->default(0)->comment('有效刀,0为不限');
|
||||
$table->unsignedInteger('expire_hours')->default(0)->comment('过期小时');
|
||||
$table->timestamp('start_at')->nullable()->comment('开始时间');
|
||||
$table->timestamp('end_at')->nullable()->comment('结束时间');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('bargain_activities');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateBargainOrdersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('bargain_orders', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('activity_id')->comment('参与活动ID');
|
||||
$table->unsignedBigInteger('user_id')->comment('发起用户ID');
|
||||
$table->unsignedBigInteger('sku_id')->comment('砍价商品');
|
||||
$table->unsignedBigInteger('sku_price')->default(0)->comment('原价:分');
|
||||
$table->unsignedBigInteger('bargain_price')->default(0)->comment('已砍价格:分');
|
||||
$table->unsignedTinyInteger('status')->default(0)->comment('状态:0未开始,1已开始,2已完成');
|
||||
$table->timestamp('expire_at')->nullable()->comment('过期时间');
|
||||
$table->unsignedBigInteger('order_id')->nullable()->comment('下单支付ID');
|
||||
$table->string('remark')->nullable()->comment('备注');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('bargain_orders');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateBargainSkusTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('bargain_skus', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('activity_id')->comment('活动ID');
|
||||
$table->unsignedBigInteger('sku_id')->comment('商品ID');
|
||||
// $table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('bargain_skus');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddBargainToOrdersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('orders', function (Blueprint $table) {
|
||||
//
|
||||
$table->unsignedBigInteger('bargain_amount')->nullable()->default(0)->comment('砍价金额');
|
||||
// $table->unsignedBigInteger('bargain_order_id')->nullable()->comment('关联砍价单ID');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('orders', function (Blueprint $table) {
|
||||
//
|
||||
$table->dropColumn(['bargain_amount']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateBargainOrderLogsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('bargain_order_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('order_id')->comment('订单ID');
|
||||
$table->unsignedBigInteger('user_id')->comment('用户ID');
|
||||
$table->unsignedBigInteger('bargain_amount')->default(0)->comment('砍价金额');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('bargain_order_logs');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddCoverToArticleCategoriesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('article_categories', function (Blueprint $table) {
|
||||
//
|
||||
$table->string('cover')->nullable()->comment('封面图');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('article_categories', function (Blueprint $table) {
|
||||
//
|
||||
$table->dropColumn(['cover']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
use App\Enums\WalletToBankLogPayWay;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddPayColumnsToWalletToBankLogsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('wallet_to_bank_logs', function (Blueprint $table) {
|
||||
$table->string('pay_sn')->nullable()->comment('支付单号');
|
||||
$table->tinyInteger('pay_way')->default(WalletToBankLogPayWay::Offline->value)->comment('支付方式: 1 线下, 2 代付');
|
||||
$table->timestamp('pay_at')->nullable()->comment('支付时间');
|
||||
$table->text('failed_reason')->nullable()->comment('失败原因');
|
||||
|
||||
$table->unique('pay_sn');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('wallet_to_bank_logs', function (Blueprint $table) {
|
||||
$table->dropColumn(['pay_sn', 'pay_way', 'failed_reason', 'pay_at']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddBargainAmountToOrderProductsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('order_products', function (Blueprint $table) {
|
||||
//
|
||||
$table->unsignedBigInteger('bargain_amount')->nullable()->default(0)->comment('砍价金额');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('order_products', function (Blueprint $table) {
|
||||
//
|
||||
$table->dropColumn(['bargain_amount']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddPayColumnsToDealerWalletToBankLogsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('dealer_wallet_to_bank_logs', function (Blueprint $table) {
|
||||
$table->string('pay_sn')->nullable()->comment('支付单号');
|
||||
$table->tinyInteger('pay_way')->default(1)->comment('支付方式: 1 线下, 2 代付');
|
||||
$table->timestamp('pay_at')->nullable()->comment('支付时间');
|
||||
$table->text('failed_reason')->nullable()->comment('失败原因');
|
||||
|
||||
$table->unique('pay_sn');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('dealer_wallet_to_bank_logs', function (Blueprint $table) {
|
||||
$table->dropColumn(['pay_sn', 'pay_way', 'failed_reason', 'pay_at']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -420,6 +420,17 @@ class AdminPermissionSeeder extends Seeder
|
|||
'name' => '每月统计',
|
||||
'curd' => ['index'],
|
||||
],
|
||||
'bargain_activities'=>[
|
||||
'name' =>'砍价活动',
|
||||
'curd'=> true,
|
||||
],
|
||||
'bargain_orders'=>[
|
||||
'name' =>'砍价活动记录',
|
||||
'curd' => ['index', 'show'],
|
||||
'children'=>[
|
||||
'remark'=>['name' =>'备注'],
|
||||
],
|
||||
],
|
||||
];
|
||||
// try {
|
||||
// DB::begintransaction();
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -7,6 +7,7 @@ return [
|
|||
],
|
||||
'fields' => [
|
||||
'name' => '名称',
|
||||
'cover' => '封面图',
|
||||
'parent_id' => '父级',
|
||||
'is_show' => '显示',
|
||||
'is_recommend' => '推荐',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'BargainActivity' => '砍价活动',
|
||||
'bargain-activities' => '砍价活动',
|
||||
],
|
||||
'fields' => [
|
||||
'name' => '活动名称',
|
||||
'description' => '活动描述',
|
||||
'is_enable' => '是否开启',
|
||||
'rules' => '砍价规则',
|
||||
'times' => '有效刀',
|
||||
'expire_hours' => '过期小时',
|
||||
'start_at' => '开始时间',
|
||||
'end_at' => '结束时间',
|
||||
'skus'=>'关联商品',
|
||||
'images' => '活动图',
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'BargainOrder' => '砍价记录',
|
||||
'bargain-orders' => '砍价记录',
|
||||
],
|
||||
'fields' => [
|
||||
'activity' => [
|
||||
'name'=> '活动名称',
|
||||
],
|
||||
'sku' => [
|
||||
'name' => '商品名称',
|
||||
],
|
||||
'user'=>[
|
||||
'phone'=>'手机号',
|
||||
],
|
||||
'userInfo'=>[
|
||||
'nickname' => '昵称',
|
||||
],
|
||||
'mallOrder'=>[
|
||||
'sn'=>'订单编号',
|
||||
],
|
||||
'activity_id' => '参与活动',
|
||||
'user_id' => '发起用户',
|
||||
'sku_id' => '砍价商品',
|
||||
'sku_price' => '原价',
|
||||
'bargain_price' => '已砍价格',
|
||||
'status' => '状态',
|
||||
'expire_at' => '过期时间',
|
||||
'order_id' => '商城订单',
|
||||
'remark' => '备注',
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -17,6 +17,8 @@ return [
|
|||
'account_amount' => '到账金额',
|
||||
'status' => '状态',
|
||||
'remarks' => '备注',
|
||||
'failed_reason' => '失败原因',
|
||||
'pay_way' => '支付方式',
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ return [
|
|||
'coupon_discount_amount' => '优惠券金额',
|
||||
'vip_discount_amount' => '会员优惠',
|
||||
'reduced_amount' => '减免金额',
|
||||
'bargain_amount' => '砍价金额',
|
||||
'shipping_fee' => '运费',
|
||||
'products_total_amount' => '商品总额',
|
||||
'total_amount' => '订单总额',
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ return [
|
|||
'status' => '状态',
|
||||
'remarks' => '备注',
|
||||
'created_at'=> '申请时间',
|
||||
'pay_way' => '支付方式',
|
||||
'pay_at' => '支付时间',
|
||||
'failed_reason' => '失败原因',
|
||||
'user'=>[
|
||||
'phone' => '申请人',
|
||||
],
|
||||
|
|
|
|||
Loading…
Reference in New Issue