mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-08-13 01:33:42 +08:00
update 后管取消订单支持退款与结算逻辑
This commit is contained in:
@@ -375,6 +375,193 @@ public class OrderService {
|
||||
log.info("主动停止充电, orderCode:{}, transactionCode:{}, 发送停机指令成功", dto.getOrderCode(), orderInfo.getTransactionCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* 后管取消订单
|
||||
* 除最终状态(订单完成/订单关闭)外,其他状态均可取消:
|
||||
* - 待支付:直接关闭订单
|
||||
* - 已支付未启动充电:关闭订单并退款
|
||||
* - 充电中:发送停机指令,由充电桩返回交易记录后自动结算(结算含退款)
|
||||
* - 待结算/待补缴/异常/可疑:按最近一次充电数据直接结算(结算含退款)
|
||||
*
|
||||
* @param orderCode 订单编号
|
||||
*/
|
||||
public void cancelOrderForWeb(String orderCode) {
|
||||
OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode);
|
||||
if (orderBasicInfo == null) {
|
||||
throw new BusinessException(ReturnCodeEnum.CODE_QUERY_ORDER_INFO_IS_NULL);
|
||||
}
|
||||
String orderStatus = orderBasicInfo.getOrderStatus();
|
||||
String payStatus = orderBasicInfo.getPayStatus();
|
||||
|
||||
// 最终状态不可取消
|
||||
if (StringUtils.equals(orderStatus, OrderStatusEnum.ORDER_COMPLETE.getValue())
|
||||
|| StringUtils.equals(orderStatus, OrderStatusEnum.ORDER_CLOSE_TIMEOUT.getValue())) {
|
||||
throw new BusinessException(ReturnCodeEnum.CODE_ORDER_INFO_ERROR);
|
||||
}
|
||||
|
||||
// 1. 待支付:直接关闭订单
|
||||
if (StringUtils.equals(payStatus, OrderPayStatusEnum.unpaid.getValue())) {
|
||||
closeOrderForCancel(orderBasicInfo);
|
||||
log.info("取消订单-待支付订单直接关闭, orderCode:{}", orderCode);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 已支付未启动充电:关闭订单并退款
|
||||
if (StringUtils.equals(orderStatus, OrderStatusEnum.NOT_START.getValue())) {
|
||||
closeOrderForCancel(orderBasicInfo);
|
||||
refundOrderForCancel(orderBasicInfo);
|
||||
log.info("取消订单-已支付未启动订单关闭并退款, orderCode:{}", orderCode);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 充电中:发送停机指令,结算由桩返回交易记录后自动完成
|
||||
if (StringUtils.equals(orderStatus, OrderStatusEnum.IN_THE_CHARGING.getValue())) {
|
||||
sendStopChargingCommand(orderBasicInfo);
|
||||
log.info("取消订单-充电中订单发送停机指令, orderCode:{}", orderCode);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 待结算/待补缴/异常/可疑:直接触发结算(含退款)
|
||||
settleOrderForCancel(orderBasicInfo);
|
||||
log.info("取消订单-未结算订单执行结算, orderCode:{}", orderCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭订单(状态改为 7-订单关闭)
|
||||
*/
|
||||
private void closeOrderForCancel(OrderBasicInfo orderBasicInfo) {
|
||||
orderBasicInfo.setOrderStatus(OrderStatusEnum.ORDER_CLOSE_TIMEOUT.getValue());
|
||||
orderBasicInfoService.updateOrderBasicInfo(orderBasicInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 已支付未启动订单退款:按实际支付金额全额退款
|
||||
*/
|
||||
private void refundOrderForCancel(OrderBasicInfo orderBasicInfo) {
|
||||
String orderCode = orderBasicInfo.getOrderCode();
|
||||
String payMode = orderBasicInfo.getPayMode();
|
||||
|
||||
// 白名单支付无需退款
|
||||
if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue())) {
|
||||
log.info("取消订单退款-白名单支付不退款, orderCode:{}", orderCode);
|
||||
return;
|
||||
}
|
||||
|
||||
// 已存在退款记录,说明已经退过,跳过
|
||||
List<OrderDetailInfoVO.OrderRefundInfo> refundInfoList = orderBasicInfoService.getOrderRefundInfoList(orderBasicInfo);
|
||||
if (CollectionUtils.isNotEmpty(refundInfoList)) {
|
||||
log.info("取消订单退款-订单已存在退款记录, 跳过退款, orderCode:{}", orderCode);
|
||||
return;
|
||||
}
|
||||
|
||||
// 退款金额取实际支付金额
|
||||
BigDecimal refundAmount = orderBasicInfo.getPayAmount() != null
|
||||
? orderBasicInfo.getPayAmount()
|
||||
: orderBasicInfo.getOrderAmount();
|
||||
if (refundAmount == null || refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
log.info("取消订单退款-退款金额小于等于0, 跳过退款, orderCode:{}", orderCode);
|
||||
return;
|
||||
}
|
||||
orderBasicInfo.setRefundAmount(refundAmount);
|
||||
orderBasicInfoService.updateOrderBasicInfo(orderBasicInfo);
|
||||
|
||||
// 余额支付:退到会员余额
|
||||
if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue())) {
|
||||
orderBasicInfoService.refundBalancePaymentOrder(orderBasicInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
// 在线支付:根据支付机构退款
|
||||
MemberTransactionRecord transactionRecord = memberTransactionRecordService.selectByOrderCode(orderCode, ActionTypeEnum.FORWARD.getValue());
|
||||
if (transactionRecord == null) {
|
||||
log.warn("取消订单退款-未查到正向支付流水, 无法自动退款, orderCode:{}", orderCode);
|
||||
return;
|
||||
}
|
||||
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(orderBasicInfo.getMerchantId());
|
||||
ApplyRefundDTO applyRefundDTO = new ApplyRefundDTO();
|
||||
applyRefundDTO.setOrderCode(orderCode);
|
||||
applyRefundDTO.setRefundType(Constants.ONE);
|
||||
applyRefundDTO.setRefundAmount(refundAmount);
|
||||
applyRefundDTO.setWechatAppId(wechatAppId);
|
||||
applyRefundDTO.setMemberId(orderBasicInfo.getMemberId());
|
||||
if (StringUtils.equals(transactionRecord.getPaymentInstitutions(), PaymentInstitutionsEnum.ADAPAY.getValue())) {
|
||||
// 汇付支付:撤销/退款
|
||||
orderBasicInfoService.refundOrderWithAdapay(applyRefundDTO);
|
||||
} else if (StringUtils.equals(transactionRecord.getPaymentInstitutions(), PaymentInstitutionsEnum.WECHAT_PAY.getValue())) {
|
||||
// 微信支付:退款
|
||||
orderBasicInfoService.refundOrderWithWechatPay(applyRefundDTO);
|
||||
} else {
|
||||
log.info("取消订单退款-支付机构:{}不支持自动退款, orderCode:{}", transactionRecord.getPaymentInstitutions(), orderCode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 充电中订单发送停机指令(含第三方桩统一停止充电)
|
||||
*/
|
||||
private void sendStopChargingCommand(OrderBasicInfo orderBasicInfo) {
|
||||
List<ThirdPartySnRelationVO> list = snRelationService.selectSnRelationListByParams(
|
||||
orderBasicInfo.getStationId(), orderBasicInfo.getPileSn(), null);
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
for (ThirdPartySnRelationVO vo : list) {
|
||||
ThirdPartyCommonStopChargeDTO commonStopChargeDTO = new ThirdPartyCommonStopChargeDTO();
|
||||
commonStopChargeDTO.setThirdPartyType(vo.getThirdPartyType());
|
||||
commonStopChargeDTO.setOrderBasicInfo(orderBasicInfo);
|
||||
String result = commonService.commonStopCharge(commonStopChargeDTO);
|
||||
log.info("取消订单-订单:{} 调用统一停止充电接口, result:{}", orderBasicInfo.getOrderCode(), result);
|
||||
}
|
||||
} else {
|
||||
pileRemoteService.remoteStopCharging(orderBasicInfo.getPileSn(),
|
||||
orderBasicInfo.getConnectorCode(), orderBasicInfo.getTransactionCode());
|
||||
}
|
||||
log.info("取消订单-订单:{} 发送停机指令成功", orderBasicInfo.getOrderCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* 待结算/待补缴/异常/可疑订单:按最近一次充电数据执行结算(结算含退款)
|
||||
*/
|
||||
private void settleOrderForCancel(OrderBasicInfo orderBasicInfo) {
|
||||
TransactionRecordsData data = null;
|
||||
// 优先取桩返回的交易记录
|
||||
List<PileMsgRecord> pileFeedList = pileMsgRecordService.queryPileFeedList(
|
||||
orderBasicInfo.getPileSn(), "0x3B", orderBasicInfo.getTransactionCode());
|
||||
for (PileMsgRecord pileMsgRecord : pileFeedList) {
|
||||
TransactionRecordsData parse = JSONObject.parseObject(pileMsgRecord.getJsonMsg(), TransactionRecordsData.class);
|
||||
if (StringUtils.equals(parse.getTransactionCode(), orderBasicInfo.getTransactionCode())) {
|
||||
data = parse;
|
||||
data.setVinCode("");
|
||||
}
|
||||
}
|
||||
|
||||
// 没有交易记录时,用最后一次实时数据兜底
|
||||
if (data == null) {
|
||||
data = new TransactionRecordsData();
|
||||
List<RealTimeMonitorData> chargingRealTimeData = orderBasicInfoService.getChargingRealTimeData(orderBasicInfo.getTransactionCode());
|
||||
if (CollectionUtils.isNotEmpty(chargingRealTimeData)) {
|
||||
RealTimeMonitorData realTimeMonitorData = chargingRealTimeData.get(0);
|
||||
data.setConsumptionAmount(realTimeMonitorData.getChargingAmount());
|
||||
data.setTotalElectricity(realTimeMonitorData.getChargingDegree());
|
||||
} else {
|
||||
data.setConsumptionAmount(Constants.ZERO);
|
||||
data.setTotalElectricity(Constants.ZERO);
|
||||
}
|
||||
data.setStopReasonMsg("后管取消订单,操作人:" + SecurityUtils.getUsername());
|
||||
}
|
||||
|
||||
String mode = pileMerchantInfoService.getDelayModeByMerchantId(orderBasicInfo.getMerchantId());
|
||||
AbstractProgramLogic orderLogic = ProgramLogicFactory.getProgramLogic(mode);
|
||||
if (YouDianUtils.isEBikePileSn(orderBasicInfo.getPileSn())) {
|
||||
// 电单车桩
|
||||
BigDecimal chargingDegree = StringUtils.isNotBlank(data.getTotalElectricity())
|
||||
? new BigDecimal(data.getTotalElectricity()) : BigDecimal.ZERO;
|
||||
EBikeMessageCmd03 message = new EBikeMessageCmd03(chargingDegree, EBikeStopReasonEnum.EXTERNAL_OPERATION_STOPPED.getCode());
|
||||
orderLogic.settleOrderForEBike(message, orderBasicInfo);
|
||||
} else {
|
||||
// 汽车桩
|
||||
orderLogic.settleOrder(data, orderBasicInfo);
|
||||
}
|
||||
log.info("取消订单-订单:{} 结算完成", orderBasicInfo.getOrderCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信退款
|
||||
*
|
||||
|
||||
@@ -179,15 +179,16 @@ public class OrderBasicInfoController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消订单/关闭待支付订单
|
||||
* 仅待支付状态的订单可取消,取消后订单状态变为 7-订单关闭
|
||||
* 取消订单
|
||||
* 除订单完成/订单关闭外均可取消:
|
||||
* 待支付直接关闭;已支付未启动关闭并退款;充电中发送停机指令并结算;未结算状态直接结算
|
||||
* http://localhost:8080/order/closeOrderByOrderCode/{orderCode}
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('order:order:edit')")
|
||||
@Log(title = "订单", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/closeOrderByOrderCode/{orderCode}")
|
||||
public AjaxResult closeOrderByOrderCode(@PathVariable("orderCode") String orderCode) {
|
||||
orderBasicInfoService.closeOrderByOrderCode(orderCode);
|
||||
orderService.cancelOrderForWeb(orderCode);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user