解决冲突
parent
03d0c1d0d3
commit
df17196b3f
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Actions\Show;
|
||||
|
||||
use App\Models\AfterSale;
|
||||
use App\Services\AfterSaleService;
|
||||
use Dcat\Admin\Show\AbstractTool;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Throwable;
|
||||
|
||||
class AfterSaleFinance extends AbstractTool
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected $title = '<i class="fa fa-exclamation-triangle icon-shuffle"></i> 打款';
|
||||
|
||||
/**
|
||||
* 按钮样式定义,默认 btn btn-white waves-effect
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $style = 'btn btn-sm btn-danger';
|
||||
|
||||
/**
|
||||
* 权限判断,如不需要可以删除此方法
|
||||
*
|
||||
* @param Model|Authenticatable|HasPermissions|null $user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.after_sales.finance');
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理请求,如果不需要接口处理,请直接删除这个方法
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function handle(Request $request)
|
||||
{
|
||||
// 获取主键
|
||||
$key = $this->getKey();
|
||||
|
||||
$afterSaleService = new AfterSaleService();
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$afterSale = AfterSale::where('state', AfterSale::STATE_FINANCE)->findOrFail($key);
|
||||
$afterSaleService->finance($afterSale);
|
||||
DB::commit();
|
||||
} catch (Throwable $th) {
|
||||
DB::rollBack();
|
||||
report($th);
|
||||
return $this->response()->error('操作失败:'.$th->getMessage());
|
||||
}
|
||||
|
||||
return $this->response()
|
||||
->success(__('admin.update_succeeded'))
|
||||
->refresh();
|
||||
}
|
||||
|
||||
public function html()
|
||||
{
|
||||
return parent::html().' ';
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认弹窗信息,如不需要可以删除此方法
|
||||
*
|
||||
* @return string|array|void
|
||||
*/
|
||||
public function confirm()
|
||||
{
|
||||
return ['是否确认打款?', '该操作不可逆,打款后退款金额将原路退还。'];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Actions\Show;
|
||||
|
||||
use App\Models\AfterSale;
|
||||
use App\Services\AfterSaleService;
|
||||
use Dcat\Admin\Show\AbstractTool;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Throwable;
|
||||
|
||||
class AfterSaleShipping extends AbstractTool
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected $title = '<i class="fa fa-exclamation-triangle icon-shuffle"></i> 确认收货';
|
||||
|
||||
/**
|
||||
* 按钮样式定义,默认 btn btn-white waves-effect
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $style = 'btn btn-sm btn-success';
|
||||
|
||||
/**
|
||||
* 权限判断,如不需要可以删除此方法
|
||||
*
|
||||
* @param Model|Authenticatable|HasPermissions|null $user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.after_sales.shipping');
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理请求,如果不需要接口处理,请直接删除这个方法
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function handle(Request $request)
|
||||
{
|
||||
// 获取主键
|
||||
$key = $this->getKey();
|
||||
|
||||
$afterSaleService = new AfterSaleService();
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$afterSale = AfterSale::where('state', AfterSale::STATE_SHIPPING)->findOrFail($key);
|
||||
$afterSaleService->shipping($afterSale);
|
||||
DB::commit();
|
||||
} catch (Throwable $th) {
|
||||
DB::rollBack();
|
||||
report($th);
|
||||
return $this->response()->error('操作失败:'.$th->getMessage());
|
||||
}
|
||||
|
||||
return $this->response()
|
||||
->success(__('admin.update_succeeded'))
|
||||
->refresh();
|
||||
}
|
||||
|
||||
public function html()
|
||||
{
|
||||
return parent::html().' ';
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认弹窗信息,如不需要可以删除此方法
|
||||
*
|
||||
* @return string|array|void
|
||||
*/
|
||||
public function confirm()
|
||||
{
|
||||
return ['是否确认收货?', '该操作不可逆,确认后将进入打款流程。'];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Actions\Show;
|
||||
|
||||
use App\Admin\Forms\AfterSaleVerify as AfterSaleVerifyForm;
|
||||
use Dcat\Admin\Show\AbstractTool;
|
||||
use Dcat\Admin\Widgets\Modal;
|
||||
|
||||
class AfterSaleVerify extends AbstractTool
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected $title = '<i class="feather icon-shuffle"></i> 审核';
|
||||
|
||||
/**
|
||||
* 按钮样式定义,默认 btn btn-white waves-effect
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $style = 'btn-success';
|
||||
|
||||
public function render()
|
||||
{
|
||||
$form = AfterSaleVerifyForm::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> ");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Admin\Actions\Show\AfterSaleFinance;
|
||||
use App\Admin\Actions\Show\AfterSaleShipping;
|
||||
use App\Admin\Actions\Show\AfterSaleVerify;
|
||||
use App\Admin\Repositories\AfterSale;
|
||||
use App\Models\AfterSale as AfterSaleModel;
|
||||
use App\Models\AfterSaleLog;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Layout\Row;
|
||||
use Dcat\Admin\Show;
|
||||
|
||||
class AfterSaleController extends AdminController
|
||||
{
|
||||
/**
|
||||
* Make a grid builder.
|
||||
*
|
||||
* @return Grid
|
||||
*/
|
||||
protected function grid()
|
||||
{
|
||||
$builder = AfterSale::with(['user', 'order', 'orderProduct']);
|
||||
return Grid::make($builder, function (Grid $grid) {
|
||||
$grid->column('id')->sortable();
|
||||
$grid->column('user.phone');
|
||||
$grid->column('order.sn');
|
||||
$grid->column('sn');
|
||||
$grid->column('orderProduct.name');
|
||||
$grid->column('num');
|
||||
$grid->column('amount');
|
||||
$grid->column('type')->using([
|
||||
AfterSaleModel::TYPE_REFUND_AND_RETURN => '退款退货',
|
||||
AfterSaleModel::TYPE_REFUND => '退款',
|
||||
AfterSaleModel::TYPE_CHANGE => '换货',
|
||||
AfterSaleModel::TYPE_FILL => '漏发',
|
||||
])->label();
|
||||
$grid->column('state')->using([
|
||||
AfterSaleModel::STATE_APPLY=>'待补充资料',
|
||||
AfterSaleModel::STATE_VERIFY=>'待审核',
|
||||
AfterSaleModel::STATE_AGREE=>'待确认',
|
||||
AfterSaleModel::STATE_SHIPPING=>'待收货',
|
||||
AfterSaleModel::STATE_FINANCE=>'待打款',
|
||||
AfterSaleModel::STATE_FINISH=>'已完成',
|
||||
AfterSaleModel::STATE_CANCEL=>'已取消',
|
||||
])->dot([
|
||||
AfterSaleModel::STATE_APPLY=>'warning',
|
||||
AfterSaleModel::STATE_VERIFY=>'danger',
|
||||
AfterSaleModel::STATE_AGREE=>'warning',
|
||||
AfterSaleModel::STATE_SHIPPING=>'primary',
|
||||
AfterSaleModel::STATE_FINANCE=>'primary',
|
||||
AfterSaleModel::STATE_FINISH=>'success',
|
||||
]);
|
||||
// $grid->column('remarks');
|
||||
// $grid->column('tracking_number');
|
||||
$grid->column('created_at');
|
||||
$grid->column('updated_at')->sortable();
|
||||
$grid->model()->orderBy('created_at', 'desc');
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableView(false);
|
||||
});
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->equal('state')->select([
|
||||
AfterSaleModel::STATE_APPLY=>'待补充资料',
|
||||
AfterSaleModel::STATE_VERIFY=>'待审核',
|
||||
AfterSaleModel::STATE_AGREE=>'待确认',
|
||||
AfterSaleModel::STATE_SHIPPING=>'待收货',
|
||||
AfterSaleModel::STATE_FINANCE=>'待打款',
|
||||
AfterSaleModel::STATE_FINISH=>'已完成',
|
||||
AfterSaleModel::STATE_CANCEL=>'已取消',
|
||||
])->width(3);
|
||||
$filter->equal('user.phone')->width(3);
|
||||
$filter->equal('order.sn')->width(3);
|
||||
$filter->equal('sn')->width(3);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a show builder.
|
||||
*
|
||||
* @param mixed $id
|
||||
*
|
||||
* @return Show
|
||||
*/
|
||||
protected function detail($id)
|
||||
{
|
||||
return function (Row $row) use ($id) {
|
||||
$row->column(4, function ($column) use ($id) {
|
||||
$builder = AfterSale::with(['user', 'order', 'orderProduct']);
|
||||
$column->row(Show::make($id, $builder, function (Show $show) {
|
||||
$show->field('id');
|
||||
$show->field('sn');
|
||||
$show->field('order.sn');
|
||||
$show->field('order_product.name');
|
||||
$show->field('num');
|
||||
$show->field('type')->using([
|
||||
AfterSaleModel::TYPE_REFUND_AND_RETURN => '退款退货',
|
||||
AfterSaleModel::TYPE_REFUND => '退款',
|
||||
AfterSaleModel::TYPE_CHANGE => '换货',
|
||||
AfterSaleModel::TYPE_FILL => '漏发',
|
||||
])->label();
|
||||
$show->field('state')->using([
|
||||
AfterSaleModel::STATE_APPLY=>'待补充资料',
|
||||
AfterSaleModel::STATE_VERIFY=>'待审核',
|
||||
AfterSaleModel::STATE_AGREE=>'待确认',
|
||||
AfterSaleModel::STATE_SHIPPING=>'待收货',
|
||||
AfterSaleModel::STATE_FINANCE=>'待打款',
|
||||
AfterSaleModel::STATE_FINISH=>'已完成',
|
||||
AfterSaleModel::STATE_CANCEL=>'已取消',
|
||||
])->dot([
|
||||
AfterSaleModel::STATE_APPLY=>'warning',
|
||||
AfterSaleModel::STATE_VERIFY=>'danger',
|
||||
AfterSaleModel::STATE_AGREE=>'warning',
|
||||
AfterSaleModel::STATE_SHIPPING=>'primary',
|
||||
AfterSaleModel::STATE_FINANCE=>'primary',
|
||||
AfterSaleModel::STATE_FINISH=>'success',
|
||||
]);
|
||||
// $show->field('order_product.cover')->image();
|
||||
$show->field('created_at');
|
||||
$show->field('updated_at');
|
||||
$show->panel()
|
||||
->tools(function (Show\Tools $tools) use ($show) {
|
||||
$tools->disableEdit();
|
||||
$tools->disableDelete();
|
||||
if ($show->model()->state == AfterSaleModel::STATE_VERIFY) {
|
||||
$tools->append(new AfterSaleVerify());
|
||||
}
|
||||
if ($show->model()->state == AfterSaleModel::STATE_SHIPPING) {
|
||||
$tools->append(new AfterSaleShipping());
|
||||
}
|
||||
if ($show->model()->state == AfterSaleModel::STATE_FINANCE) {
|
||||
$tools->append(new AfterSaleFinance());
|
||||
}
|
||||
});
|
||||
}));
|
||||
});
|
||||
$row->column(8, function ($column) use ($id) {
|
||||
$logs = AfterSaleLog::where('after_sale_id', $id)->latest('id')->get();
|
||||
$title = '售后明细';
|
||||
$column->row(admin_view('admin.show.timeline', compact('title', 'logs')));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a form builder.
|
||||
*
|
||||
* @return Form
|
||||
*/
|
||||
protected function form()
|
||||
{
|
||||
return Form::make(new AfterSale(), function (Form $form) {
|
||||
$form->display('id');
|
||||
$form->text('user_id');
|
||||
$form->text('order_id');
|
||||
$form->text('sn');
|
||||
$form->text('order_product_id');
|
||||
$form->text('num');
|
||||
$form->text('amount');
|
||||
$form->text('type');
|
||||
$form->text('state');
|
||||
$form->text('description');
|
||||
$form->text('images');
|
||||
$form->text('remarks');
|
||||
$form->text('tracking_number');
|
||||
|
||||
$form->display('created_at');
|
||||
$form->display('updated_at');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,18 @@ class AddSku extends Form implements LazyRenderable
|
|||
{
|
||||
use LazyWidget;
|
||||
|
||||
/**
|
||||
* 权限判断,如不需要可以删除此方法
|
||||
*
|
||||
* @param Model|Authenticatable|HasPermissions|null $user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.product_spus.add_sku');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the form request.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Forms;
|
||||
|
||||
use App\Models\AfterSale;
|
||||
use App\Services\AfterSaleService;
|
||||
use Dcat\Admin\Contracts\LazyRenderable;
|
||||
use Dcat\Admin\Traits\LazyWidget;
|
||||
use Dcat\Admin\Widgets\Form;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Throwable;
|
||||
|
||||
class AfterSaleVerify extends Form implements LazyRenderable
|
||||
{
|
||||
use LazyWidget;
|
||||
|
||||
/**
|
||||
* 权限判断,如不需要可以删除此方法
|
||||
*
|
||||
* @param Model|Authenticatable|HasPermissions|null $user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.after_sales.verify');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the form request.
|
||||
*
|
||||
* @param array $input
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(array $input)
|
||||
{
|
||||
$afterSaleService = new AfterSaleService();
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$afterSale = AfterSale::where('state', AfterSale::STATE_VERIFY)->findOrFail($this->payload['id']);
|
||||
if ($input['state'] == 3) {//审核通过
|
||||
$afterSaleService->verify($afterSale, $input['remarks3']);
|
||||
} elseif ($input['state'] == 1) {//需要补充资料
|
||||
$afterSaleService->backApply($afterSale, $input['remarks1']);
|
||||
}
|
||||
DB::commit();
|
||||
} catch (Throwable $th) {
|
||||
DB::rollBack();
|
||||
report($th);
|
||||
return $this->response()->error('操作失败:'.$th->getMessage());
|
||||
}
|
||||
|
||||
return $this->response()
|
||||
->success(__('admin.update_succeeded'))
|
||||
->refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a form here.
|
||||
*/
|
||||
public function form()
|
||||
{
|
||||
$id = $this->payload['id'] ?? 0;
|
||||
$afterSale = AfterSale::findOrFail($id);
|
||||
$this->currency('amount')->symbol('¥')->value($afterSale->amount);
|
||||
$this->radio('state')
|
||||
->when(3, function (Form $form) use ($afterSale) {
|
||||
$defaultRemarks = '';
|
||||
switch ($afterSale->type) {
|
||||
case 1:
|
||||
$defaultRemarks = '同意退款退货';//需要用户确认并填入回寄单号
|
||||
break;
|
||||
case 2:
|
||||
$defaultRemarks = '同意退款,等待财务打款审核。';
|
||||
break;
|
||||
case 3:
|
||||
$defaultRemarks = '同意换货';//需要用户确认并填入回寄单号
|
||||
break;
|
||||
case 4:
|
||||
$defaultRemarks = '同意补货, 新的订单号:';//需要用户收到补货后确认,可后台关闭
|
||||
}
|
||||
$this->text('remarks3')->value($defaultRemarks);
|
||||
})
|
||||
->when(1, function (Form $form) {
|
||||
$this->text('remarks1')->value('需要补充资料');
|
||||
})->options([
|
||||
3=>'审核通过',
|
||||
1=>'需要补充资料',
|
||||
])->default(3);
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,16 @@ class DisableUser extends Form implements LazyRenderable
|
|||
{
|
||||
use LazyWidget;
|
||||
|
||||
/**
|
||||
* @param Model|Authenticatable|HasPermissions|null $user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.users.disable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the form request.
|
||||
*
|
||||
|
|
@ -23,9 +33,10 @@ class DisableUser extends Form implements LazyRenderable
|
|||
public function handle(array $input)
|
||||
{
|
||||
$id = $this->payload['id'] ?? 0;
|
||||
$user = User::findOrFail($id);
|
||||
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$user = User::findOrFail($id);
|
||||
$user->disable($input['status_remark']);
|
||||
DB::commit();
|
||||
} catch (Throwable $th) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ class SettingSpuSpecs extends Form implements LazyRenderable
|
|||
{
|
||||
use LazyWidget;
|
||||
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.product_spus.setting_specs');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the form request.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -15,6 +15,16 @@ class SkuGift extends Form implements LazyRenderable
|
|||
{
|
||||
use LazyWidget;
|
||||
|
||||
/**
|
||||
* @param Model|Authenticatable|HasPermissions|null $user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.product_skus.sku_gift');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the form request.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -14,6 +14,16 @@ class SkuVerify extends Form implements LazyRenderable
|
|||
{
|
||||
use LazyWidget;
|
||||
|
||||
/**
|
||||
* @param Model|Authenticatable|HasPermissions|null $user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.product_sku_verifies.verify');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the form request.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -14,6 +14,17 @@ class SkuVerifyBatch extends Form implements LazyRenderable
|
|||
{
|
||||
use LazyWidget;
|
||||
|
||||
/**
|
||||
* 是否有权限判断.
|
||||
*
|
||||
* @param Model|Authenticatable|HasPermissions|null $user
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.product_sku_verifies.batch_verify');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the form request.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Repositories;
|
||||
|
||||
use App\Models\AfterSale as Model;
|
||||
use Dcat\Admin\Repositories\EloquentRepository;
|
||||
|
||||
class AfterSale extends EloquentRepository
|
||||
{
|
||||
/**
|
||||
* Model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eloquentClass = Model::class;
|
||||
}
|
||||
|
|
@ -80,6 +80,9 @@ Route::group([
|
|||
'index',
|
||||
])->names('coupon_task_logs');
|
||||
|
||||
$router->get('after-sales', 'AfterSaleController@index')->name('after_sales.index');
|
||||
$router->get('after-sales/{after_sale}', 'AfterSaleController@show')->name('after_sales.show');
|
||||
|
||||
$router->resource('users', 'UserController');
|
||||
|
||||
$router->resource('vips', 'VipController');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
|
||||
namespace App\Endpoint\Api\Http\Controllers;
|
||||
|
||||
use App\Endpoint\Api\Http\Resources\AfterSaleResource;
|
||||
use App\Endpoint\Api\Http\Resources\AfterSaleSimpleResource;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Helpers\Paginator as PaginatorHelper;
|
||||
use App\Models\AfterSale;
|
||||
use App\Models\OrderProduct;
|
||||
use App\Services\AfterSaleService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Throwable;
|
||||
|
||||
class AfterSaleController extends Controller
|
||||
{
|
||||
/**
|
||||
* 售后订单列表
|
||||
*
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$query = AfterSale::query()->with(['order', 'orderProduct']);
|
||||
$query->where('user_id', $request->user()->id);
|
||||
|
||||
if ($request->filled('doing')) {
|
||||
$doing = (bool) $request->query('doing');
|
||||
if ($doing) {//获取正在处理中的订单
|
||||
$query->where('state', '<', AfterSale::STATE_FINISH)->latest('updated_at');
|
||||
} else {//获取已完成+已取消的售后订单
|
||||
$query->where('state', '>=', AfterSale::STATE_FINISH)->latest();
|
||||
}
|
||||
} else {//获取全部申请记录
|
||||
$query->latest();
|
||||
}
|
||||
|
||||
$afterSales = $query->simplePaginate(PaginatorHelper::resolvePerPage('per_page', 20, 50));
|
||||
|
||||
return AfterSaleSimpleResource::collection($afterSales);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交审核
|
||||
*
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function store(Request $request, AfterSaleService $afterSaleService)
|
||||
{
|
||||
$input = $request->validate([
|
||||
'order_product_id' => ['bail', 'required', 'integer'],
|
||||
'num' => ['bail', 'required', 'integer', 'min:1'],
|
||||
'type' => ['bail', 'required', 'integer', 'min:1', 'max:4'],
|
||||
'description' => ['bail', 'required', 'string', 'max:255'],
|
||||
'images' => ['bail', 'required', 'array', 'max:6'],
|
||||
]);
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$orderProduct = OrderProduct::where('user_id', $request->user()->id)->findOrFail($input['order_product_id']);
|
||||
$afterSale = $afterSaleService->create($request->user(), $orderProduct, $input['type'], $input['num'], $input);
|
||||
|
||||
DB::commit();
|
||||
} catch (Throwable $th) {
|
||||
DB::rollBack();
|
||||
report($th);
|
||||
throw new BizException('申请失败,请稍后再试');
|
||||
}
|
||||
|
||||
return AfterSaleResource::make($afterSale);
|
||||
}
|
||||
|
||||
/**
|
||||
* 售后订单详情
|
||||
*
|
||||
* @param [type] $id
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function show($id, Request $request)
|
||||
{
|
||||
$afterSale = $request->user()->afterSales()->find($id);
|
||||
return AfterSaleResource::make($afterSale);
|
||||
}
|
||||
|
||||
/**
|
||||
* 补充资料
|
||||
*
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function update($id, Request $request, AfterSaleService $afterSaleService)
|
||||
{
|
||||
$afterSale = $request->user()->afterSales()->where('state', '=', AfterSale::STATE_APPLY)->findOrFail($id);
|
||||
$input = $request->validate([
|
||||
'type' => ['bail', 'required', 'integer', 'min:1', 'max:4'],
|
||||
'description' => ['bail', 'required', 'string', 'max:255'],
|
||||
'images' => ['bail', 'required', 'array', 'max:6'],
|
||||
]);
|
||||
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$afterSale = $afterSaleService->apply($afterSale, $input);
|
||||
|
||||
DB::commit();
|
||||
} catch (Throwable $th) {
|
||||
DB::rollBack();
|
||||
report($th);
|
||||
throw new BizException('提交失败,请稍后再试');
|
||||
}
|
||||
return AfterSaleResource::make($afterSale);
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户同意
|
||||
*
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function agree($id, Request $request)
|
||||
{
|
||||
$afterSale = $request->user()->afterSales()->where('state', '=', AfterSale::STATE_AGREE)->findOrFail($id);
|
||||
$input = $request->validate([
|
||||
'tracking_number' => ['bail', 'string', 'max:255'],
|
||||
]);
|
||||
|
||||
//如果是
|
||||
if (in_array($afterSale->type, [AfterSale::TYPE_REFUND_AND_RETURN, AfterSale::TYPE_CHANGE]) && (!isset($input['tracking_number']) || empty($input['tracking_number']))) {
|
||||
throw new BizException('请填写物流单号');
|
||||
}
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$afterSaleService = new AfterSaleService();
|
||||
$afterSale = $afterSaleService->agree($afterSale, $input);
|
||||
DB::commit();
|
||||
} catch (Throwable $th) {
|
||||
DB::rollBack();
|
||||
report($th);
|
||||
throw new BizException('提交失败,请稍后再试');
|
||||
}
|
||||
return AfterSaleResource::make($afterSale);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消申请
|
||||
*
|
||||
* @param Request $request
|
||||
* @return void
|
||||
*/
|
||||
public function cancel($id, Request $request)
|
||||
{
|
||||
$afterSale = $request->user()->afterSales()->where('state', '<', 4)->findOrFail($id);
|
||||
|
||||
$afterSale->update(
|
||||
['state'=> AfterSale::STATE_CANCEL, 'remarks'=>'用户取消售后申请']
|
||||
);
|
||||
|
||||
return AfterSaleResource::make($afterSale);
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ class LoginController extends Controller
|
|||
*/
|
||||
public function __invoke(LoginRequest $request)
|
||||
{
|
||||
throw new BizException(__('Incorrect account or password'));
|
||||
$user = User::where('phone', $request->input('phone'))->first();
|
||||
|
||||
if (! $user?->verifyPassword($request->input('password'))) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Endpoint\Api\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class AfterSaleLogResource 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,
|
||||
'desc' => $this->desc,
|
||||
'created_at' => $this->created_at->toDateTimeString(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Endpoint\Api\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class AfterSaleResource 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,
|
||||
'order_sn' => $this->order->sn,
|
||||
'order_product'=>'',
|
||||
'state' => $this->state,
|
||||
'type' => $this->type,
|
||||
'images' => $this->images,
|
||||
'description' => $this->description,
|
||||
'remarks' => $this->remarks,
|
||||
'created_at' => $this->created_at->toDateTimeString(),
|
||||
// 'logs' => AfterSaleLogResource::make($this->whenLoaded('logs')),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Endpoint\Api\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class AfterSaleSimpleResource 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,
|
||||
'order_sn' => $this->whenLoaded('order')?->sn,
|
||||
'order_product'=>'',
|
||||
'state' => $this->state,
|
||||
'remarks' => $this->remarks,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
use App\Endpoint\Api\Http\Controllers\Account\ChangePasswordController;
|
||||
use App\Endpoint\Api\Http\Controllers\Account\UserController;
|
||||
use App\Endpoint\Api\Http\Controllers\AdController;
|
||||
use App\Endpoint\Api\Http\Controllers\AfterSaleController;
|
||||
use App\Endpoint\Api\Http\Controllers\Auth\LoginController;
|
||||
use App\Endpoint\Api\Http\Controllers\Auth\LogoutController;
|
||||
use App\Endpoint\Api\Http\Controllers\Auth\RegisterController;
|
||||
|
|
@ -71,5 +72,13 @@ Route::group([
|
|||
Route::put('shopping-cart-items/{shopping_cart_item}', [ShoppingCartItemController::class, 'update']);
|
||||
|
||||
Route::apiResource('shipping-addresses', ShippingAddressController::class);
|
||||
|
||||
//售后订单
|
||||
Route::get('after-sales', [AfterSaleController::class, 'index']);
|
||||
Route::post('after-sales', [AfterSaleController::class, 'store']);
|
||||
Route::get('after-sales/{after_sales}', [AfterSaleController::class, 'show']);
|
||||
Route::put('after-sales/{after_sales}', [AfterSaleController::class, 'update']);
|
||||
Route::put('after-sales/{after_sales}/agree', [AfterSaleController::class, 'agree']);
|
||||
Route::delete('after-sales/{after_sales}', [AfterSaleController::class, 'cancel']);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Casts\JsonArray;
|
||||
use App\Casts\Price;
|
||||
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class AfterSale extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasDateTimeFormatter;
|
||||
|
||||
public const STATE_APPLY = 1; // 待补充资料
|
||||
public const STATE_VERIFY = 2; // 待审核
|
||||
public const STATE_AGREE = 3; // 待同意
|
||||
public const STATE_SHIPPING = 4; // 待收货
|
||||
public const STATE_FINANCE = 5; // 待打款
|
||||
public const STATE_FINISH = 6; // 完成
|
||||
public const STATE_CANCEL = 7; // 取消
|
||||
|
||||
public const TYPE_REFUND_AND_RETURN = 1; // 退款退货
|
||||
public const TYPE_REFUND = 2; // 退款不退货
|
||||
public const TYPE_CHANGE = 3; // 换货
|
||||
public const TYPE_FILL = 4; // 漏发
|
||||
|
||||
protected $casts = [
|
||||
'images' => JsonArray::class,
|
||||
'amount' => Price::class,
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'order_id',
|
||||
'order_product_id',
|
||||
'num',
|
||||
'amount',
|
||||
'type',
|
||||
'state',
|
||||
'description',
|
||||
'images',
|
||||
'remarks',
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(Order::class, 'order_id');
|
||||
}
|
||||
|
||||
public function orderProduct()
|
||||
{
|
||||
return $this->belongsTo(OrderProduct::class, 'order_product_id');
|
||||
}
|
||||
|
||||
public function logs()
|
||||
{
|
||||
return $this->hasMany(AfterSaleLog::class, 'after_sale_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置申请售后时的录入操作日志
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param self|null $inviter
|
||||
* @return self
|
||||
*/
|
||||
public static function create(array $attributes = [], ?self $inviter = null): self
|
||||
{
|
||||
$afterSale = static::query()->create($attributes);
|
||||
|
||||
$afterSale->createApplyLog();
|
||||
|
||||
return $afterSale;
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请日志
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function createApplyLog()
|
||||
{
|
||||
$this->logs()->create([
|
||||
'after_sale_id' => $this->id,
|
||||
'name' => '售后申请',
|
||||
'desc' => '申请理由:'.$this->description,
|
||||
'images'=> $this->images,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消日志
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function createCancelLog()
|
||||
{
|
||||
$this->logs()->create([
|
||||
'after_sale_id' => $this->id,
|
||||
'name' => '取消申请',
|
||||
'desc' => '用户取消售后申请',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
parent::saving(function ($afterSale) {
|
||||
// 如果自动创建sn
|
||||
if ($afterSale->sn === null) {
|
||||
$afterSale->sn = self::createSn();
|
||||
}
|
||||
//如果取消订单
|
||||
if ($afterSale->state == self::STATE_CANCEL) {
|
||||
$afterSale->createCancelLog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建售后单号
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function createSn()
|
||||
{
|
||||
return 'AS'.now()->format('YmdHisu').strtoupper(Str::random(2));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?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 AfterSaleLog extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasDateTimeFormatter;
|
||||
|
||||
protected $casts = [
|
||||
'images' => JsonArray::class,
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'desc',
|
||||
'after_sale_id',
|
||||
'images',
|
||||
];
|
||||
}
|
||||
|
|
@ -2,10 +2,15 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Casts\Price;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class OrderProduct extends Model
|
||||
{
|
||||
protected $casts = [
|
||||
'total_amount'=>Price::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -120,6 +120,14 @@ class User extends Model implements AuthorizableContract, AuthenticatableContrac
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 属于此用户的售后订单
|
||||
*/
|
||||
public function afterSales()
|
||||
{
|
||||
return $this->hasMany(AfterSale::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用用户
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,307 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Exceptions\BizException;
|
||||
use App\Models\AfterSale;
|
||||
use App\Models\AfterSaleLog;
|
||||
use App\Models\OrderProduct;
|
||||
use App\Models\User;
|
||||
|
||||
class AfterSaleService
|
||||
{
|
||||
/**
|
||||
* 创建售后单
|
||||
*
|
||||
* @param User $user
|
||||
* @param OrderProduct $orderProduct
|
||||
* @param integer $type
|
||||
* @param integer $num
|
||||
* @param array $params
|
||||
* @return AfterSale
|
||||
*/
|
||||
public function create(User $user, OrderProduct $orderProduct, int $type, int $num, array $params): AfterSale
|
||||
{
|
||||
// todo 校验这个订单商品是否还能发起售后-待完成
|
||||
// if (1) {
|
||||
// throw new BizException('该订单商品已过售后时间');
|
||||
// }
|
||||
|
||||
//校验该订单商品不能有已完成、处理中的售后记录
|
||||
if (AfterSale::where('order_product_id', $orderProduct->id)->where('state', '<', AfterSale::STATE_FINISH)->exists()) {
|
||||
throw new BizException('该订单商品已申请售后');
|
||||
}
|
||||
//校验申请数量不能超过订单商品数量
|
||||
if ($num > $orderProduct->quantity) {
|
||||
throw new BizException('申请售后的数量不能大于订单商品数量');
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case in_array($type, [3, 4])://换货,漏发退款金额为0
|
||||
$amount = 0;
|
||||
break;
|
||||
default:
|
||||
// dd(bcmul(bcdiv(10, 3, 2), 3, 2));如果数量相等,则直接取总额
|
||||
$amount = ($num == $orderProduct->quantity) ? $orderProduct->total_amount : bcmul(bcdiv($orderProduct->total_amount, $orderProduct->quantity, 2), $num, 2);
|
||||
break;
|
||||
}
|
||||
$afterSale = AfterSale::create(array_merge($params, [
|
||||
'user_id' => $user->id,
|
||||
'order_id' => $orderProduct->order_id,
|
||||
'amount' => $amount,
|
||||
'state' => AfterSale::STATE_VERIFY,
|
||||
]));
|
||||
return $afterSale;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否待审核
|
||||
*
|
||||
* @param AfterSale $afterSale
|
||||
* @return boolean
|
||||
*/
|
||||
protected function isWaitVerify(AfterSale $afterSale)
|
||||
{
|
||||
return $afterSale->state == $afterSale::STATE_VERIFY;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否待补充资料
|
||||
*
|
||||
* @param AfterSale $afterSale
|
||||
* @return boolean
|
||||
*/
|
||||
protected function isWaitApply(AfterSale $afterSale)
|
||||
{
|
||||
return $afterSale->state == $afterSale::STATE_APPLY;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否待确认
|
||||
*
|
||||
* @param AfterSale $afterSale
|
||||
* @return boolean
|
||||
*/
|
||||
protected function isWaitAgree(AfterSale $afterSale)
|
||||
{
|
||||
return $afterSale->state == $afterSale::STATE_AGREE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否待确认收货
|
||||
*
|
||||
* @param AfterSale $afterSale
|
||||
* @return boolean
|
||||
*/
|
||||
protected function isWaitShipping(AfterSale $afterSale)
|
||||
{
|
||||
return $afterSale->state == $afterSale::STATE_SHIPPING;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否待打款
|
||||
*
|
||||
* @param AfterSale $afterSale
|
||||
* @return boolean
|
||||
*/
|
||||
protected function isWaitFinance(AfterSale $afterSale)
|
||||
{
|
||||
return $afterSale->state == $afterSale::STATE_FINANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 补充资料申请
|
||||
*
|
||||
* @param [AfterSale] $afterSale
|
||||
* @param array $params
|
||||
* @return AfterSale
|
||||
*/
|
||||
public function apply(AfterSale $afterSale, array $params): AfterSale
|
||||
{
|
||||
if ($this->isWaitApply($afterSale)) {
|
||||
$afterSale->update(array_merge($params, [
|
||||
'state' => AfterSale::STATE_VERIFY,
|
||||
]));
|
||||
|
||||
AfterSaleLog::create([
|
||||
'after_sale_id' => $afterSale->id,
|
||||
'name' => '补充资料',
|
||||
'desc' => $afterSale->description,
|
||||
'images' => $afterSale->images,
|
||||
]);
|
||||
return $afterSale;
|
||||
} else {
|
||||
throw new BizException('售后订单状态异常,请稍后再试');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核通过
|
||||
*
|
||||
* @param AfterSale $afterSale
|
||||
* @param string $remarks
|
||||
* @return void
|
||||
*/
|
||||
public function verify(AfterSale $afterSale, string $remarks)
|
||||
{
|
||||
if ($this->isWaitVerify($afterSale)) {
|
||||
switch ($afterSale->type) {
|
||||
case AfterSale::TYPE_REFUND_AND_RETURN:
|
||||
$afterSale->update([
|
||||
'state' => $afterSale::STATE_AGREE,
|
||||
'remarks' => $remarks,
|
||||
]);
|
||||
AfterSaleLog::create([
|
||||
'after_sale_id' => $afterSale->id,
|
||||
'name' => '客服审核',
|
||||
'desc' => $remarks,
|
||||
]);
|
||||
break;
|
||||
case AfterSale::TYPE_REFUND:
|
||||
$afterSale->update([
|
||||
'state' => $afterSale::STATE_AGREE,
|
||||
'remarks' => $remarks,
|
||||
]);
|
||||
AfterSaleLog::create([
|
||||
'after_sale_id' => $afterSale->id,
|
||||
'name' => '客服审核',
|
||||
'desc' => $remarks,
|
||||
]);
|
||||
break;
|
||||
case AfterSale::TYPE_CHANGE:
|
||||
$afterSale->update([
|
||||
'state' => $afterSale::STATE_AGREE,
|
||||
'remarks' => $remarks,
|
||||
]);
|
||||
AfterSaleLog::create([
|
||||
'after_sale_id' => $afterSale->id,
|
||||
'name' => '客服审核',
|
||||
'desc' => $remarks,
|
||||
]);
|
||||
break;
|
||||
case AfterSale::TYPE_FILL:
|
||||
$afterSale->update([
|
||||
'state' => $afterSale::STATE_AGREE,
|
||||
'remarks' => $remarks,
|
||||
]);
|
||||
AfterSaleLog::create([
|
||||
'after_sale_id' => $afterSale->id,
|
||||
'name' => '客服审核',
|
||||
'desc' => $remarks,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
throw new BizException('该售后订单状态异常');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 补充资料
|
||||
*
|
||||
* @param AfterSale $afterSale
|
||||
* @param string $remarks
|
||||
* @return void
|
||||
*/
|
||||
public function backApply(AfterSale $afterSale, string $remarks)
|
||||
{
|
||||
if ($this->isWaitVerify($afterSale)) {
|
||||
$afterSale->update([
|
||||
'state' => $afterSale::STATE_APPLY,
|
||||
'remarks' => $remarks,
|
||||
]);
|
||||
AfterSaleLog::create([
|
||||
'after_sale_id' => $afterSale->id,
|
||||
'name' => '客服审核',
|
||||
'desc' => $remarks,
|
||||
]);
|
||||
} else {
|
||||
throw new BizException('该售后订单状态异常');
|
||||
}
|
||||
}
|
||||
|
||||
public function agree(AfterSale $afterSale, array $params, $remarks = '用户已同意客服审核结果')
|
||||
{
|
||||
if ($this->isWaitAgree($afterSale)) {
|
||||
switch ($afterSale->type) {
|
||||
case AfterSale::TYPE_REFUND:
|
||||
if (isset($params['tracking_number'])) {
|
||||
unset($params['tracking_number']);
|
||||
}
|
||||
break;
|
||||
case AfterSale::TYPE_FILL:
|
||||
if (isset($params['tracking_number'])) {
|
||||
unset($params['tracking_number']);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
$afterSale->update(array_merge($params, [
|
||||
'remarks' => $remarks,
|
||||
]));
|
||||
AfterSaleLog::create([
|
||||
'after_sale_id' => $afterSale->id,
|
||||
'name' => '客户确认',
|
||||
'desc' => $remarks,
|
||||
]);
|
||||
} else {
|
||||
throw new BizException('售后订单状态异常,请稍后再试');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 物流确认收货
|
||||
*
|
||||
* @param AfterSale $afterSale
|
||||
* @param string $remarks
|
||||
* @return void
|
||||
*/
|
||||
public function shipping(AfterSale $afterSale, $remarks ='物流确认收货')
|
||||
{
|
||||
if ($this->isWaitShipping($afterSale)) {
|
||||
$afterSale->update([
|
||||
'state' => $afterSale::STATE_FINANCE,
|
||||
'remarks' => $remarks,
|
||||
]);
|
||||
AfterSaleLog::create([
|
||||
'after_sale_id' => $afterSale->id,
|
||||
'name' => '仓库审核',
|
||||
'desc' => $remarks,
|
||||
]);
|
||||
} else {
|
||||
throw new BizException('该售后订单状态异常');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 财务确认退款
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function finance(AfterSale $afterSale, $remarks ='退款成功')
|
||||
{
|
||||
if ($this->isWaitFinance($afterSale)) {
|
||||
|
||||
//todo-执行实际退款操作;
|
||||
|
||||
$afterSale->update([
|
||||
'state' => $afterSale::STATE_FINISH,
|
||||
'remarks' => $remarks,
|
||||
]);
|
||||
AfterSaleLog::create([
|
||||
'after_sale_id' => $afterSale->id,
|
||||
'name' => '财务审核',
|
||||
'desc' => $remarks,
|
||||
]);
|
||||
AfterSaleLog::create([
|
||||
'after_sale_id' => $afterSale->id,
|
||||
'name' => '售后完成',
|
||||
'desc' => '售后已结束',
|
||||
]);
|
||||
} else {
|
||||
throw new BizException('该售后订单状态异常');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateAfterSalesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('after_sales', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('user_id')->comment('用户ID');
|
||||
$table->unsignedBigInteger('order_id')->comment('原订单ID');
|
||||
$table->string('sn')->comment('售后订单编号');
|
||||
$table->unsignedBigInteger('order_product_id')->comment('订单商品ID');
|
||||
$table->unsignedBigInteger('num')->comment('数量');
|
||||
$table->unsignedBigInteger('amount')->default(0)->comment('退款金额:分');
|
||||
$table->unsignedTinyInteger('type')->default(0)->comment('1.退款退货;2.退款不退货;3.换货');
|
||||
$table->unsignedTinyInteger('state')->default(0)->comment('1待补充资料,2待审核,3待客户确认,4待收货,5待打款,6完成,7已取消');
|
||||
$table->string('description')->comment('申请描述');
|
||||
$table->json('images')->comment('照片地址');
|
||||
$table->string('remarks')->nullable()->comment('备注');
|
||||
$table->string('tracking_number')->nullable()->comment('运单号');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('after_sales');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateAfterSaleLogsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('after_sale_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('after_sale_id')->comment('售后ID');
|
||||
$table->string('name')->comment('进度名称');
|
||||
$table->string('desc')->nullable()->comment('描述');
|
||||
$table->json('images')->nullable()->comment('图片内容');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('after_sale_logs');
|
||||
}
|
||||
}
|
||||
|
|
@ -111,6 +111,10 @@ class AdminPermissionSeeder extends Seeder
|
|||
'batch_release_down'=>['name' =>'批量下架'],
|
||||
'batch_release_cacel'=>['name' =>'批量取消申请'],
|
||||
'batch_sku_sync_spu'=>['name' =>'批量同步主商品'],
|
||||
'release_up'=> ['name'=>'上架申请'],
|
||||
'release_down'=> ['name'=>'商品下架'],
|
||||
'release_cacel'=> ['name'=>'取消申请'],
|
||||
'sku_sync_spu'=>['name' =>'同步主商品'],
|
||||
'sku_gift' =>['name' =>'赠品管理'],
|
||||
],
|
||||
],
|
||||
|
|
@ -138,9 +142,7 @@ class AdminPermissionSeeder extends Seeder
|
|||
'name' =>'优惠券管理',
|
||||
'curd' => true,
|
||||
'children'=>[
|
||||
'range_list' =>[
|
||||
'name' =>'使用范围',
|
||||
],
|
||||
'range_list' =>['name' =>'使用范围'],
|
||||
],
|
||||
],
|
||||
'coupon_ranges'=>[
|
||||
|
|
@ -151,9 +153,7 @@ class AdminPermissionSeeder extends Seeder
|
|||
'name' =>'运费模板管理',
|
||||
'curd' => true,
|
||||
'children'=>[
|
||||
'rule_list' =>[
|
||||
'name' =>'运费规则',
|
||||
],
|
||||
'rule_list' =>['name' =>'运费规则'],
|
||||
],
|
||||
],
|
||||
'shipping_rules'=>[
|
||||
|
|
@ -171,6 +171,15 @@ class AdminPermissionSeeder extends Seeder
|
|||
'name' =>'优惠券发放日志',
|
||||
'curd' => ['index'],
|
||||
],
|
||||
'after_sales'=>[
|
||||
'name' =>'售后管理',
|
||||
'curd' => ['index', 'show'],
|
||||
'children' => [
|
||||
'verify'=>['name' =>'审核'],
|
||||
'shipping'=>['name' =>'确认收货'],
|
||||
'finance'=>['name' =>'确认打款'],
|
||||
],
|
||||
],
|
||||
];
|
||||
try {
|
||||
DB::begintransaction();
|
||||
|
|
|
|||
|
|
@ -50,6 +50,17 @@ namespace Dcat\Admin {
|
|||
* @property Grid\Column|Collection jump_link
|
||||
* @property Grid\Column|Collection jump_type
|
||||
* @property Grid\Column|Collection sort
|
||||
* @property Grid\Column|Collection after_sale_id
|
||||
* @property Grid\Column|Collection desc
|
||||
* @property Grid\Column|Collection images
|
||||
* @property Grid\Column|Collection amount
|
||||
* @property Grid\Column|Collection num
|
||||
* @property Grid\Column|Collection order_id
|
||||
* @property Grid\Column|Collection order_product_id
|
||||
* @property Grid\Column|Collection remarks
|
||||
* @property Grid\Column|Collection sn
|
||||
* @property Grid\Column|Collection state
|
||||
* @property Grid\Column|Collection tracking_number
|
||||
* @property Grid\Column|Collection _lft
|
||||
* @property Grid\Column|Collection _rgt
|
||||
* @property Grid\Column|Collection is_recommend
|
||||
|
|
@ -61,12 +72,11 @@ namespace Dcat\Admin {
|
|||
* @property Grid\Column|Collection coupon_id
|
||||
* @property Grid\Column|Collection ranges
|
||||
* @property Grid\Column|Collection status
|
||||
* @property Grid\Column|Collection num
|
||||
* @property Grid\Column|Collection task_id
|
||||
* @property Grid\Column|Collection administrator_id
|
||||
* @property Grid\Column|Collection amount
|
||||
* @property Grid\Column|Collection task_id
|
||||
* @property Grid\Column|Collection limit
|
||||
* @property Grid\Column|Collection sent
|
||||
* @property Grid\Column|Collection stock
|
||||
* @property Grid\Column|Collection threshold
|
||||
* @property Grid\Column|Collection use_day
|
||||
* @property Grid\Column|Collection use_end_at
|
||||
|
|
@ -80,7 +90,6 @@ namespace Dcat\Admin {
|
|||
* @property Grid\Column|Collection after_sale_deadline
|
||||
* @property Grid\Column|Collection discount_amount
|
||||
* @property Grid\Column|Collection is_comment
|
||||
* @property Grid\Column|Collection order_id
|
||||
* @property Grid\Column|Collection quantity
|
||||
* @property Grid\Column|Collection reduced_amount
|
||||
* @property Grid\Column|Collection sell_price
|
||||
|
|
@ -103,30 +112,27 @@ namespace Dcat\Admin {
|
|||
* @property Grid\Column|Collection products_total_amount
|
||||
* @property Grid\Column|Collection remark
|
||||
* @property Grid\Column|Collection shipping_fee
|
||||
* @property Grid\Column|Collection sn
|
||||
* @property Grid\Column|Collection user_coupon_id
|
||||
* @property Grid\Column|Collection abilities
|
||||
* @property Grid\Column|Collection last_used_at
|
||||
* @property Grid\Column|Collection token
|
||||
* @property Grid\Column|Collection tokenable_id
|
||||
* @property Grid\Column|Collection tokenable_type
|
||||
* @property Grid\Column|Collection remarks
|
||||
* @property Grid\Column|Collection gift_sku_id
|
||||
* @property Grid\Column|Collection attrs
|
||||
* @property Grid\Column|Collection part_id
|
||||
* @property Grid\Column|Collection applicant_id
|
||||
* @property Grid\Column|Collection reviewer_id
|
||||
* @property Grid\Column|Collection buynote_id
|
||||
* @property Grid\Column|Collection cost_price
|
||||
* @property Grid\Column|Collection images
|
||||
* @property Grid\Column|Collection market_price
|
||||
* @property Grid\Column|Collection media
|
||||
* @property Grid\Column|Collection release_at
|
||||
* @property Grid\Column|Collection sales
|
||||
* @property Grid\Column|Collection shipping_template_id
|
||||
* @property Grid\Column|Collection stock
|
||||
* @property Grid\Column|Collection verify_state
|
||||
* @property Grid\Column|Collection feature_id
|
||||
* @property Grid\Column|Collection items
|
||||
* @property Grid\Column|Collection product_spu_id
|
||||
* @property Grid\Column|Collection view_date
|
||||
* @property Grid\Column|Collection rule_id
|
||||
* @property Grid\Column|Collection info
|
||||
|
|
@ -135,10 +141,10 @@ namespace Dcat\Admin {
|
|||
* @property Grid\Column|Collection expires_at
|
||||
* @property Grid\Column|Collection is_use
|
||||
* @property Grid\Column|Collection phone
|
||||
* @property Grid\Column|Collection coupon_amount
|
||||
* @property Grid\Column|Collection coupon_name
|
||||
* @property Grid\Column|Collection coupon_threshold
|
||||
* @property Grid\Column|Collection coupon_type
|
||||
* @property Grid\Column|Collection coupon_value
|
||||
* @property Grid\Column|Collection birthday
|
||||
* @property Grid\Column|Collection gender
|
||||
* @property Grid\Column|Collection inviter_id
|
||||
|
|
@ -192,6 +198,17 @@ namespace Dcat\Admin {
|
|||
* @method Grid\Column|Collection jump_link(string $label = null)
|
||||
* @method Grid\Column|Collection jump_type(string $label = null)
|
||||
* @method Grid\Column|Collection sort(string $label = null)
|
||||
* @method Grid\Column|Collection after_sale_id(string $label = null)
|
||||
* @method Grid\Column|Collection desc(string $label = null)
|
||||
* @method Grid\Column|Collection images(string $label = null)
|
||||
* @method Grid\Column|Collection amount(string $label = null)
|
||||
* @method Grid\Column|Collection num(string $label = null)
|
||||
* @method Grid\Column|Collection order_id(string $label = null)
|
||||
* @method Grid\Column|Collection order_product_id(string $label = null)
|
||||
* @method Grid\Column|Collection remarks(string $label = null)
|
||||
* @method Grid\Column|Collection sn(string $label = null)
|
||||
* @method Grid\Column|Collection state(string $label = null)
|
||||
* @method Grid\Column|Collection tracking_number(string $label = null)
|
||||
* @method Grid\Column|Collection _lft(string $label = null)
|
||||
* @method Grid\Column|Collection _rgt(string $label = null)
|
||||
* @method Grid\Column|Collection is_recommend(string $label = null)
|
||||
|
|
@ -203,12 +220,11 @@ namespace Dcat\Admin {
|
|||
* @method Grid\Column|Collection coupon_id(string $label = null)
|
||||
* @method Grid\Column|Collection ranges(string $label = null)
|
||||
* @method Grid\Column|Collection status(string $label = null)
|
||||
* @method Grid\Column|Collection num(string $label = null)
|
||||
* @method Grid\Column|Collection task_id(string $label = null)
|
||||
* @method Grid\Column|Collection administrator_id(string $label = null)
|
||||
* @method Grid\Column|Collection amount(string $label = null)
|
||||
* @method Grid\Column|Collection task_id(string $label = null)
|
||||
* @method Grid\Column|Collection limit(string $label = null)
|
||||
* @method Grid\Column|Collection sent(string $label = null)
|
||||
* @method Grid\Column|Collection stock(string $label = null)
|
||||
* @method Grid\Column|Collection threshold(string $label = null)
|
||||
* @method Grid\Column|Collection use_day(string $label = null)
|
||||
* @method Grid\Column|Collection use_end_at(string $label = null)
|
||||
|
|
@ -222,7 +238,6 @@ namespace Dcat\Admin {
|
|||
* @method Grid\Column|Collection after_sale_deadline(string $label = null)
|
||||
* @method Grid\Column|Collection discount_amount(string $label = null)
|
||||
* @method Grid\Column|Collection is_comment(string $label = null)
|
||||
* @method Grid\Column|Collection order_id(string $label = null)
|
||||
* @method Grid\Column|Collection quantity(string $label = null)
|
||||
* @method Grid\Column|Collection reduced_amount(string $label = null)
|
||||
* @method Grid\Column|Collection sell_price(string $label = null)
|
||||
|
|
@ -245,30 +260,27 @@ namespace Dcat\Admin {
|
|||
* @method Grid\Column|Collection products_total_amount(string $label = null)
|
||||
* @method Grid\Column|Collection remark(string $label = null)
|
||||
* @method Grid\Column|Collection shipping_fee(string $label = null)
|
||||
* @method Grid\Column|Collection sn(string $label = null)
|
||||
* @method Grid\Column|Collection user_coupon_id(string $label = null)
|
||||
* @method Grid\Column|Collection abilities(string $label = null)
|
||||
* @method Grid\Column|Collection last_used_at(string $label = null)
|
||||
* @method Grid\Column|Collection token(string $label = null)
|
||||
* @method Grid\Column|Collection tokenable_id(string $label = null)
|
||||
* @method Grid\Column|Collection tokenable_type(string $label = null)
|
||||
* @method Grid\Column|Collection remarks(string $label = null)
|
||||
* @method Grid\Column|Collection gift_sku_id(string $label = null)
|
||||
* @method Grid\Column|Collection attrs(string $label = null)
|
||||
* @method Grid\Column|Collection part_id(string $label = null)
|
||||
* @method Grid\Column|Collection applicant_id(string $label = null)
|
||||
* @method Grid\Column|Collection reviewer_id(string $label = null)
|
||||
* @method Grid\Column|Collection buynote_id(string $label = null)
|
||||
* @method Grid\Column|Collection cost_price(string $label = null)
|
||||
* @method Grid\Column|Collection images(string $label = null)
|
||||
* @method Grid\Column|Collection market_price(string $label = null)
|
||||
* @method Grid\Column|Collection media(string $label = null)
|
||||
* @method Grid\Column|Collection release_at(string $label = null)
|
||||
* @method Grid\Column|Collection sales(string $label = null)
|
||||
* @method Grid\Column|Collection shipping_template_id(string $label = null)
|
||||
* @method Grid\Column|Collection stock(string $label = null)
|
||||
* @method Grid\Column|Collection verify_state(string $label = null)
|
||||
* @method Grid\Column|Collection feature_id(string $label = null)
|
||||
* @method Grid\Column|Collection items(string $label = null)
|
||||
* @method Grid\Column|Collection product_spu_id(string $label = null)
|
||||
* @method Grid\Column|Collection view_date(string $label = null)
|
||||
* @method Grid\Column|Collection rule_id(string $label = null)
|
||||
* @method Grid\Column|Collection info(string $label = null)
|
||||
|
|
@ -277,10 +289,10 @@ namespace Dcat\Admin {
|
|||
* @method Grid\Column|Collection expires_at(string $label = null)
|
||||
* @method Grid\Column|Collection is_use(string $label = null)
|
||||
* @method Grid\Column|Collection phone(string $label = null)
|
||||
* @method Grid\Column|Collection coupon_amount(string $label = null)
|
||||
* @method Grid\Column|Collection coupon_name(string $label = null)
|
||||
* @method Grid\Column|Collection coupon_threshold(string $label = null)
|
||||
* @method Grid\Column|Collection coupon_type(string $label = null)
|
||||
* @method Grid\Column|Collection coupon_value(string $label = null)
|
||||
* @method Grid\Column|Collection birthday(string $label = null)
|
||||
* @method Grid\Column|Collection gender(string $label = null)
|
||||
* @method Grid\Column|Collection inviter_id(string $label = null)
|
||||
|
|
@ -339,6 +351,17 @@ namespace Dcat\Admin {
|
|||
* @property Show\Field|Collection jump_link
|
||||
* @property Show\Field|Collection jump_type
|
||||
* @property Show\Field|Collection sort
|
||||
* @property Show\Field|Collection after_sale_id
|
||||
* @property Show\Field|Collection desc
|
||||
* @property Show\Field|Collection images
|
||||
* @property Show\Field|Collection amount
|
||||
* @property Show\Field|Collection num
|
||||
* @property Show\Field|Collection order_id
|
||||
* @property Show\Field|Collection order_product_id
|
||||
* @property Show\Field|Collection remarks
|
||||
* @property Show\Field|Collection sn
|
||||
* @property Show\Field|Collection state
|
||||
* @property Show\Field|Collection tracking_number
|
||||
* @property Show\Field|Collection _lft
|
||||
* @property Show\Field|Collection _rgt
|
||||
* @property Show\Field|Collection is_recommend
|
||||
|
|
@ -350,12 +373,11 @@ namespace Dcat\Admin {
|
|||
* @property Show\Field|Collection coupon_id
|
||||
* @property Show\Field|Collection ranges
|
||||
* @property Show\Field|Collection status
|
||||
* @property Show\Field|Collection num
|
||||
* @property Show\Field|Collection task_id
|
||||
* @property Show\Field|Collection administrator_id
|
||||
* @property Show\Field|Collection amount
|
||||
* @property Show\Field|Collection task_id
|
||||
* @property Show\Field|Collection limit
|
||||
* @property Show\Field|Collection sent
|
||||
* @property Show\Field|Collection stock
|
||||
* @property Show\Field|Collection threshold
|
||||
* @property Show\Field|Collection use_day
|
||||
* @property Show\Field|Collection use_end_at
|
||||
|
|
@ -369,7 +391,6 @@ namespace Dcat\Admin {
|
|||
* @property Show\Field|Collection after_sale_deadline
|
||||
* @property Show\Field|Collection discount_amount
|
||||
* @property Show\Field|Collection is_comment
|
||||
* @property Show\Field|Collection order_id
|
||||
* @property Show\Field|Collection quantity
|
||||
* @property Show\Field|Collection reduced_amount
|
||||
* @property Show\Field|Collection sell_price
|
||||
|
|
@ -392,30 +413,27 @@ namespace Dcat\Admin {
|
|||
* @property Show\Field|Collection products_total_amount
|
||||
* @property Show\Field|Collection remark
|
||||
* @property Show\Field|Collection shipping_fee
|
||||
* @property Show\Field|Collection sn
|
||||
* @property Show\Field|Collection user_coupon_id
|
||||
* @property Show\Field|Collection abilities
|
||||
* @property Show\Field|Collection last_used_at
|
||||
* @property Show\Field|Collection token
|
||||
* @property Show\Field|Collection tokenable_id
|
||||
* @property Show\Field|Collection tokenable_type
|
||||
* @property Show\Field|Collection remarks
|
||||
* @property Show\Field|Collection gift_sku_id
|
||||
* @property Show\Field|Collection attrs
|
||||
* @property Show\Field|Collection part_id
|
||||
* @property Show\Field|Collection applicant_id
|
||||
* @property Show\Field|Collection reviewer_id
|
||||
* @property Show\Field|Collection buynote_id
|
||||
* @property Show\Field|Collection cost_price
|
||||
* @property Show\Field|Collection images
|
||||
* @property Show\Field|Collection market_price
|
||||
* @property Show\Field|Collection media
|
||||
* @property Show\Field|Collection release_at
|
||||
* @property Show\Field|Collection sales
|
||||
* @property Show\Field|Collection shipping_template_id
|
||||
* @property Show\Field|Collection stock
|
||||
* @property Show\Field|Collection verify_state
|
||||
* @property Show\Field|Collection feature_id
|
||||
* @property Show\Field|Collection items
|
||||
* @property Show\Field|Collection product_spu_id
|
||||
* @property Show\Field|Collection view_date
|
||||
* @property Show\Field|Collection rule_id
|
||||
* @property Show\Field|Collection info
|
||||
|
|
@ -424,10 +442,10 @@ namespace Dcat\Admin {
|
|||
* @property Show\Field|Collection expires_at
|
||||
* @property Show\Field|Collection is_use
|
||||
* @property Show\Field|Collection phone
|
||||
* @property Show\Field|Collection coupon_amount
|
||||
* @property Show\Field|Collection coupon_name
|
||||
* @property Show\Field|Collection coupon_threshold
|
||||
* @property Show\Field|Collection coupon_type
|
||||
* @property Show\Field|Collection coupon_value
|
||||
* @property Show\Field|Collection birthday
|
||||
* @property Show\Field|Collection gender
|
||||
* @property Show\Field|Collection inviter_id
|
||||
|
|
@ -481,6 +499,17 @@ namespace Dcat\Admin {
|
|||
* @method Show\Field|Collection jump_link(string $label = null)
|
||||
* @method Show\Field|Collection jump_type(string $label = null)
|
||||
* @method Show\Field|Collection sort(string $label = null)
|
||||
* @method Show\Field|Collection after_sale_id(string $label = null)
|
||||
* @method Show\Field|Collection desc(string $label = null)
|
||||
* @method Show\Field|Collection images(string $label = null)
|
||||
* @method Show\Field|Collection amount(string $label = null)
|
||||
* @method Show\Field|Collection num(string $label = null)
|
||||
* @method Show\Field|Collection order_id(string $label = null)
|
||||
* @method Show\Field|Collection order_product_id(string $label = null)
|
||||
* @method Show\Field|Collection remarks(string $label = null)
|
||||
* @method Show\Field|Collection sn(string $label = null)
|
||||
* @method Show\Field|Collection state(string $label = null)
|
||||
* @method Show\Field|Collection tracking_number(string $label = null)
|
||||
* @method Show\Field|Collection _lft(string $label = null)
|
||||
* @method Show\Field|Collection _rgt(string $label = null)
|
||||
* @method Show\Field|Collection is_recommend(string $label = null)
|
||||
|
|
@ -492,12 +521,11 @@ namespace Dcat\Admin {
|
|||
* @method Show\Field|Collection coupon_id(string $label = null)
|
||||
* @method Show\Field|Collection ranges(string $label = null)
|
||||
* @method Show\Field|Collection status(string $label = null)
|
||||
* @method Show\Field|Collection num(string $label = null)
|
||||
* @method Show\Field|Collection task_id(string $label = null)
|
||||
* @method Show\Field|Collection administrator_id(string $label = null)
|
||||
* @method Show\Field|Collection amount(string $label = null)
|
||||
* @method Show\Field|Collection task_id(string $label = null)
|
||||
* @method Show\Field|Collection limit(string $label = null)
|
||||
* @method Show\Field|Collection sent(string $label = null)
|
||||
* @method Show\Field|Collection stock(string $label = null)
|
||||
* @method Show\Field|Collection threshold(string $label = null)
|
||||
* @method Show\Field|Collection use_day(string $label = null)
|
||||
* @method Show\Field|Collection use_end_at(string $label = null)
|
||||
|
|
@ -511,7 +539,6 @@ namespace Dcat\Admin {
|
|||
* @method Show\Field|Collection after_sale_deadline(string $label = null)
|
||||
* @method Show\Field|Collection discount_amount(string $label = null)
|
||||
* @method Show\Field|Collection is_comment(string $label = null)
|
||||
* @method Show\Field|Collection order_id(string $label = null)
|
||||
* @method Show\Field|Collection quantity(string $label = null)
|
||||
* @method Show\Field|Collection reduced_amount(string $label = null)
|
||||
* @method Show\Field|Collection sell_price(string $label = null)
|
||||
|
|
@ -534,30 +561,27 @@ namespace Dcat\Admin {
|
|||
* @method Show\Field|Collection products_total_amount(string $label = null)
|
||||
* @method Show\Field|Collection remark(string $label = null)
|
||||
* @method Show\Field|Collection shipping_fee(string $label = null)
|
||||
* @method Show\Field|Collection sn(string $label = null)
|
||||
* @method Show\Field|Collection user_coupon_id(string $label = null)
|
||||
* @method Show\Field|Collection abilities(string $label = null)
|
||||
* @method Show\Field|Collection last_used_at(string $label = null)
|
||||
* @method Show\Field|Collection token(string $label = null)
|
||||
* @method Show\Field|Collection tokenable_id(string $label = null)
|
||||
* @method Show\Field|Collection tokenable_type(string $label = null)
|
||||
* @method Show\Field|Collection remarks(string $label = null)
|
||||
* @method Show\Field|Collection gift_sku_id(string $label = null)
|
||||
* @method Show\Field|Collection attrs(string $label = null)
|
||||
* @method Show\Field|Collection part_id(string $label = null)
|
||||
* @method Show\Field|Collection applicant_id(string $label = null)
|
||||
* @method Show\Field|Collection reviewer_id(string $label = null)
|
||||
* @method Show\Field|Collection buynote_id(string $label = null)
|
||||
* @method Show\Field|Collection cost_price(string $label = null)
|
||||
* @method Show\Field|Collection images(string $label = null)
|
||||
* @method Show\Field|Collection market_price(string $label = null)
|
||||
* @method Show\Field|Collection media(string $label = null)
|
||||
* @method Show\Field|Collection release_at(string $label = null)
|
||||
* @method Show\Field|Collection sales(string $label = null)
|
||||
* @method Show\Field|Collection shipping_template_id(string $label = null)
|
||||
* @method Show\Field|Collection stock(string $label = null)
|
||||
* @method Show\Field|Collection verify_state(string $label = null)
|
||||
* @method Show\Field|Collection feature_id(string $label = null)
|
||||
* @method Show\Field|Collection items(string $label = null)
|
||||
* @method Show\Field|Collection product_spu_id(string $label = null)
|
||||
* @method Show\Field|Collection view_date(string $label = null)
|
||||
* @method Show\Field|Collection rule_id(string $label = null)
|
||||
* @method Show\Field|Collection info(string $label = null)
|
||||
|
|
@ -566,10 +590,10 @@ namespace Dcat\Admin {
|
|||
* @method Show\Field|Collection expires_at(string $label = null)
|
||||
* @method Show\Field|Collection is_use(string $label = null)
|
||||
* @method Show\Field|Collection phone(string $label = null)
|
||||
* @method Show\Field|Collection coupon_amount(string $label = null)
|
||||
* @method Show\Field|Collection coupon_name(string $label = null)
|
||||
* @method Show\Field|Collection coupon_threshold(string $label = null)
|
||||
* @method Show\Field|Collection coupon_type(string $label = null)
|
||||
* @method Show\Field|Collection coupon_value(string $label = null)
|
||||
* @method Show\Field|Collection birthday(string $label = null)
|
||||
* @method Show\Field|Collection gender(string $label = null)
|
||||
* @method Show\Field|Collection inviter_id(string $label = null)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'AfterSale' => '售后申请',
|
||||
'after-sales' => '售后申请',
|
||||
],
|
||||
'fields' => [
|
||||
'user_id' => '用户ID',
|
||||
'user'=>[
|
||||
'phone' => '手机号',
|
||||
],
|
||||
'order_id' => '原订单ID',
|
||||
'order'=>[
|
||||
'sn' => '订单编号',
|
||||
],
|
||||
'sn' => '售后编号',
|
||||
'order_product_id' => '订单商品',
|
||||
'orderProduct'=>[
|
||||
'name' => '商品名称',
|
||||
'cover' => '商品图片',
|
||||
],
|
||||
'order_product'=>[
|
||||
'name' => '商品名称',
|
||||
'cover' => '商品图片',
|
||||
],
|
||||
'num' => '数量',
|
||||
'amount' => '退款金额',
|
||||
'type' => '类别',
|
||||
'state' => '状态',
|
||||
'description' => '申请描述',
|
||||
'images' => '图片',
|
||||
'remarks' => '回复',
|
||||
'remarks1' => '备注',
|
||||
'remarks3' => '备注',
|
||||
'tracking_number' => '运单号',
|
||||
'created_at'=>'申请时间',
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<div class="card">
|
||||
<div class="box-header with-border" style="height:50px;">
|
||||
<h3 class="box-title" style="line-height:20px;">{{$title}}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="col-md-12" style="position: relative; overflow: auto; width: auto; height: 75vh;">
|
||||
<div style="overflow: auto; width: auto; height: 100%;">
|
||||
<!-- The time line -->
|
||||
@if($logs->count() > 0)
|
||||
<div class="timeline">
|
||||
@foreach($logs as $log)
|
||||
<!-- timeline time label -->
|
||||
<div class="time-label">
|
||||
<span class="bg-green">{{$log->created_at}}</span>
|
||||
</div>
|
||||
<!-- /.timeline-label -->
|
||||
<!-- timeline item -->
|
||||
<div>
|
||||
<i class="fa fa-envelope bg-blue"></i>
|
||||
<div class="timeline-item">
|
||||
<span class="time"><i class="fas fa-clock"></i> {{$log->created_at->diffForHumans()}}</span>
|
||||
<h3 class="timeline-header">{{$log->name}}</h3>
|
||||
<div class="timeline-body">{{$log->desc}}</div>
|
||||
@if(count($log->images) > 0)
|
||||
<div class="timeline-body">
|
||||
@foreach ($log->images as $image)
|
||||
<a href="{{$image}}" target="_blank" style="display:inline-block; margin:10px;">
|
||||
<img src="{{$image}}" style="max-height: 100px;max-width: 100px;vertical-align: middle;">
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<!-- ./ timeline item -->
|
||||
@endforeach
|
||||
<div>
|
||||
<i class="fas fa-clock bg-gray"></i>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue