xiangqinxiaochengxu/miniprogram/pages/home/home.js
2026-04-17 21:28:56 +08:00

175 lines
5.6 KiB
JavaScript

const request = require('../../utils/request')
const { getCustomerServiceWechat } = require('../../utils/constants')
const HOME_CACHE_KEY = 'home_cache_v1'
const HOME_CACHE_TTL = 2 * 60 * 1000
Page({
data: {
activities: [],
announcements: [],
members: [],
heroAnnouncementText: '暂无公告',
heroAnnouncementId: null,
activeMember: null,
activeMemberTagsText: '',
featuredMembers: [],
customerServiceWechat: getCustomerServiceWechat(),
loadingHome: false
},
onShow() {
const app = getApp()
this.setData({ customerServiceWechat: app.globalData.customerServiceWechat || getCustomerServiceWechat() })
this.loadHomeData(true)
},
getCachedHomeData() {
const cache = wx.getStorageSync(HOME_CACHE_KEY)
if (!cache || !cache.ts || Date.now() - cache.ts > HOME_CACHE_TTL) {
return null
}
return cache.data || null
},
saveCachedHomeData(data) {
wx.setStorageSync(HOME_CACHE_KEY, { ts: Date.now(), data })
},
applyHomeData(homeData) {
const { activities = [], announcements = [], members = [] } = homeData || {}
const safeActivities = activities.slice(0, 5).map((item) => ({
...item,
id: item.id != null ? String(item.id) : '',
title: item.title || '未命名活动',
start_time: item.start_time || '时间待定',
cover_image: item.cover_image || '',
remainText: this.getRemainText(item)
}))
const safeAnnouncements = announcements.slice(0, 3).map((item) => ({
...item,
id: item.id != null ? String(item.id) : ''
}))
const safeMembers = members.slice(0, 6).map((item) => this.normalizeMember(item))
this.setData({
activities: safeActivities,
announcements: safeAnnouncements,
members: safeMembers,
featuredMembers: safeMembers.slice(0, 3),
heroAnnouncementText: safeAnnouncements.length ? safeAnnouncements[0].title : '暂无公告',
heroAnnouncementId: safeAnnouncements.length ? safeAnnouncements[0].id : null
})
},
async loadHomeData(silent = false) {
const cached = this.getCachedHomeData()
if (cached) {
this.applyHomeData(cached)
if (silent) {
return
}
}
if (this.data.loadingHome) {
return
}
this.setData({ loadingHome: true })
try {
const [activities, announcements, members] = await Promise.all([
request({ url: '/activities?status=1&page_size=5' }),
request({ url: '/announcements?page_size=3' }),
request({ url: '/matches/candidates?source=manual' })
])
const safeActivities = Array.isArray(activities) ? activities : []
const safeAnnouncements = Array.isArray(announcements) ? announcements : []
const safeMembers = Array.isArray(members) ? members : []
const nextData = {
activities: safeActivities.slice(0, 5),
announcements: safeAnnouncements,
members: safeMembers.slice(0, 6).map((item) => this.normalizeMember(item))
}
this.applyHomeData(nextData)
this.saveCachedHomeData(nextData)
} catch (err) {
console.error('Load home data failed:', err)
if (!cached) {
wx.showToast({ title: '首页内容加载失败', icon: 'none' })
}
} finally {
this.setData({ loadingHome: false })
}
},
normalizeMember(item) {
const member = item || {}
const personalityTags = Array.isArray(member.personality_tags) ? member.personality_tags : []
const userId = member.user_id ?? member.id ?? member.member_id
return {
...member,
user_id: userId != null ? String(userId) : '',
nicknameText: member.nickname || member.name || '匿名用户',
cityText: member.city || member.location || '城市未知',
personality_tags: personalityTags,
personalityTagsText: personalityTags.slice(0, 3).join(' / ') || '性格待完善',
introText: member.self_intro || member.intro || '对方还没有填写更多公开信息',
birthYearRangeText: member.birth_year_range || member.birth_year || '年龄未知',
avatar_blur_url: member.avatar_blur_url || member.avatar_url || ''
}
},
getRemainText(item) {
const maleRemain = Math.max((item.capacity_male || 0) - (item.registered_male || 0), 0)
const femaleRemain = Math.max((item.capacity_female || 0) - (item.registered_female || 0), 0)
return `还剩 ${maleRemain + femaleRemain} 个名额`
},
goActivityDetail(e) {
wx.navigateTo({ url: `/pages/activity-detail/activity-detail?id=${e.currentTarget.dataset.id}` })
},
goAnnouncement(e) {
wx.navigateTo({ url: '/pages/announcement/announcement' })
},
goHeroAnnouncement() {
wx.navigateTo({ url: '/pages/announcement/announcement' })
},
openMemberCard(e) {
const userId = e.currentTarget.dataset.id != null ? String(e.currentTarget.dataset.id) : ''
const activeMember = this.data.members.find((item) => String(item.user_id) === userId) || null
this.setData({
activeMember,
activeMemberTagsText: activeMember && Array.isArray(activeMember.personality_tags) ? activeMember.personality_tags.join(' / ') : ''
})
},
closeMemberCard() {
this.setData({ activeMember: null, activeMemberTagsText: '' })
},
noop() {},
goMatch() {
wx.switchTab({ url: '/pages/match/match' })
},
goActivity() {
wx.switchTab({ url: '/pages/activity/activity' })
},
goAnnouncementList() {
wx.navigateTo({ url: '/pages/announcement/announcement' })
},
goMessageBoard() {
wx.showModal({
title: '联系客服',
content: `客服微信号:${this.data.customerServiceWechat || '暂未设置'}`,
showCancel: false,
confirmText: '我知道了'
})
}
})