335 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			335 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package entities
 | ||
| 
 | ||
| import (
 | ||
| 	"context"
 | ||
| 	"encoding/json"
 | ||
| 	"fmt"
 | ||
| 	"time"
 | ||
| 
 | ||
| 	"tyapi-server/internal/infrastructure/task/types"
 | ||
| )
 | ||
| 
 | ||
| // TaskFactory 任务工厂
 | ||
| type TaskFactory struct {
 | ||
| 	taskManager interface{} // 使用interface{}避免循环导入
 | ||
| }
 | ||
| 
 | ||
| // NewTaskFactory 创建任务工厂
 | ||
| func NewTaskFactory() *TaskFactory {
 | ||
| 	return &TaskFactory{}
 | ||
| }
 | ||
| 
 | ||
| // NewTaskFactoryWithManager 创建带管理器的任务工厂
 | ||
| func NewTaskFactoryWithManager(taskManager interface{}) *TaskFactory {
 | ||
| 	return &TaskFactory{
 | ||
| 		taskManager: taskManager,
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // CreateArticlePublishTask 创建文章发布任务
 | ||
| func (f *TaskFactory) CreateArticlePublishTask(articleID string, publishAt time.Time, userID string) (*AsyncTask, error) {
 | ||
| 	// 创建任务实体,ID将由GORM的BeforeCreate钩子自动生成UUID
 | ||
| 	task := &AsyncTask{
 | ||
| 		Type:        string(types.TaskTypeArticlePublish),
 | ||
| 		Status:      TaskStatusPending,
 | ||
| 		ScheduledAt: &publishAt,
 | ||
| 		CreatedAt:   time.Now(),
 | ||
| 		UpdatedAt:   time.Now(),
 | ||
| 	}
 | ||
| 	
 | ||
| 	// 在payload中添加任务ID(将在保存后更新)
 | ||
| 	payloadWithID := map[string]interface{}{
 | ||
| 		"article_id": articleID,
 | ||
| 		"publish_at": publishAt,
 | ||
| 		"user_id":    userID,
 | ||
| 	}
 | ||
| 
 | ||
| 	payloadDataWithID, err := json.Marshal(payloadWithID)
 | ||
| 	if err != nil {
 | ||
| 		return nil, err
 | ||
| 	}
 | ||
| 
 | ||
| 	task.Payload = string(payloadDataWithID)
 | ||
| 	return task, nil
 | ||
| }
 | ||
| 
 | ||
| // CreateArticleCancelTask 创建文章取消任务
 | ||
| func (f *TaskFactory) CreateArticleCancelTask(articleID string, userID string) (*AsyncTask, error) {
 | ||
| 	// 创建任务实体,ID将由GORM的BeforeCreate钩子自动生成UUID
 | ||
| 	task := &AsyncTask{
 | ||
| 		Type:      string(types.TaskTypeArticleCancel),
 | ||
| 		Status:    TaskStatusPending,
 | ||
| 		CreatedAt: time.Now(),
 | ||
| 		UpdatedAt: time.Now(),
 | ||
| 	}
 | ||
| 	
 | ||
| 	// 在payload中添加任务数据
 | ||
| 	payloadWithID := map[string]interface{}{
 | ||
| 		"article_id": articleID,
 | ||
| 		"user_id":    userID,
 | ||
| 	}
 | ||
| 
 | ||
| 	payloadDataWithID, err := json.Marshal(payloadWithID)
 | ||
| 	if err != nil {
 | ||
| 		return nil, err
 | ||
| 	}
 | ||
| 
 | ||
| 	task.Payload = string(payloadDataWithID)
 | ||
| 	return task, nil
 | ||
| }
 | ||
| 
 | ||
| // CreateArticleModifyTask 创建文章修改任务
 | ||
| func (f *TaskFactory) CreateArticleModifyTask(articleID string, newPublishAt time.Time, userID string) (*AsyncTask, error) {
 | ||
| 	// 创建任务实体,ID将由GORM的BeforeCreate钩子自动生成UUID
 | ||
| 	task := &AsyncTask{
 | ||
| 		Type:        string(types.TaskTypeArticleModify),
 | ||
| 		Status:      TaskStatusPending,
 | ||
| 		ScheduledAt: &newPublishAt,
 | ||
| 		CreatedAt:   time.Now(),
 | ||
| 		UpdatedAt:   time.Now(),
 | ||
| 	}
 | ||
| 	
 | ||
| 	// 在payload中添加任务数据
 | ||
| 	payloadWithID := map[string]interface{}{
 | ||
| 		"article_id":      articleID,
 | ||
| 		"new_publish_at":  newPublishAt,
 | ||
| 		"user_id":         userID,
 | ||
| 	}
 | ||
| 
 | ||
| 	payloadDataWithID, err := json.Marshal(payloadWithID)
 | ||
| 	if err != nil {
 | ||
| 		return nil, err
 | ||
| 	}
 | ||
| 
 | ||
| 	task.Payload = string(payloadDataWithID)
 | ||
| 	return task, nil
 | ||
| }
 | ||
| 
 | ||
| // CreateApiCallTask 创建API调用任务
 | ||
| func (f *TaskFactory) CreateApiCallTask(apiCallID string, userID string, productID string, amount string) (*AsyncTask, error) {
 | ||
| 	// 创建任务实体,ID将由GORM的BeforeCreate钩子自动生成UUID
 | ||
| 	task := &AsyncTask{
 | ||
| 		Type:      string(types.TaskTypeApiCall),
 | ||
| 		Status:    TaskStatusPending,
 | ||
| 		CreatedAt: time.Now(),
 | ||
| 		UpdatedAt: time.Now(),
 | ||
| 	}
 | ||
| 	
 | ||
| 	// 在payload中添加任务数据
 | ||
| 	payloadWithID := map[string]interface{}{
 | ||
| 		"api_call_id": apiCallID,
 | ||
| 		"user_id":     userID,
 | ||
| 		"product_id":  productID,
 | ||
| 		"amount":      amount,
 | ||
| 	}
 | ||
| 
 | ||
| 	payloadDataWithID, err := json.Marshal(payloadWithID)
 | ||
| 	if err != nil {
 | ||
| 		return nil, err
 | ||
| 	}
 | ||
| 
 | ||
| 	task.Payload = string(payloadDataWithID)
 | ||
| 	return task, nil
 | ||
| }
 | ||
| 
 | ||
| // CreateDeductionTask 创建扣款任务
 | ||
| func (f *TaskFactory) CreateDeductionTask(apiCallID string, userID string, productID string, amount string, transactionID string) (*AsyncTask, error) {
 | ||
| 	// 创建任务实体,ID将由GORM的BeforeCreate钩子自动生成UUID
 | ||
| 	task := &AsyncTask{
 | ||
| 		Type:      string(types.TaskTypeDeduction),
 | ||
| 		Status:    TaskStatusPending,
 | ||
| 		CreatedAt: time.Now(),
 | ||
| 		UpdatedAt: time.Now(),
 | ||
| 	}
 | ||
| 	
 | ||
| 	// 在payload中添加任务数据
 | ||
| 	payloadWithID := map[string]interface{}{
 | ||
| 		"api_call_id":    apiCallID,
 | ||
| 		"user_id":        userID,
 | ||
| 		"product_id":     productID,
 | ||
| 		"amount":         amount,
 | ||
| 		"transaction_id": transactionID,
 | ||
| 	}
 | ||
| 
 | ||
| 	payloadDataWithID, err := json.Marshal(payloadWithID)
 | ||
| 	if err != nil {
 | ||
| 		return nil, err
 | ||
| 	}
 | ||
| 
 | ||
| 	task.Payload = string(payloadDataWithID)
 | ||
| 	return task, nil
 | ||
| }
 | ||
| 
 | ||
| // CreateApiCallLogTask 创建API调用日志任务
 | ||
| func (f *TaskFactory) CreateApiCallLogTask(transactionID string, userID string, apiName string, productID string) (*AsyncTask, error) {
 | ||
| 	// 创建任务实体,ID将由GORM的BeforeCreate钩子自动生成UUID
 | ||
| 	task := &AsyncTask{
 | ||
| 		Type:      string(types.TaskTypeApiLog),
 | ||
| 		Status:    TaskStatusPending,
 | ||
| 		CreatedAt: time.Now(),
 | ||
| 		UpdatedAt: time.Now(),
 | ||
| 	}
 | ||
| 	
 | ||
| 	// 在payload中添加任务数据
 | ||
| 	payloadWithID := map[string]interface{}{
 | ||
| 		"transaction_id": transactionID,
 | ||
| 		"user_id":        userID,
 | ||
| 		"api_name":       apiName,
 | ||
| 		"product_id":     productID,
 | ||
| 	}
 | ||
| 
 | ||
| 	payloadDataWithID, err := json.Marshal(payloadWithID)
 | ||
| 	if err != nil {
 | ||
| 		return nil, err
 | ||
| 	}
 | ||
| 
 | ||
| 	task.Payload = string(payloadDataWithID)
 | ||
| 	return task, nil
 | ||
| }
 | ||
| 
 | ||
| // CreateUsageStatsTask 创建使用统计任务
 | ||
| func (f *TaskFactory) CreateUsageStatsTask(subscriptionID string, userID string, productID string, increment int) (*AsyncTask, error) {
 | ||
| 	// 创建任务实体,ID将由GORM的BeforeCreate钩子自动生成UUID
 | ||
| 	task := &AsyncTask{
 | ||
| 		Type:      string(types.TaskTypeUsageStats),
 | ||
| 		Status:    TaskStatusPending,
 | ||
| 		CreatedAt: time.Now(),
 | ||
| 		UpdatedAt: time.Now(),
 | ||
| 	}
 | ||
| 	
 | ||
| 	// 在payload中添加任务数据
 | ||
| 	payloadWithID := map[string]interface{}{
 | ||
| 		"subscription_id": subscriptionID,
 | ||
| 		"user_id":         userID,
 | ||
| 		"product_id":      productID,
 | ||
| 		"increment":       increment,
 | ||
| 	}
 | ||
| 
 | ||
| 	payloadDataWithID, err := json.Marshal(payloadWithID)
 | ||
| 	if err != nil {
 | ||
| 		return nil, err
 | ||
| 	}
 | ||
| 
 | ||
| 	task.Payload = string(payloadDataWithID)
 | ||
| 	return task, nil
 | ||
| }
 | ||
| 
 | ||
| // CreateAndEnqueueArticlePublishTask 创建并入队文章发布任务
 | ||
| func (f *TaskFactory) CreateAndEnqueueArticlePublishTask(ctx context.Context, articleID string, publishAt time.Time, userID string) error {
 | ||
| 	if f.taskManager == nil {
 | ||
| 		return fmt.Errorf("TaskManager未初始化")
 | ||
| 	}
 | ||
| 
 | ||
| 	task, err := f.CreateArticlePublishTask(articleID, publishAt, userID)
 | ||
| 	if err != nil {
 | ||
| 		return err
 | ||
| 	}
 | ||
| 
 | ||
| 	delay := publishAt.Sub(time.Now())
 | ||
| 	if delay < 0 {
 | ||
| 		delay = 0
 | ||
| 	}
 | ||
| 
 | ||
| 	// 使用类型断言调用TaskManager方法
 | ||
| 	if tm, ok := f.taskManager.(interface {
 | ||
| 		CreateAndEnqueueDelayedTask(ctx context.Context, task *AsyncTask, delay time.Duration) error
 | ||
| 	}); ok {
 | ||
| 		return tm.CreateAndEnqueueDelayedTask(ctx, task, delay)
 | ||
| 	}
 | ||
| 
 | ||
| 	return fmt.Errorf("TaskManager类型不匹配")
 | ||
| }
 | ||
| 
 | ||
| // CreateAndEnqueueApiLogTask 创建并入队API日志任务
 | ||
| func (f *TaskFactory) CreateAndEnqueueApiLogTask(ctx context.Context, transactionID string, userID string, apiName string, productID string) error {
 | ||
| 	if f.taskManager == nil {
 | ||
| 		return fmt.Errorf("TaskManager未初始化")
 | ||
| 	}
 | ||
| 
 | ||
| 	task, err := f.CreateApiCallLogTask(transactionID, userID, apiName, productID)
 | ||
| 	if err != nil {
 | ||
| 		return err
 | ||
| 	}
 | ||
| 
 | ||
| 	// 使用类型断言调用TaskManager方法
 | ||
| 	if tm, ok := f.taskManager.(interface {
 | ||
| 		CreateAndEnqueueTask(ctx context.Context, task *AsyncTask) error
 | ||
| 	}); ok {
 | ||
| 		return tm.CreateAndEnqueueTask(ctx, task)
 | ||
| 	}
 | ||
| 
 | ||
| 	return fmt.Errorf("TaskManager类型不匹配")
 | ||
| }
 | ||
| 
 | ||
| // CreateAndEnqueueApiCallTask 创建并入队API调用任务
 | ||
| func (f *TaskFactory) CreateAndEnqueueApiCallTask(ctx context.Context, apiCallID string, userID string, productID string, amount string) error {
 | ||
| 	if f.taskManager == nil {
 | ||
| 		return fmt.Errorf("TaskManager未初始化")
 | ||
| 	}
 | ||
| 
 | ||
| 	task, err := f.CreateApiCallTask(apiCallID, userID, productID, amount)
 | ||
| 	if err != nil {
 | ||
| 		return err
 | ||
| 	}
 | ||
| 
 | ||
| 	// 使用类型断言调用TaskManager方法
 | ||
| 	if tm, ok := f.taskManager.(interface {
 | ||
| 		CreateAndEnqueueTask(ctx context.Context, task *AsyncTask) error
 | ||
| 	}); ok {
 | ||
| 		return tm.CreateAndEnqueueTask(ctx, task)
 | ||
| 	}
 | ||
| 
 | ||
| 	return fmt.Errorf("TaskManager类型不匹配")
 | ||
| }
 | ||
| 
 | ||
| // CreateAndEnqueueDeductionTask 创建并入队扣款任务
 | ||
| func (f *TaskFactory) CreateAndEnqueueDeductionTask(ctx context.Context, apiCallID string, userID string, productID string, amount string, transactionID string) error {
 | ||
| 	if f.taskManager == nil {
 | ||
| 		return fmt.Errorf("TaskManager未初始化")
 | ||
| 	}
 | ||
| 
 | ||
| 	task, err := f.CreateDeductionTask(apiCallID, userID, productID, amount, transactionID)
 | ||
| 	if err != nil {
 | ||
| 		return err
 | ||
| 	}
 | ||
| 
 | ||
| 	// 使用类型断言调用TaskManager方法
 | ||
| 	if tm, ok := f.taskManager.(interface {
 | ||
| 		CreateAndEnqueueTask(ctx context.Context, task *AsyncTask) error
 | ||
| 	}); ok {
 | ||
| 		return tm.CreateAndEnqueueTask(ctx, task)
 | ||
| 	}
 | ||
| 
 | ||
| 	return fmt.Errorf("TaskManager类型不匹配")
 | ||
| }
 | ||
| 
 | ||
| // CreateAndEnqueueUsageStatsTask 创建并入队使用统计任务
 | ||
| func (f *TaskFactory) CreateAndEnqueueUsageStatsTask(ctx context.Context, subscriptionID string, userID string, productID string, increment int) error {
 | ||
| 	if f.taskManager == nil {
 | ||
| 		return fmt.Errorf("TaskManager未初始化")
 | ||
| 	}
 | ||
| 
 | ||
| 	task, err := f.CreateUsageStatsTask(subscriptionID, userID, productID, increment)
 | ||
| 	if err != nil {
 | ||
| 		return err
 | ||
| 	}
 | ||
| 
 | ||
| 	// 使用类型断言调用TaskManager方法
 | ||
| 	if tm, ok := f.taskManager.(interface {
 | ||
| 		CreateAndEnqueueTask(ctx context.Context, task *AsyncTask) error
 | ||
| 	}); ok {
 | ||
| 		return tm.CreateAndEnqueueTask(ctx, task)
 | ||
| 	}
 | ||
| 
 | ||
| 	return fmt.Errorf("TaskManager类型不匹配")
 | ||
| }
 | ||
| 
 | ||
| // generateRandomString 生成随机字符串
 | ||
| func generateRandomString(length int) string {
 | ||
| 	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
 | ||
| 	b := make([]byte, length)
 | ||
| 	for i := range b {
 | ||
| 		b[i] = charset[time.Now().UnixNano()%int64(len(charset))]
 | ||
| 	}
 | ||
| 	return string(b)
 | ||
| } |