| | |
| | | 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.Customer; |
| | | 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.StringUtils; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import com.ruoyi.production.dto.ProductProcessDto; |
| | | import com.ruoyi.production.dto.ProductProcessImportDto; |
| | | import com.ruoyi.production.enums.ProductProcessEnum; |
| | | import com.ruoyi.production.mapper.ProcessRouteItemMapper; |
| | | import com.ruoyi.production.mapper.ProductProcessMapper; |
| | | import com.ruoyi.production.mapper.ProductProcessRouteItemMapper; |
| | |
| | | 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<ProductProcessMapper, ProductProcess> implements ProductProcessService { |
| | | public class ProductProcessServiceImpl extends ServiceImpl<ProductProcessMapper, ProductProcess> |
| | | 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<ProductProcessDto> listPage(Page page, ProductProcessDto productProcessDto) { |
| | |
| | | } |
| | | |
| | | @Override |
| | | public AjaxResult add(ProductProcessDto productProcessDto) { |
| | | @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.<ProductProcess>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); |
| | | BeanUtils.copyProperties(productProcessDto, productProcess); |
| | | productProcess.setProductModelId(productModel.getId()); |
| | | |
| | | validatePlanner(productProcessDto.getPlannerId(), productProcessDto.getPlannerName(), null); |
| | | |
| | | boolean save = productProcessMapper.insert(productProcess) > 0; |
| | | if (save && ObjectUtils.isNull(productProcessDto.getNo())) { |
| | | // 根据id生成no字段:GX + 8位数字(不足8位前面补0) |
| | | if (save && ObjectUtils.isEmpty(productProcess.getNo())) { |
| | | String no = "GX" + String.format("%08d", productProcess.getId()); |
| | | productProcess.setNo(no); |
| | | |
| | | productProcessMapper.updateById(productProcess); |
| | | return AjaxResult.success(); |
| | | } |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @Override |
| | | public AjaxResult importData(MultipartFile file) { |
| | | try { |
| | | ExcelUtil<ProductProcess> util = new ExcelUtil<ProductProcess>(ProductProcess.class); |
| | | List<ProductProcess> productProcessList = util.importExcel(file.getInputStream()); |
| | | if(CollectionUtils.isEmpty(productProcessList)){ |
| | | return AjaxResult.warn("模板错误或导入数据为空"); |
| | | @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.<ProductProcess>lambdaQuery() |
| | | .eq(ProductProcess::getNo, productProcessDto.getNo()) |
| | | .ne(ProductProcess::getId, productProcessDto.getId())); |
| | | if (noCount > 0) { |
| | | throw new ServiceException("工序编号已存在,不能重复"); |
| | | } |
| | | this.saveOrUpdateBatch(productProcessList); |
| | | return AjaxResult.success(true); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | return AjaxResult.error("导入失败"); |
| | | } |
| | | |
| | | 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<ProductProcessImportDto> util = new ExcelUtil<>(ProductProcessImportDto.class); |
| | | List<ProductProcessImportDto> importList = util.importExcel(file.getInputStream()); |
| | | if (CollectionUtils.isEmpty(importList)) { |
| | | throw new ServiceException("模板错误或导入数据为空"); |
| | | } |
| | | |
| | | List<ProductProcess> 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<Product>().eq(Product::getProductName, importDto.getName())); |
| | | if (product == null) { |
| | | throw new ServiceException("第" + rowNum + "行: 部件【" + importDto.getName() + "】不存在"); |
| | | } |
| | | ProductModel productModel = productModelService.getOne(new LambdaQueryWrapper<ProductModel>().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() + "】的类型不能为空"); |
| | | } |
| | | ProductProcessEnum enumByInfo = ProductProcessEnum.getEnumByInfo(importDto.getProductProcessType()); |
| | | if (ObjectUtils.isEmpty(enumByInfo)) { |
| | | throw new ServiceException("第" + rowNum + "行:部件【" + importDto.getName() + "】的类型【" |
| | | + importDto.getProductProcessType() + "】不存在,请填写正确的类型:加工、刮板冷芯制作、管路组对、罐体连接及调试、测试打压、其他"); |
| | | } |
| | | // 检验计划工时 |
| | | 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(enumByInfo.getCode()); |
| | | 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<ProductModel> productModels = productModelService.list( |
| | | Wrappers.<ProductModel>lambdaQuery().eq(ProductModel::getProductId, currentModel.getProductId())); |
| | | if (CollectionUtils.isEmpty(productModels)) { |
| | | return; |
| | | } |
| | | List<Long> productModelIds = productModels.stream().map(ProductModel::getId).collect(Collectors.toList()); |
| | | LambdaQueryWrapper<ProductProcess> queryWrapper = Wrappers.<ProductProcess>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 |
| | | public String batchDelete(List<Integer> ids) { |
| | | //查询是否生产中已经引用了这些工序 |
| | | List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(Wrappers.<ProcessRouteItem>lambdaQuery().in(ProcessRouteItem::getProcessId, ids)); |
| | | List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().in(ProductProcessRouteItem::getProcessId, ids)); |
| | | if (!CollectionUtils.isEmpty(processRouteItems) || !CollectionUtils.isEmpty(productProcessRouteItems)){ |
| | | throw new RuntimeException("该工序已经被使用,无法删除"); |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void batchDelete(List<Integer> ids) { |
| | | // 查询是否生产中已经引用了这些工序 |
| | | List<ProcessRouteItem> processRouteItems = processRouteItemMapper |
| | | .selectList(Wrappers.<ProcessRouteItem>lambdaQuery().in(ProcessRouteItem::getProcessId, ids)); |
| | | List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList( |
| | | Wrappers.<ProductProcessRouteItem>lambdaQuery().in(ProductProcessRouteItem::getProcessId, ids)); |
| | | if (!CollectionUtils.isEmpty(processRouteItems) || !CollectionUtils.isEmpty(productProcessRouteItems)) { |
| | | throw new ServiceException("该工序已经被使用,无法删除"); |
| | | } |
| | | productProcessMapper.deleteBatchIds(ids); |
| | | return null; |
| | | } |
| | | } |