Rust-用户信息完善

举报
林太白 发表于 2025/12/26 16:03:51 2025/12/26
【摘要】 Rust-用户信息完善

Rust-用户信息完善

🍎返回用户信息完善

我们添加一些从token之中获取当前用户的详细信息,比如头像,用户名,昵称等等

// 根据 token 里的 username 查询用户信息
let user = sqlx::query_as::<_, User>("SELECT * FROM sys_user WHERE username = ?")
    .bind(&token_data.claims.username)
    .fetch_one(pool.get_ref())
    .await;

match user {
    Ok(u) => HttpResponse::Ok().json(ApiResponse {
        code: 200,
        msg: "获取用户信息成功",
        data: Some(u),
    }),
    Err(_) => HttpResponse::InternalServerError().json(ApiResponse {
        code: 500,
        msg: "用户不存在",
        data: None::<()>,
    }),
}

🍎返回用户角色

我们的用户信息的接口一般除了返回用户的基本信息以外还会返回用户的角色信息,接下来我们完善一下返回的菜单角色信息

获取角色id

根据我们的用户id去查找对应的角色id,这里假设我们的角色并不是一种,而是多角色的方式

 match user {
        Ok(u) => {
            // 根据用户ID查询角色信息
            match sqlx::query_as::<_, UserRole>(
                "SELECT role_id, user_id FROM sys_user_role WHERE user_id = ?",
            )
            .bind(u.user_id)
            .fetch_all(pool.get_ref())
            .await
            {
                Ok(roles) => {

                    
                    // 收集所有角色ID
                    let role_ids: Vec<i32> = roles.iter().map(|r| r.role_id).collect();

                    if roles.is_empty() {
                        HttpResponse::NotFound().json(ApiResponse {
                            code: 404,
                            msg: "该用户未分配角色",
                            data: None::<Vec<i32>>,  // 明确指定None的类型为Vec<i32>
                        })
                    } else {
                        HttpResponse::Ok().json(ApiResponse {
                            code: 200,
                            msg: "获取用户角色成功",
                            data: Some(role_ids),  // 返回所有角色ID的集合
                        })
                    }

                }
                Err(e) => {
                    eprintln!("Database error: {}", e);
                    HttpResponse::InternalServerError().json(ApiResponse {
                        code: 500,
                        msg: "数据库查询错误",
                        data: None::<()>,
                    })
                }
            }
        }
        Err(_) => HttpResponse::NotFound().json(ApiResponse {
            code: 404,
            msg: "用户不存在",
            data: None::<()>,
        }),
    }

拿角色名称和角色key

根据role_ids 去 sys_role表中拿取所有的 status 为 0 的 role_name

 // /收集所有角色ID
    let role_ids: Vec<i32> = roles.iter().map(|role| role.role_id).collect();

    // 使用 get_roles_by_ids 获取角色信息
    let role_info = match get_roles_by_ids(pool.get_ref(), &role_ids).await {
        Ok(info) => info,
        Err(e) => {
            eprintln!("获取角色信息失败: {}", e);
            return HttpResponse::InternalServerError().json(ApiResponse {
                code: 500,
                msg: "获取角色信息失败",
                data: None::<()>,
            });
        }
    };

    // 提取角色键和名称列表
    let (role_keys, role_names): (Vec<String>, Vec<String>) = role_info.into_iter().unzip();

这个时候我们返回信息调整。已经可以拿到属于用户的角色以及角色信息名称了

 // 将菜单信息组合为树形结构
  HttpResponse::Ok().json(UserInfoResponse {
      msg: "获取成功".to_string(),
      code: 200,
      permissions: vec!["*:*:*".to_string()],
      roles: role_keys,// 使用从数据库获取的角色键
      roleNames: role_names,// 使用从数据库获取的角色名称
      data: UserDetail {
          userId: user.user_id.to_string(),
          userName: user.username.clone(),
          realName: user.username.clone(),
          phone: user.username.clone(),
          deptId:"获取成功".to_string(),
      },
  })
msg: "获取成功"
permissions: ["*:*:*"]
roleNames: ["普通角色"]
roles: ["common"]

拿用户permissions权限系列

接下来我们拿一下用户的按钮权限,也就是菜单里面的按钮类型对应的信息

先拿到菜单信息

 // 根据角色ID查询菜单ID并去重
    let menu_ids: Vec<i32> = match get_menu_ids_by_roles(pool.get_ref(), &role_ids).await {
        Ok(ids) => ids,
        Err(e) => {
            eprintln!("获取菜单ID失败: {}", e);
            return HttpResponse::InternalServerError().json(ApiResponse {
                code: 500,
                msg: "获取用户菜单失败",
                data: None::<()>,
            });
        }
    };

    // 根据菜单ID查询菜单信息
    let menus = match get_menus_by_ids(pool.get_ref(), &menu_ids, Some("F")).await {
        Ok(menus) => menus,
        Err(e) => {
            eprintln!("获取菜单信息失败: {}", e);
            return HttpResponse::InternalServerError().json(ApiResponse {
                code: 500,
                msg: "获取菜单信息失败",
                data: None::<()>,
            });
        }
    };

然后我们过滤拿到需要的信息

 let permissions: Vec<String> = menus
    .iter()
    .filter_map(|menu| menu.perms.clone())  // 过滤掉 None 值
    .filter(|perm| !perm.is_empty())  // 过滤掉空字符串
    .collect::<std::collections::HashSet<_>>()  // 转换为 HashSet 去重
    .into_iter()  // 转回迭代器
    .collect();  // 收集为 Vec

    // 如果没有权限,可以返回默认权限
    let permissions = if permissions.is_empty() {
        vec!["*:*:*".to_string()]
    } else {
        permissions
    };
    // eprintln!("菜单权限信息: {:?}", permissions);

    // 将菜单信息组合为树形结构
    let menus = build_menu_tree(menus);
    eprint!("菜单信息: {:?}", menus);
    HttpResponse::Ok().json(UserInfoResponse {
        msg: "获取成功".to_string(),
        code: 200,
        permissions: permissions,
        roles: role_keys,// 使用从数据库获取的角色键
        roleNames: role_names,// 使用从数据库获取的角色名称
        data: UserDetail {
            userId: user.user_id.to_string(),
            userName: user.username.clone(),
            realName: user.username.clone(),
            phone: user.username.clone(),
            deptId:"获取成功".to_string(),
        },
    })

这个时候我们返回的信息已经有对应的数据了,我们就可以使用对应的权限去校验用户全局

[
    "system:menu:list",
    "system:dict:list",
    "monitor:server:list",
    "monitor:cache:list",
    "tool:gen:list",
    "system:post:list",
    "monitor:operlog:list",
    "tool:swagger:list",
    "monitor:job:list",
    "system:dept:list",
    "system:notice:list",
    "monitor:online:list",
    "system:user:list",
    "system:role:list",
    "system:config:list",
    "tool:build:list",
    "monitor:logininfor:list",
    "monitor:druid:list"
]
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。