Procházet zdrojové kódy

fix(report): 修复B4报告解析——自我概念按「维度 分数」提取6维、自驱力按维度顺序映射我的得分,去除错误兜底

Xiaogang Liao před 4 dny
rodič
revize
29b8218af3

+ 43 - 55
cfc-backend/src/main/java/com/etotem/cfc/service/DanReportParseService.java

@@ -218,9 +218,12 @@ public class DanReportParseService {
         extra.put("reportDate", reportDate);
 
         // 2. 自我概念 (Self-Concept)
-        int selfConceptStart = findSectionStart(lines, "自我概念", "自我认知", "自我意识");
+        int selfConceptStart = findLineIndex(lines, "自我概念");
+        int mindsetStart = findLineIndex(lines, "成长型思维模式");
+        int drivingStart = findLineIndex(lines, "自驱力");
         if (selfConceptStart >= 0) {
-            Map<String, String> selfConcept = parseSelfConcept(lines, selfConceptStart);
+            int end = mindsetStart > selfConceptStart ? mindsetStart : lines.size();
+            Map<String, String> selfConcept = parseSelfConcept(lines, selfConceptStart, end);
             if (!selfConcept.isEmpty()) {
                 for (Map.Entry<String, String> entry : selfConcept.entrySet()) {
                     items.add(new DataItem(entry.getKey(), entry.getKey(), entry.getValue(), "selfConcept"));
@@ -230,9 +233,9 @@ public class DanReportParseService {
         }
 
         // 3. 成长型思维 (Growth Mindset)
-        int mindsetStart = findSectionStart(lines, "成长思维", "成长型思维", "思维模式");
         if (mindsetStart >= 0) {
-            Map<String, String> mindset = parseGrowthMindset(lines, mindsetStart);
+            int end = drivingStart > mindsetStart ? drivingStart : lines.size();
+            Map<String, String> mindset = parseGrowthMindset(lines, mindsetStart, end);
             if (!mindset.isEmpty()) {
                 for (Map.Entry<String, String> entry : mindset.entrySet()) {
                     items.add(new DataItem(entry.getKey(), entry.getKey(), entry.getValue(), "growthMindset"));
@@ -242,9 +245,8 @@ public class DanReportParseService {
         }
 
         // 4. 自驱力 (Self-Driving)
-        int drivingStart = findSectionStart(lines, "自驱力", "自主性", "内驱力", "自我驱动");
         if (drivingStart >= 0) {
-            Map<String, String> selfDriving = parseSelfDriving(lines, drivingStart);
+            Map<String, String> selfDriving = parseSelfDriving(lines, drivingStart, lines.size());
             if (!selfDriving.isEmpty()) {
                 for (Map.Entry<String, String> entry : selfDriving.entrySet()) {
                     items.add(new DataItem(entry.getKey(), entry.getKey(), entry.getValue(), "selfDriving"));
@@ -253,24 +255,6 @@ public class DanReportParseService {
             }
         }
 
-        // 5. 通用正则提取
-        Pattern scorePattern = Pattern.compile("([\\u4e00-\\u9fa5]{2,8})[::]\\s*(\\d+(\\.\\d+)?)");
-        Matcher matcher = scorePattern.matcher(fullText);
-        while (matcher.find()) {
-            String key = matcher.group(1).trim();
-            String val = matcher.group(2).trim();
-            boolean exists = false;
-            for (DataItem item : items) {
-                if (item.getName().equals(key)) {
-                    exists = true;
-                    break;
-                }
-            }
-            if (!exists && !key.contains("日期") && !key.contains("姓名")) {
-                items.add(new DataItem("score_" + key.hashCode(), key, val, "auto"));
-            }
-        }
-
         summary.append(extractSection(fullText, "测评总结", "成长建议"));
         suggestions.append(extractSection(fullText, "成长建议", null));
 
@@ -1320,25 +1304,15 @@ public class DanReportParseService {
     /**
      * 解析自我概念(B4)
      */
-    private Map<String, String> parseSelfConcept(List<String> lines, int startIdx) {
+    private Map<String, String> parseSelfConcept(List<String> lines, int start, int end) {
         Map<String, String> result = new LinkedHashMap<>();
-        // 自我概念通常包含6个维度
-        for (int i = startIdx; i < Math.min(startIdx + 30, lines.size()); i++) {
-            String line = lines.get(i);
-            if (line.length() > 1 && line.length() < 15 && !line.matches(".*[\\d]{2,}.*")) {
-                String nextLine = i + 1 < lines.size() ? lines.get(i + 1) : "";
-                String score = extractScore(nextLine.isEmpty() ? line : nextLine);
-                if (score != null) {
-                    result.put(line, score);
-                    i++;
-                }
-            } else {
-                String score = extractScore(line);
-                if (score != null) {
-                    String name = line.replaceAll("\\d+", "").replaceAll("[::()().%]", "").trim();
-                    if (name.length() >= 2) {
-                        result.put(name, score);
-                    }
+        Pattern pattern = Pattern.compile("^([\\u4e00-\\u9fa5]{2,15})\\s+(\\d{1,3})$");
+        for (int i = start; i < end && i < lines.size(); i++) {
+            Matcher m = pattern.matcher(lines.get(i).trim());
+            if (m.matches()) {
+                int score = Integer.parseInt(m.group(2));
+                if (score >= 0 && score <= 100) {
+                    result.put(m.group(1), m.group(2));
                 }
             }
         }
@@ -1348,10 +1322,10 @@ public class DanReportParseService {
     /**
      * 解析成长型思维(B4)
      */
-    private Map<String, String> parseGrowthMindset(List<String> lines, int startIdx) {
+    private Map<String, String> parseGrowthMindset(List<String> lines, int start, int end) {
         Map<String, String> result = new LinkedHashMap<>();
         Pattern pattern = Pattern.compile("(成长[型思维]*|思维模式|智力[观看法]*|能力[观看法]*)[^\\d]*(\\d+)");
-        for (int i = startIdx; i < Math.min(startIdx + 20, lines.size()); i++) {
+        for (int i = start; i < end && i < lines.size(); i++) {
             String line = lines.get(i);
             Matcher m = pattern.matcher(line);
             if (m.find()) {
@@ -1372,24 +1346,38 @@ public class DanReportParseService {
     /**
      * 解析自驱力(B4)
      */
-    private Map<String, String> parseSelfDriving(List<String> lines, int startIdx) {
+    private Map<String, String> parseSelfDriving(List<String> lines, int start, int end) {
         Map<String, String> result = new LinkedHashMap<>();
-        String[] keywords = {"自主性", "胜任感", "归属感", "自驱力", "自我驱动", "主动性"};
-        for (int i = startIdx; i < Math.min(startIdx + 30, lines.size()); i++) {
+        String[] dimensions = {"自主性", "胜任感", "归属感"};
+        Pattern pattern = Pattern.compile("我的得分\\s*(\\d+(?:\\.\\d+)?)");
+        for (int i = start; i < end && i < lines.size(); i++) {
             String line = lines.get(i);
-            for (String kw : keywords) {
-                if (line.contains(kw)) {
-                    String score = extractScore(line);
-                    if (score != null) {
-                        result.put(kw, score);
-                    }
-                    break;
-                }
+            if (!line.contains("我的得分")) {
+                continue;
+            }
+            Matcher m = pattern.matcher(line);
+            int idx = 0;
+            while (m.find() && idx < dimensions.length) {
+                result.put(dimensions[idx++], m.group(1));
+            }
+            if (!result.isEmpty()) {
+                break;
             }
         }
         return result;
     }
 
+    private int findLineIndex(List<String> lines, String... headers) {
+        for (int i = 0; i < lines.size(); i++) {
+            for (String header : headers) {
+                if (lines.get(i).contains(header)) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
     // ======================== 通用工具方法 ========================
 
     /**