golang-yitisheng-server/server/modules/system/service/sys_user_service.go

232 lines
6.0 KiB
Go

// Package service 业务逻辑层
package service
import (
"context"
"encoding/json"
"errors"
"fmt"
"log"
"time"
"server/common"
"server/config"
"server/modules/system/entity"
"server/modules/system/mapper"
"github.com/google/uuid"
)
const (
TokenPrefix = "login:token:" // Redis中Token前缀
TokenExpire = 24 * time.Hour // Token过期时间
)
type SysUserService struct {
mapper *mapper.SysUserMapper
}
func NewSysUserService() *SysUserService {
return &SysUserService{mapper: mapper.NewSysUserMapper()}
}
// Login 用户登录
// 密码验证方式与 Java JeecgBoot 兼容: PBEWithMD5AndDES(username, password, salt)
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("账号已被冻结")
}
// 验证密码 (与Java兼容: encrypt(username, password, salt))
encrypted, err := common.Encrypt(user.Username, password, user.Salt)
if (user.Password != encrypted) || (err != nil) {
return nil, "", errors.New("用户名或密码错误")
}
// 生成Token
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,
}
// 存储到Redis
if err := s.saveLoginUser(token, loginUser); err != nil {
return nil, "", errors.New("登录失败,请重试")
}
return loginUser, token, nil
}
// SysLogin 用户登录
// 密码验证方式与 Java JeecgBoot 兼容: PBEWithMD5AndDES(username, password, salt)
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("账号已被冻结")
}
// 验证密码 (与Java兼容: encrypt(username, password, salt))
encrypted, err := common.Encrypt(username, password, user.Salt)
if (user.Password != encrypted) || (err != nil) {
return nil, "", errors.New("用户名或密码错误")
}
// 生成Token
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,
}
// 存储到Redis
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, TokenPrefix+token).Err()
}
// GetLoginUser 根据Token获取登录用户信息
func (s *SysUserService) GetLoginUser(token string) (*entity.LoginUser, error) {
ctx := context.Background()
data, err := config.RDB.Get(ctx, TokenPrefix+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, TokenPrefix+token, TokenExpire)
return &loginUser, nil
}
// RefreshToken 刷新Token过期时间
func (s *SysUserService) RefreshToken(token string) error {
ctx := context.Background()
return config.RDB.Expire(ctx, TokenPrefix+token, TokenExpire).Err()
}
// 保存登录用户到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, TokenPrefix+token, data, TokenExpire).Err()
}
// 生成Token
func (s *SysUserService) generateToken() string {
return uuid.New().String()
}
// ========== 用户管理 ==========
func (s *SysUserService) List(page, size int) ([]entity.SysUser, int64, error) {
return s.mapper.FindAll(page, size)
}
func (s *SysUserService) GetByID(id string) (*entity.SysUser, error) {
return s.mapper.FindByID(id)
}
func (s *SysUserService) Create(item *entity.SysUser) error {
item.ID = uuid.New().String()
// 生成盐值 (8字节)
item.Salt = uuid.New().String()[:8]
// 加密密码 (与Java兼容)
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)
}
func (s *SysUserService) Update(item *entity.SysUser) error {
now := time.Now()
item.UpdateTime = &now
return s.mapper.Update(item)
}
func (s *SysUserService) UpdateFields(id string, fields map[string]interface{}) error {
return s.mapper.UpdateFields(id, fields)
}
func (s *SysUserService) Delete(id string) error {
return s.mapper.Delete(id)
}
// UpdatePassword 修改密码
func (s *SysUserService) UpdatePassword(id, oldPwd, newPwd string) error {
user, err := s.mapper.FindByID(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,
})
}