Browse Source

feat: 心智页添加心/智双Tab结构

实施 docs/superpowers/plans/2026-06-19-mind-page-dual-tab.md:

- Tab栏:心·心理 / 智·认知 双Tab切换
- 心理Tab:EMI心理四维、大五人格、每日心理、推荐阅读(心理相关)
- 认知Tab:DAN综合认知评分、六维雷达图、认知训练、阅读统计、推荐阅读(认知相关)
- Tab切换时活动/商品跟随切换维度(mind/wisdom)
- 推荐阅读根据文章 relatedDimensions 按Tab筛选
Sisyphus 3 tháng trước cách đây
mục cha
commit
e6a54f49ea
1 tập tin đã thay đổi với 143 bổ sung10 xóa
  1. 143 10
      cfc-frontend/pages/mind/index.vue

+ 143 - 10
cfc-frontend/pages/mind/index.vue

@@ -51,6 +51,25 @@
       @childChanged="onChildChanged"
       @scrollTo="scrollToSection" />
 
+    <!-- ===== 心/智 Tab栏 ===== -->
+    <view class="tab-bar">
+      <view
+        :class="['tab-item', activeTab === 'emotion' ? 'active' : '']"
+        @click="switchTab('emotion')">
+        <text class="tab-icon">&#x2764;</text>
+        <text class="tab-label">心·心理</text>
+      </view>
+      <view
+        :class="['tab-item', activeTab === 'cognitive' ? 'active' : '']"
+        @click="switchTab('cognitive')">
+        <text class="tab-icon">&#x1F9E0;</text>
+        <text class="tab-label">智·认知</text>
+      </view>
+    </view>
+
+    <!-- ===== 心·心理 Tab ===== -->
+    <template v-if="activeTab === 'emotion'">
+
     <!-- ===== 心理能量概况 ===== -->
     <view class="energy-overview" v-if="emiData">
       <view class="energy-badge">
@@ -138,7 +157,7 @@
         <text class="section-title">推荐阅读</text>
       </view>
       <view class="article-list">
-        <view class="article-card" v-for="article in articles" :key="article.id" @click="goArticleDetail(article.id)">
+        <view class="article-card" v-for="article in emotionArticles" :key="article.id" @click="goArticleDetail(article.id)">
           <view class="article-category" :style="{ background: article.categoryColor }">
             <text class="article-category-text">{{ article.category }}</text>
           </view>
@@ -159,6 +178,11 @@
       </view>
     </view>
 
+    </template>
+
+    <!-- ===== 智·认知 Tab ===== -->
+    <template v-if="activeTab === 'cognitive'">
+
     <!-- ===== 认知区块 ===== -->
       <!-- 综合认知评分 -->
       <view class="cognitive-overview" v-if="assessmentData">
@@ -274,22 +298,51 @@
         </view>
       </view>
 
+      <!-- 推荐阅读(认知Tab内) -->
+      <view class="section" v-if="sectionVisible('recommended_reading')">
+        <view class="section-header">
+          <text class="section-title">推荐阅读</text>
+        </view>
+        <view class="article-list">
+          <view class="article-card" v-for="article in cognitiveArticles" :key="article.id" @click="goArticleDetail(article.id)">
+            <view class="article-category" :style="{ background: article.categoryColor }">
+              <text class="article-category-text">{{ article.category }}</text>
+            </view>
+            <text class="article-title">{{ article.title }}</text>
+            <text class="article-summary">{{ article.summary }}</text>
+            <view class="article-meta">
+              <view class="meta-item">
+                <text class="meta-icon">&#x1F4D6;</text>
+                <text class="meta-text">{{ article.views }}</text>
+              </view>
+              <view class="meta-item">
+                <text class="meta-icon">&#x1F44D;</text>
+                <text class="meta-text">{{ article.likes }}</text>
+              </view>
+              <text class="article-date">{{ article.date }}</text>
+            </view>
+          </view>
+        </view>
+      </view>
+
+    </template>
+
     <!-- ===== 底部:维度任务/活动/商品 ===== -->
     <DimensionTasks
       v-if="isLoggedIn"
-      dimensionCode="mind"
+      :dimensionCode="currentDimensionCode"
       :tasks="dimensionTasks"
       @taskClick="onTaskClick"
       @moreTasks="goTasks" />
 
     <DimensionActivities
-      dimensionCode="mind"
+      :dimensionCode="currentDimensionCode"
       :activities="dimensionActivities"
       @activityClick="goActivityDetail"
       @moreActivities="goMoreActivities" />
 
     <DimensionProducts
-      dimensionCode="mind"
+      :dimensionCode="currentDimensionCode"
       :products="dimensionProducts"
       @productClick="goProductDetail"
       @moreProducts="goMoreProducts" />
