Files
AIclinicalresearch/frontend-v2/src/framework/router/PermissionDenied.tsx
HaHafeng 8eef9e0544 feat(asl): Complete Week 4 - Results display and Excel export with hybrid solution
Features:
- Backend statistics API (cloud-native Prisma aggregation)
- Results page with hybrid solution (AI consensus + human final decision)
- Excel export (frontend generation, zero disk write, cloud-native)
- PRISMA-style exclusion reason analysis with bar chart
- Batch selection and export (3 export methods)
- Fixed logic contradiction (inclusion does not show exclusion reason)
- Optimized table width (870px, no horizontal scroll)

Components:
- Backend: screeningController.ts - add getProjectStatistics API
- Frontend: ScreeningResults.tsx - complete results page (hybrid solution)
- Frontend: excelExport.ts - Excel export utility (40 columns full info)
- Frontend: ScreeningWorkbench.tsx - add navigation button
- Utils: get-test-projects.mjs - quick test tool

Architecture:
- Cloud-native: backend aggregation reduces network transfer
- Cloud-native: frontend Excel generation (zero file persistence)
- Reuse platform: global prisma instance, logger
- Performance: statistics API < 500ms, Excel export < 3s (1000 records)

Documentation:
- Update module status guide (add Week 4 features)
- Update task breakdown (mark Week 4 completed)
- Update API design spec (add statistics API)
- Update database design (add field usage notes)
- Create Week 4 development plan
- Create Week 4 completion report
- Create technical debt list

Test:
- End-to-end flow test passed
- All features verified
- Performance test passed
- Cloud-native compliance verified

Ref: Week 4 Development Plan
Scope: ASL Module MVP - Title Abstract Screening Results
Cloud-Native: Backend aggregation + Frontend Excel generation
2025-11-21 20:12:38 +08:00

164 lines
4.5 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.
import { Result, Button } from 'antd'
import { LockOutlined, HomeOutlined, RocketOutlined } from '@ant-design/icons'
import { useNavigate } from 'react-router-dom'
/**
* 无权限访问提示页面
*
* @description
* 当用户尝试访问无权限的模块时显示
* 引导用户升级版本或返回首页
*
* @version Week 2 Day 7 - 任务17
*/
interface PermissionDeniedProps {
/** 模块名称 */
moduleName?: string
/** 所需权限等级 */
requiredVersion?: string
/** 用户当前权限等级 */
currentVersion?: string
}
const PermissionDenied = ({
moduleName = '该功能',
requiredVersion = 'advanced',
currentVersion = 'basic',
}: PermissionDeniedProps) => {
const navigate = useNavigate()
/**
* 返回首页
*/
const handleGoHome = () => {
navigate('/')
}
/**
* 去升级(后续实现)
*/
const handleUpgrade = () => {
// TODO: 跳转到升级页面或打开升级对话框
console.log('用户点击升级按钮')
// 暂时跳转到首页
navigate('/')
}
// 权限等级名称映射
const versionName: Record<string, string> = {
basic: '基础版',
advanced: '高级版',
premium: '旗舰版',
}
return (
<div className="flex-1 flex items-center justify-center bg-gray-50">
<Result
icon={<LockOutlined style={{ fontSize: 72, color: '#faad14' }} />}
title={<span className="text-2xl">访</span>}
subTitle={
<div className="space-y-3 mt-4">
<p className="text-gray-600">
<strong>{versionName[currentVersion]}</strong>
访<strong>{moduleName}</strong>
</p>
<p className="text-gray-500">
<strong className="text-blue-600">{versionName[requiredVersion]}</strong>
</p>
</div>
}
extra={
<div className="flex gap-3 justify-center mt-6">
<Button
type="primary"
icon={<RocketOutlined />}
onClick={handleUpgrade}
size="large"
>
{versionName[requiredVersion]}
</Button>
<Button
icon={<HomeOutlined />}
onClick={handleGoHome}
size="large"
>
</Button>
</div>
}
>
{/* 版本对比 */}
<div className="mt-8 max-w-md mx-auto">
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
<div className="flex items-center gap-2 mb-3">
<RocketOutlined className="text-blue-600" />
<span className="font-semibold text-blue-900">
{versionName[requiredVersion]}
</span>
</div>
<ul className="space-y-2 text-sm text-gray-700 list-disc list-inside">
{requiredVersion === 'advanced' && (
<>
<li>AI智能文献筛选4LLM模型</li>
<li></li>
<li></li>
</>
)}
{requiredVersion === 'premium' && (
<>
<li></li>
<li></li>
<li></li>
<li></li>
</>
)}
</ul>
</div>
</div>
</Result>
</div>
)
}
export default PermissionDenied
/**
* 🎨 设计说明:
*
* 1. 用户体验:
* - ✅ 明确告知用户为什么无法访问
* - ✅ 显示当前版本和所需版本
* - ✅ 提供明确的升级路径
* - ✅ 展示升级后的价值(功能列表)
*
* 2. 商业转化:
* - ✅ 突出显示"升级"按钮(主按钮)
* - ✅ 列举升级后可获得的功能
* - ✅ 引导用户做出升级决策
*
* 3. 后续优化:
* - [ ] 接入真实的升级流程(支付系统)
* - [ ] 显示价格对比
* - [ ] 添加"免费试用"选项
* - [ ] 记录转化数据(用户点击升级的次数)
*
* 4. 权限策略:
* 【当前阶段】所有用户都是premium不会看到此页面
* 【Week 3+】ASL模块需要advanced权限可测试此页面
* 【Week 5+】完整的权限和付费体系
*/