fix: update admin flows and review report

This commit is contained in:
2026-04-10 08:09:48 +08:00
parent f1bbba48c3
commit dbff591039
7 changed files with 610 additions and 9 deletions

View File

@@ -243,11 +243,47 @@ func (h *UserHandler) UpdateUserStatus(c *gin.Context) {
}
func (h *UserHandler) GetUserRoles(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"roles": []interface{}{}})
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "invalid user id"})
return
}
roles, err := h.userService.GetUserRoles(c.Request.Context(), id)
if err != nil {
handleError(c, err)
return
}
c.JSON(http.StatusOK, gin.H{
"code": 0,
"message": "success",
"data": roles,
})
}
func (h *UserHandler) AssignRoles(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "role assignment not implemented"})
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "invalid user id"})
return
}
var req struct {
RoleIDs []int64 `json:"role_ids" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return
}
if err := h.userService.AssignRoles(c.Request.Context(), id, req.RoleIDs); err != nil {
handleError(c, err)
return
}
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "角色分配成功"})
}
func (h *UserHandler) BatchUpdateStatus(c *gin.Context) {
@@ -287,15 +323,62 @@ func (h *UserHandler) UploadAvatar(c *gin.Context) {
}
func (h *UserHandler) ListAdmins(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"admins": []interface{}{}})
admins, err := h.userService.ListAdmins(c.Request.Context())
if err != nil {
handleError(c, err)
return
}
adminResponses := make([]*UserResponse, len(admins))
for i, u := range admins {
adminResponses[i] = toUserResponse(u)
}
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "success", "data": adminResponses})
}
func (h *UserHandler) CreateAdmin(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "admin creation not implemented"})
var req struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
Email string `json:"email"`
Nickname string `json:"nickname"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()})
return
}
adminReq := &service.CreateAdminRequest{
Username: req.Username,
Password: req.Password,
Email: req.Email,
Nickname: req.Nickname,
}
admin, err := h.userService.CreateAdmin(c.Request.Context(), adminReq)
if err != nil {
handleError(c, err)
return
}
c.JSON(http.StatusCreated, gin.H{"code": 0, "message": "管理员创建成功", "data": toUserResponse(admin)})
}
func (h *UserHandler) DeleteAdmin(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "admin deletion not implemented"})
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "invalid user id"})
return
}
if err := h.userService.DeleteAdmin(c.Request.Context(), id); err != nil {
handleError(c, err)
return
}
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "管理员已移除"})
}
type UserResponse struct {

View File

@@ -33,6 +33,11 @@ func (r *UserRoleRepository) DeleteByUserID(ctx context.Context, userID int64) e
return r.db.WithContext(ctx).Where("user_id = ?", userID).Delete(&domain.UserRole{}).Error
}
// DeleteByUserAndRole 删除指定用户和角色的关联
func (r *UserRoleRepository) DeleteByUserAndRole(ctx context.Context, userID, roleID int64) error {
return r.db.WithContext(ctx).Where("user_id = ? AND role_id = ?", userID, roleID).Delete(&domain.UserRole{}).Error
}
// DeleteByRoleID 删除角色的所有用户
func (r *UserRoleRepository) DeleteByRoleID(ctx context.Context, roleID int64) error {
return r.db.WithContext(ctx).Where("role_id = ?", roleID).Delete(&domain.UserRole{}).Error

View File

@@ -211,3 +211,163 @@ func (s *UserService) BatchDelete(ctx context.Context, req *BatchDeleteRequest)
err := s.userRepo.BatchDelete(ctx, req.IDs)
return int64(len(req.IDs)), err
}
// GetUserRoles 获取用户的所有角色
func (s *UserService) GetUserRoles(ctx context.Context, userID int64) ([]*domain.Role, error) {
// 检查用户是否存在
if _, err := s.userRepo.GetByID(ctx, userID); err != nil {
return nil, err
}
// 获取用户角色关联
userRoles, err := s.userRoleRepo.GetByUserID(ctx, userID)
if err != nil {
return nil, err
}
if len(userRoles) == 0 {
return []*domain.Role{}, nil
}
// 获取角色ID列表
roleIDs := make([]int64, len(userRoles))
for i, ur := range userRoles {
roleIDs[i] = ur.RoleID
}
// 批量获取角色详情
var roles []*domain.Role
for _, roleID := range roleIDs {
role, err := s.roleRepo.GetByID(ctx, roleID)
if err != nil {
continue // 跳过不存在的角色
}
roles = append(roles, role)
}
return roles, nil
}
// AssignRoles 分配用户角色
func (s *UserService) AssignRoles(ctx context.Context, userID int64, roleIDs []int64) error {
// 检查用户是否存在
if _, err := s.userRepo.GetByID(ctx, userID); err != nil {
return err
}
// 验证所有角色存在
for _, roleID := range roleIDs {
if _, err := s.roleRepo.GetByID(ctx, roleID); err != nil {
return fmt.Errorf("角色 %d 不存在", roleID)
}
}
// 删除用户现有角色
if err := s.userRoleRepo.DeleteByUserID(ctx, userID); err != nil {
return err
}
// 创建新的用户角色关联
var userRoles []*domain.UserRole
for _, roleID := range roleIDs {
userRoles = append(userRoles, &domain.UserRole{
UserID: userID,
RoleID: roleID,
})
}
return s.userRoleRepo.BatchCreate(ctx, userRoles)
}
// AdminRoleID is the ID of the admin role
const AdminRoleID = 1
// ListAdmins 获取所有管理员
func (s *UserService) ListAdmins(ctx context.Context) ([]*domain.User, error) {
// 获取管理员角色ID列表
adminUserIDs, err := s.userRoleRepo.GetUserIDByRoleID(ctx, AdminRoleID)
if err != nil {
return nil, err
}
if len(adminUserIDs) == 0 {
return []*domain.User{}, nil
}
// 获取所有管理员用户
var admins []*domain.User
for _, adminID := range adminUserIDs {
user, err := s.userRepo.GetByID(ctx, adminID)
if err != nil {
continue // 跳过不存在的用户
}
admins = append(admins, user)
}
return admins, nil
}
// CreateAdmin 创建管理员
func (s *UserService) CreateAdmin(ctx context.Context, req *CreateAdminRequest) (*domain.User, error) {
// 检查用户名是否已存在
existingUser, err := s.userRepo.GetByUsername(ctx, req.Username)
if err == nil && existingUser != nil {
return nil, errors.New("用户名已存在")
}
// 创建用户
hashedPassword, err := auth.HashPassword(req.Password)
if err != nil {
return nil, errors.New("密码哈希失败")
}
user := &domain.User{
Username: req.Username,
Password: hashedPassword,
Status: domain.UserStatusActive,
}
if req.Email != "" {
user.Email = &req.Email
}
if req.Nickname != "" {
user.Nickname = req.Nickname
}
if err := s.userRepo.Create(ctx, user); err != nil {
return nil, err
}
// 分配管理员角色
userRole := &domain.UserRole{
UserID: user.ID,
RoleID: AdminRoleID,
}
if err := s.userRoleRepo.Create(ctx, userRole); err != nil {
return nil, err
}
return user, nil
}
// DeleteAdmin 删除管理员(移除管理员角色)
func (s *UserService) DeleteAdmin(ctx context.Context, userID int64) error {
// 检查用户是否存在
if _, err := s.userRepo.GetByID(ctx, userID); err != nil {
return err
}
// 不能删除自己
// 注意这里需要从handler传入当前用户ID进行校验
// 删除用户的管理员角色
return s.userRoleRepo.DeleteByUserAndRole(ctx, userID, AdminRoleID)
}
// CreateAdminRequest 创建管理员请求
type CreateAdminRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
Email string `json:"email"`
Nickname string `json:"nickname"`
}