<?php
/**
 * 测试专用控制器
 * Created by PhpStorm.
 * User: leo
 * Date: 2018/3/9
 * Time: 上午11:56
 */
namespace console\controllers;

use common\helpers\bonus\BonusCalc;
use common\helpers\bonus\BonusSend;
use common\helpers\bonus\CalcCache;
use common\helpers\bonus\PerfCalc;
use common\helpers\Cache;
use common\helpers\DataBak;
use common\helpers\Date;
use common\helpers\Form;
use common\helpers\ocr\OcrApi;
use common\helpers\snowflake\SnowFake;
use common\helpers\Tool;
use common\helpers\user\Balance;
use common\helpers\user\Info;
use common\helpers\user\Reconsume;
use common\libs\api\sms\SmsApi;
use common\libs\swoole\RPCApi;
use common\libs\taskQueue\Queue;
use common\libs\taskQueue\TaskFunc;
use common\models\CalcBonus;
use common\models\CalcBonusBD;
use common\models\CalcBonusFX;
use common\models\CalcBonusGL;
use common\models\CalcBonusGX;
use common\models\CalcBonusQY;
use common\models\CalcBonusTG;
use common\models\CalcBonusYC;
use common\models\CalcBonusYJ;
use common\models\CalcMonthBonusUser;
use common\models\DealType;
use common\models\EmployLevel;
use common\models\FlowBonus;
use common\models\FlowReconsumePoints;
use common\models\forms\ClearDataForm;
use common\models\forms\DeclarationForm;
use common\models\forms\DeclarationLoopForm;
use common\models\forms\HistoryBonusForm;
use common\models\forms\UserForm;
use common\models\Order;
use common\models\OrderShop;
use common\models\PerfMonth;
use common\models\PerfOrder;
use common\models\PerfPeriod;
use common\models\Period;
use common\models\ReconsumePool;
use common\models\ReconsumePoolFlow;
use common\models\DecOrder;
use common\models\ScoreMonth;
use common\models\TaskQueue;
use common\models\TmpOldNetwork;
use common\models\User;
use common\models\UserBind;
use common\models\UserBonus;
use common\models\UserInfo;
use common\models\UserMove;
use common\models\UserNetwork;
use common\models\UserPerf;
use common\models\UserRelation;
use yii\base\Exception;
use yii\db\Expression;
use yii\db\Query;
use yii\helpers\Json;

class TestController extends BaseController
{
    public function actionPut(){
        file_put_contents(\Yii::getAlias('@common/runtime/logs/asyncLog.log'), var_export(['asdasd'=>'中午'], true));
    }

    /**
     * 测试异步任务
     * ./yii test/async-task calcBonus
     * @param null $routeAndParamsMethod 想要测试的方法名
     * @throws \yii\base\Exception
     * @throws \yii\base\InvalidConfigException
     */
    public function actionAsyncTask($routeAndParamsMethod = null){
        if($routeAndParamsMethod !== null){
            $routeAndParams = call_user_func(self::class.'::_'.$routeAndParamsMethod);
            $route = $routeAndParams['route'];
            $params = $routeAndParams['params'];
        } else {

            $moveInfo = UserMove::find()->select('UM.ID,UM.LOCATION,UM.TYPE,MU.USER_NAME AS moveUserName,TU.USER_NAME AS toConUserName,TU.REAL_NAME AS toConRealName')
                ->from(UserMove::tableName().' AS UM')
                ->leftJoin(User::tableName().' AS MU', 'UM.USER_ID=MU.ID')
                ->leftJoin(User::tableName() . ' AS TU', 'UM.TO_UID=TU.ID')
                ->where('AUDIT_STATUS=0')->asArray()->all();
            foreach($moveInfo as $k=>$moves){
                // route换成要测试的路由路径
                if($moves['TYPE']=='relation'){
                    $route = 'user/move-relation';
                }else{
                    $route = 'user/move-network';
                }
                // params的数组内容替换为要传的值
                $params = [
                    'moveId' => $moves['ID'],
                    'moveUserName' => $moves['moveUserName'],
                    'toConUserName' => $moves['toConUserName'],
                    'toConRealName' => $moves['toConRealName'],
                    'location' => $moves['LOCATION'],
                    'type' => $moves['TYPE'],
                ];
                echo sprintf("任务【%s】开始执行".PHP_EOL, $k);
                $params['handleUserId'] = null;
                $taskKey = Cache::setAsyncParams($params);
                $parts = \Yii::$app->createController($route);
                if(is_array($parts)){
                    $res = \Yii::$app->runAction($route,[$taskKey]);
                    var_dump($res);
                    unset($res);
                } else {
                    echo('失败'.PHP_EOL);
                }

                unset($k,$moves,$route,$params,$taskKey,$parts);
            }
        }

//        $params['handleUserId'] = null;
//        $taskKey = Cache::setAsyncParams($params);
//        $parts = \Yii::$app->createController($route);
//        if(is_array($parts)){
//            $res = \Yii::$app->runAction($route,[$taskKey]);
//            var_dump($res);
//        } else {
//            echo('失败'.PHP_EOL);
//        }
    }

    /**
     *  异步发奖
     * @param string $router
     * @param int $periodNum
     * @return void
     */
    public function actionBonusAsyncTask($router='bonus/perf', $periodNum=105) {
        // 异步处理添加任务
        $taskKey = Cache::setAsyncParams([
            'handleUserId' => null,
            'handleUserName' => null,
            'periodNum' => $periodNum,
        ]);
        $data = [
            'data' => [
                [
                    'a' => $router,
                    'p' => [$taskKey],
                ]
            ],
        ];
        if(\Yii::$app->swooleAsyncTimer->async(Json::encode($data))){
            echo 'ok' . PHP_EOL;
        } else {
            echo 'fail' . PHP_EOL;
        }


    }

    private static function _calcPerf(){
        return [
            'route' => 'bonus/perf',
            'params' => [
                'periodNum' => 105,
            ],
        ];
    }

    /**
     * 测试结算
     * @return array
     */
    private static function _calcBonus(){
        return [
            'route' => 'bonus/calc',
            'params' => [
                'periodNum' => 105,
            ],
        ];
    }

    /**
     * 测试结算
     * @return array
     */
    private static function _sendBonus(){
        return [
            'route' => 'bonus/send',
            'params' => [
                'periodNum' => 118,
            ],
        ];
    }

    /**
     * 测试移网
     * @return array
     */
    private static function _moveRouteAndParams(){
        return [
            'route' => 'user/move-network',
            'params' => [
                'moveId' => 'A090B24973524443BE8BA95A40EE2148',
                'moveUserName' => 'b30746926',
                'toConUserName' => 'tester004',
                'toConRealName' => 'hhhjhjj',
                'location' => 1,
                'type' => 'network',
            ],
        ];
    }

    /**
     * 添加体系
     * @return array
     */
    private static function _addSystem(){
        return [
            'route' => 'user/system-add',
            'params' => [
                'systemName' => '测试',
                'leaderUserName' => 'tester001',
                'remark' => '测试',
            ],
        ];
    }


    private $_addUserNum = 1;
    private $_md5UserId = 2;
    private $_userNameNum = 2;

    public function actionAddUserTable(){
        $notDelUserId = "'670B84FD7C216D4EE055736AECE8644D','B322C18F7E274A9D9FC5DADC3B385E8B','638A5A3B617F46C999C5E4D072EED369','3C313C66D1724D658BF10B08194022BB'";

        User::deleteAll("ID NOT IN (".$notDelUserId.")");
        DecOrder::deleteAll("TO_USER_ID NOT IN (".$notDelUserId.")");
        $offset = 100;
        $allCount = UserInfo::find()->where("USER_ID NOT IN (".$notDelUserId.")")->orderBy('NETWORK_DEEP ASC')->asArray()->count("USER_ID");
        $pageCount = ceil($allCount/$offset);
        for($page=1;$page<=$pageCount;$page++) {
            $allUser = UserInfo::find()->where("USER_ID NOT IN (".$notDelUserId.")")->offset(($page-1)*$offset)->limit($offset)->orderBy('NETWORK_DEEP ASC')->asArray()->all();
            $insertData = [];
            $userInsertData=[];
            $decSn = 190310000000;
            foreach($allUser as $key=>$user){
                $decSn += 1;
                $decPv = rand(1, 100) * 1000;
                $insertData[] = [
                    'DEC_SN' => 'D'.$decSn.'0000',
                    'ORDER_SN' => $decSn,
                    'USER_ID' => $user['USER_ID'],
                    'TYPE' => 'ZC',
                    'TO_USER_ID' => $user['USER_ID'],
                    'DEC_AMOUNT' => $decPv,
                    'DEC_PV' => $decPv,
                    'PAID_WALLET' => 'bill',
                    'PERIOD_NUM' => 102,
                    'IS_DEL' => 0,
                    'P_CALC_MONTH' => Date::ociToDate(202001, Date::OCI_TIME_FORMAT_SHORT_MONTH),
                    'CREATED_AT' => strtotime('2020-01-20'),
                    'DEC_ID' => $user['REC_UID'],
                ];

                $userInsertData[] = [
                    'ID' =>  $user['USER_ID'],
                    'USER_NAME' =>  $user['USER_NAME'],
                    'AVATAR' =>  'http://abc.anran.ming/cdn/avatar/1.png',
                    'PASSWORD_HASH' => password_hash('111111', PASSWORD_DEFAULT),
                    'PAY_PASSWORD' => password_hash('111111', PASSWORD_DEFAULT),
                    'NATION' => 1,
                    'REAL_NAME' => $user['USER_NAME'],
                    'ID_CARD' => '130322111111111113',
                    'ID_TYPE' => 0,
                    'MOBILE' => '13333333339',
                    'ADDRESS' => '广东省 / 广州市荔湾区三号五弄',
                    'IS_DEC' => 1,
                    'DEC_ID' => '670B84FD7C216D4EE055736AECE8644D',
                    'PERIOD_AT' => 102,
                    'CREATED_AT' => strtotime('2020-02-12'),
                    'LAST_DEC_LV' => '67ABCE0ECE705575E055736AECE8644D',
                    'DEC_LV' => '67ABCB8C1F7D5519E055736AECE8644D',
                    'EMP_LV' => '67BE1C6C21F81B32E055736AECE8644D'
                ];

            }

            User::batchInsert($userInsertData);
            DecOrder::batchInsert($insertData);
            echo('第'.$page.'页数据'.PHP_EOL);
        }

        echo('全部完成'.PHP_EOL);

    }


    /**
     * 模拟添加会员
     * @param $num
     * @param string $conUid
     * @param string $recUid
     * @param int $location
     * @return bool
     * @throws Exception
     * @throws \yii\db\Exception
     */
    public function actionAddUser($num, $conUid = 'B322C18F7E274A9D9FC5DADC3B385E8B', $recUid = 'B322C18F7E274A9D9FC5DADC3B385E8B', $location = 1){
        if($num <= $this->_addUserNum) {
            echo('模拟加入完成'.PHP_EOL);
            return true;
        }
        $this->_md5UserId += 1;
        $this->_userNameNum += 1;
        $form = new UserForm();
        $form->scenario = 'addWithUid';
        $form->userId = md5($this->_md5UserId);
        $form->userName = 'simulate'.($this->_userNameNum);
        $form->zcPv = 1000;
        $form->zcAmount = 1000;
        $form->conUid = $conUid;
        $form->recUid = $recUid;
        $form->location = $location;
        if($form->add()){
            echo('添加了'.$this->_addUserNum.'名会员'.PHP_EOL);
            $this->_addUserNum += 1;
            // 获取全网深度最浅还没满的会员ID 作为节点人ID
            $conUser = UserInfo::find()->select('USER_ID, CON_NUM')->where('CON_NUM < 3')->orderBy('NETWORK_DEEP ASC')->asArray()->one();
            if($conUser['CON_NUM'] == 0){
                $newLocation = 1;
            } elseif($conUser['CON_NUM'] == 1){
                $newLocation = 2;
            } elseif($conUser['CON_NUM'] == 2) {
                $newLocation = 3;
            } else {
                throw new Exception('添加失败,原因：加入会员的点位区位错误');
            }
            return $this->actionAddUser($num, $conUser['USER_ID'], $conUser['USER_ID'], $newLocation);
        } else {
            throw new Exception('添加失败,原因：'.Form::formatErrorsForApi($form->getErrors()));
        }
        return true;
    }

    /**
     * 清空已增加的会员
     */
    public function actionClearAddUser(){
        $notDelUserId = "'670B84FD7C216D4EE055736AECE8644D','B322C18F7E274A9D9FC5DADC3B385E8B','638A5A3B617F46C999C5E4D072EED369','3C313C66D1724D658BF10B08194022BB'";
        $netChangeUserId = "'B322C18F7E274A9D9FC5DADC3B385E8B','638A5A3B617F46C999C5E4D072EED369','3C313C66D1724D658BF10B08194022BB'";
        UserInfo::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        UserNetwork::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        UserRelation::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        UserInfo::updateAll(['CON_NUM' => 0, 'REC_NUM' => 0], "USER_ID IN (".$netChangeUserId.")");
        User::deleteAll("ID NOT IN (".$notDelUserId.")");
        CalcBonus::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        CalcBonusBD::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        CalcBonusTG::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        CalcBonusYJ::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        CalcBonusGX::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        CalcBonusGL::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        CalcBonusQY::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        CalcBonusYC::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        FlowBonus::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        FlowReconsumePoints::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        PerfPeriod::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        PerfMonth::deleteAll("USER_ID NOT IN (".$notDelUserId.")");
        DecOrder::deleteAll("TO_USER_ID NOT IN (".$notDelUserId.")");
        UserBonus::deleteAll();

        echo '删除完成'.PHP_EOL;
    }

