214 lines
6.3 KiB
TypeScript
214 lines
6.3 KiB
TypeScript
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<any> {
|
||
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<any> {
|
||
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<any> {
|
||
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'
|
||
// });
|
||
}
|