#!/usr/bin/env node /** * D4: completion-rate.vue 完成率分析页清理 (debt 121) * * 1) template 5 处内联 SVG/legend 色绑定到 data.rateColors(JS 色板收编) * 2) style 块 ~25 处专属 hex 收编为页面级局部 SCSS 变量 * 3) 3 个全局令牌映射:#F97316->$brand-primary / #FFF5F5->$status-danger-tint / #E74C3C->$status-danger-flat */ const fs = require('fs'); const F = 'pages/stats/completion-rate.vue'; let src = fs.readFileSync(F, 'utf8'); // ---- 1. template 内联色 -> 动态绑定 ---- const TEMPLATE_REPL = [ ['stroke="#FFF0E6"', ':stroke="rateColors.track"'], ['stroke="#4ECDC4"', ':stroke="rateColors.done"'], ['stop-color="#4ECDC4"', ':stop-color="rateColors.done"'], ['stop-color="#44B09E"', ':stop-color="rateColors.doneDeep"'], ['style="background: #4ECDC4;"', ':style="{ background: rateColors.done }"'], ['style="background: #FFB088;"', ':style="{ background: rateColors.pending }"'], ['style="background: #F97316;"', ':style="{ background: rateColors.overdue }"'], ]; for (const [from, to] of TEMPLATE_REPL) { if (!src.includes(from)) console.warn('TPL NOT FOUND:', from); src = src.split(from).join(to); } // ---- 2. script data 增加色板 ---- const PALETTE_JS = [ "import { BrandColors } from '../../utils/brand-colors.js'", "", "// 完成率页专属色板(flat 青绿图表系 + 米白卡片系,单页专用)", "const RATE_COLORS = {", " track: '#FFF0E6', // 环形底轨", " done: '#4ECDC4', // 已完成(青绿)", " doneDeep: '#44B09E', // 青绿渐变深档", " pending: '#FFB088', // 进行中(浅橙)", " overdue: BrandColors.primary, // 已逾期(品牌橙)", " bar: '#FFD93D', // 柱图高亮黄", " barGreen: '#A8E063', // 柱图渐变绿起", " barGreenTo: '#56AB2F', // 柱图渐变绿终", "};", ].join('\n'); src = src.replace( "import { getChildCompletionStats, getFamilyCompletionStats, getChildren } from '../../utils/api.js'", "import { getChildCompletionStats, getFamilyCompletionStats, getChildren } from '../../utils/api.js'\n" + PALETTE_JS ); // data() 中注入 rateColors src = src.replace( / return \{\n loading: true,/, " return {\n rateColors: RATE_COLORS,\n loading: true," ); // ---- 3. style 块收编 ---- const styleIdx = src.indexOf(' p[0] !== '#4223FC')]) { const esc = from.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); styleBody = styleBody.replace(new RegExp(esc + '(?![0-9a-fA-F])', 'g'), to); } const palette = [ '// ===== 完成率页专属色阶(flat 图表青绿 + 米白卡片,单页专用;约定见 uni.scss §14)=====', '$c-comp-bg: #FFF9F0; // 页面米白底', '$c-comp-card: #FFF5EB; // 暖白卡片底', '$c-comp-warm: #FFF0E6; // 暖米色(环形底轨 / 分隔)', '$c-comp-ink: #2D3436; // 主文字(深灰)', '$c-comp-muted: #B2BEC3; // 次要文字(灰)', '$c-comp-muted2: #636E72; // 辅助文字(中灰)', '$c-comp-danger-line: #FFE0E0; // 危险浅描边', '$c-comp-orange-text: #E17055; // 警示橙文字', '$c-comp-bar-yellow: #FFD93D; // 柱图高亮黄', '$c-comp-bar-green: #A8E063; // 柱图绿渐变起', '$c-comp-bar-green-to: #56AB2F; // 柱图绿渐变终', '' ].join('\n'); styleBody = styleBody.replace(/(]*>\s*\n)/, '$1' + palette + '\n'); fs.writeFileSync(F, before + styleBody); console.log('D4 done');