| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- <?php
- namespace addons\ScoreExpansion\common\services;
- use addons\ScoreExpansion\common\enums\ScoreExpansionEnum;
- use addons\ScoreExpansion\common\models\ScoreExpansionRecommendRewardDetails;
- use addons\ScoreExpansion\common\models\ScoreExpansionRecommendRewardGoods;
- use addons\ScoreExpansion\common\models\ScoreExpansionRecommendRewardOrder;
- use addons\ScoreExpansion\common\models\ScoreExpansionWallet;
- use common\enums\StatusEnum;
- use common\helpers\ArrayHelper;
- use common\helpers\FormatHelper;
- use common\models\mall\MallAddons;
- use common\models\order\Order;
- use common\models\user\User;
- use common\models\user\UserPartitionRelationship;
- use Exception;
- use RuntimeException;
- use Yii;
- class RecommendRewardOrderService extends BaseService
- {
- public $setting;
- /**
- * 创建推荐奖励订单
- *
- * @param int $orderId
- * @param int $eventType
- *
- * @return void
- */
- public function createRecommendRewardOrder(int $orderId, int $eventType)
- {
- $order = Order::find()
- ->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)]);
- }
- }
- }
- }
- }
|