diff --git a/api/role/init.go b/api/role/init.go index a04e9c8..7f3e1c4 100644 --- a/api/role/init.go +++ b/api/role/init.go @@ -15,4 +15,6 @@ func init() { Router.Delete("/{id}", "Delete Role", cfg.Auth.RequireWrite("role:*"), del) Router.Get("/{id}/permissions", "Get Role Permissions", cfg.Auth.RequireRead("role:*"), getPermissions) Router.Put("/{id}/permissions", "Update Role Permissions", cfg.Auth.RequireWrite("role:*"), updatePermissions) + Router.Get("/{id}/users", "Get Role Users", cfg.Auth.RequireRead("role:*"), getUsers) + Router.Put("/{id}/users", "Update Role Users", cfg.Auth.RequireWrite("role:*"), updateUsers) } diff --git a/api/role/users.go b/api/role/users.go new file mode 100644 index 0000000..21ac239 --- /dev/null +++ b/api/role/users.go @@ -0,0 +1,82 @@ +package role + +import ( + "github.com/veypi/vbase/cfg" + "github.com/veypi/vbase/models" + "github.com/veypi/vigo" + "gorm.io/gorm" +) + +type GetUsersReq struct { + RoleID string `src:"path@id" desc:"Role ID"` + Page int `src:"query" default:"1" desc:"Page number"` + PageSize int `src:"query" default:"50" desc:"Page size"` +} + +type UsersResponse struct { + Items []models.User `json:"items"` + Total int64 `json:"total"` +} + +// getUsers 获取角色下的用户列表(分页) +func getUsers(x *vigo.X, req *GetUsersReq) (*UsersResponse, error) { + var role models.Role + if err := cfg.DB().First(&role, "id = ?", req.RoleID).Error; err != nil { + return nil, vigo.ErrNotFound + } + + var total int64 + cfg.DB().Model(&models.UserRole{}).Where("role_id = ?", req.RoleID).Count(&total) + + var users []models.User + offset := (req.Page - 1) * req.PageSize + cfg.DB().Debug(). + Joins("JOIN vb_user_roles ON vb_user_roles.user_id = vb_users.id"). + Where("vb_user_roles.role_id = ?", req.RoleID). + Offset(offset).Limit(req.PageSize). + Find(&users) + + return &UsersResponse{Items: users, Total: total}, nil +} + +type UpdateUsersReq struct { + RoleID string `src:"path@id" desc:"Role ID"` + UserIDs []string `json:"user_ids" src:"json" desc:"List of User IDs"` +} + +// updateUsers 批量设置角色的用户 +func updateUsers(x *vigo.X, req *UpdateUsersReq) error { + var role models.Role + if err := cfg.DB().First(&role, "id = ?", req.RoleID).Error; err != nil { + return vigo.ErrNotFound + } + + if role.IsSystem { + return vigo.NewError("cannot modify users of system role").WithCode(40300) + } + + return cfg.DB().Transaction(func(tx *gorm.DB) error { + // 删除不在新列表中的关联 + if err := tx.Where("role_id = ? AND user_id NOT IN ?", req.RoleID, req.UserIDs). + Delete(&models.UserRole{}).Error; err != nil { + return err + } + + // 添加新关联(跳过已存在的) + for _, uid := range req.UserIDs { + var count int64 + tx.Model(&models.UserRole{}). + Where("role_id = ? AND user_id = ?", req.RoleID, uid). + Count(&count) + if count == 0 { + if err := tx.Create(&models.UserRole{ + RoleID: req.RoleID, + UserID: uid, + }).Error; err != nil { + return err + } + } + } + return nil + }) +}