// 把样式层剩余的字面量旧色值替换为甄房新色板(精确 1:1 映射,大小写不敏感) // 只作用于指定的两个文件,不碰任何 .vue 业务页面 // 用法: node _design-test/apply-scss-colors.js (预演,只报告不写) // node _design-test/apply-scss-colors.js --write (真写) const fs = require('fs'); const WRITE = process.argv.includes('--write'); const MAP = [ ['#ff7a1a', '#0070F2'], // 品牌橙 → 交互蓝 ['#e86a0c', '#0064D9'], ['#d96408', '#0057D2'], ['#ff8a3d', '#4D9BF6'], ['#ffc48a', '#A6CFFF'], ['#ffe8d1', '#EBF8FF'], ['#fff6ec', '#F0F6FE'], ['#f6ead8', '#EAECEE'], ['#faf7f2', '#F5F6F7'], // 暖白 → 冷白 ['#e9d3b0', '#758CA4'], // 暖边框 → 冷边框 ['#efe7dc', '#E5E5E5'], ['#fbf5ea', '#F5F6F7'], ['#2a2118', '#131E29'], // 暖墨 → 冷墨 ['#3a322a', '#556B82'], ['#756a5e', '#5F7590'], ['#9a8e80', '#5F7590'], ['#b8ac9e', '#A9B4BE'], ['#8a7f73', '#758CA4'], ['#c9beb0', '#BBC1CA'], ['#ffb31a', '#E76500'], // 琥珀 → 警告橙 ['#fff6e0', '#FDF1E8'], ['#d9481c', '#AA0808'], // 红橙 → 官方 Negative ['#fdeee8', '#FBF0F0'], ['#2e9e5b', '#256F3A'], // 绿 → 官方 Positive ['#ecf7f0', '#F1F7F3'], ['#1f8a5b', '#256F3A'], ['#ea580c', '#B44F00'], ['#f08060', '#D98A8A'], ['#fbbf24', '#E76500'], ['#2f2820', '#0A1D35'], ['#4a4036', '#1E2A36'], ['#d3dce6', '#223040'], ['#99a9bf', '#6B7F94'] ]; const FILES = [ 'e:/KF_7/ZhenOS-ZF/ruoyi-ui/src/assets/styles/ruoyi.scss', 'e:/KF_7/ZhenOS-ZF/ruoyi-ui/src/assets/styles/btn.scss' ]; let grand = 0; for (const f of FILES) { let txt = fs.readFileSync(f, 'utf8'); const hits = []; for (const [from, to] of MAP) { const re = new RegExp(from.replace('#', '#'), 'gi'); const n = (txt.match(re) || []).length; if (n) { hits.push(from + ' -> ' + to + ' x' + n); txt = txt.replace(re, to); grand += n; } } console.log('\n' + f.split('/').pop() + ' 共 ' + hits.length + ' 种色值'); hits.forEach(h => console.log(' ' + h)); if (WRITE && hits.length) fs.writeFileSync(f, txt); } console.log('\n合计替换 ' + grand + ' 处 ' + (WRITE ? '(已写入)' : '(预演,未写入;加 --write 生效)'));