import { http, HttpResponse, delay } from 'msw'; import { mockOptimizationTasks, type MockOptimizationTask } from '../data/aps'; // Generate a simple UUID-like string function generateTaskId() { return `task-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`; } // Mutable in-memory store let tasks = [...mockOptimizationTasks]; function paginate(list: T[], pageNo: number, pageSize: number) { const start = (pageNo - 1) * pageSize; return { list: list.slice(start, start + pageSize), total: list.length, }; } export const apsTaskHandlers = [ // Submit single coil task http.post('/admin-api/aps/task/single-coil/submit', async ({ request }) => { await delay(500); const body = (await request.json()) as { coilIds: string[]; orderIds: string[]; strategy?: 'AUTO' | 'LENGTH_FIRST' | 'WIDTH_FIRST'; }; const newTask: MockOptimizationTask = { taskId: generateTaskId(), taskType: 'SINGLE_COIL', status: 'PENDING', progress: 0, currentPhase: 'PRE_PLANNING', progressDesc: '排队中', inputParams: { coilIds: body.coilIds, orderIds: body.orderIds, strategy: body.strategy || 'AUTO', }, createdBy: 'admin', createTime: new Date().toISOString().replace('T', ' ').slice(0, 19), updateTime: new Date().toISOString().replace('T', ' ').slice(0, 19), }; tasks.unshift(newTask); // Simulate task execution setTimeout(() => { const task = tasks.find((t) => t.taskId === newTask.taskId); if (task && task.status === 'PENDING') { task.status = 'RUNNING'; task.progress = 50; task.currentPhase = 'DETAILED_ENUMERATION'; task.progressDesc = '详细枚举中...'; task.updateTime = new Date().toISOString().replace('T', ' ').slice(0, 19); setTimeout(() => { if (task && task.status === 'RUNNING') { task.status = 'COMPLETED'; task.progress = 100; task.currentPhase = 'GLOBAL_OPTIMIZATION'; task.progressDesc = '已完成'; task.resultRef = `plan-${Date.now()}`; task.updateTime = new Date().toISOString().replace('T', ' ').slice(0, 19); } }, 2000); } }, 1000); return HttpResponse.json({ code: 0, data: newTask.taskId, msg: '' }); }), // Submit global optimization task http.post('/admin-api/aps/task/global/submit', async ({ request }) => { await delay(500); const body = (await request.json()) as { coilIds: string[]; orderIds: string[]; strategy?: 'AUTO' | 'LENGTH_FIRST' | 'WIDTH_FIRST'; }; // Check per-user limit (max 2 running/pending) const runningCount = tasks.filter( (t) => t.createdBy === 'admin' && (t.status === 'RUNNING' || t.status === 'PENDING') ).length; if (runningCount >= 2) { return HttpResponse.json({ code: 1024001001, data: null, msg: '您已有 2 个任务在进行中', }); } const newTask: MockOptimizationTask = { taskId: generateTaskId(), taskType: 'GLOBAL_OPTIMIZATION', status: 'PENDING', progress: 0, currentPhase: 'PRE_PLANNING', progressDesc: '排队中', inputParams: { coilIds: body.coilIds, orderIds: body.orderIds, strategy: body.strategy || 'AUTO', }, createdBy: 'admin', createTime: new Date().toISOString().replace('T', ' ').slice(0, 19), updateTime: new Date().toISOString().replace('T', ' ').slice(0, 19), }; tasks.unshift(newTask); // Simulate task execution with phases const phases: Array<{ phase: MockOptimizationTask['currentPhase']; desc: string; progress: number }> = [ { phase: 'PRE_PLANNING', desc: '预规划中...', progress: 20 }, { phase: 'COIL_SCREENING', desc: '母卷筛选中...', progress: 40 }, { phase: 'DETAILED_ENUMERATION', desc: `详细枚举 0/${body.coilIds.length} 母卷`, progress: 60 }, { phase: 'GLOBAL_OPTIMIZATION', desc: '全局寻优中...', progress: 80 }, ]; let phaseIndex = 0; const interval = setInterval(() => { const task = tasks.find((t) => t.taskId === newTask.taskId); if (!task || (task.status !== 'RUNNING' && task.status !== 'PENDING')) { clearInterval(interval); return; } if (task.status === 'PENDING') { task.status = 'RUNNING'; } if (phaseIndex < phases.length) { task.currentPhase = phases[phaseIndex].phase; task.progressDesc = phases[phaseIndex].desc; task.progress = phases[phaseIndex].progress; task.updateTime = new Date().toISOString().replace('T', ' ').slice(0, 19); phaseIndex++; } else { task.status = 'COMPLETED'; task.progress = 100; task.currentPhase = 'GLOBAL_OPTIMIZATION'; task.progressDesc = '已完成'; task.resultRef = `plan-${Date.now()}`; task.updateTime = new Date().toISOString().replace('T', ' ').slice(0, 19); clearInterval(interval); } }, 1500); return HttpResponse.json({ code: 0, data: newTask.taskId, msg: '' }); }), // Get task status http.get('/admin-api/aps/task/status', async ({ request }) => { await delay(200); const url = new URL(request.url); const taskId = url.searchParams.get('taskId'); const task = tasks.find((t) => t.taskId === taskId); if (!task) { return HttpResponse.json({ code: 1, data: null, msg: '任务不存在' }); } return HttpResponse.json({ code: 0, data: task, msg: '' }); }), // Get paginated task list http.get('/admin-api/aps/task/page', async ({ request }) => { await delay(300); const url = new URL(request.url); const pageNo = Number(url.searchParams.get('pageNo') || 1); const pageSize = Number(url.searchParams.get('pageSize') || 10); const taskType = url.searchParams.get('taskType'); const status = url.searchParams.get('status'); let filtered = [...tasks]; if (taskType) { filtered = filtered.filter((t) => t.taskType === taskType); } if (status) { filtered = filtered.filter((t) => t.status === status); } return HttpResponse.json({ code: 0, data: paginate(filtered, pageNo, pageSize), msg: '', }); }), // Cancel task http.post('/admin-api/aps/task/cancel', async ({ request }) => { await delay(300); const url = new URL(request.url); const taskId = url.searchParams.get('taskId'); const task = tasks.find((t) => t.taskId === taskId); if (!task) { return HttpResponse.json({ code: 1, data: null, msg: '任务不存在' }); } if (task.status !== 'RUNNING' && task.status !== 'PENDING') { return HttpResponse.json({ code: 1, data: null, msg: '只能取消运行中或排队中的任务' }); } task.status = 'CANCELLED'; task.progressDesc = '用户取消'; task.updateTime = new Date().toISOString().replace('T', ' ').slice(0, 19); return HttpResponse.json({ code: 0, data: true, msg: '' }); }), // Resume task http.post('/admin-api/aps/task/resume', async ({ request }) => { await delay(300); const url = new URL(request.url); const taskId = url.searchParams.get('taskId'); const task = tasks.find((t) => t.taskId === taskId); if (!task) { return HttpResponse.json({ code: 1, data: null, msg: '任务不存在' }); } if (task.status !== 'FAILED' && task.status !== 'CANCELLED' && task.status !== 'PAUSED') { return HttpResponse.json({ code: 1, data: null, msg: '只能续算失败、取消或暂停的任务' }); } task.status = 'RUNNING'; task.progressDesc = '续算中...'; task.updateTime = new Date().toISOString().replace('T', ' ').slice(0, 19); // Simulate resume completion setTimeout(() => { if (task.status === 'RUNNING') { task.status = 'COMPLETED'; task.progress = 100; task.progressDesc = '已完成'; task.resultRef = `plan-${Date.now()}`; task.updateTime = new Date().toISOString().replace('T', ' ').slice(0, 19); } }, 3000); return HttpResponse.json({ code: 0, data: true, msg: '' }); }), // Delete task http.delete('/admin-api/aps/task/delete', async ({ request }) => { await delay(200); const url = new URL(request.url); const taskId = url.searchParams.get('taskId'); tasks = tasks.filter((t) => t.taskId !== taskId); return HttpResponse.json({ code: 0, data: true, msg: '' }); }), ];