yangys
2025-08-16 f77951077aa87daae6460c0161868bd5661efb2f
bug修复
已添加3个文件
已修改19个文件
528 ■■■■■ 文件已修改
blade-service/blade-mdm/src/main/java/org/springblade/mdm/basesetting/producedivision/service/ProduceDivisionService.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/constants/FlowContants.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/FlowProgramController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/ReplaceFlowController.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/AutoAssignUsersService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/StartDispatcher.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/CureFlowService.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/FlowProgramFileService.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/ReplaceFlowService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/task/cure/CureFinishOperateTask.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/DncSendBackController.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/NcNodeController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/mapper/NcProgramApprovedMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/DNCSendBackService.java 80 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcProgramExportDNCService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/vo/DncSendBackData.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/vo/DncSendBackFile.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/test/OssTestController.java 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/utils/AnsiTextDetector.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/utils/FileContentUtil.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/test/java/org/springblade/mdm/utils/FileContentUtilTest.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/test/resources/filecontenttest.txt 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/basesetting/producedivision/service/ProduceDivisionService.java
@@ -161,14 +161,6 @@
            .eq(ProduceDivision::getTeamLeaderId,division.getTeamLeaderId()).count()>0;
    }
    public ProduceDivision getByDrawingNo(String drawingNo){
        List<ProduceDivision> divs = lambdaQuery().eq(ProduceDivision::getDrawingNo, drawingNo).list();
        if(divs.isEmpty()){
            return null;
        }else{
            return divs.get(0);
        }
    }
    /**
     * æ ¹æ®å‹¤å“²é›¶ä»¶å·äºŽä¸»ç®¡ç¼–制获取分工表数据 å›¾å·->勤哲数据(编制) ->  ä¸»åˆ¶åˆ†å·¥è¡¨æ•°æ®
@@ -179,7 +171,7 @@
    public ProduceDivision getByDrawingNoWithQinzhe(String drawingNo){
        QinzheFgb qinzheFgb = qinzheFgbService.getByLjh(drawingNo);
        if(qinzheFgb == null){
            throw new ServiceException("未找到零组件号");
            throw new ServiceException("未找到零组件号:"+drawingNo);
        }
        Long programmerId = tUserService.getUserIdByName(qinzheFgb.getZggy());
@@ -190,11 +182,7 @@
        if(division == null){
            throw new ServiceException("主制分工表无工艺员"+qinzheFgb.getZggy()+"对应的数据");
        }
        List<ProduceDivision> divs = lambdaQuery().eq(ProduceDivision::getDrawingNo, drawingNo).list();
        if(divs.isEmpty()){
            return null;
        }else{
            return divs.get(0);
        }
        return division;
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/constants/FlowContants.java
@@ -104,7 +104,7 @@
    /**
     * ä»»åŠ¡è½¦é—´
     */
    public static final String WORK_SHOP = "workShop";
    public static final String WORKSHOP = "workshop";
    /**
     * åç¦»å•号
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/FlowProgramController.java
@@ -18,8 +18,6 @@
import org.springblade.mdm.program.service.ProcessProgRefService;
import org.springframework.web.bind.annotation.*;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/ReplaceFlowController.java
@@ -10,6 +10,8 @@
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springblade.core.tool.api.R;
import org.springblade.mdm.basesetting.producedivision.entity.ProduceDivision;
import org.springblade.mdm.basesetting.producedivision.service.ProduceDivisionService;
import org.springblade.mdm.flow.constants.FlowContants;
import org.springblade.mdm.flow.excution.StartDispatcher;
import org.springblade.mdm.flow.service.ApproveRecordService;
@@ -24,6 +26,7 @@
import org.springblade.mdm.flow.vo.ReplaceUploadVO;
import org.springblade.mdm.flow.vo.TaskAssignVO;
import org.springblade.mdm.program.service.ProcessProgRefService;
import org.springblade.mdm.program.service.ProgramFlowStatusQueryService;
import org.springblade.mdm.program.vo.NcNodeVO;
import org.springframework.web.bind.annotation.*;
@@ -35,14 +38,7 @@
@RequestMapping("/flow/replace")
@Tag(name = "替换流程", description = "替换流程")
public class ReplaceFlowController {
    private final TaskService taskService;
    private final RuntimeService runtimeService;
    private final ApproveRecordService approveRecordService;
    private final FlowProgramFileService flowProgramFileService;
    private final DefaultFlowCompleteService defaultFlowCompleteService;
    private final TaskDispatchService taskDispatchService;
    private final ProduceDivisionService produceDivisionService;
    private final ReplaceFlowService replaceFlowService;
    @PostMapping("/pre")
@@ -85,4 +81,11 @@
        }
        return R.success();
    }
    @GetMapping("/default-assignees")
    @Operation(summary = "默认的审核用户", description = "准备程序替换流程,打开界面之前调用,调用之后会初始化文件列表,")
    public R<ProduceDivision> defaultAssignees(@Parameter(description = "零组件号") String drawingNo) {
        return R.data(produceDivisionService.getByDrawingNoWithQinzhe(drawingNo));
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/AutoAssignUsersService.java
@@ -23,7 +23,7 @@
    //private final ProduceDivisionMapper divMapper;
    private final ProduceDivisionService divService;
    /*
    public Map<String,Object> autoAssignUsers(TaskAssignVO startVO){
        LambdaQueryWrapper<ProduceDivision> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProduceDivision::getDrawingNo,startVO.getDrawingNo());
@@ -42,5 +42,5 @@
        result.put(FlowContants.SENIOR,division.getSeniorId());
        return result;
    }
    }*/
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/StartDispatcher.java
@@ -7,6 +7,8 @@
import org.flowable.engine.runtime.ProcessInstance;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.mdm.basesetting.producedivision.entity.ProduceDivision;
import org.springblade.mdm.basesetting.producedivision.service.ProduceDivisionService;
import org.springblade.mdm.flow.constants.FlowContants;
import org.springblade.mdm.flow.entity.FlowProgramFile;
import org.springblade.mdm.flow.service.FlowProgramFileService;
@@ -37,7 +39,8 @@
    private final FlowProgramFileService flowProgramFileService;
    private final NodeDeptQueryService nodeDeptQueryService;
    //public static final String PROCESS_KEY = "dispatch";
    private final ProduceDivisionService produceDivisionService;
    /**
     * å¯åŠ¨æ´¾å·¥æµç¨‹
@@ -46,19 +49,17 @@
     */
    @Transactional
    public String start(TaskAssignVO startVO){
        Map<String,Object> preAssignee = autoAssignUsersService.autoAssignUsers(startVO);
        Map<String, Object> vars = new HashMap<>(preAssignee);
        vars.put(FlowContants.ASSIGNEE,preAssignee.get(FlowContants.TEAM_LEADER));//第一个审批用户:组长
        Map<String, Object> vars = new HashMap<>();
        //Map<String,Object> preAssignee = autoAssignUsersService.autoAssignUsers(startVO);
        this.putDefaultAssignees(vars,startVO.getDrawingNo());
        vars.put(FlowContants.TITLE,startVO.getTitle());
        //机床编号
        vars.put(FlowContants.MACHINE_CODE,startVO.getMachineCode());
        String workshop = nodeDeptQueryService.getWorkshopNameByMachineCode(startVO.getMachineCode());
        vars.put("workshop",workshop);
        vars.put(FlowContants.WORKSHOP,workshop);
        //机床型号
        vars.put(FlowContants.MACHINE_MODE,startVO.getMachineMode());
        vars.put(FlowContants.PROCESS_NO,startVO.getProcessNo());
        vars.put(FlowContants.PROCESS_NAME,startVO.getProcessName());
@@ -93,6 +94,9 @@
        if(vars.getOrDefault(FlowContants.HAS_CURED_PROGRAM,FlowContants.N).equals(FlowContants.Y)){
            myProcessName = "固化下发流程";
        }
        if(StringUtils.isNotBlank(startVO.getDeviation()) ){
            myProcessName = "偏离单";
        }
        vars.put(FlowContants.MY_PROCESS_NAME, myProcessName);
        String businessKey = "0";//业务表key
@@ -107,18 +111,18 @@
    }
    /**
     * æ ¹æ®åŽŸæœ‰å›ºåŒ–ç¨‹åºåŒ…åèŠ‚ç‚¹ï¼Œå¤åˆ¶ä¸€ä¸ªï¼Œèµ‹äºˆæ–°çš„æµç¨‹å®žä¾‹id
     * @param programPkg åŽŸæœ‰å›ºåŒ–çš„ç¨‹åºåŒ…åèŠ‚ç‚¹
     * @param processInstanceId æµç¨‹å®žä¾‹id
     * å°†é»˜è®¤å®¡æ‰¹ç”¨æˆ·æ”¾å…¥map中
     * @param vars å¯åŠ¨æµç¨‹çš„å˜é‡map
     * @param drawingNo é›¶ç»„件号
     */
    void putDefaultAssignees(Map<String, Object> vars,String drawingNo){
        ProduceDivision div = produceDivisionService.getByDrawingNoWithQinzhe(drawingNo);
        vars.put(FlowContants.TEAM_LEADER,div.getTeamLeaderId());
        vars.put(FlowContants.PROGRAMMER,div.getProgrammerId());
        vars.put(FlowContants.CHECKER,div.getCheckerId());
        vars.put(FlowContants.SENIOR,div.getSeniorId());
    void cloneNodes(NcNode programPkg,String processInstanceId){
        NcNode newProgramPkg = new NcNode();
        BeanUtils.copyProperties(programPkg,newProgramPkg);
        EntityUtil.clearBaseProperties(newProgramPkg);
        newProgramPkg.setProcessInstanceId(processInstanceId);
        this.ncNodeService.save(newProgramPkg);
        vars.put(FlowContants.ASSIGNEE,div.getTeamLeaderId());//第一个审批用户:组长
    }
    /**
@@ -140,21 +144,5 @@
        }
    }
    /**
     * ç”Ÿæˆé›¶ç»„件编号
     * å›¾å·ã€å›¾å·ç‰ˆæ¬¡ã€å·¥åºå·ã€å·¥åºåç§°ã€å·¥è‰ºç‰ˆæ¬¡ã€å·¥åºç‰ˆæ¬¡ ç»„合起来获得零组件号
     * @param startVO
     * @return
     */
    /*
    String generatePartNo(TaskAssignVO startVO){
        //TODO è¿™ä¸ªæ ¼å¼æœªç¡®å®šï¼Œéœ€è¦ç¡®è®¤
        return String.format("%s-%s-%s-%s-%s-%s",
            startVO.getPartNo(),
            startVO.getPartNoEdition(),
            startVO.getProcessNo(),
            startVO.getProcessName(),
            startVO.getCraftEdition(),
            startVO.getProcessEdition());
    }*/
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/CureFlowService.java
@@ -17,16 +17,9 @@
import org.springblade.mdm.basesetting.producedivision.service.ProduceDivisionService;
import org.springblade.mdm.flow.constants.FlowContants;
import org.springblade.mdm.flow.entity.FlowProgramFile;
import org.springblade.mdm.flow.excution.AutoAssignUsersService;
import org.springblade.mdm.flow.vo.TaskAssignVO;
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.entity.NcProgram;
import org.springblade.mdm.program.entity.ProcessProgRef;
import org.springblade.mdm.program.service.NcNodeService;
import org.springblade.mdm.program.service.NcProgramService;
import org.springblade.mdm.program.service.ProcessProgRefService;
import org.springblade.mdm.program.vo.DncSendBackData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springblade.mdm.program.service.NodeDeptQueryService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -48,7 +41,7 @@
    private final HistoryService historyService;
    private final TaskService taskService;
    private final IdentityService identityService;
    private final NodeDeptQueryService nodeDeptQueryService;
    private final NcNodeService ncNodeService;
    private final FlowProgramFileService flowProgramFileService;
@@ -79,6 +72,10 @@
                vars.put(FlowContants.MACHINE_CODE,oldVars.get(FlowContants.MACHINE_CODE));
                //机床型号
                vars.put(FlowContants.MACHINE_MODE,oldVars.get(FlowContants.MACHINE_MODE));
                String workshop = nodeDeptQueryService.getWorkshopNameByMachineCode(programPackage.getMachineCode());
                vars.put(FlowContants.WORKSHOP,workshop);
                vars.put(FlowContants.PROCESS_NO,oldVars.get(FlowContants.PROCESS_NO));
                vars.put(FlowContants.PROCESS_NAME,oldVars.get(FlowContants.PROCESS_NAME));
                vars.put(FlowContants.PROCESS_EDITION,oldVars.get(FlowContants.PROCESS_EDITION));
@@ -186,8 +183,9 @@
        vars.put(FlowContants.PRODUCT_MODEL,programPackage.getProductModel());
        vars.put(FlowContants.PROGRAM_PACKAGE_NAME,programPackage.getName());
        ProduceDivision div = produceDivisionService.getByDrawingNo(programPackage.getDrawingNo());
        ProduceDivision div = produceDivisionService.getByDrawingNoWithQinzhe(programPackage.getDrawingNo());
        if(div != null) {
            vars.put(FlowContants.PROGRAMMER,div.getProgrammerId());
            vars.put(FlowContants.CHECKER,div.getCheckerId());
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/FlowProgramFileService.java
@@ -86,9 +86,12 @@
        String fileName = programFile.getOssName();
        try (InputStream inputStream = ossTemplate.statFileStream(fileName)) {
            ByteArrayInputStream bos = new ByteArrayInputStream(inputStream.readAllBytes());
            boolean isText= FileContentUtil.isTextFile(bos);
            boolean isText = StringUtils.endsWithIgnoreCase(fileName,".txt") || StringUtils.endsWithIgnoreCase(fileName,".nc")|| StringUtils.endsWithIgnoreCase(fileName,".xml");
            if(!isText){
                isText= FileContentUtil.isTextFile(bos);
            }
            if(isText){
            bos.reset();
                bos.reset();
                result = FileContentUtil.getContentFromStream(bos);
            }else{
                result = "<非文本文件>";
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/ReplaceFlowService.java
@@ -23,6 +23,7 @@
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.service.NcNodeService;
import org.springblade.mdm.program.service.NodeDeptQueryService;
import org.springblade.mdm.program.service.ProgramFlowStatusQueryService;
import org.springblade.mdm.program.vo.NcNodeVO;
import org.springblade.mdm.utils.EntityUtil;
import org.springblade.mdm.utils.ProgramFileNameCheckUtil;
@@ -47,6 +48,7 @@
    private final IdentityService identityService;
    private final FlowProgramFileService flowProgramFileService;
    private final ReplaceProgramFileService replaceProgramFileService;
    private final ProgramFlowStatusQueryService flowStatusQueryService;
    private final NodeDeptQueryService nodeDeptQueryService;
    private OssTemplate ossTemplate;
    public static final String NODE_ID = "nodeId";
@@ -79,8 +81,15 @@
     */
    /**
     * å‡†å¤‡æ›¿æ¢æµç¨‹éœ€è¦çš„æ•°æ®
     * @param nodeId è¦æ›¿æ¢çš„程序包名节点id
     * @param tempInstanceId ä¸´æ—¶æµç¨‹å®žä¾‹id,用于新的文件
     * @return å¯åŠ¨æ•°æ®
     */
    @Transactional
    public NcNodeVO pre(long nodeId, String tempInstanceId) {
        checkFlowStatus(nodeId);
        List<NcNode> fileNodes = nodeService.lambdaQuery()
            .eq(NcNode::getParentId, nodeId)
@@ -113,6 +122,14 @@
        return vo;
    }
    void checkFlowStatus(long nodeId) {
        NcNode packageNode = nodeService.getById(nodeId);
        int status = flowStatusQueryService.queryFlowStatus(packageNode.getProcessInstanceId());
        if (status == 1) {
            throw new ServiceException("程序的流程正在进行中,不能进行替换");
        }
    }
    /**
     * å¯åŠ¨æ›¿æ¢æµç¨‹
     */
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/task/cure/CureFinishOperateTask.java
@@ -4,8 +4,12 @@
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.N;
import org.flowable.engine.delegate.DelegateExecution;
import org.springblade.core.oss.OssTemplate;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.mdm.basesetting.machine.MachineService;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.commons.contants.ParamConstants;
import org.springblade.mdm.flow.entity.FlowProgramFile;
import org.springblade.mdm.flow.service.FlowCommonService;
@@ -14,9 +18,15 @@
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.service.NcNodeAutoCreateService;
import org.springblade.mdm.program.service.NcNodeService;
import org.springblade.mdm.program.service.ProgramAnnotationService;
import org.springblade.mdm.utils.FileContentUtil;
import org.springblade.system.feign.ISysClient;
import org.springblade.system.pojo.entity.Dict;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.Date;
@@ -31,6 +41,13 @@
    private final FlowCommonService flowCommonService;
    private final FlowProgramFileService flowProgramFileService;
    private final ISysClient sysClient;
    private final OssTemplate ossTemplate;
    private final ProgramAnnotationService programAnnotationService;
    private final MachineService machineService;
    public static final String GH = "GH";
    /**
     * é»˜è®¤æœ‰æ•ˆæœŸé—´ï¼ˆæœˆæ•°ï¼‰,2å¹´
     */
@@ -41,10 +58,10 @@
     * å›ºåŒ–审批通过处理任务,
     * @param execution æµç¨‹execution
     */
    public void execute(DelegateExecution execution) {
    @Transactional
    public void execute(DelegateExecution execution) throws IOException {
        log.info("执行固化程序任务服务,流程实例id={}", execution.getProcessInstanceId());
        //固化程序检查有效期,
        //1.将流程设置
        dealWithNode(execution.getProcessInstanceId());
    }
@@ -52,7 +69,7 @@
     * å¤„理node状态。
     * @param processInstanceId æµç¨‹å®žä¾‹id
     */
    void dealWithNode(String processInstanceId) {
    void dealWithNode(String processInstanceId) throws IOException {
        //程序包节点和下属程序节点(包括历史节点非最新版本的)从试切挪到固化下面
        //程序包节点 è®¾ç½®æœªå·²å›ºåŒ–
        NcNode pkgNode =  nodeService.lambdaQuery().eq(NcNode::getProcessInstanceId, processInstanceId).one();
@@ -78,7 +95,7 @@
     * @param pkgNode è¦æŒªåŠ¨çš„èŠ‚ç‚¹
     * @param historyProgramPackageNodes ç¨‹åºåŒ…名 åŽ†å²èŠ‚ç‚¹
     */
    void moveNodeToCuredTree(NcNode pkgNode,List<NcNode> historyProgramPackageNodes, FlowProgramProperties programProperties) {
    void moveNodeToCuredTree(NcNode pkgNode,List<NcNode> historyProgramPackageNodes, FlowProgramProperties programProperties) throws IOException {
        //创建节点到机床级别.(固化树)
        NcNode machineNode = ncNodeAutoCreateService.createNodeTreeToMachine(programProperties);
@@ -104,6 +121,8 @@
        }
        nodeService.updateBatchById(historyProgramPackageNodes);
        Machine machine = machineService.getByCode(pkgNode.getMachineCode());
        List<Dict> annoDicts = programAnnotationService.getAnnotionList();
        //新的流程文件,需要在包节点下新建,不能用老的
        List<FlowProgramFile> files = flowProgramFileService.lambdaQuery().eq(FlowProgramFile::getProcessInstanceId,pkgNode.getProcessInstanceId()).list();
        for(FlowProgramFile flowProgramFile : files){
@@ -117,6 +136,39 @@
            newProgNode.setFlowProgramFileId(flowProgramFile.getId());
            newProgNode.setIsCured(1);
            ncNodeService.save(newProgNode);
            //修改文件内容更新注释,并更新文件数据的地址
            ///替换注释后总是不行啊
            setGhAnnotation(flowProgramFile,machine.getMachineGroupCode(),annoDicts);
            flowProgramFileService.updateById(flowProgramFile);
        }
    }
    /**
     * è®¾ç½®å›ºåŒ–注释,实现方式,获取文件字节下,修改后替换文件
     * @param flowProgramFile oss æ–‡ä»¶
     *
     */
    void setGhAnnotation(FlowProgramFile flowProgramFile,String machineGroup,List<Dict> annoDicts) throws IOException {
        String ossName = flowProgramFile.getOssName();
        //
        try(InputStream ins = ossTemplate.statFileStream(ossName);){
            String annoTxt = programAnnotationService.generateAnnotation("GH",machineGroup,annoDicts);
            int statusLineIndex = 2;
            String line2 = FileContentUtil.readLineAt(ins,statusLineIndex);//第三行应该是状态注释
            InputStream finishedStream;
            if(programAnnotationService.isAnnotation(line2,machineGroup,annoDicts)){
                finishedStream = FileContentUtil.replaceAtLine(ins,statusLineIndex,annoTxt);
            }else{
                finishedStream = FileContentUtil.insertLine(ins,statusLineIndex,annoTxt);
            }
            try(finishedStream) {
                finishedStream.reset();
                BladeFile bfile = ossTemplate.putFile(flowProgramFile.getName(), finishedStream);
                //替换原有的文件地址
                flowProgramFile.setOssName(bfile.getName());
            }
        }
    }
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/DncSendBackController.java
@@ -3,6 +3,7 @@
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -45,14 +46,16 @@
            return R.fail(e.getMessage());
        }
    }
    /*
    @Operation(summary = "dnc回传数据分页", description = "dnc回传数据分页")
    @GetMapping("/page")
    public R<IPage<DncSendBackData>> page(Query query) {
        IPage<DncSendBackData> pages = ncProgramExchangeService.dncSendBackPageQuery(query);
        return R.data(pages);
    @GetMapping("/back-file-content")
    @Operation(summary = "获取回传文件内容", description = "查看工控网回传文件内容")
    public R<String> fileContent(@Parameter(description = "文件的entryName") String entryName) {
        try {
            return R.data(dncSendBackService.getEntryFileContent(entryName));
        }catch(Exception e) {
            log.error("删除文件失败",e);
            return R.fail(e.getMessage());
        }
    }
    */
    @PostMapping("accept")
    @ApiOperationSupport(order = 2)
    @Operation(summary = "DNC回传数据入库", description = "入库,同时启动固化流程,入参为上传是解析的数据列表")
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/NcNodeController.java
@@ -73,12 +73,10 @@
        List<NcNodeVO> list = ncNodeService.lazyList(parentId);
        if(list != null && !list.isEmpty()) {
            for(NcNodeVO ncNodeVO : list) {
                if(!NcNode.TYPE_PROGRAM_PACKAGE.equals(ncNodeVO.getNodeType())){
                    break;
                if(NcNode.TYPE_PROGRAM_PACKAGE.equals(ncNodeVO.getNodeType())){
                    ncNodeVO.setFlowStatus(programFlowStatusQueryService.queryFlowStatus(ncNodeVO.getProcessInstanceId()));
                }
                ncNodeVO.setFlowStatus(programFlowStatusQueryService.queryFlowStatus(ncNodeVO.getProcessInstanceId()));
            }
        }
        return R.data(list);
    }
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/mapper/NcProgramApprovedMapper.xml
@@ -11,7 +11,7 @@
        <result column="is_deleted" property="isDeleted"/>
    </resultMap>
    <select id="exportDncPageQuery" resultType="org.springblade.mdm.program.vo.NcProgramExportDncPageVO">
        select a.id,a.title,n.name,a.nc_node_id,n.drawing_no,n.drawing_no_edition,n.process_name,a.create_time from mdm_nc_program_approved a
        select a.id,a.title,n.name,a.nc_node_id,n.drawing_no,n.drawing_no_edition,n.process_name,a.create_time,a.update_time from mdm_nc_program_approved a
            inner join mdm_nc_node n on a.nc_node_id=n.id
        <where>
            a.is_deleted=0 and a.status=#{query.status}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/DNCSendBackService.java
@@ -24,6 +24,7 @@
import org.springblade.mdm.program.entity.NcProgramExchange;
import org.springblade.mdm.program.mapper.NcProgramExchangeMapper;
import org.springblade.mdm.program.vo.DncSendBackData;
import org.springblade.mdm.program.vo.DncSendBackFile;
import org.springblade.mdm.utils.EntityUtil;
import org.springblade.mdm.utils.FileContentUtil;
import org.springframework.beans.BeanUtils;
@@ -57,7 +58,7 @@
    private final FlowCommonService flowCommonService;
    private String getFileKey(){
        return "dncexpfile-"+ AuthUtil.getUserId();
        return "dncimpfile-"+ AuthUtil.getUserId();
    }
    /**
     * dnc回传文件上传
@@ -78,10 +79,10 @@
            //设置一个缓存,2小时过期
            bladeRedis.setEx(getFileKey(),bfile.getName(), Duration.ofHours(2));
            InputStream zipFileInputStream = file.getInputStream();//test
            list = parseProgramListFromZip(zipFileInputStream);
            try(InputStream zipFileInputStream = ossTemplate.statFileStream(bfile.getName());) {
                //InputStream zipFileInputStream = file.getInputStream();//test
                list = parseProgramListFromZip(zipFileInputStream);
            }
        } catch (IOException e) {
            log.error("上传dnc回传文件失败",e);
            throw new ServiceException("解析DNC回传数据失败");
@@ -145,6 +146,17 @@
                    if(programPackageNode != null) {
                        progData.setId(programPackageNode.getId());
                        progData.setProgramNo(programPackageNode.getProgramNo());
                        List<String> fileEtriyNames  = fileEntryNameList.stream().filter(n -> n.startsWith(packageName)).toList();
                        List<DncSendBackFile> programFiles = new ArrayList<>();
                        fileEtriyNames.forEach( filePath ->{
                                DncSendBackFile backFile = new DncSendBackFile();
                                backFile.setEntryName(filePath);
                                backFile.setName(StringUtils.removeStart(filePath,entryName));
                                programFiles.add(backFile);
                        });
                        progData.setFiles(programFiles);
                        list.add(progData);
                    }else{
                        throw new ServiceException("找不到程序包名:"+packageName+statusLine);
@@ -189,9 +201,9 @@
            this.save(exchange);
        }*/
        bladeRedis.del(filekey);
        this.ossTemplate.removeFile(zipFileName);
        log.info("删除oss文件:{}",zipFileName);
        //bladeRedis.del(filekey);
        //this.ossTemplate.removeFile(zipFileName);
        //log.info("删除oss文件:{}",zipFileName);
        //cureFlowService.startCure(newProgramPackageList,programPackageSubMap);
        cureFlowService.startCureNew(pkgIdFileMap);
@@ -394,20 +406,42 @@
        return tempFile;
    }
    void setBaseProperties(BizEntity entity, JSONObject jsonObject){
        entity.setCreateTime(jsonObject.getDate("createTime"));
        entity.setUpdateTime(jsonObject.getDate("updateTime"));
        entity.setStatus(jsonObject.getInteger("status"));
        entity.setCreateUser(jsonObject.getLong("createUser"));
        entity.setUpdateUser(jsonObject.getLong("updateUser"));
    /**
     * èŽ·å–å›žä¼ æ–‡ä»¶çš„å†…å®¹
     * @param entryName æ–‡ä»¶åœ¨åŽ‹ç¼©åŒ…å†…çš„è·¯å¾„
     * @return æ–‡ä»¶å†…容文本
     */
    public String getEntryFileContent(String entryName) throws IOException {
        String result  = "";
        String zipFileName = bladeRedis.get(getFileKey());
        try(InputStream inputStream = this.ossTemplate.statFileStream(zipFileName);){
            Path tempZipFile = createTempFile(inputStream);
            ZipEntry entry;
            try (java.util.zip.ZipFile zipFile = new java.util.zip.ZipFile(tempZipFile.toFile())) {
                Enumeration<? extends ZipEntry> entries = zipFile.entries();
                while (entries.hasMoreElements()) {
                    entry = entries.nextElement();
                    if (!entryName.equals(entry.getName())) {
                        continue;
                    }
                    try (InputStream fileIns = zipFile.getInputStream(zipFile.getEntry(entryName))) {
                        ByteArrayInputStream bos = new ByteArrayInputStream(fileIns.readAllBytes());
                        boolean isText = FileContentUtil.isTextFile(bos);
                        if (isText) {
                            bos.reset();
                            result = FileContentUtil.getContentFromStream(bos);
                        } else {
                            result = "<非文本文件>";
                        }
                    }
                }
            }
        }
        return result;
    }
    /*
    void clearBaseProperties(BizEntity entity){
        entity.setId(null);
        entity.setCreateTime(null);
        entity.setUpdateTime(null);
        entity.setStatus(null);
        entity.setCreateUser(null);
        entity.setUpdateUser(null);
    }*/
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcProgramExportDNCService.java
@@ -83,11 +83,15 @@
            for (Long approvedId : approvedIdArray) {
                NcProgramApproved approved = approvedService.getById(approvedId);
                addProgramPackageToZip(zipOut,approved);
                approved.setStatus(NcProgramApproved.STATUS_EXPORTED);
                approvedService.updateById(approved);
            }
            //状态修改为已导出
            /*
            approvedService.lambdaUpdate().in(NcProgramApproved::getId, Arrays.asList(approvedIdArray))
                .set(NcProgramApproved::getStatus,NcProgramApproved.STATUS_EXPORTED).update();
                .set(NcProgramApproved::getStatus,NcProgramApproved.STATUS_EXPORTED).update();*/
        }catch(Exception e){
            Throwable [] err = e.getSuppressed();
            throw new ServiceException("导出工控网错误"+e.getMessage());
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/vo/DncSendBackData.java
@@ -25,6 +25,6 @@
    private String md5;
    @Schema(description = "子文件(用于可识别文件加的机器返回的程序)")
    private List<String> children;
    private List<DncSendBackFile> files;
    private boolean hasChildren;
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/vo/DncSendBackFile.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package org.springblade.mdm.program.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.List;
@Setter
@Getter
@Schema(description = "DNC回传数据")
public class DncSendBackFile {
    @Schema(description = "文件名")
    private String name;
    @Schema(description = "文件路径")
    private String entryName;
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/test/OssTestController.java
@@ -8,9 +8,11 @@
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.oss.OssTemplate;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.FileUtil;
import org.springblade.mdm.utils.FileContentUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -68,54 +70,20 @@
        System.out.println(entryNameList);
        /*
        try (ZipFile zipFile = new ZipFile(tempFile.toFile())) {
            ZipEntry entry = zipFile.getEntry(entryn);
            InputStream ins = zipFile.getInputStream(entry);
            Path outputPath = Paths.get("d:/downtest.txt");
            Files.copy(ins, outputPath, StandardCopyOption.REPLACE_EXISTING);
        }
            List<String> entryNameList = new ArrayList<>();
        try (SeekableInMemoryByteChannel channel = new SeekableInMemoryByteChannel(bytes);
             ZipFile zipFile = new ZipFile(channel)) {
            ZipArchiveEntry entry;
            Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
            String entryn = "CP1-13-1/CP1-13-1-1-1-1.txt";
            while (entries.hasMoreElements()) {
                entry = entries.nextElement();
                entryNameList.add(entry.getName());
            }
        }*/
            /*
        try (SeekableInMemoryByteChannel channel = new SeekableInMemoryByteChannel(bytes);
             ZipFile zipFile = new ZipFile(channel)) {
            List<String> dirList = entryNameList.stream().filter(s -> s.endsWith("/")).toList();
            for(String dir : dirList) {
                entryNameList.stream().filter(s -> s.startsWith(dir)).forEach(entryName -> {
                    ZipArchiveEntry fileEntry = zipFile.getEntry(entryName);
                    //ZipArchiveEntry fileEntry = entryMap.get(entryName);
                    String fileName = StringUtils.removeStart(entryName,dir);//去除文件名路径部分
                    try {
                        InputStream ins = zipFile.getInputStream(fileEntry);
                        ByteArrayInputStream byteS = new ByteArrayInputStream(ins.readAllBytes());
                        Path outputPath = Paths.get("d:/downtest.txt");
                        Files.copy(byteS, outputPath, StandardCopyOption.REPLACE_EXISTING);
                        byteS.reset();
                        BladeFile newOssFile = ossTemplate.putFile("mdm", fileName, byteS);
                        r.setData(newOssFile.getName());
                        System.out.println(newOssFile.getName());
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                });
            }
        }*/
        return r;
    }
    @GetMapping("/replace")
    @ApiOperationSupport(order = 2)
    @Operation(summary = "替换内容")
    public R<String> replace(String filepath) throws IOException {
        File file = new File(filepath);
        FileInputStream fis = new FileInputStream(file);
        InputStream newins = FileContentUtil.replaceAtLine(fis,2,"GHTEST");
        BladeFile bfile = ossTemplate.putFile("replaceok.txt",newins);
        return R.data(bfile.getLink()+","+bfile.getName());
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/utils/AnsiTextDetector.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
package org.springblade.mdm.utils;
import org.apache.tika.detect.Detector;
import org.apache.tika.io.TikaInputStream;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.mime.MediaType;
import java.io.IOException;
import java.io.InputStream;
public class AnsiTextDetector  implements Detector {
    // å¯æ‰“印字符范围(ASCII + æ‰©å±•ANSI字符)
    private static final int PRINTABLE_START = 32;
    private static final int PRINTABLE_END = 126;
    private static final int EXTENDED_ANSI_START = 128;
    private static final int EXTENDED_ANSI_END = 255;
    // æ–‡æœ¬åˆ¤å®šé˜ˆå€¼ï¼šå¯æ‰“印字符占比 >= 80%
    private static final double TEXT_THRESHOLD = 0.8;
    @Override
    public MediaType detect(InputStream input, Metadata metadata) throws IOException {
        TikaInputStream tis = TikaInputStream.get(input);
        byte[] buffer = new byte[1024];
        int bytesRead = tis.read(buffer);
        if (bytesRead <= 0) {
            return MediaType.OCTET_STREAM;
        }
        int total = 0;
        int printable = 0;
        for (int i = 0; i < bytesRead; i++) {
            byte b = buffer[i];
            int unsigned = b & 0xFF; // è½¬ä¸ºæ— ç¬¦å·å­—节
            total++;
            // åˆ¤æ–­æ˜¯å¦ä¸ºå¯æ‰“印字符(含扩展ANSI)
            if ((unsigned >= PRINTABLE_START && unsigned <= PRINTABLE_END) ||
                (unsigned >= EXTENDED_ANSI_START && unsigned <= EXTENDED_ANSI_END)) {
                printable++;
            }
        }
        // è‹¥å¯æ‰“印字符占比达标,判定为文本
        if ((double) printable / total >= TEXT_THRESHOLD) {
            return MediaType.TEXT_PLAIN;
        }
        return MediaType.OCTET_STREAM;
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/utils/FileContentUtil.java
@@ -1,12 +1,22 @@
package org.springblade.mdm.utils;
import org.apache.tika.Tika;
import org.apache.tika.config.TikaConfig;
import org.apache.tika.detect.CompositeDetector;
import org.apache.tika.detect.DefaultDetector;
import org.apache.tika.detect.Detector;
import org.apache.tika.detect.TextDetector;
import org.apache.tika.mime.MimeType;
import org.apache.tika.mime.MimeTypeException;
import org.apache.tika.mime.MimeTypes;
import org.mozilla.universalchardet.UniversalDetector;
import org.springblade.core.tool.utils.Charsets;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
@@ -18,7 +28,9 @@
     * @return
     */
    public static boolean isTextFile(InputStream inputStream) {
        Tika tika = new Tika();
        MimeTypes mimeTypes = MimeTypes.getDefaultMimeTypes();
        Tika tika = new Tika(mimeTypes);
        try {
            String mimeType = tika.detect(inputStream);
            //String mimeType = tika.detect(file);
@@ -143,4 +155,40 @@
        return new String(bytes, charset);
    }
    /**
     * æ›¿æ¢æ–‡ä»¶ä¸­çš„æŸä¸€è¡Œ
     * @param ins è¾“入流
     * @param repalceWith æ›¿æ¢åŽçš„æ–‡æœ¬
     * @param lineIndex è¡Œç´¢å¼• 0 based
     */
    public static InputStream replaceAtLine(InputStream ins, int lineIndex,String repalceWith) throws IOException {
        byte[] bytes = ins.readAllBytes();
        ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
        Charset charset = Charsets.charset(detectFromInputStream(byteStream));
        byteStream.reset();
        Path tempFile = Files.createTempFile("temppro"+System.currentTimeMillis(), ".tmp");
        try (InputStreamReader isr = new InputStreamReader(byteStream, charset);
             BufferedReader reader = new BufferedReader(isr);
             BufferedWriter writer = Files.newBufferedWriter(tempFile,charset)) {//
            int currentLine = 0;
            String line;
            while ((line = reader.readLine()) != null) {
                // å¦‚果是目标行,写入新内容
                if (currentLine == lineIndex) {
                    writer.write(repalceWith);
                } else {
                    writer.write(line);
                }
                writer.newLine();
                currentLine++;
            }
        }
        return new ByteArrayInputStream(Files.newInputStream(tempFile).readAllBytes());
    }
}
blade-service/blade-mdm/src/test/java/org/springblade/mdm/utils/FileContentUtilTest.java
@@ -1,7 +1,10 @@
package org.springblade.mdm.utils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Charsets;
@@ -9,6 +12,9 @@
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class FileContentUtilTest {
@@ -46,15 +52,34 @@
        //System.out.println(charset);
    }
    //@Test
    @Test
    public void testReadLineAt() throws IOException {
        String file = "D:/a.txt";
        Path source = Paths.get("src/test/resources/filecontenttest.txt");
        int lineIndex = 1;
        FileInputStream fis = new FileInputStream(file);
        FileInputStream fis = new FileInputStream(source.toFile());
        String expected = "第二行";
        String read = FileContentUtil.readLineAt(fis,lineIndex);
        Assertions.assertEquals(expected,read);
    }
    @Test
    public void testReplaceReadLineAt(@TempDir Path tempDir) throws IOException {
        // åŠ è½½èµ„æºæ–‡ä»¶
        Path source = Paths.get("src/test/resources/filecontenttest.txt");
        //File file = new File(classLoader.getResource("filecontenttest.txt").getFile());
        File testFile = source.toFile();
        try(FileInputStream fis = new FileInputStream(testFile);) {
            String expected = "newline2";
            int lineIndex = 1;
            InputStream ins = FileContentUtil.replaceAtLine(fis, lineIndex, expected);
            List<String> list = IOUtils.readLines(ins, Charsets.UTF_8);
            System.out.println(list);
            Assertions.assertEquals(expected, list.get(lineIndex));
        }
    }
}
blade-service/blade-mdm/src/test/resources/filecontenttest.txt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,4 @@
等一会
第二行
第二3
第4行x