Sfoglia il codice sorgente

refactor(beautify): D7 FamilyEnergyBar 家庭能量条组件清理 (hex 16->0)

- 补充 brand-colors.js violet/infoBlue 两个 key(#8B5CF6/#3B82F6)
- script 顶部注入 DIM_COLORS 常量(5 维色板引用 BrandColors)
- 16 处 hex 收编为 BrandColors.* / DIM_COLORS.*
- template 6 处内联 fallback '#8B5CF6'/'#3B82F6' 改绑 data.fallbackPrimary/SecondaryColor
- component-level debt 清零
liaoxg 6 giorni fa
parent
commit
c77882b4fe

+ 30 - 17
cfc-frontend/components/FamilyEnergyBar.vue

@@ -35,8 +35,8 @@
         <view class="bar-row bar-row-family">
           <text class="bar-label">全家</text>
           <view class="bar-track stacked-track">
-            <view class="bar-fill bar-fill-primary" :style="{ width: (sandboxData[dualDimension.primary.code + 'Score'] || 0) + '%', background: dualDimension.primary.color || '#8B5CF6' }"></view>
-            <view class="bar-fill bar-fill-secondary" :style="{ width: (sandboxData[dualDimension.secondary.code + 'Score'] || 0) + '%', background: dualDimension.secondary.color || '#3B82F6' }"></view>
+            <view class="bar-fill bar-fill-primary" :style="{ width: (sandboxData[dualDimension.primary.code + 'Score'] || 0) + '%', background: dualDimension.primary.color || fallbackPrimaryColor }"></view>
+            <view class="bar-fill bar-fill-secondary" :style="{ width: (sandboxData[dualDimension.secondary.code + 'Score'] || 0) + '%', background: dualDimension.secondary.color || fallbackSecondaryColor }"></view>
           </view>
           <text class="bar-value">{{ familyScore }}</text>
         </view>
@@ -48,8 +48,8 @@
         >
           <text class="bar-label">{{ member.name }}</text>
           <view class="bar-track stacked-track">
-            <view class="bar-fill bar-fill-primary" :style="{ width: getMemberPrimaryScore(member) + '%', background: dualDimension.primary.color || '#8B5CF6' }"></view>
-            <view class="bar-fill bar-fill-secondary" :style="{ width: getMemberSecondaryScore(member) + '%', background: dualDimension.secondary.color || '#3B82F6' }"></view>
+            <view class="bar-fill bar-fill-primary" :style="{ width: getMemberPrimaryScore(member) + '%', background: dualDimension.primary.color || fallbackPrimaryColor }"></view>
+            <view class="bar-fill bar-fill-secondary" :style="{ width: getMemberSecondaryScore(member) + '%', background: dualDimension.secondary.color || fallbackSecondaryColor }"></view>
           </view>
           <text class="bar-value">{{ getMemberScore(member) }}</text>
           <text class="bar-arrow">›</text>
@@ -57,11 +57,11 @@
         <!-- 图例 -->
         <view class="stacked-legend">
           <view class="legend-item">
-            <view class="legend-dot" :style="{ background: dualDimension.primary.color || '#8B5CF6' }"></view>
+            <view class="legend-dot" :style="{ background: dualDimension.primary.color || fallbackPrimaryColor }"></view>
             <text class="legend-label">{{ dualDimension.primary.label || '心' }}</text>
           </view>
           <view class="legend-item">
-            <view class="legend-dot" :style="{ background: dualDimension.secondary.color || '#3B82F6' }"></view>
+            <view class="legend-dot" :style="{ background: dualDimension.secondary.color || fallbackSecondaryColor }"></view>
             <text class="legend-label">{{ dualDimension.secondary.label || '智' }}</text>
           </view>
         </view>
@@ -71,6 +71,17 @@
 </template>
 
 <script>
+import { BrandColors } from '../utils/brand-colors.js'
+
+// 维度色板(JS 侧单一事实源;SCSS 侧等值令牌见 uni.scss $dim-*/$facade-violet/$status-info)
+var DIM_COLORS = {
+  body:   BrandColors.action,    // 身体
+  mind:   BrandColors.violet,    // 心
+  wisdom: BrandColors.infoBlue,  // 智
+  action: BrandColors.primary,   // 行动
+  wealth: BrandColors.wealth     // 富
+}
+
 export default {
   props: {
     dimensionCode: { type: String, required: true },
@@ -79,7 +90,9 @@ export default {
   },
   data: function() {
     return {
-      showMembers: false
+      showMembers: false,
+      fallbackPrimaryColor: BrandColors.violet,
+      fallbackSecondaryColor: BrandColors.infoBlue
     }
   },
   computed: {
@@ -88,13 +101,13 @@ export default {
     },
     dimensionConfig: function() {
       var maps = {
-        body:     { name: '身体', icon: '\u{1F3C3}', color: '#10B981' },
-        mind:     { name: '心',   icon: '\u2764',    color: '#8B5CF6' },
-        wisdom:   { name: '智',   icon: '\u{1F9E0}', color: '#3B82F6' },
-        action:   { name: '行动', icon: '\u{1F3CB}', color: '#F97316' },
-        wealth:   { name: '富',   icon: '\u{1F4B0}', color: '#F59E0B' }
+        body:     { name: '身体', icon: '\u{1F3C3}', color: DIM_COLORS.body },
+        mind:     { name: '心',   icon: '\u2764',    color: DIM_COLORS.mind },
+        wisdom:   { name: '智',   icon: '\u{1F9E0}', color: DIM_COLORS.wisdom },
+        action:   { name: '行动', icon: '\u{1F3CB}', color: DIM_COLORS.action },
+        wealth:   { name: '富',   icon: '\u{1F4B0}', color: DIM_COLORS.wealth }
       }
-      return maps[this.dimensionCode] || { name: '', icon: '', color: '#999' }
+      return maps[this.dimensionCode] || { name: '', icon: '', color: BrandColors.textMuted }
     },
     dimensionIcon: function() { return this.dimensionConfig.icon },
     dimensionName: function() { return this.dimensionConfig.name },
@@ -134,10 +147,10 @@ export default {
     },
     memberColor: function(member) {
       var score = this.getMemberScore(member)
-      if (score >= 80) return '#10B981'
-      if (score >= 60) return '#3B82F6'
-      if (score >= 40) return '#F97316'
-      return '#EF4444'
+      if (score >= 80) return BrandColors.action
+      if (score >= 60) return BrandColors.infoBlue
+      if (score >= 40) return BrandColors.primary
+      return BrandColors.danger
     },
     onMemberClick: function(member) {
       var self = this

+ 75 - 0
cfc-frontend/scripts/d7-family-energy-bar.js

@@ -0,0 +1,75 @@
+#!/usr/bin/env node
+/**
+ * D7: FamilyEnergyBar.vue 家庭能量条组件清理
+ * - script 顶部定义 DIM_COLORS 常量(维度色板 JS 单一事实源)引用 BrandColors
+ * - maps 5 个维度色 + #999 fallback + memberColor 4 档分级色收编
+ * - template 6 处内联 fallback hex 改绑 data.fallbackPrimaryColor/fallbackSecondaryColor
+ * - brand-colors.js 补充 violet(#8B5CF6)/infoBlue(#3B82F6)
+ */
+const fs = require('fs');
+const F = 'components/FamilyEnergyBar.vue';
+let src = fs.readFileSync(F, 'utf8');
+let replaced = 0;
+
+function repl(from, to, expect) {
+  const cnt = src.split(from).length - 1;
+  if (cnt === 0) { console.warn('NOT FOUND:', from.slice(0, 60)); return; }
+  src = src.split(from).join(to);
+  replaced += cnt;
+}
+
+// ---- 1. template 6 处内联 fallback -> data 绑定 ----
+repl("dualDimension.primary.color || '#8B5CF6'", 'dualDimension.primary.color || fallbackPrimaryColor');
+repl("dualDimension.secondary.color || '#3B82F6'", 'dualDimension.secondary.color || fallbackSecondaryColor');
+
+// ---- 2. script 顶部常量 + import ----
+repl(
+  "<script>\nexport default {",
+  [
+    "<script>",
+    "import { BrandColors } from '../utils/brand-colors.js'",
+    "",
+    "// 维度色板(JS 侧单一事实源;SCSS 侧等值令牌见 uni.scss $dim-*/$facade-violet/$status-info)",
+    "var DIM_COLORS = {",
+    "  body:   BrandColors.action,    // 身体",
+    "  mind:   BrandColors.violet,    // 心",
+    "  wisdom: BrandColors.infoBlue,  // 智",
+    "  action: BrandColors.primary,   // 行动",
+    "  wealth: BrandColors.wealth     // 富",
+    "};",
+    "",
+    "export default {",
+  ].join('\n')
+);
+
+// ---- 3. maps 五维色板收编 ----
+repl("body:     { name: '身体', icon: '\\u{1F3C3}', color: '#10B981' },", "body:     { name: '身体', icon: '\\u{1F3C3}', color: DIM_COLORS.body },");
+repl("mind:     { name: '心',   icon: '\\u2764',    color: '#8B5CF6' },", "mind:     { name: '心',   icon: '\\u2764',    color: DIM_COLORS.mind },");
+repl("wisdom:   { name: '智',   icon: '\\u{1F9E0}', color: '#3B82F6' },", "wisdom:   { name: '智',   icon: '\\u{1F9E0}', color: DIM_COLORS.wisdom },");
+repl("action:   { name: '行动', icon: '\\u{1F3CB}', color: '#F97316' },", "action:   { name: '行动', icon: '\\u{1F3CB}', color: DIM_COLORS.action },");
+repl("wealth:   { name: '富',   icon: '\\u{1F4B0}', color: '#F59E0B' }", "wealth:   { name: '富',   icon: '\\u{1F4B0}', color: DIM_COLORS.wealth }");
+repl("return maps[this.dimensionCode] || { name: '', icon: '', color: '#999' }",
+     "return maps[this.dimensionCode] || { name: '', icon: '', color: BrandColors.textMuted }");
+
+// ---- 4. memberColor 分级色收编 ----
+repl("if (score >= 80) return '#10B981'", "if (score >= 80) return BrandColors.action");
+repl("if (score >= 60) return '#3B82F6'", "if (score >= 60) return BrandColors.infoBlue");
+repl("if (score >= 40) return '#F97316'", "if (score >= 40) return BrandColors.primary");
+repl("return '#EF4444'", "return BrandColors.danger");
+
+// ---- 5. data 注入 fallback 色 ----
+repl(
+  "    return {\n      showMembers: false\n    }",
+  "    return {\n      showMembers: false,\n      fallbackPrimaryColor: BrandColors.violet,\n      fallbackSecondaryColor: BrandColors.infoBlue\n    }"
+);
+
+fs.writeFileSync(F, src);
+console.log('total replaced:', replaced);
+
+// 校验
+const lines = src.split('\n');
+let n = 0;
+for (let i = 0; i < lines.length; i++) {
+  if (/#[0-9a-fA-F]{3,8}\b/.test(lines[i])) { console.log('HEX ' + (i + 1) + ': ' + lines[i].trim()); n++; }
+}
+console.log('remaining hex lines:', n);

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

@@ -61,6 +61,10 @@ export const BrandColors = {
   // 状态深阶
   dangerDeep: '#C62828',
 
+  // 语义别名(后端配置色兜底;SCSS 侧等值令牌见 uni.scss $facade-violet/$status-info)
+  violet: '#8B5CF6',      // violet-500 紫罗兰(心智维度组件色板)
+  infoBlue: '#3B82F6',    // blue-500 信息蓝(智慧维度组件色板)
+
   // 通用语义别名(方便使用)
   brand: '#F97316',
   dimMind: '#FF6B9D',