소스 검색

refactor(applet): 优化充电接口详情获取逻辑

- 移除充电中实时数据字段及相关查询逻辑,简化AppletConnectorDetailVO结构
- 改为一次SQL查询同时获取接口基本信息、价格信息、企业价格、用户余额及新用户优惠
- 新增优惠活动实体及Mapper支持新用户首单优惠计算
- 在AppletHomeServiceImpl中重构getConnectorDetail方法,整合用户余额和优惠数据查询
- 优化ThirdPartyConnectorInfoMapper XML,实现复杂信息联合查询,减少多次数据库访问
- ChargingUtil中新增带重试机制的chargingRequest方法,提升第三方接口调用稳定性
- 统一错误处理及日志输出,保证重试过程可追踪与中断响应
SheepHy 2 일 전
부모
커밋
29ce2b956f

+ 16 - 0
src/main/java/com/zsElectric/boot/business/mapper/DiscountsActivityMapper.java

@@ -0,0 +1,16 @@
+package com.zsElectric.boot.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zsElectric.boot.business.model.entity.DiscountsActivity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 优惠活动 Mapper 接口
+ *
+ * @author system
+ * @since 2025-12-22
+ */
+@Mapper
+public interface DiscountsActivityMapper extends BaseMapper<DiscountsActivity> {
+
+}

+ 64 - 0
src/main/java/com/zsElectric/boot/business/model/entity/DiscountsActivity.java

@@ -0,0 +1,64 @@
+package com.zsElectric.boot.business.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.zsElectric.boot.common.base.BaseEntity;
+import lombok.Getter;
+import lombok.Setter;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.math.BigDecimal;
+
+/**
+ * 优惠活动实体对象
+ *
+ * @author system
+ * @since 2025-12-22
+ */
+@Getter
+@Setter
+@TableName("c_discounts_activity")
+public class DiscountsActivity extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 活动名称
+     */
+    private String name;
+    
+    /**
+     * 优惠类型 1-新用户首单立减 2-活动折扣
+     */
+    private Integer type;
+    
+    /**
+     * 优惠金额/折扣
+     */
+    private BigDecimal discount;
+    
+    /**
+     * 活动描述
+     */
+    private String activityDesc;
+    
+    /**
+     * 状态 0-未启用 1-启用
+     */
+    private Integer status;
+    
+    /**
+     * 创建人
+     */
+    private Long createBy;
+    
+    /**
+     * 更新人
+     */
+    private Long updateBy;
+    
+    /**
+     * 逻辑删除(0-未删除 1-已删除)
+     */
+    @TableLogic
+    private Integer isDeleted;
+}

+ 6 - 12
src/main/java/com/zsElectric/boot/business/model/vo/applet/AppletConnectorDetailVO.java

