Bläddra i källkod

fix(health): 菌群报告详情补齐未呈现数据(性别/年龄/AI解读)并统一手风琴统计口径

liaoxg 1 månad sedan
förälder
incheckning
7fc0427acc
1 ändrade filer med 54 tillägg och 4 borttagningar
  1. 54 4
      cfc-frontend/pages/health/gut-flora-detail.vue

+ 54 - 4
cfc-frontend/pages/health/gut-flora-detail.vue

@@ -25,6 +25,11 @@
         <view class="interpretation-box" v-if="reportInterpretation && reportInterpretation.gutAgeAssessment">
           <text class="interp-text">{{ reportInterpretation.gutAgeAssessment }}</text>
         </view>
+        <!-- AI 解读 -->
+        <view class="interpretation-box ai-box" v-if="aiAnalysisText">
+          <text class="interp-label">🤖 AI 解读</text>
+          <text class="interp-text">{{ aiAnalysisText }}</text>
+        </view>
       </view>
 
       <!-- 评分圆环(折行显示,无横向滚动) -->
@@ -110,7 +115,7 @@
         <view class="accordion-section" v-if="analysisData && analysisData.riskIndicators && analysisData.riskIndicators.length > 0">
           <view class="accordion-header" @tap="toggleAccordion('riskGroup')">
             <text class="accordion-title">菌群风险分组</text>
-            <text class="accordion-stats">共 {{ analysisData.riskIndicators.length }} 组</text>
+            <text class="accordion-stats" v-if="analysisData.riskIndicators.length > 0">异常 <text class="abnormal-num">{{ riskGroupAbnormalCount }}</text> / 共 {{ analysisData.riskIndicators.length }} 组</text>
             <text class="accordion-arrow">{{ accordionOpen.riskGroup ? '收起' : '展开' }}</text>
           </view>
           <view class="accordion-body" v-if="accordionOpen.riskGroup">
@@ -181,7 +186,7 @@
         <view class="accordion-section">
           <view class="accordion-header" @tap="toggleNutriGroup(gIdx)">
             <text class="accordion-title">{{ group.category }}</text>
-            <text class="accordion-stats" v-if="group.abnormalCount > 0">异常 <text class="abnormal-num">{{ group.abnormalCount }}</text> 项</text>
+            <text class="accordion-stats" v-if="group.items.length > 0">异常 <text class="abnormal-num">{{ group.abnormalCount }}</text> / 共 {{ group.items.length }} 项</text>
             <text class="accordion-arrow">{{ nutriGroupOpen[gIdx] ? '收起' : '展开' }}</text>
           </view>
           <view class="accordion-body" v-if="nutriGroupOpen[gIdx]">
@@ -217,7 +222,7 @@
       <view class="accordion-section" v-if="diseaseRisks.length > 0">
         <view class="accordion-header" @tap="toggleAccordion('risks')">
           <text class="accordion-title">疾病风险</text>
-          <text class="accordion-stats" v-if="diseaseRisksAbnormal > 0">需关注 <text class="abnormal-num">{{ diseaseRisksAbnormal }}</text> 项</text>
+          <text class="accordion-stats" v-if="diseaseRisks.length > 0">异常 <text class="abnormal-num">{{ diseaseRisksAbnormal }}</text> / 共 {{ diseaseRisks.length }} 项</text>
           <text class="accordion-arrow">{{ accordionOpen.risks ? '收起' : '展开' }}</text>
         </view>
         <view class="accordion-body" v-if="accordionOpen.risks">
@@ -369,6 +374,7 @@ export default {
       reportData: null,
       report: {},
       reportInterpretation: null,
+      aiAnalysisText: '',
       isEditing: false,
       accordionOpen: { gut: false, risks: false, riskGroup: false },
       riskGroupOpen: [],
@@ -449,6 +455,16 @@ export default {
       }
       return count
     },
+    riskGroupAbnormalCount: function() {
+      if (!this.analysisData || !this.analysisData.riskIndicators) return 0
+      var list = this.analysisData.riskIndicators
+      var count = 0
+      for (var i = 0; i < list.length; i++) {
+        var lv = list[i].level || ''
+        if (lv !== '良好' && lv !== '正常') count++
+      }
+      return count
+    },
     draftMemberText: function() {
       if (this.selectedMemberObj) return this.selectedMemberObj.nickname || this.selectedMemberObj.name || '已选择'
       if (this.extractedName) return this.extractedName + '(待绑定)'
@@ -569,8 +585,24 @@ export default {
       getReportDetail(this.reportId).then(function(res) {
         if (res.code === 200 && res.data) {
           self.reportData = res.data
-          self.report = res.data.report || res.data
+          var reportObj = res.data.report || res.data
+          // HealthReport 实体无 gender/age 字段,从 payload.summary 补齐(采集到但未落库)
+          var ps = (res.data.payload && res.data.payload.summary) || {}
+          self.report = Object.assign({}, reportObj, {
+            gender: reportObj.gender || ps.gender || '',
+            age: reportObj.age != null ? reportObj.age : (ps.age != null ? ps.age : '')
+          })
           self.reportInterpretation = res.data.reportInterpretation || null
+          // 解析 AI 解读(aiAnalysis 为 JSON 字符串 {analysis, traceId, ...})
+          var aiRaw = reportObj.aiAnalysis
+          if (aiRaw) {
+            try {
+              var aiObj = typeof aiRaw === 'string' ? JSON.parse(aiRaw) : aiRaw
+              self.aiAnalysisText = (aiObj && aiObj.analysis) || ''
+            } catch (e) {
+              self.aiAnalysisText = ''
+            }
+          }
           self.buildScores(res.data)
           self.buildIndicators(res.data)
           self.floraCount = (res.data.gutFlora || []).length
@@ -668,6 +700,8 @@ export default {
       if (payload.summary) {
         var s = payload.summary
         report.personName = s.personName || ''
+        report.gender = s.gender || ''
+        report.age = s.age != null ? s.age : ''
         report.reportNumber = s.reportNumber || ''
         report.gutAge = s.gutAge || ''
 report.gutType = s.gutType || ''
@@ -1138,6 +1172,22 @@ report.gutType = s.gutType || ''
   line-height: 1.6;
 }
 
+/* AI 解读框 */
+.ai-box {
+  background: #E0F2F1;
+  border-left-color: #00897B;
+}
+.interp-label {
+  font-size: 24rpx;
+  font-weight: 600;
+  color: #00695C;
+  display: block;
+  margin-bottom: 6rpx;
+}
+.ai-box .interp-text {
+  color: #004D40;
+}
+
 /* 解读入口 */
 .ai-fab {
   position: fixed;