From e1c8c9d51f1c6e42c9868743f16fa8e52bb419cd Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期三, 14 十月 2026 09:24:04 +0800
Subject: [PATCH] Merge branch '2.3' of http://120.76.84.145:10101/gitblit/r/java/mx_charging_pile into 2.3

---
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java      |   25 +++--
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java   |   16 ++-
 ruoyi-service/ruoyi-account/src/main/resources/mapper/account/TChargingCardMapper.xml                    |    9 ++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/model/UdanEmsDeviceState.java               |    1 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TChargingCardServiceImpl.java   |   30 +++++++
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TCardChargingOrderServiceImpl.java  |   15 ++-
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/service/UdanEmsMessageProcessor.java        |   25 ++++-
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/emind/service/EmindEnergyChainDetailService.java |   10 ++
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/TChargingCard.java                 |    6 +
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/HuWeiUtils.java                             |    4 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/model/PeripheralDeviceState.java            |   79 +++++++++++++++++++
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TStationInfoServiceImpl.java        |    1 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/energyreport/vo/StorageDailyReportRow.java       |    4 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/mapper/TChargingCardMapper.java              |    2 
 14 files changed, 196 insertions(+), 31 deletions(-)

diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/TChargingCard.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/TChargingCard.java
index 0b46a07..92a2724 100644
--- a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/TChargingCard.java
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/TChargingCard.java
@@ -31,6 +31,12 @@
     @ApiModelProperty(value = "卡号")
     private String cardNo;
 
+    /** 完整卡号(固定16位,不足前面补0;仅充电桩刷卡查询用,不在前端展示,不对外返回) */
+    @JsonIgnore
+    @TableField("full_card_no")
+    @ApiModelProperty(value = "完整卡号(固定16位,不足前面补0,仅充电查询用,不对外返回)")
+    private String fullCardNo;
+
     /** 卡密码(BCrypt 密文);为空表示未配置密码,刷卡启动时不校验密码(V0.2 定稿) */
     @JsonIgnore
     @ApiModelProperty(value = "卡密码(BCrypt 密文,仅内部存储与校验,不对外返回;空表示未配置,刷卡时不校验密码)")
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/mapper/TChargingCardMapper.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/mapper/TChargingCardMapper.java
index 3c336ac..b7a44d2 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/mapper/TChargingCardMapper.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/mapper/TChargingCardMapper.java
@@ -20,6 +20,8 @@
 
     int countByCardNo(@Param("cardNo") String cardNo, @Param("excludeId") Long excludeId);
 
