From e03f9a706ba46df72c1914870a0a707d6e5e676b Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期三, 30 九月 2026 09:02:38 +0800
Subject: [PATCH] 修改后台功能

---
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TAppUserWhitelistServiceImpl.java |  229 ++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 187 insertions(+), 42 deletions(-)

diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TAppUserWhitelistServiceImpl.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TAppUserWhitelistServiceImpl.java
index 68c8bac..0e0ef69 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TAppUserWhitelistServiceImpl.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/TAppUserWhitelistServiceImpl.java
@@ -3,12 +3,15 @@
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
+import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.account.api.dto.AppUserWhitelistAllocateDTO;
 import com.ruoyi.account.api.dto.AppUserWhitelistAllocateItemDTO;
+import com.ruoyi.account.api.dto.AppUserWhitelistExcelDTO;
 import com.ruoyi.account.api.dto.AppUserWhitelistImportDTO;
 import com.ruoyi.account.api.dto.AppUserWhitelistQueryDTO;
 import com.ruoyi.account.api.dto.AppUserWhitelistSaveDTO;
+import com.ruoyi.account.api.dto.AppUserWhitelistStatusDTO;
 import com.ruoyi.account.api.model.TAppUser;
 import com.ruoyi.account.api.model.TAppUserWhitelist;
 import com.ruoyi.account.api.model.TAppUserWhitelistSite;
@@ -91,6 +94,15 @@
     /** 姓名最大长度(对应 varchar(64)) */
     private static final int MAX_NAME_LENGTH = 64;
 
+    /** 共享模式(公司账户模式 1=共享模式,可用余额取公司可用余额) */
+    private static final int ACCOUNT_MODE_SHARED = 1;
+    /** 账户状态:正常 */
+    private static final int ACCOUNT_STATUS_NORMAL = 1;
+    /** 账户状态:欠款 */
+    private static final int ACCOUNT_STATUS_OVERDUE = 2;
+    /** 金额小数位(元,对应 decimal(12,2)) */
+    private static final int AMOUNT_SCALE = 2;
+
     /** 公司账户模式:2=分配模式(可设置初始分配额度并扣减公司可用余额) */
     private static final int ACCOUNT_MODE_ALLOCATION = 2;
     /** 初始分配额度上限(对应 decimal(12,2)) */
