|
|
@@ -38,9 +38,46 @@
|
|
|
<FamilyChallengeCard
|
|
|
v-for="ch in activeChallenges"
|
|
|
:key="ch.id"
|
|
|
- :challenge="ch" />
|
|
|
+:challenge="ch" />
|
|
|
+
|
|
|
+ <!-- ===== 健康圈入口(P3:社区扩散) ===== -->
|
|
|
+ <view class="circle-entry-section">
|
|
|
+ <!-- 有健康圈数据:显示排行榜预览 -->
|
|
|
+ <PlayfulCard v-if="circleName && circleRankings.length > 0" variant="flat" shadow="sm" :clickable="true" @click="goToHealthCircle" class="circle-card-wide">
|
|
|
+ <view class="circle-card-content">
|
|
|
+ <view class="circle-header">
|
|
|
+ <view class="circle-icon-wrap">
|
|
|
+ <text class="circle-icon">🏅</text>
|
|
|
+ </view>
|
|
|
+ <view class="circle-header-body">
|
|
|
+ <text class="circle-card-title">健康圈</text>
|
|
|
+ <text class="circle-card-subtitle">{{ circleName }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="circle-ranking-preview">
|
|
|
+ <view class="circle-rank-row" v-for="(item, idx) in circleRankings.slice(0, 3)" :key="idx">
|
|
|
+ <text class="circle-rank-badge">{{ '🥇🥈🥉'[idx] || '#' + (idx + 1) }}</text>
|
|
|
+ <text class="circle-rank-family">家庭 {{ idx + 1 }}</text>
|
|
|
+ <text class="circle-rank-score">{{ item.totalScore || 0 }} 分</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="circle-action">
|
|
|
+ <text class="circle-action-text">查看详情 →</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </PlayfulCard>
|
|
|
+ <!-- 无健康圈数据:邀请加入 -->
|
|
|
+ <PlayfulCard v-else variant="flat" shadow="sm" :clickable="true" @click="goToHealthCircle" class="circle-card-wide circle-card-invite">
|
|
|
+ <view class="circle-invite-content">
|
|
|
+ <view class="circle-invite-icon">🏅</view>
|
|
|
+ <text class="circle-invite-title">健康圈</text>
|
|
|
+ <text class="circle-invite-desc">加入健康圈,和更多家庭一起健康打卡</text>
|
|
|
+ <text class="circle-invite-cta">去看看 →</text>
|
|
|
+ </view>
|
|
|
+ </PlayfulCard>
|
|
|
+ </view>
|
|
|
|
|
|
-<!-- ===== 家庭成员关系图谱 ===== -->
|
|
|
+ <!-- ===== 家庭成员关系图谱 ===== -->
|
|
|
<FamilyRelationGraph
|
|
|
v-if="familyMembersVisible.length > 0"
|
|
|
dimensionCode="home"
|
|
|
@@ -395,7 +432,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import { getFamilyMembers, getChildren, getPendingReviewTasks, getPendingWishes, approveTask, rejectTask, getChildCompletionStats, getParentDashboard, getFamilyEnergySandbox, getEnergyOverview, getVisibleFamilyMembers, getActivityList, getProductsByDomain, getContactList, getFeaturedArticles, getActiveAlerts, dismissAlert, getFamilyRanking, getChallengeList } from '../../utils/api.js'
|
|
|
+import { getFamilyMembers, getChildren, getPendingReviewTasks, getPendingWishes, approveTask, rejectTask, getChildCompletionStats, getParentDashboard, getFamilyEnergySandbox, getEnergyOverview, getVisibleFamilyMembers, getActivityList, getProductsByDomain, getContactList, getFeaturedArticles, getActiveAlerts, dismissAlert, getFamilyRanking, getChallengeList, getCircleRanking } from '../../utils/api.js'
|
|
|
import PageBanner from '../../components/PageBanner.vue'
|
|
|
import PlayfulCard from '../../components/PlayfulCard.vue'
|
|
|
import PlayfulButton from '../../components/PlayfulButton.vue'
|
|
|
@@ -415,10 +452,11 @@ import FeedbackToast from '../../components/FeedbackToast.vue'
|
|
|
import MilestoneCelebration from '../../components/MilestoneCelebration.vue'
|
|
|
import DailySummary from '../../components/DailySummary.vue'
|
|
|
import HealthAlertBanner from '../../components/HealthAlertBanner.vue'
|
|
|
+import CircleRanking from '../../components/CircleRanking.vue'
|
|
|
import feedbackEngine from '../../utils/feedback-engine.js'
|
|
|
|
|
|
export default {
|
|
|
- components: { PageBanner, RecommendedFeed, PlayfulCard, PlayfulButton, BaseBadge, BaseEmpty, BaseLoading, FamilyRelationGraph, WuxingSandbox, ContactCard, ContactImport, FamilyMemberStrip, MicroActionCard, FeedbackToast, MilestoneCelebration, DailySummary, HealthAlertBanner, FamilyHealthRanking, FamilyChallengeCard },
|
|
|
+ components: { PageBanner, RecommendedFeed, PlayfulCard, PlayfulButton, BaseBadge, BaseEmpty, BaseLoading, FamilyRelationGraph, WuxingSandbox, ContactCard, ContactImport, FamilyMemberStrip, MicroActionCard, FeedbackToast, MilestoneCelebration, DailySummary, HealthAlertBanner, FamilyHealthRanking, FamilyChallengeCard, CircleRanking },
|
|
|
data() {
|
|
|
return {
|
|
|
nickname: '',
|
|
|
@@ -483,7 +521,11 @@ export default {
|
|
|
// P2-2 家庭互动
|
|
|
rankingMembers: [],
|
|
|
rankingTotalScore: 0,
|
|
|
- activeChallenges: []
|
|
|
+ activeChallenges: [],
|
|
|
+ // P3 健康圈(社区扩散)
|
|
|
+ circleRankings: [],
|
|
|
+ circleName: '',
|
|
|
+ circleLoading: false
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
@@ -750,6 +792,8 @@ export default {
|
|
|
this.loadAlerts()
|
|
|
// 加载家庭健康互动(P2-2)
|
|
|
this.loadFamilyInteraction()
|
|
|
+ // 加载健康圈(P3:社区扩散)
|
|
|
+ this.loadHealthCircle()
|
|
|
// 加载外部联系人
|
|
|
this.loadContacts()
|
|
|
// 加载推荐阅读
|
|
|
@@ -867,6 +911,26 @@ export default {
|
|
|
}
|
|
|
}).catch(function() {})
|
|
|
},
|
|
|
+ loadHealthCircle: function() {
|
|
|
+ var familyId = this._familyId
|
|
|
+ if (!familyId) return
|
|
|
+ var self = this
|
|
|
+ self.circleLoading = true
|
|
|
+ getCircleRanking({ familyId: familyId }).then(function(res) {
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
+ self.circleName = res.data.circleName || ''
|
|
|
+ self.circleRankings = res.data.rankings || []
|
|
|
+ }
|
|
|
+ }).catch(function() {
|
|
|
+ self.circleRankings = []
|
|
|
+ self.circleName = ''
|
|
|
+ }).finally(function() {
|
|
|
+ self.circleLoading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ goToHealthCircle: function() {
|
|
|
+ uni.navigateTo({ url: '/pages/share/index' })
|
|
|
+ },
|
|
|
goMemberDetail(member) {
|
|
|
if (!member || !member.memberId) return
|
|
|
uni.navigateTo({
|
|
|
@@ -1566,4 +1630,122 @@ export default {
|
|
|
font-size: 22rpx;
|
|
|
color: #bbb;
|
|
|
}
|
|
|
+
|
|
|
+/* ===== 健康圈入口卡片(P3:社区扩散) ===== */
|
|
|
+.circle-entry-section {
|
|
|
+ margin: 0 20rpx 28rpx 20rpx;
|
|
|
+}
|
|
|
+.circle-card-wide {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+.circle-card-content {
|
|
|
+ padding: 24rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 16rpx;
|
|
|
+}
|
|
|
+.circle-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 12rpx;
|
|
|
+}
|
|
|
+.circle-icon-wrap {
|
|
|
+ width: 56rpx;
|
|
|
+ height: 56rpx;
|
|
|
+ border-radius: 14rpx;
|
|
|
+ background: linear-gradient(135deg, #10B981, #34D399);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+.circle-icon {
|
|
|
+ font-size: 28rpx;
|
|
|
+}
|
|
|
+.circle-header-body {
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+.circle-card-title {
|
|
|
+ display: block;
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: 700;
|
|
|
+ color: #1E293B;
|
|
|
+ line-height: 1.4;
|
|
|
+}
|
|
|
+.circle-card-subtitle {
|
|
|
+ display: block;
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #6B7280;
|
|
|
+ margin-top: 2rpx;
|
|
|
+}
|
|
|
+.circle-ranking-preview {
|
|
|
+ background: #F0FDF4;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ padding: 16rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 10rpx;
|
|
|
+}
|
|
|
+.circle-rank-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 10rpx;
|
|
|
+}
|
|
|
+.circle-rank-badge {
|
|
|
+ font-size: 24rpx;
|
|
|
+ width: 40rpx;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+.circle-rank-family {
|
|
|
+ flex: 1;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #374151;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+.circle-rank-score {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #F97316;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+.circle-action {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+}
|
|
|
+.circle-action-text {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #F97316;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+/* 无数据:邀请加入样式 */
|
|
|
+.circle-card-invite {
|
|
|
+ background: linear-gradient(135deg, #F0FDF4, #ECFDF5);
|
|
|
+}
|
|
|
+.circle-invite-content {
|
|
|
+ padding: 32rpx 24rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ gap: 12rpx;
|
|
|
+}
|
|
|
+.circle-invite-icon {
|
|
|
+ font-size: 48rpx;
|
|
|
+ margin-bottom: 4rpx;
|
|
|
+}
|
|
|
+.circle-invite-title {
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: 700;
|
|
|
+ color: #065F46;
|
|
|
+}
|
|
|
+.circle-invite-desc {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #6B7280;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 1.5;
|
|
|
+}
|
|
|
+.circle-invite-cta {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #F97316;
|
|
|
+ font-weight: 600;
|
|
|
+ margin-top: 4rpx;
|
|
|
+}
|
|
|
</style>
|