From ff41f9a13e981b543c114336058150c940110393 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期五, 17 四月 2026 16:24:25 +0800
Subject: [PATCH] fix: 修复客户档案的导入、新增、编辑的的数据验证

---
 src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java |  286 ++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 204 insertions(+), 82 deletions(-)

diff --git a/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
index 58810c9..5083192 100644
--- a/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
+++ b/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -1,8 +1,6 @@
 package com.ruoyi.basic.service.impl;
 
 
-import cn.hutool.core.date.DateUtil;
-import cn.hutool.core.date.LocalDateTimeUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -10,21 +8,16 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.basic.dto.CustomerDto;
-import com.ruoyi.basic.dto.CustomerFollowUpDto;
+import com.ruoyi.basic.dto.CustomerImportDto;
 import com.ruoyi.basic.mapper.CustomerMapper;
 import com.ruoyi.basic.pojo.Customer;
-import com.ruoyi.basic.pojo.CustomerFollowUp;
-import com.ruoyi.basic.pojo.CustomerFollowUpFile;
-import com.ruoyi.basic.service.CustomerFollowUpFileService;
-import com.ruoyi.basic.service.CustomerFollowUpService;
-import com.ruoyi.basic.service.CustomerReturnVisitService;
-import com.ruoyi.basic.service.ICustomerService;
+import com.ruoyi.basic.pojo.CustomerRegions;
+import com.ruoyi.basic.service.*;
+import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.security.LoginUser;
-import com.ruoyi.framework.web.domain.AjaxResult;
-import com.ruoyi.project.system.domain.SysUser;
 import com.ruoyi.sales.mapper.SalesLedgerMapper;
 import com.ruoyi.sales.pojo.SalesLedger;
 import lombok.AllArgsConstructor;
@@ -35,8 +28,6 @@
 import org.springframework.util.CollectionUtils;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.time.LocalDate;
