Sprint 1-3 Completed (Backend + Frontend): Backend (Sprint 1-2): - Implement 5-layer Agent framework (Query->Planner->Executor->Tools->Reflection) - Create agent_schema with 6 tables (agent_definitions, stages, prompts, sessions, traces, reflexion_rules) - Create protocol_schema with 2 tables (protocol_contexts, protocol_generations) - Implement Protocol Agent core services (Orchestrator, ContextService, PromptBuilder) - Integrate LLM service adapter (DeepSeek/Qwen/GPT-5/Claude) - 6 API endpoints with full authentication - 10/10 API tests passed Frontend (Sprint 3): - Add Protocol Agent entry in AgentHub (indigo theme card) - Implement ProtocolAgentPage with 3-column layout - Collapsible sidebar (Gemini style, 48px <-> 280px) - StatePanel with 5 stage cards (scientific_question, pico, study_design, sample_size, endpoints) - ChatArea with sync button and action cards integration - 100% prototype design restoration (608 lines CSS) - Detailed endpoints structure: baseline, exposure, outcomes, confounders Features: - 5-stage dialogue flow for research protocol design - Conversation-driven interaction with sync-to-protocol button - Real-time context state management - One-click protocol generation button (UI ready, backend pending) Database: - agent_schema: 6 tables for reusable Agent framework - protocol_schema: 2 tables for Protocol Agent - Seed data: 1 agent + 5 stages + 9 prompts + 4 reflexion rules Code Stats: - Backend: 13 files, 4338 lines - Frontend: 14 files, 2071 lines - Total: 27 files, 6409 lines Status: MVP core functionality completed, pending frontend-backend integration testing Next: Sprint 4 - One-click protocol generation + Word export
178 lines
2.6 KiB
TypeScript
178 lines
2.6 KiB
TypeScript
/**
|
|
* DC模块 - 数据资产Hook
|
|
*
|
|
* 管理数据资产库的状态和数据获取
|
|
*/
|
|
|
|
import { useState, useEffect } from 'react';
|
|
import type { Asset, AssetTabType } from '../types/portal';
|
|
|
|
// Mock数据
|
|
const mockAssets: Asset[] = [
|
|
{
|
|
id: 'asset-001',
|
|
name: '2025糖尿病研究_AI提取结果.xlsx',
|
|
type: 'processed',
|
|
source: 'tool-b',
|
|
rowCount: 150,
|
|
tags: ['糖尿病', 'AI结构化'],
|
|
modifiedAt: '2025-12-01T11:45:00Z',
|
|
fileSize: 245760,
|
|
fileKey: 'dc/outputs/task-001-result.xlsx'
|
|
},
|
|
{
|
|
id: 'asset-002',
|
|
name: '高血压病历原始数据.xlsx',
|
|
type: 'raw',
|
|
source: 'upload',
|
|
rowCount: 320,
|
|
tags: ['高血压', '原始数据'],
|
|
modifiedAt: '2025-12-02T09:00:00Z',
|
|
fileSize: 512000,
|
|
fileKey: 'dc/uploads/hypertension-raw.xlsx'
|
|
},
|
|
{
|
|
id: 'asset-003',
|
|
name: '多中心数据合并结果.xlsx',
|
|
type: 'processed',
|
|
source: 'tool-a',
|
|
rowCount: 580,
|
|
tags: ['多中心', '数据合并'],
|
|
modifiedAt: '2025-11-30T16:20:00Z',
|
|
fileSize: 1048576,
|
|
fileKey: 'dc/outputs/merged-data.xlsx'
|
|
}
|
|
];
|
|
|
|
export const useAssets = (activeTab: AssetTabType) => {
|
|
const [assets, setAssets] = useState<Asset[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
// 获取资产列表
|
|
const fetchAssets = async () => {
|
|
try {
|
|
setLoading(true);
|
|
|
|
// TODO: 替换为真实API调用
|
|
// const response = await fetch(`/api/v1/dc/assets?type=${activeTab}`);
|
|
// const data = await response.json();
|
|
|
|
// 模拟API延迟
|
|
await new Promise(resolve => setTimeout(resolve, 300));
|
|
|
|
// 根据Tab筛选
|
|
let filteredAssets = mockAssets;
|
|
if (activeTab === 'processed') {
|
|
filteredAssets = mockAssets.filter(a => a.type === 'processed');
|
|
} else if (activeTab === 'raw') {
|
|
filteredAssets = mockAssets.filter(a => a.type === 'raw');
|
|
}
|
|
|
|
setAssets(filteredAssets);
|
|
setError(null);
|
|
} catch (err) {
|
|
setError(err instanceof Error ? err.message : '获取资产列表失败');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchAssets();
|
|
}, [activeTab]);
|
|
|
|
// 刷新资产列表
|
|
const refresh = () => {
|
|
fetchAssets();
|
|
};
|
|
|
|
// 删除资产
|
|
const deleteAsset = async (id: string) => {
|
|
// TODO: 实现删除逻辑
|
|
console.log('Delete asset:', id);
|
|
setAssets(assets.filter(a => a.id !== id));
|
|
};
|
|
|
|
return {
|
|
assets,
|
|
loading,
|
|
error,
|
|
refresh,
|
|
deleteAsset
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|