| | |
| | | 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.enums.CommonStatusEnum; |
| | | 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.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.api.unit.MdmUnitMeasureApi; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO; |
| | | 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.Collection; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.*; |
| | |
| | | /** |
| | | * WMS 商品 Service 实现类 |
| | | * |
| | | * 改造说明:WMS 商品数据来源于 MDM 物料主数据 |
| | | * - 所有操作调用 MDM API |
| | | * - WMS 商品对应 MDM 物料类型 = 物料(itemType = 1) |
| | | * - 字段映射:WmsItemDO.unit <- MDM 计量单位名称 |
| | | * |
| | | * @author 芋道源码 |
| | | */ |
| | | @Service |
| | | @Validated |
| | | public class WmsItemServiceImpl implements WmsItemService { |
| | | |
| | | /** WMS 商品对应的 MDM 物料类型:物料 */ |
| | | private static final int MDM_ITEM_TYPE_MATERIAL = 1; |
| | | |
| | | @Resource |
| | | private WmsItemMapper itemMapper; |
| | | private MdmItemApi mdmItemApi; |
| | | |
| | | @Resource |
| | | @Lazy // 延迟加载,避免循环依赖 |
| | | private WmsItemCategoryService categoryService; |
| | | @Resource |
| | | @Lazy // 延迟加载,避免循环依赖 |
| | | private WmsItemBrandService brandService; |
| | | @Resource |
| | | private WmsItemSkuService itemSkuService; |
| | | private MdmUnitMeasureApi mdmUnitMeasureApi; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createItem(WmsItemSaveReqVO createReqVO) { |
| | | // 校验数据 |
| | | validateItemSaveData(createReqVO); |
| | | |
| | | // 插入商品 |
| | | WmsItemDO item = BeanUtils.toBean(createReqVO, WmsItemDO.class); |
| | | itemMapper.insert(item); |
| | | // 插入 SKU |
| | | itemSkuService.createItemSkuList(item.getId(), createReqVO.getSkus()); |
| | | return item.getId(); |
| | | // 构建创建请求并调用 MDM API |
| | | MdmItemCreateReqDTO createReqDTO = buildCreateReqDTO(createReqVO); |
| | | return mdmItemApi.createItem(createReqDTO).getCheckedData(); |
| | | } |
| | | |
| | | @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) { |
| | | WmsItemDO item = itemMapper.selectByCode(code); |
| | | if (item == null) { |
| | | return; |
| | | } |
| | | if (id == 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); |
| | | // 构建更新请求并调用 MDM API |
| | | MdmItemUpdateReqDTO updateReqDTO = buildUpdateReqDTO(updateReqVO); |
| | | mdmItemApi.updateItem(updateReqDTO); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deleteItem(Long id) { |
| | | // 校验存在 |
| | | validateItemExists(id); |
| | | |
| | | // 删除商品和 SKU |
| | | itemSkuService.deleteItemSkuListByItemId(id); |
| | | itemMapper.deleteById(id); |
| | | // WMS 商品删除实际为禁用(MDM 物料不能物理删除) |
| | | mdmItemApi.updateItemStatus(id, CommonStatusEnum.DISABLE.getStatus()); |
| | | } |
| | | |
| | | @Override |
| | | public WmsItemDO validateItemExists(Long id) { |
| | | WmsItemDO item = itemMapper.selectById(id); |
| | | if (item == null) { |
| | | throw exception(ITEM_NOT_EXISTS); |
| | | } |
| | | return item; |
| | | MdmItemRespDTO item = mdmItemApi.validateItemExists(id).getCheckedData(); |
| | | return convertToWmsItemDO(item); |
| | | } |
| | | |
| | | @Override |
| | | public WmsItemDO getItem(Long id) { |
| | | return itemMapper.selectById(id); |
| | | MdmItemRespDTO item = mdmItemApi.getItem(id).getCheckedData(); |
| | | if (item == null) { |
| | | return null; |
| | | } |
| | | return convertToWmsItemDO(item); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<WmsItemDO> getItemPage(WmsItemPageReqVO pageReqVO) { |
| | | return itemMapper.selectPage(pageReqVO, |
| | | categoryService.getSelfAndChildItemCategoryIdList(pageReqVO.getCategoryId())); |
| | | // 调用 MDM API 分页查询 |
| | | PageResult<MdmItemRespDTO> mdmPageResult = mdmItemApi.getItemPage( |
| | | MDM_ITEM_TYPE_MATERIAL, |
| | | pageReqVO.getStatus(), |
| | | pageReqVO.getPageNo(), |
| | | pageReqVO.getPageSize() |
| | | ).getCheckedData(); |
| | | |
| | | // 转换结果 |
| | | List<WmsItemDO> itemList = convertToWmsItemDOList(mdmPageResult.getList()); |
| | | return new PageResult<>(itemList, mdmPageResult.getTotal()); |
| | | } |
| | | |
| | | @Override |
| | | public List<WmsItemDO> getItemList(WmsItemListReqVO listReqVO) { |
| | | return itemMapper.selectList(listReqVO, |
| | | categoryService.getSelfAndChildItemCategoryIdList(listReqVO.getCategoryId())); |
| | | // 调用 MDM API 获取列表 |
| | | List<MdmItemRespDTO> itemList = mdmItemApi.getItemListByStatus(listReqVO.getStatus()).getCheckedData(); |
| | | return convertToWmsItemDOList(itemList); |
| | | } |
| | | |
| | | @Override |
| | |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return itemMapper.selectByIds(ids); |
| | | List<MdmItemRespDTO> itemList = mdmItemApi.getItemList(ids).getCheckedData(); |
| | | return convertToWmsItemDOList(itemList); |
| | | } |
| | | |
| | | @Override |
| | | public long getItemCountByCategoryId(Long categoryId) { |
| | | return itemMapper.selectCountByCategoryId(categoryId); |
| | | return mdmItemApi.getItemCountByCategoryId(categoryId).getCheckedData(); |
| | | } |
| | | |
| | | @Override |
| | | public long getItemCountByBrandId(Long brandId) { |
| | | return itemMapper.selectCountByBrandId(brandId); |
| | | // MDM 暂无按品牌统计方法,返回 0 |
| | | return 0L; |
| | | } |
| | | |
| | | } |
| | | // ==================== 私有方法 ==================== |
| | | |
| | | /** |
| | | * 校验商品保存数据 |
| | | */ |
| | | private void validateItemSaveData(WmsItemSaveReqVO reqVO) { |
| | | // 校验商品编码唯一 |
| | | if (reqVO.getCode() != null) { |
| | | MdmItemRespDTO existItem = mdmItemApi.getItemByCode(reqVO.getCode()).getCheckedData(); |
| | | if (existItem != null && !existItem.getId().equals(reqVO.getId())) { |
| | | throw exception(ITEM_CODE_DUPLICATE); |
| | | } |
| | | } |
| | | // 校验商品名称唯一 |
| | | if (reqVO.getName() != null) { |
| | | // MDM 暂无按名称查询方法,跳过此校验 |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 构建创建请求 DTO |
| | | */ |
| | | private MdmItemCreateReqDTO buildCreateReqDTO(WmsItemSaveReqVO saveReqVO) { |
| | | MdmItemCreateReqDTO createReqDTO = new MdmItemCreateReqDTO(); |
| | | createReqDTO.setCode(saveReqVO.getCode()); |
| | | createReqDTO.setName(saveReqVO.getName()); |
| | | createReqDTO.setCategoryId(saveReqVO.getCategoryId()); |
| | | createReqDTO.setBrandId(saveReqVO.getBrandId()); |
| | | createReqDTO.setUnitMeasureId(saveReqVO.getUnitMeasureId()); |
| | | createReqDTO.setItemType(MDM_ITEM_TYPE_MATERIAL); |
| | | createReqDTO.setStatus(CommonStatusEnum.ENABLE.getStatus()); |
| | | createReqDTO.setRemark(saveReqVO.getRemark()); |
| | | return createReqDTO; |
| | | } |
| | | |
| | | /** |
| | | * 构建更新请求 DTO |
| | | */ |
| | | private MdmItemUpdateReqDTO buildUpdateReqDTO(WmsItemSaveReqVO saveReqVO) { |
| | | MdmItemUpdateReqDTO updateReqDTO = new MdmItemUpdateReqDTO(); |
| | | updateReqDTO.setId(saveReqVO.getId()); |
| | | updateReqDTO.setCode(saveReqVO.getCode()); |
| | | updateReqDTO.setName(saveReqVO.getName()); |
| | | updateReqDTO.setCategoryId(saveReqVO.getCategoryId()); |
| | | updateReqDTO.setBrandId(saveReqVO.getBrandId()); |
| | | updateReqDTO.setUnitMeasureId(saveReqVO.getUnitMeasureId()); |
| | | updateReqDTO.setStatus(CommonStatusEnum.ENABLE.getStatus()); |
| | | updateReqDTO.setRemark(saveReqVO.getRemark()); |
| | | return updateReqDTO; |
| | | } |
| | | |
| | | /** |
| | | * 转换 MDM 物料为 WMS 商品 |
| | | */ |
| | | private WmsItemDO convertToWmsItemDO(MdmItemRespDTO mdmItem) { |
| | | if (mdmItem == null) { |
| | | return null; |
| | | } |
| | | WmsItemDO item = new WmsItemDO(); |
| | | item.setId(mdmItem.getId()); |
| | | item.setCode(mdmItem.getCode()); |
| | | item.setName(mdmItem.getName()); |
| | | item.setCategoryId(mdmItem.getCategoryId()); |
| | | item.setBrandId(mdmItem.getBrandId()); |
| | | item.setRemark(mdmItem.getRemark()); |
| | | |
| | | // 获取计量单位名称 |
| | | if (mdmItem.getUnitMeasureId() != null) { |
| | | MdmUnitMeasureRespDTO unit = mdmUnitMeasureApi.getUnitMeasure(mdmItem.getUnitMeasureId()).getCheckedData(); |
| | | if (unit != null) { |
| | | item.setUnit(unit.getName()); |
| | | } |
| | | } |
| | | return item; |
| | | } |
| | | |
| | | /** |
| | | * 批量转换 MDM 物料列表为 WMS 商品列表 |
| | | */ |
| | | private List<WmsItemDO> convertToWmsItemDOList(List<MdmItemRespDTO> mdmItemList) { |
| | | if (CollUtil.isEmpty(mdmItemList)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | // 批量获取计量单位 |
| | | Set<Long> unitIds = mdmItemList.stream() |
| | | .map(MdmItemRespDTO::getUnitMeasureId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | Map<Long, MdmUnitMeasureRespDTO> unitMap = new HashMap<>(); |
| | | if (!unitIds.isEmpty()) { |
| | | List<MdmUnitMeasureRespDTO> units = mdmUnitMeasureApi.getUnitMeasureList(unitIds).getCheckedData(); |
| | | for (MdmUnitMeasureRespDTO unit : units) { |
| | | unitMap.put(unit.getId(), unit); |
| | | } |
| | | } |
| | | |
| | | // 转换列表 |
| | | List<WmsItemDO> result = new ArrayList<>(); |
| | | for (MdmItemRespDTO mdmItem : mdmItemList) { |
| | | WmsItemDO item = new WmsItemDO(); |
| | | item.setId(mdmItem.getId()); |
| | | item.setCode(mdmItem.getCode()); |
| | | item.setName(mdmItem.getName()); |
| | | item.setCategoryId(mdmItem.getCategoryId()); |
| | | item.setBrandId(mdmItem.getBrandId()); |
| | | item.setRemark(mdmItem.getRemark()); |
| | | |
| | | // 设置单位名称 |
| | | if (mdmItem.getUnitMeasureId() != null) { |
| | | MdmUnitMeasureRespDTO unit = unitMap.get(mdmItem.getUnitMeasureId()); |
| | | if (unit != null) { |
| | | item.setUnit(unit.getName()); |
| | | } |
| | | } |
| | | result.add(item); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | } |