body_part拼接功能调试说明.md 7.7 KB

study_info.body_part 拼接功能调试说明

问题现象

study_info.body_part 字段没有显示为 CHEST+ABDOMEN 这样的拼接格式。


可能的原因和解决方案

原因1:使用了单文件上传接口

症状: 即使上传多个文件,body_part 也只显示单个部位

检查方法: 查看您使用的是哪个上传接口:

  • /api/dicom/upload - 单文件上传(不支持多部位拼接)
  • /api/dicom/batch-upload-advanced - 批量上传(支持多部位拼接)

解决方案: 使用 /api/dicom/batch-upload-advanced 接口上传多个文件。


原因2:所有文件都是同一个部位

症状: 日志显示所有文件解析到相同的部位

示例日志:

INFO - 文件 chest_001.dcm 解析到部位: CHEST
INFO - 文件 chest_002.dcm 解析到部位: CHEST
INFO - 文件 chest_003.dcm 解析到部位: CHEST
INFO - ✅ 最终解析的检查部位: CHEST (来源: 3 个文件,去重后)

原因: 虽然 Set 会自动去重,但如果所有文件的部位都相同,最终结果就是单个部位。

解决方案: 确保上传的文件包含不同部位的DICOM文件。


原因3:DICOM文件的 body_part_examined 字段为空

症状: 日志显示 "body_part_examined 为空或null"

示例日志:

WARN - 文件 image_001.dcm 的 body_part_examined 为空或null
WARN - ⚠️ 未能从文件中解析到部位,使用第一个文件的值: null

原因: DICOM 文件本身没有 BodyPartExamined 标签,或者该标签为空。

解决方案: 检查DICOM文件是否包含 BodyPartExamined (0018,0015) 标签。


原因4:代码未重新编译或应用未重启

症状: 修改了代码但行为没有改变

解决方案:

# 1. 重新编译
mvn clean compile

# 2. 重启应用
mvn spring-boot:run

# 或者如果在IDE中,点击停止后重新运行

详细诊断步骤

第1步:确认使用的上传接口

方法A:查看前端代码

// 确认使用的是哪个接口
axios.post('/api/dicom/batch-upload-advanced', formData)  // ✅ 正确
// 或
axios.post('/api/dicom/upload', formData)  // ❌ 单文件上传

方法B:查看后端日志 上传时应该看到以下日志:

INFO - 处理study: studyInstanceUid=1.2.3..., 文件数=5

如果只看到 上传DICOM文件 而没有 处理study,说明用的是单文件上传接口。


第2步:查看详细的解析日志

重启应用后上传文件,应该看到以下日志:

✅ 正确的日志(多部位)

INFO - 处理study: studyInstanceUid=1.2.3..., 文件数=3

INFO - 文件 chest_001.dcm 解析到部位: CHEST
INFO - 文件 chest_001.dcm 匹配到检查项目: 胸部CT

INFO - 文件 abdomen_001.dcm 解析到部位: ABDOMEN
INFO - 文件 abdomen_001.dcm 匹配到检查项目: 腹部CT

INFO - 文件 pelvis_001.dcm 解析到部位: PELVIS
INFO - 文件 pelvis_001.dcm 匹配到检查项目: 盆部CT

INFO - ✅ 最终解析的检查部位: CHEST+ABDOMEN+PELVIS (来源: 3 个文件,去重后)
INFO -    部位列表: [CHEST, ABDOMEN, PELVIS]
INFO - 💾 保存到 study_info.body_part: CHEST+ABDOMEN+PELVIS

INFO - 创建study记录: studyId=STY001, studyInstanceUid=1.2.3...

❌ 错误的日志1(单部位)

INFO - 处理study: studyInstanceUid=1.2.3..., 文件数=3

INFO - 文件 chest_001.dcm 解析到部位: CHEST
INFO - 文件 chest_002.dcm 解析到部位: CHEST
INFO - 文件 chest_003.dcm 解析到部位: CHEST

INFO - ✅ 最终解析的检查部位: CHEST (来源: 3 个文件,去重后)
INFO -    部位列表: [CHEST]
INFO - 💾 保存到 study_info.body_part: CHEST

原因: 所有文件都是同一个部位,自动去重后只剩一个。

❌ 错误的日志2(部位为空)

INFO - 处理study: studyInstanceUid=1.2.3..., 文件数=3

