ai-c/pages/city-activities/city-activities.js
2026-02-02 18:21:32 +08:00

359 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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'
})
}
}
}
})