skyline před 2 roky
rodič
revize
93b21bf927
18 změnil soubory, kde provedl 554 přidání a 81 odebrání
  1. 7 2
      admin/src/main/java/com/kym/admin/controller/StatController.java
  2. 18 0
      admin/src/main/java/com/kym/admin/controller/StationStatDayController.java
  3. 18 0
      admin/src/main/java/com/kym/admin/controller/StationStatMonthController.java
  4. 78 0
      admin/src/main/java/com/kym/admin/jobs/StationStatJob.java
  5. 81 0
      entity/src/main/java/com/kym/entity/admin/StationStatDay.java
  6. 81 0
      entity/src/main/java/com/kym/entity/admin/StationStatMonth.java
  7. 16 0
      mapper/src/main/java/com/kym/mapper/admin/StationStatDayMapper.java
  8. 16 0
      mapper/src/main/java/com/kym/mapper/admin/StationStatMonthMapper.java
  9. 28 0
      mapper/src/main/resources/mappers/admin/StationStatDayMapper.xml
  10. 29 0
      mapper/src/main/resources/mappers/admin/StationStatMonthMapper.xml
  11. 16 0
      service/src/main/java/com/kym/service/admin/StationStatDayService.java
  12. 16 0
      service/src/main/java/com/kym/service/admin/StationStatMonthService.java
  13. 20 0
      service/src/main/java/com/kym/service/admin/impl/StationStatDayServiceImpl.java
  14. 20 0
      service/src/main/java/com/kym/service/admin/impl/StationStatMonthServiceImpl.java
  15. 3 3
      service/src/main/java/com/kym/service/enplus/impl/EnPlusServiceImpl.java
  16. 1 2
      service/src/main/java/com/kym/service/miniapp/ChargeService.java
  17. 105 74
      service/src/main/java/com/kym/service/miniapp/impl/ChargeServiceImpl.java
  18. 1 0
      service/src/main/java/com/kym/service/wechat/impl/WxPayServiceImpl.java

+ 7 - 2
admin/src/main/java/com/kym/admin/controller/StatController.java

