| | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.jeecg.common.api.vo.Result; |
| | | import org.jeecg.modules.dnc.entity.Cutter; |
| | | import org.jeecg.modules.dnc.entity.DocFile; |
| | | import org.jeecg.modules.dnc.entity.DocInfo; |
| | | import org.jeecg.modules.dnc.entity.GuideCardBatch; |
| | | import org.jeecg.modules.dnc.exception.ExceptionCast; |
| | | import org.jeecg.modules.dnc.mapper.CutterMapper; |
| | | import org.jeecg.modules.dnc.response.CommonCode; |
| | | import org.jeecg.modules.dnc.response.ProcessInfoCode; |
| | | import org.jeecg.modules.dnc.service.ICutterService; |
| | | import org.jeecg.modules.dnc.service.IDocFileService; |
| | | import org.jeecg.modules.dnc.service.IDocInfoService; |
| | | import org.jeecg.modules.dnc.service.IGuideCardBatchService; |
| | | import org.jeecg.modules.dnc.utils.ValidateUtil; |
| | | import org.jeecg.modules.dnc.utils.file.FileUtilS; |
| | | import org.jeecg.modules.tms.entity.PreparationOrderDetail; |
| | | import org.jeecg.modules.tms.entity.dto.PreparationOrderAndDetailDto; |
| | | import org.jeecg.modules.tms.service.IPreparationOrderService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Service |
| | | @Slf4j |
| | | public class CutterServiceImpl extends ServiceImpl<CutterMapper, Cutter> implements ICutterService { |
| | | |
| | | @Autowired |
| | | private IDocInfoService docInfoService; |
| | | |
| | | @Autowired |
| | | private IDocFileService docFileService; |
| | | |
| | | @Autowired |
| | | private IGuideCardBatchService guideCardBatchService; |
| | | |
| | | @Autowired |
| | | private IPreparationOrderService preparationOrderService; |
| | | /** |
| | | * 新增刀具信息 |
| | | * @param cutter |
| | |
| | | public Result<?> add(Cutter cutter){ |
| | | if(cutter == null) |
| | | ExceptionCast.cast(CommonCode.INVALID_PARAM); |
| | | if(!ValidateUtil.validateString(cutter.getProcessStepId())) |
| | | if(!ValidateUtil.validateString(cutter.getAttributionId())) |
| | | Result.error("无效的刀具"); |
| | | boolean b =this.checkCutterNo(cutter); |
| | | if(!b) |
| | | List<Cutter> cutterList =this.checkCutterNo(cutter); |
| | | if (cutterList != null && !cutterList.isEmpty()) { |
| | | return Result.error("已存在相同的刀具编号"); |
| | | } |
| | | boolean save = this.save(cutter); |
| | | if(save){ |
| | | return Result.OK("添加刀具成功"); |
| | |
| | | */ |
| | | @Override |
| | | public Result<?> edit(Cutter cutter){ |
| | | if(cutter == null) |
| | | ExceptionCast.cast(CommonCode.INVALID_PARAM); |
| | | if(!ValidateUtil.validateString(cutter.getCutterName())) |
| | | ExceptionCast.cast(ProcessInfoCode.PROCESS_NAME_NONE); |
| | | Cutter en = super.getById(cutter.getId()); |
| | | if(en == null) |
| | | ExceptionCast.cast(ProcessInfoCode.WORKSTEP_NOT_EXIST); |
| | | boolean b =this.checkCutterNo(cutter); |
| | | if(!b) |
| | | return Result.error("已存在相同的刀具编号"); |
| | | boolean save = this.updateById(cutter); |
| | | if(save){ |
| | | return Result.OK("刀具信息编辑成功"); |
| | | // 检查传入的刀具对象是否为空 |
| | | if (cutter == null) { |
| | | return Result.OK("刀具对象不能为空"); |
| | | } |
| | | return Result.OK("刀具信息编辑失败"); |
| | | // 检查刀具名称是否有效 |
| | | if (!ValidateUtil.validateString(cutter.getCutterName())) { |
| | | return Result.OK("刀具名称无效"); |
| | | } |
| | | // 根据刀具 ID 获取刀具信息 |
| | | Cutter existingCutter = super.getById(cutter.getId()); |
| | | if (existingCutter == null) { |
| | | return Result.OK("刀具不存在"); |
| | | } |
| | | // 过滤掉当前要编辑的刀具,检查是否有其他刀具存在相同编号 |
| | | List<Cutter> otherCuttersWithSameNo = this.checkCutterNo(cutter).stream() |
| | | .filter(cut -> !cut.getId().equals(cutter.getId())) |
| | | .collect(Collectors.toList()); |
| | | if (!otherCuttersWithSameNo.isEmpty()) { |
| | | // 如果存在除当前刀具外的其他刀具编号重复 |
| | | return Result.error("已存在相同的刀具编号"); |
| | | } |
| | | // 尝试更新刀具信息 |
| | | boolean updated = this.updateById(cutter); |
| | | if (updated) { |
| | | return Result.OK("刀具信息编辑成功"); |
| | | } else { |
| | | return Result.error("刀具信息编辑失败"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param cutter |
| | | * @return |
| | | */ |
| | | public boolean checkCutterNo(Cutter cutter){ |
| | | public List<Cutter> checkCutterNo(Cutter cutter){ |
| | | QueryWrapper<Cutter> queryWrapper = new QueryWrapper<>(); |
| | | queryWrapper.eq(StrUtil.isNotEmpty(cutter.getProcessStepId()),"process_step_id",cutter.getProcessStepId()); |
| | | queryWrapper.eq("type",cutter.getType()); |
| | | queryWrapper.eq(StrUtil.isNotEmpty(cutter.getCutterCode()),"craft_code",cutter.getCutterCode()); |
| | | List<Cutter> list = baseMapper.selectList(queryWrapper); |
| | | return list.isEmpty(); |
| | | queryWrapper.eq(StrUtil.isNotEmpty(cutter.getAttributionId()),"attribution_id",cutter.getAttributionId()); |
| | | queryWrapper.eq("attribution_type",cutter.getAttributionType()); |
| | | queryWrapper.eq(StrUtil.isNotEmpty(cutter.getCutterCode()),"cutter_code",cutter.getCutterCode()); |
| | | queryWrapper.eq(StrUtil.isNotEmpty(cutter.getCutterType()),"cutter_type",cutter.getCutterType()); |
| | | queryWrapper.eq(StrUtil.isNotEmpty(cutter.getCutterSpacing()),"cutter_spacing",cutter.getCutterSpacing()); |
| | | return baseMapper.selectList(queryWrapper); |
| | | } |
| | | |
| | | /** |
| | |
| | | @Override |
| | | public Result<?> query(Cutter cutter, Integer pageNo, Integer pageSize){ |
| | | QueryWrapper<Cutter> queryWrapper = new QueryWrapper<>(); |
| | | queryWrapper.eq(StrUtil.isNotEmpty(cutter.getProcessStepId()),"process_step_id",cutter.getProcessStepId()); |
| | | if (cutter.getType() != null){ |
| | | queryWrapper.eq("type",cutter.getType()); |
| | | queryWrapper.eq(StrUtil.isNotEmpty(cutter.getAttributionId()),"attribution_id",cutter.getAttributionId()); |
| | | if (cutter.getAttributionType() != null){ |
| | | queryWrapper.eq("attribution_type",cutter.getAttributionType()); |
| | | } |
| | | queryWrapper.like(StrUtil.isNotEmpty(cutter.getCutterName()),"craft_code",cutter.getCutterCode()); |
| | | queryWrapper.like(StrUtil.isNotEmpty(cutter.getCutterName()),"craft_name",cutter.getCutterName()); |
| | | queryWrapper.eq(StrUtil.isNotEmpty(cutter.getDocId()),"doc_id",cutter.getDocId()); |
| | | queryWrapper.like(StrUtil.isNotEmpty(cutter.getCutterCode()),"cutter_code",cutter.getCutterCode()); |
| | | queryWrapper.like(StrUtil.isNotEmpty(cutter.getCutterName()),"cutter_name",cutter.getCutterName()); |
| | | queryWrapper.orderByDesc("create_time"); |
| | | Page<Cutter> page = new Page<>(pageNo,pageSize); |
| | | IPage<Cutter> cutterIPage = baseMapper.selectPage(page, queryWrapper); |
| | | return Result.OK(cutterIPage); |
| | | } |
| | | |
| | | /** |
| | | * 从NC文件内容提取刀具信息并保存 |
| | | */ |
| | | @Override |
| | | @Transactional |
| | | public Result<?> extractAndSaveFromContent(String docId,String attributionId,Integer attributionType){ |
| | | DocInfo docInfo=docInfoService.getById(docId); |
| | | if (docInfo == null) { |
| | | return Result.error("未找到对应文档信息,无法提取刀具信息"); |
| | | } |
| | | docInfo.setAttributionId(attributionId); |
| | | docInfo.setAttributionType(attributionType); |
| | | DocFile docFile=docFileService.getById(docInfo.getPublishFileId()); |
| | | if (docFile == null) { |
| | | return Result.error("未找到对应文件信息,无法提取刀具信息"); |
| | | } |
| | | String filePath = docFile.getFilePath(); |
| | | String fileEncodeName = docFile.getFileEncodeName(); |
| | | //文档内容 |
| | | List<String> list = FileUtilS.readFile(fileEncodeName, filePath); |
| | | if (list == null || list.isEmpty()) { |
| | | return Result.error("文档内容为空,无法提取刀具信息"); |
| | | } |
| | | List<Cutter> cutterList = extractToolAfterM6(docInfo,list); |
| | | // 保存刀具 |
| | | if (!cutterList.isEmpty()) { |
| | | List<Cutter> newCutterList = new ArrayList<>(); |
| | | //验证刀具是否已经存在 |
| | | cutterList.forEach(item -> { |
| | | List<Cutter> otherCuttersWithSameNo = checkCutterNo(item); |
| | | if (otherCuttersWithSameNo == null || otherCuttersWithSameNo.isEmpty()) { |
| | | newCutterList.add(item); |
| | | } |
| | | }); |
| | | if (newCutterList.isEmpty()) { |
| | | return Result.error("未发现刀具的参数信息注释,无法提取刀具信息"); |
| | | } |
| | | this.saveBatch(newCutterList); |
| | | return Result.OK("提取刀具信息成功"); |
| | | }else { |
| | | return Result.error("未发现刀具的参数信息注释,无法提取刀具信息"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public Result<?> sendToCutterSystem(String docId,String attributionId,Integer attributionType){ |
| | | List<Cutter> cutterList = this.list(new QueryWrapper<Cutter>() |
| | | .eq("doc_id", docId) |
| | | .eq(StrUtil.isNotEmpty(attributionId),"attribution_id",attributionId) |
| | | .eq("attribution_type",attributionType)); |
| | | if (cutterList == null || cutterList.isEmpty()) { |
| | | return Result.error("未发现刀具信息,无法发送到刀具系统"); |
| | | } |
| | | if (cutterList.stream().anyMatch(item -> item.getCutterCode() == null)) { |
| | | return Result.error("未发现刀具编号信息,无法发送到刀具系统"); |
| | | } |
| | | //获取最新数控程序加工确认表 |
| | | List<GuideCardBatch> guideCardBatchList = guideCardBatchService.list(new QueryWrapper<GuideCardBatch>() |
| | | .eq("doc_id", docId) |
| | | .isNotNull("serial_number") |
| | | .orderByDesc("SUBSTRING(serial_number, LEN(serial_number)-3, 4)")); |
| | | if (guideCardBatchList == null || guideCardBatchList.isEmpty()) { |
| | | return Result.error("未发现程序加工确认表信息,无法发送到刀具系统"); |
| | | } |
| | | GuideCardBatch guideCardBatch = guideCardBatchList.get(0); |
| | | PreparationOrderAndDetailDto dto = new PreparationOrderAndDetailDto(); |
| | | dto.setPartDrawingNo(guideCardBatch.getPartsCode()); |
| | | dto.setPartName(guideCardBatch.getPartsName()); |
| | | dto.setPartMaterial(guideCardBatch.getMaterielDesp()); |
| | | dto.setProductionProcessesNo(guideCardBatch.getProcessWorkCode()); |
| | | dto.setBatchCode(guideCardBatch.getProcessingBatch()); |
| | | dto.setMachiningCount(guideCardBatch.getProcessingQuantity()); |
| | | dto.setEquipmentCode(guideCardBatch.getProcessingEquipment()); |
| | | dto.setNcName(guideCardBatch.getDocName()); |
| | | List<PreparationOrderDetail> detailList = new ArrayList<>(); |
| | | cutterList.forEach(item -> { |
| | | PreparationOrderDetail detail = new PreparationOrderDetail(); |
| | | detail.setToolCode(item.getToolsId()); |
| | | detailList.add(detail); |
| | | }); |
| | | dto.setPreparationOrderDetailList(detailList); |
| | | preparationOrderService.addPreparationOrderFromDnc(dto); |
| | | return Result.OK("发送到刀具系统成功"); |
| | | } |
| | | |
| | | public List<Cutter> extractToolAfterM6(DocInfo docInfo, List<String> ncLines) { |
| | | List<Cutter> cutterList = new ArrayList<>(); |
| | | String currentToolCode = null; // 用于追踪当前换刀指令的刀具号 |
| | | |
| | | for (String line : ncLines) { |
| | | String trimmedLine = line.trim(); |
| | | |
| | | // 1. 匹配 M6 换刀指令,提取 T代码(如 T01 M06 或 T 02 M06) |
| | | if (trimmedLine.contains("M6")||trimmedLine.contains("M06")) { |
| | | currentToolCode = extractToolCodeFromM6Line(trimmedLine); |
| | | } |
| | | |
| | | // 2. 匹配刀具参数注释(紧跟在 M6 后的括号内容) |
| | | if (currentToolCode != null && trimmedLine.startsWith("(") && trimmedLine.endsWith(")")) { |
| | | String toolDescription = trimmedLine.substring(1, trimmedLine.length() - 1).trim(); |
| | | if (!toolDescription.isEmpty()) { |
| | | Cutter cutter = new Cutter(); |
| | | cutter.setDocId(docInfo.getDocId()); |
| | | cutter.setAttributionId(docInfo.getAttributionId()); |
| | | cutter.setAttributionType(docInfo.getAttributionType()); |
| | | cutter.setDescription(toolDescription); |
| | | |
| | | // 从刀具描述中提取 cutterCode (例如从 "90E-10A" 中提取 "E") |
| | | extractToolInfoFromDescription(toolDescription, cutter); |
| | | |
| | | // 设置刀具间距(使用T代码或其他逻辑) |
| | | cutter.setCutterSpacing(currentToolCode); |
| | | |
| | | // 拆分刀具名称与规格(简单按空格分割,前部分为名称,后部分为规格) |
| | | String[] parts = toolDescription.split(" ", 2); |
| | | if (parts.length >= 1) { |
| | | cutter.setCutterName(parts[0]); |
| | | } |
| | | cutterList.add(cutter); |
| | | currentToolCode = null; // 重置,避免重复匹配 |
| | | } |
| | | } |
| | | } |
| | | |
| | | return cutterList; |
| | | } |
| | | |
| | | /** |
| | | * 从刀具描述中提取 cutterType 和 cutterCode |
| | | * 例如: "8CH-90A" -> cutterType="CH", cutterCode="90A" |
| | | */ |
| | | private void extractToolInfoFromDescription(String description, Cutter cutter) { |
| | | // 提取刀具型号(一个或多个连续的大写字母) |
| | | String cutterType = extractCutterType(description); |
| | | cutter.setCutterType(cutterType); |
| | | // 提取破折号后的规格部分 |
| | | String cutterSpec = ""; |
| | | int dashIndex = description.indexOf('-'); |
| | | if (dashIndex != -1 && dashIndex < description.length() - 1) { |
| | | cutterSpec = description.substring(dashIndex + 1).trim(); |
| | | cutter.setCutterSpec(cutterSpec); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 提取刀具型号(一个或多个连续的大写字母) |
| | | */ |
| | | private String extractCutterType(String description) { |
| | | Pattern pattern = Pattern.compile("[A-Z]+"); |
| | | Matcher matcher = pattern.matcher(description); |
| | | |
| | | if (matcher.find()) { |
| | | return matcher.group(); |
| | | } |
| | | |
| | | return description; |
| | | } |
| | | |
| | | // 辅助方法:从 M6 行提取 T代码(支持 T01 或 T 01 格式) |
| | | private String extractToolCodeFromM6Line(String line) { |
| | | Matcher matcher = Pattern.compile("T(\\d+)").matcher(line); |
| | | return matcher.find() ? "T" + matcher.group(1).trim() : null; |
| | | } |
| | | } |
| | | |