微信后端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

333 lines
14 KiB

package com.ynxbd.common.action.pay;
import com.alibaba.fastjson.JSONObject;
import com.ynxbd.common.action.base.BaseAction;
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.bean.pay.Register;
import com.ynxbd.common.dao.RecipeDao;
import com.ynxbd.common.dao.his.HisMedicalDao;
import com.ynxbd.common.helper.common.AesHelper;
import com.ynxbd.common.helper.common.Base64Helper;
import com.ynxbd.common.helper.common.DateHelper;
import com.ynxbd.common.helper.common.HttpHelper;
import com.ynxbd.common.result.JsonResult;
import com.ynxbd.common.result.Result;
import com.ynxbd.common.result.ResultEnum;
import com.ynxbd.common.result.ServiceException;
import com.ynxbd.common.service.MedicalService;
import com.ynxbd.common.service.params.RegParams;
import com.ynxbd.wx.wxfactory.WxCacheHelper;
import com.ynxbd.wx.wxfactory.WxMedicalHelper;
import com.ynxbd.wx.wxfactory.WxPayHelper;
import com.ynxbd.wx.wxfactory.bean.*;
import com.ynxbd.wx.wxfactory.medical.MdConfig;
import com.ynxbd.wx.wxfactory.utils.MdRespHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import java.math.BigDecimal;
import java.util.List;
/**
* @Author wsq
* @Date 2020/9/14 15:43
* @Copyright @ 2020 云南新八达科技有限公司 All rights reserved.
*/
@Slf4j
@Namespace("/medical")
public class MedicalAction extends BaseAction {
/**
* 用户信息获取 | 医保上传 | 医保支付下单
*/
@Action("getFeeDetails")
public Result getFeeDetails(String callNo, String payCode, String openid, String qrCode, String patientId, String cardNo, String realName, BigDecimal totalFee, Boolean isTime,String ybAttrib,String ybBZCode, String ybBZName) {
try {
log.info("【医保】上传明细下单 callNo={}, payCode={}, openid={}, qrCode={}, patientId={}, totalFee={}, ybAttrib={}, ybBZCode={}, ybBZName={}", callNo, payCode, openid, qrCode, patientId, totalFee,ybAttrib,ybBZCode,ybBZName);
if (callNo == null || payCode == null || openid == null || qrCode == null || patientId == null || cardNo == null || totalFee == null) {
return Result.error(ResultEnum.PARAM_IS_DEFECT);
}
MedicalInfo medicalInfo;
switch (PEnum.toEnum(callNo)) {
case REG:
Register reg = RegParams.getRegParams(request, true);
if ("*".equals(reg.getRegCode())) {
return Result.error("任意医师的号源不能进行医保支付");
}
if (!DateHelper.isToday(reg.getRegDate())) {
return Result.error("医保支付仅支持今日挂号");
}
medicalInfo = MedicalService.regMdUploadFeeDetails(qrCode, openid, patientId, cardNo, realName, reg, isTime);
break;
case RECIPE:
String treatNum = getString("treatNum");
String recipeJson = getString("recipeJson");
if (treatNum == null || recipeJson == null) {
return Result.error(ResultEnum.PARAM_IS_DEFECT);
}
medicalInfo = MedicalService.recipeMdUploadFeeDetails(qrCode, openid, patientId, cardNo, realName, treatNum, recipeJson, totalFee,ybAttrib,ybBZCode,ybBZName);
break;
default:
return Result.error("调用方式不存在");
}
return Result.success(medicalInfo);
} catch (ServiceException e) {
return Result.error(e);
}
}
/**
* 获取授权链接
*/
@Action("getRefundAuthUrl")
public Result getRefundAuthUrl() {
JSONObject respJson = WxMedicalHelper.getMdAuthUrl("wx-medical-refund.html", null);
return Result.success(respJson);
}
/**
* 获取对账链接
* @param billDate 账单日期
* @param billType 账单类型 ALL,返回当日所有订单信息,默认 SUCCESS,返回当日成功支付的订单 REFUND,返回当日退款订单
* @param key 加密密钥
* @return 下载链接
*/
@Action("downBill")
public Result downBill(String billDate, String billType, String key) {
log.info("[医保]下载对账订单,billDate-{}, billType-{}, key-{}",billDate,billType,key);
if(billDate== null || billType == null){
return Result.error(ResultEnum.PARAM_IS_DEFECT);
}
if (!DateHelper.getCurDate().equals(AesHelper.deCode(key))) {
return Result.error(ResultEnum.PARAM_IS_INVALID);
}
return Result.success(WxMedicalHelper.downBill(billDate,billType));
}
/**
* 医保支付下单
*
* @param openid openid
* @param payOrdId 医保订单号
* @param payAuthNo 用户授权码
* @param chrgBchno 收费单据号
* @param mdUserId 医保用户id
* @param totalFee 支付总金额
* @param acctFee 医保个账支付金额
* @param cashFee 现金支付金额
* @param cardNo 卡号
* @param realName 用户真实姓名
*/
@Action("order")
public Result order(String callNo, String payCode, String openid, String patientId, String cardNo, String realName, String treatNum, String payOrdId, String payAuthNo, String mdTrtId, String chrgBchno, String mdUserId,
BigDecimal totalFee, BigDecimal acctFee, BigDecimal hifpFee, BigDecimal insuranceFee, BigDecimal cashFee, String notifyType) {
try {
log.info("【医保】下单 callNo={}, payCode={}, openid={}, patientId={}, totalFee={}", callNo, payCode, openid, patientId, totalFee);
if (callNo == null || payCode == null || openid == null || patientId == null || cardNo == null || totalFee == null) {
return Result.error(ResultEnum.PARAM_IS_DEFECT);
}
String ip = HttpHelper.getIpAddress(request);
switch (PEnum.toEnum(callNo)) {
case REG:
Register reg = RegParams.getRegParams(request, true);
return MedicalService.createRegOrder(payCode, openid, cardNo, realName, ip, payOrdId, payAuthNo, mdTrtId, chrgBchno, mdUserId,
totalFee, acctFee, hifpFee, insuranceFee, cashFee,
callNo, reg);
case RECIPE:
String recipeJson = getString("recipeJson");
if (recipeJson == null) {
return Result.error(ResultEnum.PARAM_IS_BLANK);
}
String payWay = getString("payWay");
return MedicalService.createOrder(payCode, openid, patientId, cardNo, realName, ip,
payOrdId, payAuthNo, mdTrtId, chrgBchno, mdUserId,
totalFee, acctFee, hifpFee, insuranceFee, cashFee,
callNo, recipeJson, treatNum, payWay);
default:
return Result.error("调用方式不存在");
}
} catch (ServiceException e) {
return Result.error(e);
}
}
/**
* HIS医保退费(线上)
*/
@Action("refundMedical")
public Result refundMedical(String callNo, String openid, String qrCode, String outTradeNo, String tradeNo) {
try {
tradeNo = Base64Helper.decodeEn(tradeNo);
log.info("[医保退费] callNo={}, openid={}, qrCode={}, outTradeNo={}, tradeNo={}", callNo, openid, qrCode, outTradeNo, tradeNo);
if (openid == null || qrCode == null || outTradeNo == null || tradeNo == null) {
return Result.error(ResultEnum.PARAM_IS_DEFECT);
}
MedicalUserInfo userInfo = WxMedicalHelper.getUserInfo(openid, qrCode, null, null);
RecipeDao recipeDao = new RecipeDao();
Recipe recipe = recipeDao.selectByTradeNo(tradeNo);
if (recipe == null) {
return Result.error(ResultEnum.DATA_NOT_FOUND);
}
Integer payStatus = recipe.getPayStatus();
Integer hisStatus = recipe.getHisStatus();
String chrgBchno = recipe.getChrgBchno();
String bankTransNo = recipe.getBankTransNo();
String mdUserId = recipe.getMdUserId();
BigDecimal cashFee = recipe.getPayMoney();
BigDecimal acctFee = recipe.getAcctFee();
BigDecimal hifpFee = recipe.getHifpFee();
if (payStatus == null || hisStatus == null || chrgBchno == null || bankTransNo == null || mdUserId == null || cashFee == null || acctFee == null || hifpFee == null) {
log.info("【医保】退费参数缺失 outTradeNo={}, bankTransNo={}, payStatus={}, hisStatus={}, chrgBchno={}, cashFee={}, acctFee={}, hifpFee={}", outTradeNo, bankTransNo, payStatus, hisStatus, chrgBchno, cashFee, acctFee, hifpFee);
return Result.error(ResultEnum.PAY_ORDER_PARAMS_IS_DEFECT);
}
BigDecimal insuranceFee = acctFee.add(hifpFee);
if (payStatus != 0) { // 都已成功禁止退费
return Result.error(ResultEnum.PAY_ORDER_NO_PAY);
}
// if (hisStatus == 0) { // 都已成功禁止退费
// return Result.error(ResultEnum.PAY_ORDER_NO_PAY);
// }
Result result = MedicalService.refund(userInfo.getPayAuthNo(), chrgBchno.substring(1), outTradeNo, bankTransNo, tradeNo, mdUserId, cashFee, insuranceFee);
String message = result.isSuccess() ? WxPayHelper.OK : result.getMessage();
if (!recipeDao.updateRefundRByTradeNo(tradeNo, message)) {
log.info("【医保】修改退费信息失败 [{}] outTradeNo={}, tradeNo={}", message, outTradeNo, tradeNo);
}
if (result.isSuccess()) {
return Result.success();
}
return Result.error();
} catch (ServiceException e) {
return Result.error(e);
}
}
/**
* 获取需要退费的订单
*/
@Action("getRefundList")
public Result getRefundList(String openid, String begDate, String endDate) {
log.info("查询需退费订单 begDate={}, endDate={}", begDate, endDate);
RecipeDao recipeDao = new RecipeDao();
List<Order> orders = recipeDao.selectRefundList(openid, begDate, endDate);
for (Order order : orders) {
if (order.getTradeNo() != null) {
order.setTradeNo(Base64Helper.encode(order.getTradeNo(), true));
}
}
return Result.success(orders);
}
/**
* HIS医保退费
*/
@Action("getHisAccountsInfo")
public Result getHisAccountsInfo(String mdUserId) {
JsonResult jsonResult = HisMedicalDao.getMedicalAccounts(mdUserId);
return Result.success(jsonResult);
}
/**
* [医保]微信支付订单查询
*
* @param outTradeNo 订单号
* @param medTransId 医保交易流水号
*/
@Action("queryOrder")
public Result queryOrder(String outTradeNo, String medTransId) {
log.info("【医保】现金退费 outTradeNo={}, medTransId={}", outTradeNo, medTransId);
MedicalOrder order = WxMedicalHelper.queryOrder(WxCacheHelper.getAccessToken(), outTradeNo, medTransId);
if (order.isOk()) {
return Result.success(order);
}
return Result.error(order.getMessage());
}
/**
* HIS医保退费
*/
@Action("queryRefund")
public Result queryRefund(String accessToken, String outTradeNo, String mdTransId) {
MedicalRefundInfo info = WxMedicalHelper.queryRefund(accessToken, outTradeNo, mdTransId);
return Result.success(info);
}
// /**
// * HIS医保退费
// */
// @Action("queryRefund")
// public Result queryRefund(String accessToken, String outTradeNo, String mdTransId) {
// MedicalRefundInfo info = WxMedicalHelper.queryRefund(accessToken, outTradeNo, mdTransId);
// return Result.success(info);
// }
/**
* 回调通知
*/
@Action("payNotify")
public Result payNotify() {
log.info("[医保]回调通知------------------------------");
try {
MedicalNotify notifyInfo = WxMedicalHelper.medicalPayNotify(request);
// 成功返回
Result.respXml(MdRespHelper.respOk(MdConfig.PAY_KEY));
String openid = notifyInfo.getOpenid();
String bankTransNo = notifyInfo.getMedTransId();
String outTradeNo = notifyInfo.getHospOutTradeNo();
String payInfo = notifyInfo.getInfo();
// BigDecimal totalFee = notifyInfo.getTotalFee();
String payDate = notifyInfo.getPayDate();
String payTime = notifyInfo.getPayTime();
String notifyType = notifyInfo.getAttach();
log.info("【医保】[{}] 收到通知 outTradeNo={}, bankTransNo={}, notifyType={}", notifyType, outTradeNo, bankTransNo, notifyType);
switch (PEnum.toEnum(notifyType)) {
case RECIPE:
MedicalService.recipePay(MerchantEnum.WX, outTradeNo, bankTransNo, payDate, payTime, openid, payInfo);
break;
case REG: // 挂号
MedicalService.regPay(MerchantEnum.WX, outTradeNo, bankTransNo, payDate, payTime, openid, payInfo);
break;
case IN_HOSP:
break;
default:
log.info("【医保】通知类型错误");
break;
}
return null;
} catch (ServiceException e) {
return Result.respXml(MdRespHelper.resp(e, MdConfig.PAY_KEY));
}
}
}