package com.lxzn.activiti.service.impl; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fasterxml.jackson.annotation.JsonFormat; import com.lxzn.activiti.dao.AssignFileStreamMapper; import com.lxzn.activiti.service.IActivitiDefinitionService; import com.lxzn.activiti.service.IAssignFileStreamService; import com.lxzn.activiti.service.IToEquipmentTaskService; import com.lxzn.auth.JwtUtil; import com.lxzn.base.service.IDncPassLogService; import com.lxzn.framework.domain.activiti.AssignFileStream; import com.lxzn.framework.domain.activiti.ToEquipmentTask; import com.lxzn.framework.domain.activiti.ext.ActTaskExt; import com.lxzn.framework.domain.activiti.ext.AssignFileStreamExt; import com.lxzn.framework.domain.activiti.request.ApproveBatchRequest; import com.lxzn.framework.domain.activiti.request.AssignFileRequest; import com.lxzn.framework.domain.activiti.request.AssignFileStreamQueryRequest; import com.lxzn.framework.domain.activiti.request.TaskRequest; import com.lxzn.framework.domain.activiti.response.ActivitiCode; import com.lxzn.framework.domain.base.DncPassLog; import com.lxzn.framework.domain.base.ext.NcTxtFilePathInfo; import com.lxzn.framework.domain.nc.*; import com.lxzn.framework.domain.nc.response.DeviceCode; import com.lxzn.framework.domain.nc.response.DocumentCode; import com.lxzn.framework.domain.ucenter.Department; import com.lxzn.framework.domain.ucenter.response.UcenterCode; import com.lxzn.framework.exception.ExceptionCast; import com.lxzn.framework.model.response.CommonCode; import com.lxzn.framework.model.response.QueryPageResponseResult; import com.lxzn.framework.model.response.ResponseResult; import com.lxzn.framework.model.response.ResultCode; import com.lxzn.framework.utils.TelnetUtil; import com.lxzn.framework.utils.ValidateUtil; import com.lxzn.framework.utils.date.DateUtil; import com.lxzn.framework.utils.file.FileUtil; import com.lxzn.nc.service.*; import com.lxzn.ucenter.service.IDepartmentService; import lombok.extern.slf4j.Slf4j; import org.activiti.engine.HistoryService; import org.activiti.engine.RuntimeService; import org.activiti.engine.TaskService; import org.activiti.engine.history.HistoricProcessInstance; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.*; import java.util.stream.Collectors; @Service @Slf4j public class AssignFileStreamServiceImpl extends ServiceImpl implements IAssignFileStreamService { private static final String PROCESS_KEY = "assign_nc_to_device"; private static final String APPLY_VARIABLE = "apply_user"; private static final String APPROVE_VARIABLE = "approve_users"; private static final String SEND_CODE = "SEND"; @Value("${activiti.enable}") private Boolean activeEnable; @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; @Autowired private IDocInfoService docInfoService; @Autowired private IProductInfoService productInfoService; @Autowired private IComponentInfoService componentInfoService; @Autowired private IPartsInfoService partsInfoService; @Autowired private IProcessStreamService processStreamService; @Autowired private IPermissionStreamService permissionStreamService; @Autowired private IDepartmentService departmentService; @Autowired private HistoryService historyService; @Autowired private IDocClassificationService classificationService; @Autowired private IToEquipmentTaskService equipmentTaskService; @Autowired private IDeviceInfoService deviceInfoService; @Autowired private IDocFileService docFileService; @Autowired private IActivitiDefinitionService definitionService; @Autowired private IDocRelativeService docRelativeService; @Autowired private ISynchronizedFlagService synchronizedFlagService; @Autowired private IDeviceGroupService deviceGroupService; @Autowired private IDncPassLogService dncPassLogService; @Autowired private IDeviceCharactersService iDeviceCharactersService; @Autowired private INcLogInfoService ncLogInfoService; @Autowired private StringRedisTemplate redisTemplate; @Value("${securedoc.serverIp}") private String serverIp; @Value("${securedoc.serverPort}") private int serverPort; @Value("${securedoc.whether}") private String whether; @Value("${securedoc.localFilePath}") private String localFilePath; @Value("${fileNCPath}") private String fileNCPath; @Override @Transactional(rollbackFor = {Exception.class}) public ResponseResult applyAssignFile(AssignFileStream stream) { synchronized (this){ //判断设备特殊字符 String specialChar = getDeviceSpecialChar(stream.getDeviceId(),stream.getFileId()); if (StrUtil.isNotEmpty(specialChar)){ //抛出特殊字符异常 return createSpecialCharErrorResponse(specialChar); } if(activeEnable) { boolean b = applyAssignFileActive(stream); if (b) { return ResponseResult.SUCCESS(); } else { return ResponseResult.SUCCESS(); } }else { return applyAssignFileNonActive(stream); } } } /** * 判断设备特殊字符 * @param deviceId,fileId * 设备ID,文件ID */ public String getDeviceSpecialChar(String deviceId, String fileId){ DeviceInfo deviceInfo = deviceInfoService.getById(deviceId); if(deviceInfo == null) ExceptionCast.cast(ActivitiCode.ACT_ASSIGN_DEVICE_NONE); // DocFile docFile = docFileService.getById(fileId); DocInfo docInfo = docInfoService.getOne(new QueryWrapper().eq("publish_file_id",fileId)); if(docInfo == null) ExceptionCast.cast(ActivitiCode.ACT_FILE_ERROR); List deviceCharactersList=iDeviceCharactersService.list( new LambdaQueryWrapper().eq(DeviceCharacters::getDeviceNo,deviceInfo.getDeviceNo())); if (deviceCharactersList.isEmpty()){ return ""; }else { List specialCharList=deviceCharactersList.stream().map(DeviceCharacters::getCharacters).collect(Collectors.toList()); if(!specialCharList.isEmpty()){ //对比文件名是否包含特殊字符 String fileName=docInfo.getDocName(); for(String specialChar:specialCharList){ if (fileName.contains(specialChar)){ return specialChar; } } }else { return ""; } } return ""; } private ResponseResult createSpecialCharErrorResponse(String specialChar) { return new ResponseResult(new ResultCode() { @Override public boolean success() { return false; } @Override public int code() { return 88881; } @Override public String message() { return "文件名称存在设备特殊字符" + specialChar; } }); } @Override @Transactional(rollbackFor = {Exception.class}) public boolean applyAssignFileActive(AssignFileStream stream) { //校验开始 if(stream == null) ExceptionCast.cast(CommonCode.INVALID_PARAM); if(!ValidateUtil.validateString(stream.getProcessId()) || !ValidateUtil.validateString(stream.getDocId()) || !ValidateUtil.validateString(stream.getFileId())) ExceptionCast.cast(ActivitiCode.ACT_BUSINESS_SAVE_ERROR); if(!ValidateUtil.validateString(stream.getDeviceId())) ExceptionCast.cast(ActivitiCode.ACT_ASSIGN_DEVICE_NONE); String userId = JwtUtil.getUserId(); if(!ValidateUtil.validateString(userId)) ExceptionCast.cast(UcenterCode.UCENTER_ACCOUNT_NOT_EXIST); DocInfo docInfo = docInfoService.getByDocAttrAndDocId(stream.getDocId(), 5, stream.getProcessId()); if(docInfo == null || docInfo.getDocStatus() == 3) ExceptionCast.cast(ActivitiCode.ACT_DOC_ERROR); DeviceInfo deviceInfo = deviceInfoService.getById(stream.getDeviceId()); if(deviceInfo == null) ExceptionCast.cast(ActivitiCode.ACT_ASSIGN_DEVICE_NONE); if(deviceInfo == null) ExceptionCast.cast(ActivitiCode.ACT_ASSIGN_DEVICE_NONE); DocFile docFile = docFileService.getById(stream.getFileId()); DocInfo deviceDoc = docInfoService.getByDocAttrAndDocId(stream.getDocId(), 4, stream.getDeviceId()); if(deviceDoc != null) { /*// 删除 备份 覆盖 原有的 List strings = deviceGroupService.findListParentTreeAll(deviceInfo.getGroupId()); if (strings != null && !strings.isEmpty()) { String path = StringUtils.join(strings.toArray(), "/"); boolean copyFileNc = FileUtil.copyFileNcToBak(path + "/"+ deviceInfo.getDeviceNo(), docFile.getFileName(), docFile.getFileSuffix()); if (!copyFileNc) { ExceptionCast.cast(ActivitiCode.ACT_FILE_ERROR); } else { //docInfoService.getBaseMapper().deleteById(deviceDoc.getDocId()); boolean doc = docRelativeService.deleteDocByAttr(deviceDoc.getDocId(),4,stream.getDeviceId()); if (!doc) { ExceptionCast.cast(ActivitiCode.ACT_DOC_ERROR_DELEVE); } } }*/ } deviceDoc = docInfoService.findByAttrAndDocName(docInfo.getDocName(), 4, stream.getDeviceId(),docInfo.getDocSuffix()); if(deviceDoc != null) { // 删除 备份 覆盖 原有的 /* List strings = deviceGroupService.findListParentTreeAll(deviceInfo.getGroupId()); if (strings != null && !strings.isEmpty()) { String path = StringUtils.join(strings.toArray(), "/"); boolean copyFileNc = FileUtil.copyFileNcToBak(path + "/"+ deviceInfo.getDeviceNo(), docFile.getFileName(), docFile.getFileSuffix()); if (!copyFileNc) { ExceptionCast.cast(ActivitiCode.ACT_FILE_ERROR); } else { //docInfoService.getBaseMapper().deleteById(deviceDoc.getDocId()); boolean doc = docRelativeService.deleteDocByAttr(deviceDoc.getDocId(),4,stream.getDeviceId()); if (!doc) { ExceptionCast.cast(ActivitiCode.ACT_DOC_ERROR_DELEVE); } } }*/ } ProcessStream processStream = processStreamService.getById(stream.getProcessId()); if(processStream == null) ExceptionCast.cast(ActivitiCode.ACT_BUSINESS_SAVE_ERROR); stream.setProductId(processStream.getProductId()); stream.setComponentId(processStream.getComponentId()); stream.setPartsId(processStream.getPartsId()); List permissionStreams = null; if(ValidateUtil.validateString(processStream.getPartsId())) { //进入零件 permissionStreams = permissionStreamService.getByPartsId(stream.getProductId(), stream.getComponentId(), stream.getPartsId()); }else if(ValidateUtil.validateString(processStream.getComponentId())) { //进入部件的处理 permissionStreams = permissionStreamService.getByComponentId(stream.getProductId(), stream.getComponentId()); } if(permissionStreams == null || permissionStreams.isEmpty()) ExceptionCast.cast(ActivitiCode.ACT_NODE_DEPART_NONE); List departIds = new ArrayList<>(); Map map = departmentService.getMapByUserId(userId); permissionStreams.forEach(item -> { if(map.containsKey(item.getDepartId())) { departIds.add(item.getDepartId()); } }); if(departIds.isEmpty()) ExceptionCast.cast(ActivitiCode.ACT_USER_NOT_PERM); //获取部门审批人 List userIdList = definitionService.getByDepartIds(departIds); if(userIdList == null || userIdList.isEmpty()) ExceptionCast.cast(ActivitiCode.ACT_APPROVE_USERS_NONE); //校验结束 String streamId = IdWorker.getIdStr(); stream.setStreamId(streamId); stream.setApplyUserId(userId); stream.setApplyTime(DateUtil.getNow()); stream.setStatus(1); //保存流程业务对象 boolean b = super.save(stream); if(!b) ExceptionCast.cast(ActivitiCode.ACT_BUSINESS_SAVE_ERROR); //保存流程任务 String approveUsers = String.join(",", userIdList); Map avariableMap = new HashMap<>(); avariableMap.put(APPLY_VARIABLE, userId); avariableMap.put(APPROVE_VARIABLE, approveUsers); //启动流程 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(PROCESS_KEY, streamId, avariableMap); if(processInstance == null) ExceptionCast.cast(ActivitiCode.ACT_APPROVE_USERS_NONE); //查询当前流程用户流程任务 Task task = taskService.createTaskQuery().processDefinitionKey(PROCESS_KEY).taskAssignee(userId) .processInstanceId(processInstance.getId()).singleResult(); if(task == null) ExceptionCast.cast(ActivitiCode.ACT_APPROVE_USERS_NONE); //完成流程任务 taskService.complete(task.getId()); return true; } @Override @Transactional(rollbackFor = {Exception.class}) public ResponseResult applyAssignFileNonActive(AssignFileStream stream) { if(stream == null) ExceptionCast.cast(CommonCode.INVALID_PARAM); if(!ValidateUtil.validateString(stream.getProcessId()) || !ValidateUtil.validateString(stream.getDocId()) || !ValidateUtil.validateString(stream.getFileId())) ExceptionCast.cast(CommonCode.INVALID_PARAM); if(!ValidateUtil.validateString(stream.getDeviceId())) ExceptionCast.cast(ActivitiCode.ACT_ASSIGN_DEVICE_NONE); String userId = JwtUtil.getUserId(); if(!ValidateUtil.validateString(userId)) ExceptionCast.cast(UcenterCode.UCENTER_ACCOUNT_NOT_EXIST); DocInfo docInfo = docInfoService.getByDocAttrAndDocId(stream.getDocId(), 5, stream.getProcessId()); if(docInfo == null || docInfo.getDocStatus() == 3) ExceptionCast.cast(ActivitiCode.ACT_DOC_ERROR); DeviceInfo deviceInfo = deviceInfoService.getById(stream.getDeviceId()); if(deviceInfo == null) ExceptionCast.cast(ActivitiCode.ACT_ASSIGN_DEVICE_NONE); DocFile docFile = docFileService.getById(stream.getFileId()); if(docFile == null) ExceptionCast.cast(ActivitiCode.ACT_FILE_ERROR); DocInfo deviceDoc = docInfoService.getByDocAttrAndDocId(stream.getDocId(), 4, stream.getDeviceId()); if(deviceDoc != null) { // 删除 备份 覆盖 原有的 List strings = deviceGroupService.findListParentTreeAll(deviceInfo.getGroupId()); if (strings != null && !strings.isEmpty()) { String path = StringUtils.join(strings.toArray(), "/"); boolean copyFileNc = FileUtil.copyFileNcToBak(path + "/"+ deviceInfo.getDeviceNo(), docFile.getFileName(), docFile.getFileSuffix()); } } /*deviceDoc = docInfoService.findByAttrAndDocName(docInfo.getDocName(), 4, stream.getDeviceId()); if(deviceDoc != null) { // 删除 备份 覆盖 原有的 List strings = deviceGroupService.findListParentTreeAll(deviceInfo.getGroupId()); if (strings != null && !strings.isEmpty()) { String path = StringUtils.join(strings.toArray(), "/"); boolean copyFileNc = FileUtil.copyFileNcToBak(path + "/"+ deviceInfo.getDeviceNo(), docFile.getFileName(), docFile.getFileSuffix()); } }*/ ProcessStream processStream = processStreamService.getById(stream.getProcessId()); if(processStream == null) ExceptionCast.cast(CommonCode.INVALID_PARAM); stream.setProductId(processStream.getProductId()); stream.setComponentId(processStream.getComponentId()); stream.setPartsId(processStream.getPartsId()); List permissionStreams = null; if(ValidateUtil.validateString(processStream.getPartsId())) { //进入零件 permissionStreams = permissionStreamService.getByPartsId(stream.getProductId(), stream.getComponentId(), stream.getPartsId()); }else if(ValidateUtil.validateString(processStream.getComponentId())) { //进入部件的处理 permissionStreams = permissionStreamService.getByComponentId(stream.getProductId(), stream.getComponentId()); } if(permissionStreams == null || permissionStreams.isEmpty()) ExceptionCast.cast(ActivitiCode.ACT_NODE_DEPART_NONE); List departIds = new ArrayList<>(); Map map = departmentService.getMapByUserId(userId); permissionStreams.forEach(item -> { if(map.containsKey(item.getDepartId())) { departIds.add(item.getDepartId()); } }); if(departIds.isEmpty()) ExceptionCast.cast(ActivitiCode.ACT_USER_NOT_PERM); //deviceDoc = docInfoService.findByAttrAndDocName(docInfo.getDocName(), 4, stream.getDeviceId()); /*if(deviceDoc != null) ExceptionCast.cast(ActivitiCode.ACT_DEVICE_DOC_ERROR);*/ //插入文档到设备发送文档 if(deviceDoc == null) { DocClassification classification = classificationService.getByCode(SEND_CODE); if(classification == null) ExceptionCast.cast(DocumentCode.DOC_CLASS_ERROR); DocRelative docRelative = new DocRelative(); docRelative.setDocId(docInfo.getDocId()); docRelative.setClassificationId(classification.getClassificationId()); docRelative.setAttributionType(4); docRelative.setAttributionId(stream.getDeviceId()); boolean b = docRelativeService.save(docRelative); if(!b) { ExceptionCast.cast(ActivitiCode.ACT_APPROVE_ERROR); } } //TODO //插入文件传输任务表 List strings = deviceGroupService.findListParentTreeAll(deviceInfo.getGroupId()); if (strings != null && !strings.isEmpty()) { String path = StringUtils.join(strings.toArray(), "/"); boolean copyFileNc = FileUtil.copyFileNc(docFile.getFilePath(),path + "/"+ deviceInfo.getDeviceNo(), docFile.getFileEncodeName(), docFile.getFileName(),docFile.getFileSuffix()); if (!copyFileNc) { ExceptionCast.cast(ActivitiCode.ACT_FILE_ERROR); } else { FileUtil.deleteZipFromToSend(path + "/"+ deviceInfo.getDeviceNo(), docFile.getFileName(),docFile.getFileSuffix()); } } else { return new ResponseResult(CommonCode.FAIL); } String size = FileUtil.fileSizeNC(docFile.getFilePath(),docFile.getFileEncodeName()); if (whether.equals("true") && !docFile.getFileSuffix().equals("zip") && !docFile.getFileSuffix().equals("rar") ) { //处理文件 记录并上报 //1、 判断端口是否能够访问 文件路径加 /*boolean btelnetPort = TelnetUtil.telnetPort(serverIp,serverPort,10); if (!btelnetPort) { ExceptionCast.cast(ActivitiCode.ACT_DEVICE_DOC_FILELABLE); }*/ DncPassLog passInfoTxt = new DncPassLog(); String path = StringUtils.join(strings.toArray(), "/"); Date dateFirst = DateUtil.getNow(); passInfoTxt.setDayTime(DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY)); /*查询最后一条记录*/ //休眠 500毫秒 DncPassLog dncPassLog = dncPassLogService.findDayTime(DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY)); Integer fileTxt = 0, fileNc =0; if (dncPassLog !=null) { fileTxt = dncPassLog.getSequenceNumber() + 1; fileNc = fileTxt + 1; } else { fileTxt = 1; fileNc = fileTxt + 1; } //处理文件名称 文件路径 String sequence = String.format("%06d",fileTxt); String sequenceNc = String.format("%06d",fileNc); passInfoTxt.setSequenceNumber(fileTxt); passInfoTxt.setSequenceOrder(sequence); passInfoTxt.setCreateTime(dateFirst); System.out.println(DateUtil.format(dateFirst,DateUtil.STR_DATE_TIME)); passInfoTxt.setPassType("02"); dncPassLogService.save(passInfoTxt); DncPassLog passInfoNc = new DncPassLog(); passInfoNc.setSequenceNumber(fileNc); passInfoNc.setSequenceOrder(sequenceNc); passInfoNc.setDayTime(DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY)); passInfoNc.setPassType("02"); passInfoNc.setPassName(docFile.getFileName()); try { Thread.sleep(1000); Date date = new Date(); passInfoNc.setCreateTime(date); System.out.println(DateUtil.format(date,DateUtil.STR_DATE_TIME)); } catch (InterruptedException e) { e.printStackTrace(); } dncPassLogService.save(passInfoNc); NcTxtFilePathInfo ncTxt = new NcTxtFilePathInfo(); ncTxt.setEquipmentId(deviceInfo.getDeviceNo()); ncTxt.setFileNcName("10A"+DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY)+sequenceNc); ncTxt.setFileTxtName("10A"+DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY)+sequence); ncTxt.setFilePath(path + "/"+ deviceInfo.getDeviceNo() + "/" ); ncTxt.setOrigFileName(docFile.getFileName()); ncTxt.setOrigFileSuffix(docFile.getFileSuffix()); ncTxt.setFileAddOrDelete(1); String loFilePath = localFilePath +"//"+ ncTxt.getFileTxtName() + ".nc"; try { String allList = new String(); allList=(ncTxt.getFileTxtName()+"\n"); allList+=(ncTxt.getFileNcName()+"\n"); allList+=(ncTxt.getOrigFileName()+"\n"); allList+=(ncTxt.getOrigFileSuffix()+"\n"); allList+=(ncTxt.getFilePath()+"\n"); allList+=(ncTxt.getEquipmentId()+"\n"); allList+=(ncTxt.getFileAddOrDelete().toString()+"\n"); // 文件大小字节 第二行 工控网进行文件分析 allList+= (size+"\n"); FileUtil.fileWriterSql(loFilePath,allList); // 源文件和目标文件路径 String sourcePath = path + "/"+ deviceInfo.getDeviceNo() +"/send/" + docFile.getFileName(); String targetPath = localFilePath + "//" + ncTxt.getFileNcName(); boolean copySuccess = false; int maxRetries = 3; int attempt = 0; // 如果源文件不存在,直接报错并跳过 if (!Files.exists(Paths.get(fileNCPath+"/"+sourcePath+"."+docFile.getFileSuffix()))) { log.error("源文件不存在: {}", sourcePath); throw new IOException("源文件不存在"); } while (attempt < maxRetries && !copySuccess) { attempt++; try { // 复制文件(同名覆盖) boolean copyResult = FileUtil.copyFileUpName( sourcePath, targetPath, docFile.getFileSuffix(), "NC" ); if (!copyResult) { log.warn("文件复制失败(第{}次尝试)", attempt); continue; } // 计算源文件和目标文件的MD5 String sourceMd5 = FileUtil.calculateMD5(fileNCPath+"/"+sourcePath+"."+docFile.getFileSuffix()); String targetMd5 = FileUtil.calculateMD5(targetPath+".NC"); if (sourceMd5.equals(targetMd5)) { copySuccess = true; log.info("文件复制成功且MD5一致(第{}次尝试)", attempt); } else { log.warn("MD5不一致,源文件MD5: {},目标文件MD5: {}(第{}次尝试)", sourceMd5, targetMd5, attempt); // 立即进行同名覆盖重试 if (attempt < maxRetries) { log.info("执行MD5校验失败后的同名覆盖重试..."); } else { log.error("MD5校验失败,已达最大重试次数"); } } } catch (Exception e) { log.error("文件复制或校验时出错(第{}次尝试)", attempt, e); // 重试前等待 if (attempt < maxRetries) { try { Thread.sleep(300); // 300ms后重试 } catch (InterruptedException ie) { Thread.currentThread().interrupt(); } } } } if (!copySuccess) { log.error("文件复制最终失败: 源={} 目标={}", sourcePath, targetPath); // 处理复制失败的情况(根据业务需求决定后续操作) ExceptionCast.cast(ActivitiCode.ACT_FILE_ERROR); } } catch (IOException e) { e.printStackTrace(); } } synchronizedFlagService.updateFlag(2); return new ResponseResult(CommonCode.SUCCESS); } @Override public List getUndoTaskList() { String userId = JwtUtil.getUserId(); if(!ValidateUtil.validateString(userId)) return null; List list = taskService.createTaskQuery().taskCandidateOrAssigned(userId).list(); if(list == null || list.isEmpty()) return null; List extList = new ArrayList<>(); list.forEach(item -> { ActTaskExt ext = new ActTaskExt(); ext.instanceOfTask(item); HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId( item.getProcessInstanceId()).singleResult(); if(historicProcessInstance == null || !ValidateUtil.validateString(historicProcessInstance.getBusinessKey())) { ExceptionCast.cast(ActivitiCode.ACT_PROC_INST_ERROR); } ext.setBusinessKey(historicProcessInstance.getBusinessKey()); AssignFileStreamExt streamDetail = getAssignFileStreamDetail(historicProcessInstance.getBusinessKey()); if(streamDetail == null) ExceptionCast.cast(ActivitiCode.ACT_BUSINESS_DETAIL_ERROR); ext.setAssignFileStream(streamDetail); extList.add(ext); }); return extList; } @Override public AssignFileStreamExt getAssignFileStreamDetail(String streamId) { if(!ValidateUtil.validateString(streamId)) return null; return super.getBaseMapper().getAssignFileStreamDetail(streamId); } @Override @Transactional(rollbackFor = {Exception.class}) public boolean approveAssignFile(String taskId, String streamId, AssignFileStream stream) { if(!ValidateUtil.validateString(taskId) || !ValidateUtil.validateString(streamId) || stream == null) ExceptionCast.cast(CommonCode.INVALID_PARAM); String userId = JwtUtil.getUserId(); if(!ValidateUtil.validateString(userId)) ExceptionCast.cast(UcenterCode.UCENTER_ACCOUNT_NOT_EXIST); if(!ValidateUtil.validateInteger(stream.getStatus())) ExceptionCast.cast(ActivitiCode.ACT_STATUS_ERROR); AssignFileStream en = super.getById(streamId); if(en == null) ExceptionCast.cast(ActivitiCode.ACT_BUSINESS_DETAIL_ERROR); Task task = taskService.createTaskQuery().taskId(taskId).taskCandidateOrAssigned(userId).singleResult(); if(task == null) ExceptionCast.cast(ActivitiCode.ACT_TASK_ERROR); if(!ValidateUtil.validateString(task.getAssignee())) { //拾取任务 taskService.claim(task.getId(), userId); //完成任务 taskService.complete(task.getId()); }else { //完成任务 taskService.complete(task.getId()); } //更新对象封装 AssignFileStream up = new AssignFileStream(); up.setApproveContent(stream.getApproveContent()); up.setStatus(stream.getStatus()); up.setApproveUserId(userId); up.setApproveTime(DateUtil.getNow()); up.setStreamId(streamId); boolean b = super.updateById(up); if(!b) ExceptionCast.cast(ActivitiCode.ACT_APPROVE_ERROR); if(up.getStatus() == 2) { //同意操作 DocInfo docInfo = docInfoService.getByDocAttrAndDocId(en.getDocId(), 5, en.getProcessId()); if(docInfo == null || docInfo.getDocStatus() == 3) ExceptionCast.cast(ActivitiCode.ACT_DOC_ERROR); DeviceInfo deviceInfo = deviceInfoService.getById(en.getDeviceId()); if(deviceInfo == null) ExceptionCast.cast(ActivitiCode.ACT_ASSIGN_DEVICE_NONE); DocFile docFile = docFileService.getById(en.getFileId()); if(docFile == null) ExceptionCast.cast(ActivitiCode.ACT_FILE_ERROR); DocInfo deviceDoc = docInfoService.getByDocAttrAndDocId(en.getDocId(),4, en.getDeviceId()); if(deviceDoc != null) { // 删除 备份 覆盖 原有的 List strings = deviceGroupService.findListParentTreeAll(deviceInfo.getGroupId()); if (strings != null && !strings.isEmpty()) { String path = StringUtils.join(strings.toArray(), "/"); boolean copyFileNc = FileUtil.copyFileNcToBak(path + "/"+ deviceInfo.getDeviceNo(), docFile.getFileName(), docFile.getFileSuffix()); /* //docInfoService.getBaseMapper().deleteById(deviceDoc.getDocId()); boolean doc = docRelativeService.deleteCopyDocByAttrNext(deviceDoc.getDocId(),4,stream.getDeviceId()); if (!doc) { ExceptionCast.cast(ActivitiCode.ACT_DOC_ERROR_DELEVE); }*/ } } else { //插入文档到设备发送文档 DocClassification classification = classificationService.getByCode(SEND_CODE); if(classification == null) ExceptionCast.cast(DocumentCode.DOC_CLASS_ERROR); DocRelative docRelative = new DocRelative(); docRelative.setDocId(docInfo.getDocId()); docRelative.setClassificationId(classification.getClassificationId()); docRelative.setAttributionType(4); docRelative.setAttributionId(en.getDeviceId()); b = docRelativeService.save(docRelative); } if(!b) ExceptionCast.cast(ActivitiCode.ACT_APPROVE_ERROR); if (deviceInfo != null) { List strings = deviceGroupService.findListParentTreeAll(deviceInfo.getGroupId()); if (strings != null && !strings.isEmpty()) { String path = StringUtils.join(strings.toArray(), "/"); boolean copyFileNc = FileUtil.copyFileNc(docFile.getFilePath(),path + "/"+ deviceInfo.getDeviceNo(), docFile.getFileEncodeName(), docFile.getFileName(),docFile.getFileSuffix()); if (!copyFileNc) { ExceptionCast.cast(ActivitiCode.ACT_FILE_ERROR); } else { FileUtil.deleteZipFromToSend(path + "/"+ deviceInfo.getDeviceNo(), docFile.getFileName(),docFile.getFileSuffix()); } } } return synchronizedFlagService.updateFlag(1); }else if(up.getStatus() == 3) { //拒绝操作 什么也不做 return true; }else { ExceptionCast.cast(ActivitiCode.ACT_APPROVE_ERROR); } return false; } @Override @Transactional(rollbackFor = {Exception.class}) public boolean applyBatchAssignFile(AssignFileRequest assignFileRequest) { if(assignFileRequest == null) ExceptionCast.cast(CommonCode.INVALID_PARAM); String[] deviceIds = assignFileRequest.getDeviceIds(); if(deviceIds == null || deviceIds.length < 1) ExceptionCast.cast(ActivitiCode.ACT_ASSIGN_DEVICE_NONE); AssignFileStream stream; for(String id : deviceIds) { stream = new AssignFileStream(); stream.setProcessId(assignFileRequest.getProcessId()); stream.setDocId(assignFileRequest.getDocId()); stream.setFileId(assignFileRequest.getFileId()); stream.setApplyReason(assignFileRequest.getApplyReason()); stream.setDeviceId(id); ResponseResult b = applyAssignFile(stream); if(!b.isSuccess()) ExceptionCast.cast(ActivitiCode.ACT_APPLY_ERROR); } return true; } @Override @Transactional(rollbackFor = {Exception.class}) public boolean approveBatchAssignFile(ApproveBatchRequest approveBatchRequest) { if(approveBatchRequest == null) ExceptionCast.cast(CommonCode.INVALID_PARAM); List list = approveBatchRequest.getTaskArr(); if(list == null || list.isEmpty()) ExceptionCast.cast(CommonCode.INVALID_PARAM); list.forEach(item -> { AssignFileStream stream = new AssignFileStream(); stream.setApproveContent(approveBatchRequest.getApproveContent()); stream.setStatus(approveBatchRequest.getStatus()); boolean b = approveAssignFile(item.getId(), item.getBusinessKey(), stream); if(!b) ExceptionCast.cast(ActivitiCode.ACT_APPROVE_ERROR); }); return synchronizedFlagService.updateFlag(1); } @Override public QueryPageResponseResult findPageList(int page, int size, AssignFileStreamQueryRequest request) { if(page < 1 || size < 1) { ExceptionCast.cast(CommonCode.INVALID_PAGE); } String userId = JwtUtil.getUserId(); if(!ValidateUtil.validateString(userId)) ExceptionCast.cast(UcenterCode.UCENTER_ACCOUNT_NOT_EXIST); LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); lambdaQueryWrapper.eq(AssignFileStreamExt::getApproveUserId, userId); lambdaQueryWrapper.orderByDesc(AssignFileStreamExt::getApproveTime); IPage pageData = new Page<>(page, size); if(request != null) { if(ValidateUtil.validateString(request.getAscStr())) { String[] ascArr = request.getAscStr().split(","); ((Page) pageData).setAsc(ascArr); } if(ValidateUtil.validateString(request.getDescStr())) { String[] descStr = request.getDescStr().split(","); ((Page) pageData).setDesc(descStr); } } IPage streamExtIPage = super.getBaseMapper().findByPage(pageData, lambdaQueryWrapper); return new QueryPageResponseResult<>(CommonCode.SUCCESS, streamExtIPage); } @Override public QueryPageResponseResult findPageListByDocId(int page, int size, String docId) { if(page < 1 || size < 1) { ExceptionCast.cast(CommonCode.INVALID_PAGE); } if(!ValidateUtil.validateString(docId)) ExceptionCast.cast(ActivitiCode.ACT_DOC_ID_NONE); QueryWrapper queryWrapper = Wrappers.query(); queryWrapper.eq("a.doc_id", docId); queryWrapper.orderByDesc("approve_time"); IPage pageData = new Page<>(page, size); IPage streamExtIPage = super.getBaseMapper().findByPage(pageData, queryWrapper); return new QueryPageResponseResult<>(CommonCode.SUCCESS, streamExtIPage); } @Override public Boolean getActiveEnable() { if(activeEnable != null) { return activeEnable; } return false; } @Override @Transactional(rollbackFor = {Exception.class}) public boolean transferDocFile(String pnCode, String deviceNo) { List streams = processStreamService.validateDeviceProcessInfo(pnCode, deviceNo); DeviceInfo deviceInfo = deviceInfoService.getByDeviceNo(deviceNo); if(deviceInfo == null) ExceptionCast.cast(DeviceCode.DEVICE_NOT_EXIST); //删除原来设备下的所有文档 docRelativeService.deleteByDocAttr(4, deviceInfo.getDeviceId()); List docInfoList = docInfoService.getByProcessIds(streams); if(docInfoList == null || docInfoList.isEmpty()) ExceptionCast.cast(DocumentCode.DOC_NOT_EXIST); String userId = JwtUtil.getUserId(); if(!ValidateUtil.validateString(userId)) ExceptionCast.cast(UcenterCode.UCENTER_ACCOUNT_NOT_EXIST); for(DocInfo docInfo : docInfoList) { DocFile docFile = docFileService.getById(docInfo.getPublishFileId()); if(docFile == null) ExceptionCast.cast(ActivitiCode.ACT_FILE_ERROR); //插入文档到设备发送文档 DocClassification classification = classificationService.getByCode(SEND_CODE); if(classification == null) ExceptionCast.cast(DocumentCode.DOC_CLASS_ERROR); DocRelative docRelative = new DocRelative(); docRelative.setDocId(docInfo.getDocId()); docRelative.setClassificationId(classification.getClassificationId()); docRelative.setAttributionType(4); docRelative.setAttributionId(deviceInfo.getDeviceId()); boolean b = docRelativeService.save(docRelative); if(!b) ExceptionCast.cast(ActivitiCode.ACT_APPROVE_ERROR); //插入文件传输任务表 ToEquipmentTask equipmentTask = new ToEquipmentTask(); //不能直接从doc中拿fileId 和version 可能会存在斌更 //equipmentTask.setFileId(docInfo.getPublishFileId()); //equipmentTask.setDocVersion(docInfo.getPublishVersion()); equipmentTask.setDocId(docInfo.getDocId()); equipmentTask.setSyncFlag(1); equipmentTask.setDeviceNo(deviceInfo.getDeviceNo()); equipmentTask.setDeviceId(deviceInfo.getDeviceId()); equipmentTask.setDepartId(deviceInfo.getDepartId()); //文件相关信息 equipmentTask.setFileId(docFile.getFileId()); equipmentTask.setDocVersion(docFile.getDocVersion()); equipmentTask.setFileName(docInfo.getDocName()); equipmentTask.setFileEncodeName(docFile.getFileEncodeName()); equipmentTask.setFilePath(docFile.getFilePath()); equipmentTask.setFileSuffix(docFile.getFileSuffix()); equipmentTask.setFileSize(docFile.getFileSize()); b = equipmentTaskService.save(equipmentTask); if(!b) { ExceptionCast.cast(ActivitiCode.ACT_APPROVE_ERROR); } } return synchronizedFlagService.updateFlag(1); } @Override @Transactional(rollbackFor = {Exception.class}) public Map disPatchTaskNc(String equipmentId, String workshop, String partsCode, String processCode, String description,String id) { NcLogInfo dncLog = new NcLogInfo(); dncLog.setModuleInfo(equipmentId + "设备程序下发"); dncLog.setLogContent("DNC程序下发,工厂编号:"+workshop+"设备编号"+equipmentId); boolean btelnetPort = TelnetUtil.telnetPort(serverIp,serverPort,10); Map map = new HashMap<>(); //统一错误处理 - 条件检测 if (!btelnetPort) { return handleError(dncLog, map, "网闸异常"); } ProductInfo productInfo=productInfoService.getByProductNo("PLM"); if (productInfo == null) { return handleError(dncLog, map, "无此车间信息"); } List componentInfoList = componentInfoService.getByProductId(productInfo.getProductId()); List comlist = new ArrayList<>(); if (componentInfoList != null && !componentInfoList.isEmpty()) { for (ComponentInfo cc : componentInfoList) { comlist.add(cc.getComponentId()); } } else { return handleError(dncLog, map, "无部件信息"); } PartsInfo part = partsInfoService.getByCodeAndComIdList(partsCode,comlist); if (part == null) { return handleError(dncLog, map, "无此零件信息"+"__" + partsCode); } processCode = processCode.split("_")[0]; ProcessStream stream = processStreamService.findByProcessEquipment(equipmentId, processCode,description,productInfo.getProductId(),part.getPartsId()); if (stream == null) { return handleError(dncLog, map, "无此工序信息"+"__" + processCode); } DeviceInfo deviceInfo = deviceInfoService.getByDeviceNo(equipmentId); if(deviceInfo == null) { return handleError(dncLog, map, "DNC中设备不存在,无此设备的程序下发_" + equipmentId); } //删除原来设备下的所有文档 docRelativeService.deleteByDocAttr(4, deviceInfo.getDeviceId()); List streams = new ArrayList<>(); streams.add(stream); List docInfoList = docInfoService.getByProcessIds(streams); if(docInfoList == null || docInfoList.isEmpty()) { return handleError(dncLog, map, "无此文档信息"); } // 文件处理部分保持不变 for(DocInfo docInfo : docInfoList) { DocFile docFile = docFileService.getById(docInfo.getPublishFileId()); if(docFile == null) { return handleError(dncLog, map, "未找到在对应文件信息"); } //插入文档到设备发送文档 DocClassification classification = classificationService.getByCode(SEND_CODE); if(classification == null) { return handleError(dncLog, map, "未找到根据文档分类编码获取文档"); } DocRelative docRelative = new DocRelative(); docRelative.setDocId(docInfo.getDocId()); docRelative.setClassificationId(classification.getClassificationId()); docRelative.setAttributionType(4); docRelative.setAttributionId(deviceInfo.getDeviceId()); boolean b = docRelativeService.save(docRelative); if(!b) { return handleError(dncLog, map, "添加文档失败"); } //插入文件传输任务表 ToEquipmentTask equipmentTask = new ToEquipmentTask(); String path=""; //不能直接从doc中拿fileId 和version 可能会存在变更 List strings = deviceGroupService.findListParentTreeAll(deviceInfo.getGroupId()); if (strings != null && !strings.isEmpty()) { path = StringUtils.join(strings.toArray(), "/"); } String newPath = "/"+path + "/"+ deviceInfo.getDeviceNo(); equipmentTask.setDocId(docInfo.getDocId()); equipmentTask.setSyncFlag(1); equipmentTask.setDeviceNo(deviceInfo.getDeviceNo()); equipmentTask.setDeviceId(deviceInfo.getDeviceId()); equipmentTask.setDepartId(deviceInfo.getDepartId()); //文件相关信息 equipmentTask.setFileId(docFile.getFileId()); equipmentTask.setDocVersion(docFile.getDocVersion()); equipmentTask.setFileName(docInfo.getDocName()); equipmentTask.setFileEncodeName(docFile.getFileEncodeName()); equipmentTask.setFilePath(docFile.getFilePath()); equipmentTask.setFileSuffix(docFile.getFileSuffix()); equipmentTask.setFileSize(docFile.getFileSize()); b = equipmentTaskService.save(equipmentTask); if(!b) { return handleError(dncLog, map, "文件任务传输失败"); } //复制文件,进行预定密 b = FileUtil.copyFile(docFile.getFilePath(), newPath, docFile.getFileEncodeName()); if(!b){ return handleError(dncLog, map, "文件复制失败"); } String absPath = FileUtil.getFileAbsPath(newPath, docFile.getFileEncodeName()); if(absPath == null){ return handleError(dncLog, map, "获取文件绝对路径失败"); } //文件名改为docInfo.getDocName() // 获取原始文件和新文件名 File originalFile = new File(absPath); String newFileName = docInfo.getDocName(); // 确保新文件名有效 if (newFileName == null || newFileName.trim().isEmpty()) { return handleError(dncLog, map, "新文件名无效"); } // 构建目标文件路径 File destFile = new File(originalFile.getParent(), newFileName); try { // 使用Files.move提供更好的错误处理和跨文件系统支持 Files.move( originalFile.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING ); } catch (IOException e) { return handleError(dncLog, map, "文件重命名失败: " + e.getMessage()); } String size = FileUtil.fileSizeNC(docFile.getFilePath(),docFile.getFileEncodeName()); if (whether.equals("true") && !docFile.getFileSuffix().equals("zip") && !docFile.getFileSuffix().equals("rar") ) { //处理文件 记录并上报 //1、 判断端口是否能够访问 文件路径加 DncPassLog passInfoTxt = new DncPassLog(); Date dateFirst = DateUtil.getNow(); passInfoTxt.setDayTime(DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY)); /*查询最后一条记录*/ //休眠 500毫秒 DncPassLog dncPassLog = dncPassLogService.findDayTime(DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY)); Integer fileTxt = 0, fileNc =0; if (dncPassLog !=null) { fileTxt = dncPassLog.getSequenceNumber() + 1; fileNc = fileTxt + 1; } else { fileTxt = 1; fileNc = fileTxt + 1; } //处理文件名称 文件路径 String sequence = String.format("%06d",fileTxt); String sequenceNc = String.format("%06d",fileNc); passInfoTxt.setSequenceNumber(fileTxt); passInfoTxt.setSequenceOrder(sequence); passInfoTxt.setCreateTime(dateFirst); System.out.println(DateUtil.format(dateFirst,DateUtil.STR_DATE_TIME)); passInfoTxt.setPassType("02"); dncPassLogService.save(passInfoTxt); DncPassLog passInfoNc = new DncPassLog(); passInfoNc.setSequenceNumber(fileNc); passInfoNc.setSequenceOrder(sequenceNc); passInfoNc.setDayTime(DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY)); passInfoNc.setPassType("02"); passInfoNc.setPassName(docFile.getFileName()); try { Thread.sleep(1000); Date date = new Date(); passInfoNc.setCreateTime(date); System.out.println(DateUtil.format(date,DateUtil.STR_DATE_TIME)); } catch (InterruptedException e) { e.printStackTrace(); } dncPassLogService.save(passInfoNc); NcTxtFilePathInfo ncTxt = new NcTxtFilePathInfo(); ncTxt.setEquipmentId(deviceInfo.getDeviceNo()); ncTxt.setFileNcName("10A"+DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY)+sequenceNc); ncTxt.setFileTxtName("10A"+DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY)+sequence); ncTxt.setFilePath(path + "/"+ deviceInfo.getDeviceNo() + "/" ); ncTxt.setOrigFileName(docFile.getFileName()); ncTxt.setOrigFileSuffix(docFile.getFileSuffix()); ncTxt.setFileAddOrDelete(1); String loFilePath = localFilePath + ncTxt.getFileTxtName() + ".nc"; try { String allList = new String(); allList=(ncTxt.getFileTxtName()+"\n"); allList+=(ncTxt.getFileNcName()+"\n"); allList+=(ncTxt.getOrigFileName()+"\n"); allList+=(ncTxt.getOrigFileSuffix()+"\n"); allList+=(ncTxt.getFilePath()+"\n"); allList+=(ncTxt.getEquipmentId()+"\n"); allList+=(ncTxt.getFileAddOrDelete().toString()+"\n"); // 文件大小字节 第二行 工控网进行文件分析 allList+= (size+"\n"); FileUtil.fileWriterSql(loFilePath,allList); //文件解析重新规划 //添加文件名字,第一行, boolean copyFileNc = FileUtil.copyFileUpName(path + "/"+ deviceInfo.getDeviceNo() +"/send/" + docFile.getFileName(), localFilePath + ncTxt.getFileNcName(), docFile.getFileSuffix(),"NC"); if (!copyFileNc) { FileUtil.deleteNcFile(loFilePath); } } catch (IOException e) { e.printStackTrace(); } } } if (synchronizedFlagService.updateFlag(0)){ dncLog.setLogContent("下发成功"); ncLogInfoService.save(dncLog); map.put(true,"下发成功"); return map; } // 统一错误处理 - 最后的下发失败情况 return handleError(dncLog, map, "下发失败"); } // 统一错误处理方法 private Map handleError(NcLogInfo log, Map map, String errorMessage) { log.setLogContent(errorMessage); ncLogInfoService.save(log); map.put(false, errorMessage); return map; } }