|
|
|
|
package com.ynxbd.common.service;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.util.HexUtil;
|
|
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
import com.ynxbd.common.action.pay.PEnum;
|
|
|
|
|
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.common.RSAHelper;
|
|
|
|
|
import com.ynxbd.common.helper.http.OkHttpHelper;
|
|
|
|
|
import com.ynxbd.common.helper.xbd.XbdConfigHelper;
|
|
|
|
|
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.nio.charset.StandardCharsets;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @author 王绍全
|
|
|
|
|
* @ClassName PEISService
|
|
|
|
|
* @Description TODO
|
|
|
|
|
* @date 2025/12/17 15:53:00
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
@Slf4j
|
|
|
|
|
public class PEISService {
|
|
|
|
|
private final String PEIS_SUCCESS_CODE = "200";
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JsonResult jsonResult = postForm(XbdConfigHelper.PEIS_URL + "/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, message, 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(XbdConfigHelper.PEIS_URL + "/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 noticeResult, 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, noticeResult);
|
|
|
|
|
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(XbdConfigHelper.PEIS_URL + "/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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 体检影像报告
|
|
|
|
|
*
|
|
|
|
|
* @param cardNo 加密后的证件号
|
|
|
|
|
* @param begDate 开始时间
|
|
|
|
|
* @param endDate 结束时间
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray queryPEISRecordByCardNo(String cardNo, String begDate, String endDate) throws Exception {
|
|
|
|
|
String enIdCard = HexUtil.encodeHexStr(RSAHelper.enBytePKCS1Padding(cardNo, "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5klqI5STWTcbfjR093j+hvCEjNlZMQscIJg8jxZGqKW84AdFmSqPWEPu9ilqP+QUASiVSZ1QevGr2DWODFZ8Zw35aDA2bqCEprUx81gDdVPO7H7Bij+r8zAg8fT2c0Bi5rFq0xWMEQiTI+CyWwc5prOpquJU/P5yauEAdkRzlDwIDAQAB"));
|
|
|
|
|
|
|
|
|
|
RequestBody formBody = new FormBody.Builder().
|
|
|
|
|
add("enIdCard", enIdCard)
|
|
|
|
|
.add("begDate", begDate)
|
|
|
|
|
.add("endDate", endDate)
|
|
|
|
|
.build();
|
|
|
|
|
String result = OkHttpHelper.post(XbdConfigHelper.PEIS_URL + "/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");
|
|
|
|
|
String message = jsonResult.getString("message");
|
|
|
|
|
if (!PEIS_SUCCESS_CODE.equals(code)) {
|
|
|
|
|
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);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
}
|