Kaynağa Gözat

Merge branch 'new-version' into feature/1561-uploadServiceChange

kevin_zhangl 3 yıl önce
ebeveyn
işleme
bb2f8267a6

+ 24 - 0
backendApi/modules/v1/models/lists/bonus/PeriodBonusList.php

@@ -495,6 +495,30 @@ class PeriodBonusList extends \common\libs\dataList\DataList implements DataList
                         'prop'=>'ORI_MONTH_GX_BONUS',
                     ],
                 ],
+                'BONUS_ST' => [
+                    'header' => '店服务奖',
+                    'value' => function($row) {
+                        return (new Price([
+                            'value' => $row['BONUS_ST'],
+                        ]))->result();
+                    },
+                    'headerOther' => [
+                        'width' => '120',
+                        'prop'=>'BONUS_ST',
+                    ],
+                ],
+                'ORI_BONUS_ST' => [
+                    'header' => '店服务奖原金额',
+                    'value' => function($row) {
+                        return (new Price([
+                            'value' => $row['ORI_BONUS_ST'],
+                        ]))->result();
+                    },
+                    'headerOther' => [
+                        'width' => '120',
+                        'prop'=>'ORI_BONUS_ST',
+                    ],
+                ],
                 'BONUS_BD' => [
                     'header' => '服务奖',
                     'value' => function($row) {

+ 180 - 6
common/helpers/bonus/BonusCalc.php

@@ -26,6 +26,7 @@ use common\models\CalcBonusHB;
 use common\models\CalcBonusLS;
 use common\models\CalcBonusLX;
 use common\models\CalcBonusQY;
+use common\models\CalcBonusST;
 use common\models\CalcBonusStandard;
 use common\models\CalcBonusTG;
 use common\models\CalcBonusVIP;
@@ -253,13 +254,25 @@ class BonusCalc extends BaseObject {
 //            $t14 = microtime(true);
 //            echo('计算复消管理奖'.($this->_sysConfig['fxOpenGL']['VALUE']?'完成':'关闭').',耗时:' . round($t14 - $t13, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
 //            $this->_updatePercent(70);
-
-            if($this->_sysConfig['openYC']['VALUE']) {
-                $this->calcBonusYCStepOne();
-                $this->calcBonusYCStepTwo();
+          
+
+            // if($this->_sysConfig['openYC']['VALUE']) {
+            //     $this->calcBonusYCStepOne();
+            //     $this->calcBonusYCStepTwo();
+            // }
+
+            // 计算店服务奖 月奖
+            if($this->_sysConfig['openStore']['VALUE']) {
+                if ($this->_sysConfig['openStoreReduce']['VALUE']) {
+                    // 开启了紧缩方式,计算店服务
+                    $this->calcStoreBonusReduce();
+                } else {
+                    // 未开启紧缩方式,计算店服务
+                    $this->calcStoreBonus();
+                }
             }
             $t16 = microtime(true);
-            echo('计算荣衔奖'.($this->_sysConfig['openYC']['VALUE']?'完成':'关闭').',耗时:' . round($t16 - $t13, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+            echo('计算店服务奖金'.($this->_sysConfig['openStore']['VALUE']?'完成':'关闭').',耗时:' . round($t16 - $t13, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
             $this->_updatePercent(55);
 
             if($this->_sysConfig['openVIP']['VALUE']) {
@@ -421,6 +434,7 @@ class BonusCalc extends BaseObject {
         CalcBonusGL::pageDeleteAll('PERIOD_NUM='.$this->_periodNum);
         // 月结时要清空的数据
         if ($this->_isCalcMonth) {
+            CalcBonusST::pageDeleteAll('PERIOD_NUM='.$this->_periodNum);
             CalcBonusYC::pageDeleteAll('PERIOD_NUM='.$this->_periodNum);
             CalcBonusVIP::pageDeleteAll('PERIOD_NUM='.$this->_periodNum);
             CalcBonusStandard::pageDeleteAll('PERIOD_NUM='.$this->_periodNum);
@@ -921,6 +935,164 @@ class BonusCalc extends BaseObject {
         return true;
     }
 
+    // 紧缩计算店服务奖,不活跃,则给一个活跃的店铺
+    public function calcStoreBonusReduce(int $offset = 0) {
+        if( !$this->_isCalcMonth ) {
+            // 不是结算月,则不进行计算
+            echo sprintf("时间:[%s]店服务奖金非月节点,不进行计算,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
+            return false;
+        }
+        echo sprintf("时间:[%s]店服务奖金计算--紧缩方式,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
+        $allData = CalcCache::getHasPerfUsers($this->_periodNum, $offset, $this->_limit);
+        if ($allData) {
+            $insertBonusData = [];
+            foreach ($allData as $userId) {
+                $storeBonus = $this->verifyStorePerf($userId);
+                if (empty($storeBonus)) continue;
+                // 判断此店铺是否是活跃用户,如果不活跃,则往上找一个活跃的店铺获得此奖
+                $isActive = $this->_isMonthPerfLimit($userId);
+                $bonusUserId = '';
+                // 如果用户不活跃,且上面没有活跃的,则不累计了,是不是
+                if (!$isActive) {
+                    // 如果此店铺不活跃,则找最近的一个店铺获得此奖
+                    $this->loopRelationParentDo($userId, function ($parent) use (&$bonusUserId) {
+                        if ($this->_isMonthPerfLimit($parent['PARENT_UID'])) {
+                            // 判断是否是店铺
+                            $parentUser = CalcCache::getUserInfo($parent['PARENT_UID'], $this->_periodNum);
+                            if ($parentUser['IS_STUDIO'] == 1) {
+                                $bonusUserId = $parent['PARENT_UID'];
+
+                                return self::LOOP_FINISH;
+                            }
+                            
+                        }
+                        unset($parent);
+                    });
+                }
+                if (!$isActive && !$bonusUserId) {
+                    continue;
+                }
+               
+                $realBonusUserId = $bonusUserId ? $bonusUserId : $userId; 
+                //扣除相应的复消积分和管理费
+                $deductData = $this->deduct($realBonusUserId, $storeBonus);
+                // 把对碰后的奖金存入缓存中
+                CalcCache::bonus($realBonusUserId, $this->_periodNum, 'BONUS_STORE', $storeBonus, $deductData);
+                $surplus = $deductData['surplus'];
+                $manageTax = $deductData['manageTax'];
+                $reConsumePoints = $deductData['reConsumePoints'];
+                
+                //店服务奖流水
+                $insertBonusData[] = [
+                    'ID' => SnowFake::instance()->generateId(),
+                    'USER_ID' => $realBonusUserId,
+                    'FROM_USER_ID' => $bonusUserId ? $userId : '', // 分享店铺的ID.只有紧缩且未活跃,才有此值
+                    'AMOUNT' => $surplus,
+                    'ORI_BONUS' => $storeBonus,
+                    'RECONSUME_POINTS' => $reConsumePoints,
+                    'MANAGE_TAX' => $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()
+                ];
+
+                unset($bonusUserId, $userId, $deductData);
+            }
+            CalcBonusST::batchInsert($insertBonusData);
+            unset($allData, $insertBonusData);
+            return $this->calcStoreBonusReduce($offset + $this->_limit);
+        }
+    
+        unset($allData);
+    
+        return true;
+    }
+
+    // 未开启紧缩方式计算店服务奖,不活跃即不给奖金 
+    public function calcStoreBonus(int $offset = 0) {
+        if( !$this->_isCalcMonth ) {
+            // 不是结算月,则不进行计算
+            echo sprintf("时间:[%s]店服务奖金非月节点,不进行计算,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
+            return false;
+        }
+        echo sprintf("时间:[%s]店服务奖金计算--非紧缩方式,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
+        $allData = CalcCache::getHasPerfUsers($this->_periodNum, $offset, $this->_limit);
+        if ($allData) {
+            $insertBonusData = [];
+            foreach ($allData as $userId) {
+                $storeBonus = $this->verifyStorePerf($userId);
+                if (empty($storeBonus)) continue;
+                // 未开启紧缩,不活跃,则不发放了
+                $isActive = $this->_isMonthPerfLimit($userId);
+                if (!$isActive) continue;
+                $surplus = $storeBonus;
+                //扣除相应的复消积分和管理费
+                $deductData = $this->deduct($userId, $storeBonus);
+                CalcCache::bonus($userId, $this->_periodNum, 'BONUS_STORE', $storeBonus, $deductData);
+                $surplus = $deductData['surplus'];
+                $manageTax = $deductData['manageTax'];
+                $reConsumePoints = $deductData['reConsumePoints'];
+
+                //店服务奖流水
+                $insertBonusData[] = [
+                    'ID' => SnowFake::instance()->generateId(),
+                    'USER_ID' => $userId,
+                    'AMOUNT' => $surplus,
+                    'ORI_BONUS' => $storeBonus,
+                    'RECONSUME_POINTS' => $reConsumePoints,
+                    'MANAGE_TAX' => $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()
+                ];
+
+                unset($userId, $deductData);
+            }
+            CalcBonusST::batchInsert($insertBonusData);
+            unset($allData, $insertBonusData);
+            return $this->calcStoreBonus($offset + $this->_limit);
+        }
+    
+        unset($allData);
+    
+        return true;
+    }
+
+    /**
+     * 通过用户id,校验店服务奖,此用户是否有原奖金
+     */
+    public function verifyStorePerf($userId) {
+        // 从缓存中获取会员的业绩信息
+        $perfData = CalcCache::nowPeriodPerf($userId, $this->_periodNum);
+        if( !$perfData ) {
+            return false;
+        }
+        // 获取小组+自己的业绩
+        $perfPv = $perfData['STORE_PV_GRAND'] ?? 0;
+        if( $perfPv <= 0 ) {
+            return false;
+        }
+        // 业绩乘以比例为奖金
+        $storeBonus = Tool::formatPrice($perfPv * $this->_sysConfig['storePercent']['VALUE'] / 100);
+        if ($storeBonus <= 0) {
+            return false;
+        }
+        // 获取会员的报单级别
+        $userBaseInfo = CalcCache::getUserInfo($userId, $this->_periodNum);
+        $storeBonus = $this->bonusTotalLimit($storeBonus, $userId, $userBaseInfo['REC_NUM'], $userBaseInfo['ZC_AMOUNT']);
+        if( $storeBonus <= 0 ) {
+            return false;
+        }
+
+        unset($perfData, $perfPv, $userBaseInfo, $userId);
+
+        return $storeBonus;
+    }
+
     /**
      * 报单业绩奖
      * @param int $offset
@@ -3436,7 +3608,7 @@ class BonusCalc extends BaseObject {
                 $bonus['MANAGE_TAX'] = $bonus['MANAGE_TAX'] + $monthGxManageTax;
                 $realBonusGl += $bonusGlSum + $bonus['BONUS_GL'];
                 $realBonusBs = $blueStartAmount;
-                $bonusReal += $realBonusGx + $realBonusBs + $realBonusGl;
+                $bonusReal += $realBonusGx + $realBonusBs + $realBonusGl + $bonus['BONUS_STORE']; // 再加上店服务奖的实发
                 $exchangePoints = isset($userBS['PRODUCT_POINT']) && !empty($userBS['PRODUCT_POINT']) ? $userBS['PRODUCT_POINT'] : 0; // 兑换积分
                 unset($monthSumData, $bonusGxSum, $bonusGlSum);
                 $oriBonusBs = isset($bonus['ORI_BONUS_BS']) && $bonus['ORI_BONUS_BS'] > 0 ? $bonus['ORI_BONUS_BS'] : 0;
@@ -3515,6 +3687,8 @@ class BonusCalc extends BaseObject {
             'ORI_BONUS_YC' => $bonus['ORI_BONUS_YC'] + $bonus['ORI_BONUS_YC_EXTRA'],
             'ORI_BONUS_VIP' => $bonus['ORI_BONUS_VIP'],
             'ORI_BONUS_STANDARD' => $standardBonus,
+            'BONUS_ST' => $bonus['BONUS_STORE'], // 店服务奖实发
+            'ORI_BONUS_ST' => $bonus['ORI_BONUS_STORE'], // 店服务奖原奖金
 
 
 

+ 2 - 0
common/helpers/bonus/BonusSend.php

@@ -320,6 +320,7 @@ class BonusSend extends BaseObject {
                             'GX' => $data['REAL_BONUS_GX'],
                             'GL' => $data['BONUS_GL'],
                             'BS' => $data['BONUS_BS'],
+                            'ST' => $data['BONUS_ST'],
 
                             'ORI_QY' => $data['ORI_BONUS_QY'],
                             'ORI_YC' => $data['ORI_BONUS_YC'],
@@ -331,6 +332,7 @@ class BonusSend extends BaseObject {
                             'ORI_GX' => $data['ORI_BONUS_GX'],
                             'ORI_GL' => $data['ORI_BONUS_GL'],
                             'ORI_BS' => $data['ORI_BONUS_BS'],
+                            'ORI_ST' => $data['ORI_BONUS_ST'],
 
                             //'RECONSUME_POINTS_TOTAL' => $data['RECONSUME_POINTS'], 2022/05/17 复消积分,直接发放到余额账户
                             'RECONSUME_POINTS_TOTAL' => $data['RECONSUME_POINTS'],

+ 38 - 3
common/helpers/bonus/CalcCache.php

@@ -34,6 +34,7 @@ class CalcCache {
     const REDIS_KEY_PREFIX_USER = 'calc:user_';
     const REDIS_KEY_PREFIX_USER_ACTIVE = 'calc:userActive_';
     const REDIS_KEY_PREFIX_USER_INFO = 'calc:userInfo_';
+    const REDIS_KEY_PREFIX_USER_RELATION_INFO = 'calc:userRelationInfo_';
     const REDIS_KEY_PREFIX_USER_BONUS = 'calc:userBonus_';
     const REDIS_KEY_PREFIX_PERIOD_MONTH_CALC_BONUS = 'calc:periodMonthCalcBonus_';
     const REDIS_KEY_PREFIX_USER_PERF = 'calc:userPerf_';
@@ -743,6 +744,26 @@ class CalcCache {
         return $list;
     }
 
+    /**
+     * 根据用户id,获取会员小组上级
+     */
+    public static function getUserRelationInfo($userId, $periodNum) {
+        $key = self::REDIS_KEY_PREFIX_USER_RELATION_INFO . $periodNum;
+        $data = Yii::$app->redis->hget($key, $userId);
+        if (!$data) {
+            $relation = UserRelation::findUseDbCalc()
+            ->select('USER_ID,PARENT_UID')
+            ->where('USER_ID=:USER_ID', [':USER_ID' => $userId])
+            ->asArray()
+            ->one();
+            $data = Json::encode($relation);
+            Yii::$app->redis->hset($key, $userId, $data);
+            unset($relation, $key, $userId, $periodNum);
+        }
+
+        return $data ? Json::decode($data, true) : [];
+    }
+
     /**
      * 获取会员信息从缓存
      * @param $userId
@@ -754,16 +775,27 @@ class CalcCache {
         $key = self::REDIS_KEY_PREFIX_USER_INFO . $periodNum;
         $data = Yii::$app->redis->hget($key, $userId);
         if (!$data) {
-            $userInfo = UserInfo::findUseDbCalc()->select('USER_ID,USER_NAME,ZC_AMOUNT,ZC_PV,CON_UID,REC_UID,CON_NUM,REC_NUM,NETWORK_DEEP,RELATION_DEEP,STORE_TYPE,UPDATED_AT,SYSTEM_ID')->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
+            $userInfo = UserInfo::findUseDbCalc()
+            ->select('USER_ID,USER_NAME,ZC_AMOUNT,ZC_PV,CON_UID,REC_UID,CON_NUM,REC_NUM,NETWORK_DEEP,RELATION_DEEP,STORE_TYPE,
+            UPDATED_AT,SYSTEM_ID')
+            ->where('USER_ID=:USER_ID', [':USER_ID' => $userId])
+            ->asArray()
+            ->one();
             if( !$userInfo ) {
                 throw new \Exception('用户信息表数据不存在,userId:'.$userId);
             }
             // 在获取商城库的会员的级别信息和是否报单中心的会员
-            $userShopInfo = User::find()->select('REAL_NAME,LAST_DEC_LV,DEC_LV,EMP_LV,IS_DEC,DEC_ID,DEC_ROLE_ID,STATUS,PERIOD_AT,MOBILE,CREATED_AT,SUB_COM_ID,PROVINCE,CITY,COUNTY,DEC_PROVINCE,DEC_CITY,DEC_COUNTY,IS_DIRECT_SELLER,SUB_COM_LEADER')->where('ID=:ID', [':ID' => $userId])->asArray()->one();
+            $userShopInfo = User::find()
+            ->select('IS_STUDIO,REAL_NAME,LAST_DEC_LV,DEC_LV,EMP_LV,IS_DEC,DEC_ID,DEC_ROLE_ID,STATUS,PERIOD_AT,MOBILE,CREATED_AT,SUB_COM_ID,
+            PROVINCE,CITY,COUNTY,DEC_PROVINCE,DEC_CITY,DEC_COUNTY,IS_DIRECT_SELLER,SUB_COM_LEADER')
+            ->where('ID=:ID', [':ID' => $userId])
+            ->asArray()
+            ->one();
             if ( !$userShopInfo ) {
                 throw new \Exception('用户表数据不存在,userId:'.$userId);
             }
             $userInfo['REAL_NAME'] = $userShopInfo['REAL_NAME'];
+            $userInfo['IS_STUDIO'] = $userShopInfo['IS_STUDIO'];
 //            $userInfo['DEC_LV'] = $userShopInfo['DEC_LV'];
             //先用last_dec_lv
             $userInfo['DEC_LV'] = $userShopInfo['LAST_DEC_LV'];
@@ -1066,6 +1098,7 @@ class CalcCache {
             $value = Json::decode($cacheValue);
         } else {
             $value = [
+                'STORE_PV_GRAND' => 0, // 用户的店铺业绩
                 'FX_AMOUNT_CASH' => 0,
                 'PV_PCS' => 0,
                 'PV_PSS' => 0,//本期的团队业绩
@@ -1206,7 +1239,7 @@ class CalcCache {
                 'EMP_LEVEL' => EmployLevel::getDefaultLevelId(),
                 'CF_PERCENT' => 0,
                 'LX_PERCENT' => 0,
-                'FX_STATUS' => PerfMonth::NEXT_MONTH_FX_FALSE,
+                'FX_STATUS' => PerfMonth::NEXT_MONTH_FX_FALSE
             ];
         }
         if ($perf !== null) {
@@ -1434,6 +1467,7 @@ class CalcCache {
             'BONUS_YC' => 0,
             'BONUS_VIP' => 0,
             'BONUS_BS' => 0,
+            'BONUS_STORE' => 0, // 店服务奖实发
 
             'BONUS_BU_GL'=>0,  //蓝星管理奖实发
             'BONUS_BU_YJ'=>0,  // 蓝星业绩奖实发
@@ -1444,6 +1478,7 @@ class CalcCache {
 
 
             'BONUS_YC_EXTRA' => 0,
+            'ORI_BONUS_STORE' => 0, // 店服务奖原奖金
             'ORI_BONUS_BD' => 0,
             'ORI_BONUS_BS' => 0,
             'ORI_BONUS_TG' => 0,

+ 105 - 5
common/helpers/bonus/PerfCalc.php

@@ -32,6 +32,7 @@ use common\models\Period;
 use common\models\DecOrder;
 use common\models\EmployLevel;
 use common\models\PerfActiveUser;
+use common\models\StorePerfLog;
 use common\models\UserRelation;
 use yii\base\Exception;
 use yii\base\StaticInstanceTrait;
@@ -174,12 +175,18 @@ class PerfCalc {
             echo('本月业绩入库完成,耗时:' . round($t7 - $t6, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
             $this->_updatePercent(90);
 
-            // //达标业绩
-            $this->loopCalcPerfByStandardFXOrder();
-            // //达标业绩入库
-            $this->loopWriteStandardPerf();
+            // 店服务奖/月节点
+            $this->storePerf();
+            $t8 = microtime(true);
+            echo('店服务业绩计算,耗时:' . round($t8 - $t7, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+            $this->_updatePercent(95);
+            
+            // // //达标业绩
+            // $this->loopCalcPerfByStandardFXOrder();
+            // // //达标业绩入库
+            // $this->loopWriteStandardPerf();
             $t9 = microtime(true);
-            echo('本月业绩入库完成,耗时:' . round($t9 - $t7, 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);
             $this->_updatePercent(95);
 
             
@@ -294,6 +301,8 @@ class PerfCalc {
         if ($this->_isCalcMonth) {
             // 月业绩表
             PerfMonth::pageDeleteAll("CALC_MONTH='{$this->_calcYearMonth}'");
+            // 店服务业绩log表
+            StorePerfLog::pageDeleteAll("CALC_MONTH='{$this->_calcYearMonth}'");
             //达标业绩表
             PerfStandard::pageDeleteAll("CALC_MONTH='{$this->_calcYearMonth}'");
         }
@@ -1165,6 +1174,97 @@ class PerfCalc {
         return true;
     }
 
+    /**
+     * 店服务奖,循环结算月所有数据,并计算小组业绩
+     * @param int $offset
+     * @return bool
+     * @throws \yii\db\Exception
+     */
+    public function storePerf($offset = 0) {
+        if(!$this->_isCalcMonth){
+            return true;
+        }
+        echo sprintf("时间:[%s]店服务奖业绩计算,当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);
+
+        $allData = PerfOrder::findUseDbCalc()
+        ->select('ID,USER_ID, SUM(PV) AS MONTH_PV, CALC_MONTH')
+        ->where('CALC_MONTH=:CALC_MONTH', [':CALC_MONTH' => $this->_calcYearMonth])
+        ->groupBy('USER_ID')
+        ->orderBy('USER_ID DESC')
+        ->offset($offset)
+        ->limit($this->_limit)
+        ->asArray()
+        ->all();
+
+        if ($allData) {
+            foreach ($allData as $everyData) {
+                $userId = $everyData['USER_ID'];
+                $pv = $everyData['MONTH_PV'];
+                $userBaseInfo = CalcCache::getUserInfo($userId, $this->_periodNum);
+                $userRelation = CalcCache::getUserRelationInfo($userId, $this->_periodNum);
+                // 记录有业绩单的用户
+                StorePerfLog::addOrUpdate(
+                    $this->_periodNum, 
+                    $this->_calcYearMonth, 
+                    $userId, 
+                    [
+                        'USER_ID' => $userId,
+                        'IS_STUDIO' => $userBaseInfo['IS_STUDIO'],
+                        'MONTH_PV' => $pv,
+                        'PERIOD_NUM' => $this->_periodNum,
+                        'CALC_MONTH' => $this->_calcYearMonth,
+                        'CREATE_AT' => time(),
+                        'PARENT_UID' => $userRelation['PARENT_UID']
+                    ],
+                    $pv
+                );
+                // 判断此用户是否是店铺,如果是店铺则累计此业绩到自己身上
+                if ($userBaseInfo['IS_STUDIO'] == 1) {
+                    CalcCache::addHasPerfUsers($userId, $this->_periodNum);
+                    CalcCache::nowPeriodPerf($userId, $this->_periodNum, [
+                        'STORE_PV_GRAND' => $pv,
+                    ]);
+                } else {
+                    // 如果此用户不是店铺,继续上找到店铺并累加上去PV
+                    $this->loopRelationParentDo($userId, function ($parent) use (&$everyData) {
+                        $parentUser = CalcCache::getUserInfo($parent['PARENT_UID'], $this->_periodNum);
+                        $userRelation = CalcCache::getUserRelationInfo($parent['PARENT_UID'], $this->_periodNum);
+                        StorePerfLog::addOrUpdate(
+                            $this->_periodNum, 
+                            $this->_calcYearMonth, 
+                            $parent['PARENT_UID'], 
+                            [
+                                'USER_ID' => $parent['PARENT_UID'],
+                                'IS_STUDIO' => $parentUser['IS_STUDIO'],
+                                'MONTH_PV' => 0,
+                                'PERIOD_NUM' => $this->_periodNum,
+                                'CALC_MONTH' => $this->_calcYearMonth,
+                                'CREATE_AT' => time(),
+                                'PARENT_UID' => $userRelation['PARENT_UID']
+                            ],
+                            $everyData['MONTH_PV']
+                        );
+                        if ($parentUser['IS_STUDIO']) {
+                            CalcCache::nowPeriodPerf($parent['PARENT_UID'], $this->_periodNum, [
+                                'STORE_PV_GRAND' => $everyData['MONTH_PV']
+                            ]);
+                            CalcCache::addHasPerfUsers($parent['PARENT_UID'], $this->_periodNum);
+                            
+                            return self::LOOP_FINISH;
+                        }
+                        
+                        unset($parent);
+                    });
+                }
+            }
+            unset($allData);
+            return $this->storePerf($offset + $this->_limit);
+        }
+
+        unset($allData);
+        return true;
+    }
+
 
     /**
      * 循环达标业绩会员,并入库

+ 6 - 0
common/helpers/user/Balance.php

@@ -276,6 +276,9 @@ class Balance {
                     $paramData['BS_TOTAL'] = new Expression('BS_TOTAL + '.$params['BS']);
                     //$oneUserBonusModel->GL_TOTAL += $params['GL'];
                 }
+                if (isset($params['ST'])) {
+                    $paramData['STORE_TOTAL'] = new Expression('STORE_TOTAL + '.$params['ST']);
+                }
                 if (isset($params['RECONSUME_POINTS_TOTAL'])) {
                     $paramData['RECONSUME_POINTS_TOTAL'] = new Expression('RECONSUME_POINTS_TOTAL + '.$params['RECONSUME_POINTS_TOTAL']);
                     //$oneUserBonusModel->RECONSUME_POINTS_TOTAL += $params['RECONSUME_POINTS_TOTAL'];
@@ -329,6 +332,9 @@ class Balance {
                     $paramData['ORI_BS_TOTAL'] = new Expression('ORI_BS_TOTAL + '.$params['ORI_BS']);
                     //$oneUserBonusModel->ORI_GL_TOTAL += $params['ORI_GL'];
                 }
+                if (isset($params['ORI_ST'])) {
+                    $paramData['ORI_STORE_TOTAL'] = new Expression('ORI_STORE_TOTAL + '.$params['ORI_ST']);
+                }
 
                 if (isset($params['BONUS_TOTAL'])) {
                     $paramData['BONUS_TOTAL'] = new Expression('BONUS_TOTAL + '.$params['BONUS_TOTAL']);

+ 63 - 0
common/models/CalcBonusST.php

@@ -0,0 +1,63 @@
+<?php
+
+namespace common\models;
+
+use Yii;
+
+/**
+ * This is the model class for table "{{%CALC_BONUS_ST}}".
+ *
+ * @property string $ID
+ * @property string $USER_ID 会员ID
+ * @property string $FROM_USER_ID 来源会员ID
+ * @property string $AMOUNT 金额
+ * @property int $PERIOD_NUM 结算期数
+ * @property int $CALC_MONTH 所在结算月
+ * @property int $CREATED_AT 创建时间
+ * @property $ORI_BONUS 原奖金
+ * @property $RECONSUME_POINTS 重复消费积分
+ * @property $MANAGE_TAX 管理费
+ */
+class CalcBonusST extends \common\components\ActiveRecord
+{
+    /**
+     * @inheritdoc
+     */
+    public static function tableName()
+    {
+        return '{{%CALC_BONUS_ST}}';
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['USER_ID', 'PERIOD_NUM', 'CALC_MONTH', 'CREATED_AT'], 'required'],
+            [['AMOUNT', 'ORI_BONUS', 'RECONSUME_POINTS', 'MANAGE_TAX'], 'number'],
+            [['PERIOD_NUM', 'CALC_MONTH', 'CREATED_AT'], 'integer'],
+            [['ID', 'USER_ID', 'FROM_USER_ID'], 'string', 'max' => 32],
+            [['ID'], 'unique'],
+        ];
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function attributeLabels()
+    {
+        return [
+            'ID' => 'ID',
+            'USER_ID' => '会员ID',
+            'FROM_USER_ID' => '来源会员ID',
+            'AMOUNT' => '金额',
+            'PERIOD_NUM' => '结算期数',
+            'CALC_MONTH' => '所在结算月',
+            'CREATED_AT' => '创建时间',
+            'ORI_BONUS' => '原奖金',
+            'RECONSUME_POINTS' => '重复消费积分',
+            'MANAGE_TAX' => '管理费',
+        ];
+    }
+}

+ 82 - 0
common/models/StorePerfLog.php

@@ -0,0 +1,82 @@
+<?php
+
+namespace common\models;
+
+/**
+ * This is the model class for table "{{%STORE_PERF_LOG}}".
+ *
+ * @property string $ID
+ * @property string $PERF_ORDER_ID PERF_ORDER表的ID字段值
+ * @property string $USER_ID USER表用户ID
+ * @property int $IS_STUDIO 是否是工作室 0 不是 1是
+ * @property string $PV 业绩单PV
+ * @property string $PERIOD_NUM 业绩期
+ * @property int $CALC_MONTH 结算月份
+ * @property int $CREATE_AT 创建时间
+ */
+class StorePerfLog extends \common\components\ActiveRecord
+{
+    /**
+     * @inheritdoc
+     */
+    public static function tableName()
+    {
+        return '{{%STORE_PERF_LOG}}';
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['USER_ID', 'IS_STUDIO', 'CREATED_AT'], 'required'],
+            [['ID'], 'unique'],
+        ];
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function attributeLabels()
+    {
+        return [
+            'ID' => 'ID',
+            'PERF_ORDER_ID' => 'PERF_ORDER表的ID字段值',
+            'USER_ID' => 'USER表用户ID',
+            'IS_STUDIO' => '是否是工作室 0 不是 1是',
+            'PV' => '业绩单PV',
+            'PERIOD_NUM' => '业绩期',
+            'CALC_MONTH' => '结算月份',
+            'CREATE_AT' => '创建时间',
+        ];
+    }
+
+    // 更新或者添加业绩数据
+    /**
+     * @param $periodNum 结算业绩期
+     * @param $calcMonth 结算月
+     * @param $userId 结算过程中的用户
+     * @param $data 数据
+     * @param $appendPv 往上找店铺,需要给店铺的PV值
+     */
+    public static function addOrUpdate($periodNum, $calcMonth, $userId, $data, $appendPv = 0) {
+        $info = StorePerfLog::findUseDbCalc()
+        ->select('ID')
+        ->where('USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM AND CALC_MONTH=:CALC_MONTH',
+         [':USER_ID'=>$userId,':PERIOD_NUM' => $periodNum, ':CALC_MONTH' => $calcMonth]
+        )
+        ->asArray()
+        ->one();
+        if (empty($info)) {
+            StorePerfLog::insertOne($data);
+        } else {
+            // 如果循环到此用户有业绩单,则将此用户的PV更新为自己业绩单的值
+            if ($data['MONTH_PV'] > 0) {
+                StorePerfLog::updateAll(['MONTH_PV' => $data['MONTH_PV']], 'ID=:ID', [':ID' => $info['ID']]);
+            }
+        }
+
+        return true;
+    }
+}

+ 4 - 0
common/models/UserBonus.php

@@ -15,6 +15,8 @@ use common\libs\logging\operate\valueType\Config as ValueTypeConfig;
  * @property string $BONUS_FREEZE 奖金冻结部分
  * @property string $CF 车房养老奖
  * @property string $LX 领袖分红奖
+ * @property string $STORE_TOTAL 店服务奖累计
+ * @property string $ORI_STORE_TOTAL 店服务奖原奖金累计
  * @property string $QY_TOTAL 区域津贴累计
  * @property string $YC_TOTAL 育成津贴累计
  * @property string $VIP_TOTAL VIP奖金累计
@@ -87,6 +89,7 @@ class UserBonus extends \common\components\ActiveRecord
             'BONUS_FREEZE' => '奖金冻结部分',
             'CF' => '车房养老奖',
             'LX' => '领袖分红奖',
+            'STORE_TOTAL' => '店服务奖累计',
             'QY_TOTAL' => '区域津贴累计',
             'YC_TOTAL' => '育成津贴累计',
             'VIP_TOTAL' => 'VIP奖金累计',
@@ -107,6 +110,7 @@ class UserBonus extends \common\components\ActiveRecord
             'YJ_TOTAL'=> '业绩奖累计',
             'GX_TOTAL'=> '共享奖累计',
             'GL_TOTAL'=> '管理奖累计',
+            'ORI_STORE_TOTAL' => '店服务奖原奖金累计',
             'ORI_QY_TOTAL' => '团队奖原奖金累计',
             'ORI_YC_TOTAL' => '荣衔奖原奖金累计',
             'ORI_VIP_TOTAL' => 'VIP奖原奖金累计',

+ 13 - 1
frontendApi/modules/v1/controllers/BonusController.php

@@ -382,6 +382,10 @@ class BonusController extends BaseController {
                 $data[] = ['name' => '周共享奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_GX'])];
                 $data[] = ['name' => '月共享奖金', 'value' => Tool::formatPrice($calcBonus['ORI_MONTH_GX_BONUS'])];
             }
+            if ($sysConfig['openStore']['VALUE']) {
+                // 店服务奖
+                $data[] = ['name' => '店服务奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_ST'])];
+            }
             if ($sysConfig['openFW']['VALUE']) {
                 if (\Yii::$app->user->id == '670B84FD7C216D4EE055736AECE8644D') {
                     $data[] = ['name' => '服务奖金', 'value' => '0.00'];
@@ -463,7 +467,7 @@ class BonusController extends BaseController {
         //获取可以查看几期奖金
         $showBonusPeriodNum = Cache::getSystemConfig()['showBonusPeriodNum']['VALUE'];
         $calcBonus = CalcBonus::find()->where('USER_ID=:USER_ID AND IS_SENT=1', [':USER_ID' => \Yii::$app->user->id])
-        ->select('USER_ID,PERIOD_NUM,ORI_BONUS_QY,ORI_BONUS_YC,ORI_BONUS_VIP,ORI_BONUS_STANDARD,ORI_BONUS_BD,ORI_BONUS_TG,
+        ->select('ORI_BONUS_ST,USER_ID,PERIOD_NUM,ORI_BONUS_QY,ORI_BONUS_YC,ORI_BONUS_VIP,ORI_BONUS_STANDARD,ORI_BONUS_BD,ORI_BONUS_TG,
         ORI_BONUS_XF,BONUS_TOTAL,MANAGE_TAX,BONUS_REAL,BONUS_INCOME,ORI_BONUS_YJ,ORI_BONUS_GX,ORI_MONTH_GX_BONUS,ORI_BONUS_GL,RECONSUME_POINTS,
         LAST_DEC_LV,LAST_EMP_LV,EXCHANGE_POINTS,ORI_BONUS_BS,ORI_BONUS_BU_GL,ORI_BONUS_BU_YJ')
         ->limit($showBonusPeriodNum)
@@ -503,6 +507,10 @@ class BonusController extends BaseController {
                     $calcBonus[$key]['BONUS_GX'] = ['name' => '周共享奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_GX'])];
                     $calcBonus[$key]['ORI_MONTH_GX_BONUS'] = ['name' => '月共享奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_MONTH_GX_BONUS'])];
                 }
+                //店服务奖
+                if ($sysConfig['openStore']['VALUE']) {
+                    $calcBonus[$key]['BONUS_ST'] = ['name' => '店服务奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_ST'])];
+                }
                 //服务奖
                 if ($sysConfig['openFW']['VALUE']) {
                     $calcBonus[$key]['BONUS_BD'] = ['name' => '服务奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_BD'])];
@@ -570,10 +578,14 @@ class BonusController extends BaseController {
             // if ($sysConfig['openVIP']['VALUE']) {
             //     $tableKey[] = 'BONUS_VIP';
             // }
+            if ($sysConfig['openStore']['VALUE']) {
+                $tableKey[] = 'BONUS_ST';
+            }
             if ($sysConfig['openFW']['VALUE']) {
                 $tableKey[] = 'BONUS_BD';
             }
             
+            
             // if ($sysConfig['openXF']['VALUE']) {
             //     $tableKey[] = 'BONUS_XF';
             // }