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
+67
View File
@@ -0,0 +1,67 @@
// 临时脚本:按品牌意象关键词从图标数据文件提取候选(画个标 logo 测试用)
const fs = require('fs');
const path = require('path');
const vm = require('vm');
const ROOT = process.cwd();
const OUT = '_design-test';
fs.mkdirSync(OUT, { recursive: true });
const manifest = JSON.parse(fs.readFileSync('js/data/manifest/icons.json', 'utf8'));
const srcMap = {};
manifest.sources.forEach(s => { srcMap[s.id] = s; });
// 候选源:线条主库 + 实心/多色特色
const TARGETS = ['feather', 'lucide', 'tabler', 'bootstrap', 'remix', 'heroicons', 'iconoir', 'phosphor', 'fluent', 'fluent-mdl2'];
// 品牌意象词表:画个标 = 画(绘) + 标(标志)
const THEMES = {
design: ['pen', 'pencil', 'palette', 'brush', 'paint', 'edit', 'ruler', 'compass', 'layout', 'draft', 'design', 'sketch', 'ink'],
brand: ['flag', 'tag', 'badge', 'bookmark', 'award', 'crown', 'star', 'sparkle', 'label', 'logo', 'target', 'certificate'],
symbol: ['hexagon', 'diamond', 'triangle', 'shield', 'anchor', 'gem', 'bolt', 'zap', 'infinity', 'sun', 'moon', 'leaf', 'flower'],
tech: ['rocket', 'cpu', 'cloud', 'code', 'terminal', 'wifi', 'database', 'globe'],
commerce: ['bag', 'cart', 'coin', 'wallet', 'briefcase', 'chart', 'store', 'gift'],
misc: ['key', 'lock', 'mail', 'phone', 'calendar', 'clock', 'home', 'book', 'heart', 'camera', 'map', 'plane']
};
function loadSource(sid) {
const file = path.join(ROOT, 'js/data/sources', sid + '.js');
if (!fs.existsSync(file)) return null;
const code = fs.readFileSync(file, 'utf8');
const sb = {};
sb.window = sb; sb.self = sb; sb.globalThis = sb;
vm.runInNewContext(code, sb, { filename: sid + '.js' });
const src = sb.window['HGB_Source_' + sid];
return src ? src.icons : null;
}
const out = [];
const seen = new Set();
for (const sid of TARGETS) {
const cfg = srcMap[sid];
if (!cfg) continue;
const icons = loadSource(sid);
if (!icons) { console.log('SKIP(无数据文件): ' + sid); continue; }
for (const [theme, kws] of Object.entries(THEMES)) {
for (const kw of kws) {
let hits = icons.filter(ic => (ic.name || '').toLowerCase().includes(kw) && !seen.has(sid + ':' + ic.id));
hits = hits.slice(0, 1); // 每源每词取 1 个,控制候选量
for (const h of hits) {
seen.add(sid + ':' + h.id);
out.push({
theme, source: sid, id: h.id, name: h.name,
categoryCn: h.categoryCn || '', type: h.type || cfg.type,
svg: h.svg, license: cfg.license, licenseNote: cfg.licenseNote,
coordText: cfg.coordText, style: cfg.style || ''
});
}
}
}
console.log(` 加载 ${sid}(${cfg.count} 图标)→ 命中 ${out.filter(o => o.source === sid).length}`);
}
fs.writeFileSync(path.join(OUT, 'candidates.json'), JSON.stringify(out, null, 1), 'utf8');
console.log(`\n候选池共 ${out.length} 个图标 → ${OUT}/candidates.json`);
const byTheme = {};
out.forEach(o => { byTheme[o.theme] = (byTheme[o.theme] || 0) + 1; });
console.log('按主题分布:' + JSON.stringify(byTheme));