|
@@ -456,6 +456,7 @@ import OnboardingGuide from '../../components/OnboardingGuide.vue'
|
|
|
import ConfigurableGuide from '../../components/ConfigurableGuide.vue'
|
|
import ConfigurableGuide from '../../components/ConfigurableGuide.vue'
|
|
|
import { acceptParentInvite, getActivityList, getFeaturedArticles, productList, getEnergySandbox, getEnergyOverview, getFamilyMemberList, getChallengeList, getGuideConfig, getGuidePopupList, consumeGuidePopup, switchToFamilyMember, getMyMembership, updateChallengeProgress, respondChallenge, getTodayTasks, completeTask as completeTaskApi, getTodayParentTasks, completeParentTask as completeParentTaskApi, getTaskHistory, getNotices, getNotificationList, readNotification, getSurveyStatus, getSelfCheckStatus, getReferralCode, extractReferralCode, getAppLibrary, reportAppEnter, getEnergyLogs, getPointsLogs, getCfList, getCfSummary } from '../../utils/api.js'
|
|
import { acceptParentInvite, getActivityList, getFeaturedArticles, productList, getEnergySandbox, getEnergyOverview, getFamilyMemberList, getChallengeList, getGuideConfig, getGuidePopupList, consumeGuidePopup, switchToFamilyMember, getMyMembership, updateChallengeProgress, respondChallenge, getTodayTasks, completeTask as completeTaskApi, getTodayParentTasks, completeParentTask as completeParentTaskApi, getTaskHistory, getNotices, getNotificationList, readNotification, getSurveyStatus, getSelfCheckStatus, getReferralCode, extractReferralCode, getAppLibrary, reportAppEnter, getEnergyLogs, getPointsLogs, getCfList, getCfSummary } from '../../utils/api.js'
|
|
|
import { findAppByKey, getShortcutableApps } from '../../utils/app-library.js'
|
|
import { findAppByKey, getShortcutableApps } from '../../utils/app-library.js'
|
|
|
|
|
+import { isActiveMember } from '../../utils/membershipGate.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'
|
|
@@ -595,6 +596,8 @@ membershipDays: 0,
|
|
|
// 首页快捷区(应用库自定义)
|
|
// 首页快捷区(应用库自定义)
|
|
|
quickApps: [],
|
|
quickApps: [],
|
|
|
myShortcuts: [],
|
|
myShortcuts: [],
|
|
|
|
|
+ // 会员有效态(isActive):控制 AI 管家入口可见性,默认 false(fail-closed)
|
|
|
|
|
+ memberActive: false,
|
|
|
appUsage: {},
|
|
appUsage: {},
|
|
|
quickLoaded: false,
|
|
quickLoaded: false,
|
|
|
|
|
|
|
@@ -845,6 +848,8 @@ membershipDays: 0,
|
|
|
this._doInit(options)
|
|
this._doInit(options)
|
|
|
},
|
|
},
|
|
|
onShow() {
|
|
onShow() {
|
|
|
|
|
+ // 每次进入前台刷新会员有效态(覆盖从升级/续费页返回),无 token 由封装内部短路
|
|
|
|
|
+ this.refreshMemberActive()
|
|
|
// splash overlay 已在 data() 中根据 storage 标记初始化,此处只需配置关闭条件
|
|
// splash overlay 已在 data() 中根据 storage 标记初始化,此处只需配置关闭条件
|
|
|
if (this.splashOverlay) {
|
|
if (this.splashOverlay) {
|
|
|
uni.removeStorageSync('_showSplashOverlay')
|
|
uni.removeStorageSync('_showSplashOverlay')
|
|
@@ -929,7 +934,11 @@ membershipDays: 0,
|
|
|
var remaining = 6 - lockedApps.length
|
|
var remaining = 6 - lockedApps.length
|
|
|
var lockedKeys = {}
|
|
var lockedKeys = {}
|
|
|
lockedApps.forEach(function(s) { lockedKeys[s.appKey] = true })
|
|
lockedApps.forEach(function(s) { lockedKeys[s.appKey] = true })
|
|
|
- var candidates = getShortcutableApps().filter(function(app) { return !lockedKeys[app.key] })
|
|
|
|
|
|
|
+ // 非有效会员:频度候选中剔除 AI 管家(key='ai'),避免其占位后被渲染
|
|
|
|
|
+ var selfActive = this.memberActive
|
|
|
|
|
+ var candidates = getShortcutableApps().filter(function(app) {
|
|
|
|
|
+ return !lockedKeys[app.key] && (app.key !== 'ai' || selfActive)
|
|
|
|
|
+ })
|
|
|
candidates.sort(function(a, b) {
|
|
candidates.sort(function(a, b) {
|
|
|
var ca = (usage && usage[a.key]) || 0
|
|
var ca = (usage && usage[a.key]) || 0
|
|
|
var cb = (usage && usage[b.key]) || 0
|
|
var cb = (usage && usage[b.key]) || 0
|
|
@@ -975,15 +984,33 @@ membershipDays: 0,
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
- self.quickApps = shown
|
|
|
|
|
|
|
+ // 合并结果出口再兜底过滤一次:连用户已锁定的 ai 项对非会员也不可见
|
|
|
|
|
+ self.quickApps = self.filterAiApps(shown)
|
|
|
self.quickLoaded = true
|
|
self.quickLoaded = true
|
|
|
}
|
|
}
|
|
|
}).catch(function() {
|
|
}).catch(function() {
|
|
|
// 接口失败:回退到默认 6 个
|
|
// 接口失败:回退到默认 6 个
|
|
|
- self.quickApps = self.getDefaultQuickApps()
|
|
|
|
|
|
|
+ self.quickApps = self.filterAiApps(self.getDefaultQuickApps())
|
|
|
self.quickLoaded = true
|
|
self.quickLoaded = true
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
|
|
+ // 会员有效态刷新:唯一判据 /api/ai/gate 的 data.isActive(不随运营开关,fail-closed)
|
|
|
|
|
+ refreshMemberActive: function() {
|
|
|
|
|
+ var self = this
|
|
|
|
|
+ isActiveMember().then(function(active) {
|
|
|
|
|
+ var changed = self.memberActive !== active
|
|
|
|
|
+ self.memberActive = active
|
|
|
|
|
+ // 频度候选依赖 memberActive,状态变化后按最新口径重算快捷区
|
|
|
|
|
+ if (changed && self.isLoggedIn()) {
|
|
|
|
|
+ self.loadQuickApps()
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ // 非有效会员剔除 AI 管家(key='ai');会员原样返回
|
|
|
|
|
+ filterAiApps: function(list) {
|
|
|
|
|
+ var active = this.memberActive
|
|
|
|
|
+ return (list || []).filter(function(app) { return app.key !== 'ai' || active })
|
|
|
|
|
+ },
|
|
|
onQuickTap: function(app) {
|
|
onQuickTap: function(app) {
|
|
|
if (!app || !app.route) return
|
|
if (!app || !app.route) return
|
|
|
// 记录进入次数(静默,失败不影响跳转)
|
|
// 记录进入次数(静默,失败不影响跳转)
|