1、医共体认证调整

2、体检预约接口逻辑存在问题,重新设计,接口请求封装。
3、体检预约接口新增限制,如果没有配置请求链接时,禁止下单。
debug
王绍全 2 days ago
parent 70fbcfefe3
commit 3b61627b61
  1. 56
      src/main/java/com/ynxbd/common/TestA.java
  2. 16
      src/main/java/com/ynxbd/common/action/RecipeAction.java
  3. 4
      src/main/java/com/ynxbd/common/action/XBDAction.java
  4. 2
      src/main/java/com/ynxbd/common/action/pay/NotifyAction.java
  5. 17
      src/main/java/com/ynxbd/common/action/pay/PEnum.java
  6. 156
      src/main/java/com/ynxbd/common/action/pay/PayAction.java
  7. 4
      src/main/java/com/ynxbd/common/action/pay/WxAuthAction.java
  8. 2
      src/main/java/com/ynxbd/common/action/pay/WxPayAction.java
  9. 15
      src/main/java/com/ynxbd/common/action/test/TestAction.java
  10. 25
      src/main/java/com/ynxbd/common/action/weihu/DataWHAction.java
  11. 13
      src/main/java/com/ynxbd/common/bean/pay/Order.java
  12. 47
      src/main/java/com/ynxbd/common/bean/pay/PEISOrderInfo.java
  13. 25
      src/main/java/com/ynxbd/common/bean/pay/PEISReserve.java
  14. 4
      src/main/java/com/ynxbd/common/dao/his/HisRegisterDao.java
  15. 114
      src/main/java/com/ynxbd/common/dao/peis/PEISDao.java
  16. 116
      src/main/java/com/ynxbd/common/dao/peis/PeisDao.java
  17. 16
      src/main/java/com/ynxbd/common/helper/common/HttpHelper.java
  18. 74
      src/main/java/com/ynxbd/common/helper/http/OkHttpHelper.java
  19. 1
      src/main/java/com/ynxbd/common/helper/xbd/XBDHelper.java
  20. 24
      src/main/java/com/ynxbd/common/result/JsonResult.java
  21. 4
      src/main/java/com/ynxbd/common/result/JsonResultEnum.java
  22. 282
      src/main/java/com/ynxbd/common/service/PEISService.java
  23. 14
      src/main/java/com/ynxbd/common/service/PayService.java
  24. 221
      src/main/java/com/ynxbd/common/service/PeisService.java
  25. 2
      src/main/java/com/ynxbd/common/service/RecipeService.java
  26. 2
      src/main/java/com/ynxbd/common/service/RegService.java
  27. 15
      src/main/java/com/ynxbd/common/service/Test.java
  28. 33
      src/main/java/com/ynxbd/wx/servlet/test/RefundTestServlet.java
  29. 27
      src/main/java/com/ynxbd/wx/servlet/test/WxIsAuthServlet.java
  30. 106
      src/main/java/com/ynxbd/wx/wxfactory/WxAuthHelper.java
  31. 40
      src/main/java/com/ynxbd/wx/wxfactory/WxCacheHelper.java

