db->beginTransaction(); try { // 获取订单内容 $where = ['id' => $order_id]; $order = Order::find()->select("id,user_id,mall_id,order_no,pay_time") ->where($where) ->with(['detail' => function($query){ $query->select("id, order_id,goods_id,num,goods_price,goods_name,price,pic_url"); }]) ->asArray()->one(); if(empty($order)) throw new Exception("订单不存在"); $mall_id = $order['mall_id']; $user_id = $order['user_id']; // 获取推三返一基础配置内容 $settingService = new SettingService(['mall_id' => $mall_id]); $config = $settingService->getSetting(); $settlement_method = $config['settlement_method']; $addons_name = $config['addons_name']; // 获取推三返一的商品 $rebate_list = Rebate::getRebateAllGoodsId($mall_id); $goods_arr = []; foreach ($rebate_list as $item) { $goods_arr[$item['item_id']][] = $item; } $order_settlement_status = 0;// 订单结算状态[0:未达成;1:已达成] if($settlement_method == $settlement_type) $order_settlement_status = 1; $reward_commission = []; $unfozenRebateBuys = []; foreach($order['detail'] as $order_detail) { // 检查该商品是否参与了推三返一活动 if(!isset($goods_arr[$order_detail['goods_id']])) continue; foreach ($goods_arr[$order_detail['goods_id']] as $rebate) { // 获取消费者的直推上级 $parent_id = User::find()->select('parent_id')->where(['id' => $user_id, 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED])->asArray()->scalar(); if(empty($parent_id)) { continue; } if(empty($rebate['join_type'])){ // 判断上级是否有权限 if($rebate['initiate_type'] == RebateEnum::INITIATE_TYPE_NEW && Rebate::checkUserHasOrder($mall_id, $parent_id) !== false) { continue; } if($rebate['initiate_type'] == RebateEnum::INITIATE_TYPE_LEVEL && Rebate::checkUserLevel($parent_id, $rebate['initiate_level']) == false) { continue; } // 判断消费者是否符合权限 if($rebate['consume_type'] == RebateEnum::CONSUME_TYPE_NEW) { $order_num = Rebate::checkUserHasOrder($mall_id, $user_id); if (!empty($order_num) && $order_num > 1) { continue; } } if($rebate['consume_type'] == RebateEnum::CONSUME_TYPE_LEVEL && Rebate::checkUserLevel($user_id, $rebate['consume_level']) == false) { continue; } }else{ // 判断上级是否有权限 if($rebate['initiate_type'] == RebateEnum::INITIATE_TYPE_NEW && Rebate::checkNewRegisterUser($mall_id, $parent_id) == false) { continue; } if($rebate['initiate_type'] == RebateEnum::INITIATE_TYPE_LEVEL && Rebate::checkRebateUserLevel($parent_id, $rebate['initiate_level']) == false) { continue; } // 判断消费者是否符合权限 if($rebate['consume_type'] == RebateEnum::CONSUME_TYPE_NEW && Rebate::checkNewRegisterUser($mall_id, $user_id)==false) { continue; } if($rebate['consume_type'] == RebateEnum::CONSUME_TYPE_LEVEL && Rebate::checkRebateUserLevel($user_id, $rebate['consume_level']) == false) { continue; } } // 初始化参与活动 $res = RebateRecommendNum::initRecommendNum($mall_id, ['r_id' => $rebate['id'], 'user_id' => $parent_id]); if ($res === false) throw new \Exception(RebateRecommendNum::getStaticError()); // 检测购买此商品是否有使用优惠或抵扣(随机减不算) if (!empty($rebate['is_grant']) && ($order_detail['price'] * $order_detail['num']) != $order_detail['goods_price']) continue; // 保存消费者数据 $rabate_buy = self::saveRebateBuy($mall_id, $rebate['id'], $user_id, $parent_id, $order, $order_detail, $order_settlement_status); if ($rabate_buy && $rabate_buy['is_settlement'] == 1) {// 如果此订单已经结算过则不再触发 continue; } if($settlement_method != $settlement_type) { continue; } // 获取未结算的ids $rebate_buy_ids = RebateBuy::getNoSettlementList($mall_id, $rebate['id'], $parent_id); // 奖励的内容 $rebate_info = Json::decode($rebate['reward_info'], true); // 获取用户上级已有的订单数 $recommend_num = RebateRecommendNum::setData($mall_id, ['r_id' => $rebate['id'], 'user_id' => $parent_id, 'pay_num' => 1]); // 活动统计 RebateStatistics::setData($mall_id, ['r_id' => $rebate['id'], 'pay_money' => $order_detail['goods_price']]); // 判断奖励方式 $reward_title = $content = ''; if($rebate['reward_type'] == RebateEnum::REWARD_TYPE_COND) {// 条件奖励 if($recommend_num['pay_num'] % $rebate_info[0]['num'] == 0) {// 取余=0则代表可的奖励 $reward_title = "每推荐" . $rebate_info[0]['num']. "人购买"; $content = self::giveParentReward($mall_id, $rebate_info[0]['data'], $parent_id, $order_id, $order_detail['id'], $addons_name,$reward_commission); $reward_key = 0; } } else { // 阶梯奖励 if (empty($rebate['is_repeat'])) { foreach($rebate_info as $k => $item){ if($item['num'] == $recommend_num['pay_num']) { $reward_title = "推荐" . $item['num']. "人购买"; $is_frozen = $k === 0 && $rebate['is_freeze_first_reward'] ? RebateEnum::FROZEN : RebateEnum::NOT_FROZEN; $content = self::giveParentReward($mall_id, $item['data'], $parent_id, $order_id, $order_detail['id'], $addons_name,$reward_commission, $is_frozen, $rebate); $reward_key = $k; break; } } } else { // 重复发奖处理 $last_value = $rebate_info[count($rebate_info) - 1]['num'];// 获取数组中最后一个的数值 $multiple = empty($recommend_num['pay_num']) ? 0 : ceil($recommend_num['pay_num'] / $last_value) - 1;// 向上取整再减1,获取倍数 // 设置循环奖励,从第二轮开始 if ($recommend_num['pay_num'] > $last_value && !empty($rebate['is_reward_after_n']) && !empty($rebate['reward_threshold'])) { if (!is_numeric($offset = array_search($rebate['reward_threshold'], array_column($rebate_info, 'num')))) { continue; } // 得到 $rebate['reward_threshold'] 的奖励 $rebate_info_by_threshold = array_slice($rebate_info, $offset); if (empty($rebate_info_by_threshold)) { continue; } $rebate_info_by_threshold_count = count($rebate_info_by_threshold); $rewardIndex = (($recommend_num['pay_num'] - $last_value) % $rebate_info_by_threshold_count) - 1; $rewardIndex < 0 && $rewardIndex = $rebate_info_by_threshold_count - 1; $item = $rebate_info_by_threshold[$rewardIndex]; $reward_title = "推荐" . $recommend_num['pay_num']. "人购买"; $content = self::giveParentReward($mall_id, $item['data'], $parent_id, $order_id, $order_detail['id'], $addons_name,$reward_commission); $reward_key = $offset + $rewardIndex; // 在$rebate_info数组的key $isRepeat = true; // 标识这是循环奖励 } else { foreach($rebate_info as $k => $item) { $item['num'] = $item['num'] + $last_value * $multiple;// 奖励个数计算=阶梯个数 + 最后数值 * 向下取整倍数 if($item['num'] == $recommend_num['pay_num']) { $is_frozen = $k === 0 && $rebate['is_freeze_first_reward'] ? RebateEnum::FROZEN : RebateEnum::NOT_FROZEN; $reward_title = "推荐" . $item['num']. "人购买"; $content = self::giveParentReward($mall_id, $item['data'], $parent_id, $order_id, $order_detail['id'], $addons_name,$reward_commission, $is_frozen, $rebate); $item['num'] = $rebate_info[$k]['num']; $reward_key = $k; break; } } } } // 如果当前获取第二项奖励,并且第一项是冻结的,需要解冻第一项 if (isset($reward_key) && $reward_key == 1 && !isset($isRepeat)) { $unfozenRebateBuys[] = $rabate_buy; } } if($content) { // 保存数据时的配置 $setting = [ 'title' => $rebate['title'], 'item_id' => $rebate['id'], 'settlement_method' => $settlement_method, 'reward_type' => $rebate['reward_type'], 'reward_info' => $rebate_info, 'log_ids' => implode(',', $rebate_buy_ids), 'reward_key' => $reward_key ?? -1, 'order_detail_id' => $order_detail['id'], 'freeze_first_reward_type' => $rebate['freeze_first_reward_type'], 'freeze_first_reward_percentage' => $rebate['freeze_first_reward_percentage'] ]; // 保存奖励数据 $log = [ 'r_id' => $rebate['id'], 'user_id' => $parent_id, 'reward_title' => $reward_title, 'content' => $content, 'setting' => Json::encode($setting), 'is_frozen' => $is_frozen ?? RebateEnum::NOT_FROZEN, ]; $reward = RebateRewardLog::setData($mall_id, $log); if($reward == false) throw new Exception(RebateRewardLog::getStaticError()); // 将购买记录改为已结算 RebateBuy::updateAll(['is_reward_trigger' => 1, 'updated_at' => time()], ['id' => $rabate_buy['id'], 'order_settlement_status' => 1]); RebateBuy::updateAll(['is_settlement' => 1, 'reward_id' => $reward['id'], 'updated_at' => time()], ['id' => $rebate_buy_ids, 'order_settlement_status' => 1]); } } } self::unfrozenFirstReward2Queue($unfozenRebateBuys); $t->commit(); LevelUpLogic::execute($order,$settlement_type); // 推三返一订单完成-触发的奖励 if ($settlement_type==2 && MallAddons::isInstall($order['mall_id'], 'BonusPool')) { $handle_class = \addons\BonusPool\common\listeners\order\OrderComputeCommissionListener::class; $data = [ 'rebate_commission_reward_arr' => $reward_commission, 'order_id' => $order_id, ]; \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_ORDER, RabbitMqEnum::ORDER_QUEUE, $data, $handle_class, 'handleSync'); } return true; } catch (Exception $e) { $t->rollBack(); self::setStaticError($e->getMessage()); return false; } } /** * 保存购买者信息 * @Author: lun * @DateTime: 2022/1/15 0015 9:47 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $mall_id * @param $r_id * @param $user_id * @param $parent_id * @param $order * @param $order_detail * @param $order_settlement_status * @return array| bool */ private static function saveRebateBuy($mall_id, $r_id, $user_id, $parent_id, $order, $order_detail, $order_settlement_status = 0, $is_virtual = 0, $is_settlement = 0) { $params = [ 'mall_id' => $mall_id, 'r_id' => $r_id, 'pid' => $parent_id, 'order_no' => $order['order_no'], 'pay_at' => $order['pay_time'], 'pay_money' => $order_detail['goods_price'], 'goods_info' => Json::encode([ 'id' => $order_detail['goods_id'], 'goods_name' => $order_detail['goods_name'], 'cover_pic' => $order_detail['pic_url'], 'price' => $order_detail['price'], ]), 'user_id' => $user_id, 'order_settlement_status' => $order_settlement_status, 'is_virtual' => $is_virtual, 'is_settlement' => $is_settlement, 'order_detail_id' => $order_detail['id'] ]; // 检测是否已经生成过数据 $has_buy = RebateBuy::find()->where(['r_id' => $r_id, 'pid' => $parent_id, 'user_id' => $user_id, 'order_no' => $order['order_no']])->one(); if ($has_buy) { if (empty($has_buy->order_settlement_status) && $order_settlement_status == 1) { $has_buy->order_settlement_status = 1; $has_buy->settlement_at = time(); $has_buy->position = self::getPosition($mall_id, $r_id, $parent_id); if (!$has_buy->save()) throw new Exception($has_buy->getErrorMessage()); } return $has_buy->toArray(); } if ($params['order_settlement_status']) { $params['settlement_at'] = time(); $params['position'] = self::getPosition($mall_id, $r_id, $parent_id); } return RebateBuy::setData($params); } /** * 得到position * * @param int $mallId * @param int $rId * @param int $parentId * * @return int */ public static function getPosition(int $mallId, int $rId, int $parentId): int { $position = RebateBuy::find() ->where([ 'mall_id' => $mallId, 'r_id' => $rId, 'pid' => $parentId, 'order_settlement_status' => StatusEnum::ENABLED ]) ->orderBy('position desc') ->select('position') ->scalar() ?: 0; return ++$position; } /** * 赠送活动奖励 * @Author: lun * @DateTime: 2022/1/15 0015 9:47 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $mall_id * @param $rewards * @param $user_id * @param $order_id * @param string $desc * @param string $rebate 推三返一活动数据 * @return bool|string */ private static function giveParentReward($mall_id, $rewards, $user_id, $order_id, $order_detail_id, $desc = '推三返一',&$reward_commission = [], bool $is_frozen = false, array $rebate = []) { try { $orderInfo = OrderDetail::find()->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'id' => $order_detail_id]) ->select('id, goods_price as pay_money, original_goods_price, cost_price, num') ->asArray()->one(); $reward_text = ""; //判断是否安装红包拓客插件 $has_redpack = MallAddons::isInstall($mall_id, AddonsEnum::ADDONS_NAME_REDPACK); $insert_wallet = []; foreach ($rewards as $item) { // 注意:冻结奖励时,商城资产 积分 佣金 余额 冻结时会转为冻结资产。优惠券奖励则订单完成后再发奖励。积分拓客则发未冻结的,已冻结的订单完成再发送 switch ($item['type']) { case RebateEnum::REWARD_SCORE:// 积分 if ($item['ratio']) { $item['data'] = self::getPercentage($mall_id, $orderInfo, $item); } // 当赠送金额小于等于0,不赠送 if ($item['data'] <= 0) break; $reward_text.= ",积分:" . $item['data']; $walletItem = [ 'mall_id' => $mall_id, 'user_id' => $user_id, 'wallet_type' => $item['type'], 'desc' => $desc . '赠送', 'source_table' => Order::tableName(), 'source_table_id' => $order_id, 'from_type' => AddonsEnum::ADDONS_NAME_REBATE, 'capital_type' => UserWalletEnum::GIVE, ]; self::computeAndInsertWallet($is_frozen, $item['data'], $rebate, $walletItem, $insert_wallet, $reward_text); break; case RebateEnum::REWARD_BALANCE:// 余额 if ($item['ratio']) { $item['data'] = self::getPercentage($mall_id, $orderInfo, $item); } if ($item['data'] <= 0) break; $reward_text.= ",余额:¥" . $item['data']; $walletItem = [ 'mall_id' => $mall_id, 'user_id' => $user_id, 'wallet_type' => $item['type'], 'desc' => $desc . '赠送', 'source_table' => Order::tableName(), 'source_table_id' => $order_id, 'from_type' => AddonsEnum::ADDONS_NAME_REBATE, 'capital_type' => UserWalletEnum::GIVE, ]; self::computeAndInsertWallet($is_frozen, $item['data'], $rebate, $walletItem, $insert_wallet, $reward_text); break; case RebateEnum::REWARD_COMMISSION:// 佣金 if ($item['ratio']) { $item['data'] = self::getPercentage($mall_id, $orderInfo, $item); } if ($item['data'] <= 0) break; $reward_text.= ",佣金:¥" . $item['data']; $walletItem = [ 'mall_id' => $mall_id, 'user_id' => $user_id, 'wallet_type' => $item['type'], 'desc' => $desc . '赠送', 'source_table' => OrderDetail::tableName(), 'source_table_id' => $order_detail_id, 'from_type' => AddonsEnum::ADDONS_NAME_REBATE, 'capital_type' => UserWalletEnum::GIVE, ]; self::computeAndInsertWallet($is_frozen, $item['data'], $rebate, $walletItem, $insert_wallet, $reward_text); if(isset($reward_commission[$order_detail_id])){ $reward_commission[$order_detail_id]['money'] += $item['data']; }else{ $reward_commission[$order_detail_id]['money'] = $item['data']; } break; case RebateEnum::REWARD_COUPON:// 优惠券 // 赠送优惠券 foreach ($item['data'] as $coupon) { $give_coupon_arr[$coupon['relevant_id']] = $coupon['num']; } if (empty($give_coupon_arr)) { break; } if ($is_frozen) { $coupon_arr = AddonsCoupon::find() ->select('name') ->where(['mall_id' => $mall_id, 'id' => array_keys($give_coupon_arr), 'status' => StatusEnum::ENABLED, 'coupon_status' => AddonsCouponEnum::STATUS_RECEIVING]) ->asArray() ->all(); } else { $coupon_arr = AddonsCouponUserRelate::giveCoupon($mall_id, $user_id, $give_coupon_arr, AddonsCouponEnum::SEND_FROM14); } if ($coupon_arr) { foreach ($coupon_arr as $info) { $coupon_text[] = $info['name']; } $reward_text.= ",优惠券:[" . implode(',', $coupon_text) .']'; } break; case RebateEnum::REWARD_REDPACK://激活红包 case RebateEnum::REWARD_FROZEN_REDPACK: //未安装红包拓客插件,则跳出 if (!$has_redpack) break; if ($item['ratio']) { $item['data'] = self::getPercentage($mall_id, $orderInfo, $item); } // 当赠送金额小于等于0,不赠送 if ($item['data'] <= 0) break; ['frozen_money' => $frozen_money, 'money' => $money] = self::computeRewardMoney( $is_frozen, $item['data'], $rebate['freeze_first_reward_type'] ?? RebateEnum::FREEZE_FIRST_REWARD_TYPE_ALL, $rebate['freeze_first_reward_percentage'] ?? 0 ); $redpack_data = [ 'mall_id' => $mall_id, 'user_id' => $user_id, 'is_frozen' => false, 'money' => $money, 'desc' => '订单('.$order_id.')推三返一赠送红包', 'source_table' => OrderDetail::tableName(), 'source_table_id' => $order_detail_id, 'from_type' => \addons\Redpack\common\enums\RedpackEnum::FROM_REBATE_REWARD, ]; if ($item['type'] == 'frozen_redpack') { $reward_text.= ",冻结红包:" . $item['data']; $redpack_data['is_frozen'] = true; } else { $reward_text.= ",激活红包:" . $item['data']; } if ($frozen_money > 0) { $reward_text .= '(冻结 ' . $frozen_money . ')'; } if ($money > 0) { $res = \addons\Redpack\common\models\RedpackWallet::setData($redpack_data); if (!$res) throw new Exception(\addons\Redpack\common\models\RedpackWallet::$static_error); } break; default: break; } } if (!empty($insert_wallet)) { $res = UserWalletService::batchHandleByQueue($insert_wallet); if (empty($res)) throw new \Exception(UserWalletService::getStaticError()); } return ltrim($reward_text, ','); } catch (\Exception $e) { Yii::error("推三返一奖励报错=" . $e->getMessage()); return false; } } /** * 计算冻结奖励和非冻结奖励 * * @return void */ private static function computeRewardMoney(bool $is_frozen, float $rewardMoney, int $freezeFirstRewardType, float $freezeFirstRewardPercentage): array { if ( !$is_frozen || ( $freezeFirstRewardType == RebateEnum::FREEZE_FIRST_REWARD_TYPE_PERCENTAGE && $freezeFirstRewardPercentage <= 0 ) ) { return [ 'frozen_money' => 0, 'money' => $rewardMoney, ]; } // 全部冻结 if ( $freezeFirstRewardType == RebateEnum::FREEZE_FIRST_REWARD_TYPE_ALL || ( $freezeFirstRewardType == RebateEnum::FREEZE_FIRST_REWARD_TYPE_PERCENTAGE && $freezeFirstRewardPercentage >= 100 ) ) { return [ 'frozen_money' => $rewardMoney, 'money' => 0, ]; } // 按百分比冻结 $frozen_money = bcmul($rewardMoney, $freezeFirstRewardPercentage / 100, 2); return [ 'frozen_money' => $frozen_money, 'money' => bcsub($rewardMoney, $frozen_money, 2), ]; } /** * 计算并插入奖励 * * @param bool $is_frozen * @param float $rewardMoney * @param array $rebate * @param array $walletItem * @param array $insert_wallet * @param string $reward_text * * @return void */ private static function computeAndInsertWallet(bool $is_frozen, float $rewardMoney, array $rebate, array $walletItem, array &$insert_wallet, string &$reward_text) { ['frozen_money' => $frozen_money, 'money' => $money] = self::computeRewardMoney( $is_frozen, $rewardMoney, $rebate['freeze_first_reward_type'] ?? RebateEnum::FREEZE_FIRST_REWARD_TYPE_ALL, $rebate['freeze_first_reward_percentage'] ?? 0 ); if ($money > 0) { $insert_wallet[] = array_merge($walletItem, ['is_frozen' => false, 'money' => $money]); } $rewardFlag = in_array($walletItem['wallet_type'], [RebateEnum::REWARD_BALANCE, RebateEnum::REWARD_COMMISSION]) ? '¥' : ''; if ($frozen_money > 0) { $insert_wallet[] = array_merge($walletItem, ['is_frozen' => true, 'money' => $frozen_money]); $reward_text .= '(冻结 ' . $rewardFlag . $frozen_money . ')'; } } /** * 奖励(余额-佣金-积分)百分比计算 * @param $mall_id //商户id * @param $order //商品信息 * @param $item //占比信息 */ public static function getPercentage($mall_id, $order, $item) { $ratio_money = 0; //返回比率计算价格 // 获取配置字段 $settingService = new SettingService(['mall_id' => $mall_id]); $system = $settingService->getSetting()['computing_method']; //计算比率 $ratio = $item['data'] / 100; switch ($system) { case RebateEnum::COMPUTING_METHOD_PAY_PRICE:// 支付价格计算 //计算金额 $ratio_money = bcmul($order['pay_money'], $ratio,2); break; case RebateEnum::COMPUTING_METHOD_GOODS_PRICE:// 商品售价计算 $ratio_money = bcmul($order['original_goods_price'], $ratio, 2); break; case RebateEnum::COMPUTING_METHOD_GOODS_PROFIT:// 商品利润计算 //商品利润=商品支付价格-成本 $profit_money = $order['pay_money'] - ($order['cost_price'] * $order['num']); $ratio_money = bcmul($profit_money, $ratio, 2); break; default: break; } return $ratio_money; } /** * 奖励判断 * @return bool */ public static function checkOrder($order_id,$settlement_type){ // 获取订单内容 $where = ['id' => $order_id]; $order = Order::find()->select("id,user_id,mall_id,order_no,pay_time") ->where($where) ->with(['detail' => function($query){ $query->select("order_id,goods_id,num,goods_price,goods_name,price,pic_url"); }]) ->asArray()->one(); if(empty($order)) return true; $mall_id = $order['mall_id']; $user_id = $order['user_id']; // 获取推三返一基础配置内容 $settingService = new SettingService(['mall_id' => $mall_id]); $config = $settingService->getSetting(); $settlement_method = $config['settlement_method']; //结算状态与订单状态不一致时不判断 if($settlement_method != $settlement_type) { return true; } // 获取消费者的直推上级 $parent_id = User::find()->select('parent_id')->where(['id' => $user_id, 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED])->asArray()->scalar(); if(empty($parent_id)) { return true; } // 获取推三返一的商品 $rebate_list = Rebate::getRebateAllGoodsId($mall_id); if(empty($rebate_list)) return true; // 获取所有商品id $goods_arr = []; foreach ($rebate_list as $item) { $goods_arr[$item['item_id']][] = $item; } $result = true; foreach($order['detail'] as $order_detail) { // 检查该商品是否参与了推三返一活动 if(!isset($goods_arr[$order_detail['goods_id']])) continue; foreach ($goods_arr[$order_detail['goods_id']] as $rebate) { //检查活动是否开启触发奖励设置 if(empty($rebate['repeat_setting']) || empty($rebate['agent_limit_num'])) continue; //条件奖励不判断 if($rebate['reward_type'] == RebateEnum::REWARD_TYPE_COND) continue; if(empty($rebate['join_type'])){ // 判断上级是否有权限 if($rebate['initiate_type'] == RebateEnum::INITIATE_TYPE_NEW && Rebate::checkUserHasOrder($mall_id, $parent_id) !== false) { continue; } if($rebate['initiate_type'] == RebateEnum::INITIATE_TYPE_LEVEL && Rebate::checkUserLevel($parent_id, $rebate['initiate_level']) == false) { continue; } // 判断消费者是否符合权限 if($rebate['consume_type'] == RebateEnum::CONSUME_TYPE_NEW) { $order_num = Rebate::checkUserHasOrder($mall_id, $user_id); if (!empty($order_num) && $order_num > 1) { continue; } } if($rebate['consume_type'] == RebateEnum::CONSUME_TYPE_LEVEL && Rebate::checkUserLevel($user_id, $rebate['consume_level']) == false) { continue; } }else{ // 判断上级是否有权限 if($rebate['initiate_type'] == RebateEnum::INITIATE_TYPE_NEW && Rebate::checkNewRegisterUser($mall_id, $parent_id) == false) { continue; } if($rebate['initiate_type'] == RebateEnum::INITIATE_TYPE_LEVEL && Rebate::checkRebateUserLevel($parent_id, $rebate['initiate_level']) == false) { continue; } // 判断消费者是否符合权限 if($rebate['consume_type'] == RebateEnum::CONSUME_TYPE_NEW && Rebate::checkNewRegisterUser($mall_id, $user_id)==false) { continue; } if($rebate['consume_type'] == RebateEnum::CONSUME_TYPE_LEVEL && Rebate::checkRebateUserLevel($user_id, $rebate['consume_level']) == false) { continue; } } // 奖励的内容 $rebate_info = Json::decode($rebate['reward_info'], true); // 获取用户上级已有的订单数 $recommend_num = RebateRecommendNum::find() ->where(['r_id'=>$rebate['id'],'user_id'=>$parent_id]) ->select('pay_num') ->scalar() ?? 0; //获取当前订单是否已统计 $has_buy = RebateBuy::find()->where(['r_id' => $rebate['id'], 'pid' => $parent_id, 'user_id' => $user_id, 'order_no' => $order['order_no'],'is_settlement'=>1])->one(); if(empty($has_buy)) $recommend_num += 1; //触发奖励判断 if($recommend_num % $rebate['agent_limit_num'] == 0){ $result = false; } } } return $result; } /** * 创建虚拟订单 * * @param $mall_id * @param $user_id * @param $rebate_id * * @return bool */ public static function createVirtualOrder($mall_id, $user_id, $rebate_id) { $parent_id = User::find()->select('parent_id')->where(['id' => $user_id, 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED])->asArray()->scalar(); if (empty($parent_id)) { self::$static_error = '上级用户不存在'; return false; } $t = Yii::$app->db->beginTransaction(); try { // 初始化参与活动 $res = RebateRecommendNum::initRecommendNum($mall_id, ['r_id' => $rebate_id, 'user_id' => $parent_id]); if ($res === false) { throw new \Exception(RebateRecommendNum::getStaticError()); } // 找到参与活动的商品 $goods = Goods::findOne(['id' => Rebate::find()->where(['id' => $rebate_id])->select('item_id')->scalar()]); if (empty($goods)) { throw new \Exception('商品不存在'); } $order_detail = [ 'id' => 0, 'goods_price' => 0, 'goods_id' => $goods->id, 'goods_name' => $goods->goods_name, 'pic_url' => $goods->cover_pic, 'price' => $goods->price, ]; // 保存消费者数据 $rabate_buy = self::saveRebateBuy( $mall_id, $rebate_id, $user_id, $parent_id, ['order_no' => Order::generateOrderNo('s'), 'pay_time' => time()], $order_detail, 1, 1, 1 ); if ($rabate_buy === false) { throw new \Exception(RebateRecommendNum::getStaticError()); } // 增加推荐数量 if (RebateRecommendNum::setData($mall_id, ['r_id' => $rebate_id, 'user_id' => $parent_id, 'pay_num' => 1]) === false) { throw new \Exception(RebateRecommendNum::getStaticError()); } // 活动统计 if (RebateStatistics::setData($mall_id, ['r_id' => $rebate_id, 'pay_money' => 0]) === false) { throw new \Exception(RebateStatistics::getStaticError()); } // 记录手动生成订单 $setRebateVirtualOrderLogRes = RebateVirtualOrderLog::setData($mall_id, [ 'user_id' => $user_id, 'user_parent_id' => $parent_id, 'rebate_id' => $rebate_id, 'rebate_buy_id' => $rabate_buy['id'] ]); if ($setRebateVirtualOrderLogRes === false) { throw new \Exception(RebateVirtualOrderLog::getStaticError()); } $t->commit(); }catch (\Exception $e) { $t->rollBack(); Yii::error(Json::encode([ 'msg' => $e->getMessage(), 'line' => $e->getLine(), 'file' => $e->getFile() ])); self::$static_error = '系统错误'; return false; } return true; } /** * 如果当前获取的奖励是第二项,则检查需要解冻第一项 * * @param array $rebate_buy * * @return void */ public static function unfrozenFirstReward(array $rebate_buy) { $rewardLog = RebateRewardLog::find() ->where([ 'mall_id' => $rebate_buy['mall_id'], 'r_id' => $rebate_buy['r_id'], 'user_id' => $rebate_buy['pid'], 'is_frozen' => RebateEnum::FROZEN, 'status' => StatusEnum::ENABLED, ]) ->one(); if (empty($rewardLog)) { return; } $rebateBuy = RebateBuy::find() ->where([ 'reward_id' => $rewardLog->id, 'status' => StatusEnum::ENABLED, 'mall_id' => $rebate_buy['mall_id'], ]) ->select('reward_id, order_no, order_detail_id') ->asArray() ->one(); if (empty($rebateBuy)) { return; } // 循环需要解冻的类型 $setting = json_decode($rewardLog->setting, true); if (isset($setting['reward_key'], $setting['reward_info'][$setting['reward_key']])) { // 查询订单 $orderId = Order::find() ->where([ 'order_no' => $rebateBuy['order_no'], 'mall_id' => $rewardLog->mall_id, 'status' => StatusEnum::ENABLED ]) ->select('id') ->scalar(); $orderInfo = OrderDetail::find() ->where(['mall_id' => $rewardLog->mall_id, 'status' => StatusEnum::ENABLED, 'id' => $rebateBuy['order_detail_id']]) ->select('id, order_id, goods_price as pay_money, original_goods_price, cost_price, num') ->asArray() ->one(); //判断是否安装红包拓客插件 $has_redpack = MallAddons::isInstall($rewardLog->mall_id, AddonsEnum::ADDONS_NAME_REDPACK); foreach ($setting['reward_info'][$setting['reward_key']]['data'] as $item) { switch ($item['type']) { case RebateEnum::REWARD_SCORE: case RebateEnum::REWARD_BALANCE: case RebateEnum::REWARD_COMMISSION: $wallet_type = $item['type']; CapitalLog::$capitalType = "{$wallet_type}_frozen"; $commission_list = CapitalLog::lists([ 'where' => [ [ 'or', ['source_table' => Order::tableName(), 'source_table_id' => $orderId], ['source_table' => OrderDetail::tableName(), 'source_table_id' => $rebateBuy['order_detail_id']], ], ['from_type' => AddonsEnum::ADDONS_NAME_REBATE], ['capital_type' => UserWalletEnum::GIVE], ['status' => CapitalLog::STATUS_WAIT_SEND] ] ]); foreach ($commission_list as $commission) { UserWalletService::unfrozen($commission['id'], $item['type']); } break; case RebateEnum::REWARD_COUPON: foreach ($item['data'] as $coupon) { $give_coupon_arr[$coupon['relevant_id']] = $coupon['num']; } if (empty($give_coupon_arr)) { break; } AddonsCouponUserRelate::giveCoupon($rewardLog->mall_id, $rewardLog->user_id, $give_coupon_arr, AddonsCouponEnum::SEND_FROM14); break; case RebateEnum::REWARD_REDPACK://激活红包 case RebateEnum::REWARD_FROZEN_REDPACK: //未安装红包拓客插件,则跳出 if (!$has_redpack) break; if ($item['ratio']) { $item['data'] = self::getPercentage($rewardLog->mall_id, $orderInfo, $item); } // 当赠送金额小于等于0,不赠送 if ($item['data'] <= 0) break; ['frozen_money' => $frozen_money] = self::computeRewardMoney( true, $item['data'], $setting['freeze_first_reward_type'] ?? RebateEnum::FREEZE_FIRST_REWARD_TYPE_ALL, $setting['freeze_first_reward_percentage'] ?? 0 ); if ($frozen_money <= 0) { break; } $redpack_data = [ 'mall_id' => $rewardLog->mall_id, 'user_id' => $rewardLog->user_id, 'is_frozen' => false, 'money' => $frozen_money, 'desc' => '订单('.$orderInfo['order_id'].')推三返一赠送红包', 'source_table' => OrderDetail::tableName(), 'source_table_id' => $orderInfo['id'], 'from_type' => \addons\Redpack\common\enums\RedpackEnum::FROM_REBATE_REWARD, ]; if ($item['type'] == 'frozen_redpack') { $redpack_data['is_frozen'] = true; } $res = \addons\Redpack\common\models\RedpackWallet::setData($redpack_data); if (!$res) throw new Exception(\addons\Redpack\common\models\RedpackWallet::$static_error); break; } } } $rewardLog->is_frozen = RebateEnum::UNFREEZE; $rewardLog->save(); } public static function unfrozenFirstReward2Queue(array $unfozenRebateBuys) { foreach ($unfozenRebateBuys as $unfozenRebateBuy) { Yii::$app->services->rabbitMq->push( RabbitMqEnum::EXCHANGE_TASK_USER_WALLET, RabbitMqEnum::USER_WALLET_QUEUE, $unfozenRebateBuy, self::class, 'unfrozenFirstReward' ); } } }