    /**
     * 清空所有会员
     */
    public function actionClearAllUser(){
        UserInfo::deleteAll();
        UserNetwork::deleteAll();
        UserRelation::deleteAll();
        User::deleteAll();
        CalcBonus::deleteAll();
        CalcBonusBD::deleteAll();
        CalcBonusTG::deleteAll();
        CalcBonusYJ::deleteAll();
        CalcBonusGX::deleteAll();
        CalcBonusGL::deleteAll();
        CalcBonusQY::deleteAll();
        CalcBonusYC::deleteAll();
        FlowBonus::deleteAll();
        FlowReconsumePoints::deleteAll();
        PerfPeriod::deleteAll();
        PerfMonth::deleteAll();
        DecOrder::deleteAll();
        UserBonus::deleteAll();

        echo '删除完成'.PHP_EOL;
    }

    /**
     * 清空结算的奖金
     */
    public function actionClearBonus(){
        CalcBonus::deleteAll();
        CalcBonusBD::deleteAll();
        CalcBonusTG::deleteAll();
        CalcBonusYJ::deleteAll();
        CalcBonusGX::deleteAll();
        CalcBonusGL::deleteAll();
        CalcBonusQY::deleteAll();
        CalcBonusYC::deleteAll();
        FlowBonus::deleteAll();
        FlowReconsumePoints::deleteAll();
        PerfPeriod::deleteAll();
        PerfMonth::deleteAll();

        echo '删除完成'.PHP_EOL;
    }

    /**
     * 清空会员的网络
     */
    public function actionClearNetRedis(){
        \Yii::$app->redis->del(Cache::USER_NETWORK_PARENTS);
        \Yii::$app->redis->del(Cache::USER_RELATION_PARENTS);
        echo '全部完成'.PHP_EOL;
    }

    public function actionLoopUser($offset = 0){
        $query = UserInfo::findUseDbCalc()->select('USER_ID,USER_NAME,ZC_PV,CON_UID,REC_UID,CON_NUM,REC_NUM,NETWORK_DEEP,RELATION_DEEP,STORE_TYPE,PERIOD_NUM,CREATED_AT,UPDATED_AT')->where('1=1')->orderBy('NETWORK_DEEP DESC')->offset($offset)->limit(100)->asArray()->all();
        if($query){
            foreach($query as $data){
                echo($data['USER_NAME'].PHP_EOL);
            }
            $this->actionLoopUser($offset + 100);
        }
        exit();
    }

    public function actionLoopUserTwo(){
//        $query = UserInfo::findUseDbCalc()->select('USER_ID,USER_NAME,ZC_PV,CON_UID,REC_UID,CON_NUM,REC_NUM,NETWORK_DEEP,RELATION_DEEP,STORE_TYPE,PERIOD_NUM,CREATED_AT,UPDATED_AT')->where('1=1')->orderBy('NETWORK_DEEP DESC')->asArray();
//
//        foreach($query->batch() as $allData){
//            foreach($allData as $data){
//                echo($data['USER_NAME'].PHP_EOL);
//            }
//        }
//
//        exit();
//        $test=(new \yii\db\Query());
//        $test->from('AR_USER_INFO');
//        $reader=$test->prepare(\Yii::$app->db->queryBuilder)->createCommand()->query();
//        while ($row = $reader->read()) {
//            print_r($row);
//        }
        $query = (new Query())->from('{{%USER_INFO}}')->prepare(\Yii::$app->db->queryBuilder)->where('1=1');
//        while ($row = $query->read()) {
//            print_r($row['USER_NAME'].PHP_EOL);
//        }

        try {
            foreach($query->batch() as $allData){
                foreach($allData as $data){
                    echo($data['USER_NAME'].PHP_EOL);
                }
            }
        } catch (\PDOException $e){
            print_r($e->getMessage());
        }

    }

    /**
     * 循环加入报单
     * @throws \yii\db\Exception
     */
    public function actionLoopAddDec(){
        // 获取最底层的100名会员
        $allUser = UserInfo::find()->where('1=1')->limit(100)->orderBy('NETWORK_DEEP DESC')->asArray()->all();
        $insertData = [];
        $decSn = 190310000000;
        foreach($allUser as $key=>$user){
            $decSn += 1;
            $decPv = rand(1, 100) * 1000;
            $insertData[] = [
                'DEC_SN' => 'D'.$decSn.'0000',
                'ORDER_SN' => $decSn,
                'USER_ID' => $user['USER_ID'],
                'TYPE' => 'ZC',
                'TO_USER_ID' => $user['USER_ID'],
                'DEC_AMOUNT' => $decPv,
                'DEC_PV' => $decPv,
                'PAID_WALLET' => 'bill',
                'PERIOD_NUM' => 121,
                'IS_DEL' => 0,
                'P_CALC_MONTH' => Date::ociToDate(202001, Date::OCI_TIME_FORMAT_SHORT_MONTH),
                'CREATED_AT' => strtotime('2020-01-20'),
                'DEC_ID' => $user['REC_UID'],
            ];
        }

        DecOrder::batchInsert($insertData);
        echo('全部完成'.PHP_EOL);
    }

    /**
     * 清空报单
     */
    public function actionClearDec(){
        DecOrder::deleteAll('PERIOD_NUM = 100');
        echo('删除完成'.PHP_EOL);
    }

    /**
     * 测试rpc接口
     * @throws Exception
     */
    public function actionRpcCli(){
//        $data = [
//            ['type' => 'ZC', 'userId' => '670B84FD7C216D4EE055736AECE8644D', 'toUserId'=>'dec001', 'decPv' => '5000', 'insertUserName' => 'dec001', 'conUserName' => 'tester005', 'recUserName' => 'tester003', 'location' => 1],
//            ['type' => 'ZC', 'userId' => '670B84FD7C216D4EE055736AECE8644D', 'toUserId'=>'dec002', 'decPv' => '5000', 'insertUserName' => 'dec002', 'conUserName' => 'tester003', 'recUserName' => 'tester003', 'location' => 2],
//            ['type' => 'ZC', 'userId' => '670B84FD7C216D4EE055736AECE8644D', 'toUserId'=>'dec003', 'decPv' => '5000', 'insertUserName' => 'dec003', 'conUserName' => 'tester003', 'recUserName' => 'tester003', 'location' => 3],
//            ['type' => 'ZC', 'userId' => '670B84FD7C216D4EE055736AECE8644D', 'toUserId'=>'dec004', 'decPv' => '5000', 'insertUserName' => 'dec004', 'conUserName' => 'dec001', 'recUserName' => 'tester003', 'location' => 1],
//            ['type' => 'ZC', 'userId' => '670B84FD7C216D4EE055736AECE8644D', 'toUserId'=>'dec005', 'decPv' => '5000', 'insertUserName' => 'dec005', 'conUserName' => 'dec001', 'recUserName' => 'tester003', 'location' => 2],
//            ['type' => 'ZC', 'userId' => '670B84FD7C216D4EE055736AECE8644D', 'toUserId'=>'dec006', 'decPv' => '5000', 'insertUserName' => 'dec006', 'conUserName' => 'dec001', 'recUserName' => 'tester003', 'location' => 3],
//        ];
//        $data = array (
//            0 =>
//                array (
//                    'type' => 'ZC',
//                    'userId' => 'B322C18F7E274A9D9FC5DADC3B385E8B',
//                    'toUserId' => '6B2869C5958446CAB479CF1A5D9E3763',
//                    'decPv' => '705',
//                    'insertUserName' => 'b80346267',
//                    'insertUserIdCard' => '130302199905051113',
//                    'conUserName' => 'b90556236',
//                    'recUserName' => 'tester002',
//                    'location' => '1',
//                ),
//            1 =>
//                array (
//                    'type' => 'ZC',
//                    'userId' => 'B322C18F7E274A9D9FC5DADC3B385E8B',
//                    'toUserId' => '940644BC1C2D41F392EA0EDCB4354F55',
//                    'decPv' => '875',
//                    'insertUserName' => 'b27486502',
//                    'insertUserIdCard' => '130302199905051113',
//                    'conUserName' => 'b80346267',
//                    'recUserName' => 'tester002',
//                    'location' => '1',
//                ),
//            2 =>
//                array (
//                    'type' => 'ZC',
//                    'userId' => 'B322C18F7E274A9D9FC5DADC3B385E8B',
//                    'toUserId' => '854E59FE17494633A853872C878B93D7',
//                    'decPv' => '1405',
//                    'insertUserName' => 'b76328656',
//                    'insertUserIdCard' => '130302199905051113',
//                    'conUserName' => 'b80346267',
//                    'recUserName' => 'b27486502',
//                    'location' => '2',
//                ),
//        );
        $data = [
            [
                'type' => 'ZC',
                'userId' => '3C313C66D1724D658BF10B08194022BB',
                'toUserId' => '',
                'decPv' => '3000',
                'insertUserName' => 'b27251926',
                'conUserName' => 'b83825142',
                'recUserName' => 'b92223569',
                'location' => '1',
                'insertUserIdCard' => '110227196504215915',
            ],
            [
                'type' => 'ZC',
                'userId' => '3C313C66D1724D658BF10B08194022BB',
                'toUserId' => '',
                'decPv' => 12000.0,
                'insertUserName' => 'b86268542',
                'conUserName' => 'b92223569',
                'recUserName' => 'b27251926',
                'location' => '2',
                'insertUserIdCard' => '110227196504215915',
            ],
        ];
        $condition = [
            'namespace' => '\\'.RPCApi::class.'::api',
            'param' => [
                'class'=> '\\'.DeclarationLoopForm::class,
                'fields'=>[
                    'scenario' => 'canDec',
                    'data' => $data,
                ],
                'action'=>'validate',
                'param'=>[],
            ],
        ];
        $rpcApi = new RPCApi();
        if($result = $rpcApi->request($condition)){
            var_dump($result);
        } else {
            var_dump($rpcApi->getError());
        }
    }

    /**
     * 发票识别
     */
    public function actionOcr(){
        $result = OcrApi::instance()->vatInvoice('/Volumes/HDD/Downloads/vatInvoice.jpg');
        print_r($result);
    }

    /**
     * 备份数据库测试
     * @throws \yii\db\Exception
     */
    public function actionBakData(){
        DataBak::backup(142);
    }

    /**
     * 测试短信发送（可协程发送）
     */
    public function actionSendSms(){
        $params = [
            'mobiles' => '19933643193',
            'content' => '测试短息，您好',
        ];
        SmsApi::instance()->clearError();
        for($i=0;$i<10;$i++){
            SmsApi::instance()->goSend($params);
        }
        print_r(SmsApi::instance()->getError());
    }

    /**
     * 测试绑定
     * @throws \yii\db\Exception
     */
    public function actionBind(){
        UserBind::autoBind('9AC80FF809B04EED96321D34CBA0EAA9','32132419900307929X');
    }

    /**
     * 测试任务队列
     */
    public function actionTaskQueue(){
        if(Queue::instance()->addTask(Queue::TYPE_FUNC, TaskFunc::class.'::testTaskQueue', [], Queue::LOOP_TYPE_DAY, '16:39:00', 2)){
            echo('任务添加成功'.PHP_EOL);
        } else {
            echo('任务添加失败'.PHP_EOL);
        }
    }

    public function actionMsg(){
        $r=Reconsume::getUserReconsumePool("8C5E7DEB93767021E053693418ACB2B6");
    }

    public function actionGenerateId() {
        for($i=1;$i<=10;$i++) {
            echo SnowFake::instance()->generateId() . PHP_EOL;
        }
    }

    public function actionShow() {
        $a4Uid = '76202856516030464';
        $data = CalcCache::bonus($a4Uid, 104);
        print_r($data);die;
    }

    public function actionLoopAllUsers($findUid='76193630875947008', $periodNum=105, $offset = 0)
    {
        // 从缓存列表里面从底层往上倒序获取会员
        $allData = CalcCache::getUsers($periodNum, $offset, 100);
        if($allData) {
            foreach($allData as $userId){
//                echo sprintf("userId:%s", $userId) . PHP_EOL;
                if( $userId === $findUid ) {
                    echo "find user" . $findUid . PHP_EOL;
//                    $data = CalcCache::bonus($findUid, 104);
//                    var_dump($data);die;
                }
                unset($userId);
            }
            unset($allData);
            return $this->actionLoopAllUsers($findUid, $periodNum, $offset + 100);
        }
        return true;
    }

    public function actionLoopAllPerfUser($offset=0, $periodNum=103, $limit=1000) {
        $allData = CalcCache::getHasPerfUsers($periodNum, $offset, $limit);
        if ($allData) {
            foreach ($allData as $userId) {
                $user = User::find()->select(["USER_NAME"])->where('ID=:ID', ['ID'=>$userId])->asArray()->all();
                if( !$user ) {
                    echo $userId . PHP_EOL;
                }
            }

            $this->actionLoopAllPerfUser($offset+$limit, $periodNum, $limit);
        }
    }


    public function actionLoopAllGxUser($offset=0, $periodNum=105, $limit=1000) {
        return false;
        $allData = CalcBonus::find()->select(["ID", "USER_ID", "ORI_BONUS_GX"])->where("PERIOD_NUM=:PERIOD_NUM", ["PERIOD_NUM"=>$periodNum])->offset($offset)->limit($limit)->asArray()->all();
        if ($allData) {
            foreach ($allData as $everyData) {
                if( $everyData['ORI_BONUS_GX'] <= 0 ) continue;

                $list = CalcBonusGX::find()->select(['ID', 'USER_ID', 'ORI_BONUS'])->where('USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', [
                    'USER_ID' => $everyData['USER_ID'],
                    'PERIOD_NUM' => $periodNum,
                ])->asArray()->all();
                if( count($list) <= 1) {
                    unset($list);
                    continue;
                }

                //删除一条
                $firstData = array_shift($list);

                if( $firstData['ORI_BONUS'] != $everyData['ORI_BONUS_GX'] ) {
                    //修改奖金
                    echo 'ID:' . $everyData['ID'] . '奖金:' . $everyData['ORI_BONUS_GX'] . '修改为:' . $firstData['ORI_BONUS'] . PHP_EOL;
                    CalcBonus::updateAll(['ORI_BONUS_GX'=>$firstData['ORI_BONUS']], 'ID=:ID', [
                        'ID' => $everyData['ID'],
                    ]);
                }

                //删除其它记录
                foreach ($list as $deleteData) {
                    echo '删除记录为:' . $deleteData['ID'] . PHP_EOL;
                    CalcBonusGX::deleteAll('ID=:ID', ['ID'=>$deleteData['ID']]);

                    unset($deleteData);
                }

                unset($everyData, $list, $firstData);
            }


            unset($allData);
            $this->actionLoopAllGxUser($offset+$limit, $periodNum, $limit);
        }
    }