@@ -30,7 +30,7 @@ public class StatController {
      * @return
      */
     @GetMapping("/stationStat")
-    R stationStat(@ModelAttribute StatQueryParam params) {
+    R<?> stationStat(@ModelAttribute StatQueryParam params) {
         var res = chargeOrderService.stationStat(params);
         return R.success(res);
     }
@@ -41,8 +41,13 @@ public class StatController {
      * @return
      */
     @GetMapping("/stationTodayStat")
-    R stationTodayStat(String stationId) {
+    R<?> stationTodayStat(String stationId) {
         var res = chargeOrderService.stationTodayStat(stationId);
         return R.success(res);
     }
+
+    // TODO: 2023-12-01 站点平均单桩充电数据 日/月/整体维度
+
+    // TODO: 2023-12-01 站点平均单度电费数据 日/月/整体维度
+
 }

+ 18 - 0
admin/src/main/java/com/kym/admin/controller/StationStatDayController.java

@@ -0,0 +1,18 @@
+package com.kym.admin.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 站点统计表-日 前端控制器
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-12-04
+ */
+@RestController
+@RequestMapping("/station-stat-day")
+public class StationStatDayController {
+
+}

+ 18 - 0
admin/src/main/java/com/kym/admin/controller/StationStatMonthController.java

@@ -0,0 +1,18 @@
+package com.kym.admin.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 站点统计表-月 前端控制器
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-12-04
+ */
+@RestController
+@RequestMapping("/station-stat-month")
+public class StationStatMonthController {
+
+}

+ 78 - 0
admin/src/main/java/com/kym/admin/jobs/StationStatJob.java

@@ -0,0 +1,78 @@
+package com.kym.admin.jobs;
+
+import com.kym.entity.admin.StationStatDay;
+import com.kym.entity.miniapp.ChargeOrder;
+import com.kym.service.admin.StationStatDayService;
+import com.kym.service.admin.StationStatMonthService;
+import com.kym.service.miniapp.ChargeOrderService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+/**
+ * 站点统计定时任务
+ */
+@Component
+@Slf4j
+public class StationStatJob {
+
+    private final ChargeOrderService chargeOrderService;
+
+    private final StationStatDayService dayService;
+    private final StationStatMonthService monthService;
+
+    public StationStatJob(ChargeOrderService chargeOrderService, StationStatDayService stationStatDayService, StationStatMonthService stationStatMonthService) {
+        this.chargeOrderService = chargeOrderService;
+        this.dayService = stationStatDayService;
+        this.monthService = stationStatMonthService;
+    }
+
+
+    // 每天14:30执行一次,通过charge_app.t_charge_order表统计start_time为前一天且充电金额大于100的充电订单,分别统计充电人数、订单数、充电总费用、充电总电量、平均充电电量、平均充电费用、平均订单费用、平均订单电量
+    @Scheduled(cron = "0 30 14 * * ?")
+    public void execute() {
+        log.info("执行站点统计定时任务");
+        // 通过charge_app.t_charge_order表统计start_time为前一天且充电金额大于100的有效充电订单
+        var statDay = LocalDateTime.now().minusDays(1);
+        var startTime = LocalDateTime.of(statDay.toLocalDate(), LocalTime.MIN);
+        var endTime = LocalDateTime.of(statDay.toLocalDate(), LocalTime.MAX);
+        var chargeOrderList = chargeOrderService.lambdaQuery()
+                .ge(ChargeOrder::getStartTime, startTime)
+                .le(ChargeOrder::getStartTime, endTime)
+                .gt(ChargeOrder::getTotalMoney, 100)
+                .list();
+
+
+        // 将chargeOrderList按照stationId分组
+        var chargeOrderMap = chargeOrderList.stream().collect(Collectors.groupingBy(ChargeOrder::getStationId));
+        // 根据分组计算每个站点的充电人数、订单数、充电总费用、充电总电量、平均充电电量、平均充电费用、平均订单费用、平均订单电量
+        var stationStats = chargeOrderMap.entrySet().stream().collect(Collectors.toMap(
+                Map.Entry::getKey,
+                entry -> {
+                    var chargeOrders = entry.getValue();
+                    var chargeUsers = chargeOrders.stream().collect(Collectors.collectingAndThen(
+                            Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ChargeOrder::getUserId))), ArrayList<ChargeOrder>::new)).size();
+                    var totalMoney = chargeOrders.stream().mapToInt(ChargeOrder::getTotalMoney).sum();
+                    var totalPower = chargeOrders.stream().mapToDouble(ChargeOrder::getTotalPower).sum();
+                    var avgPower = chargeOrders.stream().mapToDouble(ChargeOrder::getTotalPower).average().orElse(0.0);
+                    var avgOrderMoney = chargeOrders.stream().mapToInt(ChargeOrder::getTotalMoney).average().orElse(0);
+                    return new StationStatDay()
+                            .setStationId(entry.getKey())
+                            .setStatDay(statDay.toLocalDate())
+                            .setChargeUsers(chargeUsers)
+                            .setTotalMoney(totalMoney)
+                            .setTotalPower(totalPower)
+                            .setAvgOrderElec(avgPower)
+                            .setAvgOrderMoney((int) avgOrderMoney);
+                })).values();
+        dayService.saveBatch(stationStats);
+    }
+}

+ 81 - 0
entity/src/main/java/com/kym/entity/admin/StationStatDay.java

@@ -0,0 +1,81 @@
+package com.kym.entity.admin;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.kym.entity.BaseEntity;
+import java.io.Serializable;
+import java.time.LocalDate;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 站点统计表-日
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-12-04
+ */
+@Getter
+@Setter
+@TableName("t_station_stat_day")
+@Accessors(chain = true)
+public class StationStatDay extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 站点id
+     */
+    private String stationId;
+
+    /**
+     * 统计时间
+     */
+    private LocalDate statDay;
+
+    /**
+     * 充电人数
+     */
+    private Integer chargeUsers;
+
+    /**
+     * 充电有效订单数
+     */
+    private Integer validOrders;
+
+    /**
+     * 总电量
+     */
+    private Double totalPower;
+
+    /**
+     * 总充电费用
+     */
+    private Integer totalMoney;
+
+    /**
+     * 总电费
+     */
+    private Integer elecMoney;
+
+    /**
+     * 总服务费
+     */
+    private Integer serviceMoney;
+
+    /**
+     * 订单平均充电量
+     */
+    private Double avgOrderElec;
+
+    /**
+     * 订单平均充电费用
+     */
+    private Integer avgOrderMoney;
+
+    /**
+     * 单枪平均日充电量
+     */
+    private Double avgConnectorElec;
+}

+ 81 - 0
entity/src/main/java/com/kym/entity/admin/StationStatMonth.java

