// pages/index/index.js const app = getApp() const utils = require('../../lib/utils.js') Page({ data: { // 轮播图数据 banners: [], // 赛事列表 activities: [], // 加载状态 loading: true, // 是否还有更多数据 hasMore: true, // 当前页码 currentPage: 1, // 每页数量 pageSize: 10, // 搜索关键词 searchKeyword: '', // 筛选条件 filterStatus: 'all', // all, upcoming, ongoing, ended // 轮播图当前索引 currentBannerIndex: 0 }, onLoad(options) { console.log('首页加载') this.loadBanners() this.loadActivities() }, onShow() { console.log('首页显示') // 检查登录状态 if (!app.globalData.token) { app.login() } // 初始化自定义 tabbar if (typeof this.getTabBar === 'function' && this.getTabBar()) { this.getTabBar().init(); } }, onPullDownRefresh() { console.log('下拉刷新') this.refreshData() }, onReachBottom() { console.log('上拉加载更多') if (this.data.hasMore && !this.data.loading) { this.loadMoreActivities() } }, // 刷新数据 refreshData() { this.setData({ currentPage: 1, hasMore: true, activities: [] }) Promise.all([ this.loadBanners(), this.loadActivities() ]).finally(() => { wx.stopPullDownRefresh() }) }, // 加载轮播图 loadBanners() { return app.graphqlRequest(` query getBanners { banners: carouselPlayList { id title content coverImage { id name path fullUrl fullThumbUrl mediaType } images { id name path fullUrl fullThumbUrl mediaType } videos { id name path fullUrl fullThumbUrl mediaType } } } `).then(data => { if (data.banners) { // 处理轮播图数据,合并图片和视频 const processedBanners = data.banners.map(banner => { const mediaFiles = [] // 添加图片 if (banner.images && banner.images.length > 0) { banner.images.forEach(image => { mediaFiles.push({ ...image, type: 'image', url: image.fullUrl, thumbUrl: image.fullThumbUrl }) }) } // 添加视频 if (banner.videos && banner.videos.length > 0) { banner.videos.forEach(video => { mediaFiles.push({ ...video, type: 'video', url: video.fullUrl, thumbUrl: video.fullThumbUrl }) }) } // 如果没有媒体文件,使用封面图片 if (mediaFiles.length === 0 && banner.coverImage) { mediaFiles.push({ ...banner.coverImage, type: 'image', url: banner.coverImage.fullUrl, thumbUrl: banner.coverImage.fullThumbUrl }) } return { ...banner, mediaFiles } }) this.setData({ banners: processedBanners }) } }).catch(err => { console.error('加载轮播图失败:', err) }) }, // 加载赛事列表 loadActivities() { this.setData({ loading: true }) const { currentPage, pageSize, searchKeyword, filterStatus } = this.data // 名称搜索条件 const nameFilter = searchKeyword || "" return app.graphqlRequest(` query getActivities($page: Int!, $size: Int!, $name: String) { activities(page: $page, size: $size, name: $name) { content { id name description coverImage { id name path fullUrl fullThumbUrl mediaType } signupDeadline matchTime address playerMax state stateName playerCount } totalElements page size } } `, { page: currentPage, size: pageSize, name: nameFilter }).then(data => { if (data.activities) { let newActivities = data.activities.content // 为每个活动添加名称文字 newActivities = newActivities.map(activity => ({ ...activity, nameText: (activity.name || '活动').substring(0, 2) })) // 根据筛选状态过滤活动 if (filterStatus !== 'all') { newActivities = newActivities.filter(activity => activity.state === filterStatus) } // 合并数据 const mergedActivities = currentPage === 1 ? newActivities : [...this.data.activities, ...newActivities] this.setData({ activities: mergedActivities, hasMore: data.activities.totalElements > (currentPage * pageSize) && newActivities.length > 0, loading: false }) } }).catch(err => { console.error('加载赛事列表失败:', err) utils.showError('加载失败,请重试') this.setData({ loading: false }) }) }, // 加载更多赛事 loadMoreActivities() { this.setData({ currentPage: this.data.currentPage + 1 }) this.loadActivities() }, // 轮播图切换 onBannerChange(e) { this.setData({ currentBannerIndex: e.detail.current }) }, // 点击轮播图 onBannerTap(e) { const index = e.currentTarget.dataset.index const banner = this.data.banners[index] if (!banner) return // 检查是否有媒体文件 if (banner.mediaFiles && banner.mediaFiles.length > 0) { const firstMedia = banner.mediaFiles[0] if (firstMedia.type === 'video') { // 播放视频 wx.navigateTo({ url: `/pages/video/video?url=${encodeURIComponent(firstMedia.url)}&title=${encodeURIComponent(banner.title)}` }) } else if (firstMedia.type === 'image') { // 显示图片,如果有多个媒体文件,显示所有图片 const imageUrls = banner.mediaFiles .filter(media => media.type === 'image') .map(img => img.url) if (imageUrls.length > 0) { wx.previewImage({ urls: imageUrls, current: firstMedia.url }) } } } // 如果没有媒体文件,检查是否有封面图 else if (banner.coverImage && banner.coverImage.fullUrl) { wx.previewImage({ urls: [banner.coverImage.fullUrl], current: banner.coverImage.fullUrl }) } }, // 搜索输入 onSearchInput(e) { const keyword = e.detail.value this.setData({ searchKeyword: keyword }) // 防抖搜索 clearTimeout(this.searchTimer) this.searchTimer = setTimeout(() => { this.refreshData() }, 500) }, // 搜索提交 onSearchSubmit(e) { const keyword = e.detail.value this.setData({ searchKeyword: keyword }) this.refreshData() }, // 清空搜索 onSearchClear() { this.setData({ searchKeyword: '' }) this.refreshData() }, // 筛选状态切换 onFilterChange(e) { const status = e.currentTarget.dataset.status this.setData({ filterStatus: status }) this.refreshData() }, // 跳转到赛事详情 goToActivityDetail(activityId) { utils.navigateTo('/pages/activity/detail', { id: activityId }) }, // 点击赛事卡片 onActivityTap(e) { const index = e.currentTarget.dataset.index const activity = this.data.activities[index] if (activity) { this.goToActivityDetail(activity.id) } }, // 格式化日期 formatDate(date) { return utils.formatDate(date, 'MM-DD HH:mm') }, // 获取状态文本 getStatusText(state) { const statusMap = { 'DRAFT': '草稿', 'PUBLISHED': '已发布', 'SIGNUP': '报名中', 'SIGNUP_END': '报名结束', 'PLAYING': '进行中', 'ENDED': '已结束', 'CANCELLED': '已取消' } return statusMap[state] || state }, // 获取状态样式类 getStatusClass(state) { const classMap = { 'DRAFT': 'text-muted', 'PUBLISHED': 'text-primary', 'SIGNUP': 'text-success', // 报名中 'SIGNUP_END': 'text-warning', // 报名结束 'PLAYING': 'text-primary', // 进行中 'ENDED': 'text-muted', // 已结束 'CANCELLED': 'text-danger' // 已取消 } return classMap[state] || 'text-muted' }, // 计算报名进度 getRegistrationProgress(current, max) { if (!max || max <= 0) return 0 return Math.min((current / max) * 100, 100) }, // 判断是否可以报名 canRegister(activity) { const now = new Date() const signupDeadline = new Date(activity.signupDeadline) return now <= signupDeadline && activity.state === 'SIGNUP' && activity.playerCount < activity.playerMax } })