6
0
Fork 0
jiqu-library-server/app/Services/DistributeService.php

225 lines
6.9 KiB
PHP

<?php
namespace App\Services;
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;
/**
* 分销模块
*/
class DistributeService
{
/**
* 根据订单, 更新成长值
*
* @param \App\Models\Order $order
*
* @return boolean
*/
public function incrementGrowthValue(Order $order)
{
if (!$this->canDistribute($order)) {
return false;
}
// 订单成长值
$sales_value = $order->sales_value;
$user = $order->user;
$user_agent = $user->agent;
// 已经处理过订单成长值
if ($user->salesValueLogs()->where('order_id', $order->id)->exists()) {
return false;
}
// 用户获得成长值
$user->salesValueLogs()->create([
'order_id' => $order->id,
'order_user_id' => $order->user_id,
'type' => SalesValueLog::TYPE_INDIVIDUAL,
'change_sales_value' => $sales_value
]);
$user->userInfo()->increment('growth_value', $sales_value);
if ($user_agent->type === Agent::TYPE_FAVOITE) {
// 自动升级代理
$levels = Agent::where('slug', Agent::TYPE_FAVOITE)->orderBy('sort')->get();
$level_up = '';
foreach($levels->reverse() as $item) {
if ($user->userInfo->growth_value >= $item->growth_value) {
$level_up = $item;
}
}
// 如果当前等级, 比升级之后的要高, 则不升级
if ($level_up && (!$user_agent || $level_up->sort < $user_agent->sort)) {
$user->update([
'agent_id' => $level_up->id,
]);
$user_agent = $level_up;
}
}
return true;
}
/**
* 根据订单, 添加返现记录
*
* @param \App\Models\Order $order
*
* @return \App\Models\OrderProfit
*/
public function storeByOrder(Order $order)
{
$sales_value = $order->sales_value;
$user = $order->user;
$user_agent = $user->agent;
// 上级返利
$parent_ids = array_reverse($user->userInfo->parent_ids);
$parents = User::with(['userInfo', 'agent'])->whereIn('id', $parent_ids)->get();
// 过滤掉 不是代理身份 的用户
// 过滤掉 相同等级 的 后者 用户
// 过滤掉等级 低于 下单用户等级 的用户(sort = 1 为最高)
$exists_list = [];
$filtered = $parents->filter(function ($item) use ($user_agent, &$exists_list) {
if (!$item->agent) {
return false;
}
if (in_array($item->agent->sort, $exists_list)) {
return false;
}
array_push($exists_list, $item->agent->sort);
if ($user_agent) {
return $user_agent->sort > $item->agent->sort;
}
return true;
});
// 生成返利记录
$profit_list = [];
$money_sum = 0;
foreach($filtered->reverse() as $item) {
$agent = $item->agent??'';
if (!$agent) {
continue;
}
$money = floor($sales_value * $agent->ratio) / 100 - $money_sum;
if ($money <= 0) {
continue;
}
array_unshift($profit_list, [
'from_user_id' => $user->id,
'user_id' => $item->id,
'role' => $agent->slug . '-' . $agent->sort,
'role_name' => $agent->name,
'ratio' => $agent->ratio,
'growth_value' => $sales_value,
'money' => $money,
'sub_money' => $money_sum,
]);
$money_sum += $money;
}
// 订单保存返利金额
$order->update([
'profit' => $money_sum
]);
return $order->profits()->createMany($profit_list);
}
/**
* 判断订单是否可以生成返利
*
* @param \App\Models\Order $order
*
* @return boolean
*/
public function canDistribute(Order $order)
{
// 订单已取消, 换货后生成的新订单
if ($order->isCancelled() || $order->is_change) {
return false;
}
// 订单确认收货
if (!$order->isCompleted()) {
return false;
}
// 已经生成过返利记录
if ($order->profits()->exists()) {
return false;
}
// 订单超过售后期限
$value = app_settings('app.sale_after_expire_days');
if ($value && $order->completed_at) {
$diff_day = $order->completed_at->diffInDays();
return $diff_day > $value;
}
return true;
}
/**
* 批量支付
* 使用微信企业付款, 支付返利金额
* 支付的金额必须大于 1, 并且是同一个人的
*/
public function wechatTransfers(Collection $list)
{
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 BizException('用户 '.$userId.' 没有 openid');
}
$result = (new WxpayService())->transfer([
'partner_trade_no' => $sn,
'openid' => $openid,
'check_name' => 'NO_CHECK',
'amount' => $money * 100,
'desc' => '推荐返利',
]);
$this->success($filtered, $result);
}
/**
* 支付成功
*
* @param Collection $list 提成记录
* @param array $result [paid_at, remarks]
*/
public function success(Collection $list, $result = [])
{
OrderProfit::whereIn('id', $list->pluck('id'))->update([
'status' => 2,
'paid_at' => data_get($result, 'paid_at', now()),
'pay_data' => $result,
'remarks' => data_get($result, 'remarks'),
]);
}
}