瀏覽代碼

菌群报告解析成功

jiapu 1 周之前
父節點
當前提交
f55eb1f101

+ 46 - 0
cfc-backend/src/main/java/com/etotem/cfc/config/DatabaseInitializer.java

@@ -10867,5 +10867,51 @@ sqls.add("INSERT IGNORE INTO health_norm_reference (dimension, gender, age_min,
         } catch (Exception e) {
             log.warn("迁移310: health_meal_record 索引已存在或添加失败: {}", e.getMessage());
         }
+
+        // 迁移310: health_reports / health_report_drafts 补 file_hash 列
+        // 实体与 schema.sql 已含该列,但建表迁移从未 ADD;upload-only 按 MD5 去重时 SELECT 报 Unknown column 'file_hash'
+        ensureColumn("health_reports", "file_hash",
+                "VARCHAR(64) DEFAULT NULL COMMENT '文件MD5哈希,用于重复上传检测'");
+        ensureColumn("health_report_drafts", "file_hash",
+                "VARCHAR(64) DEFAULT NULL COMMENT '文件MD5哈希,用于重复上传检测'");
+        log.info("迁移310: 已补齐 health_reports/health_report_drafts.file_hash");
+
+        // 迁移311: report_type_registry 补 script_status 列
+        // 实体/schema 已含;异步采集指纹识别 SELECT 全字段时报 Unknown column 'script_status'
+        ensureColumn("report_type_registry", "script_status",
+                "VARCHAR(20) DEFAULT NULL COMMENT '采集脚本生成状态: generating/ready/failed'");
+        log.info("迁移311: 已补齐 report_type_registry.script_status");
+
+        // 迁移312: 为 gut_flora 补默认指纹规则(空表会导致指纹引擎永远 unknown)
+        seedGutFloraFingerprints();
+    }
+
+    private void seedGutFloraFingerprints() {
+        try {
+            Integer count = jdbcTemplate.queryForObject(
+                    "SELECT COUNT(*) FROM report_fingerprint WHERE type_id = ?", Integer.class, "gut_flora");
+            if (count != null && count > 0) {
+                log.info("迁移312: gut_flora 指纹规则已存在,跳过");
+                return;
+            }
+            String[][] rows = {
+                    {"肠道菌群检测", "20", "0", "1"},
+                    {"核心菌属", "15", "0", "2"},
+                    {"高通量测序", "15", "0", "3"},
+                    {"菌群健康", "10", "0", "4"},
+                    {"益生菌", "8", "0", "5"},
+                    {"Shannon", "8", "0", "6"},
+                    {"肠道菌群", "10", "0", "7"},
+            };
+            for (String[] row : rows) {
+                jdbcTemplate.update(
+                        "INSERT INTO report_fingerprint (type_id, pattern, weight, is_exclusion, sort_order, created_at) "
+                                + "VALUES ('gut_flora', ?, ?, ?, ?, NOW())",
+                        row[0], Integer.valueOf(row[1]), Integer.valueOf(row[2]), Integer.valueOf(row[3]));
+            }
+            log.info("迁移312: 已写入 gut_flora 默认指纹规则 {} 条", rows.length);
+        } catch (Exception e) {
+            log.warn("迁移312: 写入 gut_flora 指纹规则失败: {}", e.getMessage());
+        }
     }
 }

+ 15 - 0
cfc-backend/src/main/resources/application.yml

@@ -110,6 +110,7 @@ deepseek:
   callback-secret: ${DIFY_CALLBACK_SECRET:dev-only-callback-secret}
 
 python:
+  executable: python
   enabled: true
   base-url: https://ai.etotem.com.cn
   timeout-ms: 15000
@@ -126,6 +127,20 @@ langgraph:
   base-url: ${LANGGRAPH_BASE_URL:http://localhost:9000}
   profile-timeout-ms: 90000   # 画像生成推理可达 30-60s,独立超时
 
+report:
+  collect:
+    # 健康报告异步采集:未命中指纹脚本时交本地 opencode 服务解析
+    # 启动命令见根 AGENTS.md:opencode web --port 4090 --hostname 127.0.0.1
+    opencode-base: ${OPENCODE_BASE:http://127.0.0.1:4090}
+    opencode-user: opencode
+    opencode-password: ${OPENCODE_ADMIN_PASSWORD:IwinTrue@123}
+    opencode-workdir: ${OPENCODE_WORKDIR:/app/cfc}
+    # provider-id 必须与 GET /config/providers 返回的 id 完全一致(本机为 agnes,不是 agnes-ai)
+    # 模型只在 prompt_async 请求体生效;勿用 opencode/big-pickle(免费额度限流,会空转超时)
+    opencode-model-provider: ${OPENCODE_MODEL_PROVIDER:agnes}
+    opencode-model-id: ${OPENCODE_MODEL_ID:agnes-2.5-flash}
+    opencode-agent: ${OPENCODE_AGENT:build}
+
 math:
   verify-mode: dify  # dify | eval; dify=走Dify工作流, eval=服务端计算(兜底)
   workflow-id: ""    # Dify 数学判题工作流 ID(留空则使用 eval 兜底)

+ 10 - 1
opencode.json

@@ -1,5 +1,6 @@
 {
   "$schema": "https://opencode.ai/config.json",
+  "model": "agnes/agnes-2.5-flash",
   "watcher": {
     "ignore": [
       "node_modules",
@@ -14,5 +15,13 @@
       "dist"
     ]
   },
-  "snapshot": false
+  "snapshot": false,
+  "provider": {
+    "agnes": {
+      "options": {
+        "apiKey": "ah-ae0c8ad474baeb076b2f01878515d08951822f6620661a1802df20ee31c0d3db",
+        "baseUrl": "https://api.agnes-ai.cn/v1"
+      }
+    }
+  }
 }