Merge branch 'master' into feature/ticket

# Conflicts:
#	config/whitelist.php
This commit is contained in:
2025-07-15 09:11:14 +08:00
8 changed files with 182 additions and 10 deletions
+33 -4
View File
@@ -3,27 +3,56 @@
namespace app\common\logic;
use app\common\model\User;
use app\common\model\Resource;
class PermLogic
{
/**
* 获取用户所有资源(合并角色+直接分配)
* 获取用户所有资源(合并角色+直接分配),并加入公共菜单,排序按sort字段
*/
public function getUserResources(int $userId)
{
// 获取用户及其关联角色资源和直接分配的资源
$user = User::with(['roles.resources', 'resources'])->find($userId);
if (!$user) {
return collect();
}
$all = collect();
// 合并角色资源,排除不需要权限认证的资源
foreach ($user->roles as $role) {
$all = $all->merge($role->resources);
$all = $all->merge(
$role->resources->filter(function ($resource) {
// 只保留需要权限认证的资源(或公共资源)
return !$resource->no_auth;
})
);
}
$all = $all->merge($user->resources);
return $all->unique('id')->values();
// 合并用户直接分配的资源,排除不需要权限认证的资源
$all = $all->merge(
$user->resources->filter(function ($resource) {
// 只保留需要权限认证的资源(或公共资源)
return !$resource->no_auth;
})
);
// 加入公共菜单,公共菜单不管是否授权,所有人都能访问
$publicResources = Resource::where('no_auth', 1)
->orderBy('sort', 'asc') // 按 sort 字段升序排序
->get();
// 合并所有公共资源
$all = $all->merge($publicResources);
// 返回唯一的资源列表,并按 id 排序
// 使用 sortBy('sort') 来确保最终结果根据 'sort' 字段排序
return $all->unique('id')->values()->sortBy('sort');
}
/**
* 构建目录/菜单树,节点包含权限与打开方式,拼接完整路径,并对子级菜单component处理
* @param \Illuminate\Support\Collection $resources
+1 -1
View File
@@ -53,6 +53,6 @@ class Role extends Model
// 角色拥有的资源(权限点、菜单)
public function resources()
{
return $this->belongsToMany(Resource::class, 'role_resources', 'role_id', 'resource_id');
return $this->belongsToMany(Resource::class, 'role_resources', 'role_id', 'resource_id')->orderBy('sort', 'asc');
}
}
+1 -1
View File
@@ -75,7 +75,7 @@ class User extends Model
// 用户直接拥有的资源(用于特殊补权)
public function resources()
{
return $this->belongsToMany(Resource::class, 'user_resources', 'user_id', 'resource_id');
return $this->belongsToMany(Resource::class, 'user_resources', 'user_id', 'resource_id')->orderBy('sort', 'asc');
}
// 用户可访问的系统
+47
View File
@@ -0,0 +1,47 @@
<?php
namespace app\common\model;
use support\Model;
/**
* user_roles 用户-角色关联
* @property integer $user_id 用户ID(主键)
* @property integer $role_id 角色ID(主键)
*/
class UserRoles extends Model
{
/**
* The connection name for the model.
*
* @var string|null
*/
protected $connection = 'mysql';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'user_roles';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = null;
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
protected $fillable = [
'user_id',
'role_id'
];
}
+53
View File
@@ -0,0 +1,53 @@
<?php
namespace app\common\model;
use support\Model;
/**
* user_systems 用户-系统关联表:描述用户可访问哪些系统
* @property integer $user_id 用户ID(主键)
* @property integer $system_id 系统ID(主键)
* @property integer $created_at 创建时间
*/
class UserSystems extends Model
{
/**
* The connection name for the model.
*
* @var string|null
*/
protected $connection = 'mysql';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'user_systems';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = null;
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
// protected $dateFormat = 'U';
// const UPDATED_AT = false;
protected $fillable = [
'user_id',
'system_id',
'created_at'
];
}