['username', 'openid', 'password', 'email', 'tel', 'pid'], 'connect' => ['username', 'email'], 'create' => ['jucai_id', 'email', 'tel'], 'update' => ['username', 'password', 'email', 'tel', 'nickname', 'pid'], 'settings' => ['username', 'password', 'email', 'tel'], 'resetPassword' => ['password'] ]); } /** * {@inheritdoc} */ public function rules() { return [ ['username', 'string', 'on' => 'search'], ['username', 'required', 'on' => 'create'], ['password', 'required', 'on' => ['register']], [['tel'], 'match', 'pattern' => Regexp::$mobile], [['email'], 'match', 'pattern' => Regexp::$email], [['privilege'], 'string', 'max' => 255], ]; } public function attributeLabels() { return [ 'pid' => '上级用户', 'jucai_id' => '聚才网ID', 'username' => '用户名',//openid共用字段 'openid' => '微信ID', 'nickname' => '昵称', 'password' => '密码', 'email' => ' 绑定邮箱', 'tel' => '绑定手机', 'avatar' => '头像', 'created_at' => '注册时间', 'login_at' => '最后登录时间', 'type' => '用户类型', 'privilege' => '特权',//微信用户属性 'unionid' => '联合ID',//微信用户属性 ]; } /** * 根据id查询用户 * {@inheritdoc} */ public static function findIdentity($id) { return static::findOne(['id' => $id, 'blocked_at' => null]); } /** * 根据访问令牌查询用户 * api访问专用 * {@inheritdoc} */ public static function findIdentityByAccessToken($token, $type = null) { return static::find()->where(['access_token' => $token])->andWhere(['>', 'expired_at', time()])->one(); } /** * 根据用户名查询用户 * * @param string $username * * @return mixed */ public static function findByUsername($username) { return static::find()->where(['username' => $username]) ->andWhere(['blocked_at' => null]) ->one(); } /** * 根据用openid查询用户 * * @param string $openId * * @return mixed */ public static function findByOpenid($openId) { return static::find()->where(['openid' => $openId]) ->andWhere(['blocked_at' => null]) ->one(); } /** * 根据绑定邮箱查询用户 * @param $email * @return array|ActiveRecord|null * @author nodelog */ public static function findByEmail($email) { return static::find()->where(['email' => $email]) ->andWhere(['blocked_at' => null]) ->one(); } /** * 根据绑定手机号查询用户 * @param $tel * @return array|ActiveRecord|null * @author nodelog */ public static function findByTel($tel) { return static::find()->where(['email' => $tel]) ->andWhere(['blocked_at' => null]) ->one(); } /** * 根据用户名、邮箱、手机号查询用户 * @param $login * @return array|ActiveRecord|null * @author nodelog */ public static function findByUsernameOrEmailTel($login) { return static::find()->where(['or', ['username' => $login], ['email' => $login], ['tel' => $login]]) ->andWhere(['blocked_at' => null]) ->one(); } /** * 根据重置密码令牌查询用户 * Finds user by password reset token. * * @param string $token password reset token * * @return static|null */ public static function findByPasswordResetToken($token) { if (!static::isPasswordResetTokenValid($token)) { return; } return static::findOne([ 'password_reset_token' => $token, 'blocked_at' => null ]); } /** * Finds out if password reset token is valid. * * @param string $token password reset token * * @return bool */ public static function isPasswordResetTokenValid($token) { if (empty($token)) { return false; } $timestamp = (int)substr($token, strrpos($token, '_') + 1); $expire = Yii::$app->params['user.passwordResetTokenExpire']; return $timestamp + $expire >= time(); } /** * 获取当前用户id,认证身份identity使用 * {@inheritdoc} */ public function getId() { return $this->getPrimaryKey(); } /** * 获取当前身份验证密钥 * {@inheritdoc} */ public function getAuthKey() { return $this->auth_key; } /** * 验证身份验证密钥 * {@inheritdoc} */ public function validateAuthKey($authKey) { return $this->getAuthKey() === $authKey; } /** * 验证密码 * @param string $password password to validate * * @return bool if password provided is valid for current user */ public function validatePassword($password) { return Yii::$app->security->validatePassword($password, $this->password_hash); } /** * 从密码生成密码哈希并将其赋值给当前用户。 * @param $password * @throws \yii\base\Exception * @author nodelog */ public function setPassword($password) { $this->password_hash = Yii::$app->security->generatePasswordHash($password); } /** * 验证二维码哈希值 * @param $qrcodeHash * @return bool * @author nodelog */ public function validateQrcodeHash($qrcodeHash) { return $qrcodeHash == md5(self::generateQrcodeLoginUrl($this->access_token)); } /** * 生成“记住我”身份验证密钥。 */ public function generateAuthKey() { $this->auth_key = Yii::$app->security->generateRandomString(); } /** * 生成新的密码重置令牌。 */ public function generatePasswordResetToken() { $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time(); } /** * 删除密码重置令牌。 */ public function removePasswordResetToken() { $this->password_reset_token = null; } /** * 生成访问令牌和过期时间 * @param null $access_token * @throws \yii\base\Exception * @author nodelog */ public function generateAccessToken($access_token = null) { if (!$access_token) { // $access_token = Yii::$app->security->generateRandomString(); } $this->access_token = $access_token; $this->expired_at = time() + 60 * 60 * 2;//2小时 } /** * 删除访问令牌和过期时间 * @author nodelog */ public function removeAccessToken() { $this->access_token = null; $this->expired_at = null; } /** * 创建用户 * @param int $type * @return bool * @author nodelog */ public function create() { if ($this->getIsNewRecord() == false) { throw new \RuntimeException('Calling "' . __CLASS__ . '::' . __METHOD__ . '" on existing user'); } $this->confirmed_at = time(); $this->password = $this->password == null ? $this->getModule()->defaultPassword : $this->password; $this->generateAuthKey(); if (!$this->save()) { return false; } return true; } /** * 创建微信用户 并授权公司管理员角色 * @throws \Exception * @author nodelog */ public function createWechat() { $this->type = self::TYPE_PERSON; if ($this->create()) { // try { // $auth = \Yii::$app->authManager; // //todo 具体授权 // $authorRole = $auth->getRole('superAdmin'); // $auth->assign($authorRole, $this->id); // } catch (Exception $e) { // $this->addError('username', $e->getMessage()); // return false; // } //创建个人数据设置 return true; } return false; } /** * 保存之前生成密码哈希 * @param bool $insert * @return bool * @throws \yii\base\Exception * @author nodelog */ public function beforeSave($insert) { if (!empty($this->password)) { $this->password_hash = Yii::$app->security->generatePasswordHash($this->password); } return parent::beforeSave($insert); } /** * 禁用用户 * @return bool * @throws \yii\base\Exception * @author nodelog */ public function block() { return (bool)$this->updateAttributes([ 'blocked_at' => time(), 'auth_key' => \Yii::$app->security->generateRandomString(), ]); } /** * 解除禁用 * UnBlocks the user by setting 'blocked_at' field to null. */ public function unblock() { return (bool)$this->updateAttributes(['blocked_at' => null]); } /** * 发送绑定邮箱确认邮件 * @param $email * @return array * @throws \yii\base\InvalidConfigException * @author nodelog */ public function sendConfirm($email) { $exist = User::find()->where(['<>', 'id', Yii::$app->user->id])->andWhere(['email' => $email])->exists(); $user = Yii::$app->user->identity; if (!$exist && !$user->isConfirmed) { /** @var Token $token */ $token = \Yii::createObject([ 'class' => Token::className(), 'user_id' => $user->id, 'type' => Token::TYPE_CONFIRMATION, ]); $token->save(false); $mailer = Yii::$app->mailer; $mailer->viewPath = '@common/modules/user/mail'; try { $mailer->compose(['html' => 'confirmation'], ['user' => $user, 'token' => $token]) ->setTo($email) ->setSubject(Yii::t('user', 'Confirm account on {0}', Yii::$app->config->get('name'))) ->send(); return [true, null]; } catch (\Exception $e) { return [false, '发送失败,请确认邮箱是否存在!']; } } else { return [false, '邮箱已存在']; } } /** * 用户邮箱验证 * @param $code * @return array * @throws \yii\db\StaleObjectException * @author nodelog */ public function attemptConfirmation($code) { if ($this->getIsConfirmed()) { return [false, '该用户已验证邮箱']; } $token = Token::find()->where(['user_id' => $this->id, 'code' => $code, 'type' => Token::TYPE_CONFIRMATION])->one(); if ($token !== null && !$token->isExpired) { $token->delete(); if (($success = $this->confirm())) { $message = \Yii::t('user', 'Thank you, registration is now complete.'); } else { $message = \Yii::t('user', 'Something went wrong and your account has not been confirmed.'); } } else { $success = false; $message = \Yii::t('user', 'The confirmation link is invalid or expired. Please try requesting a new one.'); } return [$success, $message]; } /** * Confirms the user by setting 'confirmed_at' field to current time. */ public function confirm() { $result = (bool)$this->updateAttributes(['confirmed_at' => time()]); return $result; } /** * 获取用户头像 * @param int $width * @param int $height * @return string * @author nodelog */ public function getAvatar($width = 96, $height = 0) { if (empty($height)) { $height = $width; } if ($this->profile->avatar) { return Yii::$app->storage->thumbnail($this->profile->avatar, $width, $height); } return $this->getDefaultAvatar($width, $height); } /** * 获取用户信息 * @return \yii\db\ActiveQuery * @author nodelog */ public function getProfile() { return $this->hasOne(Profile::className(), ['user_id' => 'id']); } /** * 认证车辆 * @return \yii\db\ActiveQuery * @author nodelog */ public function getCar() { return $this->hasOne(UserCar::className(), ['user_id' => 'id']); } /** * 获取用户签名 * @return string * @author nodelog */ public function getSignature() { return $this->profile->signature; } /** * 获取默认头像 * @param $width * @param $height * @return string * @author nodelog */ public static function getDefaultAvatar($width, $height) { list ($basePath, $baseUrl) = \Yii::$app->getAssetManager()->publish("@common/static"); $name = "avatars/avatar_" . $width . "x" . $height . ".png"; if (file_exists($basePath . DIRECTORY_SEPARATOR . $name)) { return $baseUrl . "/" . $name; } return $baseUrl . "/" . "avatar_200x200.png"; } /** * 保存头像 * @param $avatar * @author nodelog */ public function saveAvatar($avatar) { $this->profile->updateAttributes(['avatar' => $avatar]); } /** * 初始化插入数据库后置事件 * @author nodelog */ public function init() { $this->on(self::EVENT_AFTER_INSERT, [$this, 'afterInsertInternal']); } /** * 设置用户信息的外键关联 * @param $event * @author nodelog */ public function afterInsertInternal($event) { $profile = new Profile(); // $profile->voice_id = Voice::getDefaultId(); $this->link('profile', $profile); //创建个人配置 } /** * 是否管理员用户 * @return bool */ public function getIsAdmin() { return (\Yii::$app->getAuthManager() && $this->module->adminPermission ? Yii::$app->getAuthManager()->checkAccess($this->getId(), $this->module->adminPermission) : false) || in_array($this->username, $this->module->admins); } /** * 是否确认 * @return bool Whether the user is confirmed or not. */ public function getIsConfirmed() { return $this->confirmed_at != null; } /** * 是否禁用 * @return bool Whether the user is blocked or not. */ public function getIsBlocked() { return $this->blocked_at != null; } /** * 获取等级 * @return string */ public function getLevel() { return UserLevel::getLevel($this->profile->money); } /** * 生成二维码登录url * @param $access_token * @return string * @author nodelog */ public static function generateQrcodeLoginUrl($access_token) { return Yii::$app->request->hostInfo . '/api/v1/weixin/code?access_token=' . $access_token; } public static $typeList = [ self::TYPE_COMPANY => '企业用户', self::TYPE_PERSON => '个人用户', self::TYPE_WEB => '后台用户' ]; public static $typeIconList = [ self::TYPE_PERSON => '', self::TYPE_WEB => '' ]; /** * 格式化昵称 * @return string * @author nodelog */ private function formatNickname() { // $name = $this->profile->nickname ?: $this->username; // if ($htmlFormat) { // return Html::tag('span', $name . ' ' . self::$typeIconList[$this->type], ['title' => self::$typeList[$this->type]]); // } return $this->nickname ? $this->nickname : $this->username; } /** * 获得用户所有角色描述 * @return string * @author nodelog */ public function getAllRoleDesc() { $roles = Yii::$app->authManager->getRolesByUser($this->id); return implode(' | ', ArrayHelper::getColumn($roles, 'description')); } /** * 查询 左连接 去除公共部分,如教练查询未绑定教练微信用户,销售查询未绑定销售微信用户,FOR 后台添加教练和销售 筛选选择列表数据 * @param $model 模型类名 * @param $inIdArray 过滤的id数组 * @return array|User[] */ public static function getAllSelectFromModel($model, $inIdArray = null) { if (empty($inIdArray)) { $list = User::find()->joinWith($model::relationName())->where([self::tableName() . '.blocked_at' => null, $model::tableName() . '.user_id' => null])->all(); } else { $list = User::find()->joinWith($model::relationName())->where([self::tableName() . '.blocked_at' => null])->andWhere(['or', [$model::tableName() . '.user_id' => null], [$model::tableName() . '.user_id' => $inIdArray]])->all(); } return $list; } /** * 获取可选管理员用户列表 * @author nodelog */ public static function lists() { if (Yii::$app->user->identity->getIsAdmin()) { $lists = User::find()->indexBy('id')->all(); $lists = ArrayHelper::map($lists, 'id', 'nickname'); return $lists; } else { return [ Yii::$app->user->id => Yii::$app->user->identity->nickname ]; } } }