Files
AIclinicalresearch/frontend-v2/src/modules/asl/components/ASLLayout.tsx
HaHafeng beb7f7f559 feat(asl): Implement full-text screening core LLM service and validation system (Day 1-3)
Core Components:
- PDFStorageService with Dify/OSS adapters
- LLM12FieldsService with Nougat-first + dual-model + 3-layer JSON parsing
- PromptBuilder for dynamic prompt assembly
- MedicalLogicValidator with 5 rules + fault tolerance
- EvidenceChainValidator for citation integrity
- ConflictDetectionService for dual-model comparison

Prompt Engineering:
- System Prompt (6601 chars, Section-Aware strategy)
- User Prompt template (PICOS context injection)
- JSON Schema (12 fields constraints)
- Cochrane standards (not loaded in MVP)

Key Innovations:
- 3-layer JSON parsing (JSON.parse + json-repair + code block extraction)
- Promise.allSettled for dual-model fault tolerance
- safeGetFieldValue for robust field extraction
- Mixed CN/EN token calculation

Integration Tests:
- integration-test.ts (full test)
- quick-test.ts (quick test)
- cached-result-test.ts (fault tolerance test)

Documentation Updates:
- Development record (Day 2-3 summary)
- Quality assurance strategy (full-text screening)
- Development plan (progress update)
- Module status (v1.1 update)
- Technical debt (10 new items)

Test Results:
- JSON parsing success rate: 100%
- Medical logic validation: 5/5 passed
- Dual-model parallel processing: OK
- Cost per PDF: CNY 0.10

Files: 238 changed, 14383 insertions(+), 32 deletions(-)
Docs: docs/03-涓氬姟妯″潡/ASL-AI鏅鸿兘鏂囩尞/05-寮€鍙戣褰?2025-11-22_Day2-Day3_LLM鏈嶅姟涓庨獙璇佺郴缁熷紑鍙?md
2025-11-22 22:21:12 +08:00

159 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* ASL模块布局组件
*
* 左侧导航栏 + 右侧内容区
* 参考原型AI智能文献-标题摘要初筛原型.html
*/
import { Layout, Menu } from 'antd';
import { Outlet, useNavigate, useLocation } from 'react-router-dom';
import {
FileTextOutlined,
SearchOutlined,
FolderOpenOutlined,
FilterOutlined,
FileSearchOutlined,
DatabaseOutlined,
BarChartOutlined,
SettingOutlined,
CheckSquareOutlined,
UnorderedListOutlined,
} from '@ant-design/icons';
import type { MenuProps } from 'antd';
const { Sider, Content } = Layout;
type MenuItem = Required<MenuProps>['items'][number];
const ASLLayout = () => {
const navigate = useNavigate();
const location = useLocation();
// 菜单项配置
const menuItems: MenuItem[] = [
{
key: 'research-plan',
icon: <FileTextOutlined />,
label: '1. 研究方案生成',
disabled: true,
title: '敬请期待'
},
{
key: 'literature-search',
icon: <SearchOutlined />,
label: '2. 智能文献检索',
disabled: true,
title: '敬请期待'
},
{
key: 'literature-management',
icon: <FolderOpenOutlined />,
label: '3. 文献管理',
disabled: true,
title: '敬请期待'
},
{
key: 'title-screening',
icon: <FilterOutlined />,
label: '4. 标题摘要初筛',
children: [
{
key: '/literature/screening/title/settings',
icon: <SettingOutlined />,
label: '设置与启动',
},
{
key: '/literature/screening/title/workbench',
icon: <CheckSquareOutlined />,
label: '审核工作台',
},
{
key: '/literature/screening/title/results',
icon: <UnorderedListOutlined />,
label: '初筛结果',
},
],
},
{
key: 'fulltext-screening',
icon: <FileSearchOutlined />,
label: '5. 全文复筛',
disabled: true,
title: '敬请期待'
},
{
key: 'data-extraction',
icon: <DatabaseOutlined />,
label: '6. 全文解析与数据提取',
disabled: true,
title: '敬请期待'
},
{
key: 'data-analysis',
icon: <BarChartOutlined />,
label: '7. 数据综合分析与报告',
disabled: true,
title: '敬请期待'
},
];
// 处理菜单点击
const handleMenuClick: MenuProps['onClick'] = ({ key }) => {
if (key.startsWith('/')) {
navigate(key);
}
};
// 获取当前选中的菜单项和展开的子菜单
const currentPath = location.pathname;
const selectedKeys = [currentPath];
const openKeys = currentPath.includes('screening/title') ? ['title-screening'] : [];
return (
<Layout className="h-screen">
{/* 左侧导航栏 */}
<Sider
width={250}
className="bg-gray-50 border-r border-gray-200"
theme="light"
>
<div className="p-4 border-b border-gray-200">
<h2 className="text-lg font-bold text-gray-800">
<FilterOutlined className="mr-2" />
AI智能文献
</h2>
<p className="text-xs text-gray-500 mt-1">
MVP
</p>
</div>
<Menu
mode="inline"
selectedKeys={selectedKeys}
defaultOpenKeys={openKeys}
items={menuItems}
onClick={handleMenuClick}
className="border-none"
style={{ height: 'calc(100vh - 80px)', overflowY: 'auto' }}
/>
</Sider>
{/* 右侧内容区 */}
<Layout>
<Content className="bg-white overflow-auto">
<Outlet />
</Content>
</Layout>
</Layout>
);
};
export default ASLLayout;