Quellcode durchsuchen

feat(applet): 新增充电终端及价格列表接口

- 在AppService接口中增加获取充电终端列表和价格列表方法定义
- 实现查询电站设备与终端状态统计功能,返回充电终端详细信息
- 根据电站ID查询价格策略及时段明细,计算合计充电价格并标识当前时段
- 设备类型、状态、时段标志均支持名称转换显示
- 新增AppConnectorListVO及AppStationPriceListVO用于接口数据封装
- 在控制器中增加对应的REST接口,支持小程序端调用终端列表与价格列表数据
SheepHy vor 23 Stunden
Ursprung
Commit
2b8a949dbc

+ 26 - 0
src/main/java/com/zsElectric/boot/business/controller/applet/AppletStationController.java

@@ -1,6 +1,8 @@
 package com.zsElectric.boot.business.controller.applet;
 
+import com.zsElectric.boot.business.model.vo.AppletConnectorListVO;
 import com.zsElectric.boot.business.model.vo.AppletStationDetailVO;
+import com.zsElectric.boot.business.model.vo.AppletStationPriceListVO;
 import com.zsElectric.boot.business.service.AppletHomeService;
 import com.zsElectric.boot.core.web.Result;
 import io.swagger.v3.oas.annotations.Operation;
@@ -37,4 +39,28 @@ public class AppletStationController {
             @RequestParam(required = false) BigDecimal latitude) {
         return Result.success(appletHomeService.getStationDetail(stationId, longitude, latitude));
     }
+
+    /**
+     * 获取充电终端列表
+     *
+     * @param stationId 站点ID
+     * @return 充电终端列表
+     */
+    @Operation(summary = "获取充电终端列表")
+    @GetMapping("/connectors")
+    public Result<AppletConnectorListVO> getConnectorList(@RequestParam Long stationId) {
+        return Result.success(appletHomeService.getConnectorList(stationId));
+    }
+
+    /**
+     * 获取电站价格列表
+     *
+     * @param stationId 站点ID
+     * @return 电站价格列表
+     */
+    @Operation(summary = "获取电站价格列表")
+    @GetMapping("/prices")
+    public Result<AppletStationPriceListVO> getStationPriceList(@RequestParam Long stationId) {
+        return Result.success(appletHomeService.getStationPriceList(stationId));
+    }
 }

+ 72 - 0
src/main/java/com/zsElectric/boot/business/model/vo/AppletConnectorListVO.java

@@ -0,0 +1,72 @@
+package com.zsElectric.boot.business.model.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 小程序电站充电终端列表VO
+ *
+ * @author system
+ * @since 2025-12-18
+ */
+@Getter
+@Setter
+@Schema(description = "小程序电站充电终端列表VO")
+public class AppletConnectorListVO implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "站点ID")
+    private Long stationId;
+
+    @Schema(description = "站点名称")
+    private String stationName;
+
+    @Schema(description = "空闲终端数")
+    private Integer idleCount;
+
+    @Schema(description = "占用终端数")
+    private Integer occupiedCount;
+
+    @Schema(description = "离线终端数")
+    private Integer offlineCount;
+
+    @Schema(description = "充电终端列表")
+    private List<ConnectorItemVO> connectorList;
+
+    /**
+     * 充电终端信息
+     */
+    @Getter
+    @Setter
+    @Schema(description = "充电终端信息")
+    public static class ConnectorItemVO implements Serializable {
+
+        @Serial
+        private static final long serialVersionUID = 1L;
+
+        @Schema(description = "充电终端ID")
+        private Long connectorId;
+
+        @Schema(description = "终端名称(如:101号直流充电桩)")
+        private String connectorName;
+
+        @Schema(description = "设备分类(如:直流设备)")
+        private String equipmentType;
+
+        @Schema(description = "终端编码")
+        private String connectorCode;
+
+        @Schema(description = "状态:0-离网 1-空闲 2-占用(未充电) 3-占用(充电中) 4-占用(预约锁定) 255-故障")
+        private Integer status;
+
+        @Schema(description = "状态名称")
+        private String statusName;
+    }
+}

+ 67 - 0
src/main/java/com/zsElectric/boot/business/model/vo/AppletStationPriceListVO.java