    public function actionLoopAllGxUserTwo($offset=0, $periodNum=105, $limit=1000) {
        return false;
        $allData = CalcBonusGX::find()->select(['ID', 'USER_ID', 'ORI_BONUS', 'AMOUNT', 'RECONSUME_POINTS', 'MANAGE_TAX'])->where('PERIOD_NUM=:PERIOD_NUM', [
            'PERIOD_NUM' => $periodNum,
        ])->offset($offset)->limit($limit)->asArray()->all();
        if ($allData) {
            foreach ($allData as $everyData) {
                $oneData = CalcBonus::find()->select(["ID", "USER_ID", "BONUS_GX", "RECONSUME_POINTS", "MANAGE_TAX", "BONUS_TOTAL"])->where('USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', [
                    'USER_ID' => $everyData['USER_ID'],
                    'PERIOD_NUM' => $periodNum,
                ])->asArray()->one();

                if( $oneData['BONUS_GX'] != $everyData['AMOUNT'] ) {
                    //修改奖金
                    echo 'ID:' . $oneData['ID'] . '奖金:' . $oneData['BONUS_GX'] . '修改为:' . $everyData['AMOUNT'] . PHP_EOL;
//                    echo 'RECONSUME_POINTS:' . ($oneData['RECONSUME_POINTS']-$everyData['RECONSUME_POINTS']) . 'MANAGE_TAX:' . ($oneData['MANAGE_TAX']-$everyData['MANAGE_TAX']) . PHP_EOL;
                    CalcBonus::updateAll([
                        'BONUS_GX'=>$everyData['AMOUNT'],
                        'RECONSUME_POINTS'=>$oneData['RECONSUME_POINTS']-$everyData['RECONSUME_POINTS'],
                        'MANAGE_TAX'=>$oneData['MANAGE_TAX']-$everyData['MANAGE_TAX'],
                        'BONUS_TOTAL'=>$oneData['BONUS_TOTAL']-$everyData['ORI_BONUS'],
                    ], 'ID=:ID', [
                        'ID' => $oneData['ID'],
                    ]);
                }

                unset($everyData, $oneData);
            }


            unset($allData);
            $this->actionLoopAllGxUserTwo($offset+$limit, $periodNum, $limit);
        }
    }

    /**
     * 导入结余业绩
     * @param int $periodNum
     */
    public function actionAddSurplusData($periodNum=107) {
        $allCount = PerfPeriod::find()->where('PERIOD_NUM=:PERIOD_NUM', ['PERIOD_NUM'=>$periodNum])->count('ID');
        $pageSize = 1000;
        $pageCount = ceil($allCount/$pageSize);
        unset($allCount);
        for($page=1;$page<=$pageCount;$page++){
            echo sprintf('导入【%d】期结余业绩，总页数为【%d】，当前页数为【%d】' . PHP_EOL, $periodNum, $pageCount, $page);
            $perfPeriodData = PerfPeriod::find()->select(['USER_ID', 'SURPLUS_1L', 'SURPLUS_2L', 'SURPLUS_3L', 'SURPLUS_4L', 'SURPLUS_5L'])->where('PERIOD_NUM=:PERIOD_NUM', ['PERIOD_NUM'=>$periodNum])->orderBy('ID ASC')->offset(($page-1)*$pageSize)->limit($pageSize)->asArray()->all();
            foreach ($perfPeriodData as $data) {
                UserPerf::updateAll([
                                'SURPLUS_1L' => $data['SURPLUS_1L'],
                                'SURPLUS_2L' => $data['SURPLUS_2L'],
                                'SURPLUS_3L' => $data['SURPLUS_3L'],
                                'SURPLUS_4L' => $data['SURPLUS_4L'],
                                'SURPLUS_5L' => $data['SURPLUS_5L'],
                            ], 'USER_ID=:USER_ID', [':USER_ID' => $data['USER_ID']]);
                unset($data);
            }
            unset($perfPeriodData);
        }

    }

    public function actionAddLastSurplus()
    {
        $data = [
            'A10505648'=>360,
            'D86714213'=>120,
            'F10401034'=>120,
            'A16768918'=>360,
            'H72700605'=>720,
            'H19166726'=>550,
            'H38585848'=>360,
            'A18950413'=>1560,
            'H87620691'=>120,
            'E10242995'=>426,
            'Eh78786514'=>124,
            'E14356640'=>120,
            'E12757473'=>360,
            'A19273920'=>240,
            'H10164357'=>120,
        ];
        foreach ($data as $username=>$perf) {
            $user = User::find()->select(['ID'])->where('USER_NAME=:USER_NAME', [
                'USER_NAME' => $username
            ])->asArray()->one();
            UserPerf::updateAll([
                'SURPLUS_2L' => $perf,
            ], 'USER_ID=:USER_ID', [':USER_ID' => $user['ID']]);
            unset($username, $perf);
        }

        echo 'OK' . PHP_EOL;
    }

    public function actionBackup() {
        DataBak::backup(105);
    }


    /**
     * 结算最后一步写数据
     * @param int $periodNum
     * @throws \yii\db\Exception
     */
    public function actionCalcWriteDb($periodNum=108) {
        // 周业绩
//        PerfPeriod::pageDeleteAll('PERIOD_NUM='.$periodNum);
//        // 奖金表
//        CalcBonus::pageDeleteAll('PERIOD_NUM='.$periodNum);
//
//        $calcWrite = new CalcWrite();
//        $calcWrite->start($periodNum);

        Period::updateAll(['IS_CALCING' => 0, 'IS_CALCULATED' => Period::CALCULATE_FINISH, 'CALCULATED_AT' => Date::nowTime(), 'CALC_PERCENT' => 100], 'PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $periodNum]);
    }

    /**
     * 计算某一期的聘级
     * @param $periodNum
     * @return string
     * @throws Exception
     * @throws \yii\db\Exception
     */
    public function actionCalcEmpLevel($periodNum) {
        $bonusCalc = PerfCalc::instance();
        $bonusCalc->setPeriodNum($periodNum);
        $bonusCalc->initCalcTask();
        $bonusCalc->loopCalcEmpLevel();

        return 'ok' . PHP_EOL;
    }

    /**
     * 计算某一期的聘级
     * @param $periodNum
     * @return string
     * @throws Exception
     * @throws \yii\db\Exception
     */
    public function actionCheckVipBonus($periodNum) {
        $bonusCalc = BonusCalc::instance();
        $bonusCalc->setPeriodNum($periodNum);
        $bonusCalc->initCalcTask();
        $bonusCalc->calcBonusVIP();

        return 'ok' . PHP_EOL;
    }

    /**
     * 检测共享奖
     * @param $periodNum
     * @return string
     * @throws \yii\db\Exception
     */
    public function actionCheckShareBonus($periodNum) {
        $bonusCalc = BonusCalc::instance();
        $bonusCalc->setPeriodNum($periodNum);
        $bonusCalc->initCalcTask();
        $bonusCalc->calcBonusGXBefore();

        return 'ok' . PHP_EOL;
    }

    /**
     * 修正导入数据的报单中心ID
     * @param int $startPage
     * @param int $limit
     * @return bool
     */
    public function actionFixImportDecId($startPage=1, $limit = 1000) {
        $numCount = TmpOldNetwork::find()->where("1=1")->orderBy("ID ASC")->count("ID");
        $pageCount = ceil($numCount/$limit);
        for ($page=$startPage;$page<=$pageCount;$page++) {
            $pageList = TmpOldNetwork::find()->where("1=1")->orderBy("ID ASC")->limit($limit)->offset(($page - 1) * $limit)->asArray()->all();
            foreach ($pageList as $pageData) {
                User::updateAll(['DEC_ID'=>'670B84FD7C216D4EE055736AECE8644D'], 'USER_NAME=:USER_NAME', ['USER_NAME'=>$pageData['USER_NAME']]);
                unset($pageData);
            }
            unset($pageList);

            echo sprintf("修改所属报单中心，总页数【%s】，当前页数：【%s】写入成功".PHP_EOL, $pageCount, $page);
        }
        unset($numCount, $pageCount, $page, $startPage, $limit);

        return true;
    }


    /**
     *
     * 环循所有会员找到错误的数据
     * @param int $periodNum
     * @param int $offset
     * @return bool
     */
    public function actionLoopAllUsersForError($periodNum=115, $offset = 0)
    {
        echo '当前offset:' . $offset . PHP_EOL;
        // 从缓存列表里面从底层往上倒序获取会员
        $allData = CalcCache::getUsers($periodNum, $offset, 1000);
        if($allData) {
            foreach($allData as $userId){
                // 获取到级别以后，给上级的相应人数中追加数量
                $parentRecUserId = $userId;
                $this->loopRelationParentDo($userId, function ($parent) use ($periodNum, &$parentRecUserId) {
                    //判断$parentRecUserId是否为$parent['PARENT_UID']的直推
                    $parentUid = $parent['PARENT_UID'];
                    $toInfo = CalcCache::getUserInfo($parentRecUserId, $periodNum);
                    if( !isset($toInfo['REC_UID']) ) {
                        echo '错误数据:' . $parentRecUserId . PHP_EOL;
                    }
                    if( isset($toInfo['REC_UID']) && $parentUid !== $toInfo['REC_UID'] ) {
                        $parentUid = $toInfo['REC_UID'];
                    }
                    unset($toInfo);
                    if( !$parentUid ) return 1;

                    //每次记录上次的USER_ID
                    $parentRecUserId = $parentUid;
                });
                unset($userId);
            }
            unset($allData);
            return $this->actionLoopAllUsersForError($periodNum, $offset + 1000);
        }
        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, 1000);
        unset($allParents);
        if ($allData) {
            foreach ($allData as $data) {
                $funcResult = $callbackFunc($data);
                if ($funcResult === 1) {
                    return true;
                } elseif ($funcResult === 2) {
                    continue;
                }
                unset($data, $funcResult);
            }

            unset($allData);
            return $this->loopRelationParentDo($userId, $callbackFunc, $offset + 1000);
        }
        return true;
    }


    /**
     * 循环父级并执行回调函数
     * @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, 1000);
        unset($allParents);
        if ($allData) {
            foreach ($allData as $data) {
                $funcResult = $callbackFunc($data);
                if ($funcResult === 1) {
                    return true;
                } elseif ($funcResult === 2) {
                    continue;
                }
                unset($data, $funcResult);
            }
            unset($allData);
            return $this->loopNetworkParentDo($userId, $callbackFunc, $offset + 1000);
        }
        return true;
    }


    /**
     * 计算某人某一期的聘级
     * @param $userId
     * @param $periodNum
     * @return string
     * @throws Exception
     * @throws \yii\db\Exception
     */
    public function actionCheckUserEmpLevel($userId, $periodNum) {
        $bonusCalc = PerfCalc::instance();
        $bonusCalc->setPeriodNum($periodNum);
        $bonusCalc->initCalcTask();
        $nowMonthPerf = CalcCache::nowMonthPerf($userId, $periodNum);
        var_dump($nowMonthPerf);
        $empLevelData = $bonusCalc->isEmpLevel1($userId, $nowMonthPerf);
        var_dump($empLevelData);
        return 'ok' . PHP_EOL;
    }

    public function actionCheckYcBonus($userId, $periodNum) {
        $empLevelConfig = Cache::getEmpLevelConfig();
        $nowMonthPerf = CalcCache::nowMonthPerf($userId, $periodNum);
//                $monthPvPss = $nowMonthPerf['PV_PCS'] + $nowMonthPerf['PV_PSS'];
        $empLevelId = $nowMonthPerf['EMP_LEVEL'];
        $empLevel = $empLevelConfig[$empLevelId];
        $rxPercent = $empLevel['RX_PERCENT'] ?? 0;
        if( $rxPercent <= 0 ) {
            echo 'rxPercent error' . PHP_EOL;
            return false;
        }

        //个人业绩的奖金
        $empBonus = $nowMonthPerf['PV_PCS'] * $rxPercent / 100;
        //2020-06-05修改荣衔奖的计算方式、不由自己的业绩决定、由直推会员的业绩决定
        $childList = CalcCache::getChildrenOneDeepFromRedis($userId, $periodNum);
        foreach ($childList as $child) {
            $childMaxPercent = CalcCache::ycMaxBonusPercent($child['USER_ID'], $periodNum);
            $percentDiff = $rxPercent - $childMaxPercent;
            if( $percentDiff <= 0 ) continue;

            $childNowMonthPerf = CalcCache::nowMonthPerf($child['USER_ID'], $periodNum);

            $childBonus = $childNowMonthPerf['PV_PSS_TOTAL'] * $percentDiff / 100;

            $empBonus += $childBonus;

            echo sprintf('childUserId:%s,childMaxPercent:%s,childBonus:%s' . PHP_EOL, $child['USER_ID'], $childMaxPercent, $childBonus);
            unset($child, $childMaxPercent, $percentDiff, $childNowMonthPerf, $childBonus);
        }
        unset($childList);

        echo sprintf('userId:%s,rxPercent:%s,empBonus:%s' . PHP_EOL, $userId, $rxPercent, $empBonus);
    }

