feat(admin,rvw,asl,frontend): Batch import redesign + RVW parallel skills + UI improvements

Backend:
- Redesign batch user import: add autoInheritModules param, users auto-inherit tenant modules when true
- Add module validation: reject modules not subscribed by the tenant
- Soften department validation: skip instead of fail when department name not found
- Fix RVW skill status semantics: review findings (ERROR issues) no longer mark skill as error
- Add parallel execution support to SkillExecutor via parallelGroup
- Configure Editorial + Methodology skills to run in parallel (~240s -> ~130s)
- Update legacy bridge error message to user-friendly text

Frontend:
- Redesign ImportUserModal: 4-step flow (select tenant -> upload -> preview -> result)
- Simplify import template: remove tenant code and module columns
- Show tenant subscribed modules before import with auto-inherit option
- Fix isLegacyEmbed modules bypassing RouteGuard and TopNavigation permission checks
- Hide ASL fulltext screening (step 3), renumber subsequent nav items
- Add ExtractionWorkbenchGuide page when no taskId provided
- Update legacy system error message to network-friendly text

Docs:
- Update deployment changelog with BE-9, FE-11 entries

Made-with: Cursor
This commit is contained in:
2026-03-05 22:04:36 +08:00
parent 0677d42345
commit 91ae80888e
19 changed files with 576 additions and 274 deletions

View File

@@ -10,7 +10,6 @@ import { Outlet, useNavigate, useLocation } from 'react-router-dom';
import {
SearchOutlined,
FilterOutlined,
FileSearchOutlined,
DatabaseOutlined,
BarChartOutlined,
SettingOutlined,
@@ -57,32 +56,10 @@ const ASLLayout = () => {
},
],
},
{
key: 'fulltext-screening',
icon: <FileSearchOutlined />,
label: '3. 全文复筛',
children: [
{
key: '/literature/screening/fulltext/settings',
icon: <SettingOutlined />,
label: '设置与启动',
},
{
key: '/literature/screening/fulltext/workbench',
icon: <CheckSquareOutlined />,
label: '审核工作台',
},
{
key: '/literature/screening/fulltext/results',
icon: <UnorderedListOutlined />,
label: '复筛结果',
},
],
},
{
key: 'extraction',
icon: <DatabaseOutlined />,
label: '4. 全文智能提取',
label: '3. 全文智能提取',
children: [
{
key: '/literature/extraction/setup',
@@ -99,12 +76,12 @@ const ASLLayout = () => {
{
key: '/literature/charting',
icon: <ApartmentOutlined />,
label: '5. SR 图表生成器',
label: '4. SR 图表生成器',
},
{
key: '/literature/meta-analysis',
icon: <BarChartOutlined />,
label: '6. Meta 分析引擎',
label: '5. Meta 分析引擎',
},
];
@@ -122,7 +99,6 @@ const ASLLayout = () => {
// 根据当前路径确定展开的菜单
const getOpenKeys = () => {
if (currentPath.includes('screening/title')) return ['title-screening'];
if (currentPath.includes('screening/fulltext')) return ['fulltext-screening'];
if (currentPath.includes('/extraction')) return ['extraction'];
if (currentPath.includes('/charting')) return [];
if (currentPath.includes('/meta-analysis')) return [];

View File

@@ -4,8 +4,9 @@
*/
import { Suspense, lazy } from 'react';
import { Routes, Route, Navigate } from 'react-router-dom';
import { Spin } from 'antd';
import { Routes, Route, Navigate, useNavigate } from 'react-router-dom';
import { Spin, Result, Button } from 'antd';
import { SettingOutlined } from '@ant-design/icons';
// 懒加载组件
const ASLLayout = lazy(() => import('./components/ASLLayout'));
@@ -36,6 +37,22 @@ const SRChartGenerator = lazy(() => import('./pages/SRChartGenerator'));
// 工具 5Meta 分析引擎
const MetaAnalysisEngine = lazy(() => import('./pages/MetaAnalysisEngine'));
const ExtractionWorkbenchGuide = () => {
const nav = useNavigate();
return (
<Result
icon={<SettingOutlined style={{ color: '#1890ff' }} />}
title="请先配置提取任务"
subTitle="审核工作台需要在「配置与启动」中创建并完成提取任务后才可使用。请先前往配置页面上传文献并启动提取。"
extra={
<Button type="primary" onClick={() => nav('/literature/extraction/setup')}>
</Button>
}
/>
);
};
const ASLModule = () => {
return (
<Suspense
@@ -77,6 +94,7 @@ const ASLModule = () => {
<Route index element={<Navigate to="setup" replace />} />
<Route path="setup" element={<ExtractionSetup />} />
<Route path="progress/:taskId" element={<ExtractionProgress />} />
<Route path="workbench" element={<ExtractionWorkbenchGuide />} />
<Route path="workbench/:taskId" element={<ExtractionWorkbench />} />
</Route>