// pages/city-activities/city-activities.js - 同城活动页面 const api = require('../../utils/api') const app = getApp() Page({ data: { statusBarHeight: 44, navBarHeight: 44, totalNavHeight: 88, loading: false, // 选中的城市 selectedCity: '深圳市', // 活动列表 activityList: [], // 二维码弹窗 showQrcodeModal: false, qrcodeImageUrl: '' // 二维码图片URL,从后端获取 }, onLoad(options) { // 计算导航栏高度 const systemInfo = wx.getSystemInfoSync() const statusBarHeight = systemInfo.statusBarHeight || 44 const menuButton = wx.getMenuButtonBoundingClientRect() const navBarHeight = menuButton.height + (menuButton.top - statusBarHeight) * 2 const totalNavHeight = statusBarHeight + navBarHeight this.setData({ statusBarHeight, navBarHeight, totalNavHeight }) // 从文娱首页获取城市信息(通过全局数据或页面参数) const app = getApp() // 解码URL参数中的城市名称 let selectedCity = '深圳市' if (options.city) { selectedCity = decodeURIComponent(options.city) } else if (app.globalData.selectedCity) { selectedCity = app.globalData.selectedCity } console.log('[city-activities] 接收到的城市:', selectedCity) this.setData({ selectedCity }) this.loadActivityList() }, /** * 页面显示时检查城市是否变化 */ onShow() { const app = getApp() if (app.globalData.selectedCity && app.globalData.selectedCity !== this.data.selectedCity) { console.log('[city-activities] 城市已变更:', app.globalData.selectedCity) this.setData({ selectedCity: app.globalData.selectedCity }) this.loadActivityList() } }, /** * 返回上一页 */ onBack() { wx.navigateBack() }, /** * 加载活动列表 - 根据categoryName筛选同城活动 */ async loadActivityList() { this.setData({ loading: true }) try { const res = await api.activity.getList({ city: this.data.selectedCity, limit: 50 // 获取更多数据用于前端筛选 }) if (res.success && res.data && res.data.list) { // 前端筛选:只显示categoryName为"同城活动"的活动 const allActivities = res.data.list const cityActivities = allActivities.filter(item => item.categoryName === '同城活动') // 转换数据格式 const activityList = cityActivities.map(item => ({ id: item.id, title: item.title, date: this.formatDate(item.activityDate), location: item.location || '', venue: item.venue || '', image: item.coverImage || '/images/activity-default.jpg', heat: item.heat || 0, // 使用后端返回的热度字段 isFree: item.priceType === 'free', price: item.priceText || '', status: item.status || ((item.current_participants || item.currentParticipants || 0) >= (item.max_participants || item.maxParticipants || 0) && (item.max_participants || item.maxParticipants || 0) > 0 ? 'full' : 'upcoming'), activityGuideQrcode: item.activityGuideQrcode || item.activity_guide_qrcode || '' })) console.log('[city-activities] 同城活动加载成功,数量:', activityList.length) this.setData({ activityList }) } else { this.setData({ activityList: [] }) } } catch (err) { console.error('加载活动列表失败', err) wx.showToast({ title: '加载失败', icon: 'none' }) this.setData({ activityList: [] }) } finally { this.setData({ loading: false }) } }, /** * 加载模拟数据(降级方案) */ loadMockActivities() { // 使用空数据,等待后端API返回真实数据 const mockActivities = [] this.setData({ activityList: mockActivities }) }, /** * 格式化日期 */ formatDate(dateStr) { if (!dateStr) return '' const date = new Date(dateStr) const year = date.getFullYear() const month = String(date.getMonth() + 1).padStart(2, '0') const day = String(date.getDate()).padStart(2, '0') return `${year}年${month}月${day}日` }, /** * 选择城市 */ onCitySelect() { wx.navigateTo({ url: `/pages/city-selector/city-selector?current=${encodeURIComponent(this.data.selectedCity)}` }) }, /** * 加入同城群 */ onJoinCityGroup() { // TODO: 从后端获取二维码图片URL // 暂时使用占位图片 this.setData({ showQrcodeModal: true, qrcodeImageUrl: '/images/city-group-qrcode-placeholder.png' // 占位图片 }) }, /** * 关闭二维码弹窗 */ onCloseQrcodeModal() { this.setData({ showQrcodeModal: false }) }, /** * 保存二维码 */ onSaveQrcode() { const { qrcodeImageUrl } = this.data if (!qrcodeImageUrl) { wx.showToast({ title: '二维码加载中', icon: 'none' }) return } wx.showLoading({ title: '保存中...' }) // 下载图片到本地 wx.downloadFile({ url: qrcodeImageUrl, success: (res) => { if (res.statusCode === 200) { // 保存到相册 wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success: () => { wx.hideLoading() wx.showToast({ title: '已保存到相册', icon: 'success' }) this.onCloseQrcodeModal() }, fail: (err) => { wx.hideLoading() if (err.errMsg.includes('auth deny')) { wx.showModal({ title: '需要相册权限', content: '请在设置中允许访问相册', confirmText: '去设置', success: (modalRes) => { if (modalRes.confirm) { wx.openSetting() } } }) } else { wx.showToast({ title: '保存失败', icon: 'none' }) } } }) } else { wx.hideLoading() wx.showToast({ title: '下载失败', icon: 'none' }) } }, fail: () => { wx.hideLoading() wx.showToast({ title: '下载失败', icon: 'none' }) } }) }, /** * 点击活动卡片 */ onActivityTap(e) { const id = e.currentTarget.dataset.id wx.navigateTo({ url: `/pages/activity-detail/activity-detail?id=${id}` }) }, /** * 立即报名 */ onSignUp(e) { const id = e.currentTarget.dataset.id const index = e.currentTarget.dataset.index const activity = this.data.activityList[index] if (!app.globalData.isLoggedIn) { wx.navigateTo({ url: '/pages/login/login' }) return } // 检查活动状态 if (activity.status === 'full' || activity.status === 'ended') { const qrCode = activity.activityGuideQrcode || activity.activity_guide_qrcode || this.data.qrcodeImageUrl || 'https://ai-c.maimanji.com/api/common/qrcode?type=group' this.setData({ qrcodeImageUrl: qrCode, showQrcodeModal: true }) return } wx.showModal({ title: '确认报名', content: '确定要报名参加这个活动吗?', success: (res) => { if (res.confirm) { this.handleSignUp(id, index) } } }) }, /** * 处理报名 */ async handleSignUp(activityId, index) { try { wx.showLoading({ title: '报名中...' }) const res = await api.activity.signup(activityId) wx.hideLoading() if (res.success) { wx.showToast({ title: '报名成功', icon: 'success' }) // 刷新列表 this.loadActivityList() } else { // 检查是否需要显示二维码(后端开关关闭或活动已结束) if (res.code === 'QR_CODE_REQUIRED' || res.error === 'QR_CODE_REQUIRED' || res.code === 'ACTIVITY_ENDED' || res.error === '活动已结束' || res.code === 'ACTIVITY_FULL' || res.error === '活动已满员') { const activity = this.data.activityList[index] if (activity.activityGuideQrcode || activity.activity_guide_qrcode) { this.setData({ qrcodeImageUrl: activity.activityGuideQrcode || activity.activity_guide_qrcode }) } this.setData({ showQrcodeModal: true }) if (res.code === 'ACTIVITY_ENDED' || res.error === '活动已结束' || res.code === 'ACTIVITY_FULL' || res.error === '活动已满员') { const tip = (res.code === 'ACTIVITY_FULL' || res.error === '活动已满员') ? '活动已满员,进群查看更多' : '活动已结束,进群查看更多' wx.showToast({ title: tip, icon: 'none' }) } } else { wx.showToast({ title: res.error || '报名失败', icon: 'none' }) } } } catch (err) { wx.hideLoading() console.error('报名失败', err) // 捕获特定错误码以显示二维码 const isQrRequired = err && (err.code === 'QR_CODE_REQUIRED' || (err.data && err.data.code === 'QR_CODE_REQUIRED')) const isActivityEnded = err && (err.code === 'ACTIVITY_ENDED' || (err.data && err.data.code === 'ACTIVITY_ENDED') || err.error === '活动已结束') const isActivityFull = err && (err.code === 'ACTIVITY_FULL' || (err.data && err.data.code === 'ACTIVITY_FULL') || err.error === '活动已满员') if (isQrRequired || isActivityEnded || isActivityFull) { const activity = this.data.activityList[index] if (activity.activityGuideQrcode || activity.activity_guide_qrcode) { this.setData({ qrcodeImageUrl: activity.activityGuideQrcode || activity.activity_guide_qrcode }) } this.setData({ showQrcodeModal: true }) if (isActivityEnded || isActivityFull) { const tip = isActivityFull ? '活动已满员,进群查看更多' : '活动已结束,进群查看更多' wx.showToast({ title: tip, icon: 'none' }) } } else { wx.showToast({ title: err.error || err.message || '报名失败', icon: 'none' }) } } } })