468 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			468 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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
 | ||
| }
 |