feat(config): 菜单动态化改造 — 侧边栏从后端 API 加载
- 新增 seed 迁移插入完整菜单树(4 directory + 23 menu = 27 条) - 新增 GET /api/v1/menus/user 端点(仅需登录,无需 menu.list 权限) - MainLayout 从 API 动态获取菜单树替换硬编码数组 - 扩展图标映射表覆盖 22 个 Ant Design 图标 - Header 标题从动态菜单数据查找,保留 fallback
This commit is contained in:
@@ -236,6 +236,39 @@ where
|
||||
}))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/menus/user",
|
||||
responses(
|
||||
(status = 200, description = "成功", body = ApiResponse<Vec<MenuResp>>),
|
||||
(status = 401, description = "未授权"),
|
||||
),
|
||||
security(("bearer_auth" = [])),
|
||||
tag = "菜单管理"
|
||||
)]
|
||||
/// GET /api/v1/menus/user
|
||||
///
|
||||
/// 获取当前用户可见的菜单树(无需 menu.list 权限,仅需登录)。
|
||||
pub async fn get_user_menus<S>(
|
||||
State(state): State<ConfigState>,
|
||||
Extension(ctx): Extension<TenantContext>,
|
||||
) -> Result<JsonResponse<ApiResponse<Vec<MenuResp>>>, AppError>
|
||||
where
|
||||
ConfigState: FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
let role_ids: Vec<Uuid> = ctx
|
||||
.roles
|
||||
.iter()
|
||||
.filter_map(|r| Uuid::parse_str(r).ok())
|
||||
.collect();
|
||||
|
||||
// 如果用户有角色关联菜单,按角色过滤;否则返回全部(admin 兜底)
|
||||
let menus = MenuService::get_menu_tree(ctx.tenant_id, &role_ids, &state.db).await?;
|
||||
|
||||
Ok(JsonResponse(ApiResponse::ok(menus)))
|
||||
}
|
||||
|
||||
/// 删除菜单的乐观锁版本号请求体。
|
||||
#[derive(Debug, serde::Deserialize, utoipa::ToSchema)]
|
||||
pub struct DeleteMenuVersionReq {
|
||||
|
||||
Reference in New Issue
Block a user