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

feat(mind): FamilyRelationGraph升级compatibilityMap属性+mind首页入口路由更新

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Xiaogang Liao 4 месяцев назад
Родитель
Сommit
093021f1a3

+ 47 - 14
cfc-frontend/components/FamilyRelationGraph.vue

@@ -127,6 +127,10 @@ export default {
     interactive: {
       type: Boolean,
       default: true
+    },
+    compatibilityMap: {
+      type: Object,
+      default: function() { return {} }
     }
   },
   data: function() {
@@ -309,15 +313,30 @@ export default {
               var otherMember = self.otherMembers[j]
               if (!otherMember) continue
 
-              // 信任度 → 线颜色 (红0°→绿120°)
-              var trust = Math.max(0, Math.min(100, self.getIntimacy(otherMember.id, 'trust')))
-              var hue = (120 * trust / 100)
-              ctx.strokeStyle = 'hsl(' + hue + ', 75%, 45%)'
-              ctx.globalAlpha = 0.6
+              var selfId = self.selfMember && self.selfMember.id
+              var pairKey = ''
+              if (selfId) {
+                pairKey = selfId < otherMember.id ? selfId + '-' + otherMember.id : otherMember.id + '-' + selfId
+              }
+              var comp = self.compatibilityMap[pairKey]
+
+              if (comp && comp.overallScore !== undefined) {
+                // 先天兼容度 → 线颜色 (红0→绿120, 紫90)
+                var cScore = Math.max(0, Math.min(100, comp.overallScore))
+                ctx.strokeStyle = 'hsl(' + (120 * cScore / 100) + ', 70%, 50%)'
+                ctx.globalAlpha = 0.55
+                ctx.lineWidth = 3 + (cScore / 100) * 6
+              } else {
+                // 信任度 → 线颜色 (红0°→绿120°)
+                var trust = Math.max(0, Math.min(100, self.getIntimacy(otherMember.id, 'trust')))
+                var hue = (120 * trust / 100)
+                ctx.strokeStyle = 'hsl(' + hue + ', 75%, 45%)'
+                ctx.globalAlpha = 0.6
 
-              // 沟通度 → 线粗细 (2~10px)
-              var comm = Math.max(0, Math.min(100, self.getIntimacy(otherMember.id, 'communication')))
-              ctx.lineWidth = 2 + (comm / 100) * 8
+                // 沟通度 → 线粗细 (2~10px)
+                var comm = Math.max(0, Math.min(100, self.getIntimacy(otherMember.id, 'communication')))
+                ctx.lineWidth = 2 + (comm / 100) * 8
+              }
 
               // 边缘起止点:沿中心向量缩进半径
               var dx = otherCX - selfCX
@@ -351,13 +370,27 @@ export default {
         var otherMember = self.otherMembers[j]
         if (!otherMember) continue
 
-        var trust = Math.max(0, Math.min(100, self.getIntimacy(otherMember.id, 'trust')))
-        var hue = (120 * trust / 100)
-        ctx.setStrokeStyle('hsl(' + hue + ', 75%, 45%)')
-        ctx.globalAlpha = 0.6
+        var selfId = self.selfMember && self.selfMember.id
+        var pairKey = ''
+        if (selfId) {
+          pairKey = selfId < otherMember.id ? selfId + '-' + otherMember.id : otherMember.id + '-' + selfId
+        }
+        var comp = self.compatibilityMap[pairKey]
+
+        if (comp && comp.overallScore !== undefined) {
+          var cScore = Math.max(0, Math.min(100, comp.overallScore))
+          ctx.setStrokeStyle('hsl(' + (120 * cScore / 100) + ', 70%, 50%)')
+          ctx.globalAlpha = 0.55
+          ctx.setLineWidth(3 + (cScore / 100) * 6)
+        } else {
+          var trust = Math.max(0, Math.min(100, self.getIntimacy(otherMember.id, 'trust')))
+          var hue = (120 * trust / 100)
+          ctx.setStrokeStyle('hsl(' + hue + ', 75%, 45%)')
+          ctx.globalAlpha = 0.6
 
-        var comm = Math.max(0, Math.min(100, self.getIntimacy(otherMember.id, 'communication')))
-        ctx.setLineWidth(2 + (comm / 100) * 8)
+          var comm = Math.max(0, Math.min(100, self.getIntimacy(otherMember.id, 'communication')))
+          ctx.setLineWidth(2 + (comm / 100) * 8)
+        }
 
         var dx = otherCX - selfCX
         var dy = otherCY - selfCY

+ 8 - 0
cfc-frontend/pages.json

@@ -647,6 +647,14 @@
         {
           "path": "screening",
           "style": { "navigationBarTitleText": "心理状态自评" }
+        },
+        {
+          "path": "family-dashboard",
+          "style": { "navigationBarTitleText": "家庭天盘" }
+        },
+        {
+          "path": "duo-compatibility",
+          "style": { "navigationBarTitleText": "双人合盘" }
         }
       ]
     },

+ 44 - 5
cfc-frontend/pages/mind/index.vue

@@ -39,6 +39,7 @@
       :members="familyMembersVisible"
       :energyMap="energyMapForGraph"
       :intimacyMap="intimacyMapForGraph"
+      :compatibilityMap="compatibilityMapForGraph"
       @memberTap="goMemberDetail" />
 
     <!-- 登录后:用户快捷入口 -->
@@ -231,9 +232,9 @@
         </view>
       </view>
 
-      <!-- 查看完整传统文化入口 -->
-      <view class="culture-card" style="text-align:center; padding:16rpx;" @click="onFuncClick({needLogin:true, page:'/pages/mind/traditional-mirror'})">
-        <text style="font-size:24rpx; color:#8B5CF6;">查看完整解读 &#x2192;</text>
+      <!-- 查看家庭天盘入口 -->
+      <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>
     </view>
 
@@ -333,7 +334,7 @@ export default {
         { icon: '\u{2728}', label: '情绪打卡', needLogin: true, page: '/pages/mind-detail/emotion-checkin' },
         { icon: '\u{1F4C8}', label: '情绪趋势', needLogin: true, page: '/pages/mind-detail/emotion-trend' },
         { icon: '\u{1F9E9}', label: '心理自评', needLogin: true, page: '/pages/mind-detail/screening' },
-        { icon: '\u{2637}', label: '传统文化', needLogin: true, page: '/pages/mind-detail/traditional-mirror' },
+        { icon: '\u{1F3E0}', label: '家庭天盘', needLogin: true, page: '/pages/mind-detail/family-dashboard' },
         { icon: '\u{1F9D8}', label: '疏导工具', needLogin: true, page: '/pages/mind-detail/soothe-toolbox' }
       ],
       articles: [],
@@ -345,6 +346,7 @@ export default {
       // 传统文化数据
       traditionalData: null,
       traditionalLoading: true,
+      compatibilityData: null,
       wuxingConfig: {
         wood: { label: '木', color: '#10B981' },
         fire: { label: '火', color: '#FF6B9D' },
@@ -392,6 +394,17 @@ export default {
     intimacyMapForGraph: function() {
       return {}
     },
+    compatibilityMapForGraph: function() {
+      var map = {}
+      if (this.compatibilityData && this.compatibilityData.relationships) {
+        for (var i = 0; i < this.compatibilityData.relationships.length; i++) {
+          var r = this.compatibilityData.relationships[i]
+          var key = r.memberId1 < r.memberId2 ? r.memberId1 + '-' + r.memberId2 : r.memberId2 + '-' + r.memberId1
+          map[key] = { overallScore: r.overallScore }
+        }
+      }
+      return map
+    },
     emotionArticles: function() {
       if (!this.articles || this.articles.length === 0) return []
       var result = []
@@ -655,6 +668,9 @@ export default {
       this.loadDimensionTasks()
       this.loadDimensionActivities()
       this.loadDimensionProducts()
+      if (this.familyMembersVisible.length > 0) {
+        this.loadCompatibilityData()
+      }
     },
     loadSandboxData: function() {
       var self = this
@@ -727,6 +743,28 @@ export default {
         self.familyMembersVisible = []
       })
     },
+    loadCompatibilityData: function() {
+      var self = this
+      var familyId = uni.getStorageSync('currentFamilyId')
+      if (!familyId) {
+        var userInfo = uni.getStorageSync('userInfo')
+        if (userInfo && userInfo.familyId) familyId = userInfo.familyId
+      }
+      if (!familyId) return
+      var token = uni.getStorageSync('token')
+      uni.request({
+        url: config.API_BASE_URL + '/api/mind/traditional/family-dashboard',
+        method: 'POST',
+        header: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
+        data: { familyId: familyId },
+        success: function(res) {
+          if (res.data && res.data.code === 200 && res.data.data) {
+            self.compatibilityData = res.data.data
+          }
+        },
+        fail: function() {}
+      })
+    },
     scrollToSection: function(section) {
       uni.pageScrollTo({ selector: '#' + section, duration: 300 })
     },
@@ -750,8 +788,9 @@ export default {
     goTasks: function() { uni.switchTab({ url: '/pages/tasks/tasks' }) },
     goMemberDetail: function(member) {
       if (!member || !member.memberId) return
+      var currentId = this.currentChildId
       uni.navigateTo({
-        url: '/pages/mind-detail/member-mind-detail?childId=' + member.memberId
+        url: '/pages/mind-detail/duo-compatibility?memberId1=' + currentId + '&memberId2=' + member.memberId
       })
     },