@@ -0,0 +1,81 @@
+package com.kym.entity.admin;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.kym.entity.BaseEntity;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+
+import java.time.LocalDate;
+
+/**
+ * <p>
+ * 站点统计表-月
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-12-04
+ */
+@Getter
+@Setter
+@TableName("t_station_stat_month")
+@Accessors(chain = true)
+public class StationStatMonth extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 站点id
+     */
+    private String stationId;
+
+    /**
+     * 统计时间
+     */
+    private LocalDate statMonth;
+
+    /**
+     * 充电人数
+     */
+    private Integer chargeUsers;
+
+    /**
+     * 充电有效订单数
+     */
+    private Integer validOrders;
+
+    /**
+     * 总电量
+     */
+    private Double totalPower;
+
+    /**
+     * 总充电费用
+     */
+    private Integer totalMoney;
+
+    /**
+     * 总电费
+     */
+    private Integer elecMoney;
+
+    /**
+     * 总服务费
+     */
+    private Integer serviceMoney;
+
+    /**
+     * 订单平均充电量
+     */
+    private Double avgOrderElec;
+
+    /**
+     * 订单平均充电费用
+     */
+    private Integer avgOrderMoney;
+
+    /**
+     * 单枪平均日充电量
+     */
+    private Double avgConnectorElec;
+}

+ 16 - 0
mapper/src/main/java/com/kym/mapper/admin/StationStatDayMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.admin;
+
+import com.kym.entity.admin.StationStatDay;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 站点统计表-日 Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-12-04
+ */
+public interface StationStatDayMapper extends BaseMapper<StationStatDay> {
+
+}

+ 16 - 0
mapper/src/main/java/com/kym/mapper/admin/StationStatMonthMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.admin;
+
+import com.kym.entity.admin.StationStatMonth;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 站点统计表-月 Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-12-04
+ */
+public interface StationStatMonthMapper extends BaseMapper<StationStatMonth> {
+
+}

+ 28 - 0
mapper/src/main/resources/mappers/admin/StationStatDayMapper.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.kym.mapper.admin.StationStatDayMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.kym.entity.admin.StationStatDay">
+        <result column="id" property="id" />
+        <result column="station_id" property="stationId" />
+        <result column="stat_day" property="statDay" />
+        <result column="charge_users" property="chargeUsers" />
+        <result column="valid_orders" property="validOrders" />
+        <result column="total_power" property="totalPower" />
+        <result column="total_money" property="totalMoney" />
+        <result column="elec_money" property="elecMoney" />
+        <result column="service_money" property="serviceMoney" />
+        <result column="avg_order_elec" property="avgOrderElec" />
+        <result column="avg_order_money" property="avgOrderMoney" />
+        <result column="avg_connector_elec" property="avgConnectorElec" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id,station_id, stat_day, charge_users, valid_orders, total_power, total_money, elec_money, service_money, avg_order_elec, avg_order_money, avg_connector_elec,create_time, update_time
+    </sql>
+
+</mapper>

+ 29 - 0
mapper/src/main/resources/mappers/admin/StationStatMonthMapper.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.kym.mapper.admin.StationStatMonthMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.kym.entity.admin.StationStatMonth">
+        <result column="id" property="id" />
+        <result column="station_id" property="stationId" />
+        <result column="stat_month" property="statMonth" />
+        <result column="charge_users" property="chargeUsers" />
+        <result column="valid_orders" property="validOrders" />
+        <result column="total_power" property="totalPower" />
+        <result column="total_money" property="totalMoney" />
+        <result column="elec_money" property="elecMoney" />
+        <result column="service_money" property="serviceMoney" />
+        <result column="avg_order_elec" property="avgOrderElec" />
+        <result column="avg_order_money" property="avgOrderMoney" />
+        <result column="avg_connector_elec" property="avgConnectorElec" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id,station_id, stat_month, charge_users, valid_orders, total_power, total_money, elec_money, service_money, avg_order_elec, avg_order_money, avg_connector_elec,create_time, update_time
+    </sql>
+    </sql>
+
+</mapper>

+ 16 - 0
service/src/main/java/com/kym/service/admin/StationStatDayService.java

@@ -0,0 +1,16 @@
+package com.kym.service.admin;
+
+import com.kym.entity.admin.StationStatDay;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 站点统计表-日 服务类
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-12-04
+ */
+public interface StationStatDayService extends IService<StationStatDay> {
+
+}

