package com.jsowell.service; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.huifu.adapay.core.exception.BaseAdaPayException; import com.jsowell.adapay.common.AdaPayment; import com.jsowell.adapay.common.PaymentConfirmInfo; import com.jsowell.adapay.dto.QueryPaymentConfirmDTO; import com.jsowell.adapay.response.PaymentConfirmResponse; import com.jsowell.adapay.response.QueryPaymentConfirmDetailResponse; import com.jsowell.adapay.service.AdapayService; import com.jsowell.adapay.vo.OrderSplitResult; import com.jsowell.adapay.vo.PaymentInfo; import com.jsowell.common.annotation.CostTime; import com.jsowell.common.core.redis.RedisCache; import com.jsowell.common.enums.adapay.AdapayStatusEnum; import com.jsowell.common.enums.ykc.*; import com.jsowell.common.exception.BusinessException; import com.jsowell.common.util.DateUtils; import com.jsowell.common.util.StringUtils; import com.jsowell.pile.domain.*; import com.jsowell.pile.dto.ApplyRefundDTO; import com.jsowell.pile.dto.QueryOrderDTO; import com.jsowell.pile.dto.SettleOrderReportDTO; import com.jsowell.pile.mapper.OrderBasicInfoMapper; import com.jsowell.pile.mapper.PileMsgRecordMapper; import com.jsowell.pile.service.*; import com.jsowell.pile.vo.web.*; import org.apache.commons.collections4.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; @Service public class TempService { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private OrderBasicInfoMapper orderBasicInfoMapper; @Autowired private OrderBasicInfoService orderBasicInfoService; @Autowired private ClearingWithdrawInfoService clearingWithdrawInfoService; @Autowired private OrderPayRecordService orderPayRecordService; @Autowired private AdapayCallbackRecordService adapayCallbackRecordService; @Autowired protected MemberGroupService memberGroupService; @Autowired private WxpayRefundCallbackService wxpayRefundCallbackService; @Autowired private PileMerchantInfoService pileMerchantInfoService; @Autowired private SettleOrderReportService settleOrderReportService; @Autowired private AdapayMemberAccountService adapayMemberAccountService; @Autowired private AdapayService adapayService; @Autowired private MemberAdapayRecordService memberAdapayRecordService; @Autowired private PileMsgRecordMapper pileMsgRecordMapper; @Autowired private OrderDetailService orderDetailService; @Autowired private OrderMonitorDataService orderMonitorDataService; @Autowired private RedisCache redisCache; /** * 计算订单耗电量 * 内蒙古站点 */ public void calculateOrderElectricity(QueryOrderDTO dto) { // 根据站点id查询充电桩列表 // List pileSnList = Lists.newArrayList("88240000006708", "88240000006709", "88240000006713", "88240000006714"); // 查询充电桩的订单列表 List orderListVOS = orderBasicInfoService.selectOrderBasicInfoList(dto); logger.info("查询订单列表:{}", JSON.toJSONString(orderListVOS)); // 根据充电桩编号,查询报文 for (OrderListVO orderVO : orderListVOS) { String pileSn = orderVO.getPileSn(); List pileFeedList = pileMsgRecordMapper.getPileFeedList(pileSn); } // } /** * 手动接口执行订单分账逻辑 */ public void tempOrderSplittingOperations(String merchantId, String tradeDate) { logger.info("手动接口执行订单分账逻辑-运营商:{}, 交易日期:{}, 进行分账处理start", merchantId, tradeDate); // 查询运营商有没有开通结算账户 AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId); if (adapayMemberAccount == null) { logger.error("手动接口执行订单分账逻辑-订单分账逻辑error, 运营商id:{}, 未配置结算账户", merchantId); return; } String appId = pileMerchantInfoService.queryAppIdByMerchantId(merchantId); // 根据交易日期查询运营商下面所有站点的交易日报 List stationReportList = settleOrderReportService.selectByMerchantIdAndDate(merchantId, tradeDate); for (SettleOrderReport orderReport : stationReportList) { String orderCodes = orderReport.getOrderCodes(); if (StringUtils.isBlank(orderCodes)) { logger.info("手动接口执行订单分账逻辑-站点:{}, 日期:{}, 没有查到订单数据", orderReport.getStationId(), tradeDate); continue; } List orderCodeList = Lists.newArrayList(StringUtils.split(orderCodes, ",")); List orderBasicInfos = orderBasicInfoService.queryOrderList(orderCodeList); if (CollectionUtils.isEmpty(orderBasicInfos)) { logger.info("手动接口执行订单分账逻辑-站点:{}, 日期:{}, 没有查到订单数据", orderReport.getStationId(), tradeDate); continue; } // 执行分账 for (OrderBasicInfo orderBasicInfo : orderBasicInfos) { try { OrderSplitResult orderSettleResult = null; logger.info("手动接口执行订单分账逻辑-orderCode:{}, payMode:{}", orderBasicInfo.getOrderCode(), orderBasicInfo.getPayMode()); if (OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue().equals(orderBasicInfo.getPayMode())) { logger.info("手动接口执行订单分账逻辑-order:{}, result:{}", JSON.toJSONString(orderBasicInfo), JSON.toJSONString(orderSettleResult)); // 余额支付的订单 只用余额支付转账 // orderSettleResult = doBalancePayment(orderBasicInfo, adapayMemberAccount); } else { // 在线支付,进行支付确认分账 // orderSettleResult = orderBasicInfo.doPaymentConfirmWithDelay(orderBasicInfo, adapayMemberAccount, appId); } // if (orderSettleResult != null && AdapayStatusEnum.SUCCEEDED.getValue().equals(orderSettleResult.getStatus())) { // JSONObject jsonObject = JSON.parseObject(orderSettleResult.getDescription()); // String orderCode = (String) jsonObject.get("orderCode"); // } } catch (Exception e) { logger.error("手动接口执行订单分账逻辑-订单交易确认失败:{}", orderBasicInfo.getOrderCode(), e); } } } logger.info("手动接口执行订单分账逻辑-运营商:{}, 交易日期:{}, 进行分账处理end", merchantId, tradeDate); } public String tempUpdateVirtualAmount(QueryOrderDTO dto) { dto.setOrderStatus(OrderStatusEnum.ORDER_COMPLETE.getValue()); List orderListVOS = orderBasicInfoMapper.selectOrderBasicInfoList(dto); if (CollectionUtils.isEmpty(orderListVOS)) { return "没有订单需要修改"; } int i = 0; for (OrderListVO orderListVO : orderListVOS) { try { tempUpdateVirtualAmount(orderListVO); i += 1; } catch (Exception e) { logger.error("修改虚拟金额字段失败", e); } } return "共查询到" + orderListVOS.size() + "条订单,修改成功" + i + "条订单数据"; } private void tempUpdateVirtualAmount(OrderListVO orderListVO) { if (orderListVO.getVirtualAmount() != null) { return; } // 订单总消费金额 BigDecimal orderAmount = new BigDecimal(orderListVO.getOrderAmount()); // 支付金额 BigDecimal payAmount = new BigDecimal(orderListVO.getPayAmount()); if (orderAmount.compareTo(payAmount) > 0) { orderAmount = payAmount; } // 使用虚拟金额消费 金额 BigDecimal virtualAmount = BigDecimal.ZERO; // 结算金额 BigDecimal settleAmount = BigDecimal.ZERO; if (orderAmount.compareTo(BigDecimal.ZERO) > 0) { if (StringUtils.equals(orderListVO.getPayMode(), OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue())) { /* 余额支付 查询支付记录,如全部用本金支付,则虚拟金额为0,结算金额为订单消费金额, 如果使用了赠送金额,虚拟金额为赠送金额支付部分,结算金额=订单消费金额-虚拟金额消费部分 */ // 查询支付记录 List orderPayRecordList = orderPayRecordService.getOrderPayRecordList(orderListVO.getOrderCode()); for (OrderPayRecord orderPayRecord : orderPayRecordList) { if (StringUtils.equals(orderPayRecord.getPayMode(), OrderPayRecordEnum.GIFT_BALANCE_PAYMENT.getValue())) { BigDecimal refundAmount = orderPayRecord.getRefundAmount(); if (refundAmount == null) { // 退款金额为null, 需要退款的金额 = 支付金额 - 订单金额 refundAmount = orderPayRecord.getPayAmount().subtract(orderAmount); } // 赠送金额消费部分 = 支付金额 - 需要退款金额 virtualAmount = orderPayRecord.getPayAmount().subtract(refundAmount); // 结算金额 = 订单金额 - 赠送金额消费部分 settleAmount = orderAmount.subtract(virtualAmount); } else { // 没有使用赠送金额支付,那么虚拟金额就是0,结算金额就等于订单金额 settleAmount = orderAmount; } } } else { /* 微信支付 虚拟金额为0 结算金额等于订单消费金额 */ settleAmount = orderAmount; } } OrderBasicInfo build = OrderBasicInfo.builder() .id(Integer.parseInt(orderListVO.getId())) .orderCode(orderListVO.getOrderCode()) .orderAmount(orderAmount) .virtualAmount(virtualAmount) .settleAmount(settleAmount) .build(); orderBasicInfoService.updateOrderBasicInfo(build); } /** * 临时订单退款 */ public void tempOrderRefund() { // 查询出2023-05-29 12:00:00到2023-05-30 23:59:59中使用微信支付,并且有退款金额的订单 String startTime = "2023-05-29 12:00:00"; String endTime = "2023-05-30 23:59:59"; List orderList = orderBasicInfoMapper.tempQueryWeChatRefundOrders(startTime, endTime); Map orderBasicInfoMap = orderList.stream().collect(Collectors.toMap(OrderBasicInfo::getOrderCode, Function.identity(), (k1, k2) -> k1)); Set orderCodes = orderBasicInfoMap.keySet(); // 根据上面的订单号,查微信退款回调,找出没有记录的订单,重新发起一遍退款 List wxpayRefundCallbacks = wxpayRefundCallbackService.selectByOrderCodeList(Lists.newArrayList(orderCodes)); Set refundOrders = wxpayRefundCallbacks.stream().map(WxpayRefundCallback::getOrderCode).collect(Collectors.toSet()); // orderCodeList refundOrders 取差集 Sets.SetView difference = Sets.difference(orderCodes, refundOrders); for (String orderCode : difference) { OrderBasicInfo orderBasicInfo = orderBasicInfoMap.get(orderCode); if (orderBasicInfo == null) { continue; } BigDecimal refundAmount = orderBasicInfo.getRefundAmount(); // 微信退款逻辑 ApplyRefundDTO weChatRefundDTO = new ApplyRefundDTO(); weChatRefundDTO.setOrderCode(orderBasicInfo.getOrderCode()); weChatRefundDTO.setRefundType("1"); weChatRefundDTO.setRefundAmount(refundAmount); try { // orderBasicInfoService.weChatRefund(weChatRefundDTO); } catch (Exception e) { logger.error("临时订单退款接口发生异常 orderCode:{}", orderBasicInfo.getOrderCode(), e); } } } public void splitTheBillForOrderTemp(String merchantId, List orderCodeList) { String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(merchantId); if (StringUtils.isBlank(wechatAppId)) { throw new BusinessException(ReturnCodeEnum.CODE_QUERY_WECHAT_APP_ID_IS_NULL); } AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId); if (adapayMemberAccount == null) { throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_MEMBER_IS_NULL_ERROR); } List orderBasicInfos = orderBasicInfoService.queryOrderList(orderCodeList); for (OrderBasicInfo orderBasicInfo : orderBasicInfos) { try { splitTheBillForOrderTemp(adapayMemberAccount, orderBasicInfo, wechatAppId); } catch (BaseAdaPayException e) { logger.error("余额支付订单分账工具, 发生异常", e); throw new RuntimeException(e); } } } public void splitTheBillForOrderTemp(AdapayMemberAccount adapayMemberAccount, OrderBasicInfo orderBasicInfo, String wechatAppId) throws BaseAdaPayException { logger.info(""); // 查询会员余额支付记录 List recordList = memberAdapayRecordService.selectAdapayRecordList(orderBasicInfo.getMemberId(), ScenarioEnum.BALANCE.getValue()); if (CollectionUtils.isEmpty(recordList)) { logger.info("余额支付订单分账工具, memberId:{}, 未查询到余额充值记录", orderBasicInfo.getMemberId()); return; } String orderCode = orderBasicInfo.getOrderCode(); if (recordList.size() > 1) { logger.info("余额支付订单分账工具, 会员充值记录存在多条,orderCode:{}由人工手动处理", orderCode); return; } // 订单分账金额 BigDecimal amount = queryBalanceOrderSettleInfo(orderCode, orderBasicInfo.getMemberId(), wechatAppId); // 判断分账金额 和结算金额是否相等 if (amount.compareTo(BigDecimal.ZERO) == 0) { logger.info("余额支付订单分账工具, orderCode:{}, 已分账金额为0, 订单结算金额为:{}, 重试执行订单分账", orderCode, orderBasicInfo.getSettleAmount()); // 修改会员的汇付支付记录 for (MemberAdapayRecord memberAdapayRecord : recordList) { BigDecimal spendAmt = memberAdapayRecord.getSpendAmt(); spendAmt = spendAmt.subtract(orderBasicInfo.getOrderAmount()); memberAdapayRecord.setSpendAmt(spendAmt); BigDecimal balanceAmt = memberAdapayRecord.getBalanceAmt(); balanceAmt = balanceAmt.add(orderBasicInfo.getOrderAmount()); memberAdapayRecord.setBalanceAmt(balanceAmt); memberAdapayRecordService.updateByPrimaryKeySelective(memberAdapayRecord); } // 分账金额为0,表示该订单没有执行过分账,再次执行分账 if (OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue().equals(orderBasicInfo.getPayMode())) { // 余额支付的订单 orderBasicInfoService.doBalancePaymentWithDelay(orderBasicInfo, adapayMemberAccount, wechatAppId); } // 再次查询分账 BigDecimal bigDecimal = queryBalanceOrderSettleInfo(orderCode, orderBasicInfo.getMemberId(), wechatAppId); logger.info("余额支付订单分账工具, orderCode:{}, 重新分账完成, 分账金额:{}, 订单结算金额:{}", orderCode, bigDecimal, orderBasicInfo.getSettleAmount()); } else { logger.info("余额支付订单分账工具, orderCode:{}, 已分账金额为:{}, 订单结算金额为:{}, 不再执行订单分账", orderCode, amount, orderBasicInfo.getSettleAmount()); } } /** * 查询余额订单 分账信息 * @param orderCode * @param memberId * @param wechatAppId * @return */ private BigDecimal queryBalanceOrderSettleInfo(String orderCode, String memberId, String wechatAppId) { BigDecimal resultAmt = BigDecimal.ZERO; // 查询会员余额支付记录 List recordList = memberAdapayRecordService.selectAdapayRecordList(memberId, ScenarioEnum.BALANCE.getValue()); if (CollectionUtils.isEmpty(recordList)) { return resultAmt; } // 用汇付api查询分账信息 for (MemberAdapayRecord record : recordList) { QueryPaymentConfirmDTO dto = new QueryPaymentConfirmDTO(); dto.setWechatAppId(wechatAppId); dto.setPaymentId(record.getPaymentId()); QueryPaymentConfirmDetailResponse response = adapayService.queryPaymentConfirmList(dto); if (response != null && CollectionUtils.isNotEmpty(response.getPaymentConfirms())) { for (PaymentConfirmInfo paymentConfirm : response.getPaymentConfirms()) { JSONObject jsonObject = JSON.parseObject(paymentConfirm.getDescription()); if (StringUtils.equals(jsonObject.getString("orderCode"), orderCode)) { // 订单号对的上,累计分账金额 resultAmt = resultAmt.add(new BigDecimal(paymentConfirm.getConfirmAmt())); } } } } return resultAmt; } /** * 查询未分账订单 * @param dto * @return */ public Map queryUndividedOrder(SettleOrderReportDTO dto) { Map resultMap = Maps.newHashMap(); SettleOrderReport orderReport = settleOrderReportService.selectByStationIdAndDate(dto.getStationId(), dto.getTradeDate()); if (orderReport == null) { throw new BusinessException("00300002", "查询站点订单日报为空"); } String orderCodes = orderReport.getOrderCodes(); List orderCodeList = Lists.newArrayList(StringUtils.split(orderCodes, ",")); List clearingBillVOList = clearingWithdrawInfoService.selectWithdrawInfoByOrderCodeList(orderCodeList); if (org.springframework.util.CollectionUtils.isEmpty(clearingBillVOList)) { throw new BusinessException("00300005", "查询清分信息为空"); } String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(orderReport.getMerchantId()); // clearing List clearingList = Lists.newArrayList(); List unClearingList = Lists.newArrayList(); for (ClearingBillVO clearingBillVO : clearingBillVOList) { String paymentId = clearingBillVO.getPaymentId(); QueryPaymentConfirmDTO build = QueryPaymentConfirmDTO.builder() .wechatAppId(wechatAppId) .paymentId(paymentId) .build(); QueryPaymentConfirmDetailResponse response = adapayService.queryPaymentConfirmList(build); List paymentConfirms = response.getPaymentConfirms(); if (CollectionUtils.isEmpty(paymentConfirms)) { unClearingList.add(clearingBillVO); } else { clearingBillVO.setConfirmInfo(paymentConfirms.get(0)); clearingList.add(clearingBillVO); } } resultMap.put("clearingList", clearingList); resultMap.put("unClearingList", unClearingList); resultMap.put("orderSize", clearingBillVOList.size()); return resultMap; } public void batchRefundOrder(List orderCodeList) throws BaseAdaPayException { List orderBasicInfos = orderBasicInfoService.queryOrderList(orderCodeList); for (OrderBasicInfo orderBasicInfo : orderBasicInfos) { String payMode = orderBasicInfo.getPayMode(); if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())) { orderBasicInfoService.retryRefundOrder(orderBasicInfo); } else { orderBasicInfoService.orderPaymentSettlementAndRefund(orderBasicInfo); } // logger.info("批量进行问题订单退款,orderCode:{}, result:{}", orderBasicInfo.getOrderCode(), JSON.toJSONString(result)); } } public void updateMemberAdapayRecord(String memberId) { // 查询 List memberAdapayRecordList = memberAdapayRecordService.selectAdapayRecordList(memberId, ScenarioEnum.BALANCE.getValue()); } /** * 余额支付分账 * @param orderBasicInfo * @param adapayMemberAccount * @param wechatAppId */ public void doBalancePaymentTemp(OrderBasicInfo orderBasicInfo, AdapayMemberAccount adapayMemberAccount, String wechatAppId) throws BaseAdaPayException { String orderCode = orderBasicInfo.getOrderCode(); // 查询订单支付记录 List orderPayRecordList = orderPayRecordService.getOrderPayRecordList(orderCode); logger.info("doBalancePaymentTemp-查询订单:{}支付记录:{}", orderCode, JSON.toJSONString(orderPayRecordList)); if (CollectionUtils.isEmpty(orderPayRecordList)) { return; } BigDecimal settleAmount = orderBasicInfo.getSettleAmount(); OrderPayRecord record = orderPayRecordList.get(0); String deductionRecord = record.getDeductionRecord(); List paymentInfos = orderPayRecordService.parseDeductionRecord(deductionRecord); // 通过paymentId查询 分账记录 for (PaymentInfo paymentInfo : paymentInfos) { QueryPaymentConfirmDTO dto = new QueryPaymentConfirmDTO(); String paymentId = paymentInfo.getPaymentId(); dto.setPaymentId(paymentId); dto.setWechatAppId(wechatAppId); QueryPaymentConfirmDetailResponse response = adapayService.queryPaymentConfirmList(dto); if (response == null) { continue; } List confirms = response.getPaymentConfirms(); if (CollectionUtils.isNotEmpty(confirms)) { // 已经分过账 for (PaymentConfirmInfo confirm : confirms) { JSONObject jsonObject = JSON.parseObject(confirm.getDescription()); // 找到orderCode的分账记录 if (StringUtils.equals(jsonObject.getString("orderCode"), orderCode)) { // 分账金额 BigDecimal confirmAmt = new BigDecimal(confirm.getConfirmAmt()); // 校验是不是分给正确的商户 String adapayMemberId = jsonObject.getString("adapayMemberId"); if (!StringUtils.equals(adapayMemberId, adapayMemberAccount.getAdapayMemberId())) { // 撤销原分账 adapayService.createConfirmReverse(confirm.getId(), wechatAppId); // 重新分账 adapayService.createPaymentConfirmRequest(paymentId, adapayMemberAccount, confirmAmt, orderCode, wechatAppId); } } } } else { // 未分账情况 adapayService.createPaymentConfirmRequest(paymentId, adapayMemberAccount, settleAmount, orderCode, wechatAppId); } } } public void verifyUndividedPayment(QueryOrderDTO dto) { String wechatAppId = "wxbb3e0d474569481d"; String startTime = dto.getStartTime(); String endTime = dto.getEndTime(); // 查询时间段的订单 // List list = adapayCallbackRecordService.selectByDateTime(startTime, endTime); List orderPayDetailVOS = orderBasicInfoService.queryOrderPayDetail(startTime, endTime); logger.info("校验未分账的支付单-在 {} - {} 期间,共查询到{}条支付记录", startTime, endTime, orderPayDetailVOS.size()); // 查询支付单 分账情况 for (OrderPaymentDetailVO record : orderPayDetailVOS) { String paymentId = record.getPaymentId(); BigDecimal confirmAmt = record.getSettleAmount(); String orderCode = record.getOrderCode(); QueryPaymentConfirmDTO queryPaymentConfirmDTO = new QueryPaymentConfirmDTO(); queryPaymentConfirmDTO.setWechatAppId(wechatAppId); queryPaymentConfirmDTO.setPaymentId(paymentId); QueryPaymentConfirmDetailResponse response = adapayService.queryPaymentConfirmList(queryPaymentConfirmDTO); logger.info("校验未分账的支付单-支付id:{}, 查询到的分账信息:{}", paymentId, JSON.toJSONString(response)); List confirms = response.getPaymentConfirms(); if (CollectionUtils.isEmpty(confirms)) { logger.info("校验未分账的支付单-支付id:{}没有进行过分账", paymentId); // 没有配置结算账户的,默认分到本商户 AdapayMemberAccount defaultAccount = adapayMemberAccountService.getDefault(); PaymentConfirmResponse paymentConfirmRequest = adapayService.createPaymentConfirmRequest(paymentId, defaultAccount, confirmAmt, orderCode, wechatAppId); logger.info("校验未分账的支付单-支付id:{}, 执行分账结果:{}", paymentId, JSON.toJSONString(paymentConfirmRequest)); } } } /** * 检查支付单 * @param dto */ public void checkPayment(QueryOrderDTO dto) throws BaseAdaPayException { // 根据时间段查询支付对象列表 List adaPayments = adapayService.queryPaymentList(dto.getStartTime(), dto.getEndTime()); if (CollectionUtils.isEmpty(adaPayments)) { return; } List paymentIdList = Lists.newArrayList(); BigDecimal total = BigDecimal.ZERO; AdapayMemberAccount aDefault = adapayMemberAccountService.getDefault(); String wechatAppId = "wxbb3e0d474569481d"; for (AdaPayment adaPayment : adaPayments) { String paymentId = adaPayment.getId(); String pay_mode = adaPayment.getPay_mode(); if (StringUtils.isBlank(pay_mode)) { // 实时分账的不检查 continue; } String status = adaPayment.getStatus(); if (!StringUtils.equals(status, AdapayStatusEnum.SUCCEEDED.getValue())) { // 不是交易成功的不检查 continue; } if (StringUtils.equals(paymentId, "002212023102509474610563069333816762368")) { continue; } // 交易金额 BigDecimal payAmt = new BigDecimal(adaPayment.getPay_amt()); // 若为延时分账时,已发起支付撤销的总金额 BigDecimal reservedAmt = new BigDecimal(adaPayment.getReserved_amt()); // 若为延时分账时,已发起支付确认的总金额 BigDecimal confirmedAmt = new BigDecimal(adaPayment.getConfirmed_amt()); BigDecimal subtract = payAmt.subtract(reservedAmt).subtract(confirmedAmt); if (subtract.compareTo(BigDecimal.ZERO) > 0) { paymentIdList.add(paymentId); total = total.add(subtract); logger.info("支付单:{}, 支付金额:{}, 总撤销金额:{}, 总确认金额:{}, 剩余金额:{}", paymentId, payAmt, reservedAmt, confirmedAmt, subtract); // adapayService.createPaymentConfirmRequest(paymentId, aDefault, subtract, null, wechatAppId); } } logger.info("{} - {} 期间,共有{}笔支付单存在剩余金额, 共计:{},list:{}", dto.getStartTime(), dto.getEndTime(), paymentIdList.size(), total, JSON.toJSONString(paymentIdList)); } /** * 校验是否为并充订单 */ @CostTime public Map> checkCombinedChargingOrder(List orderCodeList) throws BaseAdaPayException { Map> resultMap = Maps.newHashMap(); List combinedChargingOrderList = Lists.newArrayList(); List notCombinedChargingOrderList = Lists.newArrayList(); List noDataOrderList = Lists.newArrayList(); for (String orderCode : orderCodeList) { // 查询orderMonitorData OrderMonitorData orderMonitorData = orderMonitorDataService.selectByOrderCode(orderCode); if (orderMonitorData == null) { logger.info("订单:{}不存在", orderCode); noDataOrderList.add(orderCode); continue; } JSONArray jsonArray = JSONArray.parseArray(orderMonitorData.getMonitorData()); List orderOutputCurrentList = Lists.newArrayList(); for (int i = 0; i < jsonArray.size(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); String outputCurrent = jsonObject.getString("outputCurrent"); orderOutputCurrentList.add(new BigDecimal(outputCurrent)); } // 如果orderOutputCurrentList中任意一值大于250,判定为并充订单 if (orderOutputCurrentList.stream().anyMatch(current -> current.compareTo(new BigDecimal("250")) > 0)) { combinedChargingOrderList.add(orderCode); } else { notCombinedChargingOrderList.add(orderCode); } } resultMap.put("combinedChargingOrderList", combinedChargingOrderList); resultMap.put("notCombinedChargingOrderList", notCombinedChargingOrderList); resultMap.put("noDataOrderList", noDataOrderList); return resultMap; } /** * 修正并充订单数据 * @param dto */ @Transactional(rollbackFor = Exception.class) public List correctCombinedChargingOrder(QueryOrderDTO dto) { List orderCodeList = dto.getOrderCodeList(); logger.info("修正并充订单数据工具,订单号:{}", JSON.toJSONString(orderCodeList)); // 查询临时表,不要重复修正 String redisKey = "correct_combined_charging_order"; List redisResult = redisCache.getCacheList(redisKey); if (CollectionUtils.isNotEmpty(redisResult)) { logger.info("修正并充订单数据工具, 已修正订单:{}", JSON.toJSONString(redisResult)); // 过滤掉已修正的订单 orderCodeList.removeAll(redisResult); logger.info("修正并充订单数据工具. 过滤掉已修正的订单剩余:{}", JSON.toJSONString(orderCodeList)); } if (CollectionUtils.isEmpty(orderCodeList)) { logger.info("修正并充订单数据工具, 无需要修正的订单"); return Lists.newArrayList(); } BigDecimal multiple = new BigDecimal("0.5"); // 查询订单主表数据 List orderBasicInfos = orderBasicInfoService.queryOrderList(orderCodeList); for (OrderBasicInfo orderBasicInfo : orderBasicInfos) { orderBasicInfo.setOrderAmount(orderBasicInfo.getOrderAmount().multiply(multiple)); orderBasicInfo.setVirtualAmount(orderBasicInfo.getVirtualAmount().multiply(multiple)); orderBasicInfo.setUpdateTime(DateUtils.getNowDate()); } // 查询订单详情数据 List orderDetailList = orderBasicInfoService.getOrderDetailList(orderCodeList); for (OrderDetail orderDetail : orderDetailList) { // 订单总用电量 orderDetail.setTotalUsedElectricity(orderDetail.getTotalUsedElectricity().multiply(multiple)); // 订单总电费金额 orderDetail.setTotalElectricityAmount(orderDetail.getTotalElectricityAmount().multiply(multiple)); // 订单总服务费金额 orderDetail.setTotalServiceAmount(orderDetail.getTotalServiceAmount().multiply(multiple)); // 订单总金额 orderDetail.setTotalOrderAmount(orderDetail.getTotalOrderAmount().multiply(multiple)); // 尖时段 if (orderDetail.getSharpUsedElectricity() != null && orderDetail.getSharpUsedElectricity().compareTo(BigDecimal.ZERO) > 0) { orderDetail.setSharpUsedElectricity(orderDetail.getSharpUsedElectricity().multiply(multiple)); // orderDetail.setSharpAmount(orderDetail.getSharpAmount().multiply(multiple)); orderDetail.setSharpAmount(orderDetail.getSharpPrice().multiply(orderDetail.getSharpUsedElectricity())); } // 峰时段 if (orderDetail.getPeakUsedElectricity() != null && orderDetail.getPeakUsedElectricity().compareTo(BigDecimal.ZERO) > 0) { orderDetail.setPeakUsedElectricity(orderDetail.getPeakUsedElectricity().multiply(multiple)); // orderDetail.setPeakAmount(orderDetail.getPeakAmount().multiply(multiple)); orderDetail.setPeakAmount(orderDetail.getPeakPrice().multiply(orderDetail.getPeakUsedElectricity())); } // 平时段 if (orderDetail.getFlatUsedElectricity() != null && orderDetail.getFlatUsedElectricity().compareTo(BigDecimal.ZERO) > 0) { orderDetail.setFlatUsedElectricity(orderDetail.getFlatUsedElectricity().multiply(multiple)); // orderDetail.setFlatAmount(orderDetail.getFlatAmount().multiply(multiple)); orderDetail.setFlatAmount(orderDetail.getFlatPrice().multiply(orderDetail.getFlatUsedElectricity())); } // 谷时段 if (orderDetail.getValleyUsedElectricity() != null && orderDetail.getValleyUsedElectricity().compareTo(BigDecimal.ZERO) > 0) { orderDetail.setValleyUsedElectricity(orderDetail.getValleyUsedElectricity().multiply(multiple)); // orderDetail.setValleyAmount(orderDetail.getValleyAmount().multiply(multiple)); orderDetail.setValleyAmount(orderDetail.getValleyPrice().multiply(orderDetail.getValleyUsedElectricity())); } orderDetail.setUpdateTime(DateUtils.getNowDate()); } // 更新数据库 int updateCount = 0; if (CollectionUtils.isNotEmpty(orderBasicInfos)) { updateCount = orderBasicInfoService.updateBatch(orderBasicInfos); } if (CollectionUtils.isNotEmpty(orderDetailList)) { orderDetailService.updateBatch(orderDetailList); } if (orderCodeList.size() == updateCount) { logger.info("修正并充订单数据工具, 修正成功, 订单号:{}", JSON.toJSONString(orderCodeList)); Map> redisMap = Maps.newHashMap(); redisMap.put(redisKey, orderCodeList); redisCache.batchSetCacheList(redisMap, 300, TimeUnit.DAYS); } return orderCodeList; } /** * 关闭未支付订单 */ public void closeUnpaidOrder(QueryOrderDTO dto) { // 查询未支付订单 List unpaidOrderList = orderBasicInfoService.getUnpaidOrderList(dto.getStartTime(), dto.getEndTime()); logger.info("closeUnpaidOrders, startTime:{}, endTime:{}, 未支付订单:{}", dto.getStartTime(), dto.getEndTime(), JSON.toJSONString(unpaidOrderList)); // 关闭未支付订单 orderBasicInfoService.closeUnpaidOrders(unpaidOrderList); } public void calculateOrderDiscountsV2(OrderBasicInfo orderBasicInfo, OrderDetail orderDetail) { String orderCode = orderBasicInfo.getOrderCode(); String transactionCode = orderBasicInfo.getTransactionCode(); String memberId = orderBasicInfo.getMemberId(); // 会员id String stationId = orderBasicInfo.getStationId(); // 站点id String merchantId = orderBasicInfo.getMerchantId(); // 运营商id if (orderDetail == null) { logger.info("计算订单折扣V2, OrderDetail为空(orderCode:{}, transactionCode:{}), 直接返回!", orderCode, transactionCode); return; } // 原始电费金额 BigDecimal originalTotalElectricityAmount = orderDetail.getTotalElectricityAmount(); // 原始服务费金额 BigDecimal originalTotalServiceAmount = orderDetail.getTotalServiceAmount(); logger.info("计算订单折扣V2, orderCode:{}, 原始电费金额:{}, 原始服务费金额:{}", orderCode, originalTotalElectricityAmount, originalTotalServiceAmount); // 电费折扣金额 初始值为0 BigDecimal electricityAmountDiscount = BigDecimal.ZERO; // 服务费折扣金额 初始值为0 BigDecimal serviceAmountDiscount = BigDecimal.ZERO; // 优惠后电费金额 初始值为优惠前金额 BigDecimal afterDiscountElectricityAmount = BigDecimal.ZERO; // 优惠后服务费金额 初始值为优惠前金额 BigDecimal afterDiscountServiceAmount = BigDecimal.ZERO; // 查询会员在该站点享受的优惠 MemberDiscountVO memberDiscountVO = memberGroupService.queryMemberDiscountV2(merchantId, stationId, memberId); if (memberDiscountVO == null) { // 如果没有优惠,则优惠后金额 等于优惠前金额 afterDiscountServiceAmount = orderDetail.getTotalServiceAmount(); afterDiscountElectricityAmount = orderDetail.getTotalElectricityAmount(); } else { // 集团会员的订单,记录集团编号 orderBasicInfo.setGroupCode(memberDiscountVO.getGroupCode()); // 集团会员的优惠计费模板 BillingTemplateVO billingTemplateVO = memberDiscountVO.getBillingTemplateVO(); // 尖时段用电量 BigDecimal sharpUsedElectricity = orderDetail.getSharpUsedElectricity(); if (sharpUsedElectricity != null) { // 计算该时段电费 = 电费单价 x 用电量 BigDecimal sharpElectricityAmount = billingTemplateVO.getSharpElectricityPrice() .multiply(sharpUsedElectricity) .setScale(2, RoundingMode.DOWN); // 计算该时段服务费 BigDecimal sharpServiceAmount = billingTemplateVO.getSharpServicePrice() .multiply(sharpUsedElectricity) .setScale(2, RoundingMode.DOWN); // 汇总 afterDiscountElectricityAmount = afterDiscountElectricityAmount.add(sharpElectricityAmount); afterDiscountServiceAmount = afterDiscountServiceAmount.add(sharpServiceAmount); logger.info("计算订单折扣V2, orderCode:{}, 尖时段用电量:{}, 电费单价:{}, 电费金额:{}, 服务费单价:{}, 服务费金额:{}", orderCode, sharpUsedElectricity, billingTemplateVO.getSharpElectricityPrice(), sharpElectricityAmount, billingTemplateVO.getSharpServicePrice(), sharpServiceAmount); } // 峰时段用电量 BigDecimal peakUsedElectricity = orderDetail.getPeakUsedElectricity(); if (peakUsedElectricity != null) { // 计算该时段电费 = 电费单价 x 用电量 BigDecimal peakElectricityAmount = billingTemplateVO.getPeakElectricityPrice() .multiply(peakUsedElectricity) .setScale(2, RoundingMode.DOWN); // 计算该时段服务费 BigDecimal peakServiceAmount = billingTemplateVO.getPeakServicePrice() .multiply(peakUsedElectricity) .setScale(2, RoundingMode.DOWN); // 汇总 afterDiscountElectricityAmount = afterDiscountElectricityAmount.add(peakElectricityAmount); afterDiscountServiceAmount = afterDiscountServiceAmount.add(peakServiceAmount); logger.info("计算订单折扣V2, orderCode:{}, 峰时段用电量:{}, 电费单价:{}, 电费金额:{}, 服务费单价:{}, 服务费金额:{}", orderCode, peakUsedElectricity, billingTemplateVO.getPeakElectricityPrice(), peakElectricityAmount, billingTemplateVO.getPeakServicePrice(), peakServiceAmount); } // 平时段用电量 BigDecimal flatUsedElectricity = orderDetail.getFlatUsedElectricity(); if (flatUsedElectricity != null) { // 计算该时段电费 = 电费单价 x 用电量 BigDecimal flatElectricityAmount = billingTemplateVO.getFlatElectricityPrice() .multiply(flatUsedElectricity) .setScale(2, RoundingMode.DOWN); // 计算该时段服务费 BigDecimal flatServiceAmount = billingTemplateVO.getFlatServicePrice() .multiply(flatUsedElectricity) .setScale(2, RoundingMode.DOWN); // 汇总 afterDiscountElectricityAmount = afterDiscountElectricityAmount.add(flatElectricityAmount); afterDiscountServiceAmount = afterDiscountServiceAmount.add(flatServiceAmount); logger.info("计算订单折扣V2, orderCode:{}, 平时段用电量:{}, 电费单价:{}, 电费金额:{}, 服务费单价:{}, 服务费金额:{}", orderCode, flatUsedElectricity, billingTemplateVO.getFlatElectricityPrice(), flatElectricityAmount, billingTemplateVO.getFlatServicePrice(), flatServiceAmount); } // 谷时段用电量 BigDecimal valleyUsedElectricity = orderDetail.getValleyUsedElectricity(); if (valleyUsedElectricity != null) { // 计算该时段电费 = 电费单价 x 用电量 BigDecimal valleyElectricityAmount = billingTemplateVO.getValleyElectricityPrice() .multiply(valleyUsedElectricity) .setScale(2, RoundingMode.DOWN); // 计算该时段服务费 BigDecimal valleyServiceAmount = billingTemplateVO.getValleyServicePrice() .multiply(valleyUsedElectricity) .setScale(2, RoundingMode.DOWN); // 汇总 afterDiscountElectricityAmount = afterDiscountElectricityAmount.add(valleyElectricityAmount); afterDiscountServiceAmount = afterDiscountServiceAmount.add(valleyServiceAmount); logger.info("计算订单折扣V2, orderCode:{}, 谷时段用电量:{}, 电费单价:{}, 电费金额:{}, 服务费单价:{}, 服务费金额:{}", orderCode, valleyUsedElectricity, billingTemplateVO.getValleyElectricityPrice(), valleyElectricityAmount, billingTemplateVO.getValleyServicePrice(), valleyServiceAmount); } // 计算优惠了多少钱 // 电费折扣金额 = 优惠前电费 - 优惠后电费 electricityAmountDiscount = originalTotalElectricityAmount.subtract(afterDiscountElectricityAmount); // 服务费折扣金额 = 优惠前服务费 - 优惠后服务费 serviceAmountDiscount = originalTotalServiceAmount.subtract(afterDiscountServiceAmount); } /* 更新 数据 */ // 订单折扣金额 = 电费折扣金额 + 服务费折扣金额 BigDecimal discountAmount = electricityAmountDiscount.add(serviceAmountDiscount); orderBasicInfo.setDiscountAmount(discountAmount); // 更新结算金额 结算金额 = 消费金额 - 虚拟金额 - 优惠金额 BigDecimal newSettleAmount = orderBasicInfo.getSettleAmount().subtract(discountAmount); if (newSettleAmount.compareTo(BigDecimal.ZERO) < 0) { // 如果结算金额为0,减去优惠金额后为负数,还设置为0 newSettleAmount = BigDecimal.ZERO; } orderBasicInfo.setSettleAmount(newSettleAmount); // 优惠后总消费金额 = 折扣后电费 + 折扣后服务费 BigDecimal totalConsumeAmount = afterDiscountServiceAmount.add(afterDiscountElectricityAmount); // 更新退款金额 = 支付金额 - 优惠后总消费金额 BigDecimal refundAmount = orderBasicInfo.getPayAmount().subtract(totalConsumeAmount).setScale(2, RoundingMode.DOWN); orderBasicInfo.setRefundAmount(refundAmount); // 电费折扣金额(电费便宜了多少钱) orderDetail.setDiscountElectricityAmount(electricityAmountDiscount); // 服务费折扣金额(服务费便宜了多少钱) orderDetail.setDiscountServiceAmount(serviceAmountDiscount); logger.info("计算订单折扣, orderCode:{}, memberId:{}, 订单折扣金额:{}, 电费折扣金额:{}, 服务费折扣金额:{}, 优惠后总消费金额:{}", orderCode, memberId, discountAmount, electricityAmountDiscount, serviceAmountDiscount, totalConsumeAmount); } }