where(['id' => $orderId, 'status' => StatusEnum::ENABLED]) ->with(['detail']) ->asArray() ->one(); if (!$order) { Yii::$app->custom->logs('【积分拓客】创建推荐奖励订单失败,订单不存在', compact('orderId', 'eventType')); return; } $this->mall_id = $order['mall_id']; if (!MallAddons::isInstall($this->mall_id, ScoreExpansionEnum::ADDONS_NAME)) { return; } $setting = $this->getSetting(); if (!$this->checkIsCreate($orderId, $eventType)) { return; } $joinGoods = ScoreExpansionRecommendRewardGoods::find() ->where([ 'mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED, 'goods_id' => array_column($order['detail'], 'goods_id') ]) ->select('is_alone, goods_id, setting') ->indexBy('goods_id') ->all(); if (!$joinGoods) { return; } // 创建推荐奖励订单 $t = Yii::$app->db->beginTransaction(); try { foreach ($order['detail'] as $detail) { if (!isset($joinGoods[$detail['goods_id']])) { continue; } $loopNum = $setting['loop_num']; $rewardFrozenScore = $setting['reward_frozen_score']; $joinGoodsItem = $joinGoods[$detail['goods_id']]; if ($joinGoodsItem['is_alone'] && $joinGoodsItem['setting']) { $loopNum = $joinGoodsItem['setting']['loop_num']; $rewardFrozenScore = $joinGoodsItem['setting']['reward_frozen_score']; } if ( ScoreExpansionRecommendRewardOrder::setData([ 'mall_id' => $this->mall_id, 'user_id' => $order['user_id'], 'user_ids' => [], 'exclude_user_ids' => [], 'order_id' => $detail['order_id'], 'order_detail_id' => $detail['id'], 'reward_period' => $setting['reward_period'], 'reward_frozen_score' => $rewardFrozenScore, 'reward_person_count' => $setting['reward_person_count'], 'loop_num' => $loopNum, 'is_end' => (int)(!$loopNum || !$rewardFrozenScore || !$setting['reward_person_count']), ]) === false ) { throw new RuntimeException(ScoreExpansionRecommendRewardOrder::getStaticError()); } } $t->commit(); } catch (Exception $e) { $t->rollBack(); Yii::$app->custom->logs(FormatHelper::exception($e, '【积分拓客】创建推荐奖励订单失败'), compact('orderId', 'eventType')); } } /** * @param bool $overwrite * * @return array */ public function getSetting(bool $overwrite = false): array { if (!$this->setting || $overwrite) { $settingService = new SettingService(['mall_id' => $this->mall_id]); $this->setting = $settingService->getSetting(); } return $this->setting; } /** * 检查配置是否创建推荐奖励订单 * * @param int $orderId * @param int $eventType * * @return bool */ private function checkIsCreate(int $orderId, int $eventType): bool { $setting = $this->getSetting(); if (empty($setting['is_enable_buy_goods_give_frozen_score'])) { return false; } if ($eventType != $setting['gift_method']) { return false; } // 创建过则不再创建 if ( ScoreExpansionRecommendRewardOrder::find() ->where([ 'mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED, 'order_id' => $orderId ]) ->exists() ) { return false; } return true; } /** * 发放推荐奖励 * * @return void */ public function sendRecommendReward() { $date = date('Ymd'); $setting = $this->getSetting(true); // 查询推荐奖励订单 $find = ScoreExpansionRecommendRewardOrder::find(); ScoreExpansionRecommendRewardOrder::paramPack([ 'where' => [ [ 'mall_id' => $this->mall_id, 'status' => StatusEnum::ENABLED, 'is_end' => StatusEnum::DISABLED, ], ['<', 'last_exec_date', $date] ], ], $find); foreach ($find->batch(500) as $batchItem) { foreach ($batchItem as $item) { Yii::$app->custom->logs('【积分拓客】开始执行每日发放商品购买赠送冻结积分', ['recommend_reward_order_id' => $item['id'], 'date' => $date]); try { $rewardNum = $item->reward_frozen_score; $item->last_exec_date = $date; // 判断是否是第一轮 if ($item->current_loop_num <= 1) { $userId = $item->user_id; if ($item->user_ids) { $userId = end($item->user_ids); } $parentIdArr = UserPartitionRelationship::getParentIdArr($userId); if (!$parentIdArr) { $item->next(); $item->save(); continue; } // 查询会员等级 $parentUsers = User::find() ->where([ 'id' => $parentIdArr, 'status' => StatusEnum::ENABLED, 'mall_id' => $this->mall_id, 'level' => $setting['level_condition'] ]) ->select('level, id') ->indexBy('id') ->asArray() ->all(); $parentIdArr = array_reverse($parentIdArr); foreach ($parentIdArr as $parentId) { if (isset($parentUsers[$parentId])) { $findParentId = $parentId; break; } } if (empty($findParentId)) { $item->next(); $item->save(); continue; } $item->frozen_score_issued_total += $rewardNum; $userIds = $item->user_ids; $userIds[] = $findParentId; $item->user_ids = $userIds; if (count($item->user_ids) >= $item->reward_person_count) { $item->next(); } $t = Yii::$app->db->beginTransaction(); try { $item->save(); $res = ScoreExpansionRecommendRewardDetails::setData([ 'mall_id' => $this->mall_id, 'recommend_reward_order_id' => $item->id, 'user_id' => $findParentId, 'date' => $date, 'reward_frozen_score' => $rewardNum, 'loop_num' => 1, 'current_reward_person_index' => count($item->user_ids) - 1 ]); if ($res === false) { throw new RuntimeException(ScoreExpansionRecommendRewardDetails::getStaticError()); } // 发放奖励 $res = ScoreExpansionWallet::setData([ 'mall_id' => $this->mall_id, 'user_id' => $res['user_id'], 'is_frozen' => true, 'integral' => $res['reward_frozen_score'], 'source_table' => ScoreExpansionRecommendRewardDetails::tableName(), 'source_table_id' => $res['id'], 'from_type' => ScoreExpansionEnum::FROM_RECOMMEND_REWARD, 'desc' => '购买商品循环赠送冻结积分', ]); if ($res === false) { throw new RuntimeException(ScoreExpansionWallet::getStaticError()); } $t->commit(); } catch (Exception $e) { $t->rollBack(); Yii::$app->custom->logs(FormatHelper::exception($e, '【积分拓客】每日发放商品购买赠送冻结积分失败'), ['item' => ArrayHelper::toArray($item), 'user_id' => $findParentId]); } continue; } // 第一轮之后就跑定下来的关系链 user_ids $userId = $item->user_ids[$item->current_reward_person_index]; if (in_array($userId, $item->exclude_user_ids)) { $item->next(); $item->save(); continue; } // 判断这个用户的等级,是否判断条件 if ( !User::find() ->where([ 'id' => $userId, 'status' => StatusEnum::ENABLED, 'mall_id' => $this->mall_id, 'level' => $setting['level_condition'] ]) ->exists() ) { $excludeUserIds = $item->exclude_user_ids; $excludeUserIds[] = $userId; $item->exclude_user_ids = $excludeUserIds; // 关系链所有用户都被排除了,直接结束 if (count($item->exclude_user_ids) === count($item->user_ids)) { $item->is_end = StatusEnum::ENABLED; } else { $item->next(); } $item->save(); continue; } $t = Yii::$app->db->beginTransaction(); try { $res = ScoreExpansionRecommendRewardDetails::setData([ 'mall_id' => $this->mall_id, 'recommend_reward_order_id' => $item->id, 'user_id' => $userId, 'date' => $date, 'reward_frozen_score' => $rewardNum, 'loop_num' => $item->current_loop_num, 'current_reward_person_index' => $item->current_reward_person_index ]); if ($res === false) { throw new RuntimeException(ScoreExpansionRecommendRewardDetails::getStaticError()); } // 发放奖励 $res = ScoreExpansionWallet::setData([ 'mall_id' => $this->mall_id, 'user_id' => $res['user_id'], 'is_frozen' => true, 'integral' => $res['reward_frozen_score'], 'source_table' => ScoreExpansionRecommendRewardDetails::tableName(), 'source_table_id' => $res['id'], 'from_type' => ScoreExpansionEnum::FROM_RECOMMEND_REWARD, 'desc' => '购买商品循环赠送冻结积分', ]); if ($res === false) { throw new RuntimeException(ScoreExpansionWallet::getStaticError()); } $item->frozen_score_issued_total += $rewardNum; $item->next(); $item->save(); $t->commit(); } catch (Exception $e) { $t->rollBack(); Yii::$app->custom->logs(FormatHelper::exception($e, '【积分拓客】每日发放商品购买赠送冻结积分失败'), ['item' => ArrayHelper::toArray($item), 'user_id' => $userId]); } } catch (Exception $e) { Yii::$app->custom->logs(FormatHelper::exception($e, '【积分拓客】每日发放商品购买赠送冻结积分异常'), ['item' => ArrayHelper::toArray($item)]); } } } } }