Browse Source

feat(cfc-frontend): 心首页关键信息卡片 — 家庭+个人双栏概览

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Xiaogang Liao 2 months ago
parent
commit
a3e7a34257
1 changed files with 278 additions and 3 deletions
  1. 278 3
      cfc-frontend/pages/mind/index.vue

+ 278 - 3
cfc-frontend/pages/mind/index.vue

@@ -188,9 +188,53 @@
         </view>
       </view>
 
-      <!-- 查看家庭天盘入口 -->
-      <view class="culture-card" style="text-align:center; padding:16rpx;" @click="onFuncClick({needLogin:true, page:'/pages/mind-detail/family-dashboard'})">
-        <text style="font-size:24rpx; color:#8B5CF6;">查看家庭天盘 &#x2192;</text>
+      <!-- 关键信息(家庭 + 个人) -->
+      <view class="key-info-card" v-if="compatibilityData || traditionalData">
+        <view class="key-info-header">
+          <text class="key-info-icon">&#x1F511;</text>
+          <text class="key-info-title">关键信息</text>
+        </view>
+        <view class="key-info-body">
+          <!-- 左侧:家庭概览 -->
+          <view class="key-info-col" v-if="compatibilityData">
+            <view class="ki-subtitle">家庭</view>
+            <view class="ki-row" v-if="familyWuxingLabel">
+              <text class="ki-label">主导五行</text>
+              <view class="ki-dot" :style="'background:' + familyWuxingLabel.color"></view>
+              <text class="ki-valued">{{ familyWuxingLabel.label }} {{ familyWuxingLabel.value }}%</text>
+            </view>
+            <view class="ki-row">
+              <text class="ki-label">成员</text>
+              <text class="ki-valued">{{ familyMemberCount }}人</text>
+            </view>
+          </view>
+          <!-- 右侧:个人速览 -->
+          <view class="key-info-col" v-if="traditionalData">
+            <view class="ki-subtitle">个人</view>
+            <view class="ki-row" v-if="luckyColorInfo">
+              <text class="ki-label">幸运色</text>
+              <view class="ki-swatch" :style="'background:' + luckyColorInfo.hex"></view>
+              <text class="ki-valued">{{ luckyColorInfo.name }}</text>
+            </view>
+            <view class="ki-row" v-if="luckyNumber">
+              <text class="ki-label">幸运数</text>
+              <text class="ki-num">{{ luckyNumber }}</text>
+            </view>
+            <view class="ki-row" v-if="dailyFortune">
+              <text class="ki-label">运势</text>
+              <text class="ki-fortune" :class="'ki-fortune-' + dailyFortune.level">{{ dailyFortune.text }}</text>
+            </view>
+          </view>
+        </view>
+        <!-- 本周提示 -->
+        <view class="ki-insight" v-if="familyWeeklyInsight">
+          <text class="ki-insight-icon">&#x1F4A1;</text>
+          <text class="ki-insight-text">{{ familyWeeklyInsight }}</text>
+        </view>
+        <!-- 查看详情 -->
+        <view class="ki-footer" @click="onFuncClick({needLogin:true, page:'/pages/mind-detail/family-dashboard'})">
+          <text>查看家庭天盘详细 &#x2192;</text>
+        </view>
       </view>
     </view>
 
