This commit is contained in:
2026-04-25 11:59:10 +08:00
parent e246271a24
commit ba463ae38d
33 changed files with 1600 additions and 112 deletions

View File

@@ -13,6 +13,7 @@ import (
"tyapi-server/internal/domains/user/entities"
"tyapi-server/internal/domains/user/events"
user_service "tyapi-server/internal/domains/user/services"
"tyapi-server/internal/shared/auth"
"tyapi-server/internal/shared/interfaces"
"tyapi-server/internal/shared/middleware"
)
@@ -27,6 +28,7 @@ type UserApplicationServiceImpl struct {
contractService user_service.ContractAggregateService
eventBus interfaces.EventBus
jwtAuth *middleware.JWTAuthMiddleware
accountKindProvider interfaces.AccountKindProvider
logger *zap.Logger
}
@@ -39,6 +41,7 @@ func NewUserApplicationService(
contractService user_service.ContractAggregateService,
eventBus interfaces.EventBus,
jwtAuth *middleware.JWTAuthMiddleware,
accountKindProvider interfaces.AccountKindProvider,
logger *zap.Logger,
) UserApplicationService {
return &UserApplicationServiceImpl{
@@ -49,6 +52,7 @@ func NewUserApplicationService(
contractService: contractService,
eventBus: eventBus,
jwtAuth: jwtAuth,
accountKindProvider: accountKindProvider,
logger: logger,
}
}
@@ -90,76 +94,16 @@ func (s *UserApplicationServiceImpl) LoginWithPassword(ctx context.Context, cmd
return nil, err
}
// 2. 生成包含用户类型的token
accessToken, err := s.jwtAuth.GenerateToken(user.ID, user.Phone, user.Phone, user.UserType)
if err != nil {
s.logger.Error("生成令牌失败", zap.Error(err))
return nil, fmt.Errorf("生成访问令牌失败")
}
// 3. 如果是管理员,更新登录统计
if user.IsAdmin() {
if err := s.userAggregateService.UpdateLoginStats(ctx, user.ID); err != nil {
s.logger.Error("更新登录统计失败", zap.Error(err))
}
// 重新获取用户信息以获取最新的登录统计
updatedUser, err := s.userAggregateService.GetUserByID(ctx, user.ID)
if err != nil {
s.logger.Error("重新获取用户信息失败", zap.Error(err))
} else {
user = updatedUser
// 2. 账号类型(下属/普通)
accountKind := auth.AccountKindStandalone
if s.accountKindProvider != nil {
if k, err := s.accountKindProvider.AccountKind(ctx, user.ID); err == nil && k != "" {
accountKind = k
}
}
// 4. 获取用户权限(仅管理员)
var permissions []string
if user.IsAdmin() {
permissions, err = s.userAuthService.GetUserPermissions(ctx, user)
if err != nil {
s.logger.Error("获取用户权限失败", zap.Error(err))
permissions = []string{}
}
}
// 5. 构建用户信息
userProfile := &responses.UserProfileResponse{
ID: user.ID,
Phone: user.Phone,
Username: user.Username,
UserType: user.UserType,
IsActive: user.Active,
LastLoginAt: user.LastLoginAt,
LoginCount: user.LoginCount,
Permissions: permissions,
CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt,
}
return &responses.LoginUserResponse{
User: userProfile,
AccessToken: accessToken,
TokenType: "Bearer",
ExpiresIn: 86400, // 24h
LoginMethod: "password",
}, nil
}
// LoginWithSMS 短信验证码登录
// 业务流程1. 验证短信验证码 2. 验证用户登录状态 3. 生成访问令牌 4. 更新登录统计 5. 获取用户权限
func (s *UserApplicationServiceImpl) LoginWithSMS(ctx context.Context, cmd *commands.LoginWithSMSCommand) (*responses.LoginUserResponse, error) {
// 1. 验证短信验证码
if err := s.smsCodeService.VerifyCode(ctx, cmd.Phone, cmd.Code, entities.SMSSceneLogin); err != nil {
return nil, fmt.Errorf("验证码错误或已过期")
}
// 2. 验证用户登录状态
user, err := s.userAuthService.ValidateUserLogin(ctx, cmd.Phone)
if err != nil {
return nil, err
}
// 3. 生成包含用户类型的token
accessToken, err := s.jwtAuth.GenerateToken(user.ID, user.Phone, user.Phone, user.UserType)
// 3. 生成包含用户类型的 token
accessToken, err := s.jwtAuth.GenerateToken(user.ID, user.Phone, user.Phone, user.UserType, accountKind)
if err != nil {
s.logger.Error("生成令牌失败", zap.Error(err))
return nil, fmt.Errorf("生成访问令牌失败")
@@ -201,6 +145,83 @@ func (s *UserApplicationServiceImpl) LoginWithSMS(ctx context.Context, cmd *comm
Permissions: permissions,
CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt,
AccountKind: accountKind,
}
return &responses.LoginUserResponse{
User: userProfile,
AccessToken: accessToken,
TokenType: "Bearer",
ExpiresIn: 86400, // 24h
LoginMethod: "password",
}, nil
}
// LoginWithSMS 短信验证码登录
// 业务流程1. 验证短信验证码 2. 验证用户登录状态 3. 生成访问令牌 4. 更新登录统计 5. 获取用户权限
func (s *UserApplicationServiceImpl) LoginWithSMS(ctx context.Context, cmd *commands.LoginWithSMSCommand) (*responses.LoginUserResponse, error) {
// 1. 验证短信验证码
if err := s.smsCodeService.VerifyCode(ctx, cmd.Phone, cmd.Code, entities.SMSSceneLogin); err != nil {
return nil, fmt.Errorf("验证码错误或已过期")
}
// 2. 验证用户登录状态
user, err := s.userAuthService.ValidateUserLogin(ctx, cmd.Phone)
if err != nil {
return nil, err
}
accountKind := auth.AccountKindStandalone
if s.accountKindProvider != nil {
if k, err := s.accountKindProvider.AccountKind(ctx, user.ID); err == nil && k != "" {
accountKind = k
}
}
// 3. 生成包含用户类型的 token
accessToken, err := s.jwtAuth.GenerateToken(user.ID, user.Phone, user.Phone, user.UserType, accountKind)
if err != nil {
s.logger.Error("生成令牌失败", zap.Error(err))
return nil, fmt.Errorf("生成访问令牌失败")
}
// 4. 如果是管理员,更新登录统计
if user.IsAdmin() {
if err := s.userAggregateService.UpdateLoginStats(ctx, user.ID); err != nil {
s.logger.Error("更新登录统计失败", zap.Error(err))
}
// 重新获取用户信息以获取最新的登录统计
updatedUser, err := s.userAggregateService.GetUserByID(ctx, user.ID)
if err != nil {
s.logger.Error("重新获取用户信息失败", zap.Error(err))
} else {
user = updatedUser
}
}
// 5. 获取用户权限(仅管理员)
var permissions []string
if user.IsAdmin() {
permissions, err = s.userAuthService.GetUserPermissions(ctx, user)
if err != nil {
s.logger.Error("获取用户权限失败", zap.Error(err))
permissions = []string{}
}
}
// 6. 构建用户信息
userProfile := &responses.UserProfileResponse{
ID: user.ID,
Phone: user.Phone,
Username: user.Username,
UserType: user.UserType,
IsActive: user.Active,
LastLoginAt: user.LastLoginAt,
LoginCount: user.LoginCount,
Permissions: permissions,
CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt,
AccountKind: accountKind,
}
return &responses.LoginUserResponse{
@@ -262,6 +283,12 @@ func (s *UserApplicationServiceImpl) GetUserProfile(ctx context.Context, userID
Permissions: permissions,
CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt,
AccountKind: auth.AccountKindStandalone,
}
if s.accountKindProvider != nil {
if k, err := s.accountKindProvider.AccountKind(ctx, userID); err == nil && k != "" {
userProfile.AccountKind = k
}
}
// 4. 添加企业信息