# 工伤联网接口数据库设计文档
## 版本信息
| 版本号 | 修改内容 | 修改日期 | 修改人 |
|--------|----------|----------|--------|
| V1.0 | 初始版本设计 | 2024.12.19 | 系统架构师 |
## 目录
- [1 设计概述](#1-设计概述)
- [2 数据库表设计](#2-数据库表设计)
- [3 表关联关系](#3-表关联关系)
- [4 使用案例](#4-使用案例)
- [5 前端示例代码](#5-前端示例代码)
- [6 后端示例代码](#6-后端示例代码)
---
## 1 设计概述
### 1.1 业务需求
1. **工伤病人流程**:先调用工伤接口 → 存储调用记录 → 再调用HIS接口 → 存储HIS数据
2. **非工伤病人流程**:只调用HIS接口 → 存储HIS数据
3. **接口类型支持**:认证类、业务类、体检类、转院类、对账类、下载类
4. **设计原则**:简单、实用、可靠、通用、不为每个接口单独设计
### 1.2 设计思路
采用**3表设计**方案,通过通用化设计支持所有工伤接口类型:
- **工伤接口调用记录表**:记录所有工伤接口的调用情况
- **工伤病人关联信息表**:管理HIS病人与工伤系统的对应关系
- **工伤业务数据记录表**:存储具体的业务数据和结果
---
## 2 数据库表设计
### 2.1 工伤接口调用记录表 (WorkInjury_Interface_Log)
> **作用**:记录每一次工伤接口的调用情况,包括请求参数、响应结果、调用状态等
> **应用场景**:所有工伤接口调用都要记录,用于日志追踪、问题排查、数据分析
```sql
CREATE TABLE WorkInjury_Interface_Log (
-- 主键信息
LogId BIGINT IDENTITY(1,1) PRIMARY KEY,
-- 业务关联信息(用于关联HIS系统的病人和就诊)
HisPatientId VARCHAR(50), -- HIS系统病人ID(病人表主键)
HisVisitNo VARCHAR(50), -- HIS系统就诊流水号/住院号
WorkInjuryTransactionId VARCHAR(50), -- 工伤系统交易流水号
-- 接口调用信息(标识调用的是哪个工伤接口)
InterfaceCode VARCHAR(10) NOT NULL, -- 接口编号:9001签到,2201登记,2207结算等
InterfaceName VARCHAR(100), -- 接口名称:签到,门诊登记,费用结算等
InterfaceCategory VARCHAR(20), -- 接口分类:认证类,业务类,体检类,对账类,下载类
-- 调用参数记录(完整保存调用的入参和返回参数)
RequestData NTEXT, -- 请求参数JSON:调用工伤接口时的完整入参
ResponseData NTEXT, -- 响应参数JSON:工伤接口返回的完整数据
-- 调用结果信息(判断接口调用是否成功)
CallResult BIT NOT NULL DEFAULT 0, -- 调用结果:0失败,1成功
ResultCode VARCHAR(20), -- 结果编码:工伤接口返回的错误码
ResultMessage NVARCHAR(500), -- 结果描述:错误信息或成功提示
-- 工伤系统返回的关键信息(用于后续业务关联)
WorkInjuryMsgId VARCHAR(50), -- 工伤系统报文ID:用于冲正等操作
WorkInjurySignNo VARCHAR(50), -- 工伤系统签到流水号:业务操作必需
WorkInjuryQualificationId VARCHAR(50), -- 工伤资格审核ID:登记时返回的资格ID
-- 时间和操作信息(记录操作过程信息)
CallTime DATETIME NOT NULL DEFAULT GETDATE(), -- 调用时间:接口实际调用的时间
OperatorId VARCHAR(50), -- 操作员ID:谁操作的
OperatorName NVARCHAR(50), -- 操作员姓名:操作员中文名
TerminalId VARCHAR(50), -- 终端ID:哪台机器操作的
-- 扩展字段(用于存储特殊数据)
Remark NVARCHAR(500), -- 备注:额外说明信息
ExtendData NTEXT, -- 扩展数据JSON:特殊业务数据
-- 创建和修改信息
CreateTime DATETIME NOT NULL DEFAULT GETDATE(),
UpdateTime DATETIME NOT NULL DEFAULT GETDATE()
);
-- 创建索引(提高查询性能)
CREATE INDEX IX_WorkInjury_Interface_Log_Patient ON WorkInjury_Interface_Log(HisPatientId, CallTime);
CREATE INDEX IX_WorkInjury_Interface_Log_Visit ON WorkInjury_Interface_Log(HisVisitNo, InterfaceCode);
CREATE INDEX IX_WorkInjury_Interface_Log_Interface ON WorkInjury_Interface_Log(InterfaceCode, CallTime);
CREATE INDEX IX_WorkInjury_Interface_Log_MsgId ON WorkInjury_Interface_Log(WorkInjuryMsgId);
```
### 2.2 工伤病人关联信息表 (WorkInjury_Patient_Relation)
> **作用**:管理HIS系统病人与工伤系统的对应关系,判断病人是否为工伤性质
> **应用场景**:病人登记时判断是否需要调用工伤接口,读卡时建立关联关系
```sql
CREATE TABLE WorkInjury_Patient_Relation (
-- 主键信息
RelationId BIGINT IDENTITY(1,1) PRIMARY KEY,
-- HIS系统病人信息(关联HIS病人表)
HisPatientId VARCHAR(50) NOT NULL, -- HIS系统病人ID:HIS病人表主键
HisCardNo VARCHAR(50), -- HIS病人卡号:院内就诊卡号
HisPatientName NVARCHAR(50), -- HIS病人姓名:在HIS中的姓名
HisIdCard VARCHAR(30), -- HIS身份证号:HIS中的身份证
-- 工伤系统病人信息(来自工伤读卡接口返回数据)
WorkInjuryCardNo VARCHAR(50), -- 工伤社保卡号:工伤系统的卡号
WorkInjuryPsnNo VARCHAR(50), -- 工伤个人唯一识别码:工伤系统病人标识
WorkInjuryPsnName NVARCHAR(50), -- 工伤系统病人姓名:工伤系统中的姓名
WorkInjuryIdCard VARCHAR(30), -- 工伤系统身份证号:可能与HIS不完全一致
WorkInjuryInsuranceArea VARCHAR(20), -- 工伤保险统筹区:如"宿迁市"
-- 工伤资格信息(判断病人工伤性质和资格)
IsWorkInjuryPatient BIT NOT NULL DEFAULT 0, -- 是否工伤病人:0否,1是
WorkInjuryType VARCHAR(20), -- 工伤类型:门诊,住院,体检等
QualificationId VARCHAR(50), -- 工伤医疗费资格审核信息ID
QualificationStatus VARCHAR(20), -- 资格审核状态:有效,过期,暂停等
QualificationExpireDate DATETIME, -- 资格有效期:过期需重新审核
-- 最近读卡信息(记录最新的工伤读卡数据)
LastReadCardTime DATETIME, -- 最后读卡时间:最近一次成功读卡时间
LastReadCardData NTEXT, -- 最后读卡返回数据JSON:完整的读卡结果
-- 状态信息
Status CHAR(1) NOT NULL DEFAULT '1', -- 状态:1有效,0无效,2暂停
-- 扩展字段
Remark NVARCHAR(500), -- 备注:特殊说明
ExtendData NTEXT, -- 扩展数据JSON:其他相关数据
-- 创建和修改信息
CreateTime DATETIME NOT NULL DEFAULT GETDATE(),
UpdateTime DATETIME NOT NULL DEFAULT GETDATE()
);
-- 创建索引和约束
CREATE UNIQUE INDEX IX_WorkInjury_Patient_Relation_HisPatient ON WorkInjury_Patient_Relation(HisPatientId);
CREATE INDEX IX_WorkInjury_Patient_Relation_WorkInjury ON WorkInjury_Patient_Relation(WorkInjuryPsnNo, WorkInjuryCardNo);
CREATE INDEX IX_WorkInjury_Patient_Relation_IdCard ON WorkInjury_Patient_Relation(WorkInjuryIdCard);
```
### 2.3 工伤业务数据记录表 (WorkInjury_Business_Data)
> **作用**:存储具体的工伤业务数据,如登记信息、结算信息、处方明细、体检数据等
> **应用场景**:保存业务办理的详细数据,用于业务查询、数据统计、单据打印等
```sql
CREATE TABLE WorkInjury_Business_Data (
-- 主键信息
BusinessId BIGINT IDENTITY(1,1) PRIMARY KEY,
-- 关联信息(与前两个表关联)
LogId BIGINT, -- 关联接口调用记录表ID:哪次接口调用产生的数据
HisPatientId VARCHAR(50), -- HIS系统病人ID:对应病人表
HisVisitNo VARCHAR(50), -- HIS系统就诊号:门诊号或住院号
-- 业务类型信息(标识业务类型)
BusinessType VARCHAR(20) NOT NULL, -- 业务类型:登记,结算,处方,体检,对账,下载等
BusinessCode VARCHAR(10), -- 业务编码:2201,2207,2204,8104,1320等
BusinessStatus VARCHAR(20), -- 业务状态:成功,失败,撤销,已冲正等
-- 工伤系统业务关键信息(来自工伤接口返回)
WorkInjuryRegisterNo VARCHAR(50), -- 工伤登记流水号:登记成功后返回
WorkInjurySettleNo VARCHAR(50), -- 工伤结算流水号:结算成功后返回
WorkInjuryPreSettleId VARCHAR(50), -- 工伤预结算ID:预结算返回的ID
-- 费用信息(结算相关业务使用)
TotalFee DECIMAL(15,2), -- 总费用:本次业务涉及的总金额
WorkInjuryFee DECIMAL(15,2), -- 工伤基金支付:工伤保险支付金额
PersonalFee DECIMAL(15,2), -- 个人支付:病人自付金额
HospitalFee DECIMAL(15,2), -- 医院垫付:医院需要垫付的金额
-- 业务详细数据(JSON格式存储复杂数据)
BusinessDetailData NTEXT, -- 业务明细数据JSON:处方明细,费用明细,体检项目等
HisBusinessData NTEXT, -- HIS系统业务数据JSON:HIS相关的业务数据
WorkInjuryResponseData NTEXT, -- 工伤接口完整返回JSON:完整的工伤接口返回数据
-- 相关单据信息(用于单据管理)
HisReceiptNo VARCHAR(50), -- HIS发票号:HIS系统生成的发票号
WorkInjuryReceiptNo VARCHAR(50), -- 工伤结算单号:工伤系统的结算单号
HisPrescriptionNo VARCHAR(50), -- HIS处方号:处方相关业务使用
-- 时间信息
BusinessTime DATETIME, -- 业务发生时间:实际业务办理时间
-- 撤销和冲正信息(业务可能需要撤销)
IsReversed BIT DEFAULT 0, -- 是否已冲正:0否,1是
ReversedLogId BIGINT, -- 冲正操作的日志ID:关联到冲正接口调用记录
ReversedTime DATETIME, -- 冲正时间:什么时候冲正的
ReversedReason NVARCHAR(200), -- 冲正原因:为什么要冲正
-- 扩展字段
Remark NVARCHAR(500), -- 备注:业务特殊说明
ExtendData NTEXT, -- 扩展数据JSON:其他业务数据
-- 创建和修改信息
CreateTime DATETIME NOT NULL DEFAULT GETDATE(),
UpdateTime DATETIME NOT NULL DEFAULT GETDATE()
);
-- 创建索引
CREATE INDEX IX_WorkInjury_Business_Data_LogId ON WorkInjury_Business_Data(LogId);
CREATE INDEX IX_WorkInjury_Business_Data_Patient ON WorkInjury_Business_Data(HisPatientId, BusinessTime);
CREATE INDEX IX_WorkInjury_Business_Data_Visit ON WorkInjury_Business_Data(HisVisitNo, BusinessType);
CREATE INDEX IX_WorkInjury_Business_Data_WorkInjury ON WorkInjury_Business_Data(WorkInjuryRegisterNo, WorkInjurySettleNo);
CREATE INDEX IX_WorkInjury_Business_Data_Business ON WorkInjury_Business_Data(BusinessType, BusinessStatus, BusinessTime);
```
---
## 3 表关联关系
### 3.1 表关系图
```
HIS病人表 (His_Patient)
↓ (1:1)
工伤病人关联表 (WorkInjury_Patient_Relation)
↓ (1:N)
工伤接口调用记录表 (WorkInjury_Interface_Log)
↓ (1:N)
工伤业务数据记录表 (WorkInjury_Business_Data)
```
### 3.2 关联说明
1. **HIS病人表 ← → 工伤病人关联表**
- 关联字段:`HisPatientId`
- 关系:一对一,一个HIS病人对应一条工伤关联记录
- 用途:判断病人是否为工伤性质
2. **工伤病人关联表 → 工伤接口调用记录表**
- 关联字段:`HisPatientId`
- 关系:一对多,一个病人可以有多次接口调用
- 用途:追踪病人的所有工伤接口调用历史
3. **工伤接口调用记录表 → 工伤业务数据记录表**
- 关联字段:`LogId`
- 关系:一对多,一次接口调用可能产生多条业务数据
- 用途:存储接口调用产生的具体业务数据
### 3.3 数据流向
```
病人挂号/就诊
↓
判断是否工伤病人 (查询WorkInjury_Patient_Relation)
↓ (是工伤)
调用工伤接口 → 记录到WorkInjury_Interface_Log
↓ (成功)
解析业务数据 → 存储到WorkInjury_Business_Data
↓
调用HIS接口 → 存储HIS业务数据
```
---
## 4 使用案例
### 4.1 典型业务场景案例
#### 4.1.1 工伤病人门诊登记流程
**场景描述**:工伤病人来医院看门诊,需要先在工伤系统登记,再在HIS系统登记
**数据操作流程**:
```sql
-- 1. 判断是否工伤病人
SELECT IsWorkInjuryPatient, WorkInjuryPsnNo, QualificationId
FROM WorkInjury_Patient_Relation
WHERE HisPatientId = 'P12345' AND Status = '1';
-- 如果是工伤病人,继续以下步骤:
-- 2. 调用工伤登记接口后,记录接口调用日志
INSERT INTO WorkInjury_Interface_Log (
HisPatientId, HisVisitNo, InterfaceCode, InterfaceName, InterfaceCategory,
RequestData, ResponseData, CallResult, ResultCode, ResultMessage,
WorkInjuryMsgId, WorkInjuryQualificationId, CallTime, OperatorId, OperatorName
) VALUES (
'P12345', 'MZ2024120100001', '2201', '门诊/住院登记', '业务类',
'{"infno":"2201","psn_no":"32123456789","med_type":"11",...}',
'{"infcode":"0","output":{"ipt_otp_no":"WS2024120100001"},...}',
1, '0', '登记成功',
'SQ201348202412011030001', 'WS2024120100001', GETDATE(), 'DOC001', '张医生'
);
-- 3. 记录业务数据
INSERT INTO WorkInjury_Business_Data (
LogId, HisPatientId, HisVisitNo, BusinessType, BusinessCode, BusinessStatus,
WorkInjuryRegisterNo, BusinessDetailData, BusinessTime
) VALUES (
@@IDENTITY, 'P12345', 'MZ2024120100001', '登记', '2201', '成功',
'WS2024120100001', '{"med_type":"11","adm_dept":"内科",...}', GETDATE()
);
```
#### 4.1.2 工伤费用结算流程
**场景描述**:工伤病人看完病,需要先在工伤系统结算,确定报销金额,再在HIS收费
```sql
-- 1. 处方明细上传
INSERT INTO WorkInjury_Interface_Log (...) VALUES (...); -- 接口调用日志
INSERT INTO WorkInjury_Business_Data (
LogId, HisPatientId, HisVisitNo, BusinessType, BusinessCode,
BusinessDetailData, BusinessTime
) VALUES (
@@IDENTITY, 'P12345', 'MZ2024120100001', '处方', '2204',
'{"feedetail":[{"med_list_codg":"A01.01.001","med_name":"阿莫西林",...}]}',
GETDATE()
);
-- 2. 费用预结算
INSERT INTO WorkInjury_Interface_Log (...) VALUES (...);
INSERT INTO WorkInjury_Business_Data (
LogId, HisPatientId, HisVisitNo, BusinessType, BusinessCode,
WorkInjuryPreSettleId, TotalFee, WorkInjuryFee, PersonalFee,
BusinessDetailData, BusinessTime
) VALUES (
@@IDENTITY, 'P12345', 'MZ2024120100001', '预结算', '2206',
'PRE20241201001', 150.00, 120.00, 30.00,
'{"pre_settle_data":{"psn_part_amt":30.00,"fund_pay_amt":120.00}}',
GETDATE()
);
-- 3. 正式结算
INSERT INTO WorkInjury_Interface_Log (...) VALUES (...);
INSERT INTO WorkInjury_Business_Data (
LogId, HisPatientId, HisVisitNo, BusinessType, BusinessCode,
WorkInjurySettleNo, TotalFee, WorkInjuryFee, PersonalFee,
WorkInjuryReceiptNo, BusinessTime
) VALUES (
@@IDENTITY, 'P12345', 'MZ2024120100001', '结算', '2207',
'SET20241201001', 150.00, 120.00, 30.00,
'WS2024120100001', GETDATE()
);
```
#### 4.1.3 对账类接口使用
**场景描述**:每日对账,下载工伤系统的结算汇总数据
```sql
-- 总额对账接口调用
INSERT INTO WorkInjury_Interface_Log (
InterfaceCode, InterfaceName, InterfaceCategory,
RequestData, ResponseData, CallResult,
BusinessDetailData, CallTime, OperatorId
) VALUES (
'1320', '总额对账', '对账类',
'{"stmt_begndate":"20241201","stmt_enddate":"20241201"}',
'{"infcode":"0","output":{"total_cnt":15,"total_amt":2250.00}}',
1,
'{"account_date":"20241201","total_count":15,"total_amount":2250.00}',
GETDATE(), 'SYS001'
);
-- 对账业务数据记录
INSERT INTO WorkInjury_Business_Data (
LogId, BusinessType, BusinessCode, BusinessStatus,
TotalFee, BusinessDetailData, BusinessTime
) VALUES (
@@IDENTITY, '对账', '1320', '成功',
2250.00, '{"account_date":"20241201","detail_count":15}', GETDATE()
);
```
#### 4.1.4 下载类接口使用
**场景描述**:下载费用明细数据,用于对账核实
```sql
-- 费用明细下载
INSERT INTO WorkInjury_Interface_Log (
InterfaceCode, InterfaceName, InterfaceCategory,
RequestData, ResponseData, CallResult,
BusinessDetailData, CallTime
) VALUES (
'9103', '费用明细详细信息下载', '下载类',
'{"queryCond":{"stmt_begndate":"20241201","stmt_enddate":"20241201"}}',
'{"infcode":"0","output":{"feedetail":[...]}}',
1,
'{"download_date":"20241201","record_count":156}',
GETDATE()
);
```
---
## 5 前端示例代码
### 5.1 jQuery 示例 - 工伤病人登记
```html
工伤病人登记
```
### 5.2 Vue 3.0 示例 - 工伤费用结算
```vue
工伤费用结算
加载病人信息
病人信息
{{ patientInfo.patientName }}
{{ patientInfo.cardNo }}
{{ patientInfo.isWorkInjury ? '工伤病人' : '普通病人' }}
处方明细
总金额: ¥{{ totalFee.toFixed(2) }}
上传处方明细
工伤预结算
{{ patientInfo.isWorkInjury ? '工伤正式结算' : 'HIS收费结算' }}
结算结果
工伤结算单号: {{ settlementResult.workInjurySettleNo }}
总费用: ¥{{ settlementResult.totalFee }}
工伤基金支付: ¥{{ settlementResult.workInjuryFee }}
个人支付: ¥{{ settlementResult.personalFee }}
HIS收费单号: {{ settlementResult.hisReceiptNo }}
应收金额: ¥{{ settlementResult.totalFee }}
操作记录
{{ log.operation }}: {{ log.message }}
```
---
## 6 后端示例代码
### 6.1 Spring Boot 示例 - 工伤接口服务
```java
package com.hospital.workinjury.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hospital.workinjury.entity.*;
import com.hospital.workinjury.repository.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
/**
* 工伤联网接口服务类
* 负责工伤接口调用和数据存储的核心业务逻辑
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class WorkInjuryService {
private final WorkInjuryInterfaceLogRepository logRepository;
private final WorkInjuryPatientRelationRepository relationRepository;
private final WorkInjuryBusinessDataRepository businessRepository;
private final RestTemplate restTemplate;
private final ObjectMapper objectMapper;
// 工伤接口地址配置
private static final String WORK_INJURY_API_URL = "http://localhost:8321/api/workinjury/transaction";
/**
* 检查病人工伤性质
* @param patientId HIS病人ID
* @return 工伤病人信息
*/
public WorkInjuryPatientInfo checkWorkInjuryPatient(String patientId) {
log.info("检查病人工伤性质, patientId: {}", patientId);
WorkInjuryPatientRelation relation = relationRepository.findByHisPatientId(patientId);
WorkInjuryPatientInfo info = new WorkInjuryPatientInfo();
info.setPatientId(patientId);
if (relation != null && relation.getIsWorkInjuryPatient()) {
info.setWorkInjuryPatient(true);
info.setWorkInjuryCardNo(relation.getWorkInjuryCardNo());
info.setWorkInjuryPsnNo(relation.getWorkInjuryPsnNo());
info.setQualificationId(relation.getQualificationId());
info.setQualificationStatus(relation.getQualificationStatus());
info.setQualificationExpireDate(relation.getQualificationExpireDate());
} else {
info.setWorkInjuryPatient(false);
}
return info;
}
/**
* 工伤病人登记流程
* 先调用工伤接口,成功后记录数据,再调用HIS接口
*/
@Transactional
public WorkInjuryRegisterResult registerWorkInjuryPatient(WorkInjuryRegisterRequest request) {
log.info("开始工伤病人登记流程, patientId: {}, visitNo: {}",
request.getPatientId(), request.getVisitNo());
WorkInjuryRegisterResult result = new WorkInjuryRegisterResult();
try {
// 1. 检查是否工伤病人
WorkInjuryPatientRelation relation = relationRepository.findByHisPatientId(request.getPatientId());
if (relation == null || !relation.getIsWorkInjuryPatient()) {
// 非工伤病人,直接调用HIS登记
return registerHisPatientOnly(request);
}
// 2. 调用工伤登记接口
WorkInjuryApiResult workInjuryResult = callWorkInjuryRegisterApi(request, relation);
// 3. 记录工伤接口调用日志
Long logId = saveInterfaceLog(request, workInjuryResult, "2201", "门诊/住院登记", "业务类");
if (workInjuryResult.isSuccess()) {
// 4. 记录工伤业务数据
saveBusinessData(logId, request, workInjuryResult, "登记", "2201");
// 5. 调用HIS登记接口
HisRegisterResult hisResult = callHisRegisterApi(request);
// 6. 组装返回结果
result.setSuccess(true);
result.setMessage("工伤病人登记成功");
result.setWorkInjuryRegisterNo(workInjuryResult.getData().get("ipt_otp_no").toString());
result.setHisVisitNo(hisResult.getVisitNo());
result.setQualificationId(workInjuryResult.getData().get("qualification_id").toString());
log.info("工伤病人登记成功, 工伤登记号: {}, HIS就诊号: {}",
result.getWorkInjuryRegisterNo(), result.getHisVisitNo());
} else {
result.setSuccess(false);
result.setMessage("工伤登记失败: " + workInjuryResult.getMessage());
log.error("工伤登记失败: {}", workInjuryResult.getMessage());
}
} catch (Exception e) {
log.error("工伤病人登记异常", e);
result.setSuccess(false);
result.setMessage("登记异常: " + e.getMessage());
}
return result;
}
/**
* 工伤费用结算流程
* 处方上传 -> 预结算 -> 正式结算 -> HIS收费
*/
@Transactional
public WorkInjurySettlementResult settleWorkInjuryFee(WorkInjurySettlementRequest request) {
log.info("开始工伤费用结算流程, visitNo: {}", request.getVisitNo());
WorkInjurySettlementResult result = new WorkInjurySettlementResult();
try {
// 1. 检查病人工伤性质
WorkInjuryPatientRelation relation = relationRepository.findByHisPatientId(request.getPatientId());
if (relation == null || !relation.getIsWorkInjuryPatient()) {
// 非工伤病人,直接HIS收费
return settleHisFeeOnly(request);
}
// 2. 上传处方明细
WorkInjuryApiResult uploadResult = uploadPrescriptionDetail(request);
if (!uploadResult.isSuccess()) {
result.setSuccess(false);
result.setMessage("处方上传失败: " + uploadResult.getMessage());
return result;
}
// 3. 费用预结算
WorkInjuryApiResult preSettleResult = preSettleFee(request);
if (!preSettleResult.isSuccess()) {
result.setSuccess(false);
result.setMessage("预结算失败: " + preSettleResult.getMessage());
return result;
}
// 4. 正式结算
WorkInjuryApiResult settleResult = settleFee(request);
if (!settleResult.isSuccess()) {
result.setSuccess(false);
result.setMessage("工伤结算失败: " + settleResult.getMessage());
return result;
}
// 5. 解析结算结果
Map settleData = settleResult.getData();
BigDecimal totalFee = new BigDecimal(settleData.get("medfee_sumamt").toString());
BigDecimal workInjuryFee = new BigDecimal(settleData.get("fund_pay_amt").toString());
BigDecimal personalFee = new BigDecimal(settleData.get("psn_part_amt").toString());
// 6. 记录结算业务数据
Long logId = saveInterfaceLog(request, settleResult, "2207", "费用结算", "业务类");
saveSettlementBusinessData(logId, request, settleResult, totalFee, workInjuryFee, personalFee);
// 7. HIS收费(只收个人支付部分)
HisSettlementResult hisResult = callHisSettlementApi(request, personalFee);
// 8. 组装返回结果
result.setSuccess(true);
result.setMessage("工伤费用结算成功");
result.setWorkInjurySettleNo(settleData.get("setl_id").toString());
result.setTotalFee(totalFee);
result.setWorkInjuryFee(workInjuryFee);
result.setPersonalFee(personalFee);
result.setHisReceiptNo(hisResult.getReceiptNo());
log.info("工伤费用结算成功, 结算号: {}, 总费用: {}, 个人支付: {}",
result.getWorkInjurySettleNo(), totalFee, personalFee);
} catch (Exception e) {
log.error("工伤费用结算异常", e);
result.setSuccess(false);
result.setMessage("结算异常: " + e.getMessage());
}
return result;
}
/**
* 对账接口调用
* 用于每日对账核对数据
*/
public WorkInjuryAccountResult dailyAccount(String accountDate) {
log.info("开始工伤对账, 对账日期: {}", accountDate);
WorkInjuryAccountResult result = new WorkInjuryAccountResult();
try {
// 1. 构造对账请求参数
Map accountParams = new HashMap<>();
accountParams.put("stmt_begndate", accountDate);
accountParams.put("stmt_enddate", accountDate);
WorkInjuryApiRequest apiRequest = new WorkInjuryApiRequest();
apiRequest.setAction("TotalAccount");
apiRequest.setBusinessParams(accountParams);
// 2. 调用工伤总额对账接口
WorkInjuryApiResult apiResult = callWorkInjuryApi(apiRequest);
// 3. 记录接口调用日志
Long logId = saveAccountInterfaceLog(apiRequest, apiResult, "1320", "总额对账", "对账类");
if (apiResult.isSuccess()) {
// 4. 解析对账结果
Map accountData = apiResult.getData();
int totalCount = Integer.parseInt(accountData.get("total_cnt").toString());
BigDecimal totalAmount = new BigDecimal(accountData.get("total_amt").toString());
// 5. 记录对账业务数据
saveAccountBusinessData(logId, accountDate, totalCount, totalAmount);
// 6. 组装返回结果
result.setSuccess(true);
result.setMessage("对账成功");
result.setAccountDate(accountDate);
result.setTotalCount(totalCount);
result.setTotalAmount(totalAmount);
log.info("工伤对账成功, 日期: {}, 笔数: {}, 金额: {}", accountDate, totalCount, totalAmount);
} else {
result.setSuccess(false);
result.setMessage("对账失败: " + apiResult.getMessage());
log.error("工伤对账失败: {}", apiResult.getMessage());
}
} catch (Exception e) {
log.error("工伤对账异常", e);
result.setSuccess(false);
result.setMessage("对账异常: " + e.getMessage());
}
return result;
}
/**
* 下载费用明细数据
* 用于对账核实和数据分析
*/
public WorkInjuryDownloadResult downloadFeeDetail(String beginDate, String endDate) {
log.info("开始下载工伤费用明细, 开始日期: {}, 结束日期: {}", beginDate, endDate);
WorkInjuryDownloadResult result = new WorkInjuryDownloadResult();
try {
// 1. 构造下载请求参数
Map queryCondition = new HashMap<>();
queryCondition.put("stmt_begndate", beginDate);
queryCondition.put("stmt_enddate", endDate);
Map downloadParams = new HashMap<>();
downloadParams.put("queryCond", queryCondition);
WorkInjuryApiRequest apiRequest = new WorkInjuryApiRequest();
apiRequest.setAction("QueryFeeDetail");
apiRequest.setBusinessParams(downloadParams);
// 2. 调用工伤费用明细下载接口
WorkInjuryApiResult apiResult = callWorkInjuryApi(apiRequest);
// 3. 记录接口调用日志
Long logId = saveDownloadInterfaceLog(apiRequest, apiResult, "9103", "费用明细详细信息下载", "下载类");
if (apiResult.isSuccess()) {
// 4. 解析下载结果
Map downloadData = apiResult.getData();
@SuppressWarnings("unchecked")
java.util.List