@@ -413,6 +457,93 @@ export default {
     },
     funcListRow2: function() {
       return this.funcList.slice(4)
+    },
+    // ===== 关键信息 - 家庭 =====
+    familyWuxingLabel: function() {
+      if (!this.compatibilityData || !this.compatibilityData.familyWuxing || !this.compatibilityData.familyWuxing.aggregatePercentages) return null
+      var pcts = this.compatibilityData.familyWuxing.aggregatePercentages
+      var keys = ['wood', 'fire', 'earth', 'metal', 'water']
+      var maxKey = null
+      var maxVal = -1
+      for (var i = 0; i < keys.length; i++) {
+        if (pcts[keys[i]] !== undefined && pcts[keys[i]] > maxVal) {
+          maxVal = pcts[keys[i]]
+          maxKey = keys[i]
+        }
+      }
+      if (!maxKey) return null
+      return { key: maxKey, label: this.wuxingConfig[maxKey].label, color: this.wuxingConfig[maxKey].color, value: maxVal }
+    },
+    familyMemberCount: function() {
+      if (!this.compatibilityData || !this.compatibilityData.members) return 0
+      return this.compatibilityData.members.length
+    },
+    familyWeeklyInsight: function() {
+      if (!this.compatibilityData || !this.compatibilityData.weeklyInsight) return ''
+      return this.compatibilityData.weeklyInsight
+    },
+    // ===== 关键信息 - 个人 =====
+    dominantElement: function() {
+      if (!this.traditionalData || !this.traditionalData.wuxingElements) return null
+      var elements = this.traditionalData.wuxingElements
+      var keys = ['wood', 'fire', 'earth', 'metal', 'water']
+      var maxKey = null
+      var maxVal = -1
+      for (var i = 0; i < keys.length; i++) {
+        if (elements[keys[i]] !== undefined && elements[keys[i]] > maxVal) {
+          maxVal = elements[keys[i]]
+          maxKey = keys[i]
+        }
+      }
+      return maxKey
+    },
+    luckyColorInfo: function() {
+      var colorMap = {
+        wood: { name: '绿', hex: '#10B981' },
+        fire: { name: '红', hex: '#FF6B9D' },
+        earth: { name: '黄', hex: '#FF8C42' },
+        metal: { name: '白', hex: '#6366F1' },
+        water: { name: '蓝', hex: '#3B82F6' }
+      }
+      var elem = this.dominantElement
+      if (!elem) return null
+      return colorMap[elem] || null
+    },
+    luckyNumber: function() {
+      if (this.traditionalData && this.traditionalData.lifeNumber) {
+        return this.traditionalData.lifeNumber
+      }
+      var numMap = { wood: 3, fire: 9, earth: 5, metal: 7, water: 1 }
+      var elem = this.dominantElement
+      return elem ? numMap[elem] : null
+    },
+    fortuneSeed: function() {
+      if (this.traditionalData && this.traditionalData.lifeNumber) {
+        return String(this.traditionalData.lifeNumber)
+      }
+      return '0'
+    },
+    dailyFortune: function() {
+      if (!this.dominantElement) return null
+      var today = new Date()
+      var dateStr = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate()
+      var seedStr = dateStr + (this.fortuneSeed || '')
+      var hash = 0
+      for (var i = 0; i < seedStr.length; i++) {
+        hash = ((hash << 5) - hash) + seedStr.charCodeAt(i)
+        hash = hash & hash
+      }
+      var level = Math.abs(hash) % 5
+      var levels = ['大吉', '吉', '平', '凶', '大凶']
+      var descMap = {
+        wood: ['大吉:木气旺盛,宜规划', '吉:行动力强', '平:静心养性', '凶:谨言慎行', '大凶:忌冲动'],
+        fire: ['大吉:热情高涨', '吉:精力充沛', '平:适当休息', '凶:注意情绪', '大凶:静心冥想'],
+        earth: ['大吉:稳重踏实', '吉:贵人运佳', '平:按部就班', '凶:注意肠胃', '大凶:不宜投资'],
+        metal: ['大吉:决策力强', '吉:思维清晰', '平:保持专注', '凶:注意言辞', '大凶:不宜强求'],
+        water: ['大吉:灵感丰富', '吉:人际和谐', '平:安静内省', '凶:情绪波动', '大凶:宜藏不宜放']
+      }
+      var descList = descMap[this.dominantElement] || descMap.wood
+      return { level: level, text: levels[level], description: descList[level] }
     }
   },
   onShow() {
@@ -1430,4 +1561,148 @@ export default {
   background: #FEF3C7;
   color: #D97706;
 }
+
+/* ===== 关键信息(家庭+个人) ===== */
+.key-info-card {
+  background: #fff;
+  border-radius: 20rpx;
+  padding: 24rpx;
+  margin-top: 20rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
+}
+.key-info-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 20rpx;
+}
+.key-info-icon {
+  font-size: 28rpx;
+  margin-right: 8rpx;
+}
+.key-info-title {
+  font-size: 28rpx;
+  font-weight: 600;
+  color: #333;
+}
+.key-info-body {
+  display: flex;
+  flex-direction: row;
+  gap: 20rpx;
+}
+.key-info-col {
+  flex: 1;
+  background: #F8F9FA;
+  border-radius: 14rpx;
+  padding: 16rpx;
+  min-width: 0;
+}
+.ki-subtitle {
+  font-size: 22rpx;
+  color: #999;
+  margin-bottom: 12rpx;
+  font-weight: 500;
+}
+.ki-row {
+  display: flex;
+  align-items: center;
+  margin-bottom: 10rpx;
+  flex-wrap: nowrap;
+}
+.ki-row:last-child {
+  margin-bottom: 0;
+}
+.ki-label {
+  font-size: 22rpx;
+  color: #888;
+  margin-right: 8rpx;
+  white-space: nowrap;
+}
+.ki-dot {
+  width: 16rpx;
+  height: 16rpx;
+  border-radius: 50%;
+  margin-right: 6rpx;
+  flex-shrink: 0;
+}
+.ki-valuel {
+  font-size: 24rpx;
+  color: #333;
+  font-weight: 500;
+  white-space: nowrap;
+}
+.ki-valued {
+  font-size: 24rpx;
+  color: #333;
+  font-weight: 500;
+}
+.ki-swatch {
+  width: 28rpx;
+  height: 28rpx;
+  border-radius: 50%;
+  margin-right: 6rpx;
+  border: 2rpx solid rgba(0,0,0,0.06);
+  flex-shrink: 0;
+}
+.ki-num {
+  font-size: 30rpx;
+  font-weight: 700;
+  color: #FF6B9D;
+}
+.ki-fortune {
+  font-size: 24rpx;
+  font-weight: 700;
+  padding: 2rpx 12rpx;
+  border-radius: 10rpx;
+}
+.ki-fortune-0 {
+  color: #D32F2F;
+  background: #FFEBEE;
+}
+.ki-fortune-1 {
+  color: #E65100;
+  background: #FFF3E0;
+}
+.ki-fortune-2 {
+  color: #F9A825;
+  background: #FFFDE7;
+}
+.ki-fortune-3 {
+  color: #7B1FA2;
+  background: #F3E5F5;
+}
+.ki-fortune-4 {
+  color: #B71C1C;
+  background: #FFCDD2;
+}
+.ki-insight {
+  display: flex;
+  align-items: flex-start;
+  margin-top: 16rpx;
+  padding: 16rpx;
+  background: #FFF8F0;
+  border-radius: 12rpx;
+}
+.ki-insight-icon {
+  font-size: 24rpx;
+  margin-right: 8rpx;
+  flex-shrink: 0;
+}
+.ki-insight-text {
+  font-size: 22rpx;
+  color: #8B6914;
+  line-height: 1.5;
+}
+.ki-footer {
+  margin-top: 16rpx;
+  text-align: center;
+  padding: 12rpx;
+  font-size: 24rpx;
+  color: #8B5CF6;
+  font-weight: 500;
+  background: #F5F3FF;
+  border-radius: 12rpx;
+}
+.ki-footer:active {
+  opacity: 0.7;
+}
 </style>