diff --git a/.gitignore b/.gitignore index bfe8763..37c87db 100644 --- a/.gitignore +++ b/.gitignore @@ -103,3 +103,4 @@ README.html .idea wc.db .DS_Store +/src/main/resources/druid-config.properties diff --git a/pom.xml b/pom.xml index bfd0e38..8f477f3 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ UTF-8 1.8 1.8 - 6.1.1 + 6.3.0.2 2.14.1 1.2.83 diff --git a/src/main/java/com/ynxbd/common/action/PWEAction.java b/src/main/java/com/ynxbd/common/action/PWEAction.java new file mode 100644 index 0000000..44214c8 --- /dev/null +++ b/src/main/java/com/ynxbd/common/action/PWEAction.java @@ -0,0 +1,233 @@ +package com.ynxbd.common.action; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdcardUtil; +import com.alibaba.fastjson.JSONObject; + +import com.ynxbd.common.action.base.BaseAction; +import com.ynxbd.common.bean.pay.Register; +import com.ynxbd.common.dao.PWEReportDao; +import com.ynxbd.common.helper.common.JsonHelper; +import com.ynxbd.common.result.Result; +import com.ynxbd.common.result.ResultEnum; +import com.ynxbd.wx.pwe.PWEConfig; +import com.ynxbd.wx.pwe.PWEHelper; +import com.ynxbd.wx.pwe.bean.PWEResult; +import com.ynxbd.wx.pwe.bean.PWERegister; +import com.ynxbd.wx.pwe.bean.PWEReport; +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 javax.servlet.http.HttpServletRequest; + +/** + * 【预问诊】 + * 接口名,大写开头的接口是提供给第三方调用的。 + */ + +@Slf4j +@Namespace("/pwe") +public class PWEAction extends BaseAction { + + /** + * [预问诊][患者端]获取小程序短链(文档中描述:用于短信) + */ + @Action("getMiniPWEUrl") + public Result getMiniPWEUrl(String registerId) { + try { + log.info("[预问诊][患者端]获取小程序短链 registerId={}", registerId); + if (ObjectUtils.isEmpty(registerId)) { + return Result.error(ResultEnum.PARAM_IS_BLANK); + } + String miniPWEUrl = PWEHelper.getMiniPWEUrl(registerId); + return Result.success(miniPWEUrl); + } catch (Exception e) { + return Result.error(e); + } + } + + + /*** + * [预问诊][患者端]获取预问诊H5链接 + */ + @Action("getH5PWEUrl") + public Result getH5PWEUrl(String registerId) { + try { + log.info("[预问诊][患者端]获取预问诊h5链接 registerId={}", registerId); + if (ObjectUtils.isEmpty(registerId)) { + return Result.error(ResultEnum.PARAM_IS_BLANK); + } + String miniPWEUrl = PWEHelper.getH5PWEUrl(registerId); + return Result.success(miniPWEUrl); + } catch (Exception e) { + return Result.error(e); + } + } + + + /** + * [预问诊][医生端]获取预问诊报告链接 + */ + @Action("getPWEReportUrl") + public Result getPWEReportUrl(String deptCode, String doctCode, String doctName, String tradeNo) { + try { + log.info("[预问诊][医生端]获取预问诊报告链接 deptCode={}, doctCode={}, doctName={}, tradeNo={}", deptCode, doctCode, doctName, tradeNo); + if (ObjectUtils.isEmpty(deptCode) || ObjectUtils.isEmpty(doctCode) || ObjectUtils.isEmpty(doctName) || ObjectUtils.isEmpty(tradeNo)) { + return Result.error(ResultEnum.PARAM_IS_BLANK); + } + + Register order = new PWEReportDao().selectRegOrderNo(tradeNo); + if (order == null) { + return Result.error("未找到订单信息"); + } + String outTradeNo = order.getOutTradeNo(); + if (ObjectUtils.isEmpty(outTradeNo)) { + return Result.error("订单没有订单号"); + } + String miniPWEUrl = PWEHelper.getPWEReportUrl(deptCode, doctCode, doctName, outTradeNo); + return Result.success(miniPWEUrl); + } catch (Exception e) { + return Result.error(e); + } + } + + // 返回挂号信息 + + /** + * [预问诊]6.3 预问诊完成通知 ReportNotify(可选) + */ + @Action("ReportNotify") + public PWEResult ReportNotify(HttpServletRequest req) { + try { + JSONObject body = PWEHelper.verifySign(req, true); + + String partnerId = body.getString("partnerId"); + String hospitalId = body.getString("hospitalId"); + String registeredId = body.getString("registeredId"); + String progress = body.getString("progress"); + log.info("[预问诊]6.3 预问诊完成通知 partnerId={}, hospitalId={}, registeredId={}, progress={}", partnerId, hospitalId, registeredId, progress); + if ("1".equals(progress)) { + log.info("进度100%"); + } + return PWEResult.success(); + } catch (Exception e) { + return PWEResult.error(e); + } + } + + + // 返回挂号信息 + + /** + * [预问诊]挂号查询 + */ + @Action("GetRegisteredInfo") + public PWEResult GetRegisteredInfo(HttpServletRequest req) { + try { + JSONObject body = PWEHelper.verifySign(req, true); + + String registeredId = body.getString("registeredId"); + log.info("[预问诊]挂号查询 registeredId={}", registeredId); + + Register order = new PWEReportDao().selectRegOrderInfo(registeredId); + if (order == null) { + return PWEResult.error("未找到挂号订单"); + } + + String sex = order.getSex(); + String birthday = order.getBirthday(); + String idCardNo = order.getIdCardNo(); + + int gender; + if (ObjectUtils.isEmpty(sex)) { + gender = IdcardUtil.getGenderByIdCard(idCardNo) == 0 ? 1 : 0; + } else { + gender = "男".equals(sex) ? 0 : 1; + } + + int age; + if (ObjectUtils.isEmpty(birthday)) { + age = IdcardUtil.getAgeByIdCard(idCardNo); + } else { + age = DateUtil.ageOfNow(birthday); + } + + PWERegister reg = new PWERegister(); +// reg.setName(order.getPatientName()); + reg.setSex(gender); + reg.setAge(age); + reg.setRegisteredId(order.getOutTradeNo()); + + reg.setDepartments(reg.getStrList(order.getDeptName())); + reg.setDepartmentIds(reg.getStrList(order.getDeptCode())); + reg.setDoctorId(order.getDoctCode()); + reg.setDoctorName(order.getDoctName()); + + return PWEResult.success(reg); + } catch (Exception e) { + return PWEResult.error(e); + } + } + + + /** + * [预问诊]6.4.1 报告内容推送 PushReport(必选) + */ + @Action("PushReport") + public PWEResult PushReport(HttpServletRequest req) { + try { + JSONObject body = PWEHelper.verifySign(req, false); + String registeredId = body.getString("registeredId"); + log.info("[预问诊]报告内容推送 registeredId={}", registeredId); + + PWEReport report = new PWEReport(); + report.setRegisterId(registeredId); + report.setDataJson(JsonHelper.toJsonString(body)); + + PWEReport findData = new PWEReportDao().selectByRegId(registeredId); + boolean isOK; + if (findData == null) { + log.info("[预问诊]报告内容推送 新增数据 registeredId={}", registeredId); + report.setHospitalId(PWEConfig.HOSPITAL_ID); + isOK = new PWEReportDao().insert(report); + } else { + log.info("[预问诊]报告内容推送 修改数据 registeredId={}", registeredId); + isOK = new PWEReportDao().update(report); + } + + if (isOK) { + return PWEResult.success(); + } + return PWEResult.error("数据接收失败"); + } catch (Exception e) { + return PWEResult.error(e); + } + + } + + + /** + * [预问诊]6.4.2 报告内容查询 QueryReport(必选) + */ + @Action("QueryReport") + public PWEResult QueryReport(HttpServletRequest req) { + try { + JSONObject body = PWEHelper.verifySign(req, true); + String registeredId = body.getString("registeredId"); + log.info("[预问诊]报告内容查询 registeredId={}", registeredId); + PWEReport findData = new PWEReportDao().selectByRegId(registeredId); + if (findData == null) { + return PWEResult.error("未找到数据"); + } + JSONObject jsonObject = JsonHelper.parseObject(findData.getDataJson()); + if (jsonObject == null) { + return PWEResult.error("匹配到的数据为空"); + } + return PWEResult.success(jsonObject); + } catch (Exception e) { + return PWEResult.error(e); + } + } +} diff --git a/src/main/java/com/ynxbd/common/action/TestAction.java b/src/main/java/com/ynxbd/common/action/TestAction.java index 331fdfc..c28d06c 100644 --- a/src/main/java/com/ynxbd/common/action/TestAction.java +++ b/src/main/java/com/ynxbd/common/action/TestAction.java @@ -62,9 +62,15 @@ public class TestAction extends BaseAction { // } - @Action("ocPay") - public Result ocPay(String outTradeNo) throws ServiceException { - new OutCollectService().ocPayNotify(MerchantEnum.WX, "123", new BigDecimal("0.01"), outTradeNo, "123", "123"); +// @Action("ocPay") +// public Result ocPay(String outTradeNo) throws ServiceException { +// new OutCollectService().ocPayNotify(MerchantEnum.WX, "123", new BigDecimal("0.01"), outTradeNo, "123", "123"); +// return Result.success(); +// } + + + @Action("test03") + public Result test03() throws ServiceException { return Result.success(); } 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 8534c53..28df31c 100644 --- a/src/main/java/com/ynxbd/common/action/base/BaseAction.java +++ b/src/main/java/com/ynxbd/common/action/base/BaseAction.java @@ -1,7 +1,10 @@ package com.ynxbd.common.action.base; +import com.alibaba.fastjson.JSONObject; import com.ynxbd.common.helper.common.HttpHelper; +import com.ynxbd.common.helper.common.JsonHelper; import com.ynxbd.wx.wxfactory.ReqParamHelper; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.struts2.ServletActionContext; import org.apache.struts2.action.ServletRequestAware; @@ -12,10 +15,7 @@ import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Serializable; -import java.io.UnsupportedEncodingException; +import java.io.*; import java.math.BigDecimal; @@ -26,6 +26,7 @@ import java.math.BigDecimal; * @date 2022年02月21日下午12:39:32 * @copyright: 2022云南新八达科技有限公司 All rights reserved. */ +@Slf4j @ParentPackage("default") public class BaseAction implements Serializable, ServletRequestAware { private static final long serialVersionUID = 3878349193368881604L; @@ -90,8 +91,6 @@ public class BaseAction implements Serializable, ServletRequestAware { } - - protected Integer getInteger(String param) { try { String val = this.request.getParameter(param); @@ -120,7 +119,6 @@ public class BaseAction implements Serializable, ServletRequestAware { } - protected BigDecimal getBigDecimal(String param) { try { String val = this.request.getParameter(param); @@ -151,9 +149,44 @@ public class BaseAction implements Serializable, ServletRequestAware { pw.write(message); pw.flush(); } catch (IOException e) { - e.printStackTrace(); + log.error(e.getMessage()); } return "SUCCESS"; } + /** + * 读取request中的body数据 + */ + public JSONObject getBody() { + return readBody(this.request); + } + + /** + * 读取request中的body数据 + * + * @param request 请求体 + */ + public static JSONObject readBody(HttpServletRequest request) { + BufferedReader br = null; + try { + br = request.getReader(); + String line; + StringBuilder sb = new StringBuilder(); + while ((line = br.readLine()) != null) { + sb.append(line); + } + return JsonHelper.parseObject(sb.toString()); + } catch (Exception e) { + log.error(e.getMessage()); + } finally { + try { + if (br != null) { + br.close(); + } + } catch (Exception e) { + log.error(e.getMessage()); + } + } + return null; + } } diff --git a/src/main/java/com/ynxbd/common/bean/pay/Order.java b/src/main/java/com/ynxbd/common/bean/pay/Order.java index ba3cc94..4a09c20 100644 --- a/src/main/java/com/ynxbd/common/bean/pay/Order.java +++ b/src/main/java/com/ynxbd/common/bean/pay/Order.java @@ -30,6 +30,12 @@ public class Order implements Serializable { private String openid; // 患者id private String patientId; + // 患者姓名 + private String patientName; + // 患者信息 + private String idCardNo; + private String sex; + private String birthday; // 订单号 private String outTradeNo; // 银行交易流水号 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 511caae..1504a5a 100644 --- a/src/main/java/com/ynxbd/common/config/interceptor/MethodInterceptor.java +++ b/src/main/java/com/ynxbd/common/config/interceptor/MethodInterceptor.java @@ -5,6 +5,7 @@ import com.opensymphony.xwork2.ActionInvocation; import com.ynxbd.common.helper.common.ErrorHelper; import com.ynxbd.common.helper.common.JsonHelper; import com.ynxbd.common.result.Result; +import com.ynxbd.common.result.struts2.BaseResult; import org.apache.commons.lang3.ObjectUtils; import org.apache.struts2.interceptor.ServletConfigInterceptor; @@ -48,6 +49,11 @@ public class MethodInterceptor extends ServletConfigInterceptor { continue; } + if (HttpServletRequest.class.getSimpleName().equals(simpleName)) { + params.add(request); + continue; + } + initials = simpleName.substring(0, 1); if (initials.equals(initials.toUpperCase()) && ObjectUtils.isEmpty(value)) { // 大写 params.add(null); @@ -80,6 +86,7 @@ public class MethodInterceptor extends ServletConfigInterceptor { case "double": params.add(Double.valueOf(value)); + break; default: params.add(null); @@ -96,7 +103,7 @@ public class MethodInterceptor extends ServletConfigInterceptor { return "SUCCESS"; } - if (Result.class == invoke.getClass()) { + if (Result.class == invoke.getClass() || com.ynxbd.common.result.struts2.BaseResult.class == invoke.getClass().getSuperclass()) { respJson(context.getServletResponse(), action, invoke); } return "SUCCESS"; diff --git a/src/main/java/com/ynxbd/common/dao/PWEReportDao.java b/src/main/java/com/ynxbd/common/dao/PWEReportDao.java new file mode 100644 index 0000000..e0a85fa --- /dev/null +++ b/src/main/java/com/ynxbd/common/dao/PWEReportDao.java @@ -0,0 +1,60 @@ +package com.ynxbd.common.dao; + + +import com.ynxbd.common.bean.pay.Register; +import com.ynxbd.common.config.db.DataBase; +import com.ynxbd.wx.pwe.bean.PWEReport; + +public class PWEReportDao { + + public boolean insert(PWEReport report) { + String sql = "insert into pwe_report(createTime, updateTime, hospitalId, dataJson, registerId) values (now(), now(), ?, ?, ?)"; + return DataBase.insert(sql, ps -> { + ps.setString(1, report.getHospitalId()); + ps.setString(2, report.getDataJson()); + ps.setString(3, report.getRegisterId()); + }) > 0; + } + + public boolean update(PWEReport report) { + String sql = "update pwe_report set dataJson = ?, updateTime = now() where registerId = ?"; + return DataBase.insert(sql, ps -> { + ps.setString(1, report.getDataJson()); + ps.setString(2, report.getRegisterId()); + }) > 0; + } + + public PWEReport selectByRegId(String registerId) { + String sql = "select * from pwe_report where registerId = ?"; + return DataBase.selectOne(sql, PWEReport.class, ps -> { + ps.setString(1, registerId); + }); + } + + + /** + * 查询订单信息 + * + * @param outTradeNo 订单号 + */ + public Register selectRegOrderInfo(String outTradeNo) { + String sql = "select r.idCardNo, r.deptCode, r.deptName, r.doctCode, r.doctName, r.outTradeNo, r.bankTransNo, r.tradeNo, p.name as patientName, p.sex, p.birthday" + + " from register as r left join patientBase as p on (r.patientId = p.patientId and r.openid = p.openid)" + + " where r.outTradeNo = ?"; + return DataBase.selectOne(sql, Register.class, ps -> { + ps.setString(1, outTradeNo); + }); + } + + /** + * 查询订单号 + * + * @param tradeNo 订单号 + */ + public Register selectRegOrderNo(String tradeNo) { + String sql = "select deptCode, deptName, doctCode, doctName, outTradeNo, bankTransNo, tradeNo from register where tradeNo = ?"; + return DataBase.selectOne(sql, Register.class, ps -> { + ps.setString(1, tradeNo); + }); + } +} diff --git a/src/main/java/com/ynxbd/common/helper/common/URLHelper.java b/src/main/java/com/ynxbd/common/helper/common/URLHelper.java new file mode 100644 index 0000000..66144c5 --- /dev/null +++ b/src/main/java/com/ynxbd/common/helper/common/URLHelper.java @@ -0,0 +1,44 @@ +package com.ynxbd.common.helper.common; + +import java.util.HashMap; +import java.util.Map; + +public class URLHelper { + + @FunctionalInterface + public interface MapFun { + void setParams(Map map); + } + + + /** + * map转url + * + * @param map map + * @param isPrefix 是否有前缀 + * @return string + */ + public static String mapToUrl(MapFun map, boolean isPrefix) { + Map params = new HashMap<>(); + if (map == null) { + return ""; + } + + map.setParams(params); + StringBuilder sb = new StringBuilder(); + for (Map.Entry item : params.entrySet()) { + Object value = item.getValue(); + sb.append("&").append(item.getKey()).append("=").append(value == null ? "" : value); + } + sb.replace(0, 1, ""); + return (isPrefix ? "?" : "") + sb; + } + + public static void main(String[] args) { + String s = mapToUrl(map -> { + map.put("a", 2); + map.put("b", 1); + }, true); + System.out.println(s); + } +} diff --git a/src/main/java/com/ynxbd/common/helper/http/OkHttpHelper.java b/src/main/java/com/ynxbd/common/helper/http/OkHttpHelper.java index ed57d39..1881a1c 100644 --- a/src/main/java/com/ynxbd/common/helper/http/OkHttpHelper.java +++ b/src/main/java/com/ynxbd/common/helper/http/OkHttpHelper.java @@ -11,6 +11,8 @@ import com.ynxbd.wx.wxfactory.utils.XmlHelper; import lombok.extern.slf4j.Slf4j; import okhttp3.*; +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedReader; import java.io.IOException; import java.net.URL; import java.util.HashMap; @@ -319,4 +321,34 @@ public class OkHttpHelper { } + /** + * 读取request中的body数据 + * + * @param request 请求体 + */ + public static JSONObject readBody(HttpServletRequest request) { + BufferedReader br = null; + try { + br = request.getReader(); + String line; + StringBuilder sb = new StringBuilder(); + while ((line = br.readLine()) != null) { + sb.append(line); + } + return JsonHelper.parseObject(sb.toString()); + } catch (Exception e) { + log.error(e.getMessage()); + } finally { + try { + if (br != null) { + br.close(); + } + } catch (Exception e) { + log.error(e.getMessage()); + } + } + return null; + } + + } diff --git a/src/main/java/com/ynxbd/common/result/struts2/BaseResult.java b/src/main/java/com/ynxbd/common/result/struts2/BaseResult.java index 23d268e..82b157d 100644 --- a/src/main/java/com/ynxbd/common/result/struts2/BaseResult.java +++ b/src/main/java/com/ynxbd/common/result/struts2/BaseResult.java @@ -3,17 +3,13 @@ package com.ynxbd.common.result.struts2; import com.opensymphony.xwork2.ActionInvocation; import com.ynxbd.common.helper.common.JsonHelper; import com.ynxbd.common.result.Result; -import com.ynxbd.wx.wxfactory.utils.XmlHelper; import org.apache.struts2.ServletActionContext; -import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; public class BaseResult implements com.opensymphony.xwork2.Result { diff --git a/src/main/java/com/ynxbd/wx/pwe/PWEConfig.java b/src/main/java/com/ynxbd/wx/pwe/PWEConfig.java new file mode 100644 index 0000000..e022474 --- /dev/null +++ b/src/main/java/com/ynxbd/wx/pwe/PWEConfig.java @@ -0,0 +1,39 @@ +package com.ynxbd.wx.pwe; + +import com.ynxbd.common.helper.ProperHelper; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PWEConfig { + + public static final String PARTNER_ID; + public static final String PARTNER_SECRET; // 合作方密钥 + public static final String HOSPITAL_ID; // 医院ID + public static final String SECRET_KEY; // 私钥 + // + public static final boolean IS_DEV; + + static { + ProperHelper config = new ProperHelper().read("pwe.properties"); + + boolean isEnable = config.getBoolean("pwe.is_enable", false); + if (isEnable) { + IS_DEV = config.getBoolean("pwe.is_dev", false); + + HOSPITAL_ID = config.getString("pwe.hospital_id"); + PARTNER_ID = config.getString("pwe.partner_id"); + PARTNER_SECRET = config.getString(IS_DEV ? "pwe.dev.partner_secret" : "pwe.partner_secret"); + SECRET_KEY = config.getString(IS_DEV ? "pwe.dev.secret_key" : "pwe.secret_key"); + } else { + IS_DEV = false; + HOSPITAL_ID = null; + PARTNER_ID = null; + PARTNER_SECRET = null; + SECRET_KEY = null; + } + if (PARTNER_ID == null || PARTNER_SECRET == null) { + log.error("[预问诊]读取配置文件pwe.properties失败"); + } + } + +} diff --git a/src/main/java/com/ynxbd/wx/pwe/PWEHelper.java b/src/main/java/com/ynxbd/wx/pwe/PWEHelper.java new file mode 100644 index 0000000..7bea430 --- /dev/null +++ b/src/main/java/com/ynxbd/wx/pwe/PWEHelper.java @@ -0,0 +1,265 @@ +package com.ynxbd.wx.pwe; + +import com.alibaba.fastjson.JSONObject; +import com.ynxbd.common.helper.common.CodeHelper; +import com.ynxbd.common.helper.common.JsonHelper; +import com.ynxbd.common.helper.common.URLHelper; +import com.ynxbd.common.helper.http.OkHttpHelper; +import com.ynxbd.common.result.ServiceException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedReader; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +public class PWEHelper { + /** + * [患者端]8.1.获取打开小程序短链 + * + * @param registerId 挂号ID(订单号) + */ + public static String getMiniPWEUrl(String registerId) throws ServiceException { + log.info("[患者端]8.1.获取打开小程序短链 registerId={}", registerId); + String url = PWEConfig.IS_DEV + ? "https://med-biz-pre.wecity.qq.com/api/prediagnosis/getUrlLink/" + : "https://med-biz.wecity.qq.com/api/prediagnosis/getUrlLink/"; + + Map data = new HashMap<>(); + data.put("registered_id", registerId); + + Map header = new HashMap<>(); + header.put("hospital_id", PWEConfig.HOSPITAL_ID); + + url = url + PWEConfig.PARTNER_ID; + log.info("[8.1.获取打开小程序短链]req url={} {data={},header={}}", url, data, header); + JSONObject resultJson = post(url, params -> { + params.put("data", data); + params.put("header", header); + }, null); + String code = resultJson.getString("retcode"); + String message = resultJson.getString("retmsg"); + String reqId = resultJson.getString("request_id"); + log.info("[8.1.获取打开小程序短链]resp=[{}]", resultJson); + if (!"0".equals(code)) { + log.error("[8.1.获取打开小程序短链]失败[reqId:{}] code={}, message={}", reqId, code, message); + throw new ServiceException(message); + } + JSONObject dataJson = resultJson.getJSONObject("data"); + if (dataJson == null) { + throw new ServiceException("[8.1.获取打开小程序短链]data返回为空"); + } + String urlLink = dataJson.getString("url_link"); + log.info("[8.1.获取打开小程序短链][reqId:{}] urlLink=[{}]", reqId, urlLink); + if (ObjectUtils.isEmpty(urlLink)) { + throw new ServiceException("[8.1.获取打开小程序短链]获取到的链接为空"); + } + return urlLink; + + } + + + /** + * [患者端]获取预问诊h5链接 [线上挂号场景:适用场景:经由合作方页面挂号后,需要在医生问诊前进行预问诊,提供带挂号 ID 的 URL 供用户访问。] + * + * @param registerId 挂号ID(商户订单号) + */ + public static String getH5PWEUrl(String registerId) { + log.info("[患者端]获取预问诊h5链接 registerId={}", registerId); + String registerIdSign = toHmacSha256Example(PWEConfig.SECRET_KEY, (PWEConfig.HOSPITAL_ID + registerId)); + if (ObjectUtils.isEmpty(registerIdSign)) { + log.error("签名失败"); + } + String params = URLHelper.mapToUrl(map -> { + map.put("partnerId", PWEConfig.PARTNER_ID); + map.put("hospitalId", PWEConfig.HOSPITAL_ID); + map.put("registerId", registerId); + map.put("registerIdSign", registerIdSign); + }, true); + + String url = PWEConfig.IS_DEV + ? "https://dev-prediagnosis.wecity.qq.com/guide-h5-prediagnosis/pages/prediagnosis" + : "https://miying.qq.com/guide-h5-prediagnosis/pages/prediagnosis"; + return url + params; + } + + + /** + * [医生端]获取预问诊报告链接 + */ + public static String getPWEReportUrl(String departmentId, String doctorId, String doctorName, String registeredId) throws ServiceException { + String token = getPWEHisToken(doctorId, doctorName); + String params = URLHelper.mapToUrl(map -> { + map.put("token", token); + map.put("registeredId", registeredId); + map.put("departmentId", departmentId); + map.put("doctorId", doctorId); + }, true); + + String url = PWEConfig.IS_DEV + ? "https://dev-aimedical.wecity.qq.com/toolbox/prediagnosis.html" + : "https://aimedical.wecity.qq.com/toolbox/prediagnosis.html"; + return url + params; + } + + + /** + * 7.2.1 通过 HisToolLoginIn 接口获取 token + */ + private static String getPWEHisToken(String doctorId, String doctorName) throws ServiceException { + String url = PWEConfig.IS_DEV + ? "https://dev-aimedical.wecity.qq.com/cgi-bin/v1/Diagnosis/RationalDrugServer/RationalDrugServant/HisToolLogin" + : "https://aimedical.wecity.qq.com/cgi-bin/v1/Diagnosis/RationalDrugServer/RationalDrugServant/HisToolLogin"; + + Map data = new HashMap<>(); + data.put("partner_id", PWEConfig.PARTNER_ID); + data.put("doctor_id", doctorId); + data.put("doctor_name", doctorName); + + Map header = new HashMap<>(); + header.put("hospital_id", PWEConfig.HOSPITAL_ID); + + JSONObject resultJson = post(url, params -> { + params.put("data", data); + params.put("header", header); + }, null); + + String code = resultJson.getString("retcode"); + String message = resultJson.getString("retmsg"); + String reqId = resultJson.getString("request_id"); + if (!"0".equals(code)) { + log.error("[HisToolLoginIn 获取 token]失败[rid:{}] code={}, message={}", reqId, code, message); + throw new ServiceException(message); + } + JSONObject dataJson = resultJson.getJSONObject("data"); + if (dataJson == null) { + throw new ServiceException("[HisToolLoginIn 获取 token]data返回为空"); + } + String token = dataJson.getString("token"); + String expiresIn = dataJson.getString("expires_in"); + log.info("[HisToolLoginIn 获取 token][rid:{}] token=[{}] expires_in={}", reqId, token, expiresIn); + if (ObjectUtils.isEmpty(token)) { + throw new ServiceException("[HisToolLoginIn 获取 token]token为空"); + } + return token; + } + +// public static void post(String url, OkHttpHelper.MapParams params) { +// String timestamp = String.valueOf(System.currentTimeMillis()); +// JsonResult jsonResult = OkHttpHelper.postJson(url, params, headers -> { +// headers.add("god-portal-signature", toHmacSha256Example(PWEConfig.PARTNER_SECRET, (PWEConfig.PARTNER_ID + timestamp))); +// headers.add("god-portal-timestamp", timestamp); +// headers.add("god-portal-request-id", CodeHelper.get32UUID()); +// }, JsonResultEnum.SYS_RES_ONLINE); +// System.out.println(JsonHelper.toJsonString(jsonResult)); +// } + + public static JSONObject post(String url, OkHttpHelper.MapParams params, OkHttpHelper.Header header) { + String timestamp = String.valueOf(System.currentTimeMillis()); + return OkHttpHelper.postJson(url, params, headers -> { + headers.add("god-portal-signature", toHmacSha256Example(PWEConfig.PARTNER_SECRET, (PWEConfig.PARTNER_ID + timestamp))); + headers.add("god-portal-timestamp", timestamp); + headers.add("god-portal-request-id", CodeHelper.get32UUID()); + }); + } + + public static void main(String[] args) { +// getUrl(); +// System.out.println(System.currentTimeMillis()); +// +// post("http://127.0.0.1:9090/micro/test_q/post_json", map -> { +// map.put("a", "1"); +// map.put("b", "1"); +// }); +// + + String timestamp = String.valueOf(System.currentTimeMillis()); + String sign = PWEHelper.toHmacSha256Example(PWEConfig.PARTNER_SECRET, (PWEConfig.PARTNER_ID + timestamp)); + log.info("timestamp={}, sign={}, uuid={}", timestamp, sign, CodeHelper.get32UUID()); + } +// +// public static void main(String[] args) { +// +// } + + + /** + * 签名验证 + */ + public static JSONObject verifySign(HttpServletRequest req, boolean isVerifyHospitalId) throws Exception { + String signature = req.getHeader("god-portal-signature"); + String timestamp = req.getHeader("god-portal-timestamp"); + String requestId = req.getHeader("god-portal-request-id"); + log.info("[ID:{}]-[T:{}]-[S:{}]", requestId, timestamp, signature); + if (ObjectUtils.isEmpty(signature)) { + throw new ServiceException("signature前面缺失"); + } + + if (ObjectUtils.isEmpty(timestamp)) { + throw new ServiceException("timestamp"); + } + + if (ObjectUtils.isEmpty(requestId)) { + throw new ServiceException("requestId"); + } + + // 用于验证的签名 + String sysSign = PWEHelper.toHmacSha256Example(PWEConfig.PARTNER_SECRET, (PWEConfig.PARTNER_ID + timestamp)); + log.error("sysSign={}", sysSign); + if (ObjectUtils.isEmpty(sysSign)) { + throw new ServiceException("系统内部签名生成失败"); + } + if (!sysSign.equals(signature)) { + throw new ServiceException("签名验证失败"); + } + + JSONObject body = OkHttpHelper.readBody(req); + if (body == null) { + throw new Exception("post body is null"); + } + String hospitalId = body.getString("hospitalId"); + String registeredId = body.getString("registeredId"); + log.info("[预问诊]挂号查询 hospitalId={}, registeredId={}", hospitalId, registeredId); + + if (isVerifyHospitalId) { + if (ObjectUtils.isEmpty(hospitalId) || !hospitalId.equals(PWEConfig.HOSPITAL_ID)) { + throw new ServiceException("医院ID不匹配"); + } + } + + if (ObjectUtils.isEmpty(registeredId)) { + throw new ServiceException("挂号ID为空"); + } + return body; + } + + /** + * @param secretKey 密钥 + * @param data 数据 + */ + public static String toHmacSha256Example(String secretKey, String data) { + try { + // 创建一个HmacSHA256密钥 + SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); + // 获取Mac对象来执行HMAC-SHA256 + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(secretKeySpec); + // 执行HMAC-SHA256计算 + byte[] hmacBytes = mac.doFinal(data.getBytes()); + // 将计算出来的HMAC值转换为十六进制字符串 + StringBuilder sb = new StringBuilder(); + for (byte b : hmacBytes) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } catch (Exception e) { + log.error(e.getMessage()); + } + return ""; + } +} diff --git a/src/main/java/com/ynxbd/wx/pwe/bean/PWERegister.java b/src/main/java/com/ynxbd/wx/pwe/bean/PWERegister.java new file mode 100644 index 0000000..20d32bd --- /dev/null +++ b/src/main/java/com/ynxbd/wx/pwe/bean/PWERegister.java @@ -0,0 +1,47 @@ +package com.ynxbd.wx.pwe.bean; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import org.apache.commons.lang3.ObjectUtils; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +@Getter +@Setter +@ToString +@NoArgsConstructor +public class PWERegister implements Serializable { + private static final long serialVersionUID = 20240328165610001L; + + // *挂号 Id + public String registeredId; + // 患者自述 + public String query; + + // *年龄 + public Integer age; + // *性别 (0 男 1 女) + public Integer sex; + // 姓名 + public String name; + // 科室 + public List departments; + // 科室Ids + public List departmentIds; + + public String doctorId; + + public String doctorName; + + public List getStrList(String val){ + List dataList = new ArrayList<>(); + if (!ObjectUtils.isEmpty(val)) { + dataList.add(val); + } + return dataList; + } +} diff --git a/src/main/java/com/ynxbd/wx/pwe/bean/PWEReport.java b/src/main/java/com/ynxbd/wx/pwe/bean/PWEReport.java new file mode 100644 index 0000000..4f304fd --- /dev/null +++ b/src/main/java/com/ynxbd/wx/pwe/bean/PWEReport.java @@ -0,0 +1,21 @@ +package com.ynxbd.wx.pwe.bean; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +import java.util.Date; + +@Getter +@Setter +@ToString +@NoArgsConstructor +public class PWEReport { + private Long id; + private String registerId; + private String hospitalId; + private Date updateTime; + private Date createTime; + private String dataJson; +} diff --git a/src/main/java/com/ynxbd/wx/pwe/bean/PWEResult.java b/src/main/java/com/ynxbd/wx/pwe/bean/PWEResult.java new file mode 100644 index 0000000..8cb9789 --- /dev/null +++ b/src/main/java/com/ynxbd/wx/pwe/bean/PWEResult.java @@ -0,0 +1,71 @@ +package com.ynxbd.wx.pwe.bean; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.ynxbd.common.result.Result; +import com.ynxbd.common.result.struts2.BaseResult; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; + +/** + * @author wsq + * @date 2020/7/16 13:26 + * @copyright @ 2020 云南新八达科技有限公司 All rights reserved. + */ +@Getter +@Setter +@ToString +@Slf4j +@JsonInclude(JsonInclude.Include.NON_NULL) +public class PWEResult extends BaseResult implements Serializable { + private static final long serialVersionUID = 2024032800400001L; + + private Integer code; + private String message; + private Object data; + private Integer state; // 状态值,供给第三方接口使用 + + private PWEResult() { + } + + /** + * 请求成功 + */ + public static PWEResult success(Object data) { + PWEResult r = new PWEResult(); + r.code = 0; + r.message = "成功"; + r.data = data; + return r; + } + + /** + * 请求成功-不携带数据 + */ + public static PWEResult success() { + return success(null); + } + + public static PWEResult error(String message) { + PWEResult r = new PWEResult(); + r.code = -1; + r.message = message; + return r; + } + + public static PWEResult error(Exception e) { + String message; + if (e == null) { + message = "未知异常"; + } else { + message = e.getMessage(); + if (message == null && e instanceof java.lang.NullPointerException) { + message = "系统异常null"; + } + } + return error(message); + } +} diff --git a/src/main/resources/dev/druid-config.properties b/src/main/resources/dev/druid-config.properties new file mode 100644 index 0000000..196d750 --- /dev/null +++ b/src/main/resources/dev/druid-config.properties @@ -0,0 +1,30 @@ +# mysql\u4E3B\u6570\u636E\u5E93============================================================= +master.driverClassName=com.mysql.jdbc.Driver +master.jdbcUrl=jdbc:mysql://127.0.0.1:3306/ynxbd_wx?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true&allowMultiQueries=true +#master.jdbcUrl=jdbc:mariadb://192.168.12.102:3306/ynxbd_wx?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true&allowMultiQueries=true +master.username=root +master.password=1234 +## \u8FDE\u63A5\u6C60\u6570 +master.minIdle=4 +master.maxActive=16 +master.initialSize=2 +# +# +# lis\u6570\u636E\u5E93================================================================== +lis.driverclassname=com.microsoft.sqlserver.jdbc.sqlserverdriver +lis.jdbcUrl=jdbc:sqlserver://200.200.200.251:1433;databasename=lisdb +lis.username=sa +lis.password=sixflag +## \u8FDE\u63A5\u6C60\u6570 +lis.minidle=4 +lis.maxactive=8 +lis.initialsize=2 + + +pacs.driverclassname=com.microsoft.sqlserver.jdbc.sqlserverdriver +pacs.jdbcurl=jdbc:sqlserver://192.168.1.112:1433;databasename=ris_basic +pacs.username=his_interface +pacs.password=his_interface +pacs.minidle=4 +pacs.maxactive=8 +pacs.initialsize=2 \ No newline at end of file diff --git a/src/main/resources/druid-config.properties b/src/main/resources/druid-config.properties index 1784861..573be16 100644 --- a/src/main/resources/druid-config.properties +++ b/src/main/resources/druid-config.properties @@ -1,21 +1,21 @@ -# mysql主数据库============================================================= +# mysql\u4E3B\u6570\u636E\u5E93============================================================= master.driverClassName=com.mysql.jdbc.Driver master.jdbcUrl=jdbc:mysql://127.0.0.1:3306/ynxbd_wx?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true&allowMultiQueries=true #master.jdbcUrl=jdbc:mariadb://192.168.12.102:3306/ynxbd_wx?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true&allowMultiQueries=true master.username=root -master.password=toor -## 连接池数 +master.password=1234 +## \u8FDE\u63A5\u6C60\u6570 master.minIdle=4 master.maxActive=16 master.initialSize=2 # # -# lis数据库================================================================== +# lis\u6570\u636E\u5E93================================================================== lis.driverclassname=com.microsoft.sqlserver.jdbc.sqlserverdriver lis.jdbcUrl=jdbc:sqlserver://200.200.200.251:1433;databasename=lisdb lis.username=sa lis.password=sixflag -## 连接池数 +## \u8FDE\u63A5\u6C60\u6570 lis.minidle=4 lis.maxactive=8 lis.initialsize=2 diff --git a/src/main/resources/pwe.properties b/src/main/resources/pwe.properties new file mode 100644 index 0000000..22e1ffc --- /dev/null +++ b/src/main/resources/pwe.properties @@ -0,0 +1,11 @@ +# \u817E\u8BAF\u9884\u95EE\u8BCA\u914D\u7F6E +pwe.is_enable=true +pwe.is_dev=true +pwe.partner_id=100000317 +pwe.partner_secret=795b207e12572839976d9310bdde32be +pwe.hospital_id=800001119 +pwe.secret_key=ZLU6bW&x#%k@2kxW + +# dev================== +pwe.dev.partner_secret=ad99d34eb89b5fb517380ff4745ada1e +pwe.dev.secret_key=P*HEi#aNN8hJ6*EA diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 26c71a8..ab3d076 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -22,5 +22,4 @@ struts2 * -