|
@@ -0,0 +1,1437 @@
|
|
|
+# 工伤联网接口数据库设计文档
|
|
|
+
|
|
|
+## 版本信息
|
|
|
+
|
|
|
+| 版本号 | 修改内容 | 修改日期 | 修改人 |
|
|
|
+|--------|----------|----------|--------|
|
|
|
+| 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
|
|
|
+<!DOCTYPE html>
|
|
|
+<html>
|
|
|
+<head>
|
|
|
+ <title>工伤病人登记</title>
|
|
|
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
|
|
+</head>
|
|
|
+<body>
|
|
|
+ <div class="patient-register">
|
|
|
+ <h3>工伤病人登记</h3>
|
|
|
+
|
|
|
+ <!-- 病人信息 -->
|
|
|
+ <div class="patient-info">
|
|
|
+ <label>病人ID: <input type="text" id="patientId" value="P12345"></label>
|
|
|
+ <label>就诊卡号: <input type="text" id="cardNo"></label>
|
|
|
+ <label>病人姓名: <input type="text" id="patientName"></label>
|
|
|
+ <button id="checkWorkInjury">检查工伤性质</button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 工伤信息显示 -->
|
|
|
+ <div id="workInjuryInfo" style="display:none;">
|
|
|
+ <h4>工伤信息</h4>
|
|
|
+ <div id="workInjuryDetail"></div>
|
|
|
+ <button id="registerWorkInjury">工伤登记</button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- HIS登记 -->
|
|
|
+ <div class="his-register">
|
|
|
+ <h4>HIS系统登记</h4>
|
|
|
+ <label>科室: <select id="department"><option value="001">内科</option></select></label>
|
|
|
+ <label>医生: <select id="doctor"><option value="DOC001">张医生</option></select></label>
|
|
|
+ <button id="registerHis">HIS登记</button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 结果显示 -->
|
|
|
+ <div id="result"></div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+<script>
|
|
|
+$(document).ready(function() {
|
|
|
+ // 检查工伤性质
|
|
|
+ $('#checkWorkInjury').click(function() {
|
|
|
+ const patientId = $('#patientId').val();
|
|
|
+
|
|
|
+ $.ajax({
|
|
|
+ url: '/api/workinjury/checkPatient',
|
|
|
+ method: 'POST',
|
|
|
+ contentType: 'application/json',
|
|
|
+ data: JSON.stringify({ patientId: patientId }),
|
|
|
+ success: function(response) {
|
|
|
+ if (response.success && response.data.isWorkInjuryPatient) {
|
|
|
+ // 是工伤病人,显示工伤信息
|
|
|
+ $('#workInjuryDetail').html(`
|
|
|
+ <p>工伤卡号: ${response.data.workInjuryCardNo}</p>
|
|
|
+ <p>个人识别码: ${response.data.workInjuryPsnNo}</p>
|
|
|
+ <p>资格状态: ${response.data.qualificationStatus}</p>
|
|
|
+ <p>有效期: ${response.data.qualificationExpireDate}</p>
|
|
|
+ `);
|
|
|
+ $('#workInjuryInfo').show();
|
|
|
+ } else {
|
|
|
+ // 非工伤病人,直接显示HIS登记
|
|
|
+ $('#result').html('<div class="info">该病人非工伤性质,直接进行HIS登记</div>');
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error: function(xhr, status, error) {
|
|
|
+ $('#result').html('<div class="error">检查失败: ' + error + '</div>');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ // 工伤登记
|
|
|
+ $('#registerWorkInjury').click(function() {
|
|
|
+ const patientId = $('#patientId').val();
|
|
|
+ const visitNo = 'MZ' + new Date().getFullYear() +
|
|
|
+ (new Date().getMonth() + 1).toString().padStart(2, '0') +
|
|
|
+ new Date().getDate().toString().padStart(2, '0') + '00001';
|
|
|
+
|
|
|
+ const registerData = {
|
|
|
+ action: "RegisterPatient",
|
|
|
+ businessParams: {
|
|
|
+ ipt_otp_no: visitNo,
|
|
|
+ med_type: "11", // 门诊
|
|
|
+ adm_time: new Date().toISOString().replace(/[-:]/g, '').slice(0, 14),
|
|
|
+ adm_dept_codg: $('#department').val(),
|
|
|
+ atddr_no: $('#doctor').val()
|
|
|
+ },
|
|
|
+ identifyMode: "1"
|
|
|
+ };
|
|
|
+
|
|
|
+ $.ajax({
|
|
|
+ url: '/api/workinjury/transaction',
|
|
|
+ method: 'POST',
|
|
|
+ contentType: 'application/json',
|
|
|
+ data: JSON.stringify(registerData),
|
|
|
+ success: function(response) {
|
|
|
+ if (response.success) {
|
|
|
+ $('#result').html('<div class="success">工伤登记成功,登记号: ' +
|
|
|
+ response.data.ipt_otp_no + '</div>');
|
|
|
+
|
|
|
+ // 工伤登记成功后,自动进行HIS登记
|
|
|
+ $('#registerHis').click();
|
|
|
+ } else {
|
|
|
+ $('#result').html('<div class="error">工伤登记失败: ' + response.message + '</div>');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ // HIS登记
|
|
|
+ $('#registerHis').click(function() {
|
|
|
+ const hisRegisterData = {
|
|
|
+ patientId: $('#patientId').val(),
|
|
|
+ patientName: $('#patientName').val(),
|
|
|
+ department: $('#department').val(),
|
|
|
+ doctor: $('#doctor').val(),
|
|
|
+ visitType: '门诊'
|
|
|
+ };
|
|
|
+
|
|
|
+ $.ajax({
|
|
|
+ url: '/api/his/register',
|
|
|
+ method: 'POST',
|
|
|
+ contentType: 'application/json',
|
|
|
+ data: JSON.stringify(hisRegisterData),
|
|
|
+ success: function(response) {
|
|
|
+ if (response.success) {
|
|
|
+ $('#result').append('<div class="success">HIS登记成功,就诊号: ' +
|
|
|
+ response.data.visitNo + '</div>');
|
|
|
+ } else {
|
|
|
+ $('#result').append('<div class="error">HIS登记失败: ' + response.message + '</div>');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style>
|
|
|
+.patient-register { padding: 20px; }
|
|
|
+.patient-info, .his-register { margin: 15px 0; padding: 10px; border: 1px solid #ddd; }
|
|
|
+label { display: block; margin: 5px 0; }
|
|
|
+input, select { margin-left: 10px; padding: 5px; }
|
|
|
+button { margin: 10px 5px; padding: 8px 15px; background: #007cba; color: white; border: none; cursor: pointer; }
|
|
|
+.success { color: green; font-weight: bold; }
|
|
|
+.error { color: red; font-weight: bold; }
|
|
|
+.info { color: blue; font-weight: bold; }
|
|
|
+</style>
|
|
|
+</body>
|
|
|
+</html>
|
|
|
+```
|
|
|
+
|
|
|
+### 5.2 Vue 3.0 示例 - 工伤费用结算
|
|
|
+
|
|
|
+```vue
|
|
|
+<template>
|
|
|
+ <div class="work-injury-settlement">
|
|
|
+ <h3>工伤费用结算</h3>
|
|
|
+
|
|
|
+ <!-- 病人选择 -->
|
|
|
+ <div class="patient-select">
|
|
|
+ <el-form :model="patientForm" inline>
|
|
|
+ <el-form-item label="就诊号">
|
|
|
+ <el-input v-model="patientForm.visitNo" placeholder="请输入就诊号"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button type="primary" @click="loadPatientInfo">加载病人信息</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 病人信息显示 -->
|
|
|
+ <div v-if="patientInfo.patientId" class="patient-info">
|
|
|
+ <h4>病人信息</h4>
|
|
|
+ <el-descriptions :column="3" border>
|
|
|
+ <el-descriptions-item label="病人姓名">{{ patientInfo.patientName }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="就诊卡号">{{ patientInfo.cardNo }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="工伤性质">
|
|
|
+ <el-tag :type="patientInfo.isWorkInjury ? 'success' : 'info'">
|
|
|
+ {{ patientInfo.isWorkInjury ? '工伤病人' : '普通病人' }}
|
|
|
+ </el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 处方明细 -->
|
|
|
+ <div class="prescription-detail">
|
|
|
+ <h4>处方明细</h4>
|
|
|
+ <el-table :data="prescriptionList" border>
|
|
|
+ <el-table-column prop="medName" label="药品名称"></el-table-column>
|
|
|
+ <el-table-column prop="quantity" label="数量"></el-table-column>
|
|
|
+ <el-table-column prop="unitPrice" label="单价"></el-table-column>
|
|
|
+ <el-table-column prop="totalPrice" label="小计"></el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <div class="total-fee">
|
|
|
+ <strong>总金额: ¥{{ totalFee.toFixed(2) }}</strong>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 结算操作 -->
|
|
|
+ <div class="settlement-actions">
|
|
|
+ <el-button v-if="patientInfo.isWorkInjury"
|
|
|
+ type="warning"
|
|
|
+ @click="uploadPrescription"
|
|
|
+ :loading="uploading">
|
|
|
+ 上传处方明细
|
|
|
+ </el-button>
|
|
|
+
|
|
|
+ <el-button v-if="patientInfo.isWorkInjury"
|
|
|
+ type="info"
|
|
|
+ @click="preSettle"
|
|
|
+ :loading="preSettling"
|
|
|
+ :disabled="!prescriptionUploaded">
|
|
|
+ 工伤预结算
|
|
|
+ </el-button>
|
|
|
+
|
|
|
+ <el-button type="success"
|
|
|
+ @click="finalSettle"
|
|
|
+ :loading="settling">
|
|
|
+ {{ patientInfo.isWorkInjury ? '工伤正式结算' : 'HIS收费结算' }}
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 结算结果 -->
|
|
|
+ <div v-if="settlementResult" class="settlement-result">
|
|
|
+ <h4>结算结果</h4>
|
|
|
+ <el-card>
|
|
|
+ <div v-if="patientInfo.isWorkInjury">
|
|
|
+ <p><strong>工伤结算单号:</strong> {{ settlementResult.workInjurySettleNo }}</p>
|
|
|
+ <p><strong>总费用:</strong> ¥{{ settlementResult.totalFee }}</p>
|
|
|
+ <p><strong>工伤基金支付:</strong> ¥{{ settlementResult.workInjuryFee }}</p>
|
|
|
+ <p><strong>个人支付:</strong> ¥{{ settlementResult.personalFee }}</p>
|
|
|
+ </div>
|
|
|
+ <div v-else>
|
|
|
+ <p><strong>HIS收费单号:</strong> {{ settlementResult.hisReceiptNo }}</p>
|
|
|
+ <p><strong>应收金额:</strong> ¥{{ settlementResult.totalFee }}</p>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 操作记录 -->
|
|
|
+ <div class="operation-log">
|
|
|
+ <h4>操作记录</h4>
|
|
|
+ <el-timeline>
|
|
|
+ <el-timeline-item
|
|
|
+ v-for="log in operationLogs"
|
|
|
+ :key="log.id"
|
|
|
+ :timestamp="log.time"
|
|
|
+ :type="log.success ? 'success' : 'danger'">
|
|
|
+ {{ log.operation }}: {{ log.message }}
|
|
|
+ </el-timeline-item>
|
|
|
+ </el-timeline>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, reactive, computed } from 'vue'
|
|
|
+import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
+
|
|
|
+// 响应式数据
|
|
|
+const patientForm = reactive({
|
|
|
+ visitNo: ''
|
|
|
+})
|
|
|
+
|
|
|
+const patientInfo = reactive({
|
|
|
+ patientId: '',
|
|
|
+ patientName: '',
|
|
|
+ cardNo: '',
|
|
|
+ isWorkInjury: false,
|
|
|
+ workInjuryPsnNo: '',
|
|
|
+ qualificationId: ''
|
|
|
+})
|
|
|
+
|
|
|
+const prescriptionList = ref([
|
|
|
+ { medName: '阿莫西林胶囊', quantity: 2, unitPrice: 25.00, totalPrice: 50.00 },
|
|
|
+ { medName: '布洛芬片', quantity: 1, unitPrice: 18.50, totalPrice: 18.50 },
|
|
|
+ { medName: '维生素C片', quantity: 1, unitPrice: 12.80, totalPrice: 12.80 }
|
|
|
+])
|
|
|
+
|
|
|
+const uploading = ref(false)
|
|
|
+const preSettling = ref(false)
|
|
|
+const settling = ref(false)
|
|
|
+const prescriptionUploaded = ref(false)
|
|
|
+const settlementResult = ref(null)
|
|
|
+const operationLogs = ref([])
|
|
|
+
|
|
|
+// 计算属性
|
|
|
+const totalFee = computed(() => {
|
|
|
+ return prescriptionList.value.reduce((sum, item) => sum + item.totalPrice, 0)
|
|
|
+})
|
|
|
+
|
|
|
+// 方法
|
|
|
+const loadPatientInfo = async () => {
|
|
|
+ try {
|
|
|
+ const response = await fetch('/api/workinjury/getPatientInfo', {
|
|
|
+ method: 'POST',
|
|
|
+ headers: { 'Content-Type': 'application/json' },
|
|
|
+ body: JSON.stringify({ visitNo: patientForm.visitNo })
|
|
|
+ })
|
|
|
+
|
|
|
+ const result = await response.json()
|
|
|
+ if (result.success) {
|
|
|
+ Object.assign(patientInfo, result.data)
|
|
|
+ addOperationLog('加载病人信息', '成功', true)
|
|
|
+ } else {
|
|
|
+ ElMessage.error('加载病人信息失败: ' + result.message)
|
|
|
+ addOperationLog('加载病人信息', result.message, false)
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('加载病人信息异常: ' + error.message)
|
|
|
+ addOperationLog('加载病人信息', error.message, false)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const uploadPrescription = async () => {
|
|
|
+ uploading.value = true
|
|
|
+ try {
|
|
|
+ const prescriptionData = {
|
|
|
+ action: "UploadPrescription",
|
|
|
+ businessParams: {
|
|
|
+ feedetail: prescriptionList.value.map(item => ({
|
|
|
+ med_list_codg: item.medCode || 'A01.01.001',
|
|
|
+ med_name: item.medName,
|
|
|
+ med_qty: item.quantity,
|
|
|
+ pric: item.unitPrice,
|
|
|
+ det_item_fee_sumamt: item.totalPrice
|
|
|
+ }))
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const response = await fetch('/api/workinjury/transaction', {
|
|
|
+ method: 'POST',
|
|
|
+ headers: { 'Content-Type': 'application/json' },
|
|
|
+ body: JSON.stringify(prescriptionData)
|
|
|
+ })
|
|
|
+
|
|
|
+ const result = await response.json()
|
|
|
+ if (result.success) {
|
|
|
+ prescriptionUploaded.value = true
|
|
|
+ ElMessage.success('处方明细上传成功')
|
|
|
+ addOperationLog('上传处方明细', '成功', true)
|
|
|
+ } else {
|
|
|
+ ElMessage.error('处方明细上传失败: ' + result.message)
|
|
|
+ addOperationLog('上传处方明细', result.message, false)
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('处方明细上传异常: ' + error.message)
|
|
|
+ addOperationLog('上传处方明细', error.message, false)
|
|
|
+ } finally {
|
|
|
+ uploading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const preSettle = async () => {
|
|
|
+ preSettling.value = true
|
|
|
+ try {
|
|
|
+ const preSettleData = {
|
|
|
+ action: "PreSettle",
|
|
|
+ businessParams: {
|
|
|
+ ipt_otp_no: patientForm.visitNo,
|
|
|
+ psn_no: patientInfo.workInjuryPsnNo,
|
|
|
+ total_amt: totalFee.value
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const response = await fetch('/api/workinjury/transaction', {
|
|
|
+ method: 'POST',
|
|
|
+ headers: { 'Content-Type': 'application/json' },
|
|
|
+ body: JSON.stringify(preSettleData)
|
|
|
+ })
|
|
|
+
|
|
|
+ const result = await response.json()
|
|
|
+ if (result.success) {
|
|
|
+ ElMessage.success('工伤预结算成功')
|
|
|
+ addOperationLog('工伤预结算',
|
|
|
+ `个人支付: ¥${result.data.psn_part_amt}, 基金支付: ¥${result.data.fund_pay_amt}`,
|
|
|
+ true)
|
|
|
+ } else {
|
|
|
+ ElMessage.error('工伤预结算失败: ' + result.message)
|
|
|
+ addOperationLog('工伤预结算', result.message, false)
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('工伤预结算异常: ' + error.message)
|
|
|
+ addOperationLog('工伤预结算', error.message, false)
|
|
|
+ } finally {
|
|
|
+ preSettling.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const finalSettle = async () => {
|
|
|
+ settling.value = true
|
|
|
+ try {
|
|
|
+ if (patientInfo.isWorkInjury) {
|
|
|
+ // 工伤正式结算
|
|
|
+ const settleData = {
|
|
|
+ action: "Settle",
|
|
|
+ businessParams: {
|
|
|
+ ipt_otp_no: patientForm.visitNo,
|
|
|
+ psn_no: patientInfo.workInjuryPsnNo
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const response = await fetch('/api/workinjury/transaction', {
|
|
|
+ method: 'POST',
|
|
|
+ headers: { 'Content-Type': 'application/json' },
|
|
|
+ body: JSON.stringify(settleData)
|
|
|
+ })
|
|
|
+
|
|
|
+ const result = await response.json()
|
|
|
+ if (result.success) {
|
|
|
+ settlementResult.value = {
|
|
|
+ workInjurySettleNo: result.data.setl_id,
|
|
|
+ totalFee: result.data.medfee_sumamt,
|
|
|
+ workInjuryFee: result.data.fund_pay_amt,
|
|
|
+ personalFee: result.data.psn_part_amt
|
|
|
+ }
|
|
|
+ ElMessage.success('工伤结算成功')
|
|
|
+ addOperationLog('工伤正式结算', '成功', true)
|
|
|
+
|
|
|
+ // 工伤结算成功后,调用HIS收费
|
|
|
+ await hisSettle()
|
|
|
+ } else {
|
|
|
+ ElMessage.error('工伤结算失败: ' + result.message)
|
|
|
+ addOperationLog('工伤正式结算', result.message, false)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 直接HIS收费
|
|
|
+ await hisSettle()
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('结算异常: ' + error.message)
|
|
|
+ addOperationLog('结算操作', error.message, false)
|
|
|
+ } finally {
|
|
|
+ settling.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const hisSettle = async () => {
|
|
|
+ try {
|
|
|
+ const hisSettleData = {
|
|
|
+ visitNo: patientForm.visitNo,
|
|
|
+ totalFee: patientInfo.isWorkInjury ? settlementResult.value?.personalFee : totalFee.value,
|
|
|
+ paymentMethod: '现金'
|
|
|
+ }
|
|
|
+
|
|
|
+ const response = await fetch('/api/his/settle', {
|
|
|
+ method: 'POST',
|
|
|
+ headers: { 'Content-Type': 'application/json' },
|
|
|
+ body: JSON.stringify(hisSettleData)
|
|
|
+ })
|
|
|
+
|
|
|
+ const result = await response.json()
|
|
|
+ if (result.success) {
|
|
|
+ if (!settlementResult.value) {
|
|
|
+ settlementResult.value = {}
|
|
|
+ }
|
|
|
+ settlementResult.value.hisReceiptNo = result.data.receiptNo
|
|
|
+ if (!patientInfo.isWorkInjury) {
|
|
|
+ settlementResult.value.totalFee = totalFee.value
|
|
|
+ }
|
|
|
+
|
|
|
+ ElMessage.success('HIS收费成功')
|
|
|
+ addOperationLog('HIS收费', '成功', true)
|
|
|
+ } else {
|
|
|
+ ElMessage.error('HIS收费失败: ' + result.message)
|
|
|
+ addOperationLog('HIS收费', result.message, false)
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('HIS收费异常: ' + error.message)
|
|
|
+ addOperationLog('HIS收费', error.message, false)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const addOperationLog = (operation, message, success) => {
|
|
|
+ operationLogs.value.unshift({
|
|
|
+ id: Date.now(),
|
|
|
+ operation,
|
|
|
+ message,
|
|
|
+ success,
|
|
|
+ time: new Date().toLocaleString()
|
|
|
+ })
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.work-injury-settlement {
|
|
|
+ padding: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.patient-select, .patient-info, .prescription-detail,
|
|
|
+.settlement-actions, .settlement-result, .operation-log {
|
|
|
+ margin: 20px 0;
|
|
|
+}
|
|
|
+
|
|
|
+.total-fee {
|
|
|
+ text-align: right;
|
|
|
+ margin: 10px 0;
|
|
|
+ font-size: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.settlement-actions {
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.settlement-actions .el-button {
|
|
|
+ margin: 0 10px;
|
|
|
+}
|
|
|
+</style>
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> queryCondition = new HashMap<>();
|
|
|
+ queryCondition.put("stmt_begndate", beginDate);
|
|
|
+ queryCondition.put("stmt_enddate", endDate);
|
|
|
+
|
|
|
+ Map<String, Object> 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<String, Object> downloadData = apiResult.getData();
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ java.util.List<Map<String, Object>> feeDetailList =
|
|
|
+ (java.util.List<Map<String, Object>>) downloadData.get("feedetail");
|
|
|
+
|
|
|
+ int recordCount = feeDetailList != null ? feeDetailList.size() : 0;
|
|
|
+
|
|
|
+ // 5. 记录下载业务数据
|
|
|
+ saveDownloadBusinessData(logId, beginDate, endDate, recordCount, feeDetailList);
|
|
|
+
|
|
|
+ // 6. 组装返回结果
|
|
|
+ result.setSuccess(true);
|
|
|
+ result.setMessage("下载成功");
|
|
|
+ result.setBeginDate(beginDate);
|
|
|
+ result.setEndDate(endDate);
|
|
|
+ result.setRecordCount(recordCount);
|
|
|
+ result.setFeeDetailList(feeDetailList);
|
|
|
+
|
|
|
+ log.info("工伤费用明细下载成功, 记录数: {}", recordCount);
|
|
|
+ } 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ // ==================== 私有辅助方法 ====================
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 调用工伤登记接口
|
|
|
+ */
|
|
|
+ private WorkInjuryApiResult callWorkInjuryRegisterApi(
|
|
|
+ WorkInjuryRegisterRequest request,
|
|
|
+ WorkInjuryPatientRelation relation) throws Exception {
|
|
|
+
|
|
|
+ Map<String, Object> businessParams = new HashMap<>();
|
|
|
+ businessParams.put("ipt_otp_no", request.getVisitNo());
|
|
|
+ businessParams.put("med_type", "11"); // 门诊
|
|
|
+ businessParams.put("adm_time", LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
|
|
|
+ businessParams.put("adm_dept_codg", request.getDepartmentCode());
|
|
|
+ businessParams.put("atddr_no", request.getDoctorCode());
|
|
|
+ businessParams.put("psn_no", relation.getWorkInjuryPsnNo());
|
|
|
+ businessParams.put("qualification_id", relation.getQualificationId());
|
|
|
+
|
|
|
+ WorkInjuryApiRequest apiRequest = new WorkInjuryApiRequest();
|
|
|
+ apiRequest.setAction("RegisterPatient");
|
|
|
+ apiRequest.setBusinessParams(businessParams);
|
|
|
+ apiRequest.setIdentifyMode("1");
|
|
|
+
|
|
|
+ return callWorkInjuryApi(apiRequest);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 统一的工伤接口调用方法
|
|
|
+ */
|
|
|
+ private WorkInjuryApiResult callWorkInjuryApi(WorkInjuryApiRequest request) throws Exception {
|
|
|
+ log.debug("调用工伤接口, action: {}", request.getAction());
|
|
|
+
|
|
|
+ ResponseEntity<Map> response = restTemplate.postForEntity(
|
|
|
+ WORK_INJURY_API_URL,
|
|
|
+ request,
|
|
|
+ Map.class
|
|
|
+ );
|
|
|
+
|
|
|
+ Map<String, Object> responseBody = response.getBody();
|
|
|
+
|
|
|
+ WorkInjuryApiResult result = new WorkInjuryApiResult();
|
|
|
+ result.setSuccess((Boolean) responseBody.get("success"));
|
|
|
+ result.setCode((String) responseBody.get("code"));
|
|
|
+ result.setMessage((String) responseBody.get("message"));
|
|
|
+
|
|
|
+ if (result.isSuccess()) {
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ Map<String, Object> data = (Map<String, Object>) responseBody.get("data");
|
|
|
+ result.setData(data);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存接口调用日志
|
|
|
+ */
|
|
|
+ private Long saveInterfaceLog(
|
|
|
+ Object request,
|
|
|
+ WorkInjuryApiResult apiResult,
|
|
|
+ String interfaceCode,
|
|
|
+ String interfaceName,
|
|
|
+ String interfaceCategory) {
|
|
|
+
|
|
|
+ try {
|
|
|
+ WorkInjuryInterfaceLog log = new WorkInjuryInterfaceLog();
|
|
|
+
|
|
|
+ // 设置基本信息
|
|
|
+ if (request instanceof WorkInjuryRegisterRequest) {
|
|
|
+ WorkInjuryRegisterRequest registerRequest = (WorkInjuryRegisterRequest) request;
|
|
|
+ log.setHisPatientId(registerRequest.getPatientId());
|
|
|
+ log.setHisVisitNo(registerRequest.getVisitNo());
|
|
|
+ } else if (request instanceof WorkInjurySettlementRequest) {
|
|
|
+ WorkInjurySettlementRequest settlementRequest = (WorkInjurySettlementRequest) request;
|
|
|
+ log.setHisPatientId(settlementRequest.getPatientId());
|
|
|
+ log.setHisVisitNo(settlementRequest.getVisitNo());
|
|
|
+ }
|
|
|
+
|
|
|
+ log.setInterfaceCode(interfaceCode);
|
|
|
+ log.setInterfaceName(interfaceName);
|
|
|
+ log.setInterfaceCategory(interfaceCategory);
|
|
|
+
|
|
|
+ // 设置请求和响应数据
|
|
|
+ log.setRequestData(objectMapper.writeValueAsString(request));
|
|
|
+ log.setResponseData(objectMapper.writeValueAsString(apiResult));
|
|
|
+
|
|
|
+ // 设置调用结果
|
|
|
+ log.setCallResult(apiResult.isSuccess());
|
|
|
+ log.setResultCode(apiResult.getCode());
|
|
|
+ log.setResultMessage(apiResult.getMessage());
|
|
|
+
|
|
|
+ // 设置工伤系统关键信息
|
|
|
+ if (apiResult.isSuccess() && apiResult.getData() != null) {
|
|
|
+ Map<String, Object> data = apiResult.getData();
|
|
|
+ log.setWorkInjuryMsgId((String) data.get("inf_refmsgid"));
|
|
|
+ log.setWorkInjuryQualificationId((String) data.get("qualification_id"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置时间和操作信息
|
|
|
+ log.setCallTime(LocalDateTime.now());
|
|
|
+ log.setOperatorId("SYSTEM");
|
|
|
+ log.setOperatorName("系统自动");
|
|
|
+
|
|
|
+ WorkInjuryInterfaceLog savedLog = logRepository.save(log);
|
|
|
+ return savedLog.getLogId();
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("保存接口调用日志失败", e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存业务数据
|
|
|
+ */
|
|
|
+ private void saveBusinessData(
|
|
|
+ Long logId,
|
|
|
+ WorkInjuryRegisterRequest request,
|
|
|
+ WorkInjuryApiResult apiResult,
|
|
|
+ String businessType,
|
|
|
+ String businessCode) {
|
|
|
+
|
|
|
+ try {
|
|
|
+ WorkInjuryBusinessData businessData = new WorkInjuryBusinessData();
|
|
|
+
|
|
|
+ businessData.setLogId(logId);
|
|
|
+ businessData.setHisPatientId(request.getPatientId());
|
|
|
+ businessData.setHisVisitNo(request.getVisitNo());
|
|
|
+ businessData.setBusinessType(businessType);
|
|
|
+ businessData.setBusinessCode(businessCode);
|
|
|
+ businessData.setBusinessStatus("成功");
|
|
|
+
|
|
|
+ if (apiResult.getData() != null) {
|
|
|
+ Map<String, Object> data = apiResult.getData();
|
|
|
+ businessData.setWorkInjuryRegisterNo((String) data.get("ipt_otp_no"));
|
|
|
+ businessData.setBusinessDetailData(objectMapper.writeValueAsString(data));
|
|
|
+ }
|
|
|
+
|
|
|
+ businessData.setBusinessTime(LocalDateTime.now());
|
|
|
+
|
|
|
+ businessRepository.save(businessData);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("保存业务数据失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存结算业务数据
|
|
|
+ */
|
|
|
+ private void saveSettlementBusinessData(
|
|
|
+ Long logId,
|
|
|
+ WorkInjurySettlementRequest request,
|
|
|
+ WorkInjuryApiResult apiResult,
|
|
|
+ BigDecimal totalFee,
|
|
|
+ BigDecimal workInjuryFee,
|
|
|
+ BigDecimal personalFee) {
|
|
|
+
|
|
|
+ try {
|
|
|
+ WorkInjuryBusinessData businessData = new WorkInjuryBusinessData();
|
|
|
+
|
|
|
+ businessData.setLogId(logId);
|
|
|
+ businessData.setHisPatientId(request.getPatientId());
|
|
|
+ businessData.setHisVisitNo(request.getVisitNo());
|
|
|
+ businessData.setBusinessType("结算");
|
|
|
+ businessData.setBusinessCode("2207");
|
|
|
+ businessData.setBusinessStatus("成功");
|
|
|
+
|
|
|
+ // 设置费用信息
|
|
|
+ businessData.setTotalFee(totalFee);
|
|
|
+ businessData.setWorkInjuryFee(workInjuryFee);
|
|
|
+ businessData.setPersonalFee(personalFee);
|
|
|
+
|
|
|
+ if (apiResult.getData() != null) {
|
|
|
+ Map<String, Object> data = apiResult.getData();
|
|
|
+ businessData.setWorkInjurySettleNo((String) data.get("setl_id"));
|
|
|
+ businessData.setWorkInjuryReceiptNo((String) data.get("setl_detail_id"));
|
|
|
+ businessData.setBusinessDetailData(objectMapper.writeValueAsString(data));
|
|
|
+ }
|
|
|
+
|
|
|
+ businessData.setBusinessTime(LocalDateTime.now());
|
|
|
+
|
|
|
+ businessRepository.save(businessData);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("保存结算业务数据失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 其他辅助方法... (uploadPrescriptionDetail, preSettleFee, settleFee, callHisApi等)
|
|
|
+ // 为了节省篇幅,这里省略了部分辅助方法的实现
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+这个完整的文档涵盖了:
|
|
|
+
|
|
|
+1. **数据库表设计**:3个通用表支持所有工伤接口类型
|
|
|
+2. **详细注释说明**:每个字段都有明确的用途说明
|
|
|
+3. **表关联关系**:清晰的关联逻辑和数据流向
|
|
|
+4. **使用案例**:典型业务场景的数据操作示例
|
|
|
+5. **前端代码**:jQuery和Vue 3.0的完整实现示例
|
|
|
+6. **后端代码**:Spring Boot的服务层实现
|
|
|
+
|
|
|
+这套设计方案能够完美实现您的需求:**工伤病人先调用工伤接口存储数据,再调用HIS接口;非工伤病人直接调用HIS接口**,同时通过通用化设计支持所有类型的工伤接口,简单实用可靠。
|