+    int countByFullCardNo(@Param("fullCardNo") String fullCardNo, @Param("excludeId") Long excludeId);
+
     int adjustBalance(@Param("ids") List<Long> ids,
                       @Param("amount") BigDecimal amount,
                       @Param("type") Integer type,
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TChargingCardServiceImpl.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TChargingCardServiceImpl.java
index d43f322..8a6e007 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TChargingCardServiceImpl.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TChargingCardServiceImpl.java
@@ -70,6 +70,8 @@
     private static final long SYSTEM_OPERATOR = 0L;
     private static final BigDecimal MAX_AMOUNT = new BigDecimal("9999999999.99");
     private static final int PASSWORD_MAX_LENGTH = 64;
+    /** 完整卡号固定长度:16位,不足前面补0(仅充电桩刷卡查询用,不在前端展示) */
+    private static final int CARD_NO_FULL_LENGTH = 16;
     /** 公司账户模式:2=分配模式(可设置初始分配额度并扣减公司可用余额) */
     private static final int ACCOUNT_MODE_ALLOCATION = 2;
     /** 公司账户模式:1=共享模式(可用余额取公司可用余额) */
@@ -135,6 +137,7 @@
         try {
             TChargingCard card = new TChargingCard();
             card.setCardNo(cardNo);
+            card.setFullCardNo(buildFullCardNo(cardNo));
             card.setBalance(quota.signum() > 0 ? quota : BigDecimal.ZERO);
             card.setStatus(dto.getStatus() == null ? ENABLED : dto.getStatus());
             card.setPassword(encodePasswordIfPresent(dto.getPassword()));
@@ -188,6 +191,7 @@
             TChargingCard card = new TChargingCard();
             card.setId(dto.getId());
             card.setCardNo(dto.getCardNo().trim());
+            card.setFullCardNo(buildFullCardNo(card.getCardNo()));
             card.setStatus(dto.getStatus() == null ? ENABLED : dto.getStatus());
             card.setUpdateTime(LocalDateTime.now());
             card.setUpdateBy(SecurityUtils.getUserId());
@@ -435,6 +439,7 @@
             throw new ServiceException("导入数据不能为空");
         }
         Set<String> importCardNos = new HashSet<>();
+        Set<String> importFullCardNos = new HashSet<>();
         int row = 1;
         for (ChargingCardExcelDTO item : cards) {
             row++;
@@ -451,6 +456,13 @@
             if (existsCardNo(cardNo, null)) {
                 throw new ServiceException("第" + row + "行卡号已存在");
             }
+            String fullCardNo = buildFullCardNo(cardNo);
+            if (!importFullCardNos.add(fullCardNo)) {
+                throw new ServiceException("第" + row + "行卡号补零后与其他卡号重复");
+            }
+            if (existsFullCardNo(fullCardNo, null)) {
+                throw new ServiceException("第" + row + "行卡号已存在");
+            }
             if (item.getBalance() != null) {
                 validateAmount(item.getBalance(), true, "第" + row + "行卡余额");
             }
@@ -464,6 +476,7 @@
         for (ChargingCardExcelDTO item : cards) {
             TChargingCard card = new TChargingCard();
             card.setCardNo(item.getCardNo().trim());
+            card.setFullCardNo(buildFullCardNo(card.getCardNo()));
             if (lockedCompanyId != null) {
                 card.setCompanyId(lockedCompanyId);
             }
@@ -483,8 +496,10 @@
         if (dto == null || StringUtils.isEmpty(dto.getCardNo())) {
             throw new ServiceException("卡号不能为空");
         }
+        // 按完整卡号(16位补零)查询,与充电桩上报的完整卡号口径一致
+        String fullCardNo = buildFullCardNo(dto.getCardNo());
         TChargingCard card = getOne(new LambdaQueryWrapper<TChargingCard>()
-                .eq(TChargingCard::getCardNo, dto.getCardNo().trim()));
+                .eq(TChargingCard::getFullCardNo, fullCardNo));
         if (card == null) {
             throw new ServiceException("卡片不存在或已删除");
         }
@@ -1075,6 +1090,7 @@
         TChargingCard update = new TChargingCard();
         update.setId(card.getId());
         update.setCardNo(card.getCardNo());
+        update.setFullCardNo(card.getFullCardNo());
         update.setStatus(card.getStatus());
         update.setPassword(encodedPassword);
         update.setUpdateTime(card.getUpdateTime());
@@ -1134,6 +1150,11 @@
         }
     }
 
+    /** 完整卡号规范化:固定16位,不足前面补0(trim 后左补0) */
+    private String buildFullCardNo(String cardNo) {
+        return StringUtils.padl(cardNo == null ? "" : cardNo.trim(), CARD_NO_FULL_LENGTH, '0');
+    }
+
     private void validateCard(ChargingCardSaveDTO dto, boolean update) {
         if (dto == null || StringUtils.isEmpty(dto.getCardNo())) {
             throw new ServiceException("卡号不能为空");
@@ -1157,6 +1178,9 @@
             throw new ServiceException("卡片状态参数错误");
         }
         if (existsCardNo(cardNo, dto.getId())) {
+            throw new ServiceException("卡号已存在");
+        }
+        if (existsFullCardNo(buildFullCardNo(cardNo), dto.getId())) {
             throw new ServiceException("卡号已存在");
         }
     }
@@ -1194,6 +1218,10 @@
         return baseMapper.countByCardNo(cardNo, excludeId) > 0;
     }
 
