123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489 |
- <?php
- // +----------------------------------------------------------------------
- // | Yzncms [ 御宅男工作室 ]
- // +----------------------------------------------------------------------
- // | Copyright (c) 2018 http://yzncms.com All rights reserved.
- // +----------------------------------------------------------------------
- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
- // +----------------------------------------------------------------------
- // | Author: 御宅男 <530765310@qq.com>
- // +----------------------------------------------------------------------
-
- // +----------------------------------------------------------------------
- // | 前台用户服务
- // +----------------------------------------------------------------------
- namespace app\member\service;
-
- use app\member\library\Token;
- use app\member\model\Member as Member_Model;
- use think\Db;
- use think\facade\Hook;
- use think\facade\Validate;
- use util\Random;
-
- class User
- {
- protected static $instance = null;
- protected $_error = null;
- protected $_logined = false;
- //当前登录会员详细信息
- protected $_user = null;
- protected $_token = '';
- //Token默认有效时长
- protected $keeptime = 2592000;
- //默认配置
- protected $config = [];
- protected $options = [];
- protected $allowFields = ['id', 'username', 'nickname', 'mobile', 'avatar', 'point', 'amount'];
-
- public function __construct($options = [])
- {
- if ($config = get_addon_config("member")) {
- $this->config = array_merge($this->config, $config);
- }
- $this->options = array_merge($this->config, $options);
- }
-
- /**
- * 获取示例
- * @param array $options 实例配置
- * @return static
- */
- public static function instance($options = [])
- {
- if (is_null(self::$instance)) {
- self::$instance = new self($options);
- }
- return self::$instance;
- }
-
- /**
- * 获取User模型
- * @return User
- */
- public function getUser()
- {
- return $this->_user;
- }
-
- /**
- * 兼容调用user模型的属性
- *
- * @param string $name
- * @return mixed
- */
- public function __get($name)
- {
- return $this->_user ? $this->_user->$name : null;
- }
-
- /**
- * 兼容调用user模型的属性
- */
- public function __isset($name)
- {
- return isset($this->_user) ? isset($this->_user->$name) : false;
- }
-
- /**
- * 根据Token初始化
- *
- * @param string $token Token
- * @return boolean
- */
- public function init($token)
- {
- if ($this->_logined) {
- return true;
- }
- if ($this->_error) {
- return false;
- }
- $data = Token::get($token);
- if (!$data) {
- return false;
- }
- $user_id = intval($data['user_id']);
- if ($user_id > 0) {
- $user = Member_Model::get($user_id);
- if (!$user) {
- $this->setError('账户不存在');
- return false;
- }
- if ($user['status'] !== 1) {
- $this->setError('账户已经被锁定');
- return false;
- }
- $this->_user = $user;
- $this->_logined = true;
- $this->_token = $token;
-
- //初始化成功的事件
- Hook::listen("user_init_successed", $this->_user);
- return true;
- } else {
- $this->setError('你当前还未登录');
- return false;
- }
- }
-
- /**
- * 注册一个新用户
- * @param $username 用户名
- * @param $password 密码
- * @param string $email 邮箱
- * @param string $mobile 手机号
- * @param array $extend 扩展参数
- * @return bool|mixed
- */
- public function userRegister($username, $password, $email = '', $mobile = '', $extend = [])
- {
- $passwordinfo = encrypt_password($password); //对密码进行处理
- $data = [
- "mobile" => $mobile,
- "username" => $username,
- "email" => $email,
- "encrypt" => $passwordinfo['encrypt'],
- "amount" => 0,
- ];
- $nickname = $extend['nickname'] ?? $username;
- $extend['nickname'] = preg_match("/^1[3-9]\d{9}$/", $nickname) ? substr_replace($nickname, '****', 3, 4) : $nickname;
- //新注册用户积分
- $data['point'] = $this->config['defualtpoint'] ? $this->config['defualtpoint'] : 0;
- //新会员注册默认赠送资金
- $data['amount'] = $this->config['defualtamount'] ? $this->config['defualtamount'] : 0;
- //新会员注册需要管理员审核
- $data['status'] = $this->config['registerverify'] ? 0 : 1;
- //计算用户组
- $data['groupid'] = $this->get_usergroup_bypoint($data['point']);
- $params = array_merge($data, $extend);
- $params['password'] = $passwordinfo['password'];
-
- //账号注册时需要开启事务,避免出现垃圾数据
- Db::startTrans();
- try {
- $model = new Member_Model();
- $user = $model->allowField(true)->save($params);
- $this->_user = $model->get($model->id);
- //设置Token
- $this->_token = Random::uuid();
- Token::set($this->_token, $model->id, $this->keeptime);
- //设置登录状态
- $this->_logined = true;
- //注册成功的事件
- Hook::listen("user_register_successed", $this->_user, $data);
- Db::commit();
- } catch (\Exception $e) {
- Db::rollback();
- $this->setError($e->getMessage());
- return false;
- }
- return $model->id;
- }
-
- /**
- * 会员登录
- * @param $account 账户
- * @param $password 明文密码,填写表示验证密码
- * @return boolean
- */
- public function loginLocal($account, $password = null)
- {
- $field = Validate::is($account, 'email') ? 'email' : (Validate::regex($account, '/^1\d{10}$/') ? 'mobile' : 'username');
- $user = Member_Model::get([$field => $account]);
- if (!$user) {
- $this->setError('账户不正确');
- return false;
- }
-
- if ($user->status !== 1) {
- $this->setError('账户已经被锁定');
- return false;
- }
- if ($user->password != encrypt_password($password, $user->encrypt)) {
- $this->setError('密码不正确');
- return false;
- }
-
- //直接登录会员
- $this->direct($user->id);
-
- return true;
- }
-
- /**
- * 删除一个指定会员
- * @param int $user_id 会员ID
- * @return boolean
- */
- public function delete($user_id)
- {
- $user = Member_Model::get($user_id);
- if (!$user) {
- return false;
- }
- Db::startTrans();
- try {
- // 删除会员
- Member_Model::destroy($user_id);
- // 删除会员指定的所有Token
- Token::clear($user_id);
- Hook::listen("user_delete_successed", $user);
- Db::commit();
- } catch (Exception $e) {
- Db::rollback();
- $this->setError($e->getMessage());
- return false;
- }
- return true;
- }
-
- /**
- * 直接登录账号
- * @param int $user_id
- * @return boolean
- */
- public function direct($user_id)
- {
- $user = Member_Model::get($user_id);
- if ($user) {
- Db::startTrans();
- try {
- $ip = request()->ip();
- $time = time();
- //vip过期,更新vip和会员组
- if ($user->overduedate < $time && intval($user->vip)) {
- $user->vip = 0;
- }
- //检查用户积分,更新新用户组,除去邮箱认证、禁止访问、游客组用户、vip用户,如果该用户组不允许自助升级则不进行该操作
- if ($user->point >= 0 && !in_array($user->groupid, ['1', '7', '8']) && empty($user->vip)) {
- $grouplist = cache("Member_Group");
- if (!empty($grouplist[$user->groupid]['allowupgrade'])) {
- $check_groupid = $this->get_usergroup_bypoint($user->point);
- if ($check_groupid != $user->groupid) {
- $user->groupid = $check_groupid;
- }
- }
- }
- //记录本次登录的IP和时间
- $user->last_login_ip = $ip;
- $user->last_login_time = $time;
- $user->login = $user->login + 1;
- $user->save();
-
- $this->_user = $user;
- $this->_token = Random::uuid();
- Token::set($this->_token, $user->id, $this->keeptime);
- $this->_logined = true;
-
- //登录成功的事件
- Hook::listen("user_login_successed", $this->_user);
- Db::commit();
- } catch (Exception $e) {
- Db::rollback();
- $this->setError($e->getMessage());
- return false;
- }
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * 修改密码
- * @param string $newpassword 新密码
- * @param string $oldpassword 旧密码
- * @param bool $ignoreoldpassword 忽略旧密码
- * @return boolean
- */
- public function changepwd($newpassword, $oldpassword = '', $ignoreoldpassword = false)
- {
- if (!$this->_logined) {
- $this->setError('你当前还未登录');
- return false;
- }
- //判断旧密码是否正确
- if ($this->_user->password == encrypt_password($oldpassword, $this->_user->encrypt) || $ignoreoldpassword) {
- Db::startTrans();
- try {
- $encrypt = Random::alnum();
- $newpassword = encrypt_password($newpassword, $encrypt);
- $this->_user->save(['password' => $newpassword, 'encrypt' => $encrypt]);
- Token::delete($this->_token);
- //修改密码成功的事件
- Hook::listen("user_changepwd_successed", $this->_user);
- Db::commit();
- } catch (Exception $e) {
- Db::rollback();
- $this->setError($e->getMessage());
- return false;
- }
- return true;
- } else {
- $this->setError('密码不正确');
- return false;
- }
- }
-
- /**
- * 获取会员基本信息
- */
- public function getUserinfo()
- {
- $data = $this->_user->toArray();
- $allowFields = $this->getAllowFields();
- $userinfo = array_intersect_key($data, array_flip($allowFields));
- $userinfo = array_merge($userinfo, Token::get($this->_token));
- return $userinfo;
- }
-
- /**
- * 根据积分算出用户组
- * @param int $point 积分数
- * @return int|string|null
- */
- public function get_usergroup_bypoint($point = 0)
- {
- $groupid = 2;
- if (empty($point)) {
- //新会员默认点数
- $point = $this->config['defualtpoint'] ? $this->config['defualtpoint'] : 0;
- }
- //获取会有组缓存
- $grouplist = cache("Member_Group");
- foreach ($grouplist as $k => $v) {
- $grouppointlist[$k] = $v['point'];
- }
- //对数组进行逆向排序
- arsort($grouppointlist);
- //如果超出用户组积分设置则为积分最高的用户组
- if ($point > max($grouppointlist)) {
- $groupid = key($grouppointlist);
- } else {
- $tmp_k = key($grouppointlist);
- foreach ($grouppointlist as $k => $v) {
- if ($point >= $v) {
- $groupid = $tmp_k;
- break;
- }
- $tmp_k = $k;
- }
- }
- return $groupid;
- }
-
- /**
- * 检验用户是否已经登陆
- */
- public function isLogin()
- {
- if ($this->_logined) {
- return true;
- }
- return false;
- }
-
- /**
- * 获取允许输出的字段
- * @return array
- */
- public function getAllowFields()
- {
- return $this->allowFields;
- }
-
- /**
- * 设置允许输出的字段
- * @param array $fields
- */
- public function setAllowFields($fields)
- {
- $this->allowFields = $fields;
- }
-
- /**
- * 获取当前Token
- * @return string
- */
- public function getToken()
- {
- return $this->_token;
- }
-
- /**
- * 设置会话有效时间
- * @param int $keeptime 默认为永久
- */
- public function keeptime($keeptime = 0)
- {
- $this->keeptime = $keeptime;
- }
-
- /**
- * 注销登录状态
- * @return boolean
- */
- public function logout()
- {
- if (!$this->_logined) {
- $this->setError('你当前还未登录');
- return false;
- }
- //设置登录标识
- $this->_logined = false;
- //删除Token
- Token::delete($this->_token);
- //退出成功的事件
- Hook::listen("user_logout_successed", $this->_user);
- return true;
- }
-
- /**
- * 检测当前控制器和方法是否匹配传递的数组
- *
- * @param array $arr 需要验证权限的数组
- * @return boolean
- */
- public function match($arr = [])
- {
- $arr = is_array($arr) ? $arr : explode(',', $arr);
- if (!$arr) {
- return false;
- }
- $arr = array_map('strtolower', $arr);
- // 是否存在
- if (in_array(strtolower(request()->action()), $arr) || in_array('*', $arr)) {
- return true;
- }
- // 没找到匹配
- return false;
- }
-
- public function getConfig()
- {
- return $this->config;
- }
-
- /**
- * 设置错误信息
- *
- * @param $error 错误信息
- * @return Auth
- */
- public function setError($error)
- {
- $this->_error = $error;
- return $this;
- }
-
- /**
- * 获取错误信息
- * @return type
- */
- public function getError()
- {
- return $this->_error;
- }
-
- }
|