fix(pkb): fix create KB and upload issues - remove simulated upload, fix department mapping, add upload modal
Fixed issues: - Remove simulateUpload function from DashboardPage Step 3 - Map department to description field when creating KB - Add upload modal in WorkspacePage knowledge assets tab - Fix DocumentUpload import path (../../stores to ../stores) Known issue: Dify API validation error during document upload (file uploaded but DB record failed, needs investigation) Testing: KB creation works, upload dialog opens correctly
This commit is contained in:
@@ -87,6 +87,9 @@ vite.config.*.timestamp-*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -54,6 +54,9 @@ exec nginx -g 'daemon off;'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -210,6 +210,9 @@ http {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -43,3 +43,4 @@ apiClient.interceptors.response.use(
|
||||
export default apiClient;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -204,3 +204,6 @@ export function useAuth(): AuthContextType {
|
||||
|
||||
export { AuthContext };
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -240,3 +240,6 @@ export async function logout(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,3 +6,6 @@ export { AuthProvider, useAuth, AuthContext } from './AuthContext';
|
||||
export * from './types';
|
||||
export * from './api';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -32,3 +32,4 @@ export async function fetchUserModules(): Promise<string[]> {
|
||||
return result.data || [];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -99,3 +99,6 @@ export interface AuthContextType extends AuthState {
|
||||
hasRole: (...roles: UserRole[]) => boolean;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -14,10 +14,25 @@ import type {
|
||||
PaginatedResponse,
|
||||
ProjectStatistics
|
||||
} from '../types';
|
||||
import { getAccessToken } from '../../../framework/auth/api';
|
||||
|
||||
// API基础URL
|
||||
const API_BASE_URL = '/api/v1/asl';
|
||||
|
||||
/**
|
||||
* 获取带认证的请求头
|
||||
*/
|
||||
function getAuthHeaders(): HeadersInit {
|
||||
const headers: Record<string, string> = {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
const token = getAccessToken();
|
||||
if (token) {
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
// 通用请求函数
|
||||
async function request<T = any>(
|
||||
url: string,
|
||||
@@ -26,7 +41,7 @@ async function request<T = any>(
|
||||
const response = await fetch(`${API_BASE_URL}${url}`, {
|
||||
...options,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...getAuthHeaders(),
|
||||
...options?.headers,
|
||||
},
|
||||
});
|
||||
@@ -239,7 +254,8 @@ export async function exportScreeningResults(
|
||||
).toString();
|
||||
|
||||
const response = await fetch(
|
||||
`${API_BASE_URL}/projects/${projectId}/screening/results/export?${queryString}`
|
||||
`${API_BASE_URL}/projects/${projectId}/screening/results/export?${queryString}`,
|
||||
{ headers: getAuthHeaders() }
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -409,7 +425,8 @@ export async function exportFulltextResults(
|
||||
taskId: string
|
||||
): Promise<Blob> {
|
||||
const response = await fetch(
|
||||
`${API_BASE_URL}/fulltext-screening/tasks/${taskId}/export`
|
||||
`${API_BASE_URL}/fulltext-screening/tasks/${taskId}/export`,
|
||||
{ headers: getAuthHeaders() }
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -557,6 +557,9 @@ export default FulltextDetailDrawer;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,8 +3,24 @@
|
||||
* 病历结构化机器人 API调用
|
||||
*/
|
||||
|
||||
import { getAccessToken } from '../../../framework/auth/api';
|
||||
|
||||
const API_BASE = '/api/v1/dc/tool-b';
|
||||
|
||||
/**
|
||||
* 获取带认证的请求头
|
||||
*/
|
||||
function getAuthHeaders(): HeadersInit {
|
||||
const headers: Record<string, string> = {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
const token = getAccessToken();
|
||||
if (token) {
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
export interface UploadFileResponse {
|
||||
fileKey: string;
|
||||
url: string;
|
||||
@@ -86,8 +102,16 @@ export async function uploadFile(file: File): Promise<UploadFileResponse> {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
// 文件上传不设置 Content-Type,让浏览器自动设置 multipart/form-data
|
||||
const token = getAccessToken();
|
||||
const headers: HeadersInit = {};
|
||||
if (token) {
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
const response = await fetch(`${API_BASE}/upload`, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: formData,
|
||||
});
|
||||
|
||||
@@ -110,7 +134,7 @@ export async function uploadFile(file: File): Promise<UploadFileResponse> {
|
||||
export async function healthCheck(request: HealthCheckRequest): Promise<HealthCheckResponse> {
|
||||
const response = await fetch(`${API_BASE}/health-check`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: getAuthHeaders(),
|
||||
body: JSON.stringify(request),
|
||||
});
|
||||
|
||||
@@ -136,7 +160,9 @@ export async function healthCheck(request: HealthCheckRequest): Promise<HealthCh
|
||||
* 获取模板列表
|
||||
*/
|
||||
export async function getTemplates(): Promise<Template[]> {
|
||||
const response = await fetch(`${API_BASE}/templates`);
|
||||
const response = await fetch(`${API_BASE}/templates`, {
|
||||
headers: getAuthHeaders(),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Get templates failed: ${response.statusText}`);
|
||||
@@ -152,7 +178,7 @@ export async function getTemplates(): Promise<Template[]> {
|
||||
export async function createTask(request: CreateTaskRequest): Promise<CreateTaskResponse> {
|
||||
const response = await fetch(`${API_BASE}/tasks`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: getAuthHeaders(),
|
||||
body: JSON.stringify(request),
|
||||
});
|
||||
|
||||
@@ -168,7 +194,9 @@ export async function createTask(request: CreateTaskRequest): Promise<CreateTask
|
||||
* 查询任务进度
|
||||
*/
|
||||
export async function getTaskProgress(taskId: string): Promise<TaskProgress> {
|
||||
const response = await fetch(`${API_BASE}/tasks/${taskId}/progress`);
|
||||
const response = await fetch(`${API_BASE}/tasks/${taskId}/progress`, {
|
||||
headers: getAuthHeaders(),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Get task progress failed: ${response.statusText}`);
|
||||
@@ -182,7 +210,9 @@ export async function getTaskProgress(taskId: string): Promise<TaskProgress> {
|
||||
* 获取验证网格数据
|
||||
*/
|
||||
export async function getTaskItems(taskId: string): Promise<{ items: ExtractionItem[] }> {
|
||||
const response = await fetch(`${API_BASE}/tasks/${taskId}/items`);
|
||||
const response = await fetch(`${API_BASE}/tasks/${taskId}/items`, {
|
||||
headers: getAuthHeaders(),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Get task items failed: ${response.statusText}`);
|
||||
@@ -202,7 +232,7 @@ export async function resolveConflict(
|
||||
): Promise<{ success: boolean }> {
|
||||
const response = await fetch(`${API_BASE}/items/${itemId}/resolve`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: getAuthHeaders(),
|
||||
body: JSON.stringify({ field: fieldName, chosenValue: value }), // 🔑 后端期望field而非fieldName
|
||||
});
|
||||
|
||||
@@ -220,7 +250,9 @@ export async function resolveConflict(
|
||||
export async function exportResults(taskId: string): Promise<Blob> {
|
||||
console.log('[Export] Starting export for taskId:', taskId);
|
||||
|
||||
const response = await fetch(`${API_BASE}/tasks/${taskId}/export`);
|
||||
const response = await fetch(`${API_BASE}/tasks/${taskId}/export`, {
|
||||
headers: getAuthHeaders(),
|
||||
});
|
||||
|
||||
console.log('[Export] Response status:', response.status, response.statusText);
|
||||
console.log('[Export] Response headers:', {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* - AI功能:生成代码、执行代码、一步到位处理、获取历史
|
||||
*/
|
||||
|
||||
import axios from 'axios';
|
||||
import apiClient from '../../../common/api/axios';
|
||||
|
||||
const BASE_URL = '/api/v1/dc/tool-c';
|
||||
|
||||
@@ -90,7 +90,7 @@ export const uploadFile = async (file: File): Promise<UploadResponse> => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
const response = await axios.post(`${BASE_URL}/sessions/upload`, formData, {
|
||||
const response = await apiClient.post(`${BASE_URL}/sessions/upload`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
timeout: 30000, // 30秒超时
|
||||
});
|
||||
@@ -102,7 +102,7 @@ export const uploadFile = async (file: File): Promise<UploadResponse> => {
|
||||
* 获取Session元数据
|
||||
*/
|
||||
export const getSession = async (sessionId: string): Promise<SessionData> => {
|
||||
const response = await axios.get(`${BASE_URL}/sessions/${sessionId}`);
|
||||
const response = await apiClient.get(`${BASE_URL}/sessions/${sessionId}`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
@@ -110,7 +110,7 @@ export const getSession = async (sessionId: string): Promise<SessionData> => {
|
||||
* 获取预览数据(⭐ 已改为全量加载)
|
||||
*/
|
||||
export const getPreviewData = async (sessionId: string): Promise<PreviewData> => {
|
||||
const response = await axios.get(`${BASE_URL}/sessions/${sessionId}/preview`);
|
||||
const response = await apiClient.get(`${BASE_URL}/sessions/${sessionId}/preview`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
@@ -118,7 +118,7 @@ export const getPreviewData = async (sessionId: string): Promise<PreviewData> =>
|
||||
* 获取完整数据
|
||||
*/
|
||||
export const getFullData = async (sessionId: string): Promise<PreviewData> => {
|
||||
const response = await axios.get(`${BASE_URL}/sessions/${sessionId}/full`);
|
||||
const response = await apiClient.get(`${BASE_URL}/sessions/${sessionId}/full`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
@@ -126,7 +126,7 @@ export const getFullData = async (sessionId: string): Promise<PreviewData> => {
|
||||
* 更新心跳(延长10分钟)
|
||||
*/
|
||||
export const updateHeartbeat = async (sessionId: string): Promise<{ success: boolean }> => {
|
||||
const response = await axios.post(`${BASE_URL}/sessions/${sessionId}/heartbeat`);
|
||||
const response = await apiClient.post(`${BASE_URL}/sessions/${sessionId}/heartbeat`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
@@ -134,7 +134,7 @@ export const updateHeartbeat = async (sessionId: string): Promise<{ success: boo
|
||||
* 删除Session
|
||||
*/
|
||||
export const deleteSession = async (sessionId: string): Promise<{ success: boolean }> => {
|
||||
const response = await axios.delete(`${BASE_URL}/sessions/${sessionId}`);
|
||||
const response = await apiClient.delete(`${BASE_URL}/sessions/${sessionId}`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
@@ -154,7 +154,7 @@ export const generateCode = async (
|
||||
messageId: string;
|
||||
};
|
||||
}> => {
|
||||
const response = await axios.post(`${BASE_URL}/ai/generate`, {
|
||||
const response = await apiClient.post(`${BASE_URL}/ai/generate`, {
|
||||
sessionId,
|
||||
message,
|
||||
});
|
||||
@@ -176,7 +176,7 @@ export const executeCode = async (
|
||||
} | null;
|
||||
error?: string;
|
||||
}> => {
|
||||
const response = await axios.post(`${BASE_URL}/ai/execute`, {
|
||||
const response = await apiClient.post(`${BASE_URL}/ai/execute`, {
|
||||
sessionId,
|
||||
code,
|
||||
messageId,
|
||||
@@ -192,7 +192,7 @@ export const processMessage = async (
|
||||
message: string,
|
||||
maxRetries: number = 3
|
||||
): Promise<AIProcessResponse> => {
|
||||
const response = await axios.post(
|
||||
const response = await apiClient.post(
|
||||
`${BASE_URL}/ai/process`,
|
||||
{
|
||||
sessionId,
|
||||
@@ -213,7 +213,7 @@ export const getChatHistory = async (
|
||||
sessionId: string,
|
||||
limit: number = 10
|
||||
): Promise<ChatHistoryResponse> => {
|
||||
const response = await axios.get(`${BASE_URL}/ai/history/${sessionId}?limit=${limit}`);
|
||||
const response = await apiClient.get(`${BASE_URL}/ai/history/${sessionId}?limit=${limit}`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
@@ -238,7 +238,7 @@ export const getSessionStatus = async (
|
||||
};
|
||||
}> => {
|
||||
const params = jobId ? { jobId } : {};
|
||||
const response = await axios.get(`${BASE_URL}/sessions/${sessionId}/status`, { params });
|
||||
const response = await apiClient.get(`${BASE_URL}/sessions/${sessionId}/status`, { params });
|
||||
return response.data;
|
||||
};
|
||||
|
||||
|
||||
@@ -150,6 +150,9 @@ export const useAssets = (activeTab: AssetTabType) => {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -140,6 +140,9 @@ export const useRecentTasks = () => {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -339,6 +339,9 @@ export default DropnaDialog;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -424,6 +424,9 @@ export default MetricTimePanel;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -310,6 +310,9 @@ export default PivotPanel;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -110,6 +110,9 @@ export function useSessionStatus({
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -102,6 +102,9 @@ export interface DataStats {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -98,6 +98,9 @@ export type AssetTabType = 'all' | 'processed' | 'raw';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
import axios from 'axios';
|
||||
import { getAccessToken } from '../../../framework/auth/api';
|
||||
|
||||
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000';
|
||||
|
||||
@@ -15,6 +16,18 @@ const api = axios.create({
|
||||
},
|
||||
});
|
||||
|
||||
// 请求拦截器 - 自动添加 Authorization header
|
||||
api.interceptors.request.use(
|
||||
(config) => {
|
||||
const token = getAccessToken();
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => Promise.reject(error)
|
||||
);
|
||||
|
||||
/**
|
||||
* 知识库类型定义
|
||||
*/
|
||||
@@ -221,3 +234,4 @@ export const documentSelectionApi = {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -102,7 +102,9 @@ const DashboardPage: React.FC = () => {
|
||||
|
||||
const handleCreateSubmit = async () => {
|
||||
try {
|
||||
const kb = await createKnowledgeBase(formData.name, formData.department);
|
||||
// 后端期望 description 字段,将 department 作为描述的一部分
|
||||
const description = `${formData.department || ''}科 知识库`;
|
||||
const kb = await createKnowledgeBase(formData.name, description);
|
||||
message.success('知识库创建成功!');
|
||||
setIsModalOpen(false);
|
||||
navigate(`/knowledge-base/workspace/${kb.id}`);
|
||||
@@ -111,32 +113,7 @@ const DashboardPage: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 模拟文件上传
|
||||
const simulateUpload = () => {
|
||||
const newFile = {
|
||||
id: Math.random().toString(),
|
||||
name: `New_Clinical_Protocol_v${files.length + 1}.pdf`,
|
||||
size: "3.5 MB",
|
||||
status: 'uploading',
|
||||
progress: 0
|
||||
};
|
||||
setFiles(prev => [...prev, newFile]);
|
||||
|
||||
let progress = 0;
|
||||
const interval = setInterval(() => {
|
||||
progress += 2;
|
||||
setFiles(prev => prev.map(f => {
|
||||
if (f.id !== newFile.id) return f;
|
||||
let status = 'uploading';
|
||||
if (progress > 15) status = 'analyzing_layout';
|
||||
if (progress > 50) status = 'extracting_table';
|
||||
if (progress > 85) status = 'indexing';
|
||||
if (progress >= 100) status = 'ready';
|
||||
return { ...f, progress: Math.min(progress, 100), status };
|
||||
}));
|
||||
if (progress >= 100) clearInterval(interval);
|
||||
}, 100);
|
||||
};
|
||||
// 删除模拟上传功能,Step 3留作后续实现真实上传组件
|
||||
|
||||
const getStatusText = (status: string) => {
|
||||
switch (status) {
|
||||
@@ -350,14 +327,14 @@ const DashboardPage: React.FC = () => {
|
||||
{createStep === 3 && (
|
||||
<div className="max-w-3xl mx-auto space-y-6 mt-4">
|
||||
<div
|
||||
onClick={simulateUpload}
|
||||
className="border-2 border-dashed border-gray-300 rounded-xl p-12 flex flex-col items-center justify-center cursor-pointer hover:bg-blue-50 hover:border-blue-500 transition-all group bg-white"
|
||||
className="border-2 border-dashed border-gray-300 rounded-xl p-12 flex flex-col items-center justify-center bg-white"
|
||||
>
|
||||
<div className="w-20 h-20 bg-blue-50 rounded-full flex items-center justify-center mb-6 group-hover:scale-110 transition-transform">
|
||||
<Upload className="w-10 h-10 text-blue-600" />
|
||||
<div className="w-20 h-20 bg-blue-50 rounded-full flex items-center justify-center mb-6">
|
||||
<Upload className="w-10 h-10 text-blue-400" />
|
||||
</div>
|
||||
<p className="text-xl font-bold text-slate-700">点击上传 PDF 文件</p>
|
||||
<p className="text-sm text-slate-400 mt-2">支持高清 PDF 及扫描件 (MinerU 深度解析引擎已就绪)</p>
|
||||
<p className="text-xl font-bold text-slate-700">上传知识资产</p>
|
||||
<p className="text-sm text-slate-500 mt-2">知识库创建后,可在工作台中上传文档</p>
|
||||
<p className="text-xs text-slate-400 mt-3">💡 提示:点击下方"完成"按钮进入工作台,在"知识资产"Tab中上传PDF文档</p>
|
||||
</div>
|
||||
|
||||
{files.length > 0 && (
|
||||
|
||||
@@ -289,3 +289,6 @@ export default KnowledgePage;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -227,3 +227,6 @@ export const useKnowledgeBaseStore = create<KnowledgeBaseState>((set, get) => ({
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -44,3 +44,6 @@ export interface BatchTemplate {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* RVW模块API
|
||||
*/
|
||||
import axios from 'axios';
|
||||
import apiClient from '../../../common/api/axios';
|
||||
import type { ReviewTask, ReviewReport, ApiResponse, AgentType } from '../types';
|
||||
|
||||
const API_BASE = '/api/v2/rvw';
|
||||
@@ -9,7 +9,7 @@ const API_BASE = '/api/v2/rvw';
|
||||
// 获取任务列表
|
||||
export async function getTasks(status?: string): Promise<ReviewTask[]> {
|
||||
const params = status && status !== 'all' ? { status } : {};
|
||||
const response = await axios.get<ApiResponse<ReviewTask[]>>(`${API_BASE}/tasks`, { params });
|
||||
const response = await apiClient.get<ApiResponse<ReviewTask[]>>(`${API_BASE}/tasks`, { params });
|
||||
return response.data.data || [];
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ export async function uploadManuscript(file: File, selectedAgents?: AgentType[])
|
||||
formData.append('selectedAgents', JSON.stringify(selectedAgents));
|
||||
}
|
||||
|
||||
const response = await axios.post<ApiResponse<{ taskId: string }>>(`${API_BASE}/tasks`, formData, {
|
||||
const response = await apiClient.post<ApiResponse<{ taskId: string }>>(`${API_BASE}/tasks`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
|
||||
@@ -34,19 +34,19 @@ export async function uploadManuscript(file: File, selectedAgents?: AgentType[])
|
||||
|
||||
// 获取任务详情
|
||||
export async function getTask(taskId: string): Promise<ReviewTask> {
|
||||
const response = await axios.get<ApiResponse<ReviewTask>>(`${API_BASE}/tasks/${taskId}`);
|
||||
const response = await apiClient.get<ApiResponse<ReviewTask>>(`${API_BASE}/tasks/${taskId}`);
|
||||
return response.data.data!;
|
||||
}
|
||||
|
||||
// 获取任务报告
|
||||
export async function getTaskReport(taskId: string): Promise<ReviewReport> {
|
||||
const response = await axios.get<ApiResponse<ReviewReport>>(`${API_BASE}/tasks/${taskId}/report`);
|
||||
const response = await apiClient.get<ApiResponse<ReviewReport>>(`${API_BASE}/tasks/${taskId}/report`);
|
||||
return response.data.data!;
|
||||
}
|
||||
|
||||
// 运行审查任务(返回jobId供轮询)
|
||||
export async function runTask(taskId: string, agents: AgentType[]): Promise<{ taskId: string; jobId: string }> {
|
||||
const response = await axios.post<ApiResponse<{ taskId: string; jobId: string }>>(`${API_BASE}/tasks/${taskId}/run`, { agents });
|
||||
const response = await apiClient.post<ApiResponse<{ taskId: string; jobId: string }>>(`${API_BASE}/tasks/${taskId}/run`, { agents });
|
||||
if (!response.data.success) {
|
||||
throw new Error(response.data.error || '运行失败');
|
||||
}
|
||||
@@ -55,7 +55,7 @@ export async function runTask(taskId: string, agents: AgentType[]): Promise<{ ta
|
||||
|
||||
// 批量运行审查任务
|
||||
export async function batchRunTasks(taskIds: string[], agents: AgentType[]): Promise<void> {
|
||||
const response = await axios.post<ApiResponse<void>>(`${API_BASE}/tasks/batch/run`, { taskIds, agents });
|
||||
const response = await apiClient.post<ApiResponse<void>>(`${API_BASE}/tasks/batch/run`, { taskIds, agents });
|
||||
if (!response.data.success) {
|
||||
throw new Error(response.data.error || '批量运行失败');
|
||||
}
|
||||
@@ -63,7 +63,7 @@ export async function batchRunTasks(taskIds: string[], agents: AgentType[]): Pro
|
||||
|
||||
// 删除任务
|
||||
export async function deleteTask(taskId: string): Promise<void> {
|
||||
await axios.delete(`${API_BASE}/tasks/${taskId}`);
|
||||
await apiClient.delete(`${API_BASE}/tasks/${taskId}`);
|
||||
}
|
||||
|
||||
// 轮询任务状态
|
||||
@@ -129,3 +129,4 @@ export function formatTime(dateStr: string): string {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -122,3 +122,6 @@ export default function AgentModal({ visible, taskCount, onClose, onConfirm }: A
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -42,3 +42,6 @@ export default function BatchToolbar({ selectedCount, onRunBatch, onClearSelecti
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -65,3 +65,6 @@ export default function FilterChips({ filters, counts, onFilterChange }: FilterC
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -55,3 +55,6 @@ export default function Header({ onUpload }: HeaderProps) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -109,3 +109,6 @@ export default function ReportDetail({ report, onBack }: ReportDetailProps) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -37,3 +37,6 @@ export default function ScoreRing({ score, size = 'medium', showLabel = true }:
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -72,3 +72,6 @@ export default function Sidebar({ currentView, onViewChange, onSettingsClick }:
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -14,3 +14,6 @@ export { default as ReportDetail } from './ReportDetail';
|
||||
export { default as TaskDetail } from './TaskDetail';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -283,3 +283,6 @@ export default function Dashboard() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -232,3 +232,6 @@
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -365,3 +365,6 @@ export default function LoginPage() {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -335,3 +335,4 @@ const TenantListPage = () => {
|
||||
|
||||
export default TenantListPage;
|
||||
|
||||
|
||||
|
||||
@@ -244,3 +244,4 @@ export async function fetchModuleList(): Promise<ModuleInfo[]> {
|
||||
return result.data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -53,6 +53,9 @@ export { default as Placeholder } from './Placeholder';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
3
frontend-v2/src/vite-env.d.ts
vendored
3
frontend-v2/src/vite-env.d.ts
vendored
@@ -33,6 +33,9 @@ interface ImportMeta {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user