Browse Source

refactor(miniapp): TrendChart 移入 pages/health 子包并更新引用

liaoxg 2 days ago
parent
commit
97819ef4f5

+ 1 - 1
cfc-frontend/components/TrendChart.vue → cfc-frontend/pages/health/components/TrendChart.vue

@@ -189,7 +189,7 @@ export default {
         ctx.fillText(self._fmtNum(tv), padL - 4, ty + 3)
       }
       // 折线 + 数据点 + 数值
-      var palette = ['#F97316', '#0EA5E9', '#10B981', '#8B5CF6', '#EF4444', '#F59E0B']
+      var palette = ['#F97316', '#0EA5E9', '#10B981', '#F97316', '#EF4444', '#F59E0B']
       seriesList.forEach(function(s, si) {
         var color = s.color || palette[si % palette.length]
         ctx.strokeStyle = color

+ 47 - 10
cfc-frontend/pages/health/indicator-curve.vue

@@ -62,15 +62,17 @@
             <text :class="'rank-delta ' + item._cssClass">{{ item._deltaText }}</text>
           </view>
           <text :class="'rank-trend ' + item._cssClass">{{ item._trendLabel }} {{ item._arrow }}</text>
+          <text class="rank-gap" v-if="item.skipGaps > 0">中间 {{ item.skipGaps }} 期缺失</text>
         </view>
       </view>
+      <view class="rank-empty" v-else>暂无变化数据</view>
     </view>
   </view>
 </template>
 
 <script>
-import TrendChart from '@/components/TrendChart.vue'
-import { getIndicatorTrend, getIndicatorChangeRanking } from '@/utils/api'
+import TrendChart from '@/pages/health/components/TrendChart.vue'
+import { getIndicatorTrend, getIndicatorChangeRanking, getIndicatorSourceTypes } from '@/utils/api'
 import { getFamilyMemberList } from '@/utils/api'
 import { resolveChangeStyle, formatDelta, colorClassFor } from '@/utils/indicator-change'
 import { parseDate } from '@/utils/format'
@@ -80,11 +82,8 @@ export default {
   data: function() {
     return {
       members: [], currentMemberId: null,
-      reportTypeOptions: [
-        { value: 'gut_flora', label: '肠道菌群' },
-        { value: 'food_recommend', label: '食材推荐' }
-      ],
-      activeReportType: 'gut_flora',
+      reportTypeOptions: [],
+      activeReportType: '',
       indicatorOptions: [], theIndicatorId: null,
       series: [], loadedDefinitionIds: [],
       rankTabs: [ { value: 'flora', label: '菌群变化' }, { value: 'food', label: '食材变化' }, { value: 'indicator', label: '指标变化' } ],
@@ -108,7 +107,7 @@ export default {
     },
     currentReportTypeName: function() {
       var self = this
-      var o = this.reportTypeOptions.find(function(x) { return x.value === self.activeReportType })
+      var o = this.reportTypeOptions.find(function(x) { return x.sourceType === self.activeReportType })
       return (o && o.label) || ''
     }
   },
@@ -142,10 +141,34 @@ export default {
         if (!self.currentMemberId && arr.length > 0) {
           self.currentMemberId = arr[0].id
           self.onMemberSelected()
+          self.loadSourceTypes()
         }
       })
     },
     onMemberSelected: function() { this.reloadAll() },
+    loadSourceTypes: function() {
+      var self = this
+      if (!this.currentMemberId) return
+      // 报告类型动态化:以该成员 indicator_values 实际存在的 source_type 为准,避免硬编码类型错配
+      getIndicatorSourceTypes({ subjectId: this.currentMemberId }).then(function(res) {
+        var arr = (res.data instanceof Array) ? res.data : []
+        if (arr.length > 0) {
+          self.reportTypeOptions = arr
+          var first = arr[0].sourceType
+          if (self.activeReportType !== first) {
+            self.activeReportType = first
+            self.reloadAll()
+          }
+        } else {
+          // 接口空/失败回退历史默认,避免筛选器无选项
+          self.reportTypeOptions = [
+            { sourceType: 'gut_flora', label: '肠道菌群' },
+            { sourceType: 'food_recommend', label: '食材推荐' }
+          ]
+          if (!self.activeReportType) { self.activeReportType = 'gut_flora'; self.reloadAll() }
+        }
+      })
+    },
     onMemberChange: function(e) {
       var idx = Number(e.detail.value)
       var m = this.members[idx]
@@ -154,7 +177,7 @@ export default {
     onReportTypeChange: function(e) {
       var idx = Number(e.detail.value)
       var o = this.reportTypeOptions[idx]
-      if (o) { this.activeReportType = o.value; this.reloadAll() }
+      if (o) { this.activeReportType = o.sourceType; this.reloadAll() }
     },
     reloadAll: function() {
       if (!this.currentMemberId) return
@@ -168,7 +191,9 @@ export default {
     loadRankingThenCurve: function() {
       var self = this
       if (!this.currentMemberId) return
-      var reportType = this.activeReportType === 'food_recommend' ? null : this.activeReportType
+      // food_recommend 无时序数据:FoodItem 为评分型数据,NormalizeIndicatorPipeline 不写 indicator_values,
+// 此处回退为全量指标参与曲线/排名(有意为之,非 bug)
+      var reportType = (!this.activeReportType || this.activeReportType === 'food_recommend') ? null : this.activeReportType
       getIndicatorChangeRanking({
         subjectId: this.currentMemberId,
         reportType: reportType,
@@ -319,6 +344,18 @@ export default {
   font-size: 26rpx;
   color: #94A3B8;
 }
+.rank-gap {
+  display: inline-block;
+  margin: 4rpx 0;
+  color: #e53e3e;
+  font-size: 20rpx;
+}
+.rank-empty {
+  padding: 60rpx 0;
+  text-align: center;
+  font-size: 24rpx;
+  color: #94A3B8;
+}
 
 /* 排名 Tab */
 .rank-tabs {