services->setting->addons->get($mall_id, AgentEnum::ADDONS_NAME, 'basic'); if (empty($setting['is_enable'])) throw new \Exception('没开启渠道分红'); $params['where'] = [['order_id' => $order_id], ['user_id' => $user_id], ['mall_id' => $mall_id]]; $order_detail_list = OrderDetail::lists($params); if (empty($order_detail_list)) throw new \Exception('订单详情不存在'); $parent_id_arr = UserPartitionRelationship::getParentIdArr($user_id); $parent_id_arr = array_reverse($parent_id_arr); $where = ['user_id' => $parent_id_arr, 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED]; $addons_agent_list = Agent::find()->where($where)->indexBy('user_id')->all();//查询经销商列表 $agent_list = []; // 如果中间有非渠道长的那么就直接断掉后面的奖励 foreach ($parent_id_arr as $parent_id) { if (empty($addons_agent_list[$parent_id])) break; $agent_list[] = $addons_agent_list[$parent_id];//按照关系排序 } // 需要判断是否为复购 - 只有复购的情况下才会有 // 非复购情况下那么就给上级 $enable_repurchase_reward = (int) $setting['enable_repurchase_reward']; $agent = Agent::findOne(['user_id' => $user_id, 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED]);// 查询购买者身份 if ($enable_repurchase_reward) { $enable_repurchase_reward = Order::find() ->where(['mall_id' => $mall_id]) ->andWhere(['user_id' => $user_id]) ->andWhere(['<>', 'id', $order_id]) ->andWhere(['pay_status' => StatusEnum::ENABLED]) ->count(); } // 如果本人是渠道长且有开启复购且当前订单是复购订单那么当前用户就拿第一代奖励 // if ($enable_repurchase_reward == StatusEnum::ENABLED && !empty($agent)) { // array_unshift($agent_list, $agent); // } $wallet_insert = []; // 如果没有代理商,那么就不做分佣处理 if (!empty($agent_list)) { $is_frozen = $setting['compute_type'] == ComputingEnum::ORDER_FINISH; foreach ($order_detail_list as $order_detail) { $distribution_settings = AgentDistributionSetting::find() ->where(['mall_id' => $mall_id]) ->andWhere(['item_id' => $order_detail['goods_id']]) ->andWhere(['status' => StatusEnum::ENABLED]) ->select('value') ->column(); // 判断配置了没 if (empty($distribution_settings)) continue; if($order_detail['is_virtual'] == StatusEnum::ENABLED){ //虚拟商品,支付后-直接订单完成,所以直接结算 $is_frozen = false; } $tmp_agent_list = $agent_list; $tmp_enable_repurchase_reward = $enable_repurchase_reward; if (!empty($agent)) { // 独立设置 if (AgentGoodsRepurchase::isAloneSetting($mall_id, $order_detail['goods_id'])) { // 判断当前用户是否买过, 如果当前用户没有买过当前商品那么就将自己剔除 $tmp_enable_repurchase_reward = AgentGoodsRepurchase::isBuyCurrentGoods($mall_id, $user_id, $order_id, $order_detail['goods_id']) ? StatusEnum::ENABLED : StatusEnum::DISABLED; } if ($tmp_enable_repurchase_reward == StatusEnum::ENABLED) { array_unshift($tmp_agent_list, $agent); // 将自己排在第一位 } } foreach ($distribution_settings as $distribution_setting) { $distribution_setting = Json::decode($distribution_setting); // 判断启用了没 - 如果有启用单独设置 那么也是可以执行的 if (empty($distribution_setting['enable_repurchase_reward'])) continue; if (empty($distribution_setting['item_type']) || $distribution_setting['item_type'] != 'goods') continue; // 判断层级及分佣方式 $rewards = $this->execReward($order_detail, $distribution_setting, $tmp_agent_list, $order['order_no'], $setting, $is_frozen); if (!empty($rewards)) { array_push($wallet_insert, ...$rewards); } } } if (!empty($wallet_insert)) { $res = UserWalletService::batchHandleByQueue($wallet_insert); if (empty($res)) { throw new \Exception(UserWalletService::getStaticError()); } // 累加数据 foreach ($wallet_insert as $user) { $agent = Agent::findOne(['user_id' => $user['user_id'], 'status'=>[StatusEnum::DISABLED, StatusEnum::ENABLED], 'mall_id' => $user['mall_id']]); if(empty($agent)) continue; $field = 'total_' . $user['wallet_type']; $agent->$field += $user['money']; if (!$agent->save()) throw new \Exception(Agent::getStaticError()); } } } } catch (\Exception $e) { \Yii::error(FormatHelper::exception($e, __CLASS__ . "->" . __METHOD__)); } return true; } /** * @param array $orderDetail * @param array $config * @param array $parentIds * @param string $order_no * @param array $setting * @param bool $is_frozen * @return array */ protected function execReward(array $orderDetail, array $config, array $parentIds, string $order_no, array $setting, bool $is_frozen) { $insert_wallet = []; // 遍历所有上级 foreach ($parentIds as $key => $agent) { // 控制在范围内 if ($config['distribution_level_max'] < $key+1) break; $reward_amount = 0; // 需要判断是否独立设置 - 独立设置后 最终奖励那么就按独立设置的来处理 switch ($key) { case 0: if ($config['distribution_level1'] > 0) { $reward_amount = $config['distribution_level1']; // 固定金额 if ($config['distribution_type'] == 0) { // 百分比 switch ($setting['computing_method']) { case 0: // 支付价格 $reward_amount = $this->calcByPayAmount($orderDetail['goods_price'], $config['distribution_level1'] * 0.01); break; case 1: // 商品售价 $reward_amount = $this->calcByGoodsSalePrice($orderDetail['price'], $orderDetail['num'], $config['distribution_level1'] * 0.01); break; case 2: // 商品利润 $reward_amount = $this->calcByGoodsProfit($orderDetail['price'], $orderDetail['cost_price'], $orderDetail['num'], $config['distribution_level1'] * 0.01); break; } } } break; case 1: if ($config['distribution_level2'] > 0 && $config['distribution_level_max'] > 1) { $reward_amount = $config['distribution_level2']; // 固定金额 if ($config['distribution_type'] == 0) { // 百分比 switch ($setting['computing_method']) { case 0: // 支付价格 $reward_amount = $this->calcByPayAmount($orderDetail['goods_price'], $config['distribution_level2'] * 0.01); break; case 1: // 商品售价 $reward_amount = $this->calcByGoodsSalePrice($orderDetail['price'], $orderDetail['num'], $config['distribution_level2'] * 0.01); break; case 2: // 商品利润 $reward_amount = $this->calcByGoodsProfit($orderDetail['price'], $orderDetail['cost_price'], $orderDetail['num'], $config['distribution_level2'] * 0.01); break; } } } break; default: // 必须保持在指定层级内 if ($config['distribution_level3'] > 0 && $config['distribution_level_max'] > 2) { $reward_amount = $config['distribution_level3']; // 固定金额 if ($config['distribution_type'] == 0) { // 百分比 switch ($setting['computing_method']) { case 0: // 支付价格 $reward_amount = $this->calcByPayAmount($orderDetail['goods_price'], $config['distribution_level3'] * 0.01); break; case 1: // 商品售价 $reward_amount = $this->calcByGoodsSalePrice($orderDetail['price'], $orderDetail['num'], $config['distribution_level3'] * 0.01); break; case 2: // 商品利润 $reward_amount = $this->calcByGoodsProfit($orderDetail['price'], $orderDetail['cost_price'], $orderDetail['num'], $config['distribution_level3'] * 0.01); break; } } } } if ($reward_amount > 0) { // ComputingEnum::AGENT_DISTRIBUTION_PREFIX . ($key + 1) $capital_type = ComputingEnum::AGENT_DISTRIBUTION_REWARD; $insert_wallet[] = $this->pack($agent->user_id, $orderDetail, $config['commission_type'], $reward_amount, $capital_type, $order_no, ComputingEnum::AGENT_DISTRIBUTION_REWARD_TXT, $is_frozen); } } return $insert_wallet; } /** * @param int $user_id * @param array $orderDetail * @param string $commission_type * @param string $amount * @param string $capital_type * @param string $order_no * @param string $reward_type * @param bool $is_frozen * @return array */ protected function pack(int $user_id, array $orderDetail, string $commission_type, string $amount, string $capital_type, string $order_no, string $reward_type, bool $is_frozen) { // 获取奖励名称 $commission_name = \Yii::$app->services->setting->mall->get($orderDetail['mall_id'], "{$commission_type}.{$commission_type}_name"); if (empty($commission_name)) { switch ($commission_type) { case UserWalletService::WALLET_TYPE_COMMISSION: $commission_name = '佣金'; break; default: $commission_name = ''; } } $desc = "用户($user_id),获得订单({$orderDetail['order_id']})奖励,奖励类型: $reward_type, 奖励: $amount $commission_name"; return [ 'mall_id' => $orderDetail['mall_id'], 'user_id' => $user_id, 'is_frozen' => $is_frozen, 'wallet_type' => $commission_type, 'money' => $amount, 'desc' => $desc, 'source_table' => 'order_detail', 'source_table_id' => $orderDetail['id'], // 取出订单ID? 'from_type' => AgentEnum::ADDONS_NAME, 'capital_type' => $capital_type, 'order_no' => $order_no, // 这里需要订单号 'contributor_name' => $orderDetail['goods_name'], 'contributor_id' => $orderDetail['user_id'], 'contributor_money' => $orderDetail['goods_price'], ]; } /** * @param $goods_price * @param $cardinality * @return string */ protected function calcByPayAmount($goods_price, $cardinality) { return bcmul($goods_price, $cardinality, 2); } /** * @param $goods_price * @param $num * @param $cardinality * @return string */ protected function calcByGoodsSalePrice($goods_price, $num, $cardinality) { return bcmul(bcmul($goods_price, $num, 2), $cardinality, 2); } /** * @param $goods_price * @param $goods_const_price * @param $num * @param $cardinality * @return string */ protected function calcByGoodsProfit($goods_price, $goods_const_price, $num, $cardinality) { return bcmul(bcmul(bcsub($goods_price, $goods_const_price, 2), $num, 2), $cardinality, 2); } protected function traitUnshiftAgentList(int $enable_repurchase_reward, array $agent_list, array $orders, Agent $agent) { } }