package com.ynxbd.common.action; import com.ynxbd.ali.helper.AliHelper; import com.ynxbd.common.action.base.BaseAction; import com.ynxbd.common.action.pay.PEnum; import com.ynxbd.common.bean.HisTransaction; import com.ynxbd.common.bean.enums.MerchantEnum; import com.ynxbd.common.bean.pay.Bill; import com.ynxbd.common.bean.pay.Recipe; import com.ynxbd.common.bean.pay.Register; import com.ynxbd.common.config.db.DataBase; import com.ynxbd.common.dao.RecipeDao; import com.ynxbd.common.dao.RegisterDao; import com.ynxbd.common.dao.his.HisAccountDao; import com.ynxbd.common.helper.common.DateHelper; 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.PayService; import com.ynxbd.wx.wxfactory.WxPayHelper; import lombok.extern.slf4j.Slf4j; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Namespace; import java.util.*; /** * @Author wsq * @Date 2021/4/7 13:25 * @Copyright @ 2020 云南新八达科技有限公司 All rights reserved. */ @Slf4j @Namespace("/accounts") public class AccountsAction extends BaseAction { /** * 查询对账报表 *

* 注:预约对账因按财务要求,只能按就诊日期统计 * 如:2016年12月30号预约2017年1月5号 则这笔帐是算在2017年1月这个周期内 * 如果在就诊日期前取消预约则算在 2016年12月这个周期内 * 如:2017年1月4号取消预约 则2016年12月这个周期内有一笔正交易 2017年1月这个周期内有一笔负交易 */ @Action("getStatement") public Result getStatement(String begDate, String endDate) { log.info("[对账]查询对账报表 begDate={}, endDate={}", begDate, endDate); if (begDate == null || endDate == null) { return Result.error(ResultEnum.PARAM_IS_BLANK); } int days = DateHelper.intervalDays(begDate, endDate, true); if (days > 31 || days < 0) { return Result.error("[对账]查询起止日期间隔不能超过31天"); } long begTime = System.currentTimeMillis(); // 结束时间 JsonResult jsonResult = new HisAccountDao().getStatement(begDate, endDate); if (!jsonResult.success()) { return Result.error(jsonResult.getMessage()); } List dataList = jsonResult.getDataMapList(HisTransaction.class, "Item"); long endTime = System.currentTimeMillis(); // 结束时间 String takeTime = (endTime - begTime) + "ms"; // 耗时 log.info("[对账]查询对账报表-耗时:[{}]", takeTime); return Result.success(dataList); } /** * [HIS]查询交易流水 * * @param begDate 开始日期 * @param endDate 结束日期 * @param tradeNo His交易流水号 * @param bankTransNo bankTransNo * @param dateType 日期类型:{ 0:交易日期, 1:就诊日期 } * @param isContainsRefund 是否包含负交易:{ 0:不包含负交易,当使用此参数时,负交易对应的正交易也将不会出现; 1包含负交易 } * @param isUpdateState 是否需要校验数据 */ @Action("getTransaction") public Result getTransaction(String begDate, String endDate, String tradeNo, String bankTransNo, Integer dateType, Integer isContainsRefund, Boolean isUpdateState) { if (isUpdateState == null) { isUpdateState = false; } log.info("[对账] 查询交易流水 begDate={}, endDate={}, tradeNo={}, bankTransNo={}, dateType={}, isContainsRefund={}", begDate, endDate, tradeNo, bankTransNo, dateType, isContainsRefund); if (begDate == null || endDate == null || tradeNo == null) { return Result.error(ResultEnum.PARAM_IS_DEFECT); } begDate = DateHelper.getMoveDate(begDate, -2); endDate = DateHelper.getMoveDate(endDate, 2); // 日期参数不合法 if (begDate == null || endDate == null) { return Result.error(ResultEnum.PARAM_DATE_ERROR); } JsonResult JsonResult = new HisAccountDao().getTransaction(begDate, endDate, tradeNo, dateType, isContainsRefund); if (JsonResult.isTimeout()) { // 请求超时 return Result.error(ResultEnum.INTERFACE_HIS_REQ_TIMEOUT); } if (!JsonResult.success()) { return Result.error(ResultEnum.INTERFACE_HIS_NO_DATA, JsonResult.getMessage()); } List resultList = JsonResult.getDataMapList(HisTransaction.class, "Item"); if (resultList.size() == 0) { return Result.error(ResultEnum.INTERFACE_HIS_INVOKE_ERROR); } if (!isUpdateState) { // 不更新 return Result.success(resultList); } // 更新HisStatus状态 Map dataMap = new HashMap<>(); dataMap.put("list", resultList); String msgInterface = null; try { msgInterface = HisHelper.getTypeByPEnum(bankTransNo, tradeNo); } catch (ServiceException e) { log.info(e.getMessage()); } if (msgInterface == null || bankTransNo == null) { return Result.success(dataMap); } String timePoint = DateHelper.getMoveMinute(DateHelper.getCurDateTime(), -20); boolean isResult = false; switch (PEnum.toEnum(msgInterface)) { case RECIPE: // 处方 RecipeDao recipeDao = new RecipeDao(); Recipe recipe = recipeDao.selectStatusErrOrder(bankTransNo, tradeNo, timePoint); if (recipe != null) { isResult = recipeDao.updateHisStatus(bankTransNo, tradeNo, timePoint); if (isResult) { log.info("[处方]调用HIS接口状态矫正成功"); } } break; case REG: // 挂号 RegisterDao regDao = new RegisterDao(); Register reg = regDao.selectStatusErrOrder(bankTransNo, tradeNo, timePoint); if (reg != null) { isResult = regDao.updateHisStatus(bankTransNo, tradeNo, timePoint); if (isResult) { log.info("[挂号]调用HIS接口状态矫正成功"); } } break; case IN_HOSP: // 住院预交金 return Result.error(ResultEnum.SYSTEM_SERVICE_CLOSE); default: return Result.error(ResultEnum.PARAM_IS_INVALID); } dataMap.put("isUpdate", isResult); // 是否发生修改 return Result.success(dataMap); } /** * 查询退费详情 */ @Action("getRefund") public Result getRefund(String outTradeNo, String bankTransNo, String outRefundNo) { try { if (outTradeNo == null || outRefundNo == null) { return Result.error(ResultEnum.PARAM_IS_DEFECT); } MerchantEnum merchantEnum = MerchantEnum.getMerchantEnumByOutTradeNo(outTradeNo); Bill bill = PayService.queryRefund(merchantEnum, outTradeNo, bankTransNo, outRefundNo); return bill == null ? Result.error() : Result.success(bill); } catch (ServiceException e) { return Result.error(e); } } /** * 查询退费订单集 * * @param outTradeNo 订单号 * @return 订单信息 */ @Action("getRefundList") public Result getRefundList(String outTradeNo) { try { if (outTradeNo == null) { return Result.error(ResultEnum.PARAM_IS_DEFECT); } List billList = WxPayHelper.queryRefundList(outTradeNo); return Result.success(billList); } catch (ServiceException e) { return Result.error(e); } } /** * 查询退费订单集(含退费时间) * * @param outTradeNo 订单号 * @return 订单信息 */ @Action("queryRefundInfoList") public Result queryRefundInfoList(String outTradeNo) { try { if (outTradeNo == null) { return Result.error(ResultEnum.PARAM_IS_DEFECT); } List billList = WxPayHelper.queryRefundInfoList(outTradeNo); return Result.success(billList); } catch (ServiceException e) { return Result.error(e); } } /** * [查询账单] * * @param billDate * @param billType * @param callNo * @param isCompose * @param isIncludeHis */ @Action("getBill") public Result getBill(String billDate, String billType, String callNo, Boolean isCompose, Boolean isIncludeHis) { log.info("[查询账单] date={}, billType={}, callNo={}, isIncludeHis={}", billDate, billType, callNo, isIncludeHis); if (billType == null || billDate == null || callNo == null) { return Result.error(ResultEnum.PARAM_IS_DEFECT); } if (!DateHelper.isValidDate(billDate, DateHelper.DateEnum.yyyy_MM_dd)) { return Result.error(ResultEnum.PARAM_DATE_ERROR); } if (DateHelper.isToday(billDate)) { return Result.error(ResultEnum.DATE_IS_TODAY); } if (billDate.equals(DateHelper.getMoveDate(new Date(), -1)) && !DateHelper.isCurTimeOver("10:10:00")) { return Result.error("查询前一天的数据,需在今天10点10分之后"); } if (isIncludeHis == null) { isIncludeHis = true; } if (isCompose == null) { isCompose = false; } if (!WxPayHelper.ALL.equals(billType) && !WxPayHelper.REFUND.equals(billType) && !WxPayHelper.SUCCESS.equals(billType)) { return Result.error(ResultEnum.PARAM_IS_INVALID); } MerchantEnum merchantEnum = MerchantEnum.getMerchantEnumByCode(callNo); if (merchantEnum == null) { return Result.error(ResultEnum.PARAM_IS_INVALID); } List billList; try { switch (merchantEnum) { case WX: billList = WxPayHelper.queryBill(billType, billDate, isCompose); break; case ALI: billList = AliHelper.queryBill(billType, billDate, isCompose); break; default: return Result.error(ResultEnum.PARAM_IS_INVALID); } } catch (ServiceException e) { return Result.error(e); } if (!isIncludeHis) { return Result.success(billList); } String nextDate = DateHelper.getMoveDate(billDate, -1); String type = " and length(openid) " + (merchantEnum.equals(MerchantEnum.WX) ? "> 26 " : "< 26 "); List recipeList = DataBase.select("select outTradeNo, bankTransNo, tradeNo as hisTradeNo, payMoney as money from pay where updateTime between ? and DATE_ADD(?,INTERVAL 1 DAY) and outTradeNo is not null and outTradeNo != '' " + type, Bill.class, ps -> { ps.setString(1, nextDate + " 23:45"); ps.setString(2, billDate + " 00:15"); }); List regList = DataBase.select("select outTradeNo, bankTransNo, tradeNo, payMoney, regType, refundResult from register where updateTime between ? and DATE_ADD(?,INTERVAL 1 DAY) and outTradeNo is not null and outTradeNo != '' " + type, Register.class, ps -> { ps.setString(1, nextDate + " 23:45"); ps.setString(2, billDate + " 00:15"); }); boolean isBreak; Bill addBill; String outTradeNo, bankTransNo, tradeNo; int tradeNoLen; for (Bill bill : billList) { isBreak = false; outTradeNo = bill.getOutTradeNo(); bill.setHisBills(new ArrayList<>()); for (Register regItem : regList) { if (outTradeNo.equals(regItem.getOutTradeNo())) { addBill = new Bill(); tradeNo = regItem.getTradeNo(); bankTransNo = regItem.getBankTransNo(); if (("1".equals(regItem.getRegType()) || "3".equals(regItem.getRegType())) && "OK".equals(regItem.getRefundResult())) { tradeNoLen = tradeNo.length(); if (((bankTransNo.length() + 4) == tradeNoLen) && tradeNoLen > 24 && bankTransNo.equals(tradeNo.substring(0, tradeNoLen - 4))) { addBill.setHisNegTradeNo("R" + tradeNo); } } addBill.setHisTradeNo(tradeNo); addBill.setMoney(regItem.getPayMoney()); bill.getHisBills().add(addBill); isBreak = true; } } if (!isBreak) { for (Bill item : recipeList) { if (outTradeNo.equals(item.getOutTradeNo())) { addBill = new Bill(); addBill.setMoney(item.getMoney()); addBill.setHisTradeNo(item.getHisTradeNo()); bill.getHisBills().add(addBill); } } } } return Result.success(billList); } }