+    private boolean existsFullCardNo(String fullCardNo, Long excludeId) {
+        return baseMapper.countByFullCardNo(fullCardNo, excludeId) > 0;
+    }
+
     private void validateDeductRequest(ChargingCardDeductDTO dto) {
         if (dto == null) {
             throw new ServiceException("扣款参数不能为空");
diff --git a/ruoyi-service/ruoyi-account/src/main/resources/mapper/account/TChargingCardMapper.xml b/ruoyi-service/ruoyi-account/src/main/resources/mapper/account/TChargingCardMapper.xml
index 134713b..5bcebaa 100644
--- a/ruoyi-service/ruoyi-account/src/main/resources/mapper/account/TChargingCardMapper.xml
+++ b/ruoyi-service/ruoyi-account/src/main/resources/mapper/account/TChargingCardMapper.xml
@@ -65,6 +65,15 @@
         </if>
     </select>
 
+    <select id="countByFullCardNo" resultType="int">
+        SELECT COUNT(1)
+        FROM t_charging_card
+        WHERE full_card_no = #{fullCardNo}
+        <if test="excludeId != null">
+            AND id != #{excludeId}
+        </if>
+    </select>
+
     <!-- 人工调账:仍保持"增加不超过上限、扣减不低过 0"的运营约束,并叠加充电锁定条件兜底(V0.2 定稿) -->
     <update id="adjustBalance">
         UPDATE t_charging_card
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TCardChargingOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TCardChargingOrderServiceImpl.java
index 9457b9c..5429658 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TCardChargingOrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TCardChargingOrderServiceImpl.java
@@ -740,7 +740,7 @@
      * 1) 企业状态校验(未归属/不存在/停用 -> 失败码2),账户模式取企业配置(默认共享);
      * 2) 企业充电授权校验:站点范围(超范围 -> 失败码2)、可用时段(不在时段 -> 失败码2),未配置授权按放行处理;
      * 3) 可用余额校验(共享=企业可用余额,分配=卡可用余额,<=0 -> 失败码3);
-     * 4) 下发金额 = min(授权下发额, 可用余额),锁定额度与下发金额一致;授权截止时间用于监控提前停充。
+     * 4) 下发金额:共享模式=min(授权下发额, 可用余额),分配模式=卡账户余额;锁定额度与下发金额一致;授权截止时间用于监控提前停充。
      */
     private ChargeAccountSupport.ChargeContext resolveCardChargeContext(Integer siteId, Integer strategyId,
                                                                        TChargingCard card) {
@@ -796,11 +796,16 @@
             return ChargeAccountSupport.ChargeContext.fail(3, "账户可用余额不足");
         }
 
-        // 4. 下发金额 = min(授权下发额, 可用余额),锁定金额与下发金额一致
-        BigDecimal dispatchAmount = authorization == null || authorization.getDispatchAmount() == null
-                ? ChargeAccountSupport.DEFAULT_DISPATCH_AMOUNT : authorization.getDispatchAmount();
-        if (dispatchAmount.compareTo(usable) > 0) {
+        // 4. 下发金额:共享模式=min(授权下发额, 可用余额),分配模式=卡账户余额;锁定金额与下发金额一致
+        BigDecimal dispatchAmount;
+        if (Integer.valueOf(ChargeAccountSupport.ACCOUNT_MODE_ALLOCATED).equals(accountMode)) {
             dispatchAmount = usable;
+        } else {
+            dispatchAmount = authorization == null || authorization.getDispatchAmount() == null
+                    ? ChargeAccountSupport.DEFAULT_DISPATCH_AMOUNT : authorization.getDispatchAmount();
+            if (dispatchAmount.compareTo(usable) > 0) {
+                dispatchAmount = usable;
+            }
         }
         if (dispatchAmount.compareTo(BigDecimal.ZERO) <= 0) {
             return ChargeAccountSupport.ChargeContext.fail(3, "账户可用余额不足");
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
index d9d4d96..eaeb5b5 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -808,10 +808,10 @@
      * 解析白名单企业账户充电上下文(白名单用户选择余额支付时调用):
      * 1) 校验归属公司存在且启用,未归属/停用直接拒绝;
      * 2) 校验企业充电授权(站点范围、可用时段/电价阶段)并计算授权截止时间,未配置授权按放行处理(对齐 VIN 口径);
-     * 3) 下发额度 = min(用户输入充值金额, 账户可用额度, 企业设定的充值金额):
+     * 3) 下发额度:
      *    - 账户可用额度:共享模式=公司可用余额,分配模式=白名单账户余额;