@@ -88,18 +88,6 @@ public class AppletConnectorDetailVO implements Serializable {
     @Schema(description = "国家标准名称")
     private String nationalStandardName;
 
-    @Schema(description = "当前电流(A),仅充电中时有值")
-    private BigDecimal currentCurrent;
-
-    @Schema(description = "当前电压(V),仅充电中时有值")
-    private BigDecimal currentVoltage;
-
-    @Schema(description = "当前功率(kW),仅充电中时有值")
-    private BigDecimal currentPower;
-
-    @Schema(description = "电池剩余电量SOC(%),仅充电中时有值")
-    private Integer soc;
-
     @Schema(description = "当前价格(元/度)")
     private BigDecimal currentPrice;
 
@@ -112,6 +100,12 @@ public class AppletConnectorDetailVO implements Serializable {
     @Schema(description = "提示语/停车费说明")
     private String parkingTips;
 
+    @Schema(description = "用户可用余额(元)")
+    private BigDecimal availableBalance;
+
+    @Schema(description = "新用户首单优惠金额(元),仅新用户且有优惠活动时返回")
+    private BigDecimal newUserDiscount;
+
     @Schema(description = "最后更新时间")
     private String lastUpdateTime;
 }

+ 61 - 179
src/main/java/com/zsElectric/boot/business/service/impl/AppletHomeServiceImpl.java

@@ -4,8 +4,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.zsElectric.boot.business.mapper.BannerInfoMapper;
+import com.zsElectric.boot.business.mapper.ChargeOrderInfoMapper;
+import com.zsElectric.boot.business.mapper.DiscountsActivityMapper;
 import com.zsElectric.boot.business.mapper.PolicyFeeMapper;
 import com.zsElectric.boot.business.mapper.ThirdPartyStationInfoMapper;
+import com.zsElectric.boot.business.mapper.UserAccountMapper;
 import com.zsElectric.boot.business.mapper.UserFirmMapper;
 import com.zsElectric.boot.charging.entity.ThirdPartyChargeStatus;
 import com.zsElectric.boot.charging.entity.ThirdPartyConnectorInfo;
@@ -19,7 +22,10 @@ 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.ChargeOrderInfo;
+import com.zsElectric.boot.business.model.entity.DiscountsActivity;
 import com.zsElectric.boot.business.model.entity.PolicyFee;
+import com.zsElectric.boot.business.model.entity.UserAccount;
 import com.zsElectric.boot.business.model.entity.UserFirm;
 import com.zsElectric.boot.business.model.query.StationInfoQuery;
 import com.zsElectric.boot.business.model.vo.AppletConnectorListVO;
@@ -54,6 +60,7 @@ public class AppletHomeServiceImpl implements AppletHomeService {
 
     private final ThirdPartyStationInfoMapper thirdPartyStationInfoMapper;
     private final UserFirmMapper userFirmMapper;
+    private final UserAccountMapper userAccountMapper;
     private final BannerInfoMapper bannerInfoMapper;
     private final BannerInfoConverter bannerInfoConverter;
     private final ThirdPartyConnectorInfoMapper thirdPartyConnectorInfoMapper;
@@ -62,6 +69,8 @@ public class AppletHomeServiceImpl implements AppletHomeService {
     private final ThirdPartyPolicyInfoMapper thirdPartyPolicyInfoMapper;
     private final PolicyFeeMapper policyFeeMapper;
     private final ThirdPartyChargeStatusMapper thirdPartyChargeStatusMapper;
+    private final ChargeOrderInfoMapper chargeOrderInfoMapper;
+    private final DiscountsActivityMapper discountsActivityMapper;
 
     /**
      * 时间格式化器 HHmmss
@@ -678,195 +687,68 @@ public class AppletHomeServiceImpl implements AppletHomeService {
 
     @Override
     public AppletConnectorDetailVO getConnectorDetail(Long connectorId) {
-        // 查询充电接口信息
-        ThirdPartyConnectorInfo connectorInfo = thirdPartyConnectorInfoMapper.selectById(connectorId);
-        if (connectorInfo == null) {
-            log.warn("充电接口不存在,connectorId: {}", connectorId);
-            return null;
-        }
-
-        // 构建返回VO
-        AppletConnectorDetailVO result = new AppletConnectorDetailVO();
-        result.setConnectorId(connectorId);
-        result.setConnectorCode(connectorInfo.getConnectorId());
-        result.setConnectorName(connectorInfo.getConnectorName());
-        result.setConnectorType(connectorInfo.getConnectorType());
-        result.setConnectorTypeName(getConnectorTypeName(connectorInfo.getConnectorType()));
-        result.setVoltageUpperLimits(connectorInfo.getVoltageUpperLimits());
-        result.setVoltageLowerLimits(connectorInfo.getVoltageLowerLimits());
-        result.setCurrent(connectorInfo.getCurrent());
-        result.setPower(connectorInfo.getPower());
-        result.setParkNo(connectorInfo.getParkNo());
-        result.setNationalStandard(connectorInfo.getNationalStandard());
-        result.setNationalStandardName(getNationalStandardName(connectorInfo.getNationalStandard()));
-        result.setStatus(connectorInfo.getStatus());
-        result.setStatusName(getStatusName(connectorInfo.getStatus()));
-
-        // 查询设备信息
-        ThirdPartyEquipmentInfo equipmentInfo = thirdPartyEquipmentInfoMapper.selectOne(
-                new LambdaQueryWrapper<ThirdPartyEquipmentInfo>()
-                        .eq(ThirdPartyEquipmentInfo::getEquipmentId, connectorInfo.getEquipmentId())
-                        .last("LIMIT 1")
-        );
-
-        if (equipmentInfo != null) {
-            result.setEquipmentId(equipmentInfo.getId());
-            result.setEquipmentCode(equipmentInfo.getEquipmentId());
-            result.setEquipmentName(equipmentInfo.getEquipmentName());
-            result.setEquipmentType(equipmentInfo.getEquipmentType());
-            result.setEquipmentTypeName(getEquipmentTypeName(equipmentInfo.getEquipmentType()));
-
-            // 查询充电站信息
-            ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectOne(
-                    new LambdaQueryWrapper<ThirdPartyStationInfo>()
-                            .eq(ThirdPartyStationInfo::getStationId, equipmentInfo.getStationId())
-                            .last("LIMIT 1")
+        // 获取当前登录用户ID
+        Long userId = SecurityUtils.getUserId();
+        
+        // 获取当前时间(HHmmss格式)
+        String currentTime = LocalTime.now().format(TIME_FORMATTER);
+        
+        // 查询用户余额
+        BigDecimal userBalance = null;
+        if (userId != null) {
+            UserAccount userAccount = userAccountMapper.selectOne(
+                    new LambdaQueryWrapper<UserAccount>()
+                            .eq(UserAccount::getUserId, userId)
+                            .eq(UserAccount::getIsDeleted, 0)
             );
-
-            if (stationInfo != null) {
-                result.setStationId(stationInfo.getId());
-                result.setStationName(stationInfo.getStationName());
-                result.setStationAddress(stationInfo.getAddress());
-                result.setParkingTips(stationInfo.getStationTips());
-
-                // 获取当前价格信息
-                String currentTime = LocalTime.now().format(TIME_FORMATTER);
-                
-                // 查询价格策略
-                ThirdPartyEquipmentPricePolicy pricePolicy = thirdPartyEquipmentPricePolicyMapper.selectOne(
-                        new LambdaQueryWrapper<ThirdPartyEquipmentPricePolicy>()
-                                .eq(ThirdPartyEquipmentPricePolicy::getConnectorId, connectorInfo.getConnectorId())
-                                .eq(ThirdPartyEquipmentPricePolicy::getIsDeleted, 0)
-                                .last("LIMIT 1")
-                );
-
-                if (pricePolicy != null) {
-                    // 查询当前时段的价格
-                    List<ThirdPartyPolicyInfo> policyInfoList = thirdPartyPolicyInfoMapper.selectList(
-                            new LambdaQueryWrapper<ThirdPartyPolicyInfo>()
-                                    .eq(ThirdPartyPolicyInfo::getPricePolicyId, pricePolicy.getId())
-                                    .eq(ThirdPartyPolicyInfo::getIsDeleted, 0)
-                                    .le(ThirdPartyPolicyInfo::getStartTime, currentTime)
-                                    .orderByDesc(ThirdPartyPolicyInfo::getStartTime)
-                                    .last("LIMIT 1")
-                    );
-
-                    if (!policyInfoList.isEmpty()) {
-                        ThirdPartyPolicyInfo currentPolicyInfo = policyInfoList.get(0);
-                        BigDecimal elecPrice = currentPolicyInfo.getElecPrice() != null ? currentPolicyInfo.getElecPrice() : BigDecimal.ZERO;
-                        BigDecimal servicePrice = currentPolicyInfo.getServicePrice() != null ? currentPolicyInfo.getServicePrice() : BigDecimal.ZERO;
-                        result.setCurrentPrice(elecPrice.add(servicePrice));
-                        result.setCurrentPeriodDesc(getPeriodFlagName(currentPolicyInfo.getPeriodFlag()));
-
-                        // 获取当前登录用户ID,查询是否为企业用户
-                        Long userId = SecurityUtils.getUserId();
-                        if (userId != null) {
-                            UserFirm userFirm = userFirmMapper.selectOne(
-                                    new LambdaQueryWrapper<UserFirm>()
-                                            .eq(UserFirm::getUserId, userId)
-                                            .last("LIMIT 1")
-                            );
-                            
-                            if (userFirm != null) {
-                                // 查询企业价格
-                                PolicyFee policyFee = policyFeeMapper.selectOne(
-                                        new LambdaQueryWrapper<PolicyFee>()
-                                                .eq(PolicyFee::getStationInfoId, stationInfo.getId())
-                                                .eq(PolicyFee::getSalesType, 1) // 1-企业
-                                                .eq(PolicyFee::getFirmId, userFirm.getFirmId())
-                                                .eq(PolicyFee::getStartTime, currentPolicyInfo.getStartTime())
-                                                .eq(PolicyFee::getIsDeleted, 0)
-                                                .last("LIMIT 1")
-                                );
-                                
-                                if (policyFee != null) {
-                                    // 企业价格 = 电费 + 服务费 + 运营费 + 综合销售费
-                                    BigDecimal opFee = policyFee.getOpFee() != null ? policyFee.getOpFee() : BigDecimal.ZERO;
-                                    BigDecimal compSalesFee = policyFee.getCompSalesFee() != null ? policyFee.getCompSalesFee() : BigDecimal.ZERO;
-                                    BigDecimal enterprisePrice = elecPrice.add(servicePrice).add(opFee).add(compSalesFee);
-                                    result.setEnterprisePrice(enterprisePrice);
-                                }
-                            }
-                        }
-                    }
-                }
+            if (userAccount != null) {
+                userBalance = userAccount.getBalance();
             }
         }
-
-        // 如果是充电中状态,查询实时充电数据
-        if (connectorInfo.getStatus() != null && connectorInfo.getStatus() == 3) {
-            // 查询正在充电的订单
-            ThirdPartyChargeStatus chargeStatus = thirdPartyChargeStatusMapper.selectOne(
-                    new LambdaQueryWrapper<ThirdPartyChargeStatus>()
-                            .eq(ThirdPartyChargeStatus::getConnectorId, connectorInfo.getConnectorId())
-                            .eq(ThirdPartyChargeStatus::getStartChargeSeqStat, 2) // 充电中
-                            .orderByDesc(ThirdPartyChargeStatus::getUpdateTime)
-                            .last("LIMIT 1")
+        
+        // 查询新用户优惠金额(仅当用户为新用户时)
+        BigDecimal newUserDiscount = null;
+        if (userId != null) {
+            // 检查用户是否有充电订单
+            Long orderCount = chargeOrderInfoMapper.selectCount(
+                    new LambdaQueryWrapper<ChargeOrderInfo>()
+                            .eq(ChargeOrderInfo::getUserId, userId)
+                            .eq(ChargeOrderInfo::getIsDeleted, 0)
             );
-
-            if (chargeStatus != null) {
-                // 电流取A相电流
-                result.setCurrentCurrent(chargeStatus.getCurrentA());
-                // 电压取A相电压
-                result.setCurrentVoltage(chargeStatus.getVoltageA());
-                // 功率 = 电压 * 电流 / 1000 (转换为kW)
-                if (chargeStatus.getVoltageA() != null && chargeStatus.getCurrentA() != null) {
-                    BigDecimal power = chargeStatus.getVoltageA()
-                            .multiply(chargeStatus.getCurrentA())
-                            .divide(new BigDecimal("1000"), 2, BigDecimal.ROUND_HALF_UP);
-                    result.setCurrentPower(power);
+            
+            // 如果是新用户(没有订单),查询新用户首单优惠金额
+            if (orderCount == 0) {
+                // 查询c_discounts_activity表,type=1(新用户首单立减)且status=1(启用)的数据
+                List<DiscountsActivity> discountActivities = discountsActivityMapper.selectList(
+                        new LambdaQueryWrapper<DiscountsActivity>()
+                                .eq(DiscountsActivity::getType, 1) // 1-新用户首单立减
+                                .eq(DiscountsActivity::getStatus, 1) // 1-启用
+                                .eq(DiscountsActivity::getIsDeleted, 0)
+                );
+                
+                // 计算所有启用的新用户优惠金额总和
+                if (!discountActivities.isEmpty()) {
+                    newUserDiscount = discountActivities.stream()
+                            .map(DiscountsActivity::getDiscount)
+                            .filter(discount -> discount != null)
+                            .reduce(BigDecimal.ZERO, BigDecimal::add);
+                    
+                    log.info("新用户首单优惠金额 - userId: {}, discount: {}", userId, newUserDiscount);
                 }
-                result.setSoc(chargeStatus.getSoc());
             }
         }
-
-        // 设置最后更新时间
-        if (connectorInfo.getUpdateTime() != null) {
-            result.setLastUpdateTime(connectorInfo.getUpdateTime().toString());
+        
+        // 调用Mapper方法,一次SQL查询获取所有信息
+        AppletConnectorDetailVO result = thirdPartyConnectorInfoMapper.selectConnectorDetailById(
+                connectorId, userId, currentTime, userBalance, newUserDiscount
+        );
+        
+        if (result == null) {
+            log.warn("充电接口不存在,connectorId: {}", connectorId);
         }
-
+        
         return result;
     }
 
-    /**
-     * 获取接口类型名称
-     */
-    private String getConnectorTypeName(Integer connectorType) {
-        if (connectorType == null) {
-            return "未知";
-        }
-        switch (connectorType) {
-            case 1:
-                return "家用插座";
-            case 2:
-                return "交流接口插座";
-            case 3:
-                return "交流接口插头";
-            case 4:
-                return "直流接口枪头";
-            case 5:
-                return "无线充电座";
-            case 6:
-                return "其他";
-            default:
-                return "未知";
-        }
-    }
 
-    /**
-     * 获取国家标准名称
-     */
-    private String getNationalStandardName(Integer nationalStandard) {
-        if (nationalStandard == null) {
-            return "未知";
-        }
-        switch (nationalStandard) {
-            case 1:
-                return "2011版";
-            case 2:
-                return "2015版";
-            default:
-                return "未知";
-        }
-    }
 }

+ 22 - 0
src/main/java/com/zsElectric/boot/charging/mapper/ThirdPartyConnectorInfoMapper.java

@@ -1,8 +1,12 @@
 package com.zsElectric.boot.charging.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zsElectric.boot.business.model.vo.applet.AppletConnectorDetailVO;
 import com.zsElectric.boot.charging.entity.ThirdPartyConnectorInfo;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.math.BigDecimal;
 
 /**
  * 第三方充电接口信息Mapper接口
@@ -12,4 +16,22 @@ import org.apache.ibatis.annotations.Mapper;
  */
 @Mapper
 public interface ThirdPartyConnectorInfoMapper extends BaseMapper<ThirdPartyConnectorInfo> {
+    
+    /**
+     * 获取充电接口详情(包含基本信息、价格信息、企业价格)
+     *
+     * @param connectorId 充电接口ID
+     * @param userId 用户ID
+     * @param currentTime 当前时间 HHmmss格式
+     * @param userBalance 用户余额
+     * @param newUserDiscount 新用户优惠金额
+     * @return 充电接口详情
+     */
+    AppletConnectorDetailVO selectConnectorDetailById(
+            @Param("connectorId") Long connectorId,
+            @Param("userId") Long userId,
+            @Param("currentTime") String currentTime,
+            @Param("userBalance") BigDecimal userBalance,
+            @Param("newUserDiscount") BigDecimal newUserDiscount
+    );
 }

+ 80 - 29
src/main/java/com/zsElectric/boot/common/util/electric/ChargingUtil.java

@@ -21,6 +21,16 @@ import java.util.Objects;
 public class ChargingUtil {
 
     private final ObjectMapper objectMapper = new ObjectMapper();
+    
+    /**
+     * 应用层最大重试次数(除了OkHttp层的重试)
+     */
+    private static final int MAX_APP_RETRY_COUNT = 2;
+    
+    /**
+     * 重试等待时间(毫秒)
+     */
+    private static final long RETRY_WAIT_TIME_MS = 1000;
 
     @Resource
     private ElectricTokenManager tokenManager;
@@ -28,44 +38,85 @@ public class ChargingUtil {
     private OkHttpUtil okHttpUtil;
 
     /**
-     * 请求封装
-     * @param url
-     * @param queryParms
-     * @param tokenRequired
-     * @return
+     * 请求封装(带重试机制)
+     * @param url 请求URL
+     * @param queryParms 请求参数
+     * @param tokenRequired 是否需要Token
+     * @return 响应结果
+     */
+    public JsonNode chargingRequest(String url, Map<String,Object> queryParms, boolean tokenRequired){
+        Exception lastException = null;
+        
+        // 应用层重试机制(除了OkHttp层的重试之外)
+        for (int attempt = 0; attempt <= MAX_APP_RETRY_COUNT; attempt++) {
+            try {
+                if (attempt > 0) {
+                    log.warn("第三方接口调用失败,正在进行第 {} 次应用层重试 - URL: {}", attempt, url);
+                    // 重试前等待一段时间
+                    Thread.sleep(RETRY_WAIT_TIME_MS * attempt); // 线性递增等待时间
+                }
+                
+                return doChargingRequest(url, queryParms, tokenRequired);
+                
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                log.error("重试被中断 - URL: {}", url, e);
+                throw new RuntimeException("调用第三方接口被中断: " + e.getMessage(), e);
+            } catch (Exception e) {
+                lastException = e;
+                log.error("调用第三方接口失败 - URL: {}, 第 {} 次尝试", url, attempt + 1, e);
+                
+                // 如果是最后一次尝试,不再重试
+                if (attempt >= MAX_APP_RETRY_COUNT) {
+                    break;
+                }
+            }
+        }
+        
+        // 所有重试都失败
+        log.error("调用第三方接口所有重试都失败 - URL: {}, 总共尝试 {} 次", url, MAX_APP_RETRY_COUNT + 1);
+        if (lastException != null) {
+            throw new RuntimeException("调用第三方接口失败: " + lastException.getMessage(), lastException);
+        } else {
+            throw new RuntimeException("调用第三方接口失败,原因未知");
+        }
+    }
+    
+    /**
+     * 实际执行请求的方法
+     * @param url 请求URL
+     * @param queryParms 请求参数
+     * @param tokenRequired 是否需要Token
+     * @return 响应结果
      */
-    public JsonNode chargingRequest(String url, Map<String,Object> queryParms,boolean tokenRequired){
+    private JsonNode doChargingRequest(String url, Map<String,Object> queryParms, boolean tokenRequired) throws Exception {
         Map<String, String> headers = new HashMap<>();
         if(tokenRequired){
             headers.put("Authorization", "Bearer " + tokenManager.getValidAccessToken());
         }
-        try {
-            RequestParmsEntity requestParms = new RequestParmsEntity();
-            SequenceGenUtil.SequenceResult result = SequenceGenUtil.generate();
+        
+        RequestParmsEntity requestParms = new RequestParmsEntity();
+        SequenceGenUtil.SequenceResult result = SequenceGenUtil.generate();
 
-            requestParms.setOperatorID(ConnectivityConstants.OPERATOR_ID);
-            requestParms.setData(AESCryptoUtils.encrypt(objectMapper.writeValueAsString(queryParms),ConnectivityConstants.PLATFORM_DATA_SECRET,
-                            ConnectivityConstants.PLATFORM_DATA_SECRET_IV));
-            requestParms.setTimeStamp(result.getTimestamp());
-            requestParms .setSeq(result.getSequence());
-            requestParms.setSig(HmacMD5Util.genSign(requestParms.getOperatorID(),requestParms.getData(),
-                            requestParms.getTimeStamp(),
-                            requestParms.getSeq(),ConnectivityConstants.PLATFORM_SIG_SECRET));
+        requestParms.setOperatorID(ConnectivityConstants.OPERATOR_ID);
+        requestParms.setData(AESCryptoUtils.encrypt(objectMapper.writeValueAsString(queryParms),ConnectivityConstants.PLATFORM_DATA_SECRET,
+                        ConnectivityConstants.PLATFORM_DATA_SECRET_IV));
+        requestParms.setTimeStamp(result.getTimestamp());
+        requestParms .setSeq(result.getSequence());
+        requestParms.setSig(HmacMD5Util.genSign(requestParms.getOperatorID(),requestParms.getData(),
+                        requestParms.getTimeStamp(),
+                        requestParms.getSeq(),ConnectivityConstants.PLATFORM_SIG_SECRET));
 
-            String requestJson = objectMapper.writeValueAsString(requestParms);
-            log.info("调用第三方接口,URL: {}, 请求参数: {}", url, requestJson);
-            JsonNode response = okHttpUtil.doPostForm(url, requestJson, headers);
+        String requestJson = objectMapper.writeValueAsString(requestParms);
+        log.info("调用第三方接口,URL: {}, 请求参数: {}", url, requestJson);
+        JsonNode response = okHttpUtil.doPostForm(url, requestJson, headers);
 
-            if (Objects.isNull(response)) {
-                log.error("调用第三方接口返回为空,URL: {}", url);
-                return null;
-            }
-            log.info("调用第三方接口成功,URL: {}, 响应: {}", url, response);
-            return response;
-        }catch (Exception e){
-            log.error("调用第三方接口发生异常,URL: {}", url, e);
-            throw new RuntimeException("调用第三方接口发生异常: " + e.getMessage(), e);
+        if (Objects.isNull(response)) {
+            log.error("调用第三方接口返回为空,URL: {}", url);
+            throw new RuntimeException("第三方接口返回为空");
         }
+        log.info("调用第三方接口成功,URL: {}, 响应: {}", url, response);
+        return response;
     }
 
     /**

+ 5 - 0
src/main/resources/mapper/business/DiscountsActivityMapper.xml

@@ -0,0 +1,5 @@
+<?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.zsElectric.boot.business.mapper.DiscountsActivityMapper">
+
+</mapper>

+ 187 - 0
src/main/resources/mapper/charging/ThirdPartyConnectorInfoMapper.xml

@@ -0,0 +1,187 @@
+<?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.zsElectric.boot.charging.mapper.ThirdPartyConnectorInfoMapper">
+
+    <!-- 充电接口详情结果映射 -->
+    <resultMap id="ConnectorDetailResultMap" type="com.zsElectric.boot.business.model.vo.applet.AppletConnectorDetailVO">
+        <result property="connectorId" column="connector_id"/>
+        <result property="connectorCode" column="connector_code"/>
+        <result property="connectorName" column="connector_name"/>
+        <result property="stationId" column="station_id"/>
+        <result property="stationName" column="station_name"/>
+        <result property="stationAddress" column="station_address"/>
+        <result property="equipmentId" column="equipment_id"/>
+        <result property="equipmentCode" column="equipment_code"/>
+        <result property="equipmentName" column="equipment_name"/>
+        <result property="equipmentType" column="equipment_type"/>
+        <result property="equipmentTypeName" column="equipment_type_name"/>
+        <result property="parkNo" column="park_no"/>
+        <result property="status" column="status"/>
+        <result property="statusName" column="status_name"/>
+        <result property="connectorType" column="connector_type"/>
+        <result property="connectorTypeName" column="connector_type_name"/>
+        <result property="voltageUpperLimits" column="voltage_upper_limits"/>
+        <result property="voltageLowerLimits" column="voltage_lower_limits"/>
+        <result property="current" column="current"/>
+        <result property="power" column="power"/>
+        <result property="nationalStandard" column="national_standard"/>
+        <result property="nationalStandardName" column="national_standard_name"/>
+        <result property="currentPrice" column="current_price"/>
+        <result property="enterprisePrice" column="enterprise_price"/>
+        <result property="currentPeriodDesc" column="current_period_desc"/>
+        <result property="parkingTips" column="parking_tips"/>
+        <result property="availableBalance" column="available_balance"/>
+        <result property="newUserDiscount" column="new_user_discount"/>
+        <result property="lastUpdateTime" column="last_update_time"/>
+    </resultMap>
+
+    <!-- 获取充电接口详情(一次SQL查询获取所有信息) -->
+    <select id="selectConnectorDetailById" resultMap="ConnectorDetailResultMap">
+        SELECT
+            -- 充电接口基本信息
+            tpci.id AS connector_id,
+            tpci.connector_id AS connector_code,
+            tpci.connector_name,
+            tpci.park_no,
+            tpci.status,
+            CASE tpci.status
+                WHEN 0 THEN '离网'
+                WHEN 1 THEN '空闲'
+                WHEN 2 THEN '占用(未充电)'
+                WHEN 3 THEN '占用(充电中)'
+                WHEN 4 THEN '占用(预约锁定)'
+                WHEN 255 THEN '故障'
+                ELSE '未知'
+            END AS status_name,
+            tpci.connector_type,
+            CASE tpci.connector_type
+                WHEN 1 THEN '家用插座'
+                WHEN 2 THEN '交流接口插座'
+                WHEN 3 THEN '交流接口插头'
+                WHEN 4 THEN '直流接口枪头'
+                WHEN 5 THEN '无线充电座'
+                WHEN 6 THEN '其他'
+                ELSE '未知'
+            END AS connector_type_name,
+            tpci.voltage_upper_limits,
+            tpci.voltage_lower_limits,
+            tpci.current,
+            tpci.power,
+            tpci.national_standard,
+            CASE tpci.national_standard
+                WHEN 1 THEN '2011版'
+                WHEN 2 THEN '2015版'
+                ELSE '未知'
+            END AS national_standard_name,
+            tpci.update_time AS last_update_time,
+            
+            -- 设备信息
+            tpei.id AS equipment_id,
+            tpei.equipment_id AS equipment_code,
+            tpei.equipment_name,
+            tpei.equipment_type,
+            CASE tpei.equipment_type
+                WHEN 1 THEN '直流设备'
+                WHEN 2 THEN '交流设备'
+                WHEN 3 THEN '交直流一体设备'
+                WHEN 4 THEN '无线设备'
+                WHEN 5 THEN '其他'
+                ELSE '未知'
+            END AS equipment_type_name,
+            
+            -- 站点信息
+            tpsi.id AS station_id,
+            tpsi.station_name,
+            tpsi.address AS station_address,
+            tpsi.station_tips AS parking_tips,
+            
+            -- 当前价格(电价 + 服务费)
+            (IFNULL(tppi.elec_price, 0) + IFNULL(tppi.service_price, 0)) AS current_price,
+            
+            -- 当前时段描述(格式:峰 HH:mm-HH:mm)
+            (
+                SELECT CONCAT(
+                    CASE t1.period_flag
+                        WHEN 1 THEN '尖 '
+                        WHEN 2 THEN '峰 '
+                        WHEN 3 THEN '平 '
+                        WHEN 4 THEN '谷 '
+                        ELSE ''
+                    END,
+                    CONCAT(SUBSTRING(t1.start_time, 1, 2), ':', SUBSTRING(t1.start_time, 3, 2)),
+                    '-',
+                    IFNULL(
+                        CONCAT(SUBSTRING(t2.start_time, 1, 2), ':', SUBSTRING(t2.start_time, 3, 2)),
+                        '24:00'
+                    )
+                )
+                FROM third_party_policy_info t1
+                LEFT JOIN third_party_policy_info t2 ON t2.price_policy_id = t1.price_policy_id
+                    AND t2.is_deleted = 0
+                    AND t2.start_time > t1.start_time
+                    AND t2.id = (
+                        SELECT id FROM third_party_policy_info
+                        WHERE price_policy_id = t1.price_policy_id
+                            AND is_deleted = 0
+                            AND start_time > t1.start_time
+                        ORDER BY start_time ASC
+                        LIMIT 1
+                    )
+                WHERE t1.id = tppi.id
+            ) AS current_period_desc,
+            
+            -- 企业价格(电价 + 服务费 + 运营费 + 综合销售费)
+            (IFNULL(tppi.elec_price, 0) + IFNULL(tppi.service_price, 0) + 
+             IFNULL(pf.op_fee, 0) + IFNULL(pf.comp_sales_fee, 0)) AS enterprise_price,
+            
+            -- 用户余额(从参数传入)
+            #{userBalance} AS available_balance,
+            
+            -- 新用户优惠金额(从参数传入)
+            #{newUserDiscount} AS new_user_discount
+            
+        FROM third_party_connector_info tpci
+        
+        -- 关联设备信息
+        LEFT JOIN third_party_equipment_info tpei 
+            ON tpci.equipment_id = tpei.equipment_id 
+            AND tpei.is_deleted = 0
+        
+        -- 关联站点信息
+        LEFT JOIN third_party_station_info tpsi 
+            ON tpei.station_id = tpsi.station_id 
+            AND tpsi.is_deleted = 0
+        
+        -- 关联价格策略
+        LEFT JOIN third_party_equipment_price_policy tpepp 
+            ON tpci.connector_id = tpepp.connector_id 
+            AND tpepp.is_deleted = 0
+        
+        -- 关联当前时段的价格信息(子查询获取当前时段)
+        LEFT JOIN third_party_policy_info tppi ON tppi.id = (
+            SELECT id
+            FROM third_party_policy_info
+            WHERE price_policy_id = tpepp.id
+                AND is_deleted = 0
+                AND start_time &lt;= #{currentTime}
+            ORDER BY start_time DESC
+            LIMIT 1
+        )
+        
+        -- 关联企业价格(仅当用户ID不为空时关联)
+        LEFT JOIN (
+            SELECT pf1.*
+            FROM c_policy_fee pf1
+            INNER JOIN c_user_firm uf ON pf1.firm_id = uf.firm_id AND uf.is_deleted = 0
+            WHERE pf1.is_deleted = 0
+                AND pf1.sales_type = 1
+                AND uf.user_id = #{userId}
+        ) pf ON pf.station_info_id = tpsi.id 
+            AND pf.start_time = tppi.start_time
+        
+        WHERE tpci.id = #{connectorId}
+            AND tpci.is_deleted = 0
+        LIMIT 1
+    </select>
+
+</mapper>