package com.ruoyi.order.util.task; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.util.UUIDUtils; import com.alibaba.nacos.common.utils.UuidUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.ruoyi.account.api.feignClient.AppCouponClient; import com.ruoyi.account.api.feignClient.AppUserClient; import com.ruoyi.account.api.feignClient.AppUserIntegralChangeClient; import com.ruoyi.account.api.feignClient.AppUserVipDetailClient; import com.ruoyi.account.api.model.TAppCoupon; import com.ruoyi.account.api.model.TAppUser; import com.ruoyi.account.api.model.TAppUserIntegralChange; import com.ruoyi.chargingPile.api.feignClient.ChargingGunClient; import com.ruoyi.chargingPile.api.feignClient.SiteClient; import com.ruoyi.chargingPile.api.model.Site; import com.ruoyi.chargingPile.api.model.TChargingGun; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.redis.service.RedisService; import com.ruoyi.integration.api.feignClient.ChargingMessageClient; import com.ruoyi.integration.api.feignClient.ChengDuJianGuanClient; import com.ruoyi.integration.api.feignClient.TCECClient; import com.ruoyi.integration.api.feignClient.UploadRealTimeMonitoringDataClient; import com.ruoyi.integration.api.model.TransactionRecord; import com.ruoyi.integration.api.model.UploadRealTimeMonitoringData; import com.ruoyi.integration.api.vo.ChargingOrderVo; import com.ruoyi.integration.api.vo.NotificationConnectorChargeStatusVo; import com.ruoyi.order.api.model.*; import com.ruoyi.order.api.vo.AccountingStrategyDetailOrderVo; import com.ruoyi.order.api.vo.TransactionRecordMessageVO; import com.ruoyi.order.service.*; import com.ruoyi.order.util.mongodb.service.TransactionRecordService; import com.ruoyi.order.util.mongodb.service.UploadRealTimeMonitoringDataService; import com.ruoyi.other.api.domain.TCoupon; import com.ruoyi.other.api.domain.TIntegralRule; import com.ruoyi.other.api.domain.TVip; import com.ruoyi.other.api.feignClient.IntegralRuleClient; import com.ruoyi.other.api.feignClient.VipClient; import com.ruoyi.payment.api.feignClient.AliPaymentClient; import com.ruoyi.payment.api.feignClient.H5AliPaymentClient; import com.ruoyi.payment.api.feignClient.WxPaymentClient; import com.ruoyi.payment.api.model.RefundReq; import com.ruoyi.payment.api.model.RefundResp; import com.ruoyi.payment.api.model.WxPaymentRefundModel; import lombok.extern.slf4j.Slf4j; import org.apache.logging.log4j.core.util.UuidUtil; import org.apache.poi.util.StringUtil; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.context.WebServerInitializedEvent; import org.springframework.context.ApplicationListener; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** * @author zhibing.pu * @date 2023/7/11 8:39 */ @Slf4j @Component public class TaskUtil implements ApplicationListener { @Resource private TChargingBillService chargingBillService; @Resource private SiteClient siteClient; @Resource private TChargingOrderService chargingOrderService; @Resource private TChargingOrderRefundService chargingOrderRefundService; @Resource private UploadRealTimeMonitoringDataService uploadRealTimeMonitoringDataService; @Resource private TransactionRecordService transactionRecordService; @Resource private ChargingMessageClient chargingMessageClient; private Integer port = null; @Resource private AccountingStrategyDetailOrderService accountingStrategyDetailOrderService; @Resource private TChargingOrderAccountingStrategyService chargingOrderAccountingStrategyService; @Resource private AppCouponClient appCouponClient; @Resource private TCECClient tcecClient; @Resource private VipClient vipClient; @Resource private ChargingGunClient chargingGunClient; @Resource private IntegralRuleClient integralRuleClient; @Resource private AppUserClient appUserClient; @Resource private AppUserIntegralChangeClient appUserIntegralChangeClient; @Resource private WxPaymentClient wxPaymentClient; @Resource private AliPaymentClient aliPaymentClient; @Resource private H5AliPaymentClient h5AliPaymentClient; @Resource private ITChargingOrderSummaryDataService chargingOrderSummaryDataService; @Resource private ChengDuJianGuanClient chengDuJianGuanClient; //十分钟循环执行的定时任务 @Scheduled(fixedRate = 1000 * 60 * 10) public void taskTenMinutes() { if(null != port && port == 5400){ List failedStartupOrder = chargingOrderService.findFailedStartupOrder(); log.info("定时任务执行,查询到启动失败的订单数量:{}", failedStartupOrder.size()); for (TChargingOrder order : failedStartupOrder) { log.info("定时任务执行,查询到启动失败的订单:{}", order.getCode()); //查询是否有充电信息 List dataByOrderCode = uploadRealTimeMonitoringDataService.getDataByOrderCode(order.getCode()); log.info("充电实时数据:{}", dataByOrderCode.size()); //没有充电数据,则执行退款 if(null == dataByOrderCode || dataByOrderCode.isEmpty()){ log.info("定时任务执行,查询到启动失败的订单,执行退款:{}", order.getCode()); if(1 == order.getOrderSource()){ chargingOrderService.refund(order.getCode()); int num = 0; while (true){ TChargingOrderRefund one = chargingOrderRefundService.getOne(new LambdaQueryWrapper().eq(TChargingOrderRefund::getChargingOrderId, order.getId())); if(null != one && 2 == one.getRefundStatus()){ order.setStatus(-1); chargingOrderService.updateById(order); break; } try { Thread.sleep(5000); } catch (InterruptedException e) { throw new RuntimeException(e); } num++; if(num > 10){ break; } } }else{ order.setStatus(-1); chargingOrderService.updateById(order); } } } //处理退款中的数据 List stoppedOrder = chargingOrderService.findStoppedOrder(); log.info("定时任务执行,查询到停止中的订单数量:{}", stoppedOrder.size()); for (TChargingOrder order : stoppedOrder) { log.info("定时任务执行,查询到停止中的订单:{}", order.getCode()); TransactionRecord one = transactionRecordService.findOne(order.getCode()); if(null != one){ log.info("定时任务执行,查询到停止中的订单账单数据:{}", JSON.toJSONString(one)); if(null == order.getStartTime()){ List dataList = uploadRealTimeMonitoringDataService.getDataByOrderCode(order.getCode()); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); order.setStartTime(LocalDateTime.parse(sdf.format(dataList.get(dataList.size() - 1).getCreate_time()), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS").withZone(ZoneId.systemDefault()))); } if(null == order.getEndTime()){ order.setEndTime(LocalDateTime.parse(one.getEnd_time(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS").withZone(ZoneId.systemDefault()))); } chargingOrderService.updateById(order); TransactionRecordMessageVO vo = new TransactionRecordMessageVO(); BeanUtils.copyProperties(one, vo); R r = chargingOrderService.endChargeBillingCharge(vo); log.info("定时任务执行,停止中的订单处理结果:{}", JSON.toJSONString(r)); }else{ endOrder(order); } } //处理状态为充电中,但硬件已完成的订单 List chargingOrder = chargingOrderService.findChargingOrder(); log.info("定时任务执行,查询到充电中的订单数量:{}", chargingOrder.size()); for (TChargingOrder order : chargingOrder) { log.info("定时任务执行,查询到充电中的订单:{}", order.getCode()); TransactionRecord one = transactionRecordService.findOne(order.getCode()); if(null != one && StringUtils.isNotEmpty(one.getResult())){ log.info("定时任务执行,查询到充电中的订单账单数据:{}", JSON.toJSONString(one)); if(null == order.getStartTime()){ List dataList = uploadRealTimeMonitoringDataService.getDataByOrderCode(order.getCode()); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); order.setStartTime(LocalDateTime.parse(sdf.format(dataList.get(dataList.size() - 1).getCreate_time()), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS").withZone(ZoneId.systemDefault()))); } if(null == order.getEndTime()){ order.setEndTime(LocalDateTime.parse(one.getEnd_time(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS").withZone(ZoneId.systemDefault()))); } chargingOrderService.updateById(order); TransactionRecordMessageVO vo = new TransactionRecordMessageVO(); BeanUtils.copyProperties(one, vo); R r = chargingOrderService.endChargeBillingCharge(vo); log.info("定时任务执行,充电中的订单处理结果:{}", JSON.toJSONString(r)); } } //处理还未退款,但是订单状态已结束的数据 List endChargingOrder = chargingOrderService.findEndChargingOrder(); log.info("定时任务执行,查询到已结束未退款的订单数量:{}", endChargingOrder.size()); for (TChargingOrder order : endChargingOrder) { if(-1 == order.getStatus()){ order.setStatus(2); } if(5 == order.getStatus()){ order.setStatus(4); } chargingOrderService.updateById(order); } } } @Scheduled(cron = "0 0 0 2 * ?") public void taskMonth() { if(null != port && port == 5400){ try { // 获取上个月的开始和结束日期 LocalDate firstDayOfLastMonth = LocalDate.now().minusMonths(1). withDayOfMonth(2); String string = firstDayOfLastMonth.toString(); // 将-替换为空字符串 string = string.replace("-", ""); // 生成一次全站订单 TChargingBill tChargingBill = new TChargingBill(); // 订单生成规则JSD+20231201(账单所属月份)+1131304205(随机10位数)+001(当月账单序号,每月重置) Random random = new Random(); String randomDigits = random.ints(10, 0, 10) // 生成10个随机数字,范围在0-9 .mapToObj(String::valueOf) .collect(Collectors.joining()); // 将其连接成一个字符串 tChargingBill.setCode("JSD"+string+randomDigits ); tChargingBill.setType(1); tChargingBill.setSiteId(0); tChargingBill.setBillTime(LocalDateTime.now()); tChargingBill.setStatus(1); tChargingBill.setOrderState(2); tChargingBill.setBillType(1); System.err.println("定时任务生成充电算帐单:全站"); chargingBillService.save(tChargingBill); // 生成一次全站订单 TChargingBill tChargingBill1 = new TChargingBill(); // 订单生成规则JSD+20231201(账单所属月份)+1131304205(随机10位数)+001(当月账单序号,每月重置) Random random1 = new Random(); String randomDigits1 = random1.ints(10, 0, 10) // 生成10个随机数字,范围在0-9 .mapToObj(String::valueOf) .collect(Collectors.joining()); // 将其连接成一个字符串 tChargingBill1.setCode("JSD"+string+randomDigits1 ); tChargingBill1.setType(1); tChargingBill1.setSiteId(0); tChargingBill1.setBillTime(LocalDateTime.now()); tChargingBill1.setStatus(1); tChargingBill1.setOrderState(2); tChargingBill1.setBillType(2); System.err.println("定时任务生成账户结算帐单:全站"); chargingBillService.save(tChargingBill1); System.err.println("定时任务生成各个站点结算帐单"); List collect = siteClient.getSiteAll().getData().stream().map(Site::getId).collect(Collectors.toList()); // 充电算帐单 List tChargingBills = new ArrayList<>(); // 账户结算账单 List tChargingBills1 = new ArrayList<>(); for (int i = 0; i < collect.size(); i++) { TChargingBill tChargingBill2 = new TChargingBill(); Random random2 = new Random(); String randomDigits2 = random2.ints(10, 0, 10) // 生成10个随机数字,范围在0-9 .mapToObj(String::valueOf) .collect(Collectors.joining()); // 将其连接成一个字符串 tChargingBill2.setCode("JSD"+string+randomDigits2+(i+1) ); tChargingBill2.setType(2); List list = chargingOrderService.lambdaQuery() .eq(TChargingOrder::getSiteId, collect.get(i)).list(); if (list.isEmpty()){ continue; } tChargingBill2.setSiteId(collect.get(i)); tChargingBill2.setBillTime(LocalDateTime.now()); tChargingBill2.setBillType(1); tChargingBill2.setStatus(1); tChargingBill2.setOrderState(2); tChargingBills.add(tChargingBill2); TChargingBill tChargingBill3 = new TChargingBill(); Random random3 = new Random(); String randomDigits3 = random3.ints(10, 0, 10) // 生成10个随机数字,范围在0-9 .mapToObj(String::valueOf) .collect(Collectors.joining()); // 将其连接成一个字符串 tChargingBill3.setCode("JSD"+string+randomDigits3+(i+1) ); tChargingBill3.setType(2); tChargingBill3.setSiteId(collect.get(i)); tChargingBill3.setBillTime(LocalDateTime.now()); tChargingBill3.setBillType(2); tChargingBill3.setStatus(1); tChargingBill3.setOrderState(2); tChargingBills1.add(tChargingBill3); } System.err.println("列表"+tChargingBills); if (!tChargingBills.isEmpty())chargingBillService.saveBatch(tChargingBills); if (!tChargingBills1.isEmpty())chargingBillService.saveBatch(tChargingBills1); } catch (Exception e) { e.printStackTrace(); } } } // 每个月最后一天23点执行的定时任务 @Scheduled(cron = "0 0 23 * * ?") public void taskLastDay() { if(null != port && port == 5400){ try { // 获取上个月的开始和结束日期 LocalDate firstDayOfLastMonth = LocalDate.now().minusMonths(1). withDayOfMonth(1); LocalDate lastDayOfLastMonth = LocalDate.now().minusMonths(1). withDayOfMonth(firstDayOfLastMonth.lengthOfMonth()); // 将 LocalDate 转换为 LocalDateTime,并设定时间为一天的开始 LocalDateTime startDateTime = firstDayOfLastMonth.atStartOfDay(); LocalDateTime endDateTime = lastDayOfLastMonth.atTime(23, 59, 59); // 设定到最后一秒 // 构建查询条件 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.ge(TChargingBill::getBillTime, Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant())) .le(TChargingBill::getBillTime, Date.from(endDateTime.atZone(ZoneId.systemDefault()).toInstant())); // 使用 le 包括最后一天的记录 List list = chargingBillService.list(queryWrapper); for (TChargingBill tChargingBill : list) { tChargingBill.setStatus(2); } chargingBillService.updateBatchById(list); } catch (Exception e) { e.printStackTrace(); } } } @Override public void onApplicationEvent(WebServerInitializedEvent event) { port = event.getWebServer().getPort(); System.out.println("端口号:" + port); } public void endOrder(TChargingOrder order){ List dataList = uploadRealTimeMonitoringDataService.getDataByOrderCode(order.getCode()); if(!dataList.isEmpty()){ //获取当前订单的计费规则,然后分段计算总的度数和充电金额 List detailOrders = accountingStrategyDetailOrderService.list(new LambdaQueryWrapper() .eq(AccountingStrategyDetailOrder::getChargingOrderId, order.getId()).last(" order by start_time")); detailOrders.get(detailOrders.size() - 1).setEndTime("23:59"); SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); //开始解析每个时段的充电度数 BigDecimal decimal = BigDecimal.ZERO; //如果使用优惠券需要判断优惠券是否满足使用条件 //退款金额=优惠券金额+剩余充电金额 BigDecimal periodElectricPrice_total = BigDecimal.ZERO; BigDecimal periodServicePrice_total = BigDecimal.ZERO; BigDecimal vipDiscountAmount_total = BigDecimal.ZERO; BigDecimal serviceCharge_total = BigDecimal.ZERO; BigDecimal total = BigDecimal.ZERO; //判断实时数据是否跨天 SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd"); Date end_time = dataList.get(0).getCreate_time(); String end = sdf2.format(end_time); Date start_time = dataList.get(dataList.size() - 1).getCreate_time(); String start = sdf2.format(start_time); if(!end.equals(start)){ List list = detailOrders.stream().map(s->{ AccountingStrategyDetailOrder accountingStrategyDetailOrder = new AccountingStrategyDetailOrder(); BeanUtils.copyProperties(s, accountingStrategyDetailOrder); return accountingStrategyDetailOrder; }).collect(Collectors.toList()); for (AccountingStrategyDetailOrder detailOrder : detailOrders) { detailOrder.setStartTime(start + " " + detailOrder.getStartTime()); detailOrder.setEndTime(start + " " + detailOrder.getEndTime()); } for (AccountingStrategyDetailOrder detailOrder : list) { detailOrder.setStartTime(end + " " + detailOrder.getStartTime()); detailOrder.setEndTime(end + " " + detailOrder.getEndTime()); } detailOrders.addAll(list); }else{ for (AccountingStrategyDetailOrder detailOrder : detailOrders) { detailOrder.setStartTime(start + " " + detailOrder.getStartTime()); detailOrder.setEndTime(start + " " + detailOrder.getEndTime()); } } SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddHHmm"); List list = new ArrayList<>(); for (AccountingStrategyDetailOrder detailOrder : detailOrders) { long startTime = Long.parseLong(detailOrder.getStartTime().replaceAll("-", "").replaceAll(" ", "").replaceAll(":", "")); long endTime = Long.parseLong(detailOrder.getEndTime().replaceAll("-", "").replaceAll(" ", "").replaceAll(":", "")); List collect = dataList.stream().filter(s -> Long.parseLong(sdf1.format(s.getCreate_time())) > startTime && Long.parseLong(sdf1.format(s.getCreate_time())) <= endTime).collect(Collectors.toList()); if(!collect.isEmpty()){ //升序排序 collect.sort(new Comparator(){ @Override public int compare(UploadRealTimeMonitoringData o1, UploadRealTimeMonitoringData o2) { return o1.getCharging_degree().compareTo(o2.getCharging_degree()); } }); UploadRealTimeMonitoringData uploadRealTimeMonitoringData = collect.get(collect.size() - 1); BigDecimal chargingDegree = uploadRealTimeMonitoringData.getCharging_degree(); BigDecimal subtract = chargingDegree.subtract(decimal); decimal = chargingDegree; if(subtract.compareTo(BigDecimal.ZERO) > 0){ //组装充电明细数据 TChargingOrderAccountingStrategy chargingOrderAccountingStrategy = new TChargingOrderAccountingStrategy(); chargingOrderAccountingStrategy.setChargingOrderId(order.getId()); chargingOrderAccountingStrategy.setAccountingStrategyDetailId(detailOrder.getId()); chargingOrderAccountingStrategy.setType(detailOrder.getType()); chargingOrderAccountingStrategy.setElectrovalence(detailOrder.getElectrovalence()); chargingOrderAccountingStrategy.setServiceCharge(detailOrder.getServiceCharge()); chargingOrderAccountingStrategy.setCostServiceCharge(detailOrder.getCostServiceCharge()); chargingOrderAccountingStrategy.setChargingCapacity(subtract); chargingOrderAccountingStrategy.setCreateTime(LocalDateTime.now()); if (list.size() == 0) { String time = sdf.format(collect.get(0).getCreate_time()); chargingOrderAccountingStrategy.setStartTime(time); } else { chargingOrderAccountingStrategy.setStartTime(detailOrder.getStartTime().split(" ")[1]); } chargingOrderAccountingStrategy.setEndTime(detailOrder.getEndTime().split(" ")[1]); //已充电总度数 BigDecimal electrovalenc = detailOrder.getElectrovalence().multiply(subtract); BigDecimal originalServicePrice = detailOrder.getServiceCharge().multiply(subtract); BigDecimal serviceCharge = originalServicePrice; BigDecimal vipDiscountAmount = BigDecimal.ZERO; //计算优惠金额 if (null != order.getVipDiscount()) { //0.58折 vipDiscountAmount = serviceCharge.multiply(new BigDecimal(1).subtract(order.getVipDiscount())); serviceCharge = serviceCharge.multiply(order.getVipDiscount()); } chargingOrderAccountingStrategy.setPeriodElectricPrice(electrovalenc.setScale(4, RoundingMode.HALF_EVEN)); chargingOrderAccountingStrategy.setPeriodServicePrice(serviceCharge.setScale(4, RoundingMode.HALF_EVEN)); chargingOrderAccountingStrategy.setPeriodOriginalServicePrice(originalServicePrice.setScale(4, RoundingMode.HALF_EVEN)); chargingOrderAccountingStrategy.setVipDiscountAmount(vipDiscountAmount.setScale(4, RoundingMode.HALF_EVEN)); chargingOrderAccountingStrategy.setCreateTime(LocalDateTime.now()); list.add(chargingOrderAccountingStrategy); //电费 periodElectricPrice_total = periodElectricPrice_total.add(electrovalenc); //服务费(含折扣) serviceCharge_total = serviceCharge_total.add(serviceCharge); //服务费(不含折扣) periodServicePrice_total = periodServicePrice_total.add(originalServicePrice); //会员折扣优惠金额 vipDiscountAmount_total = vipDiscountAmount_total.add(vipDiscountAmount); //原始总金额(不含折扣) total = total.add(electrovalenc.add(originalServicePrice)); } } } list.get(list.size() - 1).setEndTime(sdf.format(dataList.get(0).getCreate_time())); chargingOrderAccountingStrategyService.saveBatch(list); BigDecimal orderAmount = BigDecimal.valueOf(total.doubleValue()); //原金额 BigDecimal rechargeAmount = order.getRechargeAmount(); //支付金额 BigDecimal payAmount = periodElectricPrice_total.add(serviceCharge_total); //退款金额=充值金额-实际支付金额 BigDecimal refundAmount = rechargeAmount.subtract(payAmount); UploadRealTimeMonitoringData uploadRealTimeMonitoringData = uploadRealTimeMonitoringDataService.getLastDataById(order.getCode()); if (null != uploadRealTimeMonitoringData && null == order.getEndMode()) { Integer soc = uploadRealTimeMonitoringData.getSoc(); if (soc >= 98) { order.setEndMode(2); } else if (null != order.getResidualAmount() && order.getResidualAmount().compareTo(new BigDecimal(1)) <= 0) { order.setEndMode(3); } else { order.setEndMode(1); } } order.setResidualAmount(rechargeAmount.subtract(total).setScale(2, RoundingMode.HALF_EVEN)); order.setStartTime(list.get(0).getCreateTime()); order.setEndTime(list.get(list.size() - 1).getCreateTime()); order.setStatus(5); order.setOrderAmount(orderAmount.setScale(2, RoundingMode.HALF_EVEN)); order.setElectrovalence(periodElectricPrice_total.setScale(2, RoundingMode.HALF_EVEN)); order.setChargingCapacity(list.get(list.size() - 1).getChargingCapacity()); order.setElectricity(list.get(list.size() - 1).getChargingCapacity()); order.setVipDiscountAmount(vipDiscountAmount_total); if (vipDiscountAmount_total.compareTo(BigDecimal.ZERO) == 0) { order.setVipDiscount(BigDecimal.valueOf(1)); } //计算优惠券 BigDecimal couponDiscount = BigDecimal.ZERO; if (null != order.getAppCouponId()) { //判断实际充电金额是否满足优惠券使用条件,如果不满足则不适用优惠券。 TAppCoupon appCoupon = appCouponClient.getAppCouponById(order.getAppCouponId()).getData(); String couponJson = appCoupon.getCouponJson(); TCoupon tCoupon = com.alibaba.fastjson2.JSON.parseObject(couponJson, TCoupon.class); Integer preferentialMode = tCoupon.getPreferentialMode(); if (1 == preferentialMode) { //满减 if (payAmount.compareTo(tCoupon.getMeetTheConditions()) >= 0) { BigDecimal couponDiscountAmount = tCoupon.getDiscountAmount(); //如果优惠金额大于服务费金额,以服务费作为最大限制 if (serviceCharge_total.compareTo(couponDiscountAmount) < 0) { couponDiscount = serviceCharge_total; serviceCharge_total = BigDecimal.ZERO; } else { couponDiscount = couponDiscountAmount; } appCoupon.setStatus(2); appCouponClient.updateAppCoupon(appCoupon); } else { appCouponClient.refund(order.getAppCouponId().toString()); order.setAppCouponId(null); order.setCouponDiscountAmount(BigDecimal.ZERO); } } if (2 == preferentialMode) { //抵扣 if (payAmount.compareTo(tCoupon.getMeetTheConditions()) >= 0) { //折扣金额 BigDecimal divide = payAmount.multiply(new BigDecimal(10).subtract(tCoupon.getDiscount())).divide(new BigDecimal(10)); divide = divide.compareTo(tCoupon.getMaximumDiscountAmount()) > 0 ? tCoupon.getMaximumDiscountAmount() : divide; //如果优惠金额大于服务费金额,以服务费作为最大限制 if (serviceCharge_total.compareTo(divide) < 0) { couponDiscount = serviceCharge_total; serviceCharge_total = BigDecimal.ZERO; } else { couponDiscount = divide; } appCoupon.setStatus(2); appCouponClient.updateAppCoupon(appCoupon); } else { order.setAppCouponId(null); order.setCouponDiscountAmount(BigDecimal.ZERO); appCouponClient.refund(order.getAppCouponId().toString()); } } } //优惠券优惠金额 couponDiscount = couponDiscount.setScale(4, RoundingMode.HALF_EVEN); //退款金额+优惠券 refundAmount = refundAmount.add(couponDiscount); //实际支付金额-优惠券 payAmount = payAmount.subtract(couponDiscount); if (serviceCharge_total.compareTo(BigDecimal.ZERO) > 0) { serviceCharge_total = serviceCharge_total.subtract(couponDiscount); } order.setCouponDiscountAmount(couponDiscount.setScale(2, RoundingMode.HALF_EVEN)); order.setServiceCharge(serviceCharge_total.setScale(2, RoundingMode.HALF_EVEN)); order.setPaymentAmount(payAmount.setScale(2, RoundingMode.HALF_EVEN)); order.setRefundAmount(refundAmount.setScale(2, RoundingMode.HALF_EVEN)); order.setRefundStatus(1); chargingOrderService.updateById(order); order = chargingOrderService.getById(order.getId()); Site site = siteClient.getSiteByIds(Arrays.asList(order.getSiteId())).getData().get(0); //推送三方平台 if (2 == order.getOrderSource() && 1 == site.getIsOpenSynchronization()) { TChargingOrder finalChargingOrder = order; new Thread(new Runnable() { @Override public void run() { tcecClient.notificationEquipChargeStatus(finalChargingOrder.getStartChargeSeq(), finalChargingOrder.getOperatorId()); tcecClient.notificationStopChargeResult(finalChargingOrder.getStartChargeSeq(), finalChargingOrder.getChargingGunId().toString(), finalChargingOrder.getOperatorId()); tcecClient.notificationChargeOrderInfo(finalChargingOrder.getStartChargeSeq(), finalChargingOrder.getOperatorId()); } }).start(); } //开始将优惠券优惠的金额添加到明细中 BigDecimal couponDiscountAmount = order.getCouponDiscountAmount(); if (null != couponDiscountAmount && couponDiscountAmount.compareTo(BigDecimal.ZERO) > 0) { List list1 = chargingOrderAccountingStrategyService.list(new LambdaQueryWrapper().eq(TChargingOrderAccountingStrategy::getChargingOrderId, order.getId())); BigDecimal reduce = list1.stream().map(TChargingOrderAccountingStrategy::getPeriodServicePrice).reduce(BigDecimal.ZERO, BigDecimal::add); for (TChargingOrderAccountingStrategy chargingOrderAccountingStrategy : list1) { BigDecimal periodServicePrice = chargingOrderAccountingStrategy.getPeriodServicePrice(); BigDecimal multiply = couponDiscountAmount.multiply(periodServicePrice.divide(reduce, new MathContext(4, RoundingMode.HALF_EVEN))); periodServicePrice = periodServicePrice.subtract(multiply); chargingOrderAccountingStrategy.setPeriodServicePrice(periodServicePrice.setScale(2, RoundingMode.HALF_EVEN)); chargingOrderAccountingStrategy.setCouponDiscountAmount(multiply.setScale(2, RoundingMode.HALF_EVEN)); } chargingOrderAccountingStrategyService.updateBatchById(list1); } // 将枪状态重置为空闲 TChargingGun chargingGun = new TChargingGun(); chargingGun.setId(order.getChargingGunId()); chargingGun.setStatus(2); chargingGun.setChargingPower(BigDecimal.ZERO); chargingGunClient.updateChargingGunById(chargingGun); chargingGun = chargingGunClient.getChargingGunById(order.getChargingGunId()).getData(); //推送状态给三方平台 if (2 == order.getOrderSource() && 1 == site.getIsOpenSynchronization()) { tcecClient.pushChargingGunStatus(chargingGun.getFullNumber(), 2); } ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>()); TChargingOrder finalOrder = order; threadPoolExecutor.execute(()->{ //推送成都监管 NotificationConnectorChargeStatusVo statusVo = new NotificationConnectorChargeStatusVo(); statusVo.setOrderCode(finalOrder.getCode()); statusVo.setChargingGunId(finalOrder.getChargingGunId()); chengDuJianGuanClient.notificationConnectorChargeStatus(statusVo); chengDuJianGuanClient.notificationOrderInfo(statusVo); }); //添加积分 if (1 == order.getOrderSource()) { TIntegralRule integralRule = integralRuleClient.getSet().getData(); if (null != integralRule) { TAppUser appUser = appUserClient.getUserById(order.getAppUserId()).getData(); Integer num1 = com.alibaba.fastjson2.JSON.parseObject(integralRule.getChargeCredit()).getInteger("num1"); Integer integral = order.getServiceCharge().intValue() * num1; if (null != appUser.getVipId()) { TVip vip = vipClient.getInfo1(appUser.getVipId()).getData(); Integer doubleIntegration = vip.getDoubleIntegration(); //双倍积分 if (1 == doubleIntegration) { integral *= 2; } } if (integral > 0) { TAppUserIntegralChange appUserIntegralChange = new TAppUserIntegralChange(); appUserIntegralChange.setAppUserId(appUser.getId()); appUserIntegralChange.setChangeType(2); appUserIntegralChange.setHistoricalIntegral(appUser.getPoints()); appUser.setPoints(appUser.getPoints() + integral); appUserIntegralChange.setCurrentIntegral(appUser.getPoints()); appUserIntegralChange.setCreateTime(LocalDateTime.now()); appUserIntegralChange.setOrderCode(order.getCode()); appUserIntegralChange.setExtension(order.getId().toString()); appUserClient.updateAppUser(appUser); appUserIntegralChangeClient.addAppUserIntegralChange(appUserIntegralChange); } } //计算用户标签 chargingOrderService.editUserTag(order); //用户推荐奖励 chargingOrderService.referralReward(order); //开始构建退款费用 refundAmount = refundAmount.setScale(2, RoundingMode.HALF_EVEN); if (refundAmount.compareTo(BigDecimal.ZERO) > 0) { Integer rechargePaymentType = order.getRechargePaymentType(); //构建退款明细 TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund(); chargingOrderRefund.setChargingOrderId(order.getId()); SimpleDateFormat sdfaa = new SimpleDateFormat("yyyyMMddHHmmssSSS"); chargingOrderRefund.setRefundCode("CDF" + sdfaa.format(new Date()) + (Double.valueOf(Math.random() * 1000).intValue())); chargingOrderRefund.setRefundAmount(refundAmount); chargingOrderRefund.setRefundStatus(1); chargingOrderRefund.setPayType(rechargePaymentType); chargingOrderRefund.setRefundStatus(1); chargingOrderRefund.setCode(order.getCode()); chargingOrderRefund.setRefundTitle("充电完成退款"); chargingOrderRefund.setRefundContent("充电完成退款"); chargingOrderRefund.setRefundReason("充电完成退款"); chargingOrderRefund.setRefundRemark("实际充电消费金额:" + order.getPaymentAmount()); chargingOrderRefund.setRefundTotalAmount(refundAmount); chargingOrderRefund.setPayAmount(rechargeAmount); if (1 == rechargePaymentType) { WxPaymentRefundModel model = new WxPaymentRefundModel(); model.setOut_trade_no(order.getCode()); model.setOut_refund_no(chargingOrderRefund.getRefundCode()); model.setReason("充电完成退款"); model.setNotify_url("/payment/wx/refund/notify"); WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount(); amount.setRefund(refundAmount.multiply(new BigDecimal(100)).intValue()); amount.setTotal(rechargeAmount.multiply(new BigDecimal(100)).intValue()); amount.setCurrency("CNY"); model.setAmount(amount); R> result = wxPaymentClient.refundOrderR(model); if (200 == result.getCode()) { chargingOrderRefundService.save(chargingOrderRefund); //手续费 Map amount1 = (Map) result.getData().get("amount"); Object refund_fee1 = amount1.get("refund_fee"); BigDecimal refund_fee = new BigDecimal(null == refund_fee1 ? "0" : refund_fee1.toString()).divide(new BigDecimal(100)); chargingOrderRefund.setRefundFee(refund_fee); chargingOrderRefundService.updateById(chargingOrderRefund); } } if (2 == rechargePaymentType) { RefundReq dto = new RefundReq(); dto.setOutTradeNo(order.getCode()); dto.setOutRequestNo(chargingOrderRefund.getRefundCode()); dto.setRefundAmount(refundAmount.toString()); dto.setRefundReason("充电完成退款"); RefundResp resp = aliPaymentClient.refund(dto).getData(); if (null != resp) { chargingOrderRefundService.save(chargingOrderRefund); chargingOrderService.chargingOrderStartupFailureWxRefund(chargingOrderRefund.getRefundCode(), resp.getTradeNo(), "SUCCESS", null); } } if (3 == rechargePaymentType) { RefundReq dto = new RefundReq(); dto.setOutTradeNo(order.getRechargeSerialNumber()); dto.setOutRequestNo(chargingOrderRefund.getRefundCode()); dto.setRefundAmount(refundAmount.toString()); dto.setRefundReason("充电完成退款"); RefundResp resp = h5AliPaymentClient.refund(dto).getData(); if (null != resp && "10000".equals(resp.getCode())) { chargingOrderRefundService.save(chargingOrderRefund); chargingOrderService.chargingOrderStartupFailureWxRefund(chargingOrderRefund.getRefundCode(), resp.getTradeNo(), "SUCCESS", null); } } } } //添加汇总统计数据 List list4 = chargingOrderAccountingStrategyService.list(new QueryWrapper().eq("charging_order_id", order.getId())); BigDecimal electronic_reduce = list4.stream().map(TChargingOrderAccountingStrategy::getPeriodElectricPrice).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal service_reduce = list4.stream().map(TChargingOrderAccountingStrategy::getPeriodServicePrice).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal chargingCapacity = list4.stream().map(TChargingOrderAccountingStrategy::getChargingCapacity).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal serviceMoney = BigDecimal.ZERO; BigDecimal paymentMoney = BigDecimal.ZERO; long time = 0; if (!order.getOrderSource().equals(2)) { serviceMoney = serviceMoney.add(service_reduce); paymentMoney = paymentMoney.add(electronic_reduce).add(service_reduce); } else { serviceMoney = serviceMoney.add(service_reduce.multiply(new BigDecimal("0.8"))); paymentMoney = paymentMoney.add(electronic_reduce).add(service_reduce.multiply(new BigDecimal("0.8"))); } if (order.getStartTime() != null && order.getEndTime() != null) { time = ChronoUnit.SECONDS.between(order.getStartTime(), order.getEndTime()); } TChargingOrderSummaryData summaryData = new TChargingOrderSummaryData(); summaryData.setChargingOrderId(order.getId()); summaryData.setChargingCapacity(chargingCapacity); summaryData.setChargingDuration(time); summaryData.setIncome(paymentMoney.setScale(2, BigDecimal.ROUND_HALF_EVEN)); summaryData.setElectricPrice(electronic_reduce.setScale(2, BigDecimal.ROUND_HALF_EVEN)); summaryData.setServicePrice(serviceMoney.setScale(2, BigDecimal.ROUND_HALF_EVEN)); chargingOrderSummaryDataService.save(summaryData); //推送监管平台订单状态和订单详情 ChargingOrderVo chargingOrderVo = new ChargingOrderVo(); BeanUtils.copyProperties(order, chargingOrderVo); chargingMessageClient.pushOrderInfo(chargingOrderVo); chargingMessageClient.pushOrderStatus(chargingOrderVo); } } }