调整
This commit is contained in:
parent
99adfdca80
commit
80bd441ee6
@ -1,49 +1,49 @@
|
||||
package com.example.demo.common.config;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.jdbc.datasource.init.ScriptUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
|
||||
/**
|
||||
* 数据库初始化配置
|
||||
* 应用启动时自动执行数据库脚本,包括创建表结构、插入初始数据等
|
||||
*
|
||||
* @author 岳佳君 (2025年09月25日 15:00:27)
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DatabaseInitializer implements CommandLineRunner {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
/**
|
||||
* 应用启动时执行数据库初始化
|
||||
*
|
||||
* @param args 命令行参数
|
||||
* @throws Exception 初始化过程中可能抛出的异常
|
||||
*/
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
log.info("开始初始化数据库...");
|
||||
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
// 执行数据库初始化脚本
|
||||
ClassPathResource schemaResource = new ClassPathResource("schema.sql");
|
||||
ScriptUtils.executeSqlScript(connection, schemaResource);
|
||||
|
||||
log.info("数据库初始化完成");
|
||||
} catch (Exception e) {
|
||||
log.error("数据库初始化失败: {}", e.getMessage(), e);
|
||||
throw new RuntimeException("数据库初始化失败", e);
|
||||
}
|
||||
log.info("应用启动成功....");
|
||||
}
|
||||
}
|
||||
//package com.example.demo.common.config;
|
||||
//
|
||||
//import lombok.RequiredArgsConstructor;
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.springframework.boot.CommandLineRunner;
|
||||
//import org.springframework.core.io.ClassPathResource;
|
||||
//import org.springframework.jdbc.datasource.init.ScriptUtils;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//
|
||||
//import javax.sql.DataSource;
|
||||
//import java.sql.Connection;
|
||||
//
|
||||
///**
|
||||
// * 数据库初始化配置
|
||||
// * 应用启动时自动执行数据库脚本,包括创建表结构、插入初始数据等
|
||||
// *
|
||||
// * @author 岳佳君 (2025年09月25日 15:00:27)
|
||||
// * @version 1.0.0
|
||||
// */
|
||||
//@Slf4j
|
||||
//@Component
|
||||
//@RequiredArgsConstructor
|
||||
//public class DatabaseInitializer implements CommandLineRunner {
|
||||
//
|
||||
// private final DataSource dataSource;
|
||||
//
|
||||
// /**
|
||||
// * 应用启动时执行数据库初始化
|
||||
// *
|
||||
// * @param args 命令行参数
|
||||
// * @throws Exception 初始化过程中可能抛出的异常
|
||||
// */
|
||||
// @Override
|
||||
// public void run(String... args) throws Exception {
|
||||
// log.info("开始初始化数据库...");
|
||||
//
|
||||
// try (Connection connection = dataSource.getConnection()) {
|
||||
// // 执行数据库初始化脚本
|
||||
// ClassPathResource schemaResource = new ClassPathResource("schema.sql");
|
||||
// ScriptUtils.executeSqlScript(connection, schemaResource);
|
||||
//
|
||||
// log.info("数据库初始化完成");
|
||||
// } catch (Exception e) {
|
||||
// log.error("数据库初始化失败: {}", e.getMessage(), e);
|
||||
// throw new RuntimeException("数据库初始化失败", e);
|
||||
// }
|
||||
// log.info("应用启动成功....");
|
||||
// }
|
||||
//}
|
@ -1,315 +0,0 @@
|
||||
package com.example.demo.common.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 文件操作工具类
|
||||
* 提供文件读写、复制、删除等通用功能
|
||||
*
|
||||
* @author 岳佳君 (2025年09月26日 13:48:12)
|
||||
* @version 1.0.0
|
||||
*/
|
||||
public class FileUtil {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FileUtil.class);
|
||||
|
||||
/**
|
||||
* 读取文件内容
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @return 文件内容
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static String readFileContent(String filePath) throws IOException {
|
||||
return new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入内容到文件
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @param content 文件内容
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static void writeFileContent(String filePath, String content) throws IOException {
|
||||
// 确保父目录存在
|
||||
Path path = Paths.get(filePath);
|
||||
Path parentDir = path.getParent();
|
||||
if (parentDir != null) {
|
||||
Files.createDirectories(parentDir);
|
||||
}
|
||||
// 写入文件
|
||||
Files.write(path, content.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||
}
|
||||
|
||||
/**
|
||||
* 追加内容到文件
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @param content 文件内容
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static void appendFileContent(String filePath, String content) throws IOException {
|
||||
// 确保父目录存在
|
||||
Path path = Paths.get(filePath);
|
||||
Path parentDir = path.getParent();
|
||||
if (parentDir != null) {
|
||||
Files.createDirectories(parentDir);
|
||||
}
|
||||
// 追加文件
|
||||
Files.write(path, content.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制文件
|
||||
*
|
||||
* @param sourceFilePath 源文件路径
|
||||
* @param targetFilePath 目标文件路径
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static void copyFile(String sourceFilePath, String targetFilePath) throws IOException {
|
||||
Path sourcePath = Paths.get(sourceFilePath);
|
||||
Path targetPath = Paths.get(targetFilePath);
|
||||
|
||||
// 确保目标目录存在
|
||||
Path targetDir = targetPath.getParent();
|
||||
if (targetDir != null) {
|
||||
Files.createDirectories(targetDir);
|
||||
}
|
||||
|
||||
// 复制文件
|
||||
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动文件
|
||||
*
|
||||
* @param sourceFilePath 源文件路径
|
||||
* @param targetFilePath 目标文件路径
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static void moveFile(String sourceFilePath, String targetFilePath) throws IOException {
|
||||
Path sourcePath = Paths.get(sourceFilePath);
|
||||
Path targetPath = Paths.get(targetFilePath);
|
||||
|
||||
// 确保目标目录存在
|
||||
Path targetDir = targetPath.getParent();
|
||||
if (targetDir != null) {
|
||||
Files.createDirectories(targetDir);
|
||||
}
|
||||
|
||||
// 移动文件
|
||||
Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @return 是否删除成功
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static boolean deleteFile(String filePath) throws IOException {
|
||||
return Files.deleteIfExists(Paths.get(filePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建目录
|
||||
*
|
||||
* @param dirPath 目录路径
|
||||
* @return 是否创建成功
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static boolean createDirectory(String dirPath) throws IOException {
|
||||
Path path = Paths.get(dirPath);
|
||||
if (Files.exists(path)) {
|
||||
return Files.isDirectory(path);
|
||||
}
|
||||
Files.createDirectories(path);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除目录(包括目录下的所有文件)
|
||||
*
|
||||
* @param dirPath 目录路径
|
||||
* @return 是否删除成功
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static boolean deleteDirectory(String dirPath) throws IOException {
|
||||
Path path = Paths.get(dirPath);
|
||||
if (!Files.exists(path)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 递归删除目录内容
|
||||
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
Files.delete(file);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
||||
Files.delete(dir);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件大小
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @return 文件大小(字节)
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static long getFileSize(String filePath) throws IOException {
|
||||
return Files.size(Paths.get(filePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件扩展名
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @return 文件扩展名(小写)
|
||||
*/
|
||||
public static String getFileExtension(String fileName) {
|
||||
if (fileName == null || fileName.lastIndexOf('.') == -1) {
|
||||
return "";
|
||||
}
|
||||
return fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成唯一文件名
|
||||
*
|
||||
* @param originalFileName 原始文件名
|
||||
* @return 唯一文件名
|
||||
*/
|
||||
public static String generateUniqueFileName(String originalFileName) {
|
||||
String extension = getFileExtension(originalFileName);
|
||||
String timestamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
|
||||
String uuid = UUID.randomUUID().toString().replaceAll("-|", "");
|
||||
|
||||
if (extension.isEmpty()) {
|
||||
return timestamp + "_" + uuid;
|
||||
} else {
|
||||
return timestamp + "_" + uuid + "." + extension;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出目录下的所有文件
|
||||
*
|
||||
* @param dirPath 目录路径
|
||||
* @return 文件路径列表
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static List<String> listFiles(String dirPath) throws IOException {
|
||||
List<String> filePaths = new ArrayList<>();
|
||||
Path path = Paths.get(dirPath);
|
||||
|
||||
if (Files.exists(path) && Files.isDirectory(path)) {
|
||||
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
filePaths.add(file.toString());
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return filePaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件的MIME类型
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @return MIME类型
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static String getMimeType(String filePath) throws IOException {
|
||||
return Files.probeContentType(Paths.get(filePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查文件是否存在
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @return 是否存在
|
||||
*/
|
||||
public static boolean fileExists(String filePath) {
|
||||
return Files.exists(Paths.get(filePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理临时文件
|
||||
*
|
||||
* @param dirPath 临时目录路径
|
||||
* @param daysAgo 清理多少天前的文件
|
||||
* @return 清理的文件数量
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static int cleanTempFiles(String dirPath, int daysAgo) throws IOException {
|
||||
final int[] deletedCount = {0};
|
||||
Path path = Paths.get(dirPath);
|
||||
|
||||
if (!Files.exists(path) || !Files.isDirectory(path)) {
|
||||
return deletedCount[0];
|
||||
}
|
||||
|
||||
long cutoffTime = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(daysAgo);
|
||||
|
||||
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
try {
|
||||
// 检查文件的最后修改时间
|
||||
if (Files.getLastModifiedTime(file).toMillis() < cutoffTime) {
|
||||
Files.delete(file);
|
||||
deletedCount[0]++;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("删除临时文件失败: {}", file, e);
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
|
||||
return deletedCount[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建临时文件
|
||||
*
|
||||
* @param prefix 文件前缀
|
||||
* @param suffix 文件后缀
|
||||
* @param tempDir 临时目录
|
||||
* @return 临时文件路径
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static String createTempFile(String prefix, String suffix, String tempDir) throws IOException {
|
||||
// 确保临时目录存在
|
||||
createDirectory(tempDir);
|
||||
|
||||
// 创建临时文件
|
||||
File tempFile = File.createTempFile(prefix, suffix, new File(tempDir));
|
||||
return tempFile.getAbsolutePath();
|
||||
}
|
||||
}
|
@ -1,382 +0,0 @@
|
||||
package com.example.demo.common.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.w3c.dom.*;
|
||||
import org.xml.sax.InputSource;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* XML解析工具类
|
||||
* 提供XML文件解析和转换为TXT文件的核心功能
|
||||
*
|
||||
* @author 岳佳君 (2025年09月24日 23:09:02)
|
||||
* @version 1.0.0
|
||||
*/
|
||||
public class XmlParserUtil {
|
||||
|
||||
/**
|
||||
* 解析XML文件并转换为TXT文件
|
||||
*
|
||||
* @param xmlFilePath XML文件路径
|
||||
* @param txtFilePath TXT文件路径
|
||||
* @throws Exception 解析过程中的异常
|
||||
*/
|
||||
public static void parseXmlToTxt(String xmlFilePath, String txtFilePath) throws Exception {
|
||||
// 读取XML文件并解析
|
||||
Document document = parseXmlFile(xmlFilePath);
|
||||
|
||||
// 创建TXT文件
|
||||
createTxtFile(document, txtFilePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析XML文件为Document对象
|
||||
*
|
||||
* @param xmlFilePath XML文件路径
|
||||
* @return Document对象
|
||||
* @throws Exception 解析异常
|
||||
*/
|
||||
public static Document parseXmlFile(String xmlFilePath) throws Exception {
|
||||
// 确保文件存在
|
||||
File file = new File(xmlFilePath);
|
||||
if (!file.exists()) {
|
||||
throw new FileNotFoundException("XML文件不存在: " + xmlFilePath);
|
||||
}
|
||||
|
||||
// 创建DocumentBuilder并解析文件
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
factory.setIgnoringElementContentWhitespace(true);
|
||||
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
InputSource is = new InputSource(new InputStreamReader(fis, StandardCharsets.UTF_8));
|
||||
return factory.newDocumentBuilder().parse(is);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Document对象转换为TXT文件
|
||||
*
|
||||
* @param document XML文档对象
|
||||
* @param txtFilePath TXT文件路径
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static void createTxtFile(Document document, String txtFilePath) throws IOException {
|
||||
// 确保输出目录存在
|
||||
Path outputPath = Paths.get(txtFilePath).getParent();
|
||||
if (outputPath != null && !Files.exists(outputPath)) {
|
||||
Files.createDirectories(outputPath);
|
||||
}
|
||||
|
||||
// 写入TXT文件
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(txtFilePath), StandardCharsets.UTF_8)) {
|
||||
// 处理根元素
|
||||
Element rootElement = document.getDocumentElement();
|
||||
processElement(rootElement, writer, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归处理XML元素并写入TXT文件
|
||||
* 将中文XML标签转换为特定的TXT格式
|
||||
*
|
||||
* @param element 当前XML元素
|
||||
* @param writer 输出写入器
|
||||
* @param indentLevel 缩进级别
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
private static void processElement(Element element, BufferedWriter writer, int indentLevel) throws IOException {
|
||||
String tagName = element.getTagName();
|
||||
String indent = " ".repeat(Math.max(0, indentLevel));
|
||||
|
||||
// 根据中文标签名映射到对应的TXT格式
|
||||
switch (tagName) {
|
||||
case "任务":
|
||||
processTaskElement(element, writer, indentLevel);
|
||||
break;
|
||||
case "任务信息":
|
||||
processTaskInfoElement(element, writer, indentLevel);
|
||||
break;
|
||||
case "平台":
|
||||
processPlatformElement(element, writer, indentLevel);
|
||||
break;
|
||||
case "行动":
|
||||
processActionElement(element, writer, indentLevel);
|
||||
break;
|
||||
default:
|
||||
processGenericElement(element, writer, indentLevel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理任务元素
|
||||
*/
|
||||
private static void processTaskElement(Element element, BufferedWriter writer, int indentLevel) throws IOException {
|
||||
String indent = " ".repeat(Math.max(0, indentLevel));
|
||||
|
||||
// 获取任务行动信息
|
||||
String taskAction = getElementTextByTagName(element, "任务行动信息");
|
||||
if (StrUtil.isNotBlank(taskAction)) {
|
||||
writer.write(indent + "task " + taskAction + " # 任务信息");
|
||||
writer.newLine();
|
||||
}
|
||||
|
||||
// 处理子元素
|
||||
processChildElements(element, writer, indentLevel + 1);
|
||||
|
||||
writer.write(indent + "end_task");
|
||||
writer.newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理任务信息元素
|
||||
*/
|
||||
private static void processTaskInfoElement(Element element, BufferedWriter writer, int indentLevel) throws IOException {
|
||||
String indent = " ".repeat(Math.max(0, indentLevel));
|
||||
|
||||
// 处理指令有效期(拆分为开始和结束时间)
|
||||
String instructionPeriod = getElementTextByTagName(element, "指令有效期");
|
||||
if (StrUtil.isNotBlank(instructionPeriod)) {
|
||||
String[] timeRange = instructionPeriod.split("~");
|
||||
if (timeRange.length == 2) {
|
||||
writer.write(indent + "start_time " + timeRange[0].trim());
|
||||
writer.newLine();
|
||||
writer.write(indent + "end_time " + timeRange[1].trim());
|
||||
writer.newLine();
|
||||
}
|
||||
}
|
||||
|
||||
// 处理其他子元素
|
||||
processChildElements(element, writer, indentLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理平台元素
|
||||
*/
|
||||
private static void processPlatformElement(Element element, BufferedWriter writer, int indentLevel) throws IOException {
|
||||
String indent = " ".repeat(Math.max(0, indentLevel));
|
||||
|
||||
writer.write(indent + "platform # 平台信息");
|
||||
writer.newLine();
|
||||
|
||||
// 处理平台子元素
|
||||
String platformName = getElementTextByTagName(element, "平台名称");
|
||||
String machineType = getElementTextByTagName(element, "机型");
|
||||
String numOfCpus = getElementTextByTagName(element, "架数");
|
||||
String platformId = getElementTextByTagName(element, "平台识别码");
|
||||
String country = getElementTextByTagName(element, "国家");
|
||||
|
||||
if (StrUtil.isNotBlank(platformName)) {
|
||||
writer.write(indent + " platform_name " + platformName);
|
||||
writer.newLine();
|
||||
}
|
||||
if (StrUtil.isNotBlank(machineType)) {
|
||||
writer.write(indent + " machine_type " + machineType);
|
||||
writer.newLine();
|
||||
}
|
||||
if (StrUtil.isNotBlank(numOfCpus)) {
|
||||
writer.write(indent + " num_of_cpus " + numOfCpus);
|
||||
writer.newLine();
|
||||
}
|
||||
if (StrUtil.isNotBlank(platformId)) {
|
||||
writer.write(indent + " platform_id " + platformId);
|
||||
writer.newLine();
|
||||
}
|
||||
if (StrUtil.isNotBlank(country)) {
|
||||
writer.write(indent + " country " + country);
|
||||
writer.newLine();
|
||||
}
|
||||
|
||||
// 处理行动子元素
|
||||
processChildElements(element, writer, indentLevel + 1);
|
||||
|
||||
writer.write(indent + "end_platform");
|
||||
writer.newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理行动元素
|
||||
*/
|
||||
private static void processActionElement(Element element, BufferedWriter writer, int indentLevel) throws IOException {
|
||||
String indent = " ".repeat(Math.max(0, indentLevel));
|
||||
|
||||
writer.write(indent + "action");
|
||||
writer.newLine();
|
||||
|
||||
// 处理行动属性
|
||||
if (element.hasAttributes()) {
|
||||
NamedNodeMap attributes = element.getAttributes();
|
||||
for (int i = 0; i < attributes.getLength(); i++) {
|
||||
Attr attr = (Attr) attributes.item(i);
|
||||
if ("label".equals(attr.getName())) {
|
||||
writer.write(indent + " action_name " + attr.getValue());
|
||||
writer.newLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理航线名称
|
||||
String routeName = getElementTextByTagName(element, "航线名称");
|
||||
if (StrUtil.isNotBlank(routeName)) {
|
||||
writer.write(indent + " route_name " + routeName);
|
||||
writer.newLine();
|
||||
}
|
||||
|
||||
writer.write(indent + "end_action");
|
||||
writer.newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理通用元素
|
||||
*/
|
||||
private static void processGenericElement(Element element, BufferedWriter writer, int indentLevel) throws IOException {
|
||||
String tagName = element.getTagName();
|
||||
String indent = " ".repeat(Math.max(0, indentLevel));
|
||||
|
||||
// 将中文标签名转换为英文(简单映射)
|
||||
String englishTag = convertChineseTagToEnglish(tagName);
|
||||
|
||||
if (StrUtil.isNotBlank(englishTag)) {
|
||||
String textContent = getElementText(element);
|
||||
if (StrUtil.isNotBlank(textContent)) {
|
||||
writer.write(indent + englishTag + " " + textContent);
|
||||
writer.newLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理子元素
|
||||
*/
|
||||
private static void processChildElements(Element parent, BufferedWriter writer, int indentLevel) throws IOException {
|
||||
NodeList children = parent.getChildNodes();
|
||||
for (int i = 0; i < children.getLength(); i++) {
|
||||
if (children.item(i) instanceof Element) {
|
||||
processElement((Element) children.item(i), writer, indentLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据标签名获取元素文本内容
|
||||
*/
|
||||
private static String getElementTextByTagName(Element parent, String tagName) {
|
||||
NodeList elements = parent.getElementsByTagName(tagName);
|
||||
if (elements.getLength() > 0) {
|
||||
Element element = (Element) elements.item(0);
|
||||
return getElementText(element);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 将中文标签转换为英文标签
|
||||
*/
|
||||
private static String convertChineseTagToEnglish(String chineseTag) {
|
||||
// 简单的中文到英文映射
|
||||
switch (chineseTag) {
|
||||
case "指令确认信息": return "confirm_info";
|
||||
case "覆盖的指令文档": return "document_version";
|
||||
default: return chineseTag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从XML字符串解析为Document对象
|
||||
*
|
||||
* @param xmlContent XML字符串内容
|
||||
* @return Document对象
|
||||
* @throws Exception 解析异常
|
||||
*/
|
||||
public static Document parseXmlString(String xmlContent) throws Exception {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
|
||||
try (InputStream inputStream = new ByteArrayInputStream(xmlContent.getBytes(StandardCharsets.UTF_8))) {
|
||||
InputSource is = new InputSource(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
return factory.newDocumentBuilder().parse(is);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取XML元素的文本内容
|
||||
*
|
||||
* @param element XML元素
|
||||
* @return 文本内容
|
||||
*/
|
||||
public static String getElementText(Element element) {
|
||||
if (element == null) {
|
||||
return "";
|
||||
}
|
||||
NodeList childNodes = element.getChildNodes();
|
||||
StringBuilder textContent = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (node.getNodeType() == Node.TEXT_NODE) {
|
||||
textContent.append(node.getNodeValue());
|
||||
}
|
||||
}
|
||||
|
||||
return textContent.toString().trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定路径的XML元素
|
||||
*
|
||||
* @param document XML文档对象
|
||||
* @param xpath 元素路径
|
||||
* @return 元素列表
|
||||
*/
|
||||
public static List<Element> getElementsByPath(Document document, String xpath) {
|
||||
List<Element> elements = new ArrayList<>();
|
||||
|
||||
// 简单实现XPath功能,实际项目中可使用JAXB或XPath API
|
||||
String[] pathParts = xpath.split("/");
|
||||
if (pathParts.length == 0) {
|
||||
return elements;
|
||||
}
|
||||
|
||||
// 查找根元素
|
||||
Element currentElement = document.getDocumentElement();
|
||||
if (!currentElement.getTagName().equals(pathParts[0])) {
|
||||
return elements;
|
||||
}
|
||||
|
||||
// 递归查找子元素
|
||||
for (int i = 1; i < pathParts.length; i++) {
|
||||
currentElement = findChildElement(currentElement, pathParts[i]);
|
||||
if (currentElement == null) {
|
||||
return elements;
|
||||
}
|
||||
}
|
||||
|
||||
elements.add(currentElement);
|
||||
return elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在父元素中查找指定名称的子元素
|
||||
*
|
||||
* @param parent 父元素
|
||||
* @param tagName 子元素标签名
|
||||
* @return 子元素
|
||||
*/
|
||||
private static Element findChildElement(Element parent, String tagName) {
|
||||
NodeList childNodes = parent.getChildNodes();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals(tagName)) {
|
||||
return (Element) node;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -9,6 +9,26 @@ package com.example.demo.parser.process.constant;
|
||||
*/
|
||||
public final class ParserProcessConstant {
|
||||
|
||||
public static final String LOG_GROUP_LINE = String.format(" %s> %s <%s", "=".repeat(20), "%s","=".repeat(20));
|
||||
/** 字符串模板常量 */
|
||||
public static final class ST {
|
||||
|
||||
public static final String LOG_GROUP_LINE = String.format(" %s> %s <%s", "=".repeat(20), "%s","=".repeat(20));
|
||||
|
||||
public static final String NAME_WITH_INDEX = "%s_%0";
|
||||
|
||||
}
|
||||
|
||||
/** 单个字符 */
|
||||
public static final class CHAR {
|
||||
|
||||
public static final String CHAR_D = "d";
|
||||
|
||||
public static final String CHAR_S = "s";
|
||||
|
||||
}
|
||||
|
||||
/** 字段名称 */
|
||||
public static final class Field {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ public class EnhancedConfigProcessor {
|
||||
String newValue;
|
||||
if (loopCount >= 2) {
|
||||
// 当loopCount大于等于2时,添加带序号的后缀(根据最大位数自动补零)
|
||||
newValue = String.format("%s_%0" + maxDigits + "d", processedConfig.getValues().getFirst(), i);
|
||||
newValue = String.format(ParserProcessConstant.ST.NAME_WITH_INDEX + maxDigits + ParserProcessConstant.CHAR.CHAR_D, processedConfig.getValues().getFirst(), i);
|
||||
} else {
|
||||
// 当loopCount等于1时,不添加后缀编号,直接使用原始值
|
||||
newValue = processedConfig.getValues().getFirst();
|
||||
@ -227,7 +227,7 @@ public class EnhancedConfigProcessor {
|
||||
// 1. 应用正则表达式
|
||||
if (configValue.getRegexPattern() != null && configValue.getRegexReplacement() != null) {
|
||||
System.out.println();
|
||||
log.info("{}", String.format(ParserProcessConstant.LOG_GROUP_LINE, "应用正则表达式"));
|
||||
log.info("{}", String.format(ParserProcessConstant.ST.LOG_GROUP_LINE, "应用正则表达式"));
|
||||
log.info("RegexPattern = {}", configValue.getRegexPattern());
|
||||
log.info("RegexReplacement = {}", configValue.getRegexReplacement());
|
||||
try {
|
||||
@ -242,7 +242,7 @@ public class EnhancedConfigProcessor {
|
||||
// 2. 应用枚举映射
|
||||
if (configValue.getEnumMapping() != null) {
|
||||
System.out.println();
|
||||
log.info("{}", String.format(ParserProcessConstant.LOG_GROUP_LINE, "应用枚举映射"));
|
||||
log.info("{}", String.format(ParserProcessConstant.ST.LOG_GROUP_LINE, "应用枚举映射"));
|
||||
log.info("EnumMapping = {}", JSON.toJSONString(configValue.getEnumMapping()));
|
||||
for(String dict : configValue.getEnumMapping().keySet()) {
|
||||
if(configValue.getEnumMapping().containsKey(dict)) {
|
||||
@ -255,7 +255,7 @@ public class EnhancedConfigProcessor {
|
||||
// 3. 应用工具函数
|
||||
if (configValue.getUtilFunction() != null && !configValue.getUtilFunction().isEmpty()) {
|
||||
System.out.println();
|
||||
log.info("{}", String.format(ParserProcessConstant.LOG_GROUP_LINE, "应用工具函数"));
|
||||
log.info("{}", String.format(ParserProcessConstant.ST.LOG_GROUP_LINE, "应用工具函数"));
|
||||
log.info("Function = {}", JSON.toJSONString(configValue.getUtilFunction()));
|
||||
strValue = applyUtilFunction(strValue, configValue.getUtilFunction(), context, loopIndex);
|
||||
}
|
||||
@ -315,7 +315,7 @@ public class EnhancedConfigProcessor {
|
||||
Object result = method.invoke(null, value, params);
|
||||
return result != null ? result.toString() : value;
|
||||
} catch (Exception e) {
|
||||
// 方法调用失败,尝试其他方式
|
||||
// TODO 2025-9-29 15:30:19 方法调用失败,尝试其他方式
|
||||
return callCustomUtilFunction(functionName, value, params);
|
||||
}
|
||||
}
|
||||
|
@ -100,49 +100,4 @@ public class ConfigValue {
|
||||
*/
|
||||
private Map<String, Object> utilFunction;
|
||||
|
||||
public static void main(String[] args) {
|
||||
ConfigValue configValue = ConfigValue.builder().build();
|
||||
Map<String, Map<String, String>> enumMapping = new HashMap<>();
|
||||
enumMapping = JSON.parseObject(data2, Map.class);
|
||||
System.out.println(enumMapping);
|
||||
configValue.setEnumMapping(enumMapping);
|
||||
System.out.println(JSON.toJSONString(configValue));
|
||||
}
|
||||
|
||||
private static String data1 = """
|
||||
{
|
||||
"航线点类型": [
|
||||
{
|
||||
"起飞点": "N1"
|
||||
},
|
||||
{
|
||||
"航路点": "N2"
|
||||
},
|
||||
{
|
||||
"降落点": "N3"
|
||||
},
|
||||
{
|
||||
"拐弯点": "N4"
|
||||
},
|
||||
{
|
||||
"爬坡点": "N5"
|
||||
},
|
||||
{
|
||||
"返航点": "N6"
|
||||
}
|
||||
]
|
||||
}
|
||||
""";
|
||||
private static String data2 = """
|
||||
{
|
||||
"航线点类型": {
|
||||
"起飞点": "N1",
|
||||
"航路点": "N2",
|
||||
"降落点": "N3",
|
||||
"拐弯点": "N4",
|
||||
"爬坡点": "N5",
|
||||
"返航点": "N6"
|
||||
}
|
||||
}
|
||||
""";
|
||||
}
|
||||
|
@ -1,90 +0,0 @@
|
||||
//package com.example.demo.parser.service;
|
||||
//
|
||||
//import com.example.demo.parser.model.bo.TemplateData;
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.springframework.stereotype.Service;
|
||||
//
|
||||
//import java.io.StringWriter;
|
||||
//import java.util.HashMap;
|
||||
//import java.util.Map;
|
||||
//
|
||||
///**
|
||||
// * 动态模板生成服务
|
||||
// * 使用Jinja2模板引擎生成格式化的动态代码
|
||||
// */
|
||||
//@Slf4j
|
||||
//@Service
|
||||
//public class DynamicTemplateService {
|
||||
//
|
||||
// // 默认的缩进空格数
|
||||
// private static final int DEFAULT_INDENT_SPACES = 4;
|
||||
//
|
||||
// /**
|
||||
// * 生成动态代码
|
||||
// * @param templateData 模板数据
|
||||
// * @return 生成的格式化代码
|
||||
// */
|
||||
// public String generateDynamicCode(TemplateData templateData) {
|
||||
// return generateDynamicCode(templateData, DEFAULT_INDENT_SPACES);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 生成动态代码(可自定义缩进空格数)
|
||||
// * @param templateData 模板数据
|
||||
// * @param indentSpaces 缩进空格数
|
||||
// * @return 生成的格式化代码
|
||||
// */
|
||||
// public String generateDynamicCode(TemplateData templateData, int indentSpaces) {
|
||||
// try {
|
||||
// // 创建Jinja2环境
|
||||
// Jinja2Environment env = createJinja2Environment();
|
||||
//
|
||||
// // 准备模板上下文数据
|
||||
// Map<String, Object> context = prepareTemplateContext(templateData, indentSpaces);
|
||||
//
|
||||
// // 加载模板
|
||||
// Jinja2Template template = env.getTemplate("dynamic_template.j2");
|
||||
//
|
||||
// // 渲染模板
|
||||
// StringWriter writer = new StringWriter();
|
||||
// template.render(context, writer);
|
||||
//
|
||||
// return writer.toString();
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// log.error("生成动态代码时发生错误", e);
|
||||
// throw new RuntimeException("模板生成失败", e);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 创建Jinja2环境配置
|
||||
// */
|
||||
// private Jinja2Environment createJinja2Environment() {
|
||||
// // 这里使用伪代码,实际需要根据具体的Jinja2 Java实现来配置
|
||||
// // 例如使用 com.hubspot.jinjava.Jinjava
|
||||
// return new Jinja2Environment();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 准备模板上下文数据
|
||||
// */
|
||||
// private Map<String, Object> prepareTemplateContext(TemplateData templateData, int indentSpaces) {
|
||||
// Map<String, Object> context = new HashMap<>();
|
||||
//
|
||||
// context.put("globalComment", templateData.getGlobalComment());
|
||||
// context.put("levelConfigs", templateData.getLevelConfigs());
|
||||
// context.put("conditionMap", templateData.getConditionMap());
|
||||
// context.put("indentSpaces", indentSpaces);
|
||||
// context.put("indent", " ".repeat(indentSpaces));
|
||||
//
|
||||
// return context;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 工具方法:生成缩进字符串
|
||||
// */
|
||||
// public static String generateIndent(int level, int spaces) {
|
||||
// return " ".repeat(level * spaces);
|
||||
// }
|
||||
//}
|
@ -1,37 +1,36 @@
|
||||
//package com.example.demo.parser.service.impl;
|
||||
//
|
||||
//import cn.zhxu.bs.BeanSearcher;
|
||||
//import com.example.demo.common.typography.BaseServiceImpl;
|
||||
//import com.example.demo.parser.entity.FileRecordEntity;
|
||||
//import com.example.demo.parser.mapper.FileRecordMapper;
|
||||
//import com.example.demo.parser.model.dto.FileRecordDTO;
|
||||
//import com.example.demo.parser.model.dto.FileRecordQueryDTO;
|
||||
//import com.example.demo.parser.model.vo.FileRecordVO;
|
||||
//import com.example.demo.parser.service.FileRecordService;
|
||||
//// import com.fhs.core.trans.TransService;
|
||||
//import com.fhs.trans.service.impl.TransService;
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.springframework.stereotype.Service;
|
||||
//import org.springframework.transaction.annotation.Transactional;
|
||||
//
|
||||
///**
|
||||
// * 文件记录服务实现类
|
||||
// * 提供文件记录的CRUD和查询功能
|
||||
// *
|
||||
// * @author 岳佳君 (2025年09月25日 16:57:00)
|
||||
// * @version 1.0.0
|
||||
// */
|
||||
//@Slf4j
|
||||
//@Service
|
||||
//@Transactional(rollbackFor = Exception.class)
|
||||
//public class FileRecordServiceImpl
|
||||
// extends BaseServiceImpl<FileRecordEntity, FileRecordVO, FileRecordDTO, FileRecordQueryDTO, FileRecordMapper>
|
||||
// implements FileRecordService {
|
||||
//
|
||||
// public FileRecordServiceImpl(
|
||||
// BeanSearcher beanSearcher,
|
||||
// TransService transService
|
||||
// ) {
|
||||
// super(log, FileRecordServiceImpl.class.getSimpleName(), FileRecordVO.class, beanSearcher, transService);
|
||||
// }
|
||||
//}
|
||||
package com.example.demo.parser.service.impl;
|
||||
|
||||
import cn.zhxu.bs.BeanSearcher;
|
||||
import com.example.demo.common.typography.BaseServiceImpl;
|
||||
import com.example.demo.parser.entity.FileRecordEntity;
|
||||
import com.example.demo.parser.mapper.FileRecordMapper;
|
||||
import com.example.demo.parser.model.dto.FileRecordDTO;
|
||||
import com.example.demo.parser.model.dto.FileRecordQueryDTO;
|
||||
import com.example.demo.parser.model.vo.FileRecordVO;
|
||||
import com.example.demo.parser.service.FileRecordService;
|
||||
import com.fhs.trans.service.impl.TransService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 文件记录服务实现类
|
||||
* 提供文件记录的CRUD和查询功能
|
||||
*
|
||||
* @author 岳佳君 (2025年09月25日 16:57:00)
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class FileRecordServiceImpl
|
||||
extends BaseServiceImpl<FileRecordEntity, FileRecordVO, FileRecordDTO, FileRecordQueryDTO, FileRecordMapper>
|
||||
implements FileRecordService {
|
||||
|
||||
public FileRecordServiceImpl(
|
||||
BeanSearcher beanSearcher,
|
||||
TransService transService
|
||||
) {
|
||||
super(log, FileRecordServiceImpl.class.getSimpleName(), FileRecordVO.class, beanSearcher, transService);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user