Jelajahi Sumber

refactor(beautify): D19 family-dashboard 家庭看板清理 (debt 66->~20)

- script 五行色板/吉凶色板/canvas 色全部收编 BrandColors.*(含 import)
- template 数据图标内联色 -> data.dataIconColor
- style #FFF5F7 收编局部 \-fd-blush
- brand-colors.js 补 fillGray100(#F3F4F6)/goldDeep(#FFA500)/blush(#FFF5F7)
- hex 17->0(palette 声明除外);P1 5->4
liaoxg 5 hari lalu
induk
melakukan
1eebf84c38

+ 27 - 22
cfc-frontend/pages/mind-detail/family-dashboard.vue

@@ -43,7 +43,7 @@
           
           <!-- 吉位 -->
           <view class="data-item">
-            <view class="data-icon" :style="{ backgroundColor: '#FFA500' }">
+            <view class="data-icon" :style="{ backgroundColor: dataIconColor }">
               <text class="data-icon-text">🧭</text>
             </view>
             <view class="data-info">
@@ -161,6 +161,7 @@
 </template>
 
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import MpHtml from '@/components/mp-html/mp-html.vue'
 import { parseDate } from '../../utils/format.js'
 import { getFamilyFortune, getWeekFortune, getMonthFortune, getFortuneReports, reportAppEnter
@@ -175,6 +176,7 @@ export default {
   components: { MpHtml },
   data() {
     return {
+      dataIconColor: BrandColors.goldDeep,
       showMenu: false,
       viewMode: 'week', // week, month, history
       familyFortune: {
@@ -194,11 +196,11 @@ export default {
       monthFortunes: [],
       weeklyReports: [],
       elementColors: {
-        '木': '#10B981',
-        '火': '#FF6B9D',
-        '土': '#FF8C42',
-        '金': '#6366F1',
-        '水': '#3B82F6'
+        '木': BrandColors.success,
+        '火': BrandColors.mind,
+        '土': BrandColors.body,
+        '金': BrandColors.wisdom,
+        '水': BrandColors.infoBlue
       },
       // 详情模态框
       showWeeklyReport: false,
@@ -393,7 +395,7 @@ export default {
       // 外圈背景
       ctx.beginPath()
       ctx.arc(cx, cy, outerR, 0, Math.PI * 2)
-      ctx.fillStyle = '#FFF5F7'
+      ctx.fillStyle = BrandColors.blush
       ctx.fill()
       ctx.strokeStyle = luckyColor + '40'
       ctx.lineWidth = 1.5
@@ -431,7 +433,7 @@ export default {
           ctx.stroke()
         }
         
-        ctx.fillStyle = isLucky ? luckyColor : '#9CA3AF'
+        ctx.fillStyle = isLucky ? luckyColor : BrandColors.textGray400
         ctx.font = (isLucky ? 'bold ' : '') + '12px sans-serif'
         ctx.textAlign = 'center'
         ctx.textBaseline = 'middle'
@@ -443,7 +445,7 @@ export default {
       ctx.arc(cx, cy, 5, 0, Math.PI * 2)
       ctx.fillStyle = luckyColor
       ctx.fill()
-      ctx.strokeStyle = '#FFFFFF'
+      ctx.strokeStyle = BrandColors.white
       ctx.lineWidth = 2
       ctx.stroke()
     },
@@ -481,9 +483,9 @@ export default {
       ctx.clearRect(0, 0, w, h)
       
       // 背景
-      ctx.fillStyle = '#FFFFFF'
+      ctx.fillStyle = BrandColors.white
       ctx.fillRect(padding, padding, chartW, chartH)
-      ctx.strokeStyle = '#F3F4F6'
+      ctx.strokeStyle = BrandColors.fillGray100
       ctx.lineWidth = 1
       ctx.strokeRect(padding, padding, chartW, chartH)
       
@@ -496,7 +498,7 @@ export default {
       const scoreSteps = Math.ceil((maxScore - minScore) / step)
       
       // Y 轴刻度
-      ctx.fillStyle = '#6B7280'
+      ctx.fillStyle = BrandColors.textSlate
       ctx.font = '10px sans-serif'
       ctx.textAlign = 'right'
       ctx.textBaseline = 'middle'
@@ -509,7 +511,7 @@ export default {
         ctx.beginPath()
         ctx.moveTo(padding - 5, y)
         ctx.lineTo(padding, y)
-        ctx.strokeStyle = '#E5E7EB'
+        ctx.strokeStyle = BrandColors.gray200
         ctx.stroke()
       }
       
@@ -517,7 +519,7 @@ export default {
       const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
       const labels = this.weekFortunes.map((f, i) => weekDays[i] || '')
       
-      ctx.fillStyle = '#6B7280'
+      ctx.fillStyle = BrandColors.textSlate
       ctx.font = '10px sans-serif'
       ctx.textAlign = 'center'
       ctx.textBaseline = 'top'
@@ -529,7 +531,7 @@ export default {
         ctx.beginPath()
         ctx.moveTo(x, padding + chartH)
         ctx.lineTo(x, padding + chartH + 5)
-        ctx.strokeStyle = '#E5E7EB'
+        ctx.strokeStyle = BrandColors.gray200
         ctx.stroke()
       }
       
@@ -551,7 +553,7 @@ export default {
         ctx.arc(x, y, 4, 0, Math.PI * 2)
         ctx.fillStyle = this.getFortuneColor(f.fortuneLevel)
         ctx.fill()
-        ctx.strokeStyle = '#FFFFFF'
+        ctx.strokeStyle = BrandColors.white
         ctx.lineWidth = 2
         ctx.stroke()
         
@@ -604,13 +606,13 @@ export default {
 // 获取运势颜色
     getFortuneColor(level) {
       const colors = {
-        '大吉': '#EF4444',
-        '吉': '#F97316',
-        '平': '#FBBF24',
-        '凶': '#6366F1',
-        '大凶': '#8B5CF6'
+        '大吉': BrandColors.danger,
+        '吉': BrandColors.primary,
+        '平': BrandColors.warning,
+        '凶': BrandColors.wisdom,
+        '大凶': BrandColors.violet
       }
-      return colors[level] || '#666666'
+      return colors[level] || BrandColors.textBody
     },
     
     // 获取运势等级数值(用于CSS class)
@@ -671,6 +673,9 @@ export default {
 </script>
 
 <style scoped lang="scss">
+// ===== 家庭看板专属色阶(单页专用,约定见 uni.scss §14)=====
+$c-fd-blush: #FFF5F7; // 画布/卡片浅粉底
+
 .family-dashboard {
   background-color: $facade-fill-gray-50;
   min-height: 100vh;

+ 82 - 0
cfc-frontend/scripts/d19-family-dashboard.js

@@ -0,0 +1,82 @@
+#!/usr/bin/env node
+/**
+ * D19: family-dashboard.vue 家庭情绪看板清理 (debt 66)
+ * script 五维色板/canvas/吉凶色板全收编 BrandColors;template 内联色绑定 data
+ * style #FFF5F7 收编局部变量
+ */
+const fs = require('fs');
+const F = 'pages/mind-detail/family-dashboard.vue';
+let src = fs.readFileSync(F, 'utf8');
+let replaced = 0;
+
+function repl(from, to) {
+  const cnt = src.split(from).length - 1;
+  if (cnt === 0) { console.warn('NOT FOUND:', from.slice(0, 90)); return; }
+  src = src.split(from).join(to);
+  replaced += cnt;
+}
+
+// ---- 1. template 内联色 ----
+repl(":style=\"{ backgroundColor: '#FFA500' }\"", ":style=\"{ backgroundColor: dataIconColor }\"");
+
+// ---- 2. import + data ----
+if (!src.includes('utils/brand-colors.js')) {
+  const head = src.match(/<script>\r?\n/);
+  if (head) src = src.replace(head[0], head[0] + "import { BrandColors } from '../../utils/brand-colors.js'\r\n");
+  else console.warn('script tag not found');
+}
+// data 注入 dataIconColor(找 data() { return { 的第一行)
+const dataMatch = src.match(/(data\(\) \{\r?\n    return \{\r?\n)/);
+if (dataMatch) {
+  src = src.replace(dataMatch[1], dataMatch[1] + '      dataIconColor: BrandColors.goldDeep,\r\n');
+} else {
+  console.warn('data() not matched — check data shape');
+}
+
+// ---- 3. script 五维色板(对象值)----
+repl("'木': '#10B981',", "'木': BrandColors.success,");
+repl("'火': '#FF6B9D',", "'火': BrandColors.mind,");
+repl("'土': '#FF8C42',", "'土': BrandColors.body,");
+repl("'金': '#6366F1',", "'金': BrandColors.wisdom,");
+repl("'水': '#3B82F6',", "'水': BrandColors.infoBlue,");
+
+// ---- 4. script canvas ----
+repl("ctx.fillStyle = '#FFF5F7'", "ctx.fillStyle = BrandColors.blush");
+repl("ctx.fillStyle = isLucky ? luckyColor : '#9CA3AF'", "ctx.fillStyle = isLucky ? luckyColor : BrandColors.textGray400");
+repl("ctx.strokeStyle = '#FFFFFF'", "ctx.strokeStyle = BrandColors.white", 2);
+repl("ctx.fillStyle = '#FFFFFF'", "ctx.fillStyle = BrandColors.white");
+repl("ctx.strokeStyle = '#F3F4F6'", "ctx.strokeStyle = BrandColors.fillGray100");
+repl("ctx.fillStyle = '#6B7280'", "ctx.fillStyle = BrandColors.textSlate", 2);
+repl("ctx.strokeStyle = '#E5E7EB'", "ctx.strokeStyle = BrandColors.gray200", 2);
+
+// ---- 5. 吉凶色板 ----
+repl("'大吉': '#EF4444',", "'大吉': BrandColors.danger,");
+repl("'吉': '#F97316',", "'吉': BrandColors.primary,");
+repl("'平': '#FBBF24',", "'平': BrandColors.warning,");
+repl("'凶': '#6366F1',", "'凶': BrandColors.wisdom,");
+repl("'大凶': '#8B5CF6'", "'大凶': BrandColors.violet");
+repl("return colors[level] || '#666666'", "return colors[level] || BrandColors.textBody");
+
+// ---- 6. style ----
+const styleIdx = src.indexOf('<style');
+const before = src.slice(0, styleIdx);
+let styleBody = src.slice(styleIdx);
+styleBody = styleBody.replace(/#FFF5F7(?![0-9a-fA-F])/gi, '$c-fd-blush');
+const palette = [
+  '// ===== 家庭看板专属色阶(单页专用,约定见 uni.scss §14)=====',
+  '$c-fd-blush: #FFF5F7; // 画布/卡片浅粉底',
+  ''
+].join('\n');
+styleBody = styleBody.replace(/(<style[^>]*>\s*\n)/, '$1' + palette + '\n');
+
+fs.writeFileSync(F, before + styleBody);
+console.log('total replaced:', replaced);
+
+const out = fs.readFileSync(F, 'utf8');
+const lines = out.split('\n');
+let n = 0;
+for (let i = 0; i < lines.length; i++) {
+  const L = lines[i].trim();
+  if (/#[0-9a-fA-F]{3,8}\b/.test(L) && L.charAt(0) !== '$') { console.log('HEX ' + (i + 1) + ': ' + L); n++; }
+}
+console.log('remaining non-palette hex:', n);

+ 3 - 0
cfc-frontend/utils/brand-colors.js

@@ -81,6 +81,9 @@ export const BrandColors = {
   textGhost: '#CCC',        // $facade-text-ghost
   hairline: '#E0E0E0',      // $facade-hairline
   fill: '#F0F0F0',          // $facade-fill
+  fillGray100: '#F3F4F6',   // $facade-fill-gray-100
+  goldDeep: '#FFA500',      // $accent-gold-deep(数据图标橙)
+  blush: '#FFF5F7',         // 浅粉底(家庭看板画布)
 
   // Plutchik 八基本情绪色板(情绪打卡专属;单一事实源)
   emotionJoy: '#FFD93D',       // 开心