Browse Source

feat(applet): 优化首页及电站详情接口返回结果格式

- 首页地图模式接口改为返回充电站列表,新增排序逻辑,增加经纬度字段支持
- 首页Banner接口统一包装Result返回,规范响应格式
- 新增电站详情接口,支持获取当前价格、企业专享价、充电终端状态及基础信息
- 电站详情接口增加企业用户识别及优惠金额计算逻辑
- 新增AppletStationController类,集中管理充电站相关接口
- 精简策略费用服务实现,优化价格查询逻辑
- 数据库Mapper调整,新增复杂的电站详情和充电站列表SQL查询
- 新增电站详情视图对象和充电终端子视图对象,丰富接口返回数据结构
- 完善实体类FirmInfo,添加余额和累计充值字段支持
SheepHy 1 ngày trước cách đây
mục cha
commit
b11f30a73c

+ 9 - 8
src/main/java/com/zsElectric/boot/business/controller/applet/AppletHomeController.java

@@ -1,5 +1,6 @@
 package com.zsElectric.boot.business.controller.applet;
 
+import com.zsElectric.boot.core.web.Result;
 import io.swagger.v3.oas.annotations.Operation;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.zsElectric.boot.business.model.query.StationInfoQuery;
@@ -37,18 +38,18 @@ public class AppletHomeController {
     }
 
     /**
-     * 首页地图模式-获取最近的充电站信息
+     * 首页地图模式-获取充电站列表(按距离排序)
      *
      * @param longitude 经度
      * @param latitude 纬度
-     * @return 最近的站点信息
+     * @return 站点列表
      */
-    @Operation(summary = "首页地图模式-获取最近的充电站信息")
-    @GetMapping("/getStationInfoMap")
-    public StationInfoMapVO getStationInfoMap(
+    @Operation(summary = "首页地图模式-获取充电站列表(按距离排序)")
+    @PostMapping("/getStationInfoMapList")
+    public Result<List<StationInfoMapVO>> getStationInfoMapList(
             @RequestParam BigDecimal longitude,
             @RequestParam BigDecimal latitude) {
-        return appletHomeService.getStationInfoMap(longitude, latitude);
+        return Result.success(appletHomeService.getStationInfoMapList(longitude, latitude));
     }
 
     /**
@@ -58,7 +59,7 @@ public class AppletHomeController {
      */
     @Operation(summary = "获取首页Banner列表")
     @GetMapping("/getBannerList")
-    public List<BannerInfoVO> getBannerList() {
-        return appletHomeService.getBannerList();
+    public Result<List<BannerInfoVO>> getBannerList() {
+        return Result.success(appletHomeService.getBannerList());
     }
 }

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

@@ -0,0 +1,39 @@
+package com.zsElectric.boot.business.controller.applet;
+
+import com.zsElectric.boot.business.model.vo.AppletStationDetailVO;
+import com.zsElectric.boot.business.service.AppletHomeService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+
+@Tag(name = "充电相关接口")
+@RestController
+@RequestMapping("/applet/v1/station")
+@RequiredArgsConstructor
+public class AppletStationController {
+
+    private final AppletHomeService appletHomeService;
+
+    /**
+     * 获取电站详情
+     *
+     * @param stationId 站点ID
+     * @param longitude 经度(用于计算距离)
+     * @param latitude 纬度(用于计算距离)
+     * @return 电站详情
+     */
+    @Operation(summary = "获取电站详情")
+    @GetMapping("/detail")
+    public AppletStationDetailVO getStationDetail(
+            @RequestParam Long stationId,
+            @RequestParam(required = false) BigDecimal longitude,
+            @RequestParam(required = false) BigDecimal latitude) {
+        return appletHomeService.getStationDetail(stationId, longitude, latitude);
+    }
+}

+ 19 - 0
src/main/java/com/zsElectric/boot/business/mapper/PolicyFeeMapper.java

@@ -2,7 +2,11 @@ package com.zsElectric.boot.business.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.zsElectric.boot.business.model.entity.PolicyFee;
+import com.zsElectric.boot.business.model.vo.TimePeriodPriceVO;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * 策略费用Mapper接口
@@ -13,4 +17,19 @@ import org.apache.ibatis.annotations.Mapper;
 @Mapper
 public interface PolicyFeeMapper extends BaseMapper<PolicyFee> {
 
+    /**
+     * 查询时段价格列表
+     *
+     * @param stationId 站点ID
+     * @param salesType 销售类型(0-平台 1-企业 2-渠道方)
+     * @param firmId 企业ID(销售类型为1时必传)
+     * @param thirdPartyId 渠道方ID(销售类型为2时必传)
+     * @return 时段价格列表
+     */
+    List<TimePeriodPriceVO> selectTimePeriodPriceList(
+            @Param("stationId") Long stationId,
+            @Param("salesType") Integer salesType,
+            @Param("firmId") Long firmId,
+            @Param("thirdPartyId") Long thirdPartyId
+    );
 }

+ 21 - 3
src/main/java/com/zsElectric/boot/business/mapper/ThirdPartyStationInfoMapper.java

@@ -3,6 +3,8 @@ package com.zsElectric.boot.business.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zsElectric.boot.business.model.vo.AppletStationDetailVO;
+import com.zsElectric.boot.business.model.vo.StationInfoMapVO;
 import com.zsElectric.boot.charging.entity.ThirdPartyStationInfo;
 import com.zsElectric.boot.business.model.query.StationInfoQuery;
 import com.zsElectric.boot.business.model.vo.StationInfoVO;
@@ -56,15 +58,31 @@ public interface ThirdPartyStationInfoMapper extends BaseMapper<ThirdPartyStatio
     );
 
     /**
-     * 小程序首页地图模式查询最近的站点信息
+     * 小程序首页地图模式查询站点列表(按距离排序)
      *
      * @param longitude 经度
      * @param latitude 纬度
      * @param currentTime 当前时间(HHmmss格式)
+     * @return 站点列表
+     */
+    java.util.List<StationInfoMapVO> selectStationMapList(
+            @Param("longitude") java.math.BigDecimal longitude,
+            @Param("latitude") java.math.BigDecimal latitude,
+            @Param("currentTime") String currentTime
+    );
+
+    /**
+     * 小程序查询站点详情基本信息
+     *
+     * @param stationId 站点ID
+     * @param longitude 经度
+     * @param latitude 纬度
+     * @param currentTime 当前时间(HHmmss格式)
      * @param firmId 企业ID(可为null)
-     * @return 最近站点信息
+     * @return 站点详情
      */
