lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/CutterServiceImpl.java
@@ -5,20 +5,42 @@
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<CutterMapper, Cutter> implements ICutterService {
    @Autowired
    private IDocInfoService docInfoService;
    @Autowired
    private IDocFileService docFileService;
    @Autowired
    private ISysDictService sysDictService;
    /**
     * 新增刀具信息
@@ -108,6 +130,8 @@
        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);
    }
@@ -123,6 +147,7 @@
        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");
@@ -130,4 +155,118 @@
        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()) {
            this.saveBatch(cutterList);
            //TODO发送刀具管理数据
            return Result.OK("提取刀具信息成功");
        }else {
            return Result.error("未发现刀具的参数信息注释,无法提取刀具信息");
        }
    }
    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;
    }
}