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.
987 lines
39 KiB
987 lines
39 KiB
package com.ynxbd.common.action.pay;
|
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.bocom.api.response.foreignccy.QueryReservationRegistResponseV1;
|
|
import com.ynxbd.common.action.base.BaseAction;
|
|
import com.ynxbd.common.bean.ConfigSelfHelp;
|
|
import com.ynxbd.common.bean.RecipeHelp;
|
|
import com.ynxbd.common.bean.SelfHelp;
|
|
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.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.*;
|
|
import com.ynxbd.common.service.params.RegParams;
|
|
import com.ynxbd.wx.config.WeChatConfig;
|
|
import com.ynxbd.wx.wxfactory.WxPayHelper;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.apache.commons.codec.digest.DigestUtils;
|
|
import org.apache.commons.lang3.ObjectUtils;
|
|
import org.apache.struts2.convention.annotation.Action;
|
|
import org.apache.struts2.convention.annotation.Namespace;
|
|
|
|
import java.math.BigDecimal;
|
|
import java.util.Date;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* @Author wsq
|
|
* @Date 2020/9/14 15:43
|
|
* @Copyright @ 2020 云南新八达科技有限公司 All rights reserved.
|
|
*/
|
|
@Slf4j
|
|
@Namespace("/pay")
|
|
public class PayAction extends BaseAction {
|
|
|
|
/**
|
|
* [挂号]下单
|
|
*
|
|
* @param payCode 支付类型
|
|
* @param isOccupySource 是否占号(分时段)
|
|
*/
|
|
@Action("regPay")
|
|
public Result regPay(String payCode, Boolean isOccupySource, Boolean isZeroPay) {
|
|
log.info("[挂号]下单 payCode={}, isOccupySource={}, isZeroPay={}", payCode, isOccupySource, isZeroPay);
|
|
try {
|
|
Register reg = RegParams.getRegParams(request, true);
|
|
|
|
String ip = HttpHelper.getIpAddress(request);
|
|
|
|
return new RegService().regPlaceOrder(payCode, ip, isOccupySource, isZeroPay, reg);
|
|
} catch (ServiceException e) {
|
|
return Result.error(e);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 处方支付
|
|
*
|
|
* @param isPrepay 预结算
|
|
* @param payCode 支付方式 { ali:支付宝;wx:微信 }
|
|
* @param openid openid
|
|
* @param patientId 患者id
|
|
* @param treatNum 治疗号
|
|
* @param totalFee 总金额
|
|
* @param recipeJson 处方
|
|
* @param payWay 支付方式
|
|
* @param awaitSecond 待秒数,0继续执行不等待(不传或null 为0)
|
|
*/
|
|
@Action("recipePay")
|
|
public Result recipePay(boolean isPrepay, String payCode, String openid, String patientId, String treatNum, String totalFee, String recipeJson, String payWay, Integer awaitSecond) {
|
|
MerchantEnum merchantEnum = MerchantEnum.getMerchantEnumByCode(payCode);
|
|
if (merchantEnum == null) { // 支付方式异常
|
|
return Result.error(ResultEnum.PAY_TYPE_ERROR);
|
|
}
|
|
RecipeService recipeService = new RecipeService();
|
|
|
|
SelfHelp selfHelp = new SelfHelpDao().selectByTreatNum(treatNum);
|
|
if (selfHelp != null) { // 是核酸
|
|
try {
|
|
recipeService.selfHelpPrepay(selfHelp.getCode(), treatNum);
|
|
} catch (ServiceException e) {
|
|
return Result.error(e);
|
|
}
|
|
}
|
|
|
|
Result result = recipeService.recipeHand(merchantEnum, openid, patientId, treatNum, totalFee, recipeJson, payWay, awaitSecond);
|
|
if (!result.isSuccess() || result.getData() != null) { // 业务错误 || 存在返回数据-需提前返回
|
|
return result;
|
|
}
|
|
|
|
if (isPrepay) { // 目前仅蒙自和红河州医院使用(开通需联系HIS开发者,否则会产生风险)
|
|
if (!HisHelper.IS_RECIPE_PREPAY || !WeChatConfig.IS_RECIPE_PREPAY) { // 配置(两个开关)
|
|
return Result.error(ResultEnum.PAY_RECIPE_PREPAY_IS_NOT);
|
|
}
|
|
|
|
log.info("{} [处方]预结算开始... patientId={}", merchantEnum.NAME, patientId);
|
|
// 调用预结算!!!!注意如果HIS不支持开启改功能后,会存在直接入库的风险
|
|
List<Recipe> respList = recipeService.hisRecipePrepay(recipeJson, patientId, treatNum);
|
|
return Result.success(respList);
|
|
}
|
|
|
|
|
|
String outTradeNo = CodeHelper.getOutTradeNo(merchantEnum);
|
|
// 订单信息预存
|
|
if (!recipeService.isSaveRecipeInfo(recipeJson, payWay, openid, patientId, treatNum, outTradeNo, totalFee)) {
|
|
log.info("{} [处方支付]预存支付信息失败 patientId={}", merchantEnum.NAME, patientId);
|
|
return Result.error(ResultEnum.SPECIFIED_QUESTIONED_USER_NOT_EXIST);
|
|
}
|
|
|
|
String ip = request.getRemoteAddr();
|
|
String body = "诊间支付 患者:" + patientId + "\n门诊号:" + treatNum;
|
|
|
|
JSONObject respJson = PayService.createOrder(merchantEnum, openid, patientId, totalFee, outTradeNo, PEnum.RECIPE.CODE, ip, body);
|
|
// 支付异常
|
|
if (respJson == null) {
|
|
return Result.error(ResultEnum.PAY_ERROR);
|
|
}
|
|
return Result.success(respJson);
|
|
}
|
|
|
|
|
|
/**
|
|
* @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.getMerchantEnumByCode(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.getMerchantEnumByCode(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.isSuccess()){
|
|
peisService.peisRefund(recipeId,"OK","");
|
|
}
|
|
else {
|
|
peisService.peisRefund(recipeId,"FAIL",result.getMessage());
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* [住院]预交金创建订单
|
|
* *
|
|
* * @param payCode 退款支付方式 { ali:支付宝;wx:微信 }
|
|
*/
|
|
@Action("inHospPrepay")
|
|
public Result inHospPrepay(String openid, String patientId, String patientName, String treatNum, String payMoney, String payWay, String payCode) {
|
|
Result result = PayService.isNoPay();
|
|
if (result != null) {
|
|
return result;
|
|
}
|
|
|
|
MerchantEnum merchantEnum = MerchantEnum.getMerchantEnumByCode(payCode);
|
|
if (merchantEnum == null) {
|
|
// 支付方式异常
|
|
return Result.error(ResultEnum.PAY_TYPE_ERROR);
|
|
}
|
|
log.info("{} [住院]预交金信息预存 payCode={}, openid={}, patientId={}, patientName={}, payMoney={}, treatNum={}", merchantEnum.NAME, payCode, openid, patientId, patientName, payMoney, treatNum);
|
|
|
|
if (openid == null || patientId == null || patientName == null || payMoney == null || treatNum == null) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
|
|
String ip = request.getRemoteAddr();
|
|
String body = "住院缴费 患者:" + patientId + " 住院号:" + treatNum;
|
|
String outTradeNo = CodeHelper.getOutTradeNo(merchantEnum);
|
|
|
|
PayInHosp payInHosp = new PayInHosp();
|
|
payInHosp.setOpenid(openid);
|
|
payInHosp.setPatientId(patientId);
|
|
payInHosp.setPatientName(patientName);
|
|
payInHosp.setTreatNum(treatNum);
|
|
payInHosp.setPayMoney(new BigDecimal(payMoney));
|
|
payInHosp.setTotalFee(new BigDecimal(payMoney));
|
|
payInHosp.setPayWay(payWay);
|
|
payInHosp.setOutTradeNo(outTradeNo);
|
|
|
|
boolean isResult = new InHospService().saveInHospPayInfo(payInHosp);
|
|
if (!isResult) {
|
|
log.info("{} [住院]缴费预存信息失败 patientId={}", merchantEnum.NAME, patientId);
|
|
return Result.error(ResultEnum.PAY_PREPAY_SAVE_ERROR);
|
|
}
|
|
|
|
JSONObject respJson = PayService.createOrder(merchantEnum, openid, patientId, payMoney, outTradeNo, PEnum.IN_HOSP.CODE, ip, body);
|
|
if (respJson == null) {
|
|
// 支付异常
|
|
return Result.error(ResultEnum.PAY_ERROR);
|
|
}
|
|
return Result.success(respJson);
|
|
}
|
|
|
|
|
|
/**
|
|
* [盒子扫码支付]
|
|
*
|
|
* @param authCode 二维码授权码
|
|
* @param callNo 调用码 { recipe:处方;register:挂号;in_hosp:住院预交金 }
|
|
* @param treatNum 门诊号
|
|
* @param patientId 患者id
|
|
* @param title 标题
|
|
* @param operateUser 操作人
|
|
* @param totalFee 总金额
|
|
* @param invoiceTransNo HIS发票流水号
|
|
* @param regDate 挂号日期,挂号不能为空
|
|
* @return Y|N
|
|
*/
|
|
@Action("payMicro")
|
|
public Result payMicro(String authCode, String callNo, String treatNum, String patientId, String title, String operateUser, BigDecimal totalFee, String invoiceTransNo, String regDate) {
|
|
Result result = PayService.isNoPay();
|
|
if (result != null) {
|
|
return result;
|
|
}
|
|
|
|
MerchantEnum merchantEnum = MerchantEnum.getMerchantEnumByAuthCode(authCode);
|
|
if (merchantEnum == null) {
|
|
log.info("[盒子支付]条码不符合规则 authCode={}", authCode);
|
|
return Result.error(ResultEnum.PAY_AUTH_CODE_RULES_ERROR); // 条码不符合规则
|
|
}
|
|
|
|
log.info("{} 盒子支付 callNo={}, title={}, patientId={}, totalFee={}, invoiceTransNo={}, regDate={}",
|
|
merchantEnum.NAME, callNo, title, patientId, totalFee, invoiceTransNo, regDate);
|
|
|
|
if (operateUser == null || invoiceTransNo == null
|
|
|| patientId == null
|
|
|| authCode == null
|
|
|| title == null
|
|
|| treatNum == null
|
|
|| totalFee == null) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
|
|
PEnum pEnum = PEnum.toEnum(callNo);
|
|
if (callNo == null) {
|
|
return Result.error(ResultEnum.PAY_TYPE_ERROR);
|
|
}
|
|
|
|
if (PEnum.REG.equals(pEnum) && ObjectUtils.isEmpty(regDate)) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
|
|
String outTradeNo = CodeHelper.getOutTradeNo(merchantEnum);
|
|
Order order = PayService.saveMicroOrderNo(pEnum, merchantEnum, outTradeNo, authCode, treatNum, patientId, operateUser, invoiceTransNo, totalFee, regDate);
|
|
if (!order.isSuccess()) {
|
|
return Result.error(order.getErrorMsg());
|
|
}
|
|
|
|
String ip = HttpHelper.getIpAddress(request);
|
|
Order orderMicro = PayService.payMicro(merchantEnum, outTradeNo, title, totalFee, authCode, ip);
|
|
if (!orderMicro.isSuccess()) {
|
|
log.info("[盒子支付]订单号={}, errMsg={}", outTradeNo, orderMicro.getErrorMsg());
|
|
// 等待输入密码
|
|
if (WxPayHelper.USER_PAYING.equals(orderMicro.getTradeState())) {
|
|
return Result.error(ResultEnum.PAY_NEED_PASSWORD, orderMicro.getOutTradeNo(), orderMicro.getErrorMsg());
|
|
}
|
|
return Result.error(ResultEnum.ERROR, orderMicro.getOutTradeNo(), orderMicro.getErrorMsg());
|
|
}
|
|
|
|
boolean isSuccess = PayService.updateMicroOrderState(pEnum, outTradeNo, orderMicro.getBankTransNo(), orderMicro.getOpenid());
|
|
|
|
return isSuccess ? Result.success(outTradeNo)
|
|
: Result.error(ResultEnum.ERROR, outTradeNo);
|
|
}
|
|
|
|
|
|
/**
|
|
* 【医保】微信现金退费
|
|
*
|
|
* @param callNo 调用码 { recipe:处方;register:挂号;in_hosp:住院预交金 }
|
|
* @param payOrdId 医保订单号
|
|
*/
|
|
@Action("mdCashRefund")
|
|
public Result mdCashRefund(String callNo, String payOrdId, String patientId, String refundDesc) {
|
|
String verify = request.getHeader("verify"); // 验证参数
|
|
log.info("[医保]线下现金退费 callNo={}, payOrdId={}, patientId={}, verify={}", callNo, payOrdId, patientId, verify);
|
|
if (verify == null || payOrdId == null || patientId == null || callNo == null) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
|
|
String piMd5 = patientId + payOrdId + "xbd";
|
|
piMd5 = DigestUtils.md5Hex(piMd5).toUpperCase();
|
|
|
|
if (!piMd5.equals(verify)) {
|
|
return Result.error(ResultEnum.PARAM_IS_INVALID); // 参数无效
|
|
}
|
|
|
|
switch (PEnum.toEnum(callNo)) {
|
|
case RECIPE:
|
|
return new RecipeService().mdCashRefund(payOrdId, refundDesc);
|
|
|
|
case REG: // 挂号
|
|
return new RegService().mdCashRefund(payOrdId, refundDesc);
|
|
|
|
case IN_HOSP: // 住院预交金
|
|
break;
|
|
|
|
default:
|
|
return Result.error("callNo不符合规则");
|
|
}
|
|
return Result.error();
|
|
}
|
|
|
|
|
|
/**
|
|
* [His退费]
|
|
*
|
|
* @param callNo 调用码 { recipe:处方;register:挂号;in_hosp:住院预交金 }
|
|
* @param patientId 患者ID
|
|
* @param refundUser 退费操作者
|
|
* @param refundDesc 退费描述
|
|
* @param refundMoney 退款金额
|
|
* @param invoiceTransNo 发票流水号
|
|
*/
|
|
@Action("hisRefund")
|
|
public Result hisRefund(String callNo, String patientId, String refundUser, String refundDesc, BigDecimal refundMoney, String invoiceTransNo) {
|
|
// 头部参数
|
|
String verify = request.getHeader("verify"); // 验证参数
|
|
|
|
log.info("[His手动退费] callNo={}, refundUser={}, refundDesc={}, refundMoney={}, patientId={}, invoiceTransNo={}, verify={}",
|
|
callNo, refundUser, refundDesc, refundMoney, patientId, invoiceTransNo, verify);
|
|
|
|
if (verify == null || invoiceTransNo == null || patientId == null || callNo == null || refundUser == null || refundDesc == null || refundMoney == null) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
|
|
String piMd5 = patientId + invoiceTransNo + "xbd";
|
|
piMd5 = DigestUtils.md5Hex(piMd5).toUpperCase();
|
|
|
|
if (!piMd5.equals(verify)) {
|
|
return Result.error(ResultEnum.PARAM_IS_INVALID); // 参数无效
|
|
}
|
|
|
|
PEnum pEnum = PEnum.toEnum(callNo);
|
|
try {
|
|
switch (pEnum) {
|
|
case RECIPE: // 处方
|
|
new RecipeService().hisRefund(invoiceTransNo, patientId, refundUser, refundDesc, refundMoney, pEnum);
|
|
break;
|
|
|
|
case REG: // 挂号
|
|
new RegService().hisRefund(invoiceTransNo, patientId, refundUser, refundDesc, refundMoney, pEnum);
|
|
break;
|
|
|
|
case IN_HOSP: // 住院预交金
|
|
new InHospService().hisRefund(invoiceTransNo, patientId, refundUser, refundDesc, refundMoney, pEnum);
|
|
break;
|
|
|
|
default:
|
|
return Result.error("callNo不符合规则");
|
|
}
|
|
return Result.success();
|
|
} catch (ServiceException e) {
|
|
return Result.error(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* HIS扫码盒子[查询商户订单]
|
|
*
|
|
* @param outTradeNo 订单号
|
|
*/
|
|
@Action("getOrderByOutTradeNo")
|
|
public Result getOrderByOutTradeNo(String outTradeNo) {
|
|
if (outTradeNo == null) {
|
|
return Result.error(ResultEnum.PARAM_IS_BLANK);
|
|
}
|
|
|
|
Order order = null;
|
|
for (int i = 0; i <= 4; i++) {
|
|
try {
|
|
if (i != 0) {
|
|
log.info("[盒子支付]订单查询 outTradeNo={} [{}]", outTradeNo, i);
|
|
Thread.sleep(2000 + (i * 1500)); // 0 | 3.5 | 5 | 6.5 | 7 = 22s
|
|
}
|
|
order = PayService.queryOrderByOutTradeNo(outTradeNo, null);
|
|
if (order.isSuccess()) {
|
|
break;
|
|
}
|
|
|
|
if (!WxPayHelper.USER_PAYING.equals(order.getTradeState())) { // 错误
|
|
break;
|
|
}
|
|
} catch (Exception e) {
|
|
ErrorHelper.println(e);
|
|
}
|
|
}
|
|
|
|
if (order == null) {
|
|
return Result.error();
|
|
}
|
|
|
|
if (order.isSuccess()) {
|
|
if (!PayService.updateMicroOrderState(null, outTradeNo, order.getBankTransNo(), order.getOpenid())) {
|
|
log.info("[扫码盒子]订单状态修改失败 outTradeNo={}", outTradeNo);
|
|
}
|
|
return Result.success(order);
|
|
}
|
|
|
|
if (!WxPayHelper.USER_PAYING.equals(order.getTradeState())) { // 错误
|
|
return Result.error(order.getErrorMsg());
|
|
}
|
|
return Result.error(ResultEnum.PAY_NEED_PASSWORD, order.getOutTradeNo()); // 等待输入密码
|
|
}
|
|
|
|
|
|
/**
|
|
* [查询商户订单]
|
|
*
|
|
* @param transId 流水号
|
|
*/
|
|
@Action("getMerOrderByTransId")
|
|
public Result getMerOrderByTransId(String transId) {
|
|
if (transId == null) {
|
|
return Result.error(ResultEnum.PARAM_IS_BLANK);
|
|
}
|
|
Order order = WxPayHelper.queryOrderByTransId(transId);
|
|
return Result.success(order);
|
|
}
|
|
|
|
/**
|
|
* [查询商户订单]
|
|
*
|
|
* @param outTradeNo 订单号
|
|
*/
|
|
@Action("getMerOrderByOutTradeNo")
|
|
public Result getMerOrderByOutTradeNo(String outTradeNo, String payWay) {
|
|
if (outTradeNo == null) {
|
|
return Result.error(ResultEnum.PARAM_IS_BLANK);
|
|
}
|
|
Order order = PayService.queryOrderByOutTradeNo(outTradeNo, payWay);
|
|
return Result.success(order);
|
|
}
|
|
|
|
|
|
/**
|
|
* 取消预约
|
|
*
|
|
* @param tradeNo HIS交易流水号
|
|
* @param patientId 患者id
|
|
* @param hisTransNo HIS流水号
|
|
*/
|
|
@Action("cancelRegReserve")
|
|
public Result cancelRegReserve(String tradeNo, String patientId, String hisTransNo) {
|
|
return new RegService().cancelRegReserve(patientId, tradeNo, hisTransNo);
|
|
}
|
|
|
|
@Action("refundRegister")
|
|
public Result refundRegister(String hisTransNo){
|
|
return new RegService().refundRegister(hisTransNo);
|
|
}
|
|
|
|
|
|
/**
|
|
* 第三方手动退费
|
|
* * @param callNo 调用方
|
|
* * @param payCode 退款支付方式 { ali:支付宝;wx:微信 }
|
|
* * @param patientId 患者id
|
|
* * @param tradeNo HIS交易流水号
|
|
*/
|
|
@Action("thirdPartyRefund")
|
|
public Result thirdPartyRefund() {
|
|
String configPwd = WeChatConfig.PASSWORD;
|
|
if (ObjectUtils.isEmpty(configPwd)) {
|
|
return Result.error(ResultEnum.SYSTEM_CONFIG_ERROR);
|
|
}
|
|
|
|
String callNo = RSAHelper.decrypt(request.getHeader("callNo"));
|
|
String tradeNo = RSAHelper.decrypt(request.getHeader("tradeNo"));
|
|
String bankTransNo = RSAHelper.decrypt(request.getHeader("bankTransNo"));
|
|
|
|
String refundUser = getString("refundUser");
|
|
String refundDesc = getString("refundDesc");
|
|
log.info("[第三方退款]callNo={}, bankTransNo={}, tradeNo={}, refundUser={}, refundDesc={}", callNo, bankTransNo, tradeNo, refundUser, refundDesc);
|
|
if (ObjectUtils.isEmpty(bankTransNo) || ObjectUtils.isEmpty(tradeNo) || ObjectUtils.isEmpty(refundUser) || ObjectUtils.isEmpty(callNo)) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
|
|
if (!"SHEN_SI_001".equals(callNo)) {
|
|
return Result.error(ResultEnum.PARAM_CALL_NO_NOT_FOUND); // 调用码不存
|
|
}
|
|
|
|
boolean isResult;
|
|
try {
|
|
PEnum orderType = PEnum.getByOrderNo(bankTransNo, tradeNo);
|
|
if (orderType == null) {
|
|
return Result.error(ResultEnum.REFUND_IS_OLD_ORDER_NUM);
|
|
}
|
|
switch (orderType) {
|
|
case RECIPE: // 处方
|
|
isResult = new RecipeService().isHandRefund(tradeNo, refundUser, refundDesc, orderType, callNo);
|
|
break;
|
|
|
|
case REG: // 挂号
|
|
isResult = new RegService().isHandRefund(tradeNo, refundUser, refundDesc, orderType, callNo);
|
|
break;
|
|
|
|
case IN_HOSP: // 住院预交金
|
|
return Result.error(ResultEnum.SYSTEM_SERVICE_CLOSE);
|
|
|
|
default:
|
|
return Result.error(ResultEnum.PARAM_IS_INVALID);
|
|
}
|
|
} catch (ServiceException e) {
|
|
return Result.error(e);
|
|
}
|
|
return isResult ? Result.success() : Result.error();
|
|
}
|
|
|
|
|
|
/**
|
|
* 微官网手动退费
|
|
* *
|
|
* * @param payCode 退款支付方式 { ali:支付宝;wx:微信 }
|
|
* * @param patientId 患者id
|
|
* * @param tradeNo HIS交易流水号
|
|
*/
|
|
@Action("handRefund")
|
|
public Result handRefund() {
|
|
String tradeNo = RSAHelper.decrypt(request.getHeader("tradeNo"));
|
|
String bankTransNo = RSAHelper.decrypt(request.getHeader("bankTransNo"));
|
|
String password = RSAHelper.decrypt(request.getHeader("password"));
|
|
String refundDesc = getString("refundDesc");
|
|
|
|
String token = request.getHeader("AuthToken");
|
|
log.info("[微官网手动退费]bankTransNo={}, tradeNo={}, refundDesc={}", bankTransNo, tradeNo, refundDesc);
|
|
if (ObjectUtils.isEmpty(bankTransNo) || ObjectUtils.isEmpty(tradeNo) || ObjectUtils.isEmpty(token) || ObjectUtils.isEmpty(password)) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
|
|
String configPwd = WeChatConfig.PASSWORD;
|
|
if (ObjectUtils.isEmpty(configPwd)) {
|
|
return Result.error(ResultEnum.SYSTEM_CONFIG_ERROR);
|
|
}
|
|
|
|
if (!configPwd.equals(password)) {
|
|
return Result.error(ResultEnum.PASS_VERIFY_ERROR);
|
|
}
|
|
|
|
String username = JwtHelper.getTokenVal(token, JwtHelper.USERNAME, String.class);
|
|
if (ObjectUtils.isEmpty(username)) {
|
|
return Result.error(ResultEnum.PARAM_IS_INVALID);
|
|
}
|
|
|
|
String sign = new SysUserDao().selectByUsername(username);
|
|
if (ObjectUtils.isEmpty(sign)) {
|
|
return Result.error(ResultEnum.PARAM_IS_INVALID);
|
|
}
|
|
|
|
if (!JwtHelper.verifyToken(token, username, sign)) {
|
|
return Result.error(ResultEnum.AUTH_FAILED);
|
|
}
|
|
|
|
boolean isResult;
|
|
try {
|
|
PEnum orderType = PEnum.getByOrderNo(bankTransNo, tradeNo);
|
|
if (orderType == null) {
|
|
return Result.error(ResultEnum.REFUND_IS_OLD_ORDER_NUM);
|
|
}
|
|
switch (orderType) {
|
|
case RECIPE: // 处方
|
|
isResult = new RecipeService().isHandRefund(tradeNo, username, refundDesc, orderType, "MICRO");
|
|
break;
|
|
|
|
case REG: // 挂号
|
|
isResult = new RegService().isHandRefund(tradeNo, username, refundDesc, orderType, "MICRO");
|
|
break;
|
|
|
|
case IN_HOSP: // 住院预交金
|
|
return Result.error(ResultEnum.SYSTEM_SERVICE_CLOSE);
|
|
|
|
default:
|
|
return Result.error(ResultEnum.PARAM_IS_INVALID);
|
|
}
|
|
} catch (ServiceException e) {
|
|
return Result.error(e);
|
|
}
|
|
return isResult ? Result.success() : Result.error();
|
|
}
|
|
|
|
|
|
/**
|
|
* 查询自助申请单价格
|
|
*
|
|
* @param pageNum 页码标识
|
|
* @param seq 序号
|
|
*/
|
|
@Action("getRecipeSelfHelpPrice")
|
|
public Result getRecipeSelfHelpPrice(String pageNum, String seq) {
|
|
if (pageNum == null || seq == null) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
JsonResult jsonResult = new HisRecipeDao().getSelfHelpInfo(pageNum, seq);
|
|
if (!jsonResult.success()) { // 失败
|
|
return Result.error(jsonResult.getMessage());
|
|
}
|
|
|
|
RecipeHelp result = jsonResult.dataMapToBean(RecipeHelp.class);
|
|
return Result.success(result);
|
|
}
|
|
|
|
|
|
/**
|
|
* [处方]自助申请单开单
|
|
*
|
|
* @param pageNum 页码标识
|
|
* @param seq 序号
|
|
*/
|
|
@Action("payRecipeSelfHelp")
|
|
public Result payRecipeSelfHelp(String patientId, String pageNum, String seq, String cardNo) {
|
|
if (patientId == null || pageNum == null || seq == null) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
|
|
// 开申请单
|
|
JsonResult JsonResult = new HisRecipeDao().createSelfHelp(patientId, pageNum, seq, cardNo);
|
|
if (JsonResult.isTimeout()) {
|
|
return Result.error(JsonResult.getMessage());
|
|
}
|
|
|
|
if (!JsonResult.success()) { // 重复开单
|
|
return Result.error(ResultEnum.RECIPE_REPEAT_BILL, null, JsonResult.getMessage());
|
|
}
|
|
|
|
Map<String, Object> resultData = new HashMap<>();
|
|
Map<String, Object> dataMap = JsonResult.getDataMap();
|
|
String recipeId = JsonResult.getDataMapString("RecipeId");
|
|
if (ObjectUtils.isEmpty(recipeId)) {
|
|
return Result.error(ResultEnum.INTERFACE_HIS_INVOKE_ERROR);
|
|
}
|
|
|
|
try {
|
|
resultData.put("recipeId", Long.toString(Long.parseLong(recipeId) + 1000000000L));
|
|
resultData.put("treatNum", dataMap.get("MZNum"));
|
|
return Result.success(resultData);
|
|
} catch (Exception e) {
|
|
ErrorHelper.println(e);
|
|
}
|
|
return Result.error();
|
|
}
|
|
|
|
|
|
/**
|
|
* [自助申请单]查询格价
|
|
*/
|
|
@Action("getSelfHelpPrice")
|
|
public Result getSelfHelpPrice(String code) {
|
|
if (code == null) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
String[] codeArr = code.split(",");
|
|
if (codeArr.length != 2) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
|
|
JsonResult jsonResult = new HisRecipeDao().getSelfHelpInfo(codeArr[0], codeArr[1]);
|
|
if (!jsonResult.success()) { // 失败
|
|
return Result.error(jsonResult.getMessage());
|
|
}
|
|
|
|
RecipeHelp result = jsonResult.dataMapToBean(RecipeHelp.class);
|
|
return Result.success(result);
|
|
}
|
|
|
|
/**
|
|
* [自助申请单]创建申请单
|
|
*
|
|
* @param code (页码标识,是否两张申请单)
|
|
*/
|
|
@Action("createSelfHelp")
|
|
public Result createSelfHelp(String code, String cardNo, String patientId, String openid) {
|
|
if (patientId == null || code == null || openid == null) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
|
|
String[] codeArr = code.split(",");
|
|
if (codeArr.length != 2) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
|
|
try {
|
|
new RecipeService().selfHelpMaxNum(code);
|
|
} catch (ServiceException e) {
|
|
return Result.error(e);
|
|
}
|
|
|
|
// 开申请单
|
|
JsonResult jsonResult = new HisRecipeDao().createSelfHelp(patientId, codeArr[0], codeArr[1], cardNo);
|
|
if (jsonResult.isTimeout()) {
|
|
return Result.error(jsonResult.getMessage());
|
|
}
|
|
|
|
if (!jsonResult.success()) { // 重复开单
|
|
return Result.error(ResultEnum.RECIPE_REPEAT_BILL, null, jsonResult.getMessage());
|
|
}
|
|
|
|
Map<String, Object> resultData = new HashMap<>();
|
|
Map<String, Object> dataMap = jsonResult.getDataMap();
|
|
String recipeId = jsonResult.getDataMapString("RecipeId");
|
|
if (ObjectUtils.isEmpty(recipeId)) {
|
|
return Result.error(ResultEnum.INTERFACE_HIS_INVOKE_ERROR);
|
|
}
|
|
|
|
try {
|
|
String treatNum = String.valueOf(dataMap.get("MZNum"));
|
|
if (ObjectUtils.isEmpty(treatNum)) {
|
|
return Result.error(ResultEnum.INTERFACE_HIS_DATA_ERROR);
|
|
}
|
|
|
|
SelfHelpDao selfHelpDao = new SelfHelpDao();
|
|
SelfHelp selfHelp = selfHelpDao.selectByTreatNum(treatNum);
|
|
if (selfHelp != null) {
|
|
if (!selfHelpDao.updateByTreatNum(treatNum)) {
|
|
return Result.error(ResultEnum.DATA_UPDATE_ERROR);
|
|
}
|
|
} else {
|
|
if (!selfHelpDao.insert(openid, treatNum, code)) {
|
|
return Result.error(ResultEnum.DATA_INSERT_ERROR);
|
|
}
|
|
}
|
|
|
|
resultData.put("recipeId", Long.toString(Long.parseLong(recipeId) + 1000000000L));
|
|
resultData.put("treatNum", treatNum);
|
|
return Result.success(resultData);
|
|
} catch (Exception e) {
|
|
ErrorHelper.println(e);
|
|
}
|
|
return Result.error();
|
|
}
|
|
|
|
|
|
/**
|
|
* [自助申请单]获取申请单列表
|
|
*
|
|
* @param groupType 类型标识
|
|
*/
|
|
@Action("getSelfHelpList")
|
|
public Result getSelfHelpList(Integer groupType) {
|
|
log.info("[自助申请单]列表 groupType={}", groupType);
|
|
if (groupType == null) {
|
|
groupType = 0;
|
|
}
|
|
List<ConfigSelfHelp> dataList = new SelfHelpDao().selectConfigList(groupType);
|
|
return Result.success(dataList);
|
|
}
|
|
|
|
|
|
/**
|
|
* [在线问诊]支付
|
|
*/
|
|
@Action("createOLOrder")
|
|
public Result createOLOrder(String payCode, String outTradeNo, String openid, String patientId, BigDecimal totalFee, String deptCode, String deptName, String doctName, String doctCode) {
|
|
if ( totalFee == null || ObjectUtils.isEmpty(openid) || ObjectUtils.isEmpty(patientId) || ObjectUtils.isEmpty(deptName) || ObjectUtils.isEmpty(doctName)) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
if (totalFee.compareTo(BigDecimal.ZERO) == 0) { // 0 元处理
|
|
return Result.error(ResultEnum.PAY_MONEY_IS_ZERO);
|
|
}
|
|
if (ObjectUtils.isEmpty(outTradeNo) || outTradeNo.length() > 32) {
|
|
return Result.error(ResultEnum.PARAM_IS_INVALID);
|
|
}
|
|
|
|
MerchantEnum merchantEnum = MerchantEnum.getMerchantEnumByCode(payCode);
|
|
if (merchantEnum == null) {
|
|
return Result.error(ResultEnum.PAY_TYPE_NOT_SUPPORT);
|
|
}
|
|
|
|
String ip = HttpHelper.getIpAddress(request);
|
|
String body = "在线问诊:" + deptName + "-" + doctName;
|
|
JSONObject respJson = PayService.createOrder(merchantEnum, openid, patientId, totalFee.toString(), outTradeNo, PEnum.OL_REG.CODE, ip, body);
|
|
if (respJson == null) {
|
|
return Result.error(ResultEnum.PAY_ERROR); // 支付异常
|
|
}
|
|
return Result.success(respJson);
|
|
}
|
|
|
|
|
|
/**
|
|
* [在线问诊]退费
|
|
*
|
|
* @param payCode
|
|
* @param outTradeNo
|
|
* @param totalFee
|
|
* @param bankTransNo
|
|
* @param openid
|
|
* @param patientId
|
|
* @param refundDesc
|
|
* @return
|
|
*/
|
|
@Action("refundOLOrder")
|
|
public Result refundOLOrder(String payCode, String outTradeNo, String totalFee, String bankTransNo, String openid, String patientId, String refundDesc) {
|
|
MerchantEnum merchantEnum = MerchantEnum.getMerchantEnumByCode(payCode);
|
|
if (merchantEnum == null) {
|
|
return Result.error(ResultEnum.PAY_TYPE_NOT_SUPPORT);
|
|
}
|
|
bankTransNo = AesHelper.deCode(bankTransNo);
|
|
outTradeNo = AesHelper.deCode(outTradeNo);
|
|
totalFee = AesHelper.deCode(totalFee);
|
|
openid = AesHelper.deCode(openid);
|
|
log.info("[问诊]退费 outTradeNo={}, bankTransNo={}, totalFee={}, openid={}, patientId={}", outTradeNo, bankTransNo, totalFee, openid, patientId);
|
|
if (outTradeNo == null || bankTransNo == null || openid == null || totalFee == null) {
|
|
return Result.error(ResultEnum.PARAM_IS_BLANK);
|
|
}
|
|
|
|
BigDecimal totalFeeDecimal = new BigDecimal(totalFee);
|
|
String outRefundNo = HisHelper.getHisTradeNo(bankTransNo, PEnum.OL_REG);
|
|
Order orderRefund = PayService.refund(merchantEnum, outTradeNo, outRefundNo, totalFeeDecimal, totalFeeDecimal, refundDesc, new Date(), openid, patientId, null);
|
|
if (orderRefund.isSuccess()) {
|
|
return Result.success(AesHelper.enCode(outRefundNo));
|
|
}
|
|
return Result.error(orderRefund.getErrorMsg());
|
|
}
|
|
|
|
/**
|
|
* [扫码支付]支付
|
|
*/
|
|
@Action("ocPay")
|
|
public Result ocPay(String payCode, String title, BigDecimal totalFee, String openid, boolean isWeb, boolean isQrCode,
|
|
String collectId, String mid, String name, String cardNo, String patientId, String remark) {
|
|
MerchantEnum merchantEnum = MerchantEnum.getMerchantEnumByCode(payCode);
|
|
if (merchantEnum == null) { // 支付方式异常
|
|
return Result.error(ResultEnum.PAY_TYPE_ERROR);
|
|
}
|
|
if (totalFee == null || ObjectUtils.isEmpty(title)) {
|
|
return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
}
|
|
if (totalFee.compareTo(BigDecimal.ZERO) == 0) { // 0 元处理
|
|
return Result.error(ResultEnum.PAY_MONEY_IS_ZERO);
|
|
}
|
|
|
|
String outTradeNo = CodeHelper.getOutTradeNo(merchantEnum);
|
|
|
|
try {
|
|
new OutCollectService().ocPay(outTradeNo, totalFee, collectId, openid, mid, name, cardNo, patientId, remark);
|
|
} catch (ServiceException e) {
|
|
return Result.error(e);
|
|
}
|
|
|
|
String ip = request.getRemoteAddr();
|
|
//
|
|
if (isWeb) {
|
|
JSONObject order = WxPayHelper.createOrder(MerchantEnum.WX, title, totalFee.toString(), outTradeNo, PEnum.OUT_COLLECT.CODE, ip, openid, null);
|
|
return Result.success(order);
|
|
}
|
|
|
|
String url = WxPayHelper.createNativeOrder(MerchantEnum.WX, title, totalFee, outTradeNo, PEnum.OUT_COLLECT.CODE, ip);
|
|
if (isQrCode) {
|
|
String base64 = QRCodeHelper.encodeToBase64(url, 200, 200);
|
|
Result.success(base64);
|
|
}
|
|
return Result.success(url);
|
|
}
|
|
|
|
|
|
// /**
|
|
// * [病历]下单
|
|
// */
|
|
// @Action("casebookPay")
|
|
// public Result casebookPay(String payCode, BigDecimal totalFee, String casebookId, String cardNo, String name, String patientId, String applyTime, String applyName, String dx, String treatNum, String deptName, String deptCode, String getWay, String address) {
|
|
// MerchantEnum merchantEnum = MerchantEnum.getMerchantEnumByCode(payCode);
|
|
// if (merchantEnum == null) { // 支付方式异常
|
|
// return Result.error(ResultEnum.PAY_TYPE_ERROR);
|
|
// }
|
|
// log.info("[病历]下单 payCode={}, totalFee={}, casebookId={}, name={}, patientId={}, applyTime={}, applyName={}, treatNum={}, deptName={}, deptCode={}, getWay={}",
|
|
// payCode, totalFee, casebookId, name, patientId, applyTime, applyName, treatNum, deptName, deptCode, getWay);
|
|
//
|
|
// String ip = HttpHelper.getIpAddress(request);
|
|
//
|
|
// PayCasebook casebook = new PayCasebook();
|
|
// casebook.setCasebookId(casebookId);
|
|
// casebook.setTotalFee(totalFee);
|
|
// casebook.setPatientId(patientId);
|
|
// casebook.setPatientName(name);
|
|
// casebook.setCardNo(cardNo);
|
|
// casebook.setApplyName(applyName);
|
|
// casebook.setApplyTime(applyTime);
|
|
//
|
|
// casebook.setDeptCode(deptCode);
|
|
// casebook.setDeptName(deptName);
|
|
// casebook.setAddress(address);
|
|
// casebook.setDx(dx);
|
|
// casebook.setGetWay(getWay);
|
|
// casebook.setTreatNum(treatNum);
|
|
//
|
|
// return new CasebookService().placeOrder(merchantEnum, ip, casebook);
|
|
// }
|
|
|
|
|
|
// /**
|
|
// * 微官网手动退费测试
|
|
// * *
|
|
// * * @param payCode 退款支付方式 { ali:支付宝;wx:微信 }
|
|
// * * @param patientId 患者id
|
|
// * * @param tradeNo HIS交易流水号
|
|
// */
|
|
// @Action("test")
|
|
// public String test() {
|
|
// String callNo = getString("callNo");
|
|
// String tradeNo = getString("tradeNo");
|
|
// String refundDesc = getString("refundDesc");
|
|
//
|
|
// log.info("[微官网手动退费]callNo={}, tradeNo={}, refundDesc={}", callNo, tradeNo, refundDesc);
|
|
// if (ObjectUtils.isEmpty(callNo) || ObjectUtils.isEmpty(tradeNo)) {
|
|
// return Result.error(ResultEnum.PARAM_IS_DEFECT);
|
|
// }
|
|
//
|
|
// boolean isResult;
|
|
// try {
|
|
// switch (callNo) {
|
|
// case "recipe": // 处方
|
|
// isResult = new RecipeService().isHandRefund(tradeNo, "123", refundDesc, callNo);
|
|
// break;
|
|
//
|
|
// case "register": // 挂号
|
|
// isResult = new RegService().isHandRefund(tradeNo, "123", refundDesc, callNo);
|
|
// break;
|
|
//
|
|
// case "in_hosp": // 住院预交金
|
|
// return Result.error(ResultEnum.SYSTEM_SERVICE_CLOSE);
|
|
//
|
|
// default:
|
|
// return Result.error(ResultEnum.PARAM_IS_INVALID);
|
|
// }
|
|
// } catch (ServiceException e) {
|
|
// return Result.error(e);
|
|
// }
|
|
// return isResult ? Result.success() : Result.error();
|
|
// }
|
|
}
|
|
|