<?php

namespace common\models\forms;

use common\helpers\Cache;
use common\helpers\Date;
use common\components\Model;
use common\helpers\Form;
use common\helpers\Tool;
use common\helpers\user\Balance;
use common\helpers\user\Info;
use common\helpers\user\Status;
use common\libs\logging\operate\AdminOperate;
use common\models\DealType;
use common\models\PerfPeriod;
use common\models\Period;
use common\models\EmployLevel;
use common\models\UserWallet;
use common\models\User;
use common\models\UserBind;
use common\models\UserBonus;
use common\models\UserClose;
use common\models\UserInfo;
use common\models\UserPerf;
use common\models\UserStatusAudit;
use common\models\Withdraw;
use yii\base\Exception;

/**
 * Login form
 */
class UserStatusForm extends Model {
    public $id;
    public $userName;
    public $statusValue;
    public $remark;
    public $auditStatus;
    public $isPeriodAddT;
    public $addTPeriodNum;
    public $isPeriodOpen;
    public $openPeriodNum;
    public $userId;
    public $periodNum;
    public $userIds;
    public $isOperating;

    private $_userId;
    private $_userStatusModel;
    private $_userModel;
    private $_periodNum;

    const STATUS_NORMAL = 1;
    const STATUS_LOGOUT = 2;//注销
    const STATUS_BLACKLIST = 3;//黑名单
    const STATUS_STOP_SEND = 4;//停发
    const STATUS_CLOSE = 9;//永久关停

