Files
jsowell-charger-web/jsowell-admin/src/main/java/com/jsowell/service/TempService.java
2023-10-13 15:33:13 +08:00

532 lines
25 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.jsowell.service;
import com.alibaba.fastjson2.JSON;
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.dto.QueryPaymentConfirmDTO;
import com.jsowell.adapay.response.QueryPaymentConfirmDetailResponse;
import com.jsowell.adapay.service.AdapayService;
import com.jsowell.adapay.vo.OrderSettleResult;
import com.jsowell.adapay.vo.PaymentInfo;
import com.jsowell.common.core.redis.RedisCache;
import com.jsowell.common.enums.ykc.*;
import com.jsowell.common.exception.BusinessException;
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.service.*;
import com.jsowell.pile.service.orderlogic.AbstractOrderLogic;
import com.jsowell.pile.service.orderlogic.DelayMerchantOrderLogic;
import com.jsowell.pile.transaction.service.TransactionService;
import com.jsowell.pile.vo.web.ClearingBillVO;
import com.jsowell.pile.vo.web.OrderListVO;
import com.jsowell.wxpay.service.WxAppletRemoteService;
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 java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Set;
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 IOrderBasicInfoService orderBasicInfoService;
@Autowired
private ClearingWithdrawInfoService clearingWithdrawInfoService;
@Autowired
private TransactionService transactionService;
@Autowired
private RedisCache redisCache;
@Autowired
private WxAppletRemoteService wxAppletRemoteService;
@Autowired
private OrderPayRecordService orderPayRecordService;
@Autowired
private IMemberBasicInfoService memberBasicInfoService;
@Autowired
private WxpayCallbackRecordService wxpayCallbackRecordService;
@Autowired
private AdapayCallbackRecordService adapayCallbackRecordService;
@Autowired
private WechatPayService wechatPayService;
@Autowired
private IOrderAbnormalRecordService orderAbnormalRecordService;
@Autowired
private TransactionService pileTransactionService;
@Autowired
private IPileBasicInfoService pileBasicInfoService;
@Autowired
private IPileConnectorInfoService pileConnectorInfoService;
@Autowired
private WxpayRefundCallbackService wxpayRefundCallbackService;
@Autowired
private IPileBillingTemplateService pileBillingTemplateService;
@Autowired
private IPileAuthCardService pileAuthCardService;
@Autowired
private OrderMonitorDataService orderMonitorDataService;
@Autowired
private IPileStationInfoService pileStationInfoService;
@Autowired
private IPileMerchantInfoService pileMerchantInfoService;
@Autowired
private IMemberPlateNumberRelationService memberPlateNumberRelationService;
@Autowired
private IMemberTransactionRecordService memberTransactionRecordService;
@Autowired
private ISettleOrderReportService settleOrderReportService;
@Autowired
private IAdapayMemberAccountService adapayMemberAccountService;
@Autowired
private PileRemoteService pileRemoteService;
@Autowired
private IPileStationWhitelistService pileStationWhitelistService;
@Autowired
private AdapayService adapayService;
@Autowired
private MemberAdapayRecordService memberAdapayRecordService;
/**
* 手动接口执行订单分账逻辑
*/
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<SettleOrderReport> stationReportList = settleOrderReportService.selectByMerchantIdAndDate(merchantId, tradeDate);
for (SettleOrderReport orderReport : stationReportList) {
String orderCodes = orderReport.getOrderCodes();
if (StringUtils.isBlank(orderCodes)) {
logger.info("手动接口执行订单分账逻辑-站点:{}, 日期:{}, 没有查到订单数据", orderReport.getStationId(), tradeDate);
continue;
}
List<String> orderCodeList = Lists.newArrayList(StringUtils.split(orderCodes, ","));
List<OrderBasicInfo> orderBasicInfos = orderBasicInfoService.queryOrderList(orderCodeList);
if (CollectionUtils.isEmpty(orderBasicInfos)) {
logger.info("手动接口执行订单分账逻辑-站点:{}, 日期:{}, 没有查到订单数据", orderReport.getStationId(), tradeDate);
continue;
}
// 执行分账
for (OrderBasicInfo orderBasicInfo : orderBasicInfos) {
try {
OrderSettleResult orderSettleResult = null;
logger.info("手动接口执行订单分账逻辑-orderCode:{}, payMode:{}", orderBasicInfo.getOrderCode(), orderBasicInfo.getPayMode());
if (OrderPayModeEnum.PAYMENT_OF_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<OrderListVO> 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_BALANCE.getValue())) {
/*
余额支付 查询支付记录如全部用本金支付则虚拟金额为0结算金额为订单消费金额
如果使用了赠送金额,虚拟金额为赠送金额支付部分,结算金额=订单消费金额-虚拟金额消费部分
*/
// 查询支付记录
List<OrderPayRecord> 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(Long.parseLong(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<OrderBasicInfo> orderList = orderBasicInfoMapper.tempQueryWeChatRefundOrders(startTime, endTime);
Map<String, OrderBasicInfo> orderBasicInfoMap = orderList.stream().collect(Collectors.toMap(OrderBasicInfo::getOrderCode, Function.identity(), (k1, k2) -> k1));
Set<String> orderCodes = orderBasicInfoMap.keySet();
// 根据上面的订单号,查微信退款回调,找出没有记录的订单,重新发起一遍退款
List<WxpayRefundCallback> wxpayRefundCallbacks = wxpayRefundCallbackService.selectByOrderCodeList(Lists.newArrayList(orderCodes));
Set<String> refundOrders = wxpayRefundCallbacks.stream().map(WxpayRefundCallback::getOrderCode).collect(Collectors.toSet());
// orderCodeList refundOrders 取差集
Sets.SetView<String> 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<String> 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<OrderBasicInfo> 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<MemberAdapayRecord> 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_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<MemberAdapayRecord> 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 (QueryPaymentConfirmDetailResponse.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<String, Object> queryUndividedOrder(SettleOrderReportDTO dto) {
Map<String, Object> resultMap = Maps.newHashMap();
SettleOrderReport orderReport = settleOrderReportService.selectByStationIdAndDate(dto.getStationId(), dto.getTradeDate());
if (orderReport == null) {
throw new BusinessException("00300002", "查询站点订单日报为空");
}
String orderCodes = orderReport.getOrderCodes();
List<String> orderCodeList = Lists.newArrayList(StringUtils.split(orderCodes, ","));
List<ClearingBillVO> clearingBillVOList = clearingWithdrawInfoService.selectWithdrawInfoByOrderCodeList(orderCodeList);
if (org.springframework.util.CollectionUtils.isEmpty(clearingBillVOList)) {
throw new BusinessException("00300005", "查询清分信息为空");
}
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(orderReport.getMerchantId());
// clearing
List<ClearingBillVO> clearingList = Lists.newArrayList();
List<ClearingBillVO> 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<QueryPaymentConfirmDetailResponse.PaymentConfirmInfo> 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<String> orderCodeList) throws BaseAdaPayException {
List<OrderBasicInfo> 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<MemberAdapayRecord> 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<OrderPayRecord> 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();
AbstractOrderLogic orderLogic = new DelayMerchantOrderLogic();
List<PaymentInfo> paymentInfos = orderLogic.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<QueryPaymentConfirmDetailResponse.PaymentConfirmInfo> confirms = response.getPaymentConfirms();
if (CollectionUtils.isNotEmpty(confirms)) {
// 已经分过账
for (QueryPaymentConfirmDetailResponse.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) {
// 查询时间段的订单
// 查询支付单 分账情况
// 没有配置结算账户的,默认分到本商户
}
}