1) 新增 pages/plan-select(加入我的计划选择器,替换详情页 actionSheet) - 默认展示我全部计划(浏览,不再强制搜索),支持 最近创建/动作最多 排序 + 名称搜索 - 点选即把动作加入该计划并返回;无计划时引导新建 - 入口接在 detail 页「加入计划」(无 planId 时 navigate 至此) 2) 增强 pages/collection(官方训练计划) - 默认展示全部分级,新增 等级筛选 chips + 名称搜索(均用现有字段,不改后端) - 筛选/搜索纯前端,viewGroups 驱动渲染 3) 修复 plan-detail 从「添加动作」返回后列表不刷新(上轮已单独提交 7ff55a6) 4) app.json 注册 plan-select 页面
93 lines
3.0 KiB
JavaScript
93 lines
3.0 KiB
JavaScript
const app = getApp();
|
||
const planSvc = require('../../services/plan');
|
||
const auth = require('../../utils/auth');
|
||
const { iconName } = require('../../utils/icon-name');
|
||
|
||
// 加入计划选择器:从动作详情「加入计划」进入,默认展示我全部计划,
|
||
// 支持 最近创建 / 动作最多 排序与名称搜索,点选即把动作加入该计划并返回。
|
||
Page({
|
||
data: {
|
||
statusBarHeight: 20,
|
||
exerciseId: '',
|
||
exerciseName: '',
|
||
allPlans: [],
|
||
plans: [],
|
||
filter: 'all', // 'all' | 'recent' | 'count'
|
||
keyword: '',
|
||
status: 'loading', // 'loading' | 'list' | 'empty' | 'error'
|
||
errorMsg: ''
|
||
},
|
||
|
||
onLoad(query) {
|
||
this.setData({
|
||
statusBarHeight: app.globalData.statusBarHeight || 20,
|
||
exerciseId: query.exerciseId || '',
|
||
exerciseName: query.name || ''
|
||
});
|
||
},
|
||
|
||
onShow() {
|
||
if (auth.isLogin()) this.load();
|
||
else {
|
||
wx.showToast({ title: '请先登录', icon: 'none' });
|
||
setTimeout(() => wx.navigateBack(), 600);
|
||
}
|
||
},
|
||
|
||
load() {
|
||
this.setData({ status: 'loading', errorMsg: '' });
|
||
planSvc.listMine().then((res) => {
|
||
const raw = (res && res.items) || res || [];
|
||
const plans = raw.map((p) => ({ ...p, icon: iconName(p.emoji, 'folder-open') }));
|
||
this.setData({ allPlans: plans, status: plans.length ? 'list' : 'empty' });
|
||
this.applyFilter();
|
||
}).catch((err) => {
|
||
const status = err && err.statusCode;
|
||
const msg = status === 401 ? '登录已失效,请重新登录' : '加载失败,请检查网络后重试';
|
||
this.setData({ status: 'error', errorMsg: msg });
|
||
});
|
||
},
|
||
|
||
// 排序 + 名称搜索(纯前端,基于已有字段 createdAt / exerciseCount / name)
|
||
applyFilter() {
|
||
const f = this.data.filter;
|
||
let list = (this.data.allPlans || []).slice();
|
||
const k = (this.data.keyword || '').trim().toLowerCase();
|
||
if (k) list = list.filter((p) => (p.name || '').toLowerCase().includes(k));
|
||
if (f === 'recent') list.sort((a, b) => (a.createdAt < b.createdAt ? 1 : -1));
|
||
else if (f === 'count') list.sort((a, b) => b.exerciseCount - a.exerciseCount);
|
||
this.setData({ plans: list });
|
||
},
|
||
|
||
onFilter(e) {
|
||
this.setData({ filter: e.detail.value }, () => this.applyFilter());
|
||
},
|
||
|
||
onSearch(e) {
|
||
this.setData({ keyword: e.detail.value }, () => this.applyFilter());
|
||
},
|
||
|
||
onSelect(e) {
|
||
const id = e.currentTarget.dataset.id;
|
||
const name = e.currentTarget.dataset.name || '';
|
||
if (!id || !this.data.exerciseId) return;
|
||
wx.showLoading({ title: '加入中…', mask: true });
|
||
planSvc.addExercise(id, this.data.exerciseId).then(() => {
|
||
wx.hideLoading();
|
||
wx.showToast({ title: name ? ('已加入「' + name + '」') : '已加入计划', icon: 'success' });
|
||
setTimeout(() => wx.navigateBack(), 400);
|
||
}).catch(() => {
|
||
wx.hideLoading();
|
||
wx.showToast({ title: '加入失败,请重试', icon: 'none' });
|
||
});
|
||
},
|
||
|
||
onCreate() {
|
||
wx.navigateTo({ url: '/pages/plan-edit/plan-edit' });
|
||
},
|
||
|
||
onRetry() {
|
||
this.load();
|
||
}
|
||
});
|