| | |
| | | private static final int WHITELIST_BENEFIT_ELECTRIC_FREE = 2; |
| | | private static final int WHITELIST_BENEFIT_SERVICE_FREE = 3; |
| | | private static final String SHARE_AFTER_COMMIT_RESOURCE_PREFIX = "chargingOrderShareAfterCommit:"; |
| | | private static final String SPECIAL_REFUND_TITLE = "特殊退款处理"; |
| | | |
| | | @Resource |
| | | private ChargingGunClient chargingGunClient; |
| | |
| | | } |
| | | LocalTime start = LocalTime.parse(site.getReservationStartTime(), DateTimeFormatter.ofPattern("HH:mm")); |
| | | LocalTime end = LocalTime.parse(site.getReservationEndTime(), DateTimeFormatter.ofPattern("HH:mm")); |
| | | if (!isTimeInWindow(LocalTime.now(), start, end) |
| | | || !isTimeInWindow(reservationTime.toLocalTime(), start, end)) { |
| | | return AjaxResult.error("当前时间或预约时间不在允许预约时段内"); |
| | | if (!isTimeInWindow(reservationTime.toLocalTime(), start, end)) { |
| | | return AjaxResult.error("预约时间不在允许预约时段内"); |
| | | } |
| | | return null; |
| | | } |
| | |
| | | |
| | | |
| | | @Override |
| | | public R<PayOrderInfoDto> getSpecialRefundOrder(PayOrderRefundDto payOrderQueryDto) { |
| | | TChargingOrder order = getSpecialRefundChargingOrder(payOrderQueryDto); |
| | | if (order == null) { |
| | | return R.fail("未查询到支付成功的充电订单"); |
| | | } |
| | | PayOrderInfoDto dto = new PayOrderInfoDto(); |
| | | dto.setOrderId(order.getId().toString()); |
| | | dto.setCode(order.getCode()); |
| | | dto.setTradeNo(order.getRechargeSerialNumber()); |
| | | dto.setPayType(order.getRechargePaymentType()); |
| | | dto.setPayAmount(money(order.getPaymentAmount())); |
| | | dto.setPayTime(order.getPayTime()); |
| | | dto.setRefundAmount(money(order.getRefundAmount())); |
| | | dto.setRechargeAmount(money(order.getRechargeAmount())); |
| | | dto.setFinalAmount(money(order.getPaymentAmount()).subtract(money(order.getRefundAmount())).setScale(2, RoundingMode.HALF_UP)); |
| | | dto.setPayMethod(order.getPayMethod()); |
| | | dto.setBalancePayAmount(order.getBalancePayAmount()); |
| | | dto.setThirdPayAmount(order.getThirdPayAmount()); |
| | | dto.setBalanceRefundAmount(order.getBalanceRefundAmount()); |
| | | dto.setThirdRefundAmount(order.getThirdRefundAmount()); |
| | | return R.ok(dto); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional |
| | | public R specialRefund(PayOrderRefundDto payOrderQueryDto) { |
| | | R passwordValid = validateOperationPassword(payOrderQueryDto); |
| | | if (passwordValid.getCode() != 200) { |
| | | return passwordValid; |
| | | } |
| | | if (payOrderQueryDto.getRefundAmount() == null || payOrderQueryDto.getRefundAmount().compareTo(BigDecimal.ZERO) <= 0) { |
| | | return R.fail("请输入正确的退款金额"); |
| | | } |
| | | TChargingOrder order = getSpecialRefundChargingOrder(payOrderQueryDto); |
| | | if (order == null) { |
| | | return R.fail("未查询到支付成功的充电订单"); |
| | | } |
| | | BigDecimal refundAmount = money(payOrderQueryDto.getRefundAmount()); |
| | | BigDecimal refundableAmount = money(order.getPaymentAmount()).subtract(money(order.getRefundAmount())).setScale(2, RoundingMode.HALF_UP); |
| | | if (refundAmount.compareTo(refundableAmount) > 0) { |
| | | return R.fail("退款金额不能超过剩余可退金额"); |
| | | } |
| | | BigDecimal refundedThirdAmount = money(order.getThirdRefundAmount()); |
| | | BigDecimal refundableThirdAmount = money(order.getThirdPayAmount()).subtract(refundedThirdAmount); |
| | | if (refundableThirdAmount.compareTo(BigDecimal.ZERO) < 0) { |
| | | refundableThirdAmount = BigDecimal.ZERO; |
| | | } |
| | | BigDecimal thirdRefundAmount = isBalancePayMode(order.getPayMethod()) |
| | | ? refundAmount.min(refundableThirdAmount).setScale(2, RoundingMode.HALF_UP) |
| | | : refundAmount; |
| | | BigDecimal balanceRefundAmount = refundAmount.subtract(thirdRefundAmount).setScale(2, RoundingMode.HALF_UP); |
| | | if (balanceRefundAmount.compareTo(BigDecimal.ZERO) < 0) { |
| | | balanceRefundAmount = BigDecimal.ZERO; |
| | | } |
| | | TChargingOrderRefund refund = buildSpecialChargingRefund(order, payOrderQueryDto, refundAmount, balanceRefundAmount, thirdRefundAmount); |
| | | if (thirdRefundAmount.compareTo(BigDecimal.ZERO) == 0) { |
| | | refund.setRefundSerialNumber("BALANCE"); |
| | | finishManualChargingRefund(order, refund, refundAmount, balanceRefundAmount, thirdRefundAmount); |
| | | return R.ok(); |
| | | } |
| | | Integer payType = order.getRechargePaymentType(); |
| | | boolean success = false; |
| | | if (Integer.valueOf(1).equals(payType) || "ICBC".equalsIgnoreCase(payOrderQueryDto.getRefundChannel())) { |
| | | success = refundByIcbcAndFinish(order, refund, thirdRefundAmount, SPECIAL_REFUND_TITLE, true, refundAmount, balanceRefundAmount); |
| | | } else if (Integer.valueOf(2).equals(payType)) { |
| | | RefundReq dto = new RefundReq(); |
| | | dto.setOutTradeNo(order.getCode()); |
| | | dto.setOutRequestNo(refund.getRefundCode()); |
| | | dto.setRefundAmount(thirdRefundAmount.toString()); |
| | | dto.setRefundReason(SPECIAL_REFUND_TITLE); |
| | | RefundResp resp = aliPaymentClient.refund(dto).getData(); |
| | | if (resp != null) { |
| | | refund.setRefundSerialNumber(resp.getTradeNo()); |
| | | refund.setRefundTime(LocalDateTime.now()); |
| | | finishManualChargingRefund(order, refund, refundAmount, balanceRefundAmount, thirdRefundAmount); |
| | | success = true; |
| | | } |
| | | } else if (Integer.valueOf(3).equals(payType)) { |
| | | RefundReq dto = new RefundReq(); |
| | | dto.setOutTradeNo(order.getRechargeSerialNumber()); |
| | | dto.setOutRequestNo(refund.getRefundCode()); |
| | | dto.setRefundAmount(thirdRefundAmount.toString()); |
| | | dto.setRefundReason(SPECIAL_REFUND_TITLE); |
| | | RefundResp resp = h5AliPaymentClient.refund(dto).getData(); |
| | | if (resp != null && "10000".equals(resp.getCode())) { |
| | | refund.setRefundSerialNumber(resp.getTradeNo()); |
| | | refund.setRefundTime(LocalDateTime.now()); |
| | | finishManualChargingRefund(order, refund, refundAmount, balanceRefundAmount, thirdRefundAmount); |
| | | success = true; |
| | | } |
| | | } |
| | | return success ? R.ok() : R.fail("退款失败,请检查支付渠道或稍后重试"); |
| | | } |
| | | |
| | | private R validateOperationPassword(PayOrderRefundDto payOrderQueryDto) { |
| | | if (payOrderQueryDto == null || StringUtils.isEmpty(payOrderQueryDto.getOperationPassword())) { |
| | | return R.fail("请输入操作密码"); |
| | | } |
| | | SysUser sysUser = sysUserClient.getSysUser(tokenService.getLoginUser().getUserid()).getData(); |
| | | if (sysUser == null || StringUtils.isEmpty(sysUser.getOperationPassword())) { |
| | | return R.fail("当前账号未配置操作密码"); |
| | | } |
| | | if (!SecurityUtils.matchesPassword(payOrderQueryDto.getOperationPassword(), sysUser.getOperationPassword())) { |
| | | return R.fail("操作密码错误"); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | private TChargingOrder getSpecialRefundChargingOrder(PayOrderRefundDto payOrderQueryDto) { |
| | | if (payOrderQueryDto == null) { |
| | | return null; |
| | | } |
| | | LambdaQueryWrapper<TChargingOrder> wrapper = new LambdaQueryWrapper<TChargingOrder>() |
| | | .eq(TChargingOrder::getRechargePaymentStatus, 2) |
| | | .eq(TChargingOrder::getDelFlag, false); |
| | | if (payOrderQueryDto.getOrderId() != null) { |
| | | wrapper.eq(TChargingOrder::getId, payOrderQueryDto.getOrderId()); |
| | | } else if (StringUtils.hasLength(payOrderQueryDto.getCode())) { |
| | | wrapper.eq(TChargingOrder::getCode, payOrderQueryDto.getCode()); |
| | | } else if (StringUtils.hasLength(payOrderQueryDto.getSerialNumber())) { |
| | | wrapper.eq(TChargingOrder::getRechargeSerialNumber, payOrderQueryDto.getSerialNumber()); |
| | | } else { |
| | | return null; |
| | | } |
| | | return this.getOne(wrapper.last("limit 1")); |
| | | } |
| | | |
| | | private TChargingOrderRefund buildSpecialChargingRefund(TChargingOrder order, PayOrderRefundDto dto, BigDecimal refundAmount, |
| | | BigDecimal balanceRefundAmount, BigDecimal thirdRefundAmount) { |
| | | TChargingOrderRefund refund = new TChargingOrderRefund(); |
| | | refund.setChargingOrderId(order.getId()); |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); |
| | | refund.setRefundCode("TSF" + sdf.format(new Date()) + (Double.valueOf(Math.random() * 1000).intValue())); |
| | | refund.setRefundAmount(refundAmount); |
| | | refund.setBalanceRefundAmount(balanceRefundAmount); |
| | | refund.setThirdRefundAmount(thirdRefundAmount); |
| | | refund.setRefundStatus(1); |
| | | refund.setPayType(order.getRechargePaymentType()); |
| | | refund.setRefundTime(LocalDateTime.now()); |
| | | refund.setCode(order.getCode()); |
| | | refund.setRefundTitle(SPECIAL_REFUND_TITLE); |
| | | refund.setRefundContent(SPECIAL_REFUND_TITLE); |
| | | refund.setRefundReason(StringUtils.hasLength(dto.getReason()) ? dto.getReason() : SPECIAL_REFUND_TITLE); |
| | | refund.setRefundRemark(dto.getRemark()); |
| | | refund.setRefundTotalAmount(money(order.getRefundAmount()).add(refundAmount)); |
| | | refund.setPayAmount(money(order.getPaymentAmount())); |
| | | return refund; |
| | | } |
| | | |
| | | @Override |
| | | public R payRefund(PayOrderRefundDto payOrderQueryDto) { |
| | | R passwordValid = validateOperationPassword(payOrderQueryDto); |
| | | if (passwordValid.getCode() != 200) { |
| | | return passwordValid; |
| | | } |
| | | if (payOrderQueryDto.getType() == 1) { |
| | | TChargingOrder tChargingOrder = this.baseMapper.selectById(payOrderQueryDto.getOrderId()); |
| | | if (tChargingOrder.getPaymentAmount().compareTo(payOrderQueryDto.getRefundAmount()) == -1) { |