package org.jeecg.modules.dnc.service.impl; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 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.exception.ExceptionCast; import org.jeecg.modules.dnc.mapper.CutterMapper; import org.jeecg.modules.dnc.response.CommonCode; 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.utils.ValidateUtil; import org.jeecg.modules.dnc.utils.file.FileUtilS; import org.jeecg.modules.system.service.ISysDictService; 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 implements ICutterService { @Autowired private IDocInfoService docInfoService; @Autowired private IDocFileService docFileService; @Autowired private ISysDictService sysDictService; /** * 新增刀具信息 * @param cutter * @return */ @Override public Result add(Cutter cutter){ if(cutter == null) ExceptionCast.cast(CommonCode.INVALID_PARAM); if(!ValidateUtil.validateString(cutter.getAttributionId())) Result.error("无效的刀具"); List cutterList =this.checkCutterNo(cutter); if (cutterList != null && !cutterList.isEmpty()) { return Result.error("已存在相同的刀具编号"); } boolean save = this.save(cutter); if(save){ return Result.OK("添加刀具成功"); } return Result.error("新增刀具失败"); } /** * 编辑刀具信息 * @param cutter * @return */ @Override public Result edit(Cutter cutter){ // 检查传入的刀具对象是否为空 if (cutter == null) { 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 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 id * @return */ @Override public Result delete(String id){ if(!ValidateUtil.validateString(id)) ExceptionCast.cast(CommonCode.INVALID_PARAM); Cutter en = super.getById(id); if(en == null) return Result.error("无效的刀具"); boolean b=super.removeById(id); if(!b) { return Result.error("删除刀具失败"); } return Result.OK("删除刀具成功"); } /** * 验证同结构下刀具编号是否重复 * @param cutter * @return */ public List checkCutterNo(Cutter cutter){ QueryWrapper queryWrapper = new QueryWrapper<>(); 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); } /** * 获取业务id下的刀具列表 * @param cutter * @return */ @Override public Result query(Cutter cutter, Integer pageNo, Integer pageSize){ QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq(StrUtil.isNotEmpty(cutter.getAttributionId()),"attribution_id",cutter.getAttributionId()); if (cutter.getAttributionType() != null){ queryWrapper.eq("attribution_type",cutter.getAttributionType()); } 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 page = new Page<>(pageNo,pageSize); IPage 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 list = FileUtilS.readFile(fileEncodeName, filePath); if (list == null || list.isEmpty()) { return Result.error("文档内容为空,无法提取刀具信息"); } List cutterList = extractToolAfterM6(docInfo,list); // 保存刀具 if (!cutterList.isEmpty()) { List newCutterList = new ArrayList<>(); //验证刀具是否已经存在 cutterList.forEach(item -> { List otherCuttersWithSameNo = checkCutterNo(item); if (otherCuttersWithSameNo == null || otherCuttersWithSameNo.isEmpty()) { newCutterList.add(item); } }); if (newCutterList.isEmpty()) { return Result.error("未发现刀具的参数信息注释,无法提取刀具信息"); } this.saveBatch(newCutterList); //TODO发送刀具管理数据 return Result.OK("提取刀具信息成功"); }else { return Result.error("未发现刀具的参数信息注释,无法提取刀具信息"); } } public List extractToolAfterM6(DocInfo docInfo, List ncLines) { List 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; } }