|
@@ -1,5 +1,8 @@
|
|
|
<template>
|
|
<template>
|
|
|
<view class="container">
|
|
<view class="container">
|
|
|
|
|
+ <!-- Tabbar 切换过渡页 -->
|
|
|
|
|
+ <tab-transition v-if="showTabTransition" dimCode="action" waitingFor="action" />
|
|
|
|
|
+
|
|
|
<!-- 品牌头部 -->
|
|
<!-- 品牌头部 -->
|
|
|
<PageBanner theme="action"
|
|
<PageBanner theme="action"
|
|
|
tagline="知行合一 · 快乐成长"
|
|
tagline="知行合一 · 快乐成长"
|
|
@@ -117,6 +120,52 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
|
|
+ <!-- ===== 关系健康概览 ===== -->
|
|
|
|
|
+ <view class="rq-section" v-if="isLoggedIn && (healthAlerts.length > 0 || milestones.length > 0)">
|
|
|
|
|
+ <view class="rq-header">
|
|
|
|
|
+ <text class="rq-title">关系健康</text>
|
|
|
|
|
+ <text class="rq-more" @click="goRelationshipQuestionnaire">去做问卷</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <!-- 健康预警列表 -->
|
|
|
|
|
+ <view class="rq-alerts" v-if="healthAlerts.length > 0">
|
|
|
|
|
+ <view class="rq-alert-card" v-for="alert in healthAlerts" :key="alert.memberId" @click="goInteractionLog(alert.memberId)">
|
|
|
|
|
+ <view class="rq-alert-icon">
|
|
|
|
|
+ <text class="rq-alert-emoji">⚠️</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="rq-alert-info">
|
|
|
|
|
+ <text class="rq-alert-name">{{ alert.memberName }}</text>
|
|
|
|
|
+ <text class="rq-alert-desc">已{{ alert.daysSinceInteraction }}天无互动</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="rq-alert-action">
|
|
|
|
|
+ <text class="rq-alert-btn">去互动</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <!-- 里程碑列表 -->
|
|
|
|
|
+ <view class="rq-milestones" v-if="milestones.length > 0">
|
|
|
|
|
+ <view class="rq-milestone-card" v-for="m in milestones" :key="m.memberId">
|
|
|
|
|
+ <view class="rq-milestone-icon">
|
|
|
|
|
+ <text class="rq-milestone-emoji">🎂</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="rq-milestone-info">
|
|
|
|
|
+ <text class="rq-milestone-name">{{ m.memberName }}</text>
|
|
|
|
|
+ <text class="rq-milestone-desc">{{ m.daysUntil > 0 ? m.daysUntil + '天后生日' : '今天生日' }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <!-- 快捷操作 -->
|
|
|
|
|
+ <view class="rq-quick-actions">
|
|
|
|
|
+ <view class="rq-action-btn" @click="goInteractionLog()">
|
|
|
|
|
+ <text class="rq-action-icon">📝</text>
|
|
|
|
|
+ <text class="rq-action-label">记录互动</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="rq-action-btn" @click="goRelationshipQuestionnaire">
|
|
|
|
|
+ <text class="rq-action-icon">🤝</text>
|
|
|
|
|
+ <text class="rq-action-label">做关系问卷</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
<!-- 功能入口(4个:活动、商品、课程) -->
|
|
<!-- 功能入口(4个:活动、商品、课程) -->
|
|
|
<view class="func-section" v-if="sectionVisible('func_entries')">
|
|
<view class="func-section" v-if="sectionVisible('func_entries')">
|
|
|
<view class="func-grid">
|
|
<view class="func-grid">
|
|
@@ -141,6 +190,7 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
|
|
+import TabTransition from '../../components/tab-transition.vue'
|
|
|
import PageBanner from '../../components/PageBanner.vue'
|
|
import PageBanner from '../../components/PageBanner.vue'
|
|
|
import LoginGuideCard from '../../components/LoginGuideCard.vue'
|
|
import LoginGuideCard from '../../components/LoginGuideCard.vue'
|
|
|
import FamilyEnergyBar from '../../components/FamilyEnergyBar.vue'
|
|
import FamilyEnergyBar from '../../components/FamilyEnergyBar.vue'
|
|
@@ -151,12 +201,13 @@ import DimensionProducts from '../../components/DimensionProducts.vue'
|
|
|
import ContactCard from '../../components/ContactCard.vue'
|
|
import ContactCard from '../../components/ContactCard.vue'
|
|
|
import ContactImport from '../../components/ContactImport.vue'
|
|
import ContactImport from '../../components/ContactImport.vue'
|
|
|
import FamilyRelationGraph from '../../components/FamilyRelationGraph.vue'
|
|
import FamilyRelationGraph from '../../components/FamilyRelationGraph.vue'
|
|
|
-import { getVisibleSections, getEnergyOverview, getFamilyEnergySandbox, getTodayTasksByCategory, getActivityList, getProductsByDomain, getChildren, getContactList, getVisibleFamilyMembers, getFeaturedArticles } from '../../utils/api.js'
|
|
|
|
|
|
|
+import { getVisibleSections, getEnergyOverview, getFamilyEnergySandbox, getTodayTasksByCategory, getActivityList, getProductsByDomain, getChildren, getContactList, getVisibleFamilyMembers, getFeaturedArticles, getHealthAlerts, getMilestones } from '../../utils/api.js'
|
|
|
|
|
|
|
|
export default {
|
|
export default {
|
|
|
- components: { PageBanner, LoginGuideCard, FamilyEnergyBar, UserQuickEntry, DimensionTasks, DimensionActivities, DimensionProducts, ContactCard, ContactImport, FamilyRelationGraph },
|
|
|
|
|
|
|
+ components: { TabTransition, PageBanner, LoginGuideCard, FamilyEnergyBar, UserQuickEntry, DimensionTasks, DimensionActivities, DimensionProducts, ContactCard, ContactImport, FamilyRelationGraph },
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
|
|
|
+ showTabTransition: false,
|
|
|
isLoggedIn: false,
|
|
isLoggedIn: false,
|
|
|
role: null,
|
|
role: null,
|
|
|
currentChildId: null,
|
|
currentChildId: null,
|
|
@@ -173,6 +224,8 @@ export default {
|
|
|
articles: [],
|
|
articles: [],
|
|
|
contactList: [],
|
|
contactList: [],
|
|
|
showImportModal: false,
|
|
showImportModal: false,
|
|
|
|
|
+ healthAlerts: [],
|
|
|
|
|
+ milestones: [],
|
|
|
funcList: [
|
|
funcList: [
|
|
|
{ icon: '\u{1F3CB}', label: '任务', needLogin: true, page: '/pages/tasks/tasks' },
|
|
{ icon: '\u{1F3CB}', label: '任务', needLogin: true, page: '/pages/tasks/tasks' },
|
|
|
{ icon: '\u{1F3C0}', label: '活动', needLogin: false, page: '/pages/discover/index?type=activity' },
|
|
{ icon: '\u{1F3C0}', label: '活动', needLogin: false, page: '/pages/discover/index?type=activity' },
|
|
@@ -213,6 +266,8 @@ export default {
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
onShow() {
|
|
onShow() {
|
|
|
|
|
+ this.showTabTransition = true
|
|
|
|
|
+
|
|
|
var token = uni.getStorageSync('token')
|
|
var token = uni.getStorageSync('token')
|
|
|
this.isLoggedIn = !!token
|
|
this.isLoggedIn = !!token
|
|
|
if (this.isLoggedIn) {
|
|
if (this.isLoggedIn) {
|
|
@@ -222,8 +277,12 @@ export default {
|
|
|
}
|
|
}
|
|
|
this.loadSectionConfig()
|
|
this.loadSectionConfig()
|
|
|
if (this.isLoggedIn) {
|
|
if (this.isLoggedIn) {
|
|
|
- this.loadChildren()
|
|
|
|
|
|
|
+ var self = this
|
|
|
|
|
+ this.loadChildren().finally(function() {
|
|
|
|
|
+ uni.setStorageSync('actionReadyTime', Date.now())
|
|
|
|
|
+ })
|
|
|
this.loadFamilyMembersVisible()
|
|
this.loadFamilyMembersVisible()
|
|
|
|
|
+ this.loadRelationshipHealth()
|
|
|
}
|
|
}
|
|
|
// 游客也能浏览活动和商品
|
|
// 游客也能浏览活动和商品
|
|
|
this.loadDimensionActivities()
|
|
this.loadDimensionActivities()
|
|
@@ -456,6 +515,33 @@ export default {
|
|
|
},
|
|
},
|
|
|
goArticleDetail: function(id) {
|
|
goArticleDetail: function(id) {
|
|
|
uni.navigateTo({ url: '/pages/action/article-detail?id=' + id })
|
|
uni.navigateTo({ url: '/pages/action/article-detail?id=' + id })
|
|
|
|
|
+ },
|
|
|
|
|
+ loadRelationshipHealth: function() {
|
|
|
|
|
+ var self = this
|
|
|
|
|
+ getHealthAlerts({}).then(function(res) {
|
|
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
|
|
+ self.healthAlerts = Array.isArray(res.data) ? res.data : []
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(function() {
|
|
|
|
|
+ self.healthAlerts = []
|
|
|
|
|
+ })
|
|
|
|
|
+ getMilestones({}, 30).then(function(res) {
|
|
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
|
|
+ self.milestones = Array.isArray(res.data) ? res.data : []
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(function() {
|
|
|
|
|
+ self.milestones = []
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ goInteractionLog: function(memberId) {
|
|
|
|
|
+ if (memberId) {
|
|
|
|
|
+ uni.navigateTo({ url: '/pages/action/interaction-log?memberId=' + memberId })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ uni.navigateTo({ url: '/pages/action/interaction-log' })
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ goRelationshipQuestionnaire: function() {
|
|
|
|
|
+ uni.navigateTo({ url: '/pages/action/relationship-questionnaire' })
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -587,6 +673,156 @@ export default {
|
|
|
color: #ccc;
|
|
color: #ccc;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/* ===== 关系健康概览 ===== */
|
|
|
|
|
+.rq-section {
|
|
|
|
|
+ margin: 20rpx 20rpx 0;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ margin-bottom: 16rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-title {
|
|
|
|
|
+ font-size: 30rpx;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-more {
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ color: #F97316;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+}
|
|
|
|
|
+/* 健康预警卡片 */
|
|
|
|
|
+.rq-alerts {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 12rpx;
|
|
|
|
|
+ margin-bottom: 16rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-alert-card {
|
|
|
|
|
+ background: #FFF7ED;
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
|
|
+ padding: 20rpx;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 16rpx;
|
|
|
|
|
+ border: 1rpx solid #FED7AA;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-alert-card:active {
|
|
|
|
|
+ opacity: 0.8;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-alert-icon {
|
|
|
|
|
+ width: 64rpx;
|
|
|
|
|
+ height: 64rpx;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-alert-emoji {
|
|
|
|
|
+ font-size: 32rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-alert-info {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 4rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-alert-name {
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-alert-desc {
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ color: #F97316;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-alert-action {
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-alert-btn {
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ background: #F97316;
|
|
|
|
|
+ padding: 8rpx 20rpx;
|
|
|
|
|
+ border-radius: 20rpx;
|
|
|
|
|
+}
|
|
|
|
|
+/* 里程碑卡片 */
|
|
|
|
|
+.rq-milestones {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 12rpx;
|
|
|
|
|
+ margin-bottom: 16rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-milestone-card {
|
|
|
|
|
+ background: #F0F9FF;
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
|
|
+ padding: 20rpx;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 16rpx;
|
|
|
|
|
+ border: 1rpx solid #BAE6FD;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-milestone-icon {
|
|
|
|
|
+ width: 64rpx;
|
|
|
|
|
+ height: 64rpx;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-milestone-emoji {
|
|
|
|
|
+ font-size: 32rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-milestone-info {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 4rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-milestone-name {
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-milestone-desc {
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ color: #0EA5E9;
|
|
|
|
|
+}
|
|
|
|
|
+/* 快捷操作 */
|
|
|
|
|
+.rq-quick-actions {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 16rpx;
|
|
|
|
|
+ margin-top: 8rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-action-btn {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
|
|
+ padding: 20rpx;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ gap: 10rpx;
|
|
|
|
|
+ box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
|
|
|
|
|
+}
|
|
|
|
|
+.rq-action-btn:active {
|
|
|
|
|
+ opacity: 0.8;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-action-icon {
|
|
|
|
|
+ font-size: 36rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.rq-action-label {
|
|
|
|
|
+ font-size: 26rpx;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/* ===== 底部 ===== */
|
|
/* ===== 底部 ===== */
|
|
|
.bottom-spacer {
|
|
.bottom-spacer {
|
|
|
height: 20rpx;
|
|
height: 20rpx;
|