-    com.zsElectric.boot.business.model.vo.StationInfoMapVO selectNearestStationMap(
+    AppletStationDetailVO selectStationDetail(
+            @Param("stationId") Long stationId,
             @Param("longitude") java.math.BigDecimal longitude,
             @Param("latitude") java.math.BigDecimal latitude,
             @Param("currentTime") String currentTime,

+ 10 - 0
src/main/java/com/zsElectric/boot/business/model/entity/FirmInfo.java

@@ -6,6 +6,8 @@ import lombok.Getter;
 import lombok.Setter;
 import com.baomidou.mybatisplus.annotation.TableName;
 
+import java.math.BigDecimal;
+
 /**
  * 企业信息实体对象
  *
@@ -35,6 +37,14 @@ public class FirmInfo extends BaseEntity {
      * 状态 0 已下线  1 上线中
      */
     private Integer status;
+    /**
+     * 当前余额
+     */
+    private BigDecimal balance;
+    /**
+     * 累计充值
+     */
+    private BigDecimal totalRecharge;
     /**
      * 创建人
      */

+ 123 - 0
src/main/java/com/zsElectric/boot/business/model/vo/AppletStationDetailVO.java

@@ -0,0 +1,123 @@
+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;
+
+/**
+ * 小程序电站详情视图对象
+ *
+ * @author system
+ * @since 2025-12-17
+ */
+@Getter
+@Setter
+@Schema(description = "小程序电站详情视图对象")
+public class AppletStationDetailVO implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "站点ID")
+    private Long stationId;
+
+    @Schema(description = "站点名称")
+    private String stationName;
+
+    @Schema(description = "提示语/标签(如:充电减免2小时停车费,超出部分按每小时3元计费)")
+    private String tips;
+
+    @Schema(description = "距离(km)")
+    private BigDecimal distance;
+
+    @Schema(description = "详细地址")
+    private String address;
+
+    @Schema(description = "站点图片列表(JSON数组)")
+    private String pictures;
+
+    // ========== 费用信息 ==========
+
+    @Schema(description = "当前价(元/度)")
+    private BigDecimal currentPrice;
+
+    @Schema(description = "当前时段(如:峰10:00-13:00)")
+    private String currentPeriod;
+
+    @Schema(description = "企业专享价(元/度)")
+    private BigDecimal enterprisePrice;
+
+    @Schema(description = "原价/划线价(元/度)")
+    private BigDecimal originalPrice;
+
+    @Schema(description = "单笔预计省(元)")
+    private BigDecimal estimatedSaving;
+
+    @Schema(description = "是否显示特惠价标签")
+    private Boolean showSpecialPriceTag;
+
+    @Schema(description = "是否企业用户")
+    private Boolean firmUser;
+
+    // ========== 充电终端统计 ==========
+
+    @Schema(description = "空闲终端数")
+    private Integer idleCount;
+
+    @Schema(description = "占用终端数")
+    private Integer occupiedCount;
+
+    @Schema(description = "离线终端数")
+    private Integer offlineCount;
+
+    @Schema(description = "充电终端列表")
+    private List<ConnectorInfoVO> connectorList;
+
+    // ========== 电站信息 ==========
+
+    @Schema(description = "营业时间(如:周一至周日 00:00-24:00)")
+    private String businessHours;
+
+    @Schema(description = "服务提供方")
+    private String serviceProvider;
+
+    @Schema(description = "发票提供方")
+    private String invoiceProvider;
+
+    @Schema(description = "客服热线")
+    private String customerServiceHotline;
+
+    /**
+     * 充电终端信息
+     */
+    @Getter
+    @Setter
+    @Schema(description = "充电终端信息")
+    public static class ConnectorInfoVO 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-占用")
+        private Integer status;
+
+        @Schema(description = "状态名称")
+        private String statusName;
+    }
+}

