diff --git a/client/src/static/icons/alert-circle-light.png b/client/src/static/icons/alert-circle-light.png index bced4e9..a7757af 100644 Binary files a/client/src/static/icons/alert-circle-light.png and b/client/src/static/icons/alert-circle-light.png differ diff --git a/client/src/static/icons/arrow-left-dark.png b/client/src/static/icons/arrow-left-dark.png index e46bb25..b87de00 100644 Binary files a/client/src/static/icons/arrow-left-dark.png and b/client/src/static/icons/arrow-left-dark.png differ diff --git a/client/src/static/icons/arrow-left-gray.png b/client/src/static/icons/arrow-left-gray.png index 8bb2437..10001b2 100644 Binary files a/client/src/static/icons/arrow-left-gray.png and b/client/src/static/icons/arrow-left-gray.png differ diff --git a/client/src/static/icons/arrow-right-gray.png b/client/src/static/icons/arrow-right-gray.png index 2850cb8..c6ae4d6 100644 Binary files a/client/src/static/icons/arrow-right-gray.png and b/client/src/static/icons/arrow-right-gray.png differ diff --git a/client/src/static/icons/arrow-right-pale.png b/client/src/static/icons/arrow-right-pale.png index 63b5038..4561e4e 100644 Binary files a/client/src/static/icons/arrow-right-pale.png and b/client/src/static/icons/arrow-right-pale.png differ diff --git a/client/src/static/icons/bell-gray.png b/client/src/static/icons/bell-gray.png index 1eaaf85..0c2c4dc 100644 Binary files a/client/src/static/icons/bell-gray.png and b/client/src/static/icons/bell-gray.png differ diff --git a/client/src/static/icons/bill-active.png b/client/src/static/icons/bill-active.png index b3e7099..efa99b4 100644 Binary files a/client/src/static/icons/bill-active.png and b/client/src/static/icons/bill-active.png differ diff --git a/client/src/static/icons/bill.png b/client/src/static/icons/bill.png index 3780aa5..7a4207d 100644 Binary files a/client/src/static/icons/bill.png and b/client/src/static/icons/bill.png differ diff --git a/client/src/static/icons/calendar-gray.png b/client/src/static/icons/calendar-gray.png index ab3f280..5c549f8 100644 Binary files a/client/src/static/icons/calendar-gray.png and b/client/src/static/icons/calendar-gray.png differ diff --git a/client/src/static/icons/chart-active.png b/client/src/static/icons/chart-active.png index 99f8de7..6035d96 100644 Binary files a/client/src/static/icons/chart-active.png and b/client/src/static/icons/chart-active.png differ diff --git a/client/src/static/icons/chart.png b/client/src/static/icons/chart.png index c2970bb..1f5d178 100644 Binary files a/client/src/static/icons/chart.png and b/client/src/static/icons/chart.png differ diff --git a/client/src/static/icons/check-white.png b/client/src/static/icons/check-white.png index fa9ecf6..9daab85 100644 Binary files a/client/src/static/icons/check-white.png and b/client/src/static/icons/check-white.png differ diff --git a/client/src/static/icons/chevron-right-light.png b/client/src/static/icons/chevron-right-light.png index d99f9e4..29c7627 100644 Binary files a/client/src/static/icons/chevron-right-light.png and b/client/src/static/icons/chevron-right-light.png differ diff --git a/client/src/static/icons/edit-gray.png b/client/src/static/icons/edit-gray.png index b3ba7c4..7be6d41 100644 Binary files a/client/src/static/icons/edit-gray.png and b/client/src/static/icons/edit-gray.png differ diff --git a/client/src/static/icons/edit-light.png b/client/src/static/icons/edit-light.png index f37dd8e..783a054 100644 Binary files a/client/src/static/icons/edit-light.png and b/client/src/static/icons/edit-light.png differ diff --git a/client/src/static/icons/home-active.png b/client/src/static/icons/home-active.png index 8e39b2c..2ceeb23 100644 Binary files a/client/src/static/icons/home-active.png and b/client/src/static/icons/home-active.png differ diff --git a/client/src/static/icons/home.png b/client/src/static/icons/home.png index 1f9038e..bae5b6a 100644 Binary files a/client/src/static/icons/home.png and b/client/src/static/icons/home.png differ diff --git a/client/src/static/icons/plus-white.png b/client/src/static/icons/plus-white.png index 0cfa4d4..7de0257 100644 Binary files a/client/src/static/icons/plus-white.png and b/client/src/static/icons/plus-white.png differ diff --git a/client/src/static/icons/refresh-gray.png b/client/src/static/icons/refresh-gray.png index 7e4dbb2..5ed6e65 100644 Binary files a/client/src/static/icons/refresh-gray.png and b/client/src/static/icons/refresh-gray.png differ diff --git a/client/src/static/icons/refresh-orange.png b/client/src/static/icons/refresh-orange.png index 73b468e..9a16f63 100644 Binary files a/client/src/static/icons/refresh-orange.png and b/client/src/static/icons/refresh-orange.png differ diff --git a/client/src/static/icons/trash-orange.png b/client/src/static/icons/trash-orange.png index 7fb75ef..b7f2bb0 100644 Binary files a/client/src/static/icons/trash-orange.png and b/client/src/static/icons/trash-orange.png differ diff --git a/client/src/static/icons/trash-red.png b/client/src/static/icons/trash-red.png index 4bc3428..0f373a3 100644 Binary files a/client/src/static/icons/trash-red.png and b/client/src/static/icons/trash-red.png differ diff --git a/client/src/static/icons/trash-white.png b/client/src/static/icons/trash-white.png index 887f544..2627eee 100644 Binary files a/client/src/static/icons/trash-white.png and b/client/src/static/icons/trash-white.png differ diff --git a/client/src/static/icons/trend-down-red.png b/client/src/static/icons/trend-down-red.png index 76ce420..0d60a40 100644 Binary files a/client/src/static/icons/trend-down-red.png and b/client/src/static/icons/trend-down-red.png differ diff --git a/client/src/static/icons/trend-up-green.png b/client/src/static/icons/trend-up-green.png index 81460c7..6dfbc22 100644 Binary files a/client/src/static/icons/trend-up-green.png and b/client/src/static/icons/trend-up-green.png differ diff --git a/client/src/static/icons/user-active.png b/client/src/static/icons/user-active.png index 1a9fa2c..4bf0a8b 100644 Binary files a/client/src/static/icons/user-active.png and b/client/src/static/icons/user-active.png differ diff --git a/client/src/static/icons/user-gray.png b/client/src/static/icons/user-gray.png index dcdbb42..1478946 100644 Binary files a/client/src/static/icons/user-gray.png and b/client/src/static/icons/user-gray.png differ diff --git a/client/src/static/icons/user-white.png b/client/src/static/icons/user-white.png index e07e527..76bc620 100644 Binary files a/client/src/static/icons/user-white.png and b/client/src/static/icons/user-white.png differ diff --git a/client/src/static/icons/user.png b/client/src/static/icons/user.png index 5418370..492118b 100644 Binary files a/client/src/static/icons/user.png and b/client/src/static/icons/user.png differ diff --git a/scripts/generate-icons.js b/scripts/generate-icons.js new file mode 100644 index 0000000..a914388 --- /dev/null +++ b/scripts/generate-icons.js @@ -0,0 +1,119 @@ +/** + * 从 Lucide SVG 图标生成高质量 PNG + * 用法: node scripts/generate-icons.js + */ +const sharp = require('sharp') +const fs = require('fs') +const path = require('path') + +const ICONS_DIR = path.join(__dirname, '../client/src/static/icons') +const LUCIDE_DIR = path.join(__dirname, '../node_modules/lucide-static/icons') + +// 颜色映射:hex -> RGB +const COLORS = { + '#2D1B1B': { r: 45, g: 27, b: 27 }, // 暖深棕 + '#8B7E7E': { r: 139, g: 126, b: 126 }, // 灰色 + '#BFB3B3': { r: 191, g: 179, b: 179 }, // 浅灰 + '#E0D6D0': { r: 224, g: 214, b: 208 }, // 极浅灰 + '#FF8C69': { r: 255, g: 140, b: 105 }, // 珊瑚橙 + '#FF6B6B': { r: 255, g: 107, b: 107 }, // 红色 + '#7BC67E': { r: 123, g: 198, b: 126 }, // 绿色 + '#FFFFFF': { r: 255, g: 255, b: 255 }, // 白色 +} + +// 图标配置:{ lucideName, variants: { colorHex: outputName } } +const ICONS = [ + // 导航 + { lucide: 'arrow-left', variants: { '#2D1B1B': 'arrow-left-dark', '#8B7E7E': 'arrow-left-gray' } }, + { lucide: 'arrow-right', variants: { '#8B7E7E': 'arrow-right-gray', '#E0D6D0': 'arrow-right-pale' } }, + { lucide: 'chevron-right', variants: { '#BFB3B3': 'chevron-right-light' } }, + + // 操作 + { lucide: 'plus', variants: { '#FFFFFF': 'plus-white' } }, + { lucide: 'check', variants: { '#FFFFFF': 'check-white' } }, + { lucide: 'edit', variants: { '#8B7E7E': 'edit-gray', '#BFB3B3': 'edit-light' } }, + { lucide: 'trash-2', variants: { '#FF8C69': 'trash-orange', '#FF6B6B': 'trash-red', '#FFFFFF': 'trash-white' } }, + { lucide: 'refresh-cw', variants: { '#8B7E7E': 'refresh-gray', '#FF8C69': 'refresh-orange' } }, + + // 功能 + { lucide: 'calendar', variants: { '#8B7E7E': 'calendar-gray' } }, + { lucide: 'bell', variants: { '#8B7E7E': 'bell-gray' } }, + { lucide: 'user', variants: { '#8B7E7E': 'user-gray', '#FFFFFF': 'user-white' } }, + { lucide: 'alert-circle', variants: { '#BFB3B3': 'alert-circle-light' } }, + + // 趋势 + { lucide: 'trending-down', variants: { '#FF6B6B': 'trend-down-red' } }, + { lucide: 'trending-up', variants: { '#7BC67E': 'trend-up-green' } }, +] + +// TabBar 图标(需要 normal + active 两套) +const TABBAR_ICONS = [ + { lucide: 'home', normal: 'home', active: 'home-active', normalColor: '#BFB3B3', activeColor: '#FF8C69' }, + { lucide: 'bar-chart-2', normal: 'chart', active: 'chart-active', normalColor: '#BFB3B3', activeColor: '#FF8C69' }, + { lucide: 'receipt', normal: 'bill', active: 'bill-active', normalColor: '#BFB3B3', activeColor: '#FF8C69' }, + { lucide: 'user', normal: 'user', active: 'user-active', normalColor: '#BFB3B3', activeColor: '#FF8C69' }, +] + +const SIZE = 96 // 输出 PNG 尺寸(px) + +async function generateIcon(svgName, outputPath, color) { + const svgPath = path.join(LUCIDE_DIR, `${svgName}.svg`) + if (!fs.existsSync(svgPath)) { + console.warn(`⚠ SVG not found: ${svgName}.svg`) + return false + } + + let svgContent = fs.readFileSync(svgPath, 'utf-8') + + // 替换 SVG 中的 stroke 颜色 + const { r, g, b } = COLORS[color] + svgContent = svgContent.replace(/stroke="[^"]*"/g, `stroke="rgb(${r},${g},${b})"`) + // 也处理可能的 fill + svgContent = svgContent.replace(/fill="none"/g, 'fill="none"') + + // 设置输出尺寸 + svgContent = svgContent.replace(/width="[^"]*"/, `width="${SIZE}"`) + svgContent = svgContent.replace(/height="[^"]*"/, `height="${SIZE}"`) + + await sharp(Buffer.from(svgContent)) + .resize(SIZE, SIZE) + .png() + .toFile(outputPath) + + return true +} + +async function main() { + console.log('🎨 开始生成图标...\n') + + let total = 0 + let success = 0 + + // 生成普通图标 + for (const icon of ICONS) { + for (const [color, outputName] of Object.entries(icon.variants)) { + const outputPath = path.join(ICONS_DIR, `${outputName}.png`) + total++ + if (await generateIcon(icon.lucide, outputPath, color)) { + console.log(` ✓ ${outputName}.png`) + success++ + } + } + } + + // 生成 TabBar 图标 + for (const icon of TABBAR_ICONS) { + for (const [outputName, color] of [[icon.normal, icon.normalColor], [icon.active, icon.activeColor]]) { + const outputPath = path.join(ICONS_DIR, `${outputName}.png`) + total++ + if (await generateIcon(icon.lucide, outputPath, color)) { + console.log(` ✓ ${outputName}.png (tabbar)`) + success++ + } + } + } + + console.log(`\n✅ 完成: ${success}/${total} 个图标已生成`) +} + +main().catch(console.error)