From f2dff53d76a7e9a23e6a2ecfed58ce978dc41442 Mon Sep 17 00:00:00 2001 From: xuhy <3313886187@qq.com> Date: 星期五, 06 九月 2024 18:22:11 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java | 1210 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 1,162 insertions(+), 48 deletions(-) diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java index 016a888..928979b 100644 --- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java +++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java @@ -1,52 +1,82 @@ package com.ruoyi.order.service.impl; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.account.api.feignClient.AppUserCarClient; -import com.ruoyi.account.api.feignClient.AppUserClient; -import com.ruoyi.account.api.feignClient.AppUserVipDetailClient; -import com.ruoyi.account.api.model.TAppUser; -import com.ruoyi.account.api.model.TAppUserCar; -import com.ruoyi.account.api.model.TAppUserVipDetail; +import com.ruoyi.account.api.feignClient.*; +import com.ruoyi.account.api.model.*; import com.ruoyi.account.api.vo.GetAppUserVipDetail; -import com.ruoyi.chargingPile.api.feignClient.ChargingGunClient; -import com.ruoyi.chargingPile.api.feignClient.ChargingPileClient; -import com.ruoyi.chargingPile.api.feignClient.SiteClient; -import com.ruoyi.chargingPile.api.model.Site; -import com.ruoyi.chargingPile.api.model.TChargingGun; -import com.ruoyi.chargingPile.api.model.TChargingPile; +import com.ruoyi.account.api.vo.GetInviteUser; +import com.ruoyi.chargingPile.api.feignClient.*; +import com.ruoyi.chargingPile.api.model.*; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.dto.ChargingOrderGroup; +import com.ruoyi.common.core.dto.ChargingPercentProvinceDto; import com.ruoyi.common.core.web.domain.AjaxResult; -import com.ruoyi.common.core.web.page.BasePage; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.common.redis.service.RedisService; import com.ruoyi.common.security.service.TokenService; -import com.ruoyi.order.api.model.TChargingOrder; -import com.ruoyi.order.api.model.TChargingOrderAccountingStrategy; +import com.ruoyi.integration.api.feignClient.ChargingHandshakeClient; +import com.ruoyi.integration.api.feignClient.PlatformStartChargingReplyClient; +import com.ruoyi.integration.api.feignClient.SendMessageClient; +import com.ruoyi.integration.api.feignClient.UploadRealTimeMonitoringDataClient; +import com.ruoyi.integration.api.model.ChargingHandshake; +import com.ruoyi.integration.api.model.PlatformStartCharging; +import com.ruoyi.integration.api.model.PlatformStartChargingReply; +import com.ruoyi.integration.api.model.UploadRealTimeMonitoringData; +import com.ruoyi.integration.api.feignClient.*; +import com.ruoyi.integration.api.model.*; +import com.ruoyi.integration.api.vo.GetPlatformStopChargingReply; +import com.ruoyi.order.api.feignClient.AccountingStrategyDetailOrderClient; +import com.ruoyi.order.api.feignClient.ChargingOrderAccountingStrategyClient; +import com.ruoyi.order.api.model.*; import com.ruoyi.order.api.query.ChargingOrderQuery; -import com.ruoyi.order.api.vo.ChargingOrderVO; -import com.ruoyi.order.api.vo.TCharingOrderVO; +import com.ruoyi.order.api.query.UploadRealTimeMonitoringDataQuery; +import com.ruoyi.order.api.vo.*; import com.ruoyi.order.dto.*; import com.ruoyi.order.mapper.TChargingOrderMapper; import com.ruoyi.order.service.TChargingOrderAccountingStrategyService; +import com.ruoyi.order.service.TChargingOrderRefundService; import com.ruoyi.order.service.TChargingOrderService; +import com.ruoyi.order.service.TOrderEvaluateService; +import com.ruoyi.order.service.*; +import com.ruoyi.other.api.domain.TCoupon; +import com.ruoyi.other.api.domain.TGoods; +import com.ruoyi.order.vo.ChargingOrderListInfoVO; +import com.ruoyi.other.api.domain.TIntegralRule; +import com.ruoyi.other.api.feignClient.IntegralRuleClient; +import com.ruoyi.other.api.feignClient.RoleSiteClient; +import com.ruoyi.other.api.feignClient.UserSiteClient; import com.ruoyi.payment.api.feignClient.AliPaymentClient; 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 com.ruoyi.payment.api.vo.*; +import com.ruoyi.system.api.feignClient.SysUserClient; import io.seata.spring.annotation.GlobalTransactional; import io.swagger.annotations.ApiModelProperty; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; 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.ZoneOffset; import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; import java.util.*; +import java.util.concurrent.*; +import java.util.stream.Collectors; /** * <p> @@ -59,6 +89,8 @@ @Service public class TChargingOrderServiceImpl extends ServiceImpl<TChargingOrderMapper, TChargingOrder> implements TChargingOrderService { + private Logger log = LoggerFactory.getLogger(TChargingOrderServiceImpl.class); + @Resource private ChargingGunClient chargingGunClient; @@ -69,7 +101,11 @@ private AppUserCarClient appUserCarClient; @Resource private AppUserClient appUserClient; - + + @Resource + private ChargingPileClient chargingPileClient; + + @Resource private TChargingOrderAccountingStrategyService chargingOrderAccountingStrategyService; @@ -82,15 +118,67 @@ @Resource private AliPaymentClient aliPaymentClient; + @Resource - private ChargingPileClient chargingPileClient; - + private AppCouponClient appCouponClient; @Resource private AppUserVipDetailClient appUserVipDetailClient; @Resource private RedisService redisService; + + @Resource + private UploadRealTimeMonitoringDataClient uploadRealTimeMonitoringDataClient; + + @Resource + private ChargingHandshakeClient chargingHandshakeClient; + + @Resource + private SendMessageClient sendMessageClient; + + @Resource + private TOrderEvaluateService orderEvaluateService; + + + @Resource + private AccountingStrategyDetailClient accountingStrategyDetailClient; + + @Resource + private AccountingStrategyDetailOrderClient accountingStrategyDetailOrderClient; + + @Resource + private AccountingStrategyClient accountingStrategyClient; + + @Resource + private PlatformStartChargingReplyClient platformStartChargingReplyClient; + + @Resource + private TChargingOrderRefundService chargingOrderRefundService; + + @Resource + private PlatformStopChargingReplyClient platformStopChargingReplyClient; + + @Resource + private AccountingStrategyOrderService accountingStrategyOrderService; + + @Resource + private AccountingStrategyDetailOrderService accountingStrategyDetailOrderService; + + @Resource + private InviteUserClient inviteUserClient; + + @Resource + private AppUserIntegralChangeClient appUserIntegralChangeClient; + + @Resource + private IntegralRuleClient integralRuleClient; + + //计数器 + private Map<String, Integer> counter_map = new HashMap<>(); + + + /** * 获取小程序充电记录列表数据 @@ -119,9 +207,14 @@ BigDecimal payMoney = tChargingOrder.getStatus() < 4 ? tChargingOrder.getRechargeAmount() : tChargingOrder.getPaymentAmount(); myChargingOrderList.setPayMoney(payMoney); myChargingOrderList.setCreateTime(tChargingOrder.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + long count = orderEvaluateService.count(new LambdaQueryWrapper<TOrderEvaluate>().eq(TOrderEvaluate::getOrderType, 1) + .eq(TOrderEvaluate::getOrderId, tChargingOrder.getId()).eq(TOrderEvaluate::getDelFlag, 0)); + myChargingOrderList.setEvaluate(count + 1L); orderLists.add(myChargingOrderList); } + list = this.baseMapper.getMyChargingOrderList(appUserId, query.getType(), null, null); map.put("list", orderLists); + map.put("totle", list.size()); return map; } @@ -164,11 +257,39 @@ .orderByAsc(TChargingOrderAccountingStrategy::getStartTime) ); myChargingOrderInfo.setStageCost(stageCost); - // todo 待完善 - //再MongoDB中获取数据 - myChargingOrderInfo.setCurrentAndVoltage(null); - //再MongoDB中获取数据 - myChargingOrderInfo.setPower(null); + List<UploadRealTimeMonitoringData> dataList = uploadRealTimeMonitoringDataClient.getDataByOrderCode(chargingOrder.getCode()).getData(); + if(null != dataList){ + //在MongoDB中获取数据 + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); + List<String> time = dataList.stream().map(s -> sdf.format(s.getCreate_time())).collect(Collectors.toList()); + List<BigDecimal> outputVoltage = dataList.stream().map(UploadRealTimeMonitoringData::getOutput_voltage).collect(Collectors.toList()); + List<BigDecimal> outputCurrent = dataList.stream().map(UploadRealTimeMonitoringData::getOutput_current).collect(Collectors.toList()); + List<Map<String, Object>> currentAndVoltage = new ArrayList<>(); + for (int i = 0; i < time.size(); i++) { + Map<String, Object> map = new HashMap<>(); + map.put("time", time.get(i)); + //电流 + map.put("electricity", outputCurrent.get(i)); + //电压 + map.put("voltage", outputVoltage.get(i)); + currentAndVoltage.add(map); + } + myChargingOrderInfo.setCurrentAndVoltage(currentAndVoltage); + //在MongoDB中获取数据 + List<Integer> soc = dataList.stream().map(UploadRealTimeMonitoringData::getSoc).collect(Collectors.toList()); + List<BigDecimal> po = dataList.stream().map(s -> s.getOutput_current().multiply(s.getOutput_voltage()).divide(new BigDecimal(1000))).collect(Collectors.toList()); + List<Map<String, Object>> power = new ArrayList<>(); + for (int i = 0; i < time.size(); i++) { + Map<String, Object> map = new HashMap<>(); + map.put("time", time.get(i)); + //soc + map.put("soc", soc.get(i)); + //功率 + map.put("power", po.get(i)); + power.add(map); + } + myChargingOrderInfo.setPower(power); + } myChargingOrderInfo.setActionable(myChargingOrderInfo.getEndTime() + 604800000L > System.currentTimeMillis() ? 0 : 1); return myChargingOrderInfo; } @@ -197,6 +318,8 @@ BigDecimal payMoney = tChargingOrder.getStatus() < 4 ? tChargingOrder.getRechargeAmount() : tChargingOrder.getPaymentAmount(); myChargingOrderList.setPayMoney(payMoney); myChargingOrderList.setCreateTime(tChargingOrder.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + myChargingOrderList.setElectricCharge(tChargingOrder.getElectrovalence()); + myChargingOrderList.setServiceCharge(tChargingOrder.getServiceCharge()); list.add(myChargingOrderList); } return list; @@ -317,6 +440,23 @@ } this.save(chargingOrder); + + //添加订单的计费策略 + TAccountingStrategy accountingStrategy = accountingStrategyClient.getAccountingStrategyById(tChargingGun.getAccountingStrategyId()).getData(); + List<TAccountingStrategyDetail> strategyDetailList = accountingStrategyDetailClient.getListByAccountingStrategyId(tChargingGun.getAccountingStrategyId()).getData(); + AccountingStrategyOrder accountingStrategyOrder = new AccountingStrategyOrder(); + BeanUtils.copyProperties(accountingStrategy, accountingStrategyOrder); + accountingStrategyOrder.setChargingOrderId(chargingOrder.getId()); + accountingStrategyOrderService.save(accountingStrategyOrder); + List<AccountingStrategyDetailOrder> list1 = new ArrayList<>(); + for (TAccountingStrategyDetail tAccountingStrategyDetail : strategyDetailList) { + AccountingStrategyDetailOrder accountingStrategyDetailOrder = new AccountingStrategyDetailOrder(); + BeanUtils.copyProperties(tAccountingStrategyDetail, accountingStrategyDetailOrder); + accountingStrategyDetailOrder.setChargingOrderId(chargingOrder.getId()); + list1.add(accountingStrategyDetailOrder); + } + accountingStrategyDetailOrderService.saveBatch(list1); + //会员优惠折扣将其计入增加充电时长(增加总充电金额) //如果充电总金额未使用完,则需要退回费用=(原金额/总金额)*(总金额-实际充电金额) if(1 == addChargingOrder.getPaymentType()){ @@ -355,6 +495,7 @@ * @return */ @Override + @GlobalTransactional(rollbackFor = Exception.class) public AjaxResult chargingOrderCallback(Integer paymentType, String out_trade_no, String transaction_id, String attach) { TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, out_trade_no)); if(chargingOrder.getRechargePaymentStatus() == 2){ @@ -362,22 +503,192 @@ } chargingOrder.setRechargePaymentStatus(2); chargingOrder.setRechargeSerialNumber(transaction_id); - this.updateById(chargingOrder); + chargingOrder.setStatus(2); + //添加安全检测数据到缓存中,每步安全检测完成后需要更新缓存数据 PreChargeCheck preChargeCheck = new PreChargeCheck(); preChargeCheck.setElectronicLockLock(false); preChargeCheck.setInsulationTesting(false); preChargeCheck.setSecureConnectionDetection(false); + preChargeCheck.setStartupSuccess(1); String key = "AQJC_" + chargingOrder.getChargingGunId(); redisService.setCacheObject(key, preChargeCheck); - //开始检测充电桩状,将检查状态写入缓存。检测完成后开始开启充电 - //充电结束后需要计算退款剩余金额 - // todo 需要完善 + //根据当前充值的金额和计费模板算出充电的金额 + BigDecimal rechargeAmount = chargingOrder.getRechargeAmount(); + //计算充电金额,会员需要将折扣金额加入到充电总金额中 + TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData(); + AccountingStrategyDetailOrder strategyDetail = accountingStrategyDetailOrderClient.getNowAccountingStrategyDetailOrder(chargingOrder.getId()).getData(); + //总单价 + BigDecimal totalUnitPrice = strategyDetail.getServiceCharge().add(strategyDetail.getElectrovalence()); + //计算能充电的度数 + BigDecimal degrees = rechargeAmount.divide(totalUnitPrice); + //计算电费金额和服务费 + BigDecimal serviceCharge = strategyDetail.getServiceCharge().multiply(degrees); + BigDecimal electrovalence = strategyDetail.getElectrovalence().multiply(degrees); + + //再处理会员折扣 + BigDecimal discount = BigDecimal.ZERO; + TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData(); + if(null != appUser.getVipId()){ + GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail(); + getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId()); + getAppUserVipDetail.setVipId(appUser.getVipId()); + TAppUserVipDetail data = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData(); + if(data.getChargeNum() > 0){ + discount = serviceCharge.multiply(data.getDiscount().divide(new BigDecimal(10))); + data.setChargeNum(data.getChargeNum() - 1); + appUserVipDetailClient.updateAppUserVipDetail(data); + } + } + electrovalence = electrovalence.add(discount); + chargingOrder.setChargeAmount(electrovalence); + this.updateById(chargingOrder); + + + TChargingPile chargingPile = chargingPileClient.getChargingPileById(chargingGun.getChargingPileId()).getData(); + //调用远程启动充电消息 + PlatformStartCharging platformStartCharging = new PlatformStartCharging(); + platformStartCharging.setTransaction_serial_number(chargingOrder.getCode()); + platformStartCharging.setCharging_pile_code(chargingPile.getCode()); + platformStartCharging.setCharging_gun_code(chargingGun.getCode()); + //使用订单id作为逻辑卡号 + platformStartCharging.setCard_number(chargingOrder.getId().toString()); + platformStartCharging.setAccount_balance(electrovalence); + sendMessageClient.platformStartCharging(platformStartCharging); + //异步线程检测远程启动的应答结果。如果失败,则需要全额退款 + String code = chargingOrder.getCode(); + //执行5分钟的定时任务检测 + ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + scheduler.scheduleAtFixedRate(()->{ + List<PlatformStartChargingReply> data = platformStartChargingReplyClient.getPlatformStartChargingReply(code).getData(); + if(data.size() != 0){ + PlatformStartChargingReply platformStartChargingReply = data.get(1); + Integer startup_result = platformStartChargingReply.getStartup_result(); + Integer failure_cause = platformStartChargingReply.getFailure_cause(); + Integer counter = counter_map.get(code); + PreChargeCheck preChargeCheck1 = redisService.getCacheObject(key); + //状态为5的时候,硬件会间隔60秒后再次检测,依然未插枪,则不启动充电 + //因这里是间隔5秒执行检测,所以累计次数在30次以上 + if(failure_cause == 5 && null == counter || counter < 35){ + counter++; + counter_map.put(code, counter); + //启动失败 + preChargeCheck1.setStartupSuccess(3); + preChargeCheck1.setFailureCause(failure_cause); + redisService.setCacheObject(key, preChargeCheck1); + return; + } + //清除计时器中的无效数据 + counter_map.remove(code); + //开始处理退款 + TChargingOrder order = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, code)); + if(0 == startup_result){ + //启动失败 + preChargeCheck1.setStartupSuccess(3); + preChargeCheck1.setFailureCause(failure_cause); + //启动失败后取消订单,退款操作 + refund(code); + order.setStatus(-1); + order.setEndMode(0); + }else{ + preChargeCheck1.setStartupSuccess(2); + order.setStatus(3); + order.setStartTime(LocalDateTime.now()); + } + this.updateById(order); + redisService.setCacheObject(key, preChargeCheck1); + //提前结束定时任务 + scheduler.shutdown(); + } + }, 5, 300, TimeUnit.SECONDS); return AjaxResult.success(); } + /** + * 启动失败后的退款,取消订单 + * @param code + */ + public void refund(String code){ + TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, code)); + if(chargingOrder.getStatus() == 2){ + Integer rechargePaymentType = chargingOrder.getRechargePaymentType(); + BigDecimal rechargeAmount = chargingOrder.getRechargeAmount(); + //构建退款明细 + TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund(); + chargingOrderRefund.setChargingOrderId(chargingOrder.getId()); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); + chargingOrderRefund.setRefundCode("CDF" + sdf.format(new Date()) + (Math.random() * 1000)); + chargingOrderRefund.setRefundAmount(rechargeAmount); + chargingOrderRefund.setRefundStatus(1); + chargingOrderRefund.setPayType(rechargePaymentType); + chargingOrderRefund.setRefundStatus(1); + chargingOrderRefund.setCode(code); + chargingOrderRefund.setRefundTitle("充电失败"); + chargingOrderRefund.setRefundContent("充电失败"); + chargingOrderRefund.setRefundReason("充电失败"); + chargingOrderRefund.setRefundRemark("全额退款"); + chargingOrderRefund.setRefundTotalAmount(rechargeAmount); + chargingOrderRefund.setPayAmount(rechargeAmount); + if(1 == rechargePaymentType){ + WxPaymentRefundModel model = new WxPaymentRefundModel(); + model.setOut_trade_no(chargingOrder.getCode()); + model.setOut_refund_no(chargingOrderRefund.getRefundCode()); + model.setReason("充电失败,取消充电订单"); + model.setNotify_url("http://127.0.0.1:9000/order/t-charging-order/chargingOrderStartupFailureWxRefund"); + WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount(); + amount.setRefund(rechargeAmount.multiply(new BigDecimal(100)).intValue()); + amount.setTotal(rechargeAmount.multiply(new BigDecimal(100)).intValue()); + amount.setCurrency("CNY"); + model.setAmount(amount); + R<String> orderR = wxPaymentClient.refundOrderR(model); + if(200 == orderR.getCode()){ + chargingOrderRefundService.save(chargingOrderRefund); + } + } + if(2 == rechargePaymentType){ + RefundReq dto = new RefundReq(); + dto.setOutTradeNo(chargingOrder.getCode()); + dto.setOutRequestNo(chargingOrderRefund.getCode()); + dto.setRefundAmount(rechargeAmount.toString()); + dto.setRefundReason("充电失败,取消充电订单"); + RefundResp resp = aliPaymentClient.refund(dto).getData(); + if(null != resp){ + SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-DDTHH:mm:ss+TIMEZONE"); + AjaxResult success = chargingOrderStartupFailureWxRefund(resp.getOutTradeNo(), resp.getTradeNo(), "SUCCESS", sdf1.format(new Date())); + if(success.isSuccess()){ + chargingOrderRefundService.save(chargingOrderRefund); + } + } + } + + } + } + + + /** + * 启动失败后微信退款的回调处理 + * @param out_refund_no + * @param refund_id + * @param tradeState + * @param success_time + * @return + */ + public AjaxResult chargingOrderStartupFailureWxRefund(String out_refund_no, String refund_id, String tradeState, String success_time){ + if("SUCCESS".equals(tradeState)){ + TChargingOrderRefund one = chargingOrderRefundService.getOne(new LambdaQueryWrapper<TChargingOrderRefund>().eq(TChargingOrderRefund::getRefundCode, out_refund_no)); + one.setRefundSerialNumber(refund_id); + one.setRefundStatus(2); + one.setRefundTime(LocalDateTime.parse(success_time, DateTimeFormatter.ofPattern("yyyy-MM-DDTHH:mm:ss+TIMEZONE"))); + chargingOrderRefundService.updateById(one); + } + return AjaxResult.success(); + } + + + + /** * 获取充电中的详情 * @param id @@ -391,7 +702,6 @@ if(null == one){ return null; } - // todo 需要完善充电实时数据 ChargingDetails chargingDetails = new ChargingDetails(); chargingDetails.setId(one.getId().toString()); TChargingGun chargingGun = chargingGunClient.getChargingGunById(id).getData(); @@ -400,6 +710,27 @@ chargingDetails.setName(site.getName() + "-" + chargingPile.getName()); chargingDetails.setCode(one.getCode()); chargingDetails.setStatus(one.getStatus()); + chargingDetails.setChargingCost(one.getResidualAmount()); + UploadRealTimeMonitoringData data = uploadRealTimeMonitoringDataClient.chargingOrderInfo(one.getCode()).getData(); + if(null != data){ + chargingDetails.setChargeCurrent(data.getOutput_current()); + chargingDetails.setChargeVoltage(data.getOutput_voltage()); + BigDecimal power = data.getOutput_current().multiply(data.getOutput_voltage()).divide(new BigDecimal(1000)); + chargingDetails.setChargePower(power); + chargingDetails.setCompletionRatio(data.getSoc()); + chargingDetails.setRemainingChargeTime(data.getTime_remaining()); + chargingDetails.setChargedDegrees(data.getCharging_degree()); + chargingDetails.setChargedTime(data.getCumulative_charging_time()); + } + ChargingHandshake chargingHandshake = chargingHandshakeClient.getDataByOrderCode(one.getCode()).getData(); + if(null != chargingHandshake && null != data && null != one.getAppUserCarId()){ + BigDecimal bms_battery_capacity = chargingHandshake.getBms_battery_capacity(); + TAppUserCar appUserCar = appUserCarClient.getCarByIds(Arrays.asList(one.getAppUserCarId())).getData().get(0); + // 续航 = 电池容量 / 续航里程 * soc + BigDecimal divide = bms_battery_capacity.divide(new BigDecimal(appUserCar.getEndurance())); + BigDecimal multiply = new BigDecimal(data.getSoc() / 100).multiply(divide); + chargingDetails.setEndurance(multiply); + } return chargingDetails; } @@ -410,6 +741,7 @@ * @return */ @Override + @GlobalTransactional(rollbackFor = Exception.class) public AjaxResult stopCharging(String id) { TChargingOrder chargingOrder = this.getById(id); Integer status = chargingOrder.getStatus(); @@ -419,10 +751,233 @@ chargingOrder.setStatus(4); chargingOrder.setEndMode(1); this.updateById(chargingOrder); - //调用硬件停止充电,停止成功后开始计算费用退款 - // todo 待完善 + + //异步线程处理停机 + ExecutorService cachedThreadPool = Executors.newFixedThreadPool(1); + cachedThreadPool.execute(()->{ + //调用硬件停止充电,停止成功后开始计算费用退款 + TChargingPile chargingPile = chargingPileClient.getChargingPileById(chargingOrder.getChargingPileId()).getData(); + TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData(); + PlatformStopCharging platformStopCharging = new PlatformStopCharging(); + platformStopCharging.setCharging_pile_code(chargingPile.getCode()); + platformStopCharging.setCharging_gun_code(chargingGun.getCode()); + sendMessageClient.platformStopCharging(platformStopCharging); + //开始查询停机应答,成功后开始计费费用 + for (int i = 0; i < 60; i++) { + GetPlatformStopChargingReply query = new GetPlatformStopChargingReply(); + query.setCharging_gun_code(chargingGun.getCode()); + query.setCharging_pile_code(chargingPile.getCode()); + PlatformStopChargingReply reply = platformStopChargingReplyClient.getPlatformStopChargingReply(query).getData(); + if(null == reply){ + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + continue; + } + + if(0 == reply.getStop_result()){ + String failure_cause = ""; + switch (reply.getFailure_cause()){ + case 0: + failure_cause = "无"; + break; + case 1: + failure_cause = "设备编号不匹配"; + break; + case 2: + failure_cause = "枪未处于充电状态"; + break; + case 3: + failure_cause = "其他"; + break; + } + log.error("停机失败:订单号:{},失败原因:{}", chargingOrder.getCode(), failure_cause); + throw new RuntimeException(failure_cause); + } + + //计算费用,处理退款 + endCharge(chargingOrder); + break; + } + }); + + + //处理推荐奖励(被推荐首单奖励) + TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData(); + long count = this.count(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, chargingOrder.getAppUserId()) + .eq(TChargingOrder::getStatus, 5).isNull(TChargingOrder::getEndMode).eq(TChargingOrder::getDelFlag, 0)); + if(null != appUser.getInviteUserId() && 1 == count){ + TIntegralRule integralRule = integralRuleClient.getSet().getData(); + String inviteUsersToEarnPoints = integralRule.getInviteUsersToEarnPoints(); + JSONObject jsonObject = JSON.parseObject(inviteUsersToEarnPoints); + Integer num1 = jsonObject.getInteger("num1"); + GetInviteUser query = new GetInviteUser(); + query.setAppUserId(appUser.getInviteUserId()); + query.setBeInvitedAppUserId(chargingOrder.getAppUserId()); + TInviteUser inviteUser = inviteUserClient.getInviteUser(query).getData(); + if(null == inviteUser){ + inviteUser = new TInviteUser(); + inviteUser.setAppUserId(appUser.getInviteUserId()); + inviteUser.setBeInvitedAppUserId(chargingOrder.getAppUserId()); + inviteUser.setAward(num1); + inviteUser.setCreateTime(LocalDateTime.now()); + inviteUserClient.saveInviteUser(inviteUser); + }else{ + inviteUser.setAward(num1); + inviteUserClient.updateInviteUser(inviteUser); + } + TAppUser appUser1 = appUserClient.getUserById(appUser.getInviteUserId()).getData(); + TAppUserIntegralChange appUserIntegralChange = new TAppUserIntegralChange(); + String code = Math.random() * 1000 + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")); + appUserIntegralChange.setCode(code); + appUserIntegralChange.setAppUserId(appUser.getInviteUserId()); + appUserIntegralChange.setChangeType(5); + appUserIntegralChange.setHistoricalIntegral(appUser1.getPoints()); + appUserIntegralChange.setCurrentIntegral(appUser1.getPoints() + num1); + appUserIntegralChange.setCreateTime(LocalDateTime.now()); + appUserIntegralChangeClient.addAppUserIntegralChange(appUserIntegralChange); + + appUser1.setPoints(appUser1.getPoints() + num1); + appUserClient.updateAppUser(appUser1); + } + return AjaxResult.success(); } + + + /** + * 手动结束后的费用计算和退款逻辑 + */ + @GlobalTransactional(rollbackFor = Exception.class) + public void endCharge(TChargingOrder chargingOrder){ + //如果使用优惠券需要判断优惠券是否满足使用条件 + //根据实际的充电金额计算退款金额 退回费用=(原金额/总金额)*(总金额-实际充电金额) + //退款金额=优惠券金额+剩余充电金额 + List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.list(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>().eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId())); + BigDecimal total = BigDecimal.ZERO; + for (TChargingOrderAccountingStrategy chargingOrderAccountingStrategy : list) { + BigDecimal periodElectricPrice = chargingOrderAccountingStrategy.getPeriodElectricPrice(); + BigDecimal periodServicePrice = chargingOrderAccountingStrategy.getPeriodOriginalServicePrice(); + total = total.add(periodElectricPrice).add(periodServicePrice); + } + BigDecimal rechargeAmount = chargingOrder.getRechargeAmount(); + BigDecimal vipDiscountAmount = chargingOrder.getVipDiscountAmount(); + BigDecimal decimal = rechargeAmount.add(vipDiscountAmount); + //退款金额(已经计算了折扣优惠部分) + BigDecimal refundAmount = rechargeAmount.divide(decimal, new MathContext(4, RoundingMode.HALF_EVEN)).multiply(decimal.subtract(total)); + BigDecimal payAmount = BigDecimal.valueOf(total.doubleValue()); + BigDecimal orderAmount = BigDecimal.valueOf(total.doubleValue()); + if(null != chargingOrder.getVipDiscount()){ + orderAmount = orderAmount.divide(chargingOrder.getVipDiscount().divide(new BigDecimal(10))); + chargingOrder.setOrderAmount(total); + } + + if(chargingOrder.getEndMode() == 2){ + chargingOrder.setEndMode(refundAmount.compareTo(BigDecimal.ZERO) > 0 ? 2 : 3); + } + chargingOrder.setStatus(5); + chargingOrder.setPaymentAmount(payAmount); + this.updateById(chargingOrder); + + //计算优惠券 + if(null != chargingOrder.getAppCouponId()){ + //判断实际充电金额是否满足优惠券使用条件,如果不满足则不适用优惠券。 + TAppCoupon appCoupon = appCouponClient.getAppCouponById(chargingOrder.getAppCouponId()).getData(); + String couponJson = appCoupon.getCouponJson(); + TCoupon tCoupon = JSON.parseObject(couponJson, TCoupon.class); + Integer preferentialMode = tCoupon.getPreferentialMode(); + if(1 == preferentialMode){ + //满减 + if(total.compareTo(tCoupon.getMeetTheConditions()) >= 0){ + refundAmount = refundAmount.add(tCoupon.getDiscountAmount()); + chargingOrder.setCouponDiscountAmount(tCoupon.getDiscountAmount()); + payAmount = payAmount.subtract(tCoupon.getDiscountAmount()); + }else{ + chargingOrder.setAppCouponId(null); + chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO); + appCouponClient.refund(chargingOrder.getAppCouponId().toString()); + } + } + if(2 == preferentialMode){ + //抵扣 + if(total.compareTo(tCoupon.getMeetTheConditions()) >= 0){ + //折扣金额 + BigDecimal divide = total.multiply(new BigDecimal(10).subtract(tCoupon.getDiscount())).divide(new BigDecimal(10)); + divide = divide.compareTo(tCoupon.getMaximumDiscountAmount()) > 0 ? tCoupon.getMaximumDiscountAmount() : divide; + refundAmount = refundAmount.add(divide); + chargingOrder.setCouponDiscountAmount(divide); + payAmount = payAmount.subtract(divide); + }else{ + chargingOrder.setAppCouponId(null); + chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO); + appCouponClient.refund(chargingOrder.getAppCouponId().toString()); + } + } + } + + if(null != chargingOrder.getVipDiscount()){ + BigDecimal subtract = orderAmount.subtract(total); + chargingOrder.setVipDiscountAmount(subtract); + payAmount = payAmount.subtract(subtract); + } + //开始构建退款费用 + if(refundAmount.compareTo(BigDecimal.ZERO) > 0){ + Integer rechargePaymentType = chargingOrder.getRechargePaymentType(); + //构建退款明细 + TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund(); + chargingOrderRefund.setChargingOrderId(chargingOrder.getId()); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); + chargingOrderRefund.setRefundCode("CDF" + sdf.format(new Date()) + (Math.random() * 1000)); + chargingOrderRefund.setRefundAmount(refundAmount); + chargingOrderRefund.setRefundStatus(1); + chargingOrderRefund.setPayType(rechargePaymentType); + chargingOrderRefund.setRefundStatus(1); + chargingOrderRefund.setCode(chargingOrder.getCode()); + chargingOrderRefund.setRefundTitle("充电完成退款"); + chargingOrderRefund.setRefundContent("充电完成退款"); + chargingOrderRefund.setRefundReason("充电完成退款"); + chargingOrderRefund.setRefundRemark("充电完成退款"); + chargingOrderRefund.setRefundTotalAmount(refundAmount); + chargingOrderRefund.setPayAmount(rechargeAmount); + if(1 == rechargePaymentType){ + WxPaymentRefundModel model = new WxPaymentRefundModel(); + model.setOut_trade_no(chargingOrder.getCode()); + model.setOut_refund_no(chargingOrderRefund.getRefundCode()); + model.setReason("充电完成退款"); + model.setNotify_url("http://127.0.0.1:9000/order/t-charging-order/chargingOrderStartupFailureWxRefund"); + 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<String> orderR = wxPaymentClient.refundOrderR(model); + if(200 == orderR.getCode()){ + chargingOrderRefundService.save(chargingOrderRefund); + } + } + if(2 == rechargePaymentType){ + RefundReq dto = new RefundReq(); + dto.setOutTradeNo(chargingOrder.getCode()); + dto.setOutRequestNo(chargingOrderRefund.getCode()); + dto.setRefundAmount(rechargeAmount.toString()); + dto.setRefundReason("充电完成退款"); + RefundResp resp = aliPaymentClient.refund(dto).getData(); + if(null != resp){ + SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-DDTHH:mm:ss+TIMEZONE"); + AjaxResult success = chargingOrderStartupFailureWxRefund(resp.getOutTradeNo(), resp.getTradeNo(), "SUCCESS", sdf1.format(new Date())); + if(success.isSuccess()){ + chargingOrderRefundService.save(chargingOrderRefund); + } + } + } + + } + + } + + @Override @@ -445,14 +1000,16 @@ endTime1 = split[0]; endTime2 = split[1]; } + PageInfo<ChargingOrderVO> pageInfo = new PageInfo<>(dto.getPageCurr(),dto.getPageSize()); + if (StringUtils.hasLength(dto.getPhone())){ List<Long> data = appUserClient.getUserIdsByPhone(dto.getPhone()).getData(); if (data.isEmpty()){ - data.add(0L); + tCharingOrderVO.setList(pageInfo); + return tCharingOrderVO; } dto.setUserIds(data); } - PageInfo<ChargingOrderVO> pageInfo = new PageInfo<>(dto.getPageCurr(),dto.getPageSize()); List<ChargingOrderVO> list = this.baseMapper.chargingOrder(pageInfo,dto,startTime1,startTime2,endTime1,endTime2); BigDecimal total = new BigDecimal("0"); long time = 0L; @@ -460,7 +1017,15 @@ BigDecimal electronicMoney = new BigDecimal("0"); BigDecimal serviceMoney = new BigDecimal("0"); for (ChargingOrderVO chargingOrderVO : list) { - total = total.add(chargingOrderVO.getChargingCapacity()); + TChargingGun data3 = chargingGunClient.getChargingGunById(chargingOrderVO.getChargingGunId()).getData(); + TChargingPile data2 = chargingPileClient.getChargingPileById(chargingOrderVO.getChargingPileId()).getData(); + if (data2!=null && data3!=null){ + chargingOrderVO.setTerminalName(data2.getName()+"-"+data3.getName()); + + } + if (chargingOrderVO.getChargingCapacity()!=null){ + total = total.add(chargingOrderVO.getChargingCapacity()); + } // 充电订单 明细记录 List<TChargingOrderAccountingStrategy> chargingOrderId = chargingOrderAccountingStrategyService.list(new QueryWrapper<TChargingOrderAccountingStrategy>() .eq("charging_order_id", chargingOrderVO.getId())); @@ -468,17 +1033,15 @@ BigDecimal electronicMoney1 = new BigDecimal("0"); // 单个订单累计服务费 BigDecimal serviceMoney1 = new BigDecimal("0"); - LocalDateTime startTime = chargingOrderVO.getStartTime(); - LocalDateTime endTime = chargingOrderVO.getEndTime(); - // 计算时间差 秒 充电时长 - long between = ChronoUnit.SECONDS.between(startTime, endTime); - chargingOrderVO.setChargingSecond(between); - time += between; + UploadRealTimeMonitoringData data5 = uploadRealTimeMonitoringDataClient.chargingOrderInfo(chargingOrderVO.getCode()).getData(); + chargingOrderVO.setChargingSecond(data5.getTime_remaining()*60L); // 总收入 - if (chargingOrderVO.getRefundStatus() == 2){ + if (chargingOrderVO.getRefundStatus() !=null && chargingOrderVO.getRefundStatus() == 2){ income = income.add(chargingOrderVO.getPaymentAmount().subtract(chargingOrderVO.getRefundAmount())); }else{ - income = income.add(chargingOrderVO.getPaymentAmount()); + if (chargingOrderVO.getPaymentAmount()!=null){ + income = income.add(chargingOrderVO.getPaymentAmount()); + } } for (TChargingOrderAccountingStrategy tChargingOrderAccountingStrategy : chargingOrderId) { // 累计电费 @@ -500,11 +1063,14 @@ // 车牌号 chargingOrderVO.setPhone(data.getPhone()); List<Long> longs = new ArrayList<>(); - longs.add(chargingOrderVO.getAppUserCarId()); - List<TAppUserCar> data1 = appUserCarClient.getCarByIds(longs).getData(); - if (!data1.isEmpty()){ - chargingOrderVO.setLicensePlate(data1.get(0).getLicensePlate()); + if (chargingOrderVO.getAppUserCarId()!=null){ + longs.add(chargingOrderVO.getAppUserCarId()); + List<TAppUserCar> data1 = appUserCarClient.getCarByIds(longs).getData(); + if (!data1.isEmpty()){ + chargingOrderVO.setLicensePlate(data1.get(0).getLicensePlate()); + } } + } } tCharingOrderVO.setTotal(total); @@ -516,4 +1082,552 @@ tCharingOrderVO.setList(pageInfo); return tCharingOrderVO; } + + @Override + public R<PageInfo<PayOrderDto>> payOrderQuery(PayOrderQueryDto payOrderQueryDto) { + PageInfo<PayOrderDto> pageInfo = new PageInfo<>(payOrderQueryDto.getPageCurr(),payOrderQueryDto.getPageSize()); + List<PayOrderDto> list = this.baseMapper.payOrderQuery(pageInfo,payOrderQueryDto); + pageInfo.setRecords(list); + return R.ok(pageInfo); + } + + @Override + public R<PageInfo<TChargingOrderRefund>> getRefundList(ChargingRefundDto chargingRefundDto) { + PageInfo<TChargingOrderRefund> pageInfo = new PageInfo<>(chargingRefundDto.getPageCurr(),chargingRefundDto.getPageSize()); + List<TChargingOrderRefund> list = this.baseMapper.getRefundList(pageInfo,chargingRefundDto); + pageInfo.setRecords(list); + + return R.ok(pageInfo); + } + + @Override + public List<ChargingOrderGroup> chargingOrderGroup(ChargingPercentProvinceDto chargingPercentProvinceDto) { + + return this.baseMapper.chargingOrderGroup(chargingPercentProvinceDto); + } + + @Override + public List<SixChargingDto> charge(LocalDate sixBefore, List<Integer> siteIds) { + return this.baseMapper.charge(sixBefore,siteIds); + } + + @Override + public List<SixCircleDto> circle(List<Integer> siteIds,LocalDate sixBefore) { + return this.baseMapper.circle(siteIds,sixBefore); + } + + @Override + public Map<String, BigDecimal> countAll(LocalDate sixBefore) { + return this.baseMapper.countAll(sixBefore); + } + + @Override + public List<Map<String, BigDecimal>> getSumByType(List<Long> chargingOrderIds) { + return this.baseMapper.getSumByType(chargingOrderIds); + } + + @Override + public List<Map<String, BigDecimal>> getDateData(List<Long> chargingOrderIds) { + return this.baseMapper.getDateData(chargingOrderIds); + } + + @Override + public List<Map<String, BigDecimal>> getWeekData(List<Long> chargingOrderIds) { + return this.baseMapper.getWeekData(chargingOrderIds); + } + + @Override + public List<Map<String, BigDecimal>> getMonthData(List<Long> chargingOrderIds) { + return this.baseMapper.getMonthData(chargingOrderIds); + } + + @Override + public List<Map<String, BigDecimal>> getYearData(List<Long> chargingOrderIds) { + return this.baseMapper.getYearData(chargingOrderIds); + } + @Resource + private SysUserClient sysUserClient; + @Resource + private UserSiteClient userSiteClient; + + @Resource + private RoleSiteClient roleSiteClient; + @Override + public ChargingOrderTimeVO chargingList(ChargingListQuery dto) { + String startTime1 = null; + String startTime2 = null; + String endTime1 = null; + String endTime2 = null; + + if (StringUtils.hasLength(dto.getStartTime())){ + String[] split = dto.getStartTime().split(" - "); + startTime1 = split[0]; + startTime2 = split[1]; + } + ChargingOrderTimeVO chargingOrderTimeVO = new ChargingOrderTimeVO(); + + PageInfo<ChargingOrderListVO> pageInfo = new PageInfo<>(dto.getPageCurr(),dto.getPageSize()); + List<ChargingOrderListVO> list = this.baseMapper.chargingList(pageInfo,dto,startTime1,startTime2,endTime1,endTime2); + for (ChargingOrderListVO chargingOrderListVO : list) { + chargingOrderListVO.setUid(chargingOrderListVO.getId()+""); + List<Integer> integers = new ArrayList<>(); + integers.add(chargingOrderListVO.getSiteId()); + List<Site> data = siteClient.getSiteByIds(integers).getData(); + if (!data.isEmpty()) { + chargingOrderListVO.setSiteName(data.get(0).getName()); + } + TChargingGun data1 = chargingGunClient.getChargingGunById(chargingOrderListVO.getChargingGunId()).getData(); + TChargingPile data2 = chargingPileClient.getChargingPileById(chargingOrderListVO.getChargingPileId()).getData(); + if (data2 != null && data1 != null) { + chargingOrderListVO.setTerminalName(data2.getName() + "-" + data1.getName()); + } + // 获取充电时间 + UploadRealTimeMonitoringData data5 = uploadRealTimeMonitoringDataClient.chargingOrderInfo(chargingOrderListVO.getCode()).getData(); + if (data5!=null){ + if (data5.getTime_remaining()!=null){ + chargingOrderListVO.setChargingSecond(data5.getTime_remaining()*60L); + + } + } + // 获取开始SOC 结束soc + List<UploadRealTimeMonitoringData> data6 = uploadRealTimeMonitoringDataClient.getDataByOrderCode(chargingOrderListVO.getCode()).getData(); + if (!data6.isEmpty()){ + // 第一条数据soc为开始 最后一条数据soc为结束soc + chargingOrderListVO.setStartSoc(data6.get(0).getSoc().toString()); + chargingOrderListVO.setEndSoc(data6.get(data6.size()-1).getSoc().toString()); + } + TAppUser data3 = appUserClient.getUserById(chargingOrderListVO.getAppUserId()).getData(); + List<Long> carId = new ArrayList<>(); + if (chargingOrderListVO.getAppUserCarId() != null) { + carId.add(chargingOrderListVO.getAppUserCarId()); + List<TAppUserCar> data4 = appUserCarClient.getCarByIds(carId).getData(); + if (!data4.isEmpty()) chargingOrderListVO.setLicensePlate(data4.get(0).getLicensePlate()); + } + if (data3 != null) chargingOrderListVO.setPhone(data3.getPhone()); + List<TChargingOrderAccountingStrategy> list2 = chargingOrderAccountingStrategyService.lambdaQuery() + .eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrderListVO.getId()).list(); + // 尖峰平谷充电量 度数 + BigDecimal jian = new BigDecimal("0"); + BigDecimal feng = new BigDecimal("0"); + BigDecimal ping = new BigDecimal("0"); + BigDecimal gu = new BigDecimal("0"); + BigDecimal total = new BigDecimal("0"); + for (TChargingOrderAccountingStrategy temp : list2) { + switch (temp.getType()) { + case 1: + jian = jian.add(temp.getChargingCapacity()); + break; + case 2: + feng = feng.add(temp.getChargingCapacity()); + break; + case 3: + ping = ping.add(temp.getChargingCapacity()); + break; + case 4: + gu = gu.add(temp.getChargingCapacity()); + break; + } + } + total = total.add(jian).add(feng).add(ping).add(gu); + chargingOrderListVO.setElectronicProportion( + jian.divide(total,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%(尖)/" + +feng.divide(total,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%(峰)/" + +ping.divide(total,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%(平)/" + +gu.divide(total,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%(谷)"); + } + // 不分页 + List<ChargingOrderListVO> list1 = this.baseMapper.chargingList1(dto,startTime1,startTime2,endTime1,endTime2); + chargingOrderTimeVO.setOrderCount(list1.size()); + // 计算充电总度数 + BigDecimal electronic = new BigDecimal("0"); + // 支付金额 + BigDecimal paymentAmount = new BigDecimal("0"); + // 电费 + BigDecimal electrovalence = new BigDecimal("0"); + // 服务费 + BigDecimal serviceCharge = new BigDecimal("0"); + // 尖峰平谷充电到账 + BigDecimal jianElectronic = new BigDecimal("0"); + BigDecimal fengElectronic = new BigDecimal("0"); + BigDecimal pingElectronic = new BigDecimal("0"); + BigDecimal guElectronic = new BigDecimal("0"); + // 尖峰平谷服务费 + BigDecimal jianService = new BigDecimal("0"); + BigDecimal fengService = new BigDecimal("0"); + BigDecimal pingService = new BigDecimal("0"); + BigDecimal guService = new BigDecimal("0"); + // 尖峰平谷充电量 度数 + BigDecimal jian = new BigDecimal("0"); + BigDecimal feng = new BigDecimal("0"); + BigDecimal ping = new BigDecimal("0"); + BigDecimal gu = new BigDecimal("0"); + for (ChargingOrderListVO chargingOrderListVO : list1) { + electronic = electronic.add(chargingOrderListVO.getChargingCapacity()); + paymentAmount = paymentAmount.add(chargingOrderListVO.getPaymentAmount()); + electrovalence = electrovalence.add(chargingOrderListVO.getElectrovalence()); + serviceCharge = serviceCharge.add(chargingOrderListVO.getServiceCharge()); + List<TChargingOrderAccountingStrategy> list2 = chargingOrderAccountingStrategyService.lambdaQuery() + .eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrderListVO.getId()).list(); + for (TChargingOrderAccountingStrategy temp : list2) { + switch (temp.getType()){ + case 1: + jian = jian.add(temp.getChargingCapacity()); + jianElectronic = jianElectronic.add(temp.getChargingCapacity()); + jianService = jianService.add(temp.getChargingCapacity()); + break; + case 2: + feng = feng.add(temp.getChargingCapacity()); + fengElectronic = fengElectronic.add(temp.getChargingCapacity()); + fengService = fengService.add(temp.getChargingCapacity()); + break; + case 3: + ping = ping.add(temp.getChargingCapacity()); + pingElectronic = pingElectronic.add(temp.getChargingCapacity()); + pingService = pingService.add(temp.getChargingCapacity()); + break; + case 4: + gu = gu.add(temp.getChargingCapacity()); + guElectronic = guElectronic.add(temp.getChargingCapacity()); + guService = guService.add(temp.getChargingCapacity()); + break; + } + } + } + + chargingOrderTimeVO.setChargingCapacity(electronic); + chargingOrderTimeVO.setPaymentAmount(paymentAmount); + chargingOrderTimeVO.setElectrovalence(electrovalence); + chargingOrderTimeVO.setServiceCharge(serviceCharge); + // 计算尖峰平谷充电量占比 + BigDecimal add = jianElectronic.add(fengElectronic).add(pingElectronic).add(guElectronic); + // 计算尖峰平谷服务费占比 + BigDecimal add1 = jianService.add(fengService).add(pingService).add(guService); + // 计算尖峰平谷充电到账占比 + BigDecimal add2 = jian.add(feng).add(ping).add(gu); + chargingOrderTimeVO.setCapacityProportion(jianElectronic+"度/"+fengElectronic+"度/"+pingElectronic+"度/"+guElectronic+"度-" + +jianElectronic.divide(add,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%/" + +fengElectronic.divide(add,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%/" + +pingElectronic.divide(add,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%/" + +guElectronic.divide(add,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%"); + chargingOrderTimeVO.setServiceProportion(jianService+"元/"+fengService+"元/"+pingService+"元/"+guService+"元-" + +jianService.divide(add1,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%/" + +fengService.divide(add1,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%/" + +pingService.divide(add1,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%/" + +guService.divide(add1,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%"); + chargingOrderTimeVO.setElectronicProportion(jian+"元/"+feng+"元/"+ping+"元/"+gu+"元-" + +jian.divide(add2,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%/" + +feng.divide(add2,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%/" + +ping.divide(add2,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%/" + +gu.divide(add2,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"))+"%"); + chargingOrderTimeVO.setList(pageInfo); + return chargingOrderTimeVO; + } + +// @Override +// public R payRefund(PayOrderRefundDto payOrderQueryDto) { +// return null; +// } + + @Override + public ChargingOrderListInfoVO chargingInfo(String uid) { + TChargingOrder chargingOrder= this.getById(uid); + + ChargingOrderListInfoVO chargingOrderListInfoVO = new ChargingOrderListInfoVO(); + chargingOrderListInfoVO.setCode(chargingOrder.getCode()); + List<Site> data = siteClient.getSiteByIds(Arrays.asList(chargingOrder.getSiteId())).getData(); + if (!data.isEmpty()){ + chargingOrderListInfoVO.setSiteName(data.get(0).getName()); + chargingOrderListInfoVO.setSiteAddress(data.get(0).getAddress()); + } + TChargingGun data1 = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData(); + TChargingPile data2 = chargingPileClient.getChargingPileById(data1.getChargingPileId()).getData(); + + if (data1!=null){ + chargingOrderListInfoVO.setGunCode(data1.getCode()); + chargingOrderListInfoVO.setTerminalName(data2.getName()+data1.getName()); + } + chargingOrderListInfoVO.setEndMode(chargingOrder.getEndMode()); + // todo 周一完善 + // 获取开始SOC 结束soc + List<UploadRealTimeMonitoringData> data6 = uploadRealTimeMonitoringDataClient.getDataByOrderCode(chargingOrder.getCode()).getData(); + if (!data6.isEmpty()){ + // 第一条数据soc为开始 最后一条数据soc为结束soc + chargingOrderListInfoVO.setStartSoc(data6.get(0).getSoc().toString()); + chargingOrderListInfoVO.setEndSoc(data6.get(data6.size()-1).getSoc().toString()); + chargingOrderListInfoVO.setChargingCapacity(data6.get(data6.size()-1).getCharging_degree()); + chargingOrderListInfoVO.setChargingSecond(data6.get(data6.size()-1).getCumulative_charging_time()*60+""); + + } + if (chargingOrder.getAppUserCarId()!=null){ + List<TAppUserCar> data3 = appUserCarClient.getCarByIds(Collections.singletonList(chargingOrder.getAppUserCarId())).getData(); + if (!data3.isEmpty())chargingOrderListInfoVO.setLicensePlate(data3.get(0).getLicensePlate()); + } + chargingOrderListInfoVO.setStartTime(chargingOrder.getStartTime()); + chargingOrderListInfoVO.setEndTime(chargingOrder.getEndTime()); + chargingOrderListInfoVO.setId(chargingOrder.getId()); + chargingOrderListInfoVO.setUid(chargingOrder.getId().toString()); + chargingOrderListInfoVO.setList(data6); + chargingOrderListInfoVO.setCouponDiscountAmount(chargingOrder.getCouponDiscountAmount()); + chargingOrderListInfoVO.setVipDiscountAmount(chargingOrder.getVipDiscountAmount()); + chargingOrderListInfoVO.setSharingAmount(chargingOrder.getSharingAmount()); + chargingOrderListInfoVO.setCommissionAmount(chargingOrder.getCommissionAmount()); + // 查询费用明细列表 + List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.lambdaQuery() + .eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId()) + .list(); + chargingOrderListInfoVO.setList1(list); + return chargingOrderListInfoVO; + } + + + /** + * 处理充电订单实时监控数据相关的业务逻辑 + * @param query + */ + @Override + public void chargeMonitoring(UploadRealTimeMonitoringDataQuery query) { + if(com.ruoyi.common.core.utils.StringUtils.isNotEmpty(query.getCharging_gun_code())){ + //获取当前的计费策略 + TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, query.getCharging_gun_code())); + AccountingStrategyDetailOrder strategyDetail = accountingStrategyDetailOrderClient.getNowAccountingStrategyDetailOrder(chargingOrder.getId()).getData(); + TChargingOrderAccountingStrategy chargingOrderAccountingStrategy = chargingOrderAccountingStrategyService.getOne(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>() + .eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId()).orderByDesc(TChargingOrderAccountingStrategy::getCreateTime).last(" limit 0, 1")); + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); + if(null == chargingOrderAccountingStrategy){ + chargingOrderAccountingStrategy = new TChargingOrderAccountingStrategy(); + chargingOrderAccountingStrategy.setChargingOrderId(chargingOrder.getId()); + chargingOrderAccountingStrategy.setAccountingStrategyDetailId(strategyDetail.getId()); + chargingOrderAccountingStrategy.setType(strategyDetail.getType()); + chargingOrderAccountingStrategy.setStartTime(sdf.format(chargingOrder.getStartTime())); + chargingOrderAccountingStrategy.setEndTime(sdf.format(new Date())); + chargingOrderAccountingStrategy.setElectrovalence(strategyDetail.getElectrovalence()); + chargingOrderAccountingStrategy.setServiceCharge(strategyDetail.getServiceCharge()); + chargingOrderAccountingStrategy.setCostServiceCharge(strategyDetail.getCostServiceCharge()); + BigDecimal charging_degree = query.getCharging_degree(); + BigDecimal electrovalenc = strategyDetail.getElectrovalence().multiply(charging_degree); + BigDecimal originalServicePrice = strategyDetail.getServiceCharge().multiply(charging_degree); + BigDecimal serviceCharge = originalServicePrice; + //计算优惠金额 + if(null != chargingOrder.getVipDiscount()){ + serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount().divide(new BigDecimal(10))); + } + chargingOrderAccountingStrategy.setChargingCapacity(charging_degree); + chargingOrderAccountingStrategy.setPeriodElectricPrice(electrovalenc); + chargingOrderAccountingStrategy.setPeriodServicePrice(serviceCharge); + chargingOrderAccountingStrategy.setPeriodOriginalServicePrice(originalServicePrice); + chargingOrderAccountingStrategy.setCreateTime(LocalDateTime.now()); + chargingOrderAccountingStrategyService.save(chargingOrderAccountingStrategy); + }else{ + if(chargingOrderAccountingStrategy.getAccountingStrategyDetailId().equals(strategyDetail.getId())){ + BigDecimal periodServicePrice = chargingOrderAccountingStrategy.getPeriodServicePrice(); + BigDecimal periodElectricPrice = chargingOrderAccountingStrategy.getPeriodElectricPrice(); + BigDecimal periodOriginalServicePrice = chargingOrderAccountingStrategy.getPeriodOriginalServicePrice(); + BigDecimal charging_degree = query.getCharging_degree(); + BigDecimal electrovalenc = strategyDetail.getElectrovalence().multiply(charging_degree); + BigDecimal originalServicePrice = strategyDetail.getServiceCharge().multiply(charging_degree); + BigDecimal serviceCharge = originalServicePrice; + //计算优惠金额 + if(null != chargingOrder.getVipDiscount()){ + serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount().divide(new BigDecimal(10))); + } + periodServicePrice = periodServicePrice.add(serviceCharge); + periodOriginalServicePrice = periodOriginalServicePrice.add(originalServicePrice); + periodElectricPrice = periodElectricPrice.add(electrovalenc); + chargingOrderAccountingStrategy.setPeriodServicePrice(periodServicePrice); + chargingOrderAccountingStrategy.setPeriodOriginalServicePrice(periodOriginalServicePrice); + chargingOrderAccountingStrategy.setPeriodElectricPrice(periodElectricPrice); + chargingOrderAccountingStrategy.setEndTime(sdf.format(new Date())); + chargingOrderAccountingStrategyService.updateById(chargingOrderAccountingStrategy); + }else{ + TChargingOrderAccountingStrategy chargingOrderAccountingStrategy1 = new TChargingOrderAccountingStrategy(); + chargingOrderAccountingStrategy1.setChargingOrderId(chargingOrder.getId()); + chargingOrderAccountingStrategy1.setAccountingStrategyDetailId(strategyDetail.getId()); + chargingOrderAccountingStrategy1.setType(strategyDetail.getType()); + chargingOrderAccountingStrategy1.setStartTime(sdf.format(chargingOrderAccountingStrategy.getEndTime())); + chargingOrderAccountingStrategy1.setEndTime(sdf.format(new Date())); + chargingOrderAccountingStrategy1.setElectrovalence(strategyDetail.getElectrovalence()); + chargingOrderAccountingStrategy1.setServiceCharge(strategyDetail.getServiceCharge()); + chargingOrderAccountingStrategy1.setCostServiceCharge(strategyDetail.getCostServiceCharge()); + BigDecimal charging_degree = query.getCharging_degree(); + BigDecimal electrovalenc = strategyDetail.getElectrovalence().multiply(charging_degree); + BigDecimal originalServicePrice = strategyDetail.getServiceCharge().multiply(charging_degree); + BigDecimal serviceCharge = originalServicePrice; + //计算优惠金额 + if(null != chargingOrder.getVipDiscount()){ + serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount().divide(new BigDecimal(10))); + } + chargingOrderAccountingStrategy1.setChargingCapacity(charging_degree); + chargingOrderAccountingStrategy1.setPeriodElectricPrice(electrovalenc); + chargingOrderAccountingStrategy1.setPeriodOriginalServicePrice(originalServicePrice); + chargingOrderAccountingStrategy1.setPeriodServicePrice(serviceCharge); + chargingOrderAccountingStrategy1.setCreateTime(LocalDateTime.now()); + chargingOrderAccountingStrategyService.save(chargingOrderAccountingStrategy1); + } + } + + List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.list(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>() + .eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId())); + BigDecimal t = BigDecimal.ZERO; + for (TChargingOrderAccountingStrategy coas : list) { + t = t.add(coas.getPeriodServicePrice()).add(coas.getPeriodElectricPrice()); + } + BigDecimal residualAmount = chargingOrder.getRechargeAmount().subtract(t).setScale(2, RoundingMode.HALF_EVEN); + chargingOrder.setResidualAmount(residualAmount); + BigDecimal divide = query.getOutput_current().multiply(query.getOutput_voltage()).divide(new BigDecimal(1000)); + chargingOrder.setChargingPower(divide); + this.updateById(chargingOrder); + } + } + + + /** + * 自动结束充电后的处理逻辑 + * @param orderCode + */ + @Override + @GlobalTransactional(rollbackFor = Exception.class) + public void endCharge(String orderCode, Integer endMode) { + TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, orderCode)); + Integer status = chargingOrder.getStatus(); + if(status == 4 || status == 5){ + return; + } + chargingOrder.setStatus(5); + chargingOrder.setEndMode(endMode); + this.updateById(chargingOrder); + + //计算费用,处理退款 + endCharge(chargingOrder); + + //处理推荐奖励(被推荐首单奖励) + TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData(); + long count = this.count(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, chargingOrder.getAppUserId()) + .eq(TChargingOrder::getStatus, 5).isNull(TChargingOrder::getEndMode).eq(TChargingOrder::getDelFlag, 0)); + if(null != appUser.getInviteUserId() && 1 == count){ + TIntegralRule integralRule = integralRuleClient.getSet().getData(); + String inviteUsersToEarnPoints = integralRule.getInviteUsersToEarnPoints(); + JSONObject jsonObject = JSON.parseObject(inviteUsersToEarnPoints); + Integer num1 = jsonObject.getInteger("num1"); + GetInviteUser query = new GetInviteUser(); + query.setAppUserId(appUser.getInviteUserId()); + query.setBeInvitedAppUserId(chargingOrder.getAppUserId()); + TInviteUser inviteUser = inviteUserClient.getInviteUser(query).getData(); + if(null == inviteUser){ + inviteUser = new TInviteUser(); + inviteUser.setAppUserId(appUser.getInviteUserId()); + inviteUser.setBeInvitedAppUserId(chargingOrder.getAppUserId()); + inviteUser.setAward(num1); + inviteUser.setCreateTime(LocalDateTime.now()); + inviteUserClient.saveInviteUser(inviteUser); + }else{ + inviteUser.setAward(num1); + inviteUserClient.updateInviteUser(inviteUser); + } + TAppUser appUser1 = appUserClient.getUserById(appUser.getInviteUserId()).getData(); + TAppUserIntegralChange appUserIntegralChange = new TAppUserIntegralChange(); + String code = Math.random() * 1000 + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")); + appUserIntegralChange.setCode(code); + appUserIntegralChange.setAppUserId(appUser.getInviteUserId()); + appUserIntegralChange.setChangeType(5); + appUserIntegralChange.setHistoricalIntegral(appUser1.getPoints()); + appUserIntegralChange.setCurrentIntegral(appUser1.getPoints() + num1); + appUserIntegralChange.setCreateTime(LocalDateTime.now()); + appUserIntegralChangeClient.addAppUserIntegralChange(appUserIntegralChange); + + appUser1.setPoints(appUser1.getPoints() + num1); + appUserClient.updateAppUser(appUser1); + } + } + + /** + * 异常结束充电处理逻辑 + * @param orderCode + */ + @Override + public void excelEndCharge(String orderCode) { + endCharge(orderCode, 0); + } + + + + @Override + public R payRefund(PayOrderRefundDto payOrderQueryDto) { + if (payOrderQueryDto.getType()==1){ + TChargingOrder tChargingOrder = this.baseMapper.selectById(payOrderQueryDto.getOrderId()); + TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund(); + chargingOrderRefund.setChargingOrderId(tChargingOrder.getId()); + chargingOrderRefund.setRefundAmount(payOrderQueryDto.getRefundAmount()); + chargingOrderRefund.setRefundStatus(1); + chargingOrderRefund.setPayType(tChargingOrder.getRechargePaymentType()); + chargingOrderRefund.setRefundTime(LocalDateTime.now()); + chargingOrderRefund.setCode(tChargingOrder.getCode()); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); + chargingOrderRefund.setRefundCode("GDF" + sdf.format(new Date()) + (Math.random() * 1000)); + chargingOrderRefund.setRefundTitle("后台退款"); + chargingOrderRefund.setRefundContent("后台退款"); + chargingOrderRefund.setRefundReason("后台退款"); + chargingOrderRefund.setRefundRemark("后台退款"); + chargingOrderRefund.setRefundTotalAmount(tChargingOrder.getRefundAmount().add(payOrderQueryDto.getRefundAmount())); + chargingOrderRefund.setPayAmount(tChargingOrder.getPaymentAmount()); + + if(1 == tChargingOrder.getRechargePaymentType()){ + WxPaymentRefundModel model = new WxPaymentRefundModel(); + model.setOut_trade_no(tChargingOrder.getCode()); + model.setOut_refund_no(chargingOrderRefund.getRefundCode()); + model.setTransaction_id(tChargingOrder.getRechargeSerialNumber()); + model.setReason("取消订单"); + model.setNotify_url("http://127.0.0.1:9000/order/t-shopping-order/cancelShoppingOrderWxRefund"); + WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount(); + amount.setRefund(payOrderQueryDto.getRefundAmount().multiply(new BigDecimal(100)).intValue()); + amount.setTotal(tChargingOrder.getPaymentAmount().multiply(new BigDecimal(100)).intValue()); + amount.setCurrency("CNY"); + model.setAmount(amount); + R<String> orderR = wxPaymentClient.refundOrderR(model); + if(200 == orderR.getCode()){ + chargingOrderRefundService.save(chargingOrderRefund); + } + } + + if(2 == tChargingOrder.getRechargePaymentType()){ + RefundReq dto = new RefundReq(); + dto.setOutTradeNo(tChargingOrder.getCode()); + dto.setOutRequestNo(tChargingOrder.getCode()); + dto.setRefundAmount(payOrderQueryDto.getRefundAmount().toString()); + dto.setRefundReason("取消订单"); + RefundResp resp = aliPaymentClient.refund(dto).getData(); + if(null != resp){ + SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-DDTHH:mm:ss+TIMEZONE"); + chargingOrderRefundService.save(chargingOrderRefund); + + } + } + + + + + + } + + + + return null; + } + + + /** + * 根据车牌号和开始时间查询充电数据 + * @param query + * @return + */ + @Override + public TChargingOrder getChargingOrderByLicensePlate(GetChargingOrderByLicensePlate query) { + TAppUserCar appUserCar = appUserCarClient.getAppUserCarByLicensePlate(query.getLicensePlate()).getData(); + if(null == appUserCar){ + return null; + } + TChargingOrder one = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserCarId, appUserCar.getId()) + .eq(TChargingOrder::getDelFlag, 0).gt(TChargingOrder::getStartTime, query.getStartTime()) + .eq(TChargingOrder::getRechargePaymentStatus, 2).ne(TChargingOrder::getStatus, -1)); + return one; + } } -- Gitblit v1.7.1