// Package service 业务逻辑层 package service import ( "context" "encoding/json" "errors" "fmt" "log" "time" "server/common" "server/config" "server/modules/system/dto" "server/modules/system/entity" "server/modules/system/mapper" "server/modules/system/vo" "github.com/google/uuid" ) type SysUserService struct { *common.BaseService[entity.SysUser] mapper *mapper.SysUserMapper } func NewSysUserService() *SysUserService { mapper := mapper.NewSysUserMapper() return &SysUserService{ BaseService: common.NewBaseService[entity.SysUser](), mapper: mapper, } } // CreateUser 创建用户并返回 VO func (s *SysUserService) CreateUser(req *dto.CreateUserRequest, createBy string) (*vo.SysUserVO, error) { // DTO 转 Entity entityItem := &entity.SysUser{ Username: req.Username, Realname: req.Realname, Password: req.Password, Email: req.Email, Phone: req.Phone, Avatar: req.Avatar, Sex: 0, // 默认值 OrgCode: req.OrgCode, DelFlag: 0, Status: 1, CreateBy: createBy, } if req.Sex != nil { entityItem.Sex = *req.Sex } if req.Birthday != "" { birthday, err := time.Parse("2006-01-02", req.Birthday) if err == nil { entityItem.Birthday = &birthday } } // 保存到数据库 if err := s.Create(entityItem); err != nil { return nil, err } // Entity 转 VO return s.convertToVO(*entityItem), nil } // UpdateUser 更新用户并返回 VO func (s *SysUserService) UpdateUser(id string, req *dto.UpdateUserRequest) (*vo.SysUserVO, error) { // 获取原数据 entityItem, err := s.GetByID(id) if err != nil { return nil, fmt.Errorf("用户不存在: %w", err) } // 更新字段 updateFields := make(map[string]interface{}) if req.Realname != "" { updateFields["realname"] = req.Realname } if req.Email != "" { updateFields["email"] = req.Email } if req.Phone != "" { updateFields["phone"] = req.Phone } if req.Avatar != "" { updateFields["avatar"] = req.Avatar } if req.Sex != nil { updateFields["sex"] = *req.Sex } if req.Status != nil { updateFields["status"] = *req.Status } if req.OrgCode != "" { updateFields["org_code"] = req.OrgCode } if req.Birthday != "" { birthday, err := time.Parse("2006-01-02", req.Birthday) if err == nil { updateFields["birthday"] = birthday } } if err := s.mapper.UpdateFields(id, updateFields); err != nil { return nil, fmt.Errorf("更新用户失败: %w", err) } // 重新获取更新后的数据 entityItem, err = s.GetByID(id) if err != nil { return nil, fmt.Errorf("获取更新后数据失败: %w", err) } return s.convertToVO(*entityItem), nil } // GetUserByID 获取用户并返回 VO func (s *SysUserService) GetUserByID(id string) (*vo.SysUserVO, error) { entityItem, err := s.GetByID(id) if err != nil { return nil, err } return s.convertToVO(*entityItem), nil } // ListUsers 获取用户列表并返回 VO 列表 func (s *SysUserService) ListUsers(page, size int) ([]vo.SysUserVO, int64, error) { entities, total, err := s.List(page, size) if err != nil { return nil, 0, err } // 批量转换 Entity 到 VO vos := make([]vo.SysUserVO, len(entities)) for i := range entities { vos[i] = *s.convertToVO(entities[i]) } return vos, total, nil } // Login 用户登录(手机号登录) func (s *SysUserService) Login(username, password string) (*entity.LoginUser, string, error) { user, err := s.mapper.FindByPhone(username) if err != nil { return nil, "", errors.New("用户不存在") } if user.Status == 2 { return nil, "", errors.New("账号已被冻结") } encrypted, err := common.Encrypt(user.Username, password, user.Salt) if (user.Password != encrypted) || (err != nil) { return nil, "", errors.New("用户名或密码错误") } token := s.generateToken() loginUser := &entity.LoginUser{ ID: user.ID, Username: user.Username, Realname: user.Realname, Avatar: user.Avatar, Phone: user.Phone, Email: user.Email, Token: token, } if err := s.saveLoginUser(token, loginUser); err != nil { return nil, "", errors.New("登录失败,请重试") } return loginUser, token, nil } // SysLogin 用户登录(用户名登录) func (s *SysUserService) SysLogin(username, password string) (*entity.LoginUser, string, error) { user, err := s.mapper.FindByUsername(username) if err != nil { return nil, "", errors.New("用户不存在") } if user.Status == 2 { return nil, "", errors.New("账号已被冻结") } encrypted, err := common.Encrypt(username, password, user.Salt) if (user.Password != encrypted) || (err != nil) { return nil, "", errors.New("用户名或密码错误") } token := s.generateToken() loginUser := &entity.LoginUser{ ID: user.ID, Username: user.Username, Realname: user.Realname, Avatar: user.Avatar, Phone: user.Phone, Email: user.Email, Token: token, } if err := s.saveLoginUser(token, loginUser); err != nil { return nil, "", errors.New("登录失败,请重试") } return loginUser, token, nil } // Logout 用户登出 func (s *SysUserService) Logout(token string) error { ctx := context.Background() return config.RDB.Del(ctx, common.RedisTokenPrefix+token).Err() } // GetLoginUser 根据Token获取登录用户信息 func (s *SysUserService) GetLoginUser(token string) (*entity.LoginUser, error) { ctx := context.Background() data, err := config.RDB.Get(ctx, common.RedisTokenPrefix+token).Result() if err != nil { return nil, errors.New("未登录或登录已过期") } var loginUser entity.LoginUser if err := json.Unmarshal([]byte(data), &loginUser); err != nil { return nil, errors.New("登录信息异常") } config.RDB.Expire(ctx, common.RedisTokenPrefix+token, common.RedisTokenExpire) return &loginUser, nil } // RefreshToken 刷新Token过期时间 func (s *SysUserService) RefreshToken(token string) error { ctx := context.Background() return config.RDB.Expire(ctx, common.RedisTokenPrefix+token, common.RedisTokenExpire).Err() } // UpdatePassword 修改密码 func (s *SysUserService) UpdatePassword(id, oldPwd, newPwd string) error { user, err := s.GetByID(id) if err != nil { return errors.New("用户不存在") } encrypted, err := common.Encrypt(user.Username, oldPwd, user.Salt) if err != nil { log.Printf("密码加密失败: %v", err) return fmt.Errorf("密码加密失败: %w,请联系管理员", err) } if encrypted != user.Password { return errors.New("原密码错误") } newEncrypted, err := common.Encrypt(user.Username, newPwd, user.Salt) if err != nil { log.Printf("密码加密失败: %v", err) return fmt.Errorf("密码加密失败: %w,请联系管理员", err) } return s.mapper.UpdateFields(id, map[string]interface{}{ "password": newEncrypted, }) } // saveLoginUser 保存登录用户到Redis func (s *SysUserService) saveLoginUser(token string, user *entity.LoginUser) error { ctx := context.Background() data, err := json.Marshal(user) if err != nil { return err } return config.RDB.Set(ctx, common.RedisTokenPrefix+token, data, common.RedisTokenExpire).Err() } // generateToken 生成Token func (s *SysUserService) generateToken() string { return uuid.New().String() } // Create 创建用户(添加密码加密逻辑) func (s *SysUserService) Create(item *entity.SysUser) error { item.ID = uuid.New().String() item.Salt = uuid.New().String()[:8] encrypted, err := common.Encrypt(item.Username, item.Password, item.Salt) if err != nil { log.Printf("密码加密失败: %v", err) return fmt.Errorf("密码加密失败: %w,请联系管理员", err) } item.Password = encrypted item.DelFlag = 0 item.Status = 1 now := time.Now() item.CreateTime = &now return s.mapper.Create(item) } // convertToVO Entity 转 VO(私有方法) func (s *SysUserService) convertToVO(entity entity.SysUser) *vo.SysUserVO { return &vo.SysUserVO{ ID: entity.ID, Username: entity.Username, Realname: entity.Realname, Avatar: entity.Avatar, Birthday: entity.Birthday, Sex: entity.Sex, Email: entity.Email, Phone: entity.Phone, OrgCode: entity.OrgCode, Status: entity.Status, CreateTime: entity.CreateTime, UpdateTime: entity.UpdateTime, // 不包含 Password、Salt 等敏感字段 } }