duidui_fiber/internal/admin_auth/service/auth_service.go
2026-03-27 10:34:03 +08:00

188 lines
4.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"fmt"
"time"
"dd_fiber_api/internal/admin_auth"
"dd_fiber_api/internal/admin_auth/dao"
jwt_pkg "dd_fiber_api/pkg/jwt"
"github.com/golang-jwt/jwt/v5"
"golang.org/x/crypto/bcrypt"
)
// AuthService 认证服务
type AuthService struct {
adminUserDAO *dao.AdminUserDAO
jwt *jwt_pkg.JWT
jwtExpiresIn time.Duration
}
// NewAuthService 创建认证服务
func NewAuthService(adminUserDAO *dao.AdminUserDAO, jwtSecret string, jwtExpiresIn time.Duration) *AuthService {
return &AuthService{
adminUserDAO: adminUserDAO,
jwt: jwt_pkg.NewJWT(jwtSecret, jwtExpiresIn),
jwtExpiresIn: jwtExpiresIn,
}
}
// Login 登录(支持用户名或手机号登录)
func (s *AuthService) Login(req *admin_auth.LoginRequest, clientIP string) (*admin_auth.LoginResponse, error) {
var user *admin_auth.AdminUser
var err error
// 优先使用用户名登录,如果没有用户名则使用手机号
if req.Username != "" {
user, err = s.adminUserDAO.GetByUsername(req.Username)
} else if req.Phone != "" {
user, err = s.adminUserDAO.GetByPhone(req.Phone)
} else {
return &admin_auth.LoginResponse{
Success: false,
Message: "用户名或手机号不能为空",
}, nil
}
if err != nil {
return &admin_auth.LoginResponse{
Success: false,
Message: "登录失败: " + err.Error(),
}, nil
}
if user == nil {
return &admin_auth.LoginResponse{
Success: false,
Message: "用户名或密码错误",
}, nil
}
// 验证密码
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)); err != nil {
return &admin_auth.LoginResponse{
Success: false,
Message: "用户名或密码错误",
}, nil
}
// 获取用户角色和权限
roles, err := s.adminUserDAO.GetUserRoles(user.ID)
if err != nil {
return &admin_auth.LoginResponse{
Success: false,
Message: "获取用户角色失败: " + err.Error(),
}, nil
}
if roles == nil {
roles = []string{}
}
permissions, err := s.adminUserDAO.GetUserPermissions(user.ID)
if err != nil {
return &admin_auth.LoginResponse{
Success: false,
Message: "获取用户权限失败: " + err.Error(),
}, nil
}
if permissions == nil {
permissions = []string{}
}
// 如果是超级管理员,添加所有权限标记
isSuperAdmin := user.IsSuperAdmin == 1
// 生成JWT token
claims := &admin_auth.JWTClaims{
UserID: user.ID,
Username: user.Username,
Phone: user.Phone,
IsSuperAdmin: isSuperAdmin,
Roles: roles,
Permissions: permissions,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(s.jwtExpiresIn)),
IssuedAt: jwt.NewNumericDate(time.Now()),
NotBefore: jwt.NewNumericDate(time.Now()),
},
}
token, err := s.jwt.GenerateToken(claims)
if err != nil {
return &admin_auth.LoginResponse{
Success: false,
Message: "生成token失败: " + err.Error(),
}, nil
}
// 更新最后登录信息
if err := s.adminUserDAO.UpdateLastLogin(user.ID, clientIP); err != nil {
// 登录信息更新失败不影响登录,只记录日志
fmt.Printf("更新最后登录信息失败: %v\n", err)
}
// 构建用户信息
userInfo := &admin_auth.AdminUserInfo{
ID: user.ID,
Username: user.Username,
Phone: user.Phone,
Nickname: user.Nickname,
Avatar: user.Avatar,
IsSuperAdmin: isSuperAdmin,
Roles: roles,
Permissions: permissions,
}
return &admin_auth.LoginResponse{
Success: true,
Message: "登录成功",
Token: token,
User: userInfo,
}, nil
}
// GetUserInfo 获取用户信息从token中解析
func (s *AuthService) GetUserInfo(tokenString string) (*admin_auth.AdminUserInfo, error) {
claims := &admin_auth.JWTClaims{}
if err := s.jwt.ParseToken(tokenString, claims); err != nil {
return nil, err
}
// 从数据库获取最新用户信息
user, err := s.adminUserDAO.GetByID(claims.UserID)
if err != nil || user == nil {
return nil, fmt.Errorf("用户不存在")
}
// 获取最新角色和权限
roles, _ := s.adminUserDAO.GetUserRoles(user.ID)
if roles == nil {
roles = []string{}
}
permissions, _ := s.adminUserDAO.GetUserPermissions(user.ID)
if permissions == nil {
permissions = []string{}
}
return &admin_auth.AdminUserInfo{
ID: user.ID,
Username: user.Username,
Phone: user.Phone,
Nickname: user.Nickname,
Avatar: user.Avatar,
IsSuperAdmin: user.IsSuperAdmin == 1,
Roles: roles,
Permissions: permissions,
}, nil
}
// VerifyToken 验证token
func (s *AuthService) VerifyToken(tokenString string) (*admin_auth.JWTClaims, error) {
claims := &admin_auth.JWTClaims{}
if err := s.jwt.ParseToken(tokenString, claims); err != nil {
return nil, err
}
return claims, nil
}