diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 64e4ba8..48f3fea 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -19,12 +19,12 @@ \ No newline at end of file diff --git a/chat-server/src/main/java/com/bjtds/brichat/controller/MarkdownController.java b/chat-server/src/main/java/com/bjtds/brichat/controller/MarkdownController.java new file mode 100644 index 0000000..2c9aec6 --- /dev/null +++ b/chat-server/src/main/java/com/bjtds/brichat/controller/MarkdownController.java @@ -0,0 +1,34 @@ +package com.bjtds.brichat.controller; + +import com.bjtds.brichat.service.MarkdownService; +import com.bjtds.brichat.util.ResultUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; + +@Api(tags="Markdown标记") +@RestController +@Slf4j +@CrossOrigin(value ="*",maxAge = 3600) +@RequestMapping("/markdown") +public class MarkdownController { + @Autowired + private MarkdownService markdownService; + + @ApiOperation("Markdown标记") + @PostMapping("/render") + public ResultUtils replaceMarkdown(@RequestBody String content) throws IOException{ + markdownService.saveItem(content) ; + markdownService.processMarkdownFiles(content); + return ResultUtils.success("success"); + } + @ApiOperation("获取文件名") + @GetMapping("/getFileName") + public ResultUtils getFileName(@RequestParam String FilePath){ + return ResultUtils.success(markdownService.getFileName(FilePath)); + } +} diff --git a/chat-server/src/main/java/com/bjtds/brichat/service/MarkdownService.java b/chat-server/src/main/java/com/bjtds/brichat/service/MarkdownService.java new file mode 100644 index 0000000..fc0e5cb --- /dev/null +++ b/chat-server/src/main/java/com/bjtds/brichat/service/MarkdownService.java @@ -0,0 +1,10 @@ +package com.bjtds.brichat.service; + +import java.io.IOException; +import java.util.List; + +public interface MarkdownService { + void saveItem(String content) throws IOException; + void processMarkdownFiles(String content) throws IOException; + List getFileName(String filePath); +} diff --git a/chat-server/src/main/java/com/bjtds/brichat/service/impl/MarkdownServiceImpl.java b/chat-server/src/main/java/com/bjtds/brichat/service/impl/MarkdownServiceImpl.java new file mode 100644 index 0000000..9eedbf0 --- /dev/null +++ b/chat-server/src/main/java/com/bjtds/brichat/service/impl/MarkdownServiceImpl.java @@ -0,0 +1,65 @@ +package com.bjtds.brichat.service.impl; + +import com.bjtds.brichat.service.MarkdownService; +import com.bjtds.brichat.util.FuzzyMatcher; +import com.itextpdf.text.pdf.parser.clipper.Path; +import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils; +import java.io.File; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class MarkdownServiceImpl implements MarkdownService { + + private static final String ITEM_FILE="F:\\project\\bjtdsweb\\ai-manus\\chat-server\\file\\item\\item.md"; + private static final String INPUT_DIR="F:\\project\\bjtdsweb\\ai-manus\\chat-server\\file\\input" ; + private static final String OUTPUT_DIR="F:\\project\\bjtdsweb\\ai-manus\\chat-server\\file\\output" ; + + @Override + public void saveItem(String content) throws IOException { + Files.write(Paths.get(ITEM_FILE),(content+"\n").getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE,StandardOpenOption.APPEND); + } + @Override + public void processMarkdownFiles(String content) throws IOException { + List files = Files.list(Paths.get(INPUT_DIR)) + .filter(f->f.toString().endsWith(".md")) + .map(Path->Path.toString()) + .collect(Collectors.toList()); + int count = 0; + for (String file : files) { + String result = FuzzyMatcher.fuzzyMarkdownProcess(file, ITEM_FILE); + if (!"no".equals(result)) { + Files.write(Paths.get(OUTPUT_DIR + "\\" + "change" + (count++) + ".md"), result.getBytes(StandardCharsets.UTF_8)); + } + } + } + + @Override + public List getFileName(String filePath) { + List fileNames = new ArrayList<>(); + File folder = new File(filePath); + if (!folder.exists() || !folder.isDirectory()) { + return fileNames; + } + File[] files = folder.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isFile()) { + fileNames.add(file.getName()); + } + } + } + + return fileNames; + } + +} diff --git a/chat-server/src/main/java/com/bjtds/brichat/util/FuzzyMatcher.java b/chat-server/src/main/java/com/bjtds/brichat/util/FuzzyMatcher.java new file mode 100644 index 0000000..fcc6235 --- /dev/null +++ b/chat-server/src/main/java/com/bjtds/brichat/util/FuzzyMatcher.java @@ -0,0 +1,102 @@ +package com.bjtds.brichat.util; + +import org.simmetrics.StringMetric; +import org.simmetrics.metrics.StringMetrics; + +import java.nio.file.Files; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +public class FuzzyMatcher { + + private static final StringMetric fuzzyMetric = StringMetrics.jaroWinkler(); + private static final int DEFAULT_THRESHOLD = 84; + + public static String fuzzyMarkdownProcess(String sourcePath, String targetPath, int threshold) throws IOException { + String source = String.join("\n", Files.readAllLines(Paths.get(sourcePath))); + String target = String.join("\n", Files.readAllLines(Paths.get(targetPath))); + + List sourceBlocks = MarkdownUtils.splitMarkdownBlocks(source); + List targetBlocks = MarkdownUtils.splitMarkdownBlocks(target); + + boolean hasReplacement = false; // ✅ 标记是否发生替换 + + for (int i = 0; i < targetBlocks.size(); i++) { + ReplacementResult result = fuzzyReplaceWithProcessing(sourceBlocks, targetBlocks.get(i), threshold); + if (result.replaced) { + hasReplacement = true; + sourceBlocks = result.updatedBlocks; + } + } + + if (!hasReplacement) { + return "no"; // ✅ 没有替换返回 no + } + + return String.join("\n\n", sourceBlocks); + } + + public static String fuzzyMarkdownProcess(String sourcePath, String targetPath) throws IOException { + return fuzzyMarkdownProcess(sourcePath, targetPath, DEFAULT_THRESHOLD); + } + + // ✅ 用类封装返回值:包含更新后的块和是否替换的标记 + private static class ReplacementResult { + List updatedBlocks; + boolean replaced; + + ReplacementResult(List updatedBlocks, boolean replaced) { + this.updatedBlocks = updatedBlocks; + this.replaced = replaced; + } + } + + private static ReplacementResult fuzzyReplaceWithProcessing(List sourceBlocks, String targetBlock, int threshold) { + int bestIndex = -1; + int bestScore = -1; + + for (int i = 0; i < sourceBlocks.size(); i++) { + String source = normalize(sourceBlocks.get(i)); + String target = normalize(targetBlock); + + float score = fuzzyMetric.compare(source, target); + int percentScore = Math.round(score * 100); + + if (percentScore > bestScore) { + bestScore = percentScore; + bestIndex = i; + } + } + + if (bestScore < threshold || bestIndex == -1) { + return new ReplacementResult(sourceBlocks, false); + } + + String replacement; + if (MarkdownUtils.isMarkdownTable(targetBlock)) { + replacement = MarkdownUtils.markdownTableToHtml(targetBlock); + } else if (MarkdownUtils.isMarkdownHeading(targetBlock)) { + replacement = MarkdownUtils.addEqualsToHeading(targetBlock); + } else { + replacement = "==" + targetBlock.trim() + "=="; + } + + List updated = new ArrayList<>(sourceBlocks); + updated.set(bestIndex, replacement); + + return new ReplacementResult(updated, true); + } + + private static String normalize(String text) { + return text + .replaceAll("\\|\\s*-+\\s*\\|", "") + .replaceAll("[\\r\\n]+", " ") + .replaceAll("\\s+", " ") + .replaceAll("[`*_#>\\[\\]<>]", "") + .replaceAll("<[^>]+>", "") + .trim() + .toLowerCase(); + } +} diff --git a/chat-server/src/main/java/com/bjtds/brichat/util/MarkdownUtils.java b/chat-server/src/main/java/com/bjtds/brichat/util/MarkdownUtils.java new file mode 100644 index 0000000..a82c6cc --- /dev/null +++ b/chat-server/src/main/java/com/bjtds/brichat/util/MarkdownUtils.java @@ -0,0 +1,95 @@ +package com.bjtds.brichat.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class MarkdownUtils { + + /** + * 将 Markdown 文本按段落块分割(连续空行视为分隔) + */ + public static List splitMarkdownBlocks(String markdown) { + return Arrays.stream(markdown.split("\\n{2,}")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .collect(Collectors.toList()); + } + + /** + * 表格判断逻辑:只要一行中包含“|”,就视为表格块 + */ + public static boolean isMarkdownTable(String block) { + return Arrays.stream(block.split("\n")).anyMatch(line -> line.contains("|")); + } + + /** + * 判断是否为 Markdown 标题(以 '#' 开头) + */ + public static boolean isMarkdownHeading(String block) { + return block.trim().startsWith("#"); + } + + /** + * 把 Markdown 标题转换为等号形式 + * 示例: "# 标题" -> "标题\n=====" + */ + public static String addEqualsToHeading(String block) { + String line = block.trim().replaceAll("^#+", "").trim(); + return line + "\n" + new String(new char[line.length()]).replace('\0', '='); + } + + /** + * 将 Markdown 表格转换为 HTML 表格(简单处理) + */ + public static String markdownTableToHtml(String block) { + List lines = Arrays.stream(block.split("\n")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .collect(Collectors.toList()); + + List rows = new ArrayList<>(); + for (String line : lines) { + String[] cells = Arrays.stream(line.split("\\|")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .toArray(String[]::new); + if (cells.length > 0) { + rows.add(cells); + } + } + + if (rows.isEmpty()) return "
"; + + StringBuilder html = new StringBuilder(); + + // 加入前置分割线 + + // 设置表格背景色为淡黄色 + html.append("\n"); + + // 表头 + html.append(" "); + for (String header : rows.get(0)) { + html.append(""); + } + html.append("\n"); + + // 表体 + html.append(" \n"); + for (int i = 1; i < rows.size(); i++) { + html.append(" "); + for (String cell : rows.get(i)) { + html.append(""); + } + html.append("\n"); + } + html.append(" \n
") + .append(header).append("
") + .append(cell).append("
"); + + return html.toString(); + } + +}