@@ -393,7 +446,8 @@ export default {
       dualDimension: null,
       dimensionTasks: [],
       dimensionActivities: [],
-      dimensionProducts: []
+      dimensionProducts: [],
+      activeTab: 'emotion'
     }
   },
   computed: {
@@ -428,6 +482,33 @@ export default {
     },
     intimacyMapForGraph: function() {
       return {}
+    },
+    emotionArticles: function() {
+      if (!this.articles || this.articles.length === 0) return []
+      var result = []
+      for (var i = 0; i < this.articles.length; i++) {
+        var a = this.articles[i]
+        if (a.relatedDimensions && a.relatedDimensions.indexOf('mind') !== -1) {
+          result.push(a)
+        }
+      }
+      if (result.length === 0) return this.articles.slice(0, 5)
+      return result.slice(0, 5)
+    },
+    cognitiveArticles: function() {
+      if (!this.articles || this.articles.length === 0) return []
+      var result = []
+      for (var i = 0; i < this.articles.length; i++) {
+        var a = this.articles[i]
+        if (a.relatedDimensions && a.relatedDimensions.indexOf('wisdom') !== -1) {
+          result.push(a)
+        }
+      }
+      if (result.length === 0) return this.articles.slice(0, 5)
+      return result.slice(0, 5)
+    },
+    currentDimensionCode: function() {
+      return this.activeTab === 'emotion' ? 'mind' : 'wisdom'
     }
   },
   onShow() {
@@ -616,7 +697,8 @@ export default {
               summary: item.summary || '',
               views: item.viewCount ? String(item.viewCount) : '0',
               likes: '0',
-              date: item.publishedAt ? item.publishedAt.slice(0, 10) : ''
+              date: item.publishedAt ? item.publishedAt.slice(0, 10) : '',
+              relatedDimensions: item.relatedDimensions || []
             }
           })
         }
@@ -749,7 +831,8 @@ export default {
     },
     loadDimensionActivities: function() {
       var self = this
-      getActivityList({ dimensionCode: 'mind', page: 1, size: 3 }).then(function(res) {
+      var dimCode = self.currentDimensionCode
+      getActivityList({ dimensionCode: dimCode, page: 1, size: 3 }).then(function(res) {
         if (res && res.data) {
           var list = Array.isArray(res.data) ? res.data : (res.data.records || [])
           self.dimensionActivities = list.slice(0, 3)
@@ -758,7 +841,8 @@ export default {
     },
     loadDimensionProducts: function() {
       var self = this
-      getProductsByDomain('mind', 1, 4).then(function(res) {
+      var dimCode = self.currentDimensionCode
+      getProductsByDomain(dimCode, 1, 4).then(function(res) {
         if (res && res.data) {
           var list = Array.isArray(res.data) ? res.data : (res.data.records || [])
           self.dimensionProducts = list.slice(0, 4)
@@ -802,13 +886,15 @@ export default {
       if (act && act.id) uni.navigateTo({ url: '/pages/discover/index?type=activity&id=' + act.id })
     },
     goMoreActivities: function() {
-      uni.navigateTo({ url: '/pages/discover/index?type=activity&dimension=mind' })
+      var dimCode = this.currentDimensionCode
+      uni.navigateTo({ url: '/pages/discover/index?type=activity&dimension=' + dimCode })
     },
     goProductDetail: function(prod) {
       if (prod && prod.id) uni.navigateTo({ url: '/pages/discover/product-detail/product-detail?id=' + prod.id })
     },
     goMoreProducts: function() {
-      uni.navigateTo({ url: '/pages/discover/index?type=product&domain=mind' })
+      var dimCode = this.currentDimensionCode
+      uni.navigateTo({ url: '/pages/discover/index?type=product&domain=' + dimCode })
     },
     goTasks: function() { uni.switchTab({ url: '/pages/tasks/tasks' }) },
     goMemberDetail: function(member) {
@@ -818,6 +904,12 @@ export default {
       })
     },
 
+    switchTab: function(tab) {
+      if (tab === this.activeTab) return
+      this.activeTab = tab
+      this.loadDimensionActivities()
+      this.loadDimensionProducts()
+    },
     goAssessment: function() { uni.navigateTo({ url: '/pages/assessment/apply' }) },
     goLogin: function() { uni.navigateTo({ url: '/pages/login/login' }) }
   }
@@ -831,6 +923,47 @@ export default {
   padding-bottom: 120rpx;
 }
 
+/* ===== 心/智 Tab 栏 ===== */
+.tab-bar {
+  display: flex;
+  flex-direction: row;
+  margin: 20rpx 30rpx;
+  background: #fff;
+  border-radius: 20rpx;
+  padding: 8rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
+}
+.tab-item {
+  flex: 1;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+  padding: 20rpx 0;
+  border-radius: 16rpx;
+  transition: all 0.3s;
+}
+.tab-item.active {
+  background: linear-gradient(135deg, #8B5CF6, #A78BFA);
+  box-shadow: 0 4rpx 12rpx rgba(139,92,246,0.3);
+}
+.tab-icon {
+  font-size: 28rpx;
+  margin-right: 8rpx;
+}
+.tab-item.active .tab-icon {
+  color: #fff;
+}
+.tab-label {
+  font-size: 28rpx;
+  font-weight: 500;
+  color: #999;
+}
+.tab-item.active .tab-label {
+  color: #fff;
+  font-weight: bold;
+}
+
 /* ===== 心理能量概况 ===== */
 .energy-overview {
   display: flex;