feat(role): add role users batch management API

- Add GET /{id}/users endpoint for paginated role user listing
    - Add PUT /{id}/users endpoint for batch role user assignment
    - Use transaction to atomically sync user-role associations
    - Prevent modification of system role user assignments
master
veypi 3 weeks ago
parent d5d2421e7e
commit c21c766b6a

@ -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)
}

@ -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
})
}
Loading…
Cancel
Save