mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-04-20 11:05:18 +08:00
update
This commit is contained in:
@@ -1,14 +1,36 @@
|
||||
package com.jsowell.pile.service.orderlogic;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.jsowell.adapay.service.AdapayService;
|
||||
import com.jsowell.common.constant.CacheConstants;
|
||||
import com.jsowell.common.core.domain.ykc.RealTimeMonitorData;
|
||||
import com.jsowell.common.core.domain.ykc.TransactionRecordsData;
|
||||
import com.jsowell.common.core.redis.RedisCache;
|
||||
import com.jsowell.common.enums.ykc.OrderPayModeEnum;
|
||||
import com.jsowell.common.enums.ykc.OrderStatusEnum;
|
||||
import com.jsowell.common.util.DateUtils;
|
||||
import com.jsowell.common.util.StringUtils;
|
||||
import com.jsowell.pile.domain.OrderBasicInfo;
|
||||
import com.jsowell.pile.domain.OrderDetail;
|
||||
import com.jsowell.pile.domain.OrderMonitorData;
|
||||
import com.jsowell.pile.domain.OrderPayRecord;
|
||||
import com.jsowell.pile.dto.PayOrderDTO;
|
||||
import com.jsowell.pile.dto.PayOrderSuccessCallbackDTO;
|
||||
import com.jsowell.pile.service.IOrderBasicInfoService;
|
||||
import com.jsowell.pile.service.*;
|
||||
import com.jsowell.pile.transaction.service.TransactionService;
|
||||
import com.jsowell.pile.vo.web.BalanceDeductionAmountVO;
|
||||
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 javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -16,8 +38,52 @@ import java.util.Map;
|
||||
* 描述订单逻辑
|
||||
*/
|
||||
public abstract class AbstractOrderLogic {
|
||||
protected Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Resource
|
||||
private IOrderBasicInfoService orderBasicInfoService;
|
||||
protected IOrderBasicInfoService orderBasicInfoService;
|
||||
|
||||
@Autowired
|
||||
protected IMemberBasicInfoService memberBasicInfoService;
|
||||
|
||||
@Autowired
|
||||
protected MemberAdapayRecordService memberAdapayRecordService;
|
||||
|
||||
@Autowired
|
||||
protected OrderPayRecordService orderPayRecordService;
|
||||
|
||||
@Autowired
|
||||
protected IMemberTransactionRecordService memberTransactionRecordService;
|
||||
|
||||
@Autowired
|
||||
protected AdapayService adapayService;
|
||||
|
||||
@Autowired
|
||||
protected IAdapayMemberAccountService adapayMemberAccountService;
|
||||
|
||||
@Autowired
|
||||
protected IPileMerchantInfoService pileMerchantInfoService;
|
||||
|
||||
@Autowired
|
||||
protected TransactionService transactionService;
|
||||
|
||||
@Autowired
|
||||
protected AdapayCallbackRecordService adapayCallbackRecordService;
|
||||
|
||||
@Autowired
|
||||
protected IPileAuthCardService pileAuthCardService;
|
||||
|
||||
@Autowired
|
||||
protected IMemberPlateNumberRelationService memberPlateNumberRelationService;
|
||||
|
||||
@Autowired
|
||||
protected WxAppletRemoteService wxAppletRemoteService;
|
||||
|
||||
@Autowired
|
||||
protected OrderMonitorDataService orderMonitorDataService;
|
||||
|
||||
@Autowired
|
||||
protected RedisCache redisCache;
|
||||
|
||||
/**
|
||||
* 余额支付订单
|
||||
@@ -42,7 +108,7 @@ public abstract class AbstractOrderLogic {
|
||||
/**
|
||||
* 余额支付订单退款
|
||||
*/
|
||||
public abstract void balancePayOrderRefund(OrderBasicInfo orderBasicInfo);
|
||||
public abstract void balancePaymentOrderRefund(OrderBasicInfo orderBasicInfo);
|
||||
|
||||
/**
|
||||
* 在线支付订单退款
|
||||
@@ -62,4 +128,285 @@ public abstract class AbstractOrderLogic {
|
||||
protected List<BalanceDeductionAmountVO> calculateTheBalanceDeductionAmount(String memberId, BigDecimal amount) {
|
||||
return orderBasicInfoService.calculateTheBalanceDeductionAmount(memberId, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回更新后的OrderBasicInfo对象
|
||||
* 专用方法,其他地方如果要用请仔细检查
|
||||
* 【公共方法】
|
||||
*/
|
||||
protected void returnUpdateOrderBasicInfo(OrderBasicInfo orderBasicInfo, TransactionRecordsData data) {
|
||||
// 订单编号
|
||||
String orderCode = orderBasicInfo.getOrderCode();
|
||||
// 消费金额就是订单总金额/交易记录传过来的消费金额
|
||||
BigDecimal orderAmount = new BigDecimal(data.getConsumptionAmount());
|
||||
// 付款金额 - 实际消费金额,如果有剩余,需要走退款操作 当使用余额支付时payAmount = principalPay + giftPay
|
||||
BigDecimal payAmount = orderBasicInfo.getPayAmount();
|
||||
|
||||
// 有时候充电桩到达金额停止充电会多出一点金额,比如实际需要充50元的电,充电桩传来的消费金额为50.01元,在后台记录的时候需要舍去
|
||||
if (orderAmount.compareTo(payAmount) > 0) {
|
||||
logger.info("结算订单:【{}】充电桩传来的消费金额:【{}】大于付款金额:【{}】, 消费金额设置为付款金额相等数据", orderCode, orderAmount, payAmount);
|
||||
orderAmount = payAmount;
|
||||
}
|
||||
orderBasicInfo.setOrderAmount(orderAmount); // 订单总金额
|
||||
|
||||
// 虚拟金额 指订单消费中不参与结算的部分
|
||||
BigDecimal virtualAmount = BigDecimal.ZERO;
|
||||
if (OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue().equals(orderBasicInfo.getPayMode())) {
|
||||
// 白名单支付所消费的金额,都属于虚拟金额,不参与结算对账
|
||||
virtualAmount = new BigDecimal(orderAmount.toString());
|
||||
}
|
||||
|
||||
// 剩余需要退回的金额 residue
|
||||
BigDecimal residue = payAmount.subtract(orderAmount);
|
||||
|
||||
// 把交易记录中的用电量,金额等信息 更新到orderBasicInfo和orderDetail
|
||||
orderBasicInfo.setVirtualAmount(virtualAmount); // 虚拟金额
|
||||
orderBasicInfo.setSettleAmount(orderAmount.subtract(virtualAmount)); // 结算金额
|
||||
orderBasicInfo.setOrderStatus(OrderStatusEnum.ORDER_COMPLETE.getValue());
|
||||
orderBasicInfo.setReason(data.getStopReasonMsg()); // 充电停止原因
|
||||
orderBasicInfo.setSettlementTime(DateUtils.getNowDate()); // 结算时间
|
||||
orderBasicInfo.setRefundAmount(residue); // 结算退款金额
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取更新数据后的orderDetail对象
|
||||
* 专用方法,其他地方如果要用请仔细检查
|
||||
* 【公共方法】
|
||||
* @return 查询并更新过数据的orderDetail
|
||||
*/
|
||||
protected OrderDetail returnUpdateOrderDetail(OrderBasicInfo orderBasicInfo, TransactionRecordsData data) {
|
||||
String orderCode = orderBasicInfo.getOrderCode();
|
||||
BigDecimal orderAmount = orderBasicInfo.getOrderAmount();
|
||||
// 更新订单详情 查询订单详情 修改订单数据
|
||||
OrderDetail orderDetail = orderBasicInfoService.getOrderDetailByOrderCode(orderCode);
|
||||
try {
|
||||
// 总电费金额
|
||||
BigDecimal totalElectricityAmount = BigDecimal.ZERO;
|
||||
|
||||
// 尖时段用电量
|
||||
String sharpUsedElectricity = data.getSharpUsedElectricity();
|
||||
if (sharpUsedElectricity != null) {
|
||||
orderDetail.setSharpUsedElectricity(new BigDecimal(sharpUsedElectricity));
|
||||
if (data.getSharpPrice() != null) {
|
||||
orderDetail.setSharpPrice(new BigDecimal(data.getSharpPrice()));
|
||||
}
|
||||
if (data.getSharpAmount() != null) {
|
||||
orderDetail.setSharpAmount(new BigDecimal(data.getSharpAmount()));
|
||||
}
|
||||
// 计算该时段电费
|
||||
BigDecimal multiply = orderDetail.getSharpElectricityPrice()
|
||||
.multiply(new BigDecimal(sharpUsedElectricity))
|
||||
.setScale(2, RoundingMode.DOWN);
|
||||
totalElectricityAmount = totalElectricityAmount.add(multiply);
|
||||
}
|
||||
|
||||
// 峰时段用电量
|
||||
String peakUsedElectricity = data.getPeakUsedElectricity();
|
||||
if (peakUsedElectricity != null) {
|
||||
orderDetail.setPeakUsedElectricity(new BigDecimal(peakUsedElectricity));
|
||||
if (data.getPeakPrice() != null) {
|
||||
orderDetail.setPeakPrice(new BigDecimal(data.getPeakPrice()));
|
||||
}
|
||||
if (data.getPeakAmount() != null) {
|
||||
orderDetail.setPeakAmount(new BigDecimal(data.getPeakAmount()));
|
||||
}
|
||||
// 计算该时段电费
|
||||
BigDecimal multiply = orderDetail.getPeakElectricityPrice()
|
||||
.multiply(new BigDecimal(peakUsedElectricity))
|
||||
.setScale(2, RoundingMode.DOWN);
|
||||
totalElectricityAmount = totalElectricityAmount.add(multiply);
|
||||
}
|
||||
|
||||
// 平时段用电量
|
||||
String flatUsedElectricity = data.getFlatUsedElectricity();
|
||||
if (flatUsedElectricity != null) {
|
||||
orderDetail.setFlatUsedElectricity(new BigDecimal(flatUsedElectricity));
|
||||
if (data.getFlatPrice() != null) {
|
||||
orderDetail.setFlatPrice(new BigDecimal(data.getFlatPrice()));
|
||||
}
|
||||
if (data.getFlatAmount() != null) {
|
||||
orderDetail.setFlatAmount(new BigDecimal(data.getFlatAmount()));
|
||||
}
|
||||
// 计算该时段电费
|
||||
BigDecimal multiply = orderDetail.getFlatElectricityPrice()
|
||||
.multiply(new BigDecimal(flatUsedElectricity))
|
||||
.setScale(2, RoundingMode.DOWN);
|
||||
totalElectricityAmount = totalElectricityAmount.add(multiply);
|
||||
}
|
||||
|
||||
// 谷时段用电量
|
||||
String valleyUsedElectricity = data.getValleyUsedElectricity();
|
||||
if (valleyUsedElectricity != null) {
|
||||
orderDetail.setValleyUsedElectricity(new BigDecimal(valleyUsedElectricity));
|
||||
if (data.getValleyPrice() != null) {
|
||||
orderDetail.setValleyPrice(new BigDecimal(data.getValleyPrice()));
|
||||
}
|
||||
if (data.getValleyAmount() != null) {
|
||||
orderDetail.setValleyAmount(new BigDecimal(data.getValleyAmount()));
|
||||
}
|
||||
// 计算该时段电费
|
||||
BigDecimal multiply = orderDetail.getValleyElectricityPrice()
|
||||
.multiply(new BigDecimal(valleyUsedElectricity))
|
||||
.setScale(2, RoundingMode.DOWN);
|
||||
totalElectricityAmount = totalElectricityAmount.add(multiply);
|
||||
}
|
||||
|
||||
// 如果算出来的电费金额大于总消费金额,则电费金额等于总消费金额
|
||||
if (totalElectricityAmount.compareTo(orderAmount) > 0) {
|
||||
totalElectricityAmount = orderAmount;
|
||||
}
|
||||
orderDetail.setTotalElectricityAmount(totalElectricityAmount);
|
||||
orderDetail.setTotalServiceAmount(orderAmount.subtract(totalElectricityAmount));
|
||||
orderDetail.setTotalUsedElectricity(new BigDecimal(data.getTotalElectricity())); // 总用电量
|
||||
orderDetail.setTotalOrderAmount(orderAmount); // 订单总金额
|
||||
} catch (Exception e) {
|
||||
logger.error("设置订单详情参数发生异常", e);
|
||||
}
|
||||
return orderDetail;
|
||||
}
|
||||
|
||||
/**
|
||||
* 余额支付 计算需要退回的金额
|
||||
* 【公共方法】
|
||||
* @param principalPay 本金支付金额
|
||||
* @param giftPay 赠送金额支付的金额
|
||||
* @param orderAmount 订单消费金额
|
||||
* @return
|
||||
*/
|
||||
protected Map<String, BigDecimal> calculateReturnAmount(BigDecimal principalPay, BigDecimal giftPay, BigDecimal orderAmount) {
|
||||
Map<String, BigDecimal> resultMap = Maps.newHashMap();
|
||||
|
||||
// 消费金额优先使用本金
|
||||
BigDecimal returnPrincipal = null; // 退回本金金额
|
||||
BigDecimal returnGift = null; // 退回赠送金额
|
||||
|
||||
// 余额支付 有3种情况
|
||||
if (principalPay != null && giftPay == null) {
|
||||
// 只有本金支付
|
||||
BigDecimal subtract = principalPay.subtract(orderAmount);
|
||||
if (subtract.compareTo(BigDecimal.ZERO) > 0) {
|
||||
returnPrincipal = subtract;
|
||||
}
|
||||
}
|
||||
if (principalPay == null && giftPay != null) {
|
||||
// 只有赠送金额支付
|
||||
BigDecimal subtract = giftPay.subtract(orderAmount);
|
||||
if (subtract.compareTo(BigDecimal.ZERO) > 0) {
|
||||
returnGift = subtract;
|
||||
}
|
||||
}
|
||||
if (principalPay != null && giftPay != null) {
|
||||
// 本金+赠送支付
|
||||
BigDecimal subtract = principalPay.subtract(orderAmount);
|
||||
if (subtract.compareTo(BigDecimal.ZERO) > 0) {
|
||||
// 本金减掉订单金额后还有剩余,那就把剩余的退回,赠送原封不动退回
|
||||
returnPrincipal = subtract;
|
||||
returnGift = giftPay;
|
||||
} else if (subtract.compareTo(BigDecimal.ZERO) == 0) {
|
||||
// 本金刚好够,那赠送金额支付的原封不动退回
|
||||
returnGift = giftPay;
|
||||
} else {
|
||||
returnGift = giftPay.subtract(subtract.negate());
|
||||
}
|
||||
}
|
||||
|
||||
resultMap.put("returnPrincipal", returnPrincipal);
|
||||
resultMap.put("returnGift", returnGift);
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算解冻金额
|
||||
* @param orderAmount 订单消费金额
|
||||
* @param payRecordList 订单支付记录
|
||||
*/
|
||||
protected List<Map<String, Object>> calculateUnfreezeAmount(BigDecimal orderAmount, List<OrderPayRecord> payRecordList) {
|
||||
List<Map<String, Object>> resultList = Lists.newArrayList();
|
||||
|
||||
BigDecimal tempAmount = new BigDecimal(orderAmount.toString()); // 临时金额
|
||||
for (OrderPayRecord record : payRecordList) {
|
||||
JSONObject jsonObject = JSON.parseObject(record.getDeductionRecord());
|
||||
String paymentId = jsonObject.getString("paymentId");
|
||||
BigDecimal payAmount = record.getPayAmount(); // 此交易单支付的金额
|
||||
// 该笔支付扣除金额
|
||||
BigDecimal deductionAmount;
|
||||
// 该笔支付解冻金额
|
||||
BigDecimal unfreezeAmount = null;
|
||||
// 临时消费金额 = 临时消费金额 - 该笔交易的剩余金额
|
||||
tempAmount = tempAmount.subtract(payAmount);
|
||||
if (tempAmount.compareTo(BigDecimal.ZERO) >= 0) {
|
||||
// 计算以后,大于等于0,说明这笔支付剩余金额需要扣完,还要继续扣下一笔
|
||||
deductionAmount = payAmount;
|
||||
unfreezeAmount = payAmount.subtract(deductionAmount); // 支付金额 - 扣除金额 = 需要退回的金额
|
||||
Map<String, Object> map = Maps.newHashMap();
|
||||
map.put("paymentId", paymentId);
|
||||
map.put("unfreezeAmount", unfreezeAmount);
|
||||
resultList.add(map);
|
||||
} else {
|
||||
// 如果小于0,则说明该笔交易的剩余金额用不完,扣除金额等于临时消费金额,并结束循环
|
||||
deductionAmount = payAmount.add(tempAmount); // 该笔交易的剩余金额加上一个负数临时消费金额,就是该笔交易扣除金额
|
||||
unfreezeAmount = payAmount.subtract(deductionAmount); // 支付金额 - 扣除金额 = 需要退回的金额
|
||||
Map<String, Object> map = Maps.newHashMap();
|
||||
map.put("paymentId", paymentId);
|
||||
map.put("unfreezeAmount", unfreezeAmount);
|
||||
resultList.add(map);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从redis中取出实时记录保存到表中j
|
||||
* 当订单完成的时候调用
|
||||
* 【公共方法】
|
||||
*/
|
||||
protected void realTimeMonitorDataRedis2DB(String transactionCode, String orderCode) {
|
||||
try {
|
||||
if (StringUtils.isBlank(transactionCode) || StringUtils.isBlank(orderCode)) {
|
||||
return;
|
||||
}
|
||||
// 校验有没有保存过
|
||||
OrderMonitorData orderMonitorData = orderMonitorDataService.selectByOrderCode(orderCode);
|
||||
if (orderMonitorData != null) {
|
||||
return;
|
||||
}
|
||||
List<RealTimeMonitorData> chargingRealTimeData = orderBasicInfoService.getChargingRealTimeData(transactionCode);
|
||||
if (CollectionUtils.isEmpty(chargingRealTimeData)) {
|
||||
return;
|
||||
}
|
||||
List<RealTimeMonitorData> list = Lists.newArrayList();
|
||||
for (RealTimeMonitorData data : chargingRealTimeData) {
|
||||
RealTimeMonitorData build = RealTimeMonitorData.builder()
|
||||
.outputCurrent(data.getOutputCurrent())
|
||||
.outputCurrent(data.getOutputCurrent()) // 电流
|
||||
.outputVoltage(data.getOutputVoltage()) // 电压
|
||||
.outputPower(data.getOutputPower()) // 功率
|
||||
.SOC(data.getSOC()) // soc
|
||||
.dateTime(data.getDateTime()) // 时间
|
||||
.batteryMaxTemperature(data.getBatteryMaxTemperature())
|
||||
.chargingAmount(data.getChargingAmount())
|
||||
.chargingDegree(data.getChargingDegree())
|
||||
.sumChargingTime(data.getSumChargingTime())
|
||||
.timeRemaining(data.getTimeRemaining())
|
||||
.gunLineTemperature(data.getGunLineTemperature())
|
||||
.build();
|
||||
list.add(build);
|
||||
}
|
||||
|
||||
OrderMonitorData record = new OrderMonitorData();
|
||||
record.setOrderCode(orderCode);
|
||||
record.setTransactionCode(transactionCode);
|
||||
record.setMonitorData(JSONObject.toJSONString(list));
|
||||
int insert = orderMonitorDataService.insertSelective(record);
|
||||
if (insert > 0) {
|
||||
// 删除redis中缓存
|
||||
String pileConnectorCode = transactionCode.substring(0, 16);
|
||||
String redisKey = CacheConstants.PILE_REAL_TIME_MONITOR_DATA + pileConnectorCode + "_" + transactionCode;
|
||||
redisCache.deleteObject(redisKey);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.info("redis中取出实时记录保存到表发生异常", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,31 +3,34 @@ package com.jsowell.pile.service.orderlogic;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.jsowell.adapay.service.AdapayService;
|
||||
import com.jsowell.adapay.operation.PaymentReverseOperation;
|
||||
import com.jsowell.adapay.response.PaymentReverseResponse;
|
||||
import com.jsowell.adapay.vo.OrderSettleResult;
|
||||
import com.jsowell.common.constant.Constants;
|
||||
import com.jsowell.common.core.domain.ykc.TransactionRecordsData;
|
||||
import com.jsowell.common.enums.AcquirerEnum;
|
||||
import com.jsowell.common.enums.MemberWalletEnum;
|
||||
import com.jsowell.common.enums.ykc.*;
|
||||
import com.jsowell.common.exception.BusinessException;
|
||||
import com.jsowell.pile.domain.MemberTransactionRecord;
|
||||
import com.jsowell.pile.domain.OrderBasicInfo;
|
||||
import com.jsowell.pile.domain.OrderPayRecord;
|
||||
import com.jsowell.common.util.StringUtils;
|
||||
import com.jsowell.pile.domain.*;
|
||||
import com.jsowell.pile.dto.ApplyRefundDTO;
|
||||
import com.jsowell.pile.dto.PayOrderDTO;
|
||||
import com.jsowell.pile.dto.PayOrderSuccessCallbackDTO;
|
||||
import com.jsowell.pile.service.IMemberBasicInfoService;
|
||||
import com.jsowell.pile.service.IMemberTransactionRecordService;
|
||||
import com.jsowell.pile.service.MemberAdapayRecordService;
|
||||
import com.jsowell.pile.service.OrderPayRecordService;
|
||||
import com.jsowell.pile.transaction.dto.OrderTransactionDTO;
|
||||
import com.jsowell.pile.vo.uniapp.MemberVO;
|
||||
import com.jsowell.pile.vo.web.BalanceDeductionAmountVO;
|
||||
import com.jsowell.pile.vo.web.UpdateMemberBalanceDTO;
|
||||
import com.jsowell.wxpay.dto.WechatSendMsgDTO;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
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.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 设置延时分账的运营商订单逻辑
|
||||
@@ -35,21 +38,6 @@ import java.util.Map;
|
||||
@Service
|
||||
public class DelayMerchantOrderLogic extends AbstractOrderLogic {
|
||||
|
||||
@Autowired
|
||||
private IMemberBasicInfoService memberBasicInfoService;
|
||||
|
||||
@Autowired
|
||||
private MemberAdapayRecordService memberAdapayRecordService;
|
||||
|
||||
@Autowired
|
||||
private OrderPayRecordService orderPayRecordService;
|
||||
|
||||
@Autowired
|
||||
private IMemberTransactionRecordService memberTransactionRecordService;
|
||||
|
||||
@Autowired
|
||||
private AdapayService adapayService;
|
||||
|
||||
/**
|
||||
* 余额支付订单
|
||||
*/
|
||||
@@ -150,7 +138,19 @@ public class DelayMerchantOrderLogic extends AbstractOrderLogic {
|
||||
*/
|
||||
@Override
|
||||
public void whitelistPaymentOrder(PayOrderDTO dto) {
|
||||
String orderCode = dto.getOrderCode();
|
||||
BigDecimal payAmount = dto.getPayAmount();
|
||||
String payMode = dto.getPayMode();
|
||||
|
||||
// 白名单直接算支付成功
|
||||
PayOrderSuccessCallbackDTO callbackDTO = PayOrderSuccessCallbackDTO.builder()
|
||||
.orderCode(orderCode)
|
||||
.payAmount(payAmount)
|
||||
.payMode(payMode)
|
||||
.startMode(dto.getStartMode())
|
||||
.acquirer(AcquirerEnum.LOCAL.getValue())
|
||||
.build();
|
||||
payOrderSuccessCallback(callbackDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,15 +158,179 @@ public class DelayMerchantOrderLogic extends AbstractOrderLogic {
|
||||
*/
|
||||
@Override
|
||||
public void orderSettle(TransactionRecordsData data, OrderBasicInfo orderBasicInfo) {
|
||||
logger.info("结算订单start data:{}, orderBasicInfo:{}", data.toString(), orderBasicInfo.toString());
|
||||
// 判断订单状态
|
||||
if (StringUtils.equals(orderBasicInfo.getOrderStatus(), OrderStatusEnum.ORDER_COMPLETE.getValue())) {
|
||||
logger.info("结算订单:{}, 是订单完成状态", orderBasicInfo.getOrderCode());
|
||||
return;
|
||||
}
|
||||
// 获取更新数据后的orderBasicInfo对象
|
||||
returnUpdateOrderBasicInfo(orderBasicInfo, data);
|
||||
// 获取更新数据后的orderDetail对象/更新订单详情 查询订单详情 修改订单数据
|
||||
OrderDetail orderDetail = returnUpdateOrderDetail(orderBasicInfo, data);
|
||||
// 更新数据库
|
||||
OrderTransactionDTO dto = new OrderTransactionDTO();
|
||||
dto.setOrderBasicInfo(orderBasicInfo);
|
||||
dto.setOrderDetail(orderDetail);
|
||||
transactionService.doUpdateOrder(dto);
|
||||
|
||||
// 订单支付结算and退款, delay商户部分解冻并退款, 非delay商户全部解冻并退款
|
||||
orderPaymentSettlementAndRefund(orderBasicInfo);
|
||||
|
||||
// 将卡/vin状态解锁
|
||||
if (!StringUtils.equals("0000000000000000", data.getLogicCard())) {
|
||||
cardStatusUnlocked(orderBasicInfo.getLogicCard());
|
||||
}
|
||||
|
||||
// 如果是vin启动,将启动锁定状态改为正常
|
||||
if (StringUtils.equals(data.getTransactionIdentifier(), "05")) {
|
||||
vinStatusUnlocked(data.getVinCode());
|
||||
}
|
||||
|
||||
// 发送停止充电订阅消息
|
||||
sendMsg(orderBasicInfo);
|
||||
|
||||
// 从redis中取出实时记录保存到表中
|
||||
realTimeMonitorDataRedis2DB(orderBasicInfo.getTransactionCode(), orderBasicInfo.getOrderCode());
|
||||
|
||||
// TODO 如果该站点的停车场优惠券信息配置不为空,则需绑定一张优惠券
|
||||
|
||||
logger.info("结算订单end:{} OrderTransactionDTO:{}", orderBasicInfo.getOrderCode(), JSONObject.toJSONString(dto));
|
||||
}
|
||||
|
||||
/**
|
||||
* 卡状态解锁
|
||||
*/
|
||||
private void cardStatusUnlocked(String logicCard) {
|
||||
try {
|
||||
// 根据物理卡号查出当前为锁定状态的卡
|
||||
PileAuthCard cardInfo = pileAuthCardService.selectSomeStatusCardInfo(CardStatusEnum.START_LOCK.getCode(), logicCard);
|
||||
if (cardInfo != null) {
|
||||
// 将此卡状态改为正常
|
||||
cardInfo.setStatus(CardStatusEnum.NORMAL.getCode());
|
||||
pileAuthCardService.updatePileAuthCard(cardInfo);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("解锁卡状态 error,", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解锁vin状态
|
||||
*
|
||||
* @param vinCode
|
||||
*/
|
||||
private void vinStatusUnlocked(String vinCode) {
|
||||
try {
|
||||
MemberPlateNumberRelation plateInfo = memberPlateNumberRelationService.getMemberPlateInfoByVinCode(vinCode);
|
||||
if (plateInfo != null && (StringUtils.equals(plateInfo.getVinStatus(), "2"))) {
|
||||
plateInfo.setVinStatus("1");
|
||||
memberPlateNumberRelationService.updateMemberPlateNumberRelation(plateInfo);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("解锁vin状态 error,", e);
|
||||
}
|
||||
}
|
||||
|
||||
// uniApp 发送停止充电订阅消息
|
||||
private void sendMsg(OrderBasicInfo orderBasicInfo) {
|
||||
try {
|
||||
WechatSendMsgDTO wechatSendMsgDTO = new WechatSendMsgDTO();
|
||||
wechatSendMsgDTO.setOrderCode(orderBasicInfo.getOrderCode());
|
||||
Map<String, String> resultMap = wxAppletRemoteService.stopChargingSendMsg(wechatSendMsgDTO);
|
||||
logger.info("小程序发送充电停止推送消息 result:{}", JSON.toJSONString(resultMap));
|
||||
} catch (Exception e) {
|
||||
logger.error("小程序发送充电停止推送消息 error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单分账逻辑
|
||||
* 订单结算完成,就执行清分and退款
|
||||
*/
|
||||
private OrderSettleResult orderPaymentSettlementAndRefund(OrderBasicInfo orderBasicInfo) {
|
||||
String merchantId = orderBasicInfo.getMerchantId();
|
||||
String orderCode = orderBasicInfo.getOrderCode();
|
||||
// 获取一级运营商信息
|
||||
PileMerchantInfo merchantInfo = pileMerchantInfoService.getFirstLevelMerchantByMerchantId(merchantId);
|
||||
if (merchantInfo == null) {
|
||||
logger.info("订单分账逻辑-订单:{}, 查不到一级运营商信息", orderCode);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取结算账户信息
|
||||
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId);
|
||||
if (adapayMemberAccount == null) {
|
||||
logger.info("订单分账逻辑-订单:{}, 运营商id:{}, 没有配置结算账户信息", orderCode, merchantId);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
String payMode = orderBasicInfo.getPayMode();
|
||||
if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_BALANCE.getValue())) {
|
||||
// 余额支付
|
||||
balancePaymentOrderRefund(orderBasicInfo);
|
||||
} else if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())) {
|
||||
// 微信支付
|
||||
onlinePaymentOrderRefund(orderBasicInfo);
|
||||
} else {
|
||||
// 白名单支付
|
||||
logger.info("订单:{}使用白名单支付,不进行退款处理", orderBasicInfo.getOrderCode());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("订单退款逻辑异常orderCode:{}", orderBasicInfo.getOrderCode(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 余额支付订单退款
|
||||
*/
|
||||
@Override
|
||||
public void balancePayOrderRefund(OrderBasicInfo orderBasicInfo) {
|
||||
public void balancePaymentOrderRefund(OrderBasicInfo orderBasicInfo) {
|
||||
// 订单编号
|
||||
String orderCode = orderBasicInfo.getOrderCode();
|
||||
// 订单消费金额
|
||||
BigDecimal orderAmount = orderBasicInfo.getOrderAmount();
|
||||
// 查支付记录
|
||||
List<OrderPayRecord> payRecordList = orderPayRecordService.getOrderPayRecordList(orderCode);
|
||||
|
||||
Map<String, OrderPayRecord> payRecordMap = payRecordList.stream()
|
||||
.collect(Collectors.toMap(OrderPayRecord::getPayMode, Function.identity(), (k1, k2) -> k1));
|
||||
// 取出本金支付金额
|
||||
BigDecimal principalPay = null;
|
||||
|
||||
// 获取本金支付的记录
|
||||
OrderPayRecord principalPayRecord = payRecordMap.get(Constants.ONE);
|
||||
if (principalPayRecord != null) {
|
||||
principalPay = principalPayRecord.getPayAmount();
|
||||
}
|
||||
|
||||
// 计算需要退回的金额
|
||||
Map<String, BigDecimal> returnAmountMap = calculateReturnAmount(principalPay, null, orderAmount);
|
||||
logger.info("结算订单:{}, 剩余金额退回余额, 订单消费金额:{}, 本金支付金额:{}, 赠送支付金额:{}, 退回金额map:{}",
|
||||
orderCode, orderAmount, principalPay, null, JSONObject.toJSONString(returnAmountMap));
|
||||
|
||||
// 需要退回本金的金额
|
||||
BigDecimal returnPrincipal = returnAmountMap.get("returnPrincipal");
|
||||
|
||||
// 更新会员钱包/余额退回到钱包
|
||||
UpdateMemberBalanceDTO updateMemberBalanceDTO = UpdateMemberBalanceDTO.builder()
|
||||
.memberId(orderBasicInfo.getMemberId())
|
||||
.type(MemberWalletEnum.TYPE_IN.getValue()) // 进账
|
||||
.subType(MemberWalletEnum.SUBTYPE_ORDER_SETTLEMENT_REFUND.getValue()) // 订单结算退款
|
||||
.updatePrincipalBalance(returnPrincipal)
|
||||
.relatedOrderCode(orderCode)
|
||||
.build();
|
||||
memberBasicInfoService.updateMemberBalance(updateMemberBalanceDTO);
|
||||
|
||||
// 更新order_pay_record, 解冻部分
|
||||
List<Map<String, Object>> list = calculateUnfreezeAmount(orderAmount, payRecordList);
|
||||
for (Map<String, Object> map : list) {
|
||||
String paymentId = (String) map.get("paymentId");
|
||||
String unfreezeAmount = (String) map.get("unfreezeAmount");
|
||||
memberAdapayRecordService.unfreezeAmount(paymentId, new BigDecimal(unfreezeAmount));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,6 +338,91 @@ public class DelayMerchantOrderLogic extends AbstractOrderLogic {
|
||||
*/
|
||||
@Override
|
||||
public void onlinePaymentOrderRefund(OrderBasicInfo orderBasicInfo) {
|
||||
// 订单编号
|
||||
String orderCode = orderBasicInfo.getOrderCode();
|
||||
|
||||
// 需要退款的金额
|
||||
BigDecimal refundAmount = orderBasicInfo.getRefundAmount();
|
||||
|
||||
// 微信退款逻辑
|
||||
ApplyRefundDTO applyRefundDTO = new ApplyRefundDTO();
|
||||
applyRefundDTO.setOrderCode(orderCode);
|
||||
applyRefundDTO.setRefundType(Constants.ONE);
|
||||
applyRefundDTO.setRefundAmount(refundAmount);
|
||||
|
||||
// 汇付退款需要一级运营商的小程序appId, 否则会退款失败
|
||||
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(orderBasicInfo.getMerchantId());
|
||||
if (StringUtils.isNotBlank(wechatAppId)) {
|
||||
applyRefundDTO.setWechatAppId(wechatAppId);
|
||||
}
|
||||
this.refundOrderWithAdapay(applyRefundDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 汇付支付-订单退款处理逻辑
|
||||
* 汇付支付订单退款
|
||||
*
|
||||
* @param dto
|
||||
*/
|
||||
public void refundOrderWithAdapay(ApplyRefundDTO dto) {
|
||||
logger.info("汇付支付订单:{}, 执行退款逻辑 param:{}", dto.getOrderCode(), JSON.toJSONString(dto));
|
||||
// 查出来原来的支付信息
|
||||
AdapayCallbackRecord callbackRecord = adapayCallbackRecordService.selectByOrderCode(dto.getOrderCode());
|
||||
if (Objects.isNull(callbackRecord)) {
|
||||
logger.error("汇付支付orderCode:{}, 订单退款处理逻辑, 查询订单微信支付记录为空!", dto.getOrderCode());
|
||||
throw new BusinessException(ReturnCodeEnum.CODE_REFUND_ORDER_CALLBACK_RECORD_ERROR);
|
||||
}
|
||||
|
||||
String paymentId = callbackRecord.getPaymentId();
|
||||
// 判断支付金额和退款金额
|
||||
BigDecimal refundAmount = dto.getRefundAmount();
|
||||
BigDecimal payAmt = callbackRecord.getPayAmt();
|
||||
if (refundAmount.compareTo(payAmt) > 0) {
|
||||
logger.error("汇付支付订单号:{}, 退款金额:{}(元),大于付款金额{}(元), 抛出异常", dto.getOrderCode(), refundAmount, payAmt);
|
||||
throw new BusinessException(ReturnCodeEnum.CODE_REFUND_ORDER_AMOUNT_ERROR);
|
||||
}
|
||||
|
||||
BigDecimal refundAmt = null; // 交易退款金额
|
||||
// 延迟分账未确认调撤销调撤销接口退款
|
||||
PaymentReverseOperation operation = new PaymentReverseOperation();
|
||||
operation.setPaymentId(paymentId);
|
||||
operation.setReverseAmt(refundAmount);
|
||||
operation.setMerchantKey(dto.getWechatAppId());
|
||||
operation.setMemberId(dto.getMemberId());
|
||||
operation.setScenarioType(ScenarioEnum.ORDER.getValue());
|
||||
operation.setOrderCode(dto.getOrderCode());
|
||||
PaymentReverseResponse response = adapayService.createPaymentReverseRequest(operation);
|
||||
if (response != null && response.isNotFailed()) {
|
||||
refundAmt = new BigDecimal(response.getReverse_amt());
|
||||
memberAdapayRecordService.updateRefundAmountFromFreezeAmount(paymentId, refundAmt);
|
||||
}
|
||||
|
||||
// 获取延时分账模式 延时分账的使用撤销方法退款,实时分账的使用退款方法
|
||||
// String expend = callbackRecord.getExpend();
|
||||
// JSONObject expendJsonObject = JSON.parseObject(expend);
|
||||
// String payMode = expendJsonObject.getString("payMode");
|
||||
// if (StringUtils.equalsIgnoreCase(payMode, Constants.ADAPAY_PAY_MODE_DELAY)) {
|
||||
// // 延迟分账未确认调撤销调撤销接口退款
|
||||
// PaymentReverseOperation operation = new PaymentReverseOperation();
|
||||
// operation.setPaymentId(paymentId);
|
||||
// operation.setReverseAmt(refundAmount);
|
||||
// operation.setMerchantKey(dto.getWechatAppId());
|
||||
// operation.setMemberId(dto.getMemberId());
|
||||
// operation.setScenarioType(ScenarioEnum.ORDER.getValue());
|
||||
// operation.setOrderCode(dto.getOrderCode());
|
||||
// PaymentReverseResponse response = adapayService.createPaymentReverseRequest(operation);
|
||||
// if (response != null && response.isNotFailed()) {
|
||||
// refundAmt = new BigDecimal(response.getReverse_amt());
|
||||
// memberAdapayRecordService.updateRefundAmountFromFreezeAmount(paymentId, refundAmt);
|
||||
// }
|
||||
// } else {
|
||||
// // // 实时分账的调退款接口
|
||||
// RefundResponse refundRequest = adapayService.createRefundRequest(paymentId, refundAmount,
|
||||
// dto.getWechatAppId(), dto.getMemberId(), ScenarioEnum.ORDER.getValue(), dto.getOrderCode());
|
||||
// if (refundRequest != null && refundRequest.isNotFailed()) {
|
||||
// refundAmt = new BigDecimal(refundRequest.getRefund_amt());
|
||||
// memberAdapayRecordService.unfreezeAmountAndUpdateSpendAmount(paymentId, payAmt, refundAmt);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user