gongchunyi
8 小时以前 ff41f9a13e981b543c114336058150c940110393
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -8,18 +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.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.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.pojo.SalesLedger;
import lombok.AllArgsConstructor;
@@ -30,10 +28,7 @@
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.stream.Collectors;
@@ -47,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;
@@ -205,6 +201,7 @@
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long tenantId = loginUser.getTenantId();
        customer.setTenantId(tenantId);
        validateCustomerNameUnique(customer, null);
        return customerMapper.insert(customer);
    }
@@ -219,6 +216,7 @@
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long tenantId = loginUser.getTenantId();
        customer.setTenantId(tenantId);
        validateCustomerNameUnique(customer, customer.getId());
        return customerMapper.updateById(customer);
    }
@@ -258,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);
        }
    /**
     * 按 “xx-xx-xx” 层级解析地区,不存在则按父级逐级创建。
     */
    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