-     *    - 企业设定充值金额=授权配置下发金额,未配置默认 200 元;
-     *    - 用户输入金额为空或非正数时按 min(企业设定充值金额, 账户可用额度) 下发。
+     *    - 共享模式=min(用户输入充值金额, 账户可用额度, 企业设定充值金额),企业设定充值金额=授权配置下发金额,未配置默认 200 元;
+     *    - 分配模式=min(用户输入充值金额, 白名单账户余额),用户输入为空或非正数时直接下发白名单账户余额(不再受企业设定充值金额限制)。
      *
      * @param whitelist       白名单命中结果(含归属公司与账户余额快照)
      * @param userInputAmount 用户输入的充值金额
@@ -871,14 +871,19 @@
         if (usable.compareTo(BigDecimal.ZERO) <= 0) {
             return ChargeAccountSupport.ChargeContext.fail(3, "企业额度不足,请选择其他支付方式");
         }
-        BigDecimal enterpriseLimit = authorization == null ? null : authorization.getDispatchAmount();
-        if (enterpriseLimit == null || enterpriseLimit.compareTo(BigDecimal.ZERO) <= 0) {
-            enterpriseLimit = ChargeAccountSupport.DEFAULT_DISPATCH_AMOUNT;
-        }
         BigDecimal dispatch = money(userInputAmount);
-        dispatch = dispatch.compareTo(BigDecimal.ZERO) <= 0
-                ? enterpriseLimit.min(usable)
-                : dispatch.min(enterpriseLimit).min(usable);
+        if (accountMode == ChargeAccountSupport.ACCOUNT_MODE_ALLOCATED) {
+            // 分配模式:直接下发白名单账户余额(用户输入正数时以用户输入为上限),不再受公司充电下发金额限制
+            dispatch = dispatch.compareTo(BigDecimal.ZERO) <= 0 ? usable : dispatch.min(usable);
+        } else {
+            BigDecimal enterpriseLimit = authorization == null ? null : authorization.getDispatchAmount();
+            if (enterpriseLimit == null || enterpriseLimit.compareTo(BigDecimal.ZERO) <= 0) {
+                enterpriseLimit = ChargeAccountSupport.DEFAULT_DISPATCH_AMOUNT;
+            }
+            dispatch = dispatch.compareTo(BigDecimal.ZERO) <= 0
+                    ? enterpriseLimit.min(usable)
+                    : dispatch.min(enterpriseLimit).min(usable);
+        }
         return ChargeAccountSupport.ChargeContext.ok(accountMode, dispatch.setScale(2, RoundingMode.HALF_UP), maxEndTime);
     }
 
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java
index 7e4fa97..77cd90d 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TVinChargingOrderServiceImpl.java
@@ -1107,12 +1107,18 @@
         if (usable.compareTo(ZERO_AMOUNT) <= 0) {
             return VinChargeContext.fail(3, "账户可用余额为0 accountMode=" + accountMode + " companyId=" + companyId);
         }
-        BigDecimal dispatch = authorization == null ? null : authorization.getDispatchAmount();
-        if (dispatch == null || dispatch.compareTo(ZERO_AMOUNT) <= 0) {
-            dispatch = VD_DEFAULT_DISPATCH_AMOUNT;
-        }
-        if (dispatch.compareTo(usable) > 0) {
+        BigDecimal dispatch;
+        if (accountMode == ACCOUNT_MODE_ALLOCATED) {
+            // 分配模式:直接下发 VIN 账户余额,不再受公司充电下发金额限制
             dispatch = usable;
+        } else {
+            dispatch = authorization == null ? null : authorization.getDispatchAmount();
+            if (dispatch == null || dispatch.compareTo(ZERO_AMOUNT) <= 0) {
+                dispatch = VD_DEFAULT_DISPATCH_AMOUNT;
+            }
+            if (dispatch.compareTo(usable) > 0) {
+                dispatch = usable;
+            }
         }
         return VinChargeContext.ok(accountMode, dispatch, maxEndTime);
     }
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/emind/service/EmindEnergyChainDetailService.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/emind/service/EmindEnergyChainDetailService.java
index 2574abf..8dc99da 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/emind/service/EmindEnergyChainDetailService.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/emind/service/EmindEnergyChainDetailService.java
@@ -102,6 +102,16 @@
             detail.setStationType("BMS");
             detailList.add(detail);
         }
