Features - User Management (Phase 4.1): - Database: Add user_modules table for fine-grained module permissions - Database: Add 4 user permissions (view/create/edit/delete) to role_permissions - Backend: UserService (780 lines) - CRUD with tenant isolation - Backend: UserController + UserRoutes (648 lines) - 13 API endpoints - Backend: Batch import users from Excel - Frontend: UserListPage (412 lines) - list/filter/search/pagination - Frontend: UserFormPage (341 lines) - create/edit with module config - Frontend: UserDetailPage (393 lines) - details/tenant/module management - Frontend: 3 modal components (592 lines) - import/assign/configure - API: GET/POST/PUT/DELETE /api/admin/users/* endpoints Architecture Upgrade - Module Permission System: - Backend: Add getUserModules() method in auth.service - Backend: Login API returns modules array in user object - Frontend: AuthContext adds hasModule() method - Frontend: Navigation filters modules based on user.modules - Frontend: RouteGuard checks requiredModule instead of requiredVersion - Frontend: Remove deprecated version-based permission system - UX: Only show accessible modules in navigation (clean UI) - UX: Smart redirect after login (avoid 403 for regular users) Fixes: - Fix UTF-8 encoding corruption in ~100 docs files - Fix pageSize type conversion in userService (String to Number) - Fix authUser undefined error in TopNavigation - Fix login redirect logic with role-based access check - Update Git commit guidelines v1.2 with UTF-8 safety rules Database Changes: - CREATE TABLE user_modules (user_id, tenant_id, module_code, is_enabled) - ADD UNIQUE CONSTRAINT (user_id, tenant_id, module_code) - INSERT 4 permissions + role assignments - UPDATE PUBLIC tenant with 8 module subscriptions Technical: - Backend: 5 new files (~2400 lines) - Frontend: 10 new files (~2500 lines) - Docs: 1 development record + 2 status updates + 1 guideline update - Total: ~4900 lines of code Status: User management 100% complete, module permission system operational
976 lines
29 KiB
Markdown
976 lines
29 KiB
Markdown
# DC数据清洗整理模块 - 当前状态与开发指南
|
||
|
||
> **文档版本:** v3.4
|
||
> **创建日期:** 2025-11-28
|
||
> **维护者:** DC模块开发团队
|
||
> **最后更新:** 2025-12-22 🏆 **Tool C异步架构+性能优化完成!**
|
||
> **重大里程碑:** Tool C Postgres-Only异步架构改造 + 性能优化(-99%)+ 多指标转换
|
||
> **文档目的:** 反映模块真实状态,记录开发历程
|
||
|
||
---
|
||
|
||
## ⚠️ 重要事件记录
|
||
|
||
### 代码丢失事件(2025-11-28)
|
||
|
||
**事件描述**:
|
||
- 在2025-11-27开发的DC模块Tool B代码完全丢失
|
||
- 原因:Cursor临时缓存丢失,代码未及时提交到Git
|
||
- 影响范围:
|
||
- ❌ 所有Service层代码(4个服务)
|
||
- ❌ Controller层代码
|
||
- ❌ Routes配置
|
||
- ❌ 数据库迁移SQL文件(`20251127_add_dc_tool_b_tables/migration.sql`为空)
|
||
- ✅ 设计文档保留(PRD、技术设计、API设计、数据库设计、UI原型)
|
||
- ✅ 开发记录保留(Day2、Day3完成总结)
|
||
- ✅ Prisma Schema定义保留(4个表模型)
|
||
|
||
**重建工作**:
|
||
- ✅ 2025-11-28:完整重建后端代码(100%功能恢复)
|
||
- ✅ Git提交:防止再次丢失
|
||
- ⚠️ 数据库表状态:**未确认**(无法连接验证,但可随时通过`npx prisma db push`创建)
|
||
|
||
**教训与改进**:
|
||
- ✅ 更新了Git提交规范:强制每日提交
|
||
- ✅ 清理了所有数据库检查脚本(终端输出问题无法解决)
|
||
- ⚠️ **关键问题**:Cursor的PowerShell终端无法正常显示输出,导致多次尝试失败
|
||
|
||
---
|
||
|
||
## 📋 文档说明
|
||
|
||
本文档是DC数据清洗整理模块的**真实状态快照**,如实记录代码丢失、重建过程和当前真实状况。
|
||
|
||
**与其他文档的关系**:
|
||
- **本文档(00-模块当前状态)**:What is(真实状态,包括问题)
|
||
- **开发计划文档**:What to do(原计划)
|
||
- **开发记录文档**:What done(包括丢失前的Day2-3记录)
|
||
- **技术设计文档**:How to do(设计方案)
|
||
|
||
---
|
||
|
||
## 🎯 模块概述
|
||
|
||
### 核心功能
|
||
DC数据清洗整理模块提供4个智能工具,帮助研究人员清洗、整理、提取医疗数据。
|
||
|
||
### 当前状态
|
||
- **开发阶段**:✅ **Tool B MVP完成** + ✅ **Tool C MVP完成** + 🏆 **Postgres-Only 架构改造完成**
|
||
- **已完成功能**:
|
||
- ✅ Portal:智能数据清洗工作台(2025-12-02)
|
||
- ✅ Tool B 后端:病历结构化机器人(2025-11-28重建完成)
|
||
- ✅ Tool B 前端:5步工作流完整实现(2025-12-03)
|
||
- ✅ Tool B API对接:6个端点全部集成(2025-12-03)
|
||
- ✅ **🏆 Tool B Postgres-Only 架构改造**(2025-12-13,Phase 7):
|
||
- ✅ 智能双模式处理(<50条直接,≥50条队列)
|
||
- ✅ 任务拆分机制(1000条→20批)
|
||
- ✅ 断点续传支持(支持长时间提取任务)
|
||
- ✅ Platform层统一管理(job.data存储)
|
||
- ✅ Worker注册(extractionWorker.ts)
|
||
- ✅ **Tool C 完整实现**(2025-12-06 ~ 2025-12-22):
|
||
- ✅ Python微服务(~2400行,Day 1 + NA处理优化 + 多指标转换)
|
||
- ✅ Node.js后端(~3900行,Day 2-3 + Day 5-10 + 异步架构 + Worker)
|
||
- ✅ 前端界面(~4500行,Day 4-10 + React Query轮询 + 进度条)
|
||
- ✅ **通用 Chat 组件**(~968行,Day 5)🎉
|
||
- ✅ 7个功能按钮(Day 6)
|
||
- ✅ NA处理优化(4个功能,Day 7)
|
||
- ✅ Pivot列顺序优化(Day 7-8)
|
||
- ✅ 计算列方案B(安全列名映射,Day 7-8)
|
||
- ✅ **UX重大改进**(列头筛选/行号/滚动条修复/全量数据,Day 8)
|
||
- ✅ **多指标转换**(方向1+2,智能分组,原始顺序保持,Day 9)
|
||
- ✅ **Postgres-Only异步架构**(上传不超时,Worker后台处理,Day 10)
|
||
- ✅ **性能优化**(clean data缓存,-99%耗时,Day 10)
|
||
- **总计:~16500行** | **完成度:99%**
|
||
- **重大成就**:
|
||
- 🎉 **前端通用能力层建设完成**
|
||
- ✨ 基于 Ant Design X 的 Chat 组件库
|
||
- 🏆 **Platform-Only 架构创新**(与 ASL 统一架构)
|
||
- 🚀 可复用于 AIA、PKB、Tool C 等模块
|
||
- ✅ **NA处理全面支持**:数值映射、分箱、条件生成列、筛选
|
||
- ✅ **Pivot优化**:保留未选列+原始列顺序
|
||
- ✅ **UX重大改进**:列头筛选(Excel风格)+ 行号列 + 滚动条修复 + 全量数据处理
|
||
- **未开发功能**:
|
||
- ❌ Tool A:医疗数据超级合并器
|
||
- ⏳ 缺失值填补(均值/中位数/众数/固定值)
|
||
- ⏳ 多重插补(MICE)
|
||
- **模型支持**:DeepSeek-V3 + Qwen-Max 双模型交叉验证(已验证可用)
|
||
- **部署状态**:✅ 前后端完整可用,数据库表已确认存在并正常工作
|
||
- **已知问题**:4个技术债务(见`07-技术债务/Tool-B技术债务清单.md`)
|
||
|
||
### 关键里程碑
|
||
|
||
**Tool B - 病历结构化机器人**:
|
||
- ✅ 2025-11-22:**Day 2完成**(首次开发)
|
||
- 数据库Schema设计(4个表)
|
||
- 4个服务骨架创建
|
||
- LLMFactory测试通过
|
||
- ✅ 2025-11-23:**Day 3完成**(首次开发)
|
||
- HealthCheckService完整实现
|
||
- TemplateService完整实现(3个预设模板)
|
||
- API测试通过
|
||
- ❌ 2025-11-27:**代码完全丢失**
|
||
- ✅ 2025-11-28:**代码重建完成**
|
||
- 4个Service重建(HealthCheck、Template、DualModel、Conflict)
|
||
- 1个Controller重建(6个API端点)
|
||
- Routes集成到主应用
|
||
- Git提交保护
|
||
- ✅ 2025-12-02:**Portal页面完成**
|
||
- 工作台界面开发完成
|
||
- UI优化,匹配原型设计
|
||
- 与系统顶部导航集成
|
||
- ✅ 2025-12-03:**Tool B MVP版本完成** 🎉
|
||
- 前端5步工作流(~1400行代码)
|
||
- API完整对接(Phase 1-5)
|
||
- 真实LLM调用验证通过
|
||
- 双模型提取成功测试
|
||
- Excel导出功能可用
|
||
|
||
**Tool C - 科研数据编辑器**:
|
||
- ✅ 2025-12-06:**Day 1完成** - Python微服务 🚀
|
||
- ✅ 2025-12-06:**Day 2完成** - Session管理
|
||
- ✅ 2025-12-07:**Day 3完成** - AI代码生成
|
||
- ✅ 2025-12-07:**Day 4完成** - 前端基础框架
|
||
- ✅ 2025-12-07:**Day 5完成** - AI Chat面板 + Ant Design X 集成 🎉
|
||
- ✅ 2025-12-07:**UI优化完成** - 7个问题修复
|
||
- ✅ 2025-12-07:**MVP 完成** - 端到端可用 ✅
|
||
- ✅ 2025-12-08:**Day 6完成** - 7个功能按钮开发 🚀
|
||
- ✅ 2025-12-09:**Day 7完成** - 计算列方案B + UX优化
|
||
- ✅ 2025-12-10:**Day 8完成** - UX重大改进 🎉
|
||
- Python微服务扩展(~1800行,含NA处理 + 全量数据处理)
|
||
- Node.js后端优化(全量返回,5处代码修改)
|
||
- 前端界面完善(筛选/行号/滚动条/全量加载)
|
||
- 7个功能按钮(筛选、映射、分箱、条件、删NA、计算、Pivot)
|
||
- 4个功能支持NA处理(映射、筛选、分箱、条件)
|
||
- Pivot优化(保留未选列+原始列顺序)
|
||
- 计算列方案B(安全列名映射 + 全角字符转换)
|
||
- **UX重大改进**:
|
||
- ✅ 列头筛选(Excel风格,Community版本,中文本地化)
|
||
- ✅ 行号列(固定左侧,灰色背景)
|
||
- ✅ 滚动条修复(修改MainLayout,整个页面无滚动条)
|
||
- ✅ 全量数据(不再限制50行,筛选精确)
|
||
- ✅ 删除预览提示条
|
||
- 测试通过率:90%+
|
||
- **Tool C 完成度:98%** ✅
|
||
|
||
- ✅ 2025-12-06:**Day 2完成** - Session管理 ✅
|
||
- SessionService.ts(383行)+ DataProcessService.ts(303行)
|
||
- SessionController.ts(300行)
|
||
- 数据库表:dc_tool_c_sessions(12字段)
|
||
- 6个Session API端点
|
||
- OSS存储集成(零落盘)
|
||
- 测试通过率:100% (7/7)
|
||
|
||
- ✅ 2025-12-07:**Day 3完成** - AI代码生成 ✅
|
||
- AICodeService.ts(550行)+ AIController.ts(257行)
|
||
- 数据库表:dc_tool_c_ai_history(14字段)
|
||
- 10个Few-shot示例(Level 1-4)
|
||
- 自我修正机制(最多3次重试)
|
||
- 4个AI API端点
|
||
- 测试通过率:81.8% (9/11场景)
|
||
|
||
- ✅ 2025-12-07:**Day 4完成** - 前端基础框架 ✅
|
||
- index.tsx(258行)- 主入口+状态管理
|
||
- Header.tsx(91行)+ Toolbar.tsx(104行)
|
||
- DataGrid.tsx(111行)- AG Grid Community集成
|
||
- Sidebar.tsx(149行)- 骨架版
|
||
- API封装toolC.ts(218行,8个方法)
|
||
- AG Grid自定义样式(Emerald绿色主题)
|
||
- 路由配置 + Portal启用
|
||
- 总代码:~1106行
|
||
- 功能验证100%通过
|
||
|
||
---
|
||
|
||
## 🏗️ 技术架构
|
||
|
||
### 技术栈
|
||
|
||
#### 前端
|
||
```
|
||
框架: React 19 + TypeScript 5
|
||
路由: React Router DOM v6
|
||
状态管理: @tanstack/react-query (React Query v5)
|
||
UI组件: Ant Design v5
|
||
样式: TailwindCSS v3
|
||
构建工具: Vite v5
|
||
|
||
⚠️ 状态:仅有Placeholder,无真实代码
|
||
```
|
||
|
||
#### 后端
|
||
```
|
||
框架: Fastify v4 (Node.js 22)
|
||
数据库: PostgreSQL 16 + Prisma 6
|
||
LLM SDK: 自研 LLMFactory (统一适配层)
|
||
模型: DeepSeek-V3, Qwen-Max
|
||
日志: Winston
|
||
Excel处理: xlsx 库(内存模式)
|
||
并发控制: p-limit(限制LLM并发数)
|
||
|
||
✅ 状态:代码已重建,100%功能恢复
|
||
```
|
||
|
||
#### 基础设施(云原生 + 🏆 Postgres-Only 架构)
|
||
```
|
||
数据库: PostgreSQL 16 with Schema isolation
|
||
Schema: dc_schema (独立隔离)
|
||
存储: storage服务(OSS ↔ LocalFS)
|
||
|
||
🏆 Postgres-Only 架构(2025-12-13 改造完成):
|
||
├── 统一缓存: platform_schema.app_cache (PostgresCacheAdapter)
|
||
├── 统一队列: platform_schema.job (PgBossQueue, pg-boss)
|
||
├── 任务管理: job.data 统一存储(不在业务表中)
|
||
└── 断点续传: CheckpointService (操作 job.data,通用)
|
||
|
||
日志: logger服务(Winston结构化)
|
||
|
||
✅ 状态:100%复用平台基础设施
|
||
✅ 架构:Platform-Only 模式,与 ASL 统一
|
||
```
|
||
|
||
#### 🏆 Postgres-Only 架构亮点(Tool B)
|
||
|
||
**智能双模式处理:**
|
||
```typescript
|
||
const QUEUE_THRESHOLD = 50;
|
||
|
||
if (records.length >= 50) {
|
||
// 队列模式:可靠性优先
|
||
- 任务拆分(50条/批)
|
||
- 断点续传(每10条保存)
|
||
- 支持长时间提取(2-24小时)
|
||
- 实例重启可恢复
|
||
} else {
|
||
// 直接模式:性能优先
|
||
- 快速响应(<1分钟)
|
||
- 无队列延迟
|
||
}
|
||
```
|
||
|
||
**核心组件:**
|
||
- `ExtractionController.ts`:智能阈值判断,推送批次任务
|
||
- `extractionWorker.ts`:批次处理,断点续传
|
||
- `CheckpointService`:操作 job.data(与 ASL 共用)
|
||
|
||
**技术优势:**
|
||
- ✅ 零额外成本(无需 Redis)
|
||
- ✅ 统一架构(与 ASL 一致)
|
||
- ✅ 高可靠性(自动重试、断点续传)
|
||
- ✅ 易扩展(未来模块直接复用)
|
||
|
||
---
|
||
|
||
## 📂 真实代码结构
|
||
|
||
### 前端代码结构
|
||
|
||
```
|
||
frontend-v2/src/modules/dc/
|
||
├── index.tsx # ❌ 仅Placeholder,无真实功能
|
||
├── components/ # 📁 空文件夹
|
||
├── pages/ # 📁 空文件夹结构
|
||
│ ├── tool-a/ # 📁 空
|
||
│ ├── tool-b/ # 📁 空(应实现V4原型)
|
||
│ └── tool-c/ # 📁 空
|
||
└── types/ # 📁 空文件夹
|
||
|
||
⚠️ 真实状态:前端完全未开发,只有占位符
|
||
```
|
||
|
||
**前端待实现功能**(基于V4原型设计):
|
||
1. **Step 1**:文件上传与列选择
|
||
2. **Step 2**:Schema映射(疾病类型、报告类型、目标字段)
|
||
3. **Step 3**:处理进度监控(实时进度、并发任务显示)
|
||
4. **Step 4**:冲突验证工作台(双模型对比、上下文显示)
|
||
5. **Step 5**:结果导出(Excel下载)
|
||
|
||
### 后端代码结构
|
||
|
||
```
|
||
backend/src/modules/dc/
|
||
├── index.ts # ✅ 模块入口(117行)
|
||
│ ├── registerDCRoutes() # 路由注册函数
|
||
│ └── initDCModule() # 初始化函数(含数据库检查)
|
||
├── tool-b/ # ✅ 工具B:病历结构化机器人
|
||
│ ├── services/ # ✅ 服务层(4个核心服务)
|
||
│ │ ├── HealthCheckService.ts # ✅ 190行 - Excel健康检查
|
||
│ │ ├── TemplateService.ts # ✅ 243行 - 预设模板管理
|
||
│ │ ├── DualModelExtractionService.ts # ✅ 390行 - 双模型提取
|
||
│ │ └── ConflictDetectionService.ts # ✅ 215行 - 冲突检测算法
|
||
│ ├── controllers/ # ✅ 控制器层
|
||
│ │ └── ExtractionController.ts # ✅ 388行 - 6个API端点
|
||
│ ├── routes/ # ✅ 路由层
|
||
│ │ └── index.ts # ✅ 115行 - 路由配置
|
||
│ ├── utils/ # 📁 空(预留)
|
||
│ └── workers/ # 📁 空(预留异步任务)
|
||
├── tool-a/ # 📁 空(未开发)
|
||
├── tool-c/ # 📁 空(未开发)
|
||
├── portal/ # 📁 空(未开发)
|
||
└── shared/ # 📁 空(预留共享代码)
|
||
|
||
✅ 真实状态:Tool B后端代码完整,共计 1,658 行
|
||
```
|
||
|
||
**后端代码统计**(重建完成):
|
||
- **总文件数**:7个TypeScript文件
|
||
- **总代码量**:约1,658行(不含注释和空行)
|
||
- **服务层**:4个服务,1,038行
|
||
- **控制器层**:1个控制器,388行
|
||
- **路由层**:1个路由文件,115行
|
||
- **模块入口**:1个index.ts,117行
|
||
|
||
---
|
||
|
||
## 🗄️ 数据库设计
|
||
|
||
### Schema隔离
|
||
|
||
```sql
|
||
-- DC模块独立Schema
|
||
dc_schema (独立隔离,包含4个表)
|
||
```
|
||
|
||
### 数据表设计
|
||
|
||
#### 1. dc_health_checks(健康检查记录)
|
||
```prisma
|
||
model DcHealthCheck {
|
||
id String @id @default(uuid())
|
||
userId String
|
||
fileName String
|
||
columnName String
|
||
emptyRate Float // 空值率
|
||
avgLength Float // 平均长度
|
||
totalRows Int // 总行数
|
||
estimatedTokens Int // 估算Token消耗
|
||
status String // pass | warning | rejected
|
||
message String // 拦截原因
|
||
createdAt DateTime @default(now())
|
||
|
||
@@schema("dc_schema")
|
||
@@map("dc_health_checks")
|
||
}
|
||
```
|
||
|
||
#### 2. dc_templates(预设模板)
|
||
```prisma
|
||
model DcTemplate {
|
||
id String @id @default(uuid())
|
||
diseaseType String // 疾病类型(lung_cancer, diabetes, hypertension)
|
||
reportType String // 报告类型(pathology, admission, outpatient)
|
||
displayName String // 显示名称
|
||
fields Json // 目标字段定义
|
||
promptTemplate String // Prompt模板
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
|
||
@@unique([diseaseType, reportType])
|
||
@@schema("dc_schema")
|
||
@@map("dc_templates")
|
||
}
|
||
```
|
||
|
||
#### 3. dc_extraction_tasks(提取任务)
|
||
```prisma
|
||
model DcExtractionTask {
|
||
id String @id @default(uuid())
|
||
userId String
|
||
projectName String
|
||
sourceFileKey String // OSS存储路径
|
||
textColumn String // 待提取列名
|
||
diseaseType String
|
||
reportType String
|
||
targetFields Json // 目标字段
|
||
modelA String @default("deepseek-v3")
|
||
modelB String @default("qwen3-72b")
|
||
status String @default("pending")
|
||
totalCount Int @default(0)
|
||
processedCount Int @default(0)
|
||
cleanCount Int @default(0) // 无冲突
|
||
conflictCount Int @default(0) // 有冲突
|
||
failedCount Int @default(0)
|
||
totalTokens Int @default(0)
|
||
totalCost Float @default(0)
|
||
error String?
|
||
createdAt DateTime @default(now())
|
||
startedAt DateTime?
|
||
completedAt DateTime?
|
||
|
||
items DcExtractionItem[]
|
||
|
||
@@schema("dc_schema")
|
||
@@map("dc_extraction_tasks")
|
||
}
|
||
```
|
||
|
||
#### 4. dc_extraction_items(提取明细)
|
||
```prisma
|
||
model DcExtractionItem {
|
||
id String @id @default(uuid())
|
||
taskId String
|
||
rowIndex Int // Excel行号
|
||
originalText String @db.Text
|
||
resultA Json? // DeepSeek结果
|
||
resultB Json? // Qwen结果
|
||
status String @default("pending")
|
||
conflictFields String[] @default([]) // 冲突字段列表
|
||
finalResult Json? // 最终结果
|
||
tokensA Int @default(0)
|
||
tokensB Int @default(0)
|
||
error String?
|
||
createdAt DateTime @default(now())
|
||
resolvedAt DateTime?
|
||
|
||
task DcExtractionTask @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
||
|
||
@@schema("dc_schema")
|
||
@@map("dc_extraction_items")
|
||
}
|
||
```
|
||
|
||
### 数据库状态
|
||
|
||
✅ **已验证完成(2025-12-02)**
|
||
|
||
**验证结果**:
|
||
- ✅ **dc_schema**: 已存在
|
||
- ✅ **dc_health_checks**: 已创建(2条记录)
|
||
- ✅ **dc_templates**: 已创建(**3条预设模板**)
|
||
- ✅ **dc_extraction_tasks**: 已创建(1条记录)
|
||
- ✅ **dc_extraction_items**: 已创建(4条记录)
|
||
|
||
**预设模板列表**:
|
||
1. 肺癌病理报告 (lung_cancer/pathology)
|
||
2. 糖尿病入院记录 (diabetes/admission)
|
||
3. 高血压门诊病历 (hypertension/outpatient)
|
||
|
||
**验证脚本**:
|
||
```bash
|
||
# 检查数据库表状态
|
||
cd backend
|
||
node scripts/check-dc-tables.mjs
|
||
```
|
||
|
||
**结论**:✅ 数据库完全准备就绪,后端API应该可以直接使用!
|
||
|
||
---
|
||
|
||
## 🔌 API接口
|
||
|
||
### 路由前缀
|
||
```
|
||
/api/v1/dc/tool-b
|
||
```
|
||
|
||
### 已实现API(6个端点)
|
||
|
||
#### 1. 健康检查
|
||
```typescript
|
||
POST /health-check
|
||
Content-Type: multipart/form-data
|
||
|
||
Body:
|
||
- file: Excel文件
|
||
- columnName: 待检查列名
|
||
|
||
Response: {
|
||
status: 'pass' | 'warning' | 'rejected',
|
||
emptyRate: number,
|
||
avgLength: number,
|
||
totalRows: number,
|
||
estimatedTokens: number,
|
||
message: string
|
||
}
|
||
```
|
||
|
||
#### 2. 获取所有模板
|
||
```typescript
|
||
GET /templates
|
||
|
||
Response: {
|
||
templates: Array<{
|
||
id: string,
|
||
diseaseType: string,
|
||
reportType: string,
|
||
displayName: string,
|
||
fields: object
|
||
}>
|
||
}
|
||
```
|
||
|
||
#### 3. 创建提取任务
|
||
```typescript
|
||
POST /tasks
|
||
Content-Type: multipart/form-data
|
||
|
||
Body:
|
||
- file: Excel文件
|
||
- projectName: 项目名称
|
||
- textColumn: 文本列名
|
||
- diseaseType: 疾病类型
|
||
- reportType: 报告类型
|
||
- targetFields: JSON字符串
|
||
|
||
Response: {
|
||
taskId: string,
|
||
status: 'pending',
|
||
message: '任务创建成功'
|
||
}
|
||
```
|
||
|
||
#### 4. 查询任务进度
|
||
```typescript
|
||
GET /tasks/:taskId/progress
|
||
|
||
Response: {
|
||
taskId: string,
|
||
status: 'pending' | 'processing' | 'completed' | 'failed',
|
||
totalCount: number,
|
||
processedCount: number,
|
||
cleanCount: number,
|
||
conflictCount: number,
|
||
failedCount: number,
|
||
totalTokens: number,
|
||
totalCost: number,
|
||
progress: number, // 百分比
|
||
error?: string
|
||
}
|
||
```
|
||
|
||
#### 5. 获取任务明细
|
||
```typescript
|
||
GET /tasks/:taskId/items?status=conflict
|
||
|
||
Query:
|
||
- status: 'conflict' | 'clean' | 'failed' | 'all'
|
||
- page: number (default: 1)
|
||
- pageSize: number (default: 20)
|
||
|
||
Response: {
|
||
items: Array<{
|
||
id: string,
|
||
rowIndex: number,
|
||
originalText: string,
|
||
resultA: object,
|
||
resultB: object,
|
||
conflictFields: string[],
|
||
finalResult?: object,
|
||
status: string
|
||
}>,
|
||
pagination: {
|
||
total: number,
|
||
page: number,
|
||
pageSize: number,
|
||
totalPages: number
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 6. 解决冲突
|
||
```typescript
|
||
POST /items/:itemId/resolve
|
||
|
||
Body: {
|
||
resolvedData: object // 用户确认的最终结果
|
||
}
|
||
|
||
Response: {
|
||
success: true,
|
||
itemId: string,
|
||
finalResult: object
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🎨 前端UI设计
|
||
|
||
### V4原型设计
|
||
|
||
**文件位置**:
|
||
- `docs/03-业务模块/DC-数据清洗整理/03-UI设计/工具B_病历结构化机器人_原型设计_V4.tsx`
|
||
|
||
**5个Step流程**:
|
||
|
||
#### Step 1:上传与Schema
|
||
```
|
||
- Excel文件上传(拖拽或选择)
|
||
- 自动检测列名
|
||
- 选择文本列(待提取)
|
||
```
|
||
|
||
#### Step 2:配置映射
|
||
```
|
||
- 选择疾病类型(肺癌、糖尿病、高血压)
|
||
- 选择报告类型(病理、入院、门诊)
|
||
- 自动加载预设模板
|
||
- 显示目标字段(可调整)
|
||
```
|
||
|
||
#### Step 3:处理进度
|
||
```
|
||
- 实时进度条
|
||
- 当前处理行号
|
||
- Token消耗统计
|
||
- 成本预估
|
||
- 并发任务显示(DeepSeek + Qwen同时运行)
|
||
```
|
||
|
||
#### Step 4:冲突验证
|
||
```
|
||
- 冲突列表(表格显示)
|
||
- 双模型结果对比(左右分栏)
|
||
- 原文上下文显示
|
||
- 冲突字段高亮
|
||
- 快速确认按钮
|
||
```
|
||
|
||
#### Step 5:结果导出
|
||
```
|
||
- 统计概览(总数、无冲突、已解决、失败)
|
||
- Excel导出按钮
|
||
- 4个Sheet:
|
||
1. 完整结果
|
||
2. 无冲突项
|
||
3. 冲突项(已解决)
|
||
4. 失败项
|
||
```
|
||
|
||
**⚠️ 状态:设计完成,代码未实现**
|
||
|
||
---
|
||
|
||
## 🔧 技术实现细节
|
||
|
||
### 1. 健康检查机制
|
||
|
||
**实现位置**:`HealthCheckService.ts`(190行)
|
||
|
||
**核心功能**:
|
||
- Excel内存解析(xlsx库,无需落盘)
|
||
- 空值率计算(拦截 >50%)
|
||
- 平均文本长度计算
|
||
- Token消耗估算(基于平均长度 × 4 × 行数)
|
||
- 拦截策略:
|
||
- 空值率 >50%:❌ rejected
|
||
- 空值率 30-50%:⚠️ warning
|
||
- 空值率 <30%:✅ pass
|
||
|
||
**云原生特性**:
|
||
- ✅ 复用`storage.getFileBuffer()`(OSS存储)
|
||
- ✅ 复用`cache.set()`(结果缓存1小时)
|
||
- ✅ 内存处理(零落盘)
|
||
|
||
### 2. 双模型提取
|
||
|
||
**实现位置**:`DualModelExtractionService.ts`(390行)
|
||
|
||
**核心功能**:
|
||
- 并发调用DeepSeek-V3和Qwen-Max
|
||
- PII脱敏(姓名、身份证号)
|
||
- 3层JSON解析(容错机制):
|
||
1. 标准JSON解析
|
||
2. 去除Markdown代码块后解析
|
||
3. 正则提取JSON对象
|
||
- 重试机制(最多3次)
|
||
- Token统计与成本计算
|
||
|
||
**云原生特性**:
|
||
- ✅ 复用`LLMFactory.getLLM()`
|
||
- ✅ 复用`jobQueue.add()`(异步任务)
|
||
- ✅ 复用`logger.info()`(结构化日志)
|
||
|
||
### 3. 冲突检测算法
|
||
|
||
**实现位置**:`ConflictDetectionService.ts`(215行)
|
||
|
||
**核心功能**:
|
||
- 字段级对比(逐字段比较DeepSeek和Qwen结果)
|
||
- 值归一化(去除空格、统一大小写)
|
||
- 数值容差(相对误差 <5%视为一致)
|
||
- 语义相似度(预留接口,可接入embedding)
|
||
- 冲突字段列表生成
|
||
|
||
**状态判断**:
|
||
```typescript
|
||
if (conflictFields.length === 0) {
|
||
status = 'clean' // 无冲突,自动通过
|
||
} else {
|
||
status = 'conflict' // 有冲突,需人工确认
|
||
}
|
||
```
|
||
|
||
### 4. 模板管理
|
||
|
||
**实现位置**:`TemplateService.ts`(243行)
|
||
|
||
**预设模板**(3个):
|
||
1. **肺癌病理报告**(lung_cancer/pathology)
|
||
- 14个字段:肿瘤类型、分期、基因突变等
|
||
2. **糖尿病入院记录**(diabetes/admission)
|
||
- 12个字段:血糖、糖化血红蛋白、并发症等
|
||
3. **高血压门诊记录**(hypertension/outpatient)
|
||
- 10个字段:血压、心率、用药等
|
||
|
||
**Prompt模板**:
|
||
```
|
||
你是一个专业的医学信息提取助手。请从以下病历文本中提取关键信息...
|
||
|
||
疾病类型:{diseaseType}
|
||
报告类型:{reportType}
|
||
目标字段:{fields}
|
||
|
||
病历原文:
|
||
{originalText}
|
||
|
||
请严格按照JSON格式输出...
|
||
```
|
||
|
||
---
|
||
|
||
## ✅ 已解决的问题
|
||
|
||
### 1. 数据库表状态验证 ✅ 已完成(2025-12-02)
|
||
|
||
**问题描述**:
|
||
- 代码丢失后无法确认数据库表是否存在
|
||
- 迁移文件丢失(`migration.sql`为空)
|
||
|
||
**解决方案**:
|
||
- ✅ 创建了数据库检查脚本 `backend/scripts/check-dc-tables.mjs`
|
||
- ✅ 验证确认所有表已创建
|
||
- ✅ 验证确认预设模板已初始化
|
||
|
||
**验证结果**:
|
||
- ✅ dc_schema存在
|
||
- ✅ 4个表全部存在
|
||
- ✅ 3个预设模板已初始化
|
||
- ✅ 有测试数据可用
|
||
|
||
**结论**:数据库完全准备就绪,可以直接使用!
|
||
|
||
---
|
||
|
||
## ⚠️ 当前存在的问题
|
||
|
||
### 2. 前端完全未开发 🔴 高优先级
|
||
|
||
**问题描述**:
|
||
- 只有Placeholder占位符
|
||
- V4原型设计已完成,但无任何实现代码
|
||
|
||
**影响**:
|
||
- ❌ 无法进行完整的端到端测试
|
||
- ❌ 无法演示给用户
|
||
|
||
**工作量估算**:
|
||
- Step 1(上传与Schema):4小时
|
||
- Step 2(配置映射):3小时
|
||
- Step 3(处理进度):3小时
|
||
- Step 4(冲突验证):6小时(最复杂)
|
||
- Step 5(结果导出):2小时
|
||
- **总计**:18小时(约2-3天)
|
||
|
||
**优先级**:🔴 高(阻塞完整功能)
|
||
|
||
---
|
||
|
||
### 3. 后端未经真实测试 🟡 中优先级
|
||
|
||
**问题描述**:
|
||
- 代码是基于设计文档重建的
|
||
- 没有运行过真实的API测试
|
||
- 没有验证过LLM调用是否正常
|
||
|
||
**风险**:
|
||
- ⚠️ 可能存在未发现的bug
|
||
- ⚠️ 实际LLM提取效果未验证
|
||
|
||
**解决方案**:
|
||
1. 先执行`npx prisma db push`创建表
|
||
2. 启动后端:`npm run dev`
|
||
3. 使用REST Client测试6个API端点
|
||
4. 上传真实Excel文件测试提取效果
|
||
|
||
**优先级**:🟡 中(前端开发前应完成)
|
||
|
||
---
|
||
|
||
### 4. Cursor终端输出问题 🟢 低优先级
|
||
|
||
**问题描述**:
|
||
- PowerShell终端无法正常显示命令输出
|
||
- 导致无法运行数据库检查脚本
|
||
- 浪费了大量时间尝试不同方法
|
||
|
||
**影响**:
|
||
- ⚠️ 开发调试不便
|
||
- ⚠️ 无法实时查看日志
|
||
|
||
**临时解决方案**:
|
||
- 使用外部PowerShell或CMD窗口
|
||
- 使用Prisma Studio可视化工具
|
||
- 直接启动后端查看启动日志
|
||
|
||
**优先级**:🟢 低(有替代方案)
|
||
|
||
---
|
||
|
||
## 📝 下一步开发计划
|
||
|
||
### 立即需要做的(紧急)
|
||
|
||
1. **验证数据库表** 🔴
|
||
```bash
|
||
cd backend
|
||
npx prisma db push
|
||
npx prisma studio # 可视化确认
|
||
```
|
||
|
||
2. **后端API测试** 🔴
|
||
- 启动后端服务
|
||
- 测试6个API端点
|
||
- 验证LLM调用
|
||
- 确认双模型提取逻辑
|
||
|
||
3. **Git再次提交** 🔴
|
||
- 确保所有代码已提交
|
||
- 推送到远程仓库(如果有)
|
||
|
||
### 短期开发任务(本周)
|
||
|
||
4. **前端UI开发** 🔴(预计2-3天)
|
||
- 基于V4原型实现5个Step
|
||
- 参考ASL模块的前端代码结构
|
||
- 使用React Query管理API调用
|
||
- 使用Ant Design组件
|
||
|
||
5. **端到端测试** 🟡
|
||
- 真实Excel文件测试
|
||
- 冲突解决流程测试
|
||
- 导出功能测试
|
||
|
||
### 中期优化任务(下周)
|
||
|
||
6. **性能优化** 🟡
|
||
- 添加并发控制(p-limit)
|
||
- 优化Excel大文件处理
|
||
- 添加进度实时推送(WebSocket)
|
||
|
||
7. **错误处理优化** 🟡
|
||
- 完善错误提示
|
||
- 添加重试机制
|
||
- 失败任务恢复
|
||
|
||
---
|
||
|
||
## 📚 相关文档
|
||
|
||
### 设计文档
|
||
- [PRD需求文档](./01-需求分析/)
|
||
- [技术设计文档](./02-技术设计/技术设计文档:工具 B - 病历结构化机器人 (The AI Structurer).md)
|
||
- [数据库设计文档](./02-技术设计/数据库设计文档-DC模块(完整版).md)
|
||
- [API设计文档](./02-技术设计/API设计文档-DC模块(完整版).md)
|
||
- [UI原型设计](./03-UI设计/工具B_病历结构化机器人_原型设计_V4.tsx)
|
||
|
||
### 开发记录
|
||
- [Day2完成总结](./06-开发记录/Day2完成总结.md)(丢失前)
|
||
- [Day3完成总结](./06-开发记录/Day3完成总结.md)(丢失前)
|
||
- [DC模块重建完成总结](./06-开发记录/DC模块重建完成总结-Day1.md)(重建后)
|
||
|
||
### 规范文档
|
||
- [云原生开发规范](../../04-开发规范/08-云原生开发规范.md)
|
||
- [Git提交规范](../../04-开发规范/06-Git提交规范.md)(已更新,强制每日提交)
|
||
|
||
---
|
||
|
||
## 🎓 给新开发者的提示
|
||
|
||
### 快速上手
|
||
|
||
1. **了解代码丢失事件**
|
||
- 阅读本文档的"重要事件记录"部分
|
||
- 理解为什么要每日Git提交
|
||
|
||
2. **熟悉后端代码**
|
||
- 先看`backend/src/modules/dc/index.ts`了解模块结构
|
||
- 阅读4个Service的代码注释
|
||
- 运行Prisma Studio查看数据库表
|
||
|
||
3. **理解云原生架构**
|
||
- 阅读`云原生开发规范`
|
||
- 了解如何复用平台基础设施
|
||
- **禁止**:本地文件存储、内存缓存、硬编码配置
|
||
|
||
4. **参考ASL模块**
|
||
- DC模块前端应类似ASL模块的前端结构
|
||
- 复用ASL的Hooks、组件和工具函数
|
||
- 保持一致的代码风格
|
||
|
||
### 常见陷阱
|
||
|
||
❌ **不要这样做**:
|
||
1. 本地开发时直接写`fs.writeFileSync()`(违反云原生规范)
|
||
2. 使用全局变量缓存数据(Serverless环境不可靠)
|
||
3. 忘记每日Git提交(代码可能丢失)
|
||
4. 在Cursor终端运行复杂脚本(输出问题)
|
||
|
||
✅ **应该这样做**:
|
||
1. 使用`storage.uploadBuffer()`存储文件
|
||
2. 使用`cache.set()`缓存数据
|
||
3. **每天下班前必须Git提交**
|
||
4. 复杂脚本在外部PowerShell运行
|
||
|
||
---
|
||
|
||
## 📊 模块统计
|
||
|
||
### 代码量统计(当前)
|
||
```
|
||
后端代码(已完成):
|
||
- TypeScript文件:7个
|
||
- 总行数:约1,658行
|
||
- 服务层:4个服务,1,038行
|
||
- 控制器层:388行
|
||
- 路由层:115行
|
||
|
||
前端代码(未开发):
|
||
- TypeScript/TSX文件:1个(Placeholder)
|
||
- 总行数:14行
|
||
- 真实功能:0%
|
||
|
||
数据库:
|
||
- 表数量:4个(Prisma Schema已定义)
|
||
- 实际创建:⚠️ 未确认
|
||
```
|
||
|
||
### 开发进度
|
||
```
|
||
整体进度:约35%
|
||
|
||
- Tool B后端:100% ✅
|
||
- Tool B前端:0% ❌
|
||
- Tool A:0% ❌
|
||
- Tool C:0% ❌
|
||
- Portal:0% ❌
|
||
```
|
||
|
||
---
|
||
|
||
## 🤝 致谢
|
||
|
||
感谢所有参与DC模块开发的同事,特别是在代码丢失后快速重建的努力。
|
||
|
||
**本文档力求真实反映模块状态,包括问题和不足,以便更好地规划后续工作。**
|
||
|
||
---
|
||
|
||
**最后更新:** 2025-12-10
|
||
**文档维护:** DC模块开发团队
|
||
**联系方式:** 项目Issues
|
||
|
||
|
||
|
||
|
||
|