feat: 初始化画个标仓库 - AI驱动设计系统(BYOK模式) - 224源/371504图标+25海报源+130技能

This commit is contained in:
sgp
2026-10-03 21:44:18 +08:00
commit 9e222877ea
497 changed files with 43611 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
// 扫描 ZF/ruoyi-ui 中残留的小虎租房旧色值,输出「色值 -> 出现次数 / 文件数」清单
// 仅统计,不修改任何文件
// 用法: node _design-test/scan-old-colors.js
const fs = require('fs');
const path = require('path');
const ROOT = 'e:/KF_7/ZhenOS-ZF/ruoyi-ui/src';
const EXT = new Set(['.vue', '.scss', '.css', '.js', '.ts']);
// 小虎租房旧色板(品牌橙 + 暖中性 + 语义 + 业务梯度)
const CAND = new Set([
'#ff7a1a', '#e86a0c', '#d96408', '#ff8a3d', '#ffc48a', '#ffe8d1', '#fff6ec', '#f6ead8',
'#faf7f2', '#e9d3b0', '#efe7dc', '#8a7f73', '#c9beb0', '#2a2118', '#3a322a', '#756a5e',
'#9a8e80', '#b8ac9e', '#2f2820', '#4a4036', '#ffb31a', '#fff6e0', '#d9481c', '#fdeee8',
'#2e9e5b', '#ecf7f0', '#f08060', '#fbbf24', '#1f8a5b', '#fbf5ea', '#d3dce6', '#99a9bf'
]);
const stats = new Map(); // hex -> { n, files:Set }
const rgbStats = new Map();
function walk(dir) {
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
const p = path.join(dir, e.name);
if (e.isDirectory()) { walk(p); continue; }
if (!EXT.has(path.extname(e.name).toLowerCase())) continue;
const txt = fs.readFileSync(p, 'utf8');
const rel = path.relative(ROOT, p).replace(/\\/g, '/');
// 十六进制
const re = /#([0-9a-fA-F]{6})\b/g;
let m;
while ((m = re.exec(txt))) {
const hex = '#' + m[1].toLowerCase();
if (!CAND.has(hex)) continue;
if (!stats.has(hex)) stats.set(hex, { n: 0, files: new Set() });
const s = stats.get(hex); s.n++; s.files.add(rel);
}
// rgb()/rgba() 三元组
const re2 = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/g;
while ((m = re2.exec(txt))) {
const key = [m[1], m[2], m[3]].join(',');
const hex = '#' + [m[1], m[2], m[3]].map(v => (+v).toString(16).padStart(2, '0')).join('');
if (!CAND.has(hex) && !['255,122,26', '255,179,26', '255,138,61'].includes(key)) continue;
if (!rgbStats.has(key)) rgbStats.set(key, { n: 0, files: new Set(), hex });
const s = rgbStats.get(key); s.n++; s.files.add(rel);
}
}
}
walk(ROOT);
const rows = [...stats.entries()].map(([hex, s]) => ({ hex, n: s.n, f: s.files.size }))
.sort((a, b) => b.n - a.n);
const rgbRows = [...rgbStats.entries()].map(([k, s]) => ({ k, hex: s.hex, n: s.n, f: s.files.size }))
.sort((a, b) => b.n - a.n);
console.log('=== 十六进制旧色值(' + rows.length + ' 种)===');
let sum = 0, filesMax = 0;
rows.forEach(r => { sum += r.n; filesMax = Math.max(filesMax, r.f); console.log(' ' + r.hex + ' ' + String(r.n).padStart(4) + ' 次 ' + String(r.f).padStart(3) + ' 文件'); });
console.log(' 小计 ' + sum + ' 次');
console.log('\n=== rgb()/rgba() 旧三元组(' + rgbRows.length + ' 种)===');
let sum2 = 0;
rgbRows.forEach(r => { sum2 += r.n; console.log(' rgb(' + r.k + ') ' + String(r.n).padStart(4) + ' 次 ' + String(r.f).padStart(3) + ' 文件'); });
console.log(' 小计 ' + sum2 + ' 次');
console.log('\n合计 ' + (sum + sum2) + ' 处');