diff --git a/backend/auth/apps/permissions/urls.py b/backend/auth/apps/permissions/urls.py
index 8835897..ec8bfa8 100644
--- a/backend/auth/apps/permissions/urls.py
+++ b/backend/auth/apps/permissions/urls.py
@@ -107,6 +107,70 @@ async def get_permission_tree(
return tree
+@router.get("/menu", response_model=list[PermissionTreeResponse])
+async def get_menu(
+ db: AsyncSession = Depends(get_db),
+ current_user: User = Depends(get_current_user),
+):
+ """获取当前用户的菜单树形结构(仅包含有路由的权限)"""
+ # 获取用户角色的权限
+ result = await db.execute(
+ select(Role)
+ .options(selectinload(Role.permissions))
+ .filter(Role.id == current_user.role_id)
+ )
+ role = result.scalar_one_or_none()
+
+ if not role:
+ raise HTTPException(status_code=404, detail="角色不存在")
+
+ # 获取用户有权限的权限编码集合
+ user_permission_codes = {perm.code for perm in role.permissions}
+
+ # 获取所有顶级模块和二级模块权限(有route字段的)
+ result = await db.execute(
+ select(Permission)
+ .filter(Permission.route.isnot(None))
+ )
+ all_menu_permissions = result.scalars().all()
+
+ # 过滤用户有权限的菜单
+ user_menu_permissions = []
+ for perm in all_menu_permissions:
+ # 检查用户是否有该权限或其子权限
+ has_access = False
+ for user_perm_code in user_permission_codes:
+ if user_perm_code.startswith(perm.code):
+ has_access = True
+ break
+ if has_access:
+ user_menu_permissions.append(perm)
+
+ # 转换为字典,便于查找
+ perm_dict = {perm.id: {
+ "id": perm.id,
+ "name": perm.name,
+ "code": perm.code,
+ "parentid": perm.parentid,
+ "route": perm.route,
+ "description": perm.description,
+ "children": []
+ } for perm in user_menu_permissions}
+
+ # 构建树形结构
+ tree = []
+ for perm_id, perm_data in perm_dict.items():
+ parentid = perm_data["parentid"]
+ if parentid == 0:
+ # 顶级节点
+ tree.append(perm_data)
+ elif parentid in perm_dict:
+ # 子节点,添加到父节点的 children
+ perm_dict[parentid]["children"].append(perm_data)
+
+ return tree
+
+
@router.get("/{permission_id}", response_model=PermissionResponse)
async def get_permission(
permission_id: int,
@@ -227,7 +291,7 @@ async def get_current_user_permissions(
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
- """获取当前登录用户的权限列表"""
+ """获取当前登录用户的权限列表和菜单"""
# 获取用户角色的权限
result = await db.execute(
select(Role)
@@ -239,9 +303,54 @@ async def get_current_user_permissions(
if not role:
raise HTTPException(status_code=404, detail="角色不存在")
- # 返回用户权限信息
+ # 获取用户有权限的权限编码集合
+ user_permission_codes = {perm.code for perm in role.permissions}
+
+ # 获取所有顶级模块和二级模块权限(有route字段的)
+ result = await db.execute(
+ select(Permission)
+ .filter(Permission.route.isnot(None))
+ )
+ all_menu_permissions = result.scalars().all()
+
+ # 过滤用户有权限的菜单
+ user_menu_permissions = []
+ for perm in all_menu_permissions:
+ # 检查用户是否有该权限或其子权限
+ has_access = False
+ for user_perm_code in user_permission_codes:
+ if user_perm_code.startswith(perm.code):
+ has_access = True
+ break
+ if has_access:
+ user_menu_permissions.append(perm)
+
+ # 转换为字典,便于查找
+ perm_dict = {perm.id: {
+ "id": perm.id,
+ "name": perm.name,
+ "code": perm.code,
+ "parentid": perm.parentid,
+ "route": perm.route,
+ "description": perm.description,
+ "children": []
+ } for perm in user_menu_permissions}
+
+ # 构建树形结构
+ menu_tree = []
+ for perm_id, perm_data in perm_dict.items():
+ parentid = perm_data["parentid"]
+ if parentid == 0:
+ # 顶级节点
+ menu_tree.append(perm_data)
+ elif parentid in perm_dict:
+ # 子节点,添加到父节点的 children
+ perm_dict[parentid]["children"].append(perm_data)
+
+ # 返回用户权限信息和菜单
return RolePermissionResponse(
role_id=role.id,
role_name=role.name,
- permissions=[PermissionResponse.from_orm(p) for p in role.permissions]
- )
\ No newline at end of file
+ permissions=[PermissionResponse.from_orm(p) for p in role.permissions],
+ menu=menu_tree
+ )
diff --git a/backend/auth/init_data.py b/backend/auth/init_data.py
index d4838b6..1775375 100644
--- a/backend/auth/init_data.py
+++ b/backend/auth/init_data.py
@@ -1,6 +1,6 @@
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, text
-from models import Role, User, Permission
+from models import Role, User, Permission, SystemSetting
from utils.password import get_password_hash
@@ -32,6 +32,14 @@ async def ensure_permission_table_structure(db: AsyncSession):
except Exception as e:
print(f"添加 parentid 字段失败: {e}")
+ # 添加 route 字段
+ if 'route' not in existing_columns:
+ try:
+ await db.execute(text("ALTER TABLE permission ADD COLUMN IF NOT EXISTS route VARCHAR(255)"))
+ print("添加 route 字段成功")
+ except Exception as e:
+ print(f"添加 route 字段失败: {e}")
+
# 删除旧字段(如果存在)
for old_column in ['module', 'submodule', 'action']:
if old_column in existing_columns:
@@ -53,21 +61,21 @@ async def init_permissions(db: AsyncSession):
# ========================================
# 顶级模块
# ========================================
- {"name": "权限管理", "code": "perm", "parentid": 0, "description": "权限管理模块"},
- {"name": "系统设置", "code": "system", "parentid": 0, "description": "系统设置模块"},
+ {"name": "权限管理", "code": "perm", "parentid": 0, "route": "/admin/permissions", "description": "权限管理模块"},
+ {"name": "系统设置", "code": "system", "parentid": 0, "route": "/admin/settings", "description": "系统设置模块"},
# ========================================
# 权限管理 -> 二级子模块
# ========================================
- {"name": "用户管理", "code": "perm:user", "parentid": 1, "description": "用户管理子模块"},
- {"name": "角色管理", "code": "perm:role", "parentid": 1, "description": "角色管理子模块"},
- {"name": "权限配置", "code": "perm:config", "parentid": 1, "description": "权限配置子模块"},
+ {"name": "用户管理", "code": "perm:user", "parentid": 1, "route": "/admin/users", "description": "用户管理子模块"},
+ {"name": "角色管理", "code": "perm:role", "parentid": 1, "route": "/admin/roles", "description": "角色管理子模块"},
+ {"name": "权限配置", "code": "perm:config", "parentid": 1, "route": "/admin/permissions", "description": "权限配置子模块"},
# ========================================
# 系统设置 -> 二级子模块
# ========================================
- {"name": "基础配置", "code": "system:basic", "parentid": 2, "description": "系统基础配置"},
- {"name": "高级配置", "code": "system:advanced", "parentid": 2, "description": "系统高级配置"},
+ {"name": "基础配置", "code": "system:basic", "parentid": 2, "route": "/admin/settings", "description": "系统基础配置"},
+ {"name": "高级配置", "code": "system:advanced", "parentid": 2, "route": "/admin/settings", "description": "系统高级配置"},
# ========================================
# 用户管理操作(parentid=3)
@@ -143,6 +151,9 @@ async def init_permissions(db: AsyncSession):
if existing_perm.parentid != perm_data["parentid"]:
existing_perm.parentid = perm_data["parentid"]
update_needed = True
+ if existing_perm.route != perm_data.get("route"):
+ existing_perm.route = perm_data.get("route")
+ update_needed = True
if existing_perm.description != perm_data["description"]:
existing_perm.description = perm_data["description"]
update_needed = True
@@ -383,6 +394,60 @@ async def init_test_user(db: AsyncSession):
print("测试用户初始化/更新完成")
+async def init_system_settings(db: AsyncSession):
+ """初始化系统设置数据"""
+ # 定义需要初始化的系统设置
+ system_settings = [
+ {
+ "key": "系统标题",
+ "value": "图书管理系统",
+ "type": "string",
+ "description": "系统显示标题"
+ },
+ ]
+
+ # 检查现有系统设置
+ result = await db.execute(select(SystemSetting))
+ existing_settings = result.scalars().all()
+ existing_setting_keys = {setting.key: setting for setting in existing_settings}
+
+ # 创建或更新系统设置
+ created_count = 0
+ updated_count = 0
+
+ for setting_data in system_settings:
+ setting_key = setting_data["key"]
+ if setting_key not in existing_setting_keys:
+ # 设置不存在,需要创建
+ db.add(SystemSetting(**setting_data))
+ created_count += 1
+ else:
+ # 设置存在,检查是否需要更新
+ existing_setting = existing_setting_keys[setting_key]
+ update_needed = False
+
+ if existing_setting.value != setting_data["value"]:
+ existing_setting.value = setting_data["value"]
+ update_needed = True
+ if existing_setting.type != setting_data["type"]:
+ existing_setting.type = setting_data["type"]
+ update_needed = True
+ if existing_setting.description != setting_data.get("description"):
+ existing_setting.description = setting_data.get("description")
+ update_needed = True
+
+ if update_needed:
+ updated_count += 1
+
+ if created_count > 0 or updated_count > 0:
+ await db.commit()
+ print(f"创建了 {created_count} 个系统设置,更新了 {updated_count} 个系统设置")
+ else:
+ print("系统设置数据已存在且无需更新,跳过初始化")
+
+ print("系统设置数据初始化/更新完成")
+
+
async def init_all_data(db: AsyncSession):
"""初始化所有数据"""
print("开始初始化数据库数据...")
@@ -392,4 +457,5 @@ async def init_all_data(db: AsyncSession):
await init_role_permissions(db)
await init_admin_user(db)
await init_test_user(db)
+ await init_system_settings(db)
print("数据库数据初始化完成")
diff --git a/backend/auth/models.py b/backend/auth/models.py
index e602496..dacd443 100644
--- a/backend/auth/models.py
+++ b/backend/auth/models.py
@@ -59,6 +59,7 @@ class Permission(Base):
name = Column(String(100), nullable=False, comment="权限名称")
code = Column(String(100), nullable=False, unique=True, comment="权限编码")
parentid = Column(Integer, default=0, comment="父权限ID(0表示顶级模块)")
+ route = Column(String(255), nullable=True, comment="前端路由路径")
description = Column(String(255), nullable=True, comment="权限描述")
createtime = Column(DateTime, default=datetime.utcnow, comment="创建时间")
updatetime = Column(
diff --git a/backend/auth/schemas.py b/backend/auth/schemas.py
index 1bf5961..67dafd6 100644
--- a/backend/auth/schemas.py
+++ b/backend/auth/schemas.py
@@ -139,6 +139,7 @@ class PermissionBase(BaseModel):
name: str = Field(..., max_length=100, description="权限名称")
code: str = Field(..., max_length=100, description="权限编码")
parentid: int = Field(0, description="父权限ID(0表示顶级模块)")
+ route: Optional[str] = Field(None, max_length=255, description="前端路由路径")
description: Optional[str] = Field(None, max_length=255, description="权限描述")
@@ -165,6 +166,7 @@ class PermissionTreeResponse(BaseModel):
name: str = Field(..., description="权限名称")
code: str = Field(..., description="权限编码")
parentid: int = Field(..., description="父权限ID")
+ route: Optional[str] = Field(None, description="前端路由路径")
description: Optional[str] = Field(None, description="权限描述")
children: list = Field([], description="子权限列表")
@@ -183,6 +185,7 @@ class RolePermissionResponse(BaseModel):
role_id: int = Field(..., description="角色ID")
role_name: str = Field(..., description="角色名称")
permissions: list[PermissionResponse] = Field(..., description="权限列表")
+ menu: list = Field([], description="菜单树形结构")
# 系统设置相关模型
diff --git a/frontend/src/modules/admin/layout/AdminLayout.vue b/frontend/src/modules/admin/layout/AdminLayout.vue
index 838eccb..0bdab64 100644
--- a/frontend/src/modules/admin/layout/AdminLayout.vue
+++ b/frontend/src/modules/admin/layout/AdminLayout.vue
@@ -9,47 +9,34 @@
text-color="#e2e8f0"
active-text-color="#38bdf8"
>
-
-
-
-
- 权限管理
-
-
+
+
+
- 用户管理
-
+
+
+ {{ menu.name }}
+
+
+ {{ child.name }}
+
+
+
- 角色管理
+
+ {{ menu.name }}
-
- 权限管理
-
-
-
-
-
-
- 系统设置
-
+
@@ -72,9 +59,9 @@