canDistribute($order)) { return false; } // 订单成长值 $sales_value = $order->sales_value; $user = $order->user; $userAgent = $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 (!$userAgent || $userAgent->type !== Agent::TYPE_AGENT) { // 自动升级代理 $levels = Agent::where('slug', Agent::TYPE_FAVOITE)->orderBy('sort')->get(); $levelUp = ''; foreach($levels->reverse() as $item) { if ($user->userInfo->growth_value >= $item->growth_value) { $levelUp = $item; } } // 如果当前等级, 比升级之后的要高, 则不升级 if ($levelUp && (!$userAgent || $levelUp->sort < $userAgent->sort)) { $user->update([ 'agent_id' => $levelUp->id, ]); $userAgent = $levelUp; } } return true; } /** * 根据订单, 添加返现记录 * * @param Order $order * * @return \Illuminate\Database\Eloquent\Collection */ public function storeByOrder(Order $order) { $sales_value = $order->sales_value; $user = $order->user; // 上级返利 $parentIds = array_reverse($user->userInfo->parent_ids); // 按照推荐的顺序, 第一位是直属推荐人 $parents = User::with(['userInfo', 'agent'])->whereIn('id', $parentIds)->get()->sortBy(fn($item) => array_search($item->id, $parentIds)); // 过滤掉 不是代理身份 的用户 // 过滤掉 相同等级 的 后者 用户 // 过滤掉等级 低于 上一个分钱 的用户(sort = 1 为最高级, slug 要相同) $existsList = []; $lastAgent = null; $filtered = collect(); foreach($parents as $item) { if (!$item->agent) { continue; } if (in_array($item->agent->sort, $existsList)) { continue; } if ($lastAgent && $item->agent->sort > $lastAgent->sort && $item->agent->slug === $lastAgent->slug) { continue; } $lastAgent = $item->agent; array_push($existsList, $item->agent->sort); $filtered->push($item); } // 生成返利记录 $profit_list = []; $money_sum = 0; foreach($filtered 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; } // 订单超过售后期限 $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, 代理等级: Agent::TYPE_FAVOITE if ($item->status === 4 && $item->user_id === $userId && $item->money > 0 && $item->isRole(Agent::TYPE_FAVOITE) ) { $item->update([ 'status' => 1, 'pay_no' => $sn ]); $money += $item->money; if ($money > 200) { break; } $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); } /** * 微信分账 * * @return void */ public function wechatShare(Order $order) { $receivers = []; $sn = serial_number(); $list = $order->profits; foreach ($list as $item) { $openid = SocialiteUser::where('socialite_type', SocialiteType::WechatMiniProgram->value)->where('user_id', $item->user_id)->value('socialite_id'); if (!$openid) { throw new BizException('用户 '.$item->user_id.' 没有 openid'); } $item->update(['pay_way' => PayWay::WxPayShare, 'pay_no' => $sn, 'status' => 1]); array_push($receivers, [ "type" => "PERSONAL_SUB_OPENID", "account" => $openid, "amount" => $item->money * 100, "description" => "推荐返利" ]); } $result = (new WxpayService())->share($order->out_trade_no, $sn, $receivers); $attributes = ['share_sn' => $sn, 'status' => 'N']; $order->update(['wx_share' => $order->wx_share ? array_merge($order->wx_share, $attributes) : $attributes]); $status = data_get($result, 'status'); if ($status == 'FINISHED') { $this->success($list, $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'), ]); } }