+ 4 - 0
src/main/java/com/zsElectric/boot/business/model/vo/StationInfoMapVO.java

@@ -14,4 +14,8 @@ public class StationInfoMapVO extends StationInfoVO{
     private BigDecimal parkingFee;
     @Schema(description = "地址")
     private String address;
+    @Schema(description = "经度")
+    private BigDecimal longitude;
+    @Schema(description = "纬度")
+    private BigDecimal latitude;
 }

+ 12 - 2
src/main/java/com/zsElectric/boot/business/service/AppletHomeService.java

@@ -2,6 +2,7 @@ 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.AppletStationDetailVO;
 import com.zsElectric.boot.business.model.vo.BannerInfoVO;
 import com.zsElectric.boot.business.model.vo.StationInfoMapVO;
 import com.zsElectric.boot.business.model.vo.StationInfoVO;
@@ -17,13 +18,22 @@ public interface AppletHomeService {
     IPage<StationInfoVO> getStationInfoPage(StationInfoQuery queryParams);
 
     /**
-     * 首页地图模式
+     * 首页地图模式-获取站点列表(按距离排序)
      * */
-    StationInfoMapVO getStationInfoMap(BigDecimal longitude, BigDecimal latitude);
+    java.util.List<StationInfoMapVO> getStationInfoMapList(BigDecimal longitude, BigDecimal latitude);
 
     /**
      * 获取启用状态的Banner列表
      * @return Banner列表
      */
     java.util.List<BannerInfoVO> getBannerList();
+
+    /**
+     * 获取电站详情
+     * @param stationId 站点ID
+     * @param longitude 经度(用于计算距离)
+     * @param latitude 纬度(用于计算距离)
+     * @return 电站详情
+     */
+    AppletStationDetailVO getStationDetail(Long stationId, BigDecimal longitude, BigDecimal latitude);
 }

+ 104 - 4
src/main/java/com/zsElectric/boot/business/service/impl/AppletHomeServiceImpl.java

@@ -6,9 +6,13 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.zsElectric.boot.business.mapper.BannerInfoMapper;
 import com.zsElectric.boot.business.mapper.ThirdPartyStationInfoMapper;
 import com.zsElectric.boot.business.mapper.UserFirmMapper;
+import com.zsElectric.boot.charging.entity.ThirdPartyConnectorInfo;
+import com.zsElectric.boot.charging.mapper.ThirdPartyConnectorInfoMapper;
+import com.zsElectric.boot.charging.entity.ThirdPartyStationInfo;
 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.AppletStationDetailVO;
 import com.zsElectric.boot.business.model.vo.BannerInfoVO;
 import com.zsElectric.boot.business.model.vo.StationInfoMapVO;
 import com.zsElectric.boot.business.model.vo.StationInfoVO;
@@ -22,7 +26,10 @@ import org.springframework.stereotype.Service;
 import java.math.BigDecimal;
 import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Service
