240 lines
8.1 KiB
TypeScript
240 lines
8.1 KiB
TypeScript
/**
|
||||
|
|
* 首页 - V1.1 新版(U18)
|
|||
|
|
* 结构:品牌区 → 用户状态条 → Banner → 8入口 → 推荐 → 服务建议 → 活动 → 服务站 → 安全提醒
|
|||
|
|
*/
|
|||
|
|
const authStore = require('../../stores/authStore')
|
|||
|
|
const api = require('../../utils/api')
|
|||
|
|
|
|||
|
|
Page({
|
|||
|
|
data: {
|
|||
|
|
unreadCount: 0,
|
|||
|
|
userState: null,
|
|||
|
|
isOnboarding: false,
|
|||
|
|
isVerified: false,
|
|||
|
|
isPaused: false,
|
|||
|
|
isSuccessful: false,
|
|||
|
|
onboardingMessage: '',
|
|||
|
|
onboardingActions: [],
|
|||
|
|
statusChecks: [],
|
|||
|
|
banners: [],
|
|||
|
|
currentBannerIndex: 0,
|
|||
|
|
quickEntries: [],
|
|||
|
|
recommendations: [],
|
|||
|
|
recState: 'idle',
|
|||
|
|
actionLoadingUserId: '',
|
|||
|
|
serviceRecommendations: [],
|
|||
|
|
activities: [],
|
|||
|
|
serviceLocation: null,
|
|||
|
|
articles: [],
|
|||
|
|
safetyNotice: {
|
|||
|
|
text: '实名认证和人工审核可以提高信息真实性,交往过程中仍请谨慎涉及借款、投资和个人隐私。',
|
|||
|
|
ctaText: '查看婚恋反诈指南',
|
|||
|
|
ctaTarget: ''
|
|||
|
|
},
|
|||
|
|
emptyActions: [
|
|||
|
|
{ text: '查看择偶条件', event: 'preference', variant: 'secondary' },
|
|||
|
|
{ text: '申请公益红娘', event: 'matchmaker', variant: 'primary' },
|
|||
|
|
],
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onLoad() {
|
|||
|
|
this.checkAuthAndLoad()
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onShow() {
|
|||
|
|
if (authStore.state.isLoggedIn) {
|
|||
|
|
this.loadHomeData()
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onPullDownRefresh() {
|
|||
|
|
this.loadHomeData().finally(() => wx.stopPullDownRefresh())
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ==================== 核心加载 ====================
|
|||
|
|
|
|||
|
|
async checkAuthAndLoad() {
|
|||
|
|
if (!authStore.state.isLoggedIn) {
|
|||
|
|
this.setData({
|
|||
|
|
isOnboarding: true,
|
|||
|
|
onboardingMessage: '登录后即可开始寻找合适的人',
|
|||
|
|
onboardingActions: [{ text: '去登录', event: 'login', variant: 'primary' }],
|
|||
|
|
})
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
await this.loadHomeData()
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
async loadHomeData() {
|
|||
|
|
try {
|
|||
|
|
const res = await api.get('/home')
|
|||
|
|
this.processHomeData(res)
|
|||
|
|
} catch (err) {
|
|||
|
|
console.error('首页数据加载失败', err)
|
|||
|
|
this.setData({ recState: 'error' })
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
processHomeData(data) {
|
|||
|
|
const { userState, banners, quickEntries, recommendations,
|
|||
|
|
serviceRecommendations, activities, serviceLocation, safetyNotice } = data
|
|||
|
|
|
|||
|
|
const relStatus = userState?.relationshipStatus || ''
|
|||
|
|
const profileStatus = userState?.profileStatus || ''
|
|||
|
|
const eligStatus = userState?.localEligibilityStatus || 'not_declared'
|
|||
|
|
|
|||
|
|
const isOnboarding = !userState || profileStatus !== 'approved'
|
|||
|
|
const isPaused = relStatus === 'paused'
|
|||
|
|
const isSuccessful = relStatus === 'matched_successfully'
|
|||
|
|
const isVerified = eligStatus === 'verified'
|
|||
|
|
|
|||
|
|
const checks = [
|
|||
|
|
{ label: '已实名', done: userState?.verified || false },
|
|||
|
|
{ label: '本地资格', done: eligStatus === 'verified' || eligStatus === 'pending_review' },
|
|||
|
|
{ label: '资料已审核', done: profileStatus === 'approved' || profileStatus === 'completed' },
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
userState,
|
|||
|
|
isOnboarding, isVerified, isPaused, isSuccessful,
|
|||
|
|
onboardingMessage: this.buildOnboardingMessage(userState, profileStatus, eligStatus),
|
|||
|
|
onboardingActions: this.buildOnboardingActions(userState, profileStatus, eligStatus),
|
|||
|
|
statusChecks: checks,
|
|||
|
|
banners, quickEntries,
|
|||
|
|
recommendations: recommendations || [],
|
|||
|
|
recState: (recommendations && recommendations.length > 0) ? 'loaded' : 'empty',
|
|||
|
|
serviceRecommendations, activities, serviceLocation,
|
|||
|
|
safetyNotice: safetyNotice || this.data.safetyNotice,
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
buildOnboardingMessage(state, profileStatus, eligStatus) {
|
|||
|
|
if (!state) return '登录后即可开始寻找合适的人'
|
|||
|
|
if (eligStatus === 'not_declared') return '完成本地资格声明后即可开始寻找合适的人'
|
|||
|
|
if (eligStatus === 'needs_evidence') return '补充本地资格佐证后即可开始寻找合适的人'
|
|||
|
|
if (profileStatus !== 'approved' && profileStatus !== 'completed') return '资料审核通过后即可开始寻找合适的人'
|
|||
|
|
return '完成资料后开始寻找合适的人'
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
buildOnboardingActions(state, profileStatus, eligStatus) {
|
|||
|
|
if (!state) return [{ text: '去登录', event: 'login', variant: 'primary' }]
|
|||
|
|
const actions = []
|
|||
|
|
if (eligStatus === 'not_declared' || eligStatus === 'needs_evidence') {
|
|||
|
|
actions.push({ text: '声明本地资格', event: 'local-eligibility', variant: 'primary' })
|
|||
|
|
}
|
|||
|
|
if (profileStatus !== 'approved' && profileStatus !== 'completed') {
|
|||
|
|
actions.push({ text: '完善资料', event: 'profile', variant: 'secondary' })
|
|||
|
|
}
|
|||
|
|
if (actions.length === 0) {
|
|||
|
|
actions.push({ text: '开始寻找', event: 'discover', variant: 'primary' })
|
|||
|
|
}
|
|||
|
|
return actions
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ==================== 事件处理 ====================
|
|||
|
|
|
|||
|
|
onBannerChange(e) {
|
|||
|
|
this.setData({ currentBannerIndex: e.detail.current })
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onBannerTap(e) {
|
|||
|
|
const { targetType, targetValue } = e.currentTarget.dataset.item
|
|||
|
|
if (targetType === 'activity' && targetValue) {
|
|||
|
|
wx.navigateTo({ url: `/pages/activity-detail/activity-detail?id=${targetValue}` })
|
|||
|
|
} else if (targetType === 'matchmaker') {
|
|||
|
|
wx.navigateTo({ url: '/pages/matchmaker/matchmaker' })
|
|||
|
|
} else if (targetType === 'service_location' && targetValue) {
|
|||
|
|
wx.navigateTo({ url: `/pages/local-eligibility/local-eligibility?from=service_station&id=${targetValue}` })
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onEntryTap(e) {
|
|||
|
|
const { code, enabled, targetPage } = e.currentTarget.dataset.entry
|
|||
|
|
if (!enabled) {
|
|||
|
|
wx.showToast({ title: '完成资料后可使用此功能', icon: 'none' })
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
if (targetPage.startsWith('pages/')) {
|
|||
|
|
wx.navigateTo({ url: targetPage })
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onViewDetail(e) {
|
|||
|
|
const userId = e.detail?.userId || e.currentTarget.dataset?.userId
|
|||
|
|
if (userId) wx.navigateTo({ url: `/pages/profile-detail/profile-detail?id=${userId}` })
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onLike(e) {
|
|||
|
|
const userId = e.detail?.userId
|
|||
|
|
if (!userId) return
|
|||
|
|
this.setData({ actionLoadingUserId: userId })
|
|||
|
|
setTimeout(() => this.setData({ actionLoadingUserId: '' }), 500)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onPass(e) {
|
|||
|
|
const userId = e.detail?.userId
|
|||
|
|
if (!userId) return
|
|||
|
|
this.setData({ actionLoadingUserId: userId })
|
|||
|
|
setTimeout(() => this.setData({ actionLoadingUserId: '' }), 500)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onEmptyAction(e) {
|
|||
|
|
const event = e.currentTarget.dataset.event
|
|||
|
|
switch (event) {
|
|||
|
|
case 'login':
|
|||
|
|
wx.reLaunch({ url: '/pages/login/login' })
|
|||
|
|
break
|
|||
|
|
case 'discover':
|
|||
|
|
wx.switchTab({ url: '/pages/discover/discover' })
|
|||
|
|
break
|
|||
|
|
case 'matchmaker':
|
|||
|
|
wx.navigateTo({ url: '/pages/matchmaker/matchmaker' })
|
|||
|
|
break
|
|||
|
|
case 'preference':
|
|||
|
|
wx.navigateTo({ url: '/pages/profile-preference/profile-preference' })
|
|||
|
|
break
|
|||
|
|
case 'local-eligibility':
|
|||
|
|
wx.navigateTo({ url: '/pages/local-eligibility/local-eligibility' })
|
|||
|
|
break
|
|||
|
|
case 'profile':
|
|||
|
|
wx.navigateTo({ url: '/pages/profile-basic/profile-basic' })
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onResume() {
|
|||
|
|
wx.showToast({ title: '功能开发中', icon: 'none' })
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onSeeMore() { wx.switchTab({ url: '/pages/discover/discover' }) },
|
|||
|
|
onSeeAllActivities() { wx.switchTab({ url: '/pages/activity/activity' }) },
|
|||
|
|
onActivityTap(e) {
|
|||
|
|
const id = e.currentTarget.dataset.id
|
|||
|
|
if (id) wx.navigateTo({ url: `/pages/activity-detail/activity-detail?id=${id}` })
|
|||
|
|
},
|
|||
|
|
onStationTap() {
|
|||
|
|
wx.navigateTo({ url: '/pages/local-eligibility/local-eligibility?from=service_station' })
|
|||
|
|
},
|
|||
|
|
onServiceTap(e) {
|
|||
|
|
const type = e.currentTarget.dataset.type
|
|||
|
|
switch (type) {
|
|||
|
|
case 'matchmaker': wx.navigateTo({ url: '/pages/matchmaker/matchmaker' })
|
|||
|
|
break
|
|||
|
|
case 'counseling':
|
|||
|
|
case 'premarital':
|
|||
|
|
wx.navigateTo({ url: `/pages/local-eligibility/local-eligibility?from=${type}` })
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
onSafetyTap() {
|
|||
|
|
wx.navigateTo({ url: '/pages/local-eligibility/local-eligibility?from=anti_fraud' })
|
|||
|
|
},
|
|||
|
|
onMessages() { wx.switchTab({ url: '/pages/messages/messages' }) },
|
|||
|
|
|
|||
|
|
formatDate(timestamp) {
|
|||
|
|
if (!timestamp) return ''
|
|||
|
|
const d = new Date(timestamp)
|
|||
|
|
return `${d.getMonth() + 1}月${d.getDate()}日 ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`
|
|||
|
|
},
|
|||
|
|
})
|