const { loadFontsManifest, listCategories } = require('../../utils/mp/font-loader') const { loadFavorites, saveFavorites } = require('../../utils/mp/storage') Page({ data: { fonts: [], filteredFonts: [], categories: ['全部'], categoryIndex: 0, favoriteOnly: false, favorites: [], searchText: '', selectedFontId: '', }, async onLoad(options) { const selectedFontId = options && options.selected ? decodeURIComponent(options.selected) : '' this.setData({ selectedFontId }) wx.showLoading({ title: '加载字体中', mask: true }) try { const favorites = loadFavorites() const fonts = await loadFontsManifest() const categories = listCategories(fonts) this.fontMap = new Map(fonts.map((font) => [font.id, font])) this.setData({ fonts, categories, favorites, }) this.applyFilter() } catch (error) { wx.showToast({ title: '字体加载失败', icon: 'none' }) } finally { wx.hideLoading() } }, applyFilter() { const { fonts, favorites, searchText, categories, categoryIndex, favoriteOnly, } = this.data const keyword = String(searchText || '').trim().toLowerCase() const selectedCategory = categories[categoryIndex] || '全部' const favoriteSet = new Set(favorites) const filteredFonts = fonts .filter((font) => { if (favoriteOnly && !favoriteSet.has(font.id)) { return false } if (selectedCategory !== '全部' && selectedCategory !== '收藏' && font.category !== selectedCategory) { return false } if (selectedCategory === '收藏' && !favoriteSet.has(font.id)) { return false } if (!keyword) { return true } return ( String(font.name || '').toLowerCase().includes(keyword) || String(font.category || '').toLowerCase().includes(keyword) ) }) .map((font) => ({ ...font, isFavorite: favoriteSet.has(font.id), })) this.setData({ filteredFonts }) }, onSearchInput(event) { this.setData({ searchText: event.detail.value || '' }) this.applyFilter() }, onCategoryChange(event) { this.setData({ categoryIndex: Number(event.detail.value) || 0 }) this.applyFilter() }, onToggleFavoriteOnly() { this.setData({ favoriteOnly: !this.data.favoriteOnly }) this.applyFilter() }, onToggleFavorite(event) { const fontId = event.currentTarget.dataset.fontId if (!fontId) { return } const next = new Set(this.data.favorites) if (next.has(fontId)) { next.delete(fontId) } else { next.add(fontId) } const favorites = saveFavorites(Array.from(next)) this.setData({ favorites }) this.applyFilter() }, onSelectFont(event) { const fontId = event.currentTarget.dataset.fontId if (!fontId) { return } this.setData({ selectedFontId: fontId }) }, onCancel() { wx.navigateBack() }, onConfirm() { const { selectedFontId } = this.data if (!selectedFontId) { wx.showToast({ title: '请选择字体', icon: 'none' }) return } const font = this.fontMap ? this.fontMap.get(selectedFontId) : null const eventChannel = this.getOpenerEventChannel() eventChannel.emit('fontSelected', { fontId: selectedFontId, font, }) wx.navigateBack() }, })