@@ -130,17 +142,28 @@
 
     @Override
     public Page<TAppUserWhitelist> pageList(AppUserWhitelistQueryDTO queryDTO) {
-        if (queryDTO == null) {
-            queryDTO = new AppUserWhitelistQueryDTO();
-        }
+        AppUserWhitelistQueryDTO safeQuery = queryDTO == null ? new AppUserWhitelistQueryDTO() : queryDTO;
+        Page<TAppUserWhitelist> page = buildListQuery(safeQuery)
+                .orderByDesc(BasePojo::getCreateTime)
+                .page(Page.of(safeQuery.getPageCurr(), safeQuery.getPageSize()));
+        fillDisplay(page.getRecords());
+        return page;
+    }
+
+    /**
+     * 列表与导出共用的查询条件(含合作商数据范围):条件为空则不参与过滤;
+     * 合作商账号只能看到自身合作商录入或本人创建的白名单数据
+     */
+    private LambdaQueryChainWrapper<TAppUserWhitelist> buildListQuery(AppUserWhitelistQueryDTO queryDTO) {
+        AppUserWhitelistQueryDTO safeQuery = queryDTO == null ? new AppUserWhitelistQueryDTO() : queryDTO;
         Integer currentPartnerId = getCurrentPartnerId();
         String username = getUsername();
         LambdaQueryChainWrapper<TAppUserWhitelist> query = this.lambdaQuery()
-                .like(StringUtils.isNotBlank(queryDTO.getPhone()), TAppUserWhitelist::getPhone, queryDTO.getPhone())
-                .like(StringUtils.isNotBlank(queryDTO.getName()), TAppUserWhitelist::getName, queryDTO.getName())
-                .eq(queryDTO.getCompanyId() != null, TAppUserWhitelist::getCompanyId, queryDTO.getCompanyId())
-                .eq(queryDTO.getFleetId() != null, TAppUserWhitelist::getFleetId, queryDTO.getFleetId())
-                .eq(queryDTO.getStatus() != null, TAppUserWhitelist::getStatus, queryDTO.getStatus())
+                .like(StringUtils.isNotBlank(safeQuery.getPhone()), TAppUserWhitelist::getPhone, safeQuery.getPhone())
+                .like(StringUtils.isNotBlank(safeQuery.getName()), TAppUserWhitelist::getName, safeQuery.getName())
+                .eq(safeQuery.getCompanyId() != null, TAppUserWhitelist::getCompanyId, safeQuery.getCompanyId())
+                .eq(safeQuery.getFleetId() != null, TAppUserWhitelist::getFleetId, safeQuery.getFleetId())
+                .eq(safeQuery.getStatus() != null, TAppUserWhitelist::getStatus, safeQuery.getStatus())
                 .eq(TAppUserWhitelist::getDelFlag, false);
         if (currentPartnerId != null) {
             if (StringUtils.isNotBlank(username)) {
@@ -151,10 +174,77 @@
                 query.eq(TAppUserWhitelist::getPartnerId, currentPartnerId);
             }
         }
-        Page<TAppUserWhitelist> page = query.orderByDesc(BasePojo::getCreateTime)
-                .page(Page.of(queryDTO.getPageCurr(), queryDTO.getPageSize()));
-        fillDisplay(page.getRecords());
-        return page;
+        return query;
+    }
+
+    @Override
+    public List<AppUserWhitelistExcelDTO> selectExportList(AppUserWhitelistQueryDTO queryDTO) {
+        List<TAppUserWhitelist> records = buildListQuery(queryDTO)
+                .orderByDesc(BasePojo::getCreateTime)
+                .list();
+        if (records == null || records.isEmpty()) {
+            return Collections.emptyList();
+        }
+        Map<Integer, String> fleetNameMap = loadFleetNameMap(records.stream()
+                .map(TAppUserWhitelist::getFleetId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList()));
+        Map<Integer, TGroupCompany> companyMap = loadCompanyMap(records.stream()
+                .map(TAppUserWhitelist::getCompanyId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList()));
+        List<AppUserWhitelistExcelDTO> items = new ArrayList<>(records.size());
+        for (TAppUserWhitelist record : records) {
+            TGroupCompany company = companyMap.get(record.getCompanyId());
+            Integer accountMode = company == null ? null : company.getAccountMode();
+            BigDecimal balance = resolveAvailableBalance(accountMode, record.getBalance(),
+                    company == null ? null : company.getAvailableBalance());
+            AppUserWhitelistExcelDTO item = new AppUserWhitelistExcelDTO();
+            item.setPhone(record.getPhone());
+            item.setName(record.getName());
+            item.setCompanyName(company == null ? null : company.getName());
+            item.setFleetName(fleetNameMap.get(record.getFleetId()));
+            item.setAccountMode(accountMode);
+            item.setAvailableBalance(balance);
+            item.setOverrun(resolveOverrun(balance));
+            item.setAccountStatus(resolveAccountStatus(balance));
+            item.setStatus(record.getStatus());
+            item.setCompanyId(record.getCompanyId());
+            item.setFleetId(record.getFleetId());
+            item.setBalance(record.getBalance());
+            items.add(item);
+        }
+        return items;
+    }
+
+    @Override
+    public boolean updateStatus(AppUserWhitelistStatusDTO statusDTO) {
+        if (statusDTO == null || statusDTO.getId() == null
+                || (!Objects.equals(statusDTO.getStatus(), STATUS_ENABLED)
+                && !Objects.equals(statusDTO.getStatus(), STATUS_DISABLED))) {
+            throw new ServiceException("白名单用户状态参数错误");
+        }
+        TAppUserWhitelist existing = this.getById(statusDTO.getId());
+        if (existing == null) {
+            throw new ServiceException("白名单用户不存在或已删除");
+        }
+        assertPartnerVisible(existing);
+        if (Objects.equals(existing.getStatus(), statusDTO.getStatus())) {
+            // 状态未变化视为幂等成功,避免无意义的更新人与更新时间变更
+            return true;
+        }
+        LambdaUpdateChainWrapper<TAppUserWhitelist> updateWrapper = lambdaUpdate()
+                .eq(TAppUserWhitelist::getId, statusDTO.getId())
+                .set(TAppUserWhitelist::getStatus, statusDTO.getStatus())
+                .setSql("update_time = now()");
+        String username = getUsername();
+        if (StringUtils.isNotBlank(username)) {
+            updateWrapper.set(TAppUserWhitelist::getUpdateBy, username);
+        }
+        if (!updateWrapper.update()) {
+            throw new ServiceException("白名单用户状态更新失败,请重试");
+        }
+        return true;
     }
 
     @Override
