package com.ruoyi.production.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.basic.pojo.Product; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.basic.service.IProductModelService; import com.ruoyi.basic.service.IProductService; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.production.dto.ProductProcessDto; import com.ruoyi.production.dto.ProductProcessImportDto; import com.ruoyi.production.mapper.ProcessRouteItemMapper; import com.ruoyi.production.mapper.ProductProcessMapper; import com.ruoyi.production.mapper.ProductProcessRouteItemMapper; import com.ruoyi.production.pojo.ProcessRouteItem; import com.ruoyi.production.pojo.ProductProcess; import com.ruoyi.production.pojo.ProductProcessRouteItem; import com.ruoyi.production.service.ProductProcessService; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.mapper.SysUserMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @Slf4j @Service public class ProductProcessServiceImpl extends ServiceImpl implements ProductProcessService { @Autowired private ProductProcessMapper productProcessMapper; @Autowired private ProcessRouteItemMapper processRouteItemMapper; @Autowired private ProductProcessRouteItemMapper productProcessRouteItemMapper; @Autowired private IProductModelService productModelService; @Autowired private IProductService productService; @Autowired private SysUserMapper sysUserMapper; @Override public IPage listPage(Page page, ProductProcessDto productProcessDto) { return productProcessMapper.listPage(page, productProcessDto); } @Override @Transactional(rollbackFor = Exception.class) public void add(ProductProcessDto productProcessDto) { if (ObjectUtils.isEmpty(productProcessDto.getName())) { throw new ServiceException("部件名称不能为空"); } if (ObjectUtils.isNotEmpty(productProcessDto.getNo())) { long noCount = this.count(Wrappers.lambdaQuery().eq(ProductProcess::getNo, productProcessDto.getNo())); if (noCount > 0) { throw new ServiceException("工序编号已存在,不能重复"); } } // 判断计划工时是否为空 if (ObjectUtils.isEmpty(productProcessDto.getSalaryQuota())) { throw new ServiceException("新增失败,计划工时不能为空"); } // 判断产品是否存在 // if (ObjectUtils.isEmpty(productProcessDto.getProductModelId())) { // throw new ServiceException("新增失败,部件不能为空"); // } // ProductModel productModel = productModelService.getById(productProcessDto.getProductModelId()); // if (productModel == null) { // throw new ServiceException("新增失败,该部件不存在"); // } // validateDuplicateTypeForSameProduct(productModel.getId(), productProcessDto.getType(), null); ProductProcess productProcess = new ProductProcess(); BeanUtils.copyProperties(productProcessDto, productProcess); // productProcess.setProductModelId(productModel.getId()); validatePlanner(productProcessDto.getPlannerId(), productProcessDto.getPlannerName(), null); boolean save = productProcessMapper.insert(productProcess) > 0; if (save && ObjectUtils.isEmpty(productProcess.getNo())) { String no = "GX" + String.format("%08d", productProcess.getId()); productProcess.setNo(no); productProcessMapper.updateById(productProcess); } } @Override @Transactional(rollbackFor = Exception.class) public void update(ProductProcessDto productProcessDto) { if (ObjectUtils.isEmpty(productProcessDto.getId())) { throw new ServiceException("修改失败,工序ID不能为空"); } if (ObjectUtils.isEmpty(productProcessDto.getName())) { throw new ServiceException("部件名称不能为空"); } if (ObjectUtils.isNotEmpty(productProcessDto.getNo())) { long noCount = this.count(Wrappers.lambdaQuery() .eq(ProductProcess::getNo, productProcessDto.getNo()) .ne(ProductProcess::getId, productProcessDto.getId())); if (noCount > 0) { throw new ServiceException("工序编号已存在,不能重复"); } } ProductProcess oldProductProcess = this.getById(productProcessDto.getId()); if (oldProductProcess == null) { throw new ServiceException("修改失败,工序不存在"); } // Long finalProductModelId = ObjectUtils.isNotEmpty(productProcessDto.getProductModelId()) // ? productProcessDto.getProductModelId() : oldProductProcess.getProductModelId(); // Integer finalType = ObjectUtils.isNotEmpty(productProcessDto.getType()) // ? productProcessDto.getType() : oldProductProcess.getType(); // // 判断关联产品是否存在 // ProductModel productModel = productModelService.getById(finalProductModelId); // if (productModel == null) { // throw new ServiceException("修改失败,关联部件不存在"); // } // validateDuplicateTypeForSameProduct(productModel.getId(), finalType, productProcessDto.getId()); // 校验计划人员 validatePlanner(productProcessDto.getPlannerId(), productProcessDto.getPlannerName(), null); ProductProcess productProcess = new ProductProcess(); BeanUtils.copyProperties(productProcessDto, productProcess); this.updateById(productProcess); } @Override @Transactional(rollbackFor = Exception.class) public void importData(MultipartFile file) { try { ExcelUtil util = new ExcelUtil<>(ProductProcessImportDto.class); List importList = util.importExcel(file.getInputStream()); if (CollectionUtils.isEmpty(importList)) { throw new ServiceException("模板错误或导入数据为空"); } List productProcessList = new ArrayList<>(); for (int i = 0; i < importList.size(); i++) { ProductProcessImportDto importDto = importList.get(i); int rowNum = i + 2; SysUser sysUser = null; if (ObjectUtils.isEmpty(importDto)) { throw new ServiceException("第" + rowNum + "行数据为空,请使用正确的模板进行导入"); } if (ObjectUtils.isEmpty(importDto.getName())) { throw new ServiceException("第" + rowNum + "行:部件名称不能为空"); } if (ObjectUtils.isEmpty(importDto.getProductModel())) { throw new ServiceException("第" + rowNum + "行:部件规格不能为空"); } // 检验产品与类型是否存在 Product product = productService.getOne(new LambdaQueryWrapper().eq(Product::getProductName, importDto.getName())); if (product == null) { throw new ServiceException("第" + rowNum + "行: 部件【" + importDto.getName() + "】不存在"); } ProductModel productModel = productModelService.getOne(new LambdaQueryWrapper().eq(ProductModel::getProductId, product.getId()).eq(ProductModel::getModel, importDto.getProductModel())); if (ObjectUtils.isEmpty(productModel)) { throw new ServiceException("第" + rowNum + "行:部件规格【" + importDto.getProductModel() + "】不存在"); } if (ObjectUtils.isEmpty(importDto.getProductProcessType())) { throw new ServiceException("第" + rowNum + "行:部件【" + importDto.getName() + "】的类型不能为空"); } String dictValue = DictUtils.getDictValue("product_process_type", importDto.getProductProcessType()); if (StringUtils.isEmpty(dictValue)) { throw new ServiceException("第" + rowNum + "行:部件【" + importDto.getName() + "】的类型【" + importDto.getProductProcessType() + "】不存在,请填写正确的类型:" + DictUtils.getDictLabels("product_process_type")); } // 检验计划工时 if (importDto.getSalaryQuota() == null || importDto.getSalaryQuota().compareTo(BigDecimal.ZERO) < 0) { throw new ServiceException("第" + rowNum + "行:计划工时不能为空与负数"); } // 检验计划人员 if (StringUtils.isNotEmpty(importDto.getPlannerName())) { sysUser = sysUserMapper.selectUserByNickName(importDto.getPlannerName()); if (ObjectUtils.isEmpty(sysUser)) { throw new ServiceException("第" + rowNum + "行:计划人员【" + importDto.getPlannerName() + "】不存在"); } } ProductProcess productProcess = new ProductProcess(); BeanUtils.copyProperties(importDto, productProcess); productProcess.setProductModelId(productModel.getId()); productProcess.setType(Integer.valueOf(dictValue)); if (sysUser != null) { productProcess.setPlannerId(sysUser.getUserId()); productProcess.setPlannerName(sysUser.getNickName()); } productProcessList.add(productProcess); } saveOrUpdateBatch(productProcessList); } catch (ServiceException e) { throw e; } catch (Exception e) { log.error("部件导入异常:{}", e.getMessage(), e); throw new ServiceException("部件导入异常:" + e.getMessage()); } } /** * 校验计划人员是否存在 * * @param plannerId 计划人员ID * @param plannerName 计划人员姓名 * @param rowNum 行号 */ private void validatePlanner(Long plannerId, String plannerName, Integer rowNum) { String prefix = rowNum != null ? "第" + rowNum + "行:" : ""; if (plannerId != null) { if (sysUserMapper.selectUserById(plannerId) == null) { throw new ServiceException(prefix + "计划人员ID【" + plannerId + "】不存在"); } } else if (ObjectUtils.isNotEmpty(plannerName)) { if (sysUserMapper.selectUserByNickName(plannerName) == null) { throw new ServiceException(prefix + "计划人员姓名【" + plannerName + "】不存在"); } } } /** * 校验同一产品下工序类型不能重复 */ private void validateDuplicateTypeForSameProduct(Long productModelId, Integer type, Long excludeId) { if (productModelId == null || type == null) { return; } ProductModel currentModel = productModelService.getById(productModelId); if (currentModel == null || currentModel.getProductId() == null) { return; } List productModels = productModelService.list( Wrappers.lambdaQuery().eq(ProductModel::getProductId, currentModel.getProductId())); if (CollectionUtils.isEmpty(productModels)) { return; } List productModelIds = productModels.stream().map(ProductModel::getId).collect(Collectors.toList()); LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery() .in(ProductProcess::getProductModelId, productModelIds) .eq(ProductProcess::getType, type); if (excludeId != null) { queryWrapper.ne(ProductProcess::getId, excludeId); } if (this.count(queryWrapper) > 0) { throw new ServiceException("操作失败,同一产品不能存在重复的部件类型"); } } @Override @Transactional(rollbackFor = Exception.class) public void batchDelete(List ids) { // 查询是否生产中已经引用了这些工序 List processRouteItems = processRouteItemMapper .selectList(Wrappers.lambdaQuery().in(ProcessRouteItem::getProcessId, ids)); List productProcessRouteItems = productProcessRouteItemMapper.selectList( Wrappers.lambdaQuery().in(ProductProcessRouteItem::getProcessId, ids)); if (!CollectionUtils.isEmpty(processRouteItems) || !CollectionUtils.isEmpty(productProcessRouteItems)) { throw new ServiceException("该工序已经被使用,无法删除"); } productProcessMapper.deleteBatchIds(ids); } }