root 3 лет назад
Родитель
Сommit
b0d7f038ac

+ 1 - 655
common/helpers/bonus/CalcCache.php

@@ -5,16 +5,11 @@
  * Date: 2018/8/2
  * Time: 上午10:38
  */
-
 namespace common\helpers\bonus;
 
-use common\components\Redis;
 use common\helpers\Cache;
-use common\helpers\Date;
-use common\helpers\user\Info;
 use common\models\CalcBonus;
 use common\models\PerfMonth;
-use common\models\PerfPeriod;
 use common\models\Period;
 use common\models\DeclarationLevel;
 use common\models\DecRole;
@@ -22,12 +17,7 @@ use common\models\EmployLevel;
 use common\models\StarCrownLevel;
 use common\models\User;
 use common\models\UserBonus;
-use common\models\UserNetwork;
 use common\models\UserPerf;
-use common\models\UserRelation;
-use common\models\RemainPv;
-use common\models\Order;
-use common\models\forms\OrderForm;
 use Yii;
 use common\models\UserInfo;
 use yii\helpers\Json;
@@ -43,15 +33,11 @@ class CalcCache {
     const REDIS_KEY_PREFIX_USER_PERF = 'calc:userPerf_';
     const REDIS_KEY_PREFIX_SURPLUS_PERF = 'calc:spPerf_';
     const REDIS_KEY_PREFIX_NOW_PERIOD_PERF = 'calc:nowPeriodPerf_';
-    const REDIS_KEY_PREFIX_NOW_STANDARD_MONTH_PERF = 'calc:nowStandardMonthPerf_';
     const REDIS_KEY_PREFIX_LAST_MONTH_PERF = 'calc:lastMonthPerf_';
     const REDIS_KEY_PREFIX_NOW_MONTH_PERF = 'calc:nowMonthPerf_';
-    const REDIS_KEY_PREFIX_NOW_MONTH_SCORE = 'calc:nowMonthScore_';
     const REDIS_KEY_PREFIX_NOW_MONTH_LAST_PERIOD_RECONSUME_POINTS = 'calc:nowMonthLastPeriodReconsumePoints_';
     const REDIS_KEY_PREFIX_EMP_NUM_PERF = 'calc:empLevelNum_';
     const REDIS_KEY_PREFIX_BONUS = 'calc:bonus_';
-    const REDIS_KEY_PREFIX_STANDARD_BONUS = 'calc:standard:bonus_';
-    const REDIS_KEY_PREFIX_YC_BONUS = 'calc:yc:bonus_';
     const REDIS_KEY_PREFIX_FW_BONUS = 'calc:fw:bonus_';
     const REDIS_KEY_PREFIX_TOURISM_BONUS = 'calc:tourism:bonus_';
     const REDIS_KEY_PREFIX_VILLA_BONUS = 'calc:villa:bonus_';
@@ -62,7 +48,6 @@ class CalcCache {
     const REDIS_KEY_PREFIX_HAS_BD_USER = 'calc:hasBDUser_';
     const REDIS_KEY_PREFIX_HAS_INCOME_USER = 'calc:hasIncomeUser_';
     const REDIS_KEY_PREFIX_HAS_BONUS_USER = 'calc:hasBonusUser_';
-    const REDIS_KEY_PREFIX_HAS_YC_BONUS_USER = 'calc:hasYcBonusUser_';
     const REDIS_KEY_PREFIX_HAS_FW_BONUS_USER = 'calc:hasFwBonusUser_';
     const REDIS_KEY_PREFIX_HAS_MONTH_BONUS_USER = 'calc:hasMonthBonusUser_';
     const REDIS_KEY_PREFIX_HAS_PERF_USER_POOL = 'calc:hasPerfUserPool_';
@@ -71,11 +56,8 @@ class CalcCache {
     const REDIS_KEY_PREFIX_HAS_BD_USER_POOL = 'calc:hasBDUserPool_';
     const REDIS_KEY_PREFIX_HAS_INCOME_USER_POOL = 'calc:hasIncomeUserPool_';
     const REDIS_KEY_PREFIX_HAS_BONUS_USER_POOL = 'calc:hasBonusUserPool_';
-    const REDIS_KEY_PREFIX_HAS_YC_BONUS_USER_POOL = 'calc:hasYcBonusUserPool_';
     const REDIS_KEY_PREFIX_HAS_FW_BONUS_USER_POOL = 'calc:hasFwBonusUserPool_';
     const REDIS_KEY_PREFIX_HAS_MONTH_BONUS_USER_POOL = 'calc:hasMonthBonusUserPool_';
-    const REDIS_KEY_PREFIX_HAS_SCORE_USER = 'calc:hasScoreUser_';
-    const REDIS_KEY_PREFIX_HAS_SCORE_USER_POOL = 'calc:hasScoreUserPool_';
     const REDIS_KEY_PREFIX_HAS_LS_PCS_USER = 'calc:hasLSPCSUser_';
     const REDIS_KEY_PREFIX_HAS_LS_PCS_USER_POOL = 'calc:hasLSPCSUserPool_';
     const REDIS_KEY_PREFIX_HAS_CF_PERCENT_USER = 'calc:hasCFPercentPCSUser_';
@@ -83,12 +65,7 @@ class CalcCache {
     const REDIS_KEY_PREFIX_HAS_LX_PERCENT_USER = 'calc:hasLXPercentPCSUser_';
     const REDIS_KEY_PREFIX_HAS_LX_PERCENT_USER_POOL = 'calc:hasLXPercentPCSUserPool_';
     const REDIS_KEY_PREFIX_DEC_ROLE_CONFIG = 'calc:decRoleConfig_';
-    const REDIS_KEY_PREFIX_CF_TOTAL_PERCENT = 'calc:cfTotalPercent_';
-    const REDIS_KEY_PREFIX_LX_TOTAL_PERCENT = 'calc:lxTotalPercent_';
     const REDIS_KEY_PREFIX_USER_INFO_CHILD_ONE_DEEP = 'calc:userInfo:ChildOneDeep_';
-    const REDIS_KEY_PREFIX_GX_BONUS_DEEP_ONE_LIST_DATA = 'calc:gxBonusDeepOneListData_';
-    const REDIS_KEY_PREFIX_GX_BONUS_DEEP_TWO_LIST_DATA = 'calc:gxBonusDeepTwoListData_';
-    const REDIS_KEY_PREFIX_YC_BONUS_LIST_DATA = 'calc:ycBonusListData_';
     const REDIS_KEY_PREFIX_FW_BONUS_LIST_DATA = 'calc:fwBonusListData_';
     const REDIS_KEY_PREFIX_BONUS_CROWN_CROWN_LIST_DATA = 'calc:bonusStarCrownListData_';
 
@@ -97,11 +74,6 @@ class CalcCache {
     const REDIS_KEY_PREFIX_HAS_REPAIR_PERF_USER = 'calc:hasRepairPerfUser_';
     const REDIS_KEY_PREFIX_HAS_REPAIR_PERF_USER_POOL = 'calc:hasRepairPerfPool_';
 
-    //收入的奖金类型
-//    const INCOME_TG_BONUS = 'BONUS_TG';
-//    const INCOME_XF_BONUS = 'BONUS_XF';
-//    const INCOME_YJ_BONUS = 'BONUS_YJ';
-//    const INCOME_QY_BONUS = 'BONUS_QY';
     const INCOME_QY_BONUS_BD = 'BONUS_QY_BD';
     const INCOME_QY_BONUS_FX = 'BONUS_QY_FX';
     const INCOME_BONUS_TRAVEL = 'BONUS_TRAVEL';
@@ -109,12 +81,7 @@ class CalcCache {
     const INCOME_BONUS_HOUSE = 'BONUS_HOUSE';
     const CAPPED_BONUS_QY = 'CAPPED_BONUS_QY'; // 团队奖封顶前的金额
     const INCOME_BONUS_LIST = [
-//        self::INCOME_TG_BONUS,
-//        self::INCOME_XF_BONUS,
-//        self::INCOME_YJ_BONUS,
-//        self::INCOME_QY_BONUS,
         self::INCOME_QY_BONUS_BD,
-//        self::INCOME_QY_BONUS_FX,
     ];
     const NOT_SEND_BONUS_LIST = [
         self::INCOME_QY_BONUS_BD,
@@ -136,13 +103,6 @@ class CalcCache {
         Yii::$app->redis->del(self::REDIS_KEY_PREFIX_BONUS . $periodNum);
         Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_BONUS_USER . $periodNum);
         Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_BONUS_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_STANDARD_BONUS . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_YC_BONUS . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_YC_BONUS_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_YC_BONUS_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_GX_BONUS_DEEP_ONE_LIST_DATA . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_GX_BONUS_DEEP_TWO_LIST_DATA . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_YC_BONUS_LIST_DATA . $periodNum);
         Yii::$app->redis->del(self::REDIS_KEY_PREFIX_FW_BONUS . $periodNum);
         Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_FW_BONUS_USER . $periodNum);
         Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_FW_BONUS_USER_POOL . $periodNum);
@@ -160,64 +120,6 @@ class CalcCache {
         \Yii::$app->redis->del(Cache::USER_RELATION_PARENTS);
     }
 
-    /**
-     * 清空所有临时计算用到的缓存
-     * @param $periodNum
-     */
-    public static function clearAll($periodNum) {
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_USER_ACTIVE . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_USER_INFO . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_USER_BONUS . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_PERIOD_MONTH_CALC_BONUS . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_SURPLUS_PERF . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_USER_PERF . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_NOW_PERIOD_PERF . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_NOW_STANDARD_MONTH_PERF . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_LAST_MONTH_PERF . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_NOW_MONTH_PERF . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_NOW_MONTH_SCORE . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_NOW_MONTH_LAST_PERIOD_RECONSUME_POINTS . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_EMP_NUM_PERF . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_BONUS . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_STANDARD_BONUS . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_YC_BONUS . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_FW_BONUS . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_PERF_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_PERF_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_MONTH_PERF_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_MONTH_PERF_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_STANDARD_MONTH_PERF_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_STANDARD_MONTH_PERF_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_BD_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_BD_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_INCOME_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_INCOME_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_BONUS_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_BONUS_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_YC_BONUS_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_YC_BONUS_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_FW_BONUS_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_FW_BONUS_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_MONTH_BONUS_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_MONTH_BONUS_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_SCORE_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_SCORE_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_LS_PCS_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_LS_PCS_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_CF_PERCENT_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_CF_PERCENT_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_LX_PERCENT_USER . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_HAS_LX_PERCENT_USER_POOL . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_DEC_ROLE_CONFIG . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_USER_INFO_CHILD_ONE_DEEP . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_GX_BONUS_DEEP_ONE_LIST_DATA . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_GX_BONUS_DEEP_TWO_LIST_DATA . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_YC_BONUS_LIST_DATA . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_FW_BONUS_LIST_DATA . $periodNum);
-        Yii::$app->redis->del(self::REDIS_KEY_PREFIX_BONUS_CROWN_CROWN_LIST_DATA . $periodNum);
-    }
-
     /**
      * 会员信息加入缓存
      * @param $periodNum
@@ -329,33 +231,6 @@ class CalcCache {
         return Yii::$app->redis->lrange(self::REDIS_KEY_PREFIX_HAS_MONTH_PERF_USER . $periodNum, $offset, ($offset + $limit - 1));
     }
 
-    /**
-     * 加入有达标业绩的会员
-     * @param $userId
-     * @param $periodNum
-     */
-    public static function addHasStandardMonthPerfUsers($userId, $periodNum) {
-        // 先从已存在的会员池里面获取
-        $isset = Yii::$app->redis->hget(self::REDIS_KEY_PREFIX_HAS_STANDARD_MONTH_PERF_USER_POOL . $periodNum, $userId);
-        if (!$isset) {
-            Yii::$app->redis->hset(self::REDIS_KEY_PREFIX_HAS_STANDARD_MONTH_PERF_USER_POOL . $periodNum, $userId, 1);
-            Yii::$app->redis->rpush(self::REDIS_KEY_PREFIX_HAS_STANDARD_MONTH_PERF_USER . $periodNum, $userId);
-        }
-        unset($userId, $periodNum, $isset);
-    }
-
-    /**
-     * 获取有达标业绩的会员
-     * @param $periodNum
-     * @param int $offset
-     * @param int $limit
-     * @return mixed
-     */
-    public static function getHasStandardMonthPerfUsers($periodNum, $offset = 0, $limit = self::LIMIT) {
-        return Yii::$app->redis->lrange(self::REDIS_KEY_PREFIX_HAS_STANDARD_MONTH_PERF_USER . $periodNum, $offset, ($offset + $limit - 1));
-    }
-
-
     /**
      * 加入被报单的会员
      * @param $userId
@@ -450,73 +325,6 @@ class CalcCache {
         return Yii::$app->redis->lrange(self::REDIS_KEY_PREFIX_HAS_BONUS_USER . $periodNum, $offset, ($offset + $limit - 1));
     }
 
-    /**
-     * 加入荣衔奖的会员
-     * @param $userId
-     * @param $periodNum
-     */
-    public static function addHasYcBonusUsers($userId, $periodNum) {
-        // 先从已存在的会员池里面获取
-        $isset = Yii::$app->redis->hget(self::REDIS_KEY_PREFIX_HAS_YC_BONUS_USER_POOL . $periodNum, $userId);
-        if (!$isset) {
-            Yii::$app->redis->hset(self::REDIS_KEY_PREFIX_HAS_YC_BONUS_USER_POOL . $periodNum, $userId, 1);
-            Yii::$app->redis->rpush(self::REDIS_KEY_PREFIX_HAS_YC_BONUS_USER . $periodNum, $userId);
-        }
-
-        unset($userId, $periodNum, $isset);
-    }
-
-    /**
-     * 保存荣衔奖奖金
-     * @param $userId
-     * @param $periodNum
-     * @param $empBonus
-     * @param array $fromData
-     */
-    public static function saveYCBonusList($userId, $periodNum, $empBonus, $fromData=[]) {
-        $userYcBonusData = Yii::$app->redis->hget(self::REDIS_KEY_PREFIX_YC_BONUS_LIST_DATA . $periodNum, $userId);
-
-        if( $userYcBonusData ) {
-            $ycBonusData = Json::decode($userYcBonusData, true);
-            $ycBonusData['empBonus'] += $empBonus;
-//            $ycBonusData['fromData'][] = $fromData;
-        }else {
-            $ycBonusData = [
-                'empBonus' => $empBonus,
-//                'fromData' => [
-//                    $fromData
-//                ]
-            ];
-        }
-        unset($userYcBonusData);
-
-        Yii::$app->redis->hset(self::REDIS_KEY_PREFIX_YC_BONUS_LIST_DATA . $periodNum, $userId, Json::encode($ycBonusData));
-        unset($ycBonusData, $userId, $periodNum, $empBonus, $fromData);
-    }
-
-    /**
-     * 返回荣衔奖信息
-     * @param $userId
-     * @param $periodNum
-     * @return array
-     */
-    public static function getYCBonusList($userId, $periodNum) {
-        $userYcBonusData = Yii::$app->redis->hget(self::REDIS_KEY_PREFIX_YC_BONUS_LIST_DATA . $periodNum, $userId);
-
-        return $userYcBonusData ? Json::decode($userYcBonusData, true) : [];
-    }
-
-    /**
-     * 获取有荣衔奖的会员
-     * @param $periodNum
-     * @param int $offset
-     * @param int $limit
-     * @return mixed
-     */
-    public static function getHasYcBonusUsers($periodNum, $offset = 0, $limit = self::LIMIT) {
-        return Yii::$app->redis->lrange(self::REDIS_KEY_PREFIX_HAS_YC_BONUS_USER . $periodNum, $offset, ($offset + $limit - 1));
-    }
-
     /**
      * 获取有服务奖的会员
      * @param $periodNum
@@ -528,7 +336,6 @@ class CalcCache {
         return Yii::$app->redis->lrange(self::REDIS_KEY_PREFIX_HAS_FW_BONUS_USER . $periodNum, $offset, ($offset + $limit - 1));
     }
 
-
     /**
      * 加入服务奖的会员
      * @param $userId
@@ -574,7 +381,7 @@ class CalcCache {
     }
 
     /**
-     * 保存荣衔奖奖金
+     * 保存服务奖奖金
      * @param $userId
      * @param $periodNum
      * @param $fwBonus
@@ -582,17 +389,12 @@ class CalcCache {
      */
     public static function saveFwBonusList($userId, $periodNum, $fwBonus, $fromData=[]) {
         $userFwBonusData = Yii::$app->redis->hget(self::REDIS_KEY_PREFIX_FW_BONUS_LIST_DATA . $periodNum, $userId);
-
         if( $userFwBonusData ) {
             $fwBonusData = Json::decode($userFwBonusData, true);
             $fwBonusData['fwBonus'] += $fwBonus;
-//            $ycBonusData['fromData'][] = $fromData;
         }else {
             $fwBonusData = [
                 'fwBonus' => $fwBonus,
-//                'fromData' => [
-//                    $fromData
-//                ]
             ];
         }
         unset($userFwBonusData);
@@ -639,57 +441,6 @@ class CalcCache {
         return Yii::$app->redis->hget(self::REDIS_KEY_PREFIX_BONUS_CROWN_CROWN_LIST_DATA . $periodNum, $userId);
     }
 
-    /**
-     * 加入有复销业绩的会员列表
-     * @param $userId
-     * @param $periodNum
-     */
-    public static function addHasScoreUsers($userId, $periodNum) {
-        $isset = Yii::$app->redis->hget(self::REDIS_KEY_PREFIX_HAS_SCORE_USER_POOL . $periodNum, $userId);
-        if (!$isset) {
-            Yii::$app->redis->hset(self::REDIS_KEY_PREFIX_HAS_SCORE_USER_POOL . $periodNum, $userId, 1);
-            $key = self::REDIS_KEY_PREFIX_HAS_SCORE_USER . $periodNum;
-            Yii::$app->redis->rpush($key, $userId);
-        }
-    }
-
-    /**
-     * 获取有复销业绩的会员列表
-     * @param $periodNum
-     * @param int $offset
-     * @param int $limit
-     * @return mixed
-     */
-    public static function getHasScoreUsers($periodNum, $offset = 0, $limit = self::LIMIT) {
-        return Yii::$app->redis->lrange(self::REDIS_KEY_PREFIX_HAS_SCORE_USER . $periodNum, $offset, ($offset + $limit - 1));
-    }
-
-    /**
-     * 加入有零售个人消费的会员列表
-     * @param $userId
-     * @param $periodNum
-     */
-    public static function addHasLSPCSUsers($userId, $periodNum) {
-        $isset = Yii::$app->redis->hget(self::REDIS_KEY_PREFIX_HAS_LS_PCS_USER_POOL . $periodNum, $userId);
-        if (!$isset) {
-            Yii::$app->redis->hset(self::REDIS_KEY_PREFIX_HAS_LS_PCS_USER_POOL . $periodNum, $userId, 1);
-            $key = self::REDIS_KEY_PREFIX_HAS_LS_PCS_USER . $periodNum;
-            $value = $userId;
-            Yii::$app->redis->rpush($key, $value);
-        }
-    }
-
-    /**
-     * 加入有零售消费的会员列表
-     * @param $periodNum
-     * @param int $offset
-     * @param int $limit
-     * @return mixed
-     */
-    public static function getHasLSPCSUsers($periodNum, $offset = 0, $limit = self::LIMIT) {
-        return Yii::$app->redis->lrange(self::REDIS_KEY_PREFIX_HAS_LS_PCS_USER . $periodNum, $offset, ($offset + $limit - 1));
-    }
-
     /**
      * 有车房补贴比例的人
      * @param $userId
@@ -716,32 +467,6 @@ class CalcCache {
         return Yii::$app->redis->lrange(self::REDIS_KEY_PREFIX_HAS_CF_PERCENT_USER . $periodNum, $offset, ($offset + $limit - 1));
     }
 
-    /**
-     * 有领袖分红的人
-     * @param $userId
-     * @param $periodNum
-     */
-    public static function addHasLXPercentUsers($userId, $periodNum) {
-        $isset = Yii::$app->redis->hget(self::REDIS_KEY_PREFIX_HAS_LX_PERCENT_USER_POOL . $periodNum, $userId);
-        if (!$isset) {
-            Yii::$app->redis->hset(self::REDIS_KEY_PREFIX_HAS_LX_PERCENT_USER_POOL . $periodNum, $userId, 1);
-            $key = self::REDIS_KEY_PREFIX_HAS_LX_PERCENT_USER . $periodNum;
-            $value = $userId;
-            Yii::$app->redis->rpush($key, $value);
-        }
-    }
-
-    /**
-     * 获取有领袖分红的人
-     * @param $periodNum
-     * @param int $offset
-     * @param int $limit
-     * @return mixed
-     */
-    public static function getHasLXPercentUsers($periodNum, $offset = 0, $limit = self::LIMIT) {
-        return Yii::$app->redis->lrange(self::REDIS_KEY_PREFIX_HAS_LX_PERCENT_USER . $periodNum, $offset, ($offset + $limit - 1));
-    }
-
     /**
      * 通过创建时间获取指定长度的用户列表
      * @param $userId
@@ -846,55 +571,6 @@ class CalcCache {
         return true;
     }
 
-    /**
-     * 用户奖金信息
-     * @param $userId
-     * @param $periodNum
-     * @return array|mixed|null|\yii\db\ActiveRecord
-     */
-    public static function LastUserBonus($userId, $periodNum) {
-
-        $cacheKey = self::REDIS_KEY_PREFIX_USER_BONUS . $periodNum;
-        $field = $userId;
-        $cacheValue = \Yii::$app->redis->hget($cacheKey, $field);
-        if ($cacheValue) {
-            $value = Json::decode($cacheValue, true);
-        } else {
-            $value = UserBonus::findUseDbCalc()->select('USER_ID,BONUS_TOTAL')->where('USER_ID=:USER_ID', [
-                'USER_ID'=>$userId
-            ])->asArray()->one();
-
-            \Yii::$app->redis->hset($cacheKey, $field, Json::encode($value));
-        }
-        return $value;
-    }
-
-    /**
-     * 用户奖金信息
-     * @param $userId
-     * @param $periodNum
-     * @param $yearMonth
-     * @return array|mixed|null|\yii\db\ActiveRecord
-     */
-    public static function lastPeriodMonthCalcBonus($userId, $periodNum, $yearMonth) {
-
-        $cacheKey = self::REDIS_KEY_PREFIX_PERIOD_MONTH_CALC_BONUS . $periodNum;
-        $field = $userId;
-        $cacheValue = \Yii::$app->redis->hget($cacheKey, $field);
-        if ($cacheValue) {
-            $value = Json::decode($cacheValue, true);
-        } else {
-            $value = CalcBonus::findUseDbCalc()->select('SUM(ORI_BONUS_QY) AS ORI_BONUS_QY_SUM,SUM(ORI_BONUS_VIP) AS ORI_BONUS_VIP_SUM')->where('USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH', [
-                'USER_ID'=>$userId,
-                'CALC_MONTH'=>$yearMonth
-            ])->asArray()->one();
-
-            \Yii::$app->redis->hset($cacheKey, $field, Json::encode($value));
-        }
-        return $value;
-    }
-
-
     /**
      * 本月往期的复消积分的数据
      * @param $userId
@@ -940,16 +616,6 @@ class CalcCache {
      * @throws \yii\db\Exception
      */
     public static function surplusPerf($userId, $periodNum) {
-//        $cacheKey = self::REDIS_KEY_PREFIX_SURPLUS_PERF . $periodNum;
-//        $field = $userId;
-//        $cacheValue = \Yii::$app->redis->hget($cacheKey, $field);
-//        if ($cacheValue) {
-//            $value = Json::decode($cacheValue);
-//        } else {
-//            $value = UserPerf::getPeriodSurplusPerf($userId);
-//            \Yii::$app->redis->hset($cacheKey, $field, Json::encode($value));
-//        }
-//        return $value;
         $userPerf = self::userPerf($userId, $periodNum);
         return [
             'SURPLUS_1L' => $userPerf['SURPLUS_1L'],
@@ -967,12 +633,6 @@ class CalcCache {
             'SURPLUS_3L_FX' => $userPerf['SURPLUS_3L_FX'],
             'SURPLUS_4L_FX' => $userPerf['SURPLUS_4L_FX'],
             'SURPLUS_5L_FX' => $userPerf['SURPLUS_5L_FX'],
-            'VIP_SURPLUS_1L_ZC' => $userPerf['VIP_SURPLUS_1L_ZC'],
-            'VIP_SURPLUS_2L_ZC' => $userPerf['VIP_SURPLUS_2L_ZC'],
-            'VIP_SURPLUS_3L_ZC' => $userPerf['VIP_SURPLUS_3L_ZC'],
-            'VIP_SURPLUS_4L_ZC' => $userPerf['VIP_SURPLUS_4L_ZC'],
-            'VIP_SURPLUS_5L_ZC' => $userPerf['VIP_SURPLUS_5L_ZC'],
-            'SURPLUS_LS' => 0,
         ];
     }
 
@@ -1095,48 +755,29 @@ class CalcCache {
                 'PV_PCS' => 0,
                 'PV_PSS' => 0,//本期的团队业绩
                 'PV_PCS_ZC' => 0,//注册
-                'PV_PCS_YH' => 0,
-                'PV_PCS_ZG' => 0,//增购
-                'PV_PCS_LS' => 0,
                 'PV_PCS_FX' => 0,
                 'PV_PCS_FX_CASH' => 0,//现金复消
                 'PV_PCS_FX_POINT' => 0,//积分复消
                 'PV_1L' => 0,
                 'PV_1L_TOUCH' => 0,
                 'PV_1L_ZC' => 0,
-                'PV_1L_YH' => 0,
-                'PV_1L_ZG' => 0,
-                'PV_1L_LS' => 0,
                 'PV_1L_FX' => 0,
                 'PV_2L' => 0,
                 'PV_2L_TOUCH' => 0,
                 'PV_2L_ZC' => 0,
-                'PV_2L_YH' => 0,
-                'PV_2L_ZG' => 0,
-                'PV_2L_LS' => 0,
                 'PV_2L_FX' => 0,
                 'PV_3L' => 0,
                 'PV_3L_TOUCH' => 0,
                 'PV_3L_ZC' => 0,
-                'PV_3L_YH' => 0,
-                'PV_3L_ZG' => 0,
-                'PV_3L_LS' => 0,
                 'PV_3L_FX' => 0,
                 'PV_4L' => 0,
                 'PV_4L_TOUCH' => 0,
                 'PV_4L_ZC' => 0,
-                'PV_4L_YH' => 0,
-                'PV_4L_ZG' => 0,
-                'PV_4L_LS' => 0,
                 'PV_4L_FX' => 0,
                 'PV_5L' => 0,
                 'PV_5L_TOUCH' => 0,
                 'PV_5L_ZC' => 0,
-                'PV_5L_YH' => 0,
-                'PV_5L_ZG' => 0,
-                'PV_5L_LS' => 0,
                 'PV_5L_FX' => 0,
-                'PV_LS_TOUCH' => 0,
                 'SURPLUS_1L' => 0,
                 'SURPLUS_2L' => 0,
                 'SURPLUS_3L' => 0,
@@ -1152,7 +793,6 @@ class CalcCache {
                 'SURPLUS_3L_FX' => 0,
                 'SURPLUS_4L_FX' => 0,
                 'SURPLUS_5L_FX' => 0,
-                'SURPLUS_LS' => 0,
             ];
         }
         if ($perf !== null) {
@@ -1229,9 +869,6 @@ class CalcCache {
                 'PV_PSS_TOTAL' => 0,
                 'DEC_LEVEL' => $baseInfo['DEC_LV'],
                 'EMP_LEVEL' => EmployLevel::getDefaultLevelId(),
-                'CF_PERCENT' => 0,
-                'LX_PERCENT' => 0,
-                'FX_STATUS' => PerfMonth::NEXT_MONTH_FX_FALSE,
             ];
         }
         if ($perf !== null) {
@@ -1243,69 +880,6 @@ class CalcCache {
         return $value;
     }
 
-    /**
-     * 当前期数的的业绩
-     * @param $userId
-     * @param $periodNum
-     * @param null $perf
-     * @return array|mixed
-     */
-    public static function nowStandardMonthPerf($userId, $periodNum, $perf = null) {
-        $cacheKey = self::REDIS_KEY_PREFIX_NOW_STANDARD_MONTH_PERF . $periodNum;
-        $field = $userId;
-        $cacheValue = \Yii::$app->redis->hget($cacheKey, $field);
-        if ($cacheValue) {
-            $value = Json::decode($cacheValue);
-        } else {
-            $value = [
-                'AMOUNT_PCS' => 0,
-                'AMOUNT_PSS' => 0
-            ];
-        }
-        if ($perf !== null) {
-            foreach ($perf as $key => $pv) {
-                $value[$key] = $pv + $value[$key];
-            }
-            Yii::$app->redis->hset($cacheKey, $field, Json::encode($value));
-        }
-        return $value;
-    }
-
-    /**
-     * 当前月的积分
-     * @param $userId
-     * @param $periodNum
-     * @param $perf
-     * @return array|mixed
-     */
-    public static function nowMonthScore($userId, $periodNum, $perf = null) {
-        $cacheKey = self::REDIS_KEY_PREFIX_NOW_MONTH_SCORE . $periodNum;
-        $cacheValue = \Yii::$app->redis->hget($cacheKey, $userId);
-        if ($cacheValue) {
-            $value = Json::decode($cacheValue);
-        } else {
-            $value = [
-                'USER_ID' => $userId,
-                'BASE_SCORE' => 0,
-                'LEVEL_SCORE' => 0,
-                'UPGRADE_SCORE' => 0,
-//                'TOTAL_SCORE' => 0,
-            ];
-        }
-        unset($cacheValue);
-        if ($perf !== null) {
-            foreach ($perf as $key => $item) {
-                $value[$key] = $item;
-//                $value['TOTAL_SCORE'] += $item;
-                unset($key, $item);
-            }
-            Yii::$app->redis->hset($cacheKey, $userId, Json::encode($value));
-        }
-
-        unset($userId, $periodNum, $perf, $cacheKey);
-        return $value;
-    }
-
     /**
      * 获取直推的所有子会员
      * @param $userId
@@ -1327,92 +901,6 @@ class CalcCache {
         return $data ? Json::decode($data, true) : [];
     }
 
-    /**
-     * 每个区有多少个什么级别的数量
-     * @param $userId
-     * @param $periodNum
-     * @param null $levelNumArr
-     * @return array|mixed
-     */
-    public static function hasEmpLevelNum($userId,  $periodNum, $levelNumArr = null) {
-        $key = self::REDIS_KEY_PREFIX_EMP_NUM_PERF . $periodNum;
-        $field = $userId;
-        $cacheValue = Yii::$app->redis->hget($key, $field);
-
-        if ($cacheValue) {
-            $value = Json::decode($cacheValue);
-        } else {
-            $allEmpLevel = EmployLevel::getFromCache();
-            $value = [];
-            $relationList = self::getChildrenOneDeepFromRedis($userId, $periodNum);
-            foreach ($relationList as $relationData) {
-                foreach ($allEmpLevel as $level) {
-                    // 从月度业绩表中找到所有下级的各个部门的数量
-                    $value[$relationData['USER_ID']][$level['ID']] = 0;
-                }
-            }
-        }
-        if ($levelNumArr != null) {
-            foreach ($levelNumArr as $departUserId => $item) {
-                foreach ($item as $levelID => $num) {
-                    if( isset($value[$departUserId][$levelID]) ) {
-                        $value[$departUserId][$levelID] += $num;
-                    }else {
-                        $value[$departUserId][$levelID] = $num;
-                    }
-                }
-            }
-        }
-        Yii::$app->redis->hset($key, $field, Json::encode($value));
-
-        if ($levelNumArr == null) return $value;
-    }
-
-    /**
-     * 会员是否本月注册
-     * @param $userId
-     * @param $periodNum
-     * @return bool
-     * @throws \yii\db\Exception
-     */
-    public static function isMonthJoinFromRedis($userId, $periodNum) {
-        $period = Period::instance();
-        $calcYearMonth = $period->getYearMonth($periodNum);
-        $userInfo = self::getUserInfo($userId, $periodNum);
-        $addYearMonth = $period->getYearMonth($userInfo['PERIOD_NUM']);
-        //当月注册
-        if ($addYearMonth == $calcYearMonth) return true;
-        //上月注册
-        $calcLastYearMonth = $period->getLastMonth($periodNum);
-        if ($addYearMonth == $calcLastYearMonth['yearMonth']) return true;
-        // 未来注册
-        if ($addYearMonth > $calcYearMonth) return true;
-        return false;
-    }
-
-    /**
-     * 荣衔奖最大比例
-     * @param $userId
-     * @param $periodNum
-     * @param int $percent
-     * @return float|int
-     */
-    public static function ycMaxBonusPercent($userId, $periodNum, $percent=0) {
-        $cacheKey = self::REDIS_KEY_PREFIX_YC_BONUS . $periodNum;
-        $value = Yii::$app->redis->hget($cacheKey, $userId);
-        $maxPercent = floatval($value)>0 ? floatval($value) : 0;
-        if ( $percent > 0 && $percent > $maxPercent ) {
-            $maxPercent = $percent;
-            unset($periodNum, $percent);
-            Yii::$app->redis->hset($cacheKey, $userId, $maxPercent);
-
-            return $maxPercent;
-        }
-
-        unset($userId, $periodNum, $oriBonus, $cacheKey, $value);
-        return $maxPercent;
-    }
-
     /**
      * 服务奖最大比例
      * @param $userId
@@ -1448,19 +936,10 @@ class CalcCache {
     public static function bonus($userId, $periodNum, $bonusType = null, $oriBonus = 0.00, $deductData=[], $fromMeans='') {
         $cacheKey = self::REDIS_KEY_PREFIX_BONUS . $periodNum;
         $value = [
-            'BONUS_BD' => 0,
             'BONUS_TG' => 0,
-            'BONUS_XF' => 0,
-            'BONUS_YJ' => 0,
-            'BONUS_GX' => 0,
-            'BONUS_GL' => 0,
             'BONUS_QY' => 0,
-            'BONUS_YC' => 0,
-            'BONUS_VIP' => 0,
             'BONUS_BS' => 0,
             'BONUS_QUARTER' => 0,
-            'BONUS_YC_EXTRA' => 0,
-            'ORI_BONUS_BD' => 0,
             'ORI_BONUS_BS' => 0,
             'BONUS_BS_MNT' => 0,
             'BONUS_BS_ABBR' => 0,
@@ -1468,34 +947,14 @@ class CalcCache {
             'ORI_BONUS_BS_ABBR' => 0,
             'ORI_BONUS_QUARTER' => 0,
             'ORI_BONUS_TG' => 0,
-            'ORI_BONUS_XF' => 0,
-            'ORI_BONUS_YJ' => 0,
-            'ORI_BONUS_YJ_BD' => 0,
-            'ORI_BONUS_YJ_FX' => 0,
-            'ORI_BONUS_GX' => 0,
-            'ORI_BONUS_GL' => 0,
-            'ORI_BONUS_GL_BD' => 0,
-            'ORI_BONUS_GL_FX' => 0,
             'ORI_BONUS_QY' => 0,
-            'ORI_BONUS_QY_BD' => 0,
-            'ORI_BONUS_QY_FX' => 0,
-            'ORI_BONUS_YC' => 0,
-            'ORI_BONUS_VIP' => 0,
-            'ORI_BONUS_YC_EXTRA' => 0,
-//            'INCOME_TG_TOTAL' => 0,
-//            'INCOME_YJ_TOTAL' => 0,
-//            'INCOME_QY_TOTAL' => 0,
             'INCOME_TOTAL' => 0,
             'BONUS_TOTAL' => 0,
             'RECONSUME_POINTS' => 0,
             'MANAGE_TAX' => 0,
             'ORI_CAPPED_BONUS_QY' => 0,// 团队奖,封顶前金额
-
             //没有用到的
             'BONUS_FX' => 0,
-            'BONUS_LS' => 0,
-            'BONUS_CF' => 0,
-            'BONUS_LX' => 0,
             'BONUS_HB' => 0,
             'BONUS_BT' => 0,
             'BONUS_BT_PROD' => 0,
@@ -1544,27 +1003,6 @@ class CalcCache {
         return $value;
     }
 
-    public static function standardBonus($userId, $periodNum, $bonus=0.00) {
-        $cacheKey = self::REDIS_KEY_PREFIX_STANDARD_BONUS . $periodNum;
-
-        $value = 0.00;
-        if( $bonus > 0 ) {
-            Yii::$app->redis->hset($cacheKey, $userId, $bonus);
-            $value = $bonus;
-            //加入有奖金的会员中
-            self::addHasBonusUsers($userId, $periodNum);
-        }else {
-            $cacheValue = \Yii::$app->redis->hget($cacheKey, $userId);
-            if ($cacheValue) {
-                $value = $cacheValue;
-            }
-            unset($cacheValue);
-        }
-
-        unset($cacheKey, $userId, $periodNum, $bonus);
-        return $value;
-    }
-
     public static function tourismBonus($userId, $periodNum, $bonus = 0.00) {
         $cacheKey = self::REDIS_KEY_PREFIX_TOURISM_BONUS . $periodNum;
 
@@ -1627,96 +1065,4 @@ class CalcCache {
         unset($cacheKey, $userId, $periodNum, $bonus);
         return $value;
     }
-
-    /**
-     * 设置车房总系数
-     * @param $periodNum
-     * @param $value
-     */
-    public static function setCFTotalPercent($periodNum, $value) {
-        Yii::$app->redis->set(self::REDIS_KEY_PREFIX_CF_TOTAL_PERCENT . $periodNum, $value);
-    }
-
-    /**
-     * 获得车房总系数
-     * @param $periodNum
-     * @return mixed
-     */
-    public static function getCFTotalPercent($periodNum) {
-        return Yii::$app->redis->get(self::REDIS_KEY_PREFIX_CF_TOTAL_PERCENT . $periodNum);
-    }
-
-    /**
-     * 设置领袖总系数
-     * @param $periodNum
-     * @param $value
-     */
-    public static function setLXTotalPercent($periodNum, $value) {
-        Yii::$app->redis->set(self::REDIS_KEY_PREFIX_LX_TOTAL_PERCENT . $periodNum, $value);
-    }
-
-    /**
-     * 获得领袖总系数
-     * @param $periodNum
-     * @return mixed
-     */
-    public static function getLXTotalPercent($periodNum) {
-        return Yii::$app->redis->get(self::REDIS_KEY_PREFIX_LX_TOTAL_PERCENT . $periodNum);
-    }
-
-
-    /**
-     * 添加上2代共享奖关系
-     * @param $bonusUserId
-     * @param $fromUserId
-     * @param $periodNum
-     * @param $validDeep
-     * @return  boolean
-     */
-    public static function addShareBonusOneRelation($bonusUserId, $fromUserId, $periodNum, $validDeep) {
-        if ($validDeep == 1) {
-            $cacheKey = self::REDIS_KEY_PREFIX_GX_BONUS_DEEP_ONE_LIST_DATA . $periodNum;
-        }else {
-            $cacheKey = self::REDIS_KEY_PREFIX_GX_BONUS_DEEP_TWO_LIST_DATA . $periodNum;
-        }
-        $fromUserDataJson = Yii::$app->redis->hget($cacheKey, $fromUserId);
-
-        $fromUserData = [];
-        if( $fromUserDataJson ) {
-            $fromUserData = Json::decode($fromUserDataJson, true);
-        }
-        unset($fromUserDataJson);
-
-        $fromUserData[] = $bonusUserId;
-
-        Yii::$app->redis->hset($cacheKey, $fromUserId, Json::encode($fromUserData));
-
-        unset($fromUserData, $bonusUserId, $fromUserId, $periodNum);
-
-        return true;
-    }
-
-    /**
-     * 获取上2代共享奖关系
-     * @param $fromUserId
-     * @param $periodNum
-     * @param $validDeep
-     * @return array
-     */
-    public static function getShareBonusOneRelation($fromUserId, $periodNum, $validDeep) {
-        if ($validDeep == 1) {
-            $cacheKey = self::REDIS_KEY_PREFIX_GX_BONUS_DEEP_ONE_LIST_DATA . $periodNum;
-        }else {
-            $cacheKey = self::REDIS_KEY_PREFIX_GX_BONUS_DEEP_TWO_LIST_DATA . $periodNum;
-        }
-        $fromUserDataJson = Yii::$app->redis->hget($cacheKey, $fromUserId);
-
-        $bonusUserData = [];
-        if( $fromUserDataJson ) {
-            $bonusUserData = Json::decode($fromUserDataJson, true);
-        }
-        unset($fromUserDataJson);
-
-        return $bonusUserData;
-    }
 }

+ 1727 - 0
common/helpers/bonus/CalcServeBonusCalc.php

@@ -0,0 +1,1727 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: leo
+ * Date: 2018/8/2
+ * Time: 上午10:32
+ */
+
+namespace common\helpers\bonus;
+
+use common\helpers\Cache;
+use common\helpers\Date;
+use common\helpers\snowflake\SnowFake;
+use common\helpers\Tool;
+use common\models\CalcBonus;
+use common\models\CalcBonusBD;
+use common\models\CalcBonusBS;
+use common\models\CalcBonusQuarter;
+use common\models\CalcBonusGarage;
+use common\models\CalcBonusGL;
+use common\models\CalcBonusGX;
+use common\models\CalcBonusQY;
+use common\models\CalcBonusStandard;
+use common\models\CalcBonusTG;
+use common\models\CalcBonusTourism;
+use common\models\CalcBonusVilla;
+use common\models\CalcBonusVIP;
+use common\models\CalcBonusXF;
+use common\models\CalcBonusYC;
+use common\models\CalcBonusYJ;
+use common\models\CalcMonthBonusUser;
+use common\models\Config;
+use common\models\PerfCompany;
+use common\models\PerfMonth;
+use common\models\PerfPeriod;
+use common\models\Period;
+use common\models\DeclarationLevel;
+use common\models\EmployLevel;
+use common\models\FlowBonus;
+use common\models\ScoreMonth;
+use common\models\StarCrownLevel;
+use yii\base\BaseObject;
+use yii\base\Exception;
+use yii\base\StaticInstanceTrait;
+use yii\helpers\Json;
+use yii\db\Query;
+
+class CalcServeBonusCalc extends BaseObject {
+    use StaticInstanceTrait;
+
+    private $_limit = 10000;
+    private $_handleUserId;
+    private $_companyMonthPerf = 0;
+    private $_cfTotalPercent = 0;
+    private $_lxTotalPercent = 0;
+    private $_sysConfig = [];
+    private $_decLevelConfig = [];
+    private $_empLevelConfig = [];
+    private $_starCrownLevelConfig = [];
+    private $_decRoleConfig = [];
+    private $_errors = [];
+    private $_periodNum = 0;
+    private $_periodId;
+    private $_isCalcMonth = 0;
+    private $_calcYear;
+    private $_calcMonth;
+    private $_calcYearMonth;
+    private $_calcMonthPeriodNumCount = 0;
+    //pv
+    private $_pvRatio;
+    private $_calcZone = ['openTravel', 'openCar', 'openHouse'];
+
+    const LOOP_FINISH = 1;
+    const LOOP_CONTINUE = 2;
+
+    const ORDER_TYPE_TO_FW_COEFFICIENT = [
+        'ZC' => 'fwCoefficientFromZc',
+        'FX_CASH' => 'fwCoefficientFromFxCash',
+        'FX_POINT' => 'fwCoefficientFromFxPoint',
+    ];
+
+    //最小报单pv
+    const MIN_BD_PV = 980;
+
+    public function init() {
+        parent::init();
+    }
+
+    /**
+     * 设置期数
+     * @param int $periodNum
+     * @return int
+     */
+    public function setPeriodNum(int $periodNum) {
+        return $this->_periodNum = $periodNum;
+    }
+
+    /**
+     * 获取期数
+     * @return int
+     */
+    public function getPeriodNum() {
+        return $this->_periodNum;
+    }
+
+    /**
+     * 加入错误错误
+     * @param $attr
+     * @param $error
+     */
+    public function addError($attr, $error) {
+        $this->_errors[$attr][] = $error;
+    }
+
+    /**
+     * 获取错误信息
+     * @return array
+     */
+    public function getErrors() {
+        return $this->_errors;
+    }
+
+    /**
+     * 开始执行结算步骤
+     * @param $periodNum
+     * @param null $handleUserId
+     * @return bool
+     */
+    public function calcStep($periodNum, $handleUserId = null) {
+        try {
+            $this->_errors = [];
+            $this->setPeriodNum($periodNum);
+            $this->_handleUserId = $handleUserId;
+            $t1 = microtime(true);
+            // 初始化结算任务
+            $this->initCalcTask();
+            // 设置结算状态
+            $this->setCalcStatus('start');
+            // 清空所有本期结算用到的缓存
+            CalcCache::clearCalcBonusCache($this->_periodNum);
+            // 清空相关表数据
+            $this->clearCalcTableData();
+            $t2 = microtime(true);
+            echo('初始化、清空缓存及相关数据表完成,耗时:' . round($t2 - $t1, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+            $t3 = microtime(true);
+            $this->_updatePercent(10);
+            // 奖金部分
+            if($this->_sysConfig['openFW']['VALUE']) {
+                $this->calcBonusBDStepOne();
+                $this->calcBonusBDStepTwo();
+            }
+            $t4 = microtime(true);
+            echo('计算服务奖'.($this->_sysConfig['openFW']['VALUE']?'完成':'关闭').',耗时:' . round($t4 - $t3, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+            $this->_updatePercent(15);
+
+            // 销售奖/推广奖
+            if($this->_sysConfig['openTG']['VALUE']) {
+                $this->calcBonusTG();
+            }
+            $t5 = microtime(true);
+            echo('计算推广奖'.($this->_sysConfig['openTG']['VALUE']?'完成':'关闭').',耗时:' . round($t5 - $t4, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+            $this->_updatePercent(20);
+
+            $t6 = microtime(true);
+            // 绩效奖/团队奖
+            if($this->_sysConfig['openQY']['VALUE']) {
+                $this->calcBonusQY();
+            }
+            $t9 = microtime(true);
+            echo('计算团队奖'.($this->_sysConfig['openQY']['VALUE']?'完成':'关闭').',耗时:' . round($t9 - $t6, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+            $this->_updatePercent(65);
+
+            $t10 = microtime(true);
+            if($this->_sysConfig['openGL']['VALUE']) {
+                echo('计算蓝星奖开始,' . date('Y-m-d H:i:s', $t10) . PHP_EOL);
+                // 调用存储过程,计算蓝星管理奖金
+                $this->calcBsProcedure();
+                // 将有【蓝星业绩奖金】的用户加入到有奖金缓存用户中
+                $this->calcBonusBsYJ();
+                // 将有【蓝星管理奖金】的用户加入到有奖金缓存用户中
+                $this->calcBonusBsGL();
+            }
+            $t20 = microtime(true);
+            echo('计算蓝星奖'.($this->_sysConfig['openGL']['VALUE']?'完成':'关闭').',耗时:' . round($t20 - $t10, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+            $this->_updatePercent(67);
+
+//            $this->calcBonusTourism($this->_sysConfig['openTourism']);
+            $t21 = microtime(true);
+//            echo('计算旅游奖' . ($this->_sysConfig['openTourism']['VALUE'] ? '完成' : '关闭') . ',耗时:' . round($t21 - $t20, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+//            $this->_updatePercent(68);
+
+            $this->calcBonusVilla();
+            $t22 = microtime(true);
+            echo('计算房奖' . ($this->_sysConfig['openVilla']['VALUE'] ? '完成' : '关闭').',耗时:' . round($t22 - $t21, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL . PHP_EOL);
+            $this->_updatePercent(69);
+
+            $this->calcBonusGarage();
+            $t23 = microtime(true);
+            echo('计算车奖' . ($this->_sysConfig['openGarage']['VALUE'] ? '完成' : '关闭').',耗时:' . round($t23 - $t22, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL . PHP_EOL);
+            $this->_updatePercent(69);
+
+            // 计算季度奖
+            $this->calcQuarter();
+            // 将用户写入缓存
+            $this->calcQuarterUser();
+            $t24 = microtime(true);
+            echo('计算季度奖' . ($this->_sysConfig['openQuarter']['VALUE'] ? '完成' : '关闭').',耗时:' . round($t24 - $t23, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL . PHP_EOL);
+
+            //把奖金会员写入缓存
+            $this->loopMonthBonusUserFromDbToCache();
+            $t30 = microtime(true);
+            echo('奖金会员写入缓存完成,耗时:' . round($t30 - $t22, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+            $this->_updatePercent(70);
+
+            // 奖金写库
+            $this->loopBonusUsers();
+            // 入库完成,将各个奖金计算流水会员聘级,更新成蓝星奖当时计算的聘级
+            $this->loopCalcBlueEmpLv(); // @todo 调整,将蓝星奖放到第一个进行计算
+            $this->_updatePercent(75);
+            unset($calcWrite);
+            $t31 = microtime(true);
+            echo('奖金写库操作完成,耗时:' . round($t31 - $t30, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+
+            //把本期奖金会员入库 - 把缓存中的月奖用户信息存到数据库.存储过程的入库不在这里进行,这里代码取的缓存,存储过程没有缓存,在上面进行入库
+            $this->loopMonthBonusUserToDb();
+            $t32 = microtime(true);
+            echo('奖金会员入库完成,耗时:' . round($t32 - $t31, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+            $this->_updatePercent(80);
+
+            $t35 = microtime(true);
+            echo('结算全部完成,共耗时:' . round($t35 - $t32, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL . PHP_EOL);
+        } catch (\Exception $e) {
+            $this->errorCalcTask();
+            $this->addError('calc', sprintf('File【%s】, Line【%s】, Msg【%s】', $e->getFile(), $e->getLine(), $e->getMessage()));
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 结算完成
+     */
+    public function endCalcTask() {
+        // 更新结算状态
+        $this->setCalcStatus('end');
+    }
+
+    /**
+     * 结算错误
+     */
+    public function errorCalcTask() {
+        // 清空所有本期结算用到的缓存
+        CalcCache::clearCalcBonusCache($this->_periodNum);
+        // 更新结算状态
+        $this->setCalcStatus('fail');
+    }
+
+    /**
+     * 初始化结算任务
+     * @throws \yii\db\Exception
+     */
+    public function initCalcTask() {
+        $this->_sysConfig = Cache::getSystemConfig();
+        $this->_decLevelConfig = Cache::getDecLevelConfig();
+        $this->_empLevelConfig = Cache::getEmpLevelConfig();
+        $this->_starCrownLevelConfig = Cache::getStarCrownLevelConfig();
+        $this->_decRoleConfig = CalcCache::getDecRoleConfig($this->_periodNum);
+        $periodNum = $this->_periodNum;
+        // 获取本年月和上年月
+        $periodObj = Period::instance();
+        $periodDataArr = $periodObj->setPeriodNum($periodNum);
+        $this->_periodId = $periodDataArr['ID'];
+        $this->_isCalcMonth = $periodObj->isCalcMonth($periodNum);
+        $this->_calcYear = $periodObj->getYear($periodNum);
+        $this->_calcMonth = $periodObj->getMonth($periodNum);
+        $this->_calcYearMonth = $periodObj->getYearMonth($periodNum);
+    }
+
+    /**
+     * 设置结算状态
+     * @param $type
+     * start|end|fail
+     */
+    public function setCalcStatus($type) {
+        if ($type == 'start') {
+            Period::updateAll(['IS_CALCING' => 1, 'IS_CALCULATED' => Period::CALCULATE_NONE, 'CALCULATE_STARTED_AT' => Date::nowTime()], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]);
+        } elseif ($type == 'end') {
+            Period::updateAll(['IS_CALCING' => 0, 'IS_CALCULATED' => Period::CALCULATE_FINISH, 'CALCULATED_AT' => Date::nowTime()], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]);
+        } elseif ($type == 'fail') {
+            Period::updateAll(['IS_CALCING' => 0, 'IS_CALCULATED' => Period::CALCULATE_FAIL, 'CALCULATED_AT' => 0], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]);
+        }
+    }
+
+    /**
+     * 清空相关表数据
+     */
+    public function clearCalcTableData() {
+        // 奖金表
+        CalcBonus::pageDeleteAll('PERIOD_NUM='.$this->_periodNum);
+        CalcBonusQY::pageDeleteAll('PERIOD_NUM='.$this->_periodNum);
+        CalcBonusBD::pageDeleteAll('PERIOD_NUM='.$this->_periodNum); // 实际上是服务奖流水表
+        CalcBonusTG::pageDeleteAll('PERIOD_NUM='.$this->_periodNum);
+        // 月结时要清空的数据
+        if ($this->_isCalcMonth) {
+            CalcBonusTourism::pageDeleteAll('PERIOD_NUM='.$this->_periodNum);
+            CalcBonusGarage::pageDeleteAll('PERIOD_NUM='.$this->_periodNum);
+            CalcBonusVilla::pageDeleteAll('PERIOD_NUM='.$this->_periodNum);
+        }
+    }
+
+    /**
+     * 推广奖
+     * @param int $offset
+     * @return bool
+     * @throws \yii\db\Exception
+     */
+    public function calcBonusTG(int $offset = 0) {
+        $periodNum = $this->_periodNum;
+        // 从缓存获取分页有业绩的会员信息
+        $allData = CalcCache::getHasPerfUsers($this->_periodNum, $offset, $this->_limit);
+        if ($allData) {
+            $insertBonusData = [];
+            foreach ($allData as $userId) {
+                // 从缓存中获取会员的业绩信息
+                $perfData = CalcCache::nowPeriodPerf($userId, $periodNum);
+                if( !$perfData ) continue;
+                //个人业绩都算推荐奖,包括报单和复消、二次购物
+                $perfPv = $perfData['PV_PCS_ZC'] ?? 0;
+                if( $perfPv <= 0 ) continue;
+
+                //推广奖使用个人PCS
+                $recBonus = Tool::formatPrice($perfPv * $this->_sysConfig['recPercent']['VALUE'] / 100);
+                if ($recBonus <= 0) continue;
+                // 把对碰后的奖金存入缓存中
+                $perfUserInfo = CalcCache::getUserInfo($userId, $periodNum);
+                $bonusUserId = $perfUserInfo['REC_UID'] ?? '';
+                if( !$bonusUserId ) continue;
+
+                // 获取会员的报单级别
+                $userBaseInfo = CalcCache::getUserInfo($bonusUserId, $this->_periodNum);
+
+                //扣除相应的复消积分和管理费
+                $deductData = $this->deduct($bonusUserId, $recBonus);
+
+                CalcCache::bonus($bonusUserId, $periodNum, 'BONUS_TG', $recBonus, $deductData);
+
+                //来源会员信息
+                $fromUserInfo = CalcCache::getUserInfo($userId, $this->_periodNum);
+                //推广奖流水
+                $insertBonusData[] = [
+                    'ID' => SnowFake::instance()->generateId(),
+                    'USER_ID' => $bonusUserId,
+                    'LAST_DEC_LV' => $userBaseInfo['DEC_LV'],
+                    'LAST_EMP_LV' => $userBaseInfo['EMP_LV'],
+                    'LAST_STATUS' => $userBaseInfo['STATUS'],
+                    'FROM_USER_ID' => $userId,
+                    'LAST_FROM_DEC_LV' => $fromUserInfo['DEC_LV'],
+                    'LAST_FROM_EMP_LV' => $fromUserInfo['EMP_LV'],
+                    'LAST_FROM_STATUS' => $fromUserInfo['STATUS'],
+                    'AMOUNT' => $deductData['surplus'],
+                    'ORI_BONUS' => $recBonus,
+                    'RECONSUME_POINTS' => $deductData['reConsumePoints'],
+                    'MANAGE_TAX' => $deductData['manageTax'],
+                    'PERIOD_NUM' => $this->_periodNum,
+                    'CALC_YEAR' => $this->_calcYear,
+                    'CALC_MONTH' => $this->_calcYearMonth,
+                    'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH),
+                    'CREATED_AT' => Date::nowTime(),
+                    'LOGS' => json_encode([
+                        'perfPv' => $perfPv,
+                        'recPercentConfig' => $this->_sysConfig['recPercent']['VALUE'],
+                        'recNum' => $userBaseInfo['REC_NUM'],
+                        'decAmount' => $userBaseInfo['ZC_AMOUNT'],
+                        'decLevel' => $userBaseInfo['DEC_LV'],
+                        'bonusTotalLimit' => [
+                            $this->_sysConfig['bonusTotalZeroLimit']['VALUE'],
+                            $this->_sysConfig['bonusTotalOneLimit']['VALUE'],
+                            $this->_sysConfig['bonusTotalTwoLimit']['VALUE'],
+                        ],
+                    ]),
+                ];
+
+                unset($perfData, $perfPv, $perfUserInfo, $recBonus, $bonusUserId, $userBaseInfo, $userId, $deductData, $fromUserInfo);
+            }
+            CalcBonusTG::batchInsert($insertBonusData);
+            unset($allData, $insertBonusData);
+            return $this->calcBonusTG($offset + $this->_limit);
+        }
+        unset($allData);
+        return true;
+    }
+
+
+    /**
+     * 服务奖第一步
+     * @param int $offset
+     * @return bool
+     * @throws \yii\db\Exception
+     */
+    public function calcBonusBDStepOne(int $offset = 0) {
+        echo sprintf("时间:[%s]服务奖第【1】步,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
+        $periodNum = $this->_periodNum;
+        // 从缓存获取分页有业绩的会员信息
+        $allData = CalcCache::getHasPerfUsers($this->_periodNum, $offset, $this->_limit);
+        if ($allData) {
+            $insertBonusData = [];
+            foreach ($allData as $userId) {
+                // 从缓存中获取会员的业绩信息
+                $perfData = CalcCache::nowPeriodPerf($userId, $periodNum);
+                if( !$perfData ) continue;
+
+                //
+                $decRoleBonusFrom = explode(',', $this->_sysConfig['decRoleBonusFrom']['VALUE']);
+                $validPvPcs = 0;
+                foreach ($decRoleBonusFrom as $orderType) {
+                    $orderTypeName = sprintf('PV_PCS_%s', $orderType);
+                    $orderTypeValue = $perfData[$orderTypeName] ?? 0;
+
+                    $coefficientName = self::ORDER_TYPE_TO_FW_COEFFICIENT[$orderType];
+                    $coefficient = $this->_sysConfig[$coefficientName]['VALUE'] ?? 1;
+                    $validPvPcs += $orderTypeValue * $coefficient;
+
+                    unset($orderType, $orderTypeName, $orderTypeValue, $coefficientName, $coefficient);
+                }
+                unset($perfData, $decRoleBonusFrom);
+                if ( $validPvPcs <= 0 ) continue;
+
+                $this->loopRelationParentDo($userId, function ($parent) use($userId, $validPvPcs){
+
+                    //判断parent的报单中心级别 和 服务奖比例
+                    $bonusUserId = $parent['PARENT_UID'];
+                    //计算级别之后更新过userInfo的缓存,缓存中级别发生了变化
+                    $bonusUserInfo = CalcCache::getUserInfo($bonusUserId, $this->_periodNum);
+                    $isDec = $bonusUserInfo['IS_DEC'];
+                    if($isDec == 0) return self::LOOP_CONTINUE;
+                    $decRoleId = $bonusUserInfo['DEC_ROLE_ID'];
+                    if( !$decRoleId ) return self::LOOP_CONTINUE;
+                    if( !isset($this->_decRoleConfig[$decRoleId]) ) return self::LOOP_CONTINUE;
+
+                    $parentDecRoleLevel = $this->_decRoleConfig[$decRoleId];
+                    $parentFwBonusPercent = $parentDecRoleLevel['FW_BONUS_PERCENT'] ?? 0;
+                    $cacheMaxPercent = CalcCache::fwMaxBonusPercent($userId, $this->_periodNum);
+                    $diffPercent = $parentFwBonusPercent - $cacheMaxPercent;
+                    if( $diffPercent <= 0 ) return self::LOOP_CONTINUE;
+
+                    $fwBonus = $validPvPcs * $diffPercent / 100;
+                    if( $fwBonus <= 0  ) return self::LOOP_CONTINUE;
+
+                    //给本人添加服务奖比例
+                    CalcCache::fwMaxBonusPercent($userId, $this->_periodNum, $parentFwBonusPercent);
+                    //记录奖金和奖金来源到缓存 并实现在缓存中奖金累加
+                    CalcCache::saveFwBonusList($bonusUserId, $this->_periodNum, $fwBonus, ['fromUid'=>$userId, 'fromPvPcs'=>$validPvPcs]);
+                    CalcCache::addHasFwBonusUsers($bonusUserId, $this->_periodNum);
+
+                    unset($bonusUserId, $bonusUserInfo, $isDec, $decRoleId, $parentDecRoleLevel, $parentFwBonusPercent, $cacheMaxPercent, $diffPercent, $fwBonus);
+                });
+
+                unset($userId, $validPvPcs);
+            }
+            unset($allData, $insertBonusData);
+            return $this->calcBonusBDStepOne($offset + $this->_limit);
+        }
+        unset($allData);
+        return true;
+    }
+
+    /**
+     * 服务奖第二步
+     * @param int $offset
+     * @return bool
+     * @throws \yii\db\Exception
+     */
+    public function calcBonusBDStepTwo(int $offset = 0) {
+        echo sprintf("时间:[%s]服务奖第【2】步,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
+
+        $allData = CalcCache::getHasFwBonusUsers($this->_periodNum, $offset, $this->_limit);
+        if ($allData) {
+            $insertBonusData = [];
+            foreach ($allData as $userId) {
+                $fwBonusData = CalcCache::getFwBonusList($userId, $this->_periodNum);
+                if( !$fwBonusData ) continue;
+                $fwBonus = $fwBonusData['fwBonus'] ?? 0;
+                if( $fwBonus <=0  ) continue;
+                //总金额限制
+                $userBaseInfo = CalcCache::getUserInfo($userId, $this->_periodNum);
+
+                CalcCache::bonus($userId, $this->_periodNum, 'BONUS_BD', $fwBonus);
+
+                $decRoleId = $userBaseInfo['DEC_ROLE_ID'];
+                $insertBonusData[] = [
+                    'ID' => SnowFake::instance()->generateId(),
+                    'USER_ID' => $userId,
+                    'LAST_DEC_LV' => $userBaseInfo['DEC_LV'],
+                    'LAST_EMP_LV' => $userBaseInfo['EMP_LV'],
+                    'LAST_STATUS' => $userBaseInfo['STATUS'],
+                    'FROM_USER_ID' => $userId,
+                    'LAST_FROM_DEC_LV' => $userBaseInfo['DEC_LV'],
+                    'LAST_FROM_EMP_LV' => $userBaseInfo['EMP_LV'],
+                    'LAST_FROM_STATUS' => $userBaseInfo['STATUS'],
+                    'AMOUNT' => $fwBonus,
+                    'ORI_BONUS' => $fwBonus,
+                    'RECONSUME_POINTS' => 0,
+                    'MANAGE_TAX' => 0,
+                    'PERIOD_NUM' => $this->_periodNum,
+                    'CALC_YEAR' => $this->_calcYear,
+                    'CALC_MONTH' => $this->_calcYearMonth,
+                    'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH),
+                    'CREATED_AT' => Date::nowTime(),
+                    'LOGS' => json_encode([
+                        'decRoleId' => $decRoleId,
+                    ])
+                ];
+
+                unset($userId, $fwBonusData, $userBaseInfo, $decRoleId, $fwBonus);
+
+            }
+
+            CalcBonusBD::batchInsert($insertBonusData);
+            unset($insertBonusData, $allData);
+            $this->calcBonusBDStepTwo($offset + $this->_limit);
+        }
+
+        unset($allData);
+        return true;
+    }
+
+    /**
+     * 团队奖
+     * @param int $offset
+     * @return bool
+     * @throws \yii\db\Exception
+     */
+    public function calcBonusQY(int $offset = 0) {
+        echo sprintf("时间:[%s]团队奖,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
+        $periodNum = $this->_periodNum;
+        // 从缓存获取分页有业绩的会员信息
+        $allData = CalcCache::getHasPerfUsers($this->_periodNum, $offset, $this->_limit);
+        if ($allData) {
+            $insertBonusData = [];
+            foreach ($allData as $userId) {
+                // 从缓存中获取会员的业绩信息
+                $perfData = CalcCache::nowPeriodPerf($userId, $periodNum);
+                // 从缓存中获取会员的上期结余业绩信息
+                $pervSurplusPerf = CalcCache::surplusPerf($userId, $periodNum);
+                // 本期 + 上期结余
+                $perfArr = [
+                    'SURPLUS_1L' => $perfData['PV_1L_TOUCH'] + $pervSurplusPerf['SURPLUS_1L'],
+                    'SURPLUS_2L' => $perfData['PV_2L_TOUCH'] + $pervSurplusPerf['SURPLUS_2L'],
+                    'SURPLUS_3L' => $perfData['PV_3L_TOUCH'] + $pervSurplusPerf['SURPLUS_3L'],
+                    'SURPLUS_4L' => $perfData['PV_4L_TOUCH'] + $pervSurplusPerf['SURPLUS_4L'],
+                    'SURPLUS_5L' => $perfData['PV_5L_TOUCH'] + $pervSurplusPerf['SURPLUS_5L'],
+                ];
+                $oriPerfArr = [
+                    'perfArr' => $perfArr,
+                    'touchBonus' => 0,
+                ];
+
+                // 获取会员的报单级别
+                $userBaseInfo = CalcCache::getUserInfo($userId, $this->_periodNum);
+                $decLevelConfig = $this->_decLevelConfig;
+                $nowDecLevelConfig = $decLevelConfig[$userBaseInfo['DEC_LV']];
+                // 对碰
+                $touchBonusArr = $this->touchPerf($oriPerfArr, $perfArr, $nowDecLevelConfig['QY_PERCENT']/100);
+                $touchPerfArr = [];
+                foreach ($touchBonusArr['perfArr'] as $keyR => $perfR) {
+                    $touchPerfArr[$keyR] = $perfR;
+                }
+                // 对碰完成后把结余的业绩存入本期业绩缓存中
+                CalcCache::nowPeriodPerf($userId, $periodNum, $touchPerfArr);
+                //更新数据库
+                PerfPeriod::updateAll($touchPerfArr, 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', [
+                    'USER_ID' => $userId,
+                    'PERIOD_NUM' => $periodNum,
+                ]);
+                if ($touchBonusArr['touchBonus'] <= 0) continue;
+
+                $teamBonus = $touchBonusArr['touchBonus'];
+                $capBonusQy = $teamBonus; // 封顶前的奖金
+                //判断级别上限,个人奖金封顶限制
+                $teamBonus = $this->declarationLevelCap($teamBonus, $userId, $userBaseInfo['DEC_LV']);
+                if( $teamBonus <= 0 ) continue;
+                // 将封顶前的金额加入用户奖金缓存中,此金额不能发放(总奖金,总实际奖金) 
+                CalcCache::bonus($userId, $periodNum, 'CAPPED_BONUS_QY', $capBonusQy); 
+
+                //扣除相应的复消积分和管理费
+                $deductData = $this->deduct($userId, $teamBonus);
+
+                // 把对碰后的奖金存入缓存中
+                CalcCache::bonus($userId, $periodNum, 'BONUS_QY', $teamBonus, $deductData);
+
+                // TODO:取小腿值
+                $payLeg = min([$perfArr['SURPLUS_1L'], $perfArr['SURPLUS_2L']]);
+                // 计算荣衔星级
+                $starCrown = StarCrownLevel::getStarCrown($payLeg);
+                // 星级放入缓存
+                CalcCache::addUserStarCrown($userId, $periodNum, $starCrown['ID']);
+
+                //团队奖流水
+                $insertBonusData[] = [
+                    'ID' => SnowFake::instance()->generateId(),
+                    'USER_ID' => $userId,
+                    'ORI_CAPPED_BONUS_QY' => $capBonusQy,
+                    'LAST_DEC_LV' => $userBaseInfo['DEC_LV'],
+                    'LAST_EMP_LV' => $userBaseInfo['EMP_LV'],
+                    'LAST_CROWN_LV' => $starCrown['ID'],
+                    'LAST_STATUS' => $userBaseInfo['STATUS'],
+                    'AMOUNT' => $deductData['surplus'],
+                    'ORI_BONUS' => $teamBonus,
+                    'RECONSUME_POINTS' => $deductData['reConsumePoints'],
+                    'MANAGE_TAX' => $deductData['manageTax'],
+                    'PERIOD_NUM' => $this->_periodNum,
+                    'CALC_YEAR' => $this->_calcYear,
+                    'CALC_MONTH' => $this->_calcYearMonth,
+                    'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH),
+                    'CREATED_AT' => Date::nowTime(),
+                    'LOGS' => json_encode([
+                        'perfArr' => $perfArr,
+                        'touchPerfArrOri' => $touchBonusArr['perfArr'],
+                        'touchPerfArr' => $touchPerfArr,
+                        'nowDecLevelConfig' => $nowDecLevelConfig,
+                        'decLevel' => $userBaseInfo['DEC_LV'],
+                    ]),
+                ];
+
+                unset($perfData, $pervSurplusPerf, $perfArr, $oriPerfArr, $touchPerfArr, $userBaseInfo, $decLevelConfig, $touchBonusArr, $userId, $nowDecLevelConfig, $teamBonus, $deductData);
+            }
+            CalcBonusQY::batchInsert($insertBonusData);
+            unset($allData, $insertBonusData);
+            return $this->calcBonusQY($offset + $this->_limit);
+        }
+        unset($allData);
+        return true;
+    }
+
+    /**
+     * 季度奖计算
+     *
+     */
+    public function calcQuarter() {
+        if( !$this->_isCalcMonth || !in_array($this->_calcMonth, [3,6,9,12])) {
+        // echo('不是季结点,进这里,不计算季度奖'. PHP_EOL);
+            return false;
+        }
+        $result = \Yii::$app->db->createCommand("CALL QtrCalc(:periodNum)")
+            ->bindValue(':periodNum' , $this->_periodNum )
+            ->execute();
+
+        return $result;
+    }
+
+    // 执行蓝星管理奖金的存储过程
+    public function calcBsProcedure() {
+        if( !$this->_isCalcMonth ) {
+            // 不是结算月,则不进行计算
+            return false;
+        }
+        $result = \Yii::$app->db->createCommand("CALL CalcBlue(:periodNum)") 
+                      ->bindValue(':periodNum' , $this->_periodNum )
+                      ->execute();
+                      
+        return $result;
+    }
+
+    // 执行旅游奖的计算
+    public function calcBonusTourism() {
+        // 月结,如果不是月结点,则直接退出
+        if (!$this->_isCalcMonth) {
+            return true;
+        }
+
+        $bonusConfig = $this->_sysConfig['openTourism'];
+        // 达标条件:聘级、级别、奖项比例
+        $config = json_decode($bonusConfig['OPTIONS'], true);
+        // 奖金总比例
+        $mate = $bonusConfig['VALUE'] / 100;
+        // 会员级别
+        $minDecLevel = $config['OPTIONS']['declarationLevel'] ?? [];
+        // 月度公司总PV
+        $monthTotalPV = PerfMonth::find()
+            ->yearMonth($this->_calcYearMonth)
+            ->where('CALC_MONTH=:CALC_MONTH', [':CALC_MONTH' => $this->_calcYearMonth])
+            ->sum('PV_PCS');
+        // 用于分发的奖金总数
+        $transferAmount = $monthTotalPV * $mate;
+
+        // 基于蓝星奖结果计算符合获奖条件的会员StarDirector
+        $userStarDirector = CalcBonusBS::find()
+            ->yearMonth($this->_calcYearMonth)
+            ->where('CALC_MONTH=:CALC_MONTH', [':CALC_MONTH' => $this->_calcYearMonth])
+            ->select('USER_ID,LEVEL_ID,LAST_DEC_LV,LAST_EMP_LV,LAST_STATUS')
+            ->groupBy('USER_ID')
+            ->asArray()
+            ->all();
+        $userStarDirectorObj = array_column($userStarDirector, NULL, 'USER_ID');
+
+        // 基于团队奖/绩效奖结果计算会员的StarCrown
+        $userStarCrown = CalcBonusQY::find()
+            ->yearMonth($this->_calcYearMonth)
+            ->where('CALC_MONTH=:CALC_MONTH', [':CALC_MONTH' => $this->_calcYearMonth])
+            ->select('USER_ID,LAST_CROWN_LV')
+            ->groupBy('USER_ID')
+            ->asArray()
+            ->all();
+        $userStarCrownObj = array_column($userStarCrown, NULL, 'USER_ID');
+
+        // 合并用户ID,去重
+        $bonusUsers = array_unique(array_merge(array_keys($userStarDirectorObj), array_keys($userStarCrownObj)));
+
+        // 奖金点数综合
+        $bonusPointComplex = 0;
+        $insertBonusData = [];
+        foreach($bonusUsers as $userId) {
+            // 计算奖金:取starDirectorPoint和starCrownPoint的大个值
+            $starDirectorPoint = $this->_empLevelConfig[$userStarDirectorObj[$userId]['LEVEL_ID']]['TOURISM_PERCENT'] ?? 0;
+            $starCrownPoint = $this->_starCrownLevelConfig[$userStarCrownObj[$userId]['LAST_CROWN_LV']]['TOURISM_PERCENT'] ?? 0;
+            // 奖金比例:
+            $bonusPoint = max($starDirectorPoint, $starCrownPoint);
+            if ($bonusPoint <= 0) {
+                continue;
+            }
+            
+            $insertBonusData[] = [
+                'ID' => SnowFake::instance()->generateId(),
+                'USER_ID' => $userId,
+                'LAST_DEC_LV' => $userStarDirectorObj[$userId]['LAST_DEC_LV'],
+                'LAST_EMP_LV' => $userStarDirectorObj[$userId]['LAST_EMP_LV'],
+                'LAST_STATUS' => $userStarDirectorObj[$userId]['LAST_STATUS'],
+                'LAST_CROWN_LV' => $userStarCrownObj[$userId]['LAST_CROWN_LV'],
+                'AMOUNT_STANDARD' => 0,
+                'POINT' => $bonusPoint,
+                'PERIOD_NUM' => $this->_periodNum,
+                'CALC_YEAR' => $this->_calcYear,
+                'CALC_MONTH' => $this->_calcYearMonth,
+                'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH),
+                'CREATED_AT' => Date::nowTime(),
+                'PERF' => $monthTotalPV,
+                'TRANSFER_RATE' => $mate,
+                'TRANSFER_AMOUNT' => Tool::formatPrice($transferAmount),
+                'CAP_AMOUNT' => 0,
+                'POINT_COMPLEX' => 0,
+            ];
+
+            $bonusPointComplex += $bonusPoint;
+        }
+
+        // 数据写入总表
+        if ($insertBonusData) {
+            foreach ($insertBonusData as &$bonusData) {
+                // 计算奖金
+                $amount = Tool::formatPrice($transferAmount * ($bonusData['POINT'] / $bonusPointComplex));
+                if ($amount <= 0) {
+                    continue;
+                }
+
+                // 会员级别达到要求才会发放奖金
+                if ($bonusData['LAST_DEC_LV'] == $minDecLevel) {
+                    // 放入缓存
+                    CalcCache::tourismBonus($bonusData['USER_ID'], $this->_periodNum, $amount);
+                    // 加入月奖的会员
+                    CalcCache::addHasMonthBonusUsers($bonusData['USER_ID'], $this->_periodNum);
+                }
+
+                $bonusData['AMOUNT'] = $amount;
+                $bonusData['POINT_COMPLEX'] = $bonusPointComplex;
+            }
+
+            CalcBonusTourism::batchInsert($insertBonusData);
+        }
+
+        return true;
+    }
+
+    // 执行房奖的计算
+    public function calcBonusVilla() {
+        // 月结,如果不是月结点,则直接退出
+        if (!$this->_isCalcMonth) {
+            return true;
+        }
+
+        $bonusConfig = $this->_sysConfig['openVilla'];
+        // 达标条件:聘级、级别、奖项比例
+        $config = json_decode($bonusConfig['OPTIONS'], true);
+        // 奖金总比例
+        $mate = $bonusConfig['VALUE'] / 100;
+        // 个人奖金封顶
+        $capBonus = intval($this->_sysConfig['openVillaCap']['VALUE'] ?? 0);
+        // 会员级别
+        $minDecLevel = $config['declarationLevel'] ?? [];
+
+        // 月度公司总PV
+        $monthTotalPV = PerfMonth::find()
+            ->yearMonth($this->_calcYearMonth)
+            ->where('CALC_MONTH=:CALC_MONTH', [':CALC_MONTH' => $this->_calcYearMonth])
+            ->sum('PV_PCS');
+        // 用于分发的奖金总数
+        $transferAmount = $monthTotalPV * $mate;
+
+        // 基于团队奖/绩效奖结果计算会员的StarCrown.StarCrown基于周期计算,一个月会产生多次,取月周期中的最高星级
+        $subQuery = CalcBonusQY::find()
+            ->yearMonth($this->_calcYearMonth)
+            ->where('CALC_MONTH = :CALC_MONTH AND LAST_CROWN_LV <> :NO_CROWN_LV', [':CALC_MONTH' => $this->_calcYearMonth, ':NO_CROWN_LV' => StarCrownLevel::NO_LEVEL_ID])
+            ->select('USER_ID,LAST_DEC_LV,LAST_CROWN_LV,LAST_STATUS,LEVEL_NAME,SORT')
+            ->joinWith(['starCrown' => function($query) {
+                $query->select(['LEVEL_NAME', 'SORT']);
+            }])
+            ->having(1)
+            ->orderBy('USER_ID ASC, SORT DESC');
+        $userStarCrownObj = (new Query())->from(['u' => $subQuery])->select('USER_ID,LAST_DEC_LV,LAST_CROWN_LV,LAST_STATUS,LEVEL_NAME,SORT')->groupBy('USER_ID')->indexBy('USER_ID')->all();
+
+        // 奖金点数综合
+        $bonusPointComplex = 0;
+        $insertBonusData = [];
+        foreach($userStarCrownObj as $item) {
+            // 奖金比例
+            $bonusPoint = $this->_starCrownLevelConfig[$item['LAST_CROWN_LV']]['VILLA_PERCENT'] ?? 0;
+            if (!$bonusPoint) {
+                continue;
+            }
+
+            // 会员级别达到要求才会发放奖金
+            if ($item['LAST_DEC_LV'] != $minDecLevel) {
+                continue;
+            }
+
+            $insertBonusData[] = [
+                'ID' => SnowFake::instance()->generateId(),
+                'USER_ID' => $item['USER_ID'],
+                'LAST_DEC_LV' => $item['LAST_DEC_LV'] ?? '',
+                'LAST_EMP_LV' => $item['LAST_EMP_LV'] ?? '',
+                'LAST_STATUS' => $item['LAST_STATUS'] ?? 0,
+                'LAST_CROWN_LV' => $item['LAST_CROWN_LV'] ?? '',
+                'AMOUNT' => 0,
+                'POINT' => $bonusPoint,
+                'PERIOD_NUM' => $this->_periodNum,
+                'CALC_YEAR' => $this->_calcYear,
+                'CALC_MONTH' => $this->_calcYearMonth,
+                'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH),
+                'CREATED_AT' => Date::nowTime(),
+                'PERF' => $monthTotalPV,
+                'TRANSFER_RATE' => $mate,
+                'TRANSFER_AMOUNT' => Tool::formatPrice($transferAmount),
+                'CAP_AMOUNT' => 0,
+                'POINT_COMPLEX' => 0,
+            ];
+
+            $bonusPointComplex += $bonusPoint;
+        }
+
+        // 数据写入总表
+        if ($insertBonusData) {
+            // 计算个人奖金
+            foreach ($insertBonusData as &$bonusData) {
+                // 计算奖金
+                $amount = Tool::formatPrice($transferAmount * ($bonusData['POINT'] / $bonusPointComplex));
+                if ($amount <= 0) {
+                    continue;
+                }
+                // 封顶前奖金数
+                $capAmount = $amount;
+                // 奖金数不能大于封顶值
+                $amount = ($amount > $capBonus) ? $capBonus : $amount;
+
+                $bonusData['AMOUNT'] = $amount;
+                $bonusData['CAP_AMOUNT'] = $capAmount;
+                $bonusData['POINT_COMPLEX'] = $bonusPointComplex;
+
+                // 放入缓存
+                CalcCache::villaBonus($bonusData['USER_ID'], $this->_periodNum, $amount);
+                // 加入月奖的会员
+                CalcCache::addHasMonthBonusUsers($bonusData['USER_ID'], $this->_periodNum);
+            }
+
+            CalcBonusVilla::batchInsert($insertBonusData);
+        }
+
+        return true;
+    }
+
+    // 执行车奖的计算
+    public function calcBonusGarage() {
+        // 月结,如果不是月结点,则直接退出
+        if (!$this->_isCalcMonth) {
+            return true;
+        }
+
+        $bonusConfig = $this->_sysConfig['openGarage'];
+        // 达标条件:聘级、级别、奖项比例
+        $config = json_decode($bonusConfig['OPTIONS'], true);
+        // 奖金总比例
+        $mate = $bonusConfig['VALUE'] / 100;
+        // 会员级别
+        $minDecLevel = $config['declarationLevel'] ?? [];
+        // 个人奖金封顶
+        $capBonus = intval($this->_sysConfig['openGarageCap']['VALUE'] ?? 0);
+
+        // 月度公司总PV
+        $monthTotalPV = PerfMonth::find()
+            ->yearMonth($this->_calcYearMonth)
+            ->where('CALC_MONTH=:CALC_MONTH', [':CALC_MONTH' => $this->_calcYearMonth])
+            ->sum('PV_PCS');
+        // 用于分发的奖金总数
+        $transferAmount = $monthTotalPV * $mate;
+
+        // 基于蓝星奖结果计算符合获奖条件的会员StarDirector
+        $userStarDirector = CalcBonusBS::find()
+            ->yearMonth($this->_calcYearMonth)
+            ->where('CALC_MONTH = :CALC_MONTH', [':CALC_MONTH' => $this->_calcYearMonth])
+            ->select('USER_ID,LEVEL_ID,LAST_DEC_LV,LAST_STATUS')
+            ->groupBy('USER_ID')
+            ->asArray()
+            ->all();
+        $userStarDirectorObj = array_column($userStarDirector, NULL, 'USER_ID');
+
+        // 基于团队奖/绩效奖结果计算会员的StarCrown.StarCrown基于周期计算,一个月会产生多次,取月周期中的最高星级
+        $subQuery = CalcBonusQY::find()
+            ->yearMonth($this->_calcYearMonth)
+            ->where('CALC_MONTH = :CALC_MONTH AND LAST_CROWN_LV <> :NO_CROWN_LV', [':CALC_MONTH' => $this->_calcYearMonth, ':NO_CROWN_LV' => StarCrownLevel::NO_LEVEL_ID])
+            ->select('USER_ID,LAST_DEC_LV,LAST_CROWN_LV,LAST_STATUS,LEVEL_NAME,SORT')
+            ->joinWith(['starCrown' => function($query) {
+                $query->select(['LEVEL_NAME', 'SORT']);
+            }])
+            ->having(1)
+            ->orderBy('USER_ID ASC, SORT DESC');
+        $userStarCrownObj = (new Query())->from(['u' => $subQuery])->select('USER_ID,LAST_DEC_LV,LAST_CROWN_LV,LAST_STATUS,LEVEL_NAME,SORT')->groupBy('USER_ID')->indexBy('USER_ID')->all();
+        
+        // 合并用户ID,去重
+        $bonusUsers = array_unique(array_merge(array_keys($userStarDirectorObj), array_keys($userStarCrownObj)));
+        sort($bonusUsers);
+
+        // 奖金点数综合
+        $bonusPointComplex = 0;
+        $insertBonusData = [];
+        foreach($bonusUsers as $userId) {
+            // 计算奖金:取starDirectorPoint和starCrownPoint的大个值
+            $starDirectorPoint = !isset($userStarDirectorObj[$userId]['LEVEL_ID']) ? 0 : ($this->_empLevelConfig[$userStarDirectorObj[$userId]['LEVEL_ID']]['GARAGE_PERCENT'] ?? 0);
+            $starCrownPoint = !isset($userStarCrownObj[$userId]['LAST_CROWN_LV']) ? 0: ($this->_starCrownLevelConfig[$userStarCrownObj[$userId]['LAST_CROWN_LV']]['GARAGE_PERCENT'] ?? 0);
+            // 奖金比例:
+            $bonusPoint = max($starDirectorPoint, $starCrownPoint);
+            if ($bonusPoint <= 0) {
+                continue;
+            }
+
+            // 会员级别达到要求才会发放奖金
+            $lastDecLv = $userStarDirectorObj[$userId]['LAST_DEC_LV'] ?? ($userStarCrownObj[$userId]['LAST_DEC_LV'] ?? '');
+            if ($lastDecLv != $minDecLevel) {
+                continue;
+            }
+
+            $insertBonusData[] = [
+                'ID' => SnowFake::instance()->generateId(),
+                'USER_ID' => $userId,
+                'LAST_DEC_LV' => $userStarDirectorObj[$userId]['LAST_DEC_LV'] ?? ($userStarCrownObj[$userId]['LAST_DEC_LV'] ?? ''),
+                'LAST_EMP_LV' => $userStarDirectorObj[$userId]['LEVEL_ID'] ?? '',
+                'LAST_STATUS' => $userStarDirectorObj[$userId]['LAST_STATUS'] ?? ($userStarCrownObj[$userId]['LAST_STATUS'] ?? 1),
+                'LAST_CROWN_LV' => $userStarCrownObj[$userId]['LAST_CROWN_LV'] ?? '',
+                'AMOUNT' => 0,
+                'POINT' => $bonusPoint,
+                'PERIOD_NUM' => $this->_periodNum,
+                'CALC_YEAR' => $this->_calcYear,
+                'CALC_MONTH' => $this->_calcYearMonth,
+                'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH),
+                'CREATED_AT' => Date::nowTime(),
+                'PERF' => $monthTotalPV,
+                'TRANSFER_RATE' => $mate,
+                'TRANSFER_AMOUNT' => Tool::formatPrice($transferAmount),
+                'CAP_AMOUNT' => 0,
+                'POINT_COMPLEX' => 0,
+            ];
+
+            $bonusPointComplex += $bonusPoint;
+        }
+
+        // 数据写入总表
+        if ($insertBonusData) {
+            foreach ($insertBonusData as &$bonusData) {
+                // 计算奖金
+                $amount = Tool::formatPrice($transferAmount * ($bonusData['POINT'] / $bonusPointComplex));
+                if ($amount <= 0) {
+                    continue;
+                }
+                // 封顶前奖金数
+                $capAmount = $amount;
+                // 奖金数不能大于封顶值
+                $amount = ($amount > $capBonus) ? $capBonus : $amount;
+
+                $bonusData['AMOUNT'] = $amount;
+                $bonusData['CAP_AMOUNT'] = $capAmount;
+                $bonusData['POINT_COMPLEX'] = $bonusPointComplex;
+
+                // 放入缓存
+                CalcCache::garageBonus($bonusData['USER_ID'], $this->_periodNum, $amount);
+                // 加入月奖的会员
+                CalcCache::addHasMonthBonusUsers($bonusData['USER_ID'], $this->_periodNum);
+            }
+
+            CalcBonusGarage::batchInsert($insertBonusData);
+        }
+
+        return true;
+    }
+
+    /**
+     * 季度奖写用户缓存
+     *
+     */
+    public function calcQuarterUser(int $offset = 0) {
+        if( !$this->_isCalcMonth || !in_array($this->_calcMonth, [3,6,9,12])) {
+            // 不是结算月,则不进行计算
+            return false;
+        }
+        $allData = CalcBonusQuarter::finduseDbCalc()
+                ->where('PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum])
+                ->groupBy('USER_ID')
+                ->offset($offset)
+                ->limit($this->_limit)
+                ->asArray()
+                ->all();
+        if ($allData){
+            // 达标条件:会员级别:钻卡
+            $config = json_decode($this->_sysConfig['openQuarter']['OPTIONS'], true);
+            $minDecLevel = $config['declarationLevel'] ?? [];
+
+            foreach ($allData as $user) {
+                // 扣除相应的复消积分和管理费
+                $deductData = $this->deduct($user['USER_ID'], $user['ORI_BONUS']);
+                $realBonusBs = $deductData['surplus']; // 扣除管理费和复消积分后的实发蓝星奖金
+                $manageTax = $deductData['manageTax']; // 管理费
+                $point = $deductData['reConsumePoints'] + $user['RECONSUME_POINTS'];// 复消积分
+                // 管理奖钻卡发放
+                if ($user['LAST_DEC_LV'] == $minDecLevel) {
+                    // 把对碰后的奖金存入缓存中
+                    CalcCache::bonus($user['USER_ID'], $this->_periodNum, 'BONUS_QUARTER', $user['ORI_BONUS'], $deductData);
+                    // 加入月奖的会员
+                    CalcCache::addHasMonthBonusUsers($user['USER_ID'], $this->_periodNum);
+                }
+
+                // 更新奖金存储过程的实发金额数据
+                CalcBonusQuarter::updateAll([
+                    'RECONSUME_POINTS' => $point,
+                    'AMOUNT' => $realBonusBs,
+                    'MANAGE_TAX' => $manageTax],
+                    'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM',
+                    [':USER_ID' => $user['USER_ID'], ':PERIOD_NUM' => $this->_periodNum]);
+            }
+            return $this->calcQuarterUser($offset + $this->_limit);
+        }
+        unset($allData);
+        return true;
+    }
+
+    /**
+     * 蓝星管理奖金
+     * @param int $offset
+     * @return bool
+     * @throws \yii\db\Exception
+     */
+    public function calcBonusBsGL(int $offset = 0) {
+        if( !$this->_isCalcMonth ) {
+            // 不是结算月,则不进行计算
+            return false;
+        }
+        // 从缓存获取分页有收入的会员信息
+        $allData = CalcBonusBS::findUseDbCalc()
+            ->where('PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum])
+            ->groupBy('USER_ID')
+            ->offset($offset)
+            ->limit($this->_limit)
+            ->asArray()
+            ->all();
+        if ($allData) {
+            // 达标条件:会员级别:钻卡
+            $config = json_decode($this->_sysConfig['openGL']['OPTIONS'], true);
+            $minDecLevel = $config['mntDec'] ?? [];
+
+            foreach ($allData as $user) {
+                //扣除相应的复消积分和管理费
+                $deductData = $this->deduct($user['USER_ID'], $user['ORI_BONUS_MNT']);
+                $realBonusBs = $deductData['surplus']; // 扣除管理费和复消积分后的实发蓝星奖金
+                $manageTax = $deductData['manageTax']; // 管理费
+                $point = $deductData['reConsumePoints'] + $user['RECONSUME_POINTS'];// 复消积分
+
+                // 管理奖钻卡发放
+//                if (in_array($user['LAST_DEC_LV'], $minDecLevel)) {
+                    // 把对碰后的奖金存入缓存中
+                    CalcCache::bonus($user['USER_ID'], $this->_periodNum, 'BONUS_BS_MNT', $user['ORI_BONUS_MNT'], $deductData);
+                    // 加入月奖的会员
+                    CalcCache::addHasMonthBonusUsers($user['USER_ID'], $this->_periodNum);
+//                }
+
+                // 更新蓝星奖金存储过程的实发金额数据
+                CalcBonusBS::updateAll([
+                    'RECONSUME_POINTS' => $point,
+                    'AMOUNT_MNT' => $realBonusBs,
+                    'MANAGE_TAX_MNT' => $manageTax],
+                'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', 
+                [':USER_ID' => $user['USER_ID'], ':PERIOD_NUM' => $this->_periodNum]);
+            }
+            return $this->calcBonusBsGL($offset + $this->_limit);
+        }
+        unset($allData);
+        return true;
+    }
+
+    /**
+     * 蓝星业绩奖金
+     * @param int $offset
+     * @return bool
+     * @throws \yii\db\Exception
+     */
+    public function calcBonusBsYJ(int $offset = 0) {
+        if( !$this->_isCalcMonth ) {
+            // 不是结算月,则不进行计算
+            return false;
+        }
+        // 从缓存获取分页有收入的会员信息
+        $allData = CalcBonusBS::findUseDbCalc()
+            ->where('PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum])
+            ->groupBy('USER_ID')
+            ->offset($offset)
+            ->limit($this->_limit)
+            ->asArray()
+            ->all();
+        if ($allData) {
+            // 达标条件:会员级别:金卡、钻卡
+            $config = json_decode($this->_sysConfig['openGL']['OPTIONS'], true);
+            $minDecLevel = $config['abbrDec'] ?? [];
+
+            foreach ($allData as $user) {
+                //扣除相应的复消积分和管理费
+                $deductData = $this->deduct($user['USER_ID'], $user['ORI_BONUS_ABBR']);
+                $realBonusBs = $deductData['surplus']; // 扣除管理费和复消积分后的实发蓝星奖金
+                $manageTax = $deductData['manageTax']; // 管理费
+                $point = $deductData['reConsumePoints'] + $user['RECONSUME_POINTS'];// 复消积分
+
+                // 业绩奖金卡、钻卡发放
+//                if (in_array($user['LAST_DEC_LV'], $minDecLevel)) {
+                    // 把对碰后的奖金存入缓存中
+                    CalcCache::bonus($user['USER_ID'], $this->_periodNum, 'BONUS_BS_ABBR', $user['ORI_BONUS_ABBR'], $deductData);
+                    // 加入月奖的会员
+                    CalcCache::addHasMonthBonusUsers($user['USER_ID'], $this->_periodNum);
+//                }
+
+                // 更新蓝星业绩奖金存储过程的实发金额数据
+                CalcBonusBS::updateAll([
+                    'AMOUNT_ABBR' => $realBonusBs,
+                    'MANAGE_TAX_ABBR' => $manageTax,
+                    'RECONSUME_POINTS' => $point],
+            'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM',
+                    [':USER_ID' => $user['USER_ID'], ':PERIOD_NUM' => $this->_periodNum]);
+            }
+            return $this->calcBonusBsYJ($offset + $this->_limit);
+        }
+        unset($allData);
+        return true;
+    }
+
+    /**
+     * 对碰
+     * @param array $oriPerfArr
+     * @param array $perfArr
+     * @param $percent
+     * @param $loopTimes
+     * @return array
+     */
+    public function touchPerf(array $oriPerfArr, array $perfArr, $percent, $loopTimes=1) {
+        $resultArr = $oriPerfArr;
+        foreach ($perfArr as $keyT => $perfT) {
+            if ($perfT <= 0) {
+                unset($perfArr[$keyT]);
+            }
+        }
+        if (count($perfArr) >= 2 && $loopTimes < 6) {
+            arsort($perfArr, SORT_NUMERIC);
+            $onePerf = null;
+            $oneKey = null;
+            // $touchSurplusAmount = 0;
+            $touchAmount = 0;
+            // 前两个进行对碰
+            foreach ($perfArr as $key => $perf) {
+                if ($onePerf === null) {
+                    $oneKey = $key;
+                    $onePerf = $perf;
+                } else {
+                    $touchSurplusAmount = $perf - $onePerf;
+                    if ($touchSurplusAmount > 0) {
+                        unset($perfArr[$oneKey]);
+                        $resultArr['perfArr'][$oneKey] = 0;
+                        $perfArr[$key] = $touchSurplusAmount;
+                        $touchAmount = $onePerf;
+                    } elseif ($touchSurplusAmount < 0) {
+                        unset($perfArr[$key]);
+                        $resultArr['perfArr'][$key] = 0;
+                        $perfArr[$oneKey] = abs($touchSurplusAmount);
+                        $touchAmount = $perf;
+                    } else {
+                        unset($perfArr[$oneKey], $perfArr[$key]);
+                        $resultArr['perfArr'][$oneKey] = 0;
+                        $resultArr['perfArr'][$key] = 0;
+                        $touchAmount = $perf;
+                    }
+                    break;
+                }
+            }
+            $touchBonus = Tool::formatPrice($touchAmount * $percent);
+            $resultArr['touchBonus'] += $touchBonus;
+
+            foreach ($perfArr as $keyR => $perfR) {
+                $resultArr['perfArr'][$keyR] = $perfR;
+            }
+            return $this->touchPerf($resultArr, $perfArr, $percent, $loopTimes+1);
+
+        }
+        return $resultArr;
+    }
+
+    /**
+     * 循环父级并执行回调函数
+     * @param $userId
+     * @param callable $callbackFunc
+     * @param int $offset
+     * @return bool
+     */
+    public function loopNetworkParentDo($userId, callable $callbackFunc, int $offset = 0) {
+        $allParents = Cache::getAllNetworkParents($userId);
+        $allData = array_slice($allParents, $offset, $this->_limit);
+        unset($allParents);
+        if ($allData) {
+            foreach ($allData as $data) {
+                $funcResult = $callbackFunc($data);
+                if ($funcResult === self::LOOP_FINISH) {
+                    return true;
+                } elseif ($funcResult === self::LOOP_CONTINUE) {
+                    continue;
+                }
+                unset($data, $funcResult);
+            }
+            unset($allData);
+            return $this->loopNetworkParentDo($userId, $callbackFunc, $offset + $this->_limit);
+        }
+        return true;
+    }
+
+    /**
+     * 循环推荐网络的父级
+     * @param $userId
+     * @param callable $callbackFunc
+     * @param int $offset
+     * @return bool
+     */
+    public function loopRelationParentDo($userId, callable $callbackFunc, int $offset = 0) {
+        $allParents = Cache::getAllRelationParents($userId);
+        $allData = array_slice($allParents, $offset, $this->_limit);
+        unset($allParents);
+        if ($allData) {
+            foreach ($allData as $data) {
+                $funcResult = $callbackFunc($data);
+                if ($funcResult === self::LOOP_FINISH) {
+                    return true;
+                } elseif ($funcResult === self::LOOP_CONTINUE) {
+                    continue;
+                }
+                unset($data, $funcResult);
+            }
+
+            unset($allData);
+            return $this->loopRelationParentDo($userId, $callbackFunc, $offset + $this->_limit);
+        }
+        return true;
+    }
+
+    /**
+     * 按级别的收入上限
+     * 新的需求调整: 改成不按月进行限制,并且去掉vip奖
+     * @param $bonus
+     * @param $userId
+     * @param $declarationLevel
+     * @return float
+     */
+    public function declarationLevelCap($bonus, $userId, $declarationLevel) {
+        $decLevelConfig = $this->_decLevelConfig;
+        $nowDecLevelConfig = $decLevelConfig[$declarationLevel];
+        unset($decLevelConfig);
+        $maxGetBonus = $nowDecLevelConfig['INCOME_CAP'];
+        if( $bonus <= $maxGetBonus) {
+            return $bonus;
+        }else {
+            return $maxGetBonus;
+        }
+    }
+
+    /**
+     * 扣除复消积分和管理费
+     * @param $userId
+     * @param $bonus
+     * @return array
+     * @throws \yii\db\Exception
+     */
+    public function deduct($userId, $bonus) {
+        //判断是否达到了本月扣除复消的上限
+        $cacheData = CalcCache::monthLastPeriodReconsumePoints($userId, $this->_periodNum, $this->_calcYearMonth);
+        $bonusCache = CalcCache::bonus($userId, $this->_periodNum);
+
+        $reConsumePointsTotal = $bonusCache['RECONSUME_POINTS'] + $cacheData['RECONSUME_POINTS_SUM'];
+        $reConsumePointsCap = $this->_sysConfig['reConsumePointsMonthCap']['VALUE'];
+        unset($cacheData, $bonusCache);
+
+        $reConsumePoints = 0;
+        if( $reConsumePointsTotal < $reConsumePointsCap ) {
+            $reConsumePoints = $bonus * $this->_sysConfig['reConsumePointsPercent']['VALUE'] / 100;
+
+            $reConsumePoints = min($reConsumePoints, $reConsumePointsCap-$reConsumePointsTotal);
+        }
+        unset($reConsumePointsTotal, $reConsumePointsCap);
+
+        $manageTax = $bonus * $this->_sysConfig['manageTaxPercent']['VALUE'] / 100;
+        $surplus = $bonus - $reConsumePoints - $manageTax;
+        return [
+            'reConsumePoints' => Tool::formatPrice($reConsumePoints),//复效积分
+            'manageTax' => Tool::formatPrice($manageTax),//管理费
+            'surplus' => Tool::formatPrice($surplus),//真实奖金
+        ];
+    }
+
+    /**
+     * 更新百分比并发送
+     * @param $percent
+     */
+    private function _updatePercent($percent) {
+        // 把数据写入数据库中
+        Period::updateAll(['CALC_PERCENT' => $percent], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]);
+        \Yii::$app->swooleAsyncTimer->pushAsyncPercentToAdmin($percent, ['MODEL' => 'PERIOD', 'ID' => $this->_periodId, 'FIELD' => 'CALC_PERCENT']);
+    }
+
+    /**
+     * @todo 将这个表去掉
+     * 把往期有月奖金的会员加到本期有奖会员缓存列表中
+     * @param int $offset
+     * @return bool
+     */
+    public function loopMonthBonusUserFromDbToCache($offset = 0) {
+        if (!$this->_isCalcMonth) {
+            return true;
+        }
+
+        $allData = CalcMonthBonusUser::findUseDbCalc()->where('CALC_MONTH=:CALC_MONTH', [':CALC_MONTH' => $this->_calcYearMonth])->offset($offset)->limit($this->_limit)->asArray()->all();
+        if ( $allData ) {
+            foreach ($allData as $everyData) {
+                CalcCache::addHasBonusUsers($everyData['USER_ID'], $this->_periodNum);
+
+                unset($everyData);
+            }
+
+            unset($allData);
+            $this->loopMonthBonusUserFromDbToCache($offset + $this->_limit);
+        }
+
+        unset($allData);
+        return true;
+    }
+
+    /**
+     * 把缓存中的月奖用户信息存到数据库
+     * @param int $offset
+     * @return bool
+     * @throws \yii\db\Exception
+     */
+    public function loopMonthBonusUserToDb($offset = 0) {
+        echo sprintf("时间:[%s]月奖会员入库,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
+        $allData = CalcCache::getHasMonthBonusUsers($this->_periodNum, $offset, $this->_limit);
+        if($allData) {
+            $insertDataBonusUser = [];
+            foreach($allData as $userId){
+                $insertDataBonusUser[] = [
+                    'ID' => SnowFake::instance()->generateId(),
+                    'USER_ID' => $userId,
+                    'CALC_MONTH' => $this->_calcYearMonth,
+                    'PERIOD_NUM' => $this->_periodNum,
+                    'CREATED_AT' => Date::nowTime()
+                ];
+
+                unset($userId);
+            }
+
+            if( $insertDataBonusUser ) CalcMonthBonusUser::batchInsert($insertDataBonusUser);
+
+            unset($insertDataBonus, $allData);
+            return $this->loopMonthBonusUserToDb($offset + $this->_limit);
+        }
+
+        unset($allData);
+        return true;
+    }
+
+    /**
+     * 循环奖服务奖金会员,并入库
+     * @param int $offset
+     * @return bool
+     * @throws \yii\db\Exception
+     */
+    public function loopBonusUsers($offset = 0) {
+        echo sprintf("时间:[%s]缓存奖金数据入库,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
+        // 从缓存列表里面从底层往上倒序获取会员
+        $allData = CalcCache::getHasBonusUsers($this->_periodNum, $offset, $this->_limit);
+        if($allData){
+            $insertDataBonus = [];
+            foreach($allData as $userId){
+                $tempBonusData = $this->bonusData($userId);
+                if(!empty($tempBonusData['result'])){
+                    $insertDataBonus[] = $tempBonusData['result'];
+                }
+
+                unset($userId, $tempBonusData);
+            }
+            CalcBonus::batchInsert($insertDataBonus);
+
+            unset($insertDataBonus, $allData);
+            return $this->loopBonusUsers($offset + $this->_limit);
+        }
+        return true;
+    }
+
+    // 奖金入库完成,将各个奖金计算流水会员聘级,更新成蓝星奖当时计算的聘级
+    public function loopCalcBlueEmpLv($offset = 0) {
+        if( !$this->_isCalcMonth ) {
+            // 不是结算月,则不需要进行聘级调整
+            return false;
+        }
+        // 从缓存获取分页有收入的会员信息
+        $allData = CalcBonusBS::findUseDbCalc()
+            ->where('PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum])
+            ->groupBy('USER_ID')
+            ->offset($offset)
+            ->limit($this->_limit)
+            ->asArray()
+            ->all();
+        if ($allData) {
+            foreach ($allData as $data) {
+                $nowBsEmpLv = $data['LEVEL_ID']; // 当前蓝星奖计算(即管理奖) 的等级
+                // 期结算结果
+                CalcBonus::updateAll(['LAST_EMP_LV' => $nowBsEmpLv], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', 
+                    [
+                        ':USER_ID' => $data['USER_ID'],
+                        ':PERIOD_NUM' => $this->_periodNum
+                    ]
+                );
+                // 奖金流水
+                FlowBonus::updateAll(['LAST_EMP_LV' => $nowBsEmpLv], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', 
+                    [
+                        ':USER_ID' => $data['USER_ID'],
+                        ':PERIOD_NUM' => $this->_periodNum
+                    ]
+                );
+                // 推广奖流水
+                CalcBonusTG::updateAll(['LAST_EMP_LV' => $nowBsEmpLv], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM',
+                    [
+                        ':USER_ID' => $data['USER_ID'],
+                        ':PERIOD_NUM' => $this->_periodNum
+                    ]
+                );
+                // 团队奖流水
+                CalcBonusQY::updateAll(['LAST_EMP_LV' => $nowBsEmpLv], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', 
+                    [
+                        ':USER_ID' => $data['USER_ID'],
+                        ':PERIOD_NUM' => $this->_periodNum
+                    ]
+                );
+//                // 服务奖流水
+//                CalcBonusBD::updateAll(['LAST_EMP_LV' => $nowBsEmpLv], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM',
+//                    [
+//                        ':USER_ID' => $data['USER_ID'],
+//                        ':PERIOD_NUM' => $this->_periodNum
+//                    ]
+//                );
+                CalcBonusTG::updateAll(['LAST_FROM_EMP_LV' => $nowBsEmpLv], 'FROM_USER_ID=:FROM_USER_ID AND PERIOD_NUM=:PERIOD_NUM',
+                    [
+                        ':FROM_USER_ID' => $data['USER_ID'],
+                        ':PERIOD_NUM' => $this->_periodNum
+                    ]
+                );
+//                CalcBonusBD::updateAll(['LAST_FROM_EMP_LV' => $nowBsEmpLv], 'FROM_USER_ID=:FROM_USER_ID AND PERIOD_NUM=:PERIOD_NUM',
+//                    [
+//                        ':FROM_USER_ID' => $data['USER_ID'],
+//                        ':PERIOD_NUM' => $this->_periodNum
+//                    ]
+//                );
+            }
+            unset($allData);
+            return $this->loopCalcBlueEmpLv($offset + $this->_limit);
+        }
+        unset($allData);
+        return true;
+    }
+
+    /**
+     * 奖金
+     * @param $userId
+     * @return array
+     * @throws \yii\db\Exception
+     */
+    public function bonusData($userId) {
+        // 从缓存中获取用户的奖金
+        $bonus = CalcCache::bonus($userId, $this->_periodNum);
+        $baseInfo = CalcCache::getUserInfo($userId, $this->_periodNum);
+        $perfData = CalcCache::nowPeriodPerf($userId, $this->_periodNum);
+        $tourismBonus = CalcCache::tourismBonus($userId, $this->_periodNum);
+        $garageBonus = CalcCache::garageBonus($userId, $this->_periodNum);
+        $villaBonus = CalcCache::villaBonus($userId, $this->_periodNum);
+        $empLv = $baseInfo['EMP_LV'];
+        $pervSurplusPerf = CalcCache::surplusPerf($userId, $this->_periodNum);
+        // 星级
+        $starCrownLv = CalcCache::getUserStarCrown($userId, $this->_periodNum);
+
+        //没有共享和管理奖
+        $bonusReal = $bonus['BONUS_BD'] + $bonus['BONUS_TG'] + $bonus['BONUS_XF'] + $bonus['BONUS_YJ'] + 
+        $bonus['BONUS_QY'] + $bonus['BONUS_YC'] + $bonus['BONUS_YC_EXTRA'] + $bonus['BONUS_VIP'] + 
+        $bonus['BONUS_BS_MNT'] + $bonus['BONUS_BS_ABBR'] + $bonus['BONUS_QUARTER'];
+        $realBonusGx = 0;
+        $realBonusGl = 0;
+        $realBonusBs = 0; // 蓝星管理奖. BlueStar
+        $blueStartOriBonus = 0;
+        $blueStartManageTax = 0;
+        $exchangePoints = 0; // 蓝星奖管理奖. 产生的兑换积分
+
+        $realBonusBsMnt = 0; // 蓝星管理奖——实发奖金
+        $blueStartOriBonusMnt = 0;  // 蓝星管理奖——原奖金
+        $blueStartManageTaxMnt = 0;   // 蓝星管理奖——管理费
+
+        $realBonusBsAbbr = 0; // 蓝星业绩奖——实发奖金
+        $blueStartOriBonusAbbr = 0; // 蓝星业绩奖——原奖金
+        $blueStartManageTaxAbbr = 0;   // 蓝星业绩奖——管理费
+        if( $this->_isCalcMonth ) {
+            // 个人月消费PV大于配置值,才会计算发放蓝星奖
+            $fxPvStatus = $this->_isMonthPerfLimit($userId);
+            // BONUS_REAL 字段是发到用户的真实奖金
+            if ( $fxPvStatus ) {
+                $userBS = CalcBonusBS::find()
+                ->where(
+                    'PERIOD_NUM=:PERIOD_NUM AND USER_ID=:USER_ID',
+                    [
+                        ':PERIOD_NUM' => $this->_periodNum,
+                        ':USER_ID' => $userId
+                    ]
+                )
+                ->select('AMOUNT,ORI_BONUS,MANAGE_TAX,LEVEL_ID,PRODUCT_POINT,AMOUNT_MNT,ORI_BONUS_MNT,MANAGE_TAX_MNT,AMOUNT_ABBR,ORI_BONUS_ABBR,MANAGE_TAX_ABBR')
+                ->limit(1)
+                ->orderBy('CREATED_AT DESC')
+                ->asArray()
+                ->all();
+
+                $userBS = is_array($userBS) ? reset($userBS) : [];
+                $blueStartAmount = isset($userBS['AMOUNT']) && !empty($userBS['AMOUNT']) ? $userBS['AMOUNT'] : 0; // 奖金
+                $blueStartOriBonus = isset($userBS['ORI_BONUS']) && !empty($userBS['ORI_BONUS']) ? $userBS['ORI_BONUS'] : 0; // 原奖金
+                $blueStartManageTax = isset($userBS['MANAGE_TAX']) && !empty($userBS['MANAGE_TAX']) ? $userBS['MANAGE_TAX'] : 0; // 管理费
+
+                $realBonusBsMnt = $userBS['AMOUNT_MNT'] ?? 0; // 蓝星管理奖. 实发奖金
+                $blueStartOriBonusMnt = $userBS['ORI_BONUS_MNT'] ?? 0; // 蓝星管理奖. 原奖金
+                $blueStartManageTaxMnt = $userBS['MANAGE_TAX_MNT'] ?? 0; // 蓝星管理奖. 管理费
+
+                $realBonusBsAbbr = $userBS['AMOUNT_ABBR'] ?? 0; // 蓝星业绩奖. 奖金
+                $blueStartOriBonusAbbr = $userBS['ORI_BONUS_ABBR'] ?? 0; // 蓝星业绩奖. 原奖金
+                $blueStartManageTaxAbbr = $userBS['MANAGE_TAX_ABBR'] ?? 0; // 蓝星业绩奖. 管理费
+
+                $blueStartManageTax += $blueStartManageTaxMnt + $blueStartManageTaxAbbr; // 管理费
+
+                $monthSumData = CalcBonus::findUseSlaves()
+                ->select('SUM(BONUS_GX) AS BONUS_GX_SUM, SUM(BONUS_GL) AS BONUS_GL_SUM')
+                ->where('USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH',
+                    [
+                        'USER_ID' => $userId,
+                        'CALC_MONTH' => $this->_calcYearMonth
+                    ]
+                )
+                ->asArray()
+                ->one();
+                $realBonusBs = $blueStartAmount; // 蓝星奖直接取数据库中算好的值PRODUCT_POINT
+                $exchangePoints = isset($userBS['PRODUCT_POINT']) && !empty($userBS['PRODUCT_POINT']) ? $userBS['PRODUCT_POINT'] : 0; // 兑换积分
+
+                unset($monthSumData, $bonusGxSum, $bonusGlSum);
+            }
+        }
+
+        if( $this->_isCalcMonth ) { //季度奖
+            if(in_array($this->_calcMonth, [3,6,9,12])){ // 季度奖
+            }
+        }
+
+        $result = [
+            'USER_ID' => $userId,
+            'LAST_USER_NAME' => $baseInfo['USER_NAME'],
+            'LAST_REAL_NAME' => $baseInfo['REAL_NAME'],
+            'LAST_DEC_LV' => $baseInfo['DEC_LV'],
+            'LAST_EMP_LV' => $empLv,
+            'LAST_CROWN_LV' => $starCrownLv ?? StarCrownLevel::getDefaultLevelId(),
+            'LAST_STATUS' => $baseInfo['STATUS'],
+            'LAST_MOBILE' => $baseInfo['MOBILE'],
+            'LAST_PERIOD_AT' => $baseInfo['PERIOD_NUM'],
+            'LAST_CREATED_AT' => $baseInfo['CREATED_AT'],
+            'LAST_SUB_COM_ID' => $baseInfo['SUB_COM_ID'],
+            'LAST_PROVINCE' => $baseInfo['PROVINCE'],
+            'LAST_CITY' => $baseInfo['CITY'],
+            'LAST_COUNTY' => $baseInfo['COUNTY'],
+            'LAST_SYSTEM_ID' => $baseInfo['SYSTEM_ID'] ? $baseInfo['SYSTEM_ID'] : '',
+            'LAST_IS_DIRECT_SELLER' => $baseInfo['IS_DIRECT_SELLER'],
+            'LAST_REC_USER_NAME' => $baseInfo['REC_USER_NAME'],
+            'LAST_REC_REAL_NAME' => $baseInfo['REC_REAL_NAME'],
+            'LAST_CON_USER_NAME' => $baseInfo['CON_USER_NAME'],
+            'LAST_CON_REAL_NAME' => $baseInfo['CON_REAL_NAME'],
+            'EXCHANGE_POINTS' => $exchangePoints, // 兑换积分
+//            'LAST_LOCATION' => $baseInfo['LOCATION'] ? $baseInfo['LOCATION'] : 1,
+            //@todo
+            'LAST_LOCATION' => 1,
+            'BONUS_BD' => $bonus['BONUS_BD'],
+            'BONUS_TG' => $bonus['BONUS_TG'],
+            'BONUS_XF' => $bonus['BONUS_XF'],
+            'BONUS_YJ' => $bonus['BONUS_YJ'],
+            'BONUS_GX' => $bonus['BONUS_GX'],
+            'BONUS_GL' => $bonus['BONUS_GL'],
+            'BONUS_QY' => $bonus['BONUS_QY'],
+            'BONUS_YC' => $bonus['BONUS_YC'] + $bonus['BONUS_YC_EXTRA'],
+            'BONUS_VIP' => $bonus['BONUS_VIP'],
+            'RECONSUME_POINTS' => $bonus['RECONSUME_POINTS'],
+            'MANAGE_TAX' => $blueStartManageTax,    // 管理费
+            'BONUS_INCOME'=>$bonus['INCOME_TOTAL'],
+            'BONUS_REAL'=>  $bonusReal,
+            'BONUS_TOTAL'=>$bonus['BONUS_TOTAL'],
+            'ORI_BONUS_BD' => $bonus['ORI_BONUS_BD'],
+            'ORI_BONUS_TG' => $bonus['ORI_BONUS_TG'],
+            'ORI_BONUS_XF' => $bonus['ORI_BONUS_XF'],
+            'ORI_BONUS_YJ' => $bonus['ORI_BONUS_YJ'],
+            'ORI_BONUS_YJ_BD' => $bonus['ORI_BONUS_YJ_BD'],
+            'ORI_BONUS_YJ_FX' => $bonus['ORI_BONUS_YJ_FX'],
+            'ORI_BONUS_GX' => $bonus['ORI_BONUS_GX'],
+            'REAL_BONUS_GX' => $realBonusGx,
+            'ORI_BONUS_GL' => $bonus['ORI_BONUS_GL'],
+            'REAL_BONUS_GL' => $realBonusGl,
+
+            'BONUS_BS' => $realBonusBs, // 新的管理奖金,即蓝星管理奖
+            'ORI_BONUS_BS' => $blueStartOriBonus, // 蓝星管理奖金原奖金,即包含管理费
+            'REAL_BONUS_BS' => $realBonusBs, // 实发蓝星管理奖金
+
+            'BONUS_BS_MNT' => $realBonusBsMnt, // 蓝星管理奖
+            'ORI_BONUS_BS_MNT' => $blueStartOriBonusMnt, // 蓝星管理奖金原奖金,即包含管理费
+            'REAL_BONUS_BS_MNT' => $realBonusBsMnt, // 实发蓝星管理奖金
+            'MANAGE_TAX_MNT' => $blueStartManageTaxMnt,  // 实发蓝星管理——管理费
+
+            'BONUS_BS_ABBR' => $realBonusBsAbbr, // 蓝星业绩奖
+            'ORI_BONUS_BS_ABBR' => $blueStartOriBonusAbbr, // 蓝星业绩奖金原奖金,即包含管理费
+            'REAL_BONUS_BS_ABBR' => $realBonusBsAbbr, // 实发蓝星业绩奖金
+            'MANAGE_TAX_ABBR' => $blueStartManageTaxAbbr, // 实发蓝星业绩奖——管理费
+
+            'ORI_BONUS_GL_BD' => $bonus['ORI_BONUS_GL_BD'],
+            'ORI_BONUS_GL_FX' => $bonus['ORI_BONUS_GL_FX'],
+            'ORI_BONUS_QY' => $bonus['ORI_BONUS_QY'],
+            'ORI_BONUS_QY_BD' => $bonus['ORI_BONUS_QY_BD'],
+            'ORI_BONUS_QY_FX' => $bonus['ORI_BONUS_QY_FX'],
+            'ORI_BONUS_YC' => $bonus['ORI_BONUS_YC'] + $bonus['ORI_BONUS_YC_EXTRA'],
+            'ORI_BONUS_VIP' => $bonus['ORI_BONUS_VIP'],
+            'ORI_CAPPED_BONUS_QY' => $bonus['ORI_CAPPED_BONUS_QY'], // 团队奖封顶前的奖金
+            'BONUS_QUARTER' => $bonus['BONUS_QUARTER'],
+            'ORI_BONUS_QUARTER' => $bonus['ORI_BONUS_QUARTER'],
+
+            'BONUS_TOURISM' => $tourismBonus, // 旅游奖
+            'BONUS_VILLA' => $villaBonus, // 房奖
+            'BONUS_GARAGE' => $garageBonus, // 车奖
+
+            //以下没有用
+            'BONUS_FW' => 0,
+            'BONUS_FX' => $bonus['BONUS_FX'],
+            'BONUS_LS' => $bonus['BONUS_LS'],
+            'BONUS_BT' => $bonus['BONUS_BT'],
+            'BONUS_BT_PROD' => $bonus['BONUS_BT_PROD'],
+            'BONUS_BT_TOOL' => $bonus['BONUS_BT_TOOL'],
+            'DEDUCT_ZR' => $bonus['DEDUCT_ZR'],
+            'BONUS_FL' => $bonus['BONUS_FL'],
+            'BONUS_CF' => $bonus['BONUS_CF'],
+            'BONUS_LX' => $bonus['BONUS_LX'],
+            'SHOULD_QY' => $bonus['BONUS_QY'],
+            'SHOULD_DEDUCT_ZR' => $bonus['DEDUCT_ZR'],
+
+            'PV_1L' => $perfData['PV_1L_TOUCH'],//TOUCH为碰业绩
+            'QY_1L' => $perfData['PV_1L_TOUCH'] + $pervSurplusPerf['SURPLUS_1L'],
+            'SURPLUS_1L' => $perfData['SURPLUS_1L'],
+            'PV_2L' => $perfData['PV_2L_TOUCH'],
+            'QY_2L' => $perfData['PV_2L_TOUCH'] + $pervSurplusPerf['SURPLUS_2L'],
+            'SURPLUS_2L' => $perfData['SURPLUS_2L'],
+            'PV_3L' => $perfData['PV_3L_TOUCH'],
+            'QY_3L' => $perfData['PV_3L_TOUCH'] + $pervSurplusPerf['SURPLUS_3L'],
+            'SURPLUS_3L' => $perfData['SURPLUS_3L'],
+            'PV_4L' => $perfData['PV_4L_TOUCH'],
+            'QY_4L' => $perfData['PV_4L_TOUCH'] + $pervSurplusPerf['SURPLUS_4L'],
+            'SURPLUS_4L' => $perfData['SURPLUS_4L'],
+            'PV_5L' => $perfData['PV_5L_TOUCH'],
+            'QY_5L' => $perfData['PV_5L_TOUCH'] + $pervSurplusPerf['SURPLUS_5L'],
+            'SURPLUS_5L' => $perfData['SURPLUS_5L'],
+            'PV_PCS' => $perfData['PV_PCS'],
+            'PV_LS_TOUCH' => 0.00,
+            'SURPLUS_LS' => 0.00,
+            'QY_LS' => 0.00,
+            'PV_TOUCH' => Tool::formatPrice($perfData['PV_1L_TOUCH'] + $perfData['PV_2L_TOUCH'] + $perfData['PV_3L_TOUCH'] + $perfData['PV_4L_TOUCH'] + $perfData['PV_5L_TOUCH'] + $perfData['PV_LS_TOUCH']),
+            'PERIOD_NUM' => $this->_periodNum,
+            'CALC_YEAR' => $this->_calcYear,
+            'CALC_MONTH' => $this->_calcYearMonth,
+            'CALCULATED_AT' => Date::nowTime(),
+            'CREATED_AT' => Date::nowTime(),
+        ];
+        $resend = [];
+
+        unset($bonus, $realBonusGx, $realBonusGl, $bonusReal);
+        return ['result'=>$result,'resend'=>$resend];
+    }
+
+    // 判断是否满足月最低消费
+    public function _isMonthPerfLimit($userId) {
+        $userMonthTotal = PerfMonth::find()->where(
+            'USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH', 
+            ['USER_ID'=>$userId, 'CALC_MONTH'=>$this->_calcYearMonth]
+        )
+        ->asArray()
+        ->one();
+        $fxPvStatus = false;
+        if (isset($userMonthTotal['PV_PCS']) && $userMonthTotal['PV_PCS'] >= $this->_sysConfig['monthPcsPvFxCondition']['VALUE']) {
+            $fxPvStatus = true;
+        }
+        
+        return $fxPvStatus;
+    }
+}

+ 43 - 767
common/helpers/bonus/CalcServePerfCalc.php

@@ -7,20 +7,10 @@ namespace common\helpers\bonus;
 use common\helpers\Cache;
 use common\helpers\Date;
 use common\helpers\snowflake\SnowFake;
-use common\models\DeclarationLevel;
-use common\models\forms\DeclarationForm;
-use common\models\Order;
-use common\models\OrderDec;
-use common\models\OrderShop;
 use common\models\PerfOrder;
 use common\models\PerfPeriod;
 use common\models\Period;
-use common\models\DecOrder;
 use common\models\PerfMonth;
-use common\models\PerfMonthPrepare;
-use common\models\PerfOrderPrepare;
-use common\models\PerfPeriodPrepare;
-use common\models\PeriodPrepare;
 use common\models\ServeProcess;
 use yii\base\Exception;
 use yii\base\StaticInstanceTrait;
@@ -28,7 +18,7 @@ use yii\base\StaticInstanceTrait;
 class CalcServePerfCalc {
     use StaticInstanceTrait;
 
-    private $_limit = 5000;
+    private $_limit = 3000;
     private $_companyMonthPerf = 0;
     private $_cfTotalPercent = 0;
     private $_lxTotalPercent = 0;
@@ -123,49 +113,26 @@ class CalcServePerfCalc {
             $this->_updatePercent(20);
             // 八、循环累计用户各项业绩数据
             $this->loopGrandPerf();
-            
-            
-
-            // // 周结,循环向上级计入业绩并加入业绩单
-            $this->loopCalcPeriodPerfByDecOrder();
-            $this->loopCalcPeriodPerfByOrderDec();
-            // $t4 = microtime(true);
-            // echo('预计算业绩计算周业绩表中的数据完成,耗时:' . round($t4 - $t1, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
-            // $this->_updatePercent(40);
-            // // 从会员的复销订单会员计算复销业绩并加入业绩单
-            $this->loopCalcPerfByFXOrder();
-            $this->loopCalcPerfByShopFXOrder();
-            // $t5 = microtime(true);
-            // echo('预计算业绩计算复销业绩并写入业绩单完成,耗时:' . round($t5 - $t4, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
-            // $this->_updatePercent(60);
-            //九、本期业绩入库
+            $t4 = microtime(true);
+            echo('累计用户业绩完成' . round($t4 - $t3, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+            // 九、本期业绩入库
             $this->loopWriteNowPerf();
             $t6 = microtime(true);
-            echo('预计算业绩本期业绩入库完成,耗时:' . round($t6 - $t5, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+            echo('本期业绩入库完成,耗时:' . round($t6 - $t4, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
             $this->_updatePercent(70);
-
             //十、计算月业绩表中的数据
             $this->loopCalcMonthPerfTableData();
             $t7 = microtime(true);
-            echo('预计算业绩计算月业绩表中的数据完成,耗时:' . round($t7 - $t6, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+            echo('计算月业绩表中的数据完成,耗时:' . round($t7 - $t6, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
             $this->_updatePercent(80);
-
-            $t8 = microtime(true);
-            // 计算预计月业绩表的数据,这些数据用户不在前三期非月节点的数据.需要将此期新用户业绩统计一下
-            $this->loopCalcMonthPerfTableDataPrepare();
-  
             //十一、本月业绩入库
             $this->loopWriteMonthPerf();
-            $t7 = microtime(true);
-            echo('预计算业绩本月业绩入库完成,耗时:' . round($t7 - $t6, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
-            $this->_updatePercent(90);
-
-            $t9 = microtime(true);
-
+            $t8 = microtime(true);
+            echo('本月业绩入库完成,耗时:' . round($t8 - $t7, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
             $this->_updatePercent(100);
-            $t10 = microtime(true);
+            $t9 = microtime(true);
             
-            echo('计算业绩业绩结算全部完成,共耗时:' . round($t10 - $t9, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+            echo('计算业绩业绩结算全部完成,共耗时:' . round($t9 - $t8, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
         } catch (\Exception $e) {
             $this->errorCalcTask();
             file_put_contents('error_test.txt', var_export([
@@ -206,56 +173,12 @@ class CalcServePerfCalc {
     public function setCalcStatus($type, $periodNum = null) {
         if ($type == 'start') {
             $this->_lastTime = !empty($periodNum) ? Date::nowTime() : $this->_lastTime;
-            PeriodPrepare::updateAll(['IS_PERFING' => 1, 'IS_PERFED' => Period::PERF_NONE, 'PERF_STARTED_AT' => $this->_lastTime], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]);
+            Period::updateAll(['IS_PERFING' => 1, 'IS_PERFED' => Period::PERF_NONE, 'PERF_STARTED_AT' => $this->_lastTime], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]);
         } elseif ($type == 'end') {
-            PeriodPrepare::updateAll(['IS_PERFING' => 0, 'IS_PERFED' => Period::PERF_FINISH, 'PERFED_AT' => Date::nowTime()], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]);
+            Period::updateAll(['IS_PERFING' => 0, 'IS_PERFED' => Period::PERF_FINISH, 'PERFED_AT' => Date::nowTime()], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]);
         } elseif ($type == 'fail') {
-            PeriodPrepare::updateAll(['IS_PERFING' => 0, 'IS_PERFED' => Period::PERF_FAIL, 'PERFED_AT' => 0], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]);
-        }
-    }
-
-    public function checkCanCalcPref($periodNum = null) {
-        
-        // 先判断时间,现在是周几,如果不是周日,则直接结束
-        // 如果是手动触发,即有业绩期$periodNum变量值,则不校验必须周日0点
-        $w = $h = '';
-        if (empty($periodNum)) {
-            $w = date('w',time());
-            if ($w != '0') {
-                return false;
-            }
-            // 判断是否是周日0点
-            $h = date('H',time());
-            if ($h !=0 ) {
-                return false;
-            }
-        }
-        // 判断此结算周期是否是月结算节点 
-        // 这里 如果定时任务业绩期是nul
-        $periodObj = Period::instance();
-        $periodDataArr = $periodObj->setPeriodNum($periodNum);
-        if ($periodDataArr['IS_MONTH'] != 1) {
-            return false;
+            Period::updateAll(['IS_PERFING' => 0, 'IS_PERFED' => Period::PERF_FAIL, 'PERFED_AT' => 0], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $this->_periodNum]);
         }
-        // 如果是手动进行计算得月业绩,则不需要判断结算当前状态
-        // 判断此结算周期是否已经进行业绩计算,如果已进行或者进行过,则不能继续执行
-        if (empty($periodNum)) {
-            $prepare = PeriodPrepare::find()
-            ->select('IS_MONTH, IS_PERFING,IS_PERFED')
-            ->where(
-                'PERIOD_NUM=:PERIOD_NUM', 
-                [
-                    'PERIOD_NUM'=>$periodDataArr['PERIOD_NUM']
-                ])
-            ->asArray()
-            ->one();
-            // 如果正在结算或者已计算完,则不进行计算,因为预计计算是定时任务每5秒扫一次,所以不能再触发预计算业绩
-            if ($prepare['IS_PERFING'] == 1 || $prepare['IS_PERFED'] == 1) {
-                return false;
-            }
-        }
-
-        return true;
     }
 
     /**
@@ -388,468 +311,31 @@ class CalcServePerfCalc {
                     ]);
                     // 把该会员加入到能拿到业绩的会员缓存中
                     CalcCache::addHasPerfUsers($data['USER_ID'], $this->_periodNum);
-                }
-            }
-
-            return $this->loopGrandPerf($offset + $this->_limit);
-        }
-        unset($allData);
-        return true;
-    }
-
-    /**
-     * 周结,向上级算业绩,并计入业绩单
-     * @param int $offset
-     * @return bool
-     * @throws \yii\db\Exception
-     */
-    public function loopCalcPeriodPerfByDecOrder($offset = 0) {
-        // 循环获取全部报单
-        $allData = DecOrder::findUseDbCalc()
-        ->select('ID,DEC_SN,ORDER_SN,USER_ID,TYPE,TO_USER_ID,IS_ADMIN,DEC_AMOUNT,DEC_PV,PERIOD_NUM,
-        CALC_MONTH,IS_DEL,P_CALC_MONTH,CREATED_AT,DEC_ID')
-        ->where(
-            "PERIOD_NUM=:PERIOD_NUM AND IS_DEL=0 AND TYPE='ZC'  AND CREATED_AT<=:CREATED_AT", 
-            [':PERIOD_NUM' => $this->_periodNum, ':CREATED_AT' => $this->_lastTime]
-        )
-        ->orderBy('CREATED_AT DESC,ID DESC')
-        ->offset($offset)
-        ->limit($this->_limit)
-        ->asArray()
-        ->all();
-        if ($allData) {
-            $insertPerfOrderData = [];
-            foreach ($allData as $data) {
-                // 给自己增加PCS(个人消费)
-                PrepareCalcCache::nowPeriodPerf($data['TO_USER_ID'], $this->_periodNum, [
-                    'PV_PCS' => $data['DEC_PV'],
-                    'PV_PCS_ZC' => $data['DEC_PV'],
-                ]);
-                // 把该会员加入到能拿到业绩的会员缓存中
-                PrepareCalcCache::addHasPerfUsers($data['TO_USER_ID'], $this->_periodNum);
-                //加入到报单会员中
-                $toInfo = PrepareCalcCache::getUserInfo($data['TO_USER_ID'], $this->_periodNum);
-                PrepareCalcCache::addHasBDUsers($data['TO_USER_ID'], $this->_periodNum, [
-                    'TO_USER_ID' => $data['TO_USER_ID'],
-                    'USER_ID' => $data['USER_ID'],
-                    'DEC_ID' => $data['DEC_ID'],
-                    //考虑可能会移网的情况
-                    'REC_USER_ID' => $toInfo['REC_UID'] ?? '',
-                    'CON_USER_ID' => $toInfo['CON_UID'] ?? '',
-                    'DEC_AMOUNT' => $data['DEC_AMOUNT'],
-                    'DEC_PV' => $data['DEC_PV'],
-                ]);
-                // 给上追加业绩
-                $this->loopNetworkParentDo($data['TO_USER_ID'], function ($parent) use (&$data) {
-                    
-                    // 给上级会员追加本期业绩到缓存中
-                    PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
-                        'PV_' . $parent['LOCATION'] . 'L' => $data['DEC_PV'],
-                        'PV_' . $parent['LOCATION'] . 'L_TOUCH' => $data['DEC_PV'],
-                        'PV_' . $parent['LOCATION'] . 'L_' . $data['TYPE'] => $data['DEC_PV'],
-                    ]);
-                    // 把该会员加入到能拿到业绩的会员缓存中
-                    PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
-                    unset($parent);
-                });
-                //给推荐关系累计增加业绩
-                $this->loopRelationParentDo($data['TO_USER_ID'], function ($parent) use (&$data) {
-                    // 给上级会员追加本期业绩到缓存中
-                    PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
-                        'PV_PSS' => $data['DEC_PV'],
-                    ]);
-                    // 把该会员加入到能拿到业绩的会员缓存中
-                    PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
-                    unset($parent);
-                });
-                
-                // 写入业绩单表
-                $decInfo = PrepareCalcCache::getUserInfo($data['USER_ID'], $this->_periodNum);
-                $sn = PerfOrderPrepare::generateSN();
-                $insertPerfOrderData[] = [
-                    'ID' => SnowFake::instance()->generateId(),
-                    'SN' => $sn,
-                    'DEC_SN' => $data['DEC_SN'],
-                    'DEC_TYPE' => strtoupper($data['TYPE']),
-                    'DEC_STATUS' => PerfOrder::STATUS_NORMAL,
-                    'USER_ID' => $data['TO_USER_ID'],
-                    'LAST_REC_USER_NAME' => $toInfo['REC_USER_NAME'],
-                    'LAST_REC_REAL_NAME' => $toInfo['REC_REAL_NAME'],
-                    'LAST_DEC_LV' => $toInfo['DEC_LV'],
-                    'LAST_EMP_LV' => $toInfo['EMP_LV'],
-                    'LAST_STATUS' => $toInfo['STATUS'],
-                    'PV' => $data['DEC_PV'],
-                    'DEC_AMOUNT' => $data['DEC_AMOUNT'],
-                    'LAST_SUB_COM_ID' => $toInfo['SUB_COM_ID'],
-                    'LAST_PROVINCE' => $toInfo['PROVINCE'],
-                    'LAST_CITY' => $toInfo['CITY'],
-                    'LAST_COUNTY' => $toInfo['COUNTY'],
-                    'DEC_USER_ID' => $data['USER_ID'],
-                    'LAST_DEC_DEC_LV' => $decInfo['DEC_LV'],
-                    'LAST_DEC_SUB_COM_ID' => $decInfo['SUB_COM_ID'],
-                    'LAST_DEC_PROVINCE' => $decInfo['DEC_PROVINCE'],
-                    'LAST_DEC_CITY' => $decInfo['DEC_CITY'],
-                    'LAST_DEC_COUNTY' => $decInfo['DEC_COUNTY'],
-                    'PERIOD_NUM' => $this->_periodNum,
-                    'CALC_MONTH' => $this->_calcYearMonth,
-                    'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH),
-                    'CREATED_AT' => Date::nowTime(),
-                    'CLOSED_AT' => 0,
-                    'ORDER_CREATED_AT' => $data['CREATED_AT'],
-                ];
-                unset($data, $decInfo, $sn, $toInfo);
-            }
-            PerfOrderPrepare::batchInsert($insertPerfOrderData);
-            unset($insertPerfOrderData, $allData, $snArr);
-            return $this->loopCalcPeriodPerfByDecOrder($offset + $this->_limit);
-        }
-        unset($allData);
-        return true;
-    }
-
-    /**
-     * 周结,向上级算业绩,并计入业绩单
-     * @param int $offset
-     * @return bool
-     * @throws \yii\db\Exception
-     */
-    public function loopCalcPeriodPerfByOrderDec($offset = 0) {
-        // 循环获取全部报单
-        $allData = OrderDec::findUseDbCalc()
-        ->select('CREATED_AT,ID,SN,USER_ID,ORDER_TYPE,ORDER_AMOUNT,PV,PAY_AMOUNT,PAY_PV,PERIOD_NUM,PAY_TYPE')
-        ->where(
-            "PERIOD_NUM=:PERIOD_NUM AND IS_DELETE=0 AND ORDER_TYPE=:ORDER_TYPE AND CREATED_AT<=:CREATED_AT", 
-            [':PERIOD_NUM' => $this->_periodNum, ':ORDER_TYPE'=>'ZC', ':CREATED_AT' => $this->_lastTime])
-            ->orderBy('ID DESC')
-            ->offset($offset)
-            ->limit($this->_limit)
-            ->asArray()
-            ->all();
-        if ($allData) {
-            $insertPerfOrderData = [];
-            foreach ($allData as $data) {
-                // 给自己增加PCS(个人消费)
-                PrepareCalcCache::nowPeriodPerf($data['USER_ID'], $this->_periodNum, [
-                    'PV_PCS' => $data['PAY_PV'],
-                    'PV_PCS_ZC' => $data['PAY_PV'],
-                ]);
-                // 把该会员加入到能拿到业绩的会员缓存中
-                PrepareCalcCache::addHasPerfUsers($data['USER_ID'], $this->_periodNum);
-                //加入到报单会员中
-                $toInfo = PrepareCalcCache::getUserInfo($data['USER_ID'], $this->_periodNum);
-                PrepareCalcCache::addHasBDUsers($data['USER_ID'], $this->_periodNum, [
-                    'TO_USER_ID' => $data['USER_ID'],
-                    'USER_ID' => $toInfo['DEC_ID'],
-                    'DEC_ID' => $toInfo['DEC_ID'],
-                    //考虑可能会移网的情况
-                    'REC_USER_ID' => $toInfo['REC_UID'] ?? '',
-                    'CON_USER_ID' => $toInfo['CON_UID'] ?? '',
-                    'DEC_AMOUNT' => $data['ORDER_AMOUNT'],
-                    'DEC_PV' => $data['PAY_PV'],
-                ]);
-                // 给上追加业绩
-                $this->loopNetworkParentDo($data['USER_ID'], function ($parent) use (&$data) {
-                    // 给上级会员追加本期业绩到缓存中
-                    PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
-                        'PV_' . $parent['LOCATION'] . 'L' => $data['PAY_PV'],
-                        'PV_' . $parent['LOCATION'] . 'L_TOUCH' => $data['PAY_PV'],
-                        'PV_' . $parent['LOCATION'] . 'L_' . $data['ORDER_TYPE'] => $data['PAY_PV'],
-                    ]);
-                    // 把该会员加入到能拿到业绩的会员缓存中
-                    PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
-                    unset($parent);
-                });
-                //给推荐关系累计增加业绩
-                $this->loopRelationParentDo($data['USER_ID'], function ($parent) use (&$data) {
-                    // 给上级会员追加本期业绩到缓存中
-                    PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
-                        'PV_PSS' => $data['PAY_PV'],
-                    ]);
-                    // 把该会员加入到能拿到业绩的会员缓存中
-                    PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
-                    unset($parent);
-                });
-
-                // 写入业绩单表
-                $decInfo = PrepareCalcCache::getUserInfo($toInfo['DEC_ID'], $this->_periodNum);
-                $sn = PerfOrderPrepare::generateSN();
-                $insertPerfOrderData[] = [
-                    'ID' => SnowFake::instance()->generateId(),
-                    'SN' => $sn,
-                    'DEC_SN' => $data['SN'],
-                    'DEC_TYPE' => strtoupper($data['ORDER_TYPE']),
-                    'DEC_STATUS' => PerfOrder::STATUS_NORMAL,
-                    'USER_ID' => $data['USER_ID'],
-                    'LAST_REC_USER_NAME' => $toInfo['REC_USER_NAME'],
-                    'LAST_REC_REAL_NAME' => $toInfo['REC_REAL_NAME'],
-                    'LAST_DEC_LV' => $toInfo['DEC_LV'],
-                    'LAST_EMP_LV' => $toInfo['EMP_LV'],
-                    'LAST_STATUS' => $toInfo['STATUS'],
-                    'PV' => $data['PAY_PV'],
-                    'DEC_AMOUNT' => $data['ORDER_AMOUNT'],
-                    'LAST_SUB_COM_ID' => $toInfo['SUB_COM_ID'],
-                    'LAST_PROVINCE' => $toInfo['PROVINCE'],
-                    'LAST_CITY' => $toInfo['CITY'],
-                    'LAST_COUNTY' => $toInfo['COUNTY'],
-                    'DEC_USER_ID' => $toInfo['DEC_ID'],
-                    'LAST_DEC_DEC_LV' => $decInfo['DEC_LV'],
-                    'LAST_DEC_SUB_COM_ID' => $decInfo['SUB_COM_ID'],
-                    'LAST_DEC_PROVINCE' => $decInfo['DEC_PROVINCE'],
-                    'LAST_DEC_CITY' => $decInfo['DEC_CITY'],
-                    'LAST_DEC_COUNTY' => $decInfo['DEC_COUNTY'],
-                    'PERIOD_NUM' => $this->_periodNum,
-                    'CALC_MONTH' => $this->_calcYearMonth,
-                    'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH),
-                    'CREATED_AT' => Date::nowTime(),
-                    'CLOSED_AT' => 0,
-                    'ORDER_CREATED_AT' => $data['CREATED_AT']
-                ];
-                unset($data, $decInfo, $sn, $toInfo);
-            }
-            PerfOrderPrepare::batchInsert($insertPerfOrderData);
-            unset($insertPerfOrderData, $allData, $snArr);
-            return $this->loopCalcPeriodPerfByOrderDec($offset + $this->_limit);
-        }
-        unset($allData);
-        return true;
-    }
-
-
-    /**
-     * 从会员的复销订单会员计算复销业绩并加入业绩单
-     * @param int $offset
-     * @return bool
-     * @throws \yii\db\Exception
-     */
-    public function loopCalcPerfByFXOrder(int $offset = 0) {
-        // 循环获取全部报单
-        $allData = Order::findUseDbCalc()
-        ->select('ID,SN,DEC_SN,USER_ID,ORDER_TYPE,ORDER_AMOUNT,PAY_AMOUNT,PAY_PV,PAY_TYPE,PERIOD_NUM,STATUS,IS_DELETE,
-        P_CALC_MONTH,CREATED_AT')
-        ->where(
-            "PERIOD_NUM=:PERIOD_NUM AND IS_DELETE=0 AND ORDER_TYPE=:ORDER_TYPE AND CREATED_AT<=:CREATED_AT", 
-            [':PERIOD_NUM' => $this->_periodNum, ':ORDER_TYPE'=>DeclarationForm::TYPE_FX,':CREATED_AT' => $this->_lastTime]
-        )
-        ->orderBy('CREATED_AT DESC,ID DESC')
-        ->offset($offset)
-        ->limit($this->_limit)
-        ->asArray()
-        ->all();
-        if ($allData) {
-            $insertPerfOrderData = [];
-            foreach ($allData as $data) {
-
-                //如果支付方式是现金,那么实际业绩是支付PV的50%
-                if( $data['PAY_TYPE'] === self::ORDER_PAY_TYPE_CASH ) {
-                    $orderCashAmount = $data['ORDER_AMOUNT'];
-                    //111期开始由50%改为60%-by 2020-04-30修改
-                    $payPv = $data['PAY_PV'] * $this->_sysConfig['cashReconsumeBonusPercent']['VALUE'] / 100;
-                    $cacheDataKey = 'PV_PCS_FX_CASH';
-                }else {
-                    $orderCashAmount = 0;
-                    $payPv = $data['PAY_PV'];
-                    $cacheDataKey = 'PV_PCS_FX_POINT';
-                }
-
-                if( $payPv <= 0 ) continue;
-
-                // 给自己增加PCS(个人消费)
-                PrepareCalcCache::nowPeriodPerf($data['USER_ID'], $this->_periodNum, [
-                    'FX_AMOUNT_CASH' => $orderCashAmount,
-                    'PV_PCS' => $payPv,
-                    'PV_PCS_FX' => $payPv,
-                    $cacheDataKey => $payPv,
-                ]);
-                // 把该会员加入到能拿到业绩的会员缓存中
-                PrepareCalcCache::addHasPerfUsers($data['USER_ID'], $this->_periodNum);
-                // 给上追加业绩
-                try {
+                    // 给上追加业绩
                     $this->loopNetworkParentDo($data['USER_ID'], function ($parent) use (&$data, $payPv) {
                         // 给上级会员追加本期业绩到缓存中
-                        PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
+                        CalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
                             'PV_' . $parent['LOCATION'] . 'L' => $payPv,
                             'PV_' . $parent['LOCATION'] . 'L_TOUCH' => $payPv,
                             'PV_' . $parent['LOCATION'] . 'L_FX' => $payPv,
                         ]);
                         // 把该会员加入到能拿到业绩的会员缓存中
-                        PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
+                        CalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
+                    });
+                    //给推荐关系累计增加业绩
+                    $this->loopRelationParentDo($data['USER_ID'], function ($parent) use ($data, $payPv) {
+                        // 给上级会员追加本期业绩到缓存中
+                        CalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
+                            'PV_PSS' => $payPv,
+                        ]);
+                        // 把该会员加入到能拿到业绩的会员缓存中
+                        CalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
                     });
-                } catch(\Exception $e) {
-                    file_put_contents('loopNetworkParentDo_error.txt', var_export([
-                        'USER_ID' => $data['USER_ID'],
-                        '_periodNum' => $this->_periodNum,
-                        'error' => $e->getMessage()
-                    ],true));
-                }
-                //给推荐关系累计增加业绩
-                $this->loopRelationParentDo($data['USER_ID'], function ($parent) use ($data, $payPv) {
-                    // 给上级会员追加本期业绩到缓存中
-                    PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
-                        'PV_PSS' => $payPv,
-                    ]);
-                    // 把该会员加入到能拿到业绩的会员缓存中
-                    PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
-                });
-
-//                }
-                // 写入业绩单表
-                $baseInfo = PrepareCalcCache::getUserInfo($data['USER_ID'], $this->_periodNum);
-                $sn = PerfOrderPrepare::generateSN();
-                $insertPerfOrderData[] = [
-                    'ID' => SnowFake::instance()->generateId(),
-                    'SN' => $sn,
-                    'DEC_SN' => null,
-                    'DEC_TYPE' => 'FX',
-                    'DEC_STATUS' => PerfOrder::STATUS_NORMAL,
-                    'USER_ID' => $data['USER_ID'],
-                    'LAST_REC_USER_NAME' => $baseInfo['REC_USER_NAME'],
-                    'LAST_REC_REAL_NAME' => $baseInfo['REC_REAL_NAME'],
-                    'LAST_DEC_LV' => $baseInfo['DEC_LV'],
-                    'LAST_EMP_LV' => $baseInfo['EMP_LV'],
-                    'LAST_STATUS' => $baseInfo['STATUS'],
-                    'PV' => $payPv,
-                    'DEC_AMOUNT' => $data['PAY_AMOUNT'],
-                    'LAST_SUB_COM_ID' => $baseInfo['SUB_COM_ID'],
-                    'LAST_PROVINCE' => $baseInfo['PROVINCE'],
-                    'LAST_CITY' => $baseInfo['CITY'],
-                    'LAST_COUNTY' => $baseInfo['COUNTY'],
-                    'DEC_USER_ID' => $data['USER_ID'],
-                    'LAST_DEC_DEC_LV' => $baseInfo['DEC_LV'],
-                    'LAST_DEC_SUB_COM_ID' => $baseInfo['SUB_COM_ID'],
-                    'LAST_DEC_PROVINCE' => $baseInfo['PROVINCE'],
-                    'LAST_DEC_CITY' => $baseInfo['CITY'],
-                    'LAST_DEC_COUNTY' => $baseInfo['COUNTY'],
-                    'PERIOD_NUM' => $this->_periodNum,
-                    'CALC_MONTH' => $this->_calcYearMonth,
-                    'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH),
-                    'CREATED_AT' => Date::nowTime(),
-                    'CLOSED_AT' => 0,
-                    'ORDER_CREATED_AT' => $data['CREATED_AT']
-                ];
-                unset($data, $baseInfo, $sn, $orderCashAmount, $payPv, $cacheDataKey);
-            }
-            PerfOrderPrepare::batchInsert($insertPerfOrderData);
-
-            unset($insertPerfOrderData, $allData, $snArr);
-            return $this->loopCalcPerfByFXOrder($offset + $this->_limit);
-        }
-
-        unset($allData);
-        return true;
-    }
-
-    /**
-     * 从会员的商城复销订单会员计算复销业绩并加入业绩单
-     * @param int $offset
-     * @return bool
-     * @throws \yii\db\Exception
-     */
-    public function loopCalcPerfByShopFXOrder(int $offset = 0) {
-        // 循环获取全部报单
-        $allData = OrderShop::findUseDbCalc()
-        ->select(
-            'ID,SN,DEC_SN,USER_ID,ORDER_TYPE,ORDER_AMOUNT,PAY_AMOUNT,PAY_PV,PAY_TYPE,PERIOD_NUM,STATUS,IS_DELETE,
-            P_CALC_MONTH,CREATED_AT')
-        ->where(
-            "PERIOD_NUM=:PERIOD_NUM AND IS_DELETE=0 AND ORDER_TYPE=:ORDER_TYPE AND CREATED_AT<=:CREATED_AT", 
-            [':PERIOD_NUM' => $this->_periodNum, ':ORDER_TYPE'=>DeclarationForm::TYPE_FX,':CREATED_AT' => $this->_lastTime]
-        )
-        ->orderBy('CREATED_AT DESC,ID DESC')
-        ->offset($offset)
-        ->limit($this->_limit)
-        ->asArray()
-        ->all();
-        if ($allData) {
-            $insertPerfOrderData = [];
-            foreach ($allData as $data) {
-
-                //如果支付方式是现金,那么实际业绩是支付PV的50%
-                if( $data['PAY_TYPE'] === self::ORDER_PAY_TYPE_CASH ) {
-                    $orderCashAmount = $data['ORDER_AMOUNT'];
-                    //111期开始由50%改为60%-by 2020-04-30修改
-                    $payPv = $data['PAY_PV'] * $this->_sysConfig['cashReconsumeBonusPercent']['VALUE'] / 100;
-                    $cacheDataKey = 'PV_PCS_FX_CASH';
-                }else {
-                    $orderCashAmount = 0;
-                    $payPv = $data['PAY_PV'];
-                    $cacheDataKey = 'PV_PCS_FX_POINT';
                 }
-
-                if( $payPv <= 0 ) continue;
-
-                // 给自己增加PCS(个人消费)
-                PrepareCalcCache::nowPeriodPerf($data['USER_ID'], $this->_periodNum, [
-                    'FX_AMOUNT_CASH' => $orderCashAmount,
-                    'PV_PCS' => $payPv,
-                    'PV_PCS_FX' => $payPv,
-                    $cacheDataKey => $payPv,
-                ]);
-                // 把该会员加入到能拿到业绩的会员缓存中
-                PrepareCalcCache::addHasPerfUsers($data['USER_ID'], $this->_periodNum);
-                // 给上追加业绩
-                $this->loopNetworkParentDo($data['USER_ID'], function ($parent) use (&$data, $payPv) {
-                    // 给上级会员追加本期业绩到缓存中
-                    PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
-                        'PV_' . $parent['LOCATION'] . 'L' => $payPv,
-                        'PV_' . $parent['LOCATION'] . 'L_TOUCH' => $payPv,
-                        'PV_' . $parent['LOCATION'] . 'L_FX' => $payPv,
-                    ]);
-                    // 把该会员加入到能拿到业绩的会员缓存中
-                    PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
-                });
-                //给推荐关系累计增加业绩
-                $this->loopRelationParentDo($data['USER_ID'], function ($parent) use ($data, $payPv) {
-                    // 给上级会员追加本期业绩到缓存中
-                    PrepareCalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
-                        'PV_PSS' => $payPv,
-                    ]);
-                    // 把该会员加入到能拿到业绩的会员缓存中
-                    PrepareCalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
-                });
-
-//                }
-                // 写入业绩单表
-                $baseInfo = PrepareCalcCache::getUserInfo($data['USER_ID'], $this->_periodNum);
-                $sn = PerfOrderPrepare::generateSN();
-                $insertPerfOrderData[] = [
-                    'ID' => SnowFake::instance()->generateId(),
-                    'SN' => $sn,
-                    'DEC_SN' => null,
-                    'DEC_TYPE' => 'FX',
-                    'DEC_STATUS' => PerfOrder::STATUS_NORMAL,
-                    'USER_ID' => $data['USER_ID'],
-                    'LAST_REC_USER_NAME' => $baseInfo['REC_USER_NAME'],
-                    'LAST_REC_REAL_NAME' => $baseInfo['REC_REAL_NAME'],
-                    'LAST_DEC_LV' => $baseInfo['DEC_LV'],
-                    'LAST_EMP_LV' => $baseInfo['EMP_LV'],
-                    'LAST_STATUS' => $baseInfo['STATUS'],
-                    'PV' => $payPv,
-                    'DEC_AMOUNT' => $data['PAY_AMOUNT'],
-                    'LAST_SUB_COM_ID' => $baseInfo['SUB_COM_ID'],
-                    'LAST_PROVINCE' => $baseInfo['PROVINCE'],
-                    'LAST_CITY' => $baseInfo['CITY'],
-                    'LAST_COUNTY' => $baseInfo['COUNTY'],
-                    'DEC_USER_ID' => $data['USER_ID'],
-                    'LAST_DEC_DEC_LV' => $baseInfo['DEC_LV'],
-                    'LAST_DEC_SUB_COM_ID' => $baseInfo['SUB_COM_ID'],
-                    'LAST_DEC_PROVINCE' => $baseInfo['PROVINCE'],
-                    'LAST_DEC_CITY' => $baseInfo['CITY'],
-                    'LAST_DEC_COUNTY' => $baseInfo['COUNTY'],
-                    'PERIOD_NUM' => $this->_periodNum,
-                    'CALC_MONTH' => $this->_calcYearMonth,
-                    'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH),
-                    'CREATED_AT' => Date::nowTime(),
-                    'CLOSED_AT' => 0,
-                    'ORDER_CREATED_AT' => $data['CREATED_AT']
-                ];
-                unset($data, $baseInfo, $sn, $orderCashAmount, $payPv, $cacheDataKey);
             }
-            PerfOrderPrepare::batchInsert($insertPerfOrderData);
 
-            unset($insertPerfOrderData, $allData, $snArr);
-            return $this->loopCalcPerfByShopFXOrder($offset + $this->_limit);
+            return $this->loopGrandPerf($offset + $this->_limit);
         }
-
         unset($allData);
         return true;
     }
@@ -865,156 +351,12 @@ class CalcServePerfCalc {
         if (!$this->_isCalcMonth) {
             return true;
         }
-        // AR_PERF_ORDER_PREPARE\AR_PERF_PERIOD_PREPARE\AR_PERIOD_PREPARE\AR_PERF_MONTH_PREPARE
-        // AR_PERIOD_PREPARE 表只需要是结算月的数据
-        // AR_PERF_PERIOD_PREPARE 表特殊,需要增加一个字段,是否存在于前三期中  已被第一次算月业绩使用过了
-        //  `IS_HAS_USER` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否有此用户,默认为0没有此用户1为有
-        // 如果依旧是0则再次循环此月业绩的时候,需要再次处理' 相当于前三期没有数据,需要单独再添加一次
-        //
-        // 月业绩由perfperiod表加上perfperiodprepare表之和,其中perfperiod表数据为此月非计算月的期业绩数据
-        // 先查询perfperiod表的数据,再查询perfperiodprepare这个表的数据.
-        // 如果查询到了perfperiodprepare的数据,则将此perfperiodprepare表的新增的是否已经在计算第一次统计到的字段标识为1.
-        // 最后再循环 perfperiodprepare 表中标识依旧为0的数据,再次循环.相当于这些数据是此结算月业绩期的新增用户
         echo sprintf("时间:[%s]月业绩,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
-        // 从缓存列表里面从底层往上倒序获取会员       
         $allData = PerfPeriod::findUseDbCalc()
-        ->select('USER_ID, SUM(FX_AMOUNT_CASH) AS FX_AMOUNT_CASH_SUM,SUM(PV_PCS) AS PV_PCS_SUM,
-        SUM(PV_PCS_FX) AS PV_PCS_FX_SUM,SUM(PV_PSS) AS PV_PSS_SUM,
-        SUM(PV_1L) AS PV_1L_SUM,SUM(PV_2L) AS PV_2L_SUM,
-        SUM(PV_3L) AS PV_3L_SUM,SUM(PV_4L) AS PV_4L_SUM,
-        SUM(PV_5L) AS PV_5L_SUM,SUM(PV_1L_ZC) AS PV_1L_ZC_SUM,
-        SUM(PV_2L_ZC) AS PV_2L_ZC_SUM,SUM(PV_3L_ZC) AS PV_3L_ZC_SUM,
-        SUM(PV_4L_ZC) AS PV_4L_ZC_SUM,SUM(PV_5L_ZC) AS PV_5L_ZC_SUM')
-        ->where('CALC_MONTH=:CALC_MONTH AND PERIOD_NUM!=:PERIOD_NUM', [':CALC_MONTH' => $this->_calcYearMonth,':PERIOD_NUM'=>$this->_periodNum])
-        ->groupBy('USER_ID')
-        ->orderBy('USER_ID DESC')
-        ->offset($offset)
-        ->limit($this->_limit)
-        ->asArray()
-        ->all();
-        if ($allData) {
-            // 月度业绩表
-            foreach ($allData as $everyData) {
-                $userId = $everyData['USER_ID'];
-                //往期业绩
-                $userLastPerf = PrepareCalcCache::userPerf($userId, $this->_periodNum);
-                //本期业绩
-                $periodPerf = PrepareCalcCache::nowPeriodPerf($userId, $this->_periodNum);
-
-                $userBaseInfo = PrepareCalcCache::getUserInfo($userId, $this->_periodNum);
-                //级别必须为VIP
-                $isVip = false;
-                if( $userBaseInfo['DEC_LV'] === DeclarationLevel::VIP_LEVEL_ID ) {
-                    $isVip= true;
-                }
-                if( $this->_sysConfig['vipBonusGoldDecLevel']['VALUE'] && $userBaseInfo['DEC_LV'] === DeclarationLevel::JIN_ZUAN_LEVEL_ID ) {
-                    $isVip = true;
-                }
-                // 查询月节点此期业绩,是否包含此用户
-                // 查询perfperiodprepare表中数据,是否有此用户信息.因为是月提前结算,所以此结算期是只有一个数据
-                $monthPrepare = PerfPeriodPrepare::findUseDbCalc()
-                ->select('USER_ID, SUM(FX_AMOUNT_CASH) AS FX_AMOUNT_CASH_SUM,SUM(PV_PCS) AS PV_PCS_SUM,
-                SUM(PV_PCS_FX) AS PV_PCS_FX_SUM,SUM(PV_PSS) AS PV_PSS_SUM,
-                SUM(PV_1L) AS PV_1L_SUM,SUM(PV_2L) AS PV_2L_SUM,
-                SUM(PV_3L) AS PV_3L_SUM,SUM(PV_4L) AS PV_4L_SUM,
-                SUM(PV_5L) AS PV_5L_SUM,SUM(PV_1L_ZC) AS PV_1L_ZC_SUM,
-                SUM(PV_2L_ZC) AS PV_2L_ZC_SUM,SUM(PV_3L_ZC) AS PV_3L_ZC_SUM,
-                SUM(PV_4L_ZC) AS PV_4L_ZC_SUM,SUM(PV_5L_ZC) AS PV_5L_ZC_SUM')
-                ->where('USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM ', [':USER_ID' => $userId, ':PERIOD_NUM' => $this->_periodNum])
-                ->asArray()
-                ->one();
-                if (!empty($monthPrepare)) {
-                    // 如果前三期中,在此提前计算业绩期中有数据,则需要加上此用户信息
-                    $everyData['FX_AMOUNT_CASH_SUM'] = $everyData['FX_AMOUNT_CASH_SUM'] + $monthPrepare['FX_AMOUNT_CASH_SUM'];
-                    $everyData['PV_PCS_SUM'] = $everyData['PV_PCS_SUM'] + $monthPrepare['PV_PCS_SUM'];
-                    $everyData['PV_PCS_FX_SUM'] =  $everyData['PV_PCS_FX_SUM'] + $monthPrepare['PV_PCS_FX_SUM'];
-                    $everyData['PV_PSS_SUM'] = $everyData['PV_PSS_SUM'] + $monthPrepare['PV_PSS_SUM'];
-                    $everyData['PV_1L_SUM'] = $everyData['PV_1L_SUM'] + $monthPrepare['PV_1L_SUM'];
-                    $everyData['PV_2L_SUM'] = $everyData['PV_2L_SUM'] + $monthPrepare['PV_2L_SUM'];
-                    $everyData['PV_3L_SUM'] = $everyData['PV_3L_SUM'] + $monthPrepare['PV_3L_SUM'];
-                    $everyData['PV_4L_SUM'] = $everyData['PV_4L_SUM'] + $monthPrepare['PV_4L_SUM'];
-                    $everyData['PV_5L_SUM'] = $everyData['PV_5L_SUM'] + $monthPrepare['PV_5L_SUM'];
-                    $everyData['PV_1L_ZC_SUM'] = $everyData['PV_1L_ZC_SUM'] + $monthPrepare['PV_1L_ZC_SUM'];
-                    $everyData['PV_2L_ZC_SUM'] = $everyData['PV_2L_ZC_SUM'] + $monthPrepare['PV_2L_ZC_SUM'];
-                    $everyData['PV_3L_ZC_SUM'] = $everyData['PV_3L_ZC_SUM'] + $monthPrepare['PV_3L_ZC_SUM'];
-                    $everyData['PV_4L_ZC_SUM'] = $everyData['PV_4L_ZC_SUM'] + $monthPrepare['PV_4L_ZC_SUM'];
-                    $everyData['PV_5L_ZC_SUM'] = $everyData['PV_5L_ZC_SUM'] + $monthPrepare['PV_5L_ZC_SUM'];
-                    // 将用户的状态改成1,为存在此用户.当之后再次循环PerfPeriodPrepare的时候,不再循环此用户了.
-                    PerfPeriodPrepare::updateAll(
-                        [
-                            'IS_HAS_USER' => 1
-                        ], 
-                        'PERIOD_NUM=:PERIOD_NUM AND USER_ID=:USER_ID', 
-                        [':PERIOD_NUM' => $this->_periodNum, ':USER_ID' => $userId]
-                    );
-                }
-
-                $nowMonthPerf = [
-                    'USER_ID' => $userId,
-                    'FX_AMOUNT_CASH' => $everyData['FX_AMOUNT_CASH_SUM'],
-                    'PV_PCS' => $everyData['PV_PCS_SUM'],
-                    'PV_PCS_FX' => $everyData['PV_PCS_FX_SUM'],
-                    'PV_PSS' => $everyData['PV_PSS_SUM'],
-                    'PV_1L' => $everyData['PV_1L_SUM'],
-                    'PV_2L' => $everyData['PV_2L_SUM'],
-                    'PV_3L' => $everyData['PV_3L_SUM'],
-                    'PV_4L' => $everyData['PV_4L_SUM'],
-                    'PV_5L' => $everyData['PV_5L_SUM'],
-
-                    //VIP统计相关业绩
-                    'VIP_PV_1L_ZC' => $isVip ? $everyData['PV_1L_ZC_SUM'] : 0,
-                    'VIP_PV_2L_ZC' => $isVip ? $everyData['PV_2L_ZC_SUM'] : 0,
-                    'VIP_PV_3L_ZC' => $isVip ? $everyData['PV_3L_ZC_SUM'] : 0,
-                    'VIP_PV_4L_ZC' => $isVip ? $everyData['PV_4L_ZC_SUM'] : 0,
-                    'VIP_PV_5L_ZC' => $isVip ? $everyData['PV_5L_ZC_SUM'] : 0,
-
-                    //总数据,历史+本期。不能用上月加本月,因为上月可能没业绩,上上个月有业绩。
-                    'PV_1L_TOTAL' => $periodPerf['PV_1L'] + $userLastPerf['PV_1L'],
-                    'PV_2L_TOTAL' => $periodPerf['PV_2L'] + $userLastPerf['PV_2L'],
-                    'PV_3L_TOTAL' => $periodPerf['PV_3L'] + $userLastPerf['PV_3L'],
-                    'PV_4L_TOTAL' => $periodPerf['PV_4L'] + $userLastPerf['PV_4L'],
-                    'PV_5L_TOTAL' => $periodPerf['PV_5L'] + $userLastPerf['PV_5L'],
-                    'PV_PSS_TOTAL' => $periodPerf['PV_PSS'] + $userLastPerf['PV_PSS_TOTAL'],
-                ];
-
-                // 把会员的月业绩写入缓存中,以便下面的奖金计算从缓冲中获取数据效率高
-                PrepareCalcCache::addHasMonthPerfUsers($userId, $this->_periodNum);
-                PrepareCalcCache::nowMonthPerf($userId, $this->_periodNum, $nowMonthPerf);
-
-                unset($userId, $everyData, $nowMonthPerf, $lastMonthData, $userBaseInfo, $isVip);
-            }
-            unset($allData);
-            return $this->loopCalcMonthPerfTableData($offset + $this->_limit);
-        }
-
-        unset($allData);
-        return true;
-    }
-
-    /**
-     * 预计计算月业绩,当前三期没有此最新业绩单的用户
-     * 再次添加进去
-     * @param int $offset
-     * @return bool
-     * @throws Exception
-     * @throws \yii\db\Exception
-     */
-    public function loopCalcMonthPerfTableDataPrepare(int $offset = 0) {
-        if (!$this->_isCalcMonth) {
-            return true;
-        }
-        // 上面的计算月业绩,计算了前三期有的用户,此次只计算此结算周期未含有前三期业绩的用户
-       
-        echo sprintf("时间:[%s]预计月业绩,结算月新添加的用户,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
-        // 从缓存列表里面从底层往上倒序获取会员      IS_HAS_USER 0 代表是此结算周期新增的业绩 
-        $allData = PerfPeriodPrepare::findUseDbCalc()
-        ->select('IS_HAS_USER,USER_ID, SUM(FX_AMOUNT_CASH) AS FX_AMOUNT_CASH_SUM,SUM(PV_PCS) AS PV_PCS_SUM,
-        SUM(PV_PCS_FX) AS PV_PCS_FX_SUM,SUM(PV_PSS) AS PV_PSS_SUM,
-        SUM(PV_1L) AS PV_1L_SUM,SUM(PV_2L) AS PV_2L_SUM,
-        SUM(PV_3L) AS PV_3L_SUM,SUM(PV_4L) AS PV_4L_SUM,
-        SUM(PV_5L) AS PV_5L_SUM,SUM(PV_1L_ZC) AS PV_1L_ZC_SUM,
-        SUM(PV_2L_ZC) AS PV_2L_ZC_SUM,SUM(PV_3L_ZC) AS PV_3L_ZC_SUM,
-        SUM(PV_4L_ZC) AS PV_4L_ZC_SUM,SUM(PV_5L_ZC) AS PV_5L_ZC_SUM')
+        ->select('USER_ID, SUM(FX_AMOUNT_CASH) AS FX_AMOUNT_CASH_SUM,SUM(PV_PCS) AS PV_PCS_SUM,SUM(PV_PCS_FX) AS PV_PCS_FX_SUM,
+        SUM(PV_PSS) AS PV_PSS_SUM,SUM(PV_1L) AS PV_1L_SUM,SUM(PV_2L) AS PV_2L_SUM,SUM(PV_3L) AS PV_3L_SUM,
+        SUM(PV_4L) AS PV_4L_SUM,SUM(PV_5L) AS PV_5L_SUM,SUM(PV_1L_ZC) AS PV_1L_ZC_SUM,SUM(PV_2L_ZC) AS PV_2L_ZC_SUM,
+        SUM(PV_3L_ZC) AS PV_3L_ZC_SUM,SUM(PV_4L_ZC) AS PV_4L_ZC_SUM,SUM(PV_5L_ZC) AS PV_5L_ZC_SUM')
         ->where('CALC_MONTH=:CALC_MONTH', [':CALC_MONTH' => $this->_calcYearMonth])
         ->groupBy('USER_ID')
         ->orderBy('USER_ID DESC')
@@ -1025,25 +367,12 @@ class CalcServePerfCalc {
         if ($allData) {
             // 月度业绩表
             foreach ($allData as $everyData) {
-                if ($everyData['IS_HAS_USER'] != 0) {
-                    continue;
-                }
                 $userId = $everyData['USER_ID'];
                 //往期业绩
-                $userLastPerf = PrepareCalcCache::userPerf($userId, $this->_periodNum);
+                $userLastPerf = CalcCache::userPerf($userId, $this->_periodNum);
                 //本期业绩
-                $periodPerf = PrepareCalcCache::nowPeriodPerf($userId, $this->_periodNum);
-
-                $userBaseInfo = PrepareCalcCache::getUserInfo($userId, $this->_periodNum);
-                //级别必须为VIP
-                $isVip = false;
-                if( $userBaseInfo['DEC_LV'] === DeclarationLevel::VIP_LEVEL_ID ) {
-                    $isVip= true;
-                }
-                if( $this->_sysConfig['vipBonusGoldDecLevel']['VALUE'] && $userBaseInfo['DEC_LV'] === DeclarationLevel::JIN_ZUAN_LEVEL_ID ) {
-                    $isVip = true;
-                }
-
+                $periodPerf = CalcCache::nowPeriodPerf($userId, $this->_periodNum);
+                $userBaseInfo = CalcCache::getUserInfo($userId, $this->_periodNum);
                 $nowMonthPerf = [
                     'USER_ID' => $userId,
                     'FX_AMOUNT_CASH' => $everyData['FX_AMOUNT_CASH_SUM'],
@@ -1055,14 +384,6 @@ class CalcServePerfCalc {
                     'PV_3L' => $everyData['PV_3L_SUM'],
                     'PV_4L' => $everyData['PV_4L_SUM'],
                     'PV_5L' => $everyData['PV_5L_SUM'],
-
-                    //VIP统计相关业绩
-                    'VIP_PV_1L_ZC' => $isVip ? $everyData['PV_1L_ZC_SUM'] : 0,
-                    'VIP_PV_2L_ZC' => $isVip ? $everyData['PV_2L_ZC_SUM'] : 0,
-                    'VIP_PV_3L_ZC' => $isVip ? $everyData['PV_3L_ZC_SUM'] : 0,
-                    'VIP_PV_4L_ZC' => $isVip ? $everyData['PV_4L_ZC_SUM'] : 0,
-                    'VIP_PV_5L_ZC' => $isVip ? $everyData['PV_5L_ZC_SUM'] : 0,
-
                     //总数据,历史+本期。不能用上月加本月,因为上月可能没业绩,上上个月有业绩。
                     'PV_1L_TOTAL' => $periodPerf['PV_1L'] + $userLastPerf['PV_1L'],
                     'PV_2L_TOTAL' => $periodPerf['PV_2L'] + $userLastPerf['PV_2L'],
@@ -1073,22 +394,13 @@ class CalcServePerfCalc {
                 ];
 
                 // 把会员的月业绩写入缓存中,以便下面的奖金计算从缓冲中获取数据效率高
-                PrepareCalcCache::addHasMonthPerfUsers($userId, $this->_periodNum);
-                PrepareCalcCache::nowMonthPerf($userId, $this->_periodNum, $nowMonthPerf);
-                // 将用户的状态改成1,为存在此用户.当之后再次循环PerfPeriodPrepare的时候,不再循环此用户了.
-                PerfPeriodPrepare::updateAll(
-                    [
-                        'IS_HAS_USER' => 1
-                    ], 
-                    'PERIOD_NUM=:PERIOD_NUM AND USER_ID=:USER_ID', 
-                    [':PERIOD_NUM' => $this->_periodNum, ':USER_ID' => $userId]
-                );
-
+                CalcCache::addHasMonthPerfUsers($userId, $this->_periodNum);
+                CalcCache::nowMonthPerf($userId, $this->_periodNum, $nowMonthPerf);
 
                 unset($userId, $everyData, $nowMonthPerf, $lastMonthData, $userBaseInfo, $isVip);
             }
             unset($allData);
-            return $this->loopCalcMonthPerfTableDataPrepare($offset + $this->_limit);
+            $this->loopCalcMonthPerfTableData($offset + $this->_limit);
         }
 
         unset($allData);
@@ -1104,14 +416,14 @@ class CalcServePerfCalc {
     public function loopWriteNowPerf($offset = 0) {
         echo sprintf("时间:[%s]缓存本期业绩数据入库,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
         // 从缓存列表里面从底层往上倒序获取会员
-        $allData = PrepareCalcCache::getHasPerfUsers($this->_periodNum, $offset, $this->_limit);
+        $allData = CalcCache::getHasPerfUsers($this->_periodNum, $offset, $this->_limit);
         if($allData){
             $insertDataPeriodPerf = [];
             foreach($allData as $userId){
                 $insertDataPeriodPerf[] = $this->nowPeriodPerfData($userId);
                 unset($userId);
             }
-            PerfPeriodPrepare::batchInsert($insertDataPeriodPerf);
+            PerfPeriod::batchInsert($insertDataPeriodPerf);
 
             unset($insertDataPeriodPerf, $allData);
             return $this->loopWriteNowPerf($offset + $this->_limit);
@@ -1132,15 +444,15 @@ class CalcServePerfCalc {
         }
         echo sprintf("时间:[%s]缓存本月业绩数据入库,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
         // 从缓存列表里面从底层往上倒序获取会员
-        $allData = PrepareCalcCache::getHasMonthPerfUsers($this->_periodNum, $offset, $this->_limit);
+        $allData = CalcCache::getHasMonthPerfUsers($this->_periodNum, $offset, $this->_limit);
         if($allData){
             $insertDataMonthPerf = [];
             foreach($allData as $userId){
                 $insertDataMonthPerf[] = $this->nowMonthPerfData($userId);
                 unset($userId);
             }
-            // 月预计计算业绩插入数据
-            PerfMonthPrepare::batchInsert($insertDataMonthPerf);
+
+            PerfMonth::batchInsert($insertDataMonthPerf);
             unset($insertDataMonthPerf, $allData);
             return $this->loopWriteMonthPerf($offset + $this->_limit);
         }
@@ -1154,58 +466,36 @@ class CalcServePerfCalc {
      * @return array
      */
     public function nowPeriodPerfData($userId){
-        $data = PrepareCalcCache::nowPeriodPerf($userId, $this->_periodNum);
-        $baseInfo = PrepareCalcCache::getUserInfo($userId, $this->_periodNum);
+        $data = CalcCache::nowPeriodPerf($userId, $this->_periodNum);
         $result = [
             'ID' => SnowFake::instance()->generateId(),
             'USER_ID' => $userId,
-            'LAST_DEC_LV' => $baseInfo['DEC_LV'],
-            'LAST_EMP_LV' => $baseInfo['EMP_LV'],
-            'LAST_STATUS' => $baseInfo['STATUS'],
             'FX_AMOUNT_CASH' => $data['FX_AMOUNT_CASH'],
             'PV_PCS' => $data['PV_PCS'],
             'PV_PSS' => $data['PV_PSS'],
             'PV_PCS_ZC' => $data['PV_PCS_ZC'],
-            'PV_PCS_YH' => $data['PV_PCS_YH'],
-            'PV_PCS_ZG' => $data['PV_PCS_ZG'],
-            'PV_PCS_LS' => $data['PV_PCS_LS'],
             'PV_PCS_FX' => $data['PV_PCS_FX'],
             'PV_PCS_FX_CASH' => $data['PV_PCS_FX_CASH'],
             'PV_PCS_FX_POINT' => $data['PV_PCS_FX_POINT'],
             'PV_1L' => $data['PV_1L'],
             'PV_1L_TOUCH' => $data['PV_1L_TOUCH'],
             'PV_1L_ZC' => $data['PV_1L_ZC'],
-            'PV_1L_YH' => $data['PV_1L_YH'],
-            'PV_1L_ZG' => $data['PV_1L_ZG'],
-            'PV_1L_LS' => $data['PV_1L_LS'],
             'PV_1L_FX' => $data['PV_1L_FX'],
             'PV_2L' => $data['PV_2L'],
             'PV_2L_TOUCH' => $data['PV_2L_TOUCH'],
             'PV_2L_ZC' => $data['PV_2L_ZC'],
-            'PV_2L_YH' => $data['PV_2L_YH'],
-            'PV_2L_ZG' => $data['PV_2L_ZG'],
-            'PV_2L_LS' => $data['PV_2L_LS'],
             'PV_2L_FX' => $data['PV_2L_FX'],
             'PV_3L' => $data['PV_3L'],
             'PV_3L_TOUCH' => $data['PV_3L_TOUCH'],
             'PV_3L_ZC' => $data['PV_3L_ZC'],
-            'PV_3L_YH' => $data['PV_3L_YH'],
-            'PV_3L_ZG' => $data['PV_3L_ZG'],
-            'PV_3L_LS' => $data['PV_3L_LS'],
             'PV_3L_FX' => $data['PV_3L_FX'],
             'PV_4L' => $data['PV_4L'],
             'PV_4L_TOUCH' => $data['PV_4L_TOUCH'],
             'PV_4L_ZC' => $data['PV_4L_ZC'],
-            'PV_4L_YH' => $data['PV_4L_YH'],
-            'PV_4L_ZG' => $data['PV_4L_ZG'],
-            'PV_4L_LS' => $data['PV_4L_LS'],
             'PV_4L_FX' => $data['PV_4L_FX'],
             'PV_5L' => $data['PV_5L'],
             'PV_5L_TOUCH' => $data['PV_5L_TOUCH'],
             'PV_5L_ZC' => $data['PV_5L_ZC'],
-            'PV_5L_YH' => $data['PV_5L_YH'],
-            'PV_5L_ZG' => $data['PV_5L_ZG'],
-            'PV_5L_LS' => $data['PV_5L_LS'],
             'PV_5L_FX' => $data['PV_5L_FX'],
             'PV_LS_TOUCH' => $data['PV_LS_TOUCH'],
             'SURPLUS_1L' => $data['SURPLUS_1L'],
@@ -1216,7 +506,6 @@ class CalcServePerfCalc {
             'SURPLUS_LS' => $data['SURPLUS_LS'],
             'PERIOD_NUM' => $this->_periodNum,
             'CALC_MONTH' => $this->_calcYearMonth,
-            'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH),
             'CREATED_AT' => Date::nowTime(),
         ];
         unset($data);
@@ -1231,14 +520,10 @@ class CalcServePerfCalc {
      * @return array
      */
     public function nowMonthPerfData($userId){
-        $data = PrepareCalcCache::nowMonthPerf($userId, $this->_periodNum);
-        $baseInfo = PrepareCalcCache::getUserInfo($userId, $this->_periodNum);
+        $data = CalcCache::nowMonthPerf($userId, $this->_periodNum);
         $result = [
             'ID' => SnowFake::instance()->generateId(),
             'USER_ID' => $userId,
-            'LAST_DEC_LV' => $baseInfo['DEC_LV'],
-            'LAST_EMP_LV' => $data['EMP_LEVEL'],
-            'LAST_STATUS' => $baseInfo['STATUS'],
             'FX_AMOUNT_CASH' => $data['FX_AMOUNT_CASH'],
             'PV_PCS' => $data['PV_PCS'],
             'PV_PCS_FX' => $data['PV_PCS_FX'],
@@ -1248,22 +533,13 @@ class CalcServePerfCalc {
             'PV_3L' => $data['PV_3L'],
             'PV_4L' => $data['PV_4L'],
             'PV_5L' => $data['PV_5L'],
-            'VIP_PV_1L_ZC' => $data['VIP_PV_1L_ZC'],
-            'VIP_PV_2L_ZC' => $data['VIP_PV_2L_ZC'],
-            'VIP_PV_3L_ZC' => $data['VIP_PV_3L_ZC'],
-            'VIP_PV_4L_ZC' => $data['VIP_PV_4L_ZC'],
-            'VIP_PV_5L_ZC' => $data['VIP_PV_5L_ZC'],
             'PV_1L_TOTAL' => $data['PV_1L_TOTAL'],
             'PV_2L_TOTAL' => $data['PV_2L_TOTAL'],
             'PV_3L_TOTAL' => $data['PV_3L_TOTAL'],
             'PV_4L_TOTAL' => $data['PV_4L_TOTAL'],
             'PV_5L_TOTAL' => $data['PV_5L_TOTAL'],
             'PV_PSS_TOTAL' => $data['PV_PSS_TOTAL'],
-            'CF_PERCENT' => $data['CF_PERCENT'],
-            'LX_PERCENT' => $data['LX_PERCENT'],
-            'FX_STATUS' => $data['FX_STATUS'],
             'CALC_MONTH' => $this->_calcYearMonth,
-            'P_CALC_MONTH' => Date::ociToDate($this->_calcYearMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH),
             'CREATED_AT' => Date::nowTime(),
         ];
         unset($data);

+ 4 - 39
common/models/PerfMonth.php

@@ -11,9 +11,6 @@ use common\libs\logging\operate\valueType\Config as ValueTypeConfig;
  *
  * @property string $ID
  * @property string $USER_ID 会员ID
- * @property string $LAST_DEC_LV 结算时会员级别
- * @property string $LAST_EMP_LV 结算时会员聘级
- * @property int $LAST_STATUS 结算时会有状态
  * @property string $FX_AMOUNT_CASH 复消现金金额
  * @property string $PV_PCS 个人消费
  * @property string $PV_PCS_FX 个人复消业绩
@@ -22,26 +19,12 @@ use common\libs\logging\operate\valueType\Config as ValueTypeConfig;
  * @property string $PV_3L 三市场业绩
  * @property string $PV_4L 四市场业绩
  * @property string $PV_5L 五市场业绩
- * @property string $VIP_PV_1L_ZC VIP一市场报单业绩
- * @property string $VIP_PV_2L_ZC VIP二市场报单业绩
- * @property string $VIP_PV_3L_ZC VIP三市场报单业绩
- * @property string $VIP_PV_4L_ZC VIP四市场报单业绩
- * @property string $VIP_PV_5L_ZC VIP五市场报单业绩
- * @property string $VIP_SURPLUS_1L_ZC VIP一市场剩余报单业绩
- * @property string $VIP_SURPLUS_2L_ZC VIP二市场剩余报单业绩
- * @property string $VIP_SURPLUS_3L_ZC VIP三市场剩余报单业绩
- * @property string $VIP_SURPLUS_4L_ZC VIP四市场剩余报单业绩
- * @property string $VIP_SURPLUS_5L_ZC VIP五市场剩余报单业绩
  * @property string $PV_1L_TOTAL 一市场历史累计加该月业绩
  * @property string $PV_2L_TOTAL 二市场历史累计加该月业绩
  * @property string $PV_3L_TOTAL 三市场历史累计加该月业绩
  * @property string $PV_4L_TOTAL 四市场历史累计加该月业绩
  * @property string $PV_5L_TOTAL 五市场历史累计加该月业绩
- * @property int $CF_PERCENT 车房养老奖分工系数
- * @property int $LX_PERCENT 领袖分红分工系数
- * @property int $FX_STATUS 本月复销状态作为下月发奖资格
  * @property int $CALC_MONTH 结算月
- * @property string $P_CALC_MONTH 表分区日期索引
  * @property int $CREATED_AT 创建时间
  */
 class PerfMonth extends \common\components\ActiveRecord
@@ -63,11 +46,10 @@ class PerfMonth extends \common\components\ActiveRecord
     public function rules()
     {
         return [
-            [['USER_ID', 'CALC_MONTH', 'P_CALC_MONTH', 'CREATED_AT'], 'required'],
-            [['LAST_STATUS', 'CF_PERCENT', 'LX_PERCENT', 'FX_STATUS', 'CALC_MONTH', 'CREATED_AT'], 'integer'],
-            [['FX_AMOUNT_CASH', 'PV_PCS', 'PV_PCS_FX', 'PV_1L', 'PV_2L', 'PV_3L', 'PV_4L', 'PV_5L', 'VIP_PV_1L_ZC', 'VIP_PV_2L_ZC',  'VIP_PV_3L_ZC', 'VIP_PV_4L_ZC', 'VIP_PV_5L_ZC', 'VIP_SURPLUS_1L_ZC', 'VIP_SURPLUS_2L_ZC', 'VIP_SURPLUS_3L_ZC', 'VIP_SURPLUS_4L_ZC', 'VIP_SURPLUS_5L_ZC', 'PV_1L_TOTAL', 'PV_2L_TOTAL', 'PV_3L_TOTAL', 'PV_4L_TOTAL', 'PV_5L_TOTAL'], 'number'],
-            [['ID', 'USER_ID', 'LAST_DEC_LV', 'LAST_EMP_LV'], 'string', 'max' => 32],
-            [['P_CALC_MONTH'], 'safe'],
+            [['USER_ID', 'CALC_MONTH', 'CREATED_AT'], 'required'],
+            [['CALC_MONTH', 'CREATED_AT'], 'integer'],
+            [['FX_AMOUNT_CASH', 'PV_PCS', 'PV_PCS_FX', 'PV_1L', 'PV_2L', 'PV_3L', 'PV_4L', 'PV_5L','PV_1L_TOTAL', 'PV_2L_TOTAL', 'PV_3L_TOTAL', 'PV_4L_TOTAL', 'PV_5L_TOTAL'], 'number'],
+            [['ID', 'USER_ID'], 'string', 'max' => 32],
             [['ID'], 'unique'],
         ];
     }
@@ -80,9 +62,6 @@ class PerfMonth extends \common\components\ActiveRecord
         return [
             'ID' => 'ID',
             'USER_ID' => '会员ID',
-            'LAST_DEC_LV' => '结算时会员级别',
-            'LAST_EMP_LV' => '结算时会员聘级',
-            'LAST_STATUS' => '结算时会有状态',
             'FX_AMOUNT_CASH' => '复消现金金额',
             'PV_PCS' => '个人消费',
             'PV_PCS_FX' => '个人复消业绩',
@@ -91,26 +70,12 @@ class PerfMonth extends \common\components\ActiveRecord
             'PV_3L' => '三市场业绩',
             'PV_4L' => '四市场业绩',
             'PV_5L' => '五市场业绩',
-            'VIP_PV_1L_ZC' => 'VIP一市场报单业绩',
-            'VIP_PV_2L_ZC' => 'VIP二市场报单业绩',
-            'VIP_PV_3L_ZC' => 'VIP三市场报单业绩',
-            'VIP_PV_4L_ZC' => 'VIP四市场报单业绩',
-            'VIP_PV_5L_ZC' => 'VIP五市场报单业绩',
-            'VIP_SURPLUS_1L_ZC' => 'VIP一市场剩余报单业绩',
-            'VIP_SURPLUS_2L_ZC' => 'VIP二市场剩余报单业绩',
-            'VIP_SURPLUS_3L_ZC' => 'VIP三市场剩余报单业绩',
-            'VIP_SURPLUS_4L_ZC' => 'VIP四市场剩余报单业绩',
-            'VIP_SURPLUS_5L_ZC' => 'VIP五市场剩余报单业绩',
             'PV_1L_TOTAL' => '一市场历史累计加该月业绩',
             'PV_2L_TOTAL' => '二市场历史累计加该月业绩',
             'PV_3L_TOTAL' => '三市场历史累计加该月业绩',
             'PV_4L_TOTAL' => '四市场历史累计加该月业绩',
             'PV_5L_TOTAL' => '五市场历史累计加该月业绩',
-            'CF_PERCENT' => '车房养老奖分工系数',
-            'LX_PERCENT' => '领袖分红分工系数',
-            'FX_STATUS' => '本月复销状态作为下月发奖资格',
             'CALC_MONTH' => '结算月',
-            'P_CALC_MONTH' => '表分区日期索引',
             'CREATED_AT' => '创建时间',
         ];
     }

+ 24 - 28
common/models/forms/CalcServePeriodForm.php

@@ -3,6 +3,7 @@ namespace common\models\forms;
 
 
 use common\components\Model;
+use common\helpers\bonus\CalcServeBonusCalc;
 use common\helpers\bonus\CalcServePerfCalc;
 use common\models\Period;
 use yii\base\Exception;
@@ -55,35 +56,8 @@ class CalcServePeriodForm extends Model
         $this->_periodModel = $periodModel;
     }
 
-    // /**
-    //  * 页面请求异步处理生成业绩单
-    //  * @return string | null
-    //  */
-    // public function perfWebToAsync(){
-    //     if(!$this->validate()){
-    //         return null;
-    //     }
-    //     $model = $this->_periodModel;
-    //     $model->IS_PERFING = 1;
-    //     $model->PERF_ADMIN_ID = \Yii::$app->user->id;
-    //     if(!$model->save()){
-    //         $this->addError('perf', Form::formatErrorsForApi($model->getErrors()));
-    //         return null;
-    //     }
-    //     // 异步处理添加任务
-    //     $settings = \Yii::$app->params['swooleAsyncTimer'];
-    //     $bonusSettings = \Yii::$app->params['swooleBonusConfig'];
-    //     $settings = array_merge($settings, $bonusSettings);
-    //     $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle('bonus/prepare-perf', \Yii::$app->request->get(), $settings);
-    //     if($taskKey === false){
-    //         $this->addError('perf', '请求失败');
-    //         return null;
-    //     }
-    //     return $model;
-    // }
-
     /**
-     * 异步处理逻辑
+     * 累计用户业绩
      * @param $handleUserId
      * @return bool|null
      * @throws Exception
@@ -96,6 +70,28 @@ class CalcServePeriodForm extends Model
         $bonusCalc = CalcServePerfCalc::instance();
         $periodNum = $periodNum ? $periodNum : $this->periodNum;
         $asyncResult = $bonusCalc->calcStep($periodNum, $handleUserId);
+        if($asyncResult){
+            $bonusCalc->endCalcTask();
+        } else {
+            $bonusCalc->errorCalcTask();
+            // $this->addErrors($bonusCalc->getErrors());
+        }
+        return $asyncResult;
+    }
+
+    /**
+     * 计算用户奖金
+     * @param $handleUserId
+     * @return bool|null
+     * @throws Exception
+     * @throws \yii\db\Exception
+     */
+    public function calcAsync($handleUserId){
+        if(!$this->validate()){
+            return null;
+        }
+        $bonusCalc = CalcServeBonusCalc::instance();
+        $asyncResult = $bonusCalc->calcStep($this->periodNum, $handleUserId);
         if($asyncResult){
             $bonusCalc->endCalcTask();
         } else {

+ 4 - 3
console/controllers/BonusController.php

@@ -52,6 +52,7 @@ use common\helpers\Form;
 use common\helpers\http\RemoteUploadApi;
 use common\helpers\Log;
 use common\libs\export\module\BonusExport;
+use common\models\forms\CalcServePeriodForm;
 use common\models\forms\PeriodForm;
 use common\models\LogAsync;
 use common\models\Withdraw;
@@ -70,12 +71,12 @@ class BonusController extends BaseController
         $periodNum = isset($params['periodNum']) && !empty($params['periodNum']) ? $params['periodNum'] : null;
         if($formModel->load($params, '') && $formModel->perfAsync($params['handleUserId'],$periodNum)){
             $handleResult = true;
-            \Yii::$app->swooleAsyncTimer->pushAsyncResultToAdmin($params['handleUserId'], "预计算月业绩第{$params['periodNum']}期生成业绩单更新成功");
+            \Yii::$app->swooleAsyncTimer->pushAsyncResultToAdmin($params['handleUserId'], "累计用户业绩第{$params['periodNum']}期生成业绩单更新成功");
         } else {
-            \Yii::$app->swooleAsyncTimer->pushAsyncResultToAdmin($params['handleUserId'], "预计算月业绩第{$params['periodNum']}期生成业绩单更新失败,原因:".Form::formatErrorsForApi($formModel->getErrors()), false);
+            \Yii::$app->swooleAsyncTimer->pushAsyncResultToAdmin($params['handleUserId'], "累计用户业绩第{$params['periodNum']}期生成业绩单更新失败,原因:".Form::formatErrorsForApi($formModel->getErrors()), false);
         }
         if(!$handleResult){
-            echo "预计算月业绩,第{$params['periodNum']}期生成业绩单更新失败,原因:".Form::formatErrorsForApi($formModel->getErrors());
+            echo "计算服务累计业绩,第{$params['periodNum']}期生成业绩单更新失败,原因:".Form::formatErrorsForApi($formModel->getErrors());
         }
     }