@ -1,13 +1,61 @@
package com.ynxbd.common;
import com.alibaba.fastjson.JSONObject;
import com.ynxbd.common.bean.pay.PEISOrderInfo;
import com.ynxbd.common.helper.common.Base64Helper;
import com.ynxbd.common.helper.common.JsonHelper;
import com.ynxbd.common.helper.http.OkHttpHelper;
import com.ynxbd.common.result.JsonResult;
import com.ynxbd.common.result.Result;
import com.ynxbd.wx.config.WeChatConfig;
import com.ynxbd.wx.utils.DesEncryptHelper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.apache.commons.lang3.ObjectUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
@Slf4j
public class TestA {
public static void main(String[] args) throws UnsupportedEncodingException {
// String a = "";
// String s = DesEncryptHelper.deCode(a);
// System.out.println(s);
// RequestBody requestBody = new FormBody.Builder()
// .add("token", "")
// .add("state", "aHR0cCUzQSUyRiUyRnNseGxmd3N5LnNseHJteXkuY24lMkZ3eCUyRndlYiUyRnJlZy1yZXNlcnZlLmh0bWwlMjMlMkY=")
// .add("isUserInfo", "false")
// .add("enuId", "false")
// .add("protocolState", "0")
// .build();
// log.info("[认证请求转发] resp:[{}]", requestBody);
// log.info("[认证请求转发] resp:[{}]", JsonHelper.toJsonString(requestBody));
// String data = OkHttpHelper.postFormStr("http://slxlfwsy.slxrmyy.cn/wx/wx_auth/is_auth", map -> {
// map.put("token", null);
// map.put("state", "aHR0cCUzQSUyRiUyRnNseGxmd3N5LnNseHJteXkuY24lMkZ3eCUyRndlYiUyRnJlZy1yZXNlcnZlLmh0bWwlMjMlMkY=");
// map.put("isUserInfo", false);
// map.put("enuId", false);
// map.put("protocolState", 0);
// }, null);
// String data = OkHttpHelper.post("http://www.slxrmyy.cn/wx/wx_auth/is_auth", requestBody);
// JSONObject jsonObject = JsonHelper.parseObject(data);
// System.out.println(JsonHelper.toJsonString(jsonObject));
//
// String state = "aHR0cCUzQSUyRiUyRnNseGxmd3N5LnNseHJteXkuY24lMkZ3eCUyRndlYiUyRnJlZy1yZXNlcnZlLmh0bWwlMjMlMkY=";
// String decode = URLDecoder.decode(Base64Helper.decode(state), "UTF-8");
// System.out.println(decode);
public static void main(String[] args) {
String a = "";
String s = DesEncryptHelper.deCode(a);
System.out.println(s);
}
}

@ -5,12 +5,12 @@ import com.ynxbd.common.bean.HisRecipe;
import com.ynxbd.common.bean.NatRecord;
import com.ynxbd.common.bean.Patient;
import com.ynxbd.common.bean.enums.MerchantEnum;
import com.ynxbd.common.bean.pay.Recipe;
import com.ynxbd.common.bean.pay.PEISReserve;
import com.ynxbd.common.config.interceptor.AesDecode;
import com.ynxbd.common.dao.NatRecordDao;
import com.ynxbd.common.dao.PatientDao;
import com.ynxbd.common.dao.his.HisRecipeDao;
import com.ynxbd.common.dao.peis.PeisDao;
import com.ynxbd.common.dao.peis.PEISDao;
import com.ynxbd.common.helper.common.DateHelper;
import com.ynxbd.common.helper.his.HisEnum;
import com.ynxbd.common.helper.his.HisHelper;
@ -201,12 +201,12 @@ public class RecipeAction extends BaseAction {
if ("".equals(treatNum) || "".equals(outTranNo)) {
return Result.error(ResultEnum.PARAM_IS_DEFECT);
}
Recipe recipe = new PeisDao().selectByOutTradeNo(outTranNo);
if (recipe == null) {
PEISReserve peisReserve = new PEISDao().selectByOutTradeNo(outTranNo);
if (peisReserve == null) {
return Result.error(ResultEnum.DATA_NOT_FOUND);
}
if (!recipe.getBankTransNo().equals(bankTransNo)) {
log.info("[体检预约请求his计费]体检系统跟微信支付系统两笔订单不一致,体检系统:bankTransNo-{},微信系统:bankTransNo-{}", bankTransNo, recipe.getBankTransNo());
if (!peisReserve.getBankTransNo().equals(bankTransNo)) {
log.info("[体检预约请求his计费]体检系统跟微信支付系统两笔订单不一致,体检系统:bankTransNo-{},微信系统:bankTransNo-{}", bankTransNo, peisReserve.getBankTransNo());
return Result.error(ResultEnum.DATA_IS_WRONG);
}
Map<String, Object> params = new HashMap<>();
@ -217,11 +217,11 @@ public class RecipeAction extends BaseAction {
params.put("PayMoney", payMoney);
params.put("PayDate", payDate);
params.put("PayTime", payTime);
params.put("TransNo", recipe.getTradeNo());
params.put("TransNo", peisReserve.getTradeNo());
params.put("PayDeviceID", "app");
params.put("PayWay", MerchantEnum.WX.HIS_PAY_WAY);
params.put("BankTransNo", bankTransNo); // 商户订单号
params.put("OpenId", recipe.getOpenid());
params.put("OpenId", peisReserve.getOpenid());
params.put("Token", WeChatConfig.TOKEN);
JsonResult result = HisHelper.getJsonResult(HisEnum.AP_Pay_Invoice, params);
return result.success() ? Result.success(result) : Result.error(result.getMessage());

@ -17,7 +17,7 @@ import com.ynxbd.common.result.Result;
import com.ynxbd.common.result.ResultEnum;
import com.ynxbd.common.result.ServiceException;
import com.ynxbd.common.service.CasebookService;
import com.ynxbd.common.service.PeisService;
import com.ynxbd.common.service.PEISService;
import com.ynxbd.common.service.XBDService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
@ -293,7 +293,7 @@ public class XBDAction extends BaseAction {
return Result.error(ResultEnum.PARAM_IS_INVALID);
}
try {
JSONArray dataList = new PeisService().getPeisByCardNo(encode, begDate, endDate);
JSONArray dataList = new PEISService().queryPEISRecordByCardNo(encode, begDate, endDate);
for (int i = 0; i < dataList.size(); i++) {
JSONObject dataItem = dataList.getJSONObject(i);
String eid = dataItem.getString("eid");

@ -32,7 +32,7 @@ public class NotifyAction extends BaseAction {
WxPayNotify notifyInfo = WxPayHelper.payNotify(request);
Result.respXml(WxRespHelper.respOk()); // 收到请求-解析成功
PayService.WxNotify(notifyInfo);
PayService.wxNotify(notifyInfo);
} catch (ServiceException e) {
Result.respXml(WxRespHelper.resp(e)); // 收到请求-解析失败
}

@ -22,8 +22,7 @@ public enum PEnum {
TPP_QR_REG("第三方-扫码挂号", "tpp_qr_reg", "G"),
PEIS_RESERVE("体检预约", "peis_reserve", "P"),
PEIS_RESERVE("体检预约", "peis_reserve", "PR"),
;
public final String NAME;
@ -49,6 +48,20 @@ public enum PEnum {
return transNo + this.ORDER_CODE;
}
public static String getTradeNo(String prefix, PEnum pEnum) {
if (pEnum == null) {
return null;
}
int len = pEnum.ORDER_CODE.length();
if (len == 1) {
return prefix + pEnum.ORDER_CODE.toUpperCase() + "001";
}
if (len == 2) {
return prefix + pEnum.ORDER_CODE.toUpperCase() + "01";
}
return prefix + pEnum.ORDER_CODE.toUpperCase();
}
/**
* 根据订单号获取类型
*

@ -9,10 +9,10 @@ import com.ynxbd.common.bean.enums.MerchantEnum;
import com.ynxbd.common.bean.pay.*;
import com.ynxbd.common.dao.SelfHelpDao;
import com.ynxbd.common.dao.his.HisRecipeDao;
import com.ynxbd.common.dao.peis.PeisDao;
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.result.JsonResult;
import com.ynxbd.common.result.Result;
import com.ynxbd.common.result.ResultEnum;
@ -57,7 +57,7 @@ public class PayAction extends BaseAction {
String ip = HttpHelper.getIpAddress(request);
return new RegService().regPlaceOrder(payCode, ip, isOccupySource, isZeroPay, reg, isHttpsWithProxy());
return new RegService().createRegOrder(payCode, ip, isOccupySource, isZeroPay, reg, isHttpsWithProxy());
} catch (ServiceException e) {
return Result.error(e);
}
@ -130,74 +130,6 @@ public class PayAction extends BaseAction {
}
/**
* @param openid openid
* @param patientId 患者id
* @param treatNum 体检号
* @param totalFee 总金额
* @param recipeId 处方号
* @param payCode 支付方式
*/
@Action("PeisPay")
public Result PeisPay(String openid, String patientId, String treatNum, String totalFee, String recipeId, String payCode) {
if (openid == null || patientId == null || treatNum == null || totalFee == null || recipeId == null) {
return Result.error(ResultEnum.PARAM_IS_DEFECT);
}
if (new BigDecimal(totalFee).compareTo(BigDecimal.ZERO) == 0) {
return Result.error(ResultEnum.PAY_MONEY_IS_ZERO);
}
MerchantEnum merchantEnum = MerchantEnum.findEnumByCode(payCode);
if (merchantEnum == null) { // 支付方式异常
return Result.error(ResultEnum.PAY_TYPE_ERROR);
}
String outTradeNo = CodeHelper.getOutTradeNo(merchantEnum);
PeisService peisService = new PeisService();
if (!peisService.Reserve(openid, patientId, treatNum, outTradeNo, totalFee, recipeId)) {
log.info("{} [体检预约]体检预约信息保存失败 patientId={},recipeId-{}", merchantEnum.NAME, patientId, recipeId);
return Result.error(ResultEnum.SPECIFIED_QUESTIONED_USER_NOT_EXIST);
}
String ip = request.getRemoteAddr();
String body = "体检预约 患者:" + patientId + "\n体检号:" + treatNum + "\n订单号:" + recipeId;
JSONObject respJson = PayService.createOrder(merchantEnum, openid, patientId, totalFee, outTradeNo, PEnum.PEIS_RESERVE.CODE, ip, body);
// 支付异常
if (respJson == null) {
return Result.error(ResultEnum.PAY_ERROR);
}
return Result.success(respJson);
}
/**
* 体检退费
*
* @param recipeId 订单号
* @param payCode 支付方式
* @param totalFee 订单金额
* @param outTradeNo outTradeNo
* @param openid openid
*/
@Action("peisRefund")
public Result peisRefund(String recipeId, String payCode, String outTradeNo, String totalFee, String openid) {
log.info("[体检预约]取消预约退费,recipeId-{}.payCode-{},outTradeNo-{},totalFee-{},openid-{}", recipeId, payCode, outTradeNo, totalFee, openid);
PeisService peisService = new PeisService();
MerchantEnum merchantEnum = MerchantEnum.findEnumByCode(payCode);
PeisDao peisDao = new PeisDao();
Recipe recipe = peisDao.selectByOutTradeNo(outTradeNo);
if (new BigDecimal(totalFee).compareTo(recipe.getTotalFee()) != 0) {
return Result.error(ResultEnum.REFUND_MONEY_ERROR);
}
String pushMessage = "已申请退款,原因:患者主动取消退费,订单号:" + outTradeNo + "orderNo:" + recipeId;
Result result = peisService.peisAutoRefund(recipeId, merchantEnum, outTradeNo, new BigDecimal(totalFee), pushMessage, new Date(), openid);
if (result.isOK()) {
peisService.peisRefund(recipeId, "OK", "");
} else {
peisService.peisRefund(recipeId, "FAIL", result.getMessage());
}
return result;
}
/**
* [住院]预交金创建订单
* *
@ -920,6 +852,90 @@ public class PayAction extends BaseAction {
}
/**
* @param payCode 支付方式
* @param openid openid
* @param patientId 患者id
* @param treatNum 体检号
* @param totalFee 总金额
* @param noticeOrderNo 体检订单号
*/
@Action("createPEISOrder")
public Result createPEISOrder(String payCode, String openid, String patientId, String treatNum, String totalFee, String noticeOrderNo) {
log.info("[体检预约]下单 payCode={}, openid={}, patientId={}, treatNum={}, totalFee={}, noticeOrderNo={}", payCode, openid, patientId, treatNum, totalFee, noticeOrderNo);
MerchantEnum merchantEnum = MerchantEnum.findEnumByCode(payCode);
if (merchantEnum == null) { // 支付方式异常
return Result.error(ResultEnum.PAY_TYPE_ERROR);
}
if (ObjectUtils.isEmpty(XBDHelper.XBD_PEIS)) {
return Result.error(ResultEnum.SYSTEM_CONFIG_ERROR);
}
if (openid == null || patientId == null || treatNum == null || totalFee == null || noticeOrderNo == null) {
return Result.error(ResultEnum.PARAM_IS_DEFECT);
}
if (new BigDecimal(totalFee).compareTo(BigDecimal.ZERO) == 0) {
return Result.error(ResultEnum.PAY_MONEY_IS_ZERO);
}
String outTradeNo = CodeHelper.getOutTradeNo(merchantEnum);
PEISService peisService = new PEISService();
if (peisService.hasPaidByNoticeOrderNo(noticeOrderNo)) {
log.info("[体检预约]订单已支付 noticeOrderNo={}", noticeOrderNo);
return Result.error(ResultEnum.PAY_REPEAT);
}
if (!peisService.isSavePEISOrder(openid, patientId, treatNum, outTradeNo, totalFee, noticeOrderNo)) {
log.info("{} [体检预约]订单信息保存失败 patientId={}, noticeOrderNo={}", merchantEnum.NAME, patientId, noticeOrderNo);
return Result.error(ResultEnum.SPECIFIED_QUESTIONED_USER_NOT_EXIST);
}
String ip = request.getRemoteAddr();
String body = "体检预约 患者:" + patientId + "\n体检号:" + treatNum + "\n订单号:" + noticeOrderNo;
JSONObject respJson = PayService.createOrder(merchantEnum, openid, patientId, totalFee, outTradeNo, PEnum.PEIS_RESERVE.CODE, ip, body);
if (respJson == null) {
return Result.error(ResultEnum.PAY_ERROR);
}
return Result.success(respJson);
}
/**
* 取消体检预约
*
* @param payCode 支付方式
* @param noticeOrderNo 体检订单号
* @param totalFee 订单金额
* @param outTradeNo outTradeNo
* @param openid openid
*/
@Action("cancelPEISRes")
public Result cancelPEISRes(String payCode, String noticeOrderNo, String outTradeNo, BigDecimal totalFee, String openid) {
try {
log.info("[体检预约]取消预约 payCode={}, noticeOrderNo={}, outTradeNo={}, totalFee={}, openid={}", payCode, noticeOrderNo, outTradeNo, totalFee, openid);
MerchantEnum merchantEnum = MerchantEnum.findEnumByCode(payCode);
if (merchantEnum == null) { // 支付方式异常
return Result.error(ResultEnum.PAY_TYPE_ERROR);
}
if (noticeOrderNo == null || outTradeNo == null || totalFee == null || openid == null) {
return Result.error(ResultEnum.PARAM_IS_DEFECT);
}
PEISService peisService = new PEISService();
String refundDesc = "取消预约 体检订单号:" + noticeOrderNo;
Result result = peisService.refundPEIS(merchantEnum, noticeOrderNo, outTradeNo, totalFee, refundDesc, new Date(), openid);
if (result.isOK()) {
peisService.cancelPEISReserve(noticeOrderNo, "OK", "");
}
return result;
} catch (Exception e) {
return Result.error(e);
}
}
// /**
// * [病历]下单
// */

@ -15,7 +15,7 @@ public class WxAuthAction extends BaseAction {
@Action("is_auth")
public Result is_auth() throws Exception {
return WxAuthHelper.isAuth(request, false);
return WxAuthHelper.isAuth(request, response, false);
}
@Action("u_auth")
@ -34,7 +34,7 @@ public class WxAuthAction extends BaseAction {
@Action("is_pay_auth")
public Result is_pay_auth() throws Exception {
// 支付使用普通授权
return WxAuthHelper.isAuth(request, true);
return WxAuthHelper.isAuth(request, response, true);
}
// @Action("pay_b_auth")

@ -30,7 +30,7 @@ public class WxPayAction extends BaseAction {
WxPayNotify notifyInfo = WxPayHelper.payNotify(request);
Result.respXml(WxRespHelper.respOk()); // 收到请求-解析成功
PayService.WxNotify(notifyInfo);
PayService.wxNotify(notifyInfo);
} catch (ServiceException e) {
Result.respXml(WxRespHelper.resp(e)); // 收到请求-解析失败
}

@ -5,11 +5,15 @@ import com.ynxbd.common.helper.common.DateHelper;
import com.ynxbd.common.result.Result;
import com.ynxbd.common.result.ResultEnum;
import com.ynxbd.common.result.ServiceException;
import com.ynxbd.wx.wxfactory.WxPayHelper;
import com.ynxbd.wx.wxfactory.medical.WxMedConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;
/**
@ -22,6 +26,17 @@ import java.util.Date;
@Namespace("/test02")
public class TestAction extends BaseAction {
private static int i = 0;
@Action("refund_test")
public Result refund_test() throws ServiceException {
if (i == 0) {
i++;
// WxPayHelper.refund("", "", new BigDecimal("0.900"), new BigDecimal("0.900"), "手动退费");
}
return Result.success();
}
// @Action("a")
// public String a() {

@ -0,0 +1,25 @@
package com.ynxbd.common.action.weihu;
import com.ynxbd.common.bean.pay.Order;
import com.ynxbd.common.dao.RecipeDao;
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.util.List;
@Slf4j
@Namespace("/data_wh")
public class DataWHAction {
@Action("getData")
public Result getData(String callNo) {
String begTime = "2025-10-27";
String endTime = "2025-12-08";
return Result.success();
}
}

@ -71,6 +71,8 @@ public class Order implements Serializable {
private BigDecimal payMoney;
// 订单总金额
private BigDecimal totalFee;
// 记录支付完成状态的时间
private Date payStatusTime;
// 商户支付状态
private Integer payStatus;
// HIS通知状态
@ -136,16 +138,15 @@ public class Order implements Serializable {
// 缴费订单类型
private String orderType;
// PEIS通知状态
private Integer peisStatus;
// PEIS返回提示
private String peisResult;
// 第三方回调状态(-1:未调用,0:调用成功,500:调用超时,其他:调用失败)
private Integer noticeStatus;
// 第三方返回结果
private String noticeResult;
// 第三方订单号
private String noticeOrderNo;
// 第三方交易流水号
private String noticeTransNo;
// 订单额外信息
private Object orderObj;

@ -0,0 +1,47 @@
package com.ynxbd.common.bean.pay;
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 PEISOrderInfo implements Serializable {
private static final long serialVersionUID = 20251217160400001L;
private Long id;
private Long eid;
private String createTime;
// 交易时间
private String payTime;
private String payStatus;
// 订单金额
private BigDecimal fee;
// 体检订单号
private String orderNo;
// 是否删除-标识体检的订单是否已退费(true:删除;false:未删除)
private Boolean isDeleted;
// 微信是否支付(true:已支付,false:未支付)
private Boolean isWxPay;
// HIS是否记账(true:已记账,false:未记账)
private Boolean isCost;
// 退费状态
private String refundStatus;
// 退费时间
private String refundTime;
// 是否已退费成功
public boolean hasRefundOK() {
return "OK".equals(refundStatus);
}
}

@ -0,0 +1,25 @@
package com.ynxbd.common.bean.pay;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
/**
* 体检预约
*
* @Author wsq
* @Date 2020/11/12 10:24
* @Copyright @ 2020 云南新八达科技有限公司 All rights reserved.
*/
@Setter
@Getter
@ToString(callSuper = true)
@NoArgsConstructor
public class PEISReserve extends Order implements Serializable {
private static final long serialVersionUID = 202512171006000001L;
}

@ -1010,9 +1010,9 @@ public class HisRegisterDao {
}
/**
* 分时段挂号--是否占号
* 分时段挂号--是否占号不能作为查询号源是否占用的单独接口容易被攻击
*
* @param patientId 患者id
* @param patientId 用于占号的患者id
* @param sourceId 号源id
* @return true false
*/

@ -0,0 +1,114 @@
package com.ynxbd.common.dao.peis;
import com.ynxbd.common.bean.pay.PEISReserve;
import com.ynxbd.common.config.db.DataBase;
import java.util.List;
/**
* @author 李进才
* @ClassName PeisDao
* @Description TODO
* @date 2023/11/16 15:43:00
*/
public class PEISDao {
/**
* 处方支付数据预存单个
*
* @param info 支付信息
* @return 是否存储成功
*/
public boolean insert(PEISReserve info) {
String sql = "insert into peis_reserve(updateTime, noticeStatus, payStatus, openId, patientId, payMoney, totalFee, outTradeNo, noticeOrderNo, treatNum) values (now(),?,?,?,?,?,?,?,?,?)";
return DataBase.insert(sql, ps -> {
ps.setInt(1, info.getPayStatus());
ps.setInt(2, info.getNoticeStatus());
ps.setString(3, info.getOpenid());
ps.setString(4, info.getPatientId());
ps.setBigDecimal(5, info.getTotalFee());
ps.setBigDecimal(6, info.getPayMoney());
//
ps.setString(7, info.getOutTradeNo());
ps.setString(8, info.getNoticeOrderNo());
ps.setString(9, info.getTreatNum());
}) > 0;
}
/**
* 判断体检订单是否已缴费
*
* @param noticeOrderNo 体检订单号
*/
public boolean hasPaidByNoticeOrderNo(String noticeOrderNo) {
String sql = "select * from peis_reserve where noticeOrderNo=? and payStatus=0";
return !DataBase.select(sql, PEISReserve.class, ps -> {
ps.setString(1, noticeOrderNo);
}).isEmpty();
}
public PEISReserve selectByOutTradeNo(String outTradeNo) {
String sql = "select * from peis_reserve where outTradeNo=?";
List<PEISReserve> list = DataBase.select(sql, PEISReserve.class, ps -> {
ps.setString(1, outTradeNo);
});
if (!list.isEmpty()) {
return list.get(0);
}
return null;
}
public PEISReserve selectByNoticeOrderNo(String noticeOrderNo) {
String sql = "select * from peis_reserve where noticeOrderNo=? and noticeStatus = 0 and payStatus=0";
List<PEISReserve> list = DataBase.select(sql, PEISReserve.class, ps -> {
ps.setString(1, noticeOrderNo);
});
if (!list.isEmpty()) {
return list.get(0);
}
return null;
}
/**
* 修改退款状态
*
* @param outTradeNo 订单号
* @param noticeOrderNo 体检订单号
* @param refundResult 退款描述
* @return 是否成功
*/
public boolean updateRefundResult(String outTradeNo, String noticeOrderNo, String refundResult, Integer refundStatus) {
String sql = "update peis_reserve set refundTime=now(), refundResult=?, refundStatus=? where outTradeNo=? and noticeOrderNo=?";
return DataBase.update(sql, ps -> {
ps.setString(1, refundResult);
ps.setInt(2, refundStatus);
ps.setString(3, outTradeNo);
ps.setString(4, noticeOrderNo);
}) > 0;
}
/**
* 修改支付状态
*
* @param outTradeNo
* @param bankTransNo
* @param tradeNo
* @return
*/
public boolean updateMerPaidByOutTradeNo(String outTradeNo, String bankTransNo, String tradeNo) {
String sql = "update peis_reserve set payStatusTime=now(), payStatus=0, bankTransNo=?, tradeNo=? where outTradeNo=? and bankTransNo is null";
return DataBase.update(sql, ps -> {
ps.setString(1, bankTransNo);
ps.setString(2, tradeNo);
ps.setString(3, outTradeNo);
}) > 0;
}
public boolean updateNoticeStatusOK(String outTradeNo, String bankTransNo) {
String sql = "update peis_reserve set noticeStatus=0, bankTransNo=? where outTradeNo=?";
return DataBase.update(sql, ps -> {
ps.setString(1, bankTransNo);
ps.setString(2, outTradeNo);
}) > 0;
}
}

@ -1,116 +0,0 @@
package com.ynxbd.common.dao.peis;
import com.ynxbd.common.bean.pay.PayCasebook;
import com.ynxbd.common.bean.pay.Recipe;
import com.ynxbd.common.bean.record.Record;
import com.ynxbd.common.config.db.DataBase;
import java.util.List;
/**
* @author 李进才
* @ClassName PeisDao
* @Description TODO
* @date 2023/11/16 15:43:00
*/
public class PeisDao {
/**
* 处方支付数据预存单个
*
* @param recipe 支付信息
* @return 是否存储成功
*/
public boolean insert(Recipe recipe) {
String sql = "insert into peis_reserve(updateTime, peisStatus, payStatus, openId, patientId, payMoney, totalFee, outTradeNo, recipeId, treatNum) values (now(),?,?,?,?,?,?,?,?,?)";
return DataBase.insert(sql, ps -> {
ps.setInt(1, recipe.getPeisStatus());
ps.setInt(2, recipe.getPayStatus());
ps.setString(3, recipe.getOpenid());
ps.setString(4, recipe.getPatientId());
ps.setBigDecimal(5, recipe.getTotalFee());
ps.setBigDecimal(6,recipe.getPayMoney());
//
ps.setString(7, recipe.getOutTradeNo());
ps.setString(8, recipe.getRecipeId());
ps.setString(9, recipe.getTreatNum());
}) > 0;
}
/**
* 判断该处方是否重复计费
* @param recipeId 处方号
* @return
*/
public boolean isRepeat(String recipeId){
String sql = "select * from peis_reserve where recipeId = ? and peisStatus = 0";
return !DataBase.select(sql,Recipe.class,ps->{
ps.setString(1,recipeId);
}).isEmpty();
}
public Recipe selectByOutTradeNo(String outTradeNo) {
String sql = "select * from peis_reserve where outTradeNo=? order by updateTime desc";
List<Recipe> list = DataBase.select(sql, Recipe.class, ps -> {
ps.setString(1, outTradeNo);
});
if (list.size() > 0) {
return list.get(0);
}
return null;
}
public boolean checkRefund(String outTradeNo){
String sql = "select * from peis_reserve where outTradeNo=? and refundResult = 'OK'";
return !DataBase.select(sql,Recipe.class,ps->{
ps.setString(1,outTradeNo);
}).isEmpty();
}
public Recipe selectByRecipeId(String recipeId) {
String sql = "select * from peis_reserve where recipeId=? and peisStatus = 0 and payStatus=0 order by updateTime desc";
List<Recipe> list = DataBase.select(sql, Recipe.class, ps -> {
ps.setString(1, recipeId);
});
if (list.size() > 0) {
return list.get(0);
}
return null;
}
/**
* 修改退款描述
*
* @param outTradeNo 订单号
* @param recipeId 体检订单号
* @param refundMsg 退款描述
* @return 是否成功
*/
public boolean updateRefundResult(String outTradeNo, String recipeId, String refundMsg) {
// 退款成功
String sql = "update peis_reserve set refundResult=?, refundTime=now() where recipeId=? and outTradeNo=?";
return DataBase.update(sql, ps -> {
ps.setString(1, refundMsg);
ps.setString(2, recipeId);
ps.setString(3, outTradeNo);
}) > 0;
}
public boolean updatePayStateOk(String outTradeNo, String bankTransNo,String tradeNo) {
String sql = "update peis_reserve set payStatus=0, bankTransNo=?, TradeNo=? where outTradeNo=? and bankTransNo is null";
return DataBase.update(sql, ps -> {
ps.setString(1, bankTransNo);
ps.setString(2, tradeNo);
ps.setString(3, outTradeNo);
}) > 0;
}
public boolean updatePeisStateOk(String outTradeNo, String bankTransNo) {
String sql = "update peis_reserve set peisStatus=0, bankTransNo=? where outTradeNo=?";
return DataBase.update(sql, ps -> {
ps.setString(1, bankTransNo);
ps.setString(2, outTradeNo);
}) > 0;
}
}

@ -3,6 +3,7 @@ package com.ynxbd.common.helper.common;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
@ -267,7 +268,6 @@ public class HttpHelper {
}
/**
* 访问目标地址并获取返回值
*
@ -337,6 +337,20 @@ public class HttpHelper {
}
}
public static String getSessionIdByCookie(HttpServletRequest request) {
String sessionId = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("JSESSIONID".equals(cookie.getName())) { // Tomcat默认Session Cookie名
sessionId = cookie.getValue();
break;
}
}
}
return sessionId;
}
// /**
// * 响应success字符串
// *

@ -10,6 +10,7 @@ import com.ynxbd.wx.utils.DesEncryptHelper;
import com.ynxbd.wx.wxfactory.utils.XmlHelper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.ObjectUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
@ -79,6 +80,9 @@ public class OkHttpHelper {
return String.format("%s:%d", host, port);
}
public static JsonResult get(String url, MapParams mapParams, JsonResultEnum jsonResultEnum) {
return JsonResult.jsonToBean(get(url, mapParams), jsonResultEnum);
}
public static String get(String url, MapParams mapParams) {
OkHttpClient client = getOkHttpClient(url);
@ -89,8 +93,11 @@ public class OkHttpHelper {
if (mapParams != null) {
mapParams.setParams(requestParams);
}
try (Response response = client.newCall(new Request.Builder().get()
.url(mackParamsUrl(url, requestParams)).build()).execute()) {
url = mackParamsUrl(url, requestParams);
if (url == null) {
return null;
}
try (Response response = client.newCall(new Request.Builder().get().url(url).build()).execute()) {
if (!response.isSuccessful()) {
return null;
}
@ -117,8 +124,12 @@ public class OkHttpHelper {
if (mapParams != null) {
mapParams.setParams(requestParams);
}
url = mackParamsUrl(url, requestParams);
if (url == null) {
return;
}
client.newCall(new Request.Builder().get().url(mackParamsUrl(url, requestParams)).build()).enqueue(new Callback() {
client.newCall(new Request.Builder().get().url(url).build()).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
log.error(e.getMessage());
@ -141,7 +152,34 @@ public class OkHttpHelper {
});
}
// public static String postCookie(String url, RequestBody requestBody, Header header) {
// OkHttpClient client = getOkHttpClient(url);
// if (client == null) {
// return null;
// }
/// / client.cookieJar(new PersistentCookieJar());
// Headers.Builder headersBuilder = new Headers.Builder();
// if (header != null) {
// header.setHeaders(headersBuilder);
// }
// try (Response response = client.newCall(new Request.Builder().url(url).post(requestBody).headers(headersBuilder.build()).build()).execute()) {
// if (!response.isSuccessful()) {
// return null;
// }
// try (ResponseBody body = response.body()) {
// if (body == null) {
// return null;
// }
// String respBody = body.string();
// log.info("接口响应数据resp={}", respBody);
// return respBody;
// }
// } catch (Exception e) {
// ErrorHelper.println(e);
// }
// return null;
// }
public static String post(String url, RequestBody requestBody, Header header) {
OkHttpClient client = getOkHttpClient(url);
if (client == null) {
@ -216,7 +254,7 @@ public class OkHttpHelper {
method.setParams(params);
}
FormBody.Builder builder = new FormBody.Builder();
if (params.size() > 0) {
if (!params.isEmpty()) {
Object value;
for (Map.Entry<String, Object> item : params.entrySet()) {
value = item.getValue();
@ -286,11 +324,11 @@ public class OkHttpHelper {
* @return 携带参数的链接 / null
*/
public static String mackParamsUrl(String url, Map<String, Object> params) {
if (url == null || "".equals(url)) {
if (ObjectUtils.isEmpty(url)) {
return null;
}
if (params == null || params.size() == 0) {
if (params == null || params.isEmpty()) {
return url;
}
@ -327,25 +365,19 @@ public class OkHttpHelper {
* @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 (BufferedReader br = request.getReader()) {
try {
if (br != null) {
br.close();
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());
}
} catch (Exception e) {
log.error(e.getMessage());
}
return null;
}

@ -396,6 +396,30 @@ public class JsonResult {
return JsonHelper.decodeBean(JsonHelper.toJsonString(this.dataMap), clazz);
}
/**
* 获取DataMap为bean
*
* @param clazz 类型
* @return bean
*/
public <T> T dataMapGetNodeToBean(Class<T> clazz) {
return dataMapGetNodeToBean(clazz, "data");
}
/**
* 获取DataMap为bean
*
* @param clazz 类型
* @return bean
*/
public <T> T dataMapGetNodeToBean(Class<T> clazz, String dataName) {
Object data = this.dataMap.get(dataName);
if (data == null) {
return null;
}
return JsonHelper.decodeBean(data.toString(), clazz);
}
/**
* 获取DataMap为bean
*

@ -22,8 +22,10 @@ public enum JsonResultEnum {
SYS_RESERVE("[天助预约]","code","msg","0","-1",String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)),
SYS_RM_LIS("[瑞美LIS]", "ResultCode", "ResultMessage", "1", "0", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT));
SYS_RM_LIS("[瑞美LIS]", "ResultCode", "ResultMessage", "1", "0", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)),
SYS_PEIS_RESERVE("[体检预约]", "code", "message", "200", "0", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT))
;
// 调用系统标识
public final String SYS;

@ -0,0 +1,282 @@
package com.ynxbd.common.service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ynxbd.common.action.pay.PEnum;
import com.ynxbd.common.bean.enums.MerchantEnum;
import com.ynxbd.common.bean.pay.Order;
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.http.OkHttpHelper;
import com.ynxbd.common.helper.xbd.XBDHelper;
import com.ynxbd.common.result.*;
import lombok.extern.slf4j.Slf4j;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.apache.commons.lang3.ObjectUtils;
import java.math.BigDecimal;
import java.util.Date;
/**
* @author 王绍全
* @ClassName PEISService
* @Description TODO
* @date 2025/12/17 15:53:00
*/
@Slf4j
public class PEISService {
public JsonResult get(String url, OkHttpHelper.MapParams params) {
return OkHttpHelper.get(url, params, JsonResultEnum.SYS_PEIS_RESERVE);
}
public JsonResult postJson(String url, OkHttpHelper.MapParams params, OkHttpHelper.Header header) {
return OkHttpHelper.postJson(url, params, header, JsonResultEnum.SYS_PEIS_RESERVE);
}
public JsonResult postForm(String url, OkHttpHelper.MapParams params, OkHttpHelper.Header header) {
return OkHttpHelper.postForm(url, params, header, JsonResultEnum.SYS_PEIS_RESERVE);
}
/**
* 判断体检订单是否已缴费
*
* @param noticeOrderNo 体检订单号
*/
public boolean hasPaidByNoticeOrderNo(String noticeOrderNo) {
return new PEISDao().hasPaidByNoticeOrderNo(noticeOrderNo);
}
/**
* 订单信息记录
*
* @param openid openid
* @param patientId 患者id
* @param treatNum 体检号
* @param outTradeNo 商户订单号
* @param totalFee 金额
* @param noticeOrderNo 体检订单号
* @return bool
*/
public boolean isSavePEISOrder(String openid, String patientId, String treatNum, String outTradeNo, String totalFee, String noticeOrderNo) {
PEISReserve info = new PEISReserve();
info.setOpenid(openid);
info.setPatientId(patientId);
info.setTreatNum(treatNum);
info.setOutTradeNo(outTradeNo);
info.setNoticeOrderNo(noticeOrderNo);
info.setTotalFee(new BigDecimal(totalFee));
info.setPayMoney(new BigDecimal(totalFee));
info.setPayStatus(-1);
info.setNoticeStatus(-1);
return new PEISDao().insert(info);
}
public PEISReserve queryByOutTradeNo(String outTradeNo) {
return new PEISDao().selectByOutTradeNo(outTradeNo);
}
public void payNotify(MerchantEnum merchantEnum, String openid, BigDecimal totalFee, String outTradeNo, String bankTransNo, String payDate, String payTime, String payInfo) {
PEISDao peisDao = new PEISDao();
PEISReserve order = peisDao.selectByOutTradeNo(outTradeNo);
if (order.hasPayStatusPaid() && order.hasNoticeStatusPaid()) {
log.info("{} [体检预约]订单已支付,停止向下执行 outTradeNo={}, bankTransNo={}", merchantEnum.NAME, outTradeNo, bankTransNo);
return;
}
String tradeNo = PEnum.getTradeNo(bankTransNo, PEnum.PEIS_RESERVE);
String noticeOrderNo = order.getNoticeOrderNo();
if (ObjectUtils.isEmpty(noticeOrderNo)) {
log.info("{} [体检预约]存储的体检订单号为空 outTradeNo={}, bankTransNo={}", merchantEnum.NAME, outTradeNo, bankTransNo);
return;
}
// 更新商户支付状态
if (!peisDao.updateMerPaidByOutTradeNo(outTradeNo, bankTransNo, tradeNo)) {
log.info("{} [体检预约]更新订单失败,停止向下执行 outTradeNo={}, bankTransNo={}, tradeNo={}", merchantEnum.NAME, outTradeNo, bankTransNo, tradeNo);
return;
}
if (order.hasNoticeStatusPaid()) {
log.info("[体检预约]订单已支付 outTradeNo={}, bankTransNo={}, noticeOrderNo={}", outTradeNo, bankTransNo, noticeOrderNo);
return;
}
JsonResult jsonResult = postForm(XBDHelper.XBD_PEIS + "/wxUse/wxPay", params -> {
params.put("orderNo", noticeOrderNo);
params.put("payStatus", "OK");
params.put("payFailReason", "");
params.put("bankTransNo", bankTransNo);
params.put("outTradeNo", outTradeNo);
}, null);
log.info("[体检预约]回调接口调用 {}", JsonHelper.toJsonString(jsonResult));
if (jsonResult.isTimeout()) { // 调用接口超时
log.info("[体检预约]回调接口调用超时 不进行退费处理");
return;
}
if (!jsonResult.success()) { // 通知失败
String message = jsonResult.getMessage();
if (message == null) {
message = "";
}
String refundDesc = "体检订单号:" + noticeOrderNo + " 通知体检系统异常:" + message;
refundPEIS(merchantEnum, noticeOrderNo, outTradeNo, totalFee, refundDesc, new Date(), openid);
return;
}
if (!peisDao.updateNoticeStatusOK(outTradeNo, bankTransNo)) {
log.info("[体检预约]修改体检系统支付状态失败 outTradeNo={}, bankTransNo={}", outTradeNo, bankTransNo);
}
}
/**
* 根据体检订单号查询体检接口
*
* @param noticeOrderNo 体检订单号
* @return bean
*/
public PEISOrderInfo queryPEISOrderByNoticeOrderNo(String noticeOrderNo) throws ServiceException {
JsonResult jsonResult = get(XBDHelper.XBD_PEIS + "/wxUse/GetOrder", params -> {
params.put("orderNo", noticeOrderNo);
});
log.info("[体检预约]订单查询 {}", JsonHelper.toJsonString(jsonResult));
if (!jsonResult.success()) {
String message = jsonResult.getMessage();
log.info("[体检预约]订单查询失败:{}", message);
throw new ServiceException(message);
}
return jsonResult.dataMapGetNodeToBean(PEISOrderInfo.class);
}
/**
* 体检退费接口
*
* @param noticeOrderNo 订单号
* @param merchantEnum 支付方式
* @param outTradeNo outTradeNo
* @param totalFee 总金额
* @param refundDesc 退费描述
* @param tradeDate 退费时间
* @param openid openid
*/
public Result refundPEIS(MerchantEnum merchantEnum, String noticeOrderNo, String outTradeNo, BigDecimal totalFee, String refundDesc, Date tradeDate, String openid) {
try {
if (totalFee.compareTo(BigDecimal.ZERO) == 0) {
log.info("{} [体检预约]订单金额为0无需退费 outTradeNo={}, noticeOrderNo={}, totalFee={}", merchantEnum.NAME, outTradeNo, noticeOrderNo, totalFee);
return Result.error("订单金额为0无需退费");
}
PEISDao peisDao = new PEISDao();
PEISReserve dbOrder = peisDao.selectByOutTradeNo(outTradeNo);
if (dbOrder.hasRefundByRefundResult()) {
log.info("{} [体检预约]订单已退费 outTradeNo={}, noticeOrderNo={}, totalFee={}", merchantEnum.NAME, outTradeNo, noticeOrderNo, totalFee);
return Result.error("订单已退费,请勿重复取消");
}
PEISOrderInfo findOrder = queryPEISOrderByNoticeOrderNo(noticeOrderNo);
log.info("[体检预约] findOrder={}", JsonHelper.toJsonString(findOrder));
if (findOrder == null) {
log.info("[体检预约]未查询到订单 noticeOrderNo={}", noticeOrderNo);
return Result.error("[体检预约]未查询到订单");
}
BigDecimal fee = findOrder.getFee();
BigDecimal payMoney = dbOrder.getPayMoney();
if (totalFee.compareTo(payMoney) != 0 || fee.compareTo(payMoney) != 0) {
log.info("{} [体检预约]订单金额不匹配 outTradeNo={}, noticeOrderNo={}, totalFee={}, payMoney={}, fee={}", merchantEnum.NAME, outTradeNo, noticeOrderNo, totalFee, payMoney, fee);
return Result.error(ResultEnum.REFUND_MONEY_ERROR);
}
Boolean isHisCost = findOrder.getIsCost();
if (isHisCost != null && isHisCost) {
log.info("{} [体检预约]HIS已计费,禁止退费 outTradeNo={}, noticeOrderNo={}, totalFee={}", merchantEnum.NAME, outTradeNo, noticeOrderNo, totalFee);
return Result.error("退费错误,体检系统his显示已计费,不允许退费");
}
String refundResult = "OK";
Order orderRefund = PayService.refund(merchantEnum, outTradeNo, noticeOrderNo, totalFee, totalFee, refundDesc, tradeDate, openid, null, refundDesc);
if (!orderRefund.isSuccess()) {
refundResult = orderRefund.getRefundResult();
log.info("{} [体检预约]退费失败 outTradeNo={}, totalFee={}, noticeOrderNo={}, refundResult={}", merchantEnum.NAME, outTradeNo, totalFee, noticeOrderNo, refundResult);
}
Integer refundStatus = "OK".equals(refundResult) ? 1 : -1;
boolean isUpdate = peisDao.updateRefundResult(outTradeNo, noticeOrderNo, refundResult, refundStatus);
if (!isUpdate) {
log.info("{} [体检预约][退费错误]退费信息更新失败 noticeOrderNo={}", merchantEnum.NAME, noticeOrderNo);
}
if (orderRefund.isSuccess()) { // 退费成功
return Result.success();
}
return Result.error(refundResult);
} catch (Exception e) {
return Result.error(e);
}
}
/**
* 取消预约
*
* @param noticeOrderNo 体检订单号
* @param refundStatus 退费状态
* @param refundFailReason 退费描述
* @return bool
*/
public boolean cancelPEISReserve(String noticeOrderNo, String refundStatus, String refundFailReason) throws ServiceException {
JsonResult jsonResult = postForm(XBDHelper.XBD_PEIS + "/wxUse/wxRefund", params -> {
params.put("orderNo", noticeOrderNo);
params.put("refundStatus", refundStatus); // 退费状态(成功:OK,失败:FAIL)
params.put("refundFailReason", refundFailReason);
}, null);
log.info("[体检预约]取消预约 {}", JsonHelper.toJsonString(jsonResult));
if (!jsonResult.success()) {
String message = jsonResult.getMessage();
log.info("[体检预约]取消预约失败 noticeOrderNo={}, message={}", noticeOrderNo, message);
throw new ServiceException(message);
}
return true;
}
public JSONArray queryPEISRecordByCardNo(String cardNo, String begDate, String endDate) throws ServiceException {
RequestBody formBody = new FormBody.Builder().
add("enIdCard", cardNo)
.add("begDate", begDate)
.add("endDate", endDate)
.build();
String result = OkHttpHelper.post(XBDHelper.XBD_PEIS + "/WxUse/GetPeisOfPacsResult", formBody);
if (ObjectUtils.isEmpty(result)) {
throw new ServiceException("请求失败");
}
JSONObject jsonResult = JsonHelper.parseObject(result);
if (jsonResult == null) {
throw new ServiceException("请求失败");
}
String code = jsonResult.getString("code");
if (!"200".equals(code)) {
String message = jsonResult.getString("message");
throw new ServiceException(ObjectUtils.isEmpty(message) ? "请求失败" : message);
}
return jsonResult.getJSONArray("data");
}
// public static void main(String[] args) {
// RequestBody formBody = new FormBody.Builder().
// add("orderNo", "Fee2023112900000001")
// .add("payStatus", "OK")
// .add("payFailReason", "")
// .add("bankTransNo", "4200001809202305012522296970")
// .build();
// String result = OkHttpHelper.post(XBDHelper.XBD_PEIS + "/wxUse/wxPay", formBody);
// System.out.println(result);
//// String result = OkHttpHelper.get(XBDHelper.XBD_PEIS+"/wxUse/GetOrder",params -> {
//// params.put("orderNo","Fee2023112900000001");
//// });
//// JSONObject jsonResult = JsonHelper.parseObject(result);
//// System.out.println(result);
// }
}

@ -44,7 +44,7 @@ public class PayService {
*
* @param notifyInfo 回调信息
*/
public static void WxNotify(WxPayNotify notifyInfo) throws ServiceException {
public static void wxNotify(WxPayNotify notifyInfo) throws ServiceException {
String openid = notifyInfo.getOpenid();
String bankTransNo = notifyInfo.getTransactionId();
String outTradeNo = notifyInfo.getOutTradeNo();
@ -79,14 +79,18 @@ public class PayService {
new CasebookService().paidNotify(MerchantEnum.WX, openid, totalFee, outTradeNo, bankTransNo, payInfo);
break;
case OUT_COLLECT:
new OutCollectService().ocPaidNotify(MerchantEnum.WX, openid, totalFee, outTradeNo, bankTransNo, payInfo);
break;
case OL_REG:
new MicroService().OLReg(openid, totalFee, outTradeNo, bankTransNo, payDate, payTime);
break;
case PEIS_RESERVE:
new PEISService().payNotify(MerchantEnum.WX, openid, totalFee, outTradeNo, bankTransNo, payDate, payTime, payInfo);
break;
case OUT_COLLECT:
new OutCollectService().ocPaidNotify(MerchantEnum.WX, openid, totalFee, outTradeNo, bankTransNo, payInfo);
break;
case TPP_QR_REG:
new ThirdPartyPayService().tppQRRegNotify(MerchantEnum.WX, openid, totalFee, outTradeNo, bankTransNo, payDate, payTime, payInfo);
break;

@ -1,221 +0,0 @@
package com.ynxbd.common.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ynxbd.common.action.pay.PEnum;
import com.ynxbd.common.bean.enums.MerchantEnum;
import com.ynxbd.common.bean.pay.Order;
import com.ynxbd.common.bean.pay.Recipe;
import com.ynxbd.common.dao.peis.PeisDao;
import com.ynxbd.common.helper.common.JsonHelper;
import com.ynxbd.common.helper.his.HisHelper;
import com.ynxbd.common.helper.http.OkHttpHelper;
import com.ynxbd.common.helper.xbd.HttpHelper;
import com.ynxbd.common.helper.xbd.XBDHelper;
import com.ynxbd.common.result.JsonResult;
import com.ynxbd.common.result.JsonResultEnum;
import com.ynxbd.common.result.Result;
import com.ynxbd.common.result.ServiceException;
import lombok.extern.slf4j.Slf4j;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.apache.commons.lang3.ObjectUtils;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author 李进才
* @ClassName PeisService
* @Description TODO
* @date 2023/11/16 15:53:00
*/
@Slf4j
public class PeisService {
public Boolean Reserve(String openid, String patientId, String treatNum, String outTradeNo, String totalFee, String recipeId) {
Recipe recipe = new Recipe();
recipe.setOpenid(openid);
recipe.setPatientId(patientId);
recipe.setTreatNum(treatNum);
recipe.setOutTradeNo(outTradeNo);
recipe.setRecipeId(recipeId);
recipe.setTotalFee(new BigDecimal(totalFee));
recipe.setPayMoney(new BigDecimal(totalFee));
recipe.setPeisStatus(-1);
recipe.setPayStatus(-1);
if (new PeisDao().isRepeat(recipe.getRecipeId())) {
log.info("[体检预约]该处方号已经缴费,recipeId-{}", recipe.getRecipeId());
return false;
}
return new PeisDao().insert(recipe);
}
public void payNotify(MerchantEnum merchantEnum, String openid, BigDecimal totalFee, String outTradeNo, String bankTransNo, String payInfo, Date tradeDate) {
PeisDao peisDao = new PeisDao();
Recipe recipe = peisDao.selectByOutTradeNo(outTradeNo);
String tradeNo = HisHelper.getHisTradeNo(bankTransNo, PEnum.PEIS_RESERVE);
String recipeId = recipe.getRecipeId();
Integer payStates = recipe.getPayStatus();
if (payStates == 0) {
log.error("[体检预约] 拒绝支付-订单已支付 outTradeNo={}, bankTransNo={}, recipeId={}", outTradeNo, bankTransNo, recipeId);
return;
}
if (!peisDao.updatePayStateOk(outTradeNo, bankTransNo, tradeNo)) {
log.info("[体检预约]修改支付状态失败 outTradeNo={}, bankTransNo={},tradeNo-{}", outTradeNo, bankTransNo, tradeNo);
RequestBody formBody = new FormBody.Builder().
add("orderNo", recipeId)
.add("payStatus", "FAIL")
.add("payFailReason", "修改支付状态失败")
.add("bankTransNo", bankTransNo)
.add("outTradeNo", outTradeNo)
.build();
String result = OkHttpHelper.post(XBDHelper.XBD_PEIS + "/wxUse/wxPay", formBody);
JSONObject jsonResult = JsonHelper.parseObject(result);
log.info("[体检预约]缴费失败回调体检系统计费 recipeId={}, bankTransNo-{}, 计费状态-{}, 计费信息-{}", recipeId, bankTransNo, jsonResult.get("code"), jsonResult.get("message"));
String pushMessage = "体检预约失败已申请退款,原因:修改支付状态失败,订单号:" + outTradeNo + "orderNo:" + recipeId;
;
peisAutoRefund(recipeId, merchantEnum, outTradeNo, totalFee, pushMessage, tradeDate, openid);
} else {
RequestBody formBody = new FormBody.Builder().
add("orderNo", recipeId)
.add("payStatus", "OK")
.add("payFailReason", "")
.add("bankTransNo", bankTransNo)
.add("outTradeNo", outTradeNo)
.build();
String result = OkHttpHelper.post(XBDHelper.XBD_PEIS + "/wxUse/wxPay", formBody);
if (result == null) {
log.info("[体检预约]体检服务无响应,开始退费");
String pushMessage = "体检预约失败已申请退款,原因:体检服务无响应,订单号:" + outTradeNo + "orderNo:" + recipeId;
peisAutoRefund(recipeId, merchantEnum, outTradeNo, totalFee, pushMessage, tradeDate, openid);
}
JSONObject jsonResult = JsonHelper.parseObject(result);
log.info("[体检预约]缴费成功回调体检系统计费 recipeId={}, bankTransNo-{}, 计费状态-{}, 计费信息-{}", recipeId, bankTransNo, jsonResult.get("code"), jsonResult.get("message"));
if ("200".equals(jsonResult.get("code").toString())) {
if (!peisDao.updatePeisStateOk(outTradeNo, bankTransNo)) {
log.info("[体检预约]修改体检系统支付状态失败 outTradeNo={}, bankTransNo={}", outTradeNo, bankTransNo);
}
} else {
log.info("[体检预约]回调体检系统计费状态码异常 recipeId={}, bankTransNo-{}, 计费状态-{}, 计费信息-{}", recipeId, bankTransNo, jsonResult.get("code"), jsonResult.get("message"));
String pushMessage = "体检预约失败已申请退款,原因:体检系统计费失败,订单号:" + outTradeNo + "orderNo:" + recipeId;
peisAutoRefund(recipeId, merchantEnum, outTradeNo, totalFee, pushMessage, tradeDate, openid);
}
}
}
/**
* 体检退费接口
*
* @param recipeId 订单号
* @param merchantEnum 支付方式
* @param outTradeNo outTradeNo
* @param totalFee 总金额
* @param pushInfo 提示信息
* @param tradeDate 退费时间
* @param openid openid
*/
public Result peisAutoRefund(String recipeId, MerchantEnum merchantEnum, String outTradeNo, BigDecimal totalFee, String pushInfo, Date tradeDate, String openid) {
PeisDao peisDao = new PeisDao();
if (peisDao.checkRefund(outTradeNo)) {
log.info("{} [体检预约][该订单已经退费,请不要重复退费] outTradeNo={}, recipeId={}, totalFee={}", merchantEnum.NAME, outTradeNo, recipeId, totalFee);
return Result.error("该订单已经退费,请不要重复退费");
}
String result = OkHttpHelper.get(XBDHelper.XBD_PEIS + "/wxUse/GetOrder", params -> {
params.put("orderNo", recipeId);
});
if (result == null) {
log.info("{} [体检预约][退费错误,计费信息查询失败] outTradeNo={}, recipeId={}, totalFee={}", merchantEnum.NAME, outTradeNo, recipeId, totalFee);
return Result.error("退费错误,计费信息查询失败");
}
JSONObject jsonResult = JsonHelper.parseObject(result);
String fee = jsonResult.getJSONObject("data").get("fee").toString();
boolean isWxPay = Boolean.parseBoolean(jsonResult.getJSONObject("data").get("isWxPay").toString());
boolean isCost = Boolean.parseBoolean(jsonResult.getJSONObject("data").get("isCost").toString());
if (totalFee.compareTo(BigDecimal.ZERO) == 0 || "0".equals(fee)) {
log.info("{} [体检预约][退费错误,退费金额为0] outTradeNo={}, recipeId={}, totalFee={}", merchantEnum.NAME, outTradeNo, recipeId, totalFee);
return Result.error("退费错误,退费金额为0");
}
if (totalFee.compareTo(new BigDecimal(fee)) != 0) {
log.info("{} [体检预约][退费错误,退费金额跟订单金额不符] outTradeNo={}, recipeId={}, totalFee={}", merchantEnum.NAME, outTradeNo, recipeId, totalFee);
return Result.error("退费错误,退费金额跟订单金额不符");
}
// if(isWxPay){
// log.info("{} [体检预约][退费错误,体检显示已计费,不允许退费] recipeId-{}, outTradeNo={}, recipeId={}, totalFee={}", recipeId, merchantEnum.NAME, outTradeNo, recipeId, totalFee);
// return Result.error("退费错误,体检显示已计费,不允许退费");
// }
if (isCost) {
log.info("{} [体检预约][退费错误,his显示已计费,不允许退费] outTradeNo={}, recipeId={}, totalFee={}", merchantEnum.NAME, outTradeNo, recipeId, totalFee);
return Result.error("退费错误,体检系统his显示已计费,不允许退费");
}
String refundResult;
Order orderRefund = PayService.refund(merchantEnum, outTradeNo, recipeId, totalFee, totalFee, pushInfo, tradeDate, openid, null, pushInfo);
if (!orderRefund.isSuccess()) {
log.info("{} [体检预约][退费错误] outTradeNo={}, totalFee={},recipeId-{}", merchantEnum.NAME, outTradeNo, totalFee, recipeId);
refundResult = orderRefund.getRefundResult();
} else {
refundResult = "OK";
}
boolean isUpdate = peisDao.updateRefundResult(outTradeNo, recipeId, refundResult);
if (!isUpdate) {
log.info("{} [体检预约][退费错误]退费信息更新失败 recipeId={}", merchantEnum.NAME, recipeId);
}
return Result.success();
}
public boolean peisRefund(String recipeId, String refundStatus, String refundFailReason) {
RequestBody formBody = new FormBody.Builder().
add("orderNo", recipeId)
.add("refundStatus", refundStatus)
.add("refundFailReason", refundFailReason)
.build();
String result = OkHttpHelper.post(XBDHelper.XBD_PEIS + "/wxUse/wxRefund", formBody);
JSONObject jsonResult = JsonHelper.parseObject(result);
return "200".equals(jsonResult.get("code"));
}
public JSONArray getPeisByCardNo(String cardNo, String begDate, String endDate) throws ServiceException {
RequestBody formBody = new FormBody.Builder().
add("enIdCard", cardNo)
.add("begDate", begDate)
.add("endDate", endDate)
.build();
String result = OkHttpHelper.post(XBDHelper.XBD_PEIS + "/WxUse/GetPeisOfPacsResult", formBody);
if (ObjectUtils.isEmpty(result)) {
throw new ServiceException("请求失败");
}
JSONObject jsonResult = JsonHelper.parseObject(result);
if (jsonResult == null) {
throw new ServiceException("请求失败");
}
String code = jsonResult.getString("code");
if (!"200".equals(code)) {
String message = jsonResult.getString("message");
throw new ServiceException(ObjectUtils.isEmpty(message) ? "请求失败" : message);
}
return jsonResult.getJSONArray("data");
}
public static void main(String[] args) {
RequestBody formBody = new FormBody.Builder().
add("orderNo", "Fee2023112900000001")
.add("payStatus", "OK")
.add("payFailReason", "")
.add("bankTransNo", "4200001809202305012522296970")
.build();
String result = OkHttpHelper.post(XBDHelper.XBD_PEIS + "/wxUse/wxPay", formBody);
System.out.println(result);
// String result = OkHttpHelper.get(XBDHelper.XBD_PEIS+"/wxUse/GetOrder",params -> {
// params.put("orderNo","Fee2023112900000001");
// });
// JSONObject jsonResult = JsonHelper.parseObject(result);
// System.out.println(result);
}
}

@ -222,7 +222,7 @@ public class RecipeService {
public boolean isSaveRecipeInfo(String recipeJson, String payWay, String openid, String patientId, String treatNum, String outTradeNo, String totalFee) {
log.info("[处方支付]预存信息 patientId={}, treatNum={}, recipeJson={}", patientId, treatNum, recipeJson);
List<Recipe> recipeList = JsonHelper.parseArray(recipeJson, Recipe.class);
if (recipeList == null || recipeList.size() == 0) {
if (recipeList == null || recipeList.isEmpty()) {
log.info("[处方支付]勾选处方数量为0 或 数据转换失败");
return false;
}

@ -680,7 +680,7 @@ public class RegService {
/**
* 挂号下单
*/
public Result regPlaceOrder(String payCode, String ip, Boolean isOccupySource, Boolean isZeroPay, Register reg, boolean isHttps) {
public Result createRegOrder(String payCode, String ip, Boolean isOccupySource, Boolean isZeroPay, Register reg, boolean isHttps) {
Result noPayTime = PayService.isPaymentPermittedByTime();
if (noPayTime != null) {
return noPayTime;

@ -1,15 +0,0 @@
package com.ynxbd.common.service;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
@Slf4j
public class Test {
public static void main(String[] args) {
// System.out.println(JsonHelper.toJsonString(queryOrder("WX7c1ea238c08f420d2bb8262f7254")));
String piMd5 = "9444144" + "Z2007" + "xbd";
piMd5 = DigestUtils.md5Hex(piMd5).toUpperCase();
System.out.println(piMd5);
}
}

@ -1,33 +0,0 @@
package com.ynxbd.wx.servlet.test;
import com.ynxbd.wx.wxfactory.WxPayHelper;
import com.ynxbd.common.result.Result;
import com.ynxbd.wx.servlet.base.BaseServlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
/**
* @Author wsq
* @Date 2021/3/4 17:57
* @Copyright @ 2020 云南新八达科技有限公司 All rights reserved.
*/
@WebServlet("/refundTest")
public class RefundTestServlet extends BaseServlet {
// show status like 'Threads%';
private int i = 0;
@Override
protected synchronized Result requestMapping(HttpServletRequest req, HttpServletResponse resp) throws Exception {
if (i == 0) {
i++;
// 1
WxPayHelper.refund("", "", new BigDecimal("0.800"), new BigDecimal("0.800"), "手动退费");
// 2
}
return Result.success();
}
}

@ -1,27 +0,0 @@
//package com.ynxbd.wx.servlet;
//
//import com.ynxbd.common.result.Result;
//import com.ynxbd.wx.servlet.base.BaseServlet;
//import com.ynxbd.wx.wxfactory.WxAuthHelper;
//import lombok.extern.slf4j.Slf4j;
//
//import javax.servlet.annotation.WebServlet;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.io.UnsupportedEncodingException;
//
///**
// * 判读微信是否已经认证
// *
// * @author antgan
// */
//@Slf4j
//@WebServlet("/is_auth")
//public class WxIsAuthServlet extends BaseServlet {
//
// @Override
// protected Result requestMapping(HttpServletRequest request, HttpServletResponse resp) throws Exception {
// return WxAuthHelper.isAuth(request);
// }
//
//}

@ -11,8 +11,6 @@ import com.ynxbd.wx.wxfactory.base.auth.models.AuthData;
import com.ynxbd.wx.wxfactory.base.auth.models.SnsOath2AccessToken;
import com.ynxbd.wx.wxfactory.base.auth.models.SnsUserInfo;
import lombok.extern.slf4j.Slf4j;
import okhttp3.FormBody;
import okhttp3.RequestBody;
import org.apache.commons.lang3.ObjectUtils;
import org.ehcache.Cache;
@ -33,26 +31,27 @@ public class WxAuthHelper {
public static String auth(HttpServletRequest request, HttpServletResponse response, boolean isUserInfo) {
String code = request.getParameter("code");
String state = request.getParameter("state"); // base64
String enuId = request.getParameter("enuId");
String params = request.getParameter("params");
log.info("[授权] code={}, state={}, enuId={}", code, state, enuId);
log.info("[授权] code={}, state={}, params={}", code, state, params);
try {
state = state == null ? "" : URLDecoder.decode(Base64Helper.decode(state), "UTF-8");
String enUnionId = null;
String protocolState = null;
String authSessionId = null;
if (!ObjectUtils.isEmpty(enuId)) {
int index = enuId.indexOf("@protocolState=");
if (index == -1) index = enuId.indexOf("%40protocolState="); // 防止数据转义失败
if (!ObjectUtils.isEmpty(params)) {
int index = params.indexOf("@SID=");
if (index == -1) index = params.indexOf("%40SID="); // 防止数据转义失败
if (index != -1) {
enUnionId = enuId.substring(0, index);
protocolState = enuId.substring(index);
enUnionId = params.substring(0, index);
authSessionId = params.substring(index);
authSessionId = AesWxHelper.decode(authSessionId);
}
}
log.info("[授权-解码] enUnionId={}, protocolState={}, state={}", enUnionId, protocolState, state);
log.info("[授权-解码] enUnionId={}, authSessionId={}, state={}", enUnionId, authSessionId, state);
SnsOath2AccessToken snsToken = WxFactory.Base.OAuth().oauth2AccessToken(WeChatConfig.APP_ID, WeChatConfig.APP_SECRET, code);
log.info("[授权-用户]snsToken={}", JsonHelper.toJsonString(snsToken));
if (snsToken != null) {
String openid = snsToken.getOpenid();
String unionId = snsToken.getUnionid();
@ -63,6 +62,7 @@ public class WxAuthHelper {
HttpSession session = request.getSession();
session.setMaxInactiveInterval(SESSION_MAX_INACTIVE_INTERVAL);
session.setAttribute("openid", openid);
WxCacheHelper.putOpenIdToAIDCache(authSessionId, openid);
Cache<String, User> cache = WxCacheHelper.getUserCacheManager();
if (WeChatConfig.isDevUser(openid) || !cache.containsKey(openid)) {
@ -116,20 +116,26 @@ public class WxAuthHelper {
}
}
} catch (Exception e) {
ErrorHelper.println(e);
log.error("[微信][获取重定向链接异常]{}", e.getMessage());
}
return null;
}
public static Result isAuth(HttpServletRequest request, boolean isPayOAuth) throws Exception {
public static Result isAuth(HttpServletRequest request, HttpServletResponse response, boolean isPayOAuth) throws Exception {
String token = request.getParameter("token"); // 前端缓存
String state = request.getParameter("state");
String isUserInfo = request.getParameter("isUserInfo");
String protocolState = request.getParameter("protocolState");
String enuId = ParamHelper.filterParamNull(request.getParameter("enuId"), "");
// String protocolState = request.getParameter("protocolState");
String enUID = ParamHelper.filterParamNull(request.getParameter("enUID"), "");
String deState = URLDecoder.decode(Base64Helper.decode(state), "UTF-8");
String authSessionId = null;
if (WeChatConfig.IS_ENABLE_GMC && WeChatConfig.IS_GMC_SERVER && !isPayOAuth) { // 开启医共体开关 & 是医共体主服务器 & 不是支付授权
authSessionId = AesWxHelper.decode(request.getHeader("AID"));
}
log.info("[is_auth]token={}, state={}, isUserInfo={}, authSessionId={}, enUID={}, deState={}", token, state, isUserInfo, authSessionId, enUID, deState);
if (WeChatConfig.IS_ENABLE_GMC && !WeChatConfig.IS_GMC_SERVER && !isPayOAuth) { // 开启医共体开关 & 不是医共体主服务器 & 不是支付授权
try { // 请求转发
String serverDomain = WeChatConfig.getDomain(false, false);
@ -137,17 +143,26 @@ public class WxAuthHelper {
return Result.error("授权域名不匹配");
}
RequestBody requestBody = new FormBody.Builder()
.add("token", token)
.add("state", state)
.add("isUserInfo", isUserInfo)
.add("enuId", enuId)
.add("protocolState", protocolState)
.build();
log.info("[认证请求转发] URL:[{}]", WeChatConfig.getGMCAuthDomain(isHttpsWithProxy(request), true));
String data = OkHttpHelper.post(WeChatConfig.getGMCAuthDomain(isHttpsWithProxy(request), true) + "wx_auth/is_auth", requestBody);
HttpSession session = request.getSession();
String sessionId = session.getId();
log.info("[认证请求转发] [sessionId:{}]URL:[{}]", sessionId, WeChatConfig.getGMCAuthDomain(isHttpsWithProxy(request), true));
String data = OkHttpHelper.postFormStr(WeChatConfig.getGMCAuthDomain(isHttpsWithProxy(request), true) + "wx_auth/is_auth", params -> {
params.put("token", token);
params.put("state", state);
params.put("isUserInfo", isUserInfo);
params.put("enuId", enUID);
// params.put("protocolState", protocolState);
}, headers -> {
if (!ObjectUtils.isEmpty(sessionId)) {
headers.add("AID", AesWxHelper.encode(sessionId));
}
});
Result result = Result.dataToResult(data, true);
System.out.println(JsonHelper.toJsonString(result));
return Result.dataToResult(data, true);
} catch (Exception e) {
e.printStackTrace();
return Result.error(e);
}
}
@ -188,39 +203,51 @@ public class WxAuthHelper {
}
HttpSession session = request.getSession();
Object openid = session.getAttribute("openid");
Object sessionOpenId = session.getAttribute("openid");
String openid = sessionOpenId == null ? null : sessionOpenId.toString();
log.info("[微信认证]获取 openid={}, authSessionId={}", openid, authSessionId);
if (!ObjectUtils.isEmpty(authSessionId) && ObjectUtils.isEmpty(openid)) {
openid = WxCacheHelper.getOpenIdByAIDCache(authSessionId);
log.info("[微信AID认证]openid={}", openid);
}
if (openid != null) {
log.info("[微信认证]openid={}", openid);
User user = WxCacheHelper.getCacheUser((String) openid);
User user = WxCacheHelper.getCacheUser(openid);
if (user == null) {
return Result.success(getAuthUrl(request, state, isFindUserInfo, enuId, protocolState));
return Result.success(getAuthUrl(request, state, isFindUserInfo, enUID, authSessionId));
} else {
if (ObjectUtils.isEmpty(openid)) {
openid = user.getOpenid(); // sessionId认证openid补充
}
}
if (isFindUserInfo) { // 更换授权模式,需更新信息
if (user.getNickName() == null || user.getAvatar() == null) {
return Result.success(getAuthUrl(request, state, true, enuId, protocolState));
return Result.success(getAuthUrl(request, state, true, enUID, authSessionId));
}
}
Map<String, Object> map = new HashMap<>();
map.put("openid", openid);
map.put("token", new AuthData().createToken(WeChatConfig.APP_ID, openid.toString(), user.getUnionId(), user.getAvatar(), user.getNickName()));
map.put("enOpenId", AesWxHelper.encode(openid.toString(), true));
map.put("token", new AuthData().createToken(WeChatConfig.APP_ID, openid, user.getUnionId(), user.getAvatar(), user.getNickName()));
map.put("enOpenId", AesWxHelper.encode(openid, true));
map.put("enUnionId", AesWxHelper.encode(user.getUnionId(), true));
map.put("date", new Date());
map.put("avatar", user.getAvatar());
map.put("nickName", user.getNickName());
map.put("patients", CodeHelper.get28UUID() + Base64Helper.encode(URLEncoder.encode(JsonHelper.toJsonString(user.getPatientList()), "UTF-8")));
map.put("enParams", AesMicroHelper.encode(openid.toString()));
map.put("enParams", AesMicroHelper.encode(openid));
return Result.success(map);
}
return Result.success(getAuthUrl(request, state, isFindUserInfo, enuId, protocolState));
return Result.success(getAuthUrl(request, state, isFindUserInfo, enUID, authSessionId));
}
private static final String OAUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WeChatConfig.APP_ID + "&redirect_uri=";
private static String getAuthUrl(HttpServletRequest request, String state, boolean isFindUserInfo, String enuId, String protocolState) {
private static String getAuthUrl(HttpServletRequest request, String state, boolean isFindUserInfo, String enUID, String SID) {
// StringBuffer url = request.getRequestURL();
// String baseUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getServletContext().getContextPath()).append("/").toString();
if (state == null) {
@ -230,13 +257,22 @@ public class WxAuthHelper {
String api = isFindUserInfo ? "u_auth" : "b_auth";
String scope = isFindUserInfo ? "snsapi_userinfo" : "snsapi_base";
String enSID = "";
try {
enSID = (SID == null ? "" : ("%40SID=" + URLEncoder.encode(AesWxHelper.encode(SID), "UTF-8")));
} catch (Exception e) {
log.error(e.getMessage());
}
log.info("[认证链接] enSID={}, SID={}", enSID, SID);
state = OAUTH_URL + WeChatConfig.getBaseURL(WeChatConfig.HAS_HTTPS_BY_BASE_URL || isHttpsWithProxy(request)) +
"wx_auth/" + api +
"?state=" + state +
"&response_type=code" +
"&scope=" + scope + "&forcePopup=true" +
"&enuId=" + (enuId == null ? "" : enuId) +
(protocolState == null ? "" : ("%40protocolState=" + protocolState)) +
"&params=" + (enUID == null ? "" : enUID) +
enSID +
"#wechat_redirect";
return Base64Helper.encode(state);
}

@ -2,9 +2,11 @@ package com.ynxbd.wx.wxfactory;
import com.ynxbd.common.bean.User;
import com.ynxbd.common.config.EhCacheConfig;
import com.ynxbd.wx.config.WeChatConfig;
import com.ynxbd.wx.wxfactory.base.auth.models.AccessToken;
import com.ynxbd.wx.wxfactory.base.auth.models.JsapiTicket;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.ehcache.Cache;
@Slf4j
@ -18,11 +20,16 @@ public class WxCacheHelper {
private static Cache<String, JsapiTicket> JSAPI_TICKET_CACHE;
private static Cache<String, String> AID_CACHE;
static {
createUserCacheManager();
createAccessTokenCache();
createAuthSessionIdManager();
}
private synchronized static void createUserCacheManager() {
if (USER_CACHE == null) {
USER_CACHE = EhCacheConfig.createCacheTTL(String.class, User.class, "wx_oauth_cache", (5400L)); // 一个半小时
@ -127,7 +134,6 @@ public class WxCacheHelper {
return token;
}
public static String getJsapiTicket() {
JsapiTicket jsapiTicket = getWxJsapiTicket();
if (jsapiTicket != null) {
@ -136,4 +142,36 @@ public class WxCacheHelper {
return null;
}
private synchronized static void createAuthSessionIdManager() {
if (AID_CACHE == null) {
AID_CACHE = EhCacheConfig.createCacheTTL(String.class, String.class, "auth_session_id_cache", (3600L)); // 一个小时
}
}
public static String getOpenIdByAIDCache(String authSessionId) {
if (AID_CACHE == null) {
createAuthSessionIdManager();
}
if (ObjectUtils.isEmpty(authSessionId)) {
return null;
}
if (AID_CACHE.containsKey(authSessionId)) {
return AID_CACHE.get(authSessionId);
}
return null;
}
public static void putOpenIdToAIDCache(String authSessionId, String openId) {
if (AID_CACHE == null) {
createAuthSessionIdManager();
}
if (ObjectUtils.isEmpty(authSessionId)) {
return;
}
if (!AID_CACHE.containsKey(authSessionId)) {
AID_CACHE.put(authSessionId, openId);
}
}
}

Loading…
Cancel
Save