Bladeren bron

feat: 新增轻量地图站点接口与站点卡片按需查询接口

- GET /charge/mapStation:仅返回站点基础信息与当前时段费率,跳过枪统计与活动查询,供首页地图 marker 使用

- GET /charge/stationCard:按需批量返回站点空闲桩数量/活动信息,点击站点图标或展开列表时查询

- listStationForApp 重构为复用 buildSimpleStationVo/fillAvailableParkingNum/fillActivityList,行为不变
skyline 3 weken geleden
bovenliggende
commit
d11e5feabc

+ 26 - 0
miniapp/src/main/java/com/kym/miniapp/controller/ChargeController.java

@@ -20,6 +20,7 @@ import org.springframework.format.annotation.DateTimeFormat;
 import org.springframework.web.bind.annotation.*;
 
 import java.time.LocalDateTime;
+import java.util.Arrays;
 import java.util.Map;
 
 
@@ -83,6 +84,31 @@ public class ChargeController {
         return R.success(stationService.listStationForApp(params));
     }
 
+    /**
+     * 地图站点列表(轻量:仅站点基础信息+当前时段费率,不含枪统计/活动信息),
+     * 首页地图 marker 只显示位置图标,避免首屏加载大量数据
+     *
+     * @param params
+     * @return
+     */
+    @GetMapping("/mapStation")
+    @SaIgnore
+    R<?> mapStation(@ModelAttribute StationQueryParam params) {
+        return R.success(stationService.listStationForMap(params));
+    }
+
+    /**
+     * 站点卡片信息(空闲桩数量/活动),地图页点击站点图标或展开列表时按需批量查询
+     *
+     * @param ids 逗号分隔的站点ID
+     * @return
+     */
+    @GetMapping("/stationCard")
+    @SaIgnore
+    R<?> stationCard(@RequestParam("stationIds") String ids) {
+        return R.success(stationService.listStationCard(Arrays.asList(ids.split(","))));
+    }
+
     /**
      * 站点信息(包含充电枪信息)
      *

+ 11 - 0
service/src/main/java/com/kym/service/admin/StationService.java

@@ -53,6 +53,17 @@ public interface StationService extends MPJBaseService<Station> {
 
     PageBean<SimpleStationVo> listStationForApp(StationQueryParam params);
 
+    /**
+     * APP首页地图轻量接口:仅返回站点基础信息与当前时段费率(不含枪统计与活动信息),
+     * 供地图 marker 展示,避免首页加载大量数据
+     */
+    PageBean<SimpleStationVo> listStationForMap(StationQueryParam params);
+
+    /**
+     * 站点卡片信息(空闲桩数量/活动),地图页点击站点图标或展开列表时按需批量查询
+     */
+    List<SimpleStationVo> listStationCard(List<String> stationIds);
+
     DetailStationVo stationInfoByShortId(String shortId);
 
     DetailStationVo stationInfoByConnectorId(String connectorId);

+ 86 - 34
service/src/main/java/com/kym/service/admin/impl/StationServiceImpl.java

@@ -208,49 +208,103 @@ public class StationServiceImpl extends MyBaseServiceImpl<StationMapper, Station
         queryWrapper.select(Station::getStationId, Station::getStationName, Station::getAddress, Station::getLocation,
                 Station::getStationStatus, Station::getParkingNum, Station::getElectricityFee, Station::getServiceFee, Station::getParkFee);
         queryWrapper.in(CommUtil.isNotEmptyAndNull(params.getStationIdList()), Station::getStationId, params.getStationIdList());
-        var stationVoList = new ArrayList<SimpleStationVo>();
-        var stationList = list(queryWrapper);
-        for (var station : stationList) {
-            var simpleStationVo = new SimpleStationVo();
-            BeanUtils.copyProperties(station, simpleStationVo);
-            // 计算距离,单位m
-            simpleStationVo.setDistance(GeodsyDistanceUtils.getDistance(
-                    station.getLocation().getDoubleValue("stationLng"),
-                    station.getLocation().getDoubleValue("stationLat"),
-                    params.getLongitude(),
-                    params.getLatitude(),
-                    2));
-            // 站点费率
-            var policyInfoList = KymCache.INSTANCE.getStationPolicyInfo(station.getStationId());
-            CommUtil.asserts(policyInfoList != null, "站点费率信息为空");
-
-            // 根据当前时间获取当前策略
-            var now = LocalTime.now();
-            if (policyInfoList.size() == 1) {
-                simpleStationVo.setCurrentPolicyInfo(policyInfoList.get(0));
-            } else {
-                policyInfoList.stream()
-                        .filter(policyInfo -> policyInfo.getStartTime().isBefore(now))
-                        .max(Comparator.comparing(PlatformPolicyInfoVo::getStartTime))
-                        .ifPresent(simpleStationVo::setCurrentPolicyInfo);
-            }
-            stationVoList.add(simpleStationVo);
-        }
+        var stationVoList = list(queryWrapper).stream()
+                .map(station -> buildSimpleStationVo(station, params))
+                .collect(Collectors.toCollection(ArrayList::new));
         // 按照距离由近到远排序
         stationVoList.sort(Comparator.comparing(SimpleStationVo::getDistance));
