| | |
| | | |
| | | package org.springblade.mdm.program.service; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.alibaba.csp.sentinel.util.StringUtil; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.io.FilenameUtils; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.jetbrains.annotations.NotNull; |
| | | import org.springblade.core.mp.base.BizEntity; |
| | | import org.springblade.core.log.exception.ServiceException; |
| | | import org.springblade.core.mp.base.BizServiceImpl; |
| | | import org.springblade.core.mp.support.Condition; |
| | | import org.springblade.core.mp.support.Query; |
| | | import org.springblade.core.oss.OssTemplate; |
| | | import org.springblade.core.tool.api.R; |
| | | import org.springblade.core.tool.utils.Func; |
| | | import org.springblade.mdm.basesetting.machine.MachineService; |
| | | import org.springblade.mdm.basesetting.machine.service.MachineService; |
| | | import org.springblade.mdm.basesetting.machine.entity.Machine; |
| | | import org.springblade.mdm.flow.entity.ApproveRecord; |
| | | import org.springblade.mdm.flow.entity.FlowProgramFile; |
| | | import org.springblade.mdm.flow.service.ApproveRecordService; |
| | | import org.springblade.mdm.flow.service.FlowProgramFileService; |
| | | import org.springblade.mdm.program.entity.NcNode; |
| | | import org.springblade.mdm.program.entity.NcProgram; |
| | | import org.springblade.mdm.program.entity.NcNodeHis; |
| | | import org.springblade.mdm.program.entity.NcProgramApproved; |
| | | 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.utils.FileContentUtil; |
| | | import org.springblade.mdm.program.service.programannotation.AnnotationData; |
| | | import org.springblade.mdm.program.service.programannotation.AnnotationProcessor; |
| | | import org.springblade.mdm.program.service.programannotation.MachineAnnotationConfig; |
| | | import org.springblade.mdm.program.service.programannotation.ProcessorHelper; |
| | | import org.springblade.system.feign.IDictClient; |
| | | import org.springblade.system.feign.ISysClient; |
| | | import org.springblade.system.pojo.entity.Dict; |
| | | import org.springblade.system.pojo.entity.DictBiz; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.io.*; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Optional; |
| | | import java.util.*; |
| | | import java.util.zip.ZipEntry; |
| | | import java.util.zip.ZipOutputStream; |
| | | |
| | |
| | | @AllArgsConstructor |
| | | public class NcProgramExportDNCService extends BizServiceImpl<NcProgramExchangeMapper, NcProgramExchange> { |
| | | |
| | | //private final NcProgramService progService; |
| | | private final IDictClient dictClient; |
| | | private final MachineService machineService; |
| | | private final NcProgramApprovedService approvedService; |
| | | private final ApproveRecordService approveRecordService; |
| | | private final NcNodeService ncNodeService; |
| | | private final NcNodeHisService ncNodeHisService; |
| | | private final OssTemplate ossTemplate; |
| | | private final FlowProgramFileService flowProgramFileService; |
| | | //public static final String PROGRAM_JSON_FILE = "exp_mdm_nc_program.json"; |
| | | public static final String NODE_JSON_FILE = "exp_mdm_nc_node.json"; |
| | | public static final String APPROVE_RECORD_JSON_FILE = "exp_mdm_approve_record.json"; |
| | | private final ProgramAnnotationService programAnnotationService; |
| | | |
| | | public static final String ANNOTATION_DICT = "machine_annotation"; |
| | | |
| | | /** |
| | | * 分页查询 |
| | | * @param query 查询参数 |
| | | * @return |
| | | */ |
| | | public IPage<DncSendBackData> dncSendBackPageQuery(Query query) { |
| | | return this.getBaseMapper().dncSendBackpageQuery(Condition.getPage(query),query); |
| | | } |
| | | |
| | | private final MachineAnnotationConfig annotationConfig; |
| | | /** |
| | | * 导出dnc压缩包 |
| | | * @param approvedIdArr 待导出审批表id数组 |
| | | * @param approvedIdArray 待导出审批表id数组 |
| | | */ |
| | | public void exportDnc(Long[] approvedIdArr, OutputStream os) throws IOException { |
| | | public void exportDnc(Long[] approvedIdArray, OutputStream os) throws IOException { |
| | | //FileOutputStream fos = new FileOutputStream("d:/exportDnc.zip"); |
| | | try (ZipOutputStream zipOut = new ZipOutputStream(os);) {//os |
| | | try (ZipOutputStream zipOut = new ZipOutputStream(os);os) {//os |
| | | |
| | | ArrayList<Long> programPackageNodeIdList = new ArrayList<Long>(); |
| | | |
| | | for (Long approvedId : approvedIdArr) { |
| | | for (Long approvedId : approvedIdArray) { |
| | | NcProgramApproved approved = approvedService.getById(approvedId); |
| | | programPackageNodeIdList.add(approved.getNcNodeId()); |
| | | |
| | | addProgramPackageToZip(zipOut,approved); |
| | | |
| | | approved.setStatus(NcProgramApproved.STATUS_EXPORTED); |
| | | approvedService.updateById(approved); |
| | | } |
| | | addDataJson(zipOut, programPackageNodeIdList); |
| | | |
| | | }catch(Exception e){ |
| | | Throwable [] err = e.getSuppressed(); |
| | | throw new ServiceException("导出工控网错误"+e.getMessage()); |
| | | } |
| | | |
| | | os.close(); |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param approved |
| | | */ |
| | | private void addProgramPackageToZip(ZipOutputStream zipOut, NcProgramApproved approved) throws IOException{ |
| | | String packageFolder = approved.getProgramName()+"/"; |
| | | NcNodeHis packageNodeHis = ncNodeHisService.getById(approved.getNcNodeId()); |
| | | |
| | | String packageFolder = packageNodeHis.getName()+"/"; |
| | | ZipEntry zipEntry = new ZipEntry(packageFolder);// "/"结尾表示文件夹 |
| | | zipOut.putNextEntry(zipEntry); |
| | | zipOut.closeEntry(); |
| | | |
| | | List<NcNode> programNodes = ncNodeService.lambdaQuery().eq(NcNode::getIsLastEdition,1).eq(NcNode::getParentId, approved.getNcNodeId()).list(); |
| | | Machine machine = machineService.getByCode(packageNodeHis.getMachineCode());//程序包节点,获取注释用 |
| | | |
| | | //List<NcNode> programNodes = ncNodeService.lambdaQuery().eq(NcNode::getIsLastEdition,1).eq(NcNode::getParentId, approved.getNcNodeId()).list(); |
| | | List<NcNodeHis> programNodes = ncNodeHisService.lambdaQuery().eq(NcNodeHis::getParentId, approved.getNcNodeId()).list(); |
| | | |
| | | FlowProgramFile programFile; |
| | | NcNode programPackageNode = this.ncNodeService.getById(approved.getNcNodeId()); |
| | | String status = "试切"; |
| | | if(programPackageNode.isDeviation()){ |
| | | status = "偏离"; |
| | | NcNodeHis programPackageNode = this.ncNodeHisService.getById(approved.getNcNodeId()); |
| | | String status = "SQ"; |
| | | if(programPackageNode.isDeviationProgram()){ |
| | | status = "PL"; |
| | | }else if(programPackageNode.hasCured()){ |
| | | status = "固化"; |
| | | status = "GH"; |
| | | } |
| | | List<Dict> annotationList = getAnnotionList(); |
| | | for (NcNode node : programNodes) { |
| | | String filePathInZip = packageFolder + node.getName(); |
| | | long deviationSerial = -1;//偏离单序号 ,-1为非偏离单,不需要加入 |
| | | if(packageNodeHis.isDeviationProgram()) { |
| | | deviationSerial = ncNodeHisService.getDeviationSerialForNode(packageNodeHis); |
| | | } |
| | | |
| | | //List<DictBiz> annotationDictList= programAnnotationService.getAnnotionDictList(); |
| | | for (NcNodeHis node : programNodes) { |
| | | String filePathInZip = genFilePathInZip(packageFolder,node,deviationSerial); |
| | | programFile = this.flowProgramFileService.getById(node.getFlowProgramFileId()); |
| | | if(programFile.isProgram()) {//程序文件,才会加入压缩包 |
| | | InputStream inputStream = ossTemplate.statFileStream(programFile.getOssName()); |
| | | String sendDir = machine.getProgSendDir()==null? StringUtil.EMPTY:machine.getProgSendDir(); |
| | | |
| | | InputStream inputStream = ossTemplate.statFileStream(programFile.getOssName()); |
| | | Machine machine = machineService.getByCode(node.getMachineCode()); |
| | | InputStream addedIns1 = addSendDirAnnotation(inputStream,machine,annotationList); |
| | | InputStream addedIns2 = addProgramStatusAnnotation(addedIns1,status,machine,annotationList); |
| | | this.addInputStreamToZip(zipOut,addedIns2,filePathInZip); |
| | | AnnotationProcessor annoProcessor = ProcessorHelper.getProcessor(machine.getControlSystem(),annotationConfig); |
| | | AnnotationData annoData = new AnnotationData(); |
| | | annoData.setSendPath(sendDir); |
| | | annoData.setProgramStatus(status); |
| | | annoData.setDeviation(programPackageNode.getDeviation()); |
| | | annoData.setFilename(programFile.getName()); |
| | | InputStream addedInsFinal = annoProcessor.setAnnotation(annoData,inputStream); |
| | | addedInsFinal.reset(); |
| | | /* |
| | | InputStream addedInsFinal; |
| | | InputStream addedIns2 = programAnnotationService.setSendDirAndStatusAnnotation(sendDir,status,inputStream,machine.getControlSystem()); |
| | | if(StringUtils.isNotBlank(programPackageNode.getDeviation())) { |
| | | //偏离单,增加偏离单号 |
| | | addedInsFinal = programAnnotationService.setPldAnnotation(programPackageNode.getDeviation(),addedIns2, machine.getControlSystem(), annotationDictList);; |
| | | }else{ |
| | | addedInsFinal = addedIns2; |
| | | }*/ |
| | | this.addInputStreamToZip(zipOut, addedInsFinal, filePathInZip); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 获取字典中配置的注释 |
| | | * @return 字典项列表 |
| | | * 生成在zip中的文件路径 |
| | | * @param packageFolder zip中的文件夹 |
| | | * @param programNode 程序节点 |
| | | * @param deviationSerial 偏离单序号 |
| | | * @return zip中的文件路径 |
| | | */ |
| | | List<Dict> getAnnotionList(){ |
| | | List<Dict> annotationList; |
| | | R<List<Dict>> dictsResult = dictClient.getList(ANNOTATION_DICT); |
| | | if(dictsResult.isSuccess()) { |
| | | annotationList = dictsResult.getData(); |
| | | String genFilePathInZip(String packageFolder,NcNodeHis programNode,long deviationSerial){ |
| | | //为文件名增加偏离单号 |
| | | String filePathInZip; |
| | | |
| | | if(deviationSerial != -1){ |
| | | //加入偏离单序号 |
| | | String ext = FilenameUtils.getExtension(programNode.getName()); |
| | | String dotExt = StringUtils.isNotBlank(ext)?"."+ext:ext;//带点的扩展名 |
| | | |
| | | String temp = programNode.getName(); |
| | | if(StringUtils.isNotBlank(ext)) { |
| | | temp = StringUtils.removeEnd(temp,dotExt); |
| | | } |
| | | filePathInZip = packageFolder + temp+"-P"+deviationSerial+dotExt; |
| | | }else{ |
| | | annotationList = Collections.emptyList(); |
| | | //非偏离单,直接使用原文件名 |
| | | filePathInZip = packageFolder + programNode.getName(); |
| | | } |
| | | |
| | | return annotationList; |
| | | return filePathInZip; |
| | | } |
| | | /** |
| | | * 加入机床下发路径和程序状态的注释 |
| | | * @param inputStream |
| | | * @return |
| | | */ |
| | | InputStream addSendDirAnnotation(InputStream inputStream,Machine machine,List<Dict> annotationList) throws IOException { |
| | | return FileContentUtil.insertLine(inputStream,1,generateAnnotation(machine.getProgSendDir(),machine.getMachineGroupCode(),annotationList)); |
| | | } |
| | | |
| | | /** |
| | | * 添加程序专改的注释 |
| | | * @param inputStream |
| | | * @param status 程序状态 |
| | | * @param machine |
| | | * @param annotationList 配置的注释字典列表 |
| | | * @return |
| | | * @throws IOException |
| | | */ |
| | | InputStream addProgramStatusAnnotation(InputStream inputStream,String status,Machine machine,List<Dict> annotationList) throws IOException { |
| | | return FileContentUtil.insertLine(inputStream,2,generateAnnotation(status,machine.getMachineGroupCode(),annotationList)); |
| | | } |
| | | |
| | | String generateAnnotation(String oriTest,String machineGroupCode,List<Dict> annotationList) { |
| | | R<List<Dict>> dictsResult = dictClient.getList(ANNOTATION_DICT); |
| | | String annotation = oriTest; |
| | | String begin = "("; |
| | | String end = ")"; |
| | | |
| | | Optional<Dict> dictOpt = dictsResult.getData().stream().filter(dict -> {return dict.getDictKey().equals(machineGroupCode);}).findFirst(); |
| | | String annotationSetting = "(,)"; |
| | | if(dictOpt.isPresent()) { |
| | | annotationSetting = dictOpt.get().getDictValue(); |
| | | } |
| | | String[] arr = annotationSetting.split(","); |
| | | if(arr.length == 2){ |
| | | begin = arr[0]; |
| | | end = arr[1]; |
| | | } |
| | | |
| | | annotation = begin + oriTest + end; |
| | | return annotation; |
| | | |
| | | } |
| | | /** |
| | | * 导入数据文件 |
| | | * @param zipOut |
| | | */ |
| | | void addDataJson(ZipOutputStream zipOut, List<Long> programPackageNodeIdList) throws IOException { |
| | | addNodeDataJson(zipOut, programPackageNodeIdList); |
| | | addApproveRecordDataJson(zipOut, programPackageNodeIdList); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * zip保重加入节点的数据 |
| | | * @param zipOut |
| | | * @param pkgNodeIdList |
| | | * @throws IOException |
| | | */ |
| | | void addNodeDataJson(ZipOutputStream zipOut,List<Long> pkgNodeIdList) throws IOException { |
| | | List<NcNode> pkgNodes = this.ncNodeService.lambdaQuery().in(NcNode::getId, pkgNodeIdList).list(); |
| | | |
| | | List<Long> allNodeIds = new ArrayList<>(); |
| | | for(NcNode node : pkgNodes){ |
| | | allNodeIds.addAll(Func.toLongList(node.getParentIds())); |
| | | allNodeIds.add(node.getId()); |
| | | } |
| | | //加入程序包下级的程序节点 |
| | | List<NcNode> programNodes = ncNodeService.lambdaQuery().in(NcNode::getParentId, pkgNodes.stream().map(NcNode::getId).toList()).list(); |
| | | |
| | | allNodeIds.addAll(programNodes.stream().map(NcNode::getId).toList()); |
| | | List<Long> distinctIds = allNodeIds.stream().distinct().toList(); |
| | | List<NcNode> allNodes = this.ncNodeService.lambdaQuery().in(NcNode::getId, distinctIds).list(); |
| | | JSONArray jsonArray = new JSONArray(); |
| | | |
| | | for(NcNode node : allNodes){ |
| | | JSONObject recObj = getNodeJsonObject(node); |
| | | addSuperProperties(recObj,node); |
| | | jsonArray.add(recObj); |
| | | } |
| | | addInputStreamToZip(zipOut,new ByteArrayInputStream(jsonArray.toJSONString().getBytes(StandardCharsets.UTF_8)),NODE_JSON_FILE); |
| | | |
| | | } |
| | | |
| | | @NotNull |
| | | private static JSONObject getNodeJsonObject(NcNode node) { |
| | | JSONObject recObj = new JSONObject(); |
| | | recObj.put("id", node.getId()); |
| | | recObj.put("name", node.getName()); |
| | | recObj.put("drawingNo", node.getDrawingNo()); |
| | | recObj.put("drawingNoEdition", node.getDrawingNoEdition()); |
| | | recObj.put("productModel", node.getProductModel()); |
| | | recObj.put("processName", node.getProcessName()); |
| | | recObj.put("processEdition", node.getProcessEdition()); |
| | | recObj.put("craftEdition", node.getCraftEdition()); |
| | | recObj.put("parentIds", node.getParentIds()); |
| | | recObj.put("processNo", node.getProcessNo()); |
| | | |
| | | recObj.put("isCured", node.getIsCured()); |
| | | recObj.put("isLocked", node.getIsLocked()); |
| | | recObj.put("nodeType", node.getNodeType()); |
| | | |
| | | recObj.put("machineCode", node.getMachineCode()); |
| | | recObj.put("flowProgramFileId", node.getFlowProgramFileId()); |
| | | recObj.put("processInstanceId", node.getProcessInstanceId()); |
| | | return recObj; |
| | | } |
| | | |
| | | /** |
| | | * 导入审批记录 |
| | | * @param zipOut |
| | | * @param programPackageNodeIdList 程序包名的id列表 |
| | | */ |
| | | void addApproveRecordDataJson(ZipOutputStream zipOut, List<Long> programPackageNodeIdList) throws IOException { |
| | | /* |
| | | List<String> instanceIds = this.ncNodeService.lambdaQuery().in(NcNode::getId, programPackageNodeIdList) |
| | | .list().stream().map(NcNode::getProcessInstanceId).toList(); |
| | | */ |
| | | //List<ApproveRecord> records = approveRecordService.lambdaQuery().in(ApproveRecord::getProcessInstanceId, instanceIds).list(); |
| | | List<ApproveRecord> records = approveRecordService.lambdaQuery().in(ApproveRecord::getNcNodeId, programPackageNodeIdList).list(); |
| | | |
| | | JSONArray jsonArray = new JSONArray(); |
| | | for(ApproveRecord record : records){ |
| | | JSONObject recObj = new JSONObject(); |
| | | recObj.put("id", record.getId()); |
| | | recObj.put("comment", record.getComment()); |
| | | recObj.put("userId",record.getUserId()); |
| | | recObj.put("userNickname",record.getUserNickname()); |
| | | recObj.put("operateTime",record.getOperateTime()); |
| | | recObj.put("operateResult",record.getOperateResult()); |
| | | recObj.put("taskName",record.getTaskName()); |
| | | recObj.put("processInstanceId",record.getProcessInstanceId()); |
| | | recObj.put("ncNodeId",record.getNcNodeId()); |
| | | addSuperProperties(recObj,record); |
| | | |
| | | jsonArray.add(recObj); |
| | | } |
| | | addInputStreamToZip(zipOut,new ByteArrayInputStream(jsonArray.toJSONString().getBytes(StandardCharsets.UTF_8)),"exp_mdm_approve_record.json"); |
| | | |
| | | } |
| | | |
| | | void addSuperProperties(JSONObject recObj, BizEntity entity){ |
| | | recObj.put("tenantId",entity.getTenantId()); |
| | | recObj.put("createTime",entity.getCreateTime()); |
| | | recObj.put("updateTime",entity.getUpdateTime()); |
| | | recObj.put("createUser",entity.getCreateUser()); |
| | | recObj.put("updateUser",entity.getUpdateUser()); |
| | | recObj.put("status",entity.getStatus()); |
| | | recObj.put("createDept",entity.getCreateDept()); |
| | | } |
| | | |
| | | /** |
| | | * 将 输入流 中的内容写入zip |
| | | * @param zipOut zip输出流 |