本模块提供HIS/PACS系统与本系统之间的数据同步接口,用于接收检查申请和DICOM影像数据。
模块位置: /src/main/java/com/zskk/pacsonline/modules/api
接口前缀: /api/sync
POST /api/sync/savePacs| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| applicationFormNo | String | 是 | 检查号/申请单号 | "APP20251213001" |
| clinicId | String | 是 | 机构ID/诊所ID | "12345678" |
| patientName | String | 是 | 患者姓名 | "张三" |
| patientSex | String | 否 | 患者性别 | "男" |
| patientBirthDate | String | 否 | 患者出生日期 | "1990-01-01" |
| patientAge | String | 否 | 患者年龄 | "35" |
| patientId | String | 是 | 患者ID(HIS系统中的患者ID) | "P123456" |
| startDate | String | 否 | 检查开始日期 | "2025-12-13 10:00:00" |
| modality | Integer | 否 | Modality类型(1=US超声, 其他=OP) | 1 |
| contentDescription | String | 否 | 检查内容描述 | "腹部超声检查" |
| department | String | 否 | 科室 | "超声科" |
| clinicalDoctor | String | 否 | 临床医生 | "李医生" |
| symptom | String | 否 | 症状 | "腹痛" |
| patientWeight | String | 否 | 患者体重 | "65kg" |
{
"applicationFormNo": "APP20251213001",
"clinicId": "12345678",
"patientName": "张三",
"patientSex": "男",
"patientBirthDate": "1990-01-01",
"patientAge": "35",
"patientId": "P123456",
"startDate": "2025-12-13 10:00:00",
"modality": 1,
"contentDescription": "腹部超声检查",
"department": "超声科",
"clinicalDoctor": "李医生",
"symptom": "腹痛",
"patientWeight": "65kg"
}
成功响应:
{
"code": 200,
"message": "保存成功",
"data": "{\"code\":\"0\"}"
}
失败响应:
{
"code": 500,
"message": "保存失败: 错误详情",
"data": null
}
去重检查: 检查是否已存在相同的申请单(根据applicationFormNo + clinicId)
创建患者信息: 在patient_infos表中创建患者记录
创建Studies记录: 在studies表中创建检查研究记录
创建Exams记录: 在exams表中创建检查记录
关联更新: 更新studies表的exam_id字段,建立关联关系
{"code":"0"}: 操作成功{"code":"1"}: 操作失败POST /api/sync/saveExam| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| studyId | String | 否 | Study ID | "abc-123-def" |
| studyuid | String | 否 | Study UID | "1.3.6.1.4.1.30071.8.xxx" |
| patientId | String | 否 | 患者ID | "patient-uuid-123" |
| patientNum | String | 否 | 病历号 | "P123456" |
| accessionNum | String | 否 | 检查号 | "APP20251213001" |
| examDatetime | String | 否 | 检查时间 | "2025-12-13 10:00:00" |
| examClass | String | 否 | 检查类别 | "US" |
| institutionId | String | 是 | 机构ID | "12345678" |
| deviceName | String | 否 | 设备名称 | "GE超声设备" |
| bodyPart | String | 否 | 检查部位 | "ABDOMEN" |
| name | String | 否 | 患者姓名 | "张三" |
| phone | String | 否 | 患者手机号 | "13800138000" |
| cardNum | String | 否 | 身份证号 | "110101199001011234" |
| sex | String | 否 | 性别 | "男" |
| age | String | 否 | 年龄 | "35" |
| nodeType | Integer | 否 | 节点类型 | 1 |
| studyid | String | 否 | studyid | "study-123" |
{
"studyId": "abc-123-def",
"studyuid": "1.3.6.1.4.1.30071.8.1702456789",
"patientId": "patient-uuid-123",
"patientNum": "P123456",
"accessionNum": "APP20251213001",
"examDatetime": "2025-12-13 10:30:00",
"examClass": "US",
"institutionId": "12345678",
"deviceName": "GE超声设备",
"bodyPart": "ABDOMEN",
"name": "张三",
"phone": "13800138000",
"cardNum": "110101199001011234",
"sex": "男",
"age": "35",
"nodeType": 1
}
成功响应:
{
"code": 200,
"message": "保存成功",
"data": "exam-uuid-456"
}
失败响应:
{
"code": 500,
"message": "保存失败: 错误详情",
"data": null
}
情况1: 检查记录已存在(根据study_id查询)
情况2: 检查记录不存在
特定机构处理逻辑:
| 状态值 | 说明 |
|---|---|
| -1 | 异常状态 |
| 1 | 登记 |
| 2 | 登记完成 |
| 3 | 影像到达 |
| 7 | 写报告 |
| 8 | 审核报告 |
| 9 | 确认报告 |
位置: ApiServiceImpl.java:99
需求说明: 在savePacs接口中,当接收到临床医生信息时,需要:
实现建议:
// 在ApiServiceImpl中添加方法
private String checkOrCreateDoctor(String doctorName, String institutionId) {
// 1. 根据姓名和机构ID查询医生
// 2. 如果存在,返回医生ID
// 3. 如果不存在,创建医生记录并返回新ID
}
相关表: doctors
原PHP代码参考: XzService.php 96-110行
位置: ApiServiceImpl.java:285
需求说明: 在saveExam接口中,当影像到达时需要自动分配医生:
实现建议:
private String handleQueue(String institutionId) {
// 1. 查询该机构的可用医生列表
// 2. 获取每个医生当前待诊数量
// 3. 按照轮询或负载均衡算法分配
// 4. 返回分配的医生ID
}
涉及字段: exams.doctor_sign
原PHP代码参考: XzService.php 382、444行(调用handle_queue方法)
位置: ApiServiceImpl.java:211, 258
需求说明: 处理电子胶片的费用流水:
实现建议:
private void saveInsFilmWater(String examId, String institutionId) {
// 1. 查询机构胶片配置(charge_mode, film_price)
// 2. 如果charge_mode是医院托管,创建money_water记录
// 3. 更新exam.pay_status = 1
}
相关表:
原PHP代码参考: XzService.php 530-544行
位置: ApiServiceImpl.java:229
需求说明: 将DICOM标准的部位代码转换为中文描述
实现建议:
private String getBodyText(String bodyPartCode) {
// 1. 维护一个部位代码映射表
// 2. 根据代码查询对应的中文描述
// 3. 返回中文文本
}
涉及字段: exams.body_part_text
原PHP代码参考: XzService.php 413-416行
位置: ApiServiceImpl.java:110
需求说明: 保留原PHP项目的检查申请原始数据表
实现建议:
相关表: xz(检查申请表)
原PHP代码参考: XzService.php 41-50, 113-115行
位置: ApiServiceImpl.java:276
需求说明: 当检查影像到达时,发送短信通知患者
实现建议:
private void sendPatientSms(String examId, String phone, String institutionId) {
// 1. 查询机构配置,检查是否开启patient_sms
// 2. 生成随机验证码
// 3. 创建share_exam记录
// 4. 调用短信服务发送通知
}
相关表:
原PHP代码参考: XzService.php 461-491行
位置: ApiServiceImpl.java:279
需求说明: 某些特定机构需要在数据创建后回调其API
实现建议:
private void handleApiCallback(String institutionId, SaveExamVO params, Exams exam) {
// 1. 查询api_config表获取该机构的回调配置
// 2. 根据action类型调用对应的回调方法
// 3. 记录回调结果
}
相关表: api_config(API配置表)
原PHP代码参考: XzService.php 492-506行(包含金盛达、医健康等特定机构的回调)
位置: ApiServiceImpl.java:301
需求说明: 保存检查监控数据用于统计分析
实现建议:
private void saveMonitorExam(SaveExamVO params) {
// 1. 查询机构名称
// 2. 组装监控数据
// 3. 插入monitor_exam表
}
相关表: monitor_exam(监控数据表)
原PHP代码参考: XzService.php 515-527行
以下表在原PHP项目中使用,新系统中可能需要创建:
1. HIS系统开立检查申请
↓
2. HIS调用 POST /api/sync/savePacs
- 创建patient_infos记录
- 创建studies记录
- 创建exams记录(状态=1 登记)
↓
3. 患者到检查设备处检查
↓
4. DICOM设备采集影像完成
↓
5. DICOM系统调用 POST /api/sync/saveExam
- 更新exams记录(状态=3 影像到达)
- 分配医生
- 发送短信通知(如果配置)
↓
6. 医生查看影像并出具报告
事务处理: savePacs和saveExam方法都使用了@Transactional注解,确保数据一致性
UUID生成: 所有ID字段使用UUID生成,格式为去除"-"的32位字符串
日期格式:
yyyy-MM-dd HH:mm:ss2025-12-13 10:00:00字符编码: 所有字符串使用UTF-8编码
去重逻辑: savePacs接口有去重检查,重复调用不会创建重复数据
状态机制: exam_status字段遵循严格的状态流转规则
特定机构逻辑: saveExam方法中包含多个特定机构的数据处理逻辑,后续可考虑抽象为配置
第一阶段 (必须实现):
第二阶段 (推荐实现):
第三阶段 (可选实现):
| 版本 | 日期 | 说明 | 作者 |
|---|---|---|---|
| 1.0.0 | 2025-12-13 | 初始版本,实现核心数据同步功能 | system |
如有问题,请联系开发团队。