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('暂无符合条件的会员'); } } }