chore: establish V1.1 recovery baseline
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* 公益活动列表页 U31
|
||||
*
|
||||
* 重构要点(遵循 AGENTS.md 不变量):
|
||||
* - 数据:ActivityStore.fetchActivities / loadMoreActivities(游标分页)
|
||||
* - 列表项:ui-activity-card 组件,"公益免费"为主视觉标识(AGENTS 第 1 条:用户永久免费)
|
||||
* - 跳转:点击卡片 → activity-detail,不在列表页处理报名
|
||||
* - 单向意向保密:本页不接入互选意向提交(仅在 activity-matches 页由用户主动操作,AGENTS 第 6 条)
|
||||
* - 下拉刷新 + onReachBottom 加载更多
|
||||
*/
|
||||
const { activityStore, appStore, authStore } = require('../../stores');
|
||||
const { to } = require('../../constants');
|
||||
|
||||
Page({
|
||||
data: {
|
||||
activities: [],
|
||||
loading: false,
|
||||
loadingMore: false,
|
||||
hasMore: true,
|
||||
firstLoaded: false,
|
||||
/** @type {{title:string, description:string, illustration:string, actions:Array}} */
|
||||
emptyConfig: {
|
||||
title: '暂无进行中的活动',
|
||||
description: '近期暂无报名中的公益活动,请稍后再来',
|
||||
illustration: 'activity',
|
||||
actions: [
|
||||
{ text: '我的活动', event: 'my', variant: 'secondary' },
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
if (!authStore.state.isLoggedIn) return;
|
||||
this._unsub = activityStore.bindToPage(this, {
|
||||
activities: 'activities',
|
||||
activitiesHasMore: 'activitiesHasMore',
|
||||
});
|
||||
this.fetchActivities(true);
|
||||
},
|
||||
|
||||
onShow() {
|
||||
if (!authStore.state.isLoggedIn) return;
|
||||
// 从活动详情返回后,若列表为空则刷新(避免详情页报名后列表不同步)
|
||||
if (this.data.firstLoaded && this.data.activities.length === 0) {
|
||||
this.fetchActivities(true);
|
||||
}
|
||||
},
|
||||
|
||||
onUnload() {
|
||||
if (this._unsub) this._unsub();
|
||||
},
|
||||
|
||||
/** 首次或下拉刷新拉取活动列表 */
|
||||
async fetchActivities(first = false) {
|
||||
if (this.data.loading) return;
|
||||
this.setData({ loading: true });
|
||||
try {
|
||||
await activityStore.fetchActivities();
|
||||
this.setData({
|
||||
loading: false,
|
||||
firstLoaded: true,
|
||||
hasMore: activityStore.state.activitiesHasMore,
|
||||
});
|
||||
} catch (err) {
|
||||
this.setData({ loading: false, firstLoaded: true });
|
||||
appStore.toastError(err, '加载活动失败');
|
||||
}
|
||||
},
|
||||
|
||||
/** 加载更多(onReachBottom 触发) */
|
||||
async loadMore() {
|
||||
if (this.data.loadingMore || !this.data.hasMore) return;
|
||||
this.setData({ loadingMore: true });
|
||||
try {
|
||||
await activityStore.loadMoreActivities();
|
||||
this.setData({
|
||||
loadingMore: false,
|
||||
hasMore: activityStore.state.activitiesHasMore,
|
||||
});
|
||||
} catch (err) {
|
||||
this.setData({ loadingMore: false });
|
||||
appStore.toastError(err, '加载更多失败');
|
||||
}
|
||||
},
|
||||
|
||||
onPullDownRefresh() {
|
||||
this.fetchActivities(true).then(() => {
|
||||
wx.stopPullDownRefresh();
|
||||
});
|
||||
},
|
||||
|
||||
onReachBottom() {
|
||||
this.loadMore();
|
||||
},
|
||||
|
||||
/** 点击活动卡片 → 跳转详情 */
|
||||
onActivityTap(e) {
|
||||
const activityId = e.detail.activityId;
|
||||
if (!activityId) return;
|
||||
wx.navigateTo({ url: to.activityDetail(activityId) });
|
||||
},
|
||||
|
||||
/** 空状态:去我的活动 */
|
||||
onEmptyAction(e) {
|
||||
const { event } = e.detail;
|
||||
if (event === 'my') {
|
||||
wx.navigateTo({ url: '/pages/my-activities/my-activities' });
|
||||
}
|
||||
},
|
||||
|
||||
/** 顶部"我的活动"入口 */
|
||||
onMyActivities() {
|
||||
wx.navigateTo({ url: '/pages/my-activities/my-activities' });
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user