Pārlūkot izejas kodu

chore: auto bump version and changelog [skip ci]

iwt 6 dienas atpakaļ
vecāks
revīzija
525e577313

+ 182 - 0
cfc-frontend/pages/action-detail/index.vue

@@ -47,6 +47,32 @@
       </view>
       <text class="explain-text">{{ actionScore >= 80 ? '家庭关系和谐,家人沟通顺畅。' : actionScore >= 60 ? '家庭关系一般,建议多花时间陪伴家人。' : '家庭关系需要改善,建议进行家庭沟通活动。' }}</text>
     </view>
+    <!-- 行维度画像 - 总体说明 -->
+    <view class="dimension-portrait-section" v-if="isLoggedIn && actionPortrait">
+      <view class="section-header">
+        <text class="section-title">🧭 行维度画像</text>
+        <text class="portrait-tier">{{ actionPortrait.tierLabel }}</text>
+      </view>
+      <view class="portrait-summary">
+        <text class="portrait-desc">{{ actionPortrait.summary }}</text>
+      </view>
+      <view class="portrait-dimensions">
+        <view class="portrait-dim-item" v-for="dim in actionPortrait.dims" :key="dim.code">
+          <view class="portrait-dim-header">
+            <view class="portrait-dim-icon" :style="{ background: dim.color }">{{ dim.icon }}</view>
+            <text class="portrait-dim-name">{{ dim.name }}</text>
+            <text class="portrait-dim-score">{{ dim.score }}</text>
+          </view>
+          <view class="portrait-dim-bar-track">
+            <view class="portrait-dim-bar-fill" :style="{ width: dim.score + '%', background: dim.color }"></view>
+          </view>
+          <text class="portrait-dim-desc">{{ dim.desc }}</text>
+        </view>
+      </view>
+      <view class="portrait-tip" v-if="actionPortrait.tip">
+        <text class="portrait-tip-text">💡 {{ actionPortrait.tip }}</text>
+      </view>
+    </view>
     <!-- 关系六维 -->
     <dimension-sub-dims
       v-if="isLoggedIn && actionSubDims.length > 0"
@@ -396,6 +422,7 @@ export default {
       }
       return scores
     },
