diff --git a/api/activity/README.md b/api/activity/README.md new file mode 100644 index 0000000..4a2cfa4 --- /dev/null +++ b/api/activity/README.md @@ -0,0 +1,251 @@ +# 活动API文档 + +## 概述 + +活动API提供了寺庙活动相关的所有接口,包括活动列表、详情、报名等功能。 + +## 接口列表 + +### 1. 获取活动列表 + +**接口地址:** `GET /app/activitie/list` + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| templeId | string | 否 | 寺庙ID | +| status | string | 否 | 活动状态 | +| pageNum | number | 否 | 页码,默认1 | +| pageSize | number | 否 | 每页数量,默认20 | + +**响应示例:** + +```json +{ + "msg": "操作成功", + "code": 200, + "data": [ + { + "id": "1", + "templeId": "12", + "title": "初一祈福", + "imgUrl": "https://api.ccttiot.com/image.jpg", + "content": "活动主题: 初一祈福,诸事圆满,心生欢喜", + "actStartTime": "2025-08-13 00:00:00", + "actEndTime": "2025-09-16 00:00:00", + "status": "1", + "address": "福建省宁德市福鼎市太姥山镇", + "phone": "13800138000", + "attendance": 100, + "readNum": 500, + "type": "1", + "currentBooking": 50 + } + ] +} +``` + +### 2. 获取活动详情 + +**接口地址:** `GET /app/activitie/detail/{id}` + +**路径参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| id | string | 是 | 活动ID | + +**响应示例:** + +```json +{ + "msg": "操作成功", + "code": 200, + "data": { + "id": "1", + "templeId": "12", + "title": "初一祈福", + "imgUrl": "https://api.ccttiot.com/image.jpg", + "content": "活动详细内容...", + "actStartTime": "2025-08-13 00:00:00", + "actEndTime": "2025-09-16 00:00:00", + "status": "1", + "address": "福建省宁德市福鼎市太姥山镇", + "phone": "13800138000", + "attendance": 100, + "readNum": 500, + "type": "1", + "currentBooking": 50 + } +} +``` + +### 3. 报名活动 + +**接口地址:** `POST /app/activitie/register` + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| activityId | string | 是 | 活动ID | +| userId | string | 是 | 用户ID | +| userName | string | 是 | 用户姓名 | +| phone | string | 是 | 联系电话 | + +**响应示例:** + +```json +{ + "msg": "报名成功", + "code": 200, + "data": { + "registrationId": "123", + "activityId": "1", + "userId": "456", + "status": "success" + } +} +``` + +### 4. 取消报名 + +**接口地址:** `POST /app/activitie/cancel/{id}` + +**路径参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| id | string | 是 | 报名记录ID | + +**响应示例:** + +```json +{ + "msg": "取消成功", + "code": 200, + "data": null +} +``` + +### 5. 获取我的报名记录 + +**接口地址:** `GET /app/activitie/my-registrations` + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| pageNum | number | 否 | 页码,默认1 | +| pageSize | number | 否 | 每页数量,默认20 | + +**响应示例:** + +```json +{ + "msg": "操作成功", + "code": 200, + "data": [ + { + "id": "123", + "activityId": "1", + "activityTitle": "初一祈福", + "registrationTime": "2025-08-10 10:00:00", + "status": "confirmed" + } + ] +} +``` + +## 数据字段说明 + +### 活动状态 (status) + +| 值 | 说明 | +|----|------| +| "0" | 已结束 | +| "1" | 报名中 | +| "2" | 进行中 | +| "3" | 已结束 | + +### 活动类型 (type) + +| 值 | 说明 | +|----|------| +| "1" | 祈福活动 | +| "2" | 法会活动 | +| "3" | 禅修活动 | +| "4" | 捐赠活动 | +| "5" | 义工活动 | + +## 使用示例 + +```javascript +import activityApi from '@/api/activity/activity.js' + +// 获取活动列表 +const getActivities = async () => { + try { + const response = await activityApi.getActivityList({ + pageNum: 1, + pageSize: 20 + }) + + if (response.code === 200) { + console.log('活动列表:', response.data) + } + } catch (error) { + console.error('获取活动列表失败:', error) + } +} + +// 报名活动 +const registerActivity = async (activityId, userInfo) => { + try { + const response = await activityApi.registerActivity({ + activityId, + userId: userInfo.id, + userName: userInfo.userName, + phone: userInfo.phone + }) + + if (response.code === 200) { + console.log('报名成功') + } + } catch (error) { + console.error('报名失败:', error) + } +} +``` + +## 错误处理 + +所有接口都会返回统一的错误格式: + +```json +{ + "msg": "错误信息", + "code": 错误码, + "data": null +} +``` + +常见错误码: + +| 错误码 | 说明 | +|--------|------| +| 200 | 成功 | +| 400 | 请求参数错误 | +| 401 | 未授权,需要登录 | +| 403 | 权限不足 | +| 404 | 资源不存在 | +| 500 | 服务器内部错误 | + +## 注意事项 + +1. 所有接口都需要在请求头中携带有效的token(除了登录相关接口) +2. 活动列表支持分页查询,建议每页不超过50条 +3. 报名活动前需要确保用户已登录 +4. 活动状态会根据时间自动更新 +5. 图片URL为完整路径,可直接使用 \ No newline at end of file diff --git a/api/activity/activity.js b/api/activity/activity.js new file mode 100644 index 0000000..d72af2e --- /dev/null +++ b/api/activity/activity.js @@ -0,0 +1,79 @@ +import request from '../../utils/request' + +// 活动相关API +export default { + /** + * 获取活动列表 + * @param {Object} params - 查询参数 + * @param {string} params.templeId - 寺庙ID + * @param {string} params.status - 活动状态 + * @param {number} params.pageNum - 页码 + * @param {number} params.pageSize - 每页数量 + * @returns {Promise} 活动列表数据 + */ + getActivityList(params = {}) { + return request({ + url: '/app/activitie/list', + method: 'GET', + params: { + pageNum: 1, + pageSize: 20, + ...params + } + }) + }, + + /** + * 获取活动详情 + * @param {string} id - 活动ID + * @returns {Promise} 活动详情数据 + */ + getActivityDetail(id) { + return request({ + url: `/app/activitie/detail/${id}`, + method: 'GET' + }) + }, + + /** + * 报名活动 + * @param {Object} data - 报名数据 + * @param {string} data.activityId - 活动ID + * @param {string} data.userId - 用户ID + * @param {string} data.userName - 用户姓名 + * @param {string} data.phone - 联系电话 + * @returns {Promise} 报名结果 + */ + registerActivity(data) { + return request({ + url: '/app/activitie/register', + method: 'POST', + data + }) + }, + + /** + * 取消报名 + * @param {string} id - 报名记录ID + * @returns {Promise} 取消结果 + */ + cancelRegistration(id) { + return request({ + url: `/app/activitie/cancel/${id}`, + method: 'POST' + }) + }, + + /** + * 获取我的活动报名记录 + * @param {Object} params - 查询参数 + * @returns {Promise} 报名记录列表 + */ + getMyRegistrations(params = {}) { + return request({ + url: '/app/activitie/my-registrations', + method: 'GET', + params + }) + } +} \ No newline at end of file diff --git a/components/activity-card/activity-card.vue b/components/activity-card/activity-card.vue index 85ec765..235b423 100644 --- a/components/activity-card/activity-card.vue +++ b/components/activity-card/activity-card.vue @@ -25,8 +25,8 @@ - - {{ getStatusText(activity.status) }} + + {{ statusText }} @@ -89,17 +89,18 @@ export default { ACTIVITY_STATUS } }, + computed: { + // 状态文本 + statusText() { + return ACTIVITY_STATUS_TEXT[this.activity.status] || '未知状态' + }, + + // 状态样式类 + statusClass() { + return ACTIVITY_STATUS_CLASS[this.activity.status] || '' + } + }, methods: { - // 获取状态文本 - getStatusText(status) { - return ACTIVITY_STATUS_TEXT[status] || '未知状态' - }, - - // 获取状态样式类 - getStatusClass(status) { - return ACTIVITY_STATUS_CLASS[status] || '' - }, - // 获取默认背景图片 getDefaultImage() { return DEFAULT_ACTIVITY_IMAGES[this.activity.type] || '/static/image/a1.png' diff --git a/pages/activity/activity.vue b/pages/activity/activity.vue index 1e91126..3ecee8a 100644 --- a/pages/activity/activity.vue +++ b/pages/activity/activity.vue @@ -9,8 +9,23 @@ loading-text="加载中..." /> + + + + + + - + { - this.loading = false - }, 1000) + const response = await activityApi.getActivityList({ + pageNum: this.pageNum, + pageSize: this.pageSize + }) + + if (response.code === 200 && response.data) { + // 格式化数据 + const formattedData = activityFormatter.formatActivityList(response.data) + this.activityList = formattedData + + // 判断是否还有更多数据 + this.hasMore = response.data.length >= this.pageSize + } else { + this.error = response.msg || '获取活动列表失败' + } } catch (error) { - console.error('获取页面数据失败:', error) + console.error('获取活动列表失败:', error) + this.error = '网络错误,请稍后重试' + } finally { + this.loading = false + uni.stopPullDownRefresh() + } + }, + + // 刷新数据 + async refreshData() { + this.pageNum = 1 + this.hasMore = true + await this.loadPageData() + }, + + // 加载更多数据 + async loadMoreData() { + if (!this.hasMore || this.loading) return + + this.loading = true + try { + const nextPage = this.pageNum + 1 + const response = await activityApi.getActivityList({ + pageNum: nextPage, + pageSize: this.pageSize + }) + + if (response.code === 200 && response.data) { + const formattedData = activityFormatter.formatActivityList(response.data) + this.activityList = [...this.activityList, ...formattedData] + this.pageNum = nextPage + this.hasMore = response.data.length >= this.pageSize + } else { + this.hasMore = false + } + } catch (error) { + console.error('加载更多活动失败:', error) + this.hasMore = false + } finally { this.loading = false } }, @@ -126,17 +155,63 @@ export default { }, // 处理报名 - handleRegister(activity) { + async handleRegister(activity) { console.log('报名活动:', activity) + + // 检查用户是否登录 + const userInfo = uni.getStorageSync('userInfo') + if (!userInfo) { + uni.showModal({ + title: '提示', + content: '请先登录后再报名活动', + confirmText: '去登录', + success: (res) => { + if (res.confirm) { + // 跳转到登录页 + uni.navigateTo({ + url: '/pages/login/login' + }) + } + } + }) + return + } + + // 确认报名 uni.showModal({ title: '确认报名', content: `确定要报名参加"${activity.name}"活动吗?`, - success: (res) => { + success: async (res) => { if (res.confirm) { - uni.showToast({ - title: '报名成功', - icon: 'success' - }) + try { + const response = await activityApi.registerActivity({ + activityId: activity.id, + userId: userInfo.id, + userName: userInfo.userName || userInfo.nickName, + phone: userInfo.phone + }) + + if (response.code === 200) { + uni.showToast({ + title: '报名成功', + icon: 'success' + }) + + // 刷新活动列表以更新报名状态 + this.refreshData() + } else { + uni.showToast({ + title: response.msg || '报名失败', + icon: 'none' + }) + } + } catch (error) { + console.error('报名失败:', error) + uni.showToast({ + title: '报名失败,请稍后重试', + icon: 'none' + }) + } } } }) @@ -147,12 +222,13 @@ export default {