6
0
Fork 0

【后台】优化管理津贴

release
李静 2022-03-07 15:40:03 +08:00
parent 2a013b5037
commit 043c10c528
11 changed files with 411 additions and 2 deletions

View File

@ -0,0 +1,51 @@
<?php
namespace App\Admin\Actions\Grid;
use App\Models\DealerManageSubsidy;
use App\Services\Dealer\ManageSubsidyService;
use Dcat\Admin\Grid\BatchAction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Throwable;
class DealerManageSubsidyBatchPay extends BatchAction
{
protected $title = '<i class="feather grid-action-icon icon-stop-circle"></i> 付款';
/**
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return $user->can('dcat.admin.dealer_manage_subsidies.batch_pay');
}
// 确认弹窗信息
public function confirm()
{
return '您确定要支付选中的管理津贴吗?';
}
// 处理请求
public function handle(Request $request)
{
try {
DB::transaction(function () {
foreach ($this->getKey() as $id) {
$dealerManageSubsidy = DealerManageSubsidy::lockForUpdate()->settled()->find($id);
if ($dealerManageSubsidy?->isPending()) {
(new ManageSubsidyService())->pay($dealerManageSubsidy);
}
}
});
} catch (Throwable $e) {
return $this->response()->error('操作失败:'.$e->getMessage())->refresh();
}
return $this->response()->success('操作成功')->refresh();
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace App\Admin\Actions\Grid;
use App\Models\DealerManageSubsidy;
use App\Services\Dealer\ManageSubsidyService;
use Dcat\Admin\Grid\RowAction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class DealerManageSubsidyPay extends RowAction
{
protected $title = '<i class="feather grid-action-icon icon-stop-circle"></i> 付款';
/**
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return $user->can('dcat.admin.dealer_manage_subsidies.pay');
}
// 确认弹窗信息
public function confirm()
{
return '您确定要支付选中的管理津贴吗?';
}
// 处理请求
public function handle(Request $request)
{
DB::transaction(function () {
$id = $this->getKey();
(new ManageSubsidyService())->pay(
DealerManageSubsidy::lockForUpdate()->settled()->findOrFail($id)
);
});
return $this->response()->success('操作成功')->refresh();
}
}

View File

@ -0,0 +1,167 @@
<?php
namespace App\Admin\Controllers;
use App\Admin\Actions\Grid\DealerManageSubsidyBatchPay;
use App\Admin\Actions\Grid\DealerManageSubsidyPay;
use App\Admin\Repositories\DealerManageSubsidy;
use App\Admin\Widgets\InfoBox;
use App\Enums\DealerManageSubsidyStatus;
use App\Models\DealerManageSubsidy as DealerManageSubsidyModel;
use Dcat\Admin\Admin;
use Dcat\Admin\Grid;
use Dcat\Admin\Http\Controllers\AdminController;
use Dcat\Admin\Layout\Row;
class DealerManageSubsidyController extends AdminController
{
protected $title = '管理津贴';
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
Admin::style(
<<<CSS
.card-header {
margin-top: 1.5rem !important;
margin-bottom: -1rem !important;
}
CSS
);
$builder = DealerManageSubsidy::with(['dealer', 'user', 'userinfo', 'earning']);
return Grid::make($builder, function (Grid $grid) {
$grid->model()->settled()->orderBy('id', 'desc');
$grid->column('settle_period', '结算周期')->display(function () {
return $this->start_at->rawFormat('Y/m/d') . '-' . $this->end_at->rawFormat('Y/m/d');
})->link(function () {
return admin_route('dealer_manage_subsidy_logs.index', [
'user[phone]' => $this->user?->phone,
'order_completed_at[start]' => $this->start_at->toDateTimeString(),
'order_completed_at[end]' => $this->end_at->toDateTimeString(),
]);
});
$grid->column('user.phone', '手机号');
$grid->column('userinfo.nickname', '昵称');
$grid->column('lvl', '经销商等级')->display(function () {
return $this->lvl->text();
});
$grid->column('total_amount', '津贴总额')->prepend('¥');
$grid->column('fee', '手续费')->prepend('¥')->help('手续费=津贴总额*手续费率');
$grid->column('real_amount', '总收入')->prepend('¥')->help('总收入=津贴总额-手续费');
$grid->column('fee_rate', '手续费率')->append('%');
$grid->column('remark', '备注')->display('查看')->modal(function ($modal) {
$modal->title('备注');
return "<div style='padding:10px'>".nl2br($this->remark).'</div>';
});
$grid->column('status', '状态')->display(function ($v) {
return '<i class="fa fa-circle" style="font-size: 13px; color: '.$v->color().';"></i>&nbsp;&nbsp;'.$v->text();
});
$grid->column('earning.pay_at', '付款时间');
$grid->showRowSelector();
$grid->tools(function ($tools) {
$tools->batch(function ($batch) {
$batch->disableDelete();
if (Admin::user()->can('dcat.admin.dealer_manage_subsidies.batch_pay')) {
$batch->add(new DealerManageSubsidyBatchPay());
}
});
});
$grid->actions(function (Grid\Displayers\Actions $actions) {
if ($actions->row->isPending() && Admin::user()->can('dcat.admin.dealer_manage_subsidies.pay')) {
$actions->append(new DealerManageSubsidyPay());
}
});
$grid->filter(function (Grid\Filter $filter) {
$filter->panel();
$filter->equal('user.phone', '手机号')->width(3);
$filter->equal('status', '状态')->select(DealerManageSubsidyStatus::texts())->width(3);
$filter->whereBetween('settle_period', function ($query) {
$start = $this->input['start'] ?? null;
$end = $this->input['end'] ?? null;
$query->when($start, function ($query, $start) {
$query->where('start_at', '>=', "{$start} 00:00:00");
});
$query->when($end, function ($query, $end) {
$query->where('end_at', '<=', "{$end} 23:59:59");
});
}, '结算周期')->date()->width(6);
});
$grid->header(function ($collection) use ($grid) {
return tap(new Row(), function ($row) use ($grid) {
$query = DealerManageSubsidyModel::query();
$grid->model()->getQueries()->unique()->each(function ($value) use (&$query) {
if (in_array($value['method'], ['paginate', 'get', 'orderBy', 'orderByDesc'], true)) {
return;
}
$query = call_user_func_array([$query, $value['method']], $value['arguments'] ?? []);
});
$totalAmount = (clone $query)->sum('total_amount');
$totalFee = (clone $query)->sum('fee');
$row->column(3, new InfoBox('津贴总额', $totalAmount, 'fa fa-cny'));
$row->column(3, new InfoBox('手续费', $totalFee, 'fa fa-cny'));
});
});
});
return Grid::make($builder, function (Grid $grid) {
$grid->model()->orderBy('id', 'desc');//默认ID倒叙
$grid->column('id')->sortable();
$grid->column('user.phone', '手机号')->copyable();
$grid->column('lvl', '等级')->display(function () {
return $this->lvl->text();
});
$grid->column('order.sn', '订单编号');
$grid->column('product.name', '商品名称');
$grid->column('sales_volume', '销量');
$grid->column('total_amount', '金额');
$grid->column('order_completed_at', '结算时间')->sortable();
$grid->column('created_at')->sortable();
$grid->disableCreateButton();
$grid->disableActions();
$grid->header(function ($collection) use ($grid) {
$query = DealerManageSubsidyLogModel::query();
// 拿到表格筛选 where 条件数组进行遍历
$grid->model()->getQueries()->unique()->each(function ($value) use (&$query) {
if (in_array($value['method'], ['paginate', 'get', 'orderBy', 'orderByDesc'], true)) {
return;
}
$query = call_user_func_array([$query, $value['method']], $value['arguments'] ?? []);
});
// 查出统计数据
$totalAmount = (clone $query)->sum('total_amount');
// 自定义组件
return "<div style='padding: 10px;'>金额:".$totalAmount.' 元</div>';
});
$grid->filter(function (Grid\Filter $filter) {
$filter->panel(false);
$filter->equal('user.phone', '手机号')->width(3);
$filter->between('order_completed_at', '结算时间')->dateTime()->width(7);
});
});
}
}

View File

@ -3,10 +3,13 @@
namespace App\Admin\Controllers;
use App\Admin\Repositories\DealerManageSubsidyLog;
use App\Admin\Widgets\InfoBox;
use App\Models\DealerManageSubsidyLog as DealerManageSubsidyLogModel;
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;
class DealerManageSubsidyLogController extends AdminController
@ -18,10 +21,20 @@ class DealerManageSubsidyLogController extends AdminController
*/
protected function grid()
{
Admin::style(
<<<CSS
.card-header {
margin-top: 1.5rem !important;
margin-bottom: -1rem !important;
}
CSS
);
$builder = DealerManageSubsidyLog::with(['user', 'order', 'product']);
return Grid::make($builder, function (Grid $grid) {
$grid->model()->orderBy('id', 'desc');//默认ID倒叙
$grid->column('id')->sortable();
$grid->column('user.phone', '手机号')->copyable();
$grid->column('lvl', '等级')->display(function () {
@ -37,6 +50,19 @@ class DealerManageSubsidyLogController extends AdminController
$grid->disableCreateButton();
$grid->disableActions();
$grid->header(function ($collection) use ($grid) {
return tap(new Row(), function ($row) use ($grid) {
$query = DealerManageSubsidyLogModel::query();
$grid->model()->getQueries()->unique()->each(function ($value) use (&$query) {
if (in_array($value['method'], ['paginate', 'get', 'orderBy', 'orderByDesc'], true)) {
return;
}
$query = call_user_func_array([$query, $value['method']], $value['arguments'] ?? []);
});
$row->column(3, new InfoBox('津贴总额', (clone $query)->sum('total_amount'), 'fa fa-cny'));
});
$query = DealerManageSubsidyLogModel::query();
// 拿到表格筛选 where 条件数组进行遍历

View File

@ -0,0 +1,16 @@
<?php
namespace App\Admin\Repositories;
use App\Models\DealerManageSubsidy as Model;
use Dcat\Admin\Repositories\EloquentRepository;
class DealerManageSubsidy extends EloquentRepository
{
/**
* Model.
*
* @var string
*/
protected $eloquentClass = Model::class;
}

View File

@ -190,8 +190,10 @@ Route::group([
$router->get('dealer-manager-subsidies', 'DealerManagerSubsidyController@index')->name('dealer_manager_subsidies.index');
$router->get('dealer-manager-sales-logs', 'DealerManagerSalesLogController@index')->name('dealer_manager_sales_logs.index');
//批零明细
// 管理津贴
$router->get('dealer-manage-subsidies', 'DealerManageSubsidyController@index')->name('dealer_manage_subsidies.index');
$router->get('dealer-manage-subsidy-logs', 'DealerManageSubsidyLogController@index')->name('dealer_manage_subsidy_logs.index');
$router->get('dealer-purchase-logs', 'DealerPurchaseLogController@index')->name('dealer_purchase_logs.index');
//批零余额提现

View File

@ -5,4 +5,25 @@ namespace App\Enums;
enum DealerManageSubsidyStatus: int {
case Pending = 0;
case Completed = 5;
public function color(): string
{
return match ($this) {
static::Pending => '#5b69bc',
static::Completed => '#21b978',
};
}
public function text(): string
{
return static::texts()[$this->value] ?? 'Unknown';
}
public static function texts(): array
{
return [
static::Pending->value => '待付款',
static::Completed->value => '已付款',
];
}
}

View File

@ -38,6 +38,17 @@ class DealerManageSubsidy extends Model
'is_settle',
];
/**
* 仅查询已结算的管理津贴
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeSettled($query)
{
return $query->where('is_settle', true);
}
/**
* 此管理津贴所属的经销商
*/
@ -46,11 +57,31 @@ class DealerManageSubsidy extends Model
return $this->belongsTo(Dealer::class, 'user_id', 'user_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 earning()
{
return $this->morphOne(DealerEarning::class, 'earningable');
}
/**
* 仅查询待付款的管理津贴
*
* @return bool
*/
public function isPending(): bool
{
return $this->is_settle && $this->status === DealerManageSubsidyStatus::Pending;
}
public function isCompleted()
{
return $this->status === DealerManageSubsidyStatus::Completed;

View File

@ -0,0 +1,43 @@
<?php
namespace App\Services\Dealer;
use App\Enums\DealerEarningStatus;
use App\Enums\DealerManageSubsidyStatus;
use App\Enums\DealerWalletAction;
use App\Exceptions\BizException;
use App\Models\DealerEarning;
use App\Models\DealerManageSubsidy;
class ManageSubsidyService
{
/**
* @param \App\Models\DealerManageSubsidy $dealerManageSubsidy
* @return void
*/
public function pay(DealerManageSubsidy $dealerManageSubsidy)
{
if (! $dealerManageSubsidy->isPending()) {
throw new BizException('管理津贴 不是待付款状态');
}
$dealerManageSubsidy->update([
'status' => DealerManageSubsidyStatus::Completed,
]);
$dealerManageSubsidy->earning->update([
'pay_way' => DealerEarning::PAY_WAY_WALLET,
'pay_at' => now(),
'pay_info' => null,
'status' => DealerEarningStatus::Completed,
]);
(new WalletService())->changeBalance(
$dealerManageSubsidy->user,
$dealerManageSubsidy->real_amount,
DealerWalletAction::ManageSubsidyIn,
'收入-管理津贴',
$dealerManageSubsidy
);
}
}

View File

@ -342,7 +342,7 @@ class AdminMenuSeeder extends Seeder
[
'title'=>'管理者津贴',
'icon' => '',
'uri' => 'dealer-manager-subsidies',
'uri' => 'dealer-earnings-manage?filter-earningable_type[]=dealer_manager_subsidy',
],
[
'title'=>'管理者津贴明细',

View File

@ -364,6 +364,14 @@ class AdminPermissionSeeder extends Seeder
'name' =>'管理者津贴明细',
'curd' => ['index'],
],
'dealer_manage_subsidies' => [
'name' =>'管理津贴',
'curd' => ['index'],
'children' => [
'pay' => ['name' => '付款'],
'batch_pay' => ['name' => '批量付款'],
],
],
'dealer_manage_subsidy_logs'=>[
'name' =>'管理津贴明细',
'curd' => ['index'],