package com.vincent.rsf.server.ai.service.diagnosis;
|
|
import com.vincent.rsf.server.system.entity.AiDiagnosisRecord;
|
import org.springframework.stereotype.Service;
|
|
import java.util.ArrayList;
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
@Service
|
public class AiDiagnosisReportService {
|
|
/**
|
* 基于模型结论和工具摘要回填诊断报告结构化字段与 Markdown 内容。
|
*/
|
public void fillReport(AiDiagnosisRecord record, String conclusion, String toolSummary) {
|
if (record == null) {
|
return;
|
}
|
Map<String, String> sections = extractSections(conclusion);
|
String executiveSummary = firstNonBlank(
|
sections.get("问题概述"),
|
sections.get("执行摘要"),
|
safeText(conclusion)
|
);
|
String evidenceSummary = firstNonBlank(
|
sections.get("关键证据"),
|
sections.get("证据摘要"),
|
safeText(toolSummary)
|
);
|
String actionSummary = firstNonBlank(
|
sections.get("建议动作"),
|
sections.get("处置建议"),
|
"请结合现场流程继续确认。"
|
);
|
String riskSummary = firstNonBlank(
|
sections.get("风险评估"),
|
sections.get("潜在风险"),
|
"如未及时处理,可能继续影响当前业务运行。"
|
);
|
record.setReportTitle(buildTitle(record));
|
record.setExecutiveSummary(executiveSummary);
|
record.setEvidenceSummary(evidenceSummary);
|
record.setActionSummary(actionSummary);
|
record.setRiskSummary(riskSummary);
|
record.setReportMarkdown(buildMarkdown(record, executiveSummary, evidenceSummary, actionSummary, riskSummary, conclusion));
|
}
|
|
/**
|
* 尝试从原始结论文本中提取“问题概述/关键证据/建议动作/风险评估”等章节。
|
*/
|
private Map<String, String> extractSections(String conclusion) {
|
Map<String, String> sections = new LinkedHashMap<>();
|
if (conclusion == null || conclusion.trim().isEmpty()) {
|
return sections;
|
}
|
String[] lines = conclusion.replace("\r", "").split("\n");
|
String currentTitle = "问题概述";
|
StringBuilder currentBody = new StringBuilder();
|
for (String rawLine : lines) {
|
String line = rawLine == null ? "" : rawLine.trim();
|
String title = normalizeTitle(line);
|
if (title != null) {
|
saveSection(sections, currentTitle, currentBody);
|
currentTitle = title;
|
currentBody = new StringBuilder();
|
String remainder = line.substring(line.indexOf(title) + title.length()).trim();
|
if (remainder.startsWith(":") || remainder.startsWith(":")) {
|
remainder = remainder.substring(1).trim();
|
}
|
if (!remainder.isEmpty()) {
|
currentBody.append(remainder);
|
}
|
continue;
|
}
|
if (currentBody.length() > 0) {
|
currentBody.append("\n");
|
}
|
currentBody.append(rawLine == null ? "" : rawLine);
|
}
|
saveSection(sections, currentTitle, currentBody);
|
return sections;
|
}
|
|
/**
|
* 将当前章节内容写入 section map。
|
*/
|
private void saveSection(Map<String, String> sections, String title, StringBuilder body) {
|
String content = body == null ? "" : body.toString().trim();
|
if (content.isEmpty()) {
|
return;
|
}
|
sections.put(title, content);
|
}
|
|
/**
|
* 判断一行文本是否可视为报告章节标题。
|
*/
|
private String normalizeTitle(String line) {
|
if (line == null) {
|
return null;
|
}
|
String normalized = line.replace("#", "").replace(":", "").replace(":", "").trim();
|
List<String> titles = new ArrayList<>();
|
titles.add("问题概述");
|
titles.add("执行摘要");
|
titles.add("关键证据");
|
titles.add("证据摘要");
|
titles.add("可能原因");
|
titles.add("建议动作");
|
titles.add("处置建议");
|
titles.add("风险评估");
|
titles.add("潜在风险");
|
for (String title : titles) {
|
if (normalized.startsWith(title)) {
|
return title;
|
}
|
}
|
return null;
|
}
|
|
/**
|
* 构造诊断报告标题。
|
*/
|
private String buildTitle(AiDiagnosisRecord record) {
|
String diagnosisNo = record.getDiagnosisNo() == null ? "-" : record.getDiagnosisNo();
|
return "WMS诊断报告-" + diagnosisNo;
|
}
|
|
/**
|
* 生成最终报告 Markdown。
|
*/
|
private String buildMarkdown(AiDiagnosisRecord record, String executiveSummary, String evidenceSummary,
|
String actionSummary, String riskSummary, String conclusion) {
|
List<String> parts = new ArrayList<>();
|
parts.add("# " + buildTitle(record));
|
parts.add("");
|
parts.add("## 问题概述");
|
parts.add(safeText(executiveSummary));
|
parts.add("");
|
parts.add("## 关键证据");
|
parts.add(safeText(evidenceSummary));
|
parts.add("");
|
parts.add("## 建议动作");
|
parts.add(safeText(actionSummary));
|
parts.add("");
|
parts.add("## 风险评估");
|
parts.add(safeText(riskSummary));
|
if (conclusion != null && !conclusion.trim().isEmpty()) {
|
parts.add("");
|
parts.add("## 原始结论");
|
parts.add(conclusion.trim());
|
}
|
return String.join("\n", parts);
|
}
|
|
/**
|
* 返回第一个非空文本。
|
*/
|
private String firstNonBlank(String... values) {
|
if (values == null) {
|
return "";
|
}
|
for (String value : values) {
|
if (value != null && !value.trim().isEmpty()) {
|
return value.trim();
|
}
|
}
|
return "";
|
}
|
|
/**
|
* 对展示文本做空值兜底。
|
*/
|
private String safeText(String value) {
|
return value == null || value.trim().isEmpty() ? "暂无内容" : value.trim();
|
}
|
}
|