#AI
zhou zhou
8 小时以前 51877df13075ad10ef51107f15bcd21f1661febe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
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();
    }
}