@@ -33,6 +40,7 @@ public class AppletHomeServiceImpl implements AppletHomeService {
     private final UserFirmMapper userFirmMapper;
     private final BannerInfoMapper bannerInfoMapper;
     private final BannerInfoConverter bannerInfoConverter;
+    private final ThirdPartyConnectorInfoMapper thirdPartyConnectorInfoMapper;
 
     /**
      * 时间格式化器 HHmmss
@@ -76,13 +84,13 @@ public class AppletHomeServiceImpl implements AppletHomeService {
     }
 
     @Override
-    public StationInfoMapVO getStationInfoMap(BigDecimal longitude, BigDecimal latitude) {
+    public List<StationInfoMapVO> getStationInfoMapList(BigDecimal longitude, BigDecimal latitude) {
         // 获取当前时间(HHmmss格式)
         String currentTime = LocalTime.now().format(TIME_FORMATTER);
         
-        // 查询最近的站点
-        return thirdPartyStationInfoMapper.selectNearestStationMap(
-                longitude, latitude, currentTime, null
+        // 查询站点列表(按距离排序)
+        return thirdPartyStationInfoMapper.selectStationMapList(
+                longitude, latitude, currentTime
         );
     }
 
@@ -96,4 +104,96 @@ public class AppletHomeServiceImpl implements AppletHomeService {
         );
         return bannerInfoConverter.toVO(bannerList);
     }
+
+    @Override
+    public AppletStationDetailVO getStationDetail(Long stationId, BigDecimal longitude, BigDecimal latitude) {
+        // 获取当前登录用户ID
+        Long userId = SecurityUtils.getUserId();
+        
+        // 查询用户是否为企业用户,获取企业ID
+        Long firmId = null;
+        boolean isFirmUser = false;
+        if (userId != null) {
+            UserFirm userFirm = userFirmMapper.selectOne(
+                    new LambdaQueryWrapper<UserFirm>()
+                            .eq(UserFirm::getUserId, userId)
+                            .last("LIMIT 1")
+            );
+            if (userFirm != null) {
+                firmId = userFirm.getFirmId();
+                isFirmUser = true;
+            }
+        }
+        
+        // 获取当前时间(HHmmss格式)
+        String currentTime = LocalTime.now().format(TIME_FORMATTER);
+        
+        // 查询站点详情基本信息
+        AppletStationDetailVO result = thirdPartyStationInfoMapper.selectStationDetail(
+                stationId, longitude, latitude, currentTime, firmId
+        );
+        
+        if (result == null) {
+            return null;
+        }
+        
+        // 设置是否企业用户
+        result.setFirmUser(isFirmUser);
+        
+        // 计算预计省多少(当前价 - 原价,如果为负则取绝对值)
+        if (result.getCurrentPrice() != null && result.getOriginalPrice() != null) {
+            BigDecimal saving = result.getOriginalPrice().subtract(result.getCurrentPrice());
+            result.setEstimatedSaving(saving.compareTo(BigDecimal.ZERO) > 0 ? saving : BigDecimal.ZERO);
+            result.setShowSpecialPriceTag(saving.compareTo(BigDecimal.ZERO) > 0);
+        }
+        
+        // 查询站点对应的stationId
+        ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(stationId);
+        if (stationInfo == null) {
+            return result;
+        }
+        
+        // 查询充电终端列表
+        List<ThirdPartyConnectorInfo> connectorList = thirdPartyConnectorInfoMapper.selectList(
+                new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
+                        .eq(ThirdPartyConnectorInfo::getStationId, stationInfo.getStationId())
+        );
+        
+        // 统计终端状态
+        int idleCount = 0;
+        int occupiedCount = 0;
+        int offlineCount = 0;
+        
+        List<AppletStationDetailVO.ConnectorInfoVO> connectorVOList = new ArrayList<>();
+        for (ThirdPartyConnectorInfo connector : connectorList) {
+            AppletStationDetailVO.ConnectorInfoVO vo = new AppletStationDetailVO.ConnectorInfoVO();
+            vo.setConnectorId(connector.getId());
+            vo.setConnectorName(connector.getConnectorName());
+            vo.setConnectorCode(connector.getConnectorId());
+            
+            // 设备分类:根据接口类型判断
+            Integer connectorType = connector.getConnectorType();
+            if (connectorType != null) {
+                if (connectorType == 1 || connectorType == 2 || connectorType == 5) {
+                    vo.setEquipmentType("直流设备");
+                } else {
+                    vo.setEquipmentType("交流设备");
+                }
+            }
+            
+            // TODO: 实际状态需要从实时数据获取,这里暂时默认为空闲
+            vo.setStatus(1);
+            vo.setStatusName("空闲");
+            idleCount++;
+            
+            connectorVOList.add(vo);
+        }
+        
+        result.setConnectorList(connectorVOList);
+        result.setIdleCount(idleCount);
+        result.setOccupiedCount(occupiedCount);
+        result.setOfflineCount(offlineCount);
+        
+        return result;
+    }
 }

+ 8 - 108
src/main/java/com/zsElectric/boot/business/service/impl/PolicyFeeServiceImpl.java

@@ -2,28 +2,18 @@ package com.zsElectric.boot.business.service.impl;
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.zsElectric.boot.business.mapper.PolicyFeeMapper;
-import com.zsElectric.boot.business.mapper.ThirdPartyEquipmentInfoMapper;
 import com.zsElectric.boot.business.mapper.ThirdPartyStationInfoMapper;
 import com.zsElectric.boot.business.model.dto.AddPolicyFeeDTO;
 import com.zsElectric.boot.business.model.entity.PolicyFee;
 import com.zsElectric.boot.business.model.vo.TimePeriodPriceVO;
 import com.zsElectric.boot.business.service.PolicyFeeService;
-import com.zsElectric.boot.charging.entity.*;
-import com.zsElectric.boot.charging.mapper.ThirdPartyConnectorInfoMapper;
-import com.zsElectric.boot.charging.mapper.ThirdPartyEquipmentPricePolicyMapper;
-import com.zsElectric.boot.charging.mapper.ThirdPartyPolicyInfoMapper;
-import com.zsElectric.boot.system.model.entity.DictItem;
-import com.zsElectric.boot.system.service.DictItemService;
+import com.zsElectric.boot.charging.entity.ThirdPartyStationInfo;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.math.BigDecimal;
-import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
  * 策略费用服务实现
@@ -36,106 +26,12 @@ import java.util.stream.Collectors;
 @RequiredArgsConstructor
 public class PolicyFeeServiceImpl implements PolicyFeeService {
 
-    /**
-     * 时段标志映射:1-尖, 2-峰, 3-平, 4-谷(固定常量,避免重复创建)
-     */
-    private static final Map<Integer, String> PERIOD_FLAG_LABEL_MAP = Map.of(
-            1, "尖",
-            2, "峰",
-            3, "平",
-            4, "谷"
-    );
-
     private final PolicyFeeMapper policyFeeMapper;
-
-    private final ThirdPartyPolicyInfoMapper thirdPartyPolicyInfoMapper;
-
-    private final ThirdPartyEquipmentPricePolicyMapper thirdPartyEquipmentPricePolicyMapper;
-
-    private final DictItemService dictItemService;
-
     private final ThirdPartyStationInfoMapper stationInfoMapper;
 
-    private final ThirdPartyConnectorInfoMapper thirdPartyConnectorInfoMapper;
-
     @Override
     public List<TimePeriodPriceVO> getPolicyFee(long stationId, int salesType, Long firmId, Long thirdPartyId) {
-        List<TimePeriodPriceVO> timePeriodPriceVOS = new ArrayList<>();
-
-        // 查询价格策略
-        ThirdPartyEquipmentPricePolicy pricePolicy = thirdPartyEquipmentPricePolicyMapper.selectOne(Wrappers.<ThirdPartyEquipmentPricePolicy>lambdaQuery()
-                .eq(ThirdPartyEquipmentPricePolicy::getConnectorId, thirdPartyConnectorInfoMapper.selectOne(Wrappers.<ThirdPartyConnectorInfo>lambdaQuery()
-                        .eq(ThirdPartyConnectorInfo::getStationId,stationInfoMapper.selectById(stationId).getStationId()).last("limit 1")).getConnectorId())
-                .eq(ThirdPartyEquipmentPricePolicy::getIsDeleted, 0)
-                .last("limit 1"));
-        if (pricePolicy == null) {
-            return timePeriodPriceVOS;
-        }
-
-        // 互联互通成本价
-        List<ThirdPartyPolicyInfo> thirdPartyPolicyInfos = thirdPartyPolicyInfoMapper.selectList(Wrappers.<ThirdPartyPolicyInfo>lambdaQuery()
-                .eq(ThirdPartyPolicyInfo::getPricePolicyId, pricePolicy.getId())
-                .eq(ThirdPartyPolicyInfo::getIsDeleted, 0));
-
-        // 运营费(按时段配置)
-        Map<String, PolicyFee> policyFeeMap = policyFeeMapper.selectList(Wrappers.<PolicyFee>lambdaQuery()
-                .eq(PolicyFee::getStationInfoId, stationId)
-                .eq(PolicyFee::getIsDeleted, 0)
-                .eq(PolicyFee::getSalesType, salesType)
-                .eq(salesType == 1, PolicyFee::getFirmId, firmId)
-                .eq(salesType == 2, PolicyFee::getThirdPartyId, thirdPartyId))
-                .stream()
-                .collect(Collectors.toMap(
-                        PolicyFee::getStartTime,
-                        policyFee -> policyFee,
-                        (v1, v2) -> v1
-                ));
-
-        // 查询时段标志字典,获取增值服务费价格(label对应中文,value对应价格)
-        Map<String, BigDecimal> labelPriceMap = dictItemService.list(
-                        Wrappers.<DictItem>lambdaQuery()
-                                .eq(DictItem::getDictCode, "time_period_flag")
-                                .eq(DictItem::getStatus, 1)
-                ).stream()
-                .collect(Collectors.toMap(
-                        DictItem::getLabel,
-                        item -> new BigDecimal(item.getValue()),
-                        (v1, v2) -> v1
-                ));
-                
-        // 计算综合价格
-        for (ThirdPartyPolicyInfo policyInfo : thirdPartyPolicyInfos) {
-            // 获取增值服务费
-            BigDecimal valueAddedFees = labelPriceMap.getOrDefault(
-                    PERIOD_FLAG_LABEL_MAP.get(policyInfo.getPeriodFlag()),
-                    BigDecimal.ZERO
-            );
-            
-            // 根据时段获取对应的运营费配置
-            PolicyFee policyFee = policyFeeMap.get(policyInfo.getStartTime());
-            
-            TimePeriodPriceVO timePeriodPriceVO = new TimePeriodPriceVO();
-            timePeriodPriceVO.setTimePeriod(policyInfo.getStartTime())
-                    .setPeriodFlag(policyInfo.getPeriodFlag())
-                    .setElectricityPrice(policyInfo.getElecPrice())
-                    .setSettlementServiceFee(policyInfo.getServicePrice())
-                    .setSettlementTotalPrice(policyInfo.getElecPrice().add(policyInfo.getServicePrice()))
-                    .setOperationServiceFee(BigDecimal.ZERO)
-                    .setSaleTotalPrice(BigDecimal.ZERO)
-                    .setValueAddedFees(valueAddedFees);
-            
-            // 只有配置了该时段的运营费才计算销售价并返回
-            if (policyFee != null) {
-                timePeriodPriceVO.setOperationServiceFee(policyFee.getOpFee())
-                        .setSaleTotalPrice(policyInfo.getElecPrice()
-                                .add(policyInfo.getServicePrice())
-                                .add(policyFee.getOpFee())
-                                .add(valueAddedFees));
-            }
-            timePeriodPriceVOS.add(timePeriodPriceVO);
-        }
-        
-        return timePeriodPriceVOS;
+        return policyFeeMapper.selectTimePeriodPriceList(stationId, salesType, firmId, thirdPartyId);
     }
 
     @Override
@@ -161,8 +57,12 @@ public class PolicyFeeServiceImpl implements PolicyFeeService {
             policyFee.setStartTime(addPolicyFeeDTO.getTimePeriod());
             policyFee.setOpFee(addPolicyFeeDTO.getOperationServiceFee());
             policyFee.setSalesType(addPolicyFeeDTO.getSalesType());
-            policyFee.setFirmId(addPolicyFeeDTO.getFirmId());
-            policyFee.setThirdPartyId(addPolicyFeeDTO.getThirdPartyId());
+            // 根据销售类型设置对应的ID
+            if (addPolicyFeeDTO.getSalesType() == 1) {
+                policyFee.setFirmId(addPolicyFeeDTO.getFirmId());
+            } else if (addPolicyFeeDTO.getSalesType() == 2) {
+                policyFee.setThirdPartyId(addPolicyFeeDTO.getThirdPartyId());
+            }
             boolean inserted = policyFeeMapper.insert(policyFee) > 0;
             
             // 新增成功后,更新站点的配置状态为已配置

+ 140 - 18
src/main/resources/mapper/business/ThirdPartyStationInfoMapper.xml

@@ -310,15 +310,19 @@
         <result property="enterprisePrice" column="enterprise_price"/>
         <result property="parkingFee" column="parking_fee"/>
         <result property="address" column="address"/>
+        <result property="longitude" column="station_lng"/>
+        <result property="latitude" column="station_lat"/>
     </resultMap>
 
-    <!-- 小程序首页地图模式查询最近站点信息 -->
-    <select id="selectNearestStationMap" resultMap="AppletStationInfoMapResultMap">
+    <!-- 小程序首页地图模式查询站点列表(按距离排序) -->
+    <select id="selectStationMapList" resultMap="AppletStationInfoMapResultMap">
         SELECT
             tpsi.id AS station_info_id,
             tpsi.station_name,
             tpsi.station_tips,
             tpsi.address,
+            tpsi.station_lng,
+            tpsi.station_lat,
             CAST(tpsi.park_fee AS DECIMAL(10,2)) AS parking_fee,
             <!-- 计算距离(km) -->
             ROUND(
@@ -402,8 +406,69 @@
                 ORDER BY pf.start_time DESC
                 LIMIT 1
             ) AS platform_price,
-            <!-- 企业价(如果有企业ID) -->
-            <if test="firmId != null">
+            <!-- 企业价(地图模式不需要) -->
+            NULL AS enterprise_price
+        FROM third_party_station_info tpsi
+        LEFT JOIN third_party_connector_info tpci ON tpsi.station_id = tpci.station_id AND tpci.is_deleted = 0
+        WHERE tpsi.is_deleted = 0
+            AND tpsi.equipment_owner_id = 'MA6DP6BE7'
+            AND tpsi.policy_configured = 1
+            <!-- 确保存在平台价配置 -->
+            AND EXISTS (
+                SELECT 1 FROM c_policy_fee pf_check
+                WHERE pf_check.station_info_id = tpsi.id
+                    AND pf_check.sales_type = 0
+                    AND pf_check.is_deleted = 0
+                    AND (pf_check.op_fee IS NOT NULL OR pf_check.comp_sales_fee IS NOT NULL)
+            )
+        GROUP BY tpsi.id
+        ORDER BY distance ASC
+    </select>
+
+    <!-- 小程序站点详情查询结果映射 -->
+    <resultMap id="AppletStationDetailResultMap" type="com.zsElectric.boot.business.model.vo.AppletStationDetailVO">
+        <result property="stationId" column="station_info_id"/>
+        <result property="stationName" column="station_name"/>
+        <result property="tips" column="station_tips"/>
+        <result property="distance" column="distance"/>
+        <result property="address" column="address"/>
+        <result property="pictures" column="pictures"/>
+        <result property="currentPrice" column="current_price"/>
+        <result property="currentPeriod" column="current_period"/>
+        <result property="enterprisePrice" column="enterprise_price"/>
+        <result property="originalPrice" column="original_price"/>
+        <result property="businessHours" column="business_hours"/>
+        <result property="serviceProvider" column="service_provider"/>
+        <result property="invoiceProvider" column="invoice_provider"/>
+        <result property="customerServiceHotline" column="customer_service_hotline"/>
+    </resultMap>
+
+    <!-- 小程序查询站点详情 -->
+    <select id="selectStationDetail" resultMap="AppletStationDetailResultMap">
+        SELECT
+            tpsi.id AS station_info_id,
+            tpsi.station_name,
+            tpsi.station_tips,
+            tpsi.address,
+            tpsi.banner_pictures AS pictures,
+            tpsi.own_business_hours AS business_hours,
+            tpsi.customer_service_hotline,
+            '华能贵州盘州市风电有限责任公司' AS service_provider,
+            '华能贵州盘州市风电有限责任公司' AS invoice_provider,
+            <!-- 计算距离(km) -->
+            <if test="longitude != null and latitude != null">
+                ROUND(
+                    6371 * ACOS(
+                        COS(RADIANS(#{latitude})) * COS(RADIANS(tpsi.station_lat))
+                        * COS(RADIANS(tpsi.station_lng) - RADIANS(#{longitude}))
+                        + SIN(RADIANS(#{latitude})) * SIN(RADIANS(tpsi.station_lat))
+                    ), 2
+                ) AS distance,
+            </if>
+            <if test="longitude == null or latitude == null">
+                NULL AS distance,
+            </if>
+            <!-- 当前价(电费+服务费+运营费+综合销售费) -->
             (
                 SELECT
                     ROUND(
@@ -414,8 +479,78 @@
                 FROM c_policy_fee pf
                 INNER JOIN third_party_policy_info tppi ON pf.start_time = tppi.start_time
                 INNER JOIN third_party_equipment_price_policy tpepp ON tppi.price_policy_id = tpepp.id AND tpepp.is_deleted = 0
+                INNER JOIN third_party_connector_info tpci3 ON tpepp.connector_id = tpci3.connector_id AND tpci3.is_deleted = 0
+                WHERE tpci3.station_id = tpsi.station_id
+                    AND pf.station_info_id = tpsi.id
+                    AND pf.sales_type = 0
+                    AND pf.is_deleted = 0
+                    AND tppi.is_deleted = 0
+                    AND pf.start_time &lt;= #{currentTime}
+                ORDER BY pf.start_time DESC
+                LIMIT 1
+            ) AS current_price,
+            <!-- 当前时段名称 -->
+            (
+                SELECT
+                    CONCAT(
+                        CASE tppi.period_flag
+                            WHEN 1 THEN '尖'
+                            WHEN 2 THEN '峰'
+                            WHEN 3 THEN '平'
+                            WHEN 4 THEN '谷'
+                            ELSE ''
+                        END,
+                        CONCAT(SUBSTRING(tppi.start_time, 1, 2), ':', SUBSTRING(tppi.start_time, 3, 2)),
+                        '-',
+                        IFNULL(
+                            (
+                                SELECT CONCAT(SUBSTRING(next_tppi.start_time, 1, 2), ':', SUBSTRING(next_tppi.start_time, 3, 2))
+                                FROM third_party_policy_info next_tppi
+                                WHERE next_tppi.price_policy_id = tppi.price_policy_id
+                                    AND next_tppi.is_deleted = 0
+                                    AND next_tppi.start_time > tppi.start_time
+                                ORDER BY next_tppi.start_time ASC
+                                LIMIT 1
+                            ),
+                            '24:00'
+                        )
+                    )
+                FROM third_party_policy_info tppi
+                INNER JOIN third_party_equipment_price_policy tpepp ON tppi.price_policy_id = tpepp.id AND tpepp.is_deleted = 0
+                INNER JOIN third_party_connector_info tpci2 ON tpepp.connector_id = tpci2.connector_id AND tpci2.is_deleted = 0
+                WHERE tpci2.station_id = tpsi.station_id
+                    AND tppi.is_deleted = 0
+                    AND tppi.start_time &lt;= #{currentTime}
+                ORDER BY tppi.start_time DESC
+                LIMIT 1
+            ) AS current_period,
+            <!-- 原价(电费+服务费) -->
+            (
+                SELECT
+                    ROUND(IFNULL(tppi.elec_price, 0) + IFNULL(tppi.service_price, 0), 4)
+                FROM third_party_policy_info tppi
+                INNER JOIN third_party_equipment_price_policy tpepp ON tppi.price_policy_id = tpepp.id AND tpepp.is_deleted = 0
                 INNER JOIN third_party_connector_info tpci4 ON tpepp.connector_id = tpci4.connector_id AND tpci4.is_deleted = 0
                 WHERE tpci4.station_id = tpsi.station_id
+                    AND tppi.is_deleted = 0
+                    AND tppi.start_time &lt;= #{currentTime}
+                ORDER BY tppi.start_time DESC
+                LIMIT 1
+            ) AS original_price,
+            <!-- 企业价 -->
+            <if test="firmId != null">
+            (
+                SELECT
+                    ROUND(
+                        IFNULL(tppi.elec_price, 0) + IFNULL(tppi.service_price, 0)
+                        + IFNULL(pf.op_fee, 0) + IFNULL(pf.comp_sales_fee, 0),
+                        4
+                    )
+                FROM c_policy_fee pf
+                INNER JOIN third_party_policy_info tppi ON pf.start_time = tppi.start_time
+                INNER JOIN third_party_equipment_price_policy tpepp ON tppi.price_policy_id = tpepp.id AND tpepp.is_deleted = 0
+                INNER JOIN third_party_connector_info tpci5 ON tpepp.connector_id = tpci5.connector_id AND tpci5.is_deleted = 0
+                WHERE tpci5.station_id = tpsi.station_id
                     AND pf.station_info_id = tpsi.id
                     AND pf.sales_type = 1
                     AND pf.firm_id = #{firmId}
@@ -430,21 +565,8 @@
             NULL AS enterprise_price
             </if>
         FROM third_party_station_info tpsi
-        LEFT JOIN third_party_connector_info tpci ON tpsi.station_id = tpci.station_id AND tpci.is_deleted = 0
         WHERE tpsi.is_deleted = 0
-            AND tpsi.equipment_owner_id = 'MA6DP6BE7'
-            AND tpsi.policy_configured = 1
-            <!-- 确保存在平台价配置 -->
-            AND EXISTS (
-                SELECT 1 FROM c_policy_fee pf_check
-                WHERE pf_check.station_info_id = tpsi.id
-                    AND pf_check.sales_type = 0
-                    AND pf_check.is_deleted = 0
-                    AND (pf_check.op_fee IS NOT NULL OR pf_check.comp_sales_fee IS NOT NULL)
-            )
-        GROUP BY tpsi.id
-        ORDER BY distance ASC
-        LIMIT 1
+            AND tpsi.id = #{stationId}
     </select>
 
 </mapper>