From 770c90dd33db8f975db417531686e93e17e5a3a8 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期二, 13 十月 2026 17:38:27 +0800
Subject: [PATCH] 修改bug

---
 ruoyi-service/ruoyi-account/src/main/resources/mapper/account/TChargingCardMapper.xml                  |    9 +++++++++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TChargingCardServiceImpl.java |   30 +++++++++++++++++++++++++++++-
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/TChargingCard.java               |    6 ++++++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/mapper/TChargingCardMapper.java            |    2 ++
 4 files changed, 46 insertions(+), 1 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

--
Gitblit v1.7.1