Files
tyapi-server/internal/application/product/subscription_application_service_impl.go
2025-08-18 14:13:16 +08:00

265 lines
9.6 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 product
import (
"context"
"go.uber.org/zap"
"tyapi-server/internal/application/product/dto/commands"
appQueries "tyapi-server/internal/application/product/dto/queries"
"tyapi-server/internal/application/product/dto/responses"
"tyapi-server/internal/domains/product/entities"
repoQueries "tyapi-server/internal/domains/product/repositories/queries"
product_service "tyapi-server/internal/domains/product/services"
user_repositories "tyapi-server/internal/domains/user/repositories"
)
// SubscriptionApplicationServiceImpl 订阅应用服务实现
// 负责业务流程编排、事务管理、数据转换,不直接操作仓库
type SubscriptionApplicationServiceImpl struct {
productSubscriptionService *product_service.ProductSubscriptionService
userRepo user_repositories.UserRepository
logger *zap.Logger
}
// NewSubscriptionApplicationService 创建订阅应用服务
func NewSubscriptionApplicationService(
productSubscriptionService *product_service.ProductSubscriptionService,
userRepo user_repositories.UserRepository,
logger *zap.Logger,
) SubscriptionApplicationService {
return &SubscriptionApplicationServiceImpl{
productSubscriptionService: productSubscriptionService,
userRepo: userRepo,
logger: logger,
}
}
// UpdateSubscriptionPrice 更新订阅价格
// 业务流程1. 获取订阅 2. 更新价格 3. 保存订阅
func (s *SubscriptionApplicationServiceImpl) UpdateSubscriptionPrice(ctx context.Context, cmd *commands.UpdateSubscriptionPriceCommand) error {
return s.productSubscriptionService.UpdateSubscriptionPrice(ctx, cmd.ID, cmd.Price)
}
// CreateSubscription 创建订阅
// 业务流程1. 创建订阅
func (s *SubscriptionApplicationServiceImpl) CreateSubscription(ctx context.Context, cmd *commands.CreateSubscriptionCommand) error {
_, err := s.productSubscriptionService.CreateSubscription(ctx, cmd.UserID, cmd.ProductID)
return err
}
// GetSubscriptionByID 根据ID获取订阅
// 业务流程1. 获取订阅信息 2. 构建响应数据
func (s *SubscriptionApplicationServiceImpl) GetSubscriptionByID(ctx context.Context, query *appQueries.GetSubscriptionQuery) (*responses.SubscriptionInfoResponse, error) {
subscription, err := s.productSubscriptionService.GetSubscriptionByID(ctx, query.ID)
if err != nil {
return nil, err
}
return s.convertToSubscriptionInfoResponse(subscription), nil
}
// ListSubscriptions 获取订阅列表(管理员用)
// 业务流程1. 获取订阅列表 2. 构建响应数据
func (s *SubscriptionApplicationServiceImpl) ListSubscriptions(ctx context.Context, query *appQueries.ListSubscriptionsQuery) (*responses.SubscriptionListResponse, error) {
repoQuery := &repoQueries.ListSubscriptionsQuery{
Page: query.Page,
PageSize: query.PageSize,
UserID: query.UserID, // 管理员可以按用户筛选
Keyword: query.Keyword,
SortBy: query.SortBy,
SortOrder: query.SortOrder,
CompanyName: query.CompanyName,
ProductName: query.ProductName,
StartTime: query.StartTime,
EndTime: query.EndTime,
}
subscriptions, total, err := s.productSubscriptionService.ListSubscriptions(ctx, repoQuery)
if err != nil {
return nil, err
}
items := make([]responses.SubscriptionInfoResponse, len(subscriptions))
for i := range subscriptions {
resp := s.convertToSubscriptionInfoResponse(subscriptions[i])
if resp != nil {
items[i] = *resp // 解引用指针
}
}
return &responses.SubscriptionListResponse{
Total: total,
Page: query.Page,
Size: query.PageSize,
Items: items,
}, nil
}
// ListMySubscriptions 获取我的订阅列表(用户用)
// 业务流程1. 获取用户订阅列表 2. 构建响应数据
func (s *SubscriptionApplicationServiceImpl) ListMySubscriptions(ctx context.Context, userID string, query *appQueries.ListSubscriptionsQuery) (*responses.SubscriptionListResponse, error) {
repoQuery := &repoQueries.ListSubscriptionsQuery{
Page: query.Page,
PageSize: query.PageSize,
UserID: userID, // 强制设置为当前用户ID
Keyword: query.Keyword,
SortBy: query.SortBy,
SortOrder: query.SortOrder,
CompanyName: query.CompanyName,
ProductName: query.ProductName,
StartTime: query.StartTime,
EndTime: query.EndTime,
}
subscriptions, total, err := s.productSubscriptionService.ListSubscriptions(ctx, repoQuery)
if err != nil {
return nil, err
}
items := make([]responses.SubscriptionInfoResponse, len(subscriptions))
for i := range subscriptions {
resp := s.convertToSubscriptionInfoResponse(subscriptions[i])
if resp != nil {
items[i] = *resp // 解引用指针
}
}
return &responses.SubscriptionListResponse{
Total: total,
Page: query.Page,
Size: query.PageSize,
Items: items,
}, nil
}
// GetUserSubscriptions 获取用户订阅
// 业务流程1. 获取用户订阅 2. 构建响应数据
func (s *SubscriptionApplicationServiceImpl) GetUserSubscriptions(ctx context.Context, query *appQueries.GetUserSubscriptionsQuery) ([]*responses.SubscriptionInfoResponse, error) {
subscriptions, err := s.productSubscriptionService.GetUserSubscriptions(ctx, query.UserID)
if err != nil {
return nil, err
}
// 转换为响应对象
items := make([]*responses.SubscriptionInfoResponse, len(subscriptions))
for i := range subscriptions {
items[i] = s.convertToSubscriptionInfoResponse(subscriptions[i])
}
return items, nil
}
// GetProductSubscriptions 获取产品订阅
// 业务流程1. 获取产品订阅 2. 构建响应数据
func (s *SubscriptionApplicationServiceImpl) GetProductSubscriptions(ctx context.Context, query *appQueries.GetProductSubscriptionsQuery) ([]*responses.SubscriptionInfoResponse, error) {
// 这里需要扩展领域服务来支持按产品查询订阅
// 暂时返回空列表
return []*responses.SubscriptionInfoResponse{}, nil
}
// GetSubscriptionUsage 获取订阅使用情况
// 业务流程1. 获取订阅使用情况 2. 构建响应数据
func (s *SubscriptionApplicationServiceImpl) GetSubscriptionUsage(ctx context.Context, subscriptionID string) (*responses.SubscriptionUsageResponse, error) {
subscription, err := s.productSubscriptionService.GetSubscriptionByID(ctx, subscriptionID)
if err != nil {
return nil, err
}
return &responses.SubscriptionUsageResponse{
ID: subscription.ID,
ProductID: subscription.ProductID,
APIUsed: subscription.APIUsed,
}, nil
}
// GetSubscriptionStats 获取订阅统计信息
// 业务流程1. 获取订阅统计 2. 构建响应数据
func (s *SubscriptionApplicationServiceImpl) GetSubscriptionStats(ctx context.Context) (*responses.SubscriptionStatsResponse, error) {
stats, err := s.productSubscriptionService.GetSubscriptionStats(ctx)
if err != nil {
return nil, err
}
return &responses.SubscriptionStatsResponse{
TotalSubscriptions: stats["total_subscriptions"].(int64),
TotalRevenue: stats["total_revenue"].(float64),
}, nil
}
// GetMySubscriptionStats 获取我的订阅统计信息
// 业务流程1. 获取用户订阅统计 2. 构建响应数据
func (s *SubscriptionApplicationServiceImpl) GetMySubscriptionStats(ctx context.Context, userID string) (*responses.SubscriptionStatsResponse, error) {
stats, err := s.productSubscriptionService.GetUserSubscriptionStats(ctx, userID)
if err != nil {
return nil, err
}
return &responses.SubscriptionStatsResponse{
TotalSubscriptions: stats["total_subscriptions"].(int64),
TotalRevenue: stats["total_revenue"].(float64),
}, nil
}
// convertToSubscriptionInfoResponse 转换为订阅信息响应
func (s *SubscriptionApplicationServiceImpl) convertToSubscriptionInfoResponse(subscription *entities.Subscription) *responses.SubscriptionInfoResponse {
// 查询用户信息
var userInfo *responses.UserSimpleResponse
if subscription.UserID != "" {
user, err := s.userRepo.GetByIDWithEnterpriseInfo(context.Background(), subscription.UserID)
if err == nil {
companyName := "未知公司"
if user.EnterpriseInfo != nil {
companyName = user.EnterpriseInfo.CompanyName
}
userInfo = &responses.UserSimpleResponse{
ID: user.ID,
CompanyName: companyName,
Phone: user.Phone,
}
}
}
var productResponse *responses.ProductSimpleResponse
if subscription.Product != nil {
productResponse = s.convertToProductSimpleResponse(subscription.Product)
}
return &responses.SubscriptionInfoResponse{
ID: subscription.ID,
UserID: subscription.UserID,
ProductID: subscription.ProductID,
Price: subscription.Price.InexactFloat64(),
User: userInfo,
Product: productResponse,
APIUsed: subscription.APIUsed,
CreatedAt: subscription.CreatedAt,
UpdatedAt: subscription.UpdatedAt,
}
}
// convertToProductSimpleResponse 转换为产品简单信息响应
func (s *SubscriptionApplicationServiceImpl) convertToProductSimpleResponse(product *entities.Product) *responses.ProductSimpleResponse {
var categoryResponse *responses.CategorySimpleResponse
if product.Category != nil {
categoryResponse = s.convertToCategorySimpleResponse(product.Category)
}
return &responses.ProductSimpleResponse{
ID: product.ID,
OldID: product.OldID,
Name: product.Name,
Code: product.Code,
Description: product.Description,
Price: product.Price.InexactFloat64(),
Category: categoryResponse,
IsPackage: product.IsPackage,
}
}
// convertToCategorySimpleResponse 转换为分类简单信息响应
func (s *SubscriptionApplicationServiceImpl) convertToCategorySimpleResponse(category *entities.ProductCategory) *responses.CategorySimpleResponse {
if category == nil {
return nil
}
return &responses.CategorySimpleResponse{
ID: category.ID,
Name: category.Name,
}
}