190 lines
4.9 KiB
Go
190 lines
4.9 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.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,
|
|
})
|
|
}
|