    public function init()
    {
        parent::init();
        $this->adminOperateLogger = new AdminOperate([
            'fetchClass' => UserStatusAudit::class,
        ]);
    }

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            [['id', 'userName', 'statusValue', 'remark', 'auditStatus', 'isPeriodAddT', 'addTPeriodNum', 'isPeriodOpen', 'openPeriodNum', 'userIds', 'isOperating', 'userId', 'periodNum'], 'trim'],
            [['id', 'userName', 'statusValue', 'auditStatus', 'userIds'], 'required'],
            [['userName'], 'exist', 'targetClass' => UserInfo::class, 'targetAttribute' => 'USER_NAME'],
            [['id'], 'exist', 'targetClass' => UserStatusAudit::class, 'targetAttribute' => 'ID'],
            [['statusValue'], 'isStatus'],
            [['auditStatus'], 'isAuditStatus'],
        ];
    }

    /**
     * 指定校验场景
     * @return array
     */
    public function scenarios() {
        $parentScenarios = parent::scenarios();
        $customScenarios = [
            // 手动申请
            'add' => ['userName', 'statusValue', 'remark', 'isPeriodAddT', 'addTPeriodNum', 'isPeriodOpen', 'openPeriodNum'],
            // 审核
            'audit' => ['id', 'auditStatus', 'remark', 'isPeriodAddT', 'addTPeriodNum', 'isPeriodOpen', 'openPeriodNum'],
            // 调整是否运作
            'operating' => ['userIds', 'isOperating'],
            'autoClose' => ['userId'],
            'clearWallet' => ['remark'],
        ];
        return array_merge($parentScenarios, $customScenarios);
    }

    public function attributeLabels() {
        return [
            'id' => 'ID',
            'userName' => '会员编号',
            'statusValue' => '调整状态',
            'remark' => '备注',
            'auditStatus' => '审核状态',
            'isPeriodAddT' => '是否立即加T',
            'addTPeriodNum' => '加T的期数',
            'isPeriodOpen' => '是否马上开通',
            'openPeriodNum' => '开通的期数',
            'userIds' => '会员ID',
            'isOperating' => '是否运作',
        ];
    }

    public function beforeValidate() {
        // 调整是否运作不走初始化流程
        if ($this->scenario == 'add' || $this->scenario == 'audit' || $this->scenario == 'autoClose' ) {
            $this->initModel();
        }
        return parent::beforeValidate();
    }

    /**
     * 初始化model和userId
     */
    public function initModel() {
        $period = Period::instance();
        $this->_periodNum = $period->getNowPeriodNum();
        if ($this->scenario == 'audit') {
            $this->_userStatusModel = UserStatusAudit::findOne(['ID' => $this->id]);
            $this->_userId = $this->_userStatusModel->USER_ID;
        } elseif ($this->scenario == 'add') {
            $this->_userStatusModel = new UserStatusAudit();
            $oneUser = UserInfo::findOneAsArray(['USER_NAME' => $this->userName], [], 'USER_ID');
            $this->_userId = $oneUser['USER_ID'];
            // 查看数据库中是否已经存在了该会员的申请未审核
            $oneUserStatus = UserStatusAudit::findOne(['USER_ID' => $this->_userId, 'AUDIT_STATUS' => \Yii::$app->params['auditStatus']['un']['value']]);
            if ($oneUserStatus && $this->scenario == 'add') {
                // 不允许重复申请
                $this->addError('initModel', '已经存在该会员的待审核数据，请等待审核后再申请');
            }
            // 查看，如果数据库中存在一条已审核，并且是关停转开通，并且是按照期数开通，并且是大于当前期数，则提示存在待开通状态，不能申请
            if (UserStatusAudit::find()->where('USER_ID=:USER_ID AND IS_PERIOD_OPEN=1 AND OPEN_PERIOD_NUM>:NOW_PERIOD_NUM AND STATUS_VALUE=:STATUS_VALUE', [':USER_ID' => $this->_userId, ':NOW_PERIOD_NUM' => $this->_periodNum, ':STATUS_VALUE' => self::STATUS_NORMAL])->exists()) {
                $this->addError('initModel', '该会员处于到期等待开通状态，不能修改其他状态');
            }
        } else {
            $this->addError('initModel', '场景不正确');
        }
        $this->_userModel = User::findOne(['ID' => $this->_userId]);
    }

    /**
     * 状态类型校验
     * @param $attribute
     */
    public function isStatus($attribute) {
        if (!array_key_exists($this->statusValue, \Yii::$app->params['userStatus'])) {
            $this->addError($attribute, '类型不正确');
        }
        // 会员当前状态
        if ($this->_userModel['STATUS'] == $this->statusValue) {
            $this->addError($attribute, '调整状态与调整前状态一致，无需提交');
        }
        $period = Period::instance();
        $nowPeriodNum = $period->getNowPeriodNum();
        // 只有注销状态才需要校验是否立即加T
        if ($this->statusValue == self::STATUS_LOGOUT || $this->statusValue == self::STATUS_STOP_SEND) {
            if ($this->isPeriodAddT && $this->addTPeriodNum <= $nowPeriodNum) {
                $this->addError($attribute, '加T的期数不能小于当前期数');
            }
        }
        // 从关停状态改为正常状态需要判断开通期数不能小于当前期数
        if ($this->_userModel['STATUS'] == self::STATUS_CLOSE && $this->statusValue == self::STATUS_NORMAL) {
            if ($this->isPeriodOpen && $this->openPeriodNum <= $nowPeriodNum) {
                $this->addError($attribute, '开通的期数不能小于当前的期数');
            }
        }
    }

    /**
     * 审核状态是否正确
     * @param $attributes
     */
    public function isAuditStatus($attributes) {
        if (!array_key_exists($this->auditStatus, \Yii::$app->params['auditStatus'])) {
            $this->addError($attributes, '无效的审核状态');
        }
    }

    /**
     * 申请
     * @return null
     * @throws \yii\db\Exception
     */
    public function add() {
        if (!$this->validate()) {
            return null;
        }
        $db = \Yii::$app->db;
        $transaction = $db->beginTransaction();
        try {
            // 获取会员当前的状态
            $oriStatus = Status::getStatus($this->_userId);
            $model = $this->_userStatusModel;
            $model->USER_ID = $this->_userId;
            $model->STATUS_VALUE = $this->statusValue;
            $model->ORI_VALUE = $oriStatus;
            $model->PERIOD_NUM = $this->_periodNum;
            $model->AUDIT_STATUS = \Yii::$app->params['auditStatus']['un']['value'];
            $model->IS_PERIOD_ADD_T = $this->isPeriodAddT ? $this->isPeriodAddT : 0;
            $model->ADD_T_PERIOD_NUM = $this->addTPeriodNum;
            $model->IS_PERIOD_OPEN = $this->isPeriodOpen ? $this->isPeriodOpen : 0;
            $model->OPEN_PERIOD_NUM = $this->openPeriodNum;
            $model->CREATE_REMARK = $this->remark;
            $model->CREATE_ADMIN = \Yii::$app->user->id;
            $model->CREATED_AT = Date::nowTime();
            if (!$model->save()) {
                throw new Exception(Form::formatErrorsForApi($model->getErrors()));
            }
            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->addError('edit', $e->getMessage());
            return null;
        }

        // 记录日志
        $this->adminOperateLogger->afterInsert($model)->clean()->save([
            'optType' => '申请修改会员状态',
            'userId' => $model->USER_ID,
            'userName' => Info::getUserNameByUserId($model->USER_ID),
            'remark' => $model->CREATE_REMARK,
        ]);

        return $model;

    }

    /**
     * 审核
     * @return null
     * @throws \yii\db\Exception
     */
    public function audit() {
        if (!$this->validate()) {
            return null;
        }

        // 日志记录操作前的数据
        $this->adminOperateLogger->beforeUpdate($this->_userStatusModel);

        $db = \Yii::$app->db;
        $transaction = $db->beginTransaction();
        try {
            $model = $this->_userStatusModel;
            if ($this->auditStatus == 'true') {
                // 获取该会员的当前的聘级和报单级别
                $model->DEC_LV = Info::getDecLv($model->USER_ID);
                $model->EMP_LV = Info::getEmpLv($model->USER_ID);
                // 获取当前会员的各个区的业绩
                $userPerf = UserPerf::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => $model->USER_ID]);
                $model->PV_1L = $userPerf['PV_1L'];
                $model->PV_2L = $userPerf['PV_2L'];
                $model->PV_3L = $userPerf['PV_3L'];
                $model->PV_4L = $userPerf['PV_4L'];
                $model->PV_5L = $userPerf['PV_5L'];
                // 获取当前会员的最新已挂网的会员的剩余业绩
                $maxPeriodNum = Period::sentMaxPeriodNum();
                $perfPeriod = PerfPeriod::findOne(['USER_ID' => $model->USER_ID, 'PERIOD_NUM' => $maxPeriodNum]);
                $model->SURPLUS_1L = $perfPeriod['SURPLUS_1L'] ?? 0;
                $model->SURPLUS_2L = $perfPeriod['SURPLUS_2L'] ?? 0;
                $model->SURPLUS_3L = $perfPeriod['SURPLUS_3L'] ?? 0;
                $model->SURPLUS_4L = $perfPeriod['SURPLUS_4L'] ?? 0;
                $model->SURPLUS_5L = $perfPeriod['SURPLUS_5L'] ?? 0;
                $model->IS_PERIOD_ADD_T = $this->isPeriodAddT ? $this->isPeriodAddT : 0;
                $model->ADD_T_PERIOD_NUM = $this->addTPeriodNum ? $this->addTPeriodNum : null;
                $model->IS_PERIOD_OPEN = $this->isPeriodOpen ? $this->isPeriodOpen : 0;
                $model->OPEN_PERIOD_NUM = $this->openPeriodNum;
                $model->CREATE_REMARK = $this->remark;
                $model->AUDIT_ADMIN = \Yii::$app->user->id;
                $model->AUDIT_STATUS = \Yii::$app->params['auditStatus']['true']['value'];
                $model->AUDITED_AT = Date::nowTime();
                if (!$model->save()) {
                    throw new Exception(Form::formatErrorsForApi($model->getErrors()));
                }
                // 把商城会员表的状态修改
                // 如果是从关停修改为正常状态，并且不是马上开通的先不开通，等待封期时，到那一期再给会员开通，其他的情况现在就调整状态
                $userModel = $this->_userModel;
                $beforeStatus = $userModel->STATUS;
                if (!($model->ORI_VALUE == self::STATUS_CLOSE && $model->STATUS_VALUE == self::STATUS_NORMAL && $model->IS_PERIOD_OPEN)) {
                    $userModel->STATUS = $model->STATUS_VALUE;
                    $userModel->STATUS_AT = Date::nowTime();
                    if (!$userModel->save()) {
                        throw new Exception(Form::formatErrorsForApi($userModel->getErrors()));
                    }
                }
                if (!($model->ORI_VALUE == self::STATUS_CLOSE && $model->IS_PERIOD_OPEN)) {
                    UserWallet::updateAll(['CLEAR_BY_CLOSED_AT'=> 0], 'USER_ID=:USER_ID', [':USER_ID' => $model->USER_ID]);
                }
                // 开始会员状态相关的后续功能
                // 注销立即清空全部会员所有钱包余额、奖金余额、大区剩余业绩、和各区业绩，自动提现改为手动提现
                // 注销需要设置立即加T，还是按照设定期数加T，（思路：假设115封期的时候先从会员状态审核表查看116期，批量更新116期需要加T的会员的身份证表前缀为字母T）
                // 设置成黑名单后自动提现改为手动提现
                // 停发立即加T，自动提现改为手动提现，清空的参照奖金需求
                // 取消关停状态可以选择期数开通，到期自动开
                // 老会员需要开通时选择报单级别
                // 关停开通时，首次报复销单需要交足额的复销，这个在会员表有参数 IS_FIRST_OPEN
                if ($model->STATUS_VALUE == self::STATUS_NORMAL) {
                    if (!$this->isPeriodOpen) {
                        // 身份证号取消加T
                        User::updateAll(['ID_CARD_PREFIX' => ''], 'ID=:ID', [':ID' => $userModel->ID]);
                        // 查看开通之前的状态是什么，如果是关停状态，就把会员表的首次开通的字段设标记
                        if ($beforeStatus == self::STATUS_CLOSE) {
                            User::updateAll(['IS_FIRST_OPEN' => 1], 'ID=:ID', [':ID' => $userModel->ID]);
                        }
                    }
                }
                //注销
                elseif ($model->STATUS_VALUE == self::STATUS_LOGOUT) {
                    if ($perfPeriod) {
                        // 清空大区剩余业绩
                        $perfPeriod->SURPLUS_1L = 0;
                        $perfPeriod->SURPLUS_2L = 0;
                        $perfPeriod->SURPLUS_3L = 0;
                        $perfPeriod->SURPLUS_4L = 0;
                        $perfPeriod->SURPLUS_5L = 0;
                        if (!$perfPeriod->save()) {
                            throw new Exception(Form::formatErrorsForApi($perfPeriod->getErrors()));
                        }
                    }
                    // 清空各区业绩
                    $userPerf = UserPerf::findOne(['USER_ID' => $userModel->ID]);
                    if ($userPerf) {
                        $userPerf->PV_1L = 0;
                        $userPerf->PV_2L = 0;
                        $userPerf->PV_3L = 0;
                        $userPerf->PV_4L = 0;
                        $userPerf->PV_5L = 0;
                        if (!$userPerf->save()) {
                            throw new Exception(Form::formatErrorsForApi($userPerf->getErrors()));
                        }
                    }
                    // 清空所有奖金
                    Balance::clearAllBonus($userModel->ID, ['REMARK' => '清空账户余额','DEAL_TYPE'=>DealType::DEDUCT_LOGOUT]);
                    // 取消自动提现
                    Withdraw::setAutoWithdraw($userModel->ID, 0);
                    // 向下找新的主会员
                    UserBind::setNewMainBind($userModel->ID);
                    // 如果立即加T，否则到期数自动加T(从封期实现)
                    if (!$this->isPeriodAddT) {
                        User::updateAll(['ID_CARD_PREFIX' => 'T'], 'ID=:ID', [':ID' => $userModel->ID]);
                    }
                } elseif ($model->STATUS_VALUE == self::STATUS_BLACKLIST) {
                    // 取消自动提现
                    Withdraw::setAutoWithdraw($userModel->ID, 0);
                    // 向下找新的主会员
                    UserBind::setNewMainBind($userModel->ID);
                } elseif ($model->STATUS_VALUE == self::STATUS_STOP_SEND) {
                    // 取消自动提现
                    Withdraw::setAutoWithdraw($userModel->ID, 0);
                    // 向下找新的主会员
                    UserBind::setNewMainBind($userModel->ID);
                    // 如果立即加T，否则到期数自动加T(从封期实现)
                    if (!$this->isPeriodAddT) {
                        User::updateAll(['ID_CARD_PREFIX' => 'T'], 'ID=:ID', [':ID' => $userModel->ID]);
                    }
                }
                //永久关停
                elseif ($model->STATUS_VALUE == self::STATUS_CLOSE) {
                    $this->_afterClose($userModel->ID,$perfPeriod);
                }
            } elseif ($this->auditStatus == 'reject') {
                $model->CREATE_REMARK = $this->remark;
                $model->AUDIT_ADMIN = \Yii::$app->user->id;
                $model->AUDIT_STATUS = \Yii::$app->params['auditStatus']['reject']['value'];
                $model->AUDITED_AT = Date::nowTime();
                if (!$model->save()) {
                    throw new Exception(Form::formatErrorsForApi($model->getErrors()));
                }
            }
            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->addError('audit', $e->getMessage());
            return null;
        }

        // 记录日志
        $this->adminOperateLogger->afterUpdate($model)->clean()->save([
            'optType' => '审核会员状态',
            'userId' => $model->USER_ID,
            'userName' => Info::getUserNameByUserId($model->USER_ID),
            'remark' => $model->CREATE_REMARK,
        ]);

        return $model;
    }

    /**
     * 调整是否运作
     * @return User|null
     */
    public function operating() {
        if (!$this->validate()) {
            return null;
        }
        $this->adminOperateLogger->fetchClass = User::class;
        $this->adminOperateLogger->setIsBatch(true)->beforeUpdate($this->userIds, 'ID',['select'=>'ID,NOT_OPERATING']);

        $allUidIn = implode("','", $this->userIds);
        User::updateAll(['NOT_OPERATING' => !$this->isOperating], "ID IN ('" . $allUidIn . "')");

        $this->adminOperateLogger->setIsBatch(true)->afterUpdate($this->userIds, 'ID',['select'=>'ID,NOT_OPERATING']);
        $this->adminOperateLogger->setBatchField('ID')->setOptObjField('ID')->clean()->save([
            'optType' => '调整会员运作状态【'.($this->isOperating ? '运作' : '不运作').'】',
            'remark' => $this->remark,
        ]);
        return $this->userIds;
    }

    /**
     * 自动关停
     * @return UserStatusAudit|null
     * @throws \yii\db\Exception
     */
    public function autoClose() {
        if (!$this->validate()) {
            return null;
        }
        $db = \Yii::$app->db;
        $transaction = $db->beginTransaction();
        try {
            // 获取会员当前的状态
            $oriStatus = Status::getStatus($this->userId);
            $model = new UserStatusAudit();
            $model->USER_ID = $this->userId;
            $model->STATUS_VALUE = self::STATUS_CLOSE;
            $model->ORI_VALUE = $oriStatus;
            $model->PERIOD_NUM = $this->periodNum;
            $model->AUDIT_STATUS = \Yii::$app->params['auditStatus']['true']['value'];
            $model->IS_PERIOD_ADD_T = 0;
            $model->ADD_T_PERIOD_NUM = 0;
            $model->IS_PERIOD_OPEN = 0;
            $model->OPEN_PERIOD_NUM = 0;
            $model->CREATE_REMARK = '自动关停';
            $model->CREATE_ADMIN = 0;
            $model->CREATED_AT = Date::nowTime();
            if (!$model->save()) {
                throw new Exception(Form::formatErrorsForApi($model->getErrors()));
            }
            $userModel = User::findOne(['ID' => $this->userId]);
            $userModel->STATUS = self::STATUS_CLOSE;
            $userModel->STATUS_AT = Date::nowTime();
            if (!$userModel->save()) {
                throw new Exception(Form::formatErrorsForApi($userModel->getErrors()));
            }
            $this->_afterClose($this->userId);
            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $this->addError('autoClose', $e->getMessage());
            return null;
        }
        return $model;
    }

    /**
     * 关停后对会员操作
     * @param $userId
     * @param null $perfPeriod
     * @throws Exception
     * @throws \yii\db\Exception
     */
    private function _afterClose($userId,$perfPeriod=null){
        if(!$perfPeriod) {
            $maxPeriodNum = Period::sentMaxPeriodNum();
            $perfPeriod = PerfPeriod::findOne(['USER_ID' => $userId, 'PERIOD_NUM' => $maxPeriodNum]);
        }
        // 清空大区剩余业绩
        if ($perfPeriod) {
            $perfPeriod->SURPLUS_1L = 0;
            $perfPeriod->SURPLUS_2L = 0;
            $perfPeriod->SURPLUS_3L = 0;
            $perfPeriod->SURPLUS_4L = 0;
            $perfPeriod->SURPLUS_5L = 0;
            if (!$perfPeriod->save()) {
                throw new Exception(Form::formatErrorsForApi($perfPeriod->getErrors()));
            }
        }
        // 清空各区业绩
        $userPerf = UserPerf::findOne(['USER_ID' => $userId]);
        if ($userPerf) {
            $userPerf->PV_1L = 0;
            $userPerf->PV_2L = 0;
            $userPerf->PV_3L = 0;
            $userPerf->PV_4L = 0;
            $userPerf->PV_5L = 0;
            if (!$userPerf->save()) {
                throw new Exception(Form::formatErrorsForApi($userPerf->getErrors()));
            }
        }
        // 清空所有奖金 暂时不清奖金<19.10.1>@190730
        // Balance::clearAllBonus($userId, ['REMARK' => '会员永久关停']);
        // 取消自动提现
        Withdraw::setAutoWithdraw($userId, 0);
        // 身份证号立即加T，聘级将为无聘级
        User::updateAll(['ID_CARD_PREFIX' => 'T', 'EMP_LV' => EmployLevel::getDefaultLevelId()], 'ID=:ID', [':ID' => $userId]);
        // 向下找新的主会员
        UserBind::setNewMainBind($userId);
    }

    /**
     * 自动关停
     * @param $periodNum
     * @param int $closedAt
     * @param $limit
     * @param int $start
     * @param null $closeInspectStart
     * @param null $closeInspectPv
     * @return bool
     * @throws \yii\db\Exception
     */
    public static function autoChkClose($periodNum, $closedAt = 0, $limit, $start = 0, $closeInspectStart = null, $closeInspectPv = null) {
        //初始化
        if (!$closeInspectStart || !$closeInspectPv) {
            $systemConfig = Cache::getSystemConfig();
            $closeInspectMonth = $systemConfig['closeInspectMonth']['VALUE'];
            $closeInspectStart = Date::lastNumMonth($closeInspectMonth, $closedAt);
            $closeInspectPv = $systemConfig['closeInspectPv']['VALUE'];
        }
        //考察所有未注销未关停的会员 (修复UserInfo没有STATUS)
        $allData = User::find()->where('STATUS!=:STATUS_CLOSE AND STATUS!=:STATUS_LOGOUT AND SUB_COM_LEADER!=1',[':STATUS_CLOSE'=>self::STATUS_CLOSE,':STATUS_LOGOUT'=>self::STATUS_LOGOUT])->select('ID')->offset($start)->limit($limit)->asArray()->all();
        if ($allData) {
            foreach ($allData as $data) {
                // 修复绑定的START和END是关键字不允许作为绑定参数
                $pvPcs = PerfPeriod::find()->where('CREATED_AT>:START_TIME AND CREATED_AT<:END_TIME', [':START_TIME' => $closeInspectStart, ':END_TIME' => $closedAt])->SUM('PV_PCS');
                if ($pvPcs < $closeInspectPv) {
                    //未达到业绩，封停会员
                    $formModel = new UserStatusForm();
                    $formModel->scenario = 'autoClose';
                    $formModel->userId = $data['ID'];
                    $formModel->periodNum = $periodNum;
                    if (!$formModel->autoClose()) {
                        continue;
                    }
                    unset($formModel);
                }
            }
            unset($allData);
            $start = $start + $limit;
            return self::autoChkClose($periodNum, $closedAt, $limit, $start, $closeInspectStart, $closeInspectPv);
        }
        return true;
    }

    /**
     * 删除前
     * @param $selected
     */
    public function beforeDelete($selected) {
        $this->adminOperateLogger->setIsBatch(true)->beforeDelete($selected, 'ID');
    }
    /**
     * 删除
     * @param $selected
     * @throws Exception
     */
    public function delete($selected) {
        $this->adminOperateLogger->clean()->save([
            'optType' => '删除会员状态待审核数据',
        ]);
    }

    /**
     * 清空关停会员钱包
     * @return array|null
     * @throws Exception
     * @throws \yii\db\Exception
     */
    public function clearWallet() {
        if (!$this->validate()) {
            return null;
        }
        $uids = [];
        $users = Status::getCloseUser();
        if ($users) {
            $uids = array_column($users, 'ID');
            $this->adminOperateLogger->fetchClass = UserBonus::class;
            $this->adminOperateLogger->setIsBatch(true)->beforeUpdate($uids, 'USER_ID');
            $userBonus = $this->adminOperateLogger->saveBeforeContent;
            $this->adminOperateLogger->fetchClass = UserWallet::class;
            $this->adminOperateLogger->setIsBatch(true)->beforeUpdate($uids, 'USER_ID');
            $shopWallet = $this->adminOperateLogger->saveBeforeContent;
            $this->adminOperateLogger->saveBeforeContent=Tool::mergeArrayWithKey($userBonus,$shopWallet);

            $db = \Yii::$app->db;
            $transaction = $db->beginTransaction();
            try {
                foreach ($users as $u) {
                    // 清空所有奖金
                    Balance::clearAllBonus($u['ID'], ['REMARK' => '清空账户余额', 'DEAL_TYPE' => DealType::DEDUCT_CLOSE]);
                }
                $transaction->commit();
            } catch (Exception $e) {
                $transaction->rollBack();
            }

            $this->adminOperateLogger->fetchClass = UserBonus::class;
            $this->adminOperateLogger->setIsBatch(true)->afterUpdate($uids, 'USER_ID');
            $userBonus = $this->adminOperateLogger->saveAfterContent;
            $this->adminOperateLogger->fetchClass = UserWallet::class;
            $this->adminOperateLogger->setIsBatch(true)->afterUpdate($uids, 'USER_ID');
            $shopWallet = $this->adminOperateLogger->saveAfterContent;
            $this->adminOperateLogger->saveAfterContent=Tool::mergeArrayWithKey($userBonus,$shopWallet);
            $this->adminOperateLogger->setBatchField('USER_ID')->setOptObjField('USER_ID')->clean()->save([
                'optType' => '清空关停会员钱包',
                'remark' => $this->remark,
            ]);

            return $uids;
        } else {
            throw new Exception('暂无符合条件的会员');
        }
    }
}
