taskExecutors.ts 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /**
  2. * 任务执行器注册
  3. * 在应用启动时注册所有任务类型的执行器
  4. */
  5. import { Task, TaskResult, TaskProgressUpdate } from '@media-manager/shared';
  6. import { taskQueueService } from './TaskQueueService.js';
  7. import { CommentService } from './CommentService.js';
  8. import { WorkService } from './WorkService.js';
  9. import { AccountService } from './AccountService.js';
  10. import { PublishService } from './PublishService.js';
  11. import { logger } from '../utils/logger.js';
  12. // 创建服务实例
  13. const commentService = new CommentService();
  14. const workService = new WorkService();
  15. const accountService = new AccountService();
  16. const publishService = new PublishService();
  17. type ProgressUpdater = (update: Partial<TaskProgressUpdate>) => void;
  18. /**
  19. * 同步评论任务执行器
  20. */
  21. async function syncCommentsExecutor(task: Task, updateProgress: ProgressUpdater): Promise<TaskResult> {
  22. updateProgress({ progress: 5, currentStep: '连接平台...' });
  23. const onProgress = (current: number, total: number, workTitle: string) => {
  24. const progress = total > 0 ? Math.min(90, Math.round((current / total) * 90) + 5) : 50;
  25. updateProgress({
  26. progress,
  27. currentStep: `正在同步: ${workTitle || `作品 ${current}/${total}`}`,
  28. currentStepIndex: current,
  29. });
  30. };
  31. // 从任务中获取 userId(需要在创建任务时传入)
  32. const userId = (task as Task & { userId?: number }).userId;
  33. if (!userId) {
  34. throw new Error('缺少用户ID');
  35. }
  36. const result = await commentService.syncComments(userId, task.accountId, onProgress);
  37. updateProgress({ progress: 100, currentStep: '同步完成' });
  38. return {
  39. success: true,
  40. message: `同步完成,共同步 ${result.synced} 条评论`,
  41. data: {
  42. syncedCount: result.synced,
  43. accountCount: result.accounts,
  44. },
  45. };
  46. }
  47. /**
  48. * 同步作品任务执行器
  49. */
  50. async function syncWorksExecutor(task: Task, updateProgress: ProgressUpdater): Promise<TaskResult> {
  51. updateProgress({ progress: 5, currentStep: '获取作品列表...' });
  52. const userId = (task as Task & { userId?: number }).userId;
  53. if (!userId) {
  54. throw new Error('缺少用户ID');
  55. }
  56. const result = await workService.syncWorks(userId, task.accountId);
  57. updateProgress({ progress: 100, currentStep: '同步完成' });
  58. return {
  59. success: true,
  60. message: `同步完成,共同步 ${result.synced} 个作品`,
  61. data: {
  62. syncedCount: result.synced,
  63. accountCount: result.accounts,
  64. },
  65. };
  66. }
  67. /**
  68. * 同步账号信息任务执行器
  69. */
  70. async function syncAccountExecutor(task: Task, updateProgress: ProgressUpdater): Promise<TaskResult> {
  71. updateProgress({ progress: 10, currentStep: '获取账号信息...' });
  72. const userId = (task as Task & { userId?: number }).userId;
  73. if (!userId) {
  74. throw new Error('缺少用户ID');
  75. }
  76. if (!task.accountId) {
  77. throw new Error('缺少账号ID');
  78. }
  79. await accountService.refreshAccount(userId, task.accountId);
  80. updateProgress({ progress: 100, currentStep: '同步完成' });
  81. return {
  82. success: true,
  83. message: '账号信息已更新',
  84. };
  85. }
  86. /**
  87. * 发布视频任务执行器
  88. */
  89. async function publishVideoExecutor(task: Task, updateProgress: ProgressUpdater): Promise<TaskResult> {
  90. updateProgress({ progress: 5, currentStep: '准备发布...' });
  91. const userId = (task as Task & { userId?: number }).userId;
  92. if (!userId) {
  93. throw new Error('缺少用户ID');
  94. }
  95. // 从任务数据中获取发布任务ID
  96. const taskData = task as Task & { publishTaskId?: number };
  97. if (!taskData.publishTaskId) {
  98. throw new Error('缺少发布任务ID');
  99. }
  100. // 执行发布任务
  101. await publishService.executePublishTaskWithProgress(
  102. taskData.publishTaskId,
  103. userId,
  104. (progress, message) => {
  105. updateProgress({ progress, currentStep: message });
  106. }
  107. );
  108. updateProgress({ progress: 100, currentStep: '发布完成' });
  109. return {
  110. success: true,
  111. message: '视频发布任务已完成',
  112. };
  113. }
  114. /**
  115. * 删除平台作品任务执行器
  116. */
  117. async function deleteWorkExecutor(task: Task, updateProgress: ProgressUpdater): Promise<TaskResult> {
  118. updateProgress({ progress: 10, currentStep: '准备删除...' });
  119. const userId = (task as Task & { userId?: number }).userId;
  120. if (!userId) {
  121. throw new Error('缺少用户ID');
  122. }
  123. const taskData = task as Task & { workId?: number };
  124. if (!taskData.workId) {
  125. throw new Error('缺少作品ID');
  126. }
  127. updateProgress({ progress: 30, currentStep: '连接平台删除作品...' });
  128. // 执行平台删除
  129. const result = await workService.deletePlatformWork(userId, taskData.workId);
  130. if (result.success) {
  131. updateProgress({ progress: 80, currentStep: '删除本地记录...' });
  132. // 平台删除成功后,删除本地记录
  133. try {
  134. await workService.deleteWork(userId, taskData.workId);
  135. logger.info(`Local work ${taskData.workId} deleted after platform deletion`);
  136. } catch (error) {
  137. logger.warn(`Failed to delete local work ${taskData.workId}:`, error);
  138. // 本地删除失败不影响整体结果
  139. }
  140. }
  141. updateProgress({ progress: 100, currentStep: result.success ? '删除完成' : '删除失败' });
  142. return {
  143. success: result.success,
  144. message: result.success ? '作品已从平台删除,本地记录已清理' : (result.errorMessage || '删除失败'),
  145. };
  146. }
  147. /**
  148. * 注册所有任务执行器
  149. */
  150. export function registerTaskExecutors(): void {
  151. taskQueueService.registerExecutor('sync_comments', syncCommentsExecutor);
  152. taskQueueService.registerExecutor('sync_works', syncWorksExecutor);
  153. taskQueueService.registerExecutor('sync_account', syncAccountExecutor);
  154. taskQueueService.registerExecutor('publish_video', publishVideoExecutor);
  155. taskQueueService.registerExecutor('delete_work', deleteWorkExecutor);
  156. logger.info('All task executors registered');
  157. }