98 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package task
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"encoding/json"
 | |
| 	"fmt"
 | |
| 	"tyapi-server/internal/domains/article/repositories"
 | |
| 
 | |
| 	"github.com/hibiken/asynq"
 | |
| 	"go.uber.org/zap"
 | |
| )
 | |
| 
 | |
| // ArticlePublisher 文章发布接口
 | |
| type ArticlePublisher interface {
 | |
| 	PublishArticleByID(ctx context.Context, articleID string) error
 | |
| }
 | |
| 
 | |
| // ArticleTaskHandler 文章任务处理器
 | |
| type ArticleTaskHandler struct {
 | |
| 	publisher         ArticlePublisher
 | |
| 	scheduledTaskRepo repositories.ScheduledTaskRepository
 | |
| 	logger            *zap.Logger
 | |
| }
 | |
| 
 | |
| // NewArticleTaskHandler 创建文章任务处理器
 | |
| func NewArticleTaskHandler(
 | |
| 	publisher ArticlePublisher,
 | |
| 	scheduledTaskRepo repositories.ScheduledTaskRepository,
 | |
| 	logger *zap.Logger,
 | |
| ) *ArticleTaskHandler {
 | |
| 	return &ArticleTaskHandler{
 | |
| 		publisher:         publisher,
 | |
| 		scheduledTaskRepo: scheduledTaskRepo,
 | |
| 		logger:           logger,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // HandleArticlePublish 处理文章定时发布任务
 | |
| func (h *ArticleTaskHandler) HandleArticlePublish(ctx context.Context, t *asynq.Task) error {
 | |
| 	var payload map[string]interface{}
 | |
| 	if err := json.Unmarshal(t.Payload(), &payload); err != nil {
 | |
| 		h.logger.Error("解析任务载荷失败", zap.Error(err))
 | |
| 		return fmt.Errorf("解析任务载荷失败: %w", err)
 | |
| 	}
 | |
| 	
 | |
| 	articleID, ok := payload["article_id"].(string)
 | |
| 	if !ok {
 | |
| 		h.logger.Error("任务载荷中缺少文章ID")
 | |
| 		return fmt.Errorf("任务载荷中缺少文章ID")
 | |
| 	}
 | |
| 	
 | |
| 	// 获取任务状态记录
 | |
| 	task, err := h.scheduledTaskRepo.GetByTaskID(ctx, t.ResultWriter().TaskID())
 | |
| 	if err != nil {
 | |
| 		h.logger.Error("获取任务状态记录失败", zap.String("task_id", t.ResultWriter().TaskID()), zap.Error(err))
 | |
| 		// 继续执行,不阻断任务
 | |
| 	} else {
 | |
| 		// 检查任务是否已取消
 | |
| 		if task.IsCancelled() {
 | |
| 			h.logger.Info("任务已取消,跳过执行", zap.String("task_id", t.ResultWriter().TaskID()))
 | |
| 			return nil
 | |
| 		}
 | |
| 		
 | |
| 		// 标记任务为正在执行
 | |
| 		task.MarkAsRunning()
 | |
| 		if err := h.scheduledTaskRepo.Update(ctx, task); err != nil {
 | |
| 			h.logger.Warn("更新任务状态失败", zap.String("task_id", t.ResultWriter().TaskID()), zap.Error(err))
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	// 执行文章发布
 | |
| 	if err := h.publisher.PublishArticleByID(ctx, articleID); err != nil {
 | |
| 		// 更新任务状态为失败
 | |
| 		if task.ID != "" {
 | |
| 			task.MarkAsFailed(err.Error())
 | |
| 			if updateErr := h.scheduledTaskRepo.Update(ctx, task); updateErr != nil {
 | |
| 				h.logger.Warn("更新任务失败状态失败", zap.String("task_id", t.ResultWriter().TaskID()), zap.Error(updateErr))
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		h.logger.Error("定时发布文章失败",
 | |
| 			zap.String("article_id", articleID),
 | |
| 			zap.Error(err))
 | |
| 		return fmt.Errorf("定时发布文章失败: %w", err)
 | |
| 	}
 | |
| 	
 | |
| 	// 更新任务状态为已完成
 | |
| 	if task.ID != "" {
 | |
| 		task.MarkAsCompleted()
 | |
| 		if err := h.scheduledTaskRepo.Update(ctx, task); err != nil {
 | |
| 			h.logger.Warn("更新任务完成状态失败", zap.String("task_id", t.ResultWriter().TaskID()), zap.Error(err))
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	h.logger.Info("定时发布文章成功", zap.String("article_id", articleID))
 | |
| 	return nil
 | |
| }
 |