2025-07-13 16:36:20 +08:00
|
|
|
|
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"
|
2025-07-28 01:46:39 +08:00
|
|
|
|
finance_service "tyapi-server/internal/domains/finance/services"
|
2025-07-13 16:36:20 +08:00
|
|
|
|
"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 用户应用服务实现
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 负责业务流程编排、事务管理、数据转换,不直接操作仓库
|
2025-07-13 16:36:20 +08:00
|
|
|
|
type UserApplicationServiceImpl struct {
|
2025-07-28 01:46:39 +08:00
|
|
|
|
userAggregateService user_service.UserAggregateService
|
|
|
|
|
|
userAuthService *user_service.UserAuthService
|
|
|
|
|
|
smsCodeService *user_service.SMSCodeService
|
|
|
|
|
|
walletService finance_service.WalletAggregateService
|
|
|
|
|
|
eventBus interfaces.EventBus
|
|
|
|
|
|
jwtAuth *middleware.JWTAuthMiddleware
|
|
|
|
|
|
logger *zap.Logger
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NewUserApplicationService 创建用户应用服务
|
|
|
|
|
|
func NewUserApplicationService(
|
2025-07-28 01:46:39 +08:00
|
|
|
|
userAggregateService user_service.UserAggregateService,
|
2025-07-20 20:53:26 +08:00
|
|
|
|
userAuthService *user_service.UserAuthService,
|
2025-07-13 16:36:20 +08:00
|
|
|
|
smsCodeService *user_service.SMSCodeService,
|
2025-07-28 01:46:39 +08:00
|
|
|
|
walletService finance_service.WalletAggregateService,
|
2025-07-13 16:36:20 +08:00
|
|
|
|
eventBus interfaces.EventBus,
|
|
|
|
|
|
jwtAuth *middleware.JWTAuthMiddleware,
|
|
|
|
|
|
logger *zap.Logger,
|
|
|
|
|
|
) UserApplicationService {
|
|
|
|
|
|
return &UserApplicationServiceImpl{
|
2025-07-28 01:46:39 +08:00
|
|
|
|
userAggregateService: userAggregateService,
|
|
|
|
|
|
userAuthService: userAuthService,
|
|
|
|
|
|
smsCodeService: smsCodeService,
|
|
|
|
|
|
walletService: walletService,
|
|
|
|
|
|
eventBus: eventBus,
|
|
|
|
|
|
jwtAuth: jwtAuth,
|
|
|
|
|
|
logger: logger,
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Register 用户注册
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 业务流程:1. 验证短信验证码 2. 创建用户 3. 发布注册事件
|
2025-07-13 16:36:20 +08:00
|
|
|
|
func (s *UserApplicationServiceImpl) Register(ctx context.Context, cmd *commands.RegisterUserCommand) (*responses.RegisterUserResponse, error) {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 1. 验证短信验证码
|
2025-07-13 16:36:20 +08:00
|
|
|
|
if err := s.smsCodeService.VerifyCode(ctx, cmd.Phone, cmd.Code, entities.SMSSceneRegister); err != nil {
|
|
|
|
|
|
return nil, fmt.Errorf("验证码错误或已过期")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 2. 创建用户
|
2025-07-28 01:46:39 +08:00
|
|
|
|
user, err := s.userAggregateService.CreateUser(ctx, cmd.Phone, cmd.Password)
|
2025-07-13 16:36:20 +08:00
|
|
|
|
if err != nil {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
return nil, err
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 3. 发布用户注册事件
|
2025-07-13 16:36:20 +08:00
|
|
|
|
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{
|
2025-07-20 20:53:26 +08:00
|
|
|
|
ID: user.ID,
|
2025-07-13 16:36:20 +08:00
|
|
|
|
Phone: user.Phone,
|
|
|
|
|
|
}, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// LoginWithPassword 密码登录
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 业务流程:1. 验证用户密码 2. 生成访问令牌 3. 更新登录统计 4. 获取用户权限
|
2025-07-13 16:36:20 +08:00
|
|
|
|
func (s *UserApplicationServiceImpl) LoginWithPassword(ctx context.Context, cmd *commands.LoginWithPasswordCommand) (*responses.LoginUserResponse, error) {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 1. 验证用户密码
|
|
|
|
|
|
user, err := s.userAuthService.ValidatePassword(ctx, cmd.Phone, cmd.Password)
|
2025-07-13 16:36:20 +08:00
|
|
|
|
if err != nil {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
return nil, err
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 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("生成访问令牌失败")
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 3. 如果是管理员,更新登录统计
|
|
|
|
|
|
if user.IsAdmin() {
|
2025-07-28 01:46:39 +08:00
|
|
|
|
if err := s.userAggregateService.UpdateLoginStats(ctx, user.ID); err != nil {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
s.logger.Error("更新登录统计失败", zap.Error(err))
|
|
|
|
|
|
}
|
|
|
|
|
|
// 重新获取用户信息以获取最新的登录统计
|
2025-07-28 01:46:39 +08:00
|
|
|
|
updatedUser, err := s.userAggregateService.GetUserByID(ctx, user.ID)
|
2025-07-20 20:53:26 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
s.logger.Error("重新获取用户信息失败", zap.Error(err))
|
|
|
|
|
|
} else {
|
|
|
|
|
|
user = updatedUser
|
|
|
|
|
|
}
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 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{}
|
|
|
|
|
|
}
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 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,
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return &responses.LoginUserResponse{
|
|
|
|
|
|
User: userProfile,
|
|
|
|
|
|
AccessToken: accessToken,
|
|
|
|
|
|
TokenType: "Bearer",
|
|
|
|
|
|
ExpiresIn: 86400, // 24h
|
|
|
|
|
|
LoginMethod: "password",
|
|
|
|
|
|
}, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// LoginWithSMS 短信验证码登录
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 业务流程:1. 验证短信验证码 2. 验证用户登录状态 3. 生成访问令牌 4. 更新登录统计 5. 获取用户权限
|
2025-07-13 16:36:20 +08:00
|
|
|
|
func (s *UserApplicationServiceImpl) LoginWithSMS(ctx context.Context, cmd *commands.LoginWithSMSCommand) (*responses.LoginUserResponse, error) {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 1. 验证短信验证码
|
2025-07-13 16:36:20 +08:00
|
|
|
|
if err := s.smsCodeService.VerifyCode(ctx, cmd.Phone, cmd.Code, entities.SMSSceneLogin); err != nil {
|
|
|
|
|
|
return nil, fmt.Errorf("验证码错误或已过期")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 2. 验证用户登录状态
|
|
|
|
|
|
user, err := s.userAuthService.ValidateUserLogin(ctx, cmd.Phone)
|
2025-07-13 16:36:20 +08:00
|
|
|
|
if err != nil {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
return nil, err
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 3. 生成包含用户类型的token
|
|
|
|
|
|
accessToken, err := s.jwtAuth.GenerateToken(user.ID, user.Phone, user.Phone, user.UserType)
|
2025-07-13 16:36:20 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
s.logger.Error("生成令牌失败", zap.Error(err))
|
|
|
|
|
|
return nil, fmt.Errorf("生成访问令牌失败")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 4. 如果是管理员,更新登录统计
|
|
|
|
|
|
if user.IsAdmin() {
|
2025-07-28 01:46:39 +08:00
|
|
|
|
if err := s.userAggregateService.UpdateLoginStats(ctx, user.ID); err != nil {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
s.logger.Error("更新登录统计失败", zap.Error(err))
|
|
|
|
|
|
}
|
|
|
|
|
|
// 重新获取用户信息以获取最新的登录统计
|
2025-07-28 01:46:39 +08:00
|
|
|
|
updatedUser, err := s.userAggregateService.GetUserByID(ctx, user.ID)
|
2025-07-20 20:53:26 +08:00
|
|
|
|
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,
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return &responses.LoginUserResponse{
|
|
|
|
|
|
User: userProfile,
|
|
|
|
|
|
AccessToken: accessToken,
|
|
|
|
|
|
TokenType: "Bearer",
|
2025-07-20 20:53:26 +08:00
|
|
|
|
ExpiresIn: int64(s.jwtAuth.GetExpiresIn().Seconds()), // 168h
|
2025-07-13 16:36:20 +08:00
|
|
|
|
LoginMethod: "sms",
|
|
|
|
|
|
}, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// SendSMS 发送短信验证码
|
|
|
|
|
|
// 业务流程:1. 发送短信验证码
|
|
|
|
|
|
func (s *UserApplicationServiceImpl) SendSMS(ctx context.Context, cmd *commands.SendCodeCommand) error {
|
|
|
|
|
|
return s.smsCodeService.SendCode(ctx, cmd.Phone, entities.SMSScene(cmd.Scene), "", "")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-13 16:36:20 +08:00
|
|
|
|
// ChangePassword 修改密码
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 业务流程:1. 修改用户密码
|
2025-07-13 16:36:20 +08:00
|
|
|
|
func (s *UserApplicationServiceImpl) ChangePassword(ctx context.Context, cmd *commands.ChangePasswordCommand) error {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
return s.userAuthService.ChangePassword(ctx, cmd.UserID, cmd.OldPassword, cmd.NewPassword)
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-15 13:21:34 +08:00
|
|
|
|
// ResetPassword 重置密码
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 业务流程:1. 验证短信验证码 2. 重置用户密码
|
2025-07-15 13:21:34 +08:00
|
|
|
|
func (s *UserApplicationServiceImpl) ResetPassword(ctx context.Context, cmd *commands.ResetPasswordCommand) error {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 1. 验证短信验证码
|
2025-07-15 13:21:34 +08:00
|
|
|
|
if err := s.smsCodeService.VerifyCode(ctx, cmd.Phone, cmd.Code, entities.SMSSceneResetPassword); err != nil {
|
|
|
|
|
|
return fmt.Errorf("验证码错误或已过期")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 2. 重置用户密码
|
|
|
|
|
|
return s.userAuthService.ResetPassword(ctx, cmd.Phone, cmd.NewPassword)
|
2025-07-15 13:21:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// GetUserProfile 获取用户资料
|
|
|
|
|
|
// 业务流程:1. 获取用户信息 2. 获取企业信息 3. 构建响应数据
|
2025-07-13 16:36:20 +08:00
|
|
|
|
func (s *UserApplicationServiceImpl) GetUserProfile(ctx context.Context, userID string) (*responses.UserProfileResponse, error) {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 1. 获取用户信息(包含企业信息)
|
2025-07-28 01:46:39 +08:00
|
|
|
|
user, err := s.userAggregateService.GetUserWithEnterpriseInfo(ctx, userID)
|
2025-07-20 20:53:26 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 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{}
|
|
|
|
|
|
}
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 3. 构建用户信息
|
|
|
|
|
|
userProfile := &responses.UserProfileResponse{
|
|
|
|
|
|
ID: user.ID,
|
|
|
|
|
|
Phone: user.Phone,
|
|
|
|
|
|
Username: user.Username,
|
|
|
|
|
|
UserType: user.UserType,
|
|
|
|
|
|
IsActive: user.Active,
|
2025-07-28 01:46:39 +08:00
|
|
|
|
IsCertified: user.IsCertified,
|
2025-07-20 20:53:26 +08:00
|
|
|
|
LastLoginAt: user.LastLoginAt,
|
|
|
|
|
|
LoginCount: user.LoginCount,
|
|
|
|
|
|
Permissions: permissions,
|
|
|
|
|
|
CreatedAt: user.CreatedAt,
|
|
|
|
|
|
UpdatedAt: user.UpdatedAt,
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 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,
|
2025-07-28 01:46:39 +08:00
|
|
|
|
LegalPersonPhone: user.EnterpriseInfo.LegalPersonPhone,
|
|
|
|
|
|
EnterpriseAddress: user.EnterpriseInfo.EnterpriseAddress,
|
|
|
|
|
|
EnterpriseEmail: user.EnterpriseInfo.EnterpriseEmail,
|
2025-07-20 20:53:26 +08:00
|
|
|
|
CreatedAt: user.EnterpriseInfo.CreatedAt,
|
|
|
|
|
|
UpdatedAt: user.EnterpriseInfo.UpdatedAt,
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
return userProfile, nil
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// GetUser 获取用户信息
|
|
|
|
|
|
// 业务流程:1. 获取用户信息 2. 构建响应数据
|
2025-07-13 16:36:20 +08:00
|
|
|
|
func (s *UserApplicationServiceImpl) GetUser(ctx context.Context, query *queries.GetUserQuery) (*responses.UserProfileResponse, error) {
|
2025-07-28 01:46:39 +08:00
|
|
|
|
user, err := s.userAggregateService.GetUserByID(ctx, query.UserID)
|
2025-07-20 20:53:26 +08:00
|
|
|
|
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
|
2025-07-13 16:36:20 +08:00
|
|
|
|
}
|
2025-07-28 01:46:39 +08:00
|
|
|
|
|
|
|
|
|
|
// 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,
|
|
|
|
|
|
EnterpriseEmail: user.EnterpriseInfo.EnterpriseEmail,
|
|
|
|
|
|
CreatedAt: user.EnterpriseInfo.CreatedAt,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加钱包余额信息
|
|
|
|
|
|
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
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
}
|