buyer = new Agent($item['user_id']); $this->item = $item; $this->_config = new Config(); } public function checkAndSetCommission() { if (!$this->item || !$this->buyer->user) { return false; } $this->goods = new Goods($this->item['goods_id'], $this->item['goods_sku_price_id']); if (!$this->goods->commissionGoods) { return false; } if ($this->goods->getCommissionConfig()) { $this->_config->setConfig($this->goods->getCommissionConfig()); } $this->commissionLevel = $this->_config->getCommissionLevel(); if (self::COMMISSION_CLOSE === $this->commissionLevel) { return false; } $this->selfBuy = $this->buyer->isAgentAvaliable() && $this->_config->isSelfBuy(); $hasParentOrSelfBuy = $this->buyer->getParentAgentId() || $this->selfBuy; $hasChainCommission = $this->_config->isChainCommissionEnable() && $this->goods->getCommissionRules() && $hasParentOrSelfBuy; $hasTierCommission = ($this->_config->isDifferentialCommissionEnable() && $this->goods->isDifferentialEnable()) || ($this->_config->isManagementAwardEnable() && $this->goods->isManagementEnable()); $hasTierCommission = $hasTierCommission && $hasParentOrSelfBuy; // 复购已在下单付款时直接减免,分销佣金奖池中不再发放买家本人复购返现 $hasRepurchaseSelf = false; if (!$hasChainCommission && !$hasTierCommission && !$hasRepurchaseSelf) { return false; } $this->amount = $this->getGoodsCommissionAmount(); if ($this->amount <= 0) { return false; } return true; } public function getGoodsCommissionAmount() { $commissionType = $this->_config->getCommissionPriceType(); $amount = round(0, 2); switch ($commissionType) { case 'pay_price': $amount = $this->item['pay_price']; break; case 'goods_price': $amount = round($this->item['goods_price'] * $this->item['goods_num'], 2); break; } return $amount; } public function addCommissionOrder() { $commissionOrder = OrderModel::where('order_item_id', $this->item['id'])->find(); if ($commissionOrder) { return $commissionOrder; } $agentId = $this->selfBuy ? $this->buyer->user->id : ($this->buyer->getParentAgentId() ?: $this->buyer->user->id); $commissionOrderParams = [ 'self_buy' => intval($this->selfBuy), 'order_id' => $this->item['order_id'], 'order_item_id' => $this->item['id'], 'buyer_id' => $this->buyer->user->id, 'goods_id' => $this->item['goods_id'], 'agent_id' => $agentId, 'amount' => $this->amount, 'commission_price_type' => $this->_config->getCommissionPriceType(), 'commission_rules' => json_encode([ 'rules' => $this->goods->getCommissionRules(), 'differential_enable' => $this->goods->isDifferentialEnable() ? 1 : 0, 'management_enable' => $this->goods->isManagementEnable() ? 1 : 0, 'repurchase_enable' => $this->goods->isRepurchaseEnable() ? 1 : 0, ]), 'commission_event' => $this->_config->getCommissionEvent(), 'commission_order_status' => $this->goods->commissionGoods->commission_order_status, ]; $commissionOrder = OrderModel::create($commissionOrderParams); $orderAgent = new Agent($commissionOrder->agent_id); if ($orderAgent->isAgentAvaliable() && $commissionOrder->commission_order_status) { $orderAgent->agent->setInc('order_money', $commissionOrder->amount); $orderAgent->agent->setInc('order_count', 1); Log::write($commissionOrder['agent_id'], 'order', [ 'action' => 'payed', 'order' => $commissionOrder, 'order_item' => $this->item, 'buyer' => $this->buyer->user ], ['oper_type' => 'user', 'oper_id' => $this->buyer->user->id]); $orderAgent->agent->save(); } return $commissionOrder; } /** * 执行分销计划:关系链、级差、管理奖可同时发放 */ public function runCommissionPlan($commissionOrder, $currentAgent = null, $currentCommissionLevel = 1) { $skipReferrer = $this->isRepurchase() && !$this->_config->isRepurchaseReferrerEnable(); if (!$skipReferrer) { if ($this->_config->isChainCommissionEnable() && $this->goods->getCommissionRules()) { $this->runChainCommissionPlan($commissionOrder, $currentAgent, $currentCommissionLevel); } if ($this->_config->isDifferentialCommissionEnable() && $this->goods->isDifferentialEnable()) { $this->runDifferentialCommissionPlan($commissionOrder); } if ($this->_config->isManagementAwardEnable() && $this->goods->isManagementEnable()) { $this->runManagementAwardPlan($commissionOrder); } } $this->runRepurchaseRewards($commissionOrder); } protected function runChainCommissionPlan($commissionOrder, $currentAgent = null, $currentCommissionLevel = 1) { if ($this->commissionLevel < $currentCommissionLevel) { return true; } if ($currentCommissionLevel === 1) { $currentAgent = new Agent($commissionOrder->agent_id); } if ($currentAgent && !empty($currentAgent->user)) { $commissionReward = RewardModel::get([ 'commission_order_id' => $commissionOrder->id, 'agent_id' => $currentAgent->user->id, 'commission_level' => $currentCommissionLevel, ]); if (!$commissionReward) { $currentAgentLevel = $currentAgent->getAgentLevel(); $currentCommissionLevelRule = $this->goods->getCommissionLevelRule($currentAgentLevel, $currentCommissionLevel); if ($currentCommissionLevelRule) { // repurchase_rate 已废弃:级差模式下无效;一级佣金为 0 时也不应再发关系链推广佣金 if ( $currentCommissionLevel === 1 && $this->isRepurchase() && $this->_config->isRepurchaseEnable() && !$this->_config->isDifferentialMode() ) { $baseRate = floatval($currentCommissionLevelRule['rate'] ?? 0); if ($baseRate > 0) { $repurchaseRate = $this->_config->getRepurchaseRate(); if ($repurchaseRate > 0) { $currentCommissionLevelRule = ['rate' => $repurchaseRate]; } } } $commission = $this->goods->caculateGoodsCommission($currentCommissionLevelRule, $this->amount, $this->item['goods_num']); if ($commission > 0) { $this->createCommissionReward($commissionOrder, $currentAgent, $currentCommissionLevel, $commission, $currentCommissionLevelRule, $currentAgentLevel, 'chain'); } } } $currentCommissionLevel++; if ($this->commissionLevel < $currentCommissionLevel) { return true; } $parentAgentId = $currentAgent->getParentAgentId(); if ($parentAgentId) { $parentAgent = new Agent($parentAgentId); $this->runChainCommissionPlan($commissionOrder, $parentAgent, $currentCommissionLevel); } } } protected function runDifferentialCommissionPlan($commissionOrder) { $chain = $this->getAgentChain($commissionOrder); if (!$chain) { return; } $isSelfBuy = intval($commissionOrder->self_buy) === 1; $buyerId = intval($commissionOrder->buyer_id); $prevTier = 0; if ($isSelfBuy) { $buyerAgent = new Agent($buyerId); if ($buyerAgent->isAgentAvaliable()) { $prevTier = $this->getTierAmount($buyerAgent->getAgentLevel()); } } foreach ($chain as $item) { $currentAgent = $item['agent']; $commissionLevel = $item['level']; if ($isSelfBuy && intval($currentAgent->user->id) === $buyerId) { continue; } $currentAgentLevel = $currentAgent->getAgentLevel(); $tier = $this->getTierAmount($currentAgentLevel); $payout = round(max(0, $tier - $prevTier), 2); $prevTier = max($prevTier, $tier); if ($payout > 0) { $rule = [ 'award_type' => 'differential', 'differential_amount' => $tier, 'payout' => $payout, ]; $this->createCommissionReward($commissionOrder, $currentAgent, $commissionLevel, $payout, $rule, $currentAgentLevel, 'differential'); } } } protected function runManagementAwardPlan($commissionOrder) { $chain = $this->getAgentChain($commissionOrder); if (!$chain) { return; } $isSelfBuy = intval($commissionOrder->self_buy) === 1; $buyerId = intval($commissionOrder->buyer_id); if ($isSelfBuy) { $buyerInChain = false; foreach ($chain as $item) { if (intval($item['agent']->user->id) === $buyerId) { $buyerInChain = true; break; } } if (!$buyerInChain) { $buyerAgent = new Agent($buyerId); if ($buyerAgent->isAgentAvaliable()) { array_unshift($chain, ['agent' => $buyerAgent, 'level' => 0]); } } } foreach ($chain as $item) { $currentAgent = $item['agent']; $commissionLevel = $item['level'] ?: 1; $currentAgentLevel = $currentAgent->getAgentLevel(); $rate = $this->getManagementRate($currentAgentLevel); if ($rate <= 0) { continue; } $commission = round($this->amount * $rate * 0.01, 2); if ($commission > 0) { $rule = [ 'award_type' => 'management', 'management_rate' => $rate, ]; $this->createCommissionReward($commissionOrder, $currentAgent, $commissionLevel, $commission, $rule, $currentAgentLevel, 'management'); } } } protected function getAgentChain($commissionOrder) { $chain = []; $depth = 1; $agent = new Agent($commissionOrder->agent_id); while ($agent && $agent->user && $depth <= $this->commissionLevel) { if ($agent->isAgentAvaliable()) { $chain[] = ['agent' => $agent, 'level' => $depth]; } $parentId = $agent->getParentAgentId(); if (!$parentId) { break; } $agent = new Agent($parentId); $depth++; } return $chain; } protected function getTierAmount($agentLevel) { $rules = $this->getAgentLevelRules($agentLevel); return floatval($rules['differential_amount'] ?? 0); } protected function getManagementRate($agentLevel) { $rules = $this->getAgentLevelRules($agentLevel); return floatval($rules['management_rate'] ?? 0); } protected function getAgentLevelRules($agentLevel) { if (!isset($this->agentLevelRulesCache[$agentLevel])) { $level = LevelModel::where('level', $agentLevel)->find(); $rules = $level ? ($level->commission_rules ?? []) : []; $this->agentLevelRulesCache[$agentLevel] = is_array($rules) ? $rules : []; } return $this->agentLevelRulesCache[$agentLevel]; } protected function runRepurchaseRewards($commissionOrder) { // 复购优惠已在商品下单付款时直接立减,此处不再发放买家本人复购返现佣金 return; } protected function isRepurchase() { $goodsId = $this->item['goods_id'] ?? 0; $userId = $this->buyer->user->id ?? 0; if (!$goodsId || !$userId) { return false; } $count = \addons\shopro\model\OrderItem::alias('oi') ->join('shopro_order o', 'o.id = oi.order_id') ->where('o.user_id', $userId) ->where('o.status', 'in', [1, 2]) ->where('oi.goods_id', $goodsId) ->where('o.id', '<', $this->item['order_id']) ->where('oi.refund_status', '<=', 0) ->count(); return $count > 0; } protected function createCommissionReward($commissionOrder, $currentAgent, $commissionLevel, $commission, $rule, $agentLevel, $awardType = 'chain') { if (!is_array($rule)) { $rule = []; } $rule['award_type'] = $awardType; $exists = RewardModel::where('commission_order_id', $commissionOrder->id) ->where('agent_id', $currentAgent->user->id) ->where('commission_level', $commissionLevel) ->select(); foreach ($exists as $item) { $existRules = json_decode($item->commission_rules, true); if (($existRules['award_type'] ?? 'chain') === $awardType) { return; } } $commissionReward = RewardModel::create([ 'order_id' => $commissionOrder->order_id, 'order_item_id' => $commissionOrder->order_item_id, 'buyer_id' => $commissionOrder->buyer_id, 'commission_order_id' => $commissionOrder->id, 'agent_id' => $currentAgent->user->id, 'type' => 'money', 'commission' => $commission, 'status' => 0, 'original_commission' => $commission, 'commission_level' => $commissionLevel, 'commission_rules' => json_encode($rule), 'agent_level' => $agentLevel, ]); Log::write($commissionReward['agent_id'], 'reward', [ 'action' => 'payed', 'reward' => $commissionReward, ], ['oper_type' => 'user', 'oper_id' => $commissionOrder->buyer_id]); } }