diff --git a/app/admin/library/Auth.php b/app/admin/library/Auth.php index ee97aa74..9accc5f2 100644 --- a/app/admin/library/Auth.php +++ b/app/admin/library/Auth.php @@ -2,56 +2,72 @@ namespace app\admin\library; +use Throwable; use ba\Random; -use think\Exception; use think\facade\Db; use think\facade\Config; use app\admin\model\Admin; use app\common\facade\Token; use app\admin\model\AdminGroup; -use think\db\exception\DbException; -use think\db\exception\PDOException; -use think\db\exception\DataNotFoundException; -use think\db\exception\ModelNotFoundException; /** * 管理员权限类 + * + * @property int $id 管理员ID + * @property string $username 管理员用户名 + * @property string $nickname 管理员昵称 + * @property string $email 管理员邮箱 + * @property string $mobile 管理员手机号 */ class Auth extends \ba\Auth { /** - * @var Auth 对象实例 + * 对象实例 + * @var ?Auth */ - protected static $instance; + protected static ?Auth $instance = null; /** - * @var bool 是否登录 + * 是否登录 + * @var bool */ - protected $logined = false; + protected bool $loginEd = false; + /** - * @var string 错误消息 + * 错误消息 + * @var string */ - protected $error = ''; + protected string $error = ''; + /** - * @var Admin Model实例 + * Model实例 + * @var ?Admin */ - protected $model = null; + protected ?Admin $model = null; + /** - * @var string 令牌 + * 令牌 + * @var string */ - protected $token = ''; + protected string $token = ''; + /** - * @var string 刷新令牌 + * 刷新令牌 + * @var string */ - protected $refreshToken = ''; + protected string $refreshToken = ''; + /** - * @var int 令牌默认有效期 + * 令牌默认有效期 + * @var int */ - protected $keeptime = 86400; + protected int $keepTime = 86400; + /** - * @var string[] 允许输出的字段 + * 允许输出的字段 + * @var array */ - protected $allowFields = ['id', 'username', 'nickname', 'avatar', 'last_login_time']; + protected array $allowFields = ['id', 'username', 'nickname', 'avatar', 'last_login_time']; public function __construct(array $config = []) { @@ -61,17 +77,17 @@ class Auth extends \ba\Auth /** * 魔术方法-管理员信息字段 * @param $name - * @return null|string 字段信息 + * @return mixed 字段信息 */ - public function __get($name) + public function __get($name): mixed { - return $this->model ? $this->model->$name : null; + return $this->model?->$name; } /** * 初始化 * @access public - * @param array $options 参数 + * @param array $options 传递到 /ba/Auth 的配置信息 * @return Auth */ public static function instance(array $options = []): Auth @@ -85,15 +101,13 @@ class Auth extends \ba\Auth /** * 根据Token初始化管理员登录态 - * @param $token + * @param string $token * @return bool - * @throws DataNotFoundException - * @throws DbException - * @throws ModelNotFoundException + * @throws Throwable */ - public function init($token): bool + public function init(string $token): bool { - if ($this->logined) { + if ($this->loginEd) { return true; } if ($this->error) { @@ -127,20 +141,18 @@ class Auth extends \ba\Auth * 管理员登录 * @param string $username * @param string $password - * @param bool $keeptime + * @param bool $keepTime * @return bool - * @throws DataNotFoundException - * @throws DbException - * @throws ModelNotFoundException + * @throws Throwable */ - public function login(string $username, string $password, bool $keeptime = false): bool + public function login(string $username, string $password, bool $keepTime = false): bool { $this->model = Admin::where('username', $username)->find(); if (!$this->model) { $this->setError('Username is incorrect'); return false; } - if ($this->model['status'] == '0') { + if ($this->model->status == '0') { $this->setError('Account disabled'); return false; } @@ -159,7 +171,7 @@ class Auth extends \ba\Auth Token::clear('admin-refresh', $this->model->id); } - if ($keeptime) { + if ($keepTime) { $this->setRefreshToken(2592000); } $this->loginSuccessful(); @@ -168,12 +180,12 @@ class Auth extends \ba\Auth /** * 设置刷新Token - * @param int $keeptime + * @param int $keepTime */ - public function setRefreshToken(int $keeptime = 0) + public function setRefreshToken(int $keepTime = 0) { $this->refreshToken = Random::uuid(); - Token::set($this->refreshToken, 'admin-refresh', $this->model->id, $keeptime); + Token::set($this->refreshToken, 'admin-refresh', $this->model->id, $keepTime); } /** @@ -185,21 +197,21 @@ class Auth extends \ba\Auth if (!$this->model) { return false; } - Db::startTrans(); + $this->model->startTrans(); try { $this->model->login_failure = 0; $this->model->last_login_time = time(); $this->model->last_login_ip = request()->ip(); $this->model->save(); - $this->logined = true; + $this->loginEd = true; if (!$this->token) { $this->token = Random::uuid(); - Token::set($this->token, 'admin', $this->model->id, $this->keeptime); + Token::set($this->token, 'admin', $this->model->id, $this->keepTime); } - Db::commit(); - } catch (PDOException|Exception $e) { - Db::rollback(); + $this->model->commit(); + } catch (Throwable $e) { + $this->model->rollback(); $this->setError($e->getMessage()); return false; } @@ -215,7 +227,7 @@ class Auth extends \ba\Auth if (!$this->model) { return false; } - Db::startTrans(); + $this->model->startTrans(); try { $this->model->login_failure++; $this->model->last_login_time = time(); @@ -224,10 +236,10 @@ class Auth extends \ba\Auth $this->token = ''; $this->model = null; - $this->logined = false; - Db::commit(); - } catch (PDOException|Exception $e) { - Db::rollback(); + $this->loginEd = false; + $this->model->commit(); + } catch (Throwable $e) { + $this->model->rollback(); $this->setError($e->getMessage()); return false; } @@ -240,11 +252,11 @@ class Auth extends \ba\Auth */ public function logout(): bool { - if (!$this->logined) { + if (!$this->loginEd) { $this->setError('You are not logged in'); return false; } - $this->logined = false; + $this->loginEd = false; Token::delete($this->token); $this->token = ''; return true; @@ -256,7 +268,7 @@ class Auth extends \ba\Auth */ public function isLogin(): bool { - return $this->logined; + return $this->loginEd; } /** @@ -304,7 +316,7 @@ class Auth extends \ba\Auth /** * 获取允许输出字段 - * @return string[] + * @return array */ public function getAllowFields(): array { @@ -314,19 +326,21 @@ class Auth extends \ba\Auth /** * 设置允许输出字段 * @param $fields + * @return void */ - public function setAllowFields($fields) + public function setAllowFields($fields): void { $this->allowFields = $fields; } /** * 设置Token有效期 - * @param int $keeptime + * @param int $keepTime + * @return void */ - public function setKeeptime(int $keeptime = 0) + public function setKeepTime(int $keepTime = 0): void { - $this->keeptime = $keeptime; + $this->keepTime = $keepTime; } public function check(string $name, int $uid = 0, string $relation = 'or', string $mode = 'url'): bool @@ -354,6 +368,10 @@ class Auth extends \ba\Auth return parent::getMenus($uid ?: $this->id); } + /** + * 是否是超级管理员 + * @throws Throwable + */ public function isSuperAdmin(): bool { return in_array('*', $this->getRuleIds()); @@ -362,9 +380,7 @@ class Auth extends \ba\Auth /** * 获取管理员所在分组的所有子级分组 * @return array - * @throws DataNotFoundException - * @throws DbException - * @throws ModelNotFoundException + * @throws Throwable */ public function getAdminChildGroups(): array { @@ -378,9 +394,18 @@ class Auth extends \ba\Auth return array_unique($children); } - public function getGroupChildGroups($groupId, &$children) + /** + * 获取一个分组下的子分组 + * @param int $groupId 分组ID + * @param array $children 存放子分组的变量 + * @return void + * @throws Throwable + */ + public function getGroupChildGroups(int $groupId, array &$children): void { - $childrenTemp = AdminGroup::where('pid', $groupId)->where('status', '1')->select(); + $childrenTemp = AdminGroup::where('pid', $groupId) + ->where('status', '1') + ->select(); foreach ($childrenTemp as $item) { $children[] = $item['id']; $this->getGroupChildGroups($item['id'], $children); @@ -403,9 +428,7 @@ class Auth extends \ba\Auth * 获取拥有"所有权限"的分组 * @param string $dataLimit 数据权限 * @return array 分组数组 - * @throws DataNotFoundException - * @throws DbException - * @throws ModelNotFoundException + * @throws Throwable */ public function getAllAuthGroups(string $dataLimit): array { @@ -439,7 +462,7 @@ class Auth extends \ba\Auth /** * 设置错误消息 * @param $error - * @return $this + * @return Auth */ public function setError($error): Auth { @@ -449,9 +472,9 @@ class Auth extends \ba\Auth /** * 获取错误消息 - * @return float|int|string + * @return string */ - public function getError() + public function getError(): string { return $this->error ? __($this->error) : ''; } diff --git a/app/admin/model/Admin.php b/app/admin/model/Admin.php index 4aa02a76..002955e5 100644 --- a/app/admin/model/Admin.php +++ b/app/admin/model/Admin.php @@ -9,6 +9,14 @@ use think\facade\Config; /** * Admin模型 + * @property int $id 管理员ID + * @property string $username 管理员用户名 + * @property string $nickname 管理员昵称 + * @property string $email 管理员邮箱 + * @property string $mobile 管理员手机号 + * @property string $last_login_ip 上次登录IP + * @property string $last_login_time 上次登录时间 + * @property int $login_failure 登录失败次数 */ class Admin extends Model { diff --git a/app/common/library/Auth.php b/app/common/library/Auth.php index 3059775b..03fe7382 100644 --- a/app/common/library/Auth.php +++ b/app/common/library/Auth.php @@ -2,63 +2,71 @@ namespace app\common\library; +use Throwable; use ba\Random; -use think\Exception; -use think\facade\Db; use think\facade\Event; use think\facade\Config; use app\common\model\User; use think\facade\Validate; use app\common\facade\Token; -use think\db\exception\DbException; -use think\db\exception\PDOException; -use think\db\exception\DataNotFoundException; -use think\db\exception\ModelNotFoundException; /** * 公共权限类(会员权限类) + * @property int $id 会员ID + * @property string $username 会员用户名 + * @property string $nickname 会员昵称 + * @property string $email 会员邮箱 + * @property string $mobile 会员手机号 */ class Auth extends \ba\Auth { /** - * @var Auth 对象实例 + * 对象实例 + * @var ?Auth */ - protected static $instance; + protected static ?Auth $instance = null; /** - * @var bool 是否登录 + * 是否登录 + * @var bool */ - protected $logined = false; + protected bool $loginEd = false; /** - * @var string 错误消息 + * 错误消息 + * @var string */ - protected $error = ''; + protected string $error = ''; /** - * @var User Model实例 + * Model实例 + * @var ?User */ - protected $model = null; + protected ?User $model = null; /** - * @var string 令牌 + * 令牌 + * @var string */ - protected $token = ''; + protected string $token = ''; /** - * @var string 刷新令牌 + * 刷新令牌 + * @var string */ - protected $refreshToken = ''; + protected string $refreshToken = ''; /** - * @var int 令牌默认有效期 + * 令牌默认有效期 + * @var int */ - protected $keeptime = 86400; + protected int $keepTime = 86400; /** - * @var string[] 允许输出的字段 + * 允许输出的字段 + * @var array */ - protected $allowFields = ['id', 'username', 'nickname', 'email', 'mobile', 'avatar', 'gender', 'birthday', 'money', 'score', 'join_time', 'motto', 'last_login_time', 'last_login_ip']; + protected array $allowFields = ['id', 'username', 'nickname', 'email', 'mobile', 'avatar', 'gender', 'birthday', 'money', 'score', 'join_time', 'motto', 'last_login_time', 'last_login_ip']; public function __construct(array $config = []) { @@ -72,17 +80,17 @@ class Auth extends \ba\Auth /** * 魔术方法-会员信息字段 * @param $name - * @return null|string 字段信息 + * @return mixed 字段信息 */ - public function __get($name) + public function __get($name): mixed { - return $this->model ? $this->model->$name : null; + return $this->model?->$name; } /** * 初始化 * @access public - * @param array $options 参数 + * @param array $options 传递给 /ba/Auth 的参数 * @return Auth */ public static function instance(array $options = []): Auth @@ -98,13 +106,11 @@ class Auth extends \ba\Auth * 根据Token初始化会员登录态 * @param $token * @return bool - * @throws DataNotFoundException - * @throws DbException - * @throws ModelNotFoundException + * @throws Throwable */ public function init($token): bool { - if ($this->logined) { + if ($this->loginEd) { return true; } if ($this->error) { @@ -121,7 +127,7 @@ class Auth extends \ba\Auth $this->setError('Account not exist'); return false; } - if ($this->model['status'] != 'enable') { + if ($this->model->status != 'enable') { $this->setError('Account disabled'); return false; } @@ -179,16 +185,16 @@ class Auth extends \ba\Auth ]; $data = array_merge($params, $data); $data = array_merge($data, $extend); - Db::startTrans(); + $this->model->startTrans(); try { $this->model = User::create($data); $this->token = Random::uuid(); - Token::set($this->token, 'user', $this->model->id, $this->keeptime); - Event::trigger('userRegisterSuccessed', $this->model); - Db::commit(); - } catch (PDOException|Exception $e) { + Token::set($this->token, 'user', $this->model->id, $this->keepTime); + $this->model->commit(); + Event::trigger('userRegisterSuccess', $this->model); + } catch (Throwable $e) { $this->setError($e->getMessage()); - Db::rollback(); + $this->model->rollback(); return false; } return true; @@ -198,13 +204,11 @@ class Auth extends \ba\Auth * 会员登录 * @param string $username * @param string $password - * @param bool $keeptime + * @param bool $keepTime * @return bool - * @throws DataNotFoundException - * @throws DbException - * @throws ModelNotFoundException + * @throws Throwable */ - public function login(string $username, string $password, bool $keeptime): bool + public function login(string $username, string $password, bool $keepTime): bool { // 判断账户类型 $accountType = false; @@ -226,7 +230,7 @@ class Auth extends \ba\Auth $this->setError('Account not exist'); return false; } - if ($this->model['status'] == 'disable') { + if ($this->model->status == 'disable') { $this->setError('Account disabled'); return false; } @@ -245,7 +249,7 @@ class Auth extends \ba\Auth Token::clear('user-refresh', $this->model->id); } - if ($keeptime) { + if ($keepTime) { $this->setRefreshToken(2592000); } $this->loginSuccessful(); @@ -256,9 +260,7 @@ class Auth extends \ba\Auth * 直接登录会员账号 * @param int $userId 用户ID * @return bool - * @throws DataNotFoundException - * @throws DbException - * @throws ModelNotFoundException + * @throws Throwable */ public function direct(int $userId): bool { @@ -294,21 +296,21 @@ class Auth extends \ba\Auth if (!$this->model) { return false; } - Db::startTrans(); + $this->model->startTrans(); try { $this->model->login_failure = 0; $this->model->last_login_time = time(); $this->model->last_login_ip = request()->ip(); $this->model->save(); - $this->logined = true; + $this->loginEd = true; if (!$this->token) { $this->token = Random::uuid(); - Token::set($this->token, 'user', $this->model->id, $this->keeptime); + Token::set($this->token, 'user', $this->model->id, $this->keepTime); } - Db::commit(); - } catch (PDOException|Exception $e) { - Db::rollback(); + $this->model->commit(); + } catch (Throwable $e) { + $this->model->rollback(); $this->setError($e->getMessage()); return false; } @@ -324,7 +326,7 @@ class Auth extends \ba\Auth if (!$this->model) { return false; } - Db::startTrans(); + $this->model->startTrans(); try { $this->model->login_failure++; $this->model->last_login_time = time(); @@ -333,10 +335,10 @@ class Auth extends \ba\Auth $this->token = ''; $this->model = null; - $this->logined = false; - Db::commit(); - } catch (PDOException|Exception $e) { - Db::rollback(); + $this->loginEd = false; + $this->model->commit(); + } catch (Throwable $e) { + $this->model->rollback(); $this->setError($e->getMessage()); return false; } @@ -349,11 +351,11 @@ class Auth extends \ba\Auth */ public function logout(): bool { - if (!$this->logined) { + if (!$this->loginEd) { $this->setError('You are not logged in'); return false; } - $this->logined = false; + $this->loginEd = false; Token::delete($this->token); $this->token = ''; return true; @@ -365,7 +367,7 @@ class Auth extends \ba\Auth */ public function isLogin(): bool { - return $this->logined; + return $this->loginEd; } /** @@ -388,12 +390,13 @@ class Auth extends \ba\Auth /** * 设置刷新Token - * @param int $keeptime + * @param int $keepTime + * @return void */ - public function setRefreshToken(int $keeptime = 0) + public function setRefreshToken(int $keepTime = 0): void { $this->refreshToken = Random::uuid(); - Token::set($this->refreshToken, 'user-refresh', $this->model->id, $keeptime); + Token::set($this->refreshToken, 'user-refresh', $this->model->id, $keepTime); } /** @@ -423,7 +426,7 @@ class Auth extends \ba\Auth /** * 获取允许输出字段 - * @return string[] + * @return array */ public function getAllowFields(): array { @@ -433,19 +436,21 @@ class Auth extends \ba\Auth /** * 设置允许输出字段 * @param $fields + * @return void */ - public function setAllowFields($fields) + public function setAllowFields($fields): void { $this->allowFields = $fields; } /** * 设置Token有效期 - * @param int $keeptime + * @param int $keepTime + * @return void */ - public function setKeeptime(int $keeptime = 0) + public function setKeepTime(int $keepTime = 0): void { - $this->keeptime = $keeptime; + $this->keepTime = $keepTime; } public function check(string $name, int $uid = 0, string $relation = 'or', string $mode = 'url'): bool @@ -468,6 +473,11 @@ class Auth extends \ba\Auth return parent::getMenus($uid ?: $this->id); } + /** + * 是否是拥有所有权限的会员 + * @return bool + * @throws Throwable + */ public function isSuperUser(): bool { return in_array('*', $this->getRuleIds()); @@ -475,10 +485,10 @@ class Auth extends \ba\Auth /** * 设置错误消息 - * @param $error - * @return $this + * @param string $error + * @return Auth */ - public function setError($error): Auth + public function setError(string $error): Auth { $this->error = $error; return $this; @@ -486,9 +496,9 @@ class Auth extends \ba\Auth /** * 获取错误消息 - * @return float|int|string + * @return string */ - public function getError() + public function getError(): string { return $this->error ? __($this->error) : ''; } diff --git a/app/common/model/User.php b/app/common/model/User.php index 8569d41d..06c61903 100644 --- a/app/common/model/User.php +++ b/app/common/model/User.php @@ -6,6 +6,15 @@ use ba\Random; use think\Model; use think\facade\Config; +/** + * 会员公共模型 + * @property int $id 会员ID + * @property string $password 密码密文 + * @property string $salt 密码盐 + * @property int $login_failure 登录失败次数 + * @property string $last_login_time 上次登录时间 + * @property string $last_login_ip 上次登录IP + */ class User extends Model { protected $autoWriteTimestamp = true; diff --git a/extend/ba/Auth.php b/extend/ba/Auth.php index 48d636ce..6ce19375 100644 --- a/extend/ba/Auth.php +++ b/extend/ba/Auth.php @@ -2,10 +2,8 @@ namespace ba; +use Throwable; use think\facade\Db; -use think\db\exception\DbException; -use think\db\exception\DataNotFoundException; -use think\db\exception\ModelNotFoundException; /** * 权限规则检测类 @@ -15,13 +13,13 @@ class Auth /** * 用户有权限的规则节点 */ - protected $rules = []; + protected array $rules = []; /** * 默认配置 * @var array|string[] */ - protected $config = [ + protected array $config = [ 'auth_group' => 'admin_group', // 用户组数据表名 'auth_group_access' => 'admin_group_access', // 用户-用户组关系表 'auth_rule' => 'admin_rule', // 权限规则表 @@ -31,9 +29,10 @@ class Auth * 子菜单规则数组 * @var array */ - protected $childrens = []; + protected array $children = []; /** + * 构造方法 * @param array $config */ public function __construct(array $config = []) @@ -42,10 +41,11 @@ class Auth } /** + * 魔术方法-获取当前配置 * @param $name - * @return mixed|string + * @return mixed */ - public function __get($name) + public function __get($name): mixed { return $this->config[$name]; } @@ -55,37 +55,37 @@ class Auth * @access public * @param int $uid 用户ID * @return array - * @throws DataNotFoundException - * @throws DbException - * @throws ModelNotFoundException + * @throws Throwable */ public function getMenus(int $uid): array { if (!$this->rules) { $this->getRuleList($uid); } - if (!$this->rules) { - return []; - } + if (!$this->rules) return []; + foreach ($this->rules as $rule) { - $this->childrens[$rule['pid']][] = $rule; + $this->children[$rule['pid']][] = $rule; } - if (!isset($this->childrens[0])) { + + // 没有根菜单规则 + if (!isset($this->children[0])) { return []; } - return $this->getChildren($this->childrens[0]); + return $this->getChildren($this->children[0]); } /** - * 获取数组中所有菜单规则的子规则 + * 获取传递的菜单规则的子规则 * @param array $rules 菜单规则 + * @return array */ private function getChildren(array $rules): array { foreach ($rules as $key => $rule) { - if (array_key_exists($rule['id'], $this->childrens)) { - $rules[$key]['children'] = $this->getChildren($this->childrens[$rule['id']]); + if (array_key_exists($rule['id'], $this->children)) { + $rules[$key]['children'] = $this->getChildren($this->children[$rule['id']]); } } return $rules; @@ -98,21 +98,19 @@ class Auth * @param string $relation 如果出现两个 name,是两个都通过(and)还是一个通过即可(or) * @param string $mode 如果不使用 url 则菜单规则name匹配到即通过 * @return bool - * @throws DataNotFoundException - * @throws DbException - * @throws ModelNotFoundException + * @throws Throwable */ public function check(string $name, int $uid, string $relation = 'or', string $mode = 'url'): bool { // 获取用户需要验证的所有有效规则列表 - $rulelist = $this->getRuleList($uid); - if (in_array('*', $rulelist)) { + $ruleList = $this->getRuleList($uid); + if (in_array('*', $ruleList)) { return true; } if ($name) { $name = strtolower($name); - if (strpos($name, ',') !== false) { + if (str_contains($name, ',')) { $name = explode(',', $name); } else { $name = [$name]; @@ -122,7 +120,7 @@ class Auth if ('url' == $mode) { $REQUEST = json_decode(strtolower(json_encode(request()->param(), JSON_UNESCAPED_UNICODE)), true); } - foreach ($rulelist as $rule) { + foreach ($ruleList as $rule) { $query = preg_replace('/^.+\?/U', '', $rule); if ('url' == $mode && $query != $rule) { parse_str($query, $param); //解析规则中的param @@ -153,9 +151,7 @@ class Auth * 获得权限规则列表 * @param int $uid 用户id * @return array - * @throws DataNotFoundException - * @throws DbException - * @throws ModelNotFoundException + * @throws Throwable */ public function getRuleList(int $uid): array { @@ -182,7 +178,8 @@ class Auth ->withoutField(['remark', 'status', 'weigh', 'update_time', 'create_time']) ->where($where) ->order('weigh desc,id asc') - ->select()->toArray(); + ->select() + ->toArray(); // 用户规则 $rules = []; @@ -203,9 +200,7 @@ class Auth * 获取权限规则ids * @param int $uid * @return array - * @throws DataNotFoundException - * @throws DbException - * @throws ModelNotFoundException + * @throws Throwable */ public function getRuleIds(int $uid): array { @@ -222,9 +217,7 @@ class Auth * 获取用户所有分组和对应权限规则 * @param int $uid * @return array - * @throws DataNotFoundException - * @throws DbException - * @throws ModelNotFoundException + * @throws Throwable */ public function getGroups(int $uid): array { @@ -239,14 +232,16 @@ class Auth ->join($this->config['auth_group'] . ' ag', 'aga.group_id = ag.id', 'LEFT') ->field('aga.uid,aga.group_id,ag.id,ag.pid,ag.name,ag.rules') ->where("aga.uid='$uid' and ag.status='1'") - ->select()->toArray(); + ->select() + ->toArray(); } else { $userGroups = Db::name('user') ->alias('u') ->join($this->config['auth_group'] . ' ag', 'u.group_id = ag.id', 'LEFT') ->field('u.id as uid,u.group_id,ag.id,ag.name,ag.rules') ->where("u.id='$uid' and ag.status='1'") - ->select()->toArray(); + ->select() + ->toArray(); } $groups[$uid] = $userGroups ?: [];