From 9843991b94ef95c8653437ef175be274f5043042 Mon Sep 17 00:00:00 2001 From: panliang <1163816051@qq.com> Date: Thu, 4 Aug 2022 13:52:55 +0800 Subject: [PATCH] order:profit --- app/Admin/Actions/Show/ProfitSuccess.php | 29 --------- .../Controllers/OrderProfitController.php | 19 +++--- .../Grid/Tools/ProfitBatchSuccess.php | 42 +++++-------- app/Admin/Forms/ProfitSuccessForm.php | 52 +++++---------- app/Console/Commands/OrderProfitCommand.php | 50 +++++++-------- app/Models/OrderProfit.php | 8 ++- app/Services/DistributeService.php | 63 ++++++++++++------- 7 files changed, 110 insertions(+), 153 deletions(-) delete mode 100644 app/Admin/Actions/Show/ProfitSuccess.php diff --git a/app/Admin/Actions/Show/ProfitSuccess.php b/app/Admin/Actions/Show/ProfitSuccess.php deleted file mode 100644 index 12386ced..00000000 --- a/app/Admin/Actions/Show/ProfitSuccess.php +++ /dev/null @@ -1,29 +0,0 @@ -getKey()); - return $info->status != 2; - } - - public function html() - { - $form = ProfitSuccessForm::make()->payload(['id' => $this->getKey()]);; - return Modal::make() - ->lg() - ->title($this->title) - ->body($form) - ->button(" {$this->title}  "); - } -} diff --git a/app/Admin/Controllers/OrderProfitController.php b/app/Admin/Controllers/OrderProfitController.php index 2323f00e..e7678877 100644 --- a/app/Admin/Controllers/OrderProfitController.php +++ b/app/Admin/Controllers/OrderProfitController.php @@ -8,8 +8,8 @@ use Dcat\Admin\Grid; use Dcat\Admin\Show; use Dcat\Admin\Http\Controllers\AdminController; use App\Admin\Extensions\Grid\Tools\ProfitBatchSuccess; -use App\Admin\Actions\Show\ProfitSuccess; use App\Enums\PayWay; +use Dcat\Admin\Admin; class OrderProfitController extends AdminController { @@ -43,13 +43,16 @@ class OrderProfitController extends AdminController $filter->like('order.sn')->width(3); $filter->like('fromUser.phone')->width(3); $filter->like('user.phone')->width(3); + $filter->equal('status')->select(OrderProfit::$statusMap)->width(3); }); - // $grid->showRowSelector(); - // $grid->batchActions(function (Grid\Tools\BatchActions $batch) { - // $batch->disableDelete(); - // $batch->add(new ProfitBatchSuccess()); - // }); + $grid->showRowSelector(); + $grid->batchActions(function (Grid\Tools\BatchActions $batch) { + $batch->disableDelete(); + if (Admin::user()->can('dcat.admin.profit.pay')) { + $batch->add(new ProfitBatchSuccess()); + } + }); }); } @@ -88,10 +91,6 @@ class OrderProfitController extends AdminController $tools->disableEdit(); $tools->disableDelete(); }); - - $show->tools(function (Show\Tools $tools) { - $tools->append(new ProfitSuccess()); - }); }); } diff --git a/app/Admin/Extensions/Grid/Tools/ProfitBatchSuccess.php b/app/Admin/Extensions/Grid/Tools/ProfitBatchSuccess.php index 67cc56fe..fd46ad18 100644 --- a/app/Admin/Extensions/Grid/Tools/ProfitBatchSuccess.php +++ b/app/Admin/Extensions/Grid/Tools/ProfitBatchSuccess.php @@ -2,41 +2,33 @@ namespace App\Admin\Extensions\Grid\Tools; -use App\Models\Profit; +use App\Admin\Forms\ProfitSuccessForm; use Dcat\Admin\Grid\BatchAction; -use Illuminate\Http\Request; -use Illuminate\Support\Facades\DB; -use Throwable; +use Dcat\Admin\Widgets\Modal; class ProfitBatchSuccess extends BatchAction { - protected $title = '支付成功'; + protected $title = '支付'; - protected function authorize($user): bool + protected function html() { - return $user->can('dcat.admin.profit.pay'); + $form = ProfitSuccessForm::make(); + return Modal::make() + ->lg() + ->title($this->title) + ->body($form) + ->onLoad($this->getModalScript()) + ->button($this->title); } - public function confirm() - { - return '是否确认?'; - } - - // 处理请求 - public function handle(Request $request) + protected function getModalScript() { + // 弹窗显示后往隐藏的id表单中写入批量选中的行ID + return <<getKey(); - try { - DB::beginTransaction(); + var key = {$this->getSelectedKeysScript()} - DB::commit(); - } catch (Throwable $th) { - DB::rollBack(); - report($th); - return $this->response()->error('操作失败,'.$th->getMessage())->refresh(); - } - - return $this->response()->success('操作成功')->refresh(); + $('#order-profit-ids').val(key); + JS; } } diff --git a/app/Admin/Forms/ProfitSuccessForm.php b/app/Admin/Forms/ProfitSuccessForm.php index 9b288b5b..1d81ab07 100644 --- a/app/Admin/Forms/ProfitSuccessForm.php +++ b/app/Admin/Forms/ProfitSuccessForm.php @@ -3,31 +3,16 @@ namespace App\Admin\Forms; use App\Services\DistributeService; -use App\Exceptions\BizException; use App\Models\OrderProfit; use Dcat\Admin\Contracts\LazyRenderable; use Dcat\Admin\Traits\LazyWidget; use Dcat\Admin\Widgets\Form; use Illuminate\Support\Facades\DB; -use Throwable; use App\Enums\PayWay; class ProfitSuccessForm extends Form implements LazyRenderable { use LazyWidget; - - /** - * 权限判断,如不需要可以删除此方法 - * - * @param Model|Authenticatable|HasPermissions|null $user - * - * @return bool - */ - protected function authorize($user): bool - { - return $user->can('dcat.admin.profit.pay'); - } - /** * Handle the form request. * @@ -37,26 +22,23 @@ class ProfitSuccessForm extends Form implements LazyRenderable */ public function handle(array $input) { - $order = OrderProfit::findOrFail($this->payload['id']); + $ids = explode(',', $input['ids']); + $list = OrderProfit::whereIn('id', $ids)->whereNotIn('status', [1, 2])->get()->groupBy('user_id'); + $way = $input['pay_way']; $service = new DistributeService(); - if ($input['pay_way'] === PayWay::WxpayTransfer->value && !$order->pay_no) { - $order->update([ - 'pay_no' => serial_number(), - 'pay_way' => PayWay::WxpayTransfer->value - ]); - } - try { - DB::beginTransaction(); - if ($input['pay_way'] === PayWay::WxpayTransfer->value) { - $service->wechatTransfer($order); - } else { - $service->success($order, $input); + foreach($list as $id => $items) { + try { + DB::beginTransaction(); + if ($way === PayWay::WxpayTransfer->value) { + $service->wechatTransfers($items); + } else if ($way === PayWay::Offline->value) { + $service->success($items, $input); + } + DB::commit(); + } catch (\Exception $e) { + DB::rollBack(); + return $this->response()->error($e->getMessage()); } - DB::commit(); - } catch (Throwable $th) { - DB::rollBack(); - report($th); - throw new BizException('操作失败:'.$th->getMessage()); } return $this->response()->success('操作成功')->refresh(); } @@ -66,15 +48,13 @@ class ProfitSuccessForm extends Form implements LazyRenderable */ public function form() { - $order = OrderProfit::findOrFail($this->payload['id']); - + $this->hidden('ids')->attribute('id', 'order-profit-ids'); $this->datetime('paid_at')->value(now()); $this->radio('pay_way')->options([ PayWay::Offline->value => PayWay::Offline->text(), PayWay::WxpayTransfer->value => PayWay::WxpayTransfer->text() ])->default(PayWay::Offline->value); $this->text('pay_no'); - $this->text('remarks')->value($order->remark); $this->disableResetButton(); } diff --git a/app/Console/Commands/OrderProfitCommand.php b/app/Console/Commands/OrderProfitCommand.php index 92fa4525..53d8301b 100644 --- a/app/Console/Commands/OrderProfitCommand.php +++ b/app/Console/Commands/OrderProfitCommand.php @@ -4,6 +4,7 @@ namespace App\Console\Commands; use App\Enums\PayWay; use App\Models\Order; +use App\Models\OrderProfit; use App\Services\DistributeService; use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; @@ -45,14 +46,10 @@ class OrderProfitCommand extends Command // 售后过期天数 7 $saleDays = app_settings('app.sale_after_expire_days'); - // 支付方式 - $payWay = PayWay::WxpayTransfer->value; while (true) { $page = 0; - $orders = Order::with([ - 'profits' => fn($q) => $q->where('status', 0) - ]) + $orders = Order::query() // 订单已完成 ->where('status', Order::STATUS_COMPLETED) // 没有售后订单 @@ -61,35 +58,30 @@ class OrderProfitCommand extends Command ->where('completed_at', '<', now()->subDays($saleDays)) // 未支付提成 ->whereNull('profit_paid') - ->limit(200) + ->limit(10) ->get(); - foreach ($orders as $order) { - foreach($order->profits as $profit) { - try { - DB::beginTransaction(); - if ($payWay === PayWay::WxpayTransfer->value) { - if (!$profit->pay_no) { - $profit->update([ - 'pay_no' => serial_number(), - 'pay_way' => $payWay - ]); - } - $service->wechatTransfer($profit); - } - DB::commit(); - } catch (\Throwable $e) { - DB::rollBack(); - $this->error($e->getMessage()); - } - } - // 没有待付款的提成记录 - if (!$order->profits()->where('status', 0)->exists()) { - // 更新订单 - $order->update(['profit_paid' => now()]); + // 修改提成记录的状态为 等待结算 + OrderProfit::whereIn('order_id', $orders->pluck('id'))->where('status', 0)->update(['status' => 4]); + + // 获取 等待结算 的提成记录, 按照 user_id 分组 + $list = OrderProfit::where('status', 4)->get()->groupBy('user_id'); + foreach($list as $id => $items) { + try { + DB::beginTransaction(); + $service->wechatTransfers($items); + DB::commit(); + } catch (\Exception $e) { + DB::rollBack(); + $this->error($e->getMessage()); } } + // 没有待付款的提成记录 + // if (!$order->profits()->where('status', 0)->exists()) { + // $order->update(['profit_paid' => now()]); + // } + $page++; if ($page === 0) { diff --git a/app/Models/OrderProfit.php b/app/Models/OrderProfit.php index cd58b146..c30ec87b 100644 --- a/app/Models/OrderProfit.php +++ b/app/Models/OrderProfit.php @@ -11,17 +11,19 @@ class OrderProfit extends Model use HasFactory, HasDateTimeFormatter; public static $statusMap = [ - 0 => '待付款', + 0 => '订单未结算', + 4 => '待付款', 1 => '付款中', 2 => '已付款', - 3 => '付款失败' + 3 => '付款失败', ]; public static $statusColor = [ 0 => 'primary', 1 => 'warning', 2 => 'success', - 3 => 'danger' + 3 => 'danger', + 4 => 'gray' ]; protected $fillable = ['id', 'order_id', 'from_user_id', 'user_id', 'role', 'role_name', 'growth_value', 'ratio', 'money', 'sub_money', 'status', 'paid_at', 'pay_no', 'pay_way', 'pay_data', 'remarks']; diff --git a/app/Services/DistributeService.php b/app/Services/DistributeService.php index bf328cb6..44a83385 100644 --- a/app/Services/DistributeService.php +++ b/app/Services/DistributeService.php @@ -2,11 +2,13 @@ namespace App\Services; -use App\Models\{User, Order, SalesValueLog, Agent, OrderProfit}; +use App\Models\{User, Order, SalesValueLog, Agent, OrderProfit, SocialiteUser}; use App\Services\Payment\WxpayService; use App\Enums\SocialiteType; use App\Exceptions\BizException; use App\Exceptions\WeChatPayException; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Support\Collection; /** * 分销模块 @@ -159,45 +161,64 @@ class DistributeService } /** + * 批量支付 * 使用微信企业付款, 支付返利金额 - * 调用之前, 需要提前生成商户订单号 - * - * @throws WeChatPayException + * 支付的金额必须大于 1, 并且是同一个人的 */ - public function wechatTransfer(OrderProfit $profit) + public function wechatTransfers(Collection $list) { - $user = $profit->user; - $openid = $user->socialites()->where('socialite_type', SocialiteType::WechatMiniProgram->value)->value('socialite_id'); - if ($profit->money <= 0) { - throw new WeChatPayException('返利金额必须大于0'); + if ($list->count() === 0) { + throw new BizException('记录数必须大于 0'); } + $filtered = collect(); + $money = 0; + $userId = $list->first()->user_id; + // 商户订单号 + $sn = serial_number(); + foreach($list as $item) { + // 待付款, 同一收款用户 + if ($item->status === 4 && $item->user_id === $userId) { + $item->update([ + 'status' => 1, + 'pay_no' => $sn + ]); + $money += $item->money; + + $filtered->push($item); + } + } + if ($money < 1) { + throw new BizException('金额小于 1, 无法打款'); + } + $openid = SocialiteUser::where('socialite_type', SocialiteType::WechatMiniProgram->value)->where('user_id', $userId)->value('socialite_id'); if (!$openid) { - throw new WeChatPayException('没有 openid'); + throw new BizException('用户 '.$userId.' 没有 openid'); } + $result = (new WxpayService())->transfer([ - 'partner_trade_no' => $profit->pay_no, + 'partner_trade_no' => $sn, 'openid' => $openid, 'check_name' => 'NO_CHECK', - 'amount' => $profit->money * 100, + 'amount' => $money * 100, 'desc' => '推荐返利', ]); - $this->success($profit, $result); + $this->success($filtered, $result); } /** - * 返现记录支付成功 + * 支付成功 * - * @param \App\Models\OrderProfit $profit - * @param mixed $data [paid_at, remarks, pay_way] + * @param Collection $list 提成记录 + * @param array $result [paid_at, remarks] */ - public function success(OrderProfit $profit, $data = null) + public function success(Collection $list, $result = []) { - $profit->update([ + OrderProfit::whereIn('id', $list->pluck('id'))->update([ 'status' => 2, - 'paid_at' => data_get($data, 'paid_at', now()), - 'pay_data' => $data, - 'remarks' => data_get($data, 'remarks'), + 'paid_at' => data_get($result, 'paid_at', now()), + 'pay_data' => $result, + 'remarks' => data_get($result, 'remarks'), ]); } }