Features: - feat: Excel template generation and download (with examples) - feat: Excel file parsing in memory (cloud-native, no disk write) - feat: Field validation (title + abstract required) - feat: Smart deduplication (DOI priority + Title fallback) - feat: Literature preview table with statistics - feat: Complete submission flow (create project + import literatures) Components: - feat: Create excelUtils.ts with full Excel processing toolkit - feat: Enhance TitleScreeningSettings page with upload/preview/submit - feat: Update API interface signatures and export unified aslApi object Dependencies: - chore: Add xlsx library for Excel file processing Ref: Week 2 Frontend Development - Day 2 Scope: ASL Module MVP - Title Abstract Screening Cloud-Native: Memory parsing, no file persistence
154 lines
3.7 KiB
TypeScript
154 lines
3.7 KiB
TypeScript
/**
|
||
* 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;
|
||
|
||
|