Просмотр исходного кода

feat(frontend): gut-flora-risks-detail.vue 展示 relatedBacteria 与 gut-flora-detail.vue gutStatusLevel 微标(P0+P1 完整)

E2E Test Bot 10 часов назад
Родитель
Сommit
84d49ab261

+ 2 - 1
cfc-frontend/pages/health/gut-flora-detail.vue

@@ -13,7 +13,8 @@
           <text class="meta-item" v-if="report.reportDate">日期: {{ reportDateText }}</text>
           <text class="meta-item" v-if="report.reportNumber">编号: {{ report.reportNumber }}</text>
         </view>
-        <view class="badge-row" v-if="report.gutAge || report.gutType || report.shannonIndex">
+        <view class="badge-row" v-if="report.gutAge || report.gutType || report.shannonIndex || report.gutStatusLevel">
+          <text class="badge" v-if="report.gutStatusLevel">菌群状态: {{ report.gutStatusLevel }}</text>
           <text class="badge" v-if="report.gutAge">肠龄: {{ report.gutAge }}</text>
           <text class="badge" v-if="report.gutType">肠型: {{ report.gutType }}</text>
           <text class="badge" v-if="report.shannonIndex">多样性指数: {{ report.shannonIndex }}</text>

+ 83 - 0
cfc-frontend/pages/health/gut-flora-risks-detail.vue

@@ -47,6 +47,15 @@
           <text class="desc-label">说明:</text>
           <text class="desc-content">{{ item.diseaseDesc }}</text>
         </view>
+        <view class="bacteria-row" v-if="!isEditing && item._relatedBacteria && item._relatedBacteria.length > 0">
+          <text class="bacteria-label">关联菌</text>
+          <view class="bacteria-list">
+            <view class="bacteria-item" v-for="(b, bIdx) in item._relatedBacteria" :key="bIdx">
+              <text class="bacteria-name">{{ b.bacteria }}</text>
+              <text class="bacteria-cor" :class="'cor-' + b._corClass">{{ b.correlation }}</text>
+            </view>
+          </view>
+        </view>
         <view class="risk-detail-row" v-if="!isEditing">
           <text class="risk-tag" :class="'tag-' + (item._cssClass || 'low')">
             {{ item.riskLevel || '--' }}
@@ -83,6 +92,15 @@
           <text class="desc-label">说明:</text>
           <text class="desc-content">{{ item.diseaseDesc }}</text>
         </view>
+        <view class="bacteria-row" v-if="!isEditing && item._relatedBacteria && item._relatedBacteria.length > 0">
+          <text class="bacteria-label">关联菌</text>
+          <view class="bacteria-list">
+            <view class="bacteria-item" v-for="(b, bIdx) in item._relatedBacteria" :key="bIdx">
+              <text class="bacteria-name">{{ b.bacteria }}</text>
+              <text class="bacteria-cor" :class="'cor-' + b._corClass">{{ b.correlation }}</text>
+            </view>
+          </view>
+        </view>
         <view class="risk-detail-row" v-if="!isEditing">
           <text class="risk-tag" :class="'tag-' + (item._cssClass || 'low')">{{ item.riskLevel || '--' }}</text>
         </view>
@@ -156,6 +174,26 @@ export default {
       var map = { '低风险': 'low', '注意': 'warning', '需注意': 'warning', '高风险': 'high', '异常': 'abnormal' }
       return map[level] || 'low'
     },
+    /** 解析关联菌(后端 health_disease_risk.related_bacteria 为 JSON 字符串数组) */
+    parseRelatedBacteria: function(str) {
+      var list = []
+      if (!str) return list
+      try {
+        if (typeof str === 'string') {
+          list = JSON.parse(str)
+        } else if (Object.prototype.toString.call(str) === '[object Array]') {
+          list = str
+        }
+      } catch (e) {
+        return []
+      }
+      if (Object.prototype.toString.call(list) !== '[object Array]') return []
+      var clsMap = { '超标': 'over', '缺乏': 'lack', '偏高': 'high', '偏低': 'low', '异常': 'abnormal', '正常': 'normal' }
+      return list.filter(function(b) { return b && b.bacteria }).map(function(b) {
+        b._corClass = clsMap[b.correlation] || 'normal'
+        return b
+      })
+    },
     /** 风险值归一化进度(0~1范围映射到百分比) */
     calcProgress: function(value) {
       var v = parseFloat(value)
@@ -173,6 +211,8 @@ export default {
           var rawRisks = res.data.diseaseRisks || []
           self.risks = rawRisks.map(function(item) {
             item._cssClass = self._cssForRiskLevel(item.riskLevel)
+            // 关联菌(健康报告详情返回 JSON 字符串数组,解析为展示列表)
+            item._relatedBacteria = self.parseRelatedBacteria(item.relatedBacteria)
             return item
           })
           // 批量预加载疾病知识库
@@ -447,6 +487,49 @@ export default {
   flex: 1;
 }
 
+/* 关联菌(P0) */
+.bacteria-row {
+  display: flex;
+  align-items: flex-start;
+  flex-wrap: wrap;
+  margin-bottom: 14rpx;
+}
+.bacteria-label {
+  font-size: 22rpx;
+  color: #999;
+  flex-shrink: 0;
+  margin-right: 10rpx;
+  padding-top: 8rpx;
+}
+.bacteria-list {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10rpx;
+}
+.bacteria-item {
+  display: flex;
+  align-items: center;
+  gap: 6rpx;
+  background: #f8f9fc;
+  border-radius: 8rpx;
+  padding: 6rpx 12rpx;
+}
+.bacteria-name {
+  font-size: 22rpx;
+  color: #333;
+}
+.bacteria-cor {
+  font-size: 20rpx;
+  padding: 2rpx 10rpx;
+  border-radius: 6rpx;
+}
+.cor-over { background: #FFEBEE; color: #C62828; }
+.cor-lack { background: #FFF3E0; color: #E65100; }
+.cor-high { background: #FFEBEE; color: #C62828; }
+.cor-low { background: #FFF3E0; color: #E65100; }
+.cor-abnormal { background: #C62828; color: #fff; }
+.cor-normal { background: #E8F5E9; color: #2E7D32; }
+
 /* 底部标签行 */
 .risk-detail-row {
   display: flex;