From 38502914f5146fe4a56acffefe62a14feaa59f35 Mon Sep 17 00:00:00 2001 From: dazer007 Date: Thu, 13 Mar 2025 16:56:54 +0800 Subject: [PATCH] =?UTF-8?q?feat(all):=20getEmrCaTimeStamp=20=E6=88=90?= =?UTF-8?q?=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../his/app/controller/AppBjCaController.java | 12 ++ .../domain/entity/his/MdcRcdInRecordSign.java | 79 ++++++++++++ .../mapper/his/MdcRcdInRecordSignMapper.java | 52 ++++++++ .../neuhis/his/service/his/IEmrCaService.java | 27 ++++ .../service/impl/his/EmrCaServiceImpl.java | 55 +++++++++ .../src/main/resources/bjca.properties | 6 +- .../mapper/his/MdcRcdInRecordSignMapper.xml | 115 ++++++++++++++++++ 7 files changed, 345 insertions(+), 1 deletion(-) create mode 100644 ruoyi-admin/src/main/java/com/neuhis/his/domain/entity/his/MdcRcdInRecordSign.java create mode 100644 ruoyi-admin/src/main/java/com/neuhis/his/mapper/his/MdcRcdInRecordSignMapper.java create mode 100644 ruoyi-admin/src/main/java/com/neuhis/his/service/his/IEmrCaService.java create mode 100644 ruoyi-admin/src/main/java/com/neuhis/his/service/impl/his/EmrCaServiceImpl.java create mode 100644 ruoyi-admin/src/main/resources/mapper/his/MdcRcdInRecordSignMapper.xml diff --git a/ruoyi-admin/src/main/java/com/neuhis/his/app/controller/AppBjCaController.java b/ruoyi-admin/src/main/java/com/neuhis/his/app/controller/AppBjCaController.java index 5ae0aa6cf..41249da36 100644 --- a/ruoyi-admin/src/main/java/com/neuhis/his/app/controller/AppBjCaController.java +++ b/ruoyi-admin/src/main/java/com/neuhis/his/app/controller/AppBjCaController.java @@ -5,6 +5,7 @@ import com.neuhis.his.domain.vo.bjca.BjCaResult; import com.neuhis.his.domain.vo.bjca.CaResultVo; import com.neuhis.his.domain.vo.bjca.CaStartVo; import com.neuhis.his.service.IBjCaService; +import com.neuhis.his.service.his.IEmrCaService; import com.neuhis.his.service.winlis.ILasSapSampleregService; import com.neuhis.his.service.winlis.IWinLisService; import com.ruoyi.common.core.domain.AjaxResult; @@ -33,6 +34,8 @@ public class AppBjCaController { @Resource private IWinLisService winLisService; @Resource + private IEmrCaService emrCaService; + @Resource private ILasSapSampleregService lasSapSampleregService; /** * startAutoSign启动自动签名获取的签名数据,[签名任务id] @@ -72,4 +75,13 @@ public class AppBjCaController { //return AjaxResult.success(lasSapSampleregService.selectWaitingCaSignList("202503", 10)); return AjaxResult.success(winLisService.winlistCaTask("202503", 10)); } + + @GetMapping("/getEmrCaTimeStamp") + @ApiOperation(value = "获取:Emr的CA签名", notes = "获取:Emr的CA签名(签名结果、证书、时间戳)") + public AjaxResult getEmrCaTimeStamp() { + String oriDataBase64 = "1/C+tLXEu7zV37ywvNLK9Lvyt6i2qLzgu6TIy6GiytrIqM6vzdDIy6O6DQogICAgICDE+rrDIcrXz8i40NC7xPoow8cp0aHU8dTaztLUur7N1e+ho7C01dXPzNH0ytChos73sLLK0NK9saPV/rLftci55raoo6jS7LXYss7V1c/M0fTK0NK9saPWp7i2t7bOp9a00NCjqaOsuPm+3cT6tcSyocfp0OjSqqOs1NrXodS61e/BxtbQyea8sLzssumhotPD0qmhorrEssShotbOwca8sMbky/uzrNK9saPWp7i2t7bOp7XE0r3Bxrf+zvHP7sS/o6zQ6M/yxPq78sT6tcS80sr0o6i84LukyMuhosrayKjOr83QyMujqcu1w/fH6b/2o6zV97XDzazS4sjPv8nHqdfWuvOjrLe9v8nWtNDQoaMNCsjnufvE+sHLveLJz8r2uObWqsTayN26zbe2zqfN4tbOwcbP7sS/o6zH68T6x6nK8NLivPuhow0KyNUgIMbaDQrP7iAgxL8NCsr9wb8NCr3wICC27g0K0r3Kprvyu6TKv8epw/sNCru81d+78rzSyvShosrayKjOr83QyMvNrNLix6nD+w0K0+u7vNXfudjPtQ0KMjAyNS0wMy0wMyAxMTo1MA0KtLLOu7fRDQrOxLG+v/IyDQqzrDMy1Kqyv7fWDQoNCru81d/HqcP7DQq4uMWuDQoyMDI1LTAzLTAzIDExOjUxDQrG+NG5scMNCs7Esb6/8jUNCjIw1Kovsr/Ouw0KLw0Ku7zV38epw/sNCri4xa4NCjIwMjUtMDMtMDMgMTE6NTENCrnI69e4yuvEoaK24M+pwdfWrPWjtai87g0KzsSxvr/yOA0K19S30Q0KLw0Ku7zV38epw/sNCri4xa4NCsjVxtoNCs7Esb6/8jEwDQrOxLG+v/IxMQ0KzsSxvr/yMTINCsepw/sNCru81d/HqcP7DQoNCsjVxtoNCs7Esb6/8jEzDQrOxLG+v/IxNA0KzsSxvr/yMTUNCsepw/sNCru81d/HqcP7DQoNCsjVxtoNCs7Esb6/8jE2DQrOxLG+v/IxNw0KzsSxvr/yMTgNCsepw/sNCru81d/HqcP7DQoNCsjVxtoNCs7Esb6/8jE5DQrOxLG+v/IyMA0KzsSxvr/yMjINCsepw/sNCru81d/HqcP7DQoNCsjVxtoNCs7Esb6/8jIzDQrOxLG+v/IyNA0KzsSxvr/yMjUNCsepw/sNCru81d/HqcP7DQoNCsjVxtoNCs7Esb6/8jI2DQrOxLG+v/IyNw0KzsSxvr/yMjgNCsepw/sNCru81d/HqcP7DQoNCrG4ICAgINeiDQoNCg0KDQoNCg0KDQrXoqO619S30c/uxL+w/MCos6yz9rv5sb7SvbGj1qe4tre2zqe1xNXvwcbP7sS/oaLSqca3oaK6xLLEo6iyu7D8uqy49sjLz8jQ0NfUuLbP7sS/o6mjrLOs1qe4trHq17y1xLSyzru30bXIoaM="; + String signature = "MEYCIQDvWclEztEGqpnd8J1zSxAnYMAwskI1P5Aznb5auDd2JwIhAJFD+EQ4CDDmMyG1GMnXnNC72+yEoWDjWMysGYypQVj6"; + return AjaxResult.success(emrCaService.generateBjCaTimestamp(oriDataBase64, signature)); + } + } diff --git a/ruoyi-admin/src/main/java/com/neuhis/his/domain/entity/his/MdcRcdInRecordSign.java b/ruoyi-admin/src/main/java/com/neuhis/his/domain/entity/his/MdcRcdInRecordSign.java new file mode 100644 index 000000000..6db56827d --- /dev/null +++ b/ruoyi-admin/src/main/java/com/neuhis/his/domain/entity/his/MdcRcdInRecordSign.java @@ -0,0 +1,79 @@ +package com.neuhis.his.domain.entity.his; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 电子病历CA签名对象 mdc_rcd_in_record_sign + * + * @author ruoyi + * @date 2025-03-13 + */ +@Getter +@Setter +@NoArgsConstructor +public class MdcRcdInRecordSign extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + private Long id; + + /** 住院病历ID */ + @Excel(name = "住院病历ID") + private Long inpatientRecordId; + + /** 签名人Code */ + @Excel(name = "签名人Code") + private String operCode; + + /** 签名人姓名 */ + @Excel(name = "签名人姓名") + private String operName; + + /** 签名时间 */ + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @Excel(name = "签名时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date signTime; + + /** 签名人级别Code */ + @Excel(name = "签名人级别Code") + private String profLevelId; + + /** 住院病历日志ID */ + @Excel(name = "住院病历日志ID") + private Long inpatientRecordLogId; + + /** 病历签名密文 */ + @Excel(name = "病历签名密文") + private String privateInfo; + + /** 授权人code */ + @Excel(name = "授权人code") + private String authorizeCode; + + /** CA签名证书Cert */ + @Excel(name = "CA签名证书Cert") + private String cert; + + /** 时间戳密文 */ + @Excel(name = "时间戳密文") + private String timeciphertext; + + /** 附属账号 */ + @Excel(name = "附属账号") + private String traineeName; + + /** 签名节ID */ + @Excel(name = "签名节ID") + private String sectionId; + + /** 签名原文BASE64后 */ + @Excel(name = "签名原文BASE64后") + private String oringinText; +} diff --git a/ruoyi-admin/src/main/java/com/neuhis/his/mapper/his/MdcRcdInRecordSignMapper.java b/ruoyi-admin/src/main/java/com/neuhis/his/mapper/his/MdcRcdInRecordSignMapper.java new file mode 100644 index 000000000..33d948666 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/neuhis/his/mapper/his/MdcRcdInRecordSignMapper.java @@ -0,0 +1,52 @@ +package com.neuhis.his.mapper.his; + +import com.neuhis.his.domain.entity.his.MdcRcdInRecordSign; + +import java.util.Date; +import java.util.List; + +/** + * 电子病历CA签名Mapper接口 + * + * @author ruoyi + * @date 2025-03-13 + */ +public interface MdcRcdInRecordSignMapper +{ + /** + * 查询电子病历CA签名 + * + * @param id 电子病历CA签名主键 + * @return 电子病历CA签名 + */ + MdcRcdInRecordSign selectMdcRcdRecordSignById(Long id); + + /** + * 查询电子病历CA签名列表 + * + * @param mdcRcdInRecordSign 电子病历CA签名 + * @return 电子病历CA签名集合 + */ + List selectMdcRcdRecordSignList(MdcRcdInRecordSign mdcRcdInRecordSign); + + /** + * 查询没有签名时间的签名数据 + */ + List getEmrUnTimestampList(Date startTime, Date endTime, int limit); + + /** + * 新增电子病历CA签名 + * + * @param mdcRcdInRecordSign 电子病历CA签名 + * @return 结果 + */ + int insertMdcRcdRecordSign(MdcRcdInRecordSign mdcRcdInRecordSign); + + /** + * 修改电子病历CA签名 + * + * @param mdcRcdInRecordSign 电子病历CA签名 + * @return 结果 + */ + int updateMdcRcdRecordSign(MdcRcdInRecordSign mdcRcdInRecordSign); +} diff --git a/ruoyi-admin/src/main/java/com/neuhis/his/service/his/IEmrCaService.java b/ruoyi-admin/src/main/java/com/neuhis/his/service/his/IEmrCaService.java new file mode 100644 index 000000000..e1b7f34df --- /dev/null +++ b/ruoyi-admin/src/main/java/com/neuhis/his/service/his/IEmrCaService.java @@ -0,0 +1,27 @@ +package com.neuhis.his.service.his; + +import com.neuhis.his.domain.entity.his.MdcRcdInRecordSign; + +import java.util.Date; +import java.util.List; + +/** + * EMR CA服务 + * + * @author dazer + * @date 2025/3/13 12:22 + **/ +public interface IEmrCaService { + /** + * 获取ERM没有时间戳的列表 + */ + List getEmrUnTimestampList(Date startTime, Date endTime, int limit); + + /** + * 生成电子病历北京CA签名时间戳 + * @param oriDataBase64 病历密文/签名密文BASE64的 + * @param signature 签名信息/签名值/私钥 + */ + String generateBjCaTimestamp(String oriDataBase64, String signature); + String generateBjCaTimestamp(MdcRcdInRecordSign recordSign); +} diff --git a/ruoyi-admin/src/main/java/com/neuhis/his/service/impl/his/EmrCaServiceImpl.java b/ruoyi-admin/src/main/java/com/neuhis/his/service/impl/his/EmrCaServiceImpl.java new file mode 100644 index 000000000..4792783e5 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/neuhis/his/service/impl/his/EmrCaServiceImpl.java @@ -0,0 +1,55 @@ +package com.neuhis.his.service.impl.his; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.neuhis.his.domain.entity.his.MdcRcdInRecordSign; +import com.neuhis.his.mapper.his.MdcRcdInRecordSignMapper; +import com.neuhis.his.service.IBjCaService; +import com.neuhis.his.service.his.IEmrCaService; +import com.ruoyi.common.annotation.DataSource; +import com.ruoyi.common.enums.DataSourceType; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +/** + * EMR CA服务 + * + * @author dazer + * @date 2025/3/13 15:31 + **/ +@Service +@DataSource(value = DataSourceType.SLAVE) +@Slf4j +public class EmrCaServiceImpl implements IEmrCaService { + @Resource + private MdcRcdInRecordSignMapper mdcRcdInRecordSignMapper; + @Autowired + private IBjCaService bjCaService; + + @Override + public List getEmrUnTimestampList(Date startTime, Date endTime, int limit) { + return mdcRcdInRecordSignMapper.getEmrUnTimestampList(startTime, endTime, limit); + } + + @Override + public String generateBjCaTimestamp(String oriDataBase64, String signature) { + if (StrUtil.isEmpty(oriDataBase64) || StrUtil.isEmpty(signature) || !Base64.isBase64(oriDataBase64)) { + return ""; + } + return bjCaService.createAndGetTssInfo(oriDataBase64, signature); + } + + @Override + public String generateBjCaTimestamp(MdcRcdInRecordSign recordSign) { + if (recordSign == null) { + return ""; + } + return generateBjCaTimestamp(recordSign.getOringinText(), recordSign.getCert()); + } +} diff --git a/ruoyi-admin/src/main/resources/bjca.properties b/ruoyi-admin/src/main/resources/bjca.properties index 0d70f2edd..5481cf0be 100644 --- a/ruoyi-admin/src/main/resources/bjca.properties +++ b/ruoyi-admin/src/main/resources/bjca.properties @@ -19,10 +19,14 @@ nhit.dc.ca.bjxt01.user_id:2122e89265cc291a00f8d20800bfd24c0f7f72db9225cb69a208dc # \u7B2C\u4E09\u65B9\u8D26\u53F7\u79D8\u94A5 #nhit.dc.ca.bjxt01.app-secret=MDAwNjY1MTZmMjczNDk4MDk2MzJhMTQ4OWYyZTdlNGE= -### \u54B8\u9633\u75C5\u5386 +### \u5317\u4EACCA\u534F\u540C\u7B7E\u540D-CA\u4EBA\u5458\u7ED9 nhit.dc.ca.bjxt01.app-id=APP_95BF9D123FCF498A83C344ED42473675 nhit.dc.ca.bjxt01.app-secret=MzI1ODNlYTI2ZjkwNDkzZjg3MDhjOTMwMDBlZDYwOTQ= +### \u54B8\u9633\u75C5\u5386-\u5317\u4EACCA\u534F\u540C\u7B7E\u540D BJCAXT\uFF0C\u751F\u4EA7 +#nhit.dc.ca.bjxt01.app-id=APP_9EE2EE50DD2F44B5B6449C8DF1E4115B +#nhit.dc.ca.bjxt01.app-secret=ZmJlMmE3YTYyNmUyNDI2YTgwMDAxODliYzkyZDhjZDM= + # \u67E5\u8BE2\u7528\u6237\u4FE1\u606F nhit.dc.ca.bjxt01.server-query-user-info=/service/v1/queryUserInfo diff --git a/ruoyi-admin/src/main/resources/mapper/his/MdcRcdInRecordSignMapper.xml b/ruoyi-admin/src/main/resources/mapper/his/MdcRcdInRecordSignMapper.xml new file mode 100644 index 000000000..2b7783ff4 --- /dev/null +++ b/ruoyi-admin/src/main/resources/mapper/his/MdcRcdInRecordSignMapper.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + select id, inpatient_record_id, oper_code, oper_name, sign_time, prof_level_id, inpatient_record_log_id, private_info, authorize_code, cert, timeciphertext, trainee_name, section_id, oringin_text from mdc_rcd_in_record_sign + + + + + + + + + + insert into mdc_rcd_in_record_sign + + id, + inpatient_record_id, + oper_code, + oper_name, + sign_time, + prof_level_id, + inpatient_record_log_id, + private_info, + authorize_code, + cert, + timeciphertext, + trainee_name, + section_id, + oringin_text, + + + #{id}, + #{inpatientRecordId}, + #{operCode}, + #{operName}, + #{signTime}, + #{profLevelId}, + #{inpatientRecordLogId}, + #{privateInfo}, + #{authorizeCode}, + #{cert}, + #{timeciphertext}, + #{traineeName}, + #{sectionId}, + #{oringinText}, + + + + + update mdc_rcd_in_record_sign + + inpatient_record_id = #{inpatientRecordId}, + oper_code = #{operCode}, + oper_name = #{operName}, + sign_time = #{signTime}, + prof_level_id = #{profLevelId}, + inpatient_record_log_id = #{inpatientRecordLogId}, + private_info = #{privateInfo}, + authorize_code = #{authorizeCode}, + cert = #{cert}, + timeciphertext = #{timeciphertext}, + trainee_name = #{traineeName}, + section_id = #{sectionId}, + oringin_text = #{oringinText}, + + where id = #{id} + + \ No newline at end of file