#!/usr/bin/env node /* 全站页面美化审计 v2(2026-10-17) * 对齐 UniForge UI 取证阶段:量化每个页面的样式债务 * 维度:硬编码色 / 旧品牌蓝 / transition:all / getSystemInfoSync / 内联样式 / px 单位 / 页面体量 */ const fs = require('fs') const path = require('path') const ROOT = path.resolve(__dirname, '..') const EXCLUDE_DIRS = new Set(['node_modules', 'dist', 'unpackage', '.git', 'dist_bak_1792213156']) // 已重制完成的页面(阶段一~四 + 成员标签),不纳入待美化清单 const DONE_PAGES = new Set([ 'pages/body-detail/index.vue', 'pages/mind-detail/index.vue', 'pages/wisdom-detail/index.vue', 'pages/wealth/index.vue', 'pages/action-detail/index.vue', ]) function walk(dir, out = []) { for (const name of fs.readdirSync(dir)) { if (EXCLUDE_DIRS.has(name)) continue const p = path.join(dir, name) const st = fs.statSync(p) if (st.isDirectory()) walk(p, out) else if (name.endsWith('.vue')) out.push(p) } return out } const files = walk(ROOT) const HEX = /#[0-9a-fA-F]{3,8}\b/g const OLD_BLUE = /#5[Bb]9[Bb][Dd]5/g const TRANS_ALL = /transition\s*:\s*all/g const SYSINFO = /getSystemInfoSync/g const INLINE_STYLE = /style="/g const PX_UNIT = /(? p.path + '.vue') console.log('========== 汇总 ==========') console.log('页面文件总数(不含 components):', rows.length) console.log('硬编码色总数:', rows.reduce((s, r) => s + r.hex, 0)) console.log('旧品牌蓝 #5B9BD5 总数:', rows.reduce((s, r) => s + r.oldBlue, 0)) console.log('transition:all 总数:', rows.reduce((s, r) => s + r.transAll, 0)) console.log('getSystemInfoSync 总数:', rows.reduce((s, r) => s + r.sysInfo, 0)) console.log('\n========== 主包 7 门面页 ==========') console.log('file|lines|hex|oldBlue|transAll|px|inlineStyle|debt') for (const p of mainPaths) { const r = rows.find((x) => x.file === p) if (r) console.log(`${r.file}|${r.lines}|${r.hex}|${r.oldBlue}|${r.transAll}|${r.px}|${r.inlineStyle}|${r.debt.toFixed(1)}`) } console.log('\n========== 旧品牌蓝 TOP25(品牌残留,必须收敛) ==========') console.log('file|oldBlue|hex|lines') rows .filter((r) => r.oldBlue > 0) .sort((a, b) => b.oldBlue - a.oldBlue || b.hex - a.hex) .slice(0, 25) .forEach((r) => console.log(`${r.file}|${r.oldBlue}|${r.hex}|${r.lines}`)) console.log('\n========== 硬编码色 TOP30(样式债务) ==========') console.log('file|hex|hexStyle|oldBlue|transAll|px|lines|debt|done') rows .filter((r) => !r.done) .sort((a, b) => b.debt - a.debt) .slice(0, 30) .forEach((r) => console.log(`${r.file}|${r.hex}|${r.hexStyle}|${r.oldBlue}|${r.transAll}|${r.px}|${r.lines}|${r.debt.toFixed(1)}|${r.done}`)) console.log('\n========== transition:all 分布 ==========') rows .filter((r) => r.transAll > 0) .sort((a, b) => b.transAll - a.transAll) .forEach((r) => console.log(`${r.file}|${r.transAll}`)) console.log('\n========== getSystemInfoSync 分布 ==========') rows .filter((r) => r.sysInfo > 0) .forEach((r) => console.log(`${r.file}|${r.sysInfo}`)) // 债务分层 const alive = rows.filter((r) => !r.done) const buckets = { P0: [], P1: [], P2: [], P3: [] } for (const r of alive) { if (r.debt >= 120) buckets.P0.push(r) else if (r.debt >= 60) buckets.P1.push(r) else if (r.debt >= 25) buckets.P2.push(r) else buckets.P3.push(r) } console.log('\n========== 债务分层(已重制 5 页除外) ==========') for (const k of ['P0', 'P1', 'P2', 'P3']) { console.log(`${k}: ${buckets[k].length} 页`) buckets[k] .sort((a, b) => b.debt - a.debt) .slice(0, 12) .forEach((r) => console.log(` ${r.file} (debt ${r.debt.toFixed(0)})`)) }