| | |
| | | package cn.iocoder.yudao.module.crm.service.product; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | 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.crm.controller.admin.product.vo.product.CrmProductPageReqVO; |
| | |
| | | import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; |
| | | import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; |
| | | import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; |
| | | 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 cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import com.mzt.logapi.context.LogRecordContext; |
| | | import com.mzt.logapi.service.impl.DiffParseFunction; |
| | |
| | | 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.Map; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; |
| | |
| | | |
| | | /** |
| | | * CRM 产品 Service 实现类 |
| | | * |
| | | * 改造说明:产品数据统一使用 MDM 主数据管理(itemType=2 产品类型) |
| | | * - 创建、更新操作通过 MDM API 进行 |
| | | * - 查询操作从 MDM 获取数据 |
| | | * - CRM 产品表保留用于权限管理 |
| | | * |
| | | * @author ZanGe丶 |
| | | */ |
| | |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | | |
| | | @Resource |
| | | private MdmItemApi mdmItemApi; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @LogRecord(type = CRM_PRODUCT_TYPE, subType = CRM_PRODUCT_CREATE_SUB_TYPE, bizNo = "{{#productId}}", |
| | |
| | | validateProductNoDuplicate(null, createReqVO.getNo()); |
| | | validateProductCategoryExists(createReqVO.getCategoryId()); |
| | | |
| | | // 2. 插入产品 |
| | | CrmProductDO product = BeanUtils.toBean(createReqVO, CrmProductDO.class); |
| | | // 2. 通过 MDM API 创建产品 |
| | | MdmItemCreateReqDTO createReqDTO = new MdmItemCreateReqDTO(); |
| | | createReqDTO.setCode(createReqVO.getNo()); |
| | | createReqDTO.setName(createReqVO.getName()); |
| | | createReqDTO.setBarCode(createReqVO.getNo()); // 使用编码作为条码 |
| | | createReqDTO.setCategoryId(createReqVO.getCategoryId()); |
| | | createReqDTO.setUnitMeasureId(createReqVO.getUnit() != null ? createReqVO.getUnit().longValue() : null); |
| | | createReqDTO.setItemType(MdmItemTypeEnum.PRODUCT.getType()); // 产品类型 |
| | | createReqDTO.setStatus(createReqVO.getStatus() != null ? createReqVO.getStatus() : CommonStatusEnum.ENABLE.getStatus()); |
| | | createReqDTO.setSalesPrice(createReqVO.getPrice()); |
| | | createReqDTO.setRemark(createReqVO.getDescription()); |
| | | Long itemId = mdmItemApi.createItem(createReqDTO).getCheckedData(); |
| | | |
| | | // 3. 插入本地产品记录(用于权限管理) |
| | | CrmProductDO product = new CrmProductDO(); |
| | | product.setId(itemId); |
| | | product.setName(createReqVO.getName()); |
| | | product.setNo(createReqVO.getNo()); |
| | | product.setUnit(createReqVO.getUnit()); |
| | | product.setPrice(createReqVO.getPrice()); |
| | | product.setStatus(createReqVO.getStatus()); |
| | | product.setCategoryId(createReqVO.getCategoryId()); |
| | | product.setDescription(createReqVO.getDescription()); |
| | | product.setOwnerUserId(createReqVO.getOwnerUserId()); |
| | | productMapper.insert(product); |
| | | |
| | | // 3. 插入数据权限 |
| | | // 4. 插入数据权限 |
| | | permissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(product.getOwnerUserId()) |
| | | .setBizType(CrmBizTypeEnum.CRM_PRODUCT.getType()).setBizId(product.getId()) |
| | | .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); |
| | | |
| | | // 4. 记录操作日志上下文 |
| | | // 5. 记录操作日志上下文 |
| | | LogRecordContext.putVariable("productId", product.getId()); |
| | | return product.getId(); |
| | | } |
| | |
| | | validateProductNoDuplicate(updateReqVO.getId(), updateReqVO.getNo()); |
| | | validateProductCategoryExists(updateReqVO.getCategoryId()); |
| | | |
| | | // 2. 更新产品 |
| | | // 2. 通过 MDM API 更新产品 |
| | | MdmItemUpdateReqDTO updateReqDTO = new MdmItemUpdateReqDTO(); |
| | | updateReqDTO.setId(updateReqVO.getId()); |
| | | updateReqDTO.setCode(updateReqVO.getNo()); |
| | | updateReqDTO.setName(updateReqVO.getName()); |
| | | updateReqDTO.setBarCode(updateReqVO.getNo()); |
| | | updateReqDTO.setCategoryId(updateReqVO.getCategoryId()); |
| | | updateReqDTO.setUnitMeasureId(updateReqVO.getUnit() != null ? updateReqVO.getUnit().longValue() : null); |
| | | updateReqDTO.setItemType(MdmItemTypeEnum.PRODUCT.getType()); |
| | | updateReqDTO.setStatus(updateReqVO.getStatus()); |
| | | updateReqDTO.setSalesPrice(updateReqVO.getPrice()); |
| | | updateReqDTO.setRemark(updateReqVO.getDescription()); |
| | | mdmItemApi.updateItem(updateReqDTO); |
| | | |
| | | // 3. 更新本地产品记录 |
| | | CrmProductDO updateObj = BeanUtils.toBean(updateReqVO, CrmProductDO.class); |
| | | productMapper.updateById(updateObj); |
| | | |
| | | // 3. 记录操作日志上下文 |
| | | // 4. 记录操作日志上下文 |
| | | LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(crmProductDO, CrmProductSaveReqVO.class)); |
| | | } |
| | | |
| | | private CrmProductDO validateProductExists(Long id) { |
| | | // 从 MDM 校验 |
| | | MdmItemRespDTO item = mdmItemApi.getItem(id).getCheckedData(); |
| | | if (item == null) { |
| | | throw exception(PRODUCT_NOT_EXISTS); |
| | | } |
| | | // 从本地获取 CRM 产品记录 |
| | | CrmProductDO product = productMapper.selectById(id); |
| | | if (product == null) { |
| | | throw exception(PRODUCT_NOT_EXISTS); |
| | | // 如果本地不存在,创建一个同步记录 |
| | | product = convertToCrmProduct(item); |
| | | productMapper.insert(product); |
| | | } |
| | | return product; |
| | | } |
| | | |
| | | private void validateProductNoDuplicate(Long id, String no) { |
| | | CrmProductDO product = productMapper.selectByNo(no); |
| | | if (product == null |
| | | || product.getId().equals(id)) { |
| | | MdmItemRespDTO item = mdmItemApi.getItemByCode(no).getCheckedData(); |
| | | if (item == null || item.getId().equals(id)) { |
| | | return; |
| | | } |
| | | throw exception(PRODUCT_NO_EXISTS); |
| | |
| | | public void deleteProduct(Long id) { |
| | | // 校验存在 |
| | | validateProductExists(id); |
| | | // 删除 |
| | | // 通过 MDM API 删除(更新状态为禁用) |
| | | mdmItemApi.updateItemStatus(id, CommonStatusEnum.DISABLE.getStatus()); |
| | | // 删除本地记录 |
| | | productMapper.deleteById(id); |
| | | } |
| | | |
| | | @Override |
| | | @CrmPermission(bizType = CrmBizTypeEnum.CRM_PRODUCT, bizId = "#id", level = CrmPermissionLevelEnum.READ) |
| | | public CrmProductDO getProduct(Long id) { |
| | | return productMapper.selectById(id); |
| | | // 从 MDM 获取产品数据 |
| | | MdmItemRespDTO item = mdmItemApi.getItem(id).getCheckedData(); |
| | | if (item == null || !MdmItemTypeEnum.PRODUCT.getType().equals(item.getItemType())) { |
| | | return null; |
| | | } |
| | | // 获取本地 CRM 产品记录(用于权限) |
| | | CrmProductDO product = productMapper.selectById(id); |
| | | if (product == null) { |
| | | // 同步创建本地记录 |
| | | product = convertToCrmProduct(item); |
| | | productMapper.insert(product); |
| | | } else { |
| | | // 更新本地记录的数据 |
| | | product.setName(item.getName()); |
| | | product.setNo(item.getCode()); |
| | | product.setPrice(item.getSalesPrice()); |
| | | product.setStatus(item.getStatus()); |
| | | product.setCategoryId(item.getCategoryId()); |
| | | product.setDescription(item.getRemark()); |
| | | } |
| | | return product; |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<CrmProductDO> getProductPage(CrmProductPageReqVO pageReqVO) { |
| | | return productMapper.selectPage(pageReqVO); |
| | | // 从 MDM 获取产品分页数据 |
| | | cn.iocoder.yudao.framework.common.pojo.PageResult<MdmItemRespDTO> mdmPageResult = |
| | | mdmItemApi.getItemPage(MdmItemTypeEnum.PRODUCT.getType(), null, |
| | | pageReqVO.getPageNo(), pageReqVO.getPageSize()).getCheckedData(); |
| | | // 转换为 CRM 产品 |
| | | List<CrmProductDO> list = mdmPageResult.getList().stream() |
| | | .map(this::convertToCrmProduct) |
| | | .collect(Collectors.toList()); |
| | | return new PageResult<>(list, mdmPageResult.getTotal()); |
| | | } |
| | | |
| | | @Override |
| | | public Long getProductByCategoryId(Long categoryId) { |
| | | return productMapper.selectCountByCategoryId(categoryId); |
| | | return mdmItemApi.getItemCountByCategoryId(categoryId).getCheckedData(); |
| | | } |
| | | |
| | | @Override |
| | | public List<CrmProductDO> getProductListByStatus(Integer status) { |
| | | return productMapper.selectListByStatus(status); |
| | | // 从 MDM 获取产品数据 |
| | | List<MdmItemRespDTO> items = mdmItemApi.getItemListByStatus(status).getCheckedData(); |
| | | // 过滤产品类型并转换 |
| | | return items.stream() |
| | | .filter(item -> MdmItemTypeEnum.PRODUCT.getType().equals(item.getItemType())) |
| | | .map(this::convertToCrmProduct) |
| | | .collect(Collectors.toList()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<CrmProductDO> list = productMapper.selectByIds(ids); |
| | | Map<Long, CrmProductDO> productMap = convertMap(list, CrmProductDO::getId); |
| | | List<MdmItemRespDTO> items = mdmItemApi.getItemList(ids).getCheckedData(); |
| | | Map<Long, MdmItemRespDTO> itemMap = convertMap(items, MdmItemRespDTO::getId); |
| | | List<CrmProductDO> result = new ArrayList<>(); |
| | | for (Long id : ids) { |
| | | CrmProductDO product = productMap.get(id); |
| | | if (productMap.get(id) == null) { |
| | | MdmItemRespDTO item = itemMap.get(id); |
| | | if (item == null) { |
| | | throw exception(PRODUCT_NOT_EXISTS); |
| | | } |
| | | if (CrmProductStatusEnum.isDisable(product.getStatus())) { |
| | | throw exception(PRODUCT_NOT_ENABLE, product.getName()); |
| | | if (CrmProductStatusEnum.isDisable(item.getStatus())) { |
| | | throw exception(PRODUCT_NOT_ENABLE, item.getName()); |
| | | } |
| | | result.add(convertToCrmProduct(item)); |
| | | } |
| | | return list; |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return productMapper.selectByIds(ids); |
| | | List<MdmItemRespDTO> items = mdmItemApi.getItemList(ids).getCheckedData(); |
| | | return items.stream() |
| | | .filter(item -> MdmItemTypeEnum.PRODUCT.getType().equals(item.getItemType())) |
| | | .map(this::convertToCrmProduct) |
| | | .collect(Collectors.toList()); |
| | | } |
| | | |
| | | /** |
| | | * 将 MDM 物料转换为 CRM 产品 |
| | | */ |
| | | private CrmProductDO convertToCrmProduct(MdmItemRespDTO item) { |
| | | CrmProductDO product = new CrmProductDO(); |
| | | product.setId(item.getId()); |
| | | product.setName(item.getName()); |
| | | product.setNo(item.getCode()); |
| | | product.setUnit(item.getUnitMeasureId() != null ? item.getUnitMeasureId().intValue() : null); |
| | | product.setPrice(item.getSalesPrice()); |
| | | product.setStatus(item.getStatus()); |
| | | product.setCategoryId(item.getCategoryId()); |
| | | product.setDescription(item.getRemark()); |
| | | return product; |
| | | } |
| | | |
| | | } |