+        if(Objects.nonNull(udanEmsDeviceState.getPeripheralDeviceState())) {
+            EmindEnergyChainDetail detail = new EmindEnergyChainDetail();
+            detail.setPlatformName("欧力特");
+            detail.setDataSource(2);
+            detail.setStationCode(udanEmsDeviceState.getEmsSystemId());
+            detail.setDetail(JSON.toJSONString(udanEmsDeviceState.getPeripheralDeviceState()));
+            detail.setStationId(udanEmsDeviceState.getTmsState().getDeviceId());
+            detail.setStationType("外设");
+            detailList.add(detail);
+        }
         detailList.forEach(d -> {
             mapper.delete(new QueryWrapper<EmindEnergyChainDetail>().eq("station_code", d.getStationCode()).eq("station_type", d.getStationType()));
             add(d);
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/energyreport/vo/StorageDailyReportRow.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/energyreport/vo/StorageDailyReportRow.java
index 924d36d..d3f5bbc 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/energyreport/vo/StorageDailyReportRow.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/energyreport/vo/StorageDailyReportRow.java
@@ -12,8 +12,8 @@
     @ExcelProperty("电站ID") private String stationId;
     @ExcelProperty("电站名称") private String stationName;
     @ExcelProperty("日期") private LocalDate statDate;
-    @ExcelProperty("当日电价") private BigDecimal price;
-    @ExcelProperty("电价名称") private String priceName;
+/*    @ExcelProperty("当日电价") private BigDecimal price;
+    @ExcelProperty("电价名称") private String priceName;*/
     @ExcelProperty("总收益(元)") private BigDecimal income;
     @ExcelProperty("总充电量(kWh)") private BigDecimal chargedEnergy;
     @ExcelProperty("尖时段充电量(kWh)") private BigDecimal chargedEnergySharp;
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TStationInfoServiceImpl.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TStationInfoServiceImpl.java
index 3114501..22c1e99 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TStationInfoServiceImpl.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TStationInfoServiceImpl.java
@@ -457,6 +457,7 @@
             info.setLoanStatus(gridTime != null && gridTime.isBefore(LocalDateTime.now()) ? 3 : 1);
             info.setGridStatus(info.getLoanStatus() == 3 ? "1" : "0");
             info.setDataSource(2);
+            info.setDeviceCount(1);
             info.setSyncTime(LocalDateTime.now());
             info.setCreateTime(LocalDateTime.now());
             info.setUpdateTime(LocalDateTime.now());
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/model/PeripheralDeviceState.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/model/PeripheralDeviceState.java
new file mode 100644
index 0000000..2996827
--- /dev/null
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/model/PeripheralDeviceState.java
@@ -0,0 +1,79 @@
+package com.ruoyi.other.udan.model;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * 外设
+ *
+ * @author Lux
+ * @version 1.0.0
+ * @since 2026/10/12 21:24
+ */
+@Data
+public class PeripheralDeviceState implements Serializable {
+
+    /**
+     * 设备id
+     */
+    private String deviceId;
+
+    /**
+     * 原始di_state值
+     */
+    private Integer diState;
+
+
+    /**
+     * 急停状态 bit1
+     */
+    private Boolean emergencyStop;
+
+
+    /**
+     * 消防状态 bit2
+     */
+    private Boolean fireStatus;
+
+
+    /**
+     * 水浸状态 bit5
+     */
+    private Boolean waterLeak;
+
+
+    /**
+     * 消防喷洒 bit7
+     */
+    private Boolean fireSpray;
+
+    /**
+     * bit解析
+     *
+     * bit1 急停
+     * bit2 消防
+     * bit5 水浸
+     * bit7 消防喷洒
+     */
+    public void convert() {
+        if(Objects.nonNull(this.getDiState())) {
+            this.setEmergencyStop(getBit(this.getDiState(),1));
+            this.setFireStatus(getBit(this.getDiState(),2));
+            this.setWaterLeak(getBit(this.getDiState(),5));
+            this.setFireSpray(getBit(this.getDiState(),7));
+        }
+    }
+
+    /**
+     * 获取bit状态
+     *
+     * @param value 原始值
+     * @param bit   bit编号,从1开始
+     */
+    public boolean getBit(int value, int bit) {
+
+        return ((value >> (bit - 1)) & 1) == 1;
+    }
+}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/model/UdanEmsDeviceState.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/model/UdanEmsDeviceState.java
index a0e30f8..5750781 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/model/UdanEmsDeviceState.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/model/UdanEmsDeviceState.java
@@ -26,6 +26,7 @@
     private PcsState pcsState;
     private ElectricMeterState electricMeterState;
     private BatteryStackState batteryStackState;
+    private PeripheralDeviceState peripheralDeviceState;
 
     public List<EmindIncomeHistoryDto> convert(Long stationId) {
         List<EmindIncomeHistoryDto> dailyList = new ArrayList<>();
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/service/UdanEmsMessageProcessor.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/service/UdanEmsMessageProcessor.java
index 15c104a..f7d2bfc 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/service/UdanEmsMessageProcessor.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/udan/service/UdanEmsMessageProcessor.java
@@ -8,13 +8,7 @@
 import com.ruoyi.other.emind.mapper.EmindStationMapper;
 import com.ruoyi.other.emind.mapper.EmindStorageDashboardMapper;
 import com.ruoyi.other.emind.service.EmindEnergyChainDetailService;
-import com.ruoyi.other.udan.model.EmsState;
-import com.ruoyi.other.udan.model.BatteryStackState;
-import com.ruoyi.other.udan.model.ElectricMeterState;
-import com.ruoyi.other.udan.model.PcsState;
-import com.ruoyi.other.udan.model.PowerMeterState;
-import com.ruoyi.other.udan.model.TmsState;
-import com.ruoyi.other.udan.model.UdanEmsDeviceState;
+import com.ruoyi.other.udan.model.*;
 import com.ruoyi.other.udan.util.UdanEmsKafkaUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
@@ -108,6 +102,9 @@
             else if (type == 2 && field == 8) state.setPowerMeterState(parsePowerMeter(in.readBytes().toByteArray()));
             else if (type == 2 && field == 14 && state.getTmsState() == null) {
                 state.setTmsState(parseTms(in.readBytes().toByteArray()));
+            }
+            else if (type == 2 && field == 15 && state.getPeripheralDeviceState() == null) {
+                state.setPeripheralDeviceState(parsePeripheral(in.readBytes().toByteArray()));
             }
             else skip(in, type);
         });
@@ -318,6 +315,19 @@
         return value;
     }
 
