2026-07-01 6b5f7c66fc40d7f6099d561e31a34fbd50dd20d3
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductServiceImpl.java
@@ -4,14 +4,16 @@
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemCreateReqDTO;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemUpdateReqDTO;
import cn.iocoder.yudao.module.mdm.enums.MdmItemTypeEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -25,6 +27,10 @@
/**
 * ERP 产品 Service 实现类
 *
 * 改造说明:产品数据统一使用 MDM 主数据管理(itemType=2 产品类型)
 * - 创建、更新、删除操作通过 MDM API 进行
 * - 查询操作从 MDM 获取数据
 *
 * @author 芋道源码
 */
@Service
@@ -35,36 +41,77 @@
    private ErpProductMapper productMapper;
    @Resource
    private ErpProductCategoryService productCategoryService;
    @Resource
    private ErpProductUnitService productUnitService;
    private MdmItemApi mdmItemApi;
    @Override
    public Long createProduct(ProductSaveReqVO createReqVO) {
        // TODO 芋艿:校验分类
        // 插入
        ErpProductDO product = BeanUtils.toBean(createReqVO, ErpProductDO.class);
        productMapper.insert(product);
        // 返回
        return product.getId();
        // 1. 校验条码是否重复
        MdmItemRespDTO existItem = mdmItemApi.getItemByBarCode(createReqVO.getBarCode()).getCheckedData();
        if (existItem != null) {
            throw exception(PRODUCT_BAR_CODE_EXISTS);
        }
        // 2. 通过 MDM API 创建产品
        MdmItemCreateReqDTO createReqDTO = new MdmItemCreateReqDTO();
        createReqDTO.setCode(createReqVO.getBarCode()); // 使用条码作为编码
        createReqDTO.setName(createReqVO.getName());
        createReqDTO.setBarCode(createReqVO.getBarCode());
        createReqDTO.setSpecification(createReqVO.getStandard());
        createReqDTO.setCategoryId(createReqVO.getCategoryId());
        createReqDTO.setUnitMeasureId(createReqVO.getUnitId());
        createReqDTO.setItemType(MdmItemTypeEnum.PRODUCT.getType()); // 产品类型
        createReqDTO.setStatus(createReqVO.getStatus() != null ? createReqVO.getStatus() : CommonStatusEnum.ENABLE.getStatus());
        createReqDTO.setPurchasePrice(createReqVO.getPurchasePrice());
        createReqDTO.setSalesPrice(createReqVO.getSalePrice());
        createReqDTO.setCostPrice(createReqVO.getMinPrice());
        createReqDTO.setExpiryDay(createReqVO.getExpiryDay());
        createReqDTO.setWeight(createReqVO.getWeight());
        createReqDTO.setRemark(createReqVO.getRemark());
        return mdmItemApi.createItem(createReqDTO).getCheckedData();
    }
    @Override
    public void updateProduct(ProductSaveReqVO updateReqVO) {
        // TODO 芋艿:校验分类
        // 校验存在
        validateProductExists(updateReqVO.getId());
        // 更新
        ErpProductDO updateObj = BeanUtils.toBean(updateReqVO, ErpProductDO.class);
        productMapper.updateById(updateObj);
        // 1. 校验存在
        MdmItemRespDTO existItem = mdmItemApi.getItem(updateReqVO.getId()).getCheckedData();
        if (existItem == null) {
            throw exception(PRODUCT_NOT_EXISTS);
        }
        // 2. 校验条码是否重复
        if (!existItem.getBarCode().equals(updateReqVO.getBarCode())) {
            MdmItemRespDTO barCodeItem = mdmItemApi.getItemByBarCode(updateReqVO.getBarCode()).getCheckedData();
            if (barCodeItem != null) {
                throw exception(PRODUCT_BAR_CODE_EXISTS);
            }
        }
        // 3. 通过 MDM API 更新产品
        MdmItemUpdateReqDTO updateReqDTO = new MdmItemUpdateReqDTO();
        updateReqDTO.setId(updateReqVO.getId());
        updateReqDTO.setCode(updateReqVO.getBarCode());
        updateReqDTO.setName(updateReqVO.getName());
        updateReqDTO.setBarCode(updateReqVO.getBarCode());
        updateReqDTO.setSpecification(updateReqVO.getStandard());
        updateReqDTO.setCategoryId(updateReqVO.getCategoryId());
        updateReqDTO.setUnitMeasureId(updateReqVO.getUnitId());
        updateReqDTO.setItemType(MdmItemTypeEnum.PRODUCT.getType());
        updateReqDTO.setStatus(updateReqVO.getStatus());
        updateReqDTO.setPurchasePrice(updateReqVO.getPurchasePrice());
        updateReqDTO.setSalesPrice(updateReqVO.getSalePrice());
        updateReqDTO.setCostPrice(updateReqVO.getMinPrice());
        updateReqDTO.setExpiryDay(updateReqVO.getExpiryDay());
        updateReqDTO.setWeight(updateReqVO.getWeight());
        updateReqDTO.setRemark(updateReqVO.getRemark());
        mdmItemApi.updateItem(updateReqDTO);
    }
    @Override
    public void deleteProduct(Long id) {
        // 校验存在
        validateProductExists(id);
        // 删除
        productMapper.deleteById(id);
        MdmItemRespDTO item = mdmItemApi.getItem(id).getCheckedData();
        if (item == null) {
            throw exception(PRODUCT_NOT_EXISTS);
        }
        // 通过 MDM API 删除(更新状态为禁用)
        mdmItemApi.updateItemStatus(id, CommonStatusEnum.DISABLE.getStatus());
    }
    @Override
