2026-09-03 50de7480237de2ba9d140a219d48a9b72211b8d2
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/supplier/SrmSupplierServiceImpl.java
@@ -1,9 +1,15 @@
package cn.iocoder.yudao.module.srm.service.supplier;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.srm.controller.admin.supplier.vo.SrmSupplierImportExcelVO;
import cn.iocoder.yudao.module.srm.controller.admin.supplier.vo.SrmSupplierImportRespVO;
import cn.iocoder.yudao.module.srm.controller.admin.supplier.vo.SrmSupplierPageReqVO;
import cn.iocoder.yudao.module.srm.controller.admin.supplier.vo.SrmSupplierSaveReqVO;
import cn.iocoder.yudao.module.srm.dal.dataobject.*;
@@ -16,18 +22,19 @@
import cn.iocoder.yudao.module.srm.dal.mysql.SrmSupplierMapper;
import cn.iocoder.yudao.module.srm.dal.mysql.SrmTenderBidMapper;
import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.srm.enums.SupplierTypeEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.hutool.core.collection.CollUtil;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Service
@Validated
@@ -103,6 +110,49 @@
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SrmSupplierImportRespVO importSupplierList(List<SrmSupplierImportExcelVO> importList, Boolean updateSupport) {
        if (CollUtil.isEmpty(importList)) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.SUPPLIER_IMPORT_LIST_IS_EMPTY);
        }
        SrmSupplierImportRespVO respVO = SrmSupplierImportRespVO.builder()
                .createList(new ArrayList<>())
                .updateList(new ArrayList<>())
                .failureList(new LinkedHashMap<>())
                .build();
        // 逐行导入:单行失败记录到 failureList,不影响其它行
        for (SrmSupplierImportExcelVO importVO : importList) {
            String code = StrUtil.trim(importVO.getCode());
            String name = StrUtil.trim(importVO.getName());
            if (StrUtil.isBlank(code) || StrUtil.isBlank(name)) {
                respVO.getFailureList().put(StrUtil.blankToDefault(name, code), "供应商编码和供应商名称不能为空");
                continue;
            }
            SrmSupplierSaveReqVO saveReqVO = toSaveReqVO(importVO);
            try {
                SrmSupplierDO existByCode = supplierMapper.selectByCode(code);
                if (existByCode != null) {
                    if (!Boolean.TRUE.equals(updateSupport)) {
                        respVO.getFailureList().put(name, "供应商编码已存在");
                        continue;
                    }
                    saveReqVO.setId(existByCode.getId());
                    updateSupplier(saveReqVO);
                    respVO.getUpdateList().add(name);
                } else {
                    createSupplier(saveReqVO);
                    respVO.getCreateList().add(name);
                }
            } catch (Exception ex) {
                // 单条失败,记录并继续
                String reason = ex instanceof ServiceException ? ((ServiceException) ex).getMessage() : ex.getMessage();
                respVO.getFailureList().put(name, reason == null ? "导入失败" : reason);
            }
        }
        return respVO;
    }
    @Override
    public List<SrmSupplierDO> getSupplierSimpleList() {
        return supplierMapper.selectApprovedList();
    }
@@ -110,6 +160,10 @@
    @Override
    public List<SrmSupplierDO> getSupplierAllList() {
        return supplierMapper.selectList(new LambdaQueryWrapperX<SrmSupplierDO>()
                // 过滤停用供应商,保留未设置状态与启用状态的档案供应商(仅用于招投标场景)
                .and(w -> w.isNull(SrmSupplierDO::getStatus)
                        .or()
                        .ne(SrmSupplierDO::getStatus, CommonStatusEnum.DISABLE.getStatus()))
                .orderByAsc(SrmSupplierDO::getId));
    }
@@ -121,6 +175,64 @@
        return supplierMapper.selectBatchIds(ids);
    }
    // ========== 导入辅助方法 ==========
    /**
     * 导入 VO -> 保存 VO,复用 create/update 逻辑;
     * 类型支持中文名称或编码(1~4),状态留空默认启用
     */
    private SrmSupplierSaveReqVO toSaveReqVO(SrmSupplierImportExcelVO importVO) {
        SrmSupplierSaveReqVO saveReqVO = new SrmSupplierSaveReqVO();
        saveReqVO.setCode(StrUtil.trim(importVO.getCode()));
        saveReqVO.setName(StrUtil.trim(importVO.getName()));
        saveReqVO.setShortName(StrUtil.trimToNull(importVO.getShortName()));
        saveReqVO.setType(parseTypeCode(importVO.getType()));
        saveReqVO.setCompanyNature(StrUtil.trimToNull(importVO.getCompanyNature()));
        saveReqVO.setRegisteredCapital(importVO.getRegisteredCapital());
        saveReqVO.setBusinessLicenseNo(StrUtil.trimToNull(importVO.getBusinessLicenseNo()));
        saveReqVO.setTaxNo(StrUtil.trimToNull(importVO.getTaxNo()));
        saveReqVO.setLegalPerson(StrUtil.trimToNull(importVO.getLegalPerson()));
        saveReqVO.setAddress(StrUtil.trimToNull(importVO.getAddress()));
        saveReqVO.setWebsite(StrUtil.trimToNull(importVO.getWebsite()));
        saveReqVO.setContactName(StrUtil.trimToNull(importVO.getContactName()));
        saveReqVO.setContactMobile(StrUtil.trimToNull(importVO.getContactMobile()));
        saveReqVO.setContactEmail(StrUtil.trimToNull(importVO.getContactEmail()));
        saveReqVO.setBankName(StrUtil.trimToNull(importVO.getBankName()));
        saveReqVO.setBankAccount(StrUtil.trimToNull(importVO.getBankAccount()));
        saveReqVO.setStatus(importVO.getStatus() != null ? importVO.getStatus() : CommonStatusEnum.ENABLE.getStatus());
        saveReqVO.setRemark(StrUtil.trimToNull(importVO.getRemark()));
        return saveReqVO;
    }
    /**
     * 供应商类型解析:中文名称或编码(1~4)均转换为编码字符串;
     * 无法识别时保留原值,避免导入被阻塞
     */
    private String parseTypeCode(String type) {
        String t = StrUtil.trimToNull(type);
        if (t == null) {
            return null;
        }
        for (SupplierTypeEnum e : SupplierTypeEnum.values()) {
            if (t.equalsIgnoreCase(e.getName()) || t.equals(String.valueOf(e.getCode()))) {
                return String.valueOf(e.getCode());
            }
        }
        // 兼容 Excel 数字单元格被读成 "1.0" 等带小数形式
        try {
            BigDecimal bd = new BigDecimal(t);
            if (bd.stripTrailingZeros().scale() <= 0) {
                int i = bd.intValueExact();
                if (i >= 1 && i <= 4) {
                    return String.valueOf(i);
                }
            }
        } catch (NumberFormatException ignored) {
            // 忽略:保持原值
        }
        return t;
    }
    // ========== 校验方法 ==========
    private void validateSupplierExists(Long id) {