Files
tyapi-server/internal/application/user/user_application_service_impl.go
2025-07-30 00:51:22 +08:00

382 lines
12 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
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,
eventBus interfaces.EventBus,
jwtAuth *middleware.JWTAuthMiddleware,
logger *zap.Logger,
) UserApplicationService {
return &UserApplicationServiceImpl{
userAggregateService: userAggregateService,
userAuthService: userAuthService,
smsCodeService: smsCodeService,
walletService: walletService,
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,
}
}
// 添加钱包余额信息
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
}