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.
596 lines
29 KiB
596 lines
29 KiB
package com.ynxbd.common.service;
|
|
|
|
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.Recipe;
|
|
import com.ynxbd.common.bean.pay.Register;
|
|
import com.ynxbd.common.dao.RecipeDao;
|
|
import com.ynxbd.common.dao.RegisterDao;
|
|
import com.ynxbd.common.dao.his.HisMedicalDao;
|
|
import com.ynxbd.common.helper.common.CodeHelper;
|
|
import com.ynxbd.common.helper.common.JsonHelper;
|
|
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.wx.config.WeChatConfig;
|
|
import com.ynxbd.wx.wxfactory.WxMedicalHelper;
|
|
import com.ynxbd.wx.wxfactory.WxPayHelper;
|
|
import com.ynxbd.wx.wxfactory.bean.MedicalInfo;
|
|
import com.ynxbd.wx.wxfactory.bean.MedicalOrder;
|
|
import com.ynxbd.wx.wxfactory.bean.MedicalUserInfo;
|
|
import com.ynxbd.wx.wxfactory.bean.OrderTypeEnum;
|
|
import com.ynxbd.wx.wxfactory.medical.MdConfig;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
import java.math.BigDecimal;
|
|
import java.util.Map;
|
|
|
|
@Slf4j
|
|
public class MedicalService {
|
|
|
|
|
|
/**
|
|
* [医保]挂号上报
|
|
*
|
|
* @param qrCode 授权码
|
|
* @param openid openid
|
|
* @param patientId 患者id
|
|
* @param cardNo 卡号
|
|
* @param realName 真实姓名
|
|
* @param reg 挂号信息
|
|
*/
|
|
public static MedicalInfo regMdUploadFeeDetails(String qrCode, String openid, String patientId, String cardNo, String realName, Register reg, Boolean isTime) throws ServiceException {
|
|
MedicalUserInfo userInfo = WxMedicalHelper.getUserInfo(openid, qrCode, cardNo, realName);
|
|
|
|
String payAuthNo = userInfo.getPayAuthNo();
|
|
|
|
log.info("[医保]上传明细:patientId={}, cardNo={}, realName={}, reg={}", patientId, cardNo, realName, reg);
|
|
JsonResult result = HisMedicalDao.regTimeMdUploadFeeDetails(reg, payAuthNo, cardNo, MerchantEnum.WX, isTime);
|
|
return mdPlaceOrder(payAuthNo, result);
|
|
}
|
|
|
|
/**
|
|
* [医保]处方上报
|
|
*
|
|
* @param qrCode 授权码
|
|
* @param openid openid
|
|
* @param patientId 患者id
|
|
* @param cardNo 卡号
|
|
* @param realName 真实姓名
|
|
* @param treatNum 门诊号
|
|
* @param recipeJson 处方json
|
|
* @param totalFee 订单金额
|
|
*/
|
|
public static MedicalInfo recipeMdUploadFeeDetails(String qrCode, String openid, String patientId, String cardNo, String realName, String treatNum, String recipeJson, BigDecimal totalFee, String ybAttrib, String ybBZCode, String ybBZName) throws ServiceException {
|
|
MedicalUserInfo userInfo = WxMedicalHelper.getUserInfo(openid, qrCode, cardNo, realName);
|
|
|
|
String payAuthNo = userInfo.getPayAuthNo();
|
|
|
|
log.info("[医保]上传明细:patientId={}, totalFee={}, cardNo={}, recipeJson={}", patientId, totalFee, cardNo, recipeJson);
|
|
JsonResult result = HisMedicalDao.recipeMdUploadFeeDetails(payAuthNo, cardNo, openid, patientId, treatNum, recipeJson, totalFee, ybAttrib, ybBZCode, ybBZName);
|
|
return mdPlaceOrder(payAuthNo, result);
|
|
}
|
|
|
|
|
|
/**
|
|
* [医保]下单
|
|
*
|
|
* @param payAuthNo 授权码
|
|
*/
|
|
private static MedicalInfo mdPlaceOrder(String payAuthNo, JsonResult result) throws ServiceException {
|
|
if (result == null) {
|
|
throw new ServiceException("[医保]返回数据为空");
|
|
}
|
|
if (!result.success()) {
|
|
log.info("[医保]费用明细上传失败 message={}", result.getMessage());
|
|
throw new ServiceException(result.getMessage());
|
|
}
|
|
String payOrdId = result.getDataMapString("PayOrdId");
|
|
String payToken = result.getDataMapString("PayToken");
|
|
String mdTrtId = result.getDataMapString("MdtrtId"); // 医保就诊ID
|
|
String chrgBchno = result.getDataMapString("ChrgBchno"); // 医疗机构订单号、收费批次号
|
|
String mdUserId = result.getDataMapString("UserID_YBZF"); // 医保用户ID
|
|
|
|
log.info("[医保]HIS费用上传明细接口返回 payAuthNo={}, payOrdId={}, payToken={}, mdtrtId={}, chrgBchno={}, userIdYBZF={}", payAuthNo, payOrdId, payToken, mdTrtId, chrgBchno, mdUserId);
|
|
if (payOrdId == null || payToken == null || mdTrtId == null || chrgBchno == null) {
|
|
throw new ServiceException("[医保]费用明细上传参数缺失");
|
|
}
|
|
|
|
MedicalInfo medicalInfo = new MedicalInfo();
|
|
medicalInfo.setPayAuthNo(payAuthNo);
|
|
medicalInfo.setPayToken(payToken);
|
|
medicalInfo.setPayOrdId(payOrdId);
|
|
medicalInfo.setMdTrtId(mdTrtId);
|
|
medicalInfo.setChrgBchno(chrgBchno);
|
|
medicalInfo.setMdUserId(mdUserId);
|
|
|
|
JsonResult resp = HisMedicalDao.mdPlaceOrder(medicalInfo);
|
|
if (!resp.success()) {
|
|
log.info("[上传明细失败] {}", resp.getMessage());
|
|
throw new ServiceException(resp.getMessage());
|
|
}
|
|
|
|
BigDecimal totalFee = resp.getDataMapBigDecimal("FeeSumamt"); // 订单总金额医保返回
|
|
String extData = resp.getDataMapString("ExtData");
|
|
log.info("extData={}", extData);
|
|
if (extData == null || totalFee == null) {
|
|
throw new ServiceException("[上传明细失败]响应参数缺失 extData is null");
|
|
}
|
|
JSONObject extDataJson = JsonHelper.parseObject(extData);
|
|
JSONObject preSetl = extDataJson.getJSONObject("preSetl");
|
|
|
|
medicalInfo.setMedFeeSumAmt(new BigDecimal(preSetl.getString("medfee_sumamt"))); // 医保金额
|
|
|
|
medicalInfo.setCashFee(new BigDecimal(preSetl.getString("psn_cash_pay"))); // 现金支付
|
|
BigDecimal acctPay = new BigDecimal(preSetl.getString("acct_pay"));
|
|
// BigDecimal hifpPay = new BigDecimal(preSetl.getString("hifp_pay"));
|
|
BigDecimal hifpPay = resp.getDataMapBigDecimal("FundPay");
|
|
medicalInfo.setAcctFee(acctPay); // 个人账户支付
|
|
medicalInfo.setHifpFee(hifpPay); // 统筹支付金额
|
|
medicalInfo.setTotalFee(totalFee); // 医保订单总金额
|
|
|
|
medicalInfo.setInsuranceFee(acctPay.add(hifpPay)); // (个账 + 统筹)
|
|
|
|
log.info("[医保]结算完成返回数据 medicalFee={}", medicalInfo);
|
|
return medicalInfo;
|
|
}
|
|
|
|
|
|
/**
|
|
* 微信下单
|
|
*/
|
|
public static Result createOrder(String payCode, String openid, String patientId, String cardNo, String realName, String ip, String payOrdId, String payAuthNo, String mdTrtId, String chrgBchno, String mdUserId, BigDecimal totalFee, BigDecimal acctFee, BigDecimal hifpFee, BigDecimal insuranceFee, BigDecimal cashFee, String notifyType,
|
|
String recipeJson, String treatNum, String payWay) {
|
|
Result result = PayService.isPaymentPermittedByTime();
|
|
if (result != null) {
|
|
return result;
|
|
}
|
|
MerchantEnum merchantEnum = MerchantEnum.findEnumByCode(payCode);
|
|
if (merchantEnum == null) { // 支付方式异常
|
|
return Result.error(ResultEnum.PAY_TYPE_ERROR);
|
|
}
|
|
|
|
// 0:公众号内支付,1:扫码支付
|
|
payWay = payWay == null ? "0" : payWay;
|
|
|
|
String outTradeNo = CodeHelper.getOutTradeNo(merchantEnum);
|
|
Recipe recipeInfo = new RecipeService().recipeJsonToInfo(treatNum, recipeJson);
|
|
log.info("[医保]处方json解析 info={}", recipeInfo);
|
|
if (recipeInfo == null) {
|
|
return Result.error(ResultEnum.PAY_PREPAY_SAVE_ERROR);
|
|
}
|
|
String recipeJsonStr = recipeInfo.getRecipeJson();
|
|
if (recipeJsonStr == null) {
|
|
return Result.error(ResultEnum.PAY_PREPAY_SAVE_ERROR);
|
|
}
|
|
|
|
log.info("[医保]下单 openid={}, outTradeNo={}, payOrdId={}, payAuthNo={}, totalFee={}, acctFee={}, cashFee={}, idCardNo={}, realName={}", openid, outTradeNo, payOrdId, payAuthNo, totalFee, acctFee, cashFee, cardNo, realName);
|
|
|
|
try {
|
|
Map<String, Object> map = WxMedicalHelper.createOrder(
|
|
OrderTypeEnum.DIAG_PAY,
|
|
outTradeNo,
|
|
chrgBchno,
|
|
openid,
|
|
cardNo,
|
|
realName,
|
|
ip,
|
|
payOrdId,
|
|
payAuthNo,
|
|
totalFee,
|
|
insuranceFee,
|
|
cashFee,
|
|
WeChatConfig.getBaseUrl() + merchantEnum.NOTIFY_URL,
|
|
WeChatConfig.getWebUrl() + "pay-info.html#/recipe-payed",
|
|
"门诊号:" + treatNum,
|
|
notifyType);
|
|
|
|
RecipeDao recipeDao = new RecipeDao();
|
|
// Recipe recipeInfo = recipeDao.selectByTradeNo(payOrdId);
|
|
|
|
Recipe addRecipe = new Recipe();
|
|
addRecipe.setOutTradeNo(outTradeNo);
|
|
addRecipe.setTradeNo(payOrdId);
|
|
addRecipe.setPayOrdId(payOrdId);
|
|
// -------------------------------------------
|
|
addRecipe.setChrgBchno(chrgBchno);
|
|
addRecipe.setMdUserId(mdUserId);
|
|
addRecipe.setMdTrtId(mdTrtId);
|
|
addRecipe.setRecipeJson(recipeJsonStr);
|
|
addRecipe.setDeptCode(recipeInfo.getDeptCode());
|
|
addRecipe.setDeptName(recipeInfo.getDeptName());
|
|
addRecipe.setReqDeptCode(recipeInfo.getReqDeptCode());
|
|
addRecipe.setReqDeptName(recipeInfo.getReqDeptName());
|
|
//
|
|
addRecipe.setPayMoney(cashFee); // 现金
|
|
addRecipe.setAcctFee(acctFee);
|
|
addRecipe.setHifpFee(hifpFee);
|
|
addRecipe.setTotalFee(totalFee);
|
|
//
|
|
addRecipe.setPayWay(payWay);
|
|
addRecipe.setOpenid(openid);
|
|
addRecipe.setPatientId(patientId);
|
|
addRecipe.setTreatNum(treatNum);
|
|
addRecipe.setBankTransNo(String.valueOf(map.get("bankTransNo")));
|
|
addRecipe.setPayStatus(-1);
|
|
addRecipe.setHisStatus(-1);
|
|
|
|
if (!recipeDao.insertMedical(addRecipe)) {
|
|
return Result.error(ResultEnum.DATA_INSERT_ERROR);
|
|
}
|
|
return Result.success(map);
|
|
|
|
} catch (ServiceException e) {
|
|
log.error(e.getMessage());
|
|
return Result.error(e);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 挂号下单
|
|
*/
|
|
public static Result createRegOrder(String payCode, String openid, String cardNo, String realName, String ip, String payOrdId, String payAuthNo, String mdTrtId, String chrgBchno, String mdUserId, BigDecimal totalFee, BigDecimal acctFee, BigDecimal hifpFee, BigDecimal insuranceFee, BigDecimal cashFee, String notifyType, Register reg) {
|
|
Result result = PayService.isPaymentPermittedByTime();
|
|
if (result != null) {
|
|
return result;
|
|
}
|
|
|
|
MerchantEnum merchantEnum = MerchantEnum.findEnumByCode(payCode);
|
|
if (merchantEnum == null) { // 支付方式异常
|
|
return Result.error(ResultEnum.PAY_TYPE_ERROR);
|
|
}
|
|
|
|
String outTradeNo = CodeHelper.getOutTradeNo(merchantEnum);
|
|
log.info("[医保]挂号下单 openid={}, outTradeNo={}, payOrdId={}, payAuthNo={}, totalFee={}, acctFee={}, cashFee={}, idCardNo={}, realName={}", openid, outTradeNo, payOrdId, payAuthNo, totalFee, acctFee, cashFee, cardNo, realName);
|
|
|
|
try {
|
|
Map<String, Object> map = WxMedicalHelper.createOrder(OrderTypeEnum.REG_PAY,
|
|
outTradeNo, chrgBchno, openid, cardNo, realName, ip, payOrdId, payAuthNo,
|
|
totalFee, insuranceFee, cashFee,
|
|
WeChatConfig.getBaseUrl() + merchantEnum.NOTIFY_URL,
|
|
WeChatConfig.getWebUrl() + "my-info.html",
|
|
"挂号",
|
|
notifyType);
|
|
|
|
RegisterDao regDao = new RegisterDao();
|
|
reg.setOutTradeNo(outTradeNo);
|
|
reg.setTradeNo(payOrdId);
|
|
reg.setPayOrdId(payOrdId);
|
|
|
|
reg.setPayMoney(cashFee);
|
|
reg.setAcctFee(acctFee);
|
|
reg.setHifpFee(hifpFee);
|
|
reg.setChrgBchno(chrgBchno);
|
|
reg.setMdTrtId(mdTrtId);
|
|
reg.setMdUserId(mdUserId);
|
|
reg.setPayDeviceId("mobile");
|
|
reg.setPayStatus(-1);
|
|
reg.setHisStatus(-1);
|
|
reg.setBankTransNo(String.valueOf(map.get("bankTransNo")));
|
|
reg.setPayWay(merchantEnum.PAY_WAY_IN);
|
|
|
|
if (!regDao.insertMedical(reg)) {
|
|
return Result.error(ResultEnum.DATA_INSERT_ERROR);
|
|
}
|
|
return Result.success(map);
|
|
|
|
} catch (ServiceException e) {
|
|
log.error(e.getMessage());
|
|
return Result.error(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* [医保]处方缴费
|
|
*
|
|
* @param merchantEnum 类型
|
|
* @param outTradeNo 订单号
|
|
* @param bankTransNo 交易流水(医保)
|
|
* @param payDate 支付日期
|
|
* @param payTime 支付时间
|
|
* @param openid openid
|
|
* @param payInfo 支付信息
|
|
*/
|
|
public static boolean regPay(MerchantEnum merchantEnum, String outTradeNo, String bankTransNo, String payDate, String payTime, String openid, String payInfo) {
|
|
if (outTradeNo == null || bankTransNo == null || payDate == null || payTime == null) {
|
|
log.info("[医保][挂号]HIS结算参数缺失 outTradeNo={}, bankTransNo={}, payDate={}, payTime={}", outTradeNo, bankTransNo, payDate, payTime);
|
|
return false;
|
|
}
|
|
RegisterDao regDao = new RegisterDao();
|
|
Register reg = regDao.selectByOutTradeNo(outTradeNo);
|
|
if (reg == null) {
|
|
log.info("{} [挂号]数据库中未找到订单 outTradeNo={}, bankTransNo={}", merchantEnum.NAME, outTradeNo, bankTransNo);
|
|
return true;
|
|
}
|
|
Integer hisStatus = reg.getHisStatus();
|
|
Integer payStatus = reg.getPayStatus();
|
|
if (payStatus == null || hisStatus == null || payStatus == 0 || hisStatus == 0) { // 状态不明确
|
|
log.info("{}[医保][挂号]订单已支付 outTradeNo={}, bankTransNo={}", merchantEnum.NAME, outTradeNo, bankTransNo);
|
|
return true;
|
|
}
|
|
|
|
if (!regDao.updateMerPaidByOutTradeNo(outTradeNo, payDate, payTime, bankTransNo)) {
|
|
log.info("[医保][挂号]修改订单支付状态 outTradeNo={}, bankTransNo={}", outTradeNo, bankTransNo);
|
|
return false;
|
|
}
|
|
|
|
reg.setPayDate(payDate);
|
|
reg.setPayTime(payTime);
|
|
reg.setBankTransNo(bankTransNo);
|
|
|
|
String mdUserId = reg.getMdUserId();
|
|
String tradeNo = reg.getTradeNo(); // 医保订单号
|
|
String chrgBchno = reg.getChrgBchno();
|
|
BigDecimal cashFee = reg.getPayMoney(); // 现金
|
|
BigDecimal acctFee = reg.getAcctFee(); // 个账
|
|
if (mdUserId == null || tradeNo == null || chrgBchno == null || cashFee == null || acctFee == null) {
|
|
log.info("[医保][挂号]HIS结算参数缺失 outTradeNo={}, bankTransNo={}, tradeNo={}, mdUserId={}, chrgBchno={}", outTradeNo, bankTransNo, tradeNo, mdUserId, chrgBchno);
|
|
return false;
|
|
}
|
|
|
|
JsonResult jsonResult = HisMedicalDao.regMdPay(mdUserId, payDate, payTime, tradeNo, bankTransNo, cashFee);
|
|
if (!jsonResult.success()) {
|
|
String respCode = jsonResult.getCode();
|
|
String respMessage = jsonResult.getMessage();
|
|
log.info("[医保][挂号]HIS结算失败 outTradeNo={}, bankTransNo={}, respCode={}, respMessage={}", outTradeNo, bankTransNo, respCode, respMessage);
|
|
|
|
if (!regDao.updateHisPaidFailByOutTradeNo(outTradeNo, respCode, respMessage)) {
|
|
log.info("[医保][挂号]更新HIS缴费失败信息异常 outTradeNo={}, code={}, message={}", outTradeNo, respCode, respMessage);
|
|
}
|
|
|
|
if (jsonResult.isTimeout()) { // 调用超时-不退费
|
|
log.info("[医保][挂号]HIS结算调用超时 outTradeNo={}, bankTransNo={}, tradeNo={}, mdUserId={}", outTradeNo, bankTransNo, tradeNo, mdUserId);
|
|
return false;
|
|
}
|
|
|
|
if (!MdConfig.IS_AUTO_REFUND) {
|
|
log.info("[医保][挂号]现金自动退费功能未开启 outTradeNo={}, bankTransNo={}, tradeNo={}", outTradeNo, bankTransNo, tradeNo);
|
|
return false;
|
|
}
|
|
|
|
if (respMessage != null && !respMessage.contains("(医保结算部分已回退)")) {
|
|
log.info("[医保][挂号]HIS医保部分未退费成功,禁止现金部分退费 outTradeNo={}, bankTransNo={}, tradeNo={}", outTradeNo, bankTransNo, tradeNo);
|
|
return false;
|
|
}
|
|
|
|
if (cashFee.compareTo(BigDecimal.ZERO) == 0) { // 现金部分为0
|
|
log.info("[医保][挂号]现金为0不执行退费 outTradeNo={}, bankTransNo={}, tradeNo={}", outTradeNo, bankTransNo, tradeNo);
|
|
return false;
|
|
}
|
|
|
|
// 微信医保自动退费
|
|
MedicalOrder order = WxMedicalHelper.refundCash(outTradeNo, tradeNo, cashFee, "系统繁忙缴费失败,自动退费");
|
|
boolean isOk = order.isOk();
|
|
String refundResult = order.isOk() ? WxPayHelper.OK : order.getMessage();
|
|
|
|
log.info("【微信】[医保][挂号]现金自动退费 outTradeNo={}, bankTransNo={}, tradeNo={} [{}]:{}", outTradeNo, bankTransNo, tradeNo, (isOk ? "成功" : "失败"), order.getMessage());
|
|
if (!regDao.updateRefundByTradeNo(tradeNo, refundResult)) {
|
|
log.info("【微信】[医保][挂号]现金自动退费 修改数据库状态失败 tradeNo={}, refundResult={}", tradeNo, refundResult);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
log.info("[医保][挂号]HIS结算成功 outTradeNo={}, bankTransNo={}", outTradeNo, bankTransNo);
|
|
// 成功处理
|
|
if (!regDao.updateHisPaidByOutTradeNo(outTradeNo)) {
|
|
log.error("[医保][挂号]修改成功数据失败");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* [医保]处方缴费
|
|
*
|
|
* @param merchantEnum 类型
|
|
* @param outTradeNo 订单号
|
|
* @param bankTransNo 交易流水(医保)
|
|
* @param payDate 支付日期
|
|
* @param payTime 支付时间
|
|
* @param openid openid
|
|
* @param payInfo 支付信息
|
|
*/
|
|
public static boolean recipePay(MerchantEnum merchantEnum, String outTradeNo, String bankTransNo, String payDate, String payTime, String openid, String payInfo) {
|
|
if (outTradeNo == null || bankTransNo == null || payDate == null || payTime == null) {
|
|
log.info("[医保][处方]HIS结算参数缺失 outTradeNo={}, bankTransNo={}, payDate={}, payTime={}", outTradeNo, bankTransNo, payDate, payTime);
|
|
return false;
|
|
}
|
|
RecipeDao recipeDao = new RecipeDao();
|
|
|
|
// 此处判断是否已经发起缴费,只要已存在数据库记录,说明已经发起了缴费请求,不能根据已经缴费成功,才取消本次缴费请求,因为请求可能已经延时,本次请求可能是重复提交的请求
|
|
if (PayService.hasUserOrderNo(outTradeNo, openid)) {
|
|
log.info("{}[医保][处方]已发起缴费 outTradeNo={}", merchantEnum.NAME, outTradeNo);
|
|
return false;
|
|
}
|
|
|
|
if (payInfo != null) {
|
|
PayService.saveOrderNo(PEnum.RECIPE, outTradeNo, openid, payInfo, null);
|
|
}
|
|
|
|
Recipe recipe = recipeDao.selectOneByOutTradeNo(outTradeNo);
|
|
if (recipe == null) {
|
|
log.info("[医保][处方]数据库中未查询到订单信息 outTradeNo={}, bankTransNo={}", outTradeNo, bankTransNo);
|
|
return false;
|
|
}
|
|
|
|
String mdUserId = recipe.getMdUserId();
|
|
String tradeNo = recipe.getTradeNo(); // 医保订单号
|
|
String chrgBchno = recipe.getChrgBchno();
|
|
BigDecimal cashFee = recipe.getPayMoney(); // 现金
|
|
BigDecimal acctFee = recipe.getAcctFee(); // 个账
|
|
if (mdUserId == null || tradeNo == null || chrgBchno == null || cashFee == null || acctFee == null) {
|
|
log.info("[医保][处方]HIS结算参数缺失 outTradeNo={}, bankTransNo={}, tradeNo={}, mdUserId={}, chrgBchno={}", outTradeNo, bankTransNo, tradeNo, mdUserId, chrgBchno);
|
|
return false;
|
|
}
|
|
|
|
Integer hisStatus = recipe.getHisStatus();
|
|
if (hisStatus != null && hisStatus == 0) {
|
|
log.info("{} [医保][处方]已交过费, 结束本次缴费流程:outTradeNo={}, bankTransNo={}", merchantEnum.NAME, outTradeNo, bankTransNo);
|
|
return false;
|
|
}
|
|
|
|
if (recipeDao.updateMerPaidByTradeNo(tradeNo, bankTransNo)) {
|
|
log.info("{} [医保][处方]更新商户信息成功 outTradeNo={}, bankTransNo={}", merchantEnum.NAME, outTradeNo, bankTransNo);
|
|
}
|
|
|
|
JsonResult jsonResult = HisMedicalDao.mdRecipePay(mdUserId, payDate, payTime, tradeNo, bankTransNo, cashFee);
|
|
|
|
if (!jsonResult.success()) {
|
|
String respCode = jsonResult.getCode();
|
|
String respMessage = jsonResult.getMessage();
|
|
log.info("[医保][处方]HIS结算失败 outTradeNo={}, bankTransNo={}, respCode={}, respMessage={}", outTradeNo, bankTransNo, respCode, respMessage);
|
|
|
|
if (!recipeDao.updateHisPaidFailByTradeNo(tradeNo, respCode, respMessage)) {
|
|
log.info("[医保][处方]更新HIS缴费失败信息失败 tradeNo={}, code={}, message={}", tradeNo, respCode, respMessage);
|
|
}
|
|
|
|
if (jsonResult.isTimeout()) { // 调用超时-不退费
|
|
log.info("[医保][处方]HIS结算调用超时-不退费 outTradeNo={}, bankTransNo={}, tradeNo={}, mdUserId={}", outTradeNo, bankTransNo, tradeNo, mdUserId);
|
|
return false;
|
|
}
|
|
|
|
if (!MdConfig.IS_AUTO_REFUND) {
|
|
log.info("[医保][处方][现金自动退费]功能未开启 outTradeNo={}, bankTransNo={}, tradeNo={}", outTradeNo, bankTransNo, tradeNo);
|
|
return false;
|
|
}
|
|
|
|
if (respMessage != null && !respMessage.contains("(医保结算部分已回退)")) {
|
|
log.info("[医保][处方]HIS医保部分未退费成功,禁止现金部分退费 outTradeNo={}, bankTransNo={}, tradeNo={}", outTradeNo, bankTransNo, tradeNo);
|
|
return false;
|
|
}
|
|
|
|
// 微信医保自动退费
|
|
if (cashFee.compareTo(BigDecimal.ZERO) == 0) { // 现金部分为0
|
|
log.info("[医保][处方]现金为0不执行退费 outTradeNo={}, bankTransNo={}, tradeNo={}", outTradeNo, bankTransNo, tradeNo);
|
|
return false;
|
|
}
|
|
MedicalOrder order = WxMedicalHelper.refundCash(outTradeNo, tradeNo, cashFee, "系统繁忙缴费失败,自动退费");
|
|
boolean isOk = order.isOk();
|
|
String refundResult = order.isOk() ? WxPayHelper.OK : order.getMessage();
|
|
log.info("【微信】[医保][处方]现金自动退费 outTradeNo={}, bankTransNo={}, tradeNo={} [{}]:{}", outTradeNo, bankTransNo, tradeNo, (isOk ? "成功" : "失败"), order.getMessage());
|
|
if (!recipeDao.updateRefundByTradeNo(tradeNo, refundResult)) {
|
|
log.info("[医保][处方]现金自动退费 修改数据库状态失败 tradeNo={}, refundResult={}", tradeNo, refundResult);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
String hisTransNo = jsonResult.getDataMapString("HISTransNo");
|
|
String invoiceTransNo = jsonResult.getDataMapString("InvoiceTransNo");
|
|
|
|
log.info("[医保][处方]HIS结算成功 outTradeNo={}, bankTransNo={}, hisTransNo={}, invoiceTransNo={}", outTradeNo, bankTransNo, hisTransNo, invoiceTransNo);
|
|
// 成功处理
|
|
if (!recipeDao.updateHisPaidByTradeNo(tradeNo, hisTransNo, invoiceTransNo)) {
|
|
log.error("[医保][处方]修改成功数据失败");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* [医保]退费流程
|
|
*
|
|
* @param outTradeNo 订单号
|
|
* @param bankTransNo 交易流水号
|
|
* @param tradeNo HIS交易流水号(医保订单号)
|
|
* @param payAuthNo 用户授权码
|
|
* @param fpNum 发票号(退费去掉M)
|
|
* @param cashFee 现金金额
|
|
* @param insuranceFee 医保金额
|
|
*/
|
|
public static Result refund(String payAuthNo, String fpNum, String outTradeNo, String bankTransNo, String tradeNo, String mdUserId, BigDecimal cashFee, BigDecimal insuranceFee) {
|
|
if (insuranceFee.compareTo(BigDecimal.ZERO) == 0 && cashFee.compareTo(BigDecimal.ZERO) == 0) {
|
|
log.info("【医保】[处方]退费金额为0不退费");
|
|
return Result.error("【医保】[处方]金额为0不退费");
|
|
}
|
|
|
|
// 医保退费-必须先执行
|
|
|
|
log.info("【医保】[处方][个账]退费开始 tradeNo={}, payAuthNo={}, fpNum={}", tradeNo, payAuthNo, fpNum);
|
|
JsonResult jsonResult = HisMedicalDao.mdRefund(payAuthNo, fpNum, bankTransNo, ("R" + tradeNo), cashFee);
|
|
if (!jsonResult.success()) { // 失败
|
|
log.info("【医保】[处方][个账]退费失败 outTradeNo={}, bankTransNo={}, tradeNo={}", outTradeNo, bankTransNo, tradeNo);
|
|
String message = jsonResult.getMessage();
|
|
if (message != null && !message.contains("已医保全部退款")) {
|
|
return Result.error(message);
|
|
}
|
|
}
|
|
// String hisRefundNo = jsonResult.getDataMapString("N_FPNum"); // His生成的退费流水号
|
|
|
|
log.info("[医保]HIS退费返回 fpNum={} resp={}", fpNum, jsonResult.getDataMap());
|
|
|
|
// 现金退费
|
|
if (cashFee.compareTo(BigDecimal.ZERO) != 0) {
|
|
log.info("【医保】[处方]现金开始退费");
|
|
// MedicalInfo info = getMedicalAccounts(mdUserId);
|
|
// if (info == null) {
|
|
// return Result.error("[订单]未找到结算信息");
|
|
// }
|
|
//
|
|
// String status = info.getStatus();
|
|
// String statusCode = info.getStatusCode();
|
|
// if ("8".equals(statusCode)) { // 8 : 已医保全部退款
|
|
// log.info("[处方][现金]退费开始 tradeNo={}", tradeNo);
|
|
// MedicalOrder order = WxMedicalHelper.refund(WxCacheHelper.getAccessToken(), outTradeNo, ("R" + tradeNo), tradeNo, cashFee.toString());
|
|
// boolean isOk = order.isOk();
|
|
// log.info("[处方][现金]退费{} outTradeNo={}, bankTransNo={}, tradeNo={}", (isOk ? "成功" : "失败"), outTradeNo, bankTransNo, tradeNo);
|
|
// if (isOk) {
|
|
// return Result.success();
|
|
// }
|
|
// return Result.error(order.getMessage());
|
|
// }
|
|
|
|
MedicalOrder order = WxMedicalHelper.refund(outTradeNo, ("R" + tradeNo), tradeNo, cashFee, null);
|
|
boolean isOk = order.isOk();
|
|
log.info("[处方][现金]退费{} outTradeNo={}, bankTransNo={}, tradeNo={}", (isOk ? "成功" : "失败"), outTradeNo, bankTransNo, tradeNo);
|
|
if (isOk) {
|
|
return Result.success();
|
|
}
|
|
return Result.error(order.getMessage());
|
|
}
|
|
return Result.success();
|
|
}
|
|
|
|
|
|
// /**
|
|
// * 医保退费
|
|
// *
|
|
// * @param payAuthNo 用户授权码
|
|
// * @param fpNum 发票号
|
|
// */
|
|
// public static Result medicalRefund(String payAuthNo, String fpNum) {
|
|
// log.info("[医保]退费开始 payAuthNo={}, fpNum={}", payAuthNo, fpNum);
|
|
// JsonResult jsonResult = HisMedicalDao.medicalRefund(payAuthNo, fpNum);
|
|
// if (!jsonResult.success()) {
|
|
// return Result.error(jsonResult.getMessage());
|
|
// }
|
|
//
|
|
// log.info("[医保]退费 fpNum={} resp={}", fpNum, jsonResult.getDataMap());
|
|
//// String hisRefundNo = jsonResult.getDataMapString("N_FPNum"); // His生成的退费流水号
|
|
// return Result.success();
|
|
// }
|
|
|
|
|
|
/**
|
|
* [医保]结算信息查询
|
|
*
|
|
* @param mdUserId 用户ID
|
|
*/
|
|
public static MedicalInfo getMedicalAccounts(String mdUserId) {
|
|
log.info("[医保]退费开始 mdUserId={}", mdUserId);
|
|
JsonResult jsonResult = HisMedicalDao.getMedicalAccounts(mdUserId);
|
|
if (!jsonResult.success()) { // 未找到
|
|
return null;
|
|
}
|
|
|
|
MedicalInfo medicalInfo = new MedicalInfo();
|
|
medicalInfo.setStatusCode(jsonResult.getDataMapString("StatusCode"));
|
|
medicalInfo.setStatus(jsonResult.getDataMapString("Status"));
|
|
|
|
log.info("[医保]查询结算信息 resp={}", medicalInfo);
|
|
return medicalInfo;
|
|
}
|
|
|
|
}
|
|
|