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) { // 待付款, 同一收款用户, 金额 > 0 if ($item->status === 4 && $item->user_id === $userId && $item->money > 0) { $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'), ]); } }