+ 16 - 0
service/src/main/java/com/kym/service/admin/StationStatMonthService.java

@@ -0,0 +1,16 @@
+package com.kym.service.admin;
+
+import com.kym.entity.admin.StationStatMonth;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 站点统计表-月 服务类
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-12-04
+ */
+public interface StationStatMonthService extends IService<StationStatMonth> {
+
+}

+ 20 - 0
service/src/main/java/com/kym/service/admin/impl/StationStatDayServiceImpl.java

@@ -0,0 +1,20 @@
+package com.kym.service.admin.impl;
+
+import com.kym.entity.admin.StationStatDay;
+import com.kym.mapper.admin.StationStatDayMapper;
+import com.kym.service.admin.StationStatDayService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 站点统计表-日 服务实现类
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-12-04
+ */
+@Service
+public class StationStatDayServiceImpl extends ServiceImpl<StationStatDayMapper, StationStatDay> implements StationStatDayService {
+
+}

+ 20 - 0
service/src/main/java/com/kym/service/admin/impl/StationStatMonthServiceImpl.java

@@ -0,0 +1,20 @@
+package com.kym.service.admin.impl;
+
+import com.kym.entity.admin.StationStatMonth;
+import com.kym.mapper.admin.StationStatMonthMapper;
+import com.kym.service.admin.StationStatMonthService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 站点统计表-月 服务实现类
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-12-04
+ */
+@Service
+public class StationStatMonthServiceImpl extends ServiceImpl<StationStatMonthMapper, StationStatMonth> implements StationStatMonthService {
+
+}

+ 3 - 3
service/src/main/java/com/kym/service/enplus/impl/EnPlusServiceImpl.java

