package user import ( "context" "fmt" "go.uber.org/zap" "tyapi-server/internal/application/user/dto/commands" "tyapi-server/internal/application/user/dto/queries" "tyapi-server/internal/application/user/dto/responses" finance_service "tyapi-server/internal/domains/finance/services" "tyapi-server/internal/domains/user/entities" "tyapi-server/internal/domains/user/events" user_service "tyapi-server/internal/domains/user/services" "tyapi-server/internal/shared/interfaces" "tyapi-server/internal/shared/middleware" ) // UserApplicationServiceImpl 用户应用服务实现 // 负责业务流程编排、事务管理、数据转换,不直接操作仓库 type UserApplicationServiceImpl struct { userAggregateService user_service.UserAggregateService userAuthService *user_service.UserAuthService smsCodeService *user_service.SMSCodeService walletService finance_service.WalletAggregateService contractService user_service.ContractAggregateService eventBus interfaces.EventBus jwtAuth *middleware.JWTAuthMiddleware logger *zap.Logger } // NewUserApplicationService 创建用户应用服务 func NewUserApplicationService( userAggregateService user_service.UserAggregateService, userAuthService *user_service.UserAuthService, smsCodeService *user_service.SMSCodeService, walletService finance_service.WalletAggregateService, contractService user_service.ContractAggregateService, eventBus interfaces.EventBus, jwtAuth *middleware.JWTAuthMiddleware, logger *zap.Logger, ) UserApplicationService { return &UserApplicationServiceImpl{ userAggregateService: userAggregateService, userAuthService: userAuthService, smsCodeService: smsCodeService, walletService: walletService, contractService: contractService, eventBus: eventBus, jwtAuth: jwtAuth, logger: logger, } } // Register 用户注册 // 业务流程:1. 验证短信验证码 2. 创建用户 3. 发布注册事件 func (s *UserApplicationServiceImpl) Register(ctx context.Context, cmd *commands.RegisterUserCommand) (*responses.RegisterUserResponse, error) { // 1. 验证短信验证码 if err := s.smsCodeService.VerifyCode(ctx, cmd.Phone, cmd.Code, entities.SMSSceneRegister); err != nil { return nil, fmt.Errorf("验证码错误或已过期") } // 2. 创建用户 user, err := s.userAggregateService.CreateUser(ctx, cmd.Phone, cmd.Password) if err != nil { return nil, err } // 3. 发布用户注册事件 event := events.NewUserRegisteredEvent(user, "") if err := s.eventBus.Publish(ctx, event); err != nil { s.logger.Warn("发布用户注册事件失败", zap.Error(err)) } s.logger.Info("用户注册成功", zap.String("user_id", user.ID), zap.String("phone", user.Phone)) return &responses.RegisterUserResponse{ ID: user.ID, Phone: user.Phone, }, nil } // LoginWithPassword 密码登录 // 业务流程:1. 验证用户密码 2. 生成访问令牌 3. 更新登录统计 4. 获取用户权限 func (s *UserApplicationServiceImpl) LoginWithPassword(ctx context.Context, cmd *commands.LoginWithPasswordCommand) (*responses.LoginUserResponse, error) { // 1. 验证用户密码 user, err := s.userAuthService.ValidatePassword(ctx, cmd.Phone, cmd.Password) if err != nil { 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 } } // 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) 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, } return &responses.LoginUserResponse{ User: userProfile, AccessToken: accessToken, TokenType: "Bearer", ExpiresIn: int64(s.jwtAuth.GetExpiresIn().Seconds()), // 168h LoginMethod: "sms", }, nil } // SendSMS 发送短信验证码 // 业务流程:1. 发送短信验证码 func (s *UserApplicationServiceImpl) SendSMS(ctx context.Context, cmd *commands.SendCodeCommand) error { return s.smsCodeService.SendCode(ctx, cmd.Phone, entities.SMSScene(cmd.Scene), "", "") } // ChangePassword 修改密码 // 业务流程:1. 修改用户密码 func (s *UserApplicationServiceImpl) ChangePassword(ctx context.Context, cmd *commands.ChangePasswordCommand) error { return s.userAuthService.ChangePassword(ctx, cmd.UserID, cmd.OldPassword, cmd.NewPassword) } // ResetPassword 重置密码 // 业务流程:1. 验证短信验证码 2. 重置用户密码 func (s *UserApplicationServiceImpl) ResetPassword(ctx context.Context, cmd *commands.ResetPasswordCommand) error { // 1. 验证短信验证码 if err := s.smsCodeService.VerifyCode(ctx, cmd.Phone, cmd.Code, entities.SMSSceneResetPassword); err != nil { return fmt.Errorf("验证码错误或已过期") } // 2. 重置用户密码 return s.userAuthService.ResetPassword(ctx, cmd.Phone, cmd.NewPassword) } // GetUserProfile 获取用户资料 // 业务流程:1. 获取用户信息 2. 获取企业信息 3. 构建响应数据 func (s *UserApplicationServiceImpl) GetUserProfile(ctx context.Context, userID string) (*responses.UserProfileResponse, error) { // 1. 获取用户信息(包含企业信息) user, err := s.userAggregateService.GetUserWithEnterpriseInfo(ctx, userID) if err != nil { return nil, err } // 2. 获取用户权限(仅管理员) var permissions []string if user.IsAdmin() { permissions, err = s.userAuthService.GetUserPermissions(ctx, user) if err != nil { s.logger.Error("获取用户权限失败", zap.Error(err)) permissions = []string{} } } // 3. 构建用户信息 userProfile := &responses.UserProfileResponse{ ID: user.ID, Phone: user.Phone, Username: user.Username, UserType: user.UserType, IsActive: user.Active, IsCertified: user.IsCertified, LastLoginAt: user.LastLoginAt, LoginCount: user.LoginCount, Permissions: permissions, CreatedAt: user.CreatedAt, UpdatedAt: user.UpdatedAt, } // 4. 添加企业信息 if user.EnterpriseInfo != nil { userProfile.EnterpriseInfo = &responses.EnterpriseInfoResponse{ ID: user.EnterpriseInfo.ID, CompanyName: user.EnterpriseInfo.CompanyName, UnifiedSocialCode: user.EnterpriseInfo.UnifiedSocialCode, LegalPersonName: user.EnterpriseInfo.LegalPersonName, LegalPersonID: user.EnterpriseInfo.LegalPersonID, LegalPersonPhone: user.EnterpriseInfo.LegalPersonPhone, EnterpriseAddress: user.EnterpriseInfo.EnterpriseAddress, CreatedAt: user.EnterpriseInfo.CreatedAt, UpdatedAt: user.EnterpriseInfo.UpdatedAt, } } return userProfile, nil } // GetUser 获取用户信息 // 业务流程:1. 获取用户信息 2. 构建响应数据 func (s *UserApplicationServiceImpl) GetUser(ctx context.Context, query *queries.GetUserQuery) (*responses.UserProfileResponse, error) { user, err := s.userAggregateService.GetUserByID(ctx, query.UserID) if err != nil { return nil, err } return &responses.UserProfileResponse{ ID: user.ID, Phone: user.Phone, Username: user.Username, UserType: user.UserType, IsActive: user.Active, LastLoginAt: user.LastLoginAt, LoginCount: user.LoginCount, CreatedAt: user.CreatedAt, UpdatedAt: user.UpdatedAt, }, nil } // ListUsers 获取用户列表(管理员功能) // 业务流程:1. 查询用户列表 2. 构建响应数据 func (s *UserApplicationServiceImpl) ListUsers(ctx context.Context, query *queries.ListUsersQuery) (*responses.UserListResponse, error) { // 1. 查询用户列表 users, total, err := s.userAggregateService.ListUsers(ctx, query.ToDomainQuery()) if err != nil { return nil, err } // 2. 构建响应数据 items := make([]*responses.UserListItem, 0, len(users)) for _, user := range users { item := &responses.UserListItem{ ID: user.ID, Phone: user.Phone, UserType: user.UserType, Username: user.Username, IsActive: user.Active, IsCertified: user.IsCertified, LoginCount: user.LoginCount, LastLoginAt: user.LastLoginAt, CreatedAt: user.CreatedAt, UpdatedAt: user.UpdatedAt, } // 添加企业信息 if user.EnterpriseInfo != nil { item.EnterpriseInfo = &responses.EnterpriseInfoItem{ ID: user.EnterpriseInfo.ID, CompanyName: user.EnterpriseInfo.CompanyName, UnifiedSocialCode: user.EnterpriseInfo.UnifiedSocialCode, LegalPersonName: user.EnterpriseInfo.LegalPersonName, LegalPersonPhone: user.EnterpriseInfo.LegalPersonPhone, EnterpriseAddress: user.EnterpriseInfo.EnterpriseAddress, CreatedAt: user.EnterpriseInfo.CreatedAt, } // 获取企业合同信息 contracts, err := s.contractService.FindByUserID(ctx, user.ID) if err == nil && len(contracts) > 0 { contractItems := make([]*responses.ContractInfoItem, 0, len(contracts)) for _, contract := range contracts { contractItems = append(contractItems, &responses.ContractInfoItem{ ID: contract.ID, ContractName: contract.ContractName, ContractType: string(contract.ContractType), ContractTypeName: contract.GetContractTypeName(), ContractFileURL: contract.ContractFileURL, CreatedAt: contract.CreatedAt, }) } item.EnterpriseInfo.Contracts = contractItems } } // 添加钱包余额信息 wallet, err := s.walletService.LoadWalletByUserId(ctx, user.ID) if err == nil && wallet != nil { item.WalletBalance = wallet.Balance.String() } else { item.WalletBalance = "0" } items = append(items, item) } return &responses.UserListResponse{ Items: items, Total: total, Page: query.Page, Size: query.PageSize, }, nil } // GetUserDetail 获取用户详情(管理员功能) // 业务流程:1. 查询用户详情 2. 构建响应数据 func (s *UserApplicationServiceImpl) GetUserDetail(ctx context.Context, userID string) (*responses.UserDetailResponse, error) { // 1. 查询用户详情(包含企业信息) user, err := s.userAggregateService.GetUserWithEnterpriseInfo(ctx, userID) if err != nil { return nil, err } // 2. 构建响应数据 item := &responses.UserListItem{ ID: user.ID, Phone: user.Phone, UserType: user.UserType, Username: user.Username, IsActive: user.Active, IsCertified: user.IsCertified, LoginCount: user.LoginCount, LastLoginAt: user.LastLoginAt, CreatedAt: user.CreatedAt, UpdatedAt: user.UpdatedAt, } // 添加企业信息 if user.EnterpriseInfo != nil { item.EnterpriseInfo = &responses.EnterpriseInfoItem{ ID: user.EnterpriseInfo.ID, CompanyName: user.EnterpriseInfo.CompanyName, UnifiedSocialCode: user.EnterpriseInfo.UnifiedSocialCode, LegalPersonName: user.EnterpriseInfo.LegalPersonName, LegalPersonPhone: user.EnterpriseInfo.LegalPersonPhone, EnterpriseAddress: user.EnterpriseInfo.EnterpriseAddress, CreatedAt: user.EnterpriseInfo.CreatedAt, } // 获取企业合同信息 contracts, err := s.contractService.FindByUserID(ctx, user.ID) if err == nil && len(contracts) > 0 { contractItems := make([]*responses.ContractInfoItem, 0, len(contracts)) for _, contract := range contracts { contractItems = append(contractItems, &responses.ContractInfoItem{ ID: contract.ID, ContractName: contract.ContractName, ContractType: string(contract.ContractType), ContractTypeName: contract.GetContractTypeName(), ContractFileURL: contract.ContractFileURL, CreatedAt: contract.CreatedAt, }) } item.EnterpriseInfo.Contracts = contractItems } } // 添加钱包余额信息 wallet, err := s.walletService.LoadWalletByUserId(ctx, user.ID) if err == nil && wallet != nil { item.WalletBalance = wallet.Balance.String() } else { item.WalletBalance = "0" } return &responses.UserDetailResponse{ UserListItem: item, }, nil } // GetUserStats 获取用户统计信息(管理员功能) // 业务流程:1. 查询用户统计信息 2. 构建响应数据 func (s *UserApplicationServiceImpl) GetUserStats(ctx context.Context) (*responses.UserStatsResponse, error) { // 1. 查询用户统计信息 stats, err := s.userAggregateService.GetUserStats(ctx) if err != nil { return nil, err } // 2. 构建响应数据 return &responses.UserStatsResponse{ TotalUsers: stats.TotalUsers, ActiveUsers: stats.ActiveUsers, CertifiedUsers: stats.CertifiedUsers, }, nil }