|
@@ -244,6 +244,7 @@
|
|
|
<OnboardingGuide
|
|
<OnboardingGuide
|
|
|
:role="currentRole"
|
|
:role="currentRole"
|
|
|
:show="showOnboardingGuide"
|
|
:show="showOnboardingGuide"
|
|
|
|
|
+ position="home"
|
|
|
@close="closeOnboardingGuide" />
|
|
@close="closeOnboardingGuide" />
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
@@ -430,7 +431,7 @@ import DailyTaskCard from '../../components/daily-task-card.vue'
|
|
|
import ReportUploadCard from '../../components/report-upload-card.vue'
|
|
import ReportUploadCard from '../../components/report-upload-card.vue'
|
|
|
import OnboardingProgressBar from '../../components/OnboardingProgressBar.vue'
|
|
import OnboardingProgressBar from '../../components/OnboardingProgressBar.vue'
|
|
|
import OnboardingGuide from '../../components/OnboardingGuide.vue'
|
|
import OnboardingGuide from '../../components/OnboardingGuide.vue'
|
|
|
-import { acceptParentInvite, getActivityList, getFeaturedArticles, getEnergySandbox, getEnergyOverview, getFamilyMemberList, getChallengeList, switchToFamilyMember, getMyMembership, updateChallengeProgress, respondChallenge, getTodayTasks, completeTask as completeTaskApi, getTodayParentTasks, completeParentTask as completeParentTaskApi, getTaskHistory, getNotices, getNotificationList, getSurveyStatus, getSelfCheckStatus, getReferralCode, extractReferralCode } from '../../utils/api.js'
|
|
|
|
|
|
|
+import { acceptParentInvite, getActivityList, getFeaturedArticles, getEnergySandbox, getEnergyOverview, getFamilyMemberList, getChallengeList, getGuideConfig, switchToFamilyMember, getMyMembership, updateChallengeProgress, respondChallenge, getTodayTasks, completeTask as completeTaskApi, getTodayParentTasks, completeParentTask as completeParentTaskApi, getTaskHistory, getNotices, getNotificationList, getSurveyStatus, getSelfCheckStatus, getReferralCode, extractReferralCode } from '../../utils/api.js'
|
|
|
import nav from '../../utils/nav.js'
|
|
import nav from '../../utils/nav.js'
|
|
|
import config from '@/config.js'
|
|
import config from '@/config.js'
|
|
|
import { parseDate } from '../../utils/format.js'
|
|
import { parseDate } from '../../utils/format.js'
|
|
@@ -470,6 +471,7 @@ export default {
|
|
|
selfCheckScore: null,
|
|
selfCheckScore: null,
|
|
|
selfCheckLoading: false,
|
|
selfCheckLoading: false,
|
|
|
showOnboardingGuide: false,
|
|
showOnboardingGuide: false,
|
|
|
|
|
+ _onboardingGuideAttempted: false,
|
|
|
|
|
|
|
|
dimensionActivities: [],
|
|
dimensionActivities: [],
|
|
|
indexArticles: [],
|
|
indexArticles: [],
|
|
@@ -710,6 +712,11 @@ membershipDays: 0,
|
|
|
|
|
|
|
|
// 首次加载:onLoad 已触发 _doInit,此处跳过避免重复调用
|
|
// 首次加载:onLoad 已触发 _doInit,此处跳过避免重复调用
|
|
|
// 后续 onShow(切 Tab 返回):刷新易变数据(会员状态、今日任务、挑战列表)
|
|
// 后续 onShow(切 Tab 返回):刷新易变数据(会员状态、今日任务、挑战列表)
|
|
|
|
|
+ // 关键修复:在 onShow 中也检查 onboarding,兼容 switchTab 后未触发 onLoad 的情况
|
|
|
|
|
+ if (!this.showOnboardingGuide) {
|
|
|
|
|
+ this._maybeShowOnboardingGuide()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (this._onLoadFired) {
|
|
if (this._onLoadFired) {
|
|
|
this._onLoadFired = false // 清标记,后续 onShow 走刷新路径
|
|
this._onLoadFired = false // 清标记,后续 onShow 走刷新路径
|
|
|
} else {
|
|
} else {
|
|
@@ -1218,16 +1225,47 @@ membershipDays: 0,
|
|
|
if (newVal) that._tryHideSplash()
|
|
if (newVal) that._tryHideSplash()
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
- // 首次登录引导浮层:仅当从未看过(无 _onboardingDone 标记)时展示一次
|
|
|
|
|
|
|
+ // 首次登录引导浮层:异步拉取配置并按版本号判断是否展示
|
|
|
_maybeShowOnboardingGuide() {
|
|
_maybeShowOnboardingGuide() {
|
|
|
if (this.showOnboardingGuide) return
|
|
if (this.showOnboardingGuide) return
|
|
|
- if (uni.getStorageSync('_onboardingDone')) return
|
|
|
|
|
- // 延迟到 splash 蒙板关闭后再弹,避免层级冲突
|
|
|
|
|
|
|
+ if (this._onboardingGuideAttempted) return
|
|
|
|
|
+ this._onboardingGuideAttempted = true
|
|
|
var self = this
|
|
var self = this
|
|
|
- setTimeout(function() {
|
|
|
|
|
- if (!self.isLoggedIn()) return
|
|
|
|
|
- self.showOnboardingGuide = true
|
|
|
|
|
- }, 600)
|
|
|
|
|
|
|
+ getGuideConfig().then(function(res) {
|
|
|
|
|
+ var cfg = (res && res.data) ? res.data : null
|
|
|
|
|
+ var cfgVersion = cfg ? (cfg.version || '1.0') : '1.0'
|
|
|
|
|
+ // 检查启用
|
|
|
|
|
+ if (cfg && cfg.enabled === false) return
|
|
|
|
|
+ // 检查位置(index-home 对应 'home' 位置)
|
|
|
|
|
+ if (cfg && cfg.positions && cfg.positions.indexOf('home') === -1) return
|
|
|
|
|
+ // 比较版本
|
|
|
|
|
+ var stored = uni.getStorageSync('_onboardingDone')
|
|
|
|
|
+ var seenVersion = '0.0'
|
|
|
|
|
+ if (stored) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ var obj = typeof stored === 'string' ? JSON.parse(stored) : stored
|
|
|
|
|
+ if (obj && obj.version) seenVersion = obj.version
|
|
|
|
|
+ } catch (e) {}
|
|
|
|
|
+ }
|
|
|
|
|
+ if (self._compareVersion(seenVersion, cfgVersion) >= 0) return
|
|
|
|
|
+ setTimeout(function() {
|
|
|
|
|
+ if (!self.isLoggedIn()) return
|
|
|
|
|
+ self.showOnboardingGuide = true
|
|
|
|
|
+ }, 600)
|
|
|
|
|
+ }).catch(function() {
|
|
|
|
|
+ // 接口失败走旧逻辑
|
|
|
|
|
+ var stored = uni.getStorageSync('_onboardingDone')
|
|
|
|
|
+ if (stored) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ var obj = typeof stored === 'string' ? JSON.parse(stored) : stored
|
|
|
|
|
+ if (obj && obj.version && self._compareVersion(obj.version, '1.0') >= 0) return
|
|
|
|
|
+ } catch (e) {}
|
|
|
|
|
+ }
|
|
|
|
|
+ setTimeout(function() {
|
|
|
|
|
+ if (!self.isLoggedIn()) return
|
|
|
|
|
+ self.showOnboardingGuide = true
|
|
|
|
|
+ }, 600)
|
|
|
|
|
+ })
|
|
|
},
|
|
},
|
|
|
closeOnboardingGuide() {
|
|
closeOnboardingGuide() {
|
|
|
this.showOnboardingGuide = false
|
|
this.showOnboardingGuide = false
|
|
@@ -1235,6 +1273,17 @@ membershipDays: 0,
|
|
|
isLoggedIn() {
|
|
isLoggedIn() {
|
|
|
return !!uni.getStorageSync('token')
|
|
return !!uni.getStorageSync('token')
|
|
|
},
|
|
},
|
|
|
|
|
+ // 版本比较:返回 >0 表示 v1 > v2,0 相等,<0 表示 v1 < v2
|
|
|
|
|
+ _compareVersion: function(v1, v2) {
|
|
|
|
|
+ var parts1 = String(v1).split('.')
|
|
|
|
|
+ var parts2 = String(v2).split('.')
|
|
|
|
|
+ for (var i = 0; i < Math.max(parts1.length, parts2.length); i++) {
|
|
|
|
|
+ var n1 = parseInt(parts1[i] || '0', 10)
|
|
|
|
|
+ var n2 = parseInt(parts2[i] || '0', 10)
|
|
|
|
|
+ if (n1 !== n2) return n1 - n2
|
|
|
|
|
+ }
|
|
|
|
|
+ return 0
|
|
|
|
|
+ },
|
|
|
// ===== 会员状态(沙盘下方会员入口) =====
|
|
// ===== 会员状态(沙盘下方会员入口) =====
|
|
|
checkMemberStatus: function() {
|
|
checkMemberStatus: function() {
|
|
|
var that = this
|
|
var that = this
|