+    private PeripheralDeviceState parsePeripheral(byte[] bytes) throws IOException {
+        PeripheralDeviceState value = new PeripheralDeviceState();
+        read(bytes, (field, type, input) -> {
+            switch (field) {
+                case 1: value.setDeviceId(str(input, type)); break;
+                case 2: value.setDiState(u32(input, type)); break;
+                default: skip(input, type);
+            }
+        });
+        value.convert();
+        return value;
+    }
+
     private void read(byte[] bytes, Reader reader) throws IOException {
         CodedInputStream input = CodedInputStream.newInstance(bytes == null ? new byte[0] : bytes);
         while (!input.isAtEnd()) {
@@ -435,4 +445,5 @@
     private interface Reader {
         void read(int field, int type, CodedInputStream input) throws IOException;
     }
+
 }
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/HuWeiUtils.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/HuWeiUtils.java
index d75e92b..04d4824 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/HuWeiUtils.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/HuWeiUtils.java
@@ -47,7 +47,9 @@
 
     /** 登录华为 FusionSolar 并取得 XSRF-TOKEN。 */
     public String getXsrfToken() {
-        TPlatformConfig config = platformConfigService.getOne(Wrappers.lambdaQuery(TPlatformConfig.class).eq(TPlatformConfig::getPlatformName, "华为"));
+        TPlatformConfig config = platformConfigService.getOne(Wrappers.lambdaQuery(TPlatformConfig.class)
+                .eq(TPlatformConfig::getType, 1)
+                .eq(TPlatformConfig::getPlatformName, "华为"));
         if (config == null || StringUtils.isBlank(config.getAccount()) || StringUtils.isBlank(config.getPassword())) {
             return getXsrfToken(DEFAULT_USER_NAME, DEFAULT_SYSTEM_CODE);
         }

--
Gitblit v1.7.1