diff --git a/src/main/java/com/ynxbd/common/TestA.java b/src/main/java/com/ynxbd/common/TestA.java
index 9d223c6..0798101 100644
--- a/src/main/java/com/ynxbd/common/TestA.java
+++ b/src/main/java/com/ynxbd/common/TestA.java
@@ -1,42 +1,31 @@
package com.ynxbd.common;
-import com.ynxbd.wx.wxfactory.AesWxHelper;
+import cn.hutool.core.util.HexUtil;
+import com.ynxbd.common.helper.common.RSAHelper;
-public class TestA {
-
-// public static void main(String[] args) {
-// String respXML = "\n" +
-// "\t1002\n" +
-// "\t0\n" +
-// "\t成功\n" +
-// "\t932606\n" +
-// "\t300349719\n" +
-// "\t137087\n" +
-// "";
-// JsonResult result = JsonResult.xmlToBean(respXML, JsonResultEnum.SYS_HIS);
-// if (result == null) {
-// return;
-// }
-// Patient patient = result.dataMapToBean(Patient.class);
-// System.out.println(patient);
-// }
+import javax.crypto.Cipher;
+import java.io.ByteArrayOutputStream;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyFactory;
+import java.security.PublicKey;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+public class TestA {
+ private static final String PUB_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5klqI5STWTcbfjR093j+hvCEjNlZMQscIJg8jxZGqKW84AdFmSqPWEPu9ilqP+QUASiVSZ1QevGr2DWODFZ8Zw35aDA2bqCEprUx81gDdVPO7H7Bij+r8zAg8fT2c0Bi5rFq0xWMEQiTI+CyWwc5prOpquJU/P5yauEAdkRzlDwIDAQAB";
-// public static void main(String[] args) {
-// System.out.println(AesWxHelper.encode("524404"));
-//
-// String dataJson = "[{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":3,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":3,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":3,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"},{\"deptCode\":\"94085\",\"deptName\":\"便民门诊\",\"description\":\"医师\",\"surplusSources\":4,\"title\":\"医师\",\"titleCode\":\"医师\"}]\n";
+ public static void main(String[] args) throws Exception{
+ String content = "533103198212184014";
+ byte[] bytes = RSAHelper.enBytePKCS1Padding(content, PUB_KEY);
+ System.out.println("【Java最终hex】:" + HexUtil.encodeHexStr(bytes));
+ }
//
-// List doctors = JsonHelper.parseArray(dataJson, Doctor.class);
-// doctors = new DoctorService().doctorListFilter(doctors);
-// System.out.println(doctors);
-// }
-// public static void main(String[] args) {
-// // System.out.println(AesWxHelper.encode("624091"));
-//
-// // System.out.println(AesWxHelper.decode("A25BF2DD5820B151B8AB2E333E05565E"));
-// }
-}
+// public static void main(String[] args) throws Exception {
+// String content = "533103198212184014";
+// String encrypt = RSAHelper.enPKCS1Padding(content, PUB_KEY);
+// System.out.println(HexUtil.encodeHexStr(encrypt));
+// }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ynxbd/common/action/PatientAction.java b/src/main/java/com/ynxbd/common/action/PatientAction.java
index b6dddf7..caae95b 100644
--- a/src/main/java/com/ynxbd/common/action/PatientAction.java
+++ b/src/main/java/com/ynxbd/common/action/PatientAction.java
@@ -278,13 +278,13 @@ public class PatientAction extends BaseAction {
return Result.error("[医共体]不支持无证绑定!");
}
- fTel = getString("fTel");
- fName = getString("fName");
- fIDCardNo = getString("fIDCardNo");
+ fTel = getReqParamByKey("fTel");
+ fName = getReqParamByKey("fName");
+ fIDCardNo = getReqParamByKey("fIDCardNo");
- mTel = getString("mTel");
- mName = getString("mName");
- mIDCardNo = getString("mIDCardNo");
+ mTel = getReqParamByKey("mTel");
+ mName = getReqParamByKey("mName");
+ mIDCardNo = getReqParamByKey("mIDCardNo");
Result result = new PatientService().noCardParamsValid(fTel, fName, fIDCardNo, mTel, mName, mIDCardNo);
if (!result.isOK()) {
diff --git a/src/main/java/com/ynxbd/common/action/XBDAction.java b/src/main/java/com/ynxbd/common/action/XBDAction.java
index 3a42bb4..123d6d6 100644
--- a/src/main/java/com/ynxbd/common/action/XBDAction.java
+++ b/src/main/java/com/ynxbd/common/action/XBDAction.java
@@ -1,5 +1,7 @@
package com.ynxbd.common.action;
+import cn.hutool.core.util.HexUtil;
+import cn.hutool.crypto.asymmetric.RSA;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ynxbd.common.action.base.BaseAction;
@@ -10,8 +12,9 @@ import com.ynxbd.common.bean.xbd.MedicalRecord;
import com.ynxbd.common.config.interceptor.AesDecode;
import com.ynxbd.common.helper.common.Base64Helper;
import com.ynxbd.common.helper.common.JsonHelper;
+import com.ynxbd.common.helper.common.RSAHelper;
import com.ynxbd.common.helper.xbd.XBDEnum;
-import com.ynxbd.common.helper.xbd.XBDHelper;
+import com.ynxbd.common.helper.xbd.XbdConfigHelper;
import com.ynxbd.common.helper.xbd.XBDHttpHelper;
import com.ynxbd.common.result.Result;
import com.ynxbd.common.result.ResultEnum;
@@ -25,6 +28,7 @@ import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
import java.util.List;
/**
@@ -54,7 +58,7 @@ public class XBDAction extends BaseAction {
public Result cloudFilm(String info) {
try {
log.info("[云胶片]info={}", info);
- String path = XBDHelper.outTeamDao.getCloudFilmPath(info);
+ String path = XbdConfigHelper.outTeamDao.getCloudFilmPath(info);
return Result.success(path);
} catch (Exception e) {
log.error("[云胶片]{}", e.getMessage());
@@ -280,20 +284,16 @@ public class XBDAction extends BaseAction {
}
/**
- * 查询体检报告
+ * 查询体检影像报告
*/
@Action("getPeisByCardNo")
public Result getPeisByCardNo(@AesDecode String cardNo, String begDate, String endDate) {
- log.info("[查询体检记录] cardNo={}, begDate={}, endDate={}", cardNo, begDate, endDate);
+ log.info("[体检影像报告]查询 cardNo={}, begDate={}, endDate={}", cardNo, begDate, endDate);
if (ObjectUtils.isEmpty(cardNo) || ObjectUtils.isEmpty(begDate) || ObjectUtils.isEmpty(endDate)) {
return Result.error(ResultEnum.PARAM_IS_DEFECT);
}
- String encode = Base64Helper.encode(cardNo);
- if (ObjectUtils.isEmpty(encode)) {
- return Result.error(ResultEnum.PARAM_IS_INVALID);
- }
try {
- JSONArray dataList = new PEISService().queryPEISRecordByCardNo(encode, begDate, endDate);
+ JSONArray dataList = new PEISService().queryPEISRecordByCardNo(cardNo, begDate, endDate);
for (int i = 0; i < dataList.size(); i++) {
JSONObject dataItem = dataList.getJSONObject(i);
String eid = dataItem.getString("eid");
diff --git a/src/main/java/com/ynxbd/common/action/base/BaseAction.java b/src/main/java/com/ynxbd/common/action/base/BaseAction.java
index 67477e0..661d0b7 100644
--- a/src/main/java/com/ynxbd/common/action/base/BaseAction.java
+++ b/src/main/java/com/ynxbd/common/action/base/BaseAction.java
@@ -1,6 +1,8 @@
package com.ynxbd.common.action.base;
import com.alibaba.fastjson.JSONObject;
+import com.ynxbd.common.bean.form.FormBlob;
+import com.ynxbd.common.bean.form.FormData;
import com.ynxbd.common.helper.common.HttpHelper;
import com.ynxbd.common.helper.common.JsonHelper;
import com.ynxbd.wx.wxfactory.AesWxHelper;
@@ -9,6 +11,8 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.action.ServletRequestAware;
import org.apache.struts2.convention.annotation.ParentPackage;
+import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
+import org.apache.struts2.dispatcher.multipart.UploadedFile;
import org.slf4j.MDC;
import javax.servlet.ServletContext;
@@ -17,8 +21,9 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.math.BigDecimal;
-import java.util.HashMap;
-import java.util.Map;
+import java.nio.file.Files;
+import java.util.*;
+import java.util.function.Function;
/**
@@ -45,7 +50,7 @@ public class BaseAction implements Serializable, ServletRequestAware {
MDC.remove("ip");
MDC.put("ip", HttpHelper.getIpAddress(request));
} catch (UnsupportedEncodingException e) {
- e.printStackTrace();
+ log.error("", e);
}
this.request = request;
@@ -80,60 +85,61 @@ public class BaseAction implements Serializable, ServletRequestAware {
return ServletActionContext.getServletContext();
}
- protected String getString(String param) {
- String parameter = this.request.getParameter(param);
- if ("".equals(parameter)) {
- return null;
- }
- return parameter;
- }
protected String decodeReqString(String param) {
return AesWxHelper.decode(param);
}
- protected Integer getInteger(String param) {
- try {
- String val = this.request.getParameter(param);
- return StringUtils.isEmpty(val) ? null : Integer.valueOf(val);
- } catch (Exception e) {
- return null;
- }
- }
-
- protected Long getLong(String param) {
- try {
- String val = this.request.getParameter(param);
- return StringUtils.isEmpty(val) ? null : Long.valueOf(val);
- } catch (Exception e) {
- return null;
- }
- }
-
- protected Double getDouble(String param) {
- try {
- String val = this.request.getParameter(param);
- return StringUtils.isEmpty(val) ? null : Double.valueOf(val);
- } catch (Exception e) {
+ protected String getReqParamByKey(String key) {
+ String val = this.request.getParameter(key);
+ if ("".equals(val)) {
return null;
}
+ return val;
}
-
- protected BigDecimal getBigDecimal(String param) {
+ /**
+ * 通用转换方法
+ *
+ * @param key key
+ * @param clazz 目标类型 Integer.class / Long.class / BigDecimal.class ...
+ * @return 转换后对象,空/格式错误返回null
+ */
+ @SuppressWarnings("unchecked")
+ protected T getReqParamByKey(String key, Class clazz) {
try {
- String val = this.request.getParameter(param);
- return StringUtils.isEmpty(val) ? null : new BigDecimal(val);
- } catch (Exception e) {
- return null;
- }
- }
+ if (clazz == null) {
+ return null;
+ }
+ String val = this.request.getParameter(key);
+ if (StringUtils.isEmpty(val)) {
+ return null;
+ }
+ val = val.trim();
- protected Boolean getBoolean(String param) {
- try {
- String val = this.request.getParameter(param);
- return StringUtils.isEmpty(val) ? null : Boolean.valueOf(val);
+ Function converter;
+ if (String.class == clazz) {
+ return clazz.cast(val);
+ } else if (Integer.class == clazz) {
+ converter = Integer::valueOf;
+ } else if (Long.class == clazz) {
+ converter = Long::valueOf;
+ } else if (Double.class == clazz) {
+ converter = Double::valueOf;
+ } else if (BigDecimal.class == clazz) {
+ converter = BigDecimal::new;
+ } else if (Boolean.class == clazz) {
+ if (!val.equalsIgnoreCase("true") && !val.equalsIgnoreCase("false")) {
+ return null;
+ }
+ converter = Boolean::valueOf;
+ } else {
+ log.error("不支持的类型:{}", clazz.getName());
+ return null;
+ }
+ Object obj = converter.apply(val);
+ return (T) obj;
} catch (Exception e) {
return null;
}
@@ -218,4 +224,157 @@ public class BaseAction implements Serializable, ServletRequestAware {
Map params = reqParamsToMap();
return JsonHelper.parseObject(JsonHelper.toJsonString(params), clazz);
}
+
+
+ /**
+ * Struts2获取FormData[表单参数+上传文件]
+ */
+ protected FormData getReqFormData() {
+ MultiPartRequestWrapper multiWrapper = null;
+ if (request instanceof MultiPartRequestWrapper) {
+ multiWrapper = (MultiPartRequestWrapper) request;
+ }
+ if (multiWrapper == null) {
+ log.info("[请求类型]不是-multipart/form-data");
+ return null;
+ }
+
+ if (multiWrapper.hasErrors()) { // 检查上传解析是否报错
+ log.error("[multipart解析]存在错误:{}", multiWrapper.getErrors());
+ return null;
+ }
+
+ FormData formData = new FormData();
+ Map params = new HashMap<>();
+ Map files = new HashMap<>();
+
+ // ========= 读取普通表单文本参数 =========
+ Enumeration> parameterNames = multiWrapper.getParameterNames();
+ String field;
+ String[] values;
+ while (parameterNames.hasMoreElements()) {
+ field = (String) parameterNames.nextElement();
+ values = multiWrapper.getParameterValues(field);
+ if (values != null && values.length > 0) {
+ params.put(field, values[0]);
+ }
+ }
+
+
+ // ========= 读取所有上传文件 =========
+ Enumeration fileFieldEnum = multiWrapper.getFileParameterNames();
+ String fileName;
+ FormBlob formBlob;
+ UploadedFile[] uploadedFiles;
+ while (fileFieldEnum.hasMoreElements()) {
+ field = fileFieldEnum.nextElement();
+ uploadedFiles = multiWrapper.getFiles(field);
+ if (uploadedFiles == null) {
+ continue;
+ }
+
+ for (UploadedFile uf : uploadedFiles) {
+ if (!uf.isFile()) {
+ continue;
+ }
+ formBlob = new FormBlob();
+ fileName = uf.getOriginalName();
+ if (fileName != null) { // 清除IE浏览器全路径文件名
+ int idx = fileName.lastIndexOf("\\");
+ if (idx > 0) {
+ fileName = fileName.substring(idx + 1);
+ }
+ }
+ formBlob.setFileName(fileName);
+ formBlob.setContentType(uf.getContentType());
+
+ try {
+ byte[] data = null;
+ Object contentObj = uf.getContent();
+ if (contentObj instanceof byte[]) {
+ data = (byte[]) contentObj;
+ } else if (contentObj instanceof File) {
+ File tempFile = (File) contentObj;
+ data = Files.readAllBytes(tempFile.toPath());
+ }
+ if (data != null) {
+ formBlob.setContent(data);
+ files.put(field, formBlob);
+ }
+ } catch (Exception e) {
+ log.error("解析上传文件失败,field={}, fileName={}", field, fileName, e);
+ }
+ }
+ }
+
+ formData.setData(params);
+ formData.setFiles(files);
+ return formData;
+ }
+
+
+ // /**
+// * 获取FormData
+// */
+// protected FormData getFormData() {
+// try {
+// boolean isMultipart = ServletFileUpload.isMultipartContent(request);
+// if (!isMultipart) {
+// System.out.println("[请求类型]不是multipart/form-data");
+// return null;
+// }
+//
+// // 判断是否multipart请求(使用Struts工具方法)
+// MultiPartRequestWrapper multiWrapper = RequestUtils.getMultiPartRequestWrapper(request);
+// if (multiWrapper == null) {
+// System.out.println("[请求类型]不是multipart/form-data");
+// return null;
+// }
+//
+// FormData formData = new FormData();
+// Map params = new HashMap<>();
+// ArrayList files = new ArrayList<>();
+//
+// String a = null;
+// // 1. 获取所有普通表单字段
+// Enumeration paramNames = multiWrapper.getParameterNames();
+//
+// String a = request.getParameter("a");
+// System.out.println(a);
+//
+// // 初始化解析器
+// FileItemFactory factory = new DiskFileItemFactory();
+// ServletFileUpload upload = new ServletFileUpload(factory);
+// // 限制最大文件 10MB,根据截图业务调整
+// upload.setFileSizeMax(10 * 1024 * 1024L);
+//
+// List itemList = upload.parseRequest(request);
+// FormData formData = new FormData();
+//
+// Map params = new HashMap<>();
+// ArrayList files = new ArrayList<>();
+// // 遍历所有上传项
+// FormBlob formBlob;
+// for (FileItem item : itemList) {
+// System.out.println(item.getFieldName());
+// if (item.isFormField()) { // 普通文本参数
+// params.put(item.getFieldName(), item.getString("UTF-8"));
+// } else {
+// formBlob = new FormBlob(); // 文件
+// formBlob.setFileName(item.getName());
+// formBlob.setContent(item.get());
+// formBlob.setContentType(item.getContentType());
+// files.add(formBlob);
+// }
+// }
+// formData.setFiles(files);
+// formData.setData(params);
+//
+// return formData;
+// } catch (Exception e) {
+// log.error(e.getMessage());
+// return null;
+// }
+// }
+//
}
diff --git a/src/main/java/com/ynxbd/common/action/healthcard/HCReportAction.java b/src/main/java/com/ynxbd/common/action/healthcard/HCReportAction.java
index b34460f..7cc4a32 100644
--- a/src/main/java/com/ynxbd/common/action/healthcard/HCReportAction.java
+++ b/src/main/java/com/ynxbd/common/action/healthcard/HCReportAction.java
@@ -2,11 +2,15 @@ package com.ynxbd.common.action.healthcard;
import com.alibaba.fastjson.JSONObject;
import com.ynxbd.common.action.base.BaseAction;
+import com.ynxbd.common.bean.form.FormBlob;
+import com.ynxbd.common.bean.form.FormData;
import com.ynxbd.common.config.healthcard.HCReportConfig;
import com.ynxbd.common.config.healthcard.HCSignHelper;
-import com.ynxbd.common.config.interceptor.AesDecode;
+import com.ynxbd.common.helper.common.Base64Helper;
import com.ynxbd.common.helper.http.OkHttpHelper;
import com.ynxbd.common.result.Result;
+import com.ynxbd.common.result.ResultEnum;
+import com.ynxbd.wx.wxfactory.AesWxHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
@@ -18,42 +22,65 @@ import java.util.Map;
@Namespace("/hc_report")
public class HCReportAction extends BaseAction {
-
+ // 报告解读:https://open.ai.tengmed.com/openAccess/docs/access#6
@Action("pushUserReport")
- public Result pushUserReport(@AesDecode String patientId, String reportId, String healthCardId, String msgId, String reportContent) {
+ public Result pushUserReport() {
+ FormData formData = getReqFormData();
+ if (formData == null) {
+ return Result.error(ResultEnum.PARAM_IS_BLANK);
+ }
+ FormBlob reportFile = formData.getFiles().get("reportContent");
+ if (reportFile == null || reportFile.getContent() == null) {
+ return Result.error(ResultEnum.PARAM_IS_BLANK);
+ }
+ String reportContentBase64 = Base64Helper.encode(reportFile.getContent());
+ if (reportContentBase64 == null) {
+ return Result.error(ResultEnum.PARAM_IS_INVALID);
+ }
+
+ String patientId = AesWxHelper.decode(formData.getParamByKey("patientId", String.class));
+ String healthCardId = formData.getParamByKey("healthCardId", String.class);
+ String reportId = formData.getParamByKey("reportId", String.class);
+ String msgId = formData.getParamByKey("msgId", String.class);
+
log.info("[报告解读] msgId={}, patientId={}, reportId={}", msgId, patientId, reportId);
+ if (patientId == null || healthCardId == null || reportId == null || msgId == null) {
+ return Result.error(ResultEnum.PARAM_IS_DEFECT);
+ }
String url = HCReportConfig.IS_DEV
? "https://med-biz-pre.wecity.qq.com/api/report/PushUserReport/"
: "https://med-biz.wecity.qq.com/api/report/PushUserReport/";
+
HCSignHelper config = HCReportConfig.createSign();
String requestId = config.getRequestId();
Map reqHead = new HashMap<>();
reqHead.put("requestId", requestId);
- Map textReportInfo = new HashMap<>();
+// Map textReportInfo = new HashMap<>();
// Map patientInfo = new HashMap<>();
// Map reportInfo = new HashMap<>();
// partnerId:合作方ID 腾讯健康提供
- JSONObject jsonObject = OkHttpHelper.postJson(url + HCReportConfig.PARTNER_ID, params -> {
- params.put("reqHead", reqHead);
- params.put("hospitalId", HCReportConfig.HOSP_ID);
- params.put("outerId", reportId);
- params.put("healthCardId", healthCardId);
- params.put("patientId", patientId);
- params.put("msgId", msgId);
- params.put("reportFileType", 2); // [ 1:pdf;2:图片;3:文本]
- params.put("reportContent", reportContent); // 报告内容:报告文件base64编码、体积需要在30MB以内 当reportFileType 取值为 1, 2时,将报告文件base64编码放在该字段
- params.put("textReportInfo", textReportInfo); // 当reportFileType 取值为 3 时,将文本报告内容放下该字段。
+ JSONObject jsonObject = OkHttpHelper.postJson(url + HCReportConfig.PARTNER_ID, req -> {
+ req.put("reqHead", reqHead);
+ req.put("hospitalId", HCReportConfig.HOSP_ID);
+ req.put("outerId", reportId);
+ req.put("healthCardId", healthCardId);
+ req.put("patientId", patientId);
+ req.put("msgId", msgId);
+ req.put("reportFileType", 2); // [ 1:pdf;2:图片;3:文本]
+ req.put("reportContent", reportContentBase64); // 报告内容:报告文件base64编码、体积需要在30MB以内 当reportFileType 取值为 1, 2时,将报告文件base64编码放在该字段
+// req.put("textReportInfo", textReportInfo); // 当reportFileType 取值为 3 时,将文本报告内容放下该字段。
+// log.warn("[报告解读] req={}", JsonHelper.toJsonString(req));
}, headers -> {
headers.add("Content-Type", "application/json");
headers.add("god-portal-signature", config.getSignature());
headers.add("god-portal-timestamp", config.getTimestamp());
headers.add("god-portal-request-id", requestId);
});
- log.warn("[报告解读] resp={}", jsonObject);
+ log.info("[报告解读] msgId={}, patientId={}, reportId={}, resp={}", msgId, patientId, reportId, jsonObject);
return Result.success();
}
}
diff --git a/src/main/java/com/ynxbd/common/action/pay/JYPayAction.java b/src/main/java/com/ynxbd/common/action/pay/JYPayAction.java
new file mode 100644
index 0000000..e72e188
--- /dev/null
+++ b/src/main/java/com/ynxbd/common/action/pay/JYPayAction.java
@@ -0,0 +1,71 @@
+package com.ynxbd.common.action.pay;
+
+import com.ynxbd.bcm.config.BCMHelper;
+import com.ynxbd.common.action.base.BaseAction;
+import com.ynxbd.common.bean.pay.PayResult;
+import com.ynxbd.common.helper.common.DateHelper;
+import com.ynxbd.common.result.Result;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.struts2.convention.annotation.Action;
+import org.apache.struts2.convention.annotation.Namespace;
+
+import java.math.BigDecimal;
+
+@Slf4j
+@Namespace("/jy_pay")
+public class JYPayAction extends BaseAction {
+
+ /**
+ * 【交行】处方支付通知
+ *
+ * @return 是否成功
+ */
+ @Action("notify")
+ public Result notify(String notifyType) {
+// if (ObjectUtils.isEmpty(notifyType)) {
+// Result.respJson(BCMHelper.respError(String.format("【京颐】获取回调参数失败,结束请求 notifyType={%s}", notifyType)));
+// return null;
+// }
+
+ try {
+ PayResult notifyInfo = BCMHelper.payNotify(request);
+ Result.respJson(BCMHelper.respOk()); // 成功
+
+ String openid = notifyInfo.getOpenid();
+ String bankTransNo = notifyInfo.getTransId();
+ String outTradeNo = notifyInfo.getOutTradeNo();
+ BigDecimal totalFee = notifyInfo.getTotalFee();
+
+ String payInfo = notifyInfo.getInfo();
+ String payDate = DateHelper.getCurDate();
+ String payTime = DateHelper.getCurTime();
+ String bankMerchantNo = notifyInfo.getBankMerchantNo();
+ log.info("【京颐】[{}] 收到通知 outTradeNo={}, bankTransNo={}, bankMerchantNo={}", notifyType, outTradeNo, bankTransNo, bankMerchantNo);
+
+ switch (PEnum.toEnum(notifyType)) {
+ case RECIPE:
+// openid = new RecipeService().queryOpenIdByOutTradeNo(outTradeNo);
+// new RecipeService().recipeListPay(MerchantEnum.JY, totalFee.toString(), openid, outTradeNo, bankTransNo, bankMerchantNo, payDate, payTime, payInfo);
+//
+ break;
+
+ case REG: // 挂号
+// try {
+// openid = new RegService().queryOpenIdByOutTradeNo(outTradeNo);
+// new RegService().regPaidNotify(MerchantEnum.JY, totalFee, openid, bankTransNo, outTradeNo, bankMerchantNo, payDate, payTime, payInfo, new Date());
+// } catch (ServiceException e) {
+// log.info("【京颐]挂号通知错误 outTradeNo={}, bankTransNo={}, message={}", outTradeNo, bankTransNo, e.getMessage());
+// }
+ break;
+
+ default:
+ log.info("【京颐】通知类型错误,结束请求");
+ break;
+ }
+
+ } catch (Exception e) {
+ log.error(e.getMessage());
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/com/ynxbd/common/action/pay/MedicalAction.java b/src/main/java/com/ynxbd/common/action/pay/MedicalAction.java
index 129949b..0a7fa13 100644
--- a/src/main/java/com/ynxbd/common/action/pay/MedicalAction.java
+++ b/src/main/java/com/ynxbd/common/action/pay/MedicalAction.java
@@ -63,7 +63,7 @@ public class MedicalAction extends BaseAction {
MedicalInfo medicalInfo;
switch (PEnum.toEnum(callNo)) {
case REG:
- Boolean isSplitTime = getBoolean("isSplitTime");
+ Boolean isSplitTime = getReqParamByKey("isSplitTime", Boolean.class);
Register reg = new Register().getRegParams(new RequestParams(request), true);
if ("*".equals(reg.getRegCode())) {
@@ -77,10 +77,10 @@ public class MedicalAction extends BaseAction {
break;
case RECIPE:
- String ybAttrib = getString("ybAttrib");
- String ybBZCode = getString("ybBZCode");
- String ybBZName = getString("ybBZName");
- String recipeJson = getString("recipeJson"); // 处方JSON集 [{ recipeId: item.id, recipeFee: item.amount }]
+ String ybAttrib = getReqParamByKey("ybAttrib");
+ String ybBZCode = getReqParamByKey("ybBZCode");
+ String ybBZName = getReqParamByKey("ybBZName");
+ String recipeJson = getReqParamByKey("recipeJson"); // 处方JSON集 [{ recipeId: item.id, recipeFee: item.amount }]
log.info("[医保-处方]上传明细下单 treatNum={}, ybAttrib={}, ybBZCode={}, ybBZName={}, recipeJson={}", treatNum, ybAttrib, ybBZCode, ybBZName, recipeJson);
if (treatNum == null || recipeJson == null) {
return Result.error(ResultEnum.PARAM_IS_DEFECT);
@@ -207,11 +207,11 @@ public class MedicalAction extends BaseAction {
familyType, familyName, familyCardNo, medicalCardInstId, medicalCardId);
case RECIPE:
- String recipeJson = getString("recipeJson");
+ String recipeJson = getReqParamByKey("recipeJson");
if (recipeJson == null) {
return Result.error(ResultEnum.PARAM_IS_BLANK);
}
- String payWay = getString("payWay");
+ String payWay = getReqParamByKey("payWay");
return new MedicalService().createRxOrder(payCode, payOpenId, openid, patientId, cardNo, realName, ip,
payOrdId, payAuthNo, mdTrtId, chrgBchno, mdUserId,
totalFee, acctFee, hifpFee, insuranceFee, cashFee,
diff --git a/src/main/java/com/ynxbd/common/action/pay/PayAction.java b/src/main/java/com/ynxbd/common/action/pay/PayAction.java
index bdae783..ae96ade 100644
--- a/src/main/java/com/ynxbd/common/action/pay/PayAction.java
+++ b/src/main/java/com/ynxbd/common/action/pay/PayAction.java
@@ -13,7 +13,7 @@ import com.ynxbd.common.dao.his.HisRecipeDao;
import com.ynxbd.common.dao.sys.SysUserDao;
import com.ynxbd.common.helper.common.*;
import com.ynxbd.common.helper.his.HisHelper;
-import com.ynxbd.common.helper.xbd.XBDHelper;
+import com.ynxbd.common.helper.xbd.XbdConfigHelper;
import com.ynxbd.common.result.JsonResult;
import com.ynxbd.common.result.Result;
import com.ynxbd.common.result.ResultEnum;
@@ -887,7 +887,7 @@ public class PayAction extends BaseAction {
return Result.error(ResultEnum.PAY_TYPE_ERROR);
}
- if (ObjectUtils.isEmpty(XBDHelper.PEIS_URL)) {
+ if (ObjectUtils.isEmpty(XbdConfigHelper.PEIS_URL)) {
return Result.error(ResultEnum.SYSTEM_CONFIG_ERROR);
}
diff --git a/src/main/java/com/ynxbd/common/action/test/TestAction.java b/src/main/java/com/ynxbd/common/action/test/TestAction.java
index 85afca8..00f380a 100644
--- a/src/main/java/com/ynxbd/common/action/test/TestAction.java
+++ b/src/main/java/com/ynxbd/common/action/test/TestAction.java
@@ -1,27 +1,26 @@
package com.ynxbd.common.action.test;
import com.ynxbd.common.action.base.BaseAction;
-import com.ynxbd.common.bean.pay.Register;
+import com.ynxbd.common.bean.form.FormBlob;
+import com.ynxbd.common.bean.form.FormData;
import com.ynxbd.common.bean.sms.SmsTempEnum;
+import com.ynxbd.common.helper.common.Base64Helper;
import com.ynxbd.common.helper.common.DateHelper;
import com.ynxbd.common.helper.common.SmsHelper;
import com.ynxbd.common.result.Result;
import com.ynxbd.common.result.ResultEnum;
import com.ynxbd.common.result.ServiceException;
import com.ynxbd.wx.config.MessagePushConfig;
-import com.ynxbd.wx.config.TZReserveConfig;
import com.ynxbd.wx.config.WeChatConfig;
-import com.ynxbd.wx.wxfactory.WxMedHelper;
import com.ynxbd.wx.wxfactory.WxPayHelper;
import com.ynxbd.wx.wxfactory.medical.WxMedConfig;
-import com.ynxbd.wx.wxfactory.medical.models.WxMedOrder;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.ObjectUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import java.math.BigDecimal;
import java.util.Date;
+import java.util.Map;
/**
* @Author wsq
@@ -51,7 +50,7 @@ public class TestAction extends BaseAction {
// 医保退费
@Action("refund_med_test")
public Result refund_med_test() throws ServiceException {
-// WxMedOrder order = WxMedHelper.refundCash("WX_M02f373d25b94475b60aa9860977c", ("R" + "ORD530100202605181442001740995"), "ORD530100202605181442001740995", new BigDecimal("24.71"), "已有缴费记录,不能再次缴费");
+ // WxMedOrder order = WxMedHelper.refundCash("WX_M02f373d25b94475b60aa9860977c", ("R" + "ORD530100202605181442001740995"), "ORD530100202605181442001740995", new BigDecimal("24.71"), "已有缴费记录,不能再次缴费");
return Result.success();
}
@@ -126,25 +125,23 @@ public class TestAction extends BaseAction {
@Action("r_test")
public Result r_test() throws ServiceException {
- String url = WeChatConfig.getHttpsBaseURL() + "ali_qrcode" + "?p=123";
- System.out.println(url);
- System.out.println();
- return Result.redirect("/wx/test02/log_test");
+ return Result.success();
}
@Action("wx_push_test")
public Result wx_push_test() {
System.out.println("HOST_URL:" + MessagePushConfig.HOST_URL);
- System.out.println("[挂号]缴费通知:" + MessagePushConfig.REG_PAID_URL);
- System.out.println("[挂号]取消预约:" + MessagePushConfig.REG_CANCEL_URL);
- System.out.println("[挂号]AI:" + MessagePushConfig.REG_AI_URL);
+ System.out.println("[挂号]缴费通知:" + MessagePushConfig.REG_PAID_API);
+ System.out.println("[挂号]取消预约:" + MessagePushConfig.REG_CANCEL_API);
+ System.out.println("[挂号]AI:" + MessagePushConfig.REG_AI_API);
- System.out.println("[处方]缴费通知:" + MessagePushConfig.RX_PAID_URL);
+ System.out.println("[处方]缴费通知:" + MessagePushConfig.RX_PAID_API);
- System.out.println("产科建档:" + MessagePushConfig.OBS_DOCUMENT_URL);
+ System.out.println("产科建档:" + MessagePushConfig.OBS_DOCUMENT_API);
return Result.success();
}
+
// @Action("lock")
// public String lock() {
// return Result.success(update());
diff --git a/src/main/java/com/ynxbd/common/bean/enums/MerchantEnum.java b/src/main/java/com/ynxbd/common/bean/enums/MerchantEnum.java
index 971229f..2a4b54b 100644
--- a/src/main/java/com/ynxbd/common/bean/enums/MerchantEnum.java
+++ b/src/main/java/com/ynxbd/common/bean/enums/MerchantEnum.java
@@ -58,6 +58,14 @@ public enum MerchantEnum {
"",
WX.PAY_WAY_IN, WX.PAY_WAY_QR, WX.PAY_WAY_MICRO),
+ ALI_MEDICAL("ali_medical", "【支付宝医保】", AliConfig.APP_ID, ALI.OUT_TRADE_NO_PREFIX,
+ AliMedConfig.IS_DEV,
+ "3",
+ "25,26,27,28,29,30",
+ "ali_pay/medical_notify",
+ "",
+ "10", "11", "12"),
+
BCM("bcm", "【交行】", "", "BCM",
false,
"4",
@@ -66,14 +74,13 @@ public enum MerchantEnum {
"",
"20", "21", "22"),
-
- ALI_MEDICAL("ali_medical", "【支付宝医保】", AliConfig.APP_ID, ALI.OUT_TRADE_NO_PREFIX,
- AliMedConfig.IS_DEV,
- "3",
- "25,26,27,28,29,30",
- "ali_pay/medical_notify",
+ JY("jy", "【京颐】", "", "JY",
+ false,
+ "4",
"",
- "10", "11", "12"),
+ "jy_pay/notify",
+ "",
+ WX.PAY_WAY_IN, WX.PAY_WAY_QR, WX.PAY_WAY_MICRO),
;
diff --git a/src/main/java/com/ynxbd/common/bean/form/FormBlob.java b/src/main/java/com/ynxbd/common/bean/form/FormBlob.java
new file mode 100644
index 0000000..505b403
--- /dev/null
+++ b/src/main/java/com/ynxbd/common/bean/form/FormBlob.java
@@ -0,0 +1,19 @@
+package com.ynxbd.common.bean.form;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@Setter
+@ToString
+@NoArgsConstructor
+public class FormBlob {
+ // 内容
+ private byte[] content;
+ // 文件名
+ private String fileName;
+ // 内容类型
+ private String contentType;
+}
diff --git a/src/main/java/com/ynxbd/common/bean/form/FormData.java b/src/main/java/com/ynxbd/common/bean/form/FormData.java
new file mode 100644
index 0000000..d47bf37
--- /dev/null
+++ b/src/main/java/com/ynxbd/common/bean/form/FormData.java
@@ -0,0 +1,73 @@
+package com.ynxbd.common.bean.form;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+@Getter
+@Setter
+@ToString
+@NoArgsConstructor
+@Slf4j
+public class FormData {
+
+ private Map files;
+
+ private Map data;
+
+
+ /**
+ * 通用转换方法
+ *
+ * @param param key
+ * @param clazz 目标类型 Integer.class / Long.class / BigDecimal.class ...
+ * @return 转换后对象,空/格式错误返回null
+ */
+ @SuppressWarnings("unchecked")
+ public T getParamByKey(String param, Class clazz) {
+ try {
+ if (clazz == null) {
+ return null;
+ }
+ String val = data.get(param);
+ if (StringUtils.isEmpty(val)) {
+ return null;
+ }
+ val = val.trim();
+
+ Function converter;
+ if (String.class == clazz) {
+ return clazz.cast(val);
+ } else if (Integer.class == clazz) {
+ converter = Integer::valueOf;
+ } else if (Long.class == clazz) {
+ converter = Long::valueOf;
+ } else if (Double.class == clazz) {
+ converter = Double::valueOf;
+ } else if (BigDecimal.class == clazz) {
+ converter = BigDecimal::new;
+ } else if (Boolean.class == clazz) {
+ if (!val.equalsIgnoreCase("true") && !val.equalsIgnoreCase("false")) {
+ return null;
+ }
+ converter = Boolean::valueOf;
+ } else {
+ log.error("不支持的类型:{}", clazz.getName());
+ return null;
+ }
+ Object obj = converter.apply(val);
+ return (T) obj;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/com/ynxbd/common/bean/pay/ReqOrder.java b/src/main/java/com/ynxbd/common/bean/pay/ReqOrder.java
new file mode 100644
index 0000000..b498e77
--- /dev/null
+++ b/src/main/java/com/ynxbd/common/bean/pay/ReqOrder.java
@@ -0,0 +1,63 @@
+package com.ynxbd.common.bean.pay;
+
+
+import com.ynxbd.jy.bean.JYOrder;
+import com.ynxbd.jy.bean.enums.JYBusinessTypeEnum;
+import com.ynxbd.jy.bean.enums.JYOrderTypeEnum;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+// 医保请求参数
+
+@Setter
+@Getter
+@ToString
+@NoArgsConstructor
+public class ReqOrder implements Serializable {
+ private static final long serialVersionUID = 2026072810440001L;
+ // 现金部分
+ public BigDecimal cashFee;
+ // 医保金额-个账 + 统筹支付金额
+ public BigDecimal insuranceFee;
+ // 医保-个人账户支付金额
+ public BigDecimal acctFee;
+ // 医保-统筹支付金额
+ public BigDecimal hifpFee;
+
+ // 订单金额
+ public BigDecimal totalFee;
+ // ip
+ public String ip;
+ // 回退地址
+ public String returnUrl;
+
+ // 医院HIS系统订单号
+ public String serialNo;
+ // 参考医保结构体(医疗机构透传医保)
+ public String requestContent;
+ // 亲情移动支付时
+ public String extendInfo;
+ // 门诊号 | 住院号
+ public String treatNum;
+ // 患者id
+ public String patientId;
+ // 患者姓名
+ public String patientName;
+ //
+ public String patientAge;
+ // 患者性别。综合支付对应用权限控制是否必传 1男 2女 9其他 最大不超过4位
+ public String patientGender;
+
+ public String patientIdCardNo;
+
+ public String patientTel;
+
+ public JYOrder jyOrder;
+
+
+}
diff --git a/src/main/java/com/ynxbd/common/config/interceptor/MethodInterceptor.java b/src/main/java/com/ynxbd/common/config/interceptor/MethodInterceptor.java
index 575157b..a0382e2 100644
--- a/src/main/java/com/ynxbd/common/config/interceptor/MethodInterceptor.java
+++ b/src/main/java/com/ynxbd/common/config/interceptor/MethodInterceptor.java
@@ -4,6 +4,7 @@ import com.ynxbd.common.helper.common.AesHelper;
import com.ynxbd.common.helper.common.ErrorHelper;
import com.ynxbd.common.helper.common.JsonHelper;
import com.ynxbd.common.result.Result;
+import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.struts2.ActionContext;
import org.apache.struts2.ActionInvocation;
@@ -21,6 +22,7 @@ import java.util.List;
/**
* 方法拦截器
*/
+@Slf4j
public class MethodInterceptor extends org.apache.struts2.interceptor.AbstractInterceptor {
@@ -133,7 +135,7 @@ public class MethodInterceptor extends org.apache.struts2.interceptor.AbstractIn
}
return "SUCCESS";
} catch (Exception e) {
- e.printStackTrace();
+ log.error("", e);
if (e.getMessage() == null) {
System.out.println("异常1");
Throwable cause = e.getCause();
diff --git a/src/main/java/com/ynxbd/common/helper/common/RSAHelper.java b/src/main/java/com/ynxbd/common/helper/common/RSAHelper.java
index ab0b493..48af689 100644
--- a/src/main/java/com/ynxbd/common/helper/common/RSAHelper.java
+++ b/src/main/java/com/ynxbd/common/helper/common/RSAHelper.java
@@ -106,7 +106,6 @@ public class RSAHelper {
}
-
/**
* RSA私钥解密
*
@@ -154,6 +153,50 @@ public class RSAHelper {
return null;
}
+ public static PublicKey getPublicKey(String base64PubKey) {
+ try {
+ byte[] keyBytes = java.util.Base64.getDecoder().decode(base64PubKey);
+ X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ return keyFactory.generatePublic(spec);
+ } catch (Exception e) {
+ log.error("", e);
+ return null;
+ }
+ }
+
+ /**
+ * PKCS8 格式私钥字符串转 PrivateKey
+ *
+ * @param privateKeyStr 带/不带头尾标记的base64私钥
+ * @return PrivateKey
+ */
+ public static PrivateKey getPrivateKey(String privateKeyStr) {
+ try {
+ // 去除头尾标记、换行、空格
+ String privateKeyPEM = privateKeyStr
+ .replace("-----BEGIN PRIVATE KEY-----", "")
+ .replace("-----END PRIVATE KEY-----", "")
+ .replaceAll("\\s+", "");
+ byte[] keyBytes = java.util.Base64.getDecoder().decode(privateKeyPEM);
+ PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ return keyFactory.generatePrivate(spec);
+ } catch (Exception e) {
+ log.error("", e);
+ return null;
+ }
+ }
+
+ // 加密方法(PKCS#1 v1.5填充)
+ public static byte[] enBytePKCS1Padding(String content, String base64PublicKey) throws Exception {
+ PublicKey publicKey = getPublicKey(base64PublicKey);
+ Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+ byte[] rawData = content.getBytes(StandardCharsets.UTF_8);
+ return cipher.doFinal(rawData);
+ }
+
// 加密方法(PKCS#1 v1.5填充)
public static String enPKCS1Padding(String plaintext, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
diff --git a/src/main/java/com/ynxbd/common/helper/common/SmsHelper.java b/src/main/java/com/ynxbd/common/helper/common/SmsHelper.java
index 7107251..da33ea4 100644
--- a/src/main/java/com/ynxbd/common/helper/common/SmsHelper.java
+++ b/src/main/java/com/ynxbd/common/helper/common/SmsHelper.java
@@ -178,7 +178,11 @@ public class SmsHelper {
* @param smsTemplate 模板参数
*/
public static boolean sendAli(String template, String tel, String signName, SmsTemplate smsTemplate) {
- if (StringUtils.isEmpty(signName)) {
+ if (ObjectUtils.isEmpty(tel)) {
+ System.out.println("[短信]tel参数为空!");
+ return false;
+ }
+ if (ObjectUtils.isEmpty(signName)) {
signName = SIGN_NAME;
}
diff --git a/src/main/java/com/ynxbd/common/helper/xbd/XBDHttpHelper.java b/src/main/java/com/ynxbd/common/helper/xbd/XBDHttpHelper.java
index 3b9b003..59c3c97 100644
--- a/src/main/java/com/ynxbd/common/helper/xbd/XBDHttpHelper.java
+++ b/src/main/java/com/ynxbd/common/helper/xbd/XBDHttpHelper.java
@@ -78,7 +78,7 @@ public class XBDHttpHelper {
private static String UsePost(String methodName, RequestBody requestBody) {
OkHttpClient httpClient = OkHttpHelper.creatClient();
Headers.Builder headersBuilder = new Headers.Builder();
- HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(XBDHelper.CASEBOOK_URL + "/api/SqlContext/PostMethodByNameEncryption")).newBuilder();
+ HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(XbdConfigHelper.CASEBOOK_URL + "/api/SqlContext/PostMethodByNameEncryption")).newBuilder();
try (Response response = httpClient.newCall(new Request.Builder().url(urlBuilder.build()).post(requestBody).headers(headersBuilder.build()).build()).execute()) {
JSONObject respJson = respFilter(response, methodName);
String code = respJson.getString("Code");
@@ -171,7 +171,7 @@ public class XBDHttpHelper {
private static String UseGet(String methodName, Object paramDic) {
try {
OkHttpClient httpClient = OkHttpHelper.creatClient();
- HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(XBDHelper.CASEBOOK_URL + "/api/SqlContext/ExecMethodByNameEncryption")).newBuilder();
+ HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(XbdConfigHelper.CASEBOOK_URL + "/api/SqlContext/ExecMethodByNameEncryption")).newBuilder();
// 加密序列化
String paramJson = JSONObject.toJSONString(paramDic == null ? "" : paramDic);
log.info("[病历GET]未加密前get请求入参:[methodName:{}] {}", methodName, paramJson);
diff --git a/src/main/java/com/ynxbd/common/helper/xbd/XBDHelper.java b/src/main/java/com/ynxbd/common/helper/xbd/XbdConfigHelper.java
similarity index 64%
rename from src/main/java/com/ynxbd/common/helper/xbd/XBDHelper.java
rename to src/main/java/com/ynxbd/common/helper/xbd/XbdConfigHelper.java
index d4c970d..a96d7c9 100644
--- a/src/main/java/com/ynxbd/common/helper/xbd/XBDHelper.java
+++ b/src/main/java/com/ynxbd/common/helper/xbd/XbdConfigHelper.java
@@ -11,7 +11,7 @@ import lombok.extern.slf4j.Slf4j;
* @date 2023/3/30 17:02
*/
@Slf4j
-public class XBDHelper {
+public class XbdConfigHelper {
private static final String PACS_CLOUD_URL;
public static final String CASEBOOK_URL;
public static final String PEIS_URL;
@@ -19,19 +19,16 @@ public class XBDHelper {
public static OutTeamDao outTeamDao;
static {
- XmlConfigHelper config = new XmlConfigHelper().read("xbd-config.xml", "tz_sms");
+ XmlConfigHelper config = new XmlConfigHelper().read("xbd-config.xml", "xbd");
- PACS_CLOUD_URL = config.getString("pacs_cloud_url");
+ PACS_CLOUD_URL = config.getString("pacs_cloud_url", "");
- CASEBOOK_URL = config.getString("casebook_url");
+ CASEBOOK_URL = config.getString("casebook_url", "");
+
+ PEIS_URL = config.getString("peis_url", "");
- PEIS_URL = config.getString("peis_url");
- if (PACS_CLOUD_URL == null) {
- log.error("新八达200团队配置文件读取失败");
- }
outTeamDao = new OutTeamDao(PACS_CLOUD_URL);
}
-
}
diff --git a/src/main/java/com/ynxbd/common/service/PEISService.java b/src/main/java/com/ynxbd/common/service/PEISService.java
index fa65ea9..0da8d6f 100644
--- a/src/main/java/com/ynxbd/common/service/PEISService.java
+++ b/src/main/java/com/ynxbd/common/service/PEISService.java
@@ -1,5 +1,6 @@
package com.ynxbd.common.service;
+import cn.hutool.core.util.HexUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ynxbd.common.action.pay.PEnum;
@@ -9,8 +10,9 @@ import com.ynxbd.common.bean.pay.PEISOrderInfo;
import com.ynxbd.common.bean.pay.PEISReserve;
import com.ynxbd.common.dao.peis.PEISDao;
import com.ynxbd.common.helper.common.JsonHelper;
+import com.ynxbd.common.helper.common.RSAHelper;
import com.ynxbd.common.helper.http.OkHttpHelper;
-import com.ynxbd.common.helper.xbd.XBDHelper;
+import com.ynxbd.common.helper.xbd.XbdConfigHelper;
import com.ynxbd.common.result.*;
import lombok.extern.slf4j.Slf4j;
import okhttp3.FormBody;
@@ -18,6 +20,7 @@ import okhttp3.RequestBody;
import org.apache.commons.lang3.ObjectUtils;
import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
import java.util.Date;
/**
@@ -102,7 +105,7 @@ public class PEISService {
return;
}
- JsonResult jsonResult = postForm(XBDHelper.PEIS_URL + "/wxUse/wxPay", params -> {
+ JsonResult jsonResult = postForm(XbdConfigHelper.PEIS_URL + "/wxUse/wxPay", params -> {
params.put("orderNo", noticeOrderNo);
params.put("payStatus", "OK");
params.put("payFailReason", "");
@@ -138,7 +141,7 @@ public class PEISService {
* @return bean
*/
public PEISOrderInfo queryPEISOrderByNoticeOrderNo(String noticeOrderNo) throws ServiceException {
- JsonResult jsonResult = get(XBDHelper.PEIS_URL + "/wxUse/GetOrder", params -> {
+ JsonResult jsonResult = get(XbdConfigHelper.PEIS_URL + "/wxUse/GetOrder", params -> {
params.put("orderNo", noticeOrderNo);
});
log.info("[体检预约]订单查询 {}", JsonHelper.toJsonString(jsonResult));
@@ -224,7 +227,7 @@ public class PEISService {
* @return bool
*/
public boolean cancelPEISReserve(String noticeOrderNo, String refundStatus, String refundFailReason) throws ServiceException {
- JsonResult jsonResult = postForm(XBDHelper.PEIS_URL + "/wxUse/wxRefund", params -> {
+ JsonResult jsonResult = postForm(XbdConfigHelper.PEIS_URL + "/wxUse/wxRefund", params -> {
params.put("orderNo", noticeOrderNo);
params.put("refundStatus", refundStatus); // 退费状态(成功:OK,失败:FAIL)
params.put("refundFailReason", refundFailReason);
@@ -238,19 +241,28 @@ public class PEISService {
return true;
}
- public JSONArray queryPEISRecordByCardNo(String cardNo, String begDate, String endDate) throws ServiceException {
+ /**
+ * 体检影像报告
+ *
+ * @param cardNo 加密后的证件号
+ * @param begDate 开始时间
+ * @param endDate 结束时间
+ */
+ public JSONArray queryPEISRecordByCardNo(String cardNo, String begDate, String endDate) throws Exception {
+ String enIdCard = HexUtil.encodeHexStr(RSAHelper.enBytePKCS1Padding(cardNo, "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5klqI5STWTcbfjR093j+hvCEjNlZMQscIJg8jxZGqKW84AdFmSqPWEPu9ilqP+QUASiVSZ1QevGr2DWODFZ8Zw35aDA2bqCEprUx81gDdVPO7H7Bij+r8zAg8fT2c0Bi5rFq0xWMEQiTI+CyWwc5prOpquJU/P5yauEAdkRzlDwIDAQAB"));
+
RequestBody formBody = new FormBody.Builder().
- add("enIdCard", cardNo)
+ add("enIdCard", enIdCard)
.add("begDate", begDate)
.add("endDate", endDate)
.build();
- String result = OkHttpHelper.post(XBDHelper.PEIS_URL + "/WxUse/GetPeisOfPacsResult", formBody);
+ String result = OkHttpHelper.post(XbdConfigHelper.PEIS_URL + "/WxUse/GetPeisOfPacsResult", formBody);
if (ObjectUtils.isEmpty(result)) {
- throw new ServiceException("请求失败");
+ throw new ServiceException("[体检]请求异常");
}
JSONObject jsonResult = JsonHelper.parseObject(result);
if (jsonResult == null) {
- throw new ServiceException("请求失败");
+ throw new ServiceException("[体检]请求解析失败");
}
String code = jsonResult.getString("code");
String message = jsonResult.getString("message");
diff --git a/src/main/java/com/ynxbd/common/service/PayService.java b/src/main/java/com/ynxbd/common/service/PayService.java
index cfbdcbd..5bc1f92 100644
--- a/src/main/java/com/ynxbd/common/service/PayService.java
+++ b/src/main/java/com/ynxbd/common/service/PayService.java
@@ -3,6 +3,7 @@ package com.ynxbd.common.service;
import com.alibaba.fastjson.JSONObject;
import com.ynxbd.ali.helper.AliHelper;
import com.ynxbd.bcm.config.BCMHelper;
+import com.ynxbd.common.action.pay.JYPayAction;
import com.ynxbd.common.action.pay.PEnum;
import com.ynxbd.common.bean.enums.MerchantEnum;
import com.ynxbd.common.bean.pay.*;
@@ -15,6 +16,7 @@ import com.ynxbd.common.result.Result;
import com.ynxbd.common.result.ResultEnum;
import com.ynxbd.common.result.ServiceException;
import com.ynxbd.common.service.cache.PayCache;
+import com.ynxbd.jy.helper.JYPayHelper;
import com.ynxbd.wx.wxfactory.WxMedHelper;
import com.ynxbd.wx.wxfactory.WxPayHelper;
import com.ynxbd.wx.wxfactory.payment.jsapi.models.WxPayNotify;
@@ -551,9 +553,12 @@ public class PayService {
} else if (MerchantEnum.ALI.equals(merchantEnum)) { // 支付宝下单
return AliHelper.createOrder(merchantEnum, title, outTradeNo, totalFee, notifyType, payOpenId);
- } else if (MerchantEnum.BCM.equals(merchantEnum)) {
+ } else if (MerchantEnum.BCM.equals(merchantEnum)) { // 交行
return BCMHelper.createOrder(merchantEnum, title, outTradeNo, totalFee, notifyType);
+ } else if (MerchantEnum.JY.equals(merchantEnum)) { // 京颐
+ return JYPayHelper.createOrder(merchantEnum, title, outTradeNo, totalFee, notifyType, ip, payOpenId, msgOpenId, new ReqOrder());
+
}
return null;
}
diff --git a/src/main/java/com/ynxbd/jy/bean/JYOrder.java b/src/main/java/com/ynxbd/jy/bean/JYOrder.java
new file mode 100644
index 0000000..715a4d8
--- /dev/null
+++ b/src/main/java/com/ynxbd/jy/bean/JYOrder.java
@@ -0,0 +1,113 @@
+package com.ynxbd.jy.bean;
+
+
+import com.ynxbd.common.bean.pay.Order;
+import com.ynxbd.common.bean.pay.ReqOrder;
+import com.ynxbd.jy.bean.enums.JYBusinessTypeEnum;
+import com.ynxbd.jy.bean.enums.JYOrderTypeDetailEnum;
+import com.ynxbd.jy.bean.enums.JYOrderTypeEnum;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.extern.slf4j.Slf4j;
+
+import java.math.BigDecimal;
+
+@Slf4j
+@Getter
+@Setter
+@ToString
+@NoArgsConstructor
+public class JYOrder extends ReqOrder {
+ private String clinicNo;
+ private String hisTransDoneTime;
+ private String hisOperatorNo;
+ private String hisOperatorName;
+ private String receiptNo;
+ // ==================================
+ private String applicationId;
+ private String merchantId;
+ // 应用方订单号
+ private String merOrderNum;
+ // 支付平台订单号
+ private String orderId;
+ // 支付平台支付流水号
+ private String orderTransId;
+ // 支付网关订单号
+ private String threeTradeNo;
+ // 银行流水号
+ private String finalTransNo;
+ // 订单金额
+ private String orderAmt;
+ // 退款金额
+ private String refundAmt;
+ // 支付交易发起时间
+ private String tranDateTime;
+ // 支付时间-YYYYMMDDHHMMSS(订单支付时间)未支付时,为空字符串
+ private String paymentTime;
+ // 支付方式
+ private String payType;
+ // 订单状态[详见字典数据5.2 没有发生过退款业务的数据会包含此字段,如果发生过退款业务,则不会返回此字段,请以退款明细中状态为准;]
+ private String orderState;
+ // 订单状态描述
+ private String orderStateMessage;
+ // 订单费用类型[如:001:挂号费 002:医疗费 详见字典数据5.2订单费用类型]
+ private String orderType;
+ // 微信公众号用户标识
+ private String openId;
+ // 订单最后退款次数,未退款时无此字段。
+ private String refundCount;
+ // 订单最后退款时间,未退款时无此字段。
+ private String refundTime;
+ // 商户ID
+ private String appId;
+ // 商户号
+ private String merchantNo;
+ // 医保局返回信息
+ private String responseContent;
+ // 由接入方生成的签名
+ private String signValue;
+ // ====================================
+
+ // 支付类型明细
+ private String orderTypeDetail;
+
+ public JYOrderTypeEnum orderTypeEnum;
+
+ public JYBusinessTypeEnum businessTypeEnum;
+ // 支付类型明细
+ public JYOrderTypeDetailEnum orderTypeDetailEnum;
+
+
+ public int toInsurancePayType() {
+ int payType = 0;
+ if (super.totalFee.compareTo(super.insuranceFee) == 0) {
+ payType = 2; // 医保
+ } else if (super.totalFee.compareTo(super.cashFee) == 0) {
+ payType = 1; // 现金(1)
+ } else {
+ payType = 3; // 医保+现金
+ }
+ return payType;
+ }
+
+ public int toConsumeType() {
+ if (acctFee == null || insuranceFee == null) {
+ return 0;
+ }
+
+ if (acctFee.compareTo(BigDecimal.ZERO) > 0 && insuranceFee.compareTo(BigDecimal.ZERO) > 0) {
+ return 0; // 0:统筹+个账
+ }
+
+ if (acctFee.compareTo(BigDecimal.ZERO) > 0 && insuranceFee.compareTo(BigDecimal.ZERO) == 0) {
+ return 1; // 1:个账
+ }
+
+ if (acctFee.compareTo(BigDecimal.ZERO) == 0 && insuranceFee.compareTo(BigDecimal.ZERO) > 0) {
+ return 2; // 2:统筹
+ }
+ return 0;
+ }
+}
diff --git a/src/main/java/com/ynxbd/jy/bean/JYRefund.java b/src/main/java/com/ynxbd/jy/bean/JYRefund.java
new file mode 100644
index 0000000..46a6d03
--- /dev/null
+++ b/src/main/java/com/ynxbd/jy/bean/JYRefund.java
@@ -0,0 +1,35 @@
+package com.ynxbd.jy.bean;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Getter
+@Setter
+@ToString
+@NoArgsConstructor
+public class JYRefund {
+ // 支付平台退款流水号
+ private String orderTransId;
+ // 应用方退款流水号
+ private String refundTransId;
+ // 支付网关流水号
+ private String threeTransId;
+ // 银行流水号
+ private String finalTransId;
+ // 退款金额
+ private String refundAmt;
+ // 交易流水状态
+ private String transState;
+ // 交易流水状态描述
+ private String transStateMessage;
+ // 交易代码[002撤销 004退费 005冲正 详细请参考数据字典5.2;$n为下标,从0开始编号]
+ private String transCode;
+ // 退款(冲正、撤销)请求创建时间YYYYMMDDHHMMSS ;$n为下标,从0开始编号
+ private String tranDateTime;
+ // 退款(冲正、撤销)请求完成时间YYYYMMDDHHMMSS ;$n为下标,从0开始编号
+ private String refundTime;
+}
diff --git a/src/main/java/com/ynxbd/jy/bean/enums/JYBusinessTypeEnum.java b/src/main/java/com/ynxbd/jy/bean/enums/JYBusinessTypeEnum.java
new file mode 100644
index 0000000..3f012f9
--- /dev/null
+++ b/src/main/java/com/ynxbd/jy/bean/enums/JYBusinessTypeEnum.java
@@ -0,0 +1,39 @@
+package com.ynxbd.jy.bean.enums;
+
+
+import lombok.ToString;
+
+@ToString
+public enum JYBusinessTypeEnum {
+ B101("B101", "预约"),
+ B102("B102", "挂号"),
+ B201("B201", "门诊缴费"),
+ B202("B202", "门诊预缴"),
+ B301("B301", "住院预缴"),
+ B302("B302", "住院结算补交"),
+ B401("B401", "卡押金"),
+ B999("B999", "其他");
+
+ public final String CODE;
+ public final String DESC;
+
+ JYBusinessTypeEnum(String CODE, String DESC) {
+ this.CODE = CODE;
+ this.DESC = DESC;
+ }
+
+ /**
+ * 根据code获取枚举
+ */
+ public static JYBusinessTypeEnum findEnum(String code) {
+ if (code == null) {
+ return null;
+ }
+ for (JYBusinessTypeEnum item : values()) {
+ if (item.CODE.equals(code)) {
+ return item;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/com/ynxbd/jy/bean/enums/JYOrderTypeDetailEnum.java b/src/main/java/com/ynxbd/jy/bean/enums/JYOrderTypeDetailEnum.java
new file mode 100644
index 0000000..770b32b
--- /dev/null
+++ b/src/main/java/com/ynxbd/jy/bean/enums/JYOrderTypeDetailEnum.java
@@ -0,0 +1,26 @@
+package com.ynxbd.jy.bean.enums;
+
+
+import lombok.ToString;
+
+@ToString
+public enum JYOrderTypeDetailEnum {
+ RegPay("RegPay", "挂号支付"),
+ DiagPay("DiagPay", "诊间支付"),
+ CovidExamPay("CovidExamPay", "新冠检测费用(核酸)"),
+ InHospPay("InHospPay", "住院费支付"),
+ PharmacyPay("PharmacyPay", "药店支付"),
+ InsurancePay("InsurancePay", "保险费支付"),
+ IntRegPay("IntRegPay", "互联网医院挂号支付"),
+ IntReDiagPay("IntReDiagPay", "互联网医院复诊支付"),
+ IntPscPay("IntPscPay", "互联网医院处方支付"),
+ CvidAntigenPay("CvidAntigenPay", "新冠抗原检测");
+
+ public final String CODE;
+ public final String DESC;
+
+ JYOrderTypeDetailEnum(String CODE, String DESC) {
+ this.CODE = CODE;
+ this.DESC = DESC;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ynxbd/jy/bean/enums/JYOrderTypeEnum.java b/src/main/java/com/ynxbd/jy/bean/enums/JYOrderTypeEnum.java
new file mode 100644
index 0000000..014e1f4
--- /dev/null
+++ b/src/main/java/com/ynxbd/jy/bean/enums/JYOrderTypeEnum.java
@@ -0,0 +1,44 @@
+package com.ynxbd.jy.bean.enums;
+
+
+import lombok.ToString;
+
+@ToString
+public enum JYOrderTypeEnum {
+ _001("001", "挂号费"),
+ _002("002", "医药费"),
+ _003("003", "住院预交金"),
+ _004("004", "药品费"),
+ _005("005", "就诊卡充值"),
+ _006("006", "新农合缴费"),
+ _007("007", "网费充值"),
+ _008("008", "健康卡充值"),
+ _010("010", "咨询费"),
+ _012("012", "复印费"),
+ _101("101", "陪诊费"),
+ _801("801", "停车费"),
+ _902("902", "卡押金"),
+ _903("903", "住院结算补交"),
+ _904("904", "体检费"),
+ _905("905", "处方药品费"),
+ _906("906", "陪护床押金"),
+ _907("907", "病历押金"),
+ _908("908", "病理切片押金");
+
+ public final String CODE;
+ public final String NAME;
+
+ JYOrderTypeEnum(String CODE, String name) {
+ this.CODE = CODE;
+ this.NAME = name;
+ }
+
+ public static JYOrderTypeEnum findEnum(String code) {
+ for (JYOrderTypeEnum value : JYOrderTypeEnum.values()) {
+ if (value.CODE.equals(code)) {
+ return value;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ynxbd/jy/helper/JYPayConfig.java b/src/main/java/com/ynxbd/jy/helper/JYPayConfig.java
new file mode 100644
index 0000000..a79dae0
--- /dev/null
+++ b/src/main/java/com/ynxbd/jy/helper/JYPayConfig.java
@@ -0,0 +1,36 @@
+package com.ynxbd.jy.helper;
+
+import com.ynxbd.common.helper.common.XmlConfigHelper;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class JYPayConfig {
+ private JYPayConfig() {
+ }
+
+ // 请求地址
+ public final static String URL;
+
+ // 应用编号
+ public final static String APPLICATION_ID;
+ // 应用商户编号
+ public final static String MERCHANT_ID;
+
+ public final static String HOSP_ID;
+
+ public final static String PRIVATE_KEY;
+
+ static {
+ XmlConfigHelper config = new XmlConfigHelper().read("xbd-config.xml", "pay");
+
+ URL = config.getString("url");
+ APPLICATION_ID = config.getString("application_id");
+ MERCHANT_ID = config.getString("merchant_id");
+ HOSP_ID = config.getString("hosp_id");
+ PRIVATE_KEY = config.getString("private_key");
+
+ if (URL == null) {
+ log.error("[京颐-支付]配置文件读取失败");
+ }
+ }
+}
diff --git a/src/main/java/com/ynxbd/jy/helper/JYPayHelper.java b/src/main/java/com/ynxbd/jy/helper/JYPayHelper.java
index c048f4e..83b76d3 100644
--- a/src/main/java/com/ynxbd/jy/helper/JYPayHelper.java
+++ b/src/main/java/com/ynxbd/jy/helper/JYPayHelper.java
@@ -2,17 +2,24 @@ package com.ynxbd.jy.helper;
import com.alibaba.fastjson.JSONObject;
import com.ynxbd.common.bean.enums.MerchantEnum;
+import com.ynxbd.common.bean.pay.ReqOrder;
import com.ynxbd.common.helper.common.ErrorHelper;
import com.ynxbd.common.helper.common.JsonHelper;
+import com.ynxbd.common.helper.common.RSAHelper;
+import com.ynxbd.common.helper.http.OkHttpHelper;
+import com.ynxbd.jy.bean.JYOrder;
import com.ynxbd.wx.config.WeChatConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
-import weixin.popular.api.PayMchAPI;
-import weixin.popular.bean.paymch.Unifiedorder;
-import weixin.popular.bean.paymch.UnifiedorderResult;
import java.math.BigDecimal;
-import java.util.UUID;
+import java.nio.charset.StandardCharsets;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
// 京颐支付
@Slf4j
@@ -31,70 +38,284 @@ public class JYPayHelper {
* @param msgOpenId 用于推送的openId
* @return 成功返回 json, 否则返回null
*/
- public static JSONObject createOrder(MerchantEnum merchantEnum, String title, String totalFee, String outTradeNo, String notifyType, String ip, String payOpenId, String msgOpenId) {
-// try {
-// if (ObjectUtils.isEmpty(payOpenId) || ObjectUtils.isEmpty(outTradeNo)
-// || merchantEnum == null || totalFee == null || notifyType == null) {
-// log.info("【京硕】下单参数缺失");
-// return null;
-// }
-//
-// String cents;
-// try {
-// cents = new BigDecimal(totalFee).movePointRight(2).toString(); // 金额转换=>单位分
-// } catch (Exception e) {
-// ErrorHelper.println(e);
-// log.info("【京硕】统一下单金额转换异常");
-// return null;
-// }
-//
-// String appId = merchantEnum.APP_ID;
-// String mchId = WeChatConfig.MCH_ID;
-// String mchKey = WeChatConfig.MCH_KEY;
-// String nonce = UUID.randomUUID().toString().replace("-", "");
-//
-// Unifiedorder unifiedorder = new Unifiedorder();
-// unifiedorder.setAppid(appId);
-// unifiedorder.setMch_id(mchId);
-// unifiedorder.setNonce_str(nonce);
-// unifiedorder.setOpenid(payOpenId);
-// unifiedorder.setOut_trade_no(outTradeNo);
-// unifiedorder.setBody(title);
-//
-// unifiedorder.setTotal_fee(cents); // 金额分
-// unifiedorder.setSpbill_create_ip(ip);
-// unifiedorder.setNotify_url(WeChatConfig.getBaseURL() + merchantEnum.NOTIFY_URL);
-// unifiedorder.setTrade_type("JSAPI");
-// // 额外参数
-// unifiedorder.setAttach(notifyType);
-//
-// log.info("【京硕】统一下单 {},{},{},{},{},{},{},{}", appId, mchId, nonce, title, outTradeNo, totalFee, ip, merchantEnum.NOTIFY_URL);
-//
-// // 微信统一下单
-// UnifiedorderResult unifiedorderResult = PayMchAPI.payUnifiedorder(unifiedorder, mchKey);
-// log.info("【京硕】统一下单返回:{}", JsonHelper.toJsonString(unifiedorderResult));
-// if (unifiedorderResult == null) {
-// log.info("【京硕】统一下单失败");
-// return null;
-// }
+ public static JSONObject createOrder(MerchantEnum merchantEnum, String title, String totalFee, String outTradeNo, String notifyType, String ip, String payOpenId, String msgOpenId, ReqOrder reqOrder) {
+ try {
+ if (ObjectUtils.isEmpty(payOpenId) || ObjectUtils.isEmpty(outTradeNo)
+ || merchantEnum == null || totalFee == null || notifyType == null) {
+ log.info("【京硕】下单参数缺失");
+ return null;
+ }
+
+ String cents;
+ try {
+ cents = new BigDecimal(totalFee).movePointRight(2).toString(); // 金额转换=>单位分
+ } catch (Exception e) {
+ ErrorHelper.println(e);
+ log.info("【京硕】下单金额转换异常");
+ return null;
+ }
+
+ log.info("【京硕】下单 {},{},{},{},{}", title, outTradeNo, totalFee, ip, merchantEnum.NOTIFY_URL);
+
+ JYOrder jyOrder = reqOrder.jyOrder;
+
+ Map req = new HashMap<>();
+ req.put("openId", payOpenId);
+ req.put("hospitalId", JYPayConfig.HOSP_ID); // 医院ID
+ req.put("applicationId", JYPayConfig.APPLICATION_ID);
+ req.put("merchantId", JYPayConfig.MERCHANT_ID);
+ req.put("merOrderNum", outTradeNo); // 商户订单号
+ req.put("hisOrderNum", null); // HIS订单号:可以为发票号[该接口若不传,在业务完成后调用2.1.6接口]
+ req.put("hisTransNum", null); // HIS流水号:可以为发票号[该接口若不传,在业务完成后调用2.1.6接口]
+ // 金额
+ req.put("orderAmt", cents); // 交易金额:只接收整数,单位:分,例如100表示壹圆整;支付宝医保支付传总金额
+
+ req.put("orderType", jyOrder.orderTypeEnum.CODE); // 如:001:挂号费 002:医药费;
+ req.put("backURL", WeChatConfig.getBaseURL() + merchantEnum.NOTIFY_URL); // 商户异步回调地址:后台发起异步回调地址, 扫码枪支付方式无需回调的可以不
+// params.put("backParamsType", "key-value"); // 商户异步回调入参格式:后台发起异步回调时参数格式,取值有:key-value和json,默认值是key-value。
+ req.put("payType", "WX_PUBLIC"); // 如:UPOP_APP, UPOP_WEB;详见附录5.1[微信公众号支付(WX_PUBLIC)]
+ req.put("bussinessType", jyOrder.businessTypeEnum.CODE); // 业务类型:综合支付对应用权限控制是否必传 最大不超过4位,详见数据字典5.2 该接口若不传,需要调用2.1.6接口再次更新
+ req.put("patientName", reqOrder.getPatientName()); // 微信医保支付必传。其余支付方式若该接口若不传,需要调用2.1.6接口再次更新
+ req.put("patientGender", reqOrder.getPatientGender()); // 患者性别。综合支付对应用权限控制是否必传 1男 2女 9其他 最大不超过4位 该接口若不传,需要调用2.1.6接口再次更新
+ req.put("patientAge", reqOrder.getPatientAge()); // 患者年龄。综合支付对应用权限控制是否必传 该接口若不传,需要调用2.1.6接口再次更新
+ req.put("patientIdNo", reqOrder.getPatientTel()); // 微信医保支付必传。其余支付方式若该接口若不传,需要调用2.1.6接口再次更新
+ req.put("patientPhoneNumber", reqOrder.getPatientTel()); // 综合支付对应用权限控制是否必传 最大不超过16位 该接口若不传,需要调用2.1.6接口再次更新
+ req.put("patientId", reqOrder.getPatientId()); // 患者ID:综合支付对应用权限控制是否必传 最大不超过32位 该接口若不传,需要调用2.1.6接口再次更新
+ req.put("patientCardNo", reqOrder.getPatientId()); // 患者卡号:综合支付对应用权限控制是否必传 最大不超过32位该接口若不传,需要调用2.1.6接口再次更新
+ req.put("clinicNo", reqOrder.getTreatNum()); // 门诊号:综合支付对应用权限控制是否必传 最大不超过32位该接口若不传,需要调用2.1.6接口再次更新
+ req.put("inpNo", reqOrder.getTreatNum()); // 住院号:综合支付对应用权限控制是否必传 最大不超过32位该接口若不传,需要调用2.1.6接口再次更新
+ req.put("hisTransDoneTime", null); // HIS业务完成时间:综合支付对应用权限控制是否必传 YYYY-MM-DD HH:MM:SS 该接口若不传,需要调用2.1.6接口再次更新
+ req.put("hisOperatorNo", jyOrder.getHisOperatorNo()); // HIS操作员编号:综合支付对应用权限控制是否必传HIS操作员编号和HIS操作员姓名必须成对出现该接口若不传,需要调用2.1.6接口再次更新
+ req.put("hisOperatorName", jyOrder.getHisOperatorName()); // HIS操作员姓名:综合支付对应用权限控制是否必传 HIS操作员编号和HIS操作员姓名必须成对出现 该接口若不传,需要调用2.1.6接口再次更新
+ req.put("receiptNo", null); // 综合支付对应用权限控制是否必传最大不超过200位 该接口若不传,需要调用2.1.6接口再次更新
+ req.put("remarks", ""); // 备注 建行渠道格式为json,参考样式:{"REMARK1":"REM1","REMARK2":"REM2"} 农行渠道参考样式:{"TerminalNo":"1234567"}
+
+ // 医保支付======================================
+// params.put("orderTotalAmt", cents); // orderTotalAmt:微信医保支付必传,有社保交易数据时,订单总金额=自费实际金额+社保金额+减免金额
+// params.put("orderTypeDetail", jyOrder.orderTypeDetailEnum.CODE); // 支付类型明细:由接入方生成的签名,支付平台根据该字段对入参进行验签;签名生成规则参考4加签验签规则
+// params.put("cashFee", reqOrder.getCashFee()); // 现金需要支付的金额:单位为分>=0 线下预结算模式填实际自费金额
+// params.put("insuranceFee", reqOrder.getInsuranceFee()); // 单位为分>=0填实际医保金额
//
-// String result_code = unifiedorderResult.getResult_code();
-// // 下单是否成功
-// Boolean sign_status = unifiedorderResult.getSign_status();
-// if (!SUCCESS.equals(result_code) || sign_status == null || !sign_status) {
-// log.info("【京硕】统一下单返回异常信息:sign_status={}, err_code=[ {} ], err_code_des=[ {} ]", sign_status, unifiedorderResult.getErr_code(), unifiedorderResult.getErr_code_des());
-// return null;
-// }
-// String json = weixin.popular.util.PayUtil.generateMchPayJsRequestJson(unifiedorderResult.getPrepay_id(), appId, mchKey);
-// if (json != null) {
-// return JsonHelper.parseObject(json);
-// }
-// } catch (Exception e) {
-// log.error("【京硕】统一下单异常信息:{}", e.getMessage());
-// ErrorHelper.println(e);
-// }
-// return null;
+// params.put("allowFeeChange", "0"); // 是否允许预结算费用发生变化:0:不允许;1:允许 当医保局返回的预结算金额与医院上传的金额不一致时,此字段为0则直接报错,为1则以医保局金额为准
+// params.put("spbillCreateIp", reqOrder.getIp()); // 用户端ip
+// params.put("returnUrl", reqOrder.getReturnUrl()); // 调用方可以在链接中加上支付单号,回跳后查询调用方订单状态,如果订单已支付则成功, 如果订单未支付则进行查单操作确认订单结果。不论成功或者失败均会回跳
+// params.put("insurancePayType", jyOrder.toInsurancePayType()); // 微信医保支付方式:1:现金;2:医保;3:现金+医保
+// params.put("consumeType", jyOrder.toConsumeType()); // 医保部分扣费类型:0:统筹+个账;1:个账;2:统筹。默认为0
+// params.put("userCardType", "1"); // 1 居民身份证
+// params.put("isDept", "4"); // 医保标识:is_dept=4 医保电子凭证支付;
+// params.put("serialNo", reqOrder.getSerialNo()); // 医院HIS系统订单号
+// params.put("requestContent", reqOrder.getRequestContent()); // 参考医保结构体(医疗机构透传医保) 示例: {"payAuthNo":"AUTH****","payOrdId":"ORD****","setlLatlnt":"118.096435,24.485407"} payAuthNo:授权码 payOrdId:对应处方上传的出参单号 setlLatlnt:用户地理定位信息, 经纬度信息,如“118.096435,24.485407”。未获取到用户定位时,传“0,0”。
+//// params.put("extendInfo", ""); //亲情移动支付时,为必填。 (就诊亲属姓名md5 - rel_user_name_md5,就诊亲属身份证件号md5 - rel_user_card_no_md5 ) { "rel_user_name_md5": "XXX","rel_user_card_no_md5": "XXX"} MD5为32位小写,uft-8编码(身份证中如果有字母需要转成大写再做MD5)
+
+ String signValue = createSign(req);
+ if (signValue == null) {
+ return null;
+ }
+ req.put("signValue", signValue); // 数字签名:由接入方生成的签名,支付平台根据该字段对入参进行验签;签名生成规则参考4加签验签规则
+
+ JSONObject resp = OkHttpHelper.postJson(JYPayConfig.URL + "/qy_iips_pay/paycore/prePayOrder", params -> {
+ params.putAll(req);
+ }, headers -> {
+ headers.add("content-type", "application/x-www-form-urlencoded");
+ });
+ log.info("【京硕】下单返回 {}", JsonHelper.toJsonString(resp));
+ } catch (Exception e) {
+ log.error("【京硕】下单异常信息:", e);
+ }
return null;
}
+
+ /**
+ * 支付状态查询
+ *
+ * @param merchantEnum 枚举
+ * @param title 商品标题
+ * @param totalFee 订单金额
+ * @param outTradeNo 订单号
+ * @return 成功返回 json, 否则返回null
+ */
+ public static JSONObject queryPayOrderInfo(MerchantEnum merchantEnum, String title, String totalFee, String outTradeNo, String bankTransNo, String tradeNo) {
+ try {
+ log.info("【京硕】支付状态查询 {},{},{},{}", title, outTradeNo, totalFee, merchantEnum.NOTIFY_URL);
+ if (ObjectUtils.isEmpty(outTradeNo) && ObjectUtils.isEmpty(bankTransNo) && ObjectUtils.isEmpty(tradeNo)) {
+ return null;
+ }
+
+ if (ObjectUtils.isEmpty(outTradeNo) && (ObjectUtils.isEmpty(bankTransNo) || ObjectUtils.isEmpty(tradeNo))) {
+ return null;
+ }
+
+ Map req = new HashMap<>();
+ req.put("applicationId", JYPayConfig.APPLICATION_ID);
+ req.put("merchantId", JYPayConfig.MERCHANT_ID);
+ req.put("merOrderNum", outTradeNo); // 商户订单号
+ req.put("orderId", bankTransNo); // 支付平台订单号
+ req.put("outTransNo", tradeNo); // 应用流水号:应用流水号outTransNo”和“支付平台订单号orderId”这两个参数必须同时传。该参数指“应用方流水号”,不许有重复
+
+ String signValue = createSign(req);
+ if (signValue == null) {
+ return null;
+ }
+ req.put("signValue", signValue); // 应用流水号:应用流水号outTransNo”和“支付平台订单号orderId”这两个参数必须同时传。该参数指“应用方流水号”,不许有重复
+
+ JSONObject resp = OkHttpHelper.postJson(JYPayConfig.URL + "/qy_iips_pay/paycore/queryPayOrderInfo", params -> {
+ params.putAll(req);
+ }, headers -> {
+ headers.add("content-type", "application/x-www-form-urlencoded");
+ });
+ log.info("【京硕】支付状态查询返回 {}", JsonHelper.toJsonString(resp));
+ } catch (Exception e) {
+ log.error("【京硕】支付状态查询异常信息:", e);
+ }
+ return null;
+ }
+
+
+ /**
+ * 退款申请
+ *
+ * @param merchantEnum 枚举
+ * @param title 商品标题
+ * @param totalFee 订单金额
+ * @param outTradeNo 订单号
+ * @return 成功返回 json, 否则返回null
+ */
+ public static JSONObject refundPayOrder(MerchantEnum merchantEnum, String title, String totalFee, String outTradeNo, String bankTransNo, String tradeNo, String sign) {
+ try {
+ log.info("【京硕】退款申请 {},{},{},{}", title, outTradeNo, totalFee, merchantEnum.NOTIFY_URL);
+ if (ObjectUtils.isEmpty(outTradeNo) && ObjectUtils.isEmpty(bankTransNo) && ObjectUtils.isEmpty(tradeNo)) {
+ return null;
+ }
+
+ if (ObjectUtils.isEmpty(outTradeNo) && (ObjectUtils.isEmpty(bankTransNo) || ObjectUtils.isEmpty(tradeNo))) {
+ return null;
+ }
+ Map req = new HashMap<>();
+ req.put("applicationId", JYPayConfig.APPLICATION_ID);
+ req.put("merchantId", JYPayConfig.MERCHANT_ID);
+ req.put("merOrderNum", outTradeNo); // 商户订单号
+ req.put("orderId", bankTransNo); // 支付平台订单号
+ req.put("outTransNo", tradeNo); // 应用流水号:应用流水号outTransNo”和“支付平台订单号orderId”这两个参数必须同时传。该参数指“应用方流水号”,不许有重复
+ req.put("signValue", sign); // 应用流水号:应用流水号outTransNo”和“支付平台订单号orderId”这两个参数必须同时传。该参数指“应用方流水号”,不许有重复
+ req.put("refundStateSync", "0"); // 退费状态是否同步返回[0:否,1:是,不传默认为否 若传值为1,则退款状态不明确,开始轮询]
+ req.put("requestContent", "0"); // 微信医保支付必传。示例:{“payOrdId”:”******”,“ref_reason”:”******”ref_reason 退款原因payOrdId: 对应处方上传的出参单号
+
+ String signValue = createSign(req);
+ if (signValue == null) {
+ return null;
+ }
+ req.put("signValue", signValue); // 数字签名:由接入方生成的签名,支付平台根据该字段对入参进行验签;签名生成规则参考4加签验签规则
+
+ JSONObject resp = OkHttpHelper.postJson(JYPayConfig.URL + "/qy_iips_pay/paycore/refundPayOrder", params -> {
+ params.putAll(req);
+ }, headers -> {
+ headers.add("content-type", "application/x-www-form-urlencoded");
+ });
+ log.info("【京硕】退款申请返回 {}", JsonHelper.toJsonString(resp));
+ } catch (Exception e) {
+ log.error("【京硕】退款申请异常信息:", e);
+ }
+ return null;
+ }
+
+ /**
+ * 更新业务信息
+ *
+ * @param merchantEnum 枚举
+ * @param title 商品标题
+ * @param totalFee 订单金额
+ * @param outTradeNo 订单号
+ * @return 成功返回 json, 否则返回null
+ */
+ public static JSONObject modifyBusinessInfo(MerchantEnum merchantEnum, String title, String totalFee, String outTradeNo, String bankTransNo, String tradeNo, String sign) {
+ try {
+ log.info("【京硕】更新业务信息 {},{},{},{}", title, outTradeNo, totalFee, merchantEnum.NOTIFY_URL);
+ if (ObjectUtils.isEmpty(outTradeNo) && ObjectUtils.isEmpty(bankTransNo) && ObjectUtils.isEmpty(tradeNo)) {
+ return null;
+ }
+
+ if (ObjectUtils.isEmpty(outTradeNo) && (ObjectUtils.isEmpty(bankTransNo) || ObjectUtils.isEmpty(tradeNo))) {
+ return null;
+ }
+
+ JSONObject resp = OkHttpHelper.postJson(JYPayConfig.URL + "/qy_iips_pay/paycore/modifyBusinessInfo", params -> {
+ params.put("applicationId", JYPayConfig.APPLICATION_ID); // 应用编号
+ params.put("merchantId", JYPayConfig.MERCHANT_ID); // 应用商户编号
+// params.put("merOrderNum", merOrderNum); // 商户订单号
+// params.put("refundTransId", refundTransId); // 商户退款流水号,非支付交易必传
+// params.put("orderId", orderId); // 支付平台订单号
+// params.put("orderTransId", orderTransId); // 支付平台流水号
+// params.put("hisOrderNum", hisOrderNum); // HIS订单号,对账场景必传
+// params.put("hisTransNum", hisTransNum); // HIS交易流水号,对账场景必传
+// params.put("hisTransAmt", hisTransAmt); // 交易金额,单位:分,整数
+// params.put("bussinessType", bussinessType); // 业务类型,最大4位
+// params.put("patientName", patientName); // 患者姓名
+// params.put("patientGender", patientGender); // 患者性别:1男 2女 9其他
+// params.put("patientAge", patientAge); // 患者年龄
+// params.put("patientIdNo", patientIdNo); // 患者身份证号,最长18位
+// params.put("patientPhoneNumber", patientPhoneNumber); // 患者手机号码,最长16位
+// params.put("patientId", patientId); // 患者ID
+// params.put("patientCardNo", patientCardNo); // 患者卡号
+// params.put("clinicNo", clinicNo); // 门诊号
+// params.put("inpNo", inpNo); // 住院号
+// params.put("hisTransDoneTime", hisTransDoneTime); // HIS业务完成时间 YYYY-MM-DD HH:MM:SS
+// params.put("hisOperatorNo", hisOperatorNo); // HIS操作员编号
+// params.put("hisOperatorName", hisOperatorName); // HIS操作员姓名
+// params.put("receiptNo", receiptNo); // HIS票据号
+// params.put("hospitalId", hospitalId); // 医院ID
+// params.put("iipsApiVersion", iipsApiVersion); // API版本号,不传默认v1.0
+ }, headers -> {
+ headers.add("content-type", "application/x-www-form-urlencoded");
+ });
+ log.info("【京硕】更新业务信息返回 {}", JsonHelper.toJsonString(resp));
+ } catch (Exception e) {
+ log.error("【京硕】更新业务信息异常信息:", e);
+ }
+ return null;
+ }
+
+
+ /**
+ * 【可选】排除signValue自身(标准支付签名规范推荐)
+ *
+ * @param params 原始参数map
+ * @return 待签名字符串
+ */
+ public static String createSign(Map params) {
+ try {
+ String signString = buildSignString(params);
+ return sign(signString, RSAHelper.getPrivateKey(JYPayConfig.PRIVATE_KEY));
+ } catch (Exception e) {
+ log.error("", e);
+ return null;
+ }
+ }
+
+ /**
+ * 【可选】排除signValue自身(标准支付签名规范推荐)
+ *
+ * @param params 原始参数map
+ * @return 待签名字符串
+ */
+ public static String buildSignString(Map params) {
+ return params.entrySet().stream().filter(entry -> entry.getValue() != null && !entry.getValue().trim().isEmpty() && !"signValue".equals(entry.getKey()))
+ .sorted(Map.Entry.comparingByKey())
+ .map(entry -> entry.getKey() + "=" + entry.getValue())
+ .collect(Collectors.joining("&"));
+ }
+
+ /**
+ * 使用私钥按照指定算法进行签名
+ *
+ * @param message 待签名串
+ * @param privateKey 签名用私钥对象
+ * @return 签名结果
+ */
+ public static String sign(String message, PrivateKey privateKey) throws Exception {
+ Signature signature = Signature.getInstance("SHA256WithRSA");
+ signature.initSign(privateKey);
+ signature.update(message.getBytes(StandardCharsets.UTF_8));
+ return Base64.getEncoder().encodeToString(signature.sign());
+ }
}
diff --git a/src/main/java/com/ynxbd/wx/config/MessagePushConfig.java b/src/main/java/com/ynxbd/wx/config/MessagePushConfig.java
index f464c06..72cae33 100644
--- a/src/main/java/com/ynxbd/wx/config/MessagePushConfig.java
+++ b/src/main/java/com/ynxbd/wx/config/MessagePushConfig.java
@@ -28,35 +28,36 @@ public class MessagePushConfig {
*/
public static final String HOST_URL;
- // [挂号]导航推送
+ // [挂号]导航推送 https://map.ipsmap.com?id=opBdKy87Gs&appKey=fnAs1mE5HP&poi=科室编码
public static final boolean REG_NAVIGATE_IS_ENABLE;
- public static final String REG_NAVIGATE_URL;
+ public static final String REG_NAVIGATE_API;
+
// [挂号]缴费通知
public static final boolean REG_PAID_IS_ENABLE;
- public static final String REG_PAID_URL;
+ public static final String REG_PAID_API;
// [挂号]取消预约
public static final boolean REG_CANCEL_IS_ENABLE;
- public static final String REG_CANCEL_URL;
+ public static final String REG_CANCEL_API;
// [挂号]AI
- public static final String REG_AI_URL;
public static final boolean REG_AI_IS_ENABLE;
+ public static final String REG_AI_API;
// [处方]缴费通知
public static final boolean RX_PAID_IS_ENABLE;
- public static final String RX_PAID_URL;
+ public static final String RX_PAID_API;
// 产科建档
public static final boolean OBS_DOCUMENT_IS_ENABLE;
- public static final String OBS_DOCUMENT_URL;
+ public static final String OBS_DOCUMENT_API;
static {
XmlConfigHelper config = new XmlConfigHelper().read("wx-msg-push.xml");
- HOST_URL = config.getString("host_url","");
+ HOST_URL = config.getString("host_url", "");
if (ObjectUtils.isEmpty(HOST_URL)) {
log.error("【消息推送】配置文件wx-msg-push.xml读取失败");
}
@@ -64,32 +65,32 @@ public class MessagePushConfig {
// [挂号]导航推送
XmlConfigHelper regNavigateConfig = config.getConfigNode("reg_navigate");
REG_NAVIGATE_IS_ENABLE = regNavigateConfig.getBoolean("is_enable", false);
- REG_NAVIGATE_URL = HOST_URL + regNavigateConfig.getString("api");
+ REG_NAVIGATE_API = HOST_URL + regNavigateConfig.getString("api");
// [挂号]缴费通知
XmlConfigHelper regPaidConfig = config.getConfigNode("reg_paid");
REG_PAID_IS_ENABLE = regPaidConfig.getBoolean("is_enable", false);
- REG_PAID_URL = HOST_URL + regPaidConfig.getString("api");
+ REG_PAID_API = HOST_URL + regPaidConfig.getString("api");
// [挂号]取消预约
XmlConfigHelper regCancelConfig = config.getConfigNode("reg_cancel");
REG_CANCEL_IS_ENABLE = regCancelConfig.getBoolean("is_enable", false);
- REG_CANCEL_URL = HOST_URL + regCancelConfig.getString("api");
+ REG_CANCEL_API = HOST_URL + regCancelConfig.getString("api");
// [挂号]AI
XmlConfigHelper regAIConfig = config.getConfigNode("reg_ai");
REG_AI_IS_ENABLE = regAIConfig.getBoolean("is_enable", false);
- REG_AI_URL = HOST_URL + regAIConfig.getString("api");
+ REG_AI_API = HOST_URL + regAIConfig.getString("api");
// [处方]缴费通知
XmlConfigHelper rxPaidConfig = config.getConfigNode("rx_paid");
RX_PAID_IS_ENABLE = rxPaidConfig.getBoolean("is_enable", false);
- RX_PAID_URL = HOST_URL + rxPaidConfig.getString("api");
+ RX_PAID_API = HOST_URL + rxPaidConfig.getString("api");
// 产科建档
XmlConfigHelper obsDocumentConfig = config.getConfigNode("obs_document");
OBS_DOCUMENT_IS_ENABLE = obsDocumentConfig.getBoolean("is_enable", false);
- OBS_DOCUMENT_URL = HOST_URL + obsDocumentConfig.getString("api");
+ OBS_DOCUMENT_API = HOST_URL + obsDocumentConfig.getString("api");
}
@@ -100,7 +101,7 @@ public class MessagePushConfig {
*/
public static void regNavigatePush(MerchantEnum merchantEnum, Register reg) {
try {
- if (!merchantEnum.equals(MerchantEnum.WX) || !REG_NAVIGATE_IS_ENABLE || ObjectUtils.isEmpty(REG_NAVIGATE_URL)) {
+ if (!merchantEnum.equals(MerchantEnum.WX) || !REG_NAVIGATE_IS_ENABLE || ObjectUtils.isEmpty(REG_NAVIGATE_API)) {
return;
}
@@ -112,14 +113,14 @@ public class MessagePushConfig {
String doctName = reg.getDoctName();
String deptName = reg.getDeptName();
String deptCode = reg.getDeptCode();
- if (openid == null || patientId == null) {
- log.warn("[推送]挂号导航通知失败,参数缺失~openid={}, patientId={}", openid, patientId);
+ if (ObjectUtils.isEmpty(openid) || ObjectUtils.isEmpty(patientId)) {
+ log.warn("[推送]挂号导航通知失败,参数缺失 openid={}, patientId={}", openid, patientId);
return;
}
Patient patient = new PatientDao().selectByOpenidAndEPId(openid, patientId);
if (patient == null) {
- log.warn("[推送]挂号导航通知失败,患者信息不存在~");
+ log.warn("[推送]挂号导航通知失败,未找到患者信息");
return;
}
@@ -127,7 +128,7 @@ public class MessagePushConfig {
String time = (ObjectUtils.isEmpty(begTime) || ObjectUtils.isEmpty(endTime)) ? "" : (" " + begTime + "-" + endTime);
- OkHttpHelper.getAsync(REG_NAVIGATE_URL, params -> {
+ OkHttpHelper.getAsync(REG_NAVIGATE_API, params -> {
params.put("patientName", patient.getName() + " ID:" + patientId);
params.put("content", "就诊时间:" + regDate + time);
params.put("deptName", deptName);
@@ -145,8 +146,7 @@ public class MessagePushConfig {
*/
public static void regPush(MerchantEnum merchantEnum, Register reg) {
try {
- if (!merchantEnum.equals(MerchantEnum.WX)
- || !REG_PAID_IS_ENABLE || reg == null || ObjectUtils.isEmpty(REG_PAID_URL)) {
+ if (!merchantEnum.equals(MerchantEnum.WX) || !REG_PAID_IS_ENABLE || reg == null || ObjectUtils.isEmpty(REG_PAID_API)) {
return;
}
@@ -174,7 +174,7 @@ public class MessagePushConfig {
String time = (ObjectUtils.isEmpty(begTime) || ObjectUtils.isEmpty(endTime)) ? "" : (" " + begTime + "-" + endTime);
- OkHttpHelper.getAsync(REG_PAID_URL, params -> {
+ OkHttpHelper.getAsync(REG_PAID_API, params -> {
params.put("openId", DesEncryptHelper.enCode(openid));
params.put("patientName", patient.getName() + " ID:" + patientId);
params.put("deptName", deptName);
@@ -196,7 +196,7 @@ public class MessagePushConfig {
*/
public static void regAI(MerchantEnum merchantEnum, Register reg) {
try {
- if (!merchantEnum.equals(MerchantEnum.WX) || !REG_AI_IS_ENABLE || reg == null || ObjectUtils.isEmpty(REG_AI_URL)) {
+ if (!merchantEnum.equals(MerchantEnum.WX) || !REG_AI_IS_ENABLE || reg == null || ObjectUtils.isEmpty(REG_AI_API)) {
return;
}
@@ -219,7 +219,7 @@ public class MessagePushConfig {
.add("url", url)
.add("organizeName", ORGANIZENAME)
.build();
- OkHttpHelper.post(REG_AI_URL, requestBody);
+ OkHttpHelper.post(REG_AI_API, requestBody);
} catch (Exception e) {
log.warn("[推送]AI智能问诊推送通知错误-{}", e.getMessage());
}
@@ -246,7 +246,7 @@ public class MessagePushConfig {
.add("url", url)
.add("organizeName", ORGANIZENAME)
.build();
- OkHttpHelper.post(REG_AI_URL, requestBody);
+ OkHttpHelper.post(REG_AI_API, requestBody);
}
@@ -257,7 +257,7 @@ public class MessagePushConfig {
*/
public static void regAIReport(String patientId, String outTradeNo, String openId) {
try {
- if (!REG_AI_IS_ENABLE || ObjectUtils.isEmpty(REG_AI_URL)) {
+ if (!REG_AI_IS_ENABLE || ObjectUtils.isEmpty(REG_AI_API)) {
return;
}
log.info("[推送]AI问诊报告推送...");
@@ -277,7 +277,7 @@ public class MessagePushConfig {
.add("url", url)
.add("organizeName", ORGANIZENAME)
.build();
- OkHttpHelper.post(REG_AI_URL, requestBody);
+ OkHttpHelper.post(REG_AI_API, requestBody);
} catch (Exception e) {
log.warn("[推送]AI问诊报告推送通知错误-{}", e.getMessage());
}
@@ -293,7 +293,7 @@ public class MessagePushConfig {
public static void regObsDocument(MerchantEnum merchantEnum, Register reg) {
try {
if (!merchantEnum.equals(MerchantEnum.WX)
- || reg == null || ObjectUtils.isEmpty(OBS_DOCUMENT_URL)) {
+ || reg == null || ObjectUtils.isEmpty(OBS_DOCUMENT_API)) {
return;
}
@@ -311,7 +311,7 @@ public class MessagePushConfig {
.add("organizeName", ORGANIZENAME)
.add("buttonName", "进入产科建档系统")
.build();
- OkHttpHelper.post(OBS_DOCUMENT_URL, requestBody);
+ OkHttpHelper.post(OBS_DOCUMENT_API, requestBody);
} catch (Exception e) {
log.warn("[推送]产科建档推送通知错误-{}", e.getMessage());
}
@@ -324,7 +324,7 @@ public class MessagePushConfig {
public static void regCancelPush(MerchantEnum merchantEnum, Register reg) {
try {
if (!merchantEnum.equals(MerchantEnum.WX)
- || !REG_CANCEL_IS_ENABLE || reg == null || ObjectUtils.isEmpty(REG_CANCEL_URL)) {
+ || !REG_CANCEL_IS_ENABLE || reg == null || ObjectUtils.isEmpty(REG_CANCEL_API)) {
return;
}
log.info("[推送]取消预约...");
@@ -350,7 +350,7 @@ public class MessagePushConfig {
String time = (ObjectUtils.isEmpty(begTime) || ObjectUtils.isEmpty(endTime)) ? "" : (" " + begTime + "-" + endTime);
- OkHttpHelper.getAsync(REG_CANCEL_URL, params -> {
+ OkHttpHelper.getAsync(REG_CANCEL_API, params -> {
params.put("openId", DesEncryptHelper.enCode(openid));
params.put("patientName", patient.getName() + " ID:" + patientId);
params.put("deptName", deptName);
@@ -370,7 +370,7 @@ public class MessagePushConfig {
*/
public static void recipePush(List recipeList, String treatNum, String patientId, String openid, String tip) {
try {
- if (!RX_PAID_IS_ENABLE || ObjectUtils.isEmpty(RX_PAID_URL)) {
+ if (!RX_PAID_IS_ENABLE || ObjectUtils.isEmpty(RX_PAID_API)) {
return;
}
@@ -394,7 +394,7 @@ public class MessagePushConfig {
return;
}
- OkHttpHelper.getAsync(RX_PAID_URL, params -> {
+ OkHttpHelper.getAsync(RX_PAID_API, params -> {
params.put("openId", DesEncryptHelper.enCode(openid));
params.put("patientName", patient.getName() + " ID:" + patientId);
params.put("content", tip);
diff --git a/src/main/java/com/ynxbd/wx/wxfactory/payment/WXPayUtility.java b/src/main/java/com/ynxbd/wx/wxfactory/payment/WXPayUtility.java
index 37b6a21..ec8e840 100644
--- a/src/main/java/com/ynxbd/wx/wxfactory/payment/WXPayUtility.java
+++ b/src/main/java/com/ynxbd/wx/wxfactory/payment/WXPayUtility.java
@@ -91,6 +91,7 @@ public class WXPayUtility {
.create();
private static final char[] SYMBOLS =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
+
private static final SecureRandom random = new SecureRandom();
/**
diff --git a/src/main/resources/copy/healthcard/石林县人民医院-hc-config.xml b/src/main/resources/copy/healthcard/石林县人民医院-hc-config.xml
index 9233575..5b88cf6 100644
--- a/src/main/resources/copy/healthcard/石林县人民医院-hc-config.xml
+++ b/src/main/resources/copy/healthcard/石林县人民医院-hc-config.xml
@@ -1,18 +1,16 @@
-
-
+
-
-
+
true
- true
+ false
100000637
@@ -25,6 +23,6 @@
暂无介绍
二级甲等
暂无地址
- 0871-67798120
+
\ No newline at end of file
diff --git a/src/main/resources/hc-config.xml b/src/main/resources/hc-config.xml
index b32b842..89cb015 100644
--- a/src/main/resources/hc-config.xml
+++ b/src/main/resources/hc-config.xml
@@ -1,11 +1,10 @@
- true
31737
- 20009251
- 3bee9edc0a2f41ac911b9b714c854cad
+ 20009250
+ c4a39049d4b1c29ffaa9a312687fdcfc
20009250
3bee9edc0a2f41ac911b9b714c854cad
@@ -22,9 +21,9 @@
34edf7cd14e646ae9c1bbca791b7b685
- b26188e6142d43b88f01453853d52a0a
-
- b26188e6142d43b88f01453853d52a0a
+ b26188e6142d43b88f01453853d52a0a
+
+ b26188e6142d43b88f01453853d52a0a
800002723
diff --git a/src/main/resources/jy-config.xml b/src/main/resources/jy-config.xml
new file mode 100644
index 0000000..ee92db4
--- /dev/null
+++ b/src/main/resources/jy-config.xml
@@ -0,0 +1,11 @@
+
+
+
+ http://127.0.0.1
+ 1
+ 1
+ MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD1eiOktZm8bUwjHA2bFlrULg9v/VAmBfUWb8/1+xyZH5eSa7itvAG2Kdzv7L59nRIspXyO6ZW+gGmofnX8CqI5ofLrpissgoqZadNfz5v/k2Q78YTBM8BEMwkrPwOsbFX62poPSKr4kZRHgMADJkgS6AhsaDNBLdH6uRE8R0H6lQIDAQAB
+ MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAPV6I6S1mbxtTCMcDZsWWtQuD2/9UCYF9RZvz/X7HJkfl5JruK28AbYp3O/svn2dEiylfI7plb6Aaah+dfwKojmh8uumKyyCiplp01/Pm/+TZDvxhMEzwEQzCSs/A6xsVframg9IqviRlEeAwAMmSBLoCGxoM0Et0fq5ETxHQfqVAgMBAAECgYAf8F9Y2+P/1zyzyL+gcR0qRD/v80aNW/MSk0O8noqPBcRD4c4qlK6oU/QSJ3x1fY1Sz8lQEuZP3gdhS+rv+zY2BjbfSq4HcZexmbBmh0NQ4Swd7i0hfkSM+koHZjVoPY/FJ/TW/Ks3iV+kpAZuVLCh60B66H8y9K5xu331nLxeYQJBAPzFeQPVJThxIBbk5g8/fYD/gbglEGqdurTJlo9tmCuqzty19fApBE+41ir9Sl2vguDnY1d9Zbuf1AlS21jsVx0CQQD4nNC1FyDKK6GxQvOm6Do+b663ft0WK7dum0c4pM57VPTRqxag4p6lYCu5KYmVvUL20KGE5LVZ9LaOIMIurD/ZAkEA4z4My1tFuPZKqQpjoXWsuNn7nrcDiTX/8iQBDTSzxx4qFtYnIh9d1uYO9Fr+DjeJa/PZpYAAg6rujutEcy8WKQJARir0WPgjIAx6gW5VGHmY3sBkvpOG0Ngb2JLo4hrZ0ENlKbwxEc2EW0aucH9BvsqBGOo/fCOU78O6tpiWVdf12QJAP8ENPIBQCLwHq0U5bzV+X94BmuOfTAqwvy/r6XQcOct0k/M/Lln0FUcPwAb6rl/1R55Xj1/DxI2UbTc4KNNpng==
+
+
+
diff --git a/src/main/resources/jy-pay-config.xml b/src/main/resources/jy-pay-config.xml
deleted file mode 100644
index 953af87..0000000
--- a/src/main/resources/jy-pay-config.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
diff --git a/src/main/resources/xbd-config.xml b/src/main/resources/xbd-config.xml
index 038330f..2e0fcde 100644
--- a/src/main/resources/xbd-config.xml
+++ b/src/main/resources/xbd-config.xml
@@ -1,9 +1,9 @@
-
+ http://200.200.200.71:5050/peisReserve
http://192.168.0.183:3307/wx3307
- http://192.168.0.183:3307/wx3307
+