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'),
]);
}
}