@@ -0,0 +1,67 @@
+package com.zsElectric.boot.business.model.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 小程序电站价格列表VO
+ *
+ * @author system
+ * @since 2025-12-18
+ */
+@Getter
+@Setter
+@Schema(description = "小程序电站价格列表VO")
+public class AppletStationPriceListVO implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "站点ID")
+    private Long stationId;
+
+    @Schema(description = "站点名称")
+    private String stationName;
+
+    @Schema(description = "价格列表")
+    private List<PriceItemVO> priceList;
+
+    /**
+     * 时段价格信息
+     */
+    @Getter
+    @Setter
+    @Schema(description = "时段价格信息")
+    public static class PriceItemVO implements Serializable {
+
+        @Serial
+        private static final long serialVersionUID = 1L;
+
+        @Schema(description = "时段(如:00:00-08:00)")
+        private String timePeriod;
+
+        @Schema(description = "时段标志(1-尖,2-峰,3-平,4-谷)")
+        private Integer periodFlag;
+
+        @Schema(description = "时段标志名称(尖/峰/平/谷)")
+        private String periodFlagName;
+
+        @Schema(description = "电费(元/度)")
+        private BigDecimal elecPrice;
+
+        @Schema(description = "服务费(元/度)")
+        private BigDecimal servicePrice;
+
+        @Schema(description = "合计充电价(元/度)= 电费 + 服务费")
+        private BigDecimal totalPrice;
+
+        @Schema(description = "是否当前时段")
+        private Boolean currentPeriod;
+    }
+}

+ 16 - 0
src/main/java/com/zsElectric/boot/business/service/AppletHomeService.java

@@ -2,7 +2,9 @@ package com.zsElectric.boot.business.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.zsElectric.boot.business.model.query.StationInfoQuery;
+import com.zsElectric.boot.business.model.vo.AppletConnectorListVO;
 import com.zsElectric.boot.business.model.vo.AppletStationDetailVO;
+import com.zsElectric.boot.business.model.vo.AppletStationPriceListVO;
 import com.zsElectric.boot.business.model.vo.BannerInfoVO;
 import com.zsElectric.boot.business.model.vo.StationInfoMapVO;
 import com.zsElectric.boot.business.model.vo.StationInfoVO;
@@ -36,4 +38,18 @@ public interface AppletHomeService {
      * @return 电站详情
      */
     AppletStationDetailVO getStationDetail(Long stationId, BigDecimal longitude, BigDecimal latitude);
+
+    /**
+     * 获取电站充电终端列表
+     * @param stationId 站点ID
+     * @return 充电终端列表
+     */
+    AppletConnectorListVO getConnectorList(Long stationId);
+
+    /**
+     * 获取电站价格列表
+     * @param stationId 站点ID
+     * @return 价格列表
+     */
+    AppletStationPriceListVO getStationPriceList(Long stationId);
 }

+ 275 - 0
src/main/java/com/zsElectric/boot/business/service/impl/AppletHomeServiceImpl.java

@@ -9,12 +9,18 @@ import com.zsElectric.boot.business.mapper.UserFirmMapper;
 import com.zsElectric.boot.charging.entity.ThirdPartyConnectorInfo;
 import com.zsElectric.boot.charging.entity.ThirdPartyEquipmentInfo;
 import com.zsElectric.boot.charging.mapper.ThirdPartyConnectorInfoMapper;
+import com.zsElectric.boot.charging.entity.ThirdPartyEquipmentPricePolicy;
+import com.zsElectric.boot.charging.entity.ThirdPartyPolicyInfo;
 import com.zsElectric.boot.charging.entity.ThirdPartyStationInfo;
 import com.zsElectric.boot.business.mapper.ThirdPartyEquipmentInfoMapper;
+import com.zsElectric.boot.charging.mapper.ThirdPartyEquipmentPricePolicyMapper;
+import com.zsElectric.boot.charging.mapper.ThirdPartyPolicyInfoMapper;
 import com.zsElectric.boot.business.model.entity.BannerInfo;
 import com.zsElectric.boot.business.model.entity.UserFirm;
 import com.zsElectric.boot.business.model.query.StationInfoQuery;
+import com.zsElectric.boot.business.model.vo.AppletConnectorListVO;
 import com.zsElectric.boot.business.model.vo.AppletStationDetailVO;
+import com.zsElectric.boot.business.model.vo.AppletStationPriceListVO;
 import com.zsElectric.boot.business.model.vo.BannerInfoVO;
 import com.zsElectric.boot.business.model.vo.StationInfoMapVO;
 import com.zsElectric.boot.business.model.vo.StationInfoVO;
