13 changed files with 667 additions and 3 deletions
-
93plugin/piadmin/app/controller/v1/ProxyMenuController.php
-
30plugin/piadmin/app/controller/v1/ProxyUserLoginController.php
-
17plugin/piadmin/app/dao/ProxyMenuDao.php
-
17plugin/piadmin/app/dao/ProxyUserDao.php
-
82plugin/piadmin/app/middleware/ProxyUserAuthorizationMiddleware.php
-
16plugin/piadmin/app/model/ProxyMenu.php
-
21plugin/piadmin/app/model/ProxyUser.php
-
21plugin/piadmin/app/route/v1/proxy.php
-
13plugin/piadmin/app/route/v1/route.php
-
222plugin/piadmin/app/service/ProxyMenuService.php
-
130plugin/piadmin/app/service/ProxyUserService.php
-
6plugin/piadmin/config/piadmin.php
-
2plugin/piadmin/config/route.php
@ -0,0 +1,93 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace plugin\piadmin\app\controller\v1; |
||||
|
|
||||
|
use plugin\piadmin\app\base\BaseController; |
||||
|
use plugin\piadmin\app\service\ProxyMenuService; |
||||
|
use plugin\piadmin\app\validate\MenuValidate; |
||||
|
use support\Request; |
||||
|
|
||||
|
class ProxyMenuController extends BaseController |
||||
|
{ |
||||
|
|
||||
|
public function __construct() |
||||
|
{ |
||||
|
parent::__construct(); |
||||
|
$this->service = app()->make(ProxyMenuService::class); |
||||
|
} |
||||
|
|
||||
|
public function index(Request $request) |
||||
|
{ |
||||
|
|
||||
|
$all = $request->all(); |
||||
|
|
||||
|
$list = $this->service->getMenuList($all); |
||||
|
|
||||
|
return success($list); |
||||
|
} |
||||
|
|
||||
|
public function save(Request $request) |
||||
|
{ |
||||
|
$params = requestOnly([ |
||||
|
'pid' => 0, |
||||
|
'name' => '', |
||||
|
'code' => '', |
||||
|
'icon' => '', |
||||
|
'route' => '', |
||||
|
'component' => '', |
||||
|
'redirect' => '', |
||||
|
'is_hidden' => 2, |
||||
|
'is_layout' => 2, |
||||
|
'type' => '', |
||||
|
'status' => 1, |
||||
|
'sort' => 1000, |
||||
|
'remark' => '' |
||||
|
]); |
||||
|
validate(MenuValidate::class)->scene('save')->check($params); |
||||
|
$res = $this->service->saveData($params); |
||||
|
return success($res); |
||||
|
} |
||||
|
|
||||
|
public function update(Request $request) |
||||
|
{ |
||||
|
$params = requestOnly([ |
||||
|
'id' => '', |
||||
|
'pid' => 0, |
||||
|
'name' => '', |
||||
|
'code' => '', |
||||
|
'icon' => '', |
||||
|
'route' => '', |
||||
|
'component' => '', |
||||
|
'redirect' => '', |
||||
|
'is_hidden' => 2, |
||||
|
'is_layout' => 2, |
||||
|
'type' => '', |
||||
|
'status' => 1, |
||||
|
'sort' => 1000, |
||||
|
'remark' => '' |
||||
|
]); |
||||
|
validate(MenuValidate::class)->scene('update')->check($params); |
||||
|
$res = $this->service->updateData($params); |
||||
|
return success($res); |
||||
|
} |
||||
|
|
||||
|
public function delete(Request $request) |
||||
|
{ |
||||
|
$ids = $request->input('ids'); |
||||
|
$res = $this->service->deleteData($ids); |
||||
|
return success($res); |
||||
|
} |
||||
|
|
||||
|
public function read(Request $request) |
||||
|
{ |
||||
|
$id = $request->input('id'); |
||||
|
$res = $this->service->readData($id); |
||||
|
return success($res); |
||||
|
} |
||||
|
|
||||
|
public function getProxyMenuPermissions() |
||||
|
{ |
||||
|
return success($this->service->getUserMenu()); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace plugin\piadmin\app\controller\v1; |
||||
|
|
||||
|
use plugin\piadmin\app\base\BaseController; |
||||
|
use plugin\piadmin\app\service\ProxyUserService; |
||||
|
use plugin\piadmin\app\validate\LoginValidate; |
||||
|
use support\Request; |
||||
|
|
||||
|
class ProxyUserLoginController extends BaseController |
||||
|
{ |
||||
|
|
||||
|
public function __construct() |
||||
|
{ |
||||
|
parent::__construct(); |
||||
|
$this->service = app()->make(ProxyUserService::class); |
||||
|
} |
||||
|
|
||||
|
public function login(Request $request){ |
||||
|
$params = $request->only([ |
||||
|
'username', |
||||
|
'password' |
||||
|
]); |
||||
|
validate(LoginValidate::class)->scene('loginByPassword')->check($params); |
||||
|
// 用户登录
|
||||
|
$res = $this->service->login($params); |
||||
|
return success($res); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace plugin\piadmin\app\dao; |
||||
|
|
||||
|
use plugin\piadmin\app\base\BaseDao; |
||||
|
use plugin\piadmin\app\model\ProxyMenu; |
||||
|
|
||||
|
class ProxyMenuDao extends BaseDao |
||||
|
{ |
||||
|
|
||||
|
protected function setModel(): string |
||||
|
{ |
||||
|
return ProxyMenu::class; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace plugin\piadmin\app\dao; |
||||
|
|
||||
|
use plugin\piadmin\app\base\BaseDao; |
||||
|
use plugin\piadmin\app\model\ProxyUser; |
||||
|
|
||||
|
class ProxyUserDao extends BaseDao |
||||
|
{ |
||||
|
|
||||
|
protected function setModel(): string |
||||
|
{ |
||||
|
return ProxyUser::class; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,82 @@ |
|||||
|
<?php |
||||
|
namespace plugin\piadmin\app\middleware; |
||||
|
|
||||
|
use Firebase\JWT\JWT; |
||||
|
use Firebase\JWT\Key; |
||||
|
use plugin\piadmin\app\dao\ProxyUserDao; |
||||
|
use plugin\piadmin\app\exception\ApiException; |
||||
|
use plugin\piadmin\app\utils\CacheUtils; |
||||
|
use support\Context; |
||||
|
use Webman\Http\Request; |
||||
|
use Webman\Http\Response; |
||||
|
use Webman\MiddlewareInterface; |
||||
|
|
||||
|
class ProxyUserAuthorizationMiddleware implements MiddlewareInterface |
||||
|
{ |
||||
|
public function process(Request $request, callable $handler) : Response |
||||
|
{ |
||||
|
$authHeader = config('plugin.piadmin.piadmin.jwt.proxy.auth_header'); |
||||
|
$token = $request->header($authHeader, ''); |
||||
|
if (empty($token)) { |
||||
|
throw new ApiException(403); |
||||
|
} |
||||
|
$token = trim(str_replace('Bearer ', '', $token)); |
||||
|
// 解token payload
|
||||
|
$key = config("plugin.piadmin.piadmin.jwt.proxy.key"); |
||||
|
$keyId = config("plugin.piadmin.piadmin.jwt.proxy.key_id"); |
||||
|
$payload = JWT::decode($token, new Key($key, 'HS256')); |
||||
|
if (empty($token)) { |
||||
|
throw new ApiException(403); |
||||
|
} |
||||
|
// 缓存
|
||||
|
$tokenCacheData = CacheUtils::get('proxy.token.'. md5($token)); |
||||
|
|
||||
|
if (empty($tokenCacheData)) { |
||||
|
throw new ApiException(403); |
||||
|
} |
||||
|
$tokenCacheData = json_decode($tokenCacheData, true); |
||||
|
if (empty($tokenCacheData) || !isset($tokenCacheData['uid'])) { |
||||
|
throw new ApiException(403); |
||||
|
} |
||||
|
// 验证账号状态
|
||||
|
$uid = $tokenCacheData['uid']; |
||||
|
$userDao = app()->make(ProxyUserDao::class); |
||||
|
$user = $userDao->getOne(['id' => $uid]); |
||||
|
if (empty($user)) { |
||||
|
throw new ApiException(403); |
||||
|
} |
||||
|
if ($user['status'] != 1 ) { |
||||
|
throw new ApiException(400006); |
||||
|
} |
||||
|
$proxyUserInfo = $user->toArray(); |
||||
|
$proxyUserInfo['is_login'] = true; |
||||
|
$proxyUserInfo['uid'] = $proxyUserInfo['id']; |
||||
|
$proxyUserInfo['token'] = $token; |
||||
|
//数据权限,目前只查自己
|
||||
|
$proxyUserInfo['dataPermission'] = [$proxyUserInfo['id']]; |
||||
|
// 检查版本
|
||||
|
$this->checkVersionKey($uid, $token); |
||||
|
$request->proxy_user = $proxyUserInfo; |
||||
|
// todo 补全session
|
||||
|
Context::set('proxy_user', $proxyUserInfo); |
||||
|
// session('user', $userInfo);
|
||||
|
return $handler($request); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 版本检查 |
||||
|
* @param string|int $uid |
||||
|
* @param string $token |
||||
|
* @return void |
||||
|
* @throws ApiException |
||||
|
*/ |
||||
|
private function checkVersionKey(string|int $uid, string $token): void |
||||
|
{ |
||||
|
$userVersionKey = "user.version.{$uid}"; |
||||
|
$version = CacheUtils::get($userVersionKey); |
||||
|
if ($version != getPiAdminVersion()) { |
||||
|
CacheUtils::delete(md5($token)); |
||||
|
throw new ApiException(403); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace plugin\piadmin\app\model; |
||||
|
|
||||
|
use plugin\piadmin\app\base\BaseModel; |
||||
|
use think\model\concern\SoftDelete; |
||||
|
|
||||
|
class ProxyMenu extends BaseModel |
||||
|
{ |
||||
|
protected $table = 'pi_proxy_menu'; |
||||
|
|
||||
|
use SoftDelete; |
||||
|
protected string $deleteTime = 'delete_time'; |
||||
|
|
||||
|
protected $defaultSoftDelete = 0; |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace plugin\piadmin\app\model; |
||||
|
|
||||
|
use plugin\piadmin\app\base\BaseModel; |
||||
|
use think\model\concern\SoftDelete; |
||||
|
|
||||
|
class ProxyUser extends BaseModel |
||||
|
{ |
||||
|
protected $table = 'pi_proxy_user'; |
||||
|
|
||||
|
protected $hidden = ['password']; |
||||
|
|
||||
|
use SoftDelete; |
||||
|
protected string $deleteTime = 'delete_time'; |
||||
|
|
||||
|
protected $defaultSoftDelete = 0; |
||||
|
|
||||
|
protected $append = []; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use plugin\piadmin\app\controller\v1\ProxyMenuController; |
||||
|
use plugin\piadmin\app\controller\v1\ProxyUserLoginController; |
||||
|
use plugin\piadmin\app\middleware\ProxyUserAuthorizationMiddleware; |
||||
|
use Webman\Route; |
||||
|
|
||||
|
// 不需要登录的接口
|
||||
|
Route::group('/piadmin/v1/proxy', function () { |
||||
|
//账号密码登录
|
||||
|
Route::post('/login', [ProxyUserLoginController::class, 'login'])->setParams(['perm' => ['userLogin']]); |
||||
|
}); |
||||
|
|
||||
|
// 需要登录的接口
|
||||
|
Route::group('/piadmin/v1/proxy', function () { |
||||
|
// 获取当前用户菜单权限
|
||||
|
Route::get('/getMenuPermissions', [ProxyMenuController::class, 'getProxyMenuPermissions'])->setParams(['perm' => ['getProxyMenuPermissions']]); |
||||
|
|
||||
|
})->middleware([ |
||||
|
ProxyUserAuthorizationMiddleware::class, |
||||
|
]); |
||||
@ -0,0 +1,222 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace plugin\piadmin\app\service; |
||||
|
|
||||
|
use plugin\piadmin\app\base\BaseService; |
||||
|
use plugin\piadmin\app\dao\ProxyMenuDao; |
||||
|
use plugin\piadmin\app\exception\ApiException; |
||||
|
use plugin\piadmin\app\utils\IdPathUtils; |
||||
|
use plugin\piadmin\app\utils\IdUtils; |
||||
|
use plugin\piadmin\app\utils\TreeUtils; |
||||
|
use support\Log; |
||||
|
use think\facade\Db; |
||||
|
|
||||
|
class ProxyMenuService extends BaseService |
||||
|
{ |
||||
|
|
||||
|
public function __construct(ProxyMenuDao $dao) |
||||
|
{ |
||||
|
$this->dao = $dao; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public function getMenuList($params = []) |
||||
|
{ |
||||
|
$where = []; |
||||
|
$list = $this->dao->getList($where, '*', 0, 0, 'sort asc'); |
||||
|
return TreeUtils::toTree($list); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 保存数据 |
||||
|
* @param $params |
||||
|
* @return \plugin\piadmin\app\base\BaseModel |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\DbException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
*/ |
||||
|
public function saveData($params) |
||||
|
{ |
||||
|
// 检查code
|
||||
|
$codeExist = $this->dao->be([ |
||||
|
'code'=>$params['code'] |
||||
|
]); |
||||
|
if ($codeExist) { |
||||
|
throw new ApiException(trans(401003)); |
||||
|
} |
||||
|
$parentMenu = $this->getMenu($params['pid']); |
||||
|
if (empty($parentMenu)) { |
||||
|
throw new ApiException(trans(401001)); |
||||
|
} |
||||
|
$newUuid = IdUtils::uuid(); |
||||
|
$newIdPath = IdPathUtils::addItem($parentMenu['id_path'], $newUuid); |
||||
|
$params['id_path'] = $newIdPath; |
||||
|
$params['uuid'] = $newUuid; |
||||
|
return $this->dao->save($params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 更新数据 |
||||
|
* @param $params |
||||
|
* @return \plugin\piadmin\app\base\BaseModel |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\DbException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
*/ |
||||
|
public function updateData($params) |
||||
|
{ |
||||
|
$menu = $this->dao->get($params['id']); |
||||
|
if (empty($menu)) { |
||||
|
throw new ApiException(trans(401005)); |
||||
|
} |
||||
|
if($params['pid'] == $menu['id']){ |
||||
|
throw new ApiException(trans(401008)); |
||||
|
} |
||||
|
// code有没有变化
|
||||
|
if ($params['code'] != $menu['code']) { |
||||
|
$codeExist = $this->dao->be([ |
||||
|
'code'=>$params['code'] |
||||
|
]); |
||||
|
if ($codeExist) { |
||||
|
throw new ApiException(trans(401003)); |
||||
|
} |
||||
|
} |
||||
|
$newIdPath = ''; |
||||
|
// 上级菜单有没有变化
|
||||
|
if ($params['pid'] != $menu['pid']) { |
||||
|
$parentMenu = $this->getMenu($params['pid']); |
||||
|
if (empty($parentMenu)) { |
||||
|
throw new ApiException(trans(401001)); |
||||
|
} |
||||
|
$newIdPath = IdPathUtils::addItem($parentMenu['id_path'], $menu['id']); |
||||
|
$params['id_path'] = $newIdPath; |
||||
|
} |
||||
|
unset($params['id']); |
||||
|
|
||||
|
// 落库
|
||||
|
Db::startTrans(); |
||||
|
try { |
||||
|
$this->dao->update(['id' => $menu['id']], $params); |
||||
|
if (!empty($newIdPath)) { |
||||
|
$this->updateAllChildrenIdPath($menu['id_path'], $newIdPath); |
||||
|
} |
||||
|
Db::commit(); |
||||
|
} catch (\Exception $exception) { |
||||
|
Db::rollback(); |
||||
|
Log::error($exception->getTraceAsString()); |
||||
|
throw new ApiException($exception->getMessage()); |
||||
|
} |
||||
|
return $params; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 删除数据 |
||||
|
* @param mixed $id |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function deleteData($ids) |
||||
|
{ |
||||
|
//根据ids获取所有子菜单
|
||||
|
$ids = $this->getChildrenMenuIdsBatch($ids); |
||||
|
// 落库
|
||||
|
Db::startTrans(); |
||||
|
try { |
||||
|
foreach ($ids as $id) { |
||||
|
$this->dao->softDel($id); |
||||
|
} |
||||
|
Db::commit(); |
||||
|
} catch (\Exception $exception) { |
||||
|
Db::rollback(); |
||||
|
Log::error($exception->getTraceAsString()); |
||||
|
throw new ApiException($exception->getMessage()); |
||||
|
} |
||||
|
return []; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取数据 |
||||
|
* @param mixed $id |
||||
|
* @return array |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\DbException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
*/ |
||||
|
public function readData(mixed $id) |
||||
|
{ |
||||
|
$menu = $this->dao->get(['id' => $id]); |
||||
|
if (empty($menu)) { |
||||
|
return []; |
||||
|
} |
||||
|
return $menu->toArray(); |
||||
|
} |
||||
|
|
||||
|
public function getUserMenu() |
||||
|
{ |
||||
|
$list = $this->dao->getList([], '*', 0, 0, 'sort asc'); |
||||
|
return TreeUtils::toTree($list); |
||||
|
} |
||||
|
|
||||
|
// ============================================================ 私有方法 ===============================================
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 获取菜单 |
||||
|
* @param $id |
||||
|
* @return array |
||||
|
* @throws \think\db\exception\DataNotFoundException |
||||
|
* @throws \think\db\exception\DbException |
||||
|
* @throws \think\db\exception\ModelNotFoundException |
||||
|
*/ |
||||
|
private function getMenu($id): array |
||||
|
{ |
||||
|
if ($id == 0) { |
||||
|
return [ |
||||
|
'id' => 0, |
||||
|
'uuid' => 0, |
||||
|
'name' => '顶级菜单', |
||||
|
'code' => 'top', |
||||
|
'type' => 'M', |
||||
|
'status' => 1, |
||||
|
'sort' => 1000, |
||||
|
'pid' => 0, |
||||
|
'id_path' => '0', |
||||
|
]; |
||||
|
} |
||||
|
$menu = $this->dao->get(['id' => $id]); |
||||
|
if (empty($menu)) { |
||||
|
return []; |
||||
|
} |
||||
|
return $menu->toArray(); |
||||
|
} |
||||
|
|
||||
|
private function updateAllChildrenIdPath($oldIdPath, $newIdPath) |
||||
|
{ |
||||
|
// 获取所有子级
|
||||
|
$childrenIds = $this->dao->getColumn([ |
||||
|
['id_path', 'like', $oldIdPath . ',%'] |
||||
|
], 'id'); |
||||
|
$children = $this->dao->getList([ |
||||
|
['id', 'in', $childrenIds] |
||||
|
], 'id, id_path'); |
||||
|
foreach ($children as $child) { |
||||
|
$newIdPath = str_replace($oldIdPath, $newIdPath, $child['id_path']); |
||||
|
$this->dao->update(['id' => $child['id']], [ |
||||
|
'id_path' => $newIdPath |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public function getChildrenMenuIdsBatch(array $ids): array |
||||
|
{ |
||||
|
$allMenus = $this->dao->getList([], 'id, pid'); |
||||
|
$allChildrenIds = []; |
||||
|
|
||||
|
// 批量处理所有ID的子节点查找
|
||||
|
foreach ($ids as $id) { |
||||
|
$childIds = TreeUtils::getChildrenIds($allMenus, $id); |
||||
|
$allChildrenIds = array_merge($allChildrenIds, $childIds); |
||||
|
} |
||||
|
return array_values(array_unique($allChildrenIds)); // 重新索引并去重
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,130 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace plugin\piadmin\app\service; |
||||
|
|
||||
|
use plugin\piadmin\app\base\BaseService; |
||||
|
use plugin\piadmin\app\dao\ProxyUserDao; |
||||
|
use plugin\piadmin\app\exception\ApiException; |
||||
|
use plugin\piadmin\app\utils\CacheUtils; |
||||
|
use plugin\piadmin\app\utils\JwtUtils; |
||||
|
|
||||
|
class ProxyUserService extends BaseService |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
|
||||
|
public function __construct(ProxyUserDao $dao) |
||||
|
{ |
||||
|
$this->dao = $dao; |
||||
|
} |
||||
|
|
||||
|
// 用户登录
|
||||
|
public function login($params) |
||||
|
{ |
||||
|
$proxyUser = $this->dao->getModel()->where(function ($query) use ($params){ |
||||
|
$query->where('email', '=', $params['username']) |
||||
|
->whereOr('phone', '=', $params['username']); |
||||
|
})->find(); |
||||
|
$this->validPassword($proxyUser, $params); |
||||
|
$tokenInfo = $this->commonLogin($proxyUser, $params); |
||||
|
$tokenInfo['user'] = $proxyUser->toArray(); |
||||
|
$tokenInfo['expire_time'] = $tokenInfo['expire'] + time(); |
||||
|
return $tokenInfo; |
||||
|
} |
||||
|
|
||||
|
// ============================================================ 私有方法 ===============================================
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 验证密码 |
||||
|
* @param mixed $adminUser |
||||
|
* @param $params |
||||
|
* @return void |
||||
|
*/ |
||||
|
private function validPassword(mixed $proxyUser, $params): void |
||||
|
{ |
||||
|
// 验证登录信息
|
||||
|
if (empty($proxyUser)) { |
||||
|
throw new ApiException(trans(400005)); |
||||
|
} |
||||
|
// 密码验证
|
||||
|
if (!password_verify($params['password'], $proxyUser['password'])) { |
||||
|
throw new ApiException(trans(400005)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 通用登录流程 |
||||
|
* @param mixed $adminUser |
||||
|
* @param array $params |
||||
|
* @return array |
||||
|
* @throws ApiException |
||||
|
*/ |
||||
|
private function commonLogin(mixed $proxyUser, array $params) |
||||
|
{ |
||||
|
if ($proxyUser['status'] == 2) { |
||||
|
throw new ApiException(trans(400006)); |
||||
|
} |
||||
|
$tokenInfo = JwtUtils::createToken($proxyUser['id'], 'proxy'); |
||||
|
$tokenCacheInfo = [ |
||||
|
'uid' => $proxyUser['id'], |
||||
|
'type' => 'user_token', |
||||
|
'token' => $tokenInfo['token'], |
||||
|
'expire_time' => time() + $tokenInfo['expire'], |
||||
|
'user' => $proxyUser->toArray(), |
||||
|
'login_time' => date('Y-m-d H:i:s'), |
||||
|
'os_type' => $this->getClientOS(), |
||||
|
'browser_name' => $this->getClientBrowserName(), |
||||
|
'login_ip' => request()->getRemoteIp() |
||||
|
]; |
||||
|
// 保存token缓存
|
||||
|
CacheUtils::set('proxy.token.' . md5($tokenInfo['token']), json_encode($tokenCacheInfo), (int)$tokenInfo['expire']); |
||||
|
// 保存用户对应版本缓存
|
||||
|
$currentVersion = getPiAdminVersion(); |
||||
|
$userVersionKey = "proxy.version.{$proxyUser['id']}"; |
||||
|
CacheUtils::set($userVersionKey, $currentVersion, (int)$tokenInfo['expire']); |
||||
|
return $tokenInfo; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取客户端操作系统 |
||||
|
* @return int |
||||
|
*/ |
||||
|
private function getClientOS(): int |
||||
|
{ |
||||
|
$userAgent = request()->header('user-agent'); |
||||
|
if (stripos($userAgent, 'Windows') !== false) { |
||||
|
$os = 1; |
||||
|
} elseif (stripos($userAgent, 'Mac') !== false) { |
||||
|
$os = 2; |
||||
|
} elseif (stripos($userAgent, 'Linux') !== false) { |
||||
|
$os = 3; |
||||
|
} elseif (stripos($userAgent, 'iPhone|iPad|iPod') !== false) { |
||||
|
$os = 4; |
||||
|
} elseif (stripos($userAgent, 'Android') !== false) { |
||||
|
$os = 5; |
||||
|
} else { |
||||
|
$os = 6; |
||||
|
} |
||||
|
return $os; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取客户端浏览器名称 |
||||
|
* @return string |
||||
|
*/ |
||||
|
private function getClientBrowserName(): string |
||||
|
{ |
||||
|
$userAgent = request()->header('user-agent'); |
||||
|
$pattern = '/(MSIE|Trident|Edge|Firefox|Chrome|Safari|Opera|OPR)\/?\s*(\d+\.\d+)?/i'; |
||||
|
preg_match($pattern, $userAgent, $matches); |
||||
|
if (isset($matches[1])) { |
||||
|
// 处理Edge和Opera的特殊标识
|
||||
|
if ($matches[1] === 'Trident') return 'Internet Explorer'; |
||||
|
if ($matches[1] === 'OPR') return 'Opera'; |
||||
|
return $matches[1]; |
||||
|
} |
||||
|
return 'Unknown Browser'; |
||||
|
} |
||||
|
|
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue