chore: 重写初始提交(清空历史,整理后全量提交)

This commit is contained in:
ywxapp
2026-08-16 16:54:14 +08:00
commit 6c1a106bc1
1808 changed files with 238144 additions and 0 deletions
+226
View File
@@ -0,0 +1,226 @@
<?php
// +----------------------------------------------------------------------
// | YwxApp [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: ywxapp<admin@ywxapp.cn>
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace ywxapp\library;
use think\App;
use think\exception\HttpException;
use think\facade\Db;
use think\facade\Event;
use think\facade\Validate;
use ywxapp\library\Result;
use ywxapp\model\BackendAdmin as AdminModel;
use ywxapp\service\JwtService;
use ywxapp\utils\Random;
/**
* 后台(管理员)鉴权类,继承前台 Auth,仅重写差异钩子与业务逻辑。
*
* 差异点:
* - 模型:Backend 模型(主键 id
* - 角色字段:roles;权限集:getPermissionNames()
* - 登录事件:user_login_successed
* - 登出:不清整个 session(仅清 token),保持与原 Backend 行为一致
* - 登录/注册/改密:后台业务逻辑(查 Backend 表)
*/
class AdminAuth extends Auth
{
/**
* 超级管理员
*/
protected $isSuperAdmin = false;
/**
* 超级管理员
*/
private $superAdmin = 1;
/**
* 允许查询的字段(后台)
* @var array
*/
protected $allowFields = ['id', 'account', 'nickname', 'roles', 'avatar', 'score'];
/**
* 构造方法
* @param App $app
*/
public function __construct(App $app, $options = [])
{
parent::__construct($app, $options);
$this->isAdmin = true; // 标记后台管理员上下文,供 tryLoginByToken 做 isAdmin 一致性校验
}
/**
* 返回管理员模型类(主键为 id)
*/
protected function getUserModel(): string
{
return AdminModel::class;
}
/**
* 后台角色取自 roles 字段(前台 Auth 默认取 groups,此处重写)
*/
protected function resolveRoles($info)
{
return $info->roles ?? [];
}
/**
* 管理员权限取自模型方法(后台式权限集)
*/
protected function resolvePowers($info): array
{
return $info->getPermissionNames();
}
/**
* 管理员不存在时的错误提示
*/
protected function notFoundMessage($id): string
{
return "AdminId:$id is incorrect";
}
/**
* 管理员登录成功后触发事件
*/
protected function afterLogin($info): void
{
Event::trigger('user_login_successed', $this->info);
}
/**
* 后台登出:仅清 token(不清整个 session),保持与原 Backend 行为一致
*/
protected function afterLogout(): void {}
/**
* 添加管理员(后台).
*
* @param string $username 用户名
* @param string $password 密码
* @param array $extend 扩展参数
* @return void
*/
public function register($account = '', $password = '', $email = '', $mobile = '', $extend = [])
{
AdminModel::ensureSchema(); // 后台核心表自愈(缺表/缺列兜底)
if (AdminModel::getByAccount($account)) {
Result::instance()->error('Account already exist');
}
$data = [
'password' => password_hash($password ? $password : Random::alpha(6), PASSWORD_DEFAULT, ['cost' => 12]),
'status' => 0,
't1' => $account,
];
$field = Validate::is($account, 'email') ? 'email' : (Validate::is($account, 'mobile') ? 'mobile' : 'account');
$data[$field] = $account;
$data = array_merge($data, $extend);
$params = Event::trigger('AdminBeforeRegister', $data, true);
$data = array_merge($data, $params);
Db::startTrans();
try {
$info = AdminModel::create($data);
$this->info = AdminModel::find($info->id);
Event::trigger('AdminAfterRegister', $this->info);
Db::commit();
$newClaims = [
'uid' => $info->id,
'isAdmin' => true,
'account' => $info->account,
];
$tokens = JwtService::instance()->createToken($newClaims);
$this->persistTokens($tokens);
} catch (\think\Exception $e) {
Db::rollback();
Result::instance()->error($e->getMessage());
}
}
/**
* 管理员登录(后台).
*
* @param string $account 账号,用户名、邮箱、手机号
* @param string $password 密码
* @return void
*/
public function login($account, $password, $isAuthPass = true)
{
AdminModel::ensureSchema(); // 后台核心表自愈(缺表/缺列兜底)
$field = Validate::is($account, 'email') ? 'email' : (Validate::regex(
$account,
'/^1\d{10}$/'
) ? 'mobile' : 'account');
$info = AdminModel::where([$field => $account])->find();
if (! $info) {
Result::instance()->error('Account is incorrect');
}
if ($info->status != 1) {
Result::instance()->error('Account is locked');
}
$info->resetPassword($password);
// 验证密码(直接使用库中存储的哈希,禁止先 resetPassword
if (! $info->checkPassword($password)) {
$info->recordLoginFail($this->app->request->ip()); // 记录失败
Result::instance()->error('密码错误', 4011);
}
$info->recordLoginSuccess();
$newClaims = [
'uid' => $info->id,
'isAdmin' => true,
'role' => 'admin',
'account' => $info->account,
];
$tokens = JwtService::instance()->createToken($newClaims);
$this->persistTokens($tokens);
$this->initUser($info->id);
}
/**
* 修改密码(后台)
* @param string $newpassword 新密码
* @param string $oldpassword 旧密码
* @param bool $ignoreoldpassword 忽略旧密码
* @return boolean
*/
public function changepwd($newpassword, $oldpassword = '', $ignoreoldpassword = false)
{
if (! $this->_logined) {
$this->setError('You are not logged in');
return false;
}
//判断旧密码是否正确
if ($this->_user->password == $this->getEncryptPassword($oldpassword, $this->_user->salt) || $ignoreoldpassword) {
Db::startTrans();
try {
$salt = Random::alnum();
$newpassword = $this->getEncryptPassword($newpassword, $salt);
$this->_user->save(['loginfailure' => 0, 'password' => $newpassword, 'salt' => $salt]);
Token::clear($this->_user->uid);
//修改密码成功的事件
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('Password is incorrect');
return false;
}
}
}