+        // 计算并填充站点空闲数量
+        fillAvailableParkingNum(stationVoList);
+        // 填充站点活动信息
+        fillActivityList(stationVoList);
+        return new PageBean<>(stationVoList);
+    }
+
+    @Override
+    public PageBean<SimpleStationVo> listStationForMap(StationQueryParam params) {
+        PageHelper.startPage(params.getPageNum(), params.getPageSize());
+        // 站点列表(仅查询地图展示所需的基础字段)
+        LambdaQueryWrapper<Station> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.select(Station::getStationId, Station::getStationName, Station::getAddress, Station::getLocation,
+                Station::getStationStatus, Station::getParkingNum, Station::getElectricityFee, Station::getServiceFee, Station::getParkFee);
+        queryWrapper.in(CommUtil.isNotEmptyAndNull(params.getStationIdList()), Station::getStationId, params.getStationIdList());
+        var stationVoList = list(queryWrapper).stream()
+                .map(station -> buildSimpleStationVo(station, params))
+                .collect(Collectors.toCollection(ArrayList::new));
+        // 按照距离由近到远排序
+        stationVoList.sort(Comparator.comparing(SimpleStationVo::getDistance));
+        // 不查询枪统计与活动信息,由前端点击站点时通过 listStationCard 按需查询
+        return new PageBean<>(stationVoList);
+    }
+
+    @Override
+    public List<SimpleStationVo> listStationCard(List<String> stationIds) {
+        if (CommUtil.isEmptyOrNull(stationIds)) {
+            return List.of();
+        }
+        var stationVoList = lambdaQuery()
+                .select(Station::getStationId, Station::getParkingNum)
+                .in(Station::getStationId, stationIds)
+                .list().stream()
+                .map(station -> new SimpleStationVo()
+                        .setStationId(station.getStationId())
+                        .setParkingNum(station.getParkingNum()))
+                .collect(Collectors.toCollection(ArrayList::new));
+        fillAvailableParkingNum(stationVoList);
+        fillActivityList(stationVoList);
+        return stationVoList;
+    }
 
-        // 计算站点空闲数量
+    /**
+     * 组装站点简要信息:基础字段 + 距离 + 当前时段费率
+     */
+    private SimpleStationVo buildSimpleStationVo(Station station, StationQueryParam params) {
+        var simpleStationVo = new SimpleStationVo();
+        BeanUtils.copyProperties(station, simpleStationVo);
+        // 计算距离,单位m
+        simpleStationVo.setDistance(GeodsyDistanceUtils.getDistance(
+                station.getLocation().getDoubleValue("stationLng"),
+                station.getLocation().getDoubleValue("stationLat"),
+                params.getLongitude(),
+                params.getLatitude(),
+                2));
+        // 站点费率
+        var policyInfoList = KymCache.INSTANCE.getStationPolicyInfo(station.getStationId());
+        CommUtil.asserts(policyInfoList != null, "站点费率信息为空");
+
+        // 根据当前时间获取当前策略
+        var now = LocalTime.now();
+        if (policyInfoList.size() == 1) {
+            simpleStationVo.setCurrentPolicyInfo(policyInfoList.get(0));
+        } else {
+            policyInfoList.stream()
+                    .filter(policyInfo -> policyInfo.getStartTime().isBefore(now))
+                    .max(Comparator.comparing(PlatformPolicyInfoVo::getStartTime))
+                    .ifPresent(simpleStationVo::setCurrentPolicyInfo);
+        }
+        return simpleStationVo;
+    }
+
+    /**
+     * 计算并填充站点空闲桩数量
+     */
+    private void fillAvailableParkingNum(List<SimpleStationVo> stationVoList) {
+        if (CommUtil.isEmptyOrNull(stationVoList)) {
+            return;
+        }
         var stationIds = stationVoList.stream().map(SimpleStationVo::getStationId).toList();
         var stationConnectorCountMap = connectorInfoService.lambdaQuery()
                 .in(ConnectorInfo::getStationId, stationIds)
                 .eq(ConnectorInfo::getStatus, EquipmentInfo.SERVICE_STATUS_空闲)
                 .list()
                 .stream().collect(Collectors.groupingBy(ConnectorInfo::getStationId, Collectors.counting()));
-
-        // 填充站点空闲数量
         stationVoList.forEach(stationVo -> stationVo.setAvailableParkingNum(stationConnectorCountMap.getOrDefault(stationVo.getStationId(), 0L).intValue()));
+    }
 
-        // 查询正在进行中的活动和各站点正在进行中的活动 (限充值优惠和优惠券领取活动) todo 性能待优化
+    /**
+     * 填充站点正在进行中的活动 (限充值优惠和优惠券领取活动) todo 性能待优化
+     */
+    private void fillActivityList(List<SimpleStationVo> stationVoList) {
         var rechargeRightsActivityList = activityService.lambdaQuery().eq(Activity::getStatus, Activity.STATUS_进行中).eq(Activity::getDiscountType, Activity.DISCOUNT_TYPE_服务费折扣权益).list();
         var couponActivityList = activityService.getAvailableCouponActivities();
         // Java 21: 使用ArrayList替代Stream.concat提高可读性
@@ -265,8 +319,6 @@ public class StationServiceImpl extends MyBaseServiceImpl<StationMapper, Station
                     v.stream().map(item -> activityList.stream().filter(activity -> activity.getId().equals(item.getActivityId())).findFirst().orElse(null)).toList()));
             stationVoList.forEach(vo -> vo.setActivityList(station2ActivityList.get(vo.getStationId())));
         }
-
-        return new PageBean<>(stationVoList);
     }
 
     @Override