+<<<<<<< Updated upstream
 
     /** 关系解读状态:good(≥80) | warn(≥60) | bad(<60) */
     scoreExplainLevel: function() {
@@ -408,6 +435,73 @@ export default {
     /** 关系解读卡片状态类(用于 :class 绑定) */
     scoreExplainClass: function() {
       return 'score-explain-' + this.scoreExplainLevel
+=======
+    actionPortrait: function() {
+      var self = this
+      if (!this.isLoggedIn) return null
+      var member = this.currentMemberEnergies
+      if (!member) return null
+      var role = this.role || uni.getStorageSync('currentRole') || ''
+      var isParent = (role === 'parent')
+      var parentDims = [
+        { key: 'actionParentChild', label: '亲子关系', color: '#10B981', desc: '与子女的沟通与陪伴质量' },
+        { key: 'actionMarital', label: '夫妻关系', color: '#FF6B9D', desc: '夫妻间的理解与支持' },
+        { key: 'actionParental', label: '父母关系', color: '#F59E0B', desc: '与长辈的相处模式' },
+        { key: 'actionLeadership', label: '领导关系', color: '#6366F1', desc: '职场上下级沟通能力' },
+        { key: 'actionSociality', label: '社会性', color: '#FF8C42', desc: '社会交往与参与度' },
+        { key: 'actionInterpersonal', label: '人际韧性', color: '#06B6D4', desc: '应对人际关系挫折的能力' }
+      ]
+      var childDims = [
+        { key: 'actionChildParentChild', label: '亲子关系', color: '#10B981', desc: '与父母的互动质量' },
+        { key: 'actionSibling', label: '同胞关系', color: '#FF6B9D', desc: '兄弟姐妹间的关系' },
+        { key: 'actionRelative', label: '亲属关系', color: '#F59E0B', desc: '与亲戚的交往频率' },
+        { key: 'actionTeacherStudent', label: '师生关系', color: '#6366F1', desc: '与老师的沟通情况' },
+        { key: 'actionChildSociality', label: '社会性', color: '#FF8C42', desc: '学校与社会参与度' },
+        { key: 'actionChildInterpersonal', label: '人际韧性', color: '#06B6D4', desc: '应对社交困难的能力' }
+      ]
+      var dims = isParent ? parentDims : childDims
+      var result = { overall: 0, tierLabel: '', summary: '', dims: [], tip: '' }
+      var total = 0
+      var count = 0
+      var dimList = []
+      for (var i = 0; i < dims.length; i++) {
+        var key = dims[i].key
+        var score = member[key] || 0
+        if (isNaN(score)) score = 0
+        score = Math.max(0, Math.min(100, Number(score)))
+        total += score
+        count++
+        dimList.push({
+          code: key,
+          name: dims[i].label,
+          score: Math.round(score),
+          color: dims[i].color,
+          desc: dims[i].desc
+        })
+      }
+      if (count === 0) return null
+      result.overall = Math.round(total / count)
+      result.dims = dimList
+      var o = result.overall
+      if (o >= 80) {
+        result.tierLabel = '关系大师'
+        result.summary = '您的家庭关系和谐稳定,与家人建立了深厚的信任纽带。'
+        result.tip = '继续保持沟通习惯,也可分享经验帮助其他家庭'
+      } else if (o >= 60) {
+        result.tierLabel = '关系进取者'
+        result.summary = '您的家庭关系处于良好水平,具备基本的沟通能力。'
+        result.tip = '多倾听家人心声,主动表达关爱,持续提升关系质量'
+      } else if (o >= 40) {
+        result.tierLabel = '关系探索者'
+        result.summary = '您的家庭关系正在建立基础,需要更多沟通与理解。'
+        result.tip = '建议定期进行家庭活动,增进彼此了解与信任'
+      } else {
+        result.tierLabel = '关系关怀者'
+        result.summary = '您可能面临家庭关系挑战,需要更多关注与努力。'
+        result.tip = '建议寻求专业家庭辅导,或从简单的家庭对话开始改善'
+      }
+      return result
+>>>>>>> Stashed changes
     }
   },
   onShow() {
@@ -1073,4 +1167,92 @@ export default {
 .bottom-spacer {
   height: 40rpx;
 }
+
+/* 维度画像样式 */
+.dimension-portrait-section {
+  margin: 24rpx 30rpx;
+  background: #fff;
+  border-radius: 24rpx;
+  padding: 32rpx 24rpx;
+  box-shadow: 0 4rpx 20rpx rgba(16, 185, 129, 0.12);
+  border: 2rpx solid rgba(16, 185, 129, 0.1);
+}
+.portrait-tier {
+  font-size: 26rpx;
+  color: #10B981;
+  font-weight: bold;
+  margin-left: 16rpx;
+}
+.portrait-summary {
+  margin-bottom: 24rpx;
+}
+.portrait-desc {
+  font-size: 26rpx;
+  color: #666;
+  line-height: 1.6;
+  display: block;
+}
+.portrait-dimensions {
+  margin-bottom: 20rpx;
+}
+.portrait-dim-item {
+  margin-bottom: 18rpx;
+}
+.portrait-dim-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 6rpx;
+}
+.portrait-dim-icon {
+  width: 36rpx;
+  height: 36rpx;
+  border-radius: 18rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 10rpx;
+  font-size: 20rpx;
+  background: linear-gradient(135deg, #D1FAE5, #A7F3D0);
+}
+.portrait-dim-name {
+  font-size: 24rpx;
+  color: #333;
+  flex: 1;
+}
+.portrait-dim-score {
+  font-size: 26rpx;
+  font-weight: bold;
+  color: #10B981;
+  margin-right: 12rpx;
+}
+.portrait-dim-bar-track {
+  height: 10rpx;
+  background: #D1FAE5;
+  border-radius: 5rpx;
+  overflow: hidden;
+  margin-bottom: 4rpx;
+  flex: 1;
+}
+.portrait-dim-bar-fill {
+  height: 100%;
+  border-radius: 5rpx;
+  transition: width 0.3s ease;
+}
+.portrait-dim-desc {
+  font-size: 20rpx;
+  color: #666;
+  display: block;
+}
+.portrait-tip {
+  padding: 16rpx 20rpx;
+  background: linear-gradient(135deg, #F0FFF4, #E6FFF2);
+  border-radius: 12rpx;
+  border-left: 4rpx solid #10B981;
+  margin-top: 16rpx;
+}
+.portrait-tip-text {
+  font-size: 22rpx;
+  color: #065F46;
+  line-height: 1.5;
+}
 </style>

+ 110 - 0
cfc-frontend/pages/body-detail/index.vue

@@ -6,6 +6,33 @@
     <!-- 品牌头部 -->
     <PageBanner theme="body" tagline="科学管理全家健康" quote="身体健康是幸福的基础" />
 
+    <!-- 身维度画像 - 总体说明 -->
+    <view class="dimension-portrait-section" v-if="isLoggedIn && bodyPortrait">
+      <view class="section-header">
+        <text class="section-title">🧭 身维度画像</text>
+        <text class="portrait-tier">{{ bodyPortrait.tierLabel }}</text>
+      </view>
+      <view class="portrait-summary">
+        <text class="portrait-desc">{{ bodyPortrait.summary }}</text>
+      </view>
+      <view class="portrait-dimensions">
+        <view class="portrait-dim-item" v-for="dim in bodyPortrait.dims" :key="dim.code">
+          <view class="portrait-dim-header">
+            <view class="portrait-dim-icon" :style="{ background: dim.color }">{{ dim.icon }}</view>
+            <text class="portrait-dim-name">{{ dim.name }}</text>
+            <text class="portrait-dim-score">{{ dim.score }}</text>
+          </view>
+          <view class="portrait-dim-bar-track">
+            <view class="portrait-dim-bar-fill" :style="{ width: dim.score + '%', background: dim.color }"></view>
+          </view>
+          <text class="portrait-dim-desc">{{ dim.desc }}</text>
+        </view>
+      </view>
+      <view class="portrait-tip" v-if="bodyPortrait.tip">
+        <text class="portrait-tip-text">💡 {{ bodyPortrait.tip }}</text>
+      </view>
+    </view>
+
     <!-- 健康概览卡片:关键物理指标一眼看清 -->
     <view class="health-overview-card">
       <view class="overview-header">
@@ -990,6 +1017,89 @@ export default {
 .risk-normal .risk-level { color: #999; }
 
 /* ─── 月引导语 ─── */
+.dimension-portrait-section {
+  margin: 20rpx 30rpx;
+  background: #fff;
+  border-radius: 24rpx;
+  padding: 28rpx 24rpx;
+  box-shadow: 0 4rpx 20rpx rgba(255, 140, 66, 0.12);
+  border: 2rpx solid rgba(255, 140, 66, 0.1);
+}
+.portrait-tier {
+  font-size: 26rpx;
+  color: #FF8C42;
+  font-weight: bold;
+  margin-left: 16rpx;
+}
+.portrait-summary {
+  margin-bottom: 20rpx;
+}
+.portrait-desc {
+  font-size: 26rpx;
+  color: #666;
+  line-height: 1.6;
+  display: block;
+}
+.portrait-dimensions {
+  margin-bottom: 16rpx;
+}
+.portrait-dim-item {
+  margin-bottom: 16rpx;
+}
+.portrait-dim-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 8rpx;
+}
+.portrait-dim-icon {
+  width: 40rpx;
+  height: 40rpx;
+  border-radius: 20rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 12rpx;
+  font-size: 22rpx;
+}
+.portrait-dim-name {
+  font-size: 26rpx;
+  color: #333;
+  flex: 1;
+}
+.portrait-dim-score {
+  font-size: 28rpx;
+  font-weight: bold;
+  color: #FF8C42;
+  margin-right: 16rpx;
+}
+.portrait-dim-bar-track {
+  height: 12rpx;
+  background: #FFF0E4;
+  border-radius: 6rpx;
+  overflow: hidden;
+  margin-bottom: 6rpx;
+}
+.portrait-dim-bar-fill {
+  height: 100%;
+  border-radius: 6rpx;
+  transition: width 0.3s ease;
+}
+.portrait-dim-desc {
+  font-size: 22rpx;
+  color: #999;
+  display: block;
+}
+.portrait-tip {
+  padding: 16rpx 20rpx;
+  background: linear-gradient(135deg, #FFF7ED, #FFF0E4);
+  border-radius: 12rpx;
+  border-left: 4rpx solid #FF8C42;
+}
+.portrait-tip-text {
+  font-size: 24rpx;
+  color: #C2410C;
+  line-height: 1.5;
+}
 .monthly-guidance {
   display: flex;
   align-items: center;

+ 169 - 0
cfc-frontend/pages/mind-detail/index.vue

@@ -105,6 +105,33 @@
           </view>
         </view>
 
+<!-- 心维度画像 - 总体说明 -->
+        <view class="dimension-portrait-section" v-if="isLoggedIn && mindPortrait">
+          <view class="section-header">
+            <text class="section-title">🧭 心维度画像</text>
+            <text class="portrait-tier">{{ mindPortrait.tierLabel }}</text>
+          </view>
+          <view class="portrait-summary">
+            <text class="portrait-desc">{{ mindPortrait.summary }}</text>
+          </view>
+          <view class="portrait-dimensions">
+            <view class="portrait-dim-item" v-for="dim in mindPortrait.dims" :key="dim.code">
+              <view class="portrait-dim-header">
+                <view class="portrait-dim-icon" :style="{ background: dim.color }">{{ dim.icon }}</view>
+                <text class="portrait-dim-name">{{ dim.name }}</text>
+                <text class="portrait-dim-score">{{ dim.score }}</text>
+              </view>
+              <view class="portrait-dim-bar-track">
+                <view class="portrait-dim-bar-fill" :style="{ width: dim.score + '%', background: dim.color }"></view>
+              </view>
+              <text class="portrait-dim-desc">{{ dim.desc }}</text>
+            </view>
+          </view>
+          <view class="portrait-tip" v-if="mindPortrait.tip">
+            <text class="portrait-tip-text">💡 {{ mindPortrait.tip }}</text>
+          </view>
+        </view>
+
         <!-- 肠脑轴情绪卡片 -->
         <view class="section" v-if="gutIndicators && gutIndicators.length > 0">
           <view class="section-header">
@@ -504,6 +531,61 @@ var descList = descMap[this.dominantElement] || descMap.wood
         if (m && (m.memberId === targetId)) return m
       }
       return members[0] || null
+    },
+    mindPortrait: function() {
+      var self = this
+      if (!this.isLoggedIn || !this.emiData) return null
+      var e = this.emiData
+      var dims = [
+        { key: 'emotionStability', label: '情绪稳定性', color: '#FF6B9D', desc: '情绪识别与调控能力' },
+        { key: 'opennessScore', label: '开放性', color: '#6366F1', desc: '对新事物的接受程度' },
+        { key: 'conscientiousnessScore', label: '尽责性', color: '#F59E0B', desc: '做事有条理、自律程度' },
+        { key: 'extraversionScore', label: '外向性', color: '#10B981', desc: '社交活跃与外向程度' },
+        { key: 'agreeablenessScore', label: '宜人性', color: '#FF8C42', desc: '与人相处的和谐程度' },
+        { key: 'neuroticismScore', label: '神经质', color: '#8B5CF6', desc: '情绪波动程度(反向)' }
+      ]
+      var result = { overall: 0, tierLabel: '', summary: '', dims: [], tip: '' }
+      var total = 0
+      var count = 0
+      var dimList = []
+      for (var i = 0; i < dims.length; i++) {
+        var key = dims[i].key
+        var score = e[key] || 0
+        if (isNaN(score)) score = 0
+        score = Math.max(0, Math.min(100, Number(score)))
+        total += score
+        count++
+        var matched = dims.find(function(d) { return d.key === key })
+        dimList.push({
+          code: key,
+          name: matched ? matched.label : key,
+          score: Math.round(score),
+          color: matched ? matched.color : '#FF6B9D',
+          desc: matched ? matched.desc : ''
+        })
+      }
+      if (count === 0) return null
+      result.overall = Math.round(total / count)
+      result.dims = dimList
+      var o = result.overall
+      if (o >= 80) {
+        result.tierLabel = '心灵智者'
+        result.summary = '您的心理状态非常健康,情绪稳定、人格成熟且内心强大。'
+        result.tip = '保持内心平衡,可分享经验帮助家人共同成长'
+      } else if (o >= 60) {
+        result.tierLabel = '心灵进取者'
+        result.summary = '您的心理状态良好,具备较强的情绪调节能力和自我认知。'
+        result.tip = '关注情绪波动,练习正念冥想,持续提升心理韧性'
+      } else if (o >= 40) {
+        result.tierLabel = '心灵探索者'
+        result.summary = '您的心理状态正在建立基础,情绪管理有待加强。'
+        result.tip = '从每日情绪打卡开始,逐步建立情绪觉察习惯'
+      } else {
+        result.tierLabel = '心灵关怀者'
+        result.summary = '您可能正处于情绪波动期,需要更多关注与支持。'
+        result.tip = '建议寻求专业心理帮助,或向家人朋友倾诉'
+      }
+      return result
     }
   },
   onShow() {
@@ -2256,4 +2338,91 @@ var descList = descMap[this.dominantElement] || descMap.wood
   margin-bottom: 16rpx;
   padding-left: 10rpx;
 }
+
+/* 维度画像样式 */
+.dimension-portrait-section {
+  margin: 24rpx 30rpx;
+  background: #fff;
+  border-radius: 24rpx;
+  padding: 32rpx 24rpx;
+  box-shadow: 0 4rpx 20rpx rgba(255, 107, 157, 0.12);
+  border: 2rpx solid rgba(255, 107, 157, 0.1);
+}
+.portrait-tier {
+  font-size: 26rpx;
+  color: #FF6B9D;
+  font-weight: bold;
+  margin-left: 16rpx;
+}
+.portrait-summary {
+  margin-bottom: 24rpx;
+}
+.portrait-desc {
+  font-size: 26rpx;
+  color: #666;
+  line-height: 1.6;
+  display: block;
+}
+.portrait-dimensions {
+  margin-bottom: 20rpx;
+}
+.portrait-dim-item {
+  margin-bottom: 18rpx;
+}
+.portrait-dim-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 6rpx;
+}
+.portrait-dim-icon {
+  width: 36rpx;
+  height: 36rpx;
+  border-radius: 18rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 10rpx;
+  font-size: 20rpx;
+}
+.portrait-dim-name {
+  font-size: 24rpx;
+  color: #333;
+  flex: 1;
+}
+.portrait-dim-score {
+  font-size: 26rpx;
+  font-weight: bold;
+  color: #FF6B9D;
+  margin-right: 12rpx;
+}
+.portrait-dim-bar-track {
+  height: 10rpx;
+  background: #F0F6F7;
+  border-radius: 5rpx;
+  overflow: hidden;
+  margin-bottom: 4rpx;
+  flex: 1;
+}
+.portrait-dim-bar-fill {
+  height: 100%;
+  border-radius: 5rpx;
+  transition: width 0.3s ease;
+}
+.portrait-dim-desc {
+  font-size: 20rpx;
+  color: #999;
+  display: block;
+}
+.portrait-tip {
+  padding: 16rpx 20rpx;
+  background: linear-gradient(135deg, #FFF0F5, #FDF2F7);
+  border-radius: 12rpx;
+  border-left: 4rpx solid #FF6B9D;
+  margin-top: 16rpx;
+}
+.portrait-tip-text {
+  font-size: 22rpx;
+  color: #C2410C;
+  line-height: 1.5;
+}
 </style>

+ 161 - 1
cfc-frontend/pages/wealth/index.vue

@@ -139,6 +139,33 @@
         </view>
       </view>
 
+      <!-- 富维度画像 - 总体说明 -->
+      <view class="dimension-portrait-section" v-if="isLoggedIn && wealthPortrait">
+        <view class="section-header">
+          <text class="section-title">🧭 富维度画像</text>
+          <text class="portrait-tier">{{ wealthPortrait.tierLabel }}</text>
+        </view>
+        <view class="portrait-summary">
+          <text class="portrait-desc">{{ wealthPortrait.summary }}</text>
+        </view>
+        <view class="portrait-dimensions">
+          <view class="portrait-dim-item" v-for="dim in wealthPortrait.dims" :key="dim.code">
+            <view class="portrait-dim-header">
+              <view class="portrait-dim-icon" :style="{ background: dim.color }">{{ dim.icon }}</view>
+              <text class="portrait-dim-name">{{ dim.name }}</text>
+              <text class="portrait-dim-score">{{ dim.score }}</text>
+            </view>
+            <view class="portrait-dim-bar-track">
+              <view class="portrait-dim-bar-fill" :style="{ width: dim.score + '%', background: dim.color }"></view>
+            </view>
+            <text class="portrait-dim-desc">{{ dim.desc }}</text>
+          </view>
+        </view>
+        <view class="portrait-tip" v-if="wealthPortrait.tip">
+          <text class="portrait-tip-text">💡 {{ wealthPortrait.tip }}</text>
+        </view>
+      </view>
+
       <!-- 财富数据卡(家长) -->
       <view class="section" v-if="role === 'parent'">
         <view class="disc-card">
@@ -353,6 +380,52 @@ export default {
         if (s > 0 && s < 60) result.push({ label: d.label, score: s })
       }
       return result
+    },
+    wealthPortrait: function() {
+      var self = this
+      if (!this.isLoggedIn || !this.wealthSubDims || this.wealthSubDims.length === 0) return null
+      var dims = this.wealthSubDims
+      var colors = ['#F59E0B', '#FF8C42', '#6366F1', '#10B981']
+      var result = { overall: 0, tierLabel: '', summary: '', dims: [], tip: '' }
+      var total = 0
+      var count = 0
+      var dimList = []
+      for (var i = 0; i < dims.length; i++) {
+        var d = dims[i]
+        var score = Number(d.score) || 0
+        score = Math.max(0, Math.min(100, score))
+        total += score
+        count++
+        dimList.push({
+          code: 'wealth' + i,
+          name: d.label,
+          score: Math.round(score),
+          color: colors[i % colors.length],
+          desc: d.desc || ''
+        })
+      }
+      if (count === 0) return null
+      result.overall = Math.round(total / count)
+      result.dims = dimList
+      var o = result.overall
+      if (o >= 80) {
+        result.tierLabel = '财富掌舵者'
+        result.summary = '您的财富管理能力突出,能够很好地规划家庭财务,为家人创造稳定的财富基础。'
+        result.tip = '保持财富积累节奏,可探索更多元化的投资渠道'
+      } else if (o >= 60) {
+        result.tierLabel = '财富进取者'
+        result.summary = '您的财富管理处于良好水平,具备一定的财务规划能力。'
+        result.tip = '坚持记账与储蓄习惯,逐步扩大财富积累'
+      } else if (o >= 40) {
+        result.tierLabel = '财富探索者'
+        result.summary = '您的财富管理正在起步阶段,正在学习如何规划家庭财务。'
+        result.tip = '从记账开始,培养财务规划意识,为家庭建立储蓄习惯'
+      } else {
+        result.tierLabel = '财富启蒙者'
+        result.summary = '您的财富管理意识刚刚萌发,需要更多财务知识的积累。'
+        result.tip = '建议学习基础理财知识,从家庭收支记录开始'
+      }
+      return result
     }
   },
   onShow() {
@@ -1152,7 +1225,94 @@ export default {
   font-size: 22rpx;
   color: #F59E0B;
 }
-</style>
+
+/* 维度画像样式 */
+.dimension-portrait-section {
+  margin: 24rpx 30rpx;
+  background: #fff;
+  border-radius: 24rpx;
+  padding: 32rpx 24rpx;
+  box-shadow: 0 4rpx 20rpx rgba(245, 158, 11, 0.12);
+  border: 2rpx solid rgba(245, 158, 11, 0.1);
+}
+.portrait-tier {
+  font-size: 26rpx;
+  color: #F59E0B;
+  font-weight: bold;
+  margin-left: 16rpx;
+}
+.portrait-summary {
+  margin-bottom: 24rpx;
+}
+.portrait-desc {
+  font-size: 26rpx;
+  color: #666;
+  line-height: 1.6;
+  display: block;
+}
+.portrait-dimensions {
+  margin-bottom: 20rpx;
+}
+.portrait-dim-item {
+  margin-bottom: 18rpx;
+}
+.portrait-dim-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 6rpx;
+}
+.portrait-dim-icon {
+  width: 36rpx;
+  height: 36rpx;
+  border-radius: 18rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 10rpx;
+  font-size: 20rpx;
+  background: linear-gradient(135deg, #FFF7ED, #FFF3E8);
+}
+.portrait-dim-name {
+  font-size: 24rpx;
+  color: #333;
+  flex: 1;
+}
+.portrait-dim-score {
+  font-size: 26rpx;
+  font-weight: bold;
+  color: #F59E0B;
+  margin-right: 12rpx;
+}
+.portrait-dim-bar-track {
+  height: 10rpx;
+  background: #FFF7ED;
+  border-radius: 5rpx;
+  overflow: hidden;
+  margin-bottom: 4rpx;
+  flex: 1;
+}
+.portrait-dim-bar-fill {
+  height: 100%;
+  border-radius: 5rpx;
+  transition: width 0.3s ease;
+}
+.portrait-dim-desc {
+  font-size: 20rpx;
+  color: #666;
+  display: block;
+}
+.portrait-tip {
+  padding: 16rpx 20rpx;
+  background: linear-gradient(135deg, #FFF7ED, #FFF3E8);
+  border-radius: 12rpx;
+  border-left: 4rpx solid #F59E0B;
+  margin-top: 16rpx;
+}
+.portrait-tip-text {
+  font-size: 22rpx;
+  color: #C2410C;
+  line-height: 1.5;
+}
 
 /* 月度引导语 */
 .monthly-guidance {

+ 182 - 0
cfc-frontend/pages/wisdom-detail/index.vue

@@ -117,6 +117,33 @@
       </view>
     </view>
 
+    <!-- 心维度画像 - 总体说明 -->
+    <view class="dimension-portrait-section" v-if="isLoggedIn && wisdomPortrait">
+      <view class="section-header">
+        <text class="section-title">🧭 心维度画像</text>
+        <text class="portrait-tier">{{ wisdomPortrait.tierLabel }}</text>
+      </view>
+      <view class="portrait-summary">
+        <text class="portrait-desc">{{ wisdomPortrait.summary }}</text>
+      </view>
+      <view class="portrait-dimensions">
+        <view class="portrait-dim-item" v-for="dim in wisdomPortrait.dims" :key="dim.code">
+          <view class="portrait-dim-header">
+            <view class="portrait-dim-icon" :style="{ background: dim.color }">{{ dim.icon }}</view>
+            <text class="portrait-dim-name">{{ dim.name }}</text>
+            <text class="portrait-dim-score">{{ dim.score }}</text>
+          </view>
+          <view class="portrait-dim-bar-track">
+            <view class="portrait-dim-bar-fill" :style="{ width: dim.score + '%', background: dim.color }"></view>
+          </view>
+          <text class="portrait-dim-desc">{{ dim.desc }}</text>
+        </view>
+      </view>
+      <view class="portrait-tip" v-if="wisdomPortrait.tip">
+        <text class="portrait-tip-text">💡 {{ wisdomPortrait.tip }}</text>
+      </view>
+    </view>
+
     <!-- ===== DAN 报告(登录后) ===== -->
     <view class="section" v-if="isLoggedIn">
       <view class="section-header">
@@ -340,6 +367,74 @@ export default {
         '十二月:年度总结,规划来年学习'
       ]
       return messages[month] || messages[0]
+    },
+    wisdomPortrait: function() {
+      var self = this
+      if (!this.isLoggedIn || !this.cognitiveReport) return null
+      var cognitiveReport = this.cognitiveReport
+      var dims = [
+        { key: 'perceptionScore', label: '感知能力', color: '#FF6B9D', desc: '感官获取信息的能力' },
+        { key: 'focusScore', label: '专注力', color: '#F59E0B', desc: '保持注意力集中的能力' },
+        { key: 'memoryScore', label: '记忆力', color: '#6366F1', desc: '记忆和回忆信息的能力' },
+        { key: 'logicScore', label: '逻辑思维', color: '#10B981', desc: '分析和推理能力' },
+        { key: 'spatialScore', label: '空间思维', color: '#F59E0B', desc: '操作空间关系的能力' },
+        { key: 'processingSpeedScore', label: '加工速度', color: '#FF8C42', desc: '快速处理信息的能力' },
+        { key: 'growthMindset', label: '成长型思维', color: '#EC4899', desc: '相信能力可提升的信念' }
+      ]
+      var result = { overall: 0, tierLabel: '', summary: '', dims: [], tip: '' }
+      var total = 0
+      var count = 0
+      var dimList = []
+      for (var i = 0; i < dims.length; i++) {
+        var key = dims[i].key
+        var score = 0
+        if (key === 'growthMindset' && cognitiveReport.structuredAnalysis) {
+          try {
+            var analysis = JSON.parse(cognitiveReport.structuredAnalysis)
+            if (analysis && analysis.extra && analysis.extra.growthMindset) {
+              var gm = analysis.extra.growthMindset
+              var vals = Object.values(gm)
+              if (vals.length > 0) score = parseInt(vals[0]) || 0
+            }
+          } catch (e) { /* ignore parse error */ }
+        } else {
+          score = cognitiveReport[key] || 0
+        }
+        if (isNaN(score)) score = 0
+        score = Math.max(0, Math.min(100, Number(score)))
+        total += score
+        count++
+        var matched = dims.find(function(d) { return d.key === key })
+        dimList.push({
+          code: key,
+          name: matched ? matched.label : key,
+          score: Math.round(score),
+          color: matched ? matched.color : '#FF6B9D',
+          desc: matched ? matched.desc : ''
+        })
+      }
+      if (count === 0) return null
+      result.overall = Math.round(total / count)
+      result.dims = dimList
+      var o = result.overall
+      if (o >= 80) {
+        result.tierLabel = '认知卓越者'
+        result.summary = '您的认知能力卓越,各项能力均衡强劲,学习效率高。'
+        result.tip = '保持学习节奏,可进一步拓展更广的知识边界'
+      } else if (o >= 60) {
+        result.tierLabel = '认知进取者'
+        result.summary = '您的认知能力处于良好水平,具备较强的学习潜力。'
+        result.tip = '针对薄弱维度进行针对性训练,逐步突破瓶颈'
+      } else if (o >= 40) {
+        result.tierLabel = '认知探索者'
+        result.summary = '您的认知能力正在建立基础,关注学习习惯的养成很重要。'
+        result.tip = '从最容易提升的维度开始,每天投入少量学习时间'
+      } else {
+        result.tierLabel = '认知起步者'
+        result.summary = '您的认知能力需要更多关注和引导,建议从基础认能训练开始。'
+        result.tip = '建议咨询专业教育者,制定个性化认知发展计划'
+      }
+      return result
     }
   },
   onShow() {
@@ -1024,4 +1119,91 @@ export default {
   line-height: 1.6;
   margin: 0;
 }
+
+/* 维度画像样式 */
+.dimension-portrait-section {
+  margin: 24rpx 30rpx;
+  background: #fff;
+  border-radius: 24rpx;
+  padding: 32rpx 24rpx;
+  box-shadow: 0 4rpx 20rpx rgba(99, 102, 241, 0.12);
+  border: 2rpx solid rgba(99, 102, 241, 0.1);
+}
+.portrait-tier {
+  font-size: 26rpx;
+  color: #6366F1;
+  font-weight: bold;
+  margin-left: 16rpx;
+}
+.portrait-summary {
+  margin-bottom: 24rpx;
+}
+.portrait-desc {
+  font-size: 26rpx;
+  color: #666;
+  line-height: 1.6;
+  display: block;
+}
+.portrait-dimensions {
+  margin-bottom: 20rpx;
+}
+.portrait-dim-item {
+  margin-bottom: 18rpx;
+}
+.portrait-dim-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 6rpx;
+}
+.portrait-dim-icon {
+  width: 36rpx;
+  height: 36rpx;
+  border-radius: 18rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 10rpx;
+  font-size: 20rpx;
+}
+.portrait-dim-name {
+  font-size: 24rpx;
+  color: #333;
+  flex: 1;
+}
+.portrait-dim-score {
+  font-size: 26rpx;
+  font-weight: bold;
+  color: #6366F1;
+  margin-right: 12rpx;
+}
+.portrait-dim-bar-track {
+  height: 10rpx;
+  background: #F0F4FF;
+  border-radius: 5rpx;
+  overflow: hidden;
+  margin-bottom: 4rpx;
+  flex: 1;
+}
+.portrait-dim-bar-fill {
+  height: 100%;
+  border-radius: 5rpx;
+  transition: width 0.3s ease;
+}
+.portrait-dim-desc {
+  font-size: 20rpx;
+  color: #999;
+  display: block;
+}
+.portrait-tip {
+  padding: 16rpx 20rpx;
+  background: linear-gradient(135deg, #F0F4FF, #E8F1FE);
+  border-radius: 12rpx;
+  border-left: 4rpx solid #6366F1;
+  margin-top: 16rpx;
+}
+.portrait-tip-text {
+  font-size: 22rpx;
+  color: #1D1D1F;
+  line-height: 1.5;
+}
 </style>

+ 1 - 1
cfc-web/.last_build_commit

@@ -1 +1 @@
-367089ec209692e5c80abbe110e633ce4289324b
+d7a77e0b7e332b4671b35115358c2c5f4407c650

+ 2 - 2
cfc-web/package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "cfc-web",
-  "version": "1.0.1524",
+  "version": "1.0.1525",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "cfc-web",
-      "version": "1.0.1524",
+      "version": "1.0.1525",
       "dependencies": {
         "@wangeditor/editor": "^5.1.23",
         "@wangeditor/editor-for-vue": "^1.0.2",

+ 1 - 1
cfc-web/package.json

@@ -1,6 +1,6 @@
 {
   "name": "cfc-web",
-  "version": "1.0.1525",
+  "version": "1.0.1526",
   "private": true,
   "scripts": {
     "dev": "vue-cli-service serve",

+ 14 - 0
cfc-web/public/CHANGELOG-v1.0.md

@@ -4,6 +4,20 @@
 
 ---
 
+## v1.0.1526 (2026-10-06)
+
+### 新功能
+- beautify action-detail (行) page — enhanced visual design with scores, gradients & hierarchy
+
+### 其他
+- - Gradient accent bar on all sections (brand green #10B981)
+- - Unified section-title-wrap with green left border
+- - Score explanation: ≥80 good, ≥60 warn, <60 bad
+- - Header subtext merged into title-wrap for consistent layout
+- - Visual hierarchy improvements throughout
+- 
+
+
 ## v1.0.1525 (2026-10-06)
 
 ### 重构

+ 15 - 1
cfc-web/public/CHANGELOG.md

@@ -1,6 +1,6 @@
 # 更新日志
 
-> 当前版本: v1.0.1525
+> 当前版本: v1.0.1526
 
 ## 历史版本
 
@@ -8,6 +8,20 @@
 
 ---
 
+## v1.0.1526 (2026-10-06)
+
+### 新功能
+- beautify action-detail (行) page — enhanced visual design with scores, gradients & hierarchy
+
+### 其他
+- - Gradient accent bar on all sections (brand green #10B981)
+- - Unified section-title-wrap with green left border
+- - Score explanation: ≥80 good, ≥60 warn, <60 bad
+- - Header subtext merged into title-wrap for consistent layout
+- - Visual hierarchy improvements throughout
+- 
+
+
 ## v1.0.1525 (2026-10-06)
 
 ### 重构