import { NAV_INNER_PX } from '../../utils/navMetrics'; import { getFavoriteList, removeFavorite } from '../../utils/favorites'; import { getDownloadLogs } from '../../utils/downloadLogs'; import type { FavoriteRecord } from '../../utils/favorites'; import type { DownloadLogRecord } from '../../utils/downloadLogs'; const { statusBarHeight } = wx.getWindowInfo(); const NAV_BLOCK_HEIGHT = statusBarHeight + NAV_INNER_PX; type FavoritesTab = 'favorites' | 'downloads'; type FavoriteItem = { id: string; worksheetId: string; variant: 'standard'; title: string; metaLine: string; stars: number; timeBadge: string; thumb: string; }; type DownloadRow = { id: string; title: string; time: string; status: string; statusHighlight: boolean; thumb?: string; placeholder?: 'draw'; }; type DownloadSection = { key: string; label: string; items: DownloadRow[]; }; function mapFavoriteToItem(record: FavoriteRecord): FavoriteItem { const ws = record.worksheet; const title = ws?.title || '未知题型'; const category = ws?.category || ''; const ageRange = ws ? `${ws.ageMin}-${ws.ageMax}岁` : ''; const metaLine = [category, ageRange].filter(Boolean).join(' · ') + ' · '; const difficulty = ws?.difficulty || 0; const timeBadge = formatTimeBadge(record.createdAt); return { id: record._id, worksheetId: record.worksheetId, variant: 'standard', title, metaLine, stars: Math.min(difficulty, 3), timeBadge, thumb: ws?.previewImg || '', }; } function formatTimeBadge(dateStr: string): string { const date = new Date(dateStr); const now = new Date(); const diff = now.getTime() - date.getTime(); const days = Math.floor(diff / (1000 * 60 * 60 * 24)); if (days === 0) return '收藏于今天'; if (days === 1) return '收藏于昨天'; if (days < 7) return `收藏于 ${days} 天前`; if (days < 30) return `收藏于 ${Math.floor(days / 7)} 周前`; return `收藏于 ${Math.floor(days / 30)} 个月前`; } function groupDownloadsByDate(records: DownloadLogRecord[]): DownloadSection[] { const now = new Date(); const todayStr = formatDateKey(now); const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000); const yesterdayStr = formatDateKey(yesterday); const groups: Record = {}; for (const record of records) { const date = new Date(record.createdAt); const key = formatDateKey(date); let label: string; if (key === todayStr) { label = '今天'; } else if (key === yesterdayStr) { label = '昨天'; } else { label = `${date.getMonth() + 1}月${date.getDate()}日`; } if (!groups[key]) { groups[key] = { label, items: [] }; } const ws = record.worksheet; groups[key].items.push({ id: record._id, title: ws?.title || '未知题型', time: `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`, status: '已保存相册', statusHighlight: true, thumb: ws?.previewImg, }); } return Object.keys(groups).map((key) => ({ key, label: groups[key].label, items: groups[key].items, })); } function formatDateKey(date: Date): string { return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`; } Page({ data: { favScrollHeight: 0, activeTab: 'favorites' as FavoritesTab, favoriteList: [] as FavoriteItem[], downloadSections: [] as DownloadSection[], loading: false, }, onLoad() { const win = wx.getWindowInfo(); this.setData({ favScrollHeight: win.windowHeight - NAV_BLOCK_HEIGHT, }); }, onShow() { const tab = wx.getStorageSync('favorites_active_tab') as FavoritesTab; if (tab === 'downloads' || tab === 'favorites') { this.setData({ activeTab: tab }); wx.removeStorageSync('favorites_active_tab'); } this.loadData(); }, onTabSwitch(e: WechatMiniprogram.TouchEvent) { const tab = e.currentTarget.dataset.tab as FavoritesTab; if (tab !== 'favorites' && tab !== 'downloads') return; this.setData({ activeTab: tab }); }, async loadData() { this.setData({ loading: true }); await Promise.all([this.loadFavorites(), this.loadDownloads()]); this.setData({ loading: false }); }, async loadFavorites() { const records = await getFavoriteList(); const list = records.map((r) => mapFavoriteToItem(r)); this.setData({ favoriteList: list }); }, async loadDownloads() { const records = await getDownloadLogs(); const sections = groupDownloadsByDate(records); this.setData({ downloadSections: sections }); }, onDiscoverTap() { wx.switchTab({ url: '/pages/home/home' }); }, onSearchTap() { wx.showToast({ title: '搜索功能开发中', icon: 'none' }); }, async onRemoveFavorite(e: WechatMiniprogram.TouchEvent) { const id = e.currentTarget.dataset.id as string | undefined; if (!id) return; const item = (this.data.favoriteList as FavoriteItem[]).find( (i) => i.id === id, ); if (!item) return; // 乐观更新 UI const list = (this.data.favoriteList as FavoriteItem[]).filter( (i) => i.id !== id, ); this.setData({ favoriteList: list }); wx.showToast({ title: '已取消收藏', icon: 'none' }); // 调用云端 await removeFavorite(item.worksheetId); }, onClearHistory() { wx.showModal({ title: '清空下载历史', content: '确定清空本地展示的历史记录吗?', success: (res) => { if (!res.confirm) return; this.setData({ downloadSections: [] }); wx.showToast({ title: '已清空', icon: 'none' }); }, }); }, onDownloadMore(e: WechatMiniprogram.TouchEvent) { const id = e.currentTarget.dataset.id as string | undefined; wx.showToast({ title: id ? `更多操作:${id}` : '更多', icon: 'none', }); }, });