@@ -847,48 +937,102 @@
             record.setSiteList(sites);
             record.setSiteIds(sites.stream().map(TAppUserWhitelistSite::getSiteId).collect(Collectors.toList()));
         }
-        fillCompanyNames(records);
+        fillCompanyInfo(records);
         fillFleetNames(records);
     }
 
-    /** 列表回填所属公司名称(远程失败仅记录日志,不影响列表查询) */
-    private void fillCompanyNames(List<TAppUserWhitelist> records) {
-        Map<Integer, String> nameMap = new HashMap<>();
+    /**
+     * 列表回填所属公司名称与账户信息(账户模式、可用余额、超额、账户状态)。
+     * 按公司ID去重后一次批量远程查询,远程失败仅记录日志并留空,不影响列表查询
+     */
+    private void fillCompanyInfo(List<TAppUserWhitelist> records) {
+        Map<Integer, TGroupCompany> companyMap = loadCompanyMap(records.stream()
+                .map(TAppUserWhitelist::getCompanyId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList()));
         for (TAppUserWhitelist record : records) {
-            Integer companyId = record.getCompanyId();
-            if (companyId == null) {
-                continue;
-            }
-            if (nameMap.containsKey(companyId)) {
-                record.setCompanyName(nameMap.get(companyId));
-                continue;
-            }
-            String companyName = null;
-            try {
-                TGroupCompany company = loadCompany(companyId);
-                companyName = company == null ? null : company.getName();
-            } catch (Exception ex) {
-                log.warn("回填公司名称失败,companyId={}", companyId, ex);
-            }
-            nameMap.put(companyId, companyName);
-            record.setCompanyName(companyName);
+            TGroupCompany company = companyMap.get(record.getCompanyId());
+            Integer accountMode = company == null ? null : company.getAccountMode();
+            BigDecimal balance = resolveAvailableBalance(accountMode, record.getBalance(),
+                    company == null ? null : company.getAvailableBalance());
+            record.setCompanyName(company == null ? null : company.getName());
+            record.setAccountMode(accountMode);
+            record.setAvailableBalance(balance);
+            record.setOverrun(resolveOverrun(balance));
+            record.setAccountStatus(resolveAccountStatus(balance));
         }
+    }
+
+    /** 按ID批量加载公司(远程失败或服务降级时返回空Map,由调用方按未知处理) */
+    private Map<Integer, TGroupCompany> loadCompanyMap(List<Integer> companyIds) {
+        List<Integer> distinctIds = companyIds.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        if (distinctIds.isEmpty()) {
+            return new HashMap<>();
+        }
+        try {
+            R<List<TGroupCompany>> response = groupCompanyClient.listCompaniesByIds(distinctIds);
+            if (response == null || !R.isSuccess(response) || response.getData() == null) {
+                return new HashMap<>();
+            }
+            Map<Integer, TGroupCompany> companyMap = new HashMap<>();
+            for (TGroupCompany company : response.getData()) {
+                if (company != null && company.getId() != null) {
+                    companyMap.put(company.getId(), company);
+                }
+            }
+            return companyMap;
+        } catch (Exception ex) {
+            log.warn("回填公司账户信息失败,companyIds={}", distinctIds, ex);
+            return new HashMap<>();
+        }
+    }
+
+    /** 计算可用余额:分配模式=白名单用户自身余额,共享模式=公司可用余额,账户模式未知时留空 */
+    private BigDecimal resolveAvailableBalance(Integer accountMode, BigDecimal whitelistBalance, BigDecimal companyBalance) {
+        if (Integer.valueOf(ACCOUNT_MODE_ALLOCATION).equals(accountMode)) {
+            return whitelistBalance;
+        }
+        if (Integer.valueOf(ACCOUNT_MODE_SHARED).equals(accountMode)) {
+            return companyBalance;
+        }
+        return null;
+    }
+
+    /** 超额:可用余额为负时取其绝对值,其余情况为空 */
+    private BigDecimal resolveOverrun(BigDecimal balance) {
+        if (balance == null || balance.signum() >= 0) {
+            return null;
+        }
+        return balance.abs().setScale(AMOUNT_SCALE, RoundingMode.HALF_UP);
+    }
+
+    /** 账户状态:可用余额为负=欠款,非负=正常,可用余额未知时为空 */
+    private Integer resolveAccountStatus(BigDecimal balance) {
+        if (balance == null) {
+            return null;
+        }
+        return balance.signum() < 0 ? ACCOUNT_STATUS_OVERDUE : ACCOUNT_STATUS_NORMAL;
     }
 
     /** 列表回填所属车队名称(批量查询,远程失败仅记录日志,不影响列表查询) */
     private void fillFleetNames(List<TAppUserWhitelist> records) {
-        List<Integer> fleetIds = records.stream()
+        Map<Integer, String> nameMap = loadFleetNameMap(records.stream()
                 .map(TAppUserWhitelist::getFleetId)
                 .filter(Objects::nonNull)
-                .distinct()
-                .collect(Collectors.toList());
-        if (fleetIds.isEmpty()) {
-            return;
+                .collect(Collectors.toList()));
+        records.forEach(record -> record.setFleetName(nameMap.get(record.getFleetId())));
+    }
+
+    /** 按ID批量加载车队名称(远程失败返回空Map,由调用方按未知处理) */
+    private Map<Integer, String> loadFleetNameMap(List<Integer> fleetIds) {
+        List<Integer> distinctIds = fleetIds.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        if (distinctIds.isEmpty()) {
+            return new HashMap<>();
         }
         try {
-            R<List<TFleet>> response = groupCompanyClient.listFleetsByIds(fleetIds);
+            R<List<TFleet>> response = groupCompanyClient.listFleetsByIds(distinctIds);
             if (response == null || !R.isSuccess(response) || response.getData() == null) {
-                return;
+                return new HashMap<>();
             }
             Map<Integer, String> nameMap = new HashMap<>();
             for (TFleet fleet : response.getData()) {
@@ -896,9 +1040,10 @@
                     nameMap.put(fleet.getId(), fleet.getFleetName());
                 }
             }
-            records.forEach(record -> record.setFleetName(nameMap.get(record.getFleetId())));
+            return nameMap;
         } catch (Exception ex) {
-            log.warn("回填车队名称失败,fleetIds={}", fleetIds, ex);
+            log.warn("回填车队名称失败,fleetIds={}", distinctIds, ex);
+            return new HashMap<>();
         }
     }
 

--
Gitblit v1.7.1