|
@@ -89,32 +89,53 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- 功能入口网格(3列,与健康/成长页一致) -->
|
|
|
|
|
|
|
+ <!-- 快捷功能入口(单排) -->
|
|
|
<view class="section">
|
|
<view class="section">
|
|
|
- <view class="grid-3col">
|
|
|
|
|
- <view class="grid-item" @click="navTo('/pages/tasks/tasks')">
|
|
|
|
|
- <view class="grid-icon" style="background:rgba(99,102,241,0.15)"><text>📋</text></view>
|
|
|
|
|
- <text class="grid-label">任务</text>
|
|
|
|
|
|
|
+ <view class="quick-bar">
|
|
|
|
|
+ <view class="quick-item" @click="navTo('/pages/tasks/tasks')">
|
|
|
|
|
+ <view class="quick-icon" style="background:rgba(99,102,241,0.15)"><text>📋</text></view>
|
|
|
|
|
+ <text class="quick-label">任务</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="grid-item" @click="navTo('/pages/action-detail/interaction-log')">
|
|
|
|
|
- <view class="grid-icon" style="background:rgba(16,185,129,0.15)"><text>💬</text></view>
|
|
|
|
|
- <text class="grid-label">记录互动</text>
|
|
|
|
|
|
|
+ <view class="quick-item" @click="navTo('/pages/action-detail/interaction-log')">
|
|
|
|
|
+ <view class="quick-icon" style="background:rgba(16,185,129,0.15)"><text>💬</text></view>
|
|
|
|
|
+ <text class="quick-label">互动</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="grid-item" @click="navTo('/pages/mind-detail/family-dashboard')">
|
|
|
|
|
- <view class="grid-icon" style="background:rgba(139,92,246,0.15)"><text>🏠</text></view>
|
|
|
|
|
- <text class="grid-label">家庭天盘</text>
|
|
|
|
|
|
|
+ <view class="quick-item" @click="navTo('/pages/mind-detail/family-dashboard')">
|
|
|
|
|
+ <view class="quick-icon" style="background:rgba(139,92,246,0.15)"><text>🏠</text></view>
|
|
|
|
|
+ <text class="quick-label">天盘</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="grid-item" @click="navTo('/pages/profile-extra/family-members')">
|
|
|
|
|
- <view class="grid-icon" style="background:rgba(245,158,11,0.15)"><text>👨👩👧👦</text></view>
|
|
|
|
|
- <text class="grid-label">成员管理</text>
|
|
|
|
|
|
|
+ <view class="quick-item" @click="navTo('/pages/profile-extra/family-members')">
|
|
|
|
|
+ <view class="quick-icon" style="background:rgba(245,158,11,0.15)"><text>👨👩👧👦</text></view>
|
|
|
|
|
+ <text class="quick-label">成员</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="grid-item" @click="navTo('/pages/discover/circles')">
|
|
|
|
|
- <view class="grid-icon" style="background:rgba(255,107,157,0.15)"><text>🤝</text></view>
|
|
|
|
|
- <text class="grid-label">圈子</text>
|
|
|
|
|
|
|
+ <view class="quick-item" @click="navTo('/pages/discover/circles')">
|
|
|
|
|
+ <view class="quick-icon" style="background:rgba(255,107,157,0.15)"><text>🤝</text></view>
|
|
|
|
|
+ <text class="quick-label">圈子</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="grid-item" @click="navTo('/pages/shop/index/index')">
|
|
|
|
|
- <view class="grid-icon" style="background:rgba(249,115,22,0.15)"><text>🛒</text></view>
|
|
|
|
|
- <text class="grid-label">商城</text>
|
|
|
|
|
|
|
+ <view class="quick-item" @click="navTo('/pages/shop/index/index')">
|
|
|
|
|
+ <view class="quick-icon" style="background:rgba(249,115,22,0.15)"><text>🛒</text></view>
|
|
|
|
|
+ <text class="quick-label">商城</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 我的任务(仅当有待完成时显示) -->
|
|
|
|
|
+ <view v-if="hasPendingTasks" class="section">
|
|
|
|
|
+ <view class="section-header">
|
|
|
|
|
+ <text class="section-title">📝 我的任务</text>
|
|
|
|
|
+ <text class="section-more" @click="navTo('/pages/tasks/tasks')">全部 ›</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="task-quick-list">
|
|
|
|
|
+ <view
|
|
|
|
|
+ v-for="task in pendingTasks"
|
|
|
|
|
+ :key="task.id"
|
|
|
|
|
+ class="task-quick-item"
|
|
|
|
|
+ >
|
|
|
|
|
+ <view class="task-quick-info">
|
|
|
|
|
+ <text class="task-quick-title line-clamp-1">{{ task.title }}</text>
|
|
|
|
|
+ <text class="task-quick-meta">+{{ task.points }}分</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <button class="btn-quick-complete" @click="quickCompleteTask(task)">完成</button>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
@@ -138,19 +159,30 @@
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
<!-- 推荐文章 -->
|
|
<!-- 推荐文章 -->
|
|
|
- <ArticleBookshelf
|
|
|
|
|
- :articles="actionArticles"
|
|
|
|
|
- :isLoggedIn="true"
|
|
|
|
|
- @articleClick="goArticleDetail"
|
|
|
|
|
- @moreArticles="goMoreArticles" />
|
|
|
|
|
|
|
+ <view class="section">
|
|
|
|
|
+ <view class="section-header">
|
|
|
|
|
+ <text class="section-title">📖 推荐阅读</text>
|
|
|
|
|
+ <text class="section-more" @click="goMoreArticles">更多 ›</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <ArticleBookshelf
|
|
|
|
|
+ :articles="actionArticles"
|
|
|
|
|
+ :isLoggedIn="true"
|
|
|
|
|
+ @articleClick="goArticleDetail" />
|
|
|
|
|
+ </view>
|
|
|
|
|
|
|
|
<!-- 推荐商品 -->
|
|
<!-- 推荐商品 -->
|
|
|
- <DimensionProducts
|
|
|
|
|
- dimensionCode="action"
|
|
|
|
|
- :products="dimensionProducts"
|
|
|
|
|
- :isLoggedIn="true"
|
|
|
|
|
- @productClick="goProductDetail"
|
|
|
|
|
- @moreProducts="goMoreProducts" />
|
|
|
|
|
|
|
+ <view class="section">
|
|
|
|
|
+ <view class="section-header">
|
|
|
|
|
+ <text class="section-title">🛍️ 推荐商品</text>
|
|
|
|
|
+ <text class="section-more" @click="goMoreProducts">更多 ›</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <DimensionProducts
|
|
|
|
|
+ dimensionCode="action"
|
|
|
|
|
+ :products="dimensionProducts"
|
|
|
|
|
+ :isLoggedIn="true"
|
|
|
|
|
+ :showMore="false"
|
|
|
|
|
+ @productClick="goProductDetail" />
|
|
|
|
|
+ </view>
|
|
|
|
|
|
|
|
<!-- 底部占位 -->
|
|
<!-- 底部占位 -->
|
|
|
<view class="bottom-spacer" style="height: 40rpx;"></view>
|
|
<view class="bottom-spacer" style="height: 40rpx;"></view>
|
|
@@ -298,13 +330,11 @@
|
|
|
import store from '../../store/index.js'
|
|
import store from '../../store/index.js'
|
|
|
import WuxingSandbox from '../../components/wuxing-sandbox.vue'
|
|
import WuxingSandbox from '../../components/wuxing-sandbox.vue'
|
|
|
import PageBanner from '../../components/PageBanner.vue'
|
|
import PageBanner from '../../components/PageBanner.vue'
|
|
|
-import WuxingSandbox from '../../components/wuxing-sandbox.vue'
|
|
|
|
|
import FamilyMemberStrip from '../../components/FamilyMemberStrip.vue'
|
|
import FamilyMemberStrip from '../../components/FamilyMemberStrip.vue'
|
|
|
import DimensionProducts from '../../components/DimensionProducts.vue'
|
|
import DimensionProducts from '../../components/DimensionProducts.vue'
|
|
|
import ArticleBookshelf from '../../components/ArticleBookshelf.vue'
|
|
import ArticleBookshelf from '../../components/ArticleBookshelf.vue'
|
|
|
import FamilyChallengeCard from '../../components/FamilyChallengeCard.vue'
|
|
import FamilyChallengeCard from '../../components/FamilyChallengeCard.vue'
|
|
|
-import { acceptParentInvite, productList, getActivityList, getFeaturedArticles, getFamilyEnergySandbox, getVisibleFamilyMembers, getChildren, getProductsByDomain, getChallengeList, switchToFamilyMember, getMyMembership, updateChallengeProgress, respondChallenge } from '../../utils/api.js'
|
|
|
|
|
-import store from '../../store/index.js'
|
|
|
|
|
|
|
+import { acceptParentInvite, productList, getActivityList, getFeaturedArticles, getFamilyEnergySandbox, getVisibleFamilyMembers, getChildren, getProductsByDomain, getChallengeList, switchToFamilyMember, getMyMembership, updateChallengeProgress, respondChallenge, getTodayTasks, completeTask as completeTaskApi, getTodayParentTasks, completeParentTask as completeParentTaskApi } from '../../utils/api.js'
|
|
|
import config from '@/config.js'
|
|
import config from '@/config.js'
|
|
|
|
|
|
|
|
export default {
|
|
export default {
|
|
@@ -332,6 +362,7 @@ export default {
|
|
|
splashOverlay: _isFirstLaunch,
|
|
splashOverlay: _isFirstLaunch,
|
|
|
splashOverlayFading: false,
|
|
splashOverlayFading: false,
|
|
|
_splashReady: false,
|
|
_splashReady: false,
|
|
|
|
|
+ _watchPageReadyDone: false,
|
|
|
|
|
|
|
|
typeList: [
|
|
typeList: [
|
|
|
{ label: '全部', value: '' },
|
|
{ label: '全部', value: '' },
|
|
@@ -367,6 +398,7 @@ export default {
|
|
|
children: [],
|
|
children: [],
|
|
|
currentChildId: null,
|
|
currentChildId: null,
|
|
|
activeChallenges: [],
|
|
activeChallenges: [],
|
|
|
|
|
+ pendingTasks: [],
|
|
|
loggedInInitDone: false,
|
|
loggedInInitDone: false,
|
|
|
|
|
|
|
|
// 会员状态(沙盘下方会员入口使用)
|
|
// 会员状态(沙盘下方会员入口使用)
|
|
@@ -399,6 +431,9 @@ export default {
|
|
|
wealth: d.wealthScore || 0
|
|
wealth: d.wealthScore || 0
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
+ hasPendingTasks: function() {
|
|
|
|
|
+ return (this.pendingTasks && this.pendingTasks.length > 0)
|
|
|
|
|
+ },
|
|
|
actionArticles: function() {
|
|
actionArticles: function() {
|
|
|
if (!this.articles || this.articles.length === 0) return []
|
|
if (!this.articles || this.articles.length === 0) return []
|
|
|
var result = []
|
|
var result = []
|
|
@@ -500,6 +535,7 @@ export default {
|
|
|
self.loadDimensionData()
|
|
self.loadDimensionData()
|
|
|
}
|
|
}
|
|
|
self.childrenChecked = true
|
|
self.childrenChecked = true
|
|
|
|
|
+ self.loadTodayTasks()
|
|
|
}).catch(function(e) {
|
|
}).catch(function(e) {
|
|
|
console.log('获取孩子列表失败', e)
|
|
console.log('获取孩子列表失败', e)
|
|
|
self.childrenChecked = true
|
|
self.childrenChecked = true
|
|
@@ -523,10 +559,10 @@ export default {
|
|
|
},
|
|
},
|
|
|
loadActionProducts: function() {
|
|
loadActionProducts: function() {
|
|
|
var self = this
|
|
var self = this
|
|
|
- getProductsByDomain('action', 1, 4).then(function(res) {
|
|
|
|
|
|
|
+ getProductsByDomain('action', 1, 2).then(function(res) {
|
|
|
if (res && res.data) {
|
|
if (res && res.data) {
|
|
|
var list = Array.isArray(res.data) ? res.data : (res.data.records || [])
|
|
var list = Array.isArray(res.data) ? res.data : (res.data.records || [])
|
|
|
- self.dimensionProducts = list.slice(0, 4)
|
|
|
|
|
|
|
+ self.dimensionProducts = list.slice(0, 2)
|
|
|
}
|
|
}
|
|
|
}).catch(function() { self.dimensionProducts = [] })
|
|
}).catch(function() { self.dimensionProducts = [] })
|
|
|
},
|
|
},
|
|
@@ -570,6 +606,35 @@ export default {
|
|
|
self.activeChallenges = []
|
|
self.activeChallenges = []
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
|
|
+ loadTodayTasks: function() {
|
|
|
|
|
+ var self = this
|
|
|
|
|
+ if (!self.currentChildId) {
|
|
|
|
|
+ self.pendingTasks = []
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ getTodayTasks(self.currentChildId).then(function(res) {
|
|
|
|
|
+ if (res.code === 200 && Array.isArray(res.data)) {
|
|
|
|
|
+ self.pendingTasks = res.data.filter(function(t) {
|
|
|
|
|
+ return t.status === 'pending'
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(function() {
|
|
|
|
|
+ self.pendingTasks = []
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ quickCompleteTask: function(task) {
|
|
|
|
|
+ var self = this
|
|
|
|
|
+ completeTaskApi(task.id, self.currentChildId, '').then(function(res) {
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ uni.showToast({ title: '获得 ' + (res.data && res.data.pointsEarned || 0) + ' 积分', icon: 'success' })
|
|
|
|
|
+ self.loadTodayTasks()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ uni.showToast({ title: (res && res.message) || '完成失败', icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(function() {
|
|
|
|
|
+ uni.showToast({ title: '完成失败,请重试', icon: 'none' })
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
onChallengeCheckin: function(payload) {
|
|
onChallengeCheckin: function(payload) {
|
|
|
var self = this
|
|
var self = this
|
|
|
updateChallengeProgress({ challengeId: payload.challengeId, delta: 1 }).then(function(res) {
|
|
updateChallengeProgress({ challengeId: payload.challengeId, delta: 1 }).then(function(res) {
|
|
@@ -699,6 +764,14 @@ export default {
|
|
|
this.checkMemberStatus()
|
|
this.checkMemberStatus()
|
|
|
this._watchPageReady()
|
|
this._watchPageReady()
|
|
|
},
|
|
},
|
|
|
|
|
+ _watchPageReady() {
|
|
|
|
|
+ if (this._watchPageReadyDone) return
|
|
|
|
|
+ this._watchPageReadyDone = true
|
|
|
|
|
+ var that = this
|
|
|
|
|
+ that.$watch('_splashReady', function(newVal) {
|
|
|
|
|
+ if (newVal) that._tryHideSplash()
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
isLoggedIn() {
|
|
isLoggedIn() {
|
|
|
return !!uni.getStorageSync('token')
|
|
return !!uni.getStorageSync('token')
|
|
|
},
|
|
},
|
|
@@ -1417,43 +1490,101 @@ export default {
|
|
|
|
|
|
|
|
/* ---- 登录态内容布局 ---- */
|
|
/* ---- 登录态内容布局 ---- */
|
|
|
.logged-in-container {
|
|
.logged-in-container {
|
|
|
- padding-bottom: 40rpx;
|
|
|
|
|
|
|
+ padding-bottom: 120rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* ===== 功能入口网格(3列,对齐健康/成长页) ===== */
|
|
|
|
|
-.grid-3col {
|
|
|
|
|
|
|
+/* ===== 快捷功能入口(单排,6个横向排列) ===== */
|
|
|
|
|
+.quick-bar {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
- flex-wrap: wrap;
|
|
|
|
|
|
|
+ flex-direction: row;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
background: #fff;
|
|
background: #fff;
|
|
|
border-radius: 20rpx;
|
|
border-radius: 20rpx;
|
|
|
- padding: 8rpx 0;
|
|
|
|
|
|
|
+ padding: 20rpx 10rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.grid-item {
|
|
|
|
|
- width: 33.33%;
|
|
|
|
|
|
|
+.quick-item {
|
|
|
|
|
+ flex: 1;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
- padding: 20rpx 0;
|
|
|
|
|
|
|
+ gap: 6rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.grid-icon {
|
|
|
|
|
- width: 72rpx;
|
|
|
|
|
- height: 72rpx;
|
|
|
|
|
- border-radius: 18rpx;
|
|
|
|
|
|
|
+.quick-icon {
|
|
|
|
|
+ width: 64rpx;
|
|
|
|
|
+ height: 64rpx;
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
justify-content: center;
|
|
|
- margin-bottom: 8rpx;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.grid-icon text {
|
|
|
|
|
- font-size: 32rpx;
|
|
|
|
|
|
|
+.quick-icon text {
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.grid-item .grid-label {
|
|
|
|
|
- font-size: 24rpx;
|
|
|
|
|
|
|
+.quick-item .quick-label {
|
|
|
|
|
+ font-size: 22rpx;
|
|
|
color: #666;
|
|
color: #666;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/* ===== 我的任务快捷列表 ===== */
|
|
|
|
|
+.task-quick-list {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 12rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.task-quick-item {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: row;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
|
|
+ padding: 18rpx 24rpx;
|
|
|
|
|
+ box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.task-quick-info {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.task-quick-title {
|
|
|
|
|
+ font-size: 26rpx;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ line-height: 1.4;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.task-quick-meta {
|
|
|
|
|
+ font-size: 22rpx;
|
|
|
|
|
+ color: #F97316;
|
|
|
|
|
+ margin-top: 4rpx;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.btn-quick-complete {
|
|
|
|
|
+ margin-left: 16rpx;
|
|
|
|
|
+ padding: 8rpx 24rpx;
|
|
|
|
|
+ background: linear-gradient(135deg, #F97316, #FB923C);
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ border-radius: 20rpx;
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ line-height: 1;
|
|
|
|
|
+ height: 44rpx;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.btn-quick-complete::after {
|
|
|
|
|
+ border: none;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
</style>
|
|
</style>
|