-import java.time.ZoneId;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -51,6 +42,7 @@
 @AllArgsConstructor
 @Slf4j
 public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements ICustomerService {
+    private static final Set<String> ALLOWED_CUSTOMER_TYPES = new HashSet<>(Arrays.asList("闆跺敭瀹㈡埛", "杩涢攢鍟嗗鎴�"));
     private final SalesLedgerMapper salesLedgerMapper;
     private CustomerMapper customerMapper;
 
@@ -59,6 +51,8 @@
     private CustomerFollowUpFileService customerFollowUpFileService;
 
     private CustomerReturnVisitService customerReturnVisitService;
+
+    private final ICustomerRegionsService customerRegionsService;
 
     /**
      * 鏌ヨ瀹㈡埛妗f
@@ -88,96 +82,112 @@
         BeanUtils.copyProperties(customer, dto);
 
         // 鏌ヨ璺熻繘璁板綍
-        List<CustomerFollowUp> followUpList = customerFollowUpService.list(
-                new LambdaQueryWrapper<CustomerFollowUp>()
-                        .eq(CustomerFollowUp::getCustomerId, id)
-                        .orderByDesc(CustomerFollowUp::getFollowUpTime)
-        );
-
-        if (!CollectionUtils.isEmpty(followUpList)) {
-            List<CustomerFollowUpDto> followUpDtoList = followUpList.stream().map(followUp -> {
-                CustomerFollowUpDto followUpDto = new CustomerFollowUpDto();
-                BeanUtils.copyProperties(followUp, followUpDto);
-
-                // 鏌ヨ闄勪欢
-                List<CustomerFollowUpFile> fileList = customerFollowUpFileService.list(
-                        new LambdaQueryWrapper<CustomerFollowUpFile>()
-                                .eq(CustomerFollowUpFile::getFollowUpId, followUp.getId())
-                );
-                followUpDto.setFileList(fileList);
-
-                return followUpDto;
-            }).collect(Collectors.toList());
-
-            dto.setFollowUpList(followUpDtoList);
+//        List<CustomerFollowUp> followUpList = customerFollowUpService.list(
+//                new LambdaQueryWrapper<CustomerFollowUp>()
+//                        .eq(CustomerFollowUp::getCustomerId, id)
+//                        .orderByDesc(CustomerFollowUp::getFollowUpTime)
+//        );
+//
+//        if (!CollectionUtils.isEmpty(followUpList)) {
+//            List<CustomerFollowUpDto> followUpDtoList = followUpList.stream().map(followUp -> {
+//                CustomerFollowUpDto followUpDto = new CustomerFollowUpDto();
+//                BeanUtils.copyProperties(followUp, followUpDto);
+//
+//                // 鏌ヨ闄勪欢
+//                List<CustomerFollowUpFile> fileList = customerFollowUpFileService.list(
+//                        new LambdaQueryWrapper<CustomerFollowUpFile>()
+//                                .eq(CustomerFollowUpFile::getFollowUpId, followUp.getId())
+//                );
+//                followUpDto.setFileList(fileList);
+//
+//                return followUpDto;
+//            }).collect(Collectors.toList());
+//
+//            dto.setFollowUpList(followUpDtoList);
+//        }
+        //  鍦板尯鍚嶇О
+        CustomerRegions customerRegions = customerRegionsService.getById(customer.getRegionsId());
+        if (customerRegions != null) {
+            dto.setRegionsName(customerRegions.getRegionsName());
         }
-
         return dto;
     }
 
     /**
      * 鏌ヨ瀹㈡埛妗f鍒楄〃
      *
-     * @param customer 瀹㈡埛妗f
-     * @return 瀹㈡埛妗f
+     * @param page     鍒嗛〉瀵硅薄
+     * @param customer 瀹㈡埛鏌ヨ鏉′欢
+     * @return 瀹㈡埛妗f鍒嗛〉鍒楄〃
      */
     @Override
-    public IPage<Customer> selectCustomerList(Page<Customer> page, Customer customer) {
-        // 1. 澶勭悊绌哄�煎満鏅紙鍙傛暟鏍¢獙锛�
-        if (page == null) {
-            page = Page.of(1, 10); // 榛樿绗�1椤碉紝姣忛〉10鏉℃暟鎹�
-        }
-        if (customer == null) {
-            customer = new Customer(); // 閬垮厤绌哄璞″鑷寸殑NPE
-        }
+    public IPage<CustomerDto> selectCustomerList(Page<Customer> page, Customer customer) {
+        if (page == null) page = Page.of(1, 10);
+        if (customer == null) customer = new Customer();
 
-        // 2. 鏋勫缓鏌ヨ鏉′欢锛堝寮虹┖鍊煎畨鍏級
         LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<>();
         String customerName = customer.getCustomerName();
         String customerType = customer.getCustomerType();
+        Long regionsId = customer.getRegionsId();
+
         if (StringUtils.isNotBlank(customerName)) {
             queryWrapper.like(Customer::getCustomerName, customerName);
         }
         if (StringUtils.isNotBlank(customerType)) {
-            queryWrapper.like(Customer::getCustomerType, customerType);
+            queryWrapper.eq(Customer::getCustomerType, customerType);
         }
 
-        // 3. 鎵ц鍒嗛〉鏌ヨ锛堜繚鐣欏垎椤靛厓鏁版嵁锛�
+        if (regionsId != null) {
+            // 璋冪敤 regionsService 鑾峰彇褰撳墠鍦板尯鍙婂叾鎵�鏈夊悗浠g殑 ID 闆嗗悎
+            List<Long> allRegionsIds = customerRegionsService.regionsChildrenIds(regionsId);
+            if (!CollectionUtils.isEmpty(allRegionsIds)) {
+                queryWrapper.in(Customer::getRegionsId, allRegionsIds);
+            } else {
+                queryWrapper.eq(Customer::getRegionsId, regionsId);
+            }
+        }
+
         IPage<Customer> customerPage = customerMapper.selectPage(page, queryWrapper);
 
-        // 4. 鏁版嵁澶勭悊锛堝寮虹┖鍊煎畨鍏� & 浠g爜鍙鎬э級
-        List<Customer> processedList = customerPage.getRecords().stream()
-                .filter(Objects::nonNull) // 杩囨护绌哄璞★紙閬垮厤鍚庣画鎿嶄綔NPE锛�
-                .peek(c -> {
-                    // 瀹夊叏鑾峰彇瀛楁锛岄伩鍏峮ull鍊兼嫾鎺�
+        List<CustomerDto> dtoList = customerPage.getRecords().stream()
+                .filter(Objects::nonNull)
+                .map(c -> {
+                    CustomerDto dto = new CustomerDto();
+                    BeanUtils.copyProperties(c, dto);
+
+                    // 鍦板潃鐢佃瘽鎷兼帴
                     String address = StringUtils.defaultString(c.getCompanyAddress(), "");
                     String phone = StringUtils.defaultString(c.getCompanyPhone(), "");
-                    c.setAddressPhone(address + "(" + phone + ")");
+                    dto.setAddressPhone(address + "(" + phone + ")");
+
+                    // 濉厖鍦板尯鍚嶇О
+                    if (c.getRegionsId() != null) {
+                        CustomerRegions regions = customerRegionsService.getById(c.getRegionsId());
+                        if (regions != null) {
+                            dto.setRegionsName(regions.getRegionsName());
+                        }
+                    }
 
                     // 鏌ヨ鏈�鏂扮殑璺熻繘璁板綍
-                    CustomerFollowUp followUp = customerFollowUpService.getOne(
-                            new LambdaQueryWrapper<CustomerFollowUp>()
-                                    .eq(CustomerFollowUp::getCustomerId, c.getId())
-                                    .orderByDesc(CustomerFollowUp::getFollowUpTime)
-                                    .last("LIMIT 1")
-                    );
-
-                    if (followUp != null) {
-                        c.setFollowUpLevel(followUp.getFollowUpLevel());
-                        c.setFollowUpTime(
-                                Date.from(
-                                        followUp.getFollowUpTime().atZone(ZoneId.systemDefault()).toInstant()
-                                )
-                        );
-                    }
+//                    CustomerFollowUp followUp = customerFollowUpService.getOne(
+//                            new LambdaQueryWrapper<CustomerFollowUp>()
+//                                    .eq(CustomerFollowUp::getCustomerId, c.getId())
+//                                    .orderByDesc(CustomerFollowUp::getFollowUpTime)
+//                                    .last("LIMIT 1")
+//                    );
+//
+//                    if (followUp != null) {
+//                        dto.setFollowUpLevel(followUp.getFollowUpLevel());
+//                        dto.setFollowUpTime(Date.from(followUp.getFollowUpTime().atZone(ZoneId.systemDefault()).toInstant()));
+//                    }
+                    return dto;
                 })
                 .collect(Collectors.toList());
 
-        // 5. 鏇存柊鍒嗛〉缁撴灉涓殑鏁版嵁锛堜繚鎸佸垎椤典俊鎭畬鏁达級
-        IPage<Customer> resultPage = new Page<>(customerPage.getCurrent(), customerPage.getSize(), customerPage.getTotal());
-        resultPage.setRecords(processedList);
+        IPage<CustomerDto> resultPage = new Page<>(customerPage.getCurrent(), customerPage.getSize(), customerPage.getTotal());
+        resultPage.setRecords(dtoList);
 
-        return customerPage; // 杩斿洖鍖呭惈鍒嗛〉淇℃伅鐨処Page瀵硅薄
+        return resultPage;
     }
 
     /**
@@ -191,6 +201,7 @@
         LoginUser loginUser = SecurityUtils.getLoginUser();
         Long tenantId = loginUser.getTenantId();
         customer.setTenantId(tenantId);
+        validateCustomerNameUnique(customer, null);
         return customerMapper.insert(customer);
     }
 
@@ -205,6 +216,7 @@
         LoginUser loginUser = SecurityUtils.getLoginUser();
         Long tenantId = loginUser.getTenantId();
         customer.setTenantId(tenantId);
+        validateCustomerNameUnique(customer, customer.getId());
         return customerMapper.updateById(customer);
     }
 
@@ -244,20 +256,130 @@
     }
 
     @Override
-    public AjaxResult importData(MultipartFile file) {
+    @Transactional(rollbackFor = Exception.class)
+    public void importData(MultipartFile file) {
+        List<CustomerImportDto> userList;
         try {
-            ExcelUtil<Customer> util = new ExcelUtil<Customer>(Customer.class);
-            List<Customer> userList = util.importExcel(file.getInputStream());
+            ExcelUtil<CustomerImportDto> util = new ExcelUtil<>(CustomerImportDto.class);
+            userList = util.importExcel(file.getInputStream());
             if (CollectionUtils.isEmpty(userList)) {
-                return AjaxResult.warn("妯℃澘閿欒鎴栧鍏ユ暟鎹负绌�");
+                throw new ServiceException("妯℃澘閿欒鎴栧鍏ユ暟鎹负绌�");
             }
-            this.saveOrUpdateBatch(userList);
-            return AjaxResult.success(true);
         } catch (Exception e) {
-            e.printStackTrace();
-            return AjaxResult.error("瀵煎叆澶辫触");
+            log.error("瀹㈡埛瀵煎叆澶辫触: {}", e.getMessage());
+            throw new ServiceException("瀵煎叆澶辫触");
         }
+        List<Customer> customers = new ArrayList<>();
+        Customer customer;
+        int rowIndex = 1;
+        Set<String> importedCustomerRegionNames = new HashSet<>();
+        for (CustomerImportDto user : userList) {
+            customer = new Customer();
+            if (user == null) {
+                throw new ServiceException("瀵煎叆澶辫触,绗��" + rowIndex + "銆戣鏁版嵁涓嶈兘涓虹┖");
+            }
+            if (StringUtils.isEmpty(user.getCustomerName())) {
+                throw new ServiceException("瀵煎叆澶辫触,绗�" + rowIndex + "琛屾暟鎹�愬鎴峰悕绉般�戜笉鑳戒负绌�");
+            }
+            String customerName = user.getCustomerName().trim();
+            customer.setCustomerName(customerName);
+            String customerType = user.getCustomerType() == null ? null : user.getCustomerType().trim();
+            if (!StringUtils.isEmpty(customerType) && !ALLOWED_CUSTOMER_TYPES.contains(customerType)) {
+                throw new ServiceException("瀵煎叆澶辫触,绗�" + rowIndex + "琛屾暟鎹�愬鎴峰垎绫汇�戜粎鏀寔锛氶浂鍞鎴枫�佽繘閿�鍟嗗鎴�");
+            }
+            customer.setCustomerType(customerType);
+            customer.setTaxpayerIdentificationNumber(user.getTaxpayerIdentificationNumber());
+            customer.setCompanyAddress(user.getCompanyAddress());
+            customer.setCompanyPhone(user.getCompanyPhone());
+            customer.setContactPerson(user.getContactPerson());
+            customer.setContactPhone(user.getContactPhone());
+            customer.setMaintainer(user.getMaintainer());
+            customer.setMaintenanceTime(user.getMaintenanceTime());
+            customer.setBasicBankAccount(user.getBasicBankAccount());
+            customer.setBankAccount(user.getBankAccount());
+            customer.setBankCode(user.getBankCode());
 
+            if (StringUtils.isEmpty(user.getCustomRegions())) {
+                throw new ServiceException("瀵煎叆澶辫触,绗�" + rowIndex + "琛屾暟鎹�愬鎴峰湴鍖恒�戜笉鑳戒负绌�");
+            }
+            Long regionsId = resolveRegionId(user.getCustomRegions(), rowIndex);
+            customer.setRegionsId(regionsId);
+            String importUniqueKey = customerName + "_" + (customer.getRegionsId() == null ? "NULL" : customer.getRegionsId());
+            if (importedCustomerRegionNames.contains(importUniqueKey)) {
+                throw new ServiceException("瀵煎叆澶辫触,绗�" + rowIndex + "琛屾暟鎹�愬悓鍦板尯瀹㈡埛鍚嶇О銆戦噸澶�");
+            }
+            importedCustomerRegionNames.add(importUniqueKey);
+            validateCustomerNameUnique(customer, null);
+            customers.add(customer);
+            rowIndex++;
+        }
+        if (CollectionUtils.isEmpty(customers)) {
+            throw new ServiceException("瀵煎叆澶辫触,鏈瘑鍒埌鍙鍏ョ殑鏁版嵁");
+        }
+        this.saveBatch(customers);
+    }
+
+    /**
+     * 鎸� 鈥渪x-xx-xx鈥� 灞傜骇瑙f瀽鍦板尯锛屼笉瀛樺湪鍒欐寜鐖剁骇閫愮骇鍒涘缓銆�
+     */
+    private Long resolveRegionId(String regionsPath, int rowIndex) {
+        if (StringUtils.isEmpty(regionsPath)) {
+            throw new ServiceException("瀵煎叆澶辫触,绗�" + rowIndex + "琛屾暟鎹�愬鎴峰湴鍖恒�戜笉鑳戒负绌�");
+        }
+        String normalizedPath = regionsPath.trim().replace("鈥�", "-").replace("锛�", "-");
+        if (!normalizedPath.matches("^[^-]+(?:-[^-]+)*$")) {
+            throw new ServiceException("瀵煎叆澶辫触,绗�" + rowIndex + "琛屾暟鎹�愬鎴峰湴鍖恒�戞牸寮忛敊璇�,浠呮敮鎸侊細xxx 鎴� xxx-xxx-xxx");
+        }
+        String[] regionParts = normalizedPath.split("-");
+        Long parentId = 0L;
+        Long currentId = null;
+        for (String rawPart : regionParts) {
+            String regionName = rawPart == null ? null : rawPart.trim();
+            if (StringUtils.isEmpty(regionName)) {
+                throw new ServiceException("瀵煎叆澶辫触,绗�" + rowIndex + "琛屾暟鎹�愬鎴峰湴鍖恒�戞牸寮忛敊璇�");
+            }
+            CustomerRegions region = customerRegionsService.getOne(new LambdaQueryWrapper<CustomerRegions>()
+                    .eq(CustomerRegions::getRegionsName, regionName)
+                    .last("limit 1"));
+            if (region == null) {
+                region = new CustomerRegions();
+                region.setParentId(parentId);
+                region.setRegionsName(regionName);
+                if (!customerRegionsService.save(region)) {
+                    throw new ServiceException("瀵煎叆澶辫触,绗�" + rowIndex + "琛屾暟鎹�愬鎴峰湴鍖恒�戝垱寤哄け璐�");
+                }
+            }
+            currentId = region.getId();
+            parentId = currentId;
+        }
+        return currentId;
+    }
+
+    private void validateCustomerNameUnique(Customer customer, Long excludeId) {
+        if (customer == null || StringUtils.isEmpty(customer.getCustomerName())) {
+            throw new ServiceException("瀹㈡埛鍚嶇О涓嶈兘涓虹┖");
+        }
+        if (customer.getRegionsId() == null) {
+            throw new ServiceException("瀹㈡埛鍦板尯涓嶈兘涓虹┖");
+        }
+        String customerName = customer.getCustomerName().trim();
+        LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<Customer>().eq(Customer::getCustomerName, customerName);
+        if (customer.getRegionsId() == null) {
+            queryWrapper.isNull(Customer::getRegionsId);
+        } else {
+            queryWrapper.eq(Customer::getRegionsId, customer.getRegionsId());
+        }
+        if (customer.getTenantId() != null) {
+            queryWrapper.eq(Customer::getTenantId, customer.getTenantId());
+        }
+        if (excludeId != null) {
+            queryWrapper.ne(Customer::getId, excludeId);
+        }
+        Long exists = customerMapper.selectCount(queryWrapper);
+        if (exists != null && exists > 0) {
+            throw new ServiceException("鍚屽湴鍖轰笅瀹㈡埛鍚嶇О宸插瓨鍦�,璇峰嬁閲嶅");
+        }
+        customer.setCustomerName(customerName);
     }
 
     @Override

--
Gitblit v1.9.3