Browse Source
- 新增通用分页组件pagination,支持空状态、加载中、无更多数据状态 - 重构活动列表页面,添加分页逻辑、分类筛选、动态数据渲染 - 完善活动详情页面,支持动态数据展示、签到报名逻辑 - 优化活动创建页面,调整上传组件与表单逻辑 - 重构登录与请求逻辑,统一鉴权处理 - 简化课表页面代码,移除旧的双向滚动逻辑 - 优化上传组件,移除预览删除功能,仅保留上传核心逻辑 - 新增活动结果页面,完善报名成功后的展示与推荐活动master
32 changed files with 2224 additions and 981 deletions
@ -0,0 +1,26 @@ |
|||||||
|
/* global getApp, Component */ |
||||||
|
const app = getApp() |
||||||
|
|
||||||
|
Component({ |
||||||
|
externalClasses: ['external-class'], |
||||||
|
properties: { |
||||||
|
pagination: { |
||||||
|
type: Object, |
||||||
|
value() { |
||||||
|
return {} |
||||||
|
}, |
||||||
|
}, |
||||||
|
customEmpty: { |
||||||
|
tyep: Boolean, |
||||||
|
value: false, |
||||||
|
}, |
||||||
|
}, |
||||||
|
data: { |
||||||
|
imageUrl: app.globalData.imageUrl, |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
handleTouchmove() { |
||||||
|
return false |
||||||
|
}, |
||||||
|
}, |
||||||
|
}) |
||||||
@ -0,0 +1,6 @@ |
|||||||
|
{ |
||||||
|
"component": true, |
||||||
|
"usingComponents": { |
||||||
|
"van-divider": "@vant/weapp/divider/index" |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,6 @@ |
|||||||
|
/* components/pagination/index.wxss */ |
||||||
|
.none { |
||||||
|
display: block; |
||||||
|
margin: 30rpx auto; |
||||||
|
width: 80%; |
||||||
|
} |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
<block wx:if="{{pagination.count==0}}"> |
||||||
|
<slot wx:if="{{customEmpty}}"></slot> |
||||||
|
<image wx:else class="none external-class" src="{{imageUrl}}/none.png?t={{Timestamp}}"></image> |
||||||
|
</block> |
||||||
|
<van-divider contentPosition="center" wx:elif="{{pagination.page<pagination.pages}}"> |
||||||
|
<van-loading /> |
||||||
|
加载中... |
||||||
|
</van-divider> |
||||||
|
<van-divider contentPosition="center" wx:elif="{{pagination.page>=pagination.pages}}">没有更多了</van-divider> |
||||||
@ -1,92 +1,20 @@ |
|||||||
<!-- |
<!-- |
||||||
Upload 上传组件 |
Upload 上传组件 |
||||||
支持图片/视频/文件上传,进度条,预览,删除,重试 |
支持图片/视频/文件上传 |
||||||
|
仅保留上传功能,不显示文件列表 |
||||||
--> |
--> |
||||||
<view class="upload"> |
<view class="upload"> |
||||||
<!-- 文件列表 --> |
<!-- 默认上传按钮 --> |
||||||
<view class="upload-list"> |
<view |
||||||
<!-- 单个文件项 --> |
wx:if="{{!readonly && fileList.length < maxCount}}" |
||||||
<view |
class="upload-trigger {{useSlot ? 'upload-trigger--slot' : ''}}" |
||||||
wx:for="{{_fileList}}" |
bindtap="onChooseFile" |
||||||
wx:key="uid" |
> |
||||||
class="upload-item upload-item--{{item.type}}" |
<!-- 具名插槽:自定义上传区域 --> |
||||||
> |
<slot name="upload-area"></slot> |
||||||
<!-- 图片预览 --> |
<!-- 默认上传占位 --> |
||||||
<view |
<view wx:if="{{!useSlot}}" class="upload-trigger-default"> |
||||||
wx:if="{{item.type === 'image'}}" |
<view class="upload-trigger-icon"></view> |
||||||
class="upload-preview" |
|
||||||
data-uid="{{item.uid}}" |
|
||||||
bindtap="onPreviewImage" |
|
||||||
> |
|
||||||
<image class="upload-preview-media" src="{{item.url}}" mode="aspectFill" /> |
|
||||||
</view> |
|
||||||
|
|
||||||
<!-- 视频预览 --> |
|
||||||
<view |
|
||||||
wx:elif="{{item.type === 'video'}}" |
|
||||||
class="upload-preview" |
|
||||||
data-uid="{{item.uid}}" |
|
||||||
bindtap="onPreviewVideo" |
|
||||||
> |
|
||||||
<video |
|
||||||
class="upload-preview-media" |
|
||||||
src="{{item.url}}" |
|
||||||
controls="{{false}}" |
|
||||||
object-fit="cover" |
|
||||||
/> |
|
||||||
<view class="upload-preview-play"> |
|
||||||
<view class="upload-preview-play-icon"></view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
|
|
||||||
<!-- 文件预览 --> |
|
||||||
<view wx:elif="{{item.type === 'file'}}" class="upload-preview upload-preview--file"> |
|
||||||
<view class="upload-file-icon"> |
|
||||||
<view class="upload-file-icon-corner"></view> |
|
||||||
<text class="upload-file-icon-text">{{item.name}}</text> |
|
||||||
</view> |
|
||||||
<text class="upload-file-name">{{item.name}}</text> |
|
||||||
</view> |
|
||||||
|
|
||||||
<!-- 上传中遮罩 + 进度条 --> |
|
||||||
<view wx:if="{{item.status === 'uploading'}}" class="upload-mask"> |
|
||||||
<view class="upload-progress"> |
|
||||||
<view class="upload-progress-bar" style="width: {{item.progress}}%"></view> |
|
||||||
</view> |
|
||||||
<text class="upload-progress-text">{{item.progress}}%</text> |
|
||||||
</view> |
|
||||||
|
|
||||||
<!-- 上传失败遮罩 + 重试 --> |
|
||||||
<view wx:if="{{item.status === 'error'}}" class="upload-mask upload-mask--error"> |
|
||||||
<text class="upload-error-text">上传失败</text> |
|
||||||
<view class="upload-retry" data-uid="{{item.uid}}" catchtap="onRetry"> |
|
||||||
<text class="upload-retry-text">重试</text> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
|
|
||||||
<!-- 删除按钮 --> |
|
||||||
<view |
|
||||||
wx:if="{{!readonly}}" |
|
||||||
class="upload-remove" |
|
||||||
data-uid="{{item.uid}}" |
|
||||||
catchtap="onRemove" |
|
||||||
> |
|
||||||
<view class="upload-remove-icon"></view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
|
|
||||||
<!-- 默认上传按钮(未达到最大数量且非只读时显示) --> |
|
||||||
<view |
|
||||||
wx:if="{{!readonly && _fileList.length < maxCount}}" |
|
||||||
class="upload-trigger {{useSlot ? 'upload-trigger--slot' : ''}}" |
|
||||||
bindtap="onChooseFile" |
|
||||||
> |
|
||||||
<!-- 具名插槽:自定义上传区域 --> |
|
||||||
<slot name="upload-area"></slot> |
|
||||||
<!-- 默认上传占位 --> |
|
||||||
<view wx:if="{{!useSlot}}" class="upload-trigger-default"> |
|
||||||
<view class="upload-trigger-icon"></view> |
|
||||||
</view> |
|
||||||
</view> |
</view> |
||||||
</view> |
</view> |
||||||
</view> |
</view> |
||||||
|
|||||||
|
After Width: | Height: | Size: 77 KiB |
@ -1,52 +1,489 @@ |
|||||||
const _app = getApp<IAppOption>() |
const app = getApp<IAppOption>() |
||||||
|
|
||||||
|
interface ILevelItem { |
||||||
|
id: number |
||||||
|
name: string |
||||||
|
code: string |
||||||
|
sort: number |
||||||
|
} |
||||||
|
|
||||||
|
interface ICategoryItem { |
||||||
|
id: number |
||||||
|
name: string |
||||||
|
code: string |
||||||
|
icon: string |
||||||
|
sort: number |
||||||
|
isEnabled: number |
||||||
|
} |
||||||
|
|
||||||
|
interface IActivityItem { |
||||||
|
id: number |
||||||
|
name: string |
||||||
|
type: number |
||||||
|
typeOther: string |
||||||
|
mainImages: string[] |
||||||
|
summary: string |
||||||
|
description: string |
||||||
|
regType: number |
||||||
|
regCondition: string |
||||||
|
contactName: string |
||||||
|
contactPhone: string |
||||||
|
startAt: string |
||||||
|
endAt: string |
||||||
|
location: string |
||||||
|
status: string |
||||||
|
} |
||||||
|
|
||||||
|
interface IPagination { |
||||||
|
page: number |
||||||
|
pageSize: number |
||||||
|
pages: number |
||||||
|
count: number |
||||||
|
} |
||||||
|
|
||||||
Page({ |
Page({ |
||||||
data: { |
data: { |
||||||
filterShow: true, |
filterShow: false, |
||||||
|
// 活动等级列表
|
||||||
|
levelList: [] as ILevelItem[], |
||||||
|
// 等级 Tab 列表(包含"全部等级")
|
||||||
|
levelTabs: [ |
||||||
|
{ |
||||||
|
id: 0, |
||||||
|
name: '全部', |
||||||
|
}, |
||||||
|
] as Array<{ id: number; name: string }>, |
||||||
|
// 当前选中的等级索引
|
||||||
|
currentLevelIndex: 0, |
||||||
|
// 活动分类列表
|
||||||
|
categoryList: [] as ICategoryItem[], |
||||||
|
// 分类 Tab 列表(包含"全部分类")
|
||||||
typeList: [ |
typeList: [ |
||||||
{ |
{ |
||||||
|
id: 0, |
||||||
name: '全部分类', |
name: '全部分类', |
||||||
icon: '5', |
icon: '/images/icon5.png', |
||||||
iconActive: '6', |
iconActive: '/images/icon6.png', |
||||||
|
isSelected: true, |
||||||
}, |
}, |
||||||
{ |
] as Array<{ id: number; name: string; icon: string; iconActive: string; isSelected: boolean }>, |
||||||
name: '学术科技', |
// 当前选中的分类 ID 数组(支持多选)
|
||||||
icon: '7', |
selectedCategoryIds: [] as number[], |
||||||
iconActive: '8', |
// 活动列表
|
||||||
|
activityList: [] as IActivityItem[], |
||||||
|
// 分页信息
|
||||||
|
pagination: { |
||||||
|
page: 1, |
||||||
|
pageSize: 20, |
||||||
|
pages: 0, |
||||||
|
count: 0, |
||||||
|
} as IPagination, |
||||||
|
// 加载状态
|
||||||
|
loading: false, |
||||||
|
// 筛选参数
|
||||||
|
filters: { |
||||||
|
status: '', |
||||||
|
keyword: '', |
||||||
|
levelId: 0, |
||||||
|
categoryIds: [] as number[], |
||||||
|
startTime: '', |
||||||
|
endTime: '', |
||||||
|
}, |
||||||
|
// 时间快捷选项
|
||||||
|
timeOptions: [ |
||||||
|
{ id: 0, name: '全部时间' }, |
||||||
|
{ id: 1, name: '今天' }, |
||||||
|
{ id: 2, name: '本周' }, |
||||||
|
{ id: 3, name: '本月' }, |
||||||
|
{ id: 4, name: '自定义时间' }, |
||||||
|
], |
||||||
|
// 当前选中的时间选项索引
|
||||||
|
selectedTimeIndex: 0, |
||||||
|
// 自定义时间范围(用于 picker 显示)
|
||||||
|
customStartTime: '', |
||||||
|
customEndTime: '', |
||||||
|
}, |
||||||
|
|
||||||
|
onLoad() { |
||||||
|
// 在 waitLogin 回调中请求接口
|
||||||
|
app.waitLogin({ type: 1 }).then(() => { |
||||||
|
this.fetchLevelList() |
||||||
|
this.fetchCategoryList() |
||||||
|
this.fetchActivityList() |
||||||
|
}) |
||||||
|
}, |
||||||
|
|
||||||
|
// 获取活动等级列表
|
||||||
|
async fetchLevelList() { |
||||||
|
try { |
||||||
|
const res = await wx.ajax({ |
||||||
|
url: '/activity-level/list', |
||||||
|
method: 'GET', |
||||||
|
data: {}, |
||||||
|
}) |
||||||
|
if (res && res.list) { |
||||||
|
// 构建 levelTabs,在开头添加"全部"
|
||||||
|
const levelTabs = [ |
||||||
|
{ |
||||||
|
id: 0, |
||||||
|
name: '全部', |
||||||
|
}, |
||||||
|
...res.list.map((item: ILevelItem) => ({ |
||||||
|
id: item.id, |
||||||
|
name: item.name, |
||||||
|
})), |
||||||
|
] |
||||||
|
this.setData({ |
||||||
|
levelList: res.list, |
||||||
|
levelTabs, |
||||||
|
}) |
||||||
|
} |
||||||
|
} catch (err) { |
||||||
|
console.error('获取活动等级列表失败:', err) |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 获取活动分类列表
|
||||||
|
async fetchCategoryList() { |
||||||
|
try { |
||||||
|
const res = await wx.ajax({ |
||||||
|
url: '/activity-category/list', |
||||||
|
method: 'GET', |
||||||
|
data: {}, |
||||||
|
}) |
||||||
|
if (res && res.list) { |
||||||
|
const { selectedCategoryIds } = this.data |
||||||
|
// 构建 typeList,在开头添加"全部分类",并计算选中状态
|
||||||
|
const typeList = [ |
||||||
|
{ |
||||||
|
id: 0, |
||||||
|
name: '全部分类', |
||||||
|
icon: '/images/icon5.png', |
||||||
|
iconActive: '/images/icon6.png', |
||||||
|
isSelected: selectedCategoryIds.length === 0, |
||||||
|
}, |
||||||
|
...res.list.map((item: ICategoryItem) => ({ |
||||||
|
id: item.id, |
||||||
|
name: item.name, |
||||||
|
icon: item.icon || '/images/icon5.png', |
||||||
|
iconActive: item.icon || '/images/icon6.png', |
||||||
|
isSelected: selectedCategoryIds.includes(item.id), |
||||||
|
})), |
||||||
|
] |
||||||
|
this.setData({ |
||||||
|
categoryList: res.list, |
||||||
|
typeList, |
||||||
|
}) |
||||||
|
} |
||||||
|
} catch (err) { |
||||||
|
console.error('获取活动分类列表失败:', err) |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 获取活动列表
|
||||||
|
async fetchActivityList(isRefresh = false) { |
||||||
|
if (this.data.loading) return |
||||||
|
|
||||||
|
const { pagination, filters, selectedCategoryIds, currentLevelIndex, levelTabs } = this.data |
||||||
|
const page = isRefresh ? 1 : pagination.page |
||||||
|
|
||||||
|
this.setData({ loading: true }) |
||||||
|
|
||||||
|
try { |
||||||
|
// 构建请求参数
|
||||||
|
const params: Record<string, any> = { |
||||||
|
page, |
||||||
|
pageSize: pagination.pageSize, |
||||||
|
} |
||||||
|
|
||||||
|
// 添加筛选参数
|
||||||
|
if (filters.status) params.status = filters.status |
||||||
|
if (filters.keyword) params.keyword = filters.keyword |
||||||
|
if (filters.startTime) params.startTime = filters.startTime |
||||||
|
if (filters.endTime) params.endTime = filters.endTime |
||||||
|
|
||||||
|
// 等级筛选:当前选中的等级(非"全部等级")
|
||||||
|
if (currentLevelIndex > 0 && levelTabs[currentLevelIndex]) { |
||||||
|
params.levelId = levelTabs[currentLevelIndex].id |
||||||
|
} |
||||||
|
|
||||||
|
// 分类筛选:选中的分类 ID 数组(非空时传值)
|
||||||
|
if (selectedCategoryIds.length > 0) { |
||||||
|
params.categoryIds = selectedCategoryIds |
||||||
|
} |
||||||
|
|
||||||
|
const res = await wx.ajax({ |
||||||
|
url: '/activity/list', |
||||||
|
method: 'GET', |
||||||
|
data: params, |
||||||
|
}) |
||||||
|
|
||||||
|
if (res) { |
||||||
|
const newList = isRefresh ? res.list : [...this.data.activityList, ...res.list] |
||||||
|
this.setData({ |
||||||
|
activityList: newList, |
||||||
|
pagination: { |
||||||
|
page: res.page || page, |
||||||
|
pageSize: res.pageSize || pagination.pageSize, |
||||||
|
pages: res.pages || 0, |
||||||
|
count: res.count || 0, |
||||||
|
}, |
||||||
|
}) |
||||||
|
} |
||||||
|
} catch (err) { |
||||||
|
console.error('获取活动列表失败:', err) |
||||||
|
} finally { |
||||||
|
this.setData({ loading: false }) |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 切换分类(支持多选)
|
||||||
|
handleTypeChange(e: WechatMiniprogram.TouchEvent) { |
||||||
|
const id = e.currentTarget.dataset.id |
||||||
|
let { selectedCategoryIds, typeList } = this.data |
||||||
|
|
||||||
|
// 点击"全部分类"(id=0)时,清空所有选中
|
||||||
|
if (id === 0) { |
||||||
|
selectedCategoryIds = [] |
||||||
|
} else { |
||||||
|
// 点击其他分类时
|
||||||
|
const index = selectedCategoryIds.indexOf(id) |
||||||
|
if (index > -1) { |
||||||
|
// 已选中,取消选中
|
||||||
|
selectedCategoryIds = selectedCategoryIds.filter((item) => item !== id) |
||||||
|
} else { |
||||||
|
// 未选中,添加选中
|
||||||
|
selectedCategoryIds = [...selectedCategoryIds, id] |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 更新 typeList 的选中状态
|
||||||
|
typeList = typeList.map((item) => ({ |
||||||
|
...item, |
||||||
|
isSelected: item.id === 0 ? selectedCategoryIds.length === 0 : selectedCategoryIds.includes(item.id), |
||||||
|
})) |
||||||
|
|
||||||
|
this.setData({ |
||||||
|
selectedCategoryIds, |
||||||
|
typeList, |
||||||
|
activityList: [], |
||||||
|
pagination: { |
||||||
|
page: 1, |
||||||
|
pageSize: 20, |
||||||
|
pages: 0, |
||||||
|
count: 0, |
||||||
}, |
}, |
||||||
{ |
}) |
||||||
name: '文体艺术', |
this.fetchActivityList(true) |
||||||
icon: '9', |
}, |
||||||
iconActive: '10', |
|
||||||
|
// 切换等级 Tab
|
||||||
|
handleLevelChange(e: WechatMiniprogram.TouchEvent) { |
||||||
|
const index = e.currentTarget.dataset.index |
||||||
|
if (index === this.data.currentLevelIndex) return |
||||||
|
|
||||||
|
this.setData({ |
||||||
|
currentLevelIndex: index, |
||||||
|
activityList: [], |
||||||
|
pagination: { |
||||||
|
page: 1, |
||||||
|
pageSize: 20, |
||||||
|
pages: 0, |
||||||
|
count: 0, |
||||||
}, |
}, |
||||||
{ |
}) |
||||||
name: '志愿公益', |
this.fetchActivityList(true) |
||||||
icon: '11', |
}, |
||||||
iconActive: '12', |
|
||||||
|
// 下拉刷新
|
||||||
|
onPullDownRefresh() { |
||||||
|
this.setData({ |
||||||
|
activityList: [], |
||||||
|
pagination: { |
||||||
|
page: 1, |
||||||
|
pageSize: 20, |
||||||
|
pages: 0, |
||||||
|
count: 0, |
||||||
}, |
}, |
||||||
{ |
}) |
||||||
name: '创新创业', |
this.fetchActivityList(true).then(() => { |
||||||
icon: '13', |
wx.stopPullDownRefresh() |
||||||
iconActive: '14', |
}) |
||||||
|
}, |
||||||
|
|
||||||
|
// 上拉加载更多
|
||||||
|
onReachBottom() { |
||||||
|
const { pagination, loading } = this.data |
||||||
|
if (loading || pagination.page >= pagination.pages) return |
||||||
|
|
||||||
|
this.setData({ |
||||||
|
pagination: { |
||||||
|
...pagination, |
||||||
|
page: pagination.page + 1, |
||||||
}, |
}, |
||||||
], |
}) |
||||||
|
this.fetchActivityList() |
||||||
}, |
}, |
||||||
onLoad() {}, |
|
||||||
|
// 关闭筛选弹窗
|
||||||
handlePopupClose() { |
handlePopupClose() { |
||||||
this.setData({ |
this.setData({ |
||||||
filterShow: false, |
filterShow: false, |
||||||
}) |
}) |
||||||
}, |
}, |
||||||
|
|
||||||
|
// 打开筛选弹窗
|
||||||
|
handleFilterOpen() { |
||||||
|
this.setData({ |
||||||
|
filterShow: true, |
||||||
|
}) |
||||||
|
}, |
||||||
|
|
||||||
|
// 选择时间快捷选项
|
||||||
|
handleTimeOptionChange(e: WechatMiniprogram.TouchEvent) { |
||||||
|
const index = e.currentTarget.dataset.index |
||||||
|
this.setData({ |
||||||
|
selectedTimeIndex: index, |
||||||
|
}) |
||||||
|
|
||||||
|
// 根据选项设置时间范围
|
||||||
|
const today = new Date() |
||||||
|
const formatDate = (date: Date) => { |
||||||
|
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}` |
||||||
|
} |
||||||
|
|
||||||
|
let startTime = '' |
||||||
|
let endTime = '' |
||||||
|
|
||||||
|
switch (index) { |
||||||
|
case 0: // 全部时间
|
||||||
|
startTime = '' |
||||||
|
endTime = '' |
||||||
|
break |
||||||
|
case 1: // 今天
|
||||||
|
startTime = formatDate(today) |
||||||
|
endTime = formatDate(today) |
||||||
|
break |
||||||
|
case 2: { // 本周
|
||||||
|
const weekStart = new Date(today) |
||||||
|
weekStart.setDate(today.getDate() - today.getDay() + 1) |
||||||
|
const weekEnd = new Date(weekStart) |
||||||
|
weekEnd.setDate(weekStart.getDate() + 6) |
||||||
|
startTime = formatDate(weekStart) |
||||||
|
endTime = formatDate(weekEnd) |
||||||
|
break |
||||||
|
} |
||||||
|
case 3: { // 本月
|
||||||
|
const monthStart = new Date(today.getFullYear(), today.getMonth(), 1) |
||||||
|
const monthEnd = new Date(today.getFullYear(), today.getMonth() + 1, 0) |
||||||
|
startTime = formatDate(monthStart) |
||||||
|
endTime = formatDate(monthEnd) |
||||||
|
break |
||||||
|
} |
||||||
|
case 4: // 自定义时间
|
||||||
|
// 使用已选择的自定义时间,或清空
|
||||||
|
startTime = this.data.customStartTime |
||||||
|
endTime = this.data.customEndTime |
||||||
|
break |
||||||
|
} |
||||||
|
|
||||||
|
this.setData({ |
||||||
|
filters: { |
||||||
|
...this.data.filters, |
||||||
|
startTime, |
||||||
|
endTime, |
||||||
|
}, |
||||||
|
}) |
||||||
|
}, |
||||||
|
|
||||||
|
// 选择开始时间
|
||||||
|
handleStartTimeChange(e: WechatMiniprogram.PickerChange) { |
||||||
|
const date = e.detail.value as string |
||||||
|
this.setData({ |
||||||
|
customStartTime: date, |
||||||
|
selectedTimeIndex: 4, // 自动切换到自定义时间
|
||||||
|
filters: { |
||||||
|
...this.data.filters, |
||||||
|
startTime: date, |
||||||
|
}, |
||||||
|
}) |
||||||
|
}, |
||||||
|
|
||||||
|
// 选择结束时间
|
||||||
|
handleEndTimeChange(e: WechatMiniprogram.PickerChange) { |
||||||
|
const date = e.detail.value as string |
||||||
|
this.setData({ |
||||||
|
customEndTime: date, |
||||||
|
selectedTimeIndex: 4, // 自动切换到自定义时间
|
||||||
|
filters: { |
||||||
|
...this.data.filters, |
||||||
|
endTime: date, |
||||||
|
}, |
||||||
|
}) |
||||||
|
}, |
||||||
|
|
||||||
|
// 取消筛选
|
||||||
|
handleFilterCancel() { |
||||||
|
// 重置筛选条件
|
||||||
|
this.setData({ |
||||||
|
filterShow: false, |
||||||
|
selectedTimeIndex: 0, |
||||||
|
customStartTime: '', |
||||||
|
customEndTime: '', |
||||||
|
filters: { |
||||||
|
status: '', |
||||||
|
keyword: '', |
||||||
|
levelId: 0, |
||||||
|
categoryIds: [], |
||||||
|
startTime: '', |
||||||
|
endTime: '', |
||||||
|
}, |
||||||
|
}) |
||||||
|
this.fetchActivityList(true) |
||||||
|
}, |
||||||
|
|
||||||
|
// 确定筛选
|
||||||
|
handleFilterConfirm() { |
||||||
|
this.setData({ |
||||||
|
filterShow: false, |
||||||
|
activityList: [], |
||||||
|
pagination: { |
||||||
|
page: 1, |
||||||
|
pageSize: 20, |
||||||
|
pages: 0, |
||||||
|
count: 0, |
||||||
|
}, |
||||||
|
}) |
||||||
|
this.fetchActivityList(true) |
||||||
|
}, |
||||||
|
|
||||||
|
// 申请活动
|
||||||
handleApply() { |
handleApply() { |
||||||
wx.navigateTo({ |
wx.navigateTo({ |
||||||
url: '/pages/actAdd/index', |
url: '/pages/actAdd/index', |
||||||
}) |
}) |
||||||
}, |
}, |
||||||
handleDetail() { |
|
||||||
|
// 查看活动详情
|
||||||
|
handleDetail(e: WechatMiniprogram.TouchEvent) { |
||||||
|
const id = e.currentTarget.dataset.id |
||||||
wx.navigateTo({ |
wx.navigateTo({ |
||||||
url: '/pages/actDetail/index', |
url: `/pages/actDetail/index?id=${id}`, |
||||||
}) |
}) |
||||||
}, |
}, |
||||||
|
|
||||||
|
// 获取活动状态文本
|
||||||
|
getStatusText(status: string): string { |
||||||
|
const statusMap: Record<string, string> = { |
||||||
|
registering: '报名中', |
||||||
|
running: '进行中', |
||||||
|
ended: '已结束', |
||||||
|
} |
||||||
|
return statusMap[status] || status |
||||||
|
}, |
||||||
}) |
}) |
||||||
|
|
||||||
export {} |
export {} |
||||||
|
|||||||
@ -1,8 +1,52 @@ |
|||||||
const _app = getApp<IAppOption>(); |
const app = getApp<IAppOption>() |
||||||
|
|
||||||
Page({ |
Page({ |
||||||
data: {}, |
data: { |
||||||
onLoad() {}, |
activityId: 0, |
||||||
}); |
status: '', // pending | draft
|
||||||
|
qrCodeUrl: '', // 公众号二维码 URL
|
||||||
|
}, |
||||||
|
|
||||||
|
onLoad(options: { id?: string; status?: string }) { |
||||||
|
const activityId = options.id ? Number(options.id) : 0 |
||||||
|
const status = options.status || '' |
||||||
|
|
||||||
|
this.setData({ |
||||||
|
activityId, |
||||||
|
status, |
||||||
|
}) |
||||||
|
|
||||||
|
app.waitLogin({ type: 1 }).then(() => { |
||||||
|
// 获取用户信息,包括公众号二维码
|
||||||
|
this.getUserProfile() |
||||||
|
}) |
||||||
|
}, |
||||||
|
|
||||||
|
// 获取用户信息
|
||||||
|
async getUserProfile() { |
||||||
|
const res = await wx.ajax({ |
||||||
|
url: '/me/profile', |
||||||
|
method: 'GET', |
||||||
|
}) |
||||||
|
|
||||||
|
this.setData({ |
||||||
|
qrCodeUrl: res.wechatSubscribe.qrCodeUrl, |
||||||
|
}) |
||||||
|
}, |
||||||
|
|
||||||
|
// 继续发布
|
||||||
|
handleContinue() { |
||||||
|
wx.redirectTo({ |
||||||
|
url: '/pages/actAdd/index', |
||||||
|
}) |
||||||
|
}, |
||||||
|
|
||||||
|
// 返回活动页
|
||||||
|
handleBack() { |
||||||
|
wx.switchTab({ |
||||||
|
url: '/pages/act/index', |
||||||
|
}) |
||||||
|
}, |
||||||
|
}) |
||||||
|
|
||||||
export {} |
export {} |
||||||
|
|||||||
@ -1,33 +1,510 @@ |
|||||||
const _app = getApp<IAppOption>() |
const app = getApp<IAppOption>() |
||||||
|
|
||||||
|
interface IActivityDetail { |
||||||
|
id: number |
||||||
|
name: string |
||||||
|
type: number |
||||||
|
typeOther: string |
||||||
|
summary: string |
||||||
|
description: string |
||||||
|
regType: number |
||||||
|
regCondition: string |
||||||
|
contactName: string |
||||||
|
contactPhone: string |
||||||
|
mainImages: string[] |
||||||
|
detailImages: string[] |
||||||
|
regStartAt: string |
||||||
|
regEndAt: string |
||||||
|
startAt: string |
||||||
|
endAt: string |
||||||
|
location: string |
||||||
|
organizer: string |
||||||
|
status: string |
||||||
|
checkinType: number |
||||||
|
checkinStartAt: string |
||||||
|
checkinEndAt: string |
||||||
|
quota: number |
||||||
|
regCount: number |
||||||
|
viewUserCount: number |
||||||
|
viewCount: number |
||||||
|
checkinCount: number |
||||||
|
commentCount: number |
||||||
|
shareCount: number |
||||||
|
collectCount: number |
||||||
|
tags: string[] |
||||||
|
levelId: number |
||||||
|
levelName: string |
||||||
|
categoryIds: number[] |
||||||
|
categoryNames: string[] |
||||||
|
isRegistered: boolean |
||||||
|
isCheckedIn: boolean |
||||||
|
isFavorited: boolean |
||||||
|
isReviewed: boolean |
||||||
|
countdownSeconds: number |
||||||
|
registrationList: Array<{ |
||||||
|
userId: number |
||||||
|
avatarUrl: string |
||||||
|
nickname: string |
||||||
|
realName: string |
||||||
|
registeredAt: string |
||||||
|
}> |
||||||
|
agendas: Array<{ |
||||||
|
id: number |
||||||
|
agendaDate: string |
||||||
|
agendaTime: string |
||||||
|
title: string |
||||||
|
description: string |
||||||
|
sort: number |
||||||
|
}> |
||||||
|
} |
||||||
|
|
||||||
|
interface IReviewItem { |
||||||
|
id: number |
||||||
|
userId: number |
||||||
|
nickname: string |
||||||
|
avatarUrl: string |
||||||
|
rating: string |
||||||
|
content: string |
||||||
|
images: string[] |
||||||
|
isAnonymous: boolean |
||||||
|
likeCount: number |
||||||
|
isLiked: boolean |
||||||
|
createdAt: string |
||||||
|
auditStatus: string |
||||||
|
} |
||||||
|
|
||||||
|
interface IPagination { |
||||||
|
page: number |
||||||
|
pageSize: number |
||||||
|
total: number |
||||||
|
totalPages: number |
||||||
|
} |
||||||
|
|
||||||
Page({ |
Page({ |
||||||
data: { |
data: { |
||||||
|
activityId: 0, |
||||||
|
detail: null as IActivityDetail | null, |
||||||
|
loading: true, |
||||||
|
|
||||||
|
// 倒计时
|
||||||
|
countdownSeconds: 0, |
||||||
|
timeData: { days: 0, hours: 0, minutes: 0, seconds: 0 }, |
||||||
|
|
||||||
|
// 弹窗
|
||||||
popupShow: false, |
popupShow: false, |
||||||
popupType: 'popup1', // 签到成功弹窗
|
popupType: 'popup1', |
||||||
popupParams: {} as any, |
popupParams: {} as any, |
||||||
|
|
||||||
|
// 评论
|
||||||
commentShow: false, |
commentShow: false, |
||||||
|
commentRating: 5, |
||||||
|
commentContent: '', |
||||||
|
commentImages: [] as Array<{ |
||||||
|
uid: string |
||||||
|
url: string |
||||||
|
type: string |
||||||
|
name: string |
||||||
|
size: number |
||||||
|
status: 'pending' | 'uploading' | 'success' | 'error' |
||||||
|
progress: number |
||||||
|
}>, |
||||||
|
commentAnonymous: false, |
||||||
|
|
||||||
|
// 评价列表
|
||||||
|
reviewList: [] as IReviewItem[], |
||||||
|
reviewPagination: { |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
total: 0, |
||||||
|
totalPages: 0, |
||||||
|
} as IPagination, |
||||||
|
reviewLoading: false, |
||||||
}, |
}, |
||||||
onLoad() {}, |
|
||||||
handlePopupOk() { |
onLoad(options: { id?: string }) { |
||||||
const { popupType } = this.data |
const activityId = options.id ? Number(options.id) : 0 |
||||||
if (popupType === 'argument') { |
if (!activityId) { |
||||||
|
wx.showToast({ title: '活动不存在', icon: 'error' }) |
||||||
|
setTimeout(() => wx.navigateBack(), 1500) |
||||||
|
return |
||||||
} |
} |
||||||
|
|
||||||
|
this.setData({ activityId }) |
||||||
|
|
||||||
|
app.waitLogin({ type: 1 }).then(() => { |
||||||
|
this.fetchActivityDetail() |
||||||
|
this.fetchReviewList() |
||||||
|
}) |
||||||
}, |
}, |
||||||
handlePopupCancel() { |
|
||||||
const { popupType } = this.data |
// 获取活动详情
|
||||||
if (popupType === 'conformBindDoctorConform') { |
async fetchActivityDetail() { |
||||||
|
try { |
||||||
|
const res = await wx.ajax({ |
||||||
|
url: `/activity/detail?id=${this.data.activityId}`, |
||||||
|
method: 'GET', |
||||||
|
data: {}, |
||||||
|
}) |
||||||
|
if (res) { |
||||||
|
this.setData({ |
||||||
|
detail: res, |
||||||
|
countdownSeconds: res.countdownSeconds || 0, |
||||||
|
loading: false, |
||||||
|
}) |
||||||
|
} |
||||||
|
} catch (err) { |
||||||
|
console.error('获取活动详情失败:', err) |
||||||
|
this.setData({ loading: false }) |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 获取评价列表
|
||||||
|
async fetchReviewList(isRefresh = false) { |
||||||
|
if (this.data.reviewLoading) return |
||||||
|
|
||||||
|
const { reviewPagination } = this.data |
||||||
|
const page = isRefresh ? 1 : reviewPagination.page |
||||||
|
|
||||||
|
this.setData({ reviewLoading: true }) |
||||||
|
|
||||||
|
try { |
||||||
|
const res = await wx.ajax({ |
||||||
|
url: `/activity/review-list?activityId=${this.data.activityId}`, |
||||||
|
method: 'GET', |
||||||
|
data: { page, pageSize: reviewPagination.pageSize }, |
||||||
|
}) |
||||||
|
if (res) { |
||||||
|
const newList = isRefresh ? res.list : [...this.data.reviewList, ...res.list] |
||||||
|
this.setData({ |
||||||
|
reviewList: newList, |
||||||
|
reviewPagination: { |
||||||
|
page: res.pagination?.page || page, |
||||||
|
pageSize: res.pagination?.pageSize || reviewPagination.pageSize, |
||||||
|
total: res.pagination?.total || 0, |
||||||
|
totalPages: res.pagination?.totalPages || 0, |
||||||
|
}, |
||||||
|
}) |
||||||
|
} |
||||||
|
} catch (err) { |
||||||
|
console.error('获取评价列表失败:', err) |
||||||
|
} finally { |
||||||
|
this.setData({ reviewLoading: false }) |
||||||
} |
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 倒计时变化
|
||||||
|
handleTimeChange(e: WechatMiniprogram.CustomEvent) { |
||||||
|
this.setData({ timeData: e.detail }) |
||||||
|
}, |
||||||
|
|
||||||
|
// 倒计时结束
|
||||||
|
handleTimeFinish() { |
||||||
|
this.setData({ countdownSeconds: 0 }) |
||||||
|
this.fetchActivityDetail() |
||||||
|
}, |
||||||
|
|
||||||
|
// 一键报名
|
||||||
|
async handleRegister() { |
||||||
|
const { detail } = this.data |
||||||
|
if (!detail) return |
||||||
|
|
||||||
|
// 检查登录状态
|
||||||
|
const accessToken = app.globalData.accessToken |
||||||
|
if (!accessToken) { |
||||||
|
wx.showToast({ title: '请先登录', icon: 'error' }) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
wx.showLoading({ title: '报名中...' }) |
||||||
|
const res = await wx.ajax({ |
||||||
|
url: `/activity/register?id=${this.data.activityId}`, |
||||||
|
method: 'POST', |
||||||
|
data: {}, |
||||||
|
}) |
||||||
|
wx.hideLoading() |
||||||
|
|
||||||
|
if (res) { |
||||||
|
wx.showToast({ title: '报名成功', icon: 'success' }) |
||||||
|
// 更新状态
|
||||||
|
this.setData({ |
||||||
|
detail: { |
||||||
|
...detail, |
||||||
|
isRegistered: true, |
||||||
|
regCount: detail.regCount + 1, |
||||||
|
}, |
||||||
|
}) |
||||||
|
// 跳转到报名成功页面
|
||||||
|
wx.navigateTo({ |
||||||
|
url: `/pages/actResult/index?id=${this.data.activityId}`, |
||||||
|
}) |
||||||
|
} |
||||||
|
} catch (err: any) { |
||||||
|
wx.hideLoading() |
||||||
|
const message = err?.message || '报名失败' |
||||||
|
wx.showToast({ title: message, icon: 'error' }) |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 签到
|
||||||
|
async handleCheckin() { |
||||||
|
const { detail } = this.data |
||||||
|
if (!detail) return |
||||||
|
|
||||||
|
// 检查登录状态
|
||||||
|
const accessToken = app.globalData.accessToken |
||||||
|
if (!accessToken) { |
||||||
|
wx.showToast({ title: '请先登录', icon: 'error' }) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
wx.showLoading({ title: '签到中...' }) |
||||||
|
const res = await wx.ajax({ |
||||||
|
url: `/activity/checkin?id=${this.data.activityId}`, |
||||||
|
method: 'POST', |
||||||
|
data: {}, |
||||||
|
}) |
||||||
|
wx.hideLoading() |
||||||
|
|
||||||
|
if (res) { |
||||||
|
// 显示签到成功弹窗
|
||||||
|
this.setData({ |
||||||
|
popupShow: true, |
||||||
|
popupType: 'checkinSuccess', |
||||||
|
popupParams: { checkedAt: res.checkedAt }, |
||||||
|
}) |
||||||
|
// 更新状态
|
||||||
|
this.setData({ |
||||||
|
detail: { |
||||||
|
...detail, |
||||||
|
isCheckedIn: true, |
||||||
|
checkinCount: detail.checkinCount + 1, |
||||||
|
}, |
||||||
|
}) |
||||||
|
} |
||||||
|
} catch (err: any) { |
||||||
|
wx.hideLoading() |
||||||
|
const message = err?.message || '签到失败' |
||||||
|
wx.showToast({ title: message, icon: 'error' }) |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 分享
|
||||||
|
async handleShare() { |
||||||
|
const { detail } = this.data |
||||||
|
if (!detail) return |
||||||
|
|
||||||
|
// 上报分享
|
||||||
|
try { |
||||||
|
await wx.ajax({ |
||||||
|
url: `/activity/share?id=${this.data.activityId}`, |
||||||
|
method: 'POST', |
||||||
|
data: { channel: 'friend' }, |
||||||
|
}) |
||||||
|
} catch (err) { |
||||||
|
console.error('上报分享失败:', err) |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 打开评论弹窗
|
||||||
|
handleOpenComment() { |
||||||
this.setData({ |
this.setData({ |
||||||
popupShow: false, |
commentShow: true, |
||||||
popupType: 'i', |
commentRating: 5, |
||||||
|
commentContent: '', |
||||||
|
commentImages: [], |
||||||
|
commentAnonymous: false, |
||||||
|
}) |
||||||
|
}, |
||||||
|
|
||||||
|
// 评论评分变化
|
||||||
|
onCommentRatingChange(e: WechatMiniprogram.CustomEvent) { |
||||||
|
this.setData({ commentRating: e.detail }) |
||||||
|
}, |
||||||
|
|
||||||
|
// 评论内容变化
|
||||||
|
onCommentContentChange(e: WechatMiniprogram.TextareaInput) { |
||||||
|
this.setData({ commentContent: e.detail.value }) |
||||||
|
}, |
||||||
|
|
||||||
|
// 评论图片上传成功
|
||||||
|
onCommentImageSuccess(e: WechatMiniprogram.CustomEvent) { |
||||||
|
const { file } = e.detail |
||||||
|
console.log('上传成功', file) |
||||||
|
// 添加上传成功的图片到列表
|
||||||
|
this.setData({ |
||||||
|
commentImages: [...this.data.commentImages, file], |
||||||
}) |
}) |
||||||
}, |
}, |
||||||
|
|
||||||
|
// 评论图片上传失败
|
||||||
|
onCommentImageError(e: WechatMiniprogram.CustomEvent) { |
||||||
|
const { file, error } = e.detail |
||||||
|
console.log('上传失败', file, error) |
||||||
|
wx.showToast({ title: '图片上传失败', icon: 'none' }) |
||||||
|
}, |
||||||
|
|
||||||
|
// 删除评论图片
|
||||||
|
onRemoveCommentImage(e: WechatMiniprogram.TouchEvent) { |
||||||
|
const index = e.currentTarget.dataset.index |
||||||
|
const commentImages = [...this.data.commentImages] |
||||||
|
commentImages.splice(index, 1) |
||||||
|
this.setData({ commentImages }) |
||||||
|
}, |
||||||
|
|
||||||
|
// 评论匿名切换
|
||||||
|
onCommentAnonymousChange(e: WechatMiniprogram.CustomEvent) { |
||||||
|
this.setData({ commentAnonymous: e.detail.value }) |
||||||
|
}, |
||||||
|
|
||||||
|
// 提交评论
|
||||||
|
async handleSubmitComment() { |
||||||
|
const { commentRating, commentContent, commentImages, commentAnonymous } = this.data |
||||||
|
|
||||||
|
if (!commentContent.trim()) { |
||||||
|
wx.showToast({ title: '请输入评价内容', icon: 'error' }) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
wx.showLoading({ title: '提交中...' }) |
||||||
|
const res = await wx.ajax({ |
||||||
|
url: `/activity/submit-review?id=${this.data.activityId}`, |
||||||
|
method: 'POST', |
||||||
|
data: { |
||||||
|
activityId: this.data.activityId, |
||||||
|
rating: commentRating, |
||||||
|
content: commentContent, |
||||||
|
images: commentImages.map((img) => img.url), |
||||||
|
isAnonymous: commentAnonymous, |
||||||
|
}, |
||||||
|
}) |
||||||
|
wx.hideLoading() |
||||||
|
|
||||||
|
if (res) { |
||||||
|
wx.showToast({ title: '评价成功', icon: 'success' }) |
||||||
|
this.setData({ |
||||||
|
commentShow: false, |
||||||
|
detail: { |
||||||
|
...this.data.detail!, |
||||||
|
isReviewed: true, |
||||||
|
commentCount: this.data.detail!.commentCount + 1, |
||||||
|
}, |
||||||
|
}) |
||||||
|
// 刷新评价列表
|
||||||
|
this.fetchReviewList(true) |
||||||
|
} |
||||||
|
} catch (err: any) { |
||||||
|
wx.hideLoading() |
||||||
|
const message = err?.message || '评价失败' |
||||||
|
wx.showToast({ title: message, icon: 'error' }) |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 关闭评论弹窗
|
||||||
onCommentClose() { |
onCommentClose() { |
||||||
|
this.setData({ commentShow: false }) |
||||||
|
}, |
||||||
|
|
||||||
|
// 点赞评价
|
||||||
|
async handleLikeReview(e: WechatMiniprogram.TouchEvent) { |
||||||
|
const reviewId = e.currentTarget.dataset.id |
||||||
|
const { reviewList } = this.data |
||||||
|
|
||||||
|
// 检查登录状态
|
||||||
|
const accessToken = app.globalData.accessToken |
||||||
|
if (!accessToken) { |
||||||
|
wx.showToast({ title: '请先登录', icon: 'error' }) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
const res = await wx.ajax({ |
||||||
|
url: `/activity/toggle-review-like`, |
||||||
|
method: 'POST', |
||||||
|
data: { |
||||||
|
reviewId, |
||||||
|
}, |
||||||
|
}) |
||||||
|
|
||||||
|
if (res) { |
||||||
|
// 更新评价列表中的点赞状态
|
||||||
|
const updatedList = reviewList.map((item) => { |
||||||
|
if (item.id === reviewId) { |
||||||
|
return { |
||||||
|
...item, |
||||||
|
isLiked: res.isLiked, |
||||||
|
likeCount: res.likeCount, |
||||||
|
} |
||||||
|
} |
||||||
|
return item |
||||||
|
}) |
||||||
|
this.setData({ reviewList: updatedList }) |
||||||
|
} |
||||||
|
} catch (err: any) { |
||||||
|
const message = err?.message || '操作失败' |
||||||
|
wx.showToast({ title: message, icon: 'error' }) |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 弹窗确认
|
||||||
|
handlePopupOk() { |
||||||
|
this.setData({ |
||||||
|
popupShow: false, |
||||||
|
popupType: 'popup1', |
||||||
|
}) |
||||||
|
}, |
||||||
|
|
||||||
|
// 弹窗取消
|
||||||
|
handlePopupCancel() { |
||||||
this.setData({ |
this.setData({ |
||||||
commentShow: false, |
popupShow: false, |
||||||
|
popupType: 'popup1', |
||||||
}) |
}) |
||||||
}, |
}, |
||||||
|
|
||||||
|
// 分享给朋友
|
||||||
|
onShareAppMessage() { |
||||||
|
const { detail } = this.data |
||||||
|
if (!detail) return {} |
||||||
|
|
||||||
|
// 上报分享
|
||||||
|
this.handleShare() |
||||||
|
|
||||||
|
return { |
||||||
|
title: detail.name, |
||||||
|
path: `/pages/actDetail/index?id=${this.data.activityId}`, |
||||||
|
imageUrl: detail.mainImages[0] || '', |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 获取活动状态文本
|
||||||
|
getStatusText(status: string): string { |
||||||
|
const statusMap: Record<string, string> = { |
||||||
|
draft: '草稿', |
||||||
|
pending: '待审核', |
||||||
|
approved: '已通过', |
||||||
|
registering: '报名中', |
||||||
|
running: '进行中', |
||||||
|
ended: '已结束', |
||||||
|
cancelled: '已取消', |
||||||
|
rejected: '已拒绝', |
||||||
|
} |
||||||
|
return statusMap[status] || status |
||||||
|
}, |
||||||
|
|
||||||
|
// 获取评分文本
|
||||||
|
getRatingText(rating: number): string { |
||||||
|
if (rating >= 4.5) return '非常满意' |
||||||
|
if (rating >= 4) return '满意' |
||||||
|
if (rating >= 3) return '一般' |
||||||
|
if (rating >= 2) return '不满意' |
||||||
|
return '非常不满意' |
||||||
|
}, |
||||||
|
handleBack() { |
||||||
|
wx.navigateBack() |
||||||
|
}, |
||||||
}) |
}) |
||||||
|
|
||||||
export {} |
export {} |
||||||
|
|||||||
@ -1,8 +1,83 @@ |
|||||||
const _app = getApp<IAppOption>(); |
const app = getApp<IAppOption>() |
||||||
|
|
||||||
|
interface IActivityItem { |
||||||
|
id: number |
||||||
|
name: string |
||||||
|
mainImages: string[] |
||||||
|
startAt: string |
||||||
|
endAt: string |
||||||
|
location: string |
||||||
|
status: string |
||||||
|
regCount: number |
||||||
|
} |
||||||
|
|
||||||
Page({ |
Page({ |
||||||
data: {}, |
data: { |
||||||
onLoad() {}, |
activityId: 0, |
||||||
}); |
detail: null as any, |
||||||
|
recommendList: [] as IActivityItem[], |
||||||
|
}, |
||||||
|
|
||||||
|
onLoad(options: { id?: string }) { |
||||||
|
const activityId = options.id ? Number(options.id) : 0 |
||||||
|
this.setData({ activityId }) |
||||||
|
|
||||||
|
app.waitLogin({ type: 0 }).then(() => { |
||||||
|
this.fetchActivityDetail() |
||||||
|
this.fetchRecommendList() |
||||||
|
}) |
||||||
|
}, |
||||||
|
|
||||||
|
// 获取活动详情
|
||||||
|
async fetchActivityDetail() { |
||||||
|
try { |
||||||
|
const res = await wx.ajax({ |
||||||
|
url: `/activity/detail?id=${this.data.activityId}`, |
||||||
|
method: 'GET', |
||||||
|
data: {}, |
||||||
|
}) |
||||||
|
if (res) { |
||||||
|
this.setData({ detail: res }) |
||||||
|
} |
||||||
|
} catch (err) { |
||||||
|
console.error('获取活动详情失败:', err) |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 获取推荐活动列表
|
||||||
|
async fetchRecommendList() { |
||||||
|
try { |
||||||
|
const res = await wx.ajax({ |
||||||
|
url: '/activity/list', |
||||||
|
method: 'GET', |
||||||
|
data: { |
||||||
|
page: 1, |
||||||
|
pageSize: 3, |
||||||
|
isRecommended: true, |
||||||
|
}, |
||||||
|
}) |
||||||
|
if (res && res.list) { |
||||||
|
this.setData({ recommendList: res.list }) |
||||||
|
} |
||||||
|
} catch (err) { |
||||||
|
console.error('获取推荐活动列表失败:', err) |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 返回活动页
|
||||||
|
handleBack() { |
||||||
|
wx.switchTab({ |
||||||
|
url: '/pages/act/index', |
||||||
|
}) |
||||||
|
}, |
||||||
|
|
||||||
|
// 查看活动详情
|
||||||
|
handleDetail(e: WechatMiniprogram.TouchEvent) { |
||||||
|
const id = e.currentTarget.dataset.id |
||||||
|
wx.navigateTo({ |
||||||
|
url: `/pages/actDetail/index?id=${id}`, |
||||||
|
}) |
||||||
|
}, |
||||||
|
}) |
||||||
|
|
||||||
export {} |
export {} |
||||||
Loading…
Reference in new issue