WARN - 文件 image_001.dcm 的 body_part_examined 为空或null
WARN - 文件 image_002.dcm 的 body_part_examined 为空或null
WARN - 文件 image_003.dcm 的 body_part_examined 为空或null

WARN - ⚠️ 未能从文件中解析到部位,使用第一个文件的值: null
INFO - 💾 保存到 study_info.body_part: null

原因: DICOM文件的 BodyPartExamined 标签为空。


第3步:验证数据库保存的值

SELECT
    study_id,
    body_part,
    exam_item_name,
    image_count,
    create_time
FROM study_info
ORDER BY create_time DESC
LIMIT 5;

预期结果: | study_id | body_part | exam_item_name | |----------|-----------|----------------| | STY001 | CHEST+ABDOMEN+PELVIS | 胸部CT+腹部CT+盆部CT | | STY002 | CHEST | 胸部CT |


第4步:验证 series_info 表

SELECT
    instance_number,
    body_part_examined,
    exam_item_name,
    scan_method
FROM series_info
WHERE study_id = 'STY001'
ORDER BY instance_number;

预期结果: | instance_number | body_part_examined | exam_item_name | |-----------------|-------------------|----------------| | 1 | CHEST | 胸部CT | | 2 | CHEST | 胸部CT | | 3 | ABDOMEN | 腹部CT | | 4 | ABDOMEN | 腹部CT | | 5 | PELVIS | 盆部CT |


测试用例

测试1:多部位文件(应该拼接)

操作: 上传包含胸部、腹部、盆部的多个DICOM文件

预期结果:

study_info.body_part = CHEST+ABDOMEN+PELVIS
study_info.exam_item_name = 胸部CT+腹部CT+盆部CT

验证日志:

INFO - ✅ 最终解析的检查部位: CHEST+ABDOMEN+PELVIS (来源: 3 个文件,去重后)

测试2:单部位多文件(自动去重)

操作: 上传3个胸部CT的不同切片文件

预期结果:

study_info.body_part = CHEST  // 虽然有3个文件,但部位相同,去重后只剩一个
study_info.exam_item_name = 胸部CT

验证日志:

INFO - ✅ 最终解析的检查部位: CHEST (来源: 3 个文件,去重后)
INFO -    部位列表: [CHEST]

测试3:使用 batch-upload-advanced 接口

curl 命令:

curl -X POST "http://localhost:8080/api/dicom/batch-upload-advanced?institutionId=INST001" \
  -F "files=@chest.dcm" \
  -F "files=@abdomen.dcm" \
  -F "files=@pelvis.dcm"

预期响应:

{
  "batchId": "batch_123",
  "totalFiles": 3,
  "studyCount": 1,
  "studies": [{
    "studyId": "STY001",
    "studyInstanceUid": "1.2.3...",
    "bodyPart": "CHEST+ABDOMEN+PELVIS",  // ✅ 应该是拼接的
    "fileCount": 3
  }]
}

常见问题

Q1: 为什么我的 body_part 没有拼接?

A: 可能的原因:

  1. 使用的是单文件上传接口(/api/dicom/upload
  2. 所有文件的部位都相同(自动去重)
  3. DICOM文件的 BodyPartExamined 标签为空
  4. 代码没有重新编译或应用没有重启

Q2: 如何确认拼接功能是否生效?

A: 查看日志,应该看到:

INFO - ✅ 最终解析的检查部位: CHEST+ABDOMEN (来源: 2 个文件,去重后)
INFO -    部位列表: [CHEST, ABDOMEN]
INFO - 💾 保存到 study_info.body_part: CHEST+ABDOMEN

Q3: 使用哪个上传接口?

A:

  • 单个文件: 使用 /api/dicom/upload/api/dicom/batch-upload
  • 多个文件(推荐): 使用 /api/dicom/batch-upload-advanced,支持多部位拼接

总结

  1. ✅ 代码已经添加了多部位拼接功能
  2. ✅ 使用 LinkedHashSet 自动去重
  3. ✅ 使用 "+" 连接多个部位
  4. ✅ 添加了详细的日志输出
  5. ⚠️ 必须使用 /api/dicom/batch-upload-advanced 接口上传多个文件
  6. ⚠️ 必须重启应用使修改生效

按照上述步骤操作后,应该能看到拼接后的 body_part 字段了! 🎯