order:profit
parent
4499c057f6
commit
9843991b94
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Actions\Show;
|
||||
|
||||
use Dcat\Admin\Show\AbstractTool;
|
||||
use Dcat\Admin\Widgets\Modal;
|
||||
use App\Admin\Forms\ProfitSuccessForm;
|
||||
use App\Models\OrderProfit;
|
||||
|
||||
class ProfitSuccess extends AbstractTool
|
||||
{
|
||||
protected $title = '支付';
|
||||
|
||||
public function allowed()
|
||||
{
|
||||
$info = OrderProfit::find($this->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("<a href=\"javascript:void(0)\" class=\"btn btn-sm btn-success\"><i class=\"feather icon-check\"></i> {$this->title}</a> ");
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <<<JS
|
||||
// 获取选中的ID数组
|
||||
$keys = $this->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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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'];
|
||||
|
|
|
|||
|
|
@ -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'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue