| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- const crypto = require('node:crypto');
- const { runBidAnalysisTask } = require('./bidAnalysisTask.cjs');
- const { runContentGenerationTask } = require('./contentGenerationTask.cjs');
- const { runOutlineGenerationTask } = require('./outlineGenerationTask.cjs');
- const taskFields = {
- 'bid-analysis': 'bidAnalysisTask',
- 'outline-generation': 'outlineGenerationTask',
- 'content-generation': 'contentGenerationTask',
- };
- function now() {
- return new Date().toISOString();
- }
- function createTask(type) {
- return {
- task_id: crypto.randomUUID(),
- type,
- status: 'running',
- progress: 0,
- logs: [],
- started_at: now(),
- updated_at: now(),
- };
- }
- function createTaskService({ aiService, workspaceStore, knowledgeBaseService }) {
- const subscribers = new Set();
- const activeTasks = new Map();
- function emit(task, technicalPlan) {
- const event = { task, technicalPlan };
- for (const webContents of subscribers) {
- if (!webContents.isDestroyed()) {
- webContents.send('tasks:event', event);
- }
- }
- }
- function subscribe(webContents) {
- subscribers.add(webContents);
- const technicalPlan = workspaceStore.loadTechnicalPlan();
- for (const task of activeTasks.values()) {
- if (!webContents.isDestroyed()) {
- webContents.send('tasks:event', { task, technicalPlan });
- }
- }
- webContents.once('destroyed', () => subscribers.delete(webContents));
- }
- function getTaskField(type) {
- return taskFields[type];
- }
- function startTask(type, payload, runner, initialPartial = {}) {
- const existingTask = activeTasks.get(type);
- if (existingTask?.status === 'running') {
- emit(existingTask, workspaceStore.loadTechnicalPlan());
- return existingTask;
- }
- const task = createTask(type);
- activeTasks.set(type, task);
- const taskField = getTaskField(type);
- let currentTask = task;
- const updateTask = (partial, technicalPlan) => {
- currentTask = {
- ...currentTask,
- ...partial,
- logs: partial.logs ? partial.logs : currentTask.logs,
- updated_at: now(),
- };
- activeTasks.set(type, currentTask);
- if (technicalPlan) emit(currentTask, technicalPlan);
- return currentTask;
- };
- const technicalPlan = workspaceStore.updateTechnicalPlan({ ...initialPartial, [taskField]: currentTask });
- emit(currentTask, technicalPlan);
- runner({ aiService, workspaceStore, knowledgeBaseService, updateTask, payload }).catch((error) => {
- const failedTask = updateTask({ status: 'error', error: error.message || '任务执行失败' });
- const nextPlan = workspaceStore.updateTechnicalPlan({ [taskField]: failedTask });
- emit(failedTask, nextPlan);
- }).finally(() => {
- activeTasks.delete(type);
- });
- return currentTask;
- }
- return {
- subscribe,
- startBidAnalysis(payload) {
- return startTask('bid-analysis', payload, runBidAnalysisTask);
- },
- startOutlineGeneration(payload) {
- return startTask('outline-generation', payload, runOutlineGenerationTask, {
- outlineMode: payload?.mode,
- referenceKnowledgeDocumentIds: Array.isArray(payload?.reference_knowledge_document_ids) ? payload.reference_knowledge_document_ids : [],
- });
- },
- startContentGeneration(payload) {
- return startTask('content-generation', payload, runContentGenerationTask);
- },
- getActiveTasks() {
- return Array.from(activeTasks.values());
- },
- };
- }
- module.exports = { createTaskService };
|