@@ -44,6 +50,8 @@ public class AppletHomeServiceImpl implements AppletHomeService {
     private final BannerInfoConverter bannerInfoConverter;
     private final ThirdPartyConnectorInfoMapper thirdPartyConnectorInfoMapper;
     private final ThirdPartyEquipmentInfoMapper thirdPartyEquipmentInfoMapper;
+    private final ThirdPartyEquipmentPricePolicyMapper thirdPartyEquipmentPricePolicyMapper;
+    private final ThirdPartyPolicyInfoMapper thirdPartyPolicyInfoMapper;
 
     /**
      * 时间格式化器 HHmmss
@@ -268,4 +276,271 @@ public class AppletHomeServiceImpl implements AppletHomeService {
         
         return result;
     }
+
+    @Override
+    public AppletConnectorListVO getConnectorList(Long stationId) {
+        // 查询站点信息
+        ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(stationId);
+        if (stationInfo == null) {
+            return null;
+        }
+        
+        AppletConnectorListVO result = new AppletConnectorListVO();
+        result.setStationId(stationId);
+        result.setStationName(stationInfo.getStationName());
+        
+        // 根据站点stationId查询设备列表
+        List<ThirdPartyEquipmentInfo> equipmentList = thirdPartyEquipmentInfoMapper.selectList(
+                new LambdaQueryWrapper<ThirdPartyEquipmentInfo>()
+                        .eq(ThirdPartyEquipmentInfo::getStationId, stationInfo.getStationId())
+        );
+        
+        // 构建设备ID到设备类型的映射
+        Map<String, Integer> equipmentTypeMap = equipmentList.stream()
+                .collect(Collectors.toMap(
+                        ThirdPartyEquipmentInfo::getEquipmentId,
+                        e -> e.getEquipmentType() != null ? e.getEquipmentType() : 0,
+                        (v1, v2) -> v1
+                ));
+        
+        // 查询充电接口信息
+        List<ThirdPartyConnectorInfo> connectorList = new ArrayList<>();
+        if (!equipmentList.isEmpty()) {
+            List<String> equipmentIds = equipmentList.stream()
+                    .map(ThirdPartyEquipmentInfo::getEquipmentId)
+                    .collect(Collectors.toList());
+            connectorList = thirdPartyConnectorInfoMapper.selectList(
+                    new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
+                            .in(ThirdPartyConnectorInfo::getEquipmentId, equipmentIds)
+            );
+        }
+        
+        // 统计终端状态
+        int idleCount = 0;
+        int occupiedCount = 0;
+        int offlineCount = 0;
+        
+        List<AppletConnectorListVO.ConnectorItemVO> connectorVOList = new ArrayList<>();
+        for (ThirdPartyConnectorInfo connector : connectorList) {
+            AppletConnectorListVO.ConnectorItemVO vo = new AppletConnectorListVO.ConnectorItemVO();
+            vo.setConnectorId(connector.getId());
+            vo.setConnectorName(connector.getConnectorName());
+            vo.setConnectorCode(connector.getConnectorId());
+            
+            // 设备分类
+            Integer equipmentType = equipmentTypeMap.get(connector.getEquipmentId());
+            vo.setEquipmentType(getEquipmentTypeName(equipmentType));
+            
+            // 状态处理
+            Integer connectorStatus = connector.getStatus();
+            if (connectorStatus == null) {
+                connectorStatus = 0;
+            }
+            vo.setStatus(connectorStatus);
+            vo.setStatusName(getStatusName(connectorStatus));
+            
+            // 统计
+            switch (connectorStatus) {
+                case 1:
+                    idleCount++;
+                    break;
+                case 2:
+                case 3:
+                case 4:
+                    occupiedCount++;
+                    break;
+                default:
+                    offlineCount++;
+            }
+            
+            connectorVOList.add(vo);
+        }
+        
+        result.setConnectorList(connectorVOList);
+        result.setIdleCount(idleCount);
+        result.setOccupiedCount(occupiedCount);
+        result.setOfflineCount(offlineCount);
+        
+        return result;
+    }
+
+    @Override
+    public AppletStationPriceListVO getStationPriceList(Long stationId) {
+        // 查询站点信息
+        ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(stationId);
+        if (stationInfo == null) {
+            return null;
+        }
+        
+        AppletStationPriceListVO result = new AppletStationPriceListVO();
+        result.setStationId(stationId);
+        result.setStationName(stationInfo.getStationName());
+        
+        // 获取当前时间(HHmmss格式)
+        String currentTime = LocalTime.now().format(TIME_FORMATTER);
+        
+        // 查询站点对应的价格策略
+        // 1. 先查询充电接口
+        ThirdPartyConnectorInfo connector = thirdPartyConnectorInfoMapper.selectOne(
+                new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
+                        .eq(ThirdPartyConnectorInfo::getStationId, stationInfo.getStationId())
+                        .last("LIMIT 1")
+        );
+        
+        if (connector == null) {
+            result.setPriceList(new ArrayList<>());
+            return result;
+        }
+        
+        // 2. 查询价格策略
+        ThirdPartyEquipmentPricePolicy pricePolicy = thirdPartyEquipmentPricePolicyMapper.selectOne(
+                new LambdaQueryWrapper<ThirdPartyEquipmentPricePolicy>()
+                        .eq(ThirdPartyEquipmentPricePolicy::getConnectorId, connector.getConnectorId())
+                        .eq(ThirdPartyEquipmentPricePolicy::getIsDeleted, 0)
+                        .last("LIMIT 1")
+        );
+        
+        if (pricePolicy == null) {
+            result.setPriceList(new ArrayList<>());
+            return result;
+        }
+        
+        // 3. 查询价格明细列表
+        List<ThirdPartyPolicyInfo> policyInfoList = thirdPartyPolicyInfoMapper.selectList(
+                new LambdaQueryWrapper<ThirdPartyPolicyInfo>()
+                        .eq(ThirdPartyPolicyInfo::getPricePolicyId, pricePolicy.getId())
+                        .eq(ThirdPartyPolicyInfo::getIsDeleted, 0)
+                        .orderByAsc(ThirdPartyPolicyInfo::getStartTime)
+        );
+        
+        // 4. 构建价格列表
+        List<AppletStationPriceListVO.PriceItemVO> priceList = new ArrayList<>();
+        for (int i = 0; i < policyInfoList.size(); i++) {
+            ThirdPartyPolicyInfo policyInfo = policyInfoList.get(i);
+            AppletStationPriceListVO.PriceItemVO priceItem = new AppletStationPriceListVO.PriceItemVO();
+            
+            // 时段格式化:HHmmss -> HH:mm
+            String startTime = formatTime(policyInfo.getStartTime());
+            // 下一个时段的开始时间作为当前时段的结束时间
+            String endTime = (i + 1 < policyInfoList.size()) 
+                    ? formatTime(policyInfoList.get(i + 1).getStartTime()) 
+                    : "24:00";
+            priceItem.setTimePeriod(startTime + "-" + endTime);
+            
+            priceItem.setPeriodFlag(policyInfo.getPeriodFlag());
+            priceItem.setPeriodFlagName(getPeriodFlagName(policyInfo.getPeriodFlag()));
+            priceItem.setElecPrice(policyInfo.getElecPrice());
+            priceItem.setServicePrice(policyInfo.getServicePrice());
+            
+            // 合计充电价 = 电费 + 服务费
+            BigDecimal elecPrice = policyInfo.getElecPrice() != null ? policyInfo.getElecPrice() : BigDecimal.ZERO;
+            BigDecimal servicePrice = policyInfo.getServicePrice() != null ? policyInfo.getServicePrice() : BigDecimal.ZERO;
+            priceItem.setTotalPrice(elecPrice.add(servicePrice));
+            
+            // 判断是否为当前时段
+            priceItem.setCurrentPeriod(isCurrentPeriod(policyInfo.getStartTime(), 
+                    (i + 1 < policyInfoList.size()) ? policyInfoList.get(i + 1).getStartTime() : null, 
+                    currentTime));
+            
+            priceList.add(priceItem);
+        }
+        
+        result.setPriceList(priceList);
+        return result;
+    }
+    
+    /**
+     * 获取设备类型名称
+     */
+    private String getEquipmentTypeName(Integer equipmentType) {
+        if (equipmentType == null) {
+            return "未知";
+        }
+        switch (equipmentType) {
+            case 1:
+                return "直流设备";
+            case 2:
+                return "交流设备";
+            case 3:
+                return "交直流一体设备";
+            case 4:
+                return "无线设备";
+            case 5:
+                return "其他";
+            default:
+                return "未知";
+        }
+    }
+    
+    /**
+     * 获取状态名称
+     */
+    private String getStatusName(Integer status) {
+        if (status == null) {
+            return "未知";
+        }
+        switch (status) {
+            case 0:
+                return "离网";
+            case 1:
+                return "空闲";
+            case 2:
+                return "占用(未充电)";
+            case 3:
+                return "占用(充电中)";
+            case 4:
+                return "占用(预约锁定)";
+            case 255:
+                return "故障";
+            default:
+                return "未知";
+        }
+    }
+    
+    /**
+     * 获取时段标志名称
+     */
+    private String getPeriodFlagName(Integer periodFlag) {
+        if (periodFlag == null) {
+            return "";
+        }
+        switch (periodFlag) {
+            case 1:
+                return "尖";
+            case 2:
+                return "峰";
+            case 3:
+                return "平";
+            case 4:
+                return "谷";
+            default:
+                return "";
+        }
+    }
+    
+    /**
+     * 格式化时间 HHmmss -> HH:mm
+     */
+    private String formatTime(String time) {
+        if (time == null || time.length() < 4) {
+            return "00:00";
+        }
+        return time.substring(0, 2) + ":" + time.substring(2, 4);
+    }
+    
+    /**
+     * 判断是否为当前时段
+     */
+    private boolean isCurrentPeriod(String startTime, String nextStartTime, String currentTime) {
+        if (startTime == null || currentTime == null) {
+            return false;
+        }
+        // 当前时间 >= 开始时间 且 当前时间 < 下一个时段开始时间
+        if (currentTime.compareTo(startTime) >= 0) {
+            if (nextStartTime == null || currentTime.compareTo(nextStartTime) < 0) {
+                return true;
+            }
+        }
+        return false;
+    }
 }