package cn.iocoder.yudao.module.wms.service.md.item; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; import cn.iocoder.yudao.module.mdm.enums.MdmItemTypeEnum; import cn.iocoder.yudao.module.wms.controller.admin.md.item.vo.item.WmsItemListReqVO; import cn.iocoder.yudao.module.wms.controller.admin.md.item.vo.item.WmsItemPageReqVO; import cn.iocoder.yudao.module.wms.controller.admin.md.item.vo.item.WmsItemSaveReqVO; import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO; import cn.iocoder.yudao.module.wms.dal.mysql.md.item.WmsItemMapper; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.*; /** * WMS 商品 Service 实现类 * * 改造说明:商品基础数据从 MDM 模块获取(itemType=1 物料类型) * WMS 特有功能(SKU、库存等)仍保留 WMS 管理 * * @author 芋道源码 */ @Service @Validated public class WmsItemServiceImpl implements WmsItemService { @Resource private WmsItemMapper itemMapper; @Resource private MdmItemApi mdmItemApi; @Resource @Lazy // 延迟加载,避免循环依赖 private WmsItemCategoryService categoryService; @Resource @Lazy // 延迟加载,避免循环依赖 private WmsItemBrandService brandService; @Resource private WmsItemSkuService itemSkuService; @Override @Transactional(rollbackFor = Exception.class) public Long createItem(WmsItemSaveReqVO createReqVO) { // 校验数据 validateItemSaveData(createReqVO); // 插入商品(暂时保留原逻辑,后续可完全迁移到 MDM) WmsItemDO item = BeanUtils.toBean(createReqVO, WmsItemDO.class); itemMapper.insert(item); // 插入 SKU itemSkuService.createItemSkuList(item.getId(), createReqVO.getSkus()); return item.getId(); } @Override @Transactional(rollbackFor = Exception.class) public void updateItem(WmsItemSaveReqVO updateReqVO) { // 校验存在 validateItemExists(updateReqVO.getId()); // 校验数据 validateItemSaveData(updateReqVO); // 更新商品(暂时保留原逻辑) WmsItemDO updateObj = BeanUtils.toBean(updateReqVO, WmsItemDO.class); itemMapper.updateById(updateObj); // 更新 SKU itemSkuService.updateItemSkuList(updateReqVO.getId(), updateReqVO.getSkus()); } private void validateItemSaveData(WmsItemSaveReqVO reqVO) { // 校验商品编号唯一 validateItemCodeUnique(reqVO.getId(), reqVO.getCode()); // 校验商品名称唯一 validateItemNameUnique(reqVO.getId(), reqVO.getName()); // 校验商品分类存在 validateCategoryExists(reqVO.getCategoryId()); // 校验商品品牌存在 validateBrandExists(reqVO.getBrandId()); } private void validateItemCodeUnique(Long id, String code) { // 检查 MDM 中编码唯一性 MdmItemRespDTO item = mdmItemApi.getItemByCode(code).getCheckedData(); if (item != null && ObjectUtil.notEqual(item.getId(), id)) { throw exception(ITEM_CODE_DUPLICATE); } } private void validateItemNameUnique(Long id, String name) { WmsItemDO item = itemMapper.selectByName(name); if (item == null) { return; } if (id == null || ObjectUtil.notEqual(item.getId(), id)) { throw exception(ITEM_NAME_DUPLICATE); } } private void validateCategoryExists(Long categoryId) { categoryService.validateItemCategoryExists(categoryId); } private void validateBrandExists(Long brandId) { if (brandId == null) { return; } brandService.validateItemBrandExists(brandId); } @Override @Transactional(rollbackFor = Exception.class) public void deleteItem(Long id) { // 校验存在 validateItemExists(id); // 删除商品和 SKU itemSkuService.deleteItemSkuListByItemId(id); itemMapper.deleteById(id); } @Override public WmsItemDO validateItemExists(Long id) { // 从 MDM 校验物料存在 MdmItemRespDTO item = mdmItemApi.validateItemExists(id).getCheckedData(); if (item == null) { // 如果 MDM 中不存在,检查本地表 WmsItemDO localItem = itemMapper.selectById(id); if (localItem == null) { throw exception(ITEM_NOT_EXISTS); } return localItem; } return convertToWmsItem(item); } @Override public WmsItemDO getItem(Long id) { // 从 MDM 获取物料数据(注意 WMS ID 偏移 30000) MdmItemRespDTO item = mdmItemApi.getItem(id).getCheckedData(); if (item == null) { // 如果 MDM 中不存在,查询本地表 return itemMapper.selectById(id); } return convertToWmsItem(item); } @Override public PageResult getItemPage(WmsItemPageReqVO pageReqVO) { // 从 MDM 获取物料分页数据(itemType=1 物料类型) cn.iocoder.yudao.framework.common.pojo.PageResult mdmPageResult = mdmItemApi.getItemPage(MdmItemTypeEnum.MATERIAL.getType(), null, pageReqVO.getPageNo(), pageReqVO.getPageSize()).getCheckedData(); // 转换为 WMS 商品 DO List list = new ArrayList<>(); for (MdmItemRespDTO item : mdmPageResult.getList()) { list.add(convertToWmsItem(item)); } return new PageResult<>(list, mdmPageResult.getTotal()); } @Override public List getItemList(WmsItemListReqVO listReqVO) { // 从 MDM 获取物料列表(itemType=1 物料类型) List items = mdmItemApi.getItemListByStatus(null).getCheckedData(); List result = new ArrayList<>(); for (MdmItemRespDTO item : items) { // 只返回物料类型 if (MdmItemTypeEnum.MATERIAL.getType().equals(item.getItemType())) { result.add(convertToWmsItem(item)); } } return result; } @Override public List getItemList(Collection ids) { if (CollUtil.isEmpty(ids)) { return Collections.emptyList(); } // 从 MDM 获取物料列表 List items = mdmItemApi.getItemList(ids).getCheckedData(); List result = new ArrayList<>(); for (MdmItemRespDTO item : items) { result.add(convertToWmsItem(item)); } return result; } /** * 将 MDM 物料转换为 WMS 商品 DO */ private WmsItemDO convertToWmsItem(MdmItemRespDTO item) { WmsItemDO wmsItem = new WmsItemDO(); wmsItem.setId(item.getId()); wmsItem.setCode(item.getCode()); wmsItem.setName(item.getName()); // MDM categoryId 映射到 WMS categoryId(注意 ID 偏移) wmsItem.setCategoryId(item.getCategoryId() != null ? item.getCategoryId() - 20000 : null); wmsItem.setBrandId(item.getBrandId()); // 单位名称需要从 MDM 单位表获取,这里暂时留空 wmsItem.setRemark(item.getRemark()); return wmsItem; } @Override public long getItemCountByCategoryId(Long categoryId) { // 从 MDM 获取分类物料数量(注意 ID 偏移) return mdmItemApi.getItemCountByCategoryId(categoryId + 20000).getCheckedData(); } @Override public long getItemCountByBrandId(Long brandId) { // 从 MDM 获取品牌物料数量 // 注意:MDM 目前没有按品牌统计的 API,暂时返回本地数据 return itemMapper.selectCountByBrandId(brandId); } }