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
This commit is contained in:
@@ -21,3 +21,7 @@ if (data.length > 0) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -58,3 +58,7 @@ createTestUser();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
85
backend/scripts/get-test-projects.mjs
Normal file
85
backend/scripts/get-test-projects.mjs
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* 快速测试脚本 - 获取已有项目ID
|
||||
*
|
||||
* 用途:快速找到数据库中已有的项目ID,方便测试结果统计页面
|
||||
* 使用方法:node scripts/get-test-projects.mjs
|
||||
*/
|
||||
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function getProjects() {
|
||||
console.log('\n🔍 查询已有项目...\n');
|
||||
|
||||
try {
|
||||
// 查询所有项目
|
||||
const projects = await prisma.aslScreeningProject.findMany({
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: 10,
|
||||
select: {
|
||||
id: true,
|
||||
projectName: true,
|
||||
createdAt: true,
|
||||
status: true,
|
||||
_count: {
|
||||
select: {
|
||||
literatures: true,
|
||||
screeningResults: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (projects.length === 0) {
|
||||
console.log('❌ 没有找到任何项目');
|
||||
console.log('\n💡 提示:请先访问"设置与启动"页面,上传Excel并启动筛选\n');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`✅ 找到 ${projects.length} 个项目:\n`);
|
||||
|
||||
projects.forEach((project, index) => {
|
||||
console.log(`${index + 1}. 项目名称: ${project.projectName}`);
|
||||
console.log(` 项目ID: ${project.id}`);
|
||||
console.log(` 状态: ${project.status}`);
|
||||
console.log(` 文献数: ${project._count.literatures}`);
|
||||
console.log(` 筛选结果数: ${project._count.screeningResults}`);
|
||||
console.log(` 创建时间: ${project.createdAt.toLocaleString('zh-CN')}`);
|
||||
console.log('');
|
||||
});
|
||||
|
||||
// 推荐一个有数据的项目
|
||||
const validProject = projects.find(p => p._count.screeningResults > 0);
|
||||
|
||||
if (validProject) {
|
||||
console.log('🎯 推荐测试项目(有筛选结果):');
|
||||
console.log(` 项目ID: ${validProject.id}`);
|
||||
console.log(` 文献数: ${validProject._count.literatures}`);
|
||||
console.log(` 筛选结果数: ${validProject._count.screeningResults}`);
|
||||
console.log('\n📝 快速测试方法:');
|
||||
console.log(`\n1. 访问审核工作台:`);
|
||||
console.log(` http://localhost:3000/literature/screening/title/workbench?projectId=${validProject.id}`);
|
||||
console.log(`\n2. 点击页面右上角的"查看结果统计"按钮`);
|
||||
console.log(`\n3. 或直接访问结果统计页:`);
|
||||
console.log(` http://localhost:3000/literature/screening/title/results?projectId=${validProject.id}\n`);
|
||||
} else {
|
||||
console.log('⚠️ 所有项目都没有筛选结果');
|
||||
console.log('\n💡 提示:请选择一个项目,等待筛选完成后再查看结果\n');
|
||||
|
||||
if (projects.length > 0) {
|
||||
console.log(`📝 测试URL(待筛选完成后访问):`);
|
||||
console.log(` http://localhost:3000/literature/screening/title/workbench?projectId=${projects[0].id}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 查询失败:', error);
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
getProjects();
|
||||
|
||||
|
||||
@@ -192,3 +192,7 @@ testAPI();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -132,3 +132,7 @@ console.log('='.repeat(60) + '\n');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -376,3 +376,7 @@ main().catch(console.error);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -114,3 +114,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -204,3 +204,7 @@ runTest().catch(console.error);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -98,3 +98,7 @@ main().catch(console.error);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user