package org.jeecg.modules.dnc.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import liquibase.pro.packaged.S;
|
import org.apache.commons.lang3.StringUtils;
|
import org.jeecg.modules.dnc.dto.ComponentHierarchy;
|
import org.jeecg.modules.dnc.dto.TransferPackage;
|
import org.jeecg.modules.dnc.entity.*;
|
import org.jeecg.modules.dnc.exception.ExceptionCast;
|
import org.jeecg.modules.dnc.mapper.DocRelativeMapper;
|
import org.jeecg.modules.dnc.response.ActivitiCode;
|
import org.jeecg.modules.dnc.response.DocumentCode;
|
import org.jeecg.modules.dnc.service.IDocClassificationService;
|
import org.jeecg.modules.dnc.service.IDocFileService;
|
import org.jeecg.modules.dnc.service.IDocInfoService;
|
import org.jeecg.modules.dnc.service.IDocRelativeService;
|
import org.jeecg.modules.dnc.utils.CompressionUtils;
|
import org.jeecg.modules.dnc.utils.JsonUtils;
|
import org.jeecg.modules.dnc.utils.file.FileUtilS;
|
import org.jeecg.modules.dncFlow.service.IAssignFileStreamService;
|
import org.jeecg.modules.mdc.entity.MdcEquipment;
|
import org.jeecg.modules.mdc.mapper.MdcEquipmentMapper;
|
import org.jeecg.modules.system.service.IMdcProductionService;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.stereotype.Service;
|
|
import java.io.File;
|
import java.io.IOException;
|
import java.nio.charset.StandardCharsets;
|
import java.nio.file.Files;
|
import java.nio.file.Path;
|
import java.nio.file.Paths;
|
import java.nio.file.StandardCopyOption;
|
import java.util.ArrayList;
|
import java.util.List;
|
|
@Service
|
public class FileFerryService {
|
|
private static final Logger logger = LoggerFactory.getLogger(FileFerryService.class);
|
|
@Value("${deploy.secretFolder}")
|
private String ferryPath;
|
|
@Value("${fileHomePath}")
|
private String fileHomePath;
|
|
@Autowired
|
private MdcEquipmentMapper mdcEquipmentMapper;
|
|
@Autowired
|
private IMdcProductionService mdcProductionService;
|
|
@Autowired
|
private IDocInfoService docInfoService;
|
|
@Autowired
|
private IDocClassificationService classificationService;
|
|
@Autowired
|
private IDocRelativeService docRelativeService;
|
|
|
public TransferPackage importData(String filePath) {
|
try {
|
// 1. 读取文件
|
Path path = Paths.get(filePath);
|
String fileName = path.getFileName().toString();
|
byte[] encrypted = Files.readAllBytes(path);
|
logger.debug("读取文件完成, 大小: {} 字节", encrypted.length);
|
|
// 2. 解密 (当前已注释)
|
// byte[] compressed = securityService.decrypt(encrypted);
|
|
// 3. 解压缩
|
// byte[] jsonBytes = CompressionUtils.gzipDecompress(encrypted);
|
String json = new String(encrypted, StandardCharsets.UTF_8);
|
logger.debug("解压缩完成, JSON长度: {} 字符", json.length());
|
|
// 记录JSON内容用于调试
|
logger.trace("原始JSON内容:\n{}", json);
|
|
// 4. JSON反序列化
|
logger.debug("开始反序列化...");
|
TransferPackage pkg = JsonUtils.fromJson(json, TransferPackage.class);
|
|
// 5. 处理文件名 - 示例: 10A20250614000026_3102038
|
String[] split = fileName.split("_");
|
if (split.length < 2) {
|
throw new IllegalArgumentException("无效的文件名格式: " + fileName);
|
}
|
|
String id = split[0];
|
String equipmentId = split[1].split("\\.")[0];
|
|
// 提取前缀和数字部分
|
int aIndex = id.indexOf("A");
|
if (aIndex == -1 || aIndex == id.length() - 1) {
|
throw new IllegalArgumentException("无效的ID格式: " + id);
|
}
|
|
String prefix = id.substring(0, aIndex + 1);
|
String numericPart = id.substring(aIndex + 1);
|
|
// 计算前一个文件名
|
long number = Long.parseLong(numericPart);
|
number--; // 获取前一个序列号
|
|
// 保持相同位数格式
|
String newNumeric = String.format("%0" + numericPart.length() + "d", number);
|
String ncFileName = prefix + newNumeric + "_" + equipmentId+".NC";
|
String ncFilePath = path.getParent().resolve(ncFileName).toString();
|
|
// 6. 获取文件复制目标路径
|
DocFile docFile = pkg.getTraceChain().getDocFile();
|
DocInfo docInfo = pkg.getTraceChain().getDocInfo();
|
if (docFile == null) {
|
throw new IllegalStateException("传输包中缺少文档文件信息");
|
}
|
|
// 构建目标路径
|
String targetDirectory = fileHomePath + docFile.getFilePath();
|
String targetPath = Paths.get(targetDirectory, docFile.getFileEncodeName()).toString();
|
|
// 确保目标目录存在
|
File targetDir = new File(targetDirectory);
|
if (!targetDir.exists() && !targetDir.mkdirs()) {
|
throw new IOException("无法创建目标目录: " + targetDirectory);
|
}
|
|
// 7. 复制文件并重命名
|
logger.info("复制文件: {} → {}", ncFilePath, targetPath);
|
Path source = Paths.get(ncFilePath);
|
Files.copy(source, Paths.get(targetPath), StandardCopyOption.REPLACE_EXISTING);
|
|
// 8. 查询设备id
|
MdcEquipment mdcEquipment=mdcEquipmentMapper.selectOne(new QueryWrapper<MdcEquipment>().eq("equipment_id",equipmentId));
|
if (mdcEquipment == null) {
|
throw new IllegalArgumentException("无效的设备ID: " + equipmentId);
|
}
|
|
// 9.传输文件到设备下
|
List<String> strings = mdcProductionService.findListParentTreeAll(mdcEquipment.getId());
|
if (strings != null && !strings.isEmpty()) {
|
DocInfo deviceDoc = docInfoService.getByDocAttrAndDocId(docInfo.getDocId(), 7, mdcEquipment.getId());
|
if (deviceDoc == null) {
|
DocClassification classification = classificationService.getByCode("send");
|
if(classification == null)
|
ExceptionCast.cast(DocumentCode.DOC_CLASS_ERROR);
|
DocRelative docRelative = new DocRelative();
|
docRelative.setDocId(docInfo.getDocId());
|
docRelative.setClassificationId(classification.getClassificationId());
|
docRelative.setAttributionType(7);
|
docRelative.setAttributionId(mdcEquipment.getId());
|
docRelativeService.save(docRelative);
|
}
|
String sendPath = StringUtils.join(strings.toArray(), "/");
|
boolean copyFileNc = FileUtilS.copyFileNc(docFile.getFilePath(), sendPath + "/" + mdcEquipment.getEquipmentId(),
|
docFile.getFileEncodeName(),
|
docFile.getFileName(), docFile.getFileSuffix());
|
if (!copyFileNc) {
|
ExceptionCast.cast(ActivitiCode.ACT_FILE_ERROR);
|
} else {
|
FileUtilS.deleteZipFromToSend(sendPath + "/" + mdcEquipment.getEquipmentId(),
|
docFile.getFileName(), docFile.getFileSuffix());
|
}
|
} else {
|
throw new RuntimeException("文件传输路径获取失败");
|
}
|
|
// 10.删除临时NC文件与json文件
|
logger.info("删除临时文件: {}", ncFilePath);
|
Files.delete(source);
|
Files.delete(path);
|
|
return JsonUtils.fromJson(json, TransferPackage.class);
|
|
} catch (NumberFormatException e) {
|
throw new RuntimeException("文件名中的数字格式无效: " + e.getMessage(), e);
|
} catch (IOException e) {
|
throw new RuntimeException("文件操作失败: " + e.getMessage(), e);
|
} catch (Exception e) {
|
logger.error("文件导入失败 [路径: {}]", filePath, e);
|
throw new RuntimeException("文件导入失败: " + e.getMessage(), e);
|
}
|
}
|
|
private void compressHierarchy(TransferPackage pkg) {
|
if (pkg.getTraceChain() == null ||
|
pkg.getTraceChain().getComponentHierarchy() == null ||
|
pkg.getTraceChain().getComponentHierarchy().getComponents().size() < 4) {
|
return;
|
}
|
|
ComponentHierarchy hierarchy = pkg.getTraceChain().getComponentHierarchy();
|
List<ComponentInfo> compressed = new ArrayList<>();
|
|
// 保留根部件
|
compressed.add(hierarchy.getComponents().get(0));
|
|
// 保留关键中间节点
|
int step = Math.max(1, hierarchy.getComponents().size() / 3);
|
for (int i = step; i < hierarchy.getComponents().size() - 1; i += step) {
|
compressed.add(hierarchy.getComponents().get(i));
|
}
|
|
// 保留叶子部件
|
compressed.add(hierarchy.getLeafComponent());
|
|
// 更新层级
|
hierarchy.getComponents().clear();
|
hierarchy.getComponents().addAll(compressed);
|
}
|
|
private String generateFilename(TransferPackage.DataType type, String id) {
|
return String.format("%s_%s_%d.ferry",
|
type.name().toLowerCase(),
|
id,
|
System.currentTimeMillis());
|
}
|
}
|