diff --git a/src/main/java/com/dpkj/common/config/ChsConfig.java b/src/main/java/com/dpkj/common/config/ChsConfig.java index 17ef7b5..bbe7d77 100644 --- a/src/main/java/com/dpkj/common/config/ChsConfig.java +++ b/src/main/java/com/dpkj/common/config/ChsConfig.java @@ -15,8 +15,34 @@ import org.springframework.stereotype.Component; public class ChsConfig { /** - * 医保机构编码 + * 医保机构代码 */ - private String orgcode; + private String orgId; + + /** + * 收款员编号 + */ + private String operatorId; + + /** + * 收款员姓名 + */ + private String operatorName; + + /** + * 科室编号 + */ + private String officeId; + + /** + * 科室名称 + */ + private String officeName; + + + /** + * 医保接口地址 + */ + private String url; } diff --git a/src/main/java/com/dpkj/modules/chs/constant/ChsDictEnum.java b/src/main/java/com/dpkj/modules/chs/constant/ChsDictEnum.java new file mode 100644 index 0000000..559fc67 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/constant/ChsDictEnum.java @@ -0,0 +1,325 @@ +package com.dpkj.modules.chs.constant; + +import lombok.Getter; + +public interface ChsDictEnum { + + /** + * 业务类型 + * + * @author 萧道子 2025/8/6 + */ + @Getter + enum BusinessType { + /** + * 医院 挂号 替代社保卡 (预约挂号,现场挂号,取号候诊) + */ + YY_101("01101"), + /** + * 医院 住院建档 替代身份证、社保卡 + */ + YY_102("01102"), + /** + * 医院 入院登记 替代社保卡 + */ + YY_103("01103"), + /** + * 医院 缴纳预缴金 替代住院押金卡 + */ + YY_104("01104"), + /** + * 医院 问诊 替代挂号条、社保卡 + */ + YY_201("01201"), + /** + * 医院 预约检查 替代检查凭条、社保卡 + */ + YY_202("01202"), + /** + * 医院 检查 替代检查凭条、社保卡 + */ + YY_203("01203"), + /** + * 医院 治疗 替代挂号条、社保卡 + */ + YY_204("01204"), + /** + * 医院 结算 替代社保卡(门诊结算,出院结算) + */ + YY_301("01301"), + /** + * 医院 取药 替代取药凭条、社保卡(门诊取药,出院带药) + */ + YY_302("01302"), + /** + * 医院 取报告 替代取报告凭条 + */ + YY_303("01303"), + /** + * 医院 打印票据和清单 替代挂号条、社保卡(打印收费清单,票据清单,结算单,异地就医结算单) + */ + YY_304("01304"), + /** + * 医院 病历材料复印 替代身份证、社保卡(门诊和住院各类材料复印) + */ + YY_305("01305"), + /** + * 医院 诊间核验身份 替代身份证、社保卡 + */ + YY_306("01306"), + /** + * 药店 药店购药 替代社保卡 + */ + YD_121("02121"), + /** + * 药店 下载外购处方 替代社保卡、身份证 + */ + YD_122("02122"), + /** + * 药店 特殊门诊 替代社保卡 + */ + YD_123("02123"), + /** + * 药店 药师审核处方 替代社保卡、身份证 + */ + YD_124("02124"), + + /** + * 医疗类APP 线上身份认证替代社保卡,目前地方医保 APP 都是绑定社保卡 + */ + APP_131("03131"), + /** + * 医疗类APP 线上结算替代社保卡,目前地方医保 APP 都是绑定社保卡 + */ + APP_132("03132"), + + /** + * 柜台 线下修改密码 线下经办柜台修改/重置医保电子凭证密码 + */ + GT_101("05101"), + /** + * 柜台 医保业务办理 线下经办柜台办理医保业务 + */ + GT_151("05151"); + + + private String code; + + BusinessType(String code) { + this.code = code; + } + + /** + * 获取值 + * + * @return java.lang.String + * @author 萧道子 2025/8/6 + */ + public String str() { + return this.code; + } + + } + + + /** + * 证件类型 + * + * @author 萧道子 2025/8/6 + */ + @Getter + enum CertificateType { + /** + * 居民身份证(户口簿) + */ + CODE_01("01"), + /** + * 中国人民解放军军官证 + */ + CODE_02("02"), + /** + * 中国人民武装警察警官证 + */ + CODE_03("03"), + /** + * 香港特区护照/港澳居民来往内地通行证 + */ + CODE_04("04"), + /** + * 澳门特区护照/港澳居民来往内地通行证 + */ + CODE_05("05"), + /** + * 台湾居民来往大陆通行证 + */ + CODE_06("06"), + /** + * 外国人永久居留证 + */ + CODE_07("07"), + /** + * 外国人护照 + */ + CODE_08("08"), + /** + * 残疾人证 + */ + CODE_09("09"), + /** + * 军烈属证明 + */ + CODE_10("10"), + /** + * 外国人就业证 + */ + CODE_11("11"), + /** + * 外国专家证 + */ + CODE_12("12"), + /** + * 外国人常驻记者证 + */ + CODE_13("13"), + /** + * 台港澳人员就业证 + */ + CODE_14("14"), + /** + * 回国(来华)定居专家证 + */ + CODE_15("15"), + /** + * 中国护照 + */ + CODE_16("16"), + /** + * 港澳台居民居住证 + */ + CODE_17("17"), + /** + * 社会保障卡 + */ + CODE_90("90"), + /** + * 其他身份证件 + */ + CODE_99("99"); + + + private String code; + + CertificateType(String code) { + this.code = code; + } + + /** + * 获取值 + * + * @return java.lang.String + * @author 萧道子 2025/8/6 + */ + public String str() { + return this.code; + } + + } + + + /** + * 订单状态 + * + * @author 萧道子 2025/8/6 + */ + @Getter + enum OrderStatus { + + /** + * 已保存 + */ + CODE_0("0"), + /** + * 预结算完成 + */ + CODE_1("1"), + /** + * 结算中 + */ + CODE_2("2"), + /** + * 自费完成 + */ + CODE_3("3"), + /** + * 医保支付完成 + */ + CODE_4("4"), + /** + * 院内结算完成 + */ + CODE_5("5"), + /** + * 结算完成 + */ + CODE_6("6"), + /** + * 已退款 + */ + CODE_7("7"), + /** + * 已医保全部退款 + */ + CODE_8("8"), + /** + * 仅自费全部退款 + */ + CODE_9("9"), + /** + * 仅自费部分退款 + */ + CODE_10("10"), + /** + * 医保全部退自费部分退款 + */ + CODE_11("11"), + /** + * 已撤销 + */ + CODE_12("12"), + /** + * 医保已撤销 + */ + CODE_13("13"), + /** + * 异常 + */ + CODE_14("14"), + /** + * 结算失败 + */ + CODE_15("15"), + /** + * 医保结算失败自费冲正失败 + */ + CODE_16("16"); + + private String code; + + OrderStatus(String code) { + this.code = code; + } + + /** + * 获取值 + * + * @return java.lang.String + * @author 萧道子 2025/8/6 + */ + public String str() { + return this.code; + } + + } + + +} diff --git a/src/main/java/com/dpkj/modules/chs/constant/NationECCodeConst.java b/src/main/java/com/dpkj/modules/chs/constant/NationECCodeConst.java new file mode 100644 index 0000000..bc79186 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/constant/NationECCodeConst.java @@ -0,0 +1,70 @@ +package com.dpkj.modules.chs.constant; + +public interface NationECCodeConst { + + /** + * 终端医保电子凭证码解码接口 + *

+ * 用于定点医疗药机构通过使用医保业务综合服务终端集成的扫码设备模块获取医保电子凭证二维码码值后,通过电子凭证中台完成解码。 + */ + String TRANSTYPE_ALICHS_QRCODEGET = "cn.nhsa.qrcode.get"; + + /** + * 刷脸获取医保用户身份授权接口 + *

+ * 定点医药机构通过医保业务综合服务终端的刷脸获取医保用户身份授权。 + */ + String TRANSTYPE_ALICHS_AUTH = "cn.nhsa.ec.auth"; + + /** + * 刷脸授权获取医保身份接口 + *

+ * 用于定点医药机构通过使用医保业务综合服务终端的刷脸模块,授权参保人通过刷脸进行医保身份认证。 + */ + String TRANSTYPE_ALICHS_AUTHCHECK = "cn.nhsa.auth.check"; + + /** + * 结算结果通知终端接口 + *

+ * 若定点医药机构没有通过终端完成医保移动支付,需要调用此接口在终端上显示结算结果。若定点医药机构通过终端完成医保移动支付,则不需要调用此接口。 + */ + String TRANSTYPE_ALICHS_NOTIFY = "cn.nhsa.settle.notify"; + + + /** + * 刷脸获取医保用户身份授权接口 + *

+ * 定点医药机构通过医保业务综合服务终端的刷脸获取医保用户身份授权 + */ + String TRANSTYPE_NATION_AUTH = "cn.nhsa.ec.auth"; + + /** + * 结算结果通知接口 + *

+ * 若定点医药机构没有通过终端完成医保移动支付,调用此接口在终端上显示结算结果或者退费结果 + */ + String TRANSTYPE_NATION_NOTIFY = "cn.nhsa.settle.notify"; + + /** + * 终端医保移动支付接口 + *

+ * 医生开具诊断或者用户购药,定点医药机构通过支付中心完成费用上传后,调用终端进行医保移动支付 + */ + String TRANSTYPE_NATION_MEDICALPAY = "cn.nhsa.medical.pay"; + + /** + * 身份证读卡器接口 + *

+ * 调用终端,终端将打开身份证读卡页面,引导用户扫描身份证,获取用户身份信息 + */ + String TRANSTYPE_NATION_CERTGET = "cn.nhsa.cert.get"; + + /** + * 刷脸核身接口 + *

+ * 定点医药机构通过医保业务综合服务终端的刷脸获取医保用户身份授权,用户授权成功后,医保电子凭证动态库调用医保电子凭证中心进行获取医保用户身份信息 + */ + String TRANSTYPE_NATION_CERTCHECK = "cn.nhsa.cert.check"; + + +} diff --git a/src/main/java/com/dpkj/modules/chs/controller/AlipayController.java b/src/main/java/com/dpkj/modules/chs/controller/AlipayController.java deleted file mode 100644 index b45ddd5..0000000 --- a/src/main/java/com/dpkj/modules/chs/controller/AlipayController.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.dpkj.modules.chs.controller; - -import com.dpkj.modules.chs.service.IAlipayService; -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * @Auther: 萧道子 - * @Date: 2025/3/22 16:25 - * @Description: 医保模块-阿里设备 - */ -@Slf4j -@AllArgsConstructor -@RestController -@RequestMapping("/chs/alipay") -public class AlipayController { - private final IAlipayService alipayService; - -} diff --git a/src/main/java/com/dpkj/modules/chs/controller/PadChsPayController.java b/src/main/java/com/dpkj/modules/chs/controller/PadChsPayController.java new file mode 100644 index 0000000..ec1deb8 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/controller/PadChsPayController.java @@ -0,0 +1,66 @@ +package com.dpkj.modules.chs.controller; + +import com.dpkj.common.vo.Result; +import com.dpkj.modules.chs.model.ChsModel; +import com.dpkj.modules.chs.response.ChsCheckResponse; +import com.dpkj.modules.chs.response.ChsQrcodeResponse; +import com.dpkj.modules.chs.service.IPadChsPayService; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Auther: 萧道子 + * @Date: 2025/3/22 16:25 + * @Description: 医保模块-阿里设备 + */ +@Slf4j +@AllArgsConstructor +@RestController +@RequestMapping("/chs/pad") +public class PadChsPayController { + private final IPadChsPayService padChsPayService; + + + /** + * 医保二维码解码 获取用户信息 + * + * @param val : + * @return com.dpkj.common.vo.Result + * @author 萧道子 2025/8/1 + */ + @PostMapping("getInfoByQrcode") + public Result getInfoByQrcode(@RequestBody @Validated ChsModel val) { + try { + ChsQrcodeResponse result = padChsPayService.qrcodeGet(val); + return Result.ok("成功", result); + } catch (Exception e) { + e.printStackTrace(); + return Result.error("医保扫码失败:" + e.getMessage()); + } + } + + /** + * 刷脸认证-获取用户信息 + * + * @param val : + * @return com.dpkj.common.vo.Result + * @author 萧道子 2025/8/1 + */ + @PostMapping("getInfoByFace") + public Result getInfoByFace(@RequestBody @Validated ChsModel val) { + try { + ChsCheckResponse result = padChsPayService.getInfoByFace(val); + return Result.ok("成功", result); + } catch (Exception e) { + e.printStackTrace(); + return Result.error("医保扫码失败:" + e.getMessage()); + } + } + + +} diff --git a/src/main/java/com/dpkj/modules/chs/dll/AlipayDll.java b/src/main/java/com/dpkj/modules/chs/dll/PadChsPayDll.java similarity index 50% rename from src/main/java/com/dpkj/modules/chs/dll/AlipayDll.java rename to src/main/java/com/dpkj/modules/chs/dll/PadChsPayDll.java index 09242b0..6d11501 100644 --- a/src/main/java/com/dpkj/modules/chs/dll/AlipayDll.java +++ b/src/main/java/com/dpkj/modules/chs/dll/PadChsPayDll.java @@ -11,20 +11,26 @@ import lombok.extern.slf4j.Slf4j; * @Description: */ @Slf4j -public class AlipayDll { +public class PadChsPayDll { /** - * 获取 AlipayDll 实例,同时注册 AlipayDll 控件。 + * 获取 PadChsPayDll 实例,同时注册 PadChsPayDll 控件。 * - * @return AlipayDll 实例 + * @return PadChsPayDll 实例 * @throws DllRegistrationException 如果注册控件失败,抛出此异常 */ - public static Dll instance() throws DllRegistrationException { + public static EcDll instance() throws DllRegistrationException { try { - return Native.load("AlipayChs", Dll.class); + EcDll dll = Native.load("NationECCode", EcDll.class); + + // 加载动态库 + Native.load("libeay32", EcDll.class); + Native.load("ssleay32", EcDll.class); + + return dll; } catch (UnsatisfiedLinkError e) { - log.info("[AlipayDll][getPrintSDK][医保动态库] SDK注册失败:{}", e.getMessage()); - throw new DllRegistrationException("Failed to load AlipayDll library: ", e); + log.info("[PadChsPayDll][instance][医保动态库] SDK注册失败:{}", e.getMessage()); + throw new DllRegistrationException("Failed to load PadChsPayDll library: ", e); } } @@ -45,12 +51,16 @@ public class AlipayDll { /** * 定义接口映射本地库中的函数。 */ - public interface Dll extends Library { + public interface EcDll extends Library { /** - * 设置打印端口和波特率。 + * 交易接口调用函数 * - * @return 返回操作结果代码 + * @param strUrl : 业务请求地址 + * @param InData : 交易请求数据 - JSON格式字符串 + * @param OutData : 交易返回数据 - code为0时,交易成功;否则返回错误信息说明 + * @return java.lang.String 返回字符串 0000 为动态库调用成功 + * @author 萧道子 2025/7/30 */ String NationEcTrans(String strUrl, String InData, Pointer OutData); diff --git a/src/main/java/com/dpkj/modules/chs/entity/AlipayEcRequestData.java b/src/main/java/com/dpkj/modules/chs/entity/AlipayEcRequestData.java deleted file mode 100644 index 2b75ded..0000000 --- a/src/main/java/com/dpkj/modules/chs/entity/AlipayEcRequestData.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.dpkj.modules.chs.entity; - -import com.alibaba.fastjson.JSONObject; -import lombok.Data; -import lombok.experimental.Accessors; - -import java.io.Serializable; - -/** - * @Auther: 萧道子 - * @Date: 2025/3/23 11:56 - * @Description: 医保请求 - */ -@Data -@Accessors(chain = true) -public class AlipayEcRequestData implements Serializable { - private static final long serialVersionUID = 1L; - - - /** - * 机构 ID 必填 - */ - private String orgId; - - /** - * 交易类型 必填 - * ec.query: 电子凭证二维码解码接口 - * cn.nhsa.qrcode.get: 终端医保电子凭证码解码接口 - * cn.nhsa.auth.check:刷脸授权获取医保身份接口 - * cn.nhsa.ec.pwd: 医保电子凭证密码核验接口 - */ - private String transType; - - /** - * 接口请求参数 JSON格式字符串 必填 - */ - private JSONObject data; - - /** - * 扩展参数 JSON格式字符串 - */ - private JSONObject extra; - -} diff --git a/src/main/java/com/dpkj/modules/chs/model/ChsModel.java b/src/main/java/com/dpkj/modules/chs/model/ChsModel.java new file mode 100644 index 0000000..0f27f43 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/model/ChsModel.java @@ -0,0 +1,32 @@ +package com.dpkj.modules.chs.model; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.io.Serializable; + +/** + * @Auther: 萧道子 + * @Date: 2025/8/1 10:07 + * @Description: + */ +@Data +@SuperBuilder +@NoArgsConstructor +public class ChsModel implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 医保科室编号 + */ + // @NotEmpty(message = "科室编号不可为空") + private String officeId; + + /** + * 科室名称 + */ + // @NotEmpty(message = "科室名称不可为空") + private String officeName; + +} diff --git a/src/main/java/com/dpkj/modules/chs/request/ChsAuthRequest.java b/src/main/java/com/dpkj/modules/chs/request/ChsAuthRequest.java new file mode 100644 index 0000000..a696875 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/request/ChsAuthRequest.java @@ -0,0 +1,27 @@ +package com.dpkj.modules.chs.request; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.SuperBuilder; + +import java.io.Serializable; + +/** + * @Auther: 萧道子 + * @Date: 2025/3/23 11:56 + * @Description: 刷脸获取医保用户身份授权接口-响应 + */ +@Data +@Accessors(chain = true) +@SuperBuilder +@NoArgsConstructor +public class ChsAuthRequest extends ChsRequestBase implements Serializable { + private static final long serialVersionUID = 1L; + + @Override + public String toString() { + return JSONObject.toJSONString(this); + } +} diff --git a/src/main/java/com/dpkj/modules/chs/request/ChsCheckRequest.java b/src/main/java/com/dpkj/modules/chs/request/ChsCheckRequest.java new file mode 100644 index 0000000..a27a122 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/request/ChsCheckRequest.java @@ -0,0 +1,32 @@ +package com.dpkj.modules.chs.request; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.SuperBuilder; + +import java.io.Serializable; + +/** + * @Auther: 萧道子 + * @Date: 2025/3/23 11:56 + * @Description: 刷脸授权获取医保身份接口-响应 + */ +@Data +@Accessors(chain = true) +@SuperBuilder +@NoArgsConstructor +public class ChsCheckRequest extends ChsRequestBase implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 实人认证业务流水号 + */ + private String authNo; + + @Override + public String toString() { + return JSONObject.toJSONString(this); + } +} diff --git a/src/main/java/com/dpkj/modules/chs/request/ChsNotifyRequest.java b/src/main/java/com/dpkj/modules/chs/request/ChsNotifyRequest.java new file mode 100644 index 0000000..4506085 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/request/ChsNotifyRequest.java @@ -0,0 +1,207 @@ +package com.dpkj.modules.chs.request; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.List; + +/** + * @Auther: 萧道子 + * @Date: 2025/3/23 11:56 + * @Description: 结算结果通知终端接口-响应 + */ +@Data +@Accessors(chain = true) +@NoArgsConstructor +public class ChsNotifyRequest implements Serializable { + private static final long serialVersionUID = 1L; + + + /** + * 核身或者刷脸的医疗机构业务流水号 + *

+ * 需要传核身接口或者电子凭证接口里的流水号(因为需要将核身结果与医保结算结果相对应。) + */ + private String outBizNo; + /** + * 医保/自费结算状态 + *

+ * SUCCESS:结算成功 + * FAIL:结算失败 + */ + private String medicalSettleState; + /** + * 实人认证业务流水号 + *

+ * 用于后续与中台交互换取身份信息 + */ + private String authNo; + /** + * 收款员编号 + */ + private String operatorId; + /** + * 收款员姓名 + */ + private String operatorName; + /** + * 总费用 + */ + private String totalFee; + /** + * 业务场景 + *

+ * register:挂号窗口 + * settle :诊间 + */ + private String bizType; + /** + * 身份证 + */ + private String idNo; + /** + * 姓名 + */ + private String userName; + /** + * 结算时间 + */ + private String setlTime; + /** + * 医院名称 + */ + private String hospitalName; + /** + * 科室编号 + */ + private String officeId; + /** + * 科室名称 + */ + private String officeName; + /** + * 医生 + */ + private String doctorName; + + // -----以下当medicalSettleState二SUCCESS时,需要传以下值(自费不需要传)----------------------- + + + /** + * 医保单据流水号 + */ + private String medicalSettleNo; + /** + * 自费费用 + */ + private String ownAmt; + /** + * 医保报销费用 + */ + private String hifAmt; + /** + * 个人帐户支出 + */ + private String acctAmt; + /** + * 统筹基金支出 + */ + private String hifpAmt; + /** + * 大额医疗保险支出 + */ + private String hifmiAmt; + /** + * 公务员补助 + */ + private String cvlservAmt; + /** + * 医疗救助 + */ + private String maAmt; + /** + * 单病种定点医疗机构垫支 + */ + private String hosPreAmt; + /** + * 药品超标扣款金额 + */ + private String medOverLmtAmt; + /** + * 扶贫救助 + */ + private String mafAmt; + /** + * 历史起付公务员返还 + */ + private String cvlservDedcAmt; + /** + * 帐户余额 + */ + private String balance; + /** + * 药品明细 + */ + private List drugList; + + @Data + @Accessors(chain = true) + public static class Drug { + /** + * 项目编号 + *

+ * 对照医保项目编码 + */ + private String ITEM_NO; + /** + * 项目名称 + */ + private String ITEMNAME; + /** + * 发票项目编号 + *

+ * 对照应医保发票项目编码 + */ + private String INVO_ITEM_NO; + /** + * 是否医保项目 + *

+ * Y是 + * N否 + */ + private String HI_ITEM; + /** + * 项目单价 + */ + private String PRIC; + /** + * 项目数量 + */ + private String ITEM_CNT; + /** + * 项目金额 + */ + private String ITEM_AMT; + /** + * 药品频率 + */ + private String DRUG_FRQU; + /** + * 药品用量 + */ + private String DRUG_DOS; + + @Override + public String toString() { + return JSONObject.toJSONString(this); + } + } + + @Override + public String toString() { + return JSONObject.toJSONString(this); + } +} diff --git a/src/main/java/com/dpkj/modules/chs/request/ChsQrcodeRequest.java b/src/main/java/com/dpkj/modules/chs/request/ChsQrcodeRequest.java new file mode 100644 index 0000000..8efe3b7 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/request/ChsQrcodeRequest.java @@ -0,0 +1,25 @@ +package com.dpkj.modules.chs.request; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.io.Serializable; + +/** + * @Auther: 萧道子 + * @Date: 2025/3/23 11:56 + * @Description: 终端医保电子凭证码解码接口-请求 + */ +@Data +@SuperBuilder +@NoArgsConstructor +public class ChsQrcodeRequest extends ChsRequestBase implements Serializable { + private static final long serialVersionUID = 1L; + + @Override + public String toString() { + return JSONObject.toJSONString(this); + } +} diff --git a/src/main/java/com/dpkj/modules/chs/request/ChsRequestBase.java b/src/main/java/com/dpkj/modules/chs/request/ChsRequestBase.java new file mode 100644 index 0000000..5c2f8b0 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/request/ChsRequestBase.java @@ -0,0 +1,88 @@ +package com.dpkj.modules.chs.request; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.SuperBuilder; + +import java.io.Serializable; + +/** + * @Auther: 萧道子 + * @Date: 2025/7/31 09:38 + * @Description: 医保请求基础参数 + */ +@Data +@SuperBuilder +@Accessors(chain = true) +@NoArgsConstructor +public class ChsRequestBase implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 机构 ID + */ + private String orgId; + + /** + * 定点医药机构本次业务流水号 + *

+ * 不可重复,每次请求需要唯一 + */ + private String outBizNo; + + /** + * 用码业务类型 + *

+ * 01101 医院 挂号 替代社保卡 (预约挂号,现场挂号,取号候诊) + * 01102 医院 住院建档 替代身份证、社保卡 + * 01103 医院 入院登记 替代社保卡 + * 01104 医院 缴纳预缴金 替代住院押金卡 + * 01201 医院 问诊 替代挂号条、社保卡 + * 01202 医院 预约检查 替代检查凭条、社保卡 + * 01203 医院 检查 替代检查凭条、社保卡 + * 01204 医院 治疗 替代挂号条、社保卡 + * 01301 医院 结算 替代社保卡(门诊结算,出院结算) + * 01302 医院 取药 替代取药凭条、社保卡(门诊取药,出院带药) + * 01303 医院 取报告 替代取报告凭条 + * 01304 医院 打印票据和清单 替代挂号条、社保卡(打印收费清单,票据清单,结算单,异地就医结算单) + * 01305 医院 病历材料复印 替代身份证、社保卡(门诊和住院各类材料复印) + * 01306 医院 诊间核验身份 替代身份证、社保卡 + * 02121 药店 药店购药 替代社保卡 + * 02122 药店 下载外购处方 替代社保卡、身份证 + * 02123 药店 特殊门诊 替代社保卡 + * 02124 药店 药师审核处方 替代社保卡、身份证 + * 03131 医疗类APP 线上身份认证替代社保卡,目前地方医保 APP 都是绑定社保卡 + * 03132 医疗类APP 线上结算替代社保卡,目前地方医保 APP 都是绑定社保卡 + * 05101 柜台 线下修改密码 线下经办柜台修改/重置医保电子凭证密码 + * 05151 柜台 医保业务办理 线下经办柜台办理医保业务 + */ + private String businessType; + + /** + * 收款员编号 + */ + private String operatorId; + + /** + * 收款员姓名 + */ + private String operatorName; + + /** + * 医保科室编号 + */ + private String officeId; + + /** + * 科室名称 + */ + private String officeName; + + /** + * 扩展参数 - JSON 对象字符串 + */ + private JSONObject extData; + +} diff --git a/src/main/java/com/dpkj/modules/chs/request/ChsRequestCommon.java b/src/main/java/com/dpkj/modules/chs/request/ChsRequestCommon.java new file mode 100644 index 0000000..4f0c7b0 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/request/ChsRequestCommon.java @@ -0,0 +1,54 @@ +package com.dpkj.modules.chs.request; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import lombok.experimental.SuperBuilder; + +import java.io.Serializable; + +/** + * @Auther: 萧道子 + * @Date: 2025/7/31 09:38 + * @Description: 医保请求公共类 + */ +@Data +@NoArgsConstructor +@Accessors(chain = true) +@SuperBuilder +public class ChsRequestCommon implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 机构 ID + */ + private String orgId; + + /** + * 交易类型 + */ + private String transType; + + /** + * 接口请求参数 - 800K JSON 格式字符串 + */ + private JSONObject data; + + /** + * 扩展参数 - 800K JSON 格式字符串 + */ + private JSONObject extData; + + + public ChsRequestCommon(String orgId, String transType, JSONObject data) { + this.orgId = orgId; + this.transType = transType; + this.data = data; + } + + @Override + public String toString() { + return JSONObject.toJSONString(this); + } +} diff --git a/src/main/java/com/dpkj/modules/chs/response/ChsAuthResponse.java b/src/main/java/com/dpkj/modules/chs/response/ChsAuthResponse.java new file mode 100644 index 0000000..c416d16 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/response/ChsAuthResponse.java @@ -0,0 +1,38 @@ +package com.dpkj.modules.chs.response; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * @Auther: 萧道子 + * @Date: 2025/3/23 11:56 + * @Description: 刷脸获取医保用户身份授权接口-响应 + */ +@Data +@Accessors(chain = true) +public class ChsAuthResponse implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 实人认证业务流水号 + */ + private String authNo; + + /** + * 定点医药机构本次业务流水号 + */ + private String outBizNo; + + /** + * 扩展参数 + */ + private JSONObject extData; + + @Override + public String toString() { + return JSONObject.toJSONString(this); + } +} diff --git a/src/main/java/com/dpkj/modules/chs/response/ChsCheckResponse.java b/src/main/java/com/dpkj/modules/chs/response/ChsCheckResponse.java new file mode 100644 index 0000000..ed176a0 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/response/ChsCheckResponse.java @@ -0,0 +1,71 @@ +package com.dpkj.modules.chs.response; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * @Auther: 萧道子 + * @Date: 2025/3/23 11:56 + * @Description: 刷脸授权获取医保身份接口-响应 + */ +@Data +@Accessors(chain = true) +public class ChsCheckResponse implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 实人认证业务流水号 + */ + private String authNo; + /** + * 参保人身份证 + */ + private String idNo; + /** + * 证件类型 + */ + private String idType; + /** + * 参保人姓名 + */ + private String userName; + /** + * 令牌 + */ + private String ecToken; + /** + * 参保地区编码 + */ + private String insuOrg; + /** + * 电子凭证索引号 + */ + private String ecIndexNo; + /** + * 性别 + */ + private String gender; + /** + * 出生日期 + */ + private String birthday; + /** + * 国籍 + */ + private String nationality; + /** + * 电子邮箱 + */ + private String email; + /** + * 扩展参数 + */ + private JSONObject extra; + + @Override + public String toString() { + return JSONObject.toJSONString(this); + } +} diff --git a/src/main/java/com/dpkj/modules/chs/response/ChsQrcodeResponse.java b/src/main/java/com/dpkj/modules/chs/response/ChsQrcodeResponse.java new file mode 100644 index 0000000..7ca8dee --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/response/ChsQrcodeResponse.java @@ -0,0 +1,68 @@ +package com.dpkj.modules.chs.response; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * @Auther: 萧道子 + * @Date: 2025/3/23 11:56 + * @Description: 终端医保电子凭证码解码接口-响应 + */ +@Data +@Accessors(chain = true) +public class ChsQrcodeResponse implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 参保人身份证 + */ + private String idNo; + /** + * 证件类型 + */ + private String idType; + /** + * 参保人姓名 + */ + private String userName; + /** + * 令牌 + */ + private String ecToken; + /** + * 参保地区编码 + */ + private String insuOrg; + /** + * 电子凭证索引号 + */ + private String ecIndexNo; + /** + * 性别 + */ + private String gender; + /** + * 出生日期 + */ + private String birthday; + /** + * 国籍 + */ + private String nationality; + /** + * 电子邮箱 + */ + private String email; + /** + * 扩展参数 + */ + private JSONObject extra; + + @Override + public String toString() { + return JSONObject.toJSONString(this); + } +} diff --git a/src/main/java/com/dpkj/modules/chs/response/ChsResponseCommon.java b/src/main/java/com/dpkj/modules/chs/response/ChsResponseCommon.java new file mode 100644 index 0000000..4afb1b5 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/response/ChsResponseCommon.java @@ -0,0 +1,43 @@ +package com.dpkj.modules.chs.response; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; + +import java.io.Serializable; + +/** + * @Auther: 萧道子 + * @Date: 2025/7/31 09:38 + * @Description: 医保请求公共类 + */ +@Data +public class ChsResponseCommon implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 机构 ID + */ + private String orgId; + + /** + * 返回码 + * 接口返回值非 0 时,该出参为交易错误信息,详见表 7 返回值代码表 + */ + private String code; + + /** + * 返回信息 + * code 非 0 时有效 + */ + private String message; + + /** + * 接口请求参数 - 800K JSON 格式字符串 + */ + private T data; + + /** + * 扩展参数 - 800K JSON 格式字符串 + */ + private JSONObject extData; +} diff --git a/src/main/java/com/dpkj/modules/chs/service/IAlipayService.java b/src/main/java/com/dpkj/modules/chs/service/IAlipayService.java deleted file mode 100644 index e4dc9b4..0000000 --- a/src/main/java/com/dpkj/modules/chs/service/IAlipayService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.dpkj.modules.chs.service; - -public interface IAlipayService { -} diff --git a/src/main/java/com/dpkj/modules/chs/service/IPadChsPayService.java b/src/main/java/com/dpkj/modules/chs/service/IPadChsPayService.java new file mode 100644 index 0000000..07fecc2 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/service/IPadChsPayService.java @@ -0,0 +1,24 @@ +package com.dpkj.modules.chs.service; + +import com.dpkj.modules.chs.model.ChsModel; +import com.dpkj.modules.chs.response.ChsCheckResponse; +import com.dpkj.modules.chs.response.ChsQrcodeResponse; + +public interface IPadChsPayService { + + /** + * 获取医保二维码解码参数 + * + * @return com.dpkj.modules.chs.response.ChsQrcodeResponse + * @author 萧道子 2025/7/31 + */ + ChsQrcodeResponse qrcodeGet(ChsModel val); + + /** + * 刷脸认证-调取刷脸 + * + * @return com.dpkj.modules.chs.response.ChsQrcodeResponse + * @author 萧道子 2025/7/31 + */ + ChsCheckResponse getInfoByFace(ChsModel val); +} diff --git a/src/main/java/com/dpkj/modules/chs/service/impl/AlipayServiceImpl.java b/src/main/java/com/dpkj/modules/chs/service/impl/AlipayServiceImpl.java deleted file mode 100644 index f6bc781..0000000 --- a/src/main/java/com/dpkj/modules/chs/service/impl/AlipayServiceImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.dpkj.modules.chs.service.impl; - -import com.dpkj.modules.chs.dll.AlipayDll; -import com.dpkj.modules.chs.service.IAlipayService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import javax.annotation.PostConstruct; - -/** - * @Auther: 萧道子 - * @Date: 2025/3/22 16:29 - * @Description: - */ -@Slf4j -@Service -public class AlipayServiceImpl implements IAlipayService { - - private AlipayDll.Dll dll; - - - @PostConstruct - public void postConstruct() { - log.info("[AlipayServiceImpl][postConstruct][医保DLL] 初始化动态链接库"); - try { - dll = AlipayDll.instance(); - } catch (AlipayDll.DllRegistrationException e) { - // TODO 萧道子 2025/6/19 : - } - initPrinter(); - } - - - private void initPrinter() { - - } -} diff --git a/src/main/java/com/dpkj/modules/chs/service/impl/HispayServiceImpl.java b/src/main/java/com/dpkj/modules/chs/service/impl/HispayServiceImpl.java index e443387..dd315c7 100644 --- a/src/main/java/com/dpkj/modules/chs/service/impl/HispayServiceImpl.java +++ b/src/main/java/com/dpkj/modules/chs/service/impl/HispayServiceImpl.java @@ -61,7 +61,7 @@ public class HispayServiceImpl implements IHispayService { log.info("[HispayServiceImpl][instanceActive][HIS医保COM库] 加载成功"); return activeXComponent; } catch (UnsatisfiedLinkError e) { - log.info("[HispayServiceImpl][instanceActive][HIS医保COM库] 加载失败:{}", e.getMessage()); + log.error("[HispayServiceImpl][instanceActive][HIS医保COM库] 加载失败:{}", e.getMessage()); throw new RuntimeException("HIS医保COM库加载失败:" + e.getMessage(), e); } } @@ -137,14 +137,14 @@ public class HispayServiceImpl implements IHispayService { .fluentPut("hzxm", "") // 患者姓名 .fluentPut("phone", ""); // 患者电话号码 String params = processParameters(val, null); - log.info("[HispayServiceImpl][readCode][医保读卡-电子凭证] 接口入参:{}", params); + log.debug("[HispayServiceImpl][readCode][医保读卡-电子凭证] 接口入参:{}", params); /** 2、调用COM函数 */ Variant vres = new Variant("", true); Variant call = Dispatch.call(dispatch, "fRun", "BMZXX010", params, vres); String resStr = vres.getStringRef(); - log.info("[HispayServiceImpl][readCode][医保读卡-电子凭证] call返回值:{} 结果:{}", call, resStr); + log.debug("[HispayServiceImpl][readCode][医保读卡-电子凭证] call返回值:{} 结果:{}", call, resStr); /** 3、处理读卡结果 */ @@ -167,14 +167,14 @@ public class HispayServiceImpl implements IHispayService { .fluentPut("hzxm", "") // 患者姓名 .fluentPut("phone", ""); // 患者电话号码 String params = processParameters(val, password); - log.info("[HispayServiceImpl][readCard][医保读卡-医保卡] 接口入参:{}", params); + log.debug("[HispayServiceImpl][readCard][医保读卡-医保卡] 接口入参:{}", params); /** 2、调用COM函数 */ Variant vres = new Variant("", true); Variant call = Dispatch.call(dispatch, "fRun", "BMZXX010", params, vres); String resStr = vres.getStringRef(); - log.info("[HispayServiceImpl][readCard][医保读卡-医保卡] call返回值:{} 结果:{}", call, resStr); + log.debug("[HispayServiceImpl][readCard][医保读卡-医保卡] call返回值:{} 结果:{}", call, resStr); /** 3、处理读卡结果 */ JSONObject result = verifyResult(resStr); @@ -196,7 +196,7 @@ public class HispayServiceImpl implements IHispayService { .fluentPut("zfjsbz", "0") // 是否自费结算,0根据医保代码缴费,1自费结算(默认自费结算) .fluentPut("ybrc", ""); // 医保入参,xml节点 String params = processParameters(val, data.getPassword()); - log.info("[HispayServiceImpl][outpatientBudget][门诊缴费-预算] 接口入参:{}", params); + log.debug("[HispayServiceImpl][outpatientBudget][门诊缴费-预算] 接口入参:{}", params); String requestTime = DateUtil.now(); @@ -206,7 +206,7 @@ public class HispayServiceImpl implements IHispayService { String responseTime = DateUtil.now(); String resStr = resVariant.getStringRef(); - log.info("[HispayServiceImpl][outpatientBudget][门诊缴费-预算] call返回值:{} 结果:{}", call, resStr); + log.debug("[HispayServiceImpl][outpatientBudget][门诊缴费-预算] call返回值:{} 结果:{}", call, resStr); /** 3、处理结果 */ @@ -249,7 +249,7 @@ public class HispayServiceImpl implements IHispayService { .fluentPut("ptlsh", "") .fluentPut("jysm", ""); String params = processParameters(val, null); - log.info("[HispayServiceImpl][chsCodeAsOutpatientFinal][门诊缴费-结算] 接口入参:{}", params); + log.debug("[HispayServiceImpl][chsCodeAsOutpatientFinal][门诊缴费-结算] 接口入参:{}", params); /** 2、调用COM函数 */ Variant resVariant = new Variant("", true); @@ -257,7 +257,7 @@ public class HispayServiceImpl implements IHispayService { String responseTime = DateUtil.now(); String resStr = resVariant.getStringRef(); - log.info("[HispayServiceImpl][chsCodeAsOutpatientFinal][门诊缴费-结算] call返回值:{} 结果:{}", call, resStr); + log.debug("[HispayServiceImpl][chsCodeAsOutpatientFinal][门诊缴费-结算] call返回值:{} 结果:{}", call, resStr); /** 3、处理结果 */ JSONObject result = verifyResult(resStr); diff --git a/src/main/java/com/dpkj/modules/chs/service/impl/PadChsPayServiceImpl.java b/src/main/java/com/dpkj/modules/chs/service/impl/PadChsPayServiceImpl.java new file mode 100644 index 0000000..e700f06 --- /dev/null +++ b/src/main/java/com/dpkj/modules/chs/service/impl/PadChsPayServiceImpl.java @@ -0,0 +1,228 @@ +package com.dpkj.modules.chs.service.impl; + +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.TypeReference; +import com.dpkj.common.config.ChsConfig; +import com.dpkj.common.utils.IDGenerator; +import com.dpkj.modules.chs.constant.ChsDictEnum; +import com.dpkj.modules.chs.constant.NationECCodeConst; +import com.dpkj.modules.chs.dll.PadChsPayDll; +import com.dpkj.modules.chs.model.ChsModel; +import com.dpkj.modules.chs.request.ChsAuthRequest; +import com.dpkj.modules.chs.request.ChsCheckRequest; +import com.dpkj.modules.chs.request.ChsQrcodeRequest; +import com.dpkj.modules.chs.request.ChsRequestCommon; +import com.dpkj.modules.chs.response.ChsAuthResponse; +import com.dpkj.modules.chs.response.ChsCheckResponse; +import com.dpkj.modules.chs.response.ChsQrcodeResponse; +import com.dpkj.modules.chs.response.ChsResponseCommon; +import com.dpkj.modules.chs.service.IPadChsPayService; +import com.sun.jna.Memory; +import com.sun.jna.Pointer; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; + +/** + * @Auther: 萧道子 + * @Date: 2025/3/22 16:29 + * @Description: + */ +@Slf4j +@Service +public class PadChsPayServiceImpl implements IPadChsPayService { + + private PadChsPayDll.EcDll dll; + + @Autowired + private ChsConfig chsConfig; + + + @PostConstruct + public void postConstruct() { + log.info("[PadChsPayServiceImpl][postConstruct][Ali医保DLL] 初始化动态链接库"); + try { + dll = PadChsPayDll.instance(); + } catch (PadChsPayDll.DllRegistrationException e) { + log.error("[PadChsPayServiceImpl][postConstruct][PAD保DLL] 加载失败:{}", e.getMessage()); + throw new RuntimeException("Ali医保DLL库加载失败:" + e.getMessage(), e); + } + initPrinter(); + } + + + private void initPrinter() { + // TODO 萧道子 2025/7/31 : + } + + @Override + public ChsQrcodeResponse qrcodeGet(ChsModel val) { + log.debug("[PadChsPayServiceImpl][getInfoByQrcode][终端医保电子凭证码解码接口] 接收参数:{}", val); + + // 封装入参 + String outBizNo = IDGenerator.getSnowflakeIdToStr(); + ChsQrcodeRequest data = ChsQrcodeRequest.builder() + .orgId(chsConfig.getOrgId()) + .outBizNo(outBizNo) + .businessType(ChsDictEnum.BusinessType.YY_201.str()) + .operatorId(chsConfig.getOperatorId()) + .operatorName(chsConfig.getOperatorName()) + .officeId(StrUtil.isNotEmpty(val.getOfficeId()) ? val.getOfficeId() : chsConfig.getOfficeId()) + .officeName(StrUtil.isNotEmpty(val.getOfficeName()) ? val.getOfficeName() : chsConfig.getOfficeName()) + .build(); + ChsRequestCommon request = new ChsRequestCommon(chsConfig.getOrgId(), NationECCodeConst.TRANSTYPE_ALICHS_QRCODEGET, JSONObject.parseObject(data.toString())); + log.debug("[PadChsPayServiceImpl][getInfoByQrcode][终端医保电子凭证码解码接口] 入参:{}", request.toString()); + + DateTime requestTime = DateUtil.date(); + + // 调用接口 + Pointer resp = new Memory(1024 * 10); + String resultStr = dll.NationEcTrans(chsConfig.getUrl(), request.toString(), resp); + String response = resp.getString(0, "GB2312"); + + DateTime responseTime = DateUtil.date(); + log.debug("[PadChsPayServiceImpl][getInfoByQrcode][终端医保电子凭证码解码接口] 响应:{} 出参:{}", resultStr, response); + log.debug("[PadChsPayServiceImpl][getInfoByQrcode][终端医保电子凭证码解码接口] 调用耗时:{} ms ", DateUtil.betweenMs(responseTime, requestTime)); + + // 处理转换参数 + ChsResponseCommon respCommon = JSONObject.parseObject(response, new TypeReference>() { + }); + if (!StrUtil.equals("0", respCommon.getCode())) { + log.error("[PadChsPayServiceImpl][getInfoByQrcode][终端医保电子凭证码解码接口] 异常 CODE:{} MSG:{}", respCommon.getCode(), respCommon.getMessage()); + throw new RuntimeException(respCommon.getCode() + "-" + respCommon.getMessage()); + } + ChsQrcodeResponse result = respCommon.getData(); + + /*new ResultData() + .setRequestTime(requestTime) + .setRequestContent(request.toString()) + .setResponseTime(responseTime) + .setResponseContent(response) + .setResult(result);*/ + + return result; + } + + + /** + * 刷脸获取医保用户身份授权接口 + * + * @param val : + * @return com.dpkj.modules.chs.response.ChsAuthResponse + * @author 萧道子 2025/8/1 + */ + private ChsAuthResponse chsAuth(ChsModel val) { + log.debug("[PadChsPayServiceImpl][chsAuth][刷脸获取医保用户身份授权接口] 接收参数:{}", val); + + // 封装入参 + String outBizNo = IDGenerator.getSnowflakeIdToStr(); + ChsAuthRequest data = ChsAuthRequest.builder() + .orgId(chsConfig.getOrgId()) + .outBizNo(outBizNo) + .businessType(ChsDictEnum.BusinessType.YY_201.str()) + .operatorId(chsConfig.getOperatorId()) + .operatorName(chsConfig.getOperatorName()) + .officeId(StrUtil.isNotEmpty(val.getOfficeId()) ? val.getOfficeId() : chsConfig.getOfficeId()) + .officeName(StrUtil.isNotEmpty(val.getOfficeName()) ? val.getOfficeName() : chsConfig.getOfficeName()) + .build(); + ChsRequestCommon request = new ChsRequestCommon(chsConfig.getOrgId(), NationECCodeConst.TRANSTYPE_ALICHS_AUTH, JSONObject.parseObject(data.toString())); + log.debug("[PadChsPayServiceImpl][chsAuth][刷脸获取医保用户身份授权接口] 入参:{}", request.toString()); + + DateTime requestTime = DateUtil.date(); + + // 调用接口 + Pointer resp = new Memory(1024 * 10); + String resultStr = dll.NationEcTrans(chsConfig.getUrl(), request.toString(), resp); + String response = resp.getString(0, "GB2312"); + + DateTime responseTime = DateUtil.date(); + log.debug("[PadChsPayServiceImpl][chsAuth][刷脸获取医保用户身份授权接口] 响应:{} 出参:{}", resultStr, response); + log.debug("[PadChsPayServiceImpl][chsAuth][刷脸获取医保用户身份授权接口] 调用耗时:{} ms ", DateUtil.betweenMs(responseTime, requestTime)); + + // 处理转换参数 + ChsResponseCommon respCommon = JSONObject.parseObject(response, new TypeReference>() { + }); + if (!StrUtil.equals("0", respCommon.getCode())) { + log.error("[PadChsPayServiceImpl][chsAuth][刷脸获取医保用户身份授权接口] 异常 CODE:{} MSG:{}", respCommon.getCode(), respCommon.getMessage()); + throw new RuntimeException(respCommon.getCode() + "-" + respCommon.getMessage()); + } + ChsAuthResponse result = respCommon.getData(); + log.debug("[PadChsPayServiceImpl][chsAuth][刷脸获取医保用户身份授权接口] 结果:{}", result.toString()); + + return result; + } + + /** + * 刷脸授权获取医保身份接口 + * + * @param val : + * @return com.dpkj.modules.chs.response.ChsAuthResponse + * @author 萧道子 2025/8/1 + */ + private ChsCheckResponse chsCheck(ChsModel val, String authNo) { + log.debug("[PadChsPayServiceImpl][chsCheck][刷脸授权获取医保身份接口] 接收参数:{} authNo:{}", val, authNo); + + // 封装入参 + String outBizNo = IDGenerator.getSnowflakeIdToStr(); + ChsCheckRequest data = ChsCheckRequest.builder() + .orgId(chsConfig.getOrgId()) + .outBizNo(outBizNo) + .businessType(ChsDictEnum.BusinessType.YY_201.str()) + .operatorId(chsConfig.getOperatorId()) + .operatorName(chsConfig.getOperatorName()) + .officeId(StrUtil.isNotEmpty(val.getOfficeId()) ? val.getOfficeId() : chsConfig.getOfficeId()) + .officeName(StrUtil.isNotEmpty(val.getOfficeName()) ? val.getOfficeName() : chsConfig.getOfficeName()) + .authNo(authNo) + .build(); + ChsRequestCommon request = new ChsRequestCommon(chsConfig.getOrgId(), NationECCodeConst.TRANSTYPE_ALICHS_AUTHCHECK, JSONObject.parseObject(data.toString())); + log.debug("[PadChsPayServiceImpl][chsCheck][刷脸授权获取医保身份接口] 入参:{}", request.toString()); + + DateTime requestTime = DateUtil.date(); + + // 调用接口 + Pointer resp = new Memory(1024 * 10); + String resultStr = dll.NationEcTrans(chsConfig.getUrl(), request.toString(), resp); + String response = resp.getString(0, "GB2312"); + + DateTime responseTime = DateUtil.date(); + log.debug("[PadChsPayServiceImpl][chsCheck][刷脸授权获取医保身份接口] 响应:{} 出参:{}", resultStr, response); + log.debug("[PadChsPayServiceImpl][chsCheck][刷脸授权获取医保身份接口] 调用耗时:{} ms ", DateUtil.betweenMs(responseTime, requestTime)); + + // 处理转换参数 + ChsResponseCommon respCommon = JSONObject.parseObject(response, new TypeReference>() { + }); + if (!StrUtil.equals("0", respCommon.getCode())) { + log.error("[PadChsPayServiceImpl][chsCheck][刷脸授权获取医保身份接口] 异常 CODE:{} MSG:{}", respCommon.getCode(), respCommon.getMessage()); + throw new RuntimeException(respCommon.getCode() + "-" + respCommon.getMessage()); + } + ChsCheckResponse result = respCommon.getData(); + log.debug("[PadChsPayServiceImpl][chsCheck][刷脸授权获取医保身份接口] 结果:{}", result.toString()); + + return result; + } + + + @Override + public ChsCheckResponse getInfoByFace(ChsModel val) { + log.debug("[PadChsPayServiceImpl][getInfoByFace][刷脸获取用户身份详情] 接收参数:{}", val); + + DateTime requestTime = DateUtil.date(); + + // 1、刷脸获取医保用户身份授权接口-调起刷脸 + ChsAuthResponse chsAuthResponse = chsAuth(val); + // 2、刷脸获取医保用户身份授权接口-获取信息 + ChsCheckResponse chsCheckResponse = chsCheck(val, chsAuthResponse.getAuthNo()); + + DateTime responseTime = DateUtil.date(); + log.debug("[PadChsPayServiceImpl][getInfoByFace][刷脸获取用户身份详情] 调用耗时:{}", DateUtil.betweenMs(responseTime, requestTime)); + + return chsCheckResponse; + } + + +} diff --git a/src/main/java/com/dpkj/modules/scanface/ali/service/impl/AliScanFaceServiceImpl.java b/src/main/java/com/dpkj/modules/scanface/ali/service/impl/AliScanFaceServiceImpl.java index e3dd322..316cfd3 100644 --- a/src/main/java/com/dpkj/modules/scanface/ali/service/impl/AliScanFaceServiceImpl.java +++ b/src/main/java/com/dpkj/modules/scanface/ali/service/impl/AliScanFaceServiceImpl.java @@ -4,21 +4,18 @@ import cn.hutool.core.util.CharsetUtil; import cn.hutool.http.ContentType; import cn.hutool.http.Header; import cn.hutool.http.HttpRequest; -import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.dpkj.common.vo.Result; -import com.dpkj.modules.chs.dll.AlipayDll; import com.dpkj.modules.scanface.ali.config.AliFaceConfig; import com.dpkj.modules.scanface.ali.constants.AliFaceConstants; import com.dpkj.modules.scanface.ali.dll.AbcpInvoke; import com.dpkj.modules.scanface.ali.service.IAliScanFaceService; import com.dpkj.modules.scanface.ali.vo.AliOrderVo; -import jodd.util.StringUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; -import org.thymeleaf.util.StringUtils; import javax.annotation.PostConstruct; import javax.annotation.Resource; diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index d5b756f..c32e69f 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -25,13 +25,35 @@ spring: resource: static-locations: classpath:/static/,classpath:/public/ + #thymeleaf: + # #缓存 + # cache: false + # #编码 + # encoding: UTF-8 + # #模版前缀 + # prefix: classpath:/templates/ + # #模板后缀 + # suffix: .html + # #模板 + # mode: HTML + dpkj: #后端项目访问地址 #https://yinyitong.yzqingyan.cn/ http://172.16.11.13:15946/ ttps://yinyitong.yzqingyan.cn serverurl: http://localhost:5946/api/ # 医保配置 chs: + # 医保中台接口地址 + url: http://ec.yn.hsip.gov.cn/localcfc/api/hsecfc/localQrCodeQuery # 医保机构编码 - orgcode: H53082800070 + org-id: H53082800070 + # 收款员-编号 + operator-id: 0001 + # 收款员-姓名 + operator-name: admin + # 科室-编号 + office-id: 00031 + # 科室-名称 + office-name: 门诊 file: # 文件保存地址 path: G:\Temp\img diff --git a/src/main/resources/win32-x86/AlipayChs.dll b/src/main/resources/win32-x86/AlipayChs.dll deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/resources/win32-x86/NationECCode.dll b/src/main/resources/win32-x86/NationECCode.dll new file mode 100644 index 0000000..5d0cf23 Binary files /dev/null and b/src/main/resources/win32-x86/NationECCode.dll differ diff --git a/src/main/resources/win32-x86/libeay32.dll b/src/main/resources/win32-x86/libeay32.dll new file mode 100644 index 0000000..db98e5b Binary files /dev/null and b/src/main/resources/win32-x86/libeay32.dll differ diff --git a/src/main/resources/win32-x86/ssleay32.dll b/src/main/resources/win32-x86/ssleay32.dll new file mode 100644 index 0000000..965b609 Binary files /dev/null and b/src/main/resources/win32-x86/ssleay32.dll differ