- 建立 Lucide 子集 iconfont(49 字形),全站 emoji 替换为 fc-icon 组件 - 重塑 Design Token(冷中性近黑底 + Volt 荧光绿 #B6F24E),消除硬编码颜色 - 首页登录后个性化:我的计划 / 我的收藏 / 今日推荐(纯前端复用现有 API) - 后端 DEFAULT_EMOJI→Lucide 名,PALETTE 对齐 Kinetic Dark 语义色板 - 修复 person-standing 缺失字形;14 个官方组合 seed emoji 全部映射到现有字形
93 lines
2.8 KiB
JavaScript
93 lines
2.8 KiB
JavaScript
const app = getApp();
|
||
const planSvc = require('../../services/plan');
|
||
|
||
// UGC 计划图标选择器:Lucide 运动子集(非 emoji)
|
||
const ICONS = ['clipboard-list', 'dumbbell', 'flame', 'accessibility', 'person-standing',
|
||
'bike', 'heart', 'target', 'trophy', 'medal', 'star', 'activity',
|
||
'sparkles', 'zap', 'trending-up', 'folder-open'];
|
||
// 计划主题色:对齐 Kinetic Dark 语义色板
|
||
const COLORS = ['#B6F24E', '#2BD9A6', '#4FA8FF', '#F2B53D', '#FF5C5C', '#9BA7A1'];
|
||
|
||
Page({
|
||
data: {
|
||
statusBarHeight: 20,
|
||
mode: 'new',
|
||
id: '',
|
||
name: '',
|
||
description: '',
|
||
emoji: 'clipboard-list',
|
||
color: '#B6F24E',
|
||
emojis: ICONS,
|
||
colors: COLORS,
|
||
loading: false,
|
||
dirty: false // 是否有未保存的修改
|
||
},
|
||
|
||
onLoad(query) {
|
||
const mode = query.mode === 'edit' ? 'edit' : 'new';
|
||
const id = query.id || '';
|
||
this.setData({ statusBarHeight: app.globalData.statusBarHeight || 20, mode, id });
|
||
if (mode === 'edit' && id) {
|
||
this.setData({ loading: true });
|
||
planSvc.get(id).then((p) => {
|
||
this.setData({
|
||
name: p.name || '',
|
||
description: p.description || '',
|
||
emoji: p.emoji || 'clipboard-list',
|
||
color: p.color || '#B6F24E',
|
||
loading: false
|
||
});
|
||
}).catch(() => {
|
||
this.setData({ loading: false });
|
||
});
|
||
}
|
||
},
|
||
|
||
onName(e) { this.setData({ name: e.detail.value, dirty: true }); },
|
||
onDesc(e) { this.setData({ description: e.detail.value, dirty: true }); },
|
||
onPickEmoji(e) { this.setData({ emoji: e.currentTarget.dataset.emoji, dirty: true }); },
|
||
onPickColor(e) { this.setData({ color: e.currentTarget.dataset.color, dirty: true }); },
|
||
|
||
// 点返回键(navbar 拦截模式)触发:有未保存改动时先确认
|
||
onBackRequest() {
|
||
if (!this.data.dirty) {
|
||
wx.navigateBack();
|
||
return;
|
||
}
|
||
wx.showModal({
|
||
title: '放弃编辑?',
|
||
content: '当前修改尚未保存,确定要退出吗?',
|
||
confirmText: '退出',
|
||
cancelText: '继续编辑',
|
||
success: (res) => {
|
||
if (res.confirm) wx.navigateBack();
|
||
}
|
||
});
|
||
},
|
||
|
||
onSave() {
|
||
const name = (this.data.name || '').trim();
|
||
if (!name) {
|
||
wx.showToast({ title: '请填写计划名称', icon: 'none' });
|
||
return;
|
||
}
|
||
const dto = {
|
||
name,
|
||
description: (this.data.description || '').trim(),
|
||
emoji: this.data.emoji,
|
||
color: this.data.color
|
||
};
|
||
wx.showLoading({ title: '保存中…', mask: true });
|
||
const op = this.data.mode === 'edit'
|
||
? planSvc.update(this.data.id, dto)
|
||
: planSvc.create(dto);
|
||
op.then(() => {
|
||
wx.hideLoading();
|
||
wx.showToast({ title: '已保存', icon: 'success' });
|
||
setTimeout(() => wx.navigateBack(), 500);
|
||
}).catch(() => {
|
||
wx.hideLoading();
|
||
});
|
||
}
|
||
});
|