Compare commits
46 Commits
1.0
...
b299ae021f
| Author | SHA1 | Date | |
|---|---|---|---|
| b299ae021f | |||
| e45d34eeae | |||
| 9471c9e01b | |||
| dd717d5392 | |||
| 47445ec1f7 | |||
| 4e0a64885e | |||
| 28aa307f8b | |||
| 4d888fb8a3 | |||
| 0ea6b18171 | |||
| 6317f78628 | |||
| 37ba56bacc | |||
| e0a2cf264f | |||
| e2ffb1051c | |||
| 88a587e51f | |||
| c4f28853dd | |||
| 52b13b73e0 | |||
| bd99a1e915 | |||
| 4af8283ff9 | |||
| 97aa3efef6 | |||
| 25597dcfc9 | |||
| 3bc83f07db | |||
| 9740a85f65 | |||
| 7b5ca7edfc | |||
| 4fc1335cc8 | |||
| 40f6728cea | |||
| 20ac1e4bb3 | |||
| 9c990e8103 | |||
| 8728b62a47 | |||
| 7b75ce8438 | |||
| 73fb4f18ff | |||
| 5e3c75d227 | |||
| 5071814758 | |||
| 8c47f5b204 | |||
| 09407c70c7 | |||
| 4da90e9a04 | |||
| 55bcca0dff | |||
| 1904cec8f8 | |||
| 60019a4283 | |||
| 9e7fc2d5a2 | |||
| 547bdb6d08 | |||
| 235306ae33 | |||
| 789d0d17cb | |||
| 26e504232e | |||
| 367429587f | |||
| 1343d01478 | |||
| c6e3d65245 |
@@ -1,5 +1,7 @@
|
||||
@echo off
|
||||
|
||||
:: 医保程序地址
|
||||
set WINEXE_CHSPATH=D:/Project/yinyitong-win/yinyitong.exe
|
||||
:: 医保程序地址
|
||||
set CHSPATH=D:/Project/CHS
|
||||
:: jar名称
|
||||
@@ -7,16 +9,17 @@ set NAME=yinyitong-dll-stand
|
||||
:: 端口号
|
||||
set PROT=5946
|
||||
|
||||
echo 关闭端口进程:%PROT%
|
||||
echo 1、关闭端口进程:%PROT%
|
||||
for /f "tokens=1-5" %%i in ('netstat -ano^|findstr ":%PROT%"') do taskkill /pid %%m -t -f
|
||||
|
||||
echo 启动:%NAME%
|
||||
echo 2、启动本地程序
|
||||
start %CHSPATH%/javaw.exe -Dfile.encoding=utf-8 -Djava.library.path=%CHSPATH% -Dlog.path=%~dp0 -jar %~dp0\%NAME%.jar --server.port=%PROT%
|
||||
|
||||
cd %CHSPATH%
|
||||
:: 延迟5秒
|
||||
timeout /NOBREAK /T 5 >nul
|
||||
|
||||
start javaw.exe -Dfile.encoding=UTF-8 -Djava.library.path=%CHSPATH% -Dlog.path=%~dp0 -jar %~dp0\%NAME%.jar --server.port=%PROT%
|
||||
|
||||
echo 启动完成
|
||||
echo 3、启动银医通
|
||||
start %WINEXE_CHSPATH%
|
||||
|
||||
exit
|
||||
::pause
|
||||
|
||||
73
pom.xml
73
pom.xml
@@ -4,7 +4,6 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.dpkj</groupId>
|
||||
<!-- 银医通-澜沧中医院-DLL-台式机 -->
|
||||
<artifactId>yinyitong-dll-stand</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>yinyitong-dll-stand</name>
|
||||
@@ -48,6 +47,11 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
@@ -61,22 +65,11 @@
|
||||
</dependency>
|
||||
|
||||
<!-- 调用DLL -->
|
||||
<!-- <dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna</artifactId>
|
||||
<version>${jna.version}</version>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna-jpms</artifactId>
|
||||
<version>${jna.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--<dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna-platform</artifactId>
|
||||
<version>${jna.version}</version>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna-platform-jpms</artifactId>
|
||||
@@ -101,7 +94,7 @@
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.83</version>
|
||||
<version>2.0.57</version>
|
||||
</dependency>
|
||||
|
||||
<!-- thymeleaf-->
|
||||
@@ -116,6 +109,11 @@
|
||||
<artifactId>flying-saucer-core</artifactId>
|
||||
<version>9.1.22</version>
|
||||
</dependency>
|
||||
<!--<dependency>
|
||||
<groupId>org.xhtmlrenderer</groupId>
|
||||
<artifactId>flying-saucer-pdf</artifactId>
|
||||
<version>9.12.0</version>
|
||||
</dependency>-->
|
||||
|
||||
<!-- ZXing for QR Code 二维码生成-->
|
||||
<dependency>
|
||||
@@ -160,22 +158,41 @@
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
</dependency>
|
||||
<!-- 报告打印转PDF -->
|
||||
<!-- iText 核心 -->
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>itextpdf</artifactId>
|
||||
<version>5.5.13.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- XML Worker (HTML 转 PDF) -->
|
||||
<dependency>
|
||||
<groupId>com.itextpdf.tool</groupId>
|
||||
<artifactId>xmlworker</artifactId>
|
||||
<version>5.5.13.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 中文字体支持 -->
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>itext-asian</artifactId>
|
||||
<version>5.2.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
|
||||
<!--打包时将resource下的文件一起打包-->
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/**</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<!-- <resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>false</filtering>
|
||||
<includes>
|
||||
<include>**/**</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>-->
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
@@ -278,14 +295,20 @@
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>dev</id>
|
||||
<activation>
|
||||
<!--默认激活配置-->
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
|
||||
<!--测试环境-->
|
||||
<profile.name>dev</profile.name>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>pro</id>
|
||||
<properties>
|
||||
|
||||
<!--正式环境-->
|
||||
<profile.name>pro</profile.name>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package com.dpkj.common.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -16,10 +14,9 @@ import java.io.Serializable;
|
||||
* @since 2025-02-08 11:03:06
|
||||
*/
|
||||
@Data
|
||||
@ToString
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class LexMarkResultDTO <T> implements Serializable {
|
||||
@Accessors(chain = true)
|
||||
public class LexMarkResultDTO<T> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
/**
|
||||
@@ -35,12 +32,12 @@ public class LexMarkResultDTO <T> implements Serializable {
|
||||
/**
|
||||
* 对应发送请求的callID。
|
||||
*/
|
||||
private int callID;
|
||||
private Integer callID;
|
||||
|
||||
/**
|
||||
* 错误码:0表示成功;其他表示失败,比如-4表示取消,-48表示超时,-14表示硬件故障
|
||||
*/
|
||||
private int result;
|
||||
private Integer result;
|
||||
|
||||
/**
|
||||
* 发送请求中的actionName
|
||||
@@ -63,53 +60,5 @@ public class LexMarkResultDTO <T> implements Serializable {
|
||||
*/
|
||||
private T data;
|
||||
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Param {
|
||||
|
||||
/**
|
||||
* 请求ID
|
||||
*/
|
||||
private int RequestID;
|
||||
|
||||
/**
|
||||
* 命令编码
|
||||
*/
|
||||
private int dwCommandCode;
|
||||
|
||||
/**
|
||||
* 事件名,由发送请求中的actionName+Over组成。
|
||||
*/
|
||||
private String eventName;
|
||||
|
||||
/**
|
||||
* 事件类型编码
|
||||
*/
|
||||
private int eventType;
|
||||
|
||||
/**
|
||||
* 服务
|
||||
*/
|
||||
private int hService;
|
||||
|
||||
/**
|
||||
* 对应发送请求中的devName
|
||||
*/
|
||||
private String cmdName;
|
||||
|
||||
/**
|
||||
* 错误码:0表示成功;其他表示失败,比如-4表示取消,-48表示超时,-14表示硬件故障
|
||||
*/
|
||||
private int result;
|
||||
|
||||
/**
|
||||
* 详情描述
|
||||
*/
|
||||
private String desc;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.dpkj.common.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.dpkj.common.dto.LexMarkDTO;
|
||||
import com.dpkj.common.dto.LexMarkResultDTO;
|
||||
@@ -8,14 +9,7 @@ import com.dpkj.common.exception.RRException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thymeleaf.util.StringUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -37,68 +31,48 @@ public class ThirdService {
|
||||
private String lexMarkServicePort;
|
||||
|
||||
private static final Map<String, String> devNameMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
devNameMap.put("HtmPrinter", "激光打印机");
|
||||
devNameMap.put("ReceiptPrinter", "凭条打印机");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 利盟台式机-立体机 接口请求
|
||||
*
|
||||
* @param lexMarkDTO 请求DTO
|
||||
* @param clazz 返回类型
|
||||
* @param clazz 返回类型
|
||||
* @return result
|
||||
*/
|
||||
public <T> LexMarkResultDTO<T> callDevice(LexMarkDTO lexMarkDTO, Class<T> clazz) {
|
||||
try {
|
||||
URL url = new URL(lexMarkServiceIp + ":" + lexMarkServicePort + "/CallDevice");
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
String urlStr = lexMarkServiceIp + ":" + lexMarkServicePort + "/CallDevice";
|
||||
log.info("[ThirdService][callDevice][激光打印机打印] 利盟打印接口-url:{}", urlStr);
|
||||
|
||||
// 将LexMarkDTO对象转换为JSON字符串
|
||||
String jsonInputString = JSON.toJSONString(lexMarkDTO);
|
||||
try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) {
|
||||
byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8);
|
||||
wr.write(input, 0, input.length);
|
||||
log.info(jsonInputString);
|
||||
}
|
||||
String params = JSONObject.toJSONString(lexMarkDTO);
|
||||
log.info("[ThirdService][callDevice][激光打印机打印] 利盟打印接口-入参:{}", params);
|
||||
|
||||
int responseCode = connection.getResponseCode();
|
||||
if (responseCode != HttpURLConnection.HTTP_OK) {
|
||||
log.error("利盟服务请求失败,响应码:{},请求参数:{}", responseCode, lexMarkDTO);
|
||||
throw new RRException("利盟服务请求失败,响应码:" + responseCode);
|
||||
}
|
||||
String bodyStr = HttpRequest.post(urlStr)
|
||||
.header("Content-Type", "application/json")
|
||||
.body(params)
|
||||
.timeout(30000)
|
||||
.execute()
|
||||
.body();
|
||||
log.info("[ThirdService][callDevice][激光打印机打印] 利盟打印接口-响应:{}", bodyStr);
|
||||
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String inputLine;
|
||||
StringBuilder response = new StringBuilder();
|
||||
while ((inputLine = in.readLine()) != null) {
|
||||
response.append(inputLine);
|
||||
JSONObject bodyJson = (JSONObject) JSONObject.parse(bodyStr);
|
||||
if (StrUtil.isEmpty(bodyJson.getString("param"))) {
|
||||
throw new RRException("利盟服务请求失败,结果响应为空");
|
||||
}
|
||||
in.close();
|
||||
|
||||
// 将响应JSON字符串转换为LexMarkResultDTO对象
|
||||
LexMarkResultDTO<T> lexMarkResultDTO = JSON.parseObject(response.toString(), LexMarkResultDTO.class);
|
||||
// if (lexMarkResultDTO.getResult() != 0) {
|
||||
// log.error("利盟服务请求出错:{}", lexMarkResultDTO);
|
||||
// throw new RRException(lexMarkResultDTO.toString());
|
||||
// }
|
||||
LexMarkResultDTO obj = JSONObject.toJavaObject(bodyJson, LexMarkResultDTO.class);
|
||||
|
||||
// 实例化param位data
|
||||
String param = lexMarkResultDTO.getParam();
|
||||
if (!StringUtils.isEmpty(param)) {
|
||||
try {
|
||||
T t = JSON.parseObject(param, clazz);
|
||||
lexMarkResultDTO.setData(t);
|
||||
}catch (Exception e){
|
||||
log.error("类型转换失败");
|
||||
throw new RRException("转换param位data时,类型与实际类型不匹配");
|
||||
}
|
||||
}
|
||||
T paramObj = JSONObject.toJavaObject(bodyJson.getJSONObject("param"), clazz);
|
||||
obj.setData(paramObj);
|
||||
|
||||
return lexMarkResultDTO;
|
||||
return obj;
|
||||
} catch (Exception e) {
|
||||
log.error("利盟服务请求失败:{}", lexMarkDTO, e);
|
||||
if (e instanceof RRException) {
|
||||
@@ -121,7 +95,8 @@ public class ThirdService {
|
||||
|
||||
/**
|
||||
* 打开设备连接或者 链接+初始化
|
||||
* @param devName 设备名称
|
||||
*
|
||||
* @param devName 设备名称
|
||||
* @param resterType 初始化类型,如果不设置,那么就不会进行初始化
|
||||
*/
|
||||
public void open(String devName, Integer resterType) {
|
||||
@@ -131,7 +106,7 @@ public class ThirdService {
|
||||
lexMarkDTO.setCallID(19283);
|
||||
lexMarkDTO.setDevName(devName);
|
||||
lexMarkDTO.setPluginMethod("exec");
|
||||
JSONObject param = new JSONObject();
|
||||
JSONObject param = new JSONObject();
|
||||
param.put("", String.format("{\"ServiceName\":\"%s\",\"TimeOut\":90000}", devName));
|
||||
lexMarkDTO.setParam(param.toString());
|
||||
LexMarkResultDTO<JSONObject> jsonObjectLexMarkResultDTO = this.callDevice(lexMarkDTO, JSONObject.class);
|
||||
@@ -143,7 +118,7 @@ public class ThirdService {
|
||||
}
|
||||
|
||||
// 打开后直接进行重置
|
||||
if ( resterType != null && data != null) {
|
||||
if (resterType != null && data != null) {
|
||||
lexMarkDTO.setActionName("Reset");
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("", String.format("{\"ResetAction\":%d,\"binNumber\":0}", resterType));
|
||||
@@ -160,6 +135,7 @@ public class ThirdService {
|
||||
|
||||
/**
|
||||
* 关闭设备练级
|
||||
*
|
||||
* @param devName 设备名称
|
||||
*/
|
||||
public void close(String devName) {
|
||||
@@ -179,17 +155,18 @@ public class ThirdService {
|
||||
|
||||
/**
|
||||
* 切纸,但是目前凭条和ms439打印机都是可以自动切纸的
|
||||
* @param devName 设备名称
|
||||
*
|
||||
* @param devName 设备名称
|
||||
* @param actionName action名称,实际的动作函数名称
|
||||
* @param mediaType 媒介类型
|
||||
* @param mediaType 媒介类型
|
||||
*/
|
||||
public void cutPaper(String devName, String actionName, Integer mediaType){
|
||||
public void cutPaper(String devName, String actionName, Integer mediaType) {
|
||||
LexMarkDTO lexMarkDTO = new LexMarkDTO();
|
||||
lexMarkDTO.setActionName(actionName);
|
||||
lexMarkDTO.setCallID(19283);
|
||||
lexMarkDTO.setDevName(devName);
|
||||
lexMarkDTO.setPluginMethod("exec");
|
||||
JSONObject param = new JSONObject();
|
||||
JSONObject param = new JSONObject();
|
||||
param.put("", String.format("{\"mediaCtrol\":%d}", mediaType));
|
||||
lexMarkDTO.setParam(param.toString());
|
||||
|
||||
|
||||
325
src/main/java/com/dpkj/modules/chs/constant/ChsDictEnum.java
Normal file
325
src/main/java/com/dpkj/modules/chs/constant/ChsDictEnum.java
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.dpkj.modules.chs.constant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Auther: 萧道子
|
||||
* @Date: 2025/6/18 15:57
|
||||
* @Description: 医保状态记录常量类
|
||||
*/
|
||||
public class ChsPayStateConst {
|
||||
|
||||
private static Map<String, Integer> chsPayState = new HashMap<String, Integer>(1);
|
||||
|
||||
|
||||
/**
|
||||
* 清除所有
|
||||
*
|
||||
* @return void
|
||||
* @author 萧道子 2025/6/18
|
||||
*/
|
||||
public static void clear() {
|
||||
chsPayState.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 按key删除
|
||||
*
|
||||
* @return void
|
||||
* @author 萧道子 2025/6/18
|
||||
*/
|
||||
public static void remove(String key) {
|
||||
chsPayState.remove(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @return void
|
||||
* @author 萧道子 2025/6/18
|
||||
*/
|
||||
public static void put(String key, Integer val) {
|
||||
chsPayState.put(key, val);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取
|
||||
*
|
||||
* @return void
|
||||
* @author 萧道子 2025/6/18
|
||||
*/
|
||||
public static Integer get(String key) {
|
||||
return chsPayState.get(key);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.dpkj.modules.chs.constant;
|
||||
|
||||
public interface NationECCodeConst {
|
||||
|
||||
/**
|
||||
* 终端医保电子凭证码解码接口
|
||||
* <p>
|
||||
* 用于定点医疗药机构通过使用医保业务综合服务终端集成的扫码设备模块获取医保电子凭证二维码码值后,通过电子凭证中台完成解码。
|
||||
*/
|
||||
String TRANSTYPE_ALICHS_QRCODEGET = "cn.nhsa.qrcode.get";
|
||||
|
||||
/**
|
||||
* 刷脸获取医保用户身份授权接口
|
||||
* <p>
|
||||
* 定点医药机构通过医保业务综合服务终端的刷脸获取医保用户身份授权。
|
||||
*/
|
||||
String TRANSTYPE_ALICHS_AUTH = "cn.nhsa.ec.auth";
|
||||
|
||||
/**
|
||||
* 刷脸授权获取医保身份接口
|
||||
* <p>
|
||||
* 用于定点医药机构通过使用医保业务综合服务终端的刷脸模块,授权参保人通过刷脸进行医保身份认证。
|
||||
*/
|
||||
String TRANSTYPE_ALICHS_AUTHCHECK = "cn.nhsa.auth.check";
|
||||
|
||||
/**
|
||||
* 结算结果通知终端接口
|
||||
* <p>
|
||||
* 若定点医药机构没有通过终端完成医保移动支付,需要调用此接口在终端上显示结算结果。若定点医药机构通过终端完成医保移动支付,则不需要调用此接口。
|
||||
*/
|
||||
String TRANSTYPE_ALICHS_NOTIFY = "cn.nhsa.settle.notify";
|
||||
|
||||
|
||||
/**
|
||||
* 刷脸获取医保用户身份授权接口
|
||||
* <p>
|
||||
* 定点医药机构通过医保业务综合服务终端的刷脸获取医保用户身份授权
|
||||
*/
|
||||
String TRANSTYPE_NATION_AUTH = "cn.nhsa.ec.auth";
|
||||
|
||||
/**
|
||||
* 结算结果通知接口
|
||||
* <p>
|
||||
* 若定点医药机构没有通过终端完成医保移动支付,调用此接口在终端上显示结算结果或者退费结果
|
||||
*/
|
||||
String TRANSTYPE_NATION_NOTIFY = "cn.nhsa.settle.notify";
|
||||
|
||||
/**
|
||||
* 终端医保移动支付接口
|
||||
* <p>
|
||||
* 医生开具诊断或者用户购药,定点医药机构通过支付中心完成费用上传后,调用终端进行医保移动支付
|
||||
*/
|
||||
String TRANSTYPE_NATION_MEDICALPAY = "cn.nhsa.medical.pay";
|
||||
|
||||
/**
|
||||
* 身份证读卡器接口
|
||||
* <p>
|
||||
* 调用终端,终端将打开身份证读卡页面,引导用户扫描身份证,获取用户身份信息
|
||||
*/
|
||||
String TRANSTYPE_NATION_CERTGET = "cn.nhsa.cert.get";
|
||||
|
||||
/**
|
||||
* 刷脸核身接口
|
||||
* <p>
|
||||
* 定点医药机构通过医保业务综合服务终端的刷脸获取医保用户身份授权,用户授权成功后,医保电子凭证动态库调用医保电子凭证中心进行获取医保用户身份信息
|
||||
*/
|
||||
String TRANSTYPE_NATION_CERTCHECK = "cn.nhsa.cert.check";
|
||||
|
||||
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package com.dpkj.modules.chs.controller;
|
||||
|
||||
import cn.hutool.core.lang.Console;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.dpkj.common.config.ChsConfig;
|
||||
import com.dpkj.common.constant.ChsConst;
|
||||
import com.dpkj.common.vo.Result;
|
||||
import com.dpkj.modules.chs.dll.AlipayDll;
|
||||
import com.dpkj.modules.chs.entity.AlipayEcRequestData;
|
||||
import com.dpkj.modules.chs.service.IAlipayService;
|
||||
import com.sun.jna.Memory;
|
||||
import com.sun.jna.Pointer;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
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/alipay")
|
||||
public class AlipayController {
|
||||
|
||||
private final IAlipayService alipayService;
|
||||
|
||||
private final ChsConfig charsConfig;
|
||||
|
||||
|
||||
@GetMapping("test")
|
||||
public Result<?> test() {
|
||||
try {
|
||||
AlipayDll.Dll dll = AlipayDll.instance();
|
||||
// Native.load("libeay32", AlipayDll.Dll.class);
|
||||
// Native.load("ssleay32", AlipayDll.Dll.class);
|
||||
|
||||
|
||||
JSONObject data = new JSONObject();
|
||||
AlipayEcRequestData alipayEcRequestData = new AlipayEcRequestData()
|
||||
.setOrgId(charsConfig.getOrgcode())
|
||||
.setTransType(ChsConst.APITYPE_DECODE)
|
||||
.setData(data);
|
||||
String dataJson = JSONObject.toJSONString(alipayEcRequestData);
|
||||
|
||||
Pointer resultStr = new Memory(1024 * 10);
|
||||
String rs = dll.NationEcTrans(
|
||||
"http://172.16.11.13:5946/api/chs/qrCodeQuery",
|
||||
dataJson,
|
||||
resultStr
|
||||
);
|
||||
String rsStrString = resultStr.getString(0, "GB18030");
|
||||
Console.log(rsStrString);
|
||||
Console.log(rs);
|
||||
|
||||
return Result.ok("成功", rsStrString);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Result.error("失败");
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("qrCodeQuery")
|
||||
public Result<?> qrCodeQuery(@RequestBody JSONObject data) {
|
||||
try {
|
||||
|
||||
Console.log(data);
|
||||
return Result.ok("成功", null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Result.error("失败");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.dpkj.common.vo.Result;
|
||||
import com.dpkj.common.vo.ResultData;
|
||||
import com.dpkj.modules.chs.constant.ChsPayStateConst;
|
||||
import com.dpkj.modules.chs.service.IHispayService;
|
||||
import com.dpkj.modules.chs.vo.OutpatientBeginModel;
|
||||
import com.dpkj.modules.chs.vo.OutpatientFinalModel;
|
||||
@@ -26,7 +27,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RequestMapping("/chs/hispay")
|
||||
public class HispayController {
|
||||
|
||||
private final IHispayService iHispayService;
|
||||
private final IHispayService hispayService;
|
||||
|
||||
|
||||
/**
|
||||
@@ -38,7 +39,7 @@ public class HispayController {
|
||||
@PostMapping("findReadCode")
|
||||
public Result<?> findReadCode() {
|
||||
try {
|
||||
JSONObject res = iHispayService.readCode();
|
||||
JSONObject res = hispayService.readCode();
|
||||
return Result.ok("成功", res);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -63,7 +64,7 @@ public class HispayController {
|
||||
throw new RuntimeException("密码不可为空");
|
||||
}
|
||||
|
||||
JSONObject res = iHispayService.readCard(password);
|
||||
JSONObject res = hispayService.readCard(password);
|
||||
return Result.ok("成功", res);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -83,8 +84,11 @@ public class HispayController {
|
||||
@PostMapping("chsCodeAsOutpatientBegin")
|
||||
public Result<?> chsCodeAsOutpatientBegin(@RequestBody @Validated OutpatientBeginModel data) {
|
||||
try {
|
||||
// 清空状态常量
|
||||
ChsPayStateConst.clear();
|
||||
|
||||
log.info("[HispayController][chsCodeAsOutpatientBegin][门诊缴费-预算-电子医保凭证] 参数:{}", data);
|
||||
ResultData res = iHispayService.chsCodeAsOutpatientBegin(data);
|
||||
ResultData res = hispayService.chsCodeAsOutpatientBegin(data);
|
||||
return Result.ok("成功", res);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -105,7 +109,7 @@ public class HispayController {
|
||||
public Result<?> chsCodeAsOutpatientFinal(@RequestBody @Validated OutpatientFinalModel data) {
|
||||
try {
|
||||
log.info("[HispayController][chsCodeAsOutpatientFinal][门诊缴费-结算-电子医保凭证] 参数:{}", data);
|
||||
ResultData res = iHispayService.chsCodeAsOutpatientFinal(data);
|
||||
ResultData res = hispayService.chsCodeAsOutpatientFinal(data);
|
||||
return Result.ok("成功", res);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -114,4 +118,20 @@ public class HispayController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取医保支付状态
|
||||
*
|
||||
* @return com.dpkj.common.vo.Result<?>
|
||||
* @author 萧道子 2025/6/18
|
||||
*/
|
||||
@PostMapping("getChsPayState")
|
||||
public Result<?> getChsPayState(@RequestBody OutpatientBeginModel data) {
|
||||
String no = data.getPrescriptionNo();
|
||||
if (StrUtil.isEmpty(no)) {
|
||||
return Result.error("收据号不可为空");
|
||||
}
|
||||
Integer num = ChsPayStateConst.get(no);
|
||||
return Result.ok("成功", num);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
32
src/main/java/com/dpkj/modules/chs/model/ChsModel.java
Normal file
32
src/main/java/com/dpkj/modules/chs/model/ChsModel.java
Normal file
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
207
src/main/java/com/dpkj/modules/chs/request/ChsNotifyRequest.java
Normal file
207
src/main/java/com/dpkj/modules/chs/request/ChsNotifyRequest.java
Normal file
@@ -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;
|
||||
|
||||
|
||||
/**
|
||||
* 核身或者刷脸的医疗机构业务流水号
|
||||
* <p>
|
||||
* 需要传核身接口或者电子凭证接口里的流水号(因为需要将核身结果与医保结算结果相对应。)
|
||||
*/
|
||||
private String outBizNo;
|
||||
/**
|
||||
* 医保/自费结算状态
|
||||
* <p>
|
||||
* SUCCESS:结算成功
|
||||
* FAIL:结算失败
|
||||
*/
|
||||
private String medicalSettleState;
|
||||
/**
|
||||
* 实人认证业务流水号
|
||||
* <p>
|
||||
* 用于后续与中台交互换取身份信息
|
||||
*/
|
||||
private String authNo;
|
||||
/**
|
||||
* 收款员编号
|
||||
*/
|
||||
private String operatorId;
|
||||
/**
|
||||
* 收款员姓名
|
||||
*/
|
||||
private String operatorName;
|
||||
/**
|
||||
* 总费用
|
||||
*/
|
||||
private String totalFee;
|
||||
/**
|
||||
* 业务场景
|
||||
* <p>
|
||||
* 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<Drug> drugList;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Drug {
|
||||
/**
|
||||
* 项目编号
|
||||
* <p>
|
||||
* 对照医保项目编码
|
||||
*/
|
||||
private String ITEM_NO;
|
||||
/**
|
||||
* 项目名称
|
||||
*/
|
||||
private String ITEMNAME;
|
||||
/**
|
||||
* 发票项目编号
|
||||
* <p>
|
||||
* 对照应医保发票项目编码
|
||||
*/
|
||||
private String INVO_ITEM_NO;
|
||||
/**
|
||||
* 是否医保项目
|
||||
* <p>
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* 定点医药机构本次业务流水号
|
||||
* <p>
|
||||
* 不可重复,每次请求需要唯一
|
||||
*/
|
||||
private String outBizNo;
|
||||
|
||||
/**
|
||||
* 用码业务类型
|
||||
* <p>
|
||||
* 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;
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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<T> 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;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
package com.dpkj.modules.chs.service;
|
||||
|
||||
public interface IAlipayService {
|
||||
}
|
||||
@@ -43,5 +43,4 @@ public interface IHispayService {
|
||||
*/
|
||||
ResultData chsCodeAsOutpatientFinal(OutpatientFinalModel data);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package com.dpkj.modules.chs.service.impl;
|
||||
|
||||
import cn.hutool.core.lang.Console;
|
||||
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 = AlipayDll.instance();
|
||||
|
||||
|
||||
public AlipayServiceImpl() throws AlipayDll.DllRegistrationException {
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
log.info("[AlipayServiceImpl][postConstruct][医保DLL] 初始化动态链接库");
|
||||
initPrinter();
|
||||
}
|
||||
|
||||
|
||||
private void initPrinter() {
|
||||
Console.log(dll);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -7,20 +7,20 @@ import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.dpkj.common.config.ChsConfig;
|
||||
import com.dpkj.common.config.HisConfig;
|
||||
import com.dpkj.common.utils.IDGenerator;
|
||||
import com.dpkj.common.vo.ResultData;
|
||||
import com.dpkj.modules.chs.constant.ChsPayStateConst;
|
||||
import com.dpkj.modules.chs.service.IHispayService;
|
||||
import com.dpkj.modules.chs.vo.OutpatientBeginModel;
|
||||
import com.dpkj.modules.chs.vo.OutpatientFinalModel;
|
||||
import com.jacob.activeX.ActiveXComponent;
|
||||
import com.jacob.com.ComThread;
|
||||
import com.jacob.com.Dispatch;
|
||||
import com.jacob.com.Variant;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@@ -31,11 +31,21 @@ import java.util.Map;
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
// @AllArgsConstructor
|
||||
public class HispayServiceImpl implements IHispayService {
|
||||
|
||||
private final HisConfig hisConfig;
|
||||
private final ChsConfig chsConfig;
|
||||
@Autowired
|
||||
private HisConfig hisConfig;
|
||||
@Autowired
|
||||
private ChsConfig chsConfig;
|
||||
|
||||
// COM对象
|
||||
private static ActiveXComponent dispatch;
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
dispatch = instanceActive();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取HIS医保实例
|
||||
@@ -43,16 +53,15 @@ public class HispayServiceImpl implements IHispayService {
|
||||
* @return com.jacob.activeX.ActiveXComponent
|
||||
* @author 萧道子 2025/5/21
|
||||
*/
|
||||
private ActiveXComponent instanceActive() {
|
||||
private static ActiveXComponent instanceActive() {
|
||||
try {
|
||||
// 初始化
|
||||
ComThread.InitSTA();
|
||||
// 获取COM对象
|
||||
ActiveXComponent active = new ActiveXComponent("PayClient.clsPayClient");
|
||||
// ComThread.InitSTA(); //容易导致线程发生阻塞
|
||||
ActiveXComponent activeXComponent = new ActiveXComponent("PayClient.clsPayClient");
|
||||
log.info("[HispayServiceImpl][instanceActive][HIS医保COM库] 加载成功");
|
||||
return active;
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -65,7 +74,7 @@ public class HispayServiceImpl implements IHispayService {
|
||||
* @author 萧道子 2025/5/21
|
||||
*/
|
||||
private void releaseActive() {
|
||||
ComThread.Release();
|
||||
// ComThread.Release(); //容易导致线程发生阻塞
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,9 +87,9 @@ public class HispayServiceImpl implements IHispayService {
|
||||
*/
|
||||
private String processParameters(JSONObject params, String password) {
|
||||
JSONObject req = new JSONObject() {{
|
||||
put("timestamp", DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss")); // 请求发送时间
|
||||
put("requestid", IDGenerator.getSnowflakeIdToStr()); // 唯一请求id
|
||||
put("operid", hisConfig.getOperationId()); // 调用者代码
|
||||
put("timestamp", ""); // 请求发送时间 DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss")
|
||||
put("requestid", ""); // 唯一请求id IDGenerator.getSnowflakeIdToStr()
|
||||
put("operid", ""); // 调用者代码 hisConfig.getOperationId()
|
||||
put("password", password); // 密码
|
||||
put("params", params);
|
||||
}};
|
||||
@@ -120,9 +129,6 @@ public class HispayServiceImpl implements IHispayService {
|
||||
|
||||
@Override
|
||||
public JSONObject readCode() {
|
||||
// 加载资源
|
||||
Dispatch dispatch = instanceActive();
|
||||
|
||||
/** 1、组装参数 */
|
||||
JSONObject val = new JSONObject()
|
||||
.fluentPut("cardtype", "9") // 1.就诊卡,2.医保卡,5.门诊号,6.患者姓名和电话号码,8.电子健康码/卡,9.医保电子凭证
|
||||
@@ -131,17 +137,15 @@ 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);
|
||||
|
||||
// 释放资源
|
||||
releaseActive();
|
||||
|
||||
/** 3、处理读卡结果 */
|
||||
JSONObject result = verifyResult(resStr);
|
||||
@@ -154,8 +158,6 @@ public class HispayServiceImpl implements IHispayService {
|
||||
|
||||
@Override
|
||||
public JSONObject readCard(String password) {
|
||||
// 加载资源
|
||||
Dispatch dispatch = instanceActive();
|
||||
|
||||
/** 1、组装参数 */
|
||||
JSONObject val = new JSONObject()
|
||||
@@ -165,17 +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);
|
||||
|
||||
// 释放资源
|
||||
releaseActive();
|
||||
log.debug("[HispayServiceImpl][readCard][医保读卡-医保卡] call返回值:{} 结果:{}", call, resStr);
|
||||
|
||||
/** 3、处理读卡结果 */
|
||||
JSONObject result = verifyResult(resStr);
|
||||
@@ -187,67 +186,7 @@ public class HispayServiceImpl implements IHispayService {
|
||||
}
|
||||
|
||||
|
||||
// public JSONObject getPatientInfo_old(String type, String content) {
|
||||
// Dispatch dispatch = instanceActive();
|
||||
//
|
||||
// /**
|
||||
// * 1、删除保存HIS读卡内容的文件 避免读取到错误信息
|
||||
// */
|
||||
// // 获取HIS-CHS医保库路径
|
||||
// String chsPath = System.getProperty("java.library.path");
|
||||
// String filePath = chsPath + "/" + chsConfig.getFileName();
|
||||
// // 删除文件
|
||||
// FileUtil.del(FileUtil.file(filePath));
|
||||
//
|
||||
// /**
|
||||
// * 2、组装参数
|
||||
// */
|
||||
// JSONObject val = new JSONObject()
|
||||
// .fluentPut("cardtype", type) // 1.就诊卡,2.医保卡,5.门诊号,6.患者姓名和电话号码,8.电子健康码/卡,9.医保电子凭证
|
||||
// .fluentPut("cardno", "") // 患者就诊卡号
|
||||
// .fluentPut("sfzh", "") // 身份证号
|
||||
// .fluentPut("hzxm", "") // 患者姓名
|
||||
// .fluentPut("phone", ""); // 患者电话号码
|
||||
// String params = processParameters(val, content);
|
||||
// log.info("[HispayServiceImpl][getPatientInfo][医保读卡] 接口入参:{}", params);
|
||||
//
|
||||
// /**
|
||||
// * 3、调用COM函数
|
||||
// */
|
||||
// Variant rest = new Variant();
|
||||
// Variant call = Dispatch.call(dispatch, "fRun", "BMZXX010", params, rest);
|
||||
// log.info("[HispayServiceImpl][getPatientInfo][医保读卡] call返回值:{}", call);
|
||||
//
|
||||
// // 释放资源
|
||||
// releaseActive();
|
||||
//
|
||||
// /**
|
||||
// * 4、处理读卡结果
|
||||
// */
|
||||
// // COM函数调用之后会生成新的文件 需要判断
|
||||
// File file = FileUtil.file(filePath);
|
||||
// if (!file.exists()) {
|
||||
// throw new RuntimeException("读卡失败:数据未读取");
|
||||
// }
|
||||
//
|
||||
// // 获取读卡结果
|
||||
// FileReader fileReader = new FileReader(file, "GBK");
|
||||
// String data = fileReader.readString();
|
||||
//
|
||||
// JSONObject result;
|
||||
// try {
|
||||
// result = JSONObject.parseObject(data);
|
||||
// log.info("[HispayServiceImpl][getPatientInfo][医保读卡] 读卡值:{}", result);
|
||||
// } catch (Exception e) {
|
||||
// throw new RuntimeException("读卡失败:" + data);
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
|
||||
private ResultData outpatientBudget(OutpatientBeginModel data) {
|
||||
// 加载资源
|
||||
ActiveXComponent dispatch = instanceActive();
|
||||
|
||||
/** 1、组装参数 */
|
||||
JSONObject val = new JSONObject()
|
||||
@@ -257,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();
|
||||
|
||||
@@ -267,10 +206,8 @@ 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);
|
||||
|
||||
// 释放资源
|
||||
releaseActive();
|
||||
|
||||
/** 3、处理结果 */
|
||||
JSONObject result = verifyResult(resStr);
|
||||
@@ -291,21 +228,28 @@ public class HispayServiceImpl implements IHispayService {
|
||||
JSONObject userInfo = readCode();
|
||||
String patientId = userInfo.getString("patid");
|
||||
data.setPatientId(patientId);
|
||||
|
||||
// 更新常量状态 已读卡
|
||||
ChsPayStateConst.put(data.getPrescriptionNo(), 1);
|
||||
|
||||
return outpatientBudget(data);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ResultData chsCodeAsOutpatientFinal(OutpatientFinalModel data) {
|
||||
// 加载资源
|
||||
ActiveXComponent dispatch = instanceActive();
|
||||
|
||||
/** 1、组装参数 */
|
||||
JSONObject val = (JSONObject) JSON.toJSON(data);
|
||||
String params = processParameters(val, null);
|
||||
log.info("[HispayServiceImpl][chsCodeAsOutpatientFinal][门诊缴费-结算] 接口入参:{}", params);
|
||||
|
||||
String requestTime = DateUtil.now();
|
||||
data.setPaytime(requestTime);
|
||||
JSONObject val = ((JSONObject) JSON.toJSON(data))
|
||||
.fluentPut("czksfbz", "0") // 是否扣院内账户,与预算保持一致
|
||||
.fluentPut("zfjsbz", "0") // 是否自费结算,与预算保持一致,0根据病人医保代码结算,1自费结算
|
||||
.fluentPut("ybrc", "")
|
||||
.fluentPut("ptlsh", "")
|
||||
.fluentPut("jysm", "");
|
||||
String params = processParameters(val, null);
|
||||
log.debug("[HispayServiceImpl][chsCodeAsOutpatientFinal][门诊缴费-结算] 接口入参:{}", params);
|
||||
|
||||
/** 2、调用COM函数 */
|
||||
Variant resVariant = new Variant("", true);
|
||||
@@ -313,14 +257,7 @@ public class HispayServiceImpl implements IHispayService {
|
||||
|
||||
String responseTime = DateUtil.now();
|
||||
String resStr = resVariant.getStringRef();
|
||||
log.info("[HispayServiceImpl][chsCodeAsOutpatientFinal][门诊缴费-结算] call返回值:{} 结果:{}", call, resStr);
|
||||
|
||||
// 释放资源
|
||||
releaseActive();
|
||||
|
||||
// TODO BEGIN 萧道子 2025/6/10 : 模拟参数
|
||||
// String resStr = "<response><resultCode>0</resultCode><resultMessage/><result><sjh>123456789</sjh><sfrq>2025-06-10 10:23:14</sfrq><bz/><pyckjh/><fyckjh/><yflshjh/><ybcc/></result></response>";
|
||||
// TODO END 萧道子 2025/6/10 : 模拟参数
|
||||
log.debug("[HispayServiceImpl][chsCodeAsOutpatientFinal][门诊缴费-结算] call返回值:{} 结果:{}", call, resStr);
|
||||
|
||||
/** 3、处理结果 */
|
||||
JSONObject result = verifyResult(resStr);
|
||||
|
||||
@@ -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<ChsQrcodeResponse> respCommon = JSONObject.parseObject(response, new TypeReference<ChsResponseCommon<ChsQrcodeResponse>>() {
|
||||
});
|
||||
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<ChsAuthResponse> respCommon = JSONObject.parseObject(response, new TypeReference<ChsResponseCommon<ChsAuthResponse>>() {
|
||||
});
|
||||
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<ChsCheckResponse> respCommon = JSONObject.parseObject(response, new TypeReference<ChsResponseCommon<ChsCheckResponse>>() {
|
||||
});
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -43,5 +43,7 @@ public class OutpatientFinalModel implements Serializable {
|
||||
/**
|
||||
* 支付时间
|
||||
*/
|
||||
// @NotEmpty(message = "支付时间不可为空!")
|
||||
private String paytime;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
package com.dpkj.modules.print.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.dpkj.common.dto.LexMarkResultDTO;
|
||||
import com.dpkj.common.vo.Result;
|
||||
import com.dpkj.modules.print.request.MS439Request;
|
||||
import com.dpkj.modules.print.service.MS439PrintService;
|
||||
import com.dpkj.modules.print.vo.PrinterStatus;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* MS439控制层,利盟打印机
|
||||
@@ -24,12 +28,26 @@ public class MS439Controller {
|
||||
private MS439PrintService ms439PrintService;
|
||||
|
||||
@PostMapping("/print")
|
||||
public Result<LexMarkResultDTO<?>> print(@Validated @RequestBody MS439Request request){
|
||||
public Result<LexMarkResultDTO<?>> print(@Validated @RequestBody MS439Request request) {
|
||||
return Result.ok(ms439PrintService.printImage(request));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检验报告打印
|
||||
*/
|
||||
@PostMapping("/printJY")
|
||||
public Result<LexMarkResultDTO<?>> printJY(@RequestBody JSONObject jsonObject) {
|
||||
JSONObject params = jsonObject.getJSONObject("reportResult");
|
||||
// 获取检验报告PDF
|
||||
String path = ms439PrintService.getJYPDFPath(params);
|
||||
MS439Request ms439Request = new MS439Request();
|
||||
ms439Request.setFileDir(path);
|
||||
LexMarkResultDTO<?> result = ms439PrintService.printImage(ms439Request);
|
||||
return Result.ok(result);
|
||||
}
|
||||
|
||||
@PostMapping("/getStatus")
|
||||
public Result<String> print(@RequestParam(defaultValue = "A4") String papersource){
|
||||
public Result<String> print(@RequestParam(defaultValue = "A4") String papersource) {
|
||||
this.ms439PrintService.getStatus(papersource);
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@@ -48,12 +48,12 @@ public class ReceiptPrintRequest implements Serializable {
|
||||
/**
|
||||
* 小票渲染宽度,默认为:690
|
||||
*/
|
||||
private Integer width = 690;
|
||||
private Integer width = 700;
|
||||
|
||||
/**
|
||||
* 生成的模板的高度,默认为:1200
|
||||
*/
|
||||
private Integer height = 1250;
|
||||
private Integer height = 1400;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
package com.dpkj.modules.print.service;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.dpkj.common.dto.LexMarkResultDTO;
|
||||
import com.dpkj.modules.print.request.MS439Request;
|
||||
import com.dpkj.modules.print.vo.PrinterStatus;
|
||||
import javassist.compiler.Lex;
|
||||
|
||||
public interface MS439PrintService {
|
||||
|
||||
LexMarkResultDTO<?> printImage(MS439Request request);
|
||||
|
||||
LexMarkResultDTO<PrinterStatus> getStatus(String papersource);
|
||||
|
||||
String getJYPDFPath(JSONObject params);
|
||||
|
||||
void deleteSysFileByPath(String path);
|
||||
}
|
||||
|
||||
@@ -1,22 +1,55 @@
|
||||
package com.dpkj.modules.print.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.dpkj.common.config.PrinterConfig;
|
||||
import com.dpkj.common.dto.LexMarkDTO;
|
||||
import com.dpkj.common.dto.LexMarkResultDTO;
|
||||
import com.dpkj.common.exception.RRException;
|
||||
import com.dpkj.common.utils.ThirdService;
|
||||
import com.dpkj.modules.print.enums.*;
|
||||
import com.dpkj.modules.print.enums.MS439DeviceStatusEnum;
|
||||
import com.dpkj.modules.print.enums.MS439InkStatusEnum;
|
||||
import com.dpkj.modules.print.enums.MS439MediaStatusEnum;
|
||||
import com.dpkj.modules.print.enums.MS439PaperStatusEnum;
|
||||
import com.dpkj.modules.print.enums.MS439StampStatusEnum;
|
||||
import com.dpkj.modules.print.enums.MS439TonerStatusEnum;
|
||||
import com.dpkj.modules.print.request.MS439Request;
|
||||
import com.dpkj.modules.print.service.MS439PrintService;
|
||||
import com.dpkj.modules.print.utils.FolderUtils;
|
||||
import com.dpkj.modules.print.utils.FontLoader;
|
||||
import com.dpkj.modules.print.utils.PDFUtils;
|
||||
import com.dpkj.modules.print.vo.PrinterParam;
|
||||
import com.dpkj.modules.print.vo.PrinterStatus;
|
||||
import com.itextpdf.text.BaseColor;
|
||||
import com.itextpdf.text.Document;
|
||||
import com.itextpdf.text.DocumentException;
|
||||
import com.itextpdf.text.Font;
|
||||
import com.itextpdf.text.PageSize;
|
||||
import com.itextpdf.text.pdf.BaseFont;
|
||||
import com.itextpdf.text.pdf.PdfWriter;
|
||||
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
|
||||
import com.itextpdf.tool.xml.XMLWorkerHelper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thymeleaf.TemplateEngine;
|
||||
import org.thymeleaf.context.Context;
|
||||
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
|
||||
import org.thymeleaf.templatemode.TemplateMode;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 利盟MS439打印机服务
|
||||
@@ -49,7 +82,7 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||
PrinterStatus ms439 = status.getData();
|
||||
|
||||
// 如果是要盖章,校验盖章机器是否正常
|
||||
if ( request.getStamp() == 1) {
|
||||
if (request.getStamp() == 1) {
|
||||
String deviceExStatus = ms439.getStDeviceExStatus();
|
||||
if (deviceExStatus == null || deviceExStatus.equals("")) {
|
||||
throw new RRException("获取打印机设备状态出问题");
|
||||
@@ -60,7 +93,7 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||
}
|
||||
String device = devices[1];
|
||||
// 校验盖章机是否正常,除了HEALTHY都抛异常
|
||||
if (!device.equals(MS439StampStatusEnum.HEALTHY.getPrintCode()) ) {
|
||||
if (!device.equals(MS439StampStatusEnum.HEALTHY.getPrintCode())) {
|
||||
throw new RRException(MS439StampStatusEnum.getPCode(device),
|
||||
MS439StampStatusEnum.getMessage(device));
|
||||
}
|
||||
@@ -72,12 +105,13 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||
lexMarkDTO.setDevName("HtmPrinter");
|
||||
lexMarkDTO.setPluginMethod("exec");
|
||||
|
||||
JSONObject param = new JSONObject();
|
||||
JSONObject param = new JSONObject();
|
||||
|
||||
// printType 选择箱子
|
||||
// param.put("prtData", String.format("PrintType=%d;pagesource=%s;copies=%d;file[0]=%s;stamp=%d;duplex=%d;color=%d;direction=%d",
|
||||
// request.getPagesource(), request.getCopies(), request.getFileDir(), request.getStamp(),
|
||||
// request.getDuplex(), request.getColor(), request.getDirection()));
|
||||
|
||||
// 计算A4/A5归属
|
||||
int printType = 1; // 默认使用第一层
|
||||
if (printerConfig.getLevelOne().equals("A5")) {
|
||||
@@ -89,7 +123,7 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||
printType = 2;
|
||||
}
|
||||
}
|
||||
param.put("prtData", String.format("PaperNum=%d;PrintType=%d;Stamp=%d;File[0]=%s;WaitNum=%d;copies=%d;stamp=%d;duplex=%d;color=%d;direction=%d",
|
||||
/*param.put("prtData", String.format("PaperNum=%d;PrintType=%d;Stamp=%d;File[0]=%s;WaitNum=%d;copies=%d;stamp=%d;duplex=%d;color=%d;direction=%d",
|
||||
request.getCopies(), // 盖章事件分数,和打印份数一致
|
||||
printType, // 打印类型1-A4或者2-A5
|
||||
request.getStamp(), // 是否盖章
|
||||
@@ -99,12 +133,21 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||
request.getStamp(), // 是否盖章 0-不盖章 1-盖章
|
||||
request.getDuplex(), // 单面还是双面打印 1-单面 2-双面
|
||||
request.getColor(), // 打印的颜色0-黑色,1-彩色
|
||||
request.getDirection()));
|
||||
request.getDirection()));*/
|
||||
|
||||
String prtData = StrUtil.format("PaperNum={};PrintType={};Stamp={};File[0]={};WaitNum={}",
|
||||
request.getCopies(), // 盖章事件分数,和打印份数一致
|
||||
printType, // 打印类型1-A4或者2-A5
|
||||
request.getStamp(), // 是否盖章
|
||||
request.getFileDir(), // 要打印的文件的路径
|
||||
request.getCopies() // 盖章事件分数,和打印份数一致
|
||||
);
|
||||
param.put("prtData", prtData);
|
||||
|
||||
lexMarkDTO.setParam(param.toString());
|
||||
LexMarkResultDTO<LexMarkResultDTO.Param> paramLexMarkResultDTO = thirdService.callDevice(lexMarkDTO, LexMarkResultDTO.Param.class);
|
||||
LexMarkResultDTO<PrinterParam> paramLexMarkResultDTO = thirdService.callDevice(lexMarkDTO, PrinterParam.class);
|
||||
|
||||
if ( paramLexMarkResultDTO.getData().getResult() != 0){
|
||||
if (paramLexMarkResultDTO.getData().getResult() != 0) {
|
||||
throw new RRException(500, paramLexMarkResultDTO.getData().getResult() + "");
|
||||
}
|
||||
|
||||
@@ -131,9 +174,12 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||
lexMarkDTO.setDevName("HtmPrinter");
|
||||
lexMarkDTO.setPluginMethod("exec");
|
||||
|
||||
// 获取状态
|
||||
LexMarkResultDTO<PrinterStatus> status = thirdService.callDevice(lexMarkDTO, PrinterStatus.class);
|
||||
if ( status.getResult() != 0){
|
||||
if (status.getResult() != 0) {
|
||||
// 打开打印机
|
||||
thirdService.open("HtmPrinter", 0);
|
||||
// 打印
|
||||
status = thirdService.callDevice(lexMarkDTO, PrinterStatus.class);
|
||||
}
|
||||
|
||||
@@ -142,7 +188,7 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||
throw new RRException("获取打印机纸张状态出问题");
|
||||
}
|
||||
String[] papers = stPaperEx.split("\\|");
|
||||
if ( papers.length < 2) {
|
||||
if (papers.length < 2) {
|
||||
throw new RRException("打印机纸盒数量不对");
|
||||
}
|
||||
String paperStatus = "";
|
||||
@@ -154,13 +200,13 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||
if (papersource.equals("A5")) {
|
||||
paperStatus = printerConfig.getLevelOne().equals("A5") ? papers[0] : papers[1];
|
||||
}
|
||||
if ( !(paperStatus.equals(MS439PaperStatusEnum.PAPERFULL.getPrintCode()) || paperStatus.equals(MS439PaperStatusEnum.PAPERLOW.getPrintCode()))){
|
||||
if (!(paperStatus.equals(MS439PaperStatusEnum.PAPERFULL.getPrintCode()) || paperStatus.equals(MS439PaperStatusEnum.PAPERLOW.getPrintCode()))) {
|
||||
throw new RRException(500, paperStatus);
|
||||
}
|
||||
|
||||
PrinterStatus ms439 = status.getData();
|
||||
// 校验打印机是否正常,除了HEALTHY都抛异常
|
||||
if (!ms439.getStDeviceStatus().equals(MS439DeviceStatusEnum.HEALTHY.getPrintCode()) ) {
|
||||
if (!ms439.getStDeviceStatus().equals(MS439DeviceStatusEnum.HEALTHY.getPrintCode())) {
|
||||
throw new RRException(500, ms439.getStDeviceStatus());
|
||||
}
|
||||
|
||||
@@ -170,19 +216,171 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||
}
|
||||
|
||||
// 校验磁带 满或者少才放行
|
||||
if ( !(ms439.getStToner().equals(MS439TonerStatusEnum.TONERFULL.getPrintCode()) || ms439.getStToner().equals(MS439TonerStatusEnum.TONERLOW.getPrintCode()))){
|
||||
if (!(ms439.getStToner().equals(MS439TonerStatusEnum.TONERFULL.getPrintCode()) || ms439.getStToner().equals(MS439TonerStatusEnum.TONERLOW.getPrintCode()))) {
|
||||
throw new RRException(500, ms439.getStToner());
|
||||
}
|
||||
|
||||
// 校验墨盒 满或者少才放行,当前获取为未知
|
||||
if ( false && !(ms439.getStInk().equals(MS439InkStatusEnum.INKFULL.getPrintCode()) || ms439.getStInk().equals(MS439InkStatusEnum.INKLOW.getPrintCode())
|
||||
|| ms439.getStInk().equals(MS439InkStatusEnum.INKUNKNOWN.getPrintCode()))){
|
||||
if (false && !(ms439.getStInk().equals(MS439InkStatusEnum.INKFULL.getPrintCode()) || ms439.getStInk().equals(MS439InkStatusEnum.INKLOW.getPrintCode())
|
||||
|| ms439.getStInk().equals(MS439InkStatusEnum.INKUNKNOWN.getPrintCode()))) {
|
||||
throw new RRException(500, ms439.getStInk());
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJYPDFPath(JSONObject params) {
|
||||
// 1. 准备输出路径
|
||||
String dirPath = "D://TempJYPDF//";
|
||||
File dir = new File(dirPath);// 确保目录存在
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
String fileName = "jiancha_" + params.getString("reportId") + "_" + System.currentTimeMillis() + ".pdf";
|
||||
String pdfPath = dirPath + fileName;
|
||||
|
||||
try {
|
||||
// 2. 准备模板数据
|
||||
Map<String, Object> data = prepareReportData(params);
|
||||
// 3. 渲染Thymeleaf模板
|
||||
String htmlContent = renderThymeleafTemplate(data);
|
||||
// 4. 生成PDF文件
|
||||
createPdfFromHtml(htmlContent, pdfPath);
|
||||
|
||||
return pdfPath;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(); // 打印完整异常堆栈
|
||||
throw new RuntimeException("PDF生成失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteSysFileByPath(String path) {
|
||||
if (path == null || path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
File file = new File(path);
|
||||
if (file.exists() && file.isFile()) {
|
||||
boolean deleted = file.delete();
|
||||
if (!deleted) {
|
||||
System.err.println("文件删除失败: " + path);
|
||||
}
|
||||
} else {
|
||||
System.err.println("文件不存在: " + path);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void createPdfFromHtml(String html, String outputPath)
|
||||
throws IOException, DocumentException {
|
||||
|
||||
// 大小为A4纸
|
||||
Document document = new Document(PageSize.A4);
|
||||
try (OutputStream os = Files.newOutputStream(Paths.get(outputPath))) {
|
||||
PdfWriter writer = PdfWriter.getInstance(document, os);
|
||||
document.open();
|
||||
|
||||
// 加载自定义字体
|
||||
BaseFont simfangFont = FontLoader.loadFont("/font/simfang.ttf");
|
||||
|
||||
// 创建自定义字体提供器
|
||||
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider() {
|
||||
@Override
|
||||
public Font getFont(String fontname, String encoding, boolean embedded, float size, int style, BaseColor color) {
|
||||
return new Font(simfangFont, size, style, color);
|
||||
}
|
||||
};
|
||||
|
||||
// 解析 HTML 并生成 PDF
|
||||
XMLWorkerHelper.getInstance().parseXHtml(
|
||||
writer, document,
|
||||
new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8)),
|
||||
null, StandardCharsets.UTF_8,
|
||||
fontProvider // 注入字体提供器
|
||||
);
|
||||
document.close(); // 这里关闭,确保 OutputStream 还没被关闭
|
||||
}
|
||||
}
|
||||
|
||||
// 模板渲染方法(保持不变)
|
||||
private String renderThymeleafTemplate(Map<String, Object> data) {
|
||||
// 设置模板数据
|
||||
Context context = new Context();
|
||||
context.setVariables(data);
|
||||
|
||||
// 填充数据到html
|
||||
TemplateEngine templateEngine = new TemplateEngine();
|
||||
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
|
||||
resolver.setPrefix("classpath:/templates/");
|
||||
resolver.setSuffix(".html");
|
||||
resolver.setTemplateMode(TemplateMode.HTML);
|
||||
resolver.setCacheable(true);
|
||||
resolver.setApplicationContext(new AnnotationConfigReactiveWebApplicationContext());
|
||||
templateEngine.setTemplateResolver(resolver);
|
||||
return templateEngine.process("reportJY", context);
|
||||
}
|
||||
|
||||
// 报告数据准备(根据实际业务实现)
|
||||
private Map<String, Object> prepareReportData(JSONObject params) {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
// 基本信息
|
||||
Map<String, String> baseInfo = new HashMap<>();
|
||||
baseInfo.put("reportId", params.getString("reportId"));// 报告id(标本编号)
|
||||
baseInfo.put("lspcmName", params.getString("lspcmName"));// 标本名称
|
||||
JSONObject patInfo = params.getJSONObject("pat_info");
|
||||
baseInfo.put("patName", patInfo.getString("pat_name"));// 姓名
|
||||
baseInfo.put("patSex", patInfo.getString("pat_sex"));// 性别
|
||||
baseInfo.put("patAge", patInfo.getString("pat_age"));// 年龄
|
||||
baseInfo.put("patHomePhno", patInfo.getString("pat_home_phno"));// 电话
|
||||
JSONObject pv1Info = params.getJSONObject("pv1_info");
|
||||
baseInfo.put("deptName", pv1Info.getString("dept_name"));// 科室
|
||||
baseInfo.put("inpBedNo", pv1Info.getString("inp_bed_no"));// 床号
|
||||
JSONObject applyInfoFirst = params.getJSONArray("apply_info").getJSONObject(0);
|
||||
baseInfo.put("placerName", applyInfoFirst.getString("placer_name"));// 申请医生
|
||||
baseInfo.put("spcmClctor", applyInfoFirst.getString("spcm_clctor"));// 标本采集人
|
||||
baseInfo.put("citemContent", params.getString("citemContent"));// 申请项目
|
||||
data.put("baseInfo", baseInfo);
|
||||
|
||||
// 检验项目数据
|
||||
List<Map<String, Object>> items = new ArrayList<>();
|
||||
JSONArray rptInfoList = params.getJSONArray("rpt_info");
|
||||
|
||||
for (int i = 0; i < rptInfoList.size(); i++) {
|
||||
JSONObject obj = rptInfoList.getJSONObject(i);
|
||||
// 项目名称:loitem_cname,
|
||||
// 结果:order_rpt_result,
|
||||
// 参考区间:loitem_rv,
|
||||
// 单位:loitem_unit,
|
||||
// 测试方法:inspection_method,
|
||||
// 结果异常标志:oaflag
|
||||
addItem(items, obj.getString("loitem_cname"),
|
||||
obj.getString("order_rpt_result"),
|
||||
obj.getString("loitem_rv"),
|
||||
obj.getString("loitem_unit"),
|
||||
obj.getString("inspection_method"),
|
||||
obj.getString("oaflag"));
|
||||
}
|
||||
data.put("items", items);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private void addItem(List<Map<String, Object>> items, String name,
|
||||
String value, String range, String unit, String method, String oaflag) {
|
||||
Map<String, Object> item = new HashMap<>();
|
||||
item.put("loitemCname", name);// 项目名称
|
||||
item.put("orderRptResult", value);// 结果
|
||||
item.put("loitemRv", range);// 参考区间
|
||||
item.put("loitemUnit", unit);// 单位
|
||||
item.put("inspectionMethod", method);// 测试方法
|
||||
item.put("oaflag", StrUtil.equals(oaflag, "0") || StrUtil.equals(oaflag, "1"));// 结果异常标志|-1-不计算改指标的参考、1-正常、2-偏低、3-偏高、4-阳性(异常)、5-警戒下限、6-警戒上限、7-复查下限、8-复查上限、9-线性异常
|
||||
item.put("oaflagLow", StrUtil.equals(oaflag, "2"));// 2显示下箭头
|
||||
item.put("oaflagHigh", StrUtil.equals(oaflag, "3"));// 3显示上箭头
|
||||
items.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,15 @@ import com.dpkj.common.dto.LexMarkResultDTO;
|
||||
import com.dpkj.common.exception.RRException;
|
||||
import com.dpkj.common.utils.TemplateUtils;
|
||||
import com.dpkj.common.utils.ThirdService;
|
||||
import com.dpkj.modules.print.enums.*;
|
||||
import com.dpkj.modules.print.enums.MS439DeviceStatusEnum;
|
||||
import com.dpkj.modules.print.enums.MS439InkStatusEnum;
|
||||
import com.dpkj.modules.print.enums.MS439MediaStatusEnum;
|
||||
import com.dpkj.modules.print.enums.MS439PaperStatusEnum;
|
||||
import com.dpkj.modules.print.enums.MS439TonerStatusEnum;
|
||||
import com.dpkj.modules.print.enums.ReceiptTemplateEnum;
|
||||
import com.dpkj.modules.print.service.PrintService;
|
||||
import com.dpkj.modules.print.utils.FolderUtils;
|
||||
import com.dpkj.modules.print.vo.PrinterParam;
|
||||
import com.dpkj.modules.print.vo.PrinterStatus;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -47,7 +53,7 @@ public class RegisterServiceImpl implements PrintService {
|
||||
private static final int FIXED_WIDTH = 730;
|
||||
|
||||
@Override
|
||||
public LexMarkResultDTO<LexMarkResultDTO.Param> printImage(JSONObject data, String template, int width, int height, String saveDir) {
|
||||
public LexMarkResultDTO<PrinterParam> printImage(JSONObject data, String template, int width, int height, String saveDir) {
|
||||
FolderUtils.checkFolderAndCreate(saveDir);
|
||||
|
||||
if (height <= 0) {
|
||||
@@ -74,8 +80,8 @@ public class RegisterServiceImpl implements PrintService {
|
||||
|
||||
int dinyHeight = 0;
|
||||
if (templateName.equals("department")) {
|
||||
// 由于是使用的门诊小票-T2,那么默认的高度为1000,强行设置,通过动态修改渲染的图片的高度
|
||||
height = 1000;
|
||||
// 由于是使用的门诊小票-T2,那么默认的高度为1100,强行设置,通过动态修改渲染的图片的高度
|
||||
height = 1100;
|
||||
|
||||
// 单行最大长度为10
|
||||
int singleLineMaxLength = 10;
|
||||
@@ -172,7 +178,7 @@ public class RegisterServiceImpl implements PrintService {
|
||||
param.put("mediaCtrl", 1); // 媒介类型,当前为:打印缓冲区 + 弹出 + 剪纸
|
||||
param.put("fields", StringUtils.join(filePathList, "&"));
|
||||
lexMarkDTO.setParam(param.toJSONString());
|
||||
LexMarkResultDTO<LexMarkResultDTO.Param> paramLexMarkResultDTO = thirdService.callDevice(lexMarkDTO, LexMarkResultDTO.Param.class);
|
||||
LexMarkResultDTO<PrinterParam> paramLexMarkResultDTO = thirdService.callDevice(lexMarkDTO, PrinterParam.class);
|
||||
|
||||
for (String path : deletePathList) {
|
||||
if (path != null && !path.isEmpty()) {
|
||||
|
||||
43
src/main/java/com/dpkj/modules/print/utils/FontLoader.java
Normal file
43
src/main/java/com/dpkj/modules/print/utils/FontLoader.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package com.dpkj.modules.print.utils;
|
||||
|
||||
import com.itextpdf.text.pdf.BaseFont;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author 余文财
|
||||
* @description 字体加载
|
||||
* @date 2025.6.24
|
||||
*/
|
||||
public class FontLoader {
|
||||
public static BaseFont loadFont(String resourcePath) {
|
||||
try (InputStream fontStream = FontLoader.class.getResourceAsStream(resourcePath)) {
|
||||
if (fontStream == null) {
|
||||
throw new IllegalArgumentException("字体文件未找到: " + resourcePath);
|
||||
}
|
||||
byte[] fontBytes = toByteArray(fontStream);
|
||||
return BaseFont.createFont(
|
||||
resourcePath,
|
||||
BaseFont.IDENTITY_H,
|
||||
BaseFont.EMBEDDED,
|
||||
false,
|
||||
fontBytes,
|
||||
null
|
||||
);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("字体加载失败: " + resourcePath, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] toByteArray(InputStream input) throws IOException {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
int nRead;
|
||||
byte[] data = new byte[4096];
|
||||
while ((nRead = input.read(data, 0, data.length)) != -1) {
|
||||
buffer.write(data, 0, nRead);
|
||||
}
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
}
|
||||
61
src/main/java/com/dpkj/modules/print/vo/PrinterParam.java
Normal file
61
src/main/java/com/dpkj/modules/print/vo/PrinterParam.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package com.dpkj.modules.print.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 利盟接口返回值DTO
|
||||
*
|
||||
* @author <a href="https://gitee.com/shi-chongli">石头人</a>
|
||||
* @version 1.0
|
||||
* @since 2025-02-08 11:03:06
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PrinterParam implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 请求ID
|
||||
*/
|
||||
private Integer RequestID;
|
||||
|
||||
/**
|
||||
* 命令编码
|
||||
*/
|
||||
private Integer dwCommandCode;
|
||||
|
||||
/**
|
||||
* 事件名,由发送请求中的actionName+Over组成。
|
||||
*/
|
||||
private String eventName;
|
||||
|
||||
/**
|
||||
* 事件类型编码
|
||||
*/
|
||||
private Integer eventType;
|
||||
|
||||
/**
|
||||
* 服务
|
||||
*/
|
||||
private Integer hService;
|
||||
|
||||
/**
|
||||
* 对应发送请求中的devName
|
||||
*/
|
||||
private String cmdName;
|
||||
|
||||
/**
|
||||
* 错误码:0表示成功;其他表示失败,比如-4表示取消,-48表示超时,-14表示硬件故障
|
||||
*/
|
||||
private Integer result;
|
||||
|
||||
/**
|
||||
* 详情描述
|
||||
*/
|
||||
private String desc;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
package com.dpkj.modules.print.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class PrinterStatus {
|
||||
@Accessors(chain = true)
|
||||
public class PrinterStatus implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* sp服务版本号
|
||||
*/
|
||||
|
||||
@@ -4,21 +4,20 @@ 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.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;
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
@@ -45,6 +44,20 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
||||
private AliFaceConfig aliFaceConfig;
|
||||
|
||||
|
||||
/**
|
||||
* 资源初始化
|
||||
* 把刷脸初始化加到项目启动时先初始化一次,防止首次调用刷脸初始化过慢的问题
|
||||
*/
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
log.info("[AliScanFaceServiceImpl][postConstruct][支付宝刷脸DLL] 初始化动态链接库");
|
||||
try {
|
||||
this.iniAbcpAbsolute();
|
||||
} catch (Exception e) {
|
||||
log.info("[AliScanFaceServiceImpl][postConstruct][56][支付宝刷脸初始化失败:] :{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: * 完整的统一的支付宝刷脸支付
|
||||
* 1、调用硬件刷脸获取到ftoken
|
||||
@@ -58,45 +71,52 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
||||
public Result<JSONObject> aliFacePay(AliOrderVo aliOrderVo) {
|
||||
try {
|
||||
/**
|
||||
* 1、获取刷脸"刷脸去初始化服务"的ftoken返回值
|
||||
* 0、执行ABCP初始化
|
||||
*/
|
||||
this.iniAbcpAbsolute();
|
||||
//参数
|
||||
JSONObject zolozConfig = new JSONObject().fluentPut("installAngle", 90);
|
||||
JSONObject params = new JSONObject()
|
||||
.fluentPut("serviceId", aliFaceConfig.getServiceId())
|
||||
.fluentPut("zolozConfig", zolozConfig);
|
||||
String json = params.toJSONString();
|
||||
String service_code = AliFaceConstants.SMILEVERIFYNIN_V1; //调用的组件编码:初始化
|
||||
Result<Object> startServiceIniResult = this.startServiceIni(json, service_code);
|
||||
log.info("[AliScanFaceServiceImpl][aliFacePay][72][调用ABCP调用刷脸的结果] :{}", startServiceIniResult.toString());
|
||||
if (startServiceIniResult.isSuccess()) {
|
||||
Map<String, String> res = (Map<String, String>) startServiceIniResult.getResult();
|
||||
String ftoken = res.get("ftoken");
|
||||
log.info("[AliScanFaceServiceImpl][aliFacePay][76][调用ABCP调用刷脸的结果的ftoken] :{}", ftoken.toString());
|
||||
|
||||
Result<Object> result = this.iniAbcpAbsolute();
|
||||
if (result.isSuccess()) {
|
||||
/**
|
||||
* 2、调用后端的支付宝统一收单交易支付接口、存入hisPay
|
||||
* 1、获取刷脸"刷脸去初始化服务"的ftoken返回值
|
||||
*/
|
||||
aliOrderVo.setAuthCode(ftoken);//Demo值:"fp128d26333fa66e66e7f34c493d30cdh76"
|
||||
JSONObject serverParams = (JSONObject) JSON.toJSON(aliOrderVo);
|
||||
//参数
|
||||
JSONObject zolozConfig = new JSONObject().fluentPut("installAngle", 90);
|
||||
JSONObject params = new JSONObject()
|
||||
.fluentPut("serviceId", aliFaceConfig.getServiceId())
|
||||
.fluentPut("zolozConfig", zolozConfig);
|
||||
String json = params.toJSONString();
|
||||
String service_code = AliFaceConstants.SMILEVERIFYNIN_V1; //调用的组件编码:初始化
|
||||
Result<Object> startServiceIniResult = this.startServiceIni(json, service_code);
|
||||
log.info("[AliScanFaceServiceImpl][aliFacePay][72][1、获取刷脸去初始化服务的结果] :{}", startServiceIniResult.toString());
|
||||
if (startServiceIniResult.isSuccess()) {
|
||||
Map<String, String> res = (Map<String, String>) startServiceIniResult.getResult();
|
||||
String ftoken = res.get("ftoken");
|
||||
log.info("[AliScanFaceServiceImpl][aliFacePay][76][[1、获取刷脸去初始化服务的结果-ftoken值] :{}", ftoken);
|
||||
|
||||
String url = serverUrl + "openapi/aliPayOrderApi/createOrder";
|
||||
log.info("[AliScanFaceServiceImpl][aliFacePay][85][调用后端的支付宝统一收单交易支付接口路径] :{}", serverUrl);
|
||||
log.info("[AliScanFaceServiceImpl][aliFacePay][85][调用后端的支付宝统一收单交易支付接口参数] :{}", serverParams.toJSONString());
|
||||
String req = HttpRequest.post(url)
|
||||
.header(Header.CONTENT_TYPE, ContentType.JSON.toString(CharsetUtil.CHARSET_UTF_8))
|
||||
.body(serverParams.toJSONString())
|
||||
.execute()
|
||||
.body();
|
||||
JSONObject serverResult = JSONObject.parseObject(req);
|
||||
log.info("[AliScanFaceServiceImpl][aliFacePay][93][调用后端的支付宝统一收单交易支付接口结果] :{}", serverResult.toString());
|
||||
/**
|
||||
* 2、调用后端的支付宝统一收单交易支付接口、存入hisPay
|
||||
*/
|
||||
aliOrderVo.setAuthCode(ftoken);//Demo值:"fp128d26333fa66e66e7f34c493d30cdh76"
|
||||
JSONObject serverParams = (JSONObject) JSON.toJSON(aliOrderVo);
|
||||
log.info("[AliScanFaceServiceImpl][aliFacePay][83][调用后端的支付宝统一收单交易支付接口参数] :{}", serverParams.toString());
|
||||
|
||||
return Result.ok(serverResult);
|
||||
} else {
|
||||
//调用ABCP 刷脸初始化服务失败
|
||||
log.error("[AliScanFaceServiceImpl][aliFacePay][299]调用ABCP 刷脸初始化服务失败 :{}", startServiceIniResult.getMessage());
|
||||
return Result.error(startServiceIniResult.getMessage());
|
||||
String url = serverUrl + "openapi/aliPayOrderApi/createOrder";
|
||||
log.info("[AliScanFaceServiceImpl][aliFacePay][86][调用后端的支付宝统一收单交易支付接口路径] :{}", url);
|
||||
String req = HttpRequest.post(url)
|
||||
.header(Header.CONTENT_TYPE, ContentType.JSON.toString(CharsetUtil.CHARSET_UTF_8))
|
||||
.body(serverParams.toJSONString())
|
||||
.execute()
|
||||
.body();
|
||||
JSONObject serverResult = JSONObject.parseObject(req);
|
||||
log.info("[AliScanFaceServiceImpl][aliFacePay][93][调用后端的支付宝统一收单交易支付接口结果] :{}", serverResult.toString());
|
||||
|
||||
return Result.ok(serverResult);
|
||||
} else {
|
||||
//调用ABCP 刷脸初始化服务失败
|
||||
log.error("[AliScanFaceServiceImpl][aliFacePay][299]调用ABCP 刷脸初始化服务失败 :{}", startServiceIniResult.getMessage());
|
||||
return Result.error(startServiceIniResult.getMessage());
|
||||
}
|
||||
}else {
|
||||
return Result.error("执行iniAbcpAbsolute初始化失败");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -132,23 +152,59 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
||||
//指定支付宝LOT SDK的本地库路径
|
||||
AbcpInvoke.SetAPIPathFile(aliFaceConfig.getDllPath());
|
||||
|
||||
// 使用 CountDownLatch 实现线程同步
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
CountDownLatch latchFinish = new CountDownLatch(1);
|
||||
|
||||
//获取返回数据
|
||||
AtomicReference<Integer> processCode = new AtomicReference<>();
|
||||
AtomicReference<String> processResult = new AtomicReference<>();
|
||||
AtomicReference<Integer> finishCode = new AtomicReference<>();
|
||||
AtomicReference<String> finishResult = new AtomicReference<>();
|
||||
|
||||
//创建回调实例
|
||||
AbcpInvoke.CallbackRsp callbackRsp = new AbcpInvoke.CallbackRsp() {
|
||||
@Override
|
||||
public void OnProcess(int code, String subCode, String subMsg, String result) {
|
||||
log.info("[AliScanFaceServiceImpl][OnProcess][123][ABCP调用iniAbcpAbsolute][code:{}][subCode:{}][subMsg:{}][result:{}]", code, subCode, subMsg, result);
|
||||
log.info("[AliScanFaceServiceImpl][OnProcess][155][0、ABCP调用iniAbcpAbsolute-OnProcess][code:{}][subCode:{}][subMsg:{}][result:{}] ", code, subCode, subMsg, result);
|
||||
try {
|
||||
processCode.set(code);
|
||||
processResult.set(result);
|
||||
} finally {
|
||||
latch.countDown(); // 确保无论如何都释放锁
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnFinish(int code, String subCode, String subMsg, String result) {
|
||||
log.info("[AliScanFaceServiceImpl][OnFinish][128][ABCP调用iniAbcpAbsolute][code:{}][subCode:{}][subMsg:{}][result:{}]", code, subCode, subMsg, result);
|
||||
log.info("[AliScanFaceServiceImpl][OnFinish][167][0、ABCP调用iniAbcpAbsolute-OnFinish][code:{}][subCode:{}][subMsg:{}][result:{}]", code, subCode, subMsg, result);
|
||||
try {
|
||||
finishCode.set(code);
|
||||
finishResult.set(result);
|
||||
} finally {
|
||||
latchFinish.countDown(); // 确保无论如何都释放锁
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//初始化
|
||||
log.info("[AliScanFaceServiceImpl][iniAbcpAbsolute][175][0、ABCP调用iniAbcpAbsolute初始化参数][appId:{}][appVersion:{}][json:{}] ", aliFaceConfig.getAppId(), aliFaceConfig.getAppVersion(), json);
|
||||
AbcpInvoke.AbcpInit(aliFaceConfig.getAppId(), aliFaceConfig.getAppVersion(), json, callbackRsp);
|
||||
|
||||
return Result.ok("支付宝ABCP初始化成功");
|
||||
// 等待finish回调完成(设置超时避免死锁)
|
||||
boolean awaitFinishSuccess = latchFinish.await(120, TimeUnit.SECONDS);
|
||||
if (!awaitFinishSuccess) {
|
||||
log.info("[AliScanFaceServiceImpl][iniAbcpAbsolute][181] [0、ABCP调用iniAbcpAbsolute初始化-120秒-等待finish回调超时]");
|
||||
return Result.error("初始化等待finish回调超时");
|
||||
} else {
|
||||
JSONObject jsonObject = JSONObject.parseObject(finishResult.get());
|
||||
log.info("[AliScanFaceServiceImpl][iniAbcpAbsolute][184][0、ABCP调用iniAbcpAbsolute初始化-finish回调结果-finishCode :{}] [返回结果:{}]", finishCode, jsonObject.toString());
|
||||
if (finishCode.get() == 1000) {
|
||||
return Result.ok("ABCP调用iniAbcpAbsolute初始化成功");
|
||||
} else {
|
||||
return Result.error("ABCP调用刷脸初始化服务finish失败");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.info("[AliScanFaceServiceImpl][iniAbcpAbsolute][55][{} :文件不存在]", aliFaceConfig.getDllPath());
|
||||
return Result.error("支付宝ABCP初始化失败:" + aliFaceConfig.getDllPath() + "不存在");
|
||||
@@ -191,7 +247,7 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
||||
AbcpInvoke.CallbackRsp callbackRsp = new AbcpInvoke.CallbackRsp() {
|
||||
@Override
|
||||
public void OnProcess(int code, String subCode, String subMsg, String result) {
|
||||
log.info("[AliScanFaceServiceImpl][OnProcess][189][service_code:{}][code:{}][subCode:{}][subMsg:{}][result:{}]", service_code, code, subCode, subMsg, result);
|
||||
log.info("[AliScanFaceServiceImpl][OnProcess][123][service_code:{}][code:{}][subCode:{}][subMsg:{}][result:{}]", service_code, code, subCode, subMsg, result);
|
||||
try {
|
||||
processCode.set(code);
|
||||
processResult.set(result);
|
||||
@@ -202,7 +258,7 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
||||
|
||||
@Override
|
||||
public void OnFinish(int code, String subCode, String subMsg, String result) {
|
||||
log.info("[AliScanFaceServiceImpl][OnFinish][200][ABCP服务调用 刷脸初始化服务,获取ftoken:][service_code:{}][code:{}][subCode:{}][subMsg:{}][result:{}]", service_code, code, subCode, subMsg, result);
|
||||
log.info("[AliScanFaceServiceImpl][OnFinish][128][service_code:{}][code:{}][subCode:{}][subMsg:{}][result:{}]", service_code, code, subCode, subMsg, result);
|
||||
|
||||
/**Demo示例记录
|
||||
* [service_code:BPaaSSmileVerifyNonInitV1][code:1000][subCode:E00000][subMsg:SUCCESS][result:{"code":1000,"subCode":"OK_SUCCESS","subMessage":"SUCCESS","barCode":"281215320962898068","ftoken":"fp1efd3d4c0230a28f5261efe7c5050eh28","alipayUid":"2088812449506047","accountList":"[\"104***@qq.com\"]","authToken":"44686f7195c77ee2e09c09bcdc657dd5h28i","result":{"accountList":["104***@qq.com"],"alipayUid":"2088812449506047","allowRetry":false,"authToken":"44686f7195c77ee2e09c09bcdc657dd5h28i","barCode":"281215320962898068","certName":"您好,*雪","ftoken":"fp1efd3d4c0230a28f5261efe7c5050eh28","type":"selectUid"},"easterEgg":false,"zolozConfig":{"installAngle":90},"serviceId":"pay","traceId":"2444-44-1745802328","callStartTimeMs":1745802328114,"localTime":"2025-04-28-09-05-41-791"}]
|
||||
@@ -223,12 +279,13 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
||||
// 等待process回调完成(设置超时避免死锁)
|
||||
boolean awaitSuccess = latch.await(10, TimeUnit.SECONDS);
|
||||
if (!awaitSuccess) {
|
||||
log.info("[AliScanFaceServiceImpl][startServiceIni][221][service_code:{}][ABCP调用刷脸:等待process回调超时]", service_code);
|
||||
log.info("[AliScanFaceServiceImpl][startServiceIni][226][10秒-等待process回调超时]");
|
||||
return Result.error("等待process回调超时");
|
||||
} else {
|
||||
log.info("[AliScanFaceServiceImpl][startServiceIni][229][ABCP调用刷脸初始化服务-process回调结果-processCode] :{}", processCode);
|
||||
if (processCode.get() == 0) {
|
||||
JSONObject jsonObject = JSONObject.parseObject(processResult.get());
|
||||
log.info("[AliScanFaceServiceImpl][startServiceIni][225][service_code:{}][ABCP调用刷脸-等待process回调完成结果] :{}", service_code, jsonObject.toString());
|
||||
log.info("[AliScanFaceServiceImpl][startServiceIni][232][ABCP调用刷脸初始化服务-process回调结果] :{}", jsonObject.toString());
|
||||
if (jsonObject.containsKey("traceId")) {
|
||||
res.put("traceId", jsonObject.getString("traceId"));
|
||||
} else {
|
||||
@@ -242,11 +299,13 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
||||
// 等待finish回调完成(设置超时避免死锁)
|
||||
boolean awaitFinishSuccess = latchFinish.await(120, TimeUnit.SECONDS);
|
||||
if (!awaitFinishSuccess) {
|
||||
log.info("[AliScanFaceServiceImpl][startServiceIni][246][120秒-等待finish回调超时]");
|
||||
return Result.error("等待finish回调超时");
|
||||
} else {
|
||||
log.info("[AliScanFaceServiceImpl][startServiceIni][249][ABCP调用刷脸初始化服务-finish回调结果-finishCode] :{}", finishCode);
|
||||
if (finishCode.get() == 1000) {
|
||||
JSONObject jsonObject = JSONObject.parseObject(finishResult.get());
|
||||
log.info("[AliScanFaceServiceImpl][startServiceIni][244][service_code:{}] [ABCP调用刷脸-等待finish回调完成结果]:{}", service_code, jsonObject.toString());
|
||||
log.info("[AliScanFaceServiceImpl][startServiceIni][252][ABCP调用刷脸初始化服务-finish回调结果] :{}", jsonObject.toString());
|
||||
if (jsonObject.containsKey("ftoken")) {
|
||||
res.put("ftoken", jsonObject.getString("ftoken"));//ftoken参数的有效期为2分钟
|
||||
res.put("barCode", jsonObject.getString("barCode"));
|
||||
@@ -260,10 +319,10 @@ public class AliScanFaceServiceImpl implements IAliScanFaceService {
|
||||
}
|
||||
|
||||
//结果返回
|
||||
log.info("[AliScanFaceServiceImpl][startServiceIni][266][][ABCP调用刷脸初始化服务成功返回结果:] :{}", finishResultRef.get());
|
||||
return finishResultRef.get();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.info("[AliScanFaceServiceImpl][startServiceIni][261][ABCP调用刷脸初始化服务失败] :{}", e.getMessage());
|
||||
return Result.error("ABCP调用刷脸初始化服务失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class AliOrderVo implements Serializable {
|
||||
private String outTradeNo;
|
||||
|
||||
/**
|
||||
* 用户支付金额
|
||||
* 用户支付金额 单位元
|
||||
*/
|
||||
//@ApiModelProperty(value = "用户支付金额")
|
||||
private String totalAmount;
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -79,6 +80,10 @@ public class WxFacePayController {
|
||||
public Result<String> doFacePay(@RequestBody WxFaceOrderVo wxFaceOrderVo) throws Exception {
|
||||
Result<String> result = new Result<>();
|
||||
try {
|
||||
//元转分
|
||||
int money = new BigDecimal(wxFaceOrderVo.getTotalAmount()).multiply(new BigDecimal(100)).intValue();
|
||||
wxFaceOrderVo.setTotalAmount(String.valueOf(money));
|
||||
|
||||
//1 初始化
|
||||
this.initWxpayface();
|
||||
|
||||
@@ -95,6 +100,7 @@ public class WxFacePayController {
|
||||
WxPayMicropayResult micropayResult = new WxPayMicropayResult();
|
||||
if (StringUtil.isNotBlank(authinfoResp.getFace_code())) {
|
||||
//5、调用后台人脸支付API发起支付
|
||||
System.out.println("---------调用后台人脸支付API发起支付");
|
||||
wxFaceOrderVo.setOutTradeNo(getOutTradeNo());
|
||||
micropayResult = this.toCreateWxOrder(authinfoResp, wxFaceOrderVo, wxFacePayResp0);
|
||||
|
||||
@@ -184,6 +190,7 @@ public class WxFacePayController {
|
||||
public WxFacePayAuthinfoResp getWxpayfaceCode(@RequestBody WxFaceOrderVo wxFaceOrderVo, WxFacePayAuthinfoResp wxFacePayResp0) throws Exception {
|
||||
//4、进行人脸识别getWxpayfaceCode(获取支付凭证)
|
||||
String outTradeNo = getOutTradeNo();//获取流水号
|
||||
|
||||
// 构建请求参数的JSON字符串
|
||||
WxFacePayReq wxFacePayReq = new WxFacePayReq("getWxpayfaceCode", "1", System.currentTimeMillis() / 1000);
|
||||
wxFacePayReq.setAuthinfo(wxFacePayResp0.getAuthinfo())
|
||||
|
||||
@@ -56,7 +56,6 @@ public class CallWxpayFaceServiceImpl implements CallWxpayFaceService {
|
||||
// 调用本地方法
|
||||
WxpayFaceSDKDll.Dll dll = WxpayFaceSDKDll.instance();
|
||||
int result = dll.wxpayCallFaceService(reqPointer.getString(0), reqSize, pRespBuf, respSize);
|
||||
//使用C:\Windows\System32目录下 int result = WxpayFaceSDK.INSTANCE.wxpayCallFaceService(reqPointer.getString(0), reqSize, pRespBuf, respSize);
|
||||
|
||||
if (result == 0) {
|
||||
Pointer pointer = new Pointer(pRespBuf[0]);
|
||||
|
||||
@@ -36,8 +36,10 @@ public class WxFaceOrderVo {
|
||||
private String outTradeNo;
|
||||
|
||||
/**
|
||||
* 用户支付金额 分
|
||||
* 用户支付金额 单位元
|
||||
* 调用微信时需要转为分
|
||||
*/
|
||||
private String totalAmount;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,59 @@
|
||||
server:
|
||||
port: 5948
|
||||
servlet:
|
||||
context-path: /api
|
||||
tomcat:
|
||||
max-swallow-size: -1
|
||||
error:
|
||||
include-exception: true
|
||||
include-stacktrace: ALWAYS
|
||||
include-message: ALWAYS
|
||||
compression:
|
||||
enabled: true
|
||||
min-response-size: 1024
|
||||
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.dpkj: debug
|
||||
|
||||
spring:
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 10MB
|
||||
max-request-size: 10MB
|
||||
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
|
||||
|
||||
@@ -1,14 +1,48 @@
|
||||
server:
|
||||
port: 5946
|
||||
servlet:
|
||||
context-path: /api
|
||||
tomcat:
|
||||
max-swallow-size: -1
|
||||
error:
|
||||
include-exception: true
|
||||
include-stacktrace: ALWAYS
|
||||
include-message: ALWAYS
|
||||
compression:
|
||||
enabled: true
|
||||
min-response-size: 1024
|
||||
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.dpkj: debug
|
||||
|
||||
spring:
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 10MB
|
||||
max-request-size: 10MB
|
||||
resource:
|
||||
static-locations: classpath:/static/,classpath:/public/
|
||||
|
||||
dpkj:
|
||||
#后端项目访问地址
|
||||
#TODO 改为正式的地址 http://www.lczyyy.com/api http://127.0.0.1:15946/api
|
||||
serverurl: http://www.lczyyy.com/api
|
||||
# 改为正式的地址 http://10.121.1.44/api/ http://172.16.50.20:15946/apitest/ http://www.lczyyy.com/apitest/
|
||||
serverurl: http://10.121.1.44/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: D:\Project\Express\upload
|
||||
@@ -45,27 +79,27 @@ dpkj:
|
||||
service-id: pay
|
||||
#微信模块
|
||||
wx:
|
||||
configs: # 清研家
|
||||
- app-id: wxc12fa4977f66974d #wxc12fa4977f66974d #wx024903d1d2e1a55a
|
||||
configs: #中医院
|
||||
- app-id: wxc12fa4977f66974d
|
||||
# 公众号的appsecret
|
||||
secret: a51dbcac25a73d7e4812a43cf550c5fc #f83420d79cc6ecd1d7fe9684ac9cdfe4
|
||||
# 接口配置里的Token值 DPKJ-YINYITONG #DPKJ-YINYITONG#dpkjylwjvote
|
||||
token: DPKJ-YINYITONG
|
||||
secret: a51dbcac25a73d7e4812a43cf550c5fc
|
||||
# 接口配置里的Token值
|
||||
token: DPKJYINYITONG
|
||||
# 接口配置里的EncodingAESKey值
|
||||
aes-key: yIBgBrHwRGjO2L3CLIE9hmnlf1FrXQQ7qJZVIg4r6Dx
|
||||
mch-config: #商户信息 驿路万家-扬州清研软件科技
|
||||
mch-config: #商户信息 中医院
|
||||
app-id: wxc12fa4977f66974d
|
||||
secret: f83420d79cc6ecd1d7fe9684ac9cdfe4
|
||||
secret: a51dbcac25a73d7e4812a43cf550c5fc
|
||||
#调用接口所需service_id
|
||||
service-id: service_id
|
||||
#商户号
|
||||
mch-id: 1557642321
|
||||
mch-id: 1603658732
|
||||
#商户秘钥
|
||||
mch-key: yndpkj15288216506YndpkjKsjytZx12
|
||||
mch-key: lczyywxc12fa4977f66974dyytzz1234
|
||||
#报文解密 APIv3密钥
|
||||
v3-key: yndpkj15288216506YndpkjKsjytZx12
|
||||
v3-key: lczyywxc12fa4977f66974dyytzz1234
|
||||
#微信: 商户APIv2密钥
|
||||
key-api: yndpkj15288216506YndpkjKsjytZx12
|
||||
key-api: lczyywxc12fa4977f66974dyytzz1234
|
||||
#p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath;开头)
|
||||
key-path: classpath:test\apiclient_cert.p12
|
||||
private-key-path: classpath:test\apiclient_key.pem
|
||||
|
||||
@@ -1,29 +1,5 @@
|
||||
server:
|
||||
servlet:
|
||||
context-path: /api
|
||||
tomcat:
|
||||
max-swallow-size: -1
|
||||
error:
|
||||
include-exception: true
|
||||
include-stacktrace: ALWAYS
|
||||
include-message: ALWAYS
|
||||
compression:
|
||||
enabled: true
|
||||
min-response-size: 1024
|
||||
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.dpkj: debug
|
||||
|
||||
spring:
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 10MB
|
||||
max-request-size: 10MB
|
||||
resource:
|
||||
static-locations: classpath:/static/,classpath:/public/
|
||||
application:
|
||||
name: ems-express-bridge
|
||||
name: yinyitong-zhongyuyuan-dll-stand
|
||||
profiles:
|
||||
active: dev
|
||||
active: '@profile.name@'
|
||||
|
||||
BIN
src/main/resources/font/simfang.ttf
Normal file
BIN
src/main/resources/font/simfang.ttf
Normal file
Binary file not shown.
@@ -29,9 +29,9 @@
|
||||
</appender>
|
||||
|
||||
<!-- 生成 error html格式日志开始 -->
|
||||
<appender name="HTML" class="ch.qos.logback.core.FileAppender">
|
||||
<!--<appender name="HTML" class="ch.qos.logback.core.FileAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<!--设置日志级别,过滤掉info日志,只输入error日志-->
|
||||
<!–设置日志级别,过滤掉info日志,只输入error日志–>
|
||||
<level>ERROR</level>
|
||||
</filter>
|
||||
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
|
||||
@@ -40,15 +40,15 @@
|
||||
</layout>
|
||||
</encoder>
|
||||
<file>${LOG_HOME}/error-log.html</file>
|
||||
</appender>
|
||||
</appender>-->
|
||||
<!-- 生成 error html格式日志结束 -->
|
||||
|
||||
<!-- 每天生成一个html格式的日志开始 -->
|
||||
<appender name="FILE_HTML" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!--<appender name="FILE_HTML" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<!--日志文件输出的文件名 -->
|
||||
<!–日志文件输出的文件名 –>
|
||||
<FileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}.%i.html</FileNamePattern>
|
||||
<!--日志文件保留天数 -->
|
||||
<!–日志文件保留天数 –>
|
||||
<MaxHistory>30</MaxHistory>
|
||||
<MaxFileSize>10MB</MaxFileSize>
|
||||
</rollingPolicy>
|
||||
@@ -57,7 +57,7 @@
|
||||
<pattern>%p%d%msg%M%F{32}%L</pattern>
|
||||
</layout>
|
||||
</encoder>
|
||||
</appender>
|
||||
</appender>-->
|
||||
<!-- 每天生成一个html格式的日志结束 -->
|
||||
|
||||
<!--myibatis log configure -->
|
||||
|
||||
@@ -7,48 +7,55 @@
|
||||
<body>
|
||||
<div style="font-size: 32px;font-weight: bold;">
|
||||
<div>
|
||||
<div style="text-align: center; font-size: 40px; "><span th:text="${hospitalName}"></span>
|
||||
<div style="height: 50px;"></div>
|
||||
<div style="text-align: center; font-size: 40px;font-weight: bold;"><span th:text="${hospitalName}"></span>
|
||||
</div>
|
||||
<div style="text-align: center; font-size: 28px;"><span>****<span
|
||||
<div style="text-align: center; font-size: 28px;font-weight: bold;"><span>****<span
|
||||
th:text="${registeTerminalName}"></span>****</span>
|
||||
</div>
|
||||
<div style="border-bottom: 1px dashed #000;margin: 3px 0;"></div>
|
||||
<div style="text-align: center; font-size: 40px; "><span th:text="${registeType}"></span></div>
|
||||
<div style="text-align: center; font-size: 40px;font-weight: bold;"><span th:text="${registeType}"></span></div>
|
||||
<div style="border-bottom: 1px dashed #000;margin: 3px 0;"></div>
|
||||
</div>
|
||||
<div style="font-size: 35px;word-break: break-all;margin: 10px 20px;">
|
||||
<div style="display: flex;">
|
||||
<div style="font-size: 35px;margin: 10px 20px;">
|
||||
<div style="margin-top: 10px;word-break: break-all;" th:if="${outpatientNumber}">门诊号:<span
|
||||
th:text="${outpatientNumber}"></span>
|
||||
</div>
|
||||
<div style="margin-top: 10px;word-break: break-all;">
|
||||
<span style="margin-right: 25px;">姓名:<span th:text="${name}"></span></span>
|
||||
<span style="margin-right: 25px;">性别:<span th:text="${gender}"></span></span>
|
||||
<span>年龄:<span th:text="${age}"></span></span>
|
||||
</div>
|
||||
<div style="word-break: break-all;margin-top: 10px;">
|
||||
<span style="margin-right: 25px;" th:if="${outpatientNumber}">
|
||||
门诊号:<span th:text="${outpatientNumber}"></span></span>
|
||||
<span th:if="${doctor}">
|
||||
就诊医生:<span th:text="${doctor}"></span>
|
||||
</span>
|
||||
<div style="margin-top: 10px;word-break: break-all;" th:if="${doctor}">
|
||||
就诊医生:<span th:text="${doctor}"></span>
|
||||
</div>
|
||||
<div style="margin-top: 10px;" th:if="${department}">就诊科室:<span th:text="${department}"></span>
|
||||
<div style="margin-top: 10px;word-break: break-all;" th:if="${department}">就诊科室:<span
|
||||
th:text="${department}"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: center; font-size: 32px;">
|
||||
-----------------------------------------------------------------------------
|
||||
</div>
|
||||
<div style="border-bottom: 1px dashed #000;margin: 3px 0;"></div>
|
||||
<div style="font-size: 35px; margin: 10px 20px">
|
||||
<div style="word-break: break-all;">
|
||||
<span style="margin-right: 25px;">费用总额:<span th:text="${totalFee}"></span></span>
|
||||
<span>个人支付:<span th:text="${personalPayment}"></span></span>
|
||||
<div style="text-align: center; font-size: 40px;font-weight: bold;"><span>费用信息</span></div>
|
||||
<div style="margin-top: 10px;">
|
||||
<div style="float: left;width: 190px;">金额合计:</div>
|
||||
<div style="margin-left: 190px;word-break: break-all;">
|
||||
<span>¥<span th:text="${totalFee}"></span>(小写金额)</span><br/>
|
||||
<span><span th:text="${actualReceiptAmountChinese}"></span>(大写金额)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 10px;word-break: break-all;">
|
||||
<span>实收金额:</span><span
|
||||
th:text="${actualReceiptAmount}"></span></div>
|
||||
<div style="margin-top: 10px;"><span>实收金额:</span><span th:text="${actualReceiptAmountChinese}"></span></div>
|
||||
<div th:if="${chs==1}">
|
||||
<div style="margin-top: 10px;word-break: break-all;">医保统筹支付:<span th:text="${ybtcjj}"></span></div>
|
||||
<div style="margin-top: 10px;word-break: break-all;">个人医保支付:<span th:text="${ybgrzh}"></span></div>
|
||||
<div style="margin-top: 10px;word-break: break-all;">医院账户支付:<span th:text="${yyzh}"></span></div>
|
||||
<div style="margin-top: 10px;word-break: break-all;">医院优惠金额:<span th:text="${yyyh}"></span></div>
|
||||
</div>
|
||||
<div style="margin-top: 10px;word-break: break-all;">个人自费:<span th:text="${personalPayment}"></span></div>
|
||||
</div>
|
||||
<div style="border-bottom: 1px dashed #000;margin: 3px 0;"></div>
|
||||
<div style="margin: 10px 20px">
|
||||
<div style="text-align: center; font-size: 40px;font-weight: bold;"><span>费用明细</span></div>
|
||||
<table style="width: 100%; table-layout: fixed; border-collapse: collapse;">
|
||||
<tr style="font-size: 35px;">
|
||||
<tr style="font-size: 32px;">
|
||||
<th style="width: 300px;text-align: left;">项目名称</th>
|
||||
<th style="width: calc(25% - 5px);text-align: center;">数量</th>
|
||||
<th style="width: calc(25% - 5px);text-align: center;">单价</th>
|
||||
@@ -63,10 +70,12 @@
|
||||
</table>
|
||||
</div>
|
||||
<div style="border-bottom: 1px dashed #000;margin-bottom: 3px;"></div>
|
||||
<div style="margin-left: 35px;font-size: 36px;">终端编号:<span th:text="${terminalNumber}"></span></div>
|
||||
<div style="margin-left: 35px;font-size: 36px;">打印时间:<span th:text="${printTime}"></span></div>
|
||||
<div style="margin-left: 35px;font-size: 36px;margin-top: 10px;">
|
||||
<span>温馨提示:请取走缴费凭证,并妥善保管。如果对缴费存在疑问,请到人工窗口咨询!</span>
|
||||
<div style="margin-left: 20px;font-size: 36px;word-break: break-all;">终端编号:<span
|
||||
th:text="${terminalNumber}"></span></div>
|
||||
<div style="margin-left: 20px;font-size: 36px;word-break: break-all;">打印时间:<span th:text="${printTime}"></span>
|
||||
</div>
|
||||
<div style="margin-left: 20px;font-size: 36px;word-break: break-all;">
|
||||
<span>温馨提示:请妥善保管好您的缴费凭条,如果对缴费存在疑问,请到人工窗口咨询。</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title>挂号单</title>
|
||||
<title>住院押金预缴</title>
|
||||
</head>
|
||||
<body>
|
||||
<div style="font-size: 32px;font-weight: bold;">
|
||||
<div>
|
||||
<div style="height: 50px;"></div>
|
||||
<div style="text-align: center; font-size: 40px; "><span th:text="${hospitalName}"></span>
|
||||
</div>
|
||||
<div style="text-align: center; font-size: 28px;"><span>****<span
|
||||
@@ -16,22 +17,22 @@
|
||||
<div style="border-bottom: 1px dashed #000;margin: 3px 0;"></div>
|
||||
</div>
|
||||
<div style=" font-size: 37px;">
|
||||
<div style="margin-left: 35px;">姓  名:<span th:text="${name}"></span></div>
|
||||
<div style="margin-left: 35px;">性  别:<span th:text="${gender}"></span></div>
|
||||
<div style="margin-left: 35px;">年  龄:<span th:text="${age}"></span></div>
|
||||
<div style="margin-left: 35px;">出生日期:<span th:text="${birthDate}"></span></div>
|
||||
<div style="margin-left: 35px;">门 诊 号:<span th:text="${outpatientNumber}"></span></div>
|
||||
<div style="margin-left: 35px;">入院科室:<span th:text="${department}"></span></div>
|
||||
<div style="margin-left: 35px;">总 费 用:<span th:text="${totalFee}"></span> 元</div>
|
||||
<div style="margin-left: 35px;">支付方式:<span th:text="${paymentMethod}"></span></div>
|
||||
<div style="margin-left: 35px;">交易流水:<span style="font-size: 35px;" th:text="${transactionNumber}"></span>
|
||||
<div style="margin-left: 20px;">姓  名:<span th:text="${name}"></span></div>
|
||||
<div style="margin-left: 20px;">性  别:<span th:text="${gender}"></span></div>
|
||||
<div style="margin-left: 20px;">年  龄:<span th:text="${age}"></span></div>
|
||||
<div style="margin-left: 20px;">出生日期:<span th:text="${birthDate}"></span></div>
|
||||
<div style="margin-left: 20px;">门 诊 号:<span th:text="${outpatientNumber}"></span></div>
|
||||
<div style="margin-left: 20px;">入院科室:<span th:text="${department}"></span></div>
|
||||
<div style="margin-left: 20px;">总 费 用:<span th:text="${totalFee}"></span> 元</div>
|
||||
<div style="margin-left: 20px;">支付方式:<span th:text="${paymentMethod}"></span></div>
|
||||
<div style="margin-left: 20px;">交易流水:<span style="font-size: 35px;" th:text="${transactionNumber}"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="border-bottom: 1px dashed #000;margin-bottom: 3px;"></div>
|
||||
<div style="margin-left: 35px;font-size: 36px;">终端编号:<span th:text="${terminalNumber}"></span></div>
|
||||
<div style="margin-left: 35px;font-size: 36px;">打印时间:<span th:text="${printTime}"></span></div>
|
||||
<div style="margin-left: 35px;font-size: 36px;margin-top: 10px;">
|
||||
<span>温馨提示:请取走缴费凭证,并妥善保管。如果对缴费存在疑问,请到人工窗口咨询!</span>
|
||||
<div style="margin-left: 20px;font-size: 36px;">终端编号:<span th:text="${terminalNumber}"></span></div>
|
||||
<div style="margin-left: 20px;font-size: 36px;">打印时间:<span th:text="${printTime}"></span></div>
|
||||
<div style="margin-left: 20px;font-size: 36px;">
|
||||
<span>温馨提示:请妥善保管好您的缴费凭条,如果对缴费存在疑问,请到人工窗口咨询。</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<body>
|
||||
<div style="font-size: 32px;font-weight: bold;">
|
||||
<div>
|
||||
<div style="height: 50px;"></div>
|
||||
<div style="text-align: center; font-size: 40px; "><span th:text="${hospitalName}"></span>
|
||||
</div>
|
||||
<div style="text-align: center; font-size: 28px;"><span>****<span
|
||||
@@ -26,10 +27,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div style="border-bottom: 1px dashed #000;margin-bottom: 3px;"></div>
|
||||
<div style="margin-left: 35px;font-size: 36px;">终端编号:<span th:text="${terminalNumber}"></span></div>
|
||||
<div style="margin-left: 35px;font-size: 36px;">打印时间:<span th:text="${printTime}"></span></div>
|
||||
<div style="margin-left: 35px;font-size: 36px;margin-top: 10px;">
|
||||
<span>温馨提示:请取走缴费凭证,并妥善保管。如果对缴费存在疑问,请到人工窗口咨询!</span>
|
||||
<div style="margin-left: 20px;font-size: 36px;">终端编号:<span th:text="${terminalNumber}"></span></div>
|
||||
<div style="margin-left: 20px;font-size: 36px;">打印时间:<span th:text="${printTime}"></span></div>
|
||||
<div style="margin-left: 20px;font-size: 36px;">
|
||||
<span>温馨提示:请妥善保管好您的缴费凭条,如果对缴费存在疑问,请到人工窗口咨询。</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
<body>
|
||||
<div style="font-size: 32px;font-weight: bold;">
|
||||
<div>
|
||||
<div style="text-align: center; font-size: 40px; "><span th:text="${hospitalName}"></span>
|
||||
<div style="height: 50px;"></div>
|
||||
<div style="text-align: center; font-size: 40px;"><span th:text="${hospitalName}"></span>
|
||||
</div>
|
||||
<div style="text-align: center; font-size: 28px;"><span>****<span
|
||||
th:text="${registeTerminalName}"></span>****</span>
|
||||
@@ -16,19 +17,20 @@
|
||||
<div style="border-bottom: 1px dashed #000;margin: 3px 0;"></div>
|
||||
</div>
|
||||
<div style=" font-size: 37px;">
|
||||
<div style="margin-left: 35px;">姓  名:<span th:text="${name}"></span></div>
|
||||
<div style="margin-left: 35px;">性  别:<span th:text="${gender}"></span></div>
|
||||
<div style="margin-left: 35px;">年  龄:<span th:text="${age}"></span></div>
|
||||
<div style="margin-left: 35px;">出生日期:<span th:text="${birthDate}"></span></div>
|
||||
<div style="margin-left: 35px;">门 诊 号:<span th:text="${outpatientNumber}"></span></div>
|
||||
<div style="margin-left: 35px;">就诊科室:<span th:text="${department}"></span></div>
|
||||
<div style="margin-left: 35px;">出诊级别:<span th:text="${visitLevel}"></span></div>
|
||||
<div style="margin-left: 35px;">就诊医生:<span th:text="${doctor}"></span></div>
|
||||
<div style="margin-left: 35px;">号  序:<span th:text="${sequence}"></span></div>
|
||||
<div style="margin-left: 35px;">挂号日期:<span th:text="${registerDate}"></span></div>
|
||||
<div style="margin-left: 35px;">总 费 用:<span th:text="${totalFee}"></span> 元</div>
|
||||
<div style="margin-left: 35px;">支付方式:<span th:text="${paymentMethod}"></span></div>
|
||||
<div style="margin-left: 35px;">交易流水:<span style="font-size: 35px;"
|
||||
<div style="margin-left: 20px;">姓  名:<span th:text="${name}"></span></div>
|
||||
<div style="margin-left: 20px;">性  别:<span th:text="${gender}"></span></div>
|
||||
<div style="margin-left: 20px;">年  龄:<span th:text="${age}"></span></div>
|
||||
<div style="margin-left: 20px;">出生日期:<span th:text="${birthDate}"></span></div>
|
||||
<div style="margin-left: 20px;">门 诊 号:<span th:text="${outpatientNumber}"></span></div>
|
||||
<div style="margin-left: 20px;">就诊科室:<span th:text="${department}"></span></div>
|
||||
<div style="margin-left: 20px;">出诊级别:<span th:text="${visitLevel}"></span></div>
|
||||
<div style="margin-left: 20px;">就诊医生:<span th:text="${doctor}"></span></div>
|
||||
<div style="margin-left: 20px;">就诊时间:<span th:text="${treatTime}"></span></div>
|
||||
<div style="margin-left: 20px;">号  序:<span th:text="${sequence}"></span></div>
|
||||
<div style="margin-left: 20px;">总 费 用:<span th:text="${totalFee}"></span>元</div>
|
||||
<div style="margin-left: 20px;">挂号时间:<span th:text="${registerDate}"></span></div>
|
||||
<div style="margin-left: 20px;">支付方式:<span th:text="${paymentMethod}"></span></div>
|
||||
<div style="margin-left: 20px;">交易流水:<span style="font-size: 35px;"
|
||||
th:text="${transactionNumber}"></span></div>
|
||||
<div style="width:100%;text-align: center;">
|
||||
<img th:src="${qrCodeBase64}"
|
||||
@@ -36,10 +38,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div style="border-bottom: 1px dashed #000;margin-bottom: 3px;"></div>
|
||||
<div style="margin-left: 35px;font-size: 36px;">终端编号:<span th:text="${terminalNumber}"></span></div>
|
||||
<div style="margin-left: 35px;font-size: 36px;">打印时间:<span th:text="${printTime}"></span></div>
|
||||
<div style="margin-left: 35px;font-size: 36px;margin-top: 10px;">
|
||||
<span>温馨提示:请取走挂号凭证,并妥善保管。如果对缴费存在疑问,请到人工窗口咨询!</span>
|
||||
<div style="margin-left: 20px;font-size: 36px;">终端编号:<span th:text="${terminalNumber}"></span></div>
|
||||
<div style="margin-left: 20px;font-size: 36px;">打印时间:<span th:text="${printTime}"></span></div>
|
||||
<div style="margin-left: 20px;font-size: 36px;">
|
||||
<span>温馨提示:请妥善保管好您的缴费凭条,如果对缴费存在疑问,请到人工窗口咨询。</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
150
src/main/resources/templates/reportJY.html
Normal file
150
src/main/resources/templates/reportJY.html
Normal file
@@ -0,0 +1,150 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>粪便检测报告单</title>
|
||||
</head>
|
||||
<body>
|
||||
<div style="font-size: 14px;">
|
||||
<!-- 医院标题 -->
|
||||
<div style="text-align: center;">
|
||||
<div style="font-size: 24px; font-weight: bold;">
|
||||
澜沧拉祜族自治县中医医院<span th:text="${baseInfo.lspcmName}"></span>报告单
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 10px;"></div>
|
||||
<div style="background-color: #000;height: 1px;"></div>
|
||||
<!-- 患者基本信息区域 - 使用表格布局以确保兼容 -->
|
||||
<table style="width: 100%;">
|
||||
<!-- 第1行:2个字段 -->
|
||||
<tr>
|
||||
<td style="width: 33%;font-weight: bold;">
|
||||
<span>姓名:</span>
|
||||
<span th:text="${baseInfo.patName}"></span>
|
||||
</td>
|
||||
<td style="width: 33%;">
|
||||
</td>
|
||||
<td style="width: 33%;font-weight: bold;">
|
||||
<span>标本编号:</span>
|
||||
<span th:text="${baseInfo.reportId}"></span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 第2行:3个字段 -->
|
||||
<tr>
|
||||
<td style="width: 33%;">
|
||||
<span>性别:</span>
|
||||
<span th:text="${baseInfo.patSex}"></span>
|
||||
</td>
|
||||
<td style="width: 33%;">
|
||||
<span>科室:</span>
|
||||
<span th:text="${baseInfo.deptName}"></span>
|
||||
</td>
|
||||
<td style="width: 33%;">
|
||||
<span>标本类型:</span>
|
||||
<span th:text="${baseInfo.lspcmName}"></span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 第3行:3个字段 -->
|
||||
<tr>
|
||||
<td style="width: 33%;">
|
||||
<span>年龄:</span>
|
||||
<span th:text="${baseInfo.patAge}"></span>
|
||||
</td>
|
||||
<td style="width: 33%;">
|
||||
<span>床号:</span>
|
||||
<span th:text="${baseInfo.inpBedNo}"></span>
|
||||
</td>
|
||||
<td style="width: 33%;">
|
||||
<span>标本形态:</span>
|
||||
<span></span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 第4行:3个字段 -->
|
||||
<tr>
|
||||
<td style="width: 33%;">
|
||||
<span>患者电话:</span>
|
||||
<span th:text="${baseInfo.patHomePhno}"></span>
|
||||
</td>
|
||||
<td style="width: 33%;">
|
||||
<span>申请医生:</span>
|
||||
<span th:text="${baseInfo.placerName}"></span>
|
||||
</td>
|
||||
<td style="width: 33%;">
|
||||
<span>采样者:</span>
|
||||
<span th:text="${baseInfo.spcmClctor}"></span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 第5行:3个字段 -->
|
||||
<tr>
|
||||
<td style="width: 33%;">
|
||||
<span>仪器:</span>
|
||||
<span></span>
|
||||
</td>
|
||||
<td style="width: 33%;">
|
||||
<span>临床诊断:</span>
|
||||
<span></span>
|
||||
</td>
|
||||
<td style="width: 33%;">
|
||||
<span>采样人:</span>
|
||||
<span th:text="${baseInfo.spcmClctor}"></span>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<!-- 第6行:1个字段 -->
|
||||
<tr>
|
||||
<td colspan="3" style="width: 100%;">
|
||||
<span>申请项目:</span>
|
||||
<span th:text="${baseInfo.citemContent}"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div style="height: 10px;"></div>
|
||||
<!-- 检测结果表格 -->
|
||||
<table style="border-collapse:collapse;width: 100%;border:1px solid gray;">
|
||||
<thead style="text-align: center;">
|
||||
<tr style="background-color: #f0f0f0;height:30px;">
|
||||
<th style="padding: 8px 5px; width: 25%;">项目名称</th>
|
||||
<th style="padding: 8px 5px; width: 20%;">结果</th>
|
||||
<th style="padding: 8px 5px; width: 15%;">单位</th>
|
||||
<th style="padding: 8px 5px; width: 20%;">参考区间</th>
|
||||
<th style="padding: 8px 5px; width: 20%;">测试方法</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody style="text-align: center;">
|
||||
<!-- 动态行渲染+异常值红色高亮 -->
|
||||
<tr th:each="item, stat : ${items}"
|
||||
th:style="${stat.index % 2 == 0} ? '' : 'background-color: #f0f0f0;'">
|
||||
<td style="padding: 8px 5px;" th:text="${item.loitemCname}"></td>
|
||||
<td style="padding: 8px 5px;">
|
||||
<span th:text="${item.orderRptResult}"></span>
|
||||
<span th:if="${item.oaflagLow}">↓</span>
|
||||
<span th:if="${item.oaflagHigh}">↑</span>
|
||||
</td>
|
||||
<td style="padding: 8px 5px;" th:text="${item.loitemUnit}"></td>
|
||||
<td style="padding: 8px 5px;" th:text="${item.loitemRv}"></td>
|
||||
<td style="padding: 8px 5px;" th:text="${item.inspectionMethod}"></td>
|
||||
</tr>
|
||||
<!-- 补齐空行 -->
|
||||
<!-- <tr th:each="i : ${#numbers.sequence(1, 10 - items.size())}" th:if="${items.size()} < 10">
|
||||
<td style="padding: 8px 5px;"> </td>
|
||||
<td style="padding: 8px 5px;"> </td>
|
||||
<td style="padding: 8px 5px;"> </td>
|
||||
<td style="padding: 8px 5px;"> </td>
|
||||
<td style="padding: 8px 5px;"> </td>
|
||||
</tr>-->
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- 建议与解释 -->
|
||||
<div>
|
||||
<div style="padding-top: 10px;">
|
||||
建议与解释:
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
src/main/resources/win32-x86/PayClient.dll
Normal file
BIN
src/main/resources/win32-x86/PayClient.dll
Normal file
Binary file not shown.
BIN
src/main/resources/win32-x86/libeay32.dll
Normal file
BIN
src/main/resources/win32-x86/libeay32.dll
Normal file
Binary file not shown.
BIN
src/main/resources/win32-x86/ssleay32.dll
Normal file
BIN
src/main/resources/win32-x86/ssleay32.dll
Normal file
Binary file not shown.
Reference in New Issue
Block a user