本次重构了影像上传和查询逻辑,主要变更:
series_info 记录代表一张 DICOM 片子(而非整个序列)sop_instance_uid VARCHAR(128) -- SOP实例UID(唯一标识一张片子)
instance_number INT -- 实例号(图像序号)
file_path VARCHAR(512) -- DICOM文件路径
file_size BIGINT -- 文件大小(字节)
scan_method VARCHAR(64) -- 扫描方式(增强、平扫、PA位等)
access_url VARCHAR(512) -- 可调阅URL地址
旧结构:
StudyInfo (检查)
└── SeriesInfo (序列)
└── DicomInstanceInfo (实例/片子)
新结构:
StudyInfo (检查)
└── SeriesInfo (每个记录代表一张片子,按 series_instance_uid 分组)
文件: SeriesInfo.java
新增字段:
sopInstanceUid - SOP实例UIDinstanceNumber - 实例号filePath - 文件路径fileSize - 文件大小scanMethod - 扫描方式accessUrl - 可调阅URL文件: DicomAsyncServiceImpl.java
修改方法: saveSeriesAndInstances()
主要变更:
series_info 记录scan_method)access_url)sop_instance_uid 去重移除方法: saveInstanceInfo() - 不再需要单独的实例表
文件: StudyQueryServiceImpl.java
修改方法:
buildStudyDetail() - 格式化生日,计算总文件大小buildSeriesDetail() → groupAndBuildSeriesDetails() - 按 series_instance_uid 分组buildInstanceDetail() → buildInstanceDetailFromSeriesInfo() - 从 series_info 获取实例信息关键变更:
transactionId 使用 studyInstanceUid(而非随机UUID)series_instance_uid 分组构建序列信息series_info 获取实例信息查询接口:GET /api/dicom/query?study_instance_uid={uid}&institution_id={id}&exam_item_name={name}
返回格式:
{
"transactionId": "1.2.194.0.108707908.20230125120222.110.19999.2228475",
"studies": [
{
"birthday": "19570125",
"size": 289937,
"aes": 0,
"hospitalId": "83000004",
"institution": "石河子市人民医院",
"accessionNum": "0001253352",
"patientAge": "066Y",
"patientId": "CT230125043",
"patientName": "吉春莲",
"patientSex": "F",
"studyDate": "2023-01-25 12:10:06",
"studyTime": "121006.882000",
"studyInstanceUid": "...",
"studyid": "2228475",
"id": "...",
"modality": "CT",
"pregnancy": null,
"partExamined": "PELVIS",
"studyDescribe": "...",
"seriesList": [
{
"modality": "CT",
"seriesuid": "...",
"seriesDescription": "...",
"seriesNumber": 3,
"instances": [
{
"url": "http://localhost:8080/api/dicom/viewer/...",
"imageNumber": 1,
"sopInstanceUid": "..."
}
]
}
]
}
]
}
执行以下SQL文件:
mysql -u root -p qconline < doc/sql/alter_series_info_add_instance_fields.sql
可通过 body_part_examined 字段查询特定部位的片子:
LambdaQueryWrapper<SeriesInfo> query = new LambdaQueryWrapper<>();
query.eq(SeriesInfo::getBodyPartExamined, "CHEST");
可通过 scan_method 字段查询特定扫描方式的片子:
LambdaQueryWrapper<SeriesInfo> query = new LambdaQueryWrapper<>();
query.eq(SeriesInfo::getScanMethod, "增强");
可组合查询特定部位和扫描方式的片子:
LambdaQueryWrapper<SeriesInfo> query = new LambdaQueryWrapper<>();
query.eq(SeriesInfo::getBodyPartExamined, "CHEST");
query.eq(SeriesInfo::getScanMethod, "增强");
sop_instance_uid 添加了索引study_id + sop_instance_uid 添加了联合索引generateAccessUrl() 方法dicom_instance_info 的数据转换为 series_info 记录series_info 记录src/main/java/com/zskk/qconline/modules/entity/SeriesInfo.javasrc/main/java/com/zskk/qconline/modules/dicom/service/impl/DicomAsyncServiceImpl.javasrc/main/java/com/zskk/qconline/modules/dicom/service/impl/StudyQueryServiceImpl.javasrc/main/java/com/zskk/qconline/modules/dicom/vo/ImageInstanceVO.javasrc/main/java/com/zskk/qconline/modules/dicom/vo/SeriesDetailVO.javasrc/main/java/com/zskk/qconline/modules/dicom/vo/StudyDetailVO.javadoc/sql/alter_series_info_add_instance_fields.sqldoc/影像上传和查询功能重构说明.md(本文件)