119 lines
3.1 KiB
Go
119 lines
3.1 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
"slogan-agent/common"
|
|
"slogan-agent/styleagent/dao"
|
|
"slogan-agent/styleagent/model/dto"
|
|
"slogan-agent/styleagent/model/entity"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
type userService struct{}
|
|
|
|
var UserService = new(userService)
|
|
|
|
func (s *userService) Register(ctx context.Context, req *dto.RegisterReq) (*dto.RegisterRes, error) {
|
|
if req.Account == "" || req.Password == "" {
|
|
return nil, errors.New("账号和密码不能为空")
|
|
}
|
|
existing, err := dao.User.GetByAccount(ctx, req.Account)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if existing != nil {
|
|
return nil, errors.New("账号已存在")
|
|
}
|
|
hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
name := req.Name
|
|
if name == "" {
|
|
name = req.Account
|
|
}
|
|
if _, err := dao.User.Insert(ctx, &entity.User{
|
|
Role: "user",
|
|
Username: req.Account,
|
|
Password: string(hash),
|
|
Name: name,
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
return &dto.RegisterRes{}, nil
|
|
}
|
|
|
|
func (s *userService) Login(ctx context.Context, req *dto.LoginReq) (*dto.LoginRes, error) {
|
|
if req.Account == "" {
|
|
return nil, errors.New("请输入账号")
|
|
}
|
|
user, err := dao.User.GetByAccount(ctx, req.Account)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if user == nil {
|
|
return nil, errors.New("账号不存在")
|
|
}
|
|
if bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)) != nil {
|
|
return nil, errors.New("密码错误")
|
|
}
|
|
now := time.Now()
|
|
claims := common.JwtClaims{
|
|
UserId: user.Id,
|
|
Role: user.Role,
|
|
RegisteredClaims: jwt.RegisteredClaims{
|
|
ExpiresAt: jwt.NewNumericDate(now.Add(7 * 24 * time.Hour)),
|
|
IssuedAt: jwt.NewNumericDate(now),
|
|
},
|
|
}
|
|
token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString([]byte(common.GetJwtSecret()))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &dto.LoginRes{
|
|
Token: token,
|
|
User: &dto.LoginUser{Id: user.Id, Role: user.Role, Name: user.Name},
|
|
}, nil
|
|
}
|
|
|
|
func (s *userService) ChangePassword(ctx context.Context, userId int64, req *dto.ChangePasswordReq) (*dto.ChangePasswordRes, error) {
|
|
user, err := dao.User.GetOne(ctx, userId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if user == nil {
|
|
return nil, errors.New("用户不存在")
|
|
}
|
|
if bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.OldPassword)) != nil {
|
|
return nil, errors.New("原密码错误")
|
|
}
|
|
hash, err := bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if err := dao.User.UpdateFields(ctx, userId, map[string]any{"password": string(hash)}); err != nil {
|
|
return nil, err
|
|
}
|
|
return &dto.ChangePasswordRes{}, nil
|
|
}
|
|
|
|
// Profile 我的资料(用户不存在返回空资料,兼容已过期 token 清理场景)
|
|
func (s *userService) Profile(ctx context.Context, userId int64) (*dto.ProfileRes, error) {
|
|
user, err := dao.User.GetOne(ctx, userId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if user == nil {
|
|
return &dto.ProfileRes{}, nil
|
|
}
|
|
return &dto.ProfileRes{
|
|
Id: user.Id, Role: user.Role, Name: user.Name,
|
|
Username: user.Username, Phone: user.Phone,
|
|
}, nil
|
|
}
|