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 }