package service import ( "errors" "time" "golang.org/x/crypto/bcrypt" "gorm.io/gorm" "laic-backend/common" "laic-backend/logger" "laic-backend/model" "laic-backend/tool" "laic-backend/vo" ) type SystemService struct{} var DefaultSystemService = &SystemService{} // GetUserPage 用户分页列表(admin 全量) func (s *SystemService) GetUserPage(req *vo.UserPageReq) (*common.PageResponse[model.User], *common.BusiError) { db := common.DB.Model(&model.User{}) if req.Keyword != "" { kw := "%" + req.Keyword + "%" db = db.Where("name LIKE ? OR phone LIKE ? OR email LIKE ?", kw, kw, kw) } if req.Role != "" { db = db.Where("role = ?", req.Role) } if req.Status != 0 { db = db.Where("status = ?", req.Status) } var total int64 if err := db.Count(&total).Error; err != nil { logger.ERROR("统计用户失败", err) return nil, common.ErrInternal } var list []model.User if err := db.Scopes(req.Paginate).Order("id DESC").Find(&list).Error; err != nil { logger.ERROR("查询用户列表失败", err) return nil, common.ErrInternal } return common.Page(req.Pagination, total, list), nil } // CreateUser 管理员创建用户 func (s *SystemService) CreateUser(req *vo.UserCreateReq) (*model.User, *common.BusiError) { var count int64 if err := common.DB.Model(&model.User{}).Where("phone = ?", req.Phone).Count(&count).Error; err != nil { return nil, common.ErrInternal } if count > 0 { return nil, common.ErrUserPhoneExists } id, err := tool.NextID() if err != nil { return nil, common.ErrInternal } hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost) if err != nil { return nil, common.ErrInternal } role := req.Role if role == "" { role = common.RoleUser } now := time.Now() user := &model.User{ ID: id, Name: req.Name, Phone: req.Phone, Email: req.Email, Password: string(hash), Role: role, Status: 1, CreatedAt: now, UpdatedAt: now, } if err := common.DB.Create(user).Error; err != nil { if code, _ := common.ParseError(err); code == 1062 { return nil, common.ErrUserPhoneExists } logger.ERROR("创建用户失败", err) return nil, common.ErrInternal } _ = common.SetUserRole(id, role) return user, nil } // UpdateUser 管理员编辑用户(角色/状态/密码等) func (s *SystemService) UpdateUser(id int64, req *vo.UserUpdateReq) (*model.User, *common.BusiError) { var user model.User if err := common.DB.First(&user, id).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, common.ErrUserNotFound } return nil, common.ErrInternal } updates := map[string]any{"updated_at": time.Now()} if req.Name != "" { updates["name"] = req.Name } if req.Email != "" { updates["email"] = req.Email } if req.Password != "" { hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost) if err != nil { return nil, common.ErrInternal } updates["password"] = string(hash) } if req.Role != "" { updates["role"] = req.Role } if req.Status != nil { updates["status"] = *req.Status } if err := common.DB.Model(&user).Updates(updates).Error; err != nil { logger.ERROR("更新用户失败", err) return nil, common.ErrInternal } common.DB.First(&user, id) if req.Role != "" { _ = common.SetUserRole(id, req.Role) } return &user, nil } // DeleteUser 删除用户 func (s *SystemService) DeleteUser(id int64) *common.BusiError { res := common.DB.Delete(&model.User{}, id) if res.Error != nil { logger.ERROR("删除用户失败", res.Error) return common.ErrInternal } if res.RowsAffected == 0 { return common.ErrUserNotFound } _ = common.SetUserRole(id, "") return nil } // GetRoles 角色列表 func (s *SystemService) GetRoles() []string { return []string{common.RoleAdmin, common.RoleUser} }