    /**
     * 修正移网业绩错误的问题
     * @return bool
     */
    public function actionFixMoveNetPerf() {
        //获取未结算的月份
        $noSentPeriod = Period::find()->where('IS_SENT=0')->orderBy('PERIOD_NUM ASC')->asArray()->one();
        if( !$noSentPeriod ) return false;

        $thisYearMonth = $noSentPeriod['CALC_YEAR'].Tool::numFix($noSentPeriod['CALC_MONTH'], 2);
        $lastYearMonth = Date::lastMonth($noSentPeriod['CALC_YEAR'].'-'.$noSentPeriod['CALC_MONTH'], 'Ym');
//        $lastYearMonth = '202003';
        echo sprintf("当前期数为:%s,当前结算年月为:%s,上一个结算年月为:%s" . PHP_EOL, $noSentPeriod['PERIOD_NUM'], $thisYearMonth, $lastYearMonth);
        unset($noSentPeriod);

        //找到所有的relation的移网
        $allRelationList = UserMove::find()->where('TYPE=:TYPE', ['TYPE'=>'relation'])->asArray()->all();
        //根据原来的父级、找到所有的原父级
        $lastYearMonthPerf = [
            '86821386802302976'=>960.000,
            '76193537884033024'=>1053.000,
            '76200969452523520'=>1098.000,
            '76193583539032064'=>360.000,
            '76220073806794752'=>4678.400,
            '76218844456292352'=>17825.000,
            '76219777546326016'=>12316.000,
            '76220534563672064'=>6844.000,
            '76220988731297792'=>2680.000,
            '86805887292936192'=>508.000,
            '86803242738126848'=>6688.200,
            '76193502618324992'=>28590.000,
            '86804998209540096'=>0.000,
            '86802876130791424'=>8938.000,
            '76196752000159744'=>436.000,
            '76189559771238400'=>90423.400,
        ];
        foreach ($allRelationList as $moveData) {
            echo sprintf("当前用户ID:%s,原看接点人ID:%s,新接点人ID:%s" . PHP_EOL, $moveData['USER_ID'], $moveData['FROM_UID'], $moveData['TO_UID']);
            if( !isset($lastYearMonthPerf[$moveData['USER_ID']]) || $lastYearMonthPerf[$moveData['USER_ID']] == 0 ) continue;
            //查找移动点位这个人的上个月的累计业绩
//            $lastYearMonthPerf = PerfMonth::find()->where('USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH', ['USER_ID'=>$moveData['USER_ID'], 'CALC_MONTH'=>$lastYearMonth])->asArray()->one();
//            echo sprintf("'%s'=>%s," . PHP_EOL, $moveData['USER_ID'], $lastYearMonthPerf['PV_PSS_TOTAL']);
            //本月的已结算业绩
//            $thisPerfPeriodList = PerfPeriod::find()->select(['PV_PCS', 'PERIOD_NUM'])->where('USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH', ['USER_ID'=>$moveData['USER_ID'], 'CALC_MONTH'=>$thisYearMonth])->asArray()->all();

            $oldParentList = UserRelation::find()->where('USER_ID=:USER_ID', ['USER_ID'=>$moveData['FROM_UID']])->asArray()->all();
            $oldParentUids = [$moveData['FROM_UID']];
            foreach ($oldParentList as $oldData) {
                $oldParentUids[] = $oldData['PARENT_UID'];
                unset($oldData);
            }
            unset($oldParentList);


            $newParentList = UserRelation::find()->where('USER_ID=:USER_ID', ['USER_ID'=>$moveData['TO_UID']])->asArray()->all();
            $newParentUids = [$moveData['TO_UID']];
            foreach ($newParentList as $newData) {
                $newParentUids[] = $newData['PARENT_UID'];
                unset($newData);
            }
            unset($newParentList);

            //修改上个月的累计业绩
            foreach ($oldParentUids as $oldParentUid) {//减
                PerfMonth::updateAllCounters(['PV_PSS_TOTAL'=>(-1)*$lastYearMonthPerf[$moveData['USER_ID']]], 'USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH', ['USER_ID'=>$oldParentUid, 'CALC_MONTH'=>$lastYearMonth]);
                unset($oldParentUid);
            }
            foreach ($newParentUids as $newParentUid) {//加
                PerfMonth::updateAllCounters(['PV_PSS_TOTAL'=>$lastYearMonthPerf[$moveData['USER_ID']]], 'USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH', ['USER_ID'=>$newParentUid, 'CALC_MONTH'=>$lastYearMonth]);
                unset($newParentUid);
            }

            //修改本月的已结算业绩
//            foreach ($thisPerfPeriodList as $periodPerf) {
//                if( $periodPerf['PV_PCS'] <= 0 ) continue;
//
//                foreach ($oldParentUids as $oldParentUid) {//减
//                    PerfPeriod::updateAllCounters(['PV_PSS'=>(-1)*$periodPerf['PV_PCS']], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', ['USER_ID'=>$oldParentUid, 'PERIOD_NUM'=>$periodPerf['PERIOD_NUM']]);
//                    unset($oldParentUid);
//                }
//                foreach ($newParentUids as $newParentUid) {//加
//                    PerfPeriod::updateAllCounters(['PV_PSS'=>$periodPerf['PV_PCS']], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', ['USER_ID'=>$newParentUid, 'PERIOD_NUM'=>$periodPerf['PERIOD_NUM']]);
//                    unset($newParentUid);
//                }
//
//                unset($periodPerf);
//            }

            unset($moveData);
        }

        unset($allRelationList, $thisYearMonth, $lastYearMonth, $lastYearMonthPerf);
    }

    /**
     * 检测聘级
     * @param $userId
     * @param int $periodNum
     * @throws \yii\db\Exception
     */
    public function actionCheckEmpLevel($userId, $periodNum=115)
    {
        $bonusCalc = PerfCalc::instance();
        $bonusCalc->setPeriodNum($periodNum);
        $bonusCalc->initCalcTask();
        $userInfo = CalcCache::getUserInfo($userId, $periodNum);
        $nowMonthPerf = CalcCache::nowMonthPerf($userId, $periodNum);
        $empLevel = $bonusCalc->checkEmpLevel($userId, $nowMonthPerf, $userInfo['EMP_LV']);

        var_dump($empLevel);
        die;
    }

    /*
     * 清空所有会员的剩余业绩
     */
    public function actionClearSurplusPerf() {
        $allCount = UserPerf::find()->where('1=1')->orderBy('ID ASC')->count('ID');
        $pageSize = 1000;
        $pageCount = ceil($allCount/$pageSize);
        for( $page=1;$page<=$pageCount;$page++ ) {
            echo sprintf('清空所有会员的剩余业绩，总页数为【%d】，当前页数为【%d】' . PHP_EOL, $pageCount, $page);
            $list = UserPerf::find()->where('1=1')->orderBy('ID ASC')->offset(($page-1)*$pageSize)->limit($pageSize)->asArray()->all();
            foreach ($list as $every) {
                UserPerf::updateAll([
                    'SURPLUS_1L' => 0,
                    'SURPLUS_2L' => 0,
                    'SURPLUS_3L' => 0,
                    'SURPLUS_4L' => 0,
                    'SURPLUS_5L' => 0], 'ID=:ID', ['ID'=>$every['ID']]);
                unset($every);
            }
            unset($list);
        }
    }


    /**
     * 手动清空RepairCache
     */
    public function actionClearRepairCache() {
        CalcCache::clearRepairAllCache();
    }


    /**
     * 修正剩余业绩没有记录的错误
     */
    public function actionFixSurplusPerf() {
        $bigPercentPeriod = 116;
        $pageSize = 1000;

        for ($periodNum=111;$periodNum<=118;$periodNum++) {
            $allCount = PerfPeriod::find()->from(PerfPeriod::tableName() . 'AS PP')->select('PP.ID,PP.USER_ID, PP.PV_1L,PP.PV_2L,PP.PV_3L,CBQ.LOGS')->leftJoin(CalcBonusQY::tableName() . ' AS CBQ', 'CBQ.USER_ID=PP.USER_ID AND CBQ.PERIOD_NUM=PP.PERIOD_NUM')->where('PP.PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $periodNum])->orderBy('PP.ID ASC')->count();
            $pageCount = ceil($allCount/$pageSize);
            for ($page=1;$page<=$pageCount;$page++) {
                $allData = PerfPeriod::find()->from(PerfPeriod::tableName() . 'AS PP')->select('PP.ID,PP.USER_ID, PP.PV_1L,PP.PV_2L,PP.PV_3L,CBQ.LOGS')->leftJoin(CalcBonusQY::tableName() . ' AS CBQ', 'CBQ.USER_ID=PP.USER_ID AND CBQ.PERIOD_NUM=PP.PERIOD_NUM')->where('PP.PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM' => $periodNum])->orderBy('PP.ID ASC')->offset(($page-1)*$pageSize)->limit($pageSize)->asArray()->all();
                if( !$allData ) continue;
                foreach ($allData as $everyData) {
                    if( $everyData['LOGS'] ) {
                        $logData = json_decode($everyData['LOGS'], true);
                        $surplusData = $logData['touchPerfArr'];
                        unset($logData);
                    }else {
                        $surplusData = [
                            'SURPLUS_1L' => $everyData['PV_1L'],
                            'SURPLUS_2L' => $everyData['PV_2L'],
                            'SURPLUS_3L' => $everyData['PV_3L'],
                            'SURPLUS_4L' => 0,
                            'SURPLUS_5L' => 0,
                        ];

                    }
                    //更新当前记录
                    PerfPeriod::updateAll($surplusData, 'ID=:ID', ['ID'=>$everyData['ID']]);
                    //更新userPerf
                    if( $periodNum >= $bigPercentPeriod ) {
                        UserPerf::updateAllCounters($surplusData, 'USER_ID=:USER_ID', ['USER_ID'=>$everyData['USER_ID']]);
                    }else {
                        //@todo 存储到缓存中或新字段里
                        CalcCache::setRepairSurplusPerf($everyData['USER_ID'], $surplusData);
                    }
                    $baseUser = Info::getBaseUserById($everyData['USER_ID']);
                    echo sprintf('当前期数:%s,当前用户ID为:%s,用户名为:%s,更新的数为,一区剩余:%s,二区剩余:%s,三区剩余:%s' . PHP_EOL, $periodNum, $everyData['USER_ID'], $baseUser['USER_NAME'], $surplusData['SURPLUS_1L'], $surplusData['SURPLUS_2L'], $surplusData['SURPLUS_3L']);

                    unset($everyData, $surplusData, $baseUser);
                }
                unset($allData);
            }


        }
    }