@@ -72,35 +119,90 @@
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        List<ErpProductDO> list = productMapper.selectByIds(ids);
        Map<Long, ErpProductDO> productMap = convertMap(list, ErpProductDO::getId);
        // 从 MDM 获取产品数据
        List<MdmItemRespDTO> items = mdmItemApi.getItemList(ids).getCheckedData();
        Map<Long, MdmItemRespDTO> itemMap = convertMap(items, MdmItemRespDTO::getId);
        List<ErpProductDO> result = new ArrayList<>();
        for (Long id : ids) {
            ErpProductDO product = productMap.get(id);
            if (productMap.get(id) == null) {
            MdmItemRespDTO item = itemMap.get(id);
            if (item == null) {
                throw exception(PRODUCT_NOT_EXISTS);
            }
            if (CommonStatusEnum.isDisable(product.getStatus())) {
                throw exception(PRODUCT_NOT_ENABLE, product.getName());
            if (CommonStatusEnum.isDisable(item.getStatus())) {
                throw exception(PRODUCT_NOT_ENABLE, item.getName());
            }
            // 转换为 ErpProductDO
            result.add(convertToErpProduct(item));
        }
        return list;
        return result;
    }
    private void validateProductExists(Long id) {
        if (productMapper.selectById(id) == null) {
        // 从 MDM 校验
        MdmItemRespDTO item = mdmItemApi.getItem(id).getCheckedData();
        if (item == null) {
            throw exception(PRODUCT_NOT_EXISTS);
        }
    }
    @Override
    public ErpProductDO getProduct(Long id) {
        return productMapper.selectById(id);
        // 从 MDM 获取产品数据
        MdmItemRespDTO item = mdmItemApi.getItem(id).getCheckedData();
        if (item == null) {
            return null;
        }
        // 检查是否为产品类型
        if (!MdmItemTypeEnum.PRODUCT.getType().equals(item.getItemType())) {
            return null;
        }
        return convertToErpProduct(item);
    }
    @Override
    public ErpProductRespVO getProductVO(Long id) {
        // 从 MDM 获取产品数据
        MdmItemRespDTO item = mdmItemApi.getItem(id).getCheckedData();
        if (item == null) {
            return null;
        }
        // 检查是否为产品类型
        if (!MdmItemTypeEnum.PRODUCT.getType().equals(item.getItemType())) {
            return null;
        }
        return convertToErpProductVO(item);
    }
    /**
     * 将 MDM 物料转换为 ERP 产品 VO
     */
    private ErpProductRespVO convertToErpProductVO(MdmItemRespDTO item) {
        ErpProductRespVO vo = new ErpProductRespVO();
        vo.setId(item.getId());
        vo.setName(item.getName());
        vo.setBarCode(item.getBarCode());
        vo.setStandard(item.getSpecification());
        vo.setCategoryId(item.getCategoryId());
        vo.setUnitId(item.getUnitMeasureId());
        vo.setStatus(item.getStatus());
        vo.setExpiryDay(item.getExpiryDay());
        vo.setWeight(item.getWeight());
        vo.setPurchasePrice(item.getPurchasePrice());
        vo.setSalePrice(item.getSalesPrice());
        vo.setMinPrice(item.getCostPrice());
        vo.setRemark(item.getRemark());
        return vo;
    }
    @Override
    public List<ErpProductRespVO> getProductVOListByStatus(Integer status) {
        List<ErpProductDO> list = productMapper.selectListByStatus(status);
        return buildProductVOList(list);
        // 从 MDM 获取产品数据(itemType=2)
        List<MdmItemRespDTO> items = mdmItemApi.getItemListByStatus(status).getCheckedData();
        // 过滤产品类型
        items = items.stream()
                .filter(item -> MdmItemTypeEnum.PRODUCT.getType().equals(item.getItemType()))
                .toList();
        return buildProductVOListFromMdm(items);
    }
    @Override
@@ -108,40 +210,78 @@
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        List<ErpProductDO> list = productMapper.selectByIds(ids);
        return buildProductVOList(list);
        // 从 MDM 获取产品数据
        List<MdmItemRespDTO> items = mdmItemApi.getItemList(ids).getCheckedData();
        return buildProductVOListFromMdm(items);
    }
    @Override
    public PageResult<ErpProductRespVO> getProductVOPage(ErpProductPageReqVO pageReqVO) {
        PageResult<ErpProductDO> pageResult = productMapper.selectPage(pageReqVO);
        return new PageResult<>(buildProductVOList(pageResult.getList()), pageResult.getTotal());
        // 从 MDM 获取产品分页数据
        cn.iocoder.yudao.framework.common.pojo.PageResult<MdmItemRespDTO> mdmPageResult =
                mdmItemApi.getItemPage(MdmItemTypeEnum.PRODUCT.getType(), null,
                        pageReqVO.getPageNo(), pageReqVO.getPageSize()).getCheckedData();
        return new PageResult<>(buildProductVOListFromMdm(mdmPageResult.getList()), mdmPageResult.getTotal());
    }
    private List<ErpProductRespVO> buildProductVOList(List<ErpProductDO> list) {
        if (CollUtil.isEmpty(list)) {
    /**
     * 从 MDM 数据构建 ERP 产品 VO 列表
     */
    private List<ErpProductRespVO> buildProductVOListFromMdm(List<MdmItemRespDTO> items) {
        if (CollUtil.isEmpty(items)) {
            return Collections.emptyList();
        }
        Map<Long, ErpProductCategoryDO> categoryMap = productCategoryService.getProductCategoryMap(
                convertSet(list, ErpProductDO::getCategoryId));
        Map<Long, ErpProductUnitDO> unitMap = productUnitService.getProductUnitMap(
                convertSet(list, ErpProductDO::getUnitId));
        return BeanUtils.toBean(list, ErpProductRespVO.class, product -> {
            MapUtils.findAndThen(categoryMap, product.getCategoryId(),
                    category -> product.setCategoryName(category.getName()));
            MapUtils.findAndThen(unitMap, product.getUnitId(),
                    unit -> product.setUnitName(unit.getName()));
        });
        List<ErpProductRespVO> result = new ArrayList<>();
        for (MdmItemRespDTO item : items) {
            ErpProductRespVO vo = new ErpProductRespVO();
            vo.setId(item.getId());
            vo.setName(item.getName());
            vo.setBarCode(item.getBarCode());
            vo.setStandard(item.getSpecification());
            vo.setCategoryId(item.getCategoryId());
            vo.setUnitId(item.getUnitMeasureId());
            vo.setStatus(item.getStatus());
            vo.setExpiryDay(item.getExpiryDay());
            vo.setWeight(item.getWeight());
            vo.setPurchasePrice(item.getPurchasePrice());
            vo.setSalePrice(item.getSalesPrice());
            vo.setMinPrice(item.getCostPrice()); // 使用成本价作为最低价
            vo.setRemark(item.getRemark());
            // 分类名称和单位名称需要额外查询(简化处理,后续可优化)
            result.add(vo);
        }
        return result;
    }
    /**
     * 将 MDM 物料转换为 ERP 产品 DO
     */
    private ErpProductDO convertToErpProduct(MdmItemRespDTO item) {
        ErpProductDO product = new ErpProductDO();
        product.setId(item.getId());
        product.setName(item.getName());
        product.setBarCode(item.getBarCode());
        product.setStandard(item.getSpecification());
        product.setCategoryId(item.getCategoryId());
        product.setUnitId(item.getUnitMeasureId());
        product.setStatus(item.getStatus());
        product.setExpiryDay(item.getExpiryDay());
        product.setWeight(item.getWeight());
        product.setPurchasePrice(item.getPurchasePrice());
        product.setSalePrice(item.getSalesPrice());
        product.setMinPrice(item.getCostPrice());
        product.setRemark(item.getRemark());
        return product;
    }
    @Override
    public Long getProductCountByCategoryId(Long categoryId) {
        return productMapper.selectCountByCategoryId(categoryId);
        return mdmItemApi.getItemCountByCategoryId(categoryId).getCheckedData();
    }
    @Override
    public Long getProductCountByUnitId(Long unitId) {
        return productMapper.selectCountByUnitId(unitId);
        return mdmItemApi.getItemCountByUnitMeasureId(unitId).getCheckedData();
    }
}