@@ -310,17 +310,17 @@ public class EnPlusServiceImpl implements EnPlusService {
      * 请求停止充电
      *
      * @param startChargeSeq
-     * @param connectorID
+     * @param connectorId
      * @return
      */
     @Override
-    public JSONObject queryStopCharge(String startChargeSeq, String connectorID) {
+    public JSONObject queryStopCharge(String startChargeSeq, String connectorId) {
         var param = """
                 {
                     "StartChargeSeq":"%s",
                     "ConnectorID":"%s"
                 }
-                """.formatted(startChargeSeq, connectorID);
+                """.formatted(startChargeSeq, connectorId);
         var response = enPlusPost(EnPlusApi.EN_PLUS_QUERY_STOP_CHARGE.getApi(), buildParams(param));
         return JSONObject.parseObject(AESUtil.decrypt(response.getData()));
     }

+ 1 - 2
service/src/main/java/com/kym/service/miniapp/ChargeService.java

@@ -19,8 +19,7 @@ public interface ChargeService {
 
     Map<String, String> queryStartCharge(Long userId, String connectorId, Long userRechargeRightsId, Boolean isBooking, LocalDateTime startTime, LocalDateTime endTime);
 
-    @DS("db-admin")
-    void updateEquipmentStatus(String connectorId);
+    void updateEquipmentAndConnectorStatus(String connectorId);
 
     ChargeOrder queryEquipChargeStatus();
 

+ 105 - 74
service/src/main/java/com/kym/service/miniapp/impl/ChargeServiceImpl.java

@@ -11,12 +11,15 @@ import com.kym.common.constant.ResponseEnum;
 import com.kym.common.exception.BusinessException;
 import com.kym.common.utils.CommUtil;
 import com.kym.common.utils.OrderUtils;
+import com.kym.entity.admin.ConnectorInfo;
 import com.kym.entity.admin.EquipmentInfo;
 import com.kym.entity.enplus.response.EnBusinessPolicy;
+import com.kym.entity.miniapp.Account;
 import com.kym.entity.miniapp.ChargeOrder;
 import com.kym.entity.miniapp.OrderRechargeRights;
 import com.kym.entity.miniapp.UserRechargeRights;
 import com.kym.entity.miniapp.delay.DelayChargeOrder;
+import com.kym.service.admin.ConnectorInfoService;
 import com.kym.service.admin.EquipmentInfoService;
 import com.kym.service.admin.EquipmentRelationService;
 import com.kym.service.enplus.EnPlusService;
@@ -50,6 +53,8 @@ public class ChargeServiceImpl implements ChargeService {
 
     private final EquipmentInfoService equipmentInfoService;
 
+    private final ConnectorInfoService connectorInfoService;
+
     private final ChargeOrderService chargeOrderService;
 
     private final OrderRechargeRightsService orderRechargeRightsService;
@@ -64,9 +69,15 @@ public class ChargeServiceImpl implements ChargeService {
     private final DelayService<DelayChargeOrder> startDelayService;
     private final DelayService<DelayChargeOrder> stopDelayService;
 
-    public ChargeServiceImpl(EquipmentRelationService equipmentRelationService, EquipmentInfoService equipmentInfoService, ChargeOrderService chargeOrderService, OrderRechargeRightsService orderRechargeRightsService, UserRechargeRightsService userRechargeRightsService, AccountService accountService, EnPlusService enPlusService, EnPlusConfig enPlusConfig, @Qualifier("StartChargeDelayJob") @Lazy DelayService<DelayChargeOrder> startDelayService, @Qualifier("StopChargeDelayJob") @Lazy DelayService<DelayChargeOrder> stopDelayService) {
+    public ChargeServiceImpl(EquipmentRelationService equipmentRelationService, EquipmentInfoService equipmentInfoService,
+                             ConnectorInfoService connectorInfoService, ChargeOrderService chargeOrderService,
+                             OrderRechargeRightsService orderRechargeRightsService, UserRechargeRightsService userRechargeRightsService,
+                             AccountService accountService, EnPlusService enPlusService, EnPlusConfig enPlusConfig,
+                             @Qualifier("StartChargeDelayJob") @Lazy DelayService<DelayChargeOrder> startDelayService,
+                             @Qualifier("StopChargeDelayJob") @Lazy DelayService<DelayChargeOrder> stopDelayService) {
         this.equipmentRelationService = equipmentRelationService;
         this.equipmentInfoService = equipmentInfoService;
+        this.connectorInfoService = connectorInfoService;
         this.chargeOrderService = chargeOrderService;
         this.orderRechargeRightsService = orderRechargeRightsService;
         this.userRechargeRightsService = userRechargeRightsService;
@@ -149,6 +160,11 @@ public class ChargeServiceImpl implements ChargeService {
         cancelBookByChargeOrder(chargeOrder);
     }
 
+    /**
+     * 取消预约订单
+     *
+     * @param chargeOrder 预约订单
+     */
     public void cancelBookByChargeOrder(ChargeOrder chargeOrder) {
         if (chargeOrder != null) {
             // 清除启动/停止队列信息
@@ -179,55 +195,11 @@ public class ChargeServiceImpl implements ChargeService {
     @Override
     @DSTransactional(rollbackFor = Exception.class)
     public Map<String, String> queryStartCharge(Long userId, String connectorId, Long userRechargeRightsId, Boolean isBooking, LocalDateTime startTime, LocalDateTime endTime) {
-        var map = getConnectorIdAndStationId(connectorId);
-        connectorId = map.get("connectorId");
-
-        if (CommUtil.isEmptyOrNull(connectorId)) {
-            throw new BusinessException("请输入正确的设备编号");
-        }
-
-        var stationId = map.get("stationId");
-
+        var connectorId2StationId = getConnectorIdAndStationId(connectorId);
+        connectorId = connectorId2StationId.get("connectorId");
+        var stationId = connectorId2StationId.get("stationId");
         LOGGER.info("用户:{},站点:{},设备:{}请求充电", userId, stationId, connectorId);
-
-        // 设备是否插枪
-        if (ConnectorStatusCache.INSTANCE.get(connectorId) == EquipmentInfo.SERVICE_STATUS_空闲) {
-            throw new BusinessException("请插入充电枪");
-        }
-
-        if (isBooking) {
-            // 预约时间不能超过未来24H
-            if (TimeUnit.SECONDS.convert(Duration.between(LocalDateTime.now(), startTime)) > 3600 * 24) {
-                throw new BusinessException("预约充电启动时间不能超过未来24小时");
-            }
-            // 预约充电通过connectorId查询预约中的订单
-            var bookingOrder = chargeOrderService.lambdaQuery().eq(ChargeOrder::getUserId, userId).eq(ChargeOrder::getConnectorId, connectorId).eq(ChargeOrder::getIsBooking, ChargeOrder.IS_BOOKING_是).eq(ChargeOrder::getOrderStatus, ChargeOrder.ORDER_STATUS_未知).eq(ChargeOrder::getChargeStatus, ChargeOrder.CHARGE_STATUS_预约中).one();
-            if (bookingOrder != null) {
-                LOGGER.error("用户:{}存在进行中的订单:{}", userId, bookingOrder.getStartChargeSeq());
-                throw new BusinessException(ResponseEnum.ORDER_IN_BOOKING);
-            }
-        }
-
-        // 二维码文本
-        var qrCode = "";
-
-        // 当前用户是否有正在进行中、预约中、启动中的订单
-        var chargeOrder = chargeOrderService.getChargingOrderByUserId(userId);
-        if (chargeOrder != null) {
-            // 预约中的订单到了启动时间则直接启动,忽略校验
-            if (!(chargeOrder.getChargeStatus().equals(ChargeOrder.CHARGE_STATUS_预约中) && chargeOrder.getStartTime().isBefore(LocalDateTime.now()))) {
-                LOGGER.error("用户:{}存在进行中的订单:{}", userId, chargeOrder.getStartChargeSeq());
-                throw new BusinessException(ResponseEnum.ORDER_IN_PROGRESS);
-            }
-        }
-        // 查询用户余额
-        var account = accountService.getAccountByUserId(userId);
-        if (account.getBalance() <= 200) {
-            LOGGER.error("用户:{}余额不足2元,余额:{}", userId, account.getBalance());
-            throw new BusinessException(ResponseEnum.INSUFFICIENT_USER_BALANCE);
-        }
-        // 传递给EN+的余额要小于实际余额,防止订单超扣的情况,这里少传0.5元
-        var amount = account.getBalance() - 50;
+        var account = checkCharge(userId, connectorId, isBooking, startTime);
 
         // 是否有之前预约充电创建的订单记录,有则直接用,没有则创建
         ChargeOrder order = chargeOrderService.lambdaQuery().eq(ChargeOrder::getConnectorId, connectorId).in(ChargeOrder::getChargeStatus, ChargeOrder.CHARGE_STATUS_已取消, ChargeOrder.CHARGE_STATUS_预约中).one();
@@ -257,9 +229,6 @@ public class ChargeServiceImpl implements ChargeService {
             }
         }
 
-        // 请求设备认证
-        var equipAuth = enPlusService.queryEquipAuth(connectorId, order.getStartChargeSeq());
-
         // 如果是预约订单,则将订单放入预约充电延迟队列
         if (isBooking) {
             order = order.setStartTime(startTime).setChargeStatus(ChargeOrder.CHARGE_STATUS_预约中).setIsBooking(ChargeOrder.IS_BOOKING_是);
@@ -280,7 +249,7 @@ public class ChargeServiceImpl implements ChargeService {
                     stopDelayService.addToDelayQueue(delayChargeOrder.setEndTime(endTime));
                 }
                 // 切换数据源,修改设备状态为预约中
-                updateEquipmentStatus(connectorId);
+                updateEquipmentAndConnectorStatus(connectorId);
                 LOGGER.info("预约充电成功,用户:{},订单号:{}", userId, order.getStartChargeSeq());
                 return Map.of("startChargeSeq", order.getStartChargeSeq());
             } else {
@@ -289,11 +258,86 @@ public class ChargeServiceImpl implements ChargeService {
             }
         }
 
+        // 传递给EN+的余额要小于实际余额,防止订单超扣的情况,这里少传0.5元
+        // TODO: 2023-11-30 快充这里考虑过充的金额要提高
+        var amount = account.getBalance() - 50;
+        return startCharge(order, connectorId, amount);
+
+    }
+
+
+    /**
+     * 启动充电校验流程
+     *
+     * @param userId
+     * @param connectorId
+     * @param isBooking
+     * @param startTime
+     * @return
+     */
+    private Account checkCharge(Long userId, String connectorId, Boolean isBooking, LocalDateTime startTime) {
+        if (CommUtil.isEmptyOrNull(connectorId)) {
+            throw new BusinessException("请输入正确的设备编号");
+        }
+
+        // 设备是否插枪
+        if (ConnectorStatusCache.INSTANCE.get(connectorId) == EquipmentInfo.SERVICE_STATUS_空闲) {
+            throw new BusinessException("请插入充电枪");
+        }
+
+        if (isBooking) {
+            // 预约时间不能超过未来24H
+            if (TimeUnit.SECONDS.convert(Duration.between(LocalDateTime.now(), startTime)) > 3600 * 24) {
+                throw new BusinessException("预约充电启动时间不能超过未来24小时");
+            }
+            // 预约充电通过connectorId查询预约中的订单
+            var bookingOrder = chargeOrderService.lambdaQuery().eq(ChargeOrder::getUserId, userId).eq(ChargeOrder::getConnectorId, connectorId).eq(ChargeOrder::getIsBooking, ChargeOrder.IS_BOOKING_是).eq(ChargeOrder::getOrderStatus, ChargeOrder.ORDER_STATUS_未知).eq(ChargeOrder::getChargeStatus, ChargeOrder.CHARGE_STATUS_预约中).one();
+            if (bookingOrder != null) {
+                LOGGER.error("用户:{}存在进行中的订单:{}", userId, bookingOrder.getStartChargeSeq());
+                throw new BusinessException(ResponseEnum.ORDER_IN_BOOKING);
+            }
+        }
+
+        // 当前用户是否有正在进行中、预约中、启动中的订单
+        var chargeOrder = chargeOrderService.getChargingOrderByUserId(userId);
+        if (chargeOrder != null) {
+            // 预约中的订单到了启动时间则直接启动,忽略校验
+            if (!(chargeOrder.getChargeStatus().equals(ChargeOrder.CHARGE_STATUS_预约中) && chargeOrder.getStartTime().isBefore(LocalDateTime.now()))) {
+                LOGGER.error("用户:{}存在进行中的订单:{}", userId, chargeOrder.getStartChargeSeq());
+                throw new BusinessException(ResponseEnum.ORDER_IN_PROGRESS);
+            }
+        }
+
+        // 查询用户余额
+        var account = accountService.getAccountByUserId(userId);
+        if (account.getBalance() <= 200) {
+            LOGGER.error("用户:{}余额不足2元,余额:{}", userId, account.getBalance());
+            throw new BusinessException(ResponseEnum.INSUFFICIENT_USER_BALANCE);
+        }
+
+        return account;
+    }
+
+    /**
+     * 启动充电
+     *
+     * @param order
+     * @param connectorId
+     * @param amount
+     * @return
+     */
+    private Map<String, String> startCharge(ChargeOrder order, String connectorId, int amount) {
+
+        // 请求设备认证
+        var equipAuth = enPlusService.queryEquipAuth(connectorId, order.getStartChargeSeq());
+
         if (equipAuth.containsKey("SuccStat") && equipAuth.getIntValue("SuccStat") == 0) {
             // 启动充电
-            JSONObject startCharge = null;
+            JSONObject startCharge;
 
             try {
+                // 二维码文本
+                var qrCode = "";
                 startCharge = enPlusService.queryStartCharge(order.getStartChargeSeq(), connectorId, qrCode, amount);
             } catch (Exception e) {
                 // 这里可能超时,忽略
@@ -303,11 +347,7 @@ public class ChargeServiceImpl implements ChargeService {
 
             if (startCharge != null && startCharge.containsKey("SuccStat") && startCharge.getIntValue("SuccStat") == 0) {
                 // 启动成功,更新充电订单状态
-                chargeOrderService.lambdaUpdate()
-                        .set(ChargeOrder::getIsBooking, ChargeOrder.IS_BOOKING_否)
-                        .set(ChargeOrder::getChargeStatus, startCharge.getIntValue("StartChargeSeqStat"))
-                        .eq(ChargeOrder::getStartChargeSeq, order.getStartChargeSeq())
-                        .update();
+                chargeOrderService.lambdaUpdate().set(ChargeOrder::getIsBooking, ChargeOrder.IS_BOOKING_否).set(ChargeOrder::getChargeStatus, startCharge.getIntValue("StartChargeSeqStat")).eq(ChargeOrder::getStartChargeSeq, order.getStartChargeSeq()).update();
                 return Map.of("startChargeSeq", order.getStartChargeSeq());
             } else {
                 // 启动充电失败
@@ -350,12 +390,12 @@ public class ChargeServiceImpl implements ChargeService {
      * @param connectorId
      */
     @Override
-    public void updateEquipmentStatus(String connectorId) {
+    public void updateEquipmentAndConnectorStatus(String connectorId) {
         // 手动切换数据源
         DynamicDataSourceContextHolder.push("db-admin");
         equipmentInfoService.lambdaUpdate().set(EquipmentInfo::getServiceStatus, EquipmentInfo.SERVICE_STATUS_预约中).eq(EquipmentInfo::getEquipmentId, connectorId.substring(0, 16)).update();
+        connectorInfoService.lambdaUpdate().set(ConnectorInfo::getStatus, EquipmentInfo.SERVICE_STATUS_预约中).eq(ConnectorInfo::getConnectorId, connectorId).update();
         DynamicDataSourceContextHolder.poll();
-
     }
 
 
@@ -383,17 +423,8 @@ public class ChargeServiceImpl implements ChargeService {
             }
 
             // 更新订单信息
-            chargeOrderService.lambdaUpdate()
-                    .set(ChargeOrder::getSoc, data.getDoubleValue("Soc"))
-                    .set(ChargeOrder::getTotalPower, data.getDoubleValue("TotalPower"))
-                    .set(ChargeOrder::getTotalMoney, (int) ((data.getDouble("TotalMoney") * 100)))
-                    .set(ChargeOrder::getElecMoney, (int) ((data.getDouble("ElecMoney") * 100)))
-                    .set(ChargeOrder::getServiceMoney, (int) ((data.getDouble("SeviceMoney") * 100))) // 这里文档service单词错误,按文档填写
-                    .set(ChargeOrder::getSumPeriod, (int) (data.getIntValue("SumPeriod")))
-                    .set(ChargeOrder::getChargeDetail, data.getString("ChargeDetails"))
-                    .set(ChargeOrder::getChargeStatus, data.getIntValue("StartChargeSeqStat"))
-                    .eq(ChargeOrder::getStartChargeSeq, startChargeSeq)
-                    .update();
+            chargeOrderService.lambdaUpdate().set(ChargeOrder::getSoc, data.getDoubleValue("Soc")).set(ChargeOrder::getTotalPower, data.getDoubleValue("TotalPower")).set(ChargeOrder::getTotalMoney, (int) ((data.getDouble("TotalMoney") * 100))).set(ChargeOrder::getElecMoney, (int) ((data.getDouble("ElecMoney") * 100))).set(ChargeOrder::getServiceMoney, (int) ((data.getDouble("SeviceMoney") * 100))) // 这里文档service单词错误,按文档填写
+                    .set(ChargeOrder::getSumPeriod, (int) (data.getIntValue("SumPeriod"))).set(ChargeOrder::getChargeDetail, data.getString("ChargeDetails")).set(ChargeOrder::getChargeStatus, data.getIntValue("StartChargeSeqStat")).eq(ChargeOrder::getStartChargeSeq, startChargeSeq).update();
 
             chargeOrder.setSoc(data.getDoubleValue("Soc"));
             chargeOrder.setTotalPower(data.getDoubleValue("TotalPower"));
@@ -425,7 +456,7 @@ public class ChargeServiceImpl implements ChargeService {
         } else if (connectorId.length() == 6) {
             // 查询EN+设备SN
             var equipmentRelation = equipmentRelationService.getByShortId(connectorId);
-            connectorId = equipmentRelation.getEquipmentId();
+            connectorId = equipmentRelation.getConnectorId();
             stationId = equipmentRelation.getStationId();
             if (connectorId.length() == 16) {
                 // 如果是16位,末尾补1作为单枪枪号
@@ -446,7 +477,7 @@ public class ChargeServiceImpl implements ChargeService {
         } else if (connectorId.length() == 6) {
             // 查询EN+设备SN
             var equipmentRelation = equipmentRelationService.getByShortId(connectorId);
-            connectorId = equipmentRelation.getEquipmentId();
+            connectorId = equipmentRelation.getConnectorId();
             if (connectorId.length() == 16) {
                 // 如果是16位,末尾补1作为单枪枪号
                 connectorId = connectorId.concat("1");

+ 1 - 0
service/src/main/java/com/kym/service/wechat/impl/WxPayServiceImpl.java

@@ -350,6 +350,7 @@ public class WxPayServiceImpl implements WxPayService {
                 var chargingOrder = chargeOrderService.getChargingOrderByUserId(walletDetail.getUserId());
                 if (chargingOrder != null) {
                     var account = accountService.getAccountByUserId(walletDetail.getUserId());
+                    // TODO: 2023-11-30 快充这里考虑过充的金额要提高 
                     var res = enPlusService.updateBalanceByQueryEquipChargeStatus(chargingOrder.getStartChargeSeq(), account.getBalance() - 50);
                     LOGGER.info("用户:{}充电过程中充值,已更新en+充电金额,en+返回数据:{}", account.getUserId(), res);
                 }