    public function actionTestUpdateEmpLevel()
    {
        $allCount = PerfMonth::find()->where('CALC_MONTH=:CALC_MONTH', ['CALC_MONTH' => '202005'])->count('ID');
        $periodNum = 115;
        $pageSize = 1000;
        $pageCount = ceil($allCount / $pageSize);
        for ($page = 1; $page <= $pageCount; $page++) {
            $list = PerfMonth::find()->where('CALC_MONTH=:CALC_MONTH', ['CALC_MONTH' => '202005'])->offset(($page - 1) * $pageSize)->limit($pageSize)->asArray()->all();
            foreach ($list as $every) {
                $userInfo = CalcCache::getUserInfo($every['USER_ID'], $periodNum);
                //更新月业绩的聘级和用户信息中的聘级
                CalcCache::nowMonthPerf($every['USER_ID'], $periodNum, [
                    'EMP_LEVEL' => $every['LAST_EMP_LV']
                ]);

                if ($userInfo['EMP_LV'] != $every['LAST_EMP_LV']) {
                    $userInfo['EMP_LV'] = $every['LAST_EMP_LV'];
                    CalcCache::setUserInfo($every['USER_ID'], $periodNum, $userInfo);
                }

                CalcBonus::updateAll(['LAST_EMP_LV' => $every['LAST_EMP_LV']], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', ['USER_ID' => $every['USER_ID'], 'PERIOD_NUM' => $periodNum]);

                unset($every, $userInfo);
            }
            unset($list);
            echo sprintf("更新【聘级】数据，总页数【%s】，当前页数：【%s】导入成功" . PHP_EOL, $pageCount, $page);

        }
    }

    /**
     * 修正PSS_TOTAL
     */
    public function actionFixPssTotal() {
        $db = \Yii::$app->db;
        $sql = "SELECT COUNT(ID) as allCount FROM AR_USER_PERF_NEW WHERE 1=1 ORDER BY ID ASC";
        $allCountOne = $db->createCommand($sql)->queryOne();
        $pageSize = 1000;
        $pageCount = ceil($allCountOne['allCount']/$pageSize);
        for($page=1;$page<=$pageCount;$page++) {
            echo sprintf('修正PSS_TOTAL，总页数为【%d】，当前页数为【%d】' . PHP_EOL, $pageCount, $page);
            $offset = ($page-1)*$pageSize;
            $listSql = "SELECT * FROM AR_USER_PERF_NEW WHERE 1=1 ORDER BY ID ASC LIMIT {$pageSize} OFFSET {$offset}";
            $list = $db->createCommand($listSql)->queryAll();
            foreach ($list as $every) {
                //更新pss_total
                UserPerf::updateAll(['PV_PSS'=>$every['PV_PSS_TOTAL'], 'PV_PSS_TOTAL'=>$every['PV_PSS_TOTAL']], 'USER_ID=:USER_ID', ['USER_ID'=>$every['USER_ID']]);
                //更新perf_month
                PerfMonth::updateAll(['PV_PSS_TOTAL'=>$every['PV_PSS_TOTAL']], 'USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH', ['USER_ID'=>$every['USER_ID'], 'CALC_MONTH'=>'202006']);

                unset($every);
            }

        }
    }

    public function actionCheckRepairUser($offset, $limit=1000) {
        $allData = CalcCache::getHasRepairPerfUsers($offset, $limit);
        if ($allData) {
            foreach ($allData as $userId) {
                if( $userId === '102239880700104704' ) {
                    echo 'OK' . PHP_EOL;
                }
            }

            $this->actionCheckRepairUser($offset+$limit);
        }

        echo 'END' . PHP_EOL;
    }

    /**
     * 在数据库查询注册的前7人
     * @param int $limit
     */
    public function actionCheckGxCreateAt($limit=7)
    {
        $userId = '110188471594913792';
        $list = UserInfo::findUseDbCalc()->select('USER_ID')->where('USER_ID>:USER_ID', [
            'USER_ID' => $userId,
        ])->orderBy('USER_ID ASC')->limit($limit)->asArray()->all();
        foreach ($list as $every) {
            echo $every['USER_ID'] . PHP_EOL;
        }
    }

    public function actionRelationList($userId) {
        $this->loopRelationParentDo($userId, function ($parent) {
            $parentUid = $parent['PARENT_UID'];
            echo $parentUid . PHP_EOL;
        });
    }

    /**
     * 检测用户服务奖金
     * @param string $userId
     * @param int $periodNum
     * @throws \yii\db\Exception
     */
    public function actionCheckUserBdQyBonus($userId='', $periodNum=125) {
            // 从缓存中获取会员的业绩信息
            $perfData = CalcCache::nowPeriodPerf($userId, $periodNum);
            // 从缓存中获取会员的上期结余业绩信息
            $pervSurplusPerf = CalcCache::surplusPerf($userId, $periodNum);
            // 本期 + 上期结余
            $perfArr = [
                'SURPLUS_1L_ZC' => $perfData['PV_1L_ZC'] + $pervSurplusPerf['SURPLUS_1L_ZC'],
                'SURPLUS_2L_ZC' => $perfData['PV_2L_ZC'] + $pervSurplusPerf['SURPLUS_2L_ZC'],
                'SURPLUS_3L_ZC' => $perfData['PV_3L_ZC'] + $pervSurplusPerf['SURPLUS_3L_ZC'],
                'SURPLUS_4L_ZC' => $perfData['PV_4L_ZC'] + $pervSurplusPerf['SURPLUS_4L_ZC'],
                'SURPLUS_5L_ZC' => $perfData['PV_5L_ZC'] + $pervSurplusPerf['SURPLUS_5L_ZC'],
            ];
            $oriPerfArr = [
                'perfArr' => $perfArr,
                'touchBonus' => 0,
            ];
            // 获取会员的报单级别
            $userBaseInfo = CalcCache::getUserInfo($userId, $periodNum);
            $decLevelConfig = Cache::getDecLevelConfig();
            // 对碰
            $touchBonusArr = $this->touchPerf($oriPerfArr, $perfArr, $userBaseInfo['DEC_LV'], $decLevelConfig);
//            $nowDecLevelConfig = $decLevelConfig[$userBaseInfo['DEC_LV']];
            $touchPerfArr = [];
            foreach ($touchBonusArr['perfArr'] as $keyR => $perfR) {
                $touchPerfArr[$keyR] = $perfR;
            }
            var_dump($touchBonusArr);die;
            // 对碰完成后把结余的业绩存入本期业绩缓存中
            if ($touchBonusArr['touchBonus'] <= 0) return;

            $teamBonus = $touchBonusArr['touchBonus'];
            // 把对碰后的奖金存入缓存中
//            CalcCache::bonus($userId, $periodNum, 'BONUS_QY_BD', $teamBonus, [
//                'reConsumePoints' => 0,
//                'manageTax' => 0,
//                'surplus' => $teamBonus,
//            ]);

            unset($perfData, $pervSurplusPerf, $perfArr, $oriPerfArr, $touchPerfArr, $userBaseInfo, $decLevelConfig, $touchBonusArr, $userId, $nowDecLevelConfig, $teamBonus, $deductData);

    }

    /**
     * 对碰
     * @param array $oriPerfArr
     * @param array $perfArr
     * @param $decLevel
     * @param $decLevelConfig
     * @param $loopTimes
     * @return array
     */
    public function touchPerf(array $oriPerfArr, array $perfArr, $decLevel, $decLevelConfig, $loopTimes=1) {
        $resultArr = $oriPerfArr;
        foreach ($perfArr as $keyT => $perfT) {
            if ($perfT <= 0) {
                unset($perfArr[$keyT]);
            }
        }
        if (count($perfArr) >= 2 && $loopTimes < 6) {
            $nowDecLevelConfig = $decLevelConfig[$decLevel];
            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;
                }
            }
            /*if ($touchAmount > $nowDecLevelConfig['QY_TOUCH_CAP']) {
                $touchAmount = $nowDecLevelConfig['QY_TOUCH_CAP'];
            }*/
            $touchBonus = Tool::formatPrice($touchAmount * $nowDecLevelConfig['QY_PERCENT'] / 100);
//            if ($touchBonus > $nowDecLevelConfig['QY_TOUCH_CAP']) {
//                $resultArr['touchBonus'] += $nowDecLevelConfig['QY_TOUCH_CAP'];
//            } else {
//                $resultArr['touchBonus'] += $touchBonus;
//            }
            $resultArr['touchBonus'] += $touchBonus;

            foreach ($perfArr as $keyR => $perfR) {
                $resultArr['perfArr'][$keyR] = $perfR;
            }
            return $this->touchPerf($resultArr, $perfArr, $decLevel, $decLevelConfig, $loopTimes+1);

        }
        return $resultArr;
    }


    /**
     * 检测用户报单管理奖奖金
     * @param string $userId
     * @param string $parentUid
     * @param int $periodNum
     * @throws \yii\db\Exception
     */
    public function actionCheckUserBdGlBonus($userId='', $parentUid='', $periodNum=125) {
        //会员信息
        $decLevelConfig = Cache::getDecLevelConfig();
        $netWorkParents = Cache::getAllRelationParents($userId);
        $userBaseInfo = CalcCache::getUserInfo($userId, $periodNum);
        $userEmpLevel = $userBaseInfo['EMP_LV'];
        foreach ($netWorkParents as $netWorkParent) {
            echo '父级ID：' . $netWorkParent['PARENT_UID'] . PHP_EOL;
            //自已距顶端的深度减去父级距顶端的深度
            $diffLayer = $netWorkParent['TOP_DEEP'] - $netWorkParent['PARENT_DEEP'];
            if( $diffLayer <= 0) continue;

            //@todo 超过最大代数就跳出本次循环

            //偶数代跳过
            if( $diffLayer % 2 == 0 ) continue;

            // 获取会员的报单级别
            $bonusUserId = $netWorkParent['PARENT_UID'];
            if( !$bonusUserId ) continue;
            if( $bonusUserId != $parentUid ) continue;
            $bonusUserBaseInfo = CalcCache::getUserInfo($bonusUserId, $periodNum);

            $nowDecLevelConfig = $decLevelConfig[$bonusUserBaseInfo['DEC_LV']];
            if( !$nowDecLevelConfig ) continue;
            //推荐人数
            $recNum = $bonusUserBaseInfo['REC_NUM'];
            if( $recNum <= 0 ) continue;
            if( $recNum == 1 ) {
                $maxOddLayer = $nowDecLevelConfig['GL_ODD_DEEP_ONE'];
            }else if( $recNum == 2 ) {
                $maxOddLayer = $nowDecLevelConfig['GL_ODD_DEEP_TWO'];
            }else {
                $maxOddLayer = $nowDecLevelConfig['GL_ODD_DEEP_THREE'];
            }

            //超过代数上限也跳过
            if( $diffLayer >= 2 * $maxOddLayer ) continue;

            $everyLayer = floor(2 * $nowDecLevelConfig['GL_ODD_DEEP_THREE'] / $nowDecLevelConfig['SORT']);
            //多少代
//                    $theLayer = $diffLayer % $everyLayer;
            $theLayerLevel = floor($diffLayer/$everyLayer);
            $parentOddPercentName = sprintf('parentOddPercent_%s', $theLayerLevel);
            if( !isset($this->_sysConfig[$parentOddPercentName]) ) continue;
            $bonusPercent = $this->_sysConfig[$parentOddPercentName]['VALUE'];

            // 从缓存中获取会员的收入信息
            $incomeBonus = CalcCache::bonus($userId, $periodNum);
            $parentOddIncomeFromName = sprintf('parentOddIncomeFrom_%s', $theLayerLevel);
            $parentOddIncomeFrom = explode(',', $this->_sysConfig[$parentOddIncomeFromName]['VALUE']);
            $parentOddIncome = 0;
            foreach ($parentOddIncomeFrom as $incomeType) {
                if( $incomeType === 'TG' ) {
                    $incomeTypeName = sprintf('ORI_BONUS_%s', $incomeType);
                }else {
                    $incomeTypeName = sprintf('ORI_BONUS_%s_BD', $incomeType);
                }
                $incomeTypeValue = $incomeBonus[$incomeTypeName] ?? 0;
                $parentOddIncome += $incomeTypeValue;
                unset($incomeType, $incomeTypeName, $incomeTypeValue);
            }
            unset($parentOddIncomeFrom);
            $manageBonus = Tool::formatPrice($parentOddIncome * $bonusPercent / 100);
            var_dump($manageBonus);die;
            if ($manageBonus <= 0) continue;

            //总金额限制
//            $manageBonus = $this->bonusTotalLimit($manageBonus, $bonusUserId, $recNum, $bonusUserBaseInfo['ZC_AMOUNT']);
//            if( $manageBonus <= 0 ) continue;

            //扣除相应的复消积分和管理费
//            $deductData = $this->deduct($bonusUserId, $manageBonus);

//            CalcCache::bonus($bonusUserId, $periodNum, 'BONUS_GL', $manageBonus, $deductData, CalcCache::FROM_MEANS_BD);

            //管理奖流水
            unset($netWorkParent, $diffLayer, $bonusUserId, $bonusUserBaseInfo, $bonusPercent, $nowDecLevelConfig, $manageBonus, $incomeBonus, $maxOddLayer, $theLayerLevel, $recNum, $parentOddPercentName, $parentOddIncomeFromName, $deductData);

        }

        unset($userId, $userBaseInfo, $userEmpLevel, $netWorkParents, $decLevelConfig);

    }

    /**
     * 修改总业绩
     */
    public function actionModifyPssTotal() {
        $modifyData = [
            'Q08186744' => 600.01,
            'Q62088906' => 150,
            'Q08480433' => 150,
            'Q43506253' => 48.75,
            'Q12863038' => 600.01,
            'Q78680727' => 41.25,
            'Q94839185' => 308265.61,
            'A14938155' => 11206.89,
            'H779051HD' => 162.5,
            'D75201679' => 150,
            'H49297159' => 481.25,
            'H17118288' => 481.25,
            'A12336641' => -160,
            'D18233466' => 157.5,
            'H19657853' => -1320,
            'H17219628' => -120,
            'H10821466' => -1320,
            'H11050788' => -4920,
            'H15532405' => -1320,
            'H65057238' => -360,
            'H49978401' => -720,
            'H17767474' => -1260,
            'F17628577' => -4008,
            'F17072646' => -359.99,
            'F59854958' => -240,
            'F10634375' => -1440,
            'F17425461' => -120,
            'F18852157' => -593,
            'F68846358' => -2301.99,
            'Q14703000' => -120,
            'D17865446' => -112,
            'D16104173' => -119.99,
            'D19426525' => -360,
            'D13146869' => -420,
            'D13336250' => -845,
            'Q16475055' => -120,
            'E19911439' => -159,
            'E17429791' => -166,
            'E14226349' => -240,
            'E16315856' => -480,
            'E18363352' => -240,
            'E18322188' => -120,
            'A19477210' => -120,
            'A13628496791' => -240,
            'A14488417' => -120,
            'A15836950' => -120,
            'E69809425' => -480,
            'D14193606' => -360,
            'D13663861' => -120,
            'D10776466' => -240,
            'D11736447' => -120,
            'D13128139' => -725,
            'D15308257' => -360,
            'D19443335' => -855,
            'H16408887' => -960,
            'H15328699' => -120,
            'H18951571' => -480,
            'H15167279' => -480,
            'H15382316' => -360,
            'H12129027' => -240,
            'H15359261' => -840,
            'H16004849' => -120,
            'H14711148' => -120,
            'H14276238' => -240,
            'H69162532' => -240,
            'H93297042' => -4680,
            'H88875817' => -120,
            'H11847679' => -120,
            'F90795660' => -3768,
            'F17797628' => -840,
            'F17546019' => -473,
            'F15803008' => -2062,
            'H10394296' => -960,
            'E17839915' => -166,
            'E13466446' => -240,
            'A16594718' => -240,
            'A19671826' => -120,
            'A15198548' => -120,
            'A51726927' => -2635.98,
            'H11036379' => -240,
            'H12907432' => -817.99,
            'H17973140' => -960,
            'H12666892' => -600,
            'H11866173' => -2460,
            'E10658077' => -120,
            'E17573755' => -480,
            'E45944014' => -1184,
            'E15960537' => -240,
            'E12683263' => -592,
            'E11002878' => -360,
            'E10602731' => -120,
            'A17081891' => -120,
            'A18717229' => -835.98,
            'H11097065' => -1200,
            'H19578891' => -1080,
            'H12505489' => -120,
            'H10746043' => -960,
            'E12569967' => -120,
            'H11295941' => -1666,
            'H59287202' => -120,
            'H18132610' => -120,
            'H18113300' => -240,
            'H19096880' => -120,
            'H12050104' => -480,
            'H10655472' => -3000,
            'H12439274' => -720,
            'F31467862' => -3528,
            'F29042730' => -360,
            'F10062708' => -982,
            'F60226072' => -120,
            'E13291482' => -120,
            'D13390146' => -360,
            'D15369301' => -376,
            'D10058595' => -240,
            'H17368844' => -120,
            'H17673492' => -360,
            'H40420622' => -120,
            'H37612456' => -240,
            'H16239634' => -720,
            'H19200443' => -2760,
            'F10693156' => -3407.99,
            'F15664716' => -360,
            'F14542850' => -120,
            'F15821274' => -600,
            'A14314525' => -120,
            'A16968827' => -480,
            'D19551159' => -240,
            'D17359769' => -120,
            'D17464140' => -240,
            'D12103432' => -128,
            'H11158785' => -578,
            'H11304078' => -120,
            'H38384841' => -120,
            'H15263058' => -120,
            'H44636655' => -240,
            'H13540567' => -720,
            'H11372262' => -2160,
            'H95402009' => -1260,
            'H59876727' => -960,
            'F16723562' => -819.99,
            'F14010022' => -2468,
            'F16485738' => -360,
            'F17398416' => -360,
            'F11668609' => -120,
            'E14666737' => -120,
            'E18812880' => -213,
            'D13299101' => -240,
            'D18768019' => -120,
            'D18898064' => -128,
            'D16748142' => -240,
            'H19464479' => -1080,
            'H11879978' => -240,
            'H18864434' => -840,
            'H15868186' => -120,
            'H68332692' => -720,
            'H50691564' => -2160,
            'F17368654' => -2348,
            'F17121859' => -699.99,
            'H93093611' => -600,
            'A17962339' => -120,
            'A18358406' => -480,
            'D15539120' => -240,
            'D19181661' => -240,
            'H17928312' => -960,
            'H14358188' => -840,
            'H10699566' => -1666,
            'H15912596' => -240,
            'H31173575' => -480,
            'H19433676' => -240,
            'H17288092' => -360,
            'A17816239' => -120,
            'A10678307' => -360,
            'H23275366' => -720,
            'H12591081' => -240,
            'H16504568' => -840,
            'H16531555' => -480,
            'H38486089' => -600,
            'H83574838' => -1320,
            'H18357186' => -120,
            'H16049391' => -120,
            'H16379925' => -240,
            'F13307818' => -120,
            'F11580708' => -1868,
            'F11108484' => -120,
            'H13915722' => -360,
            'D15805087' => -120,
            'D15467159' => -240,
            'H10366600' => -720,
            'H63372506' => -120,
            'H14710441' => -840,
            'H10090408' => -1666,
            'H33154162' => -360,
            'H15358396' => -480,
            'H72700605' => -840,
            'H12827073' => -480,
            'F15846968' => -1748,
            'H16660022' => -360,
            'D11624328' => -240,
            'H11552847' => -1666,
            'H19166726' => -240,
            'H14364498' => -480,
            'H17797668' => -600,
            'H12452235' => -480,
            'H18592203' => -120,
            'F14890926' => -1628,
            'D13778545' => -240,
            'H11066019' => -600,
            'H11306623' => -120,
            'H16157527' => -840,
            'H13701187' => -240,
            'H18248205' => -600,
            'H17907648' => -840,
            'H13779328' => -1666,
            'H19450811' => -240,
            'H17008421' => -480,
            'H16387500' => -840,
            'H91950177' => -1666,
            'H18592565' => -240,
            'H77879934' => -1666,
            'H13711477' => -120,
            'H13833502' => -240,
            'H12286615' => -240,
            'F17783334' => -1148,
            'D11204865' => -240,
            'H17393209' => -480,
            'H17832251' => -840,
            'H10164361' => -240,
            'H19291917' => -120,
            'H16253624' => -720,
            'H15216330' => -120,
            'F12562440' => -680,
            'D15177935' => -240,
            'H17439829' => -840,
            'H19424150' => -480,
            'H13125893' => -840,
            'H24399895' => -840,
            'H10159130' => -840,
            'H11682345' => -840,
            'H17826076' => -840,
            'H10656939' => -840,
            'H17396420' => -840,
            'H10514419' => -840,
            'H16934767' => -840,
            'H14181865' => -840,
            'H16130940' => -840,
            'H17608191' => -840,
            'H11569007' => -840,
            'H14576782' => -840,
            'H15577686' => -840,
            'H11753266' => -840,
            'H12284905' => -720,
            'H15872474' => -720,
            'H13200796' => -600,
            'H15478592' => -480,
            'H19659132' => -480,
            'D12199046' => 503.75,
            'D19795156' => 155,
            'D15436866' => 155,
            'H49758932' => -360,
            'H16852727' => -360,
            'H15064959' => -360,
            'H15043547' => -360,
            'H14896153' => -360,
            'H12062745' => -360,
            'H11705904' => -360,
            'H44310375' => -360,
            'H17570490' => -360,
            'H15866731' => -360,
            'H10082397' => -360,
            'H17197020' => -360,
            'H96244925' => -360,
            'H18278522' => -360,
            'H16921167' => -360,
            'H11746826' => -360,
            'H14231961' => -360,
            'H17528587' => -360,
            'H19118260' => -360,
            'H12448611' => -360,
            'H16502115' => -360,
            'H66096080' => -360,
            'H13333591' => -360,
            'H12704168' => -360,
            'H10822555' => -360,
            'H27825190' => -360,
            'H62054512' => -360,
            'H18450323' => -360,
            'H16863190' => -360,
            'H11241039' => -360,
            'H15641979' => -360,
            'H15453609' => -360,
            'H88069590' => -360,
            'H17085313' => -360,
            'H13018948' => -360,
            'H12503677' => -360,
            'H46274824' => -360,
            'H50970678' => -360,
            'H15757860' => -360,
            'H65559852' => -360,
            'H15888980' => -360,
            'H18669651' => -240,
            'H12966470' => -240,
            'H15605405' => -240,
            'H13302229' => -240,
            'H19988098' => -240,
            'H19139717' => -240,
            'H17419145' => -240,
            'H15179291' => -240,
            'H15024184' => -240,
            'H13577736' => -240,
            'D13347854' => 200,
            'H16105967' => -240,
            'H10292657' => -240,
            'H14109018' => -240,
            'H15892232' => -240,
            'H10659498' => -240,
            'H18383896' => -240,
            'H14304440' => -240,
            'H97331452' => -240,
            'H12055085' => -240,
            'H87950486' => -240,
            'H13902912' => -240,
            'H14311006' => -240,
            'H89043517' => -240,
            'H20947501' => -240,
            'H10466894' => -240,
            'H19591200' => -240,
            'H19920650' => -240,
            'H10809534' => -240,
            'H13081445' => -240,
            'H19304638' => -240,
            'H17167739' => -240,
            'H13575379' => -240,
            'H19106582' => -240,
            'H17782450' => -240,
            'H11446432' => -240,
            'H15058672' => -240,
            'H10535417' => -240,
            'H92052401' => -240,
            'H11517133' => -240,
            'H80093994' => -240,
            'H11956092' => -240,
            'H17165790' => -240,
            'H11424567' => -240,
            'H19560581' => -240,
            'H19423232' => -240,
            'H16184781' => -240,
            'H10780996' => -240,
            'H12168567' => -240,
            'H69093228' => -240,
            'H10849787' => -240,
            'D18829108' => 200,
            'D18507164' => 347.5,
            'Q73338908' => 150,
            'Q69472907' => 150
        ];
        foreach ($modifyData as $username => $modifyValue) {
            $oneUser = User::find()->select(['ID', 'USER_NAME'])->where('USER_NAME=:USER_NAME', ['USER_NAME'=>$username])->asArray()->one();
            if( !$oneUser ) {
                echo sprintf('用户%s不存在' . PHP_EOL, $username);
                continue;
            }
            $realModifyValue = (-1) * $modifyValue;
            UserPerf::updateAllCounters(['PV_PSS_TOTAL'=>$realModifyValue], 'USER_ID=:USER_ID', ['USER_ID'=>$oneUser['ID']]);
            echo sprintf('用户%s变化业绩为：%s' . PHP_EOL, $username, $realModifyValue);

            unset($username, $modifyValue, $oneUser, $realModifyValue);
        }
    }

    public function actionGetYcData($userId, $periodNum=132) {
        $ycBonusData = CalcCache::getYCBonusList($userId, $periodNum);
        if( $ycBonusData ) {
            if( $ycBonusData['fromData'] ) {
                foreach ($ycBonusData['fromData'] as $every) {
                    //fromPvPcs fromUid
                    $fromBaseInfo = CalcCache::getUserInfo($every['fromUid'], $periodNum);
                    echo sprintf("来源用户名：%s,来源用户pv：%s" . PHP_EOL, $fromBaseInfo['USER_NAME'], $every['fromPvPcs']);
                }
            }
        }
    }

    /**
     * 计算某期复消现金金额
     */
    public function actionCalcPeriodFxCash() {
        $periodNumList = [146];
        foreach ($periodNumList as $periodNum) {
            $this->_calcPeriodFxCash($periodNum);
        }
    }

    private function _calcPeriodFxCash($periodNum) {
        //复消订单
        $pageSize = 1000;
        $allCount = Order::findUseDbCalc()->where("PERIOD_NUM=:PERIOD_NUM AND IS_DELETE=0 AND ORDER_TYPE=:ORDER_TYPE", [':PERIOD_NUM' => $periodNum, ':ORDER_TYPE'=>DeclarationForm::TYPE_FX])->count('ID');
        $pageCount = ceil($allCount/$pageSize);
        for ($page=1;$page<=$pageCount;$page++) {
            echo sprintf('期数：%s，复消订单：当前页数%s，总页数：%s' . PHP_EOL, $periodNum, $page, $pageCount);

            $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", [':PERIOD_NUM' => $periodNum, ':ORDER_TYPE'=>DeclarationForm::TYPE_FX])->orderBy('CREATED_AT DESC,ID DESC')->offset(($page-1)*$pageSize)->limit($pageSize)->asArray()->all();
            if( $allData ) {
                foreach ($allData as $data) {
                    //如果支付方式是现金，那么实际业绩是支付PV的50%
                    if ($data['PAY_TYPE'] === 'cash') {
                        PerfPeriod::updateAll([
                            'FX_AMOUNT_CASH'=>new Expression('FX_AMOUNT_CASH+' . $data['ORDER_AMOUNT'])
                        ], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', ['USER_ID'=>$data['USER_ID'], 'PERIOD_NUM'=>$periodNum]);
                    }
                    unset($data);
                }
            }

            unset($allData);
        }
        unset($allCount, $pageCount, $page);
        //导入的复消订单
        $allCount = OrderShop::findUseDbCalc()->where("PERIOD_NUM=:PERIOD_NUM AND IS_DELETE=0 AND ORDER_TYPE=:ORDER_TYPE", [':PERIOD_NUM' => $periodNum, ':ORDER_TYPE'=>DeclarationForm::TYPE_FX])->count('ID');
        $pageCount = ceil($allCount/$pageSize);
        for ($page=1;$page<=$pageCount;$page++) {
            echo sprintf('期数：%s，导入订单：当前页数%s，总页数：%s' . PHP_EOL, $periodNum, $page, $pageCount);
            $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", [':PERIOD_NUM' => $periodNum, ':ORDER_TYPE'=>DeclarationForm::TYPE_FX])->orderBy('CREATED_AT DESC,ID DESC')->offset(($page-1)*$pageSize)->limit($pageSize)->asArray()->all();
            if( $allData ) {
                foreach ($allData as $data) {
                    //如果支付方式是现金，那么实际业绩是支付PV的50%
                    if ($data['PAY_TYPE'] === 'cash') {
                        PerfPeriod::updateAll([
                            'FX_AMOUNT_CASH'=>new Expression('FX_AMOUNT_CASH+' . $data['ORDER_AMOUNT'])
                        ], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', ['USER_ID'=>$data['USER_ID'], 'PERIOD_NUM'=>$periodNum]);
                    }

                    unset($data);
                }
            }

            unset($allData);
        }

        unset($allCount, $pageCount, $page);
    }


    public function actionCheckGxNextFive() {
        $userId = '76190398896279552';
        $periodNum = 160;
        $bonusUserData = [];
        $sysConfig = Cache::getSystemConfig();
        $bonusPercentTwo = $sysConfig['sharePercent']['VALUE'] / 100;

        // 从缓存中获取会员的收入信息
        $incomeBonus = CalcCache::bonus($userId, $periodNum);
        $lastTwoIncome = $incomeBonus['ORI_BONUS_QY_BD'] ?? 0;
        unset($lastTwoIncome);

        $nextFiveIncome = $incomeBonus['ORI_BONUS_QY_BD'] ?? 0;
        $shareBonusTwo = $nextFiveIncome * $bonusPercentTwo;
        unset($nextFiveIncome);

        //找到下5代(安置网) 紧缩 相对偶数层2、4、6、8、10层
        if( $shareBonusTwo > 0 ) {
            $validDeep = 1;
            $this->loopNetworkParentDo($userId, function ($parent) use ($userId, $shareBonusTwo,$periodNum,  &$validDeep, &$bonusUserData) {
                if ( $validDeep % 2 === 0 ) {
                    $bonusUserData[] = [
                        'bonusUid' => $parent['PARENT_UID'],
                        'bonus' => $shareBonusTwo
                    ];
                }
                //判断$parent是否有首单团队奖
                $parentBonus = CalcCache::bonus($parent['PARENT_UID'], $periodNum);
                if( $parentBonus['ORI_BONUS_QY_BD'] > 0 ) {//有效层
                    $validDeep += 1;
                }

                unset($parent, $parentBonus);

                if ( $validDeep >= 11 ) {
                    return 1;
                }
            });

            unset($validDeep);
        }
//        if ( !$bonusUserData ) return;
        var_dump($bonusUserData);die;


    }

    public function actionCheckGxLastTwo() {
        $userId = '76189391281852416';
        $periodNum = 160;
        $bonusUserData = [];
        $bonusPercentOne = 5 / 100;

        // 从缓存中获取会员的收入信息
        $incomeBonus = CalcCache::bonus($userId, $periodNum);
        $lastTwoIncome = $incomeBonus['ORI_BONUS_QY_BD'] ?? 0;
        $shareBonusOne = $lastTwoIncome * $bonusPercentOne;
        unset($lastTwoIncome);
        //找到上2代 新增个人+推荐团队业绩 加权平均分配 这个奖
        if( $shareBonusOne > 0) {
            $bonusUserList = CalcCache::getShareBonusOneRelation($userId, $periodNum);
            if( $bonusUserList ) {
                $bonusUserTotalPerf = 0;
                $bonusUserRealList = [];
                foreach ($bonusUserList as $bonusUserId) {
                    //查看该用户的个人业绩和团队新增业绩总和
                    $nowPeriodData = CalcCache::nowPeriodPerf($bonusUserId, $periodNum);
                    //本期新增业绩
                    $bonusUserPerf = $nowPeriodData['PV_PCS'] + $nowPeriodData['PV_PSS'];
                    if ($bonusUserPerf <= 0) {
                        unset($bonusUserId, $nowPeriodData, $bonusUserPerf);
                        continue;
                    }

                    $bonusUserTotalPerf += $bonusUserPerf;
                    $bonusUserRealList[] = [
                        'bonusUserId' => $bonusUserId,
                        'bonusUserPerf' => $bonusUserPerf
                    ];

                    unset($bonusUserId, $nowPeriodData, $bonusUserPerf);
                }
                unset($bonusUserList);

                foreach ($bonusUserRealList as $everyData) {
                    $bonusUserData[] = [
                        'bonusUid' => $everyData['bonusUserId'],
                        'bonus' => $shareBonusOne * $everyData['bonusUserPerf'] / $bonusUserTotalPerf
                    ];
                    unset($everyData);
                }

                unset($bonusUserRealList);
            }
        }

        var_dump($bonusUserData);die;
    }

    public function actionCheckGxMonthData() {
        //查看是否复消300
        $userId = '76189026280935424';
        $periodNum = 162;
        $sysConfig = Cache::getSystemConfig();
        $monthPerfData = CalcCache::nowMonthPerf($userId, $periodNum);
        $fxPvStatus = $monthPerfData['PV_PCS_FX'] >= $sysConfig['monthPcsPvFxCondition']['VALUE'];
        if ( $fxPvStatus ) {//加上本期和往期的共享和管理奖
            $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'=>'202104'])->asArray()->one();
            $bonus = CalcCache::bonus($userId, $periodNum);
            $bonusGxSum = $monthSumData['BONUS_GX_SUM'] ?? 0;
            $bonusGlSum = $monthSumData['BONUS_GL_SUM'] ?? 0;
            $realBonusGx = $bonusGxSum + $bonus['BONUS_GX'];
            $realBonusGl = $bonusGlSum + $bonus['BONUS_GL'];
            var_dump($realBonusGx, $realBonusGl);die;
        }

        echo "..OK" . PHP_EOL;
    }

    /**
     * 根据奖金表中的记录
     */
    public function actionAddMonthBonusUser($calcMonth) {
//        $calcMonth = '202104';
        $pageSize = 1000;
        $allCount = CalcBonus::find()->where('CALC_MONTH=:CALC_MONTH', [
            'CALC_MONTH' => $calcMonth
        ])->asArray()->count();
        $pageCount = ceil($allCount/$pageSize);
        for($page=1;$page<=$pageCount;$page++) {
            echo sprintf('【%d】月奖金用户，总页数为【%d】，当前页数为【%d】' . PHP_EOL, $calcMonth, $pageCount, $page);
            $insertDataBonusUser = [];
            $offset = ($page-1)*$pageSize;
            $listData = CalcBonus::find()->select('USER_ID,CALC_MONTH,PERIOD_NUM,ORI_BONUS_GX,ORI_BONUS_GL')->where('CALC_MONTH=:CALC_MONTH', [
                'CALC_MONTH' => $calcMonth
            ])->offset($offset)->limit($pageSize)->asArray()->all();
            foreach ($listData as $everyData) {

                if( $everyData['ORI_BONUS_GX'] == 0 && $everyData['ORI_BONUS_GL'] == 0 ) continue;

                $insertDataBonusUser[] = [
                    'ID' => SnowFake::instance()->generateId(),
                    'USER_ID' => $everyData['USER_ID'],
                    'CALC_MONTH' => $everyData['CALC_MONTH'],
                    'PERIOD_NUM' => $everyData['PERIOD_NUM'],
                    'CREATED_AT' => Date::nowTime()
                ];
            }

            if( $insertDataBonusUser ) CalcMonthBonusUser::batchInsert($insertDataBonusUser);
            unset($listData, $insertDataBonusUser);
        }

    }

    /**
     * 后续计算共享和管理奖
     * @param $tableName
     * @param $toPeriod
     * @throws \yii\db\Exception
     */
    public function actionAfterCalcBonusGxAndGl($tableName, $toPeriod) {
        $db = \Yii::$app->db;
        $fromTableName = sprintf("AR_CALC_BONUS_%s", $tableName);
        $sql = "SELECT COUNT(ID) as allCount FROM {$fromTableName} WHERE PERIOD_NUM={$toPeriod} ORDER BY ID ASC";
        $allCountOne = $db->createCommand($sql)->queryOne();
        $pageSize = 1000;
        $pageCount = ceil($allCountOne['allCount']/$pageSize);
        for($page=1;$page<=$pageCount;$page++) {
            echo sprintf('同步【%d】期的数据，总页数为【%d】，当前页数为【%d】' . PHP_EOL, $toPeriod, $pageCount, $page);
            $offset = ($page-1)*$pageSize;
            $listSql = "SELECT * FROM {$fromTableName} WHERE PERIOD_NUM={$toPeriod} ORDER BY ID ASC LIMIT {$pageSize} OFFSET {$offset}";
            $list = $db->createCommand($listSql)->queryAll();
            foreach ($list as $every) {
                //判断该会员在AR_CALC_BONUS 表中 对应期数是否有相应的数据，有就更新，没有就插入。
                $one = CalcBonus::find()->where('USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', ['USER_ID'=>$every['USER_ID'], 'PERIOD_NUM'=>$toPeriod])->asArray()->one();
                if( $one ) {
                    CalcBonus::updateAll([
                        'BONUS_GX' => $every['BONUS_GX'],
                        'ORI_BONUS_GX' => $every['ORI_BONUS_GX'],
                        'REAL_BONUS_GX' => $every['REAL_BONUS_GX'],
                        'BONUS_GL' => $every['BONUS_GL'],
                        'ORI_BONUS_GL' => $every['ORI_BONUS_GL'],
                        'REAL_BONUS_GL' => $every['REAL_BONUS_GL'],
                    ], 'ID=:ID', ['ID'=>$one['ID']]);
                }else {
                    $insertData = $every;
                    $insertData['ID'] = SnowFake::instance()->generateId();
                    $insertData['IS_SENT'] = 1;
                    $insertData['SENT_AT'] = Date::nowTime();
                    CalcBonus::insertOne($insertData);
                    unset($insertData);
                }
                unset($every, $one);
            }
        }
    }

    /**
     * 补发$fromPeriod 共享和管理实发奖金
     * @param $fromPeriod
     * @throws Exception
     * @throws \yii\db\Exception
     */
    public function actionSendBonusGxAndGl($fromPeriod)
    {
        $allCount = CalcBonus::find()->where('PERIOD_NUM=:PERIOD_NUM', ['PERIOD_NUM'=>$fromPeriod])->asArray()->count(1);
        $pageSize = 1000;
        $pageCount = ceil($allCount/$pageSize);
        for($page=1;$page<=$pageCount;$page++) {
            echo sprintf('补发【%d】期共享奖金和管理奖金，总页数为【%d】，当前页数为【%d】' . PHP_EOL, $fromPeriod, $pageCount, $page);
            $offset = ($page-1)*$pageSize;
            $pageList = CalcBonus::find()->select(['USER_ID', 'REAL_BONUS_GX', 'REAL_BONUS_GL'])->where('PERIOD_NUM=:PERIOD_NUM', ['PERIOD_NUM'=>$fromPeriod])->offset($offset)->limit($pageSize)->asArray()->all();
            foreach ($pageList as $everyData) {
                $sendBonus = $everyData['REAL_BONUS_GX'] + $everyData['REAL_BONUS_GL'];
                if( $sendBonus <= 0 ) {
                    unset($everyData, $sendBonus);
                    continue;
                }
                Balance::changeUserBonus($everyData['USER_ID'], 'bonus', $sendBonus, [
                    'REMARK' => 'From ' . $fromPeriod . '期补发共享和管理奖',
                    'PERIOD_NUM' => $fromPeriod,
                    'DEAL_TYPE_ID' => DealType::BONUS_SEND,
                ]);

                unset($everyData, $sendBonus);
            }
        }
    }

    public function actionCheckGxMinPv() {
        $userId = '76190155484041216';
        $periodNum = 160;
        $bonusCalc = BonusCalc::instance();
        $bonusCalc->setPeriodNum($periodNum);
        $rt = $bonusCalc->checkSmallMarketPerf($userId);

        var_dump($rt);

        return 'ok' . PHP_EOL;
    }

    /**
     * 同步VIP奖
     * @param $tableName
     * @param $toPeriod
     * @throws \yii\db\Exception
     */
    public function actionAfterCalcBonusVip($tableName, $toPeriod) {
        $db = \Yii::$app->db;
        $fromTableName = sprintf("AR_CALC_BONUS_%s", $tableName);
        $sql = "SELECT COUNT(ID) as allCount FROM {$fromTableName} WHERE PERIOD_NUM={$toPeriod} ORDER BY ID ASC";
        $allCountOne = $db->createCommand($sql)->queryOne();
        $pageSize = 1000;
        $pageCount = ceil($allCountOne['allCount']/$pageSize);
        for($page=1;$page<=$pageCount;$page++) {
            echo sprintf('同步【%d】期的VIP数据，总页数为【%d】，当前页数为【%d】' . PHP_EOL, $toPeriod, $pageCount, $page);
            $offset = ($page-1)*$pageSize;
            $listSql = "SELECT * FROM {$fromTableName} WHERE PERIOD_NUM={$toPeriod} ORDER BY ID ASC LIMIT {$pageSize} OFFSET {$offset}";
            $list = $db->createCommand($listSql)->queryAll();
            foreach ($list as $every) {
                //判断该会员在AR_CALC_BONUS 表中 对应期数是否有相应的数据，有就更新，没有就插入。
                $one = CalcBonus::find()->where('USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', ['USER_ID'=>$every['USER_ID'], 'PERIOD_NUM'=>$toPeriod])->asArray()->one();
                if( $one ) {
                    CalcBonus::updateAll([
                        'BONUS_VIP' => $every['BONUS_VIP'],
                        'ORI_BONUS_VIP' => $every['ORI_BONUS_VIP'],
                    ], 'ID=:ID', ['ID'=>$one['ID']]);
                }else {
                    $insertData = $every;
                    $insertData['ID'] = SnowFake::instance()->generateId();
                    $insertData['IS_SENT'] = 1;
                    $insertData['SENT_AT'] = Date::nowTime();
                    CalcBonus::insertOne($insertData);
                    unset($insertData);
                }
                unset($every, $one);
            }
        }
    }

    /**
     * 补发VIP奖
     * @param $fromPeriod
     * @throws Exception
     * @throws \yii\db\Exception
     */
    public function actionSendBonusVip($fromPeriod)
    {
        $allCount = CalcBonus::find()->where('PERIOD_NUM=:PERIOD_NUM', ['PERIOD_NUM'=>$fromPeriod])->asArray()->count(1);
        $pageSize = 1000;
        $pageCount = ceil($allCount/$pageSize);
        for($page=1;$page<=$pageCount;$page++) {
            echo sprintf('补发【%d】期VIP奖金，总页数为【%d】，当前页数为【%d】' . PHP_EOL, $fromPeriod, $pageCount, $page);
            $offset = ($page-1)*$pageSize;
            $pageList = CalcBonus::find()->select(['USER_ID', 'BONUS_VIP', 'ORI_BONUS_VIP'])->where('PERIOD_NUM=:PERIOD_NUM', ['PERIOD_NUM'=>$fromPeriod])->offset($offset)->limit($pageSize)->asArray()->all();
            foreach ($pageList as $everyData) {
                $sendBonus = $everyData['BONUS_VIP'];
                if( $sendBonus <= 0 ) {
                    unset($everyData, $sendBonus);
                    continue;
                }
                Balance::changeUserBonus($everyData['USER_ID'], 'bonus', $sendBonus, [
                    'REMARK' => 'From ' . $fromPeriod . '期补发VIP奖',
                    'PERIOD_NUM' => $fromPeriod,
                    'DEAL_TYPE_ID' => DealType::BONUS_SEND,
                ]);

                unset($everyData, $sendBonus);
            }
        }
    }

    /**
     * 补发复消积分对应的奖金
     * @param $calcMonth
     * @throws Exception
     * @throws \yii\db\Exception
     */
    public function actionSendReConsumePoints($calcMonth) {
        $pageSize = 1000;
        $allCount = CalcBonus::find()->where('CALC_MONTH=:CALC_MONTH', [
            'CALC_MONTH' => $calcMonth
        ])->groupBy('USER_ID')->orderBy('USER_ID DESC')->count();
        $pageCount = ceil($allCount/$pageSize);
        for($page=1;$page<=$pageCount;$page++) {
            echo sprintf('【%d】补发复消积分，总页数为【%d】，当前页数为【%d】' . PHP_EOL, $calcMonth, $pageCount, $page);
            $offset = ($page-1)*$pageSize;
            $list = CalcBonus::find()->select('USER_ID,SUM(ORI_BONUS_GX) AS ORI_BONUS_GX_SUM,SUM(ORI_BONUS_GL) AS ORI_BONUS_GL_SUM,SUM(REAL_BONUS_GX) AS REAL_BONUS_GX_SUM,SUM(REAL_BONUS_GL) AS REAL_BONUS_GL_SUM')->where('CALC_MONTH=:CALC_MONTH', [
                'CALC_MONTH' => $calcMonth
            ])->groupBy('USER_ID')->orderBy('USER_ID DESC')->offset($offset)->limit($pageSize)->asArray()->all();
            foreach ($list as $everyData) {
                //计算出实发共享奖扣除的积分和管理奖扣除的积分
                $userReconsumePoints = 0;
                if( $everyData['ORI_BONUS_GX_SUM'] > 0 ) {
                    $manageGx = $everyData['ORI_BONUS_GX_SUM'] * 5 / 100;
                    $gxReconsumePoints = $everyData['ORI_BONUS_GX_SUM'] - $manageGx - $everyData['REAL_BONUS_GX_SUM'];
                    if( $gxReconsumePoints > 0 ) $userReconsumePoints += $gxReconsumePoints;

                    unset($manageGx, $gxReconsumePoints);
                }

                if( $everyData['ORI_BONUS_GL_SUM'] > 0 ) {
                    $manageGL = $everyData['ORI_BONUS_GL_SUM'] * 5 / 100;
                    $glReconsumePoints = $everyData['ORI_BONUS_GL_SUM'] - $manageGL - $everyData['REAL_BONUS_GL_SUM'];
                    if( $glReconsumePoints > 0 ) $userReconsumePoints += $glReconsumePoints;

                    unset($manageGL, $glReconsumePoints);
                }

                if( $userReconsumePoints <= 0 ) continue;

                $all = FlowBonus::find()->where('USER_ID=:USER_ID AND REMARK=:REMARK', ['USER_ID'=>$everyData['USER_ID'], 'REMARK' => 'From162期补发复消积分对应的奖金'])->asArray()->all();

                if( $all ) {
                    $countAll = count($all);
                    if( $countAll > 1 ) {
                        array_pop($all);
                        foreach ($all as $one) {
                            $oneBonus = (-1) * Tool::formatPrice($one['AMOUNT']);
                            Balance::changeUserBonus($one['USER_ID'], 'bonus', $oneBonus, [
                                'REMARK' => 'From162期撤消重复补发复消积分对应的奖金',
                                'PERIOD_NUM' => 162,
                                'DEAL_TYPE_ID' => DealType::BONUS_SEND,
                            ]);

                            unset($one, $oneBonus);
                        }
                    }
                }else {
                    //发放复消积分金额的奖金
                    Balance::changeUserBonus($everyData['USER_ID'], 'bonus', $userReconsumePoints, [
                        'REMARK' => 'From162期补发复消积分对应的奖金',
                        'PERIOD_NUM' => 162,
                        'DEAL_TYPE_ID' => DealType::BONUS_SEND,
                    ]);
                }


                unset($everyData, $userReconsumePoints, $all);
            }
        }
    }

    /**
     * 清除某一期结算缓存
     * @param $periodNum
     */
    public function actionClearPeriodCalcCache($periodNum) {
        CalcCache::clearAll($periodNum);
    }


    public function actionDeleteSendPoints() {
        $pageSize = 1000;
        $allCount = FlowBonus::find()->where('PERIOD_NUM=162 AND REMARK=:REMARK', ['REMARK' => 'From162期补发复消积分对应的奖金'])->count(1);
        $pageCount = ceil($allCount/$pageSize);
        for($page=1;$page<=$pageCount;$page++) {
            echo sprintf('【%d】撤消补发复消积分，总页数为【%d】，当前页数为【%d】' . PHP_EOL, 162, $pageCount, $page);
            $offset = ($page-1)*$pageSize;
            $list = FlowBonus::find()->where('PERIOD_NUM=162 AND REMARK=:REMARK', ['REMARK' => 'From162期补发复消积分对应的奖金'])->offset($offset)->limit($pageSize)->asArray()->all();
            foreach ($list as $everyData) {
                //查询金额是否足够
                $bonus = Tool::formatPrice($everyData['AMOUNT']);
                $useBonus = UserBonus::find()->where('USER_ID=:USER_ID', ['USER_ID'=>$everyData['USER_ID']])->asArray()->one();
                if( $useBonus['BONUS'] <  $bonus ) {
                    echo $everyData['USER_ID'] . PHP_EOL;
                }
//                $bonus = (-1) * $everyData['AMOUNT'];
//                Balance::changeUserBonus($everyData['USER_ID'], 'bonus', $bonus, [
//                    'REMARK' => 'From162期撤消重复补发复消积分对应的奖金',
//                    'PERIOD_NUM' => 162,
//                    'DEAL_TYPE_ID' => DealType::BONUS_SEND,
//                ]);
                unset($bonus);
            }
        }
    }

    /**
     * 补发其它期奖金不正确的脚本
     * @param $tableName
     * @param $toPeriod
     * @throws Exception
     * @throws \yii\db\Exception
     */
    public function actionAddOtherPeriodGXAndGl($tableName, $toPeriod) {
        $db = \Yii::$app->db;
        $fromTableName = sprintf("AR_CALC_BONUS_%s", $tableName);
        $sql = "SELECT COUNT(ID) as allCount FROM {$fromTableName} WHERE PERIOD_NUM={$toPeriod} ORDER BY ID ASC";
        $allCountOne = $db->createCommand($sql)->queryOne();
        $pageSize = 1000;
        $pageCount = ceil($allCountOne['allCount']/$pageSize);
        for($page=1;$page<=$pageCount;$page++) {
            echo sprintf('同步【%d】期的数据，总页数为【%d】，当前页数为【%d】' . PHP_EOL, $toPeriod, $pageCount, $page);
            $offset = ($page-1)*$pageSize;
            $listSql = "SELECT * FROM {$fromTableName} WHERE PERIOD_NUM={$toPeriod} ORDER BY ID ASC LIMIT {$pageSize} OFFSET {$offset}";
            $list = $db->createCommand($listSql)->queryAll();
            foreach ($list as $every) {
                //判断该会员在AR_CALC_BONUS 表中 对应期数是否有相应的数据，有就更新，没有就插入。
                $one = CalcBonus::find()->where('USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', ['USER_ID'=>$every['USER_ID'], 'PERIOD_NUM'=>$toPeriod])->asArray()->one();
                if( !$one ) {
                    $insertData = $every;
                    $insertData['ID'] = SnowFake::instance()->generateId();
                    $insertData['IS_SENT'] = 1;
                    $insertData['SENT_AT'] = Date::nowTime();
                    CalcBonus::insertOne($insertData);
                    unset($insertData);

                    //发对应的奖金
                    $sendBonus = $every['REAL_BONUS_GX'] + $every['REAL_BONUS_GL'];
                    if( $sendBonus <= 0 ) {
                        unset($sendBonus);
                        continue;
                    }

                    //计算复消积分
                    $oldOne = CalcBonus::find()->select('USER_ID,SUM(ORI_BONUS_GX) AS ORI_BONUS_GX_SUM,SUM(ORI_BONUS_GL) AS ORI_BONUS_GL_SUM,SUM(REAL_BONUS_GX) AS REAL_BONUS_GX_SUM,SUM(REAL_BONUS_GL) AS REAL_BONUS_GL_SUM')->where('USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH', ['USER_ID'=>$every['USER_ID'], 'CALC_MONTH'=>202104])->asArray()->one();
//计算出实发共享奖扣除的积分和管理奖扣除的积分
                    $userReconsumePoints = 0;
                    if( $oldOne['ORI_BONUS_GX_SUM'] > 0 ) {
                        $manageGx = $oldOne['ORI_BONUS_GX_SUM'] * 5 / 100;
                        $gxReconsumePoints = $oldOne['ORI_BONUS_GX_SUM'] - $manageGx - $oldOne['REAL_BONUS_GX_SUM'];
                        if( $gxReconsumePoints > 0 ) $userReconsumePoints += $gxReconsumePoints;

                        unset($manageGx, $gxReconsumePoints);
                    }

                    if( $oldOne['ORI_BONUS_GL_SUM'] > 0 ) {
                        $manageGL = $oldOne['ORI_BONUS_GL_SUM'] * 5 / 100;
                        $glReconsumePoints = $oldOne['ORI_BONUS_GL_SUM'] - $manageGL - $oldOne['REAL_BONUS_GL_SUM'];
                        if( $glReconsumePoints > 0 ) $userReconsumePoints += $glReconsumePoints;

                        unset($manageGL, $glReconsumePoints);
                    }

                    $sendBonus += $userReconsumePoints;


                    Balance::changeUserBonus($every['USER_ID'], 'bonus', $sendBonus, [
                        'REMARK' => 'From ' . $toPeriod . '期补发共享和管理奖',
                        'PERIOD_NUM' => $toPeriod,
                        'DEAL_TYPE_ID' => DealType::RESEND,
                    ]);

                    unset($sendBonus, $oldOne, $userReconsumePoints);

                }
                unset($every, $one);
            }
        }
    }

    /**
     * 修正某一期bonusTotal
     * @param $periodNum
     */
    public function actionFixBonusTotal($periodNum) {
        $allCount = CalcBonus::find()->where('PERIOD_NUM=:PERIOD_NUM', ['PERIOD_NUM'=>$periodNum])->count('ID');
        $pageSize = 1000;
        $pageCount = ceil($allCount/$pageSize);
        for($page=1;$page<=$pageCount;$page++) {
            echo sprintf('修正【%d】期的数据，总页数为【%d】，当前页数为【%d】' . PHP_EOL, $periodNum, $pageCount, $page);
            $offset = ($page-1)*$pageSize;
            $list = CalcBonus::find()->where('PERIOD_NUM=:PERIOD_NUM', ['PERIOD_NUM'=>$periodNum])->offset($offset)->limit($pageSize)->asArray()->all();
            foreach ($list as $everyData) {
                $bonusTotal = $everyData['ORI_BONUS_BD'] + $everyData['ORI_BONUS_TG'] + $everyData['ORI_BONUS_XF'] + $everyData['ORI_BONUS_YJ'] + $everyData['ORI_BONUS_QY'] + $everyData['ORI_BONUS_YC'] + $everyData['ORI_BONUS_VIP'] + $everyData['ORI_BONUS_GX'] + $everyData['ORI_BONUS_GL'] + $everyData['ORI_BONUS_STANDARD'];
                $bonusTotalStr = strval($bonusTotal);
                if( $bonusTotalStr != $everyData['BONUS_TOTAL'] ) {
                    echo sprintf('当前期数【%d】BONUS_TOTAL：%s, 计算结果：%s' . PHP_EOL, $periodNum, $everyData['BONUS_TOTAL'], $bonusTotalStr);
                    CalcBonus::updateAll([
                        'BONUS_TOTAL' => $bonusTotalStr
                    ], 'ID=:ID', ['ID'=>$everyData['ID']]);
                }
            }

        }
    }

    function actionCalcPoints($offset = 0) {
        echo sprintf("时间:[%s]基础积分，当前offset为:【%s】" . PHP_EOL, date('Y-m-d H:i:s', time()) , $offset);

        //查询本月的，每人的累计总收入
        $limit = 1000;
        $empLevelConfig = Cache::getEmpLevelConfig();
        $allData = CalcBonus::findUseDbCalc()->select('USER_ID, SUM(BONUS_TOTAL) AS TOTAL_SUM, SUM(ORI_BONUS_BD) AS BD_TOTAL_SUM')->where('CALC_MONTH=:CALC_MONTH', [':CALC_MONTH' => '202104'])->groupBy('USER_ID')->orderBy('USER_ID DESC')->offset($offset)->limit($limit)->asArray()->all();
        if ($allData) {
            $insertData = [];
            foreach ($allData as $everyData) {
                $validTotalSum = $everyData['TOTAL_SUM'] - $everyData['BD_TOTAL_SUM'];
                if( $validTotalSum <=0 ) continue;

                //达不到 见习主任级别，不产生基础积分
                $userBaseInfo = User::findOneAsArray('ID=:ID', [':ID' => $everyData['USER_ID']]);
                $userEmpLevel = $empLevelConfig[$userBaseInfo['EMP_LV']];
                $userEmpLevelSort = $userEmpLevel['SORT'] ?? EmployLevel::EMP_LEVEL_SORT['NO_LEVEL'];
                unset($userBaseInfo, $userEmpLevel);
                if( $userEmpLevelSort < EmployLevel::EMP_LEVEL_SORT['JX_ZR_LEVEL'] ) {
                    unset($userEmpLevelSort);
                    continue;
                }
                unset($userEmpLevelSort);


                //根据总收入获取积分
                $baseScore = $this->_getBaseScoreByTotalBonus($validTotalSum);
                //根据用户的级别判断 能否得到级别积分
                if( $baseScore > 0 ) {
                    //有记录就更新，没有记录就插入
                    $one = ScoreMonth::find()->where("USER_ID=:USER_ID AND CALC_MONTH=:CALC_MONTH", [
                        "USER_ID" => $everyData['USER_ID'],
                        "CALC_MONTH" => 202104
                    ])->asArray()->one();
                    if ( $one ) {
                        $totalScore = $baseScore + $one["LEVEL_SCORE"] + $one["UPGRADE_SCORE"];
                        ScoreMonth::updateAll(["BASE_SCORE"=>$baseScore, "TOTAL_SCORE"=>$totalScore], "ID=:ID", ["ID"=>$one["ID"]]);
                    }else {
                        $insertData[] = [
                            'ID' => SnowFake::instance()->generateId(),
                            'USER_ID' => $everyData['USER_ID'],
                            'BASE_SCORE' => $baseScore,
                            'TOTAL_SCORE' => $baseScore,
                            'PERIOD_NUM' => 162,
                            'CALC_MONTH' => 202104,
                            'CREATED_AT' => time(),
                        ];
                    }
                }

                unset($everyData, $validTotalSum, $baseScore);
            }

            if($insertData) ScoreMonth::batchInsert($insertData);

            unset($insertData, $allData);
            return $this->actionCalcPoints($offset + $limit);
        }

        unset($allData);
        return true;
    }

    /**
     * 根据总收入获取相应的基础积分
     * @param $totalBonus
     * @return int|mixed
     */
    private function _getBaseScoreByTotalBonus($totalBonus) {
        $sysConfig = cache::getSystemConfig();
        $baseScoreConfig = Json::decode($sysConfig['baseScore']['VALUE']);
        $baseScore = 0;
        foreach ($baseScoreConfig as $everyScoreData) {
            if( $totalBonus < $everyScoreData['monthTotalPvMin'] ) continue;

            if( $everyScoreData['monthTotalPvMax'] != 0 && $totalBonus >= $everyScoreData['monthTotalPvMax'] ) continue;

            $baseScore = $everyScoreData['score'];
            unset($everyScoreData);
            break;
        }

        unset($baseScoreConfig, $totalBonus);
        return $baseScore;
    }

}