import request from '@/utils/request'; // @/api/scanCenter.ts /** * 获取历史检测记录 * @param params 分页和筛选参数 { page, size, status } * @returns 历史记录列表 */ export function getScanHistory(params: { page: number; size: number; status?: string }): Promise { return new Promise(resolve => { setTimeout(() => { // 模拟历史记录数据 const mockRecords = [ { taskId: 'scan_1689234567890', target: 'https://example.com', type: 'url', status: 'completed', riskLevel: '高危', startTime: '2024-07-13T09:23:45', completeTime: '2024-07-13T09:25:12', duration: 87000, riskStats: { critical: 1, high: 3, medium: 2, low: 5 } }, { taskId: 'scan_1689231234567', target: 'app-release.apk', type: 'file', status: 'completed', riskLevel: '中危', startTime: '2024-07-12T15:42:18', completeTime: '2024-07-12T15:47:33', duration: 315000, riskStats: { critical: 0, high: 0, medium: 2, low: 1 } }, { taskId: 'scan_1689228901234', target: 'SBOM内容', type: 'sbom', status: 'failed', riskLevel: '-', startTime: '2024-07-12T14:15:30', completeTime: '2024-07-12T14:16:05', duration: 35000, errorMsg: '格式解析错误:缺少必填字段"version"' }, { taskId: 'scan_1689225678901', target: 'https://test-api.com/v1', type: 'url', status: 'completed', riskLevel: '低危', startTime: '2024-07-12T10:08:22', completeTime: '2024-07-12T10:09:45', duration: 83000, riskStats: { critical: 0, high: 0, medium: 0, low: 2 } } ]; // 筛选逻辑 let filtered = mockRecords; if (params.status && params.status !== 'all') { filtered = filtered.filter(item => item.status === params.status); } // 分页逻辑 const total = filtered.length; const start = (params.page - 1) * params.size; const records = filtered.slice(start, start + params.size); resolve({ code: 200, message: 'success', data: { total, records, page: params.page, size: params.size, pages: Math.ceil(total / params.size) } }); }, 300); }); // 实际接口调用(注释掉,使用模拟数据) // return request({ // url: `/scan/history`, // method: 'get', // params // }); } /** * 提交检测任务 * @param data 任务数据 { type, target, file?, content? } * @returns 任务信息 */ export function submitScanTask(data: { type: 'file' | 'url' | 'sbom'; target: string; file?: FormData; content?: string; }): Promise { return new Promise(resolve => { setTimeout(() => { // 生成唯一任务ID const taskId = `scan_${Date.now()}`; const now = new Date().toISOString(); resolve({ code: 200, message: '任务提交成功', data: { taskId, type: data.type, target: data.target, status: 'pending', // 初始状态:等待中 progress: 0, startTime: now, estimatedCompleteTime: new Date(Date.now() + 300000).toISOString(), // 预计5分钟后完成 currentStep: '等待调度' } }); }, 500); }); // 实际接口调用(注释掉,使用模拟数据) // return request({ // url: `/scan/submit`, // method: 'post', // data // }); } /** * 获取检测任务状态 * @param taskId 任务ID * @returns 任务当前状态信息 */ export function getScanStatus(taskId: string): Promise { return new Promise(resolve => { setTimeout(() => { // 解析任务ID中的时间戳(模拟任务创建时间) const createTime = parseInt(taskId.split('_')[1] || Date.now().toString()); const now = Date.now(); const elapsed = now - createTime; // 模拟状态流转 let status: string, progress: number, currentStep: string, completeTime: string | null = null; if (elapsed < 3000) { // 前3秒:等待中 status = 'pending'; progress = 0; currentStep = '等待调度'; } else if (elapsed < 15000) { // 3-15秒:检测中(进度递增) status = 'scanning'; progress = Math.min(Math.floor((elapsed - 3000) / 12000 * 100), 90); currentStep = progress < 30 ? '初始化检测环境' : progress < 60 ? '执行漏洞扫描' : '生成初步报告'; } else { // 15秒后:完成(80%概率)或失败(20%概率) const isSuccess = Math.random() > 0.2; status = isSuccess ? 'completed' : 'failed'; progress = 100; completeTime = new Date().toISOString(); if (isSuccess) { currentStep = '检测完成'; } else { currentStep = '检测失败'; } } // 模拟风险统计(仅当任务完成时) const riskStats = status === 'completed' ? { critical: Math.floor(Math.random() * 2), high: Math.floor(Math.random() * 3), medium: Math.floor(Math.random() * 5), low: Math.floor(Math.random() * 8) } : null; // 模拟错误信息(仅当任务失败时) const errorMsg = status === 'failed' ? ['网络连接超时', '目标资源不可访问', '检测引擎异常'][Math.floor(Math.random() * 3)] : null; resolve({ code: 200, message: 'success', data: { taskId, status, progress, currentStep, startTime: new Date(createTime).toISOString(), estimatedCompleteTime: new Date(createTime + 300000).toISOString(), completeTime, riskStats, errorMsg, totalChecks: status === 'completed' ? 20 + Math.floor(Math.random() * 30) : null, completedChecks: status === 'scanning' ? Math.floor(progress / 100 * 40) : null } }); }, 300); }); // 实际接口调用(注释掉,使用模拟数据) // return request({ // url: `/scan/status/${taskId}`, // method: 'get' // }); }