| | |
| | | package com.ruoyi.order.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.account.api.feignClient.VinManagementClient; |
| | | import com.ruoyi.chargingPile.api.dto.GetSiteListDTO; |
| | | 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.common.core.domain.R; |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | | import com.ruoyi.common.core.web.page.PageInfo; |
| | | import com.ruoyi.common.security.service.TokenService; |
| | | import com.ruoyi.integration.api.feignClient.SendMessageClient; |
| | | import com.ruoyi.integration.api.model.PlatformStopCharging; |
| | | import com.ruoyi.integration.api.model.UploadRealTimeMonitoringData; |
| | | import com.ruoyi.order.api.model.TVinChargingOrder; |
| | | import com.ruoyi.order.api.query.VinChargingOrderQuery; |
| | | import com.ruoyi.order.api.vo.ChargingOrderVO; |
| | | import com.ruoyi.order.api.vo.VinChargingStatusVO; |
| | | import com.ruoyi.order.dto.MyVinChargingOrderList; |
| | | import com.ruoyi.order.mapper.TVinChargingOrderMapper; |
| | | import com.ruoyi.order.service.TVinChargingOrderService; |
| | | import com.ruoyi.order.util.mongodb.service.UploadRealTimeMonitoringDataService; |
| | |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDateTime; |
| | | import java.time.ZoneId; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.time.temporal.ChronoUnit; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | |
| | | @Resource |
| | | private TokenService tokenService; |
| | | @Resource |
| | | private VinManagementClient vinManagementClient; |
| | | @Resource |
| | | private SiteClient siteClient; |
| | | @Resource |
| | | private ChargingGunClient chargingGunClient; |
| | | @Resource |
| | | private ChargingPileClient chargingPileClient; |
| | | @Resource |
| | | private SendMessageClient sendMessageClient; |
| | | @Resource |
| | | private UploadRealTimeMonitoringDataService monitoringDataService; |
| | | |
| | |
| | | } |
| | | |
| | | @Override |
| | | public PageInfo<MyVinChargingOrderList> pageAppletOrders(Integer pageCurr, Integer pageSize) { |
| | | int current = pageCurr == null || pageCurr < 1 ? 1 : pageCurr; |
| | | int size = pageSize == null || pageSize < 1 ? 10 : Math.min(pageSize, 100); |
| | | PageInfo<MyVinChargingOrderList> page = new PageInfo<>(current, size); |
| | | if (tokenService.getLoginUserApplet() == null || tokenService.getLoginUserApplet().getUserId() == null) { |
| | | page.setTotal(0); |
| | | page.setRecords(Collections.emptyList()); |
| | | return page; |
| | | } |
| | | Long appUserId = tokenService.getLoginUserApplet().getUserId(); |
| | | R<List<Long>> vinIdResponse = vinManagementClient.getVinIdsByAppUserId(appUserId); |
| | | List<Long> vinIds = vinIdResponse == null ? Collections.emptyList() |
| | | : Optional.ofNullable(vinIdResponse.getData()).orElse(Collections.emptyList()); |
| | | if (vinIds.isEmpty()) { |
| | | page.setTotal(0); |
| | | page.setRecords(Collections.emptyList()); |
| | | return page; |
| | | } |
| | | long total = baseMapper.countAppletOrders(vinIds); |
| | | page.setTotal(total); |
| | | List<MyVinChargingOrderList> records = total == 0 ? Collections.emptyList() |
| | | : baseMapper.pageAppletOrders(vinIds, (long) (current - 1) * size, size); |
| | | fillAppletExtra(records); |
| | | page.setRecords(records); |
| | | return page; |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Object> appletDetail(Long chargingOrderId) { |
| | | TVinChargingOrder order = getAuthorizedAppletOrder(chargingOrderId); |
| | | if (order == null) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | Map<String, Object> result = new HashMap<>(); |
| | | result.put("id", String.valueOf(order.getId())); |
| | | result.put("chargingGunId", order.getChargingGunId()); |
| | | result.put("code", order.getCode()); |
| | | result.put("createTime", order.getCreateTime() == null ? null |
| | | : order.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
| | | result.put("status", order.getStatus()); |
| | | result.put("licensePlate", order.getPlateNum()); |
| | | result.put("startTime", toEpochMilli(order.getStartTime())); |
| | | result.put("endTime", toEpochMilli(order.getEndTime())); |
| | | result.put("orderAmount", order.getOrderAmount()); |
| | | result.put("paymentAmount", order.getPaymentAmount()); |
| | | result.put("rechargeAmount", order.getRechargeAmount()); |
| | | result.put("couponDiscountAmount", order.getCouponDiscountAmount()); |
| | | result.put("vipDiscountAmount", order.getVipDiscountAmount()); |
| | | result.put("refundAmount", order.getRefundAmount()); |
| | | result.put("electricMoney", order.getElectrovalence()); |
| | | result.put("serviceMoney", order.getServiceCharge()); |
| | | result.put("totalElectricQuantity", order.getChargingCapacity()); |
| | | result.put("stageCost", baseMapper.accountingStrategyList(order.getId())); |
| | | result.put("actionable", 0); |
| | | result.put("isAppeal", 0); |
| | | |
| | | Site site = getSite(order.getSiteId()); |
| | | result.put("title", site == null ? "未知电站" : site.getName()); |
| | | TChargingGun gun = getGun(order.getChargingGunId()); |
| | | result.put("chargeMode", gun == null ? null : gun.getChargeMode()); |
| | | result.put("name", gun == null ? null : gun.getName()); |
| | | fillAppletMonitoring(result, order.getCode()); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public List<VinChargingStatusVO> getChargingVinStatus(List<Long> vinIds) { |
| | | if (vinIds == null || vinIds.isEmpty()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<Long> distinctVinIds = vinIds.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList()); |
| | | return distinctVinIds.isEmpty() ? Collections.emptyList() : baseMapper.getChargingVinStatus(distinctVinIds); |
| | | } |
| | | |
| | | @Override |
| | | public List<ChargingOrderVO> exportList(VinChargingOrderQuery query) { |
| | | setAuthSiteIds(query); |
| | | long total = baseMapper.count(query); |
| | |
| | | result.addAll(batch); |
| | | } |
| | | fillExtra(result); |
| | | fillRealtimeData(result); |
| | | return result; |
| | | } |
| | | |
| | |
| | | return Collections.emptyMap(); |
| | | } |
| | | Map<String, Object> result = new HashMap<>(); |
| | | result.put("id", order.getId()); |
| | | result.put("id", order.getId() == null ? null : String.valueOf(order.getId())); |
| | | result.put("code", order.getCode()); |
| | | result.put("vin", order.getVin()); |
| | | result.put("vin", order.getActualVin()); |
| | | result.put("actualVin", order.getActualVin()); |
| | | result.put("expectedVin", order.getExpectedVin()); |
| | | result.put("plateNum", order.getPlateNum()); |
| | |
| | | result.put("paymentAmount", order.getPaymentAmount()); |
| | | result.put("electrovalence", order.getElectrovalence()); |
| | | result.put("serviceCharge", order.getServiceCharge()); |
| | | if (order.getStartTime() != null && order.getEndTime() != null) { |
| | | result.put("chargingSecond", ChronoUnit.SECONDS.between(order.getStartTime(), order.getEndTime())); |
| | | } |
| | | List<Site> sites = order.getSiteId() == null ? Collections.emptyList() |
| | | : Optional.ofNullable(siteClient.getSiteByIds(Collections.singletonList(order.getSiteId())).getData()).orElse(Collections.emptyList()); |
| | | Site site = sites.stream().findFirst().orElse(null); |
| | | result.put("siteName", site == null ? null : site.getName()); |
| | | List<TChargingGun> guns = order.getChargingGunId() == null ? Collections.emptyList() |
| | | : Optional.ofNullable(chargingGunClient.getChargingGunByIds(Collections.singletonList(order.getChargingGunId())).getData()).orElse(Collections.emptyList()); |
| | | TChargingGun gun = guns.stream().findFirst().orElse(null); |
| | | result.put("terminalName", gun == null ? null : gun.getName()); |
| | | List<UploadRealTimeMonitoringData> monitoring = monitoringDataService.getDataByOrderCodeAsc(order.getCode()); |
| | | result.put("list", monitoring == null ? Collections.emptyList() : monitoring); |
| | | if (monitoring == null) { |
| | | monitoring = Collections.emptyList(); |
| | | } |
| | | for (UploadRealTimeMonitoringData data : monitoring) { |
| | | if (data.getOutput_current() != null && data.getOutput_voltage() != null) { |
| | | data.setPower(data.getOutput_voltage().multiply(data.getOutput_current()).divide(new BigDecimal(1000), 2, BigDecimal.ROUND_HALF_UP)); |
| | | } |
| | | } |
| | | UploadRealTimeMonitoringData latestMonitoring = monitoring.isEmpty() ? null : monitoring.get(monitoring.size() - 1); |
| | | result.put("cdElectronic", latestMonitoring == null ? null : latestMonitoring.getOutput_current()); |
| | | result.put("cdVoltage", latestMonitoring == null ? null : latestMonitoring.getOutput_voltage()); |
| | | result.put("totalPower", latestMonitoring == null ? null : latestMonitoring.getPower()); |
| | | result.put("surplus", latestMonitoring == null ? null : latestMonitoring.getSoc()); |
| | | result.put("list", monitoring); |
| | | result.put("list1", baseMapper.accountingStrategyList(order.getId())); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public AjaxResult stopCharging(String chargingOrderId, Integer chargingGunId) { |
| | | Long orderId; |
| | | try { |
| | | orderId = Long.valueOf(chargingOrderId); |
| | | } catch (NumberFormatException e) { |
| | | return AjaxResult.error("VIN码充电订单ID无效"); |
| | | } |
| | | TVinChargingOrder order = getAuthorizedOrder(orderId); |
| | | if (order == null) { |
| | | return AjaxResult.error("VIN码充电订单不存在或无权操作"); |
| | | } |
| | | if (order.getChargingGunId() == null || !order.getChargingGunId().equals(chargingGunId)) { |
| | | return AjaxResult.error("充电枪与订单不匹配"); |
| | | } |
| | | Integer status = order.getStatus(); |
| | | if (status == null || !status.equals(3)) { |
| | | return AjaxResult.error(status != null && (status.equals(4) || status.equals(5)) ? "不能重复操作" : "还未开始充电"); |
| | | } |
| | | TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingGunId).getData(); |
| | | TChargingPile chargingPile = order.getChargingPileId() == null ? null |
| | | : chargingPileClient.getChargingPileById(order.getChargingPileId()).getData(); |
| | | if (chargingGun == null || chargingPile == null) { |
| | | return AjaxResult.error("未找到订单对应的充电设备"); |
| | | } |
| | | order.setStatus(4); |
| | | order.setEndMode(1); |
| | | order.setEndTime(LocalDateTime.now()); |
| | | if (!updateById(order)) { |
| | | return AjaxResult.error("更新VIN码充电订单状态失败"); |
| | | } |
| | | PlatformStopCharging command = new PlatformStopCharging(); |
| | | command.setCharging_pile_code(chargingPile.getCode()); |
| | | command.setCharging_gun_code(chargingGun.getCode()); |
| | | sendMessageClient.platformStopCharging(command); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @Override |
| | |
| | | .orElse(Collections.emptyList()).stream().map(GetSiteListDTO::getId).collect(Collectors.toList()); |
| | | } |
| | | |
| | | private TVinChargingOrder getAuthorizedAppletOrder(Long chargingOrderId) { |
| | | if (chargingOrderId == null || tokenService.getLoginUserApplet() == null |
| | | || tokenService.getLoginUserApplet().getUserId() == null) { |
| | | return null; |
| | | } |
| | | TVinChargingOrder order = getById(chargingOrderId); |
| | | if (order == null || order.getVinId() == null) { |
| | | return null; |
| | | } |
| | | R<List<Long>> response = vinManagementClient.getVinIdsByAppUserId( |
| | | tokenService.getLoginUserApplet().getUserId()); |
| | | List<Long> vinIds = response == null ? Collections.emptyList() |
| | | : Optional.ofNullable(response.getData()).orElse(Collections.emptyList()); |
| | | return vinIds.contains(order.getVinId()) ? order : null; |
| | | } |
| | | |
| | | private Long toEpochMilli(LocalDateTime time) { |
| | | return time == null ? null : time.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); |
| | | } |
| | | |
| | | private Site getSite(Integer siteId) { |
| | | if (siteId == null) { |
| | | return null; |
| | | } |
| | | R<List<Site>> response = siteClient.getSiteByIds(Collections.singletonList(siteId)); |
| | | List<Site> sites = response == null ? Collections.emptyList() |
| | | : Optional.ofNullable(response.getData()).orElse(Collections.emptyList()); |
| | | return sites.stream().findFirst().orElse(null); |
| | | } |
| | | |
| | | private TChargingGun getGun(Integer gunId) { |
| | | if (gunId == null) { |
| | | return null; |
| | | } |
| | | R<TChargingGun> response = chargingGunClient.getChargingGunById(gunId); |
| | | return response == null ? null : response.getData(); |
| | | } |
| | | |
| | | private void fillAppletMonitoring(Map<String, Object> result, String orderCode) { |
| | | List<UploadRealTimeMonitoringData> dataList = orderCode == null ? Collections.emptyList() |
| | | : monitoringDataService.getDataByOrderCode(orderCode); |
| | | if (dataList == null || dataList.isEmpty()) { |
| | | result.put("currentAndVoltage", Collections.emptyList()); |
| | | result.put("power", Collections.emptyList()); |
| | | return; |
| | | } |
| | | SimpleDateFormat formatter = new SimpleDateFormat("HH:mm"); |
| | | Map<String, UploadRealTimeMonitoringData> minuteData = new java.util.LinkedHashMap<>(); |
| | | for (UploadRealTimeMonitoringData data : dataList) { |
| | | if (data != null && data.getCreate_time() != null) { |
| | | minuteData.putIfAbsent(formatter.format(data.getCreate_time()), data); |
| | | } |
| | | } |
| | | List<Map<String, Object>> currentAndVoltage = new ArrayList<>(); |
| | | List<Map<String, Object>> power = new ArrayList<>(); |
| | | for (Map.Entry<String, UploadRealTimeMonitoringData> entry : minuteData.entrySet()) { |
| | | UploadRealTimeMonitoringData data = entry.getValue(); |
| | | Map<String, Object> currentItem = new HashMap<>(); |
| | | currentItem.put("time", entry.getKey()); |
| | | currentItem.put("electricity", data.getOutput_current()); |
| | | currentItem.put("voltage", data.getOutput_voltage()); |
| | | currentAndVoltage.add(currentItem); |
| | | |
| | | Map<String, Object> powerItem = new HashMap<>(); |
| | | powerItem.put("time", entry.getKey()); |
| | | powerItem.put("soc", data.getSoc()); |
| | | BigDecimal outputPower = data.getOutput_current() == null || data.getOutput_voltage() == null ? null |
| | | : data.getOutput_current().multiply(data.getOutput_voltage()) |
| | | .divide(new BigDecimal("1000"), 2, RoundingMode.HALF_DOWN); |
| | | powerItem.put("power", outputPower); |
| | | power.add(powerItem); |
| | | } |
| | | result.put("currentAndVoltage", currentAndVoltage); |
| | | result.put("power", power); |
| | | } |
| | | |
| | | private void fillAppletExtra(List<MyVinChargingOrderList> list) { |
| | | if (list == null || list.isEmpty()) { |
| | | return; |
| | | } |
| | | List<Integer> siteIds = list.stream().map(MyVinChargingOrderList::getSiteId) |
| | | .filter(Objects::nonNull).distinct().collect(Collectors.toList()); |
| | | List<Integer> gunIds = list.stream().map(MyVinChargingOrderList::getChargingGunId) |
| | | .filter(Objects::nonNull).distinct().collect(Collectors.toList()); |
| | | Map<Integer, Site> sites = siteIds.isEmpty() ? Collections.emptyMap() |
| | | : Optional.ofNullable(siteClient.getSiteByIds(siteIds).getData()).orElse(Collections.emptyList()).stream() |
| | | .collect(Collectors.toMap(Site::getId, item -> item, (a, b) -> a)); |
| | | Map<Integer, TChargingGun> guns = gunIds.isEmpty() ? Collections.emptyMap() |
| | | : Optional.ofNullable(chargingGunClient.getChargingGunByIds(gunIds).getData()).orElse(Collections.emptyList()).stream() |
| | | .collect(Collectors.toMap(TChargingGun::getId, item -> item, (a, b) -> a)); |
| | | for (MyVinChargingOrderList item : list) { |
| | | Site site = sites.get(item.getSiteId()); |
| | | item.setTitle(site == null ? "未知电站" : site.getName()); |
| | | TChargingGun gun = guns.get(item.getChargingGunId()); |
| | | item.setName(gun == null ? null : gun.getName()); |
| | | } |
| | | } |
| | | |
| | | private void fillExtra(List<ChargingOrderVO> list) { |
| | | if (list == null || list.isEmpty()) { |
| | | return; |
| | | } |
| | | List<Long> orderIds = list.stream().map(ChargingOrderVO::getId).filter(Objects::nonNull).distinct().collect(Collectors.toList()); |
| | | Map<Long, Integer> periodCounts = new HashMap<>(); |
| | | if (!orderIds.isEmpty()) { |
| | | for (Map<String, Object> item : baseMapper.countAccountingStrategies(orderIds)) { |
| | | Number chargingOrderId = (Number) item.get("chargingOrderId"); |
| | | Number periodCount = (Number) item.get("periodCount"); |
| | | if (chargingOrderId != null && periodCount != null) { |
| | | periodCounts.put(chargingOrderId.longValue(), periodCount.intValue()); |
| | | } |
| | | } |
| | | } |
| | | List<Integer> siteIds = list.stream().map(ChargingOrderVO::getSiteId).filter(Objects::nonNull).distinct().collect(Collectors.toList()); |
| | | List<Integer> gunIds = list.stream().map(ChargingOrderVO::getChargingGunId).filter(Objects::nonNull).distinct().collect(Collectors.toList()); |
| | |
| | | if (item.getStartTime() != null && item.getEndTime() != null) { |
| | | item.setChargingSecond(ChronoUnit.SECONDS.between(item.getStartTime(), item.getEndTime())); |
| | | } |
| | | UploadRealTimeMonitoringData data = monitoringDataService.getLastDataById(item.getCode()); |
| | | if (data != null) { |
| | | item.setChargeCurrent(data.getOutput_current()); |
| | | item.setChargeVoltage(data.getOutput_voltage()); |
| | | item.setChargePower(data.getPower()); |
| | | } |
| | | item.setCount(periodCounts.getOrDefault(item.getId(), 0)); |
| | | item.setPlatformIncome(BigDecimal.ZERO); |
| | | item.setPartnerIncome(BigDecimal.ZERO); |
| | | } |
| | | } |
| | | |
| | | private void fillRealtimeData(List<ChargingOrderVO> list) { |
| | | for (ChargingOrderVO item : list) { |
| | | if (item.getCode() == null || item.getCode().trim().isEmpty()) { |
| | | continue; |
| | | } |
| | | UploadRealTimeMonitoringData data = monitoringDataService.getLastDataById(item.getCode()); |
| | | if (data == null) { |
| | | continue; |
| | | } |
| | | item.setChargeCurrent(data.getOutput_current()); |
| | | item.setChargeVoltage(data.getOutput_voltage()); |
| | | BigDecimal power = data.getPower(); |
| | | if (power == null && data.getOutput_current() != null && data.getOutput_voltage() != null) { |
| | | power = data.getOutput_current().multiply(data.getOutput_voltage()) |
| | | .divide(new BigDecimal(1000), 2, BigDecimal.ROUND_HALF_UP); |
| | | } |
| | | item.setChargePower(power); |
| | | } |
| | | } |
| | | } |