Просмотр исходного кода

refactor(beautify): D31 script 段维度色批量收编 (hex 1034->764)

- 新增 d31-script-hex-harvest.js:把 script 段「整段字符串即 hex」的维度色替换为 BrandColors.*,
  自动计算相对 import 路径 / 并入已有具名导入 / 已导入则跳过
- 73 个文件 384 处收编(五维主色 success/wealth/mind/body/primary/wisdom 占 290 处)
- 新增 d31-fix-template-refs.js:模板区误替换的 36 处(模板无法访问模块级变量)
  还原为原 hex,并清理 16 个因此产生的未使用 import
- brand-colors.js 补 mindAccent(#FF6B35)/brownWarm(#8D6E63)
- 73 文件 node --check 全通过;全站硬编码色 1034 -> 764
liaoxg 5 дней назад
Родитель
Сommit
388087471d
75 измененных файлов с 512 добавлено и 311 удалено
  1. 2 1
      cfc-frontend/components/ConfigurableGuide.vue
  2. 10 10
      cfc-frontend/components/ContentSharePoster.vue
  3. 6 5
      cfc-frontend/components/DimensionActivities.vue
  4. 6 5
      cfc-frontend/components/DimensionArticles.vue
  5. 6 5
      cfc-frontend/components/DimensionIntroCard.vue
  6. 6 5
      cfc-frontend/components/DimensionVisitorCard.vue
  7. 12 11
      cfc-frontend/components/FamilyMemberCard.vue
  8. 10 9
      cfc-frontend/components/FamilyRelationGraph.vue
  9. 11 10
      cfc-frontend/components/RadarChart.vue
  10. 5 4
      cfc-frontend/components/TrendChart.vue
  11. 6 5
      cfc-frontend/components/tab-transition.vue
  12. 8 7
      cfc-frontend/pages/action-detail/components/AbilityDiagram.vue
  13. 2 1
      cfc-frontend/pages/action-detail/components/DimensionSubDims.vue
  14. 9 8
      cfc-frontend/pages/action-detail/components/OctopusDiagram.vue
  15. 2 1
      cfc-frontend/pages/action-detail/contact-detail.vue
  16. 13 12
      cfc-frontend/pages/action-detail/index.vue
  17. 7 6
      cfc-frontend/pages/activity/activity-detail/activity-detail.vue
  18. 2 2
      cfc-frontend/pages/activity/create.vue
  19. 7 6
      cfc-frontend/pages/ai/components/AITaskCard.vue
  20. 2 1
      cfc-frontend/pages/article-center/article-detail.vue
  21. 6 5
      cfc-frontend/pages/article-center/article-edit.vue
  22. 12 11
      cfc-frontend/pages/article-center/index.vue
  23. 3 2
      cfc-frontend/pages/body-detail/dimension-detail.vue
  24. 3 2
      cfc-frontend/pages/body-detail/health-dimensions.vue
  25. 1 1
      cfc-frontend/pages/body-detail/index.vue
  26. 1 1
      cfc-frontend/pages/child/rewards.vue
  27. 1 1
      cfc-frontend/pages/discover-detail/product-detail/product-detail.vue
  28. 2 1
      cfc-frontend/pages/discover/circle-feed.vue
  29. 1 1
      cfc-frontend/pages/discover/create-circle.vue
  30. 1 1
      cfc-frontend/pages/family/add-member.vue
  31. 6 5
      cfc-frontend/pages/family/manual-score-entry.vue
  32. 3 2
      cfc-frontend/pages/family/mbti-profile.vue
  33. 4 3
      cfc-frontend/pages/family/mbti-result.vue
  34. 4 3
      cfc-frontend/pages/family/mbti-test.vue
  35. 7 6
      cfc-frontend/pages/family/self-check-ai.vue
  36. 7 6
      cfc-frontend/pages/family/self-check.vue
  37. 3 2
      cfc-frontend/pages/growth/mini-trend.vue
  38. 2 1
      cfc-frontend/pages/growth/profile/index.vue
  39. 3 2
      cfc-frontend/pages/guide/packages/share.vue
  40. 9 8
      cfc-frontend/pages/health-main/index.vue
  41. 1 1
      cfc-frontend/pages/health/components/ComprehensiveSurvey.vue
  42. 5 4
      cfc-frontend/pages/health/components/TrendChart.vue
  43. 5 5
      cfc-frontend/pages/health/daily-checkin.vue
  44. 2 1
      cfc-frontend/pages/health/indicator-curve.vue
  45. 6 5
      cfc-frontend/pages/health/nutrition-profile.vue
  46. 1 1
      cfc-frontend/pages/health/report-blocks-renderer.vue
  47. 1 1
      cfc-frontend/pages/health/sleep-index.vue
  48. 4 3
      cfc-frontend/pages/home-pages/components/ContactCard.vue
  49. 6 5
      cfc-frontend/pages/home-pages/member-home-detail.vue
  50. 1 1
      cfc-frontend/pages/member-detail/components/member-detail-sections/body-section.vue
  51. 6 5
      cfc-frontend/pages/mind-detail/articles.vue
  52. 10 9
      cfc-frontend/pages/mind-detail/duo-compatibility.vue
  53. 2 1
      cfc-frontend/pages/mind-detail/emotion-report.vue
  54. 23 22
      cfc-frontend/pages/mind-detail/index.vue
  55. 6 5
      cfc-frontend/pages/mind-detail/innate-portrait.vue
  56. 7 6
      cfc-frontend/pages/mind-detail/traditional-mirror.vue
  57. 6 5
      cfc-frontend/pages/mind-detail/training.vue
  58. 1 1
      cfc-frontend/pages/profile/components/ProfileMenu.vue
  59. 3 3
      cfc-frontend/pages/profile/message-history.vue
  60. 6 5
      cfc-frontend/pages/profile/portrait-edit.vue
  61. 4 4
      cfc-frontend/pages/promotion/components/SharePoster.vue
  62. 1 1
      cfc-frontend/pages/promotion/index.vue
  63. 4 3
      cfc-frontend/pages/promotion/team.vue
  64. 6 5
      cfc-frontend/pages/psych-assessment/index.vue
  65. 1 1
      cfc-frontend/pages/rewards/rewards.vue
  66. 2 1
      cfc-frontend/pages/shop/components/countdown-tag.vue
  67. 3 2
      cfc-frontend/pages/tianpan/annual-energy.vue
  68. 12 11
      cfc-frontend/pages/tianpan/member-detail.vue
  69. 2 1
      cfc-frontend/pages/wealth/components/DimensionSubDims.vue
  70. 1 1
      cfc-frontend/pages/wealth/components/WealthEnergyRing.vue
  71. 3 2
      cfc-frontend/pages/wealth/index.vue
  72. 13 12
      cfc-frontend/pages/wisdom-detail/index.vue
  73. 40 0
      cfc-frontend/scripts/d31-fix-template-refs.js
  74. 105 0
      cfc-frontend/scripts/d31-script-hex-harvest.js
  75. 2 0
      cfc-frontend/utils/brand-colors.js

+ 2 - 1
cfc-frontend/components/ConfigurableGuide.vue

@@ -39,6 +39,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../utils/brand-colors.js'
 export default {
 export default {
   name: 'ConfigurableGuide',
   name: 'ConfigurableGuide',
   props: {
   props: {
@@ -58,7 +59,7 @@ export default {
     description() { return this.popup && this.popup.description ? this.popup.description : '' },
     description() { return this.popup && this.popup.description ? this.popup.description : '' },
     icon() { return this.popup && this.popup.icon ? this.popup.icon : '' },
     icon() { return this.popup && this.popup.icon ? this.popup.icon : '' },
     iconType() { return this.popup && this.popup.iconType !== undefined ? this.popup.iconType : 0 },
     iconType() { return this.popup && this.popup.iconType !== undefined ? this.popup.iconType : 0 },
-    themeColor() { return this.popup && this.popup.themeColor ? this.popup.themeColor : '#F97316' },
+    themeColor() { return this.popup && this.popup.themeColor ? this.popup.themeColor : BrandColors.primary },
     steps() { return this.isMulti ? this.popup.steps : [] },
     steps() { return this.isMulti ? this.popup.steps : [] },
     currentStepObj() {
     currentStepObj() {
       if (!this.isMulti) return {}
       if (!this.isMulti) return {}

+ 10 - 10
cfc-frontend/components/ContentSharePoster.vue

@@ -130,7 +130,7 @@ export default {
       // 选中的管理端模板 id(未使用管理端模板时为 null)
       // 选中的管理端模板 id(未使用管理端模板时为 null)
       activeTemplateId: null,
       activeTemplateId: null,
       // 可选的背景色(渐变模板下展示)
       // 可选的背景色(渐变模板下展示)
-      bgColors: ['BrandColors.body', 'BrandColors.wisdom', '#F59E0B', 'BrandColors.success', '#FF6B9D', '#1E293B', 'BrandColors.white']
+      bgColors: ['BrandColors.body', 'BrandColors.wisdom', BrandColors.wealth, 'BrandColors.success', BrandColors.mind, '#1E293B', 'BrandColors.white']
     }
     }
   },
   },
   methods: {
   methods: {
@@ -180,18 +180,18 @@ export default {
       if (tpl) {
       if (tpl) {
         return {
         return {
           main: tpl.mainColor || 'BrandColors.primary',
           main: tpl.mainColor || 'BrandColors.primary',
-          dark: tpl.darkColor || '#EA580C',
+          dark: tpl.darkColor || BrandColors.orangeDeep,
           light: tpl.lightColor || 'BrandColors.primaryPale'
           light: tpl.lightColor || 'BrandColors.primaryPale'
         }
         }
       }
       }
       var map = {
       var map = {
-        body: { main: 'BrandColors.body', dark: '#EA580C', light: 'BrandColors.primaryPale' },
-        mind: { main: '#FF6B9D', dark: '#DB2777', light: '#FDF2F8' },
+        body: { main: 'BrandColors.body', dark: BrandColors.orangeDeep, light: 'BrandColors.primaryPale' },
+        mind: { main: BrandColors.mind, dark: '#DB2777', light: '#FDF2F8' },
         wisdom: { main: 'BrandColors.wisdom', dark: '#4F46E5', light: '#EEF2FF' },
         wisdom: { main: 'BrandColors.wisdom', dark: '#4F46E5', light: '#EEF2FF' },
         action: { main: 'BrandColors.success', dark: '#059669', light: '#ECFDF5' },
         action: { main: 'BrandColors.success', dark: '#059669', light: '#ECFDF5' },
-        wealth: { main: '#F59E0B', dark: '#D97706', light: '#FFFBEB' }
+        wealth: { main: BrandColors.wealth, dark: '#D97706', light: '#FFFBEB' }
       }
       }
-      return map[this.dimensionCode] || { main: 'BrandColors.primary', dark: '#EA580C', light: 'BrandColors.primaryPale' }
+      return map[this.dimensionCode] || { main: 'BrandColors.primary', dark: BrandColors.orangeDeep, light: 'BrandColors.primaryPale' }
     },
     },
     // 海报模板配色
     // 海报模板配色
     getTemplateConfig() {
     getTemplateConfig() {
@@ -342,7 +342,7 @@ export default {
 
 
     _drawTopDecoration(ctx, w, colors) {
     _drawTopDecoration(ctx, w, colors) {
       var centerX = w / 2
       var centerX = w / 2
-      var dotColors = ['BrandColors.body', 'BrandColors.wisdom', '#F59E0B', 'BrandColors.success', '#FF6B9D']
+      var dotColors = ['BrandColors.body', 'BrandColors.wisdom', BrandColors.wealth, 'BrandColors.success', BrandColors.mind]
       var dotY = 28
       var dotY = 28
       var dotR = 5
       var dotR = 5
       var dotSpacing = 26
       var dotSpacing = 26
@@ -487,7 +487,7 @@ export default {
       this._roundRect(ctx, x, y, w, h, 8)
       this._roundRect(ctx, x, y, w, h, 8)
       ctx.fill()
       ctx.fill()
 
 
-      var dotColors = ['BrandColors.body', 'BrandColors.wisdom', '#F59E0B', 'BrandColors.success', '#FF6B9D']
+      var dotColors = ['BrandColors.body', 'BrandColors.wisdom', BrandColors.wealth, 'BrandColors.success', BrandColors.mind]
       var centerX = x + w / 2
       var centerX = x + w / 2
       for (var i = 0; i < 5; i++) {
       for (var i = 0; i < 5; i++) {
         ctx.setFillStyle(dotColors[i])
         ctx.setFillStyle(dotColors[i])
@@ -680,7 +680,7 @@ export default {
       ctx.setTextBaseline('top')
       ctx.setTextBaseline('top')
       ctx.fillText(this.ctaText || '长按识别二维码 · 查看详情', centerX, bottomY)
       ctx.fillText(this.ctaText || '长按识别二维码 · 查看详情', centerX, bottomY)
 
 
-      var dotColors = ['BrandColors.body', 'BrandColors.wisdom', '#F59E0B', 'BrandColors.success', '#FF6B9D']
+      var dotColors = ['BrandColors.body', 'BrandColors.wisdom', BrandColors.wealth, 'BrandColors.success', BrandColors.mind]
       var dotY = h - 22
       var dotY = h - 22
       var dotR = 4
       var dotR = 4
       var dotSpacing = 20
       var dotSpacing = 20
@@ -765,7 +765,7 @@ export default {
   }
   }
 }
 }
 </script>
 </script>
-import { body, primary, primaryPale, success, white, wisdom } from '@/utils/brand-colors.js'
+import { body, primary, primaryPale, success, white, wisdom, BrandColors } from '@/utils/brand-colors.js'
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">
 .poster-overlay {
 .poster-overlay {

+ 6 - 5
cfc-frontend/components/DimensionActivities.vue

@@ -87,16 +87,17 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../utils/brand-colors.js'
 import config from '@/config.js'
 import config from '@/config.js'
 import { parseDate } from '@/utils/format.js'
 import { parseDate } from '@/utils/format.js'
 import { getMyMembership, getActivityList } from '@/utils/api.js'
 import { getMyMembership, getActivityList } from '@/utils/api.js'
 
 
 var DIMENSION_MAP = {
 var DIMENSION_MAP = {
-  body: { name: '身', color: '#FF8C42', icon: '🌏' },
-  mind: { name: '心', color: '#FF6B9D', icon: '🔥' },
-  wisdom: { name: '智', color: '#6366F1', icon: '⚡' },
-  action: { name: '行', color: '#10B981', icon: '🌿' },
-  wealth: { name: '富', color: '#F59E0B', icon: '💧' }
+  body: { name: '身', color: BrandColors.body, icon: '🌏' },
+  mind: { name: '心', color: BrandColors.mind, icon: '🔥' },
+  wisdom: { name: '智', color: BrandColors.wisdom, icon: '⚡' },
+  action: { name: '行', color: BrandColors.success, icon: '🌿' },
+  wealth: { name: '富', color: BrandColors.wealth, icon: '💧' }
 }
 }
 
 
 export default {
 export default {

+ 6 - 5
cfc-frontend/components/DimensionArticles.vue

@@ -50,13 +50,14 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../utils/brand-colors.js'
 import { getRecommendedArticles } from '@/utils/api.js'
 import { getRecommendedArticles } from '@/utils/api.js'
 var DIMENSION_MAP = {
 var DIMENSION_MAP = {
-  body: { name: '身', color: '#FF8C42' },
-  mind: { name: '心', color: '#FF6B9D' },
-  wisdom: { name: '智', color: '#6366F1' },
-  action: { name: '行', color: '#10B981' },
-  wealth: { name: '富', color: '#F59E0B' }
+  body: { name: '身', color: BrandColors.body },
+  mind: { name: '心', color: BrandColors.mind },
+  wisdom: { name: '智', color: BrandColors.wisdom },
+  action: { name: '行', color: BrandColors.success },
+  wealth: { name: '富', color: BrandColors.wealth }
 }
 }
 
 
 var defaultGradientColors = [
 var defaultGradientColors = [

+ 6 - 5
cfc-frontend/components/DimensionIntroCard.vue

@@ -20,12 +20,13 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../utils/brand-colors.js'
 var DIM_CONFIG = {
 var DIM_CONFIG = {
-  body:    { icon: '🌏', name: '身', subtitle: '科学管理全家健康数据', features: ['七维雷达图', '健康报告解读', '能量打卡', '精准营养方案'], gradient: 'linear-gradient(135deg, #FFF7ED, rgba(255,140,66,0.12))', color: '#FF8C42' },
-  mind:    { icon: '🔥', name: '心', subtitle: '关注全家心理健康与情绪成长', features: ['EMI心理测评', '情绪趋势追踪', '家庭天盘', '疏导工具'], gradient: 'linear-gradient(135deg, #FFF0F5, rgba(255,107,157,0.12))', color: '#FF6B9D' },
-  wisdom:  { icon: '⚡', name: '智', subtitle: '提升全家认知能力与学习效率', features: ['认知雷达图', '认知训练', '测评预约', '成长记录'], gradient: 'linear-gradient(135deg, #F0F0FF, rgba(99,102,241,0.12))', color: '#6366F1' },
-  action:  { icon: '🌿', name: '行', subtitle: '改善全家关系与沟通能力', features: ['关系质量问卷', '互动记录', '任务协作', '家庭挑战'], gradient: 'linear-gradient(135deg, #F0FFF4, rgba(16,185,129,0.12))', color: '#10B981' },
-  wealth:  { icon: '💧', name: '富', subtitle: '分享价值,收获财富', features: ['财富能量仪表盘', '推广收益统计', '邀请返利', '会员权益'], gradient: 'linear-gradient(135deg, #FFFBEB, rgba(245,158,11,0.12))', color: '#F59E0B' }
+  body:    { icon: '🌏', name: '身', subtitle: '科学管理全家健康数据', features: ['七维雷达图', '健康报告解读', '能量打卡', '精准营养方案'], gradient: 'linear-gradient(135deg, #FFF7ED, rgba(255,140,66,0.12))', color: BrandColors.body },
+  mind:    { icon: '🔥', name: '心', subtitle: '关注全家心理健康与情绪成长', features: ['EMI心理测评', '情绪趋势追踪', '家庭天盘', '疏导工具'], gradient: 'linear-gradient(135deg, #FFF0F5, rgba(255,107,157,0.12))', color: BrandColors.mind },
+  wisdom:  { icon: '⚡', name: '智', subtitle: '提升全家认知能力与学习效率', features: ['认知雷达图', '认知训练', '测评预约', '成长记录'], gradient: 'linear-gradient(135deg, #F0F0FF, rgba(99,102,241,0.12))', color: BrandColors.wisdom },
+  action:  { icon: '🌿', name: '行', subtitle: '改善全家关系与沟通能力', features: ['关系质量问卷', '互动记录', '任务协作', '家庭挑战'], gradient: 'linear-gradient(135deg, #F0FFF4, rgba(16,185,129,0.12))', color: BrandColors.success },
+  wealth:  { icon: '💧', name: '富', subtitle: '分享价值,收获财富', features: ['财富能量仪表盘', '推广收益统计', '邀请返利', '会员权益'], gradient: 'linear-gradient(135deg, #FFFBEB, rgba(245,158,11,0.12))', color: BrandColors.wealth }
 }
 }
 
 
 export default {
 export default {

+ 6 - 5
cfc-frontend/components/DimensionVisitorCard.vue

@@ -33,6 +33,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../utils/brand-colors.js'
 /**
 /**
  * 维度游客价值卡 —— 五维主页面登录前统一复用
  * 维度游客价值卡 —— 五维主页面登录前统一复用
  *
  *
@@ -44,11 +45,11 @@
  * 登录行为复用全局 mixin 的 openLoginSheet()(main.js 已全局注册)。
  * 登录行为复用全局 mixin 的 openLoginSheet()(main.js 已全局注册)。
  */
  */
 var DIM_TOKENS = {
 var DIM_TOKENS = {
-  body:   { main: '#FF8C42', soft: 'rgba(255, 140, 66, 0.15)',  icon: '🌿' },
-  mind:   { main: '#FF6B9D', soft: 'rgba(255, 107, 157, 0.15)', icon: '🔥' },
-  wisdom: { main: '#6366F1', soft: 'rgba(99, 102, 241, 0.15)',  icon: '⚡' },
-  action: { main: '#10B981', soft: 'rgba(16, 185, 129, 0.15)',  icon: '🤝' },
-  wealth: { main: '#F59E0B', soft: 'rgba(245, 158, 11, 0.15)',  icon: '💧' }
+  body:   { main: BrandColors.body, soft: 'rgba(255, 140, 66, 0.15)',  icon: '🌿' },
+  mind:   { main: BrandColors.mind, soft: 'rgba(255, 107, 157, 0.15)', icon: '🔥' },
+  wisdom: { main: BrandColors.wisdom, soft: 'rgba(99, 102, 241, 0.15)',  icon: '⚡' },
+  action: { main: BrandColors.success, soft: 'rgba(16, 185, 129, 0.15)',  icon: '🤝' },
+  wealth: { main: BrandColors.wealth, soft: 'rgba(245, 158, 11, 0.15)',  icon: '💧' }
 }
 }
 
 
 export default {
 export default {

+ 12 - 11
cfc-frontend/components/FamilyMemberCard.vue

@@ -46,6 +46,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../utils/brand-colors.js'
 export default {
 export default {
   props: {
   props: {
     member: { type: Object, required: true },
     member: { type: Object, required: true },
@@ -58,15 +59,15 @@ export default {
     },
     },
     relationColor: function() {
     relationColor: function() {
       var rel = this.member && this.member.relationship
       var rel = this.member && this.member.relationship
-      if (rel === '爸爸' || rel === '妈妈' || rel === '父亲' || rel === '母亲') return '#F97316'
-      if (rel === '儿子' || rel === '女儿') return '#0EA5E9'
-      if (rel === '爷爷' || rel === '奶奶' || rel === '外公' || rel === '外婆') return '#6B7280'
-      if (rel === '哥哥' || rel === '姐姐' || rel === '弟弟' || rel === '妹妹') return '#10B981'
-      if (this.member && this.member.isSpouse) return '#EC4899'
+      if (rel === '爸爸' || rel === '妈妈' || rel === '父亲' || rel === '母亲') return BrandColors.primary
+      if (rel === '儿子' || rel === '女儿') return BrandColors.infoSky
+      if (rel === '爷爷' || rel === '奶奶' || rel === '外公' || rel === '外婆') return BrandColors.textSlate
+      if (rel === '哥哥' || rel === '姐姐' || rel === '弟弟' || rel === '妹妹') return BrandColors.success
+      if (this.member && this.member.isSpouse) return BrandColors.pink
       var role = this.member && this.member.effectiveRole
       var role = this.member && this.member.effectiveRole
-      if (role === 'parent') return '#F97316'
-      if (role === 'child') return '#0EA5E9'
-      if (role === 'teacher') return '#8B5CF6'
+      if (role === 'parent') return BrandColors.primary
+      if (role === 'child') return BrandColors.infoSky
+      if (role === 'teacher') return BrandColors.violet
       return '#9CA3AF'
       return '#9CA3AF'
     },
     },
     // 关系现状三色点颜色:信任/亲密度/沟通(绿≥70 / 黄40-69 / 红<40 / 灰空)
     // 关系现状三色点颜色:信任/亲密度/沟通(绿≥70 / 黄40-69 / 红<40 / 灰空)
@@ -78,9 +79,9 @@ export default {
       return keys.map(function(k) {
       return keys.map(function(k) {
         var v = Number(m[k]) || 0
         var v = Number(m[k]) || 0
         if (v <= 0) return empty
         if (v <= 0) return empty
-        if (v >= 70) return '#10B981'
-        if (v >= 40) return '#F59E0B'
-        return '#EF4444'
+        if (v >= 70) return BrandColors.success
+        if (v >= 40) return BrandColors.wealth
+        return BrandColors.danger
       })
       })
     }
     }
   },
   },

+ 10 - 9
cfc-frontend/components/FamilyRelationGraph.vue

@@ -26,6 +26,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../utils/brand-colors.js'
 /**
 /**
  * FamilyRelationGraph - 全 Canvas force-directed 家庭关系图
  * FamilyRelationGraph - 全 Canvas force-directed 家庭关系图
  *
  *
@@ -112,17 +113,17 @@ export default {
 
 
       // 主题色
       // 主题色
       themeColors: {
       themeColors: {
-        body: '#8D6E63',
-        mind: '#FF6B35',
-        action: '#4CAF50',
-        home: '#F97316',
+        body: BrandColors.brownWarm,
+        mind: BrandColors.mindAccent,
+        action: BrandColors.matGreen,
+        home: BrandColors.primary,
         wisdom: '#FFD700'
         wisdom: '#FFD700'
       }
       }
     }
     }
   },
   },
   computed: {
   computed: {
     themeColor: function() {
     themeColor: function() {
-      return this.themeColors[this.dimensionCode] || '#8D6E63'
+      return this.themeColors[this.dimensionCode] || BrandColors.brownWarm
     },
     },
 
 
     // ⚙ 提示位置(跟随自身节点偏移)
     // ⚙ 提示位置(跟随自身节点偏移)
@@ -609,7 +610,7 @@ simulationTick: function() {
 
 
         // 填充 + 描边
         // 填充 + 描边
         if (node.isSelf) {
         if (node.isSelf) {
-          ctx.fillStyle = '#FFFFFF'
+          ctx.fillStyle = BrandColors.white
           ctx.fill()
           ctx.fill()
           ctx.strokeStyle = this.themeColor
           ctx.strokeStyle = this.themeColor
           ctx.lineWidth = 3
           ctx.lineWidth = 3
@@ -627,7 +628,7 @@ simulationTick: function() {
         ctx.fillText(node.displayName, node.x, node.y)
         ctx.fillText(node.displayName, node.x, node.y)
 
 
         // 昵称
         // 昵称
-        ctx.fillStyle = node.isSelf ? this.themeColor : '#94A3B8'
+        ctx.fillStyle = node.isSelf ? this.themeColor : BrandColors.appTextSubtle
         ctx.font = (r * 0.4) + 'px sans-serif'
         ctx.font = (r * 0.4) + 'px sans-serif'
         ctx.fillText(node.nickname.substring(0, 3), node.x, node.y + r + 10)
         ctx.fillText(node.nickname.substring(0, 3), node.x, node.y + r + 10)
       }
       }
@@ -724,7 +725,7 @@ simulationTick: function() {
         }
         }
 
 
         if (node.isSelf) {
         if (node.isSelf) {
-          ctx.setFillStyle('#FFFFFF')
+          ctx.setFillStyle(BrandColors.white)
           ctx.fill()
           ctx.fill()
           ctx.setStrokeStyle(this.themeColor)
           ctx.setStrokeStyle(this.themeColor)
           ctx.setLineWidth(3)
           ctx.setLineWidth(3)
@@ -740,7 +741,7 @@ simulationTick: function() {
         ctx.setTextBaseline('middle')
         ctx.setTextBaseline('middle')
         ctx.fillText(node.displayName, node.x, node.y)
         ctx.fillText(node.displayName, node.x, node.y)
 
 
-        ctx.setFillStyle(node.isSelf ? this.themeColor : '#94A3B8')
+        ctx.setFillStyle(node.isSelf ? this.themeColor : BrandColors.appTextSubtle)
         ctx.setFontSize(Math.max(9, Math.round(r * 0.4)))
         ctx.setFontSize(Math.max(9, Math.round(r * 0.4)))
         ctx.fillText((node.nickname || '').substring(0, 3), node.x, node.y + r + 10)
         ctx.fillText((node.nickname || '').substring(0, 3), node.x, node.y + r + 10)
       }
       }

+ 11 - 10
cfc-frontend/components/RadarChart.vue

@@ -32,6 +32,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../utils/brand-colors.js'
 /**
 /**
  * RadarChart - 六维雷达图 Canvas 组件
  * RadarChart - 六维雷达图 Canvas 组件
  *
  *
@@ -65,7 +66,7 @@ export default {
     /** 填充颜色(可选,默认暖橙) */
     /** 填充颜色(可选,默认暖橙) */
     fillColor: {
     fillColor: {
       type: String,
       type: String,
-      default: '#F97316'
+      default: BrandColors.primary
     },
     },
     /** 网格颜色(可选,默认浅灰) */
     /** 网格颜色(可选,默认浅灰) */
     gridColor: {
     gridColor: {
@@ -112,7 +113,7 @@ export default {
     /** 平均值标签颜色(可选,默认浅灰) */
     /** 平均值标签颜色(可选,默认浅灰) */
     avgLabelColor: {
     avgLabelColor: {
       type: String,
       type: String,
-      default: '#94A3B8'
+      default: BrandColors.appTextSubtle
     },
     },
     /** 人群位置分数 0-100(同龄同性常模 P50/P75 等),显示为蓝色虚线多边形 */
     /** 人群位置分数 0-100(同龄同性常模 P50/P75 等),显示为蓝色虚线多边形 */
     populationScores: {
     populationScores: {
@@ -124,7 +125,7 @@ export default {
     /** 人群位置颜色(可选,默认蓝色) */
     /** 人群位置颜色(可选,默认蓝色) */
     populationColor: {
     populationColor: {
       type: String,
       type: String,
-      default: '#3B82F6'
+      default: BrandColors.infoBlue
     },
     },
     /** 人群位置填充颜色(可选,默认蓝色半透明) */
     /** 人群位置填充颜色(可选,默认蓝色半透明) */
     populationFillColor: {
     populationFillColor: {
@@ -465,12 +466,12 @@ export default {
       ctx.closePath()
       ctx.closePath()
 
 
       // 实色半透明填充(微信 Canvas 2D 径向渐变 rgba 颜色停靠可能静默失败)
       // 实色半透明填充(微信 Canvas 2D 径向渐变 rgba 颜色停靠可能静默失败)
-      var baseColor = this.fillColor || '#F97316'
+      var baseColor = this.fillColor || BrandColors.primary
       ctx.fillStyle = this.hexToRgba(baseColor, 0.15)
       ctx.fillStyle = this.hexToRgba(baseColor, 0.15)
       ctx.fill()
       ctx.fill()
 
 
       // 描边
       // 描边
-      ctx.strokeStyle = this.fillColor || '#F97316'
+      ctx.strokeStyle = this.fillColor || BrandColors.primary
       ctx.lineWidth = 2.5
       ctx.lineWidth = 2.5
       ctx.stroke()
       ctx.stroke()
     },
     },
@@ -523,7 +524,7 @@ export default {
     _drawPopulationScoreArea: function(ctx, cx, cy, outerR, angles, n) {
     _drawPopulationScoreArea: function(ctx, cx, cy, outerR, angles, n) {
       var scores = this.populationScores
       var scores = this.populationScores
       if (!scores || scores.length < n) { return }
       if (!scores || scores.length < n) { return }
-      var color = this.populationColor || '#3B82F6'
+      var color = this.populationColor || BrandColors.infoBlue
 
 
       var points = []
       var points = []
       for (var i = 0; i < n; i++) {
       for (var i = 0; i < n; i++) {
@@ -563,8 +564,8 @@ export default {
       var scores = this._animScores
       var scores = this._animScores
       if (!scores || scores.length < n) { return }
       if (!scores || scores.length < n) { return }
 
 
-      ctx.fillStyle = this.fillColor || '#F97316'
-      ctx.shadowColor = this.hexToRgba(this.fillColor || '#F97316', 0.3)
+      ctx.fillStyle = this.fillColor || BrandColors.primary
+      ctx.shadowColor = this.hexToRgba(this.fillColor || BrandColors.primary, 0.3)
       ctx.shadowBlur = 6
       ctx.shadowBlur = 6
 
 
       for (var i = 0; i < n; i++) {
       for (var i = 0; i < n; i++) {
@@ -589,7 +590,7 @@ export default {
       if (!scores || scores.length < n) { return }
       if (!scores || scores.length < n) { return }
 
 
       ctx.font = '11px -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif'
       ctx.font = '11px -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif'
-      ctx.fillStyle = this.fillColor || '#F97316'
+      ctx.fillStyle = this.fillColor || BrandColors.primary
       ctx.textAlign = 'center'
       ctx.textAlign = 'center'
       ctx.textBaseline = 'middle'
       ctx.textBaseline = 'middle'
 
 
@@ -696,7 +697,7 @@ export default {
       if (!name) { return }
       if (!name) { return }
 
 
       ctx.font = 'bold 15px -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif'
       ctx.font = 'bold 15px -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif'
-      ctx.fillStyle = '#F97316'
+      ctx.fillStyle = BrandColors.primary
       ctx.textAlign = 'center'
       ctx.textAlign = 'center'
       ctx.textBaseline = 'middle'
       ctx.textBaseline = 'middle'
       ctx.fillText(name, cx, cy)
       ctx.fillText(name, cx, cy)

+ 5 - 4
cfc-frontend/components/TrendChart.vue

@@ -14,6 +14,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../utils/brand-colors.js'
 /**
 /**
  * TrendChart - 多序列折线图 Canvas 组件
  * TrendChart - 多序列折线图 Canvas 组件
  * 用法:<TrendChart :series="[{name,color,points:[{reportDate,value,unit}]}]" height="360" />
  * 用法:<TrendChart :series="[{name,color,points:[{reportDate,value,unit}]}]" height="360" />
@@ -145,7 +146,7 @@ export default {
       var seriesList = this._safeSeries(this.series)
       var seriesList = this._safeSeries(this.series)
       if (seriesList.length === 0) {
       if (seriesList.length === 0) {
         ctx.clearRect(0, 0, w, h)
         ctx.clearRect(0, 0, w, h)
-        ctx.fillStyle = '#94A3B8'
+        ctx.fillStyle = BrandColors.appTextSubtle
         ctx.font = '12px sans-serif'
         ctx.font = '12px sans-serif'
         ctx.textAlign = 'center'
         ctx.textAlign = 'center'
         ctx.fillText('暂无趋势数据', w / 2, h / 2)
         ctx.fillText('暂无趋势数据', w / 2, h / 2)
@@ -180,7 +181,7 @@ export default {
         ctx.stroke()
         ctx.stroke()
       }
       }
       // Y 轴刻度文字
       // Y 轴刻度文字
-      ctx.fillStyle = '#94A3B8'
+      ctx.fillStyle = BrandColors.appTextSubtle
       ctx.font = '10px sans-serif'
       ctx.font = '10px sans-serif'
       ctx.textAlign = 'right'
       ctx.textAlign = 'right'
       for (var ti = 0; ti <= 3; ti++) {
       for (var ti = 0; ti <= 3; ti++) {
@@ -189,7 +190,7 @@ export default {
         ctx.fillText(self._fmtNum(tv), padL - 4, ty + 3)
         ctx.fillText(self._fmtNum(tv), padL - 4, ty + 3)
       }
       }
       // 折线 + 数据点 + 数值
       // 折线 + 数据点 + 数值
-      var palette = ['#F97316', '#0EA5E9', '#10B981', '#8B5CF6', '#EF4444', '#F59E0B']
+      var palette = [BrandColors.primary, BrandColors.infoSky, BrandColors.success, BrandColors.violet, BrandColors.danger, BrandColors.wealth]
       seriesList.forEach(function(s, si) {
       seriesList.forEach(function(s, si) {
         var color = s.color || palette[si % palette.length]
         var color = s.color || palette[si % palette.length]
         ctx.strokeStyle = color
         ctx.strokeStyle = color
@@ -227,7 +228,7 @@ export default {
         }
         }
       })
       })
       // X 轴日期标签(首/中/末)
       // X 轴日期标签(首/中/末)
-      ctx.fillStyle = '#94A3B8'
+      ctx.fillStyle = BrandColors.appTextSubtle
       ctx.font = '10px sans-serif'
       ctx.font = '10px sans-serif'
       ctx.textAlign = 'center'
       ctx.textAlign = 'center'
       if (allDates.length > 0) {
       if (allDates.length > 0) {

+ 6 - 5
cfc-frontend/components/tab-transition.vue

@@ -16,12 +16,13 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../utils/brand-colors.js'
 var DIM_MAP = {
 var DIM_MAP = {
-  action:  { char: '行', icon: '🌿', color: '#10B981', label: '人际和谐' },
-  body:    { char: '身', icon: '🌏', color: '#8D6E63', label: '根基永因' },
-  wisdom:  { char: '智', icon: '⚡', color: '#6366F1', label: '赋能未来' },
-  mind:    { char: '心', icon: '🔥', color: '#FF6B9D', label: '大爱传承' },
-  wealth:  { char: '富', icon: '💧', color: '#F59E0B', label: '利他创富' }
+  action:  { char: '行', icon: '🌿', color: BrandColors.success, label: '人际和谐' },
+  body:    { char: '身', icon: '🌏', color: BrandColors.brownWarm, label: '根基永因' },
+  wisdom:  { char: '智', icon: '⚡', color: BrandColors.wisdom, label: '赋能未来' },
+  mind:    { char: '心', icon: '🔥', color: BrandColors.mind, label: '大爱传承' },
+  wealth:  { char: '富', icon: '💧', color: BrandColors.wealth, label: '利他创富' }
 }
 }
 
 
 export default {
 export default {

+ 8 - 7
cfc-frontend/pages/action-detail/components/AbilityDiagram.vue

@@ -46,6 +46,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../../utils/brand-colors.js'
 /**
 /**
  * AbilityDiagram - 能力图 Canvas 组件
  * AbilityDiagram - 能力图 Canvas 组件
  *
  *
@@ -100,7 +101,7 @@ export default {
       _destroyed: false,
       _destroyed: false,
       _canvasRect: null,
       _canvasRect: null,
       // 节点颜色:技能统一金色
       // 节点颜色:技能统一金色
-      skillColor: '#F59E0B',
+      skillColor: BrandColors.wealth,
       // 边颜色
       // 边颜色
       edgeColor: '#CBD5E1'
       edgeColor: '#CBD5E1'
     }
     }
@@ -357,14 +358,14 @@ export default {
         // 中心节点:实心圆 + "我" 字
         // 中心节点:实心圆 + "我" 字
         ctx.beginPath()
         ctx.beginPath()
         ctx.arc(x, y, r, 0, Math.PI * 2)
         ctx.arc(x, y, r, 0, Math.PI * 2)
-        ctx.fillStyle = '#10B981'
+        ctx.fillStyle = BrandColors.success
         ctx.fill()
         ctx.fill()
-        ctx.strokeStyle = '#FFFFFF'
+        ctx.strokeStyle = BrandColors.white
         ctx.lineWidth = 2
         ctx.lineWidth = 2
         ctx.stroke()
         ctx.stroke()
 
 
         ctx.font = 'bold 18px PingFang SC, sans-serif'
         ctx.font = 'bold 18px PingFang SC, sans-serif'
-        ctx.fillStyle = '#FFFFFF'
+        ctx.fillStyle = BrandColors.white
         ctx.textAlign = 'center'
         ctx.textAlign = 'center'
         ctx.textBaseline = 'middle'
         ctx.textBaseline = 'middle'
         ctx.fillText('我', x, y + 1)
         ctx.fillText('我', x, y + 1)
@@ -376,13 +377,13 @@ export default {
         ctx.fill()
         ctx.fill()
 
 
         // 白边
         // 白边
-        ctx.strokeStyle = '#FFFFFF'
+        ctx.strokeStyle = BrandColors.white
         ctx.lineWidth = 2
         ctx.lineWidth = 2
         ctx.stroke()
         ctx.stroke()
 
 
         // 首字(先画兜底,头像加载成功后覆盖)
         // 首字(先画兜底,头像加载成功后覆盖)
         ctx.font = 'bold ' + Math.max(14, r * 0.7) + 'px PingFang SC, sans-serif'
         ctx.font = 'bold ' + Math.max(14, r * 0.7) + 'px PingFang SC, sans-serif'
-        ctx.fillStyle = '#FFFFFF'
+        ctx.fillStyle = BrandColors.white
         ctx.textAlign = 'center'
         ctx.textAlign = 'center'
         ctx.textBaseline = 'middle'
         ctx.textBaseline = 'middle'
         ctx.fillText(node.displayName, x, y + 1)
         ctx.fillText(node.displayName, x, y + 1)
@@ -403,7 +404,7 @@ export default {
             // 重绘白边(覆盖裁剪边缘)
             // 重绘白边(覆盖裁剪边缘)
             ctx2.beginPath()
             ctx2.beginPath()
             ctx2.arc(x, y, r, 0, Math.PI * 2)
             ctx2.arc(x, y, r, 0, Math.PI * 2)
-            ctx2.strokeStyle = '#FFFFFF'
+            ctx2.strokeStyle = BrandColors.white
             ctx2.lineWidth = 2
             ctx2.lineWidth = 2
             ctx2.stroke()
             ctx2.stroke()
           }
           }

+ 2 - 1
cfc-frontend/pages/action-detail/components/DimensionSubDims.vue

@@ -39,12 +39,13 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../../utils/brand-colors.js'
 export default {
 export default {
   name: 'DimensionSubDims',
   name: 'DimensionSubDims',
   props: {
   props: {
     title: { type: String, default: '维度评分' },
     title: { type: String, default: '维度评分' },
     subtitle: { type: String, default: '' },
     subtitle: { type: String, default: '' },
-    accentColor: { type: String, default: '#6366F1' },
+    accentColor: { type: String, default: BrandColors.wisdom },
     dims: { type: Array, default: () => [] }
     dims: { type: Array, default: () => [] }
   },
   },
   methods: {
   methods: {

+ 9 - 8
cfc-frontend/pages/action-detail/components/OctopusDiagram.vue

@@ -53,6 +53,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../../utils/brand-colors.js'
 /**
 /**
  * OctopusDiagram - 章鱼图(关键人拓展)
  * OctopusDiagram - 章鱼图(关键人拓展)
  *
  *
@@ -89,8 +90,8 @@ export default {
       // 关键人缓存(effectId -> [{...}])
       // 关键人缓存(effectId -> [{...}])
       keyPersons: {},
       keyPersons: {},
       // 颜色
       // 颜色
-      effectColors: { '金额大': '#F97316', '频次高': '#F59E0B', '新成交': '#10B981' },
-      expansionColor: '#6366F1'
+      effectColors: { '金额大': BrandColors.primary, '频次高': BrandColors.wealth, '新成交': BrandColors.success },
+      expansionColor: BrandColors.wisdom
     }
     }
   },
   },
   computed: {
   computed: {
@@ -267,17 +268,17 @@ export default {
       var r = 30
       var r = 30
       ctx.beginPath()
       ctx.beginPath()
       ctx.arc(cx, cy, r + 4, 0, Math.PI * 2)
       ctx.arc(cx, cy, r + 4, 0, Math.PI * 2)
-      ctx.fillStyle = this._hexToRgba('#10B981', 0.15)
+      ctx.fillStyle = this._hexToRgba(BrandColors.success, 0.15)
       ctx.fill()
       ctx.fill()
       ctx.beginPath()
       ctx.beginPath()
       ctx.arc(cx, cy, r, 0, Math.PI * 2)
       ctx.arc(cx, cy, r, 0, Math.PI * 2)
-      ctx.fillStyle = '#10B981'
+      ctx.fillStyle = BrandColors.success
       ctx.fill()
       ctx.fill()
-      ctx.strokeStyle = '#FFFFFF'
+      ctx.strokeStyle = BrandColors.white
       ctx.lineWidth = 3
       ctx.lineWidth = 3
       ctx.stroke()
       ctx.stroke()
       ctx.font = 'bold 18px PingFang SC, sans-serif'
       ctx.font = 'bold 18px PingFang SC, sans-serif'
-      ctx.fillStyle = '#FFFFFF'
+      ctx.fillStyle = BrandColors.white
       ctx.textAlign = 'center'
       ctx.textAlign = 'center'
       ctx.textBaseline = 'middle'
       ctx.textBaseline = 'middle'
       ctx.fillText('我', cx, cy + 1)
       ctx.fillText('我', cx, cy + 1)
@@ -295,12 +296,12 @@ export default {
       ctx.arc(x, y, r, 0, Math.PI * 2)
       ctx.arc(x, y, r, 0, Math.PI * 2)
       ctx.fillStyle = node.color
       ctx.fillStyle = node.color
       ctx.fill()
       ctx.fill()
-      ctx.strokeStyle = '#FFFFFF'
+      ctx.strokeStyle = BrandColors.white
       ctx.lineWidth = 2
       ctx.lineWidth = 2
       ctx.stroke()
       ctx.stroke()
       // 首字符
       // 首字符
       ctx.font = 'bold ' + Math.max(14, r * 0.7) + 'px PingFang SC, sans-serif'
       ctx.font = 'bold ' + Math.max(14, r * 0.7) + 'px PingFang SC, sans-serif'
-      ctx.fillStyle = '#FFFFFF'
+      ctx.fillStyle = BrandColors.white
       ctx.textAlign = 'center'
       ctx.textAlign = 'center'
       ctx.textBaseline = 'middle'
       ctx.textBaseline = 'middle'
       ctx.fillText(node.displayName, x, y + 1)
       ctx.fillText(node.displayName, x, y + 1)

+ 2 - 1
cfc-frontend/pages/action-detail/contact-detail.vue

@@ -111,6 +111,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getContactDetail, updateContact, deleteContact, recordContactInteraction } from '../../utils/api.js'
 import { getContactDetail, updateContact, deleteContact, recordContactInteraction } from '../../utils/api.js'
 
 
 export default {
 export default {
@@ -130,7 +131,7 @@ export default {
       return this.contact.name ? this.contact.name[0] : '?'
       return this.contact.name ? this.contact.name[0] : '?'
     },
     },
     avatarColor: function() {
     avatarColor: function() {
-      var colors = ['#FF6B35', '#667eea', '#10B981', '#F59E0B', '#8B5CF6', '#EC4899']
+      var colors = [BrandColors.mindAccent, '#667eea', BrandColors.success, BrandColors.wealth, BrandColors.violet, BrandColors.pink]
       var idx = (this.contact.id || 0) % colors.length
       var idx = (this.contact.id || 0) % colors.length
       return colors[idx]
       return colors[idx]
     },
     },

+ 13 - 12
cfc-frontend/pages/action-detail/index.vue

@@ -96,7 +96,7 @@
       v-if="isLoggedIn && actionSubDims.length > 0"
       v-if="isLoggedIn && actionSubDims.length > 0"
       title="🌲 关系六维"
       title="🌲 关系六维"
       subtitle="家庭关系的六个方面"
       subtitle="家庭关系的六个方面"
-      accent-color="#10B981"
+      accent-color=#10B981
       :dims="actionSubDims" />
       :dims="actionSubDims" />
 
 
     <!-- 登录后:家庭关系(行维度核心) -->
     <!-- 登录后:家庭关系(行维度核心) -->
@@ -194,7 +194,7 @@
         :scores="actionScores"
         :scores="actionScores"
         :avg-scores="actionFamilyScores"
         :avg-scores="actionFamilyScores"
         :population-scores="actionPopulationScores"
         :population-scores="actionPopulationScores"
-        fillColor="#10B981"
+        fillColor=#10B981
         gridColor="#D1FAE5"
         gridColor="#D1FAE5"
         labelColor="#065F46"
         labelColor="#065F46"
         :width="580"
         :width="580"
@@ -256,6 +256,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import TabTransition from '../../components/tab-transition.vue'
 import TabTransition from '../../components/tab-transition.vue'
 import PageBanner from '../../components/PageBanner.vue'
 import PageBanner from '../../components/PageBanner.vue'
 import FamilyEnergyBar from '../../components/FamilyEnergyBar.vue'
 import FamilyEnergyBar from '../../components/FamilyEnergyBar.vue'
@@ -465,19 +466,19 @@ export default {
       var role = this.role || uni.getStorageSync('currentRole') || ''
       var role = this.role || uni.getStorageSync('currentRole') || ''
       var isParent = (role === 'parent')
       var isParent = (role === 'parent')
       var parentDims = [
       var parentDims = [
-        { key: 'actionParentChild', label: '亲子关系', color: '#10B981', desc: '与子女的沟通与陪伴质量' },
-        { key: 'actionMarital', label: '夫妻关系', color: '#FF6B9D', desc: '夫妻间的理解与支持' },
-        { key: 'actionParental', label: '父母关系', color: '#F59E0B', desc: '与长辈的相处模式' },
-        { key: 'actionLeadership', label: '领导关系', color: '#6366F1', desc: '职场上下级沟通能力' },
-        { key: 'actionSociality', label: '社会性', color: '#FF8C42', desc: '社会交往与参与度' },
+        { key: 'actionParentChild', label: '亲子关系', color: BrandColors.success, desc: '与子女的沟通与陪伴质量' },
+        { key: 'actionMarital', label: '夫妻关系', color: BrandColors.mind, desc: '夫妻间的理解与支持' },
+        { key: 'actionParental', label: '父母关系', color: BrandColors.wealth, desc: '与长辈的相处模式' },
+        { key: 'actionLeadership', label: '领导关系', color: BrandColors.wisdom, desc: '职场上下级沟通能力' },
+        { key: 'actionSociality', label: '社会性', color: BrandColors.body, desc: '社会交往与参与度' },
         { key: 'actionInterpersonal', label: '人际韧性', color: '#06B6D4', desc: '应对人际关系挫折的能力' }
         { key: 'actionInterpersonal', label: '人际韧性', color: '#06B6D4', desc: '应对人际关系挫折的能力' }
       ]
       ]
       var childDims = [
       var childDims = [
-        { key: 'actionChildParentChild', label: '亲子关系', color: '#10B981', desc: '与父母的互动质量' },
-        { key: 'actionSibling', label: '同胞关系', color: '#FF6B9D', desc: '兄弟姐妹间的关系' },
-        { key: 'actionRelative', label: '亲属关系', color: '#F59E0B', desc: '与亲戚的交往频率' },
-        { key: 'actionTeacherStudent', label: '师生关系', color: '#6366F1', desc: '与老师的沟通情况' },
-        { key: 'actionChildSociality', label: '社会性', color: '#FF8C42', desc: '学校与社会参与度' },
+        { key: 'actionChildParentChild', label: '亲子关系', color: BrandColors.success, desc: '与父母的互动质量' },
+        { key: 'actionSibling', label: '同胞关系', color: BrandColors.mind, desc: '兄弟姐妹间的关系' },
+        { key: 'actionRelative', label: '亲属关系', color: BrandColors.wealth, desc: '与亲戚的交往频率' },
+        { key: 'actionTeacherStudent', label: '师生关系', color: BrandColors.wisdom, desc: '与老师的沟通情况' },
+        { key: 'actionChildSociality', label: '社会性', color: BrandColors.body, desc: '学校与社会参与度' },
         { key: 'actionChildInterpersonal', label: '人际韧性', color: '#06B6D4', desc: '应对社交困难的能力' }
         { key: 'actionChildInterpersonal', label: '人际韧性', color: '#06B6D4', desc: '应对社交困难的能力' }
       ]
       ]
       var dims = isParent ? parentDims : childDims
       var dims = isParent ? parentDims : childDims

+ 7 - 6
cfc-frontend/pages/activity/activity-detail/activity-detail.vue

@@ -281,6 +281,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../../utils/brand-colors.js'
 import { getActivityDetail, activityCheckin, cancelActivityRegistration, createActivityOrder, submitActivityFeedback, getActivityFeedbackList, getMyActivityFeedback, getFamilyMemberList, getShareQrCode, getMyMembership, getPosterTemplates } from '@/utils/api.js'
 import { getActivityDetail, activityCheckin, cancelActivityRegistration, createActivityOrder, submitActivityFeedback, getActivityFeedbackList, getMyActivityFeedback, getFamilyMemberList, getShareQrCode, getMyMembership, getPosterTemplates } from '@/utils/api.js'
 import config from '@/config.js'
 import config from '@/config.js'
 import shareMixin from '../../../components/share-mixin.js'
 import shareMixin from '../../../components/share-mixin.js'
@@ -760,13 +761,13 @@ export default {
     buildPosterBgColor: function() {
     buildPosterBgColor: function() {
       var dim = this.activity && this.activity.dimensionCode
       var dim = this.activity && this.activity.dimensionCode
       var map = {
       var map = {
-        body: '#FF8C42',
-        mind: '#FF6B9D',
-        wisdom: '#6366F1',
-        action: '#10B981',
-        wealth: '#F59E0B'
+        body: BrandColors.body,
+        mind: BrandColors.mind,
+        wisdom: BrandColors.wisdom,
+        action: BrandColors.success,
+        wealth: BrandColors.wealth
       }
       }
-      return map[dim] || '#F97316'
+      return map[dim] || BrandColors.primary
     },
     },
     closePoster: function() {
     closePoster: function() {
       this.showPoster = false
       this.showPoster = false

+ 2 - 2
cfc-frontend/pages/activity/create.vue

@@ -134,8 +134,8 @@
           @click="selectPosterTemplate(tpl)"
           @click="selectPosterTemplate(tpl)"
         >
         >
           <view class="tpl-colors">
           <view class="tpl-colors">
-            <view class="tpl-dot tpl-main" :style="{ background: tpl.mainColor || '#F97316' }"></view>
-            <view class="tpl-dot tpl-dark" :style="{ background: tpl.darkColor || '#EA580C' }"></view>
+            <view class="tpl-dot tpl-main" :style="{ background: tpl.mainColor || #F97316 }"></view>
+            <view class="tpl-dot tpl-dark" :style="{ background: tpl.darkColor || #EA580C }"></view>
             <view class="tpl-dot tpl-light" :style="{ background: tpl.lightColor || '#FFF7ED' }"></view>
             <view class="tpl-dot tpl-light" :style="{ background: tpl.lightColor || '#FFF7ED' }"></view>
           </view>
           </view>
           <text class="tpl-name">{{ tpl.name }}</text>
           <text class="tpl-name">{{ tpl.name }}</text>

+ 7 - 6
cfc-frontend/pages/ai/components/AITaskCard.vue

@@ -30,6 +30,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../../utils/brand-colors.js'
 export default {
 export default {
   name: 'TaskCard',
   name: 'TaskCard',
 
 
@@ -61,13 +62,13 @@ export default {
   computed: {
   computed: {
     dimensionColor: function() {
     dimensionColor: function() {
       var colorMap = {
       var colorMap = {
-        '身': '#10B981',
-        '心': '#F59E0B',
-        '智': '#3B82F6',
-        '行': '#8B5CF6',
-        '富': '#F97316'
+        '身': BrandColors.success,
+        '心': BrandColors.wealth,
+        '智': BrandColors.infoBlue,
+        '行': BrandColors.violet,
+        '富': BrandColors.primary
       }
       }
-      return colorMap[this.task.dimension] || '#F97316'
+      return colorMap[this.task.dimension] || BrandColors.primary
     }
     }
   },
   },
 
 

+ 2 - 1
cfc-frontend/pages/article-center/article-detail.vue

@@ -107,6 +107,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getArticleDetail, getArticleAudio, reportReadingTime, getShareQrCode, completeArticleRead, generateQuiz, submitQuiz, completeTask } from '@/utils/api.js'
 import { getArticleDetail, getArticleAudio, reportReadingTime, getShareQrCode, completeArticleRead, generateQuiz, submitQuiz, completeTask } from '@/utils/api.js'
 import shareMixin from '../../components/share-mixin.js'
 import shareMixin from '../../components/share-mixin.js'
 import ContentSharePoster from '@/components/ContentSharePoster.vue'
 import ContentSharePoster from '@/components/ContentSharePoster.vue'
@@ -226,7 +227,7 @@ export default {
       })
       })
     },
     },
     parseDimensions: function(article) {
     parseDimensions: function(article) {
-      var dimMap = { body: { code: 'body', color: '#FF8C42', name: '身' }, mind: { code: 'mind', color: '#FF6B9D', name: '心' }, wisdom: { code: 'wisdom', color: '#6366F1', name: '智' }, action: { code: 'action', color: '#10B981', name: '行' }, wealth: { code: 'wealth', color: '#F59E0B', name: '富' } }
+      var dimMap = { body: { code: 'body', color: BrandColors.body, name: '身' }, mind: { code: 'mind', color: BrandColors.mind, name: '心' }, wisdom: { code: 'wisdom', color: BrandColors.wisdom, name: '智' }, action: { code: 'action', color: BrandColors.success, name: '行' }, wealth: { code: 'wealth', color: BrandColors.wealth, name: '富' } }
       var raw = article && article.relatedDimensions ? article.relatedDimensions.split(',').map(function(s) { return s.trim().toLowerCase() }) : []
       var raw = article && article.relatedDimensions ? article.relatedDimensions.split(',').map(function(s) { return s.trim().toLowerCase() }) : []
       var weights = null
       var weights = null
       if (article && article.dimensionWeights) try { var w = JSON.parse(article.dimensionWeights); if (w && typeof w === 'object') weights = w } catch (e) {}
       if (article && article.dimensionWeights) try { var w = JSON.parse(article.dimensionWeights); if (w && typeof w === 'object') weights = w } catch (e) {}

+ 6 - 5
cfc-frontend/pages/article-center/article-edit.vue

@@ -96,6 +96,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { publishArticle } from '@/utils/api.js'
 import { publishArticle } from '@/utils/api.js'
 import config from '@/config.js'
 import config from '@/config.js'
 import { pickImage } from '@/utils/image-picker.js'
 import { pickImage } from '@/utils/image-picker.js'
@@ -110,11 +111,11 @@ export default {
       selectedDimensions: [],
       selectedDimensions: [],
       publishing: false,
       publishing: false,
       dimensionList: [
       dimensionList: [
-        { code: 'body', name: '身', color: '#FF8C42' },
-        { code: 'mind', name: '心', color: '#FF6B9D' },
-        { code: 'wisdom', name: '智', color: '#6366F1' },
-        { code: 'action', name: '行', color: '#10B981' },
-        { code: 'wealth', name: '富', color: '#F59E0B' }
+        { code: 'body', name: '身', color: BrandColors.body },
+        { code: 'mind', name: '心', color: BrandColors.mind },
+        { code: 'wisdom', name: '智', color: BrandColors.wisdom },
+        { code: 'action', name: '行', color: BrandColors.success },
+        { code: 'wealth', name: '富', color: BrandColors.wealth }
       ]
       ]
     }
     }
   },
   },

+ 12 - 11
cfc-frontend/pages/article-center/index.vue

@@ -136,6 +136,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getArticleList, getFeaturedArticles } from '@/utils/api.js'
 import { getArticleList, getFeaturedArticles } from '@/utils/api.js'
 import config from '@/config.js'
 import config from '@/config.js'
 import fontScaleMixin from '@/mixins/font-scale.js'
 import fontScaleMixin from '@/mixins/font-scale.js'
@@ -144,12 +145,12 @@ export default {
   data() {
   data() {
     return {
     return {
       tabList: [
       tabList: [
-        { code: '', name: '全部', color: '#F97316' },
-        { code: 'body', name: '身', color: '#FF8C42' },
-        { code: 'mind', name: '心', color: '#FF6B9D' },
-        { code: 'wisdom', name: '智', color: '#6366F1' },
-        { code: 'action', name: '行', color: '#10B981' },
-        { code: 'wealth', name: '富', color: '#F59E0B' }
+        { code: '', name: '全部', color: BrandColors.primary },
+        { code: 'body', name: '身', color: BrandColors.body },
+        { code: 'mind', name: '心', color: BrandColors.mind },
+        { code: 'wisdom', name: '智', color: BrandColors.wisdom },
+        { code: 'action', name: '行', color: BrandColors.success },
+        { code: 'wealth', name: '富', color: BrandColors.wealth }
       ],
       ],
       currentTab: '',
       currentTab: '',
       articles: [],
       articles: [],
@@ -292,11 +293,11 @@ onLoad(options) {
     parseDimensions(str) {
     parseDimensions(str) {
       if (!str) return []
       if (!str) return []
       var dimMap = {
       var dimMap = {
-        body: { code: 'body', color: '#FF8C42', name: '身' },
-        mind: { code: 'mind', color: '#FF6B9D', name: '心' },
-        wisdom: { code: 'wisdom', color: '#6366F1', name: '智' },
-        action: { code: 'action', color: '#10B981', name: '行' },
-        wealth: { code: 'wealth', color: '#F59E0B', name: '富' }
+        body: { code: 'body', color: BrandColors.body, name: '身' },
+        mind: { code: 'mind', color: BrandColors.mind, name: '心' },
+        wisdom: { code: 'wisdom', color: BrandColors.wisdom, name: '智' },
+        action: { code: 'action', color: BrandColors.success, name: '行' },
+        wealth: { code: 'wealth', color: BrandColors.wealth, name: '富' }
       }
       }
       var codes = str.split(',').map(function(s) { return s.trim().toLowerCase() })
       var codes = str.split(',').map(function(s) { return s.trim().toLowerCase() })
       return codes.filter(function(c) { return dimMap[c] }).map(function(c) { return dimMap[c] })
       return codes.filter(function(c) { return dimMap[c] }).map(function(c) { return dimMap[c] })

+ 3 - 2
cfc-frontend/pages/body-detail/dimension-detail.vue

@@ -77,6 +77,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getDimensionHistory, getDimensionOverview, getProductsByDomain } from '@/utils/api'
 import { getDimensionHistory, getDimensionOverview, getProductsByDomain } from '@/utils/api'
 import config from '@/config.js'
 import config from '@/config.js'
 
 
@@ -261,7 +262,7 @@ export default {
 
 
       // Line
       // Line
       if (points.length > 1) {
       if (points.length > 1) {
-        ctx.setStrokeStyle('#F97316')
+        ctx.setStrokeStyle(BrandColors.primary)
         ctx.setLineWidth(3)
         ctx.setLineWidth(3)
         ctx.beginPath()
         ctx.beginPath()
         ctx.moveTo(points[0].x, points[0].y)
         ctx.moveTo(points[0].x, points[0].y)
@@ -285,7 +286,7 @@ export default {
 
 
       // Dots
       // Dots
       for (var m = 0; m < points.length; m++) {
       for (var m = 0; m < points.length; m++) {
-        ctx.setFillStyle('#F97316')
+        ctx.setFillStyle(BrandColors.primary)
         ctx.beginPath()
         ctx.beginPath()
         ctx.arc(points[m].x, points[m].y, 5, 0, 2 * Math.PI)
         ctx.arc(points[m].x, points[m].y, 5, 0, 2 * Math.PI)
         ctx.fill()
         ctx.fill()

+ 3 - 2
cfc-frontend/pages/body-detail/health-dimensions.vue

@@ -116,6 +116,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getDimensionOverview, uploadDimensionScore } from '../../utils/api.js'
 import { getDimensionOverview, uploadDimensionScore } from '../../utils/api.js'
 
 
 export default {
 export default {
@@ -236,7 +237,7 @@ export default {
       }
       }
       ctx.closePath()
       ctx.closePath()
       ctx.setFillStyle('rgba(255, 140, 66, 0.15)')
       ctx.setFillStyle('rgba(255, 140, 66, 0.15)')
-      ctx.setStrokeStyle('#FF8C42')
+      ctx.setStrokeStyle(BrandColors.body)
       ctx.setLineWidth(2)
       ctx.setLineWidth(2)
       ctx.fill()
       ctx.fill()
       ctx.stroke()
       ctx.stroke()
@@ -249,7 +250,7 @@ export default {
 
 
         ctx.beginPath()
         ctx.beginPath()
         ctx.arc(dx, dy, 4, 0, Math.PI * 2)
         ctx.arc(dx, dy, 4, 0, Math.PI * 2)
-        ctx.setFillStyle('#FF8C42')
+        ctx.setFillStyle(BrandColors.body)
         ctx.fill()
         ctx.fill()
 
 
         var lR = maxR + 22
         var lR = maxR + 22

+ 1 - 1
cfc-frontend/pages/body-detail/index.vue

@@ -89,7 +89,7 @@
         :scores="radarScores"
         :scores="radarScores"
         :avg-scores="radarFamilyScores"
         :avg-scores="radarFamilyScores"
         :population-scores="radarPopulationScores"
         :population-scores="radarPopulationScores"
-        fillColor="#FF8C42"
+        fillColor=#FF8C42
         gridColor="#FED7AA"
         gridColor="#FED7AA"
         labelColor="#9A3412"
         labelColor="#9A3412"
         :width="580"
         :width="580"

+ 1 - 1
cfc-frontend/pages/child/rewards.vue

@@ -10,7 +10,7 @@
         <view class="reward-info">
         <view class="reward-info">
           <view class="reward-title">{{ reward.title }}</view>
           <view class="reward-title">{{ reward.title }}</view>
           <view class="reward-progress">
           <view class="reward-progress">
-            <progress :percent="reward.pointsRequired > 0 ? (currentPoints / reward.pointsRequired) * 100 : 0" stroke-width="6" activeColor="#F97316" backgroundColor="#eee" />
+            <progress :percent="reward.pointsRequired > 0 ? (currentPoints / reward.pointsRequired) * 100 : 0" stroke-width="6" activeColor=#F97316 backgroundColor="#eee" />
             <text class="progress-text">{{ currentPoints }}/{{ reward.pointsRequired }}积分</text>
             <text class="progress-text">{{ currentPoints }}/{{ reward.pointsRequired }}积分</text>
           </view>
           </view>
         </view>
         </view>

+ 1 - 1
cfc-frontend/pages/discover-detail/product-detail/product-detail.vue

@@ -6,7 +6,7 @@
       <text class="loading-text">加载中...</text>
       <text class="loading-text">加载中...</text>
     </view>
     </view>
     <scroll-view v-else-if="product.id" scroll-y class="content" @scrolltolower="onScrollToBottom">
     <scroll-view v-else-if="product.id" scroll-y class="content" @scrolltolower="onScrollToBottom">
-      <swiper class="cover-swiper" indicator-dots autoplay circular indicator-active-color="#F97316">
+      <swiper class="cover-swiper" indicator-dots autoplay circular indicator-active-color=#F97316>
         <swiper-item v-for="(img, idx) in displayImages" :key="idx">
         <swiper-item v-for="(img, idx) in displayImages" :key="idx">
           <image class="swiper-image" :src="getImageUrl(img)" mode="widthFix" @error="onSwiperImageError(idx)" />
           <image class="swiper-image" :src="getImageUrl(img)" mode="widthFix" @error="onSwiperImageError(idx)" />
         </swiper-item>
         </swiper-item>

+ 2 - 1
cfc-frontend/pages/discover/circle-feed.vue

@@ -145,6 +145,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getCircleFeed, getCircleMembers, createCirclePost, toggleCircleLike, addCircleComment, getCircleComments, deleteCirclePost } from '@/utils/api.js'
 import { getCircleFeed, getCircleMembers, createCirclePost, toggleCircleLike, addCircleComment, getCircleComments, deleteCirclePost } from '@/utils/api.js'
 import { parseDate } from '@/utils/format.js'
 import { parseDate } from '@/utils/format.js'
 import fontScaleMixin from '@/mixins/font-scale.js'
 import fontScaleMixin from '@/mixins/font-scale.js'
@@ -357,7 +358,7 @@ export default {
       uni.showModal({
       uni.showModal({
         title: '删除动态',
         title: '删除动态',
         content: '确定删除这条动态吗?删除后不可恢复。',
         content: '确定删除这条动态吗?删除后不可恢复。',
-        confirmColor: '#FF8C42',
+        confirmColor: BrandColors.body,
         success: function(res) {
         success: function(res) {
           if (!res.confirm) return
           if (!res.confirm) return
           post.deleting = true
           post.deleting = true

+ 1 - 1
cfc-frontend/pages/discover/create-circle.vue

@@ -48,7 +48,7 @@
         <view class="form-item">
         <view class="form-item">
           <view class="switch-row">
           <view class="switch-row">
             <text class="form-label">公开可见</text>
             <text class="form-label">公开可见</text>
-            <switch :checked="form.isPublic === 1" color="#FF8C42" @change="form.isPublic = $event.detail.value ? 1 : 0" />
+            <switch :checked="form.isPublic === 1" color=#FF8C42 @change="form.isPublic = $event.detail.value ? 1 : 0" />
           </view>
           </view>
           <text class="switch-desc">其他用户可以在发现页看到此圈子</text>
           <text class="switch-desc">其他用户可以在发现页看到此圈子</text>
         </view>
         </view>

+ 1 - 1
cfc-frontend/pages/family/add-member.vue

@@ -86,7 +86,7 @@
 <view class="form-item" v-if="isEdit && operatorAdmin">
 <view class="form-item" v-if="isEdit && operatorAdmin">
 <view class="admin-row">
 <view class="admin-row">
 <text class="admin-row-text">家庭管理员</text>
 <text class="admin-row-text">家庭管理员</text>
-<switch :checked="form.isAdmin === 1" color="#F97316" @change="onAdminChange" />
+<switch :checked="form.isAdmin === 1" color=#F97316 @change="onAdminChange" />
 </view>
 </view>
 <text class="hint">{{ form.isAdmin === 1 ? '管理员可查看/管理全家庭报告与成员' : '仅可查看本人报告' }}</text>
 <text class="hint">{{ form.isAdmin === 1 ? '管理员可查看/管理全家庭报告与成员' : '仅可查看本人报告' }}</text>
 </view>
 </view>

+ 6 - 5
cfc-frontend/pages/family/manual-score-entry.vue

@@ -42,6 +42,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getFamilyMemberList, submitManualScore } from '@/utils/api'
 import { getFamilyMemberList, submitManualScore } from '@/utils/api'
 
 
 export default {
 export default {
@@ -52,11 +53,11 @@ export default {
       selectedMemberId: null,
       selectedMemberId: null,
       scores: { body: 50, mind: 50, wisdom: 50, action: 50, wealth: 50 },
       scores: { body: 50, mind: 50, wisdom: 50, action: 50, wealth: 50 },
       dimensions: [
       dimensions: [
-        { code: 'body', label: '身', color: '#FF8C42' },
-        { code: 'mind', label: '心', color: '#FF6B9D' },
-        { code: 'wisdom', label: '智', color: '#6366F1' },
-        { code: 'action', label: '行', color: '#10B981' },
-        { code: 'wealth', label: '富', color: '#F59E0B' }
+        { code: 'body', label: '身', color: BrandColors.body },
+        { code: 'mind', label: '心', color: BrandColors.mind },
+        { code: 'wisdom', label: '智', color: BrandColors.wisdom },
+        { code: 'action', label: '行', color: BrandColors.success },
+        { code: 'wealth', label: '富', color: BrandColors.wealth }
       ],
       ],
       submitLoading: false
       submitLoading: false
     }
     }

+ 3 - 2
cfc-frontend/pages/family/mbti-profile.vue

@@ -42,6 +42,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getMbtiProfile } from '@/utils/api'
 import { getMbtiProfile } from '@/utils/api'
 
 
 export default {
 export default {
@@ -76,8 +77,8 @@ export default {
         pairing_notes: { label: '搭配建议' }
         pairing_notes: { label: '搭配建议' }
       },
       },
       dimLabels: { body: '身', mind: '心', wisdom: '智', action: '行', wealth: '富' },
       dimLabels: { body: '身', mind: '心', wisdom: '智', action: '行', wealth: '富' },
-      dimColors: { body: '#FF8C42', mind: '#FF6B9D', wisdom: '#6366F1', action: '#10B981', wealth: '#F59E0B' },
-      tagColorMap: { NT: '#6366F1', NF: '#FF6B9D', SJ: '#10B981', SP: '#F59E0B' }
+      dimColors: { body: BrandColors.body, mind: BrandColors.mind, wisdom: BrandColors.wisdom, action: BrandColors.success, wealth: BrandColors.wealth },
+      tagColorMap: { NT: BrandColors.wisdom, NF: BrandColors.mind, SJ: BrandColors.success, SP: BrandColors.wealth }
     }
     }
   },
   },
   methods: {
   methods: {

+ 4 - 3
cfc-frontend/pages/family/mbti-result.vue

@@ -45,6 +45,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getMbtiLatest } from '@/utils/api'
 import { getMbtiLatest } from '@/utils/api'
 
 
 export default {
 export default {
@@ -56,7 +57,7 @@ export default {
       canvasWidth: 340,
       canvasWidth: 340,
       canvasHeight: 340,
       canvasHeight: 340,
       dimLabels: { body: '身', mind: '心', wisdom: '智', action: '行', wealth: '富' },
       dimLabels: { body: '身', mind: '心', wisdom: '智', action: '行', wealth: '富' },
-      dimColors: { body: '#FF8C42', mind: '#FF6B9D', wisdom: '#6366F1', action: '#10B981', wealth: '#F59E0B' },
+      dimColors: { body: BrandColors.body, mind: BrandColors.mind, wisdom: BrandColors.wisdom, action: BrandColors.success, wealth: BrandColors.wealth },
       profileFields: {
       profileFields: {
         strengths: { label: '优势' },
         strengths: { label: '优势' },
         weaknesses: { label: '挑战' },
         weaknesses: { label: '挑战' },
@@ -115,7 +116,7 @@ export default {
       }
       }
 
 
       var labels = ['E/I', 'S/N', 'T/F', 'J/P']
       var labels = ['E/I', 'S/N', 'T/F', 'J/P']
-      var colors = ['#6366F1', '#10B981', '#FF6B9D', '#F59E0B']
+      var colors = [BrandColors.wisdom, BrandColors.success, BrandColors.mind, BrandColors.wealth]
       for (var j = 0; j < 4; j++) {
       for (var j = 0; j < 4; j++) {
         var a2 = j * angleStep - Math.PI / 2
         var a2 = j * angleStep - Math.PI / 2
         var lx = cx + r * Math.cos(a2), ly = cy + r * Math.sin(a2)
         var lx = cx + r * Math.cos(a2), ly = cy + r * Math.sin(a2)
@@ -143,7 +144,7 @@ export default {
       }
       }
       ctx.closePath()
       ctx.closePath()
       ctx.fillStyle = 'rgba(99,102,241,0.2)'; ctx.fill()
       ctx.fillStyle = 'rgba(99,102,241,0.2)'; ctx.fill()
-      ctx.strokeStyle = '#6366F1'; ctx.lineWidth = 2; ctx.stroke()
+      ctx.strokeStyle = BrandColors.wisdom; ctx.lineWidth = 2; ctx.stroke()
 
 
       for (var n = 0; n < 4; n++) {
       for (var n = 0; n < 4; n++) {
         var ang2 = n * angleStep - Math.PI / 2
         var ang2 = n * angleStep - Math.PI / 2

+ 4 - 3
cfc-frontend/pages/family/mbti-test.vue

@@ -4,7 +4,7 @@
       <text class="mbt-progress-text">{{ currentIndex + 1 }} / {{ questions.length }}</text>
       <text class="mbt-progress-text">{{ currentIndex + 1 }} / {{ questions.length }}</text>
     </view>
     </view>
     <view class="mbt-progress-bar">
     <view class="mbt-progress-bar">
-      <view class="mbt-progress-fill" :style="{ width: progress + '%', background: '#6366F1' }"></view>
+      <view class="mbt-progress-fill" :style="{ width: progress + '%', background: #6366F1 }"></view>
     </view>
     </view>
     <view class="mbt-loading" v-if="loading">
     <view class="mbt-loading" v-if="loading">
       <text>加载题库...</text>
       <text>加载题库...</text>
@@ -33,6 +33,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getMbtiQuestions, submitMbti } from '@/utils/api'
 import { getMbtiQuestions, submitMbti } from '@/utils/api'
 
 
 export default {
 export default {
@@ -52,8 +53,8 @@ export default {
       return map[this.currentQuestion.dimension] || ''
       return map[this.currentQuestion.dimension] || ''
     },
     },
     currentDimColor() {
     currentDimColor() {
-      var map = { E: '#6366F1', I: '#6366F1', S: '#10B981', N: '#10B981', T: '#FF6B9D', F: '#FF6B9D', J: '#F59E0B', P: '#F59E0B' }
-      return map[this.currentQuestion.dimension] || '#6366F1'
+      var map = { E: BrandColors.wisdom, I: BrandColors.wisdom, S: BrandColors.success, N: BrandColors.success, T: BrandColors.mind, F: BrandColors.mind, J: BrandColors.wealth, P: BrandColors.wealth }
+      return map[this.currentQuestion.dimension] || BrandColors.wisdom
     },
     },
     progress() { return this.questions.length > 0 ? Math.round((this.currentIndex + 1) / this.questions.length * 100) : 0 },
     progress() { return this.questions.length > 0 ? Math.round((this.currentIndex + 1) / this.questions.length * 100) : 0 },
     answer() { return this.answers[this.currentQuestion.id] || '' }
     answer() { return this.answers[this.currentQuestion.id] || '' }

+ 7 - 6
cfc-frontend/pages/family/self-check-ai.vue

@@ -100,6 +100,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getAiSelfCheckQuestions, getSelfCheckQuestions, submitSelfCheck } from '@/utils/api'
 import { getAiSelfCheckQuestions, getSelfCheckQuestions, submitSelfCheck } from '@/utils/api'
 
 
 export default {
 export default {
@@ -112,11 +113,11 @@ export default {
       rationale: '',
       rationale: '',
       answers: {},
       answers: {},
       dimMeta: {
       dimMeta: {
-        body: { name: '身', element: '土', color: '#FF8C42', slogan: '主动健康' },
-        wisdom: { name: '智', element: '金', color: '#6366F1', slogan: '赋能未来' },
-        wealth: { name: '富', element: '水', color: '#F59E0B', slogan: '利他创富' },
-        action: { name: '行', element: '木', color: '#10B981', slogan: '人际和谐' },
-        mind: { name: '心', element: '火', color: '#FF6B9D', slogan: '大爱相随' }
+        body: { name: '身', element: '土', color: BrandColors.body, slogan: '主动健康' },
+        wisdom: { name: '智', element: '金', color: BrandColors.wisdom, slogan: '赋能未来' },
+        wealth: { name: '富', element: '水', color: BrandColors.wealth, slogan: '利他创富' },
+        action: { name: '行', element: '木', color: BrandColors.success, slogan: '人际和谐' },
+        mind: { name: '心', element: '火', color: BrandColors.mind, slogan: '大爱相随' }
       }
       }
     }
     }
   },
   },
@@ -136,7 +137,7 @@ export default {
           code: code,
           code: code,
           name: m.name || dimQuestions[0].dimensionName || code,
           name: m.name || dimQuestions[0].dimensionName || code,
           element: m.element || dimQuestions[0].element || '',
           element: m.element || dimQuestions[0].element || '',
-          color: m.color || dimQuestions[0].color || '#F97316',
+          color: m.color || dimQuestions[0].color || BrandColors.primary,
           slogan: m.slogan || '',
           slogan: m.slogan || '',
           questions: dimQuestions,
           questions: dimQuestions,
           answeredCount: answered
           answeredCount: answered

+ 7 - 6
cfc-frontend/pages/family/self-check.vue

@@ -77,6 +77,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getSelfCheckQuestions, submitSelfCheck } from '@/utils/api'
 import { getSelfCheckQuestions, submitSelfCheck } from '@/utils/api'
 
 
 export default {
 export default {
@@ -88,11 +89,11 @@ export default {
       questions: [],
       questions: [],
       answers: {},
       answers: {},
       dimMeta: {
       dimMeta: {
-        body: { name: '身', element: '土', color: '#FF8C42', slogan: '主动健康' },
-        wisdom: { name: '智', element: '金', color: '#6366F1', slogan: '赋能未来' },
-        wealth: { name: '富', element: '水', color: '#F59E0B', slogan: '利他创富' },
-        action: { name: '行', element: '木', color: '#10B981', slogan: '人际和谐' },
-        mind: { name: '心', element: '火', color: '#FF6B9D', slogan: '大爱相随' }
+        body: { name: '身', element: '土', color: BrandColors.body, slogan: '主动健康' },
+        wisdom: { name: '智', element: '金', color: BrandColors.wisdom, slogan: '赋能未来' },
+        wealth: { name: '富', element: '水', color: BrandColors.wealth, slogan: '利他创富' },
+        action: { name: '行', element: '木', color: BrandColors.success, slogan: '人际和谐' },
+        mind: { name: '心', element: '火', color: BrandColors.mind, slogan: '大爱相随' }
       }
       }
     }
     }
   },
   },
@@ -114,7 +115,7 @@ export default {
           code: code,
           code: code,
           name: m.name || dimQuestions[0].dimensionName || code,
           name: m.name || dimQuestions[0].dimensionName || code,
           element: m.element || dimQuestions[0].element || '',
           element: m.element || dimQuestions[0].element || '',
-          color: m.color || dimQuestions[0].color || '#F97316',
+          color: m.color || dimQuestions[0].color || BrandColors.primary,
           slogan: m.slogan || '',
           slogan: m.slogan || '',
           questions: dimQuestions,
           questions: dimQuestions,
           answeredCount: answered
           answeredCount: answered

+ 3 - 2
cfc-frontend/pages/growth/mini-trend.vue

@@ -5,6 +5,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 export default {
 export default {
   props: {
   props: {
     data: {
     data: {
@@ -37,7 +38,7 @@ export default {
       var max = Math.max.apply(null, data)
       var max = Math.max.apply(null, data)
       var range = max - min || 1
       var range = max - min || 1
       var stepX = width / (data.length - 1 || 1)
       var stepX = width / (data.length - 1 || 1)
-      ctx.setStrokeStyle('#EF4444')
+      ctx.setStrokeStyle(BrandColors.danger)
       ctx.setLineWidth(3)
       ctx.setLineWidth(3)
       ctx.beginPath()
       ctx.beginPath()
       for (var i = 0; i < data.length; i++) {
       for (var i = 0; i < data.length; i++) {
@@ -50,7 +51,7 @@ export default {
       // 末端圆点
       // 末端圆点
       var lastX = (data.length - 1) * stepX
       var lastX = (data.length - 1) * stepX
       var lastY = height - (data[data.length - 1] - min) / range * (height - 10) - 5
       var lastY = height - (data[data.length - 1] - min) / range * (height - 10) - 5
-      ctx.setFillStyle('#EF4444')
+      ctx.setFillStyle(BrandColors.danger)
       ctx.beginPath()
       ctx.beginPath()
       ctx.arc(lastX, lastY, 4, 0, 2 * Math.PI)
       ctx.arc(lastX, lastY, 4, 0, 2 * Math.PI)
       ctx.fill()
       ctx.fill()

+ 2 - 1
cfc-frontend/pages/growth/profile/index.vue

@@ -200,6 +200,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../../utils/brand-colors.js'
 import config from '@/config.js'
 import config from '@/config.js'
 import { parseDate } from '@/utils/format.js'
 import { parseDate } from '@/utils/format.js'
 
 
@@ -260,7 +261,7 @@ export default {
       return m[dim] || dim
       return m[dim] || dim
     },
     },
     dimColor(dim) {
     dimColor(dim) {
-      var m = { body: '#FF8C42', wisdom: '#6366F1', mind: '#FF6B9D', action: '#10B981', wealth: '#F59E0B' }
+      var m = { body: BrandColors.body, wisdom: BrandColors.wisdom, mind: BrandColors.mind, action: BrandColors.success, wealth: BrandColors.wealth }
       return m[dim] || '#999'
       return m[dim] || '#999'
     },
     },
     domainLabel(d) {
     domainLabel(d) {

+ 3 - 2
cfc-frontend/pages/guide/packages/share.vue

@@ -49,6 +49,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../../utils/brand-colors.js'
 import { getPackage } from '@/utils/api.js'
 import { getPackage } from '@/utils/api.js'
 import config from '@/config.js'
 import config from '@/config.js'
 
 
@@ -86,7 +87,7 @@ export default {
       ctx.fillRect(0, 0, 600, 900)
       ctx.fillRect(0, 0, 600, 900)
       
       
       // 封面图(简化处理,实际需要下载图片)
       // 封面图(简化处理,实际需要下载图片)
-      ctx.setFillStyle('#4CAF50')
+      ctx.setFillStyle(BrandColors.matGreen)
       ctx.fillRect(0, 0, 600, 300)
       ctx.fillRect(0, 0, 600, 300)
       
       
       // 标题
       // 标题
@@ -112,7 +113,7 @@ export default {
       ctx.fillText(this.formatPriceWithSymbol(this.pkg.price), 30, 520)
       ctx.fillText(this.formatPriceWithSymbol(this.pkg.price), 30, 520)
       
       
       // 分享码
       // 分享码
-      ctx.setFillStyle('#4CAF50')
+      ctx.setFillStyle(BrandColors.matGreen)
       ctx.setFontSize(24)
       ctx.setFontSize(24)
       ctx.fillText('分享码: ' + this.shareCode, 30, 580)
       ctx.fillText('分享码: ' + this.shareCode, 30, 580)
       
       

+ 9 - 8
cfc-frontend/pages/health-main/index.vue

@@ -33,12 +33,12 @@
         </view>
         </view>
       </view>
       </view>
       
       
-        <RadarChart :dimensions="demoBodyDims" :scores="demoBodyScores" fillColor="#FF8C42" childName="示例" width="560" height="460" />
+        <RadarChart :dimensions="demoBodyDims" :scores="demoBodyScores" fillColor=#FF8C42 childName="示例" width="560" height="460" />
         <view class="demo-chart-title-row">
         <view class="demo-chart-title-row">
           <text class="demo-chart-name">🧠 认知雷达</text>
           <text class="demo-chart-name">🧠 认知雷达</text>
           <text class="demo-chart-tag">示例</text>
           <text class="demo-chart-tag">示例</text>
         </view>
         </view>
-        <RadarChart :dimensions="demoCogDims" :scores="demoCogScores" fillColor="#6366F1" childName="示例" width="560" height="460" />
+        <RadarChart :dimensions="demoCogDims" :scores="demoCogScores" fillColor=#6366F1 childName="示例" width="560" height="460" />
       <!-- 五维健康体系 -->
       <!-- 五维健康体系 -->
       <view class="wuxing-section">
       <view class="wuxing-section">
         <view class="wuxing-title">身·心·智·行·富 · 看得见的健康闭环</view>
         <view class="wuxing-title">身·心·智·行·富 · 看得见的健康闭环</view>
@@ -236,6 +236,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import LoginGuideCard from '../../components/LoginGuideCard.vue'
 import LoginGuideCard from '../../components/LoginGuideCard.vue'
 import RadarChart from '../../components/RadarChart.vue'
 import RadarChart from '../../components/RadarChart.vue'
 import ArticleBookshelf from '../../components/ArticleBookshelf.vue'
 import ArticleBookshelf from '../../components/ArticleBookshelf.vue'
@@ -257,11 +258,11 @@ export default {
       hasAiQHistory: false,
       hasAiQHistory: false,
       pendingSurveys: [],
       pendingSurveys: [],
       tabs: [
       tabs: [
-        { code: 'body', label: '健康', icon: '🟠', color: '#FF8C42' },
-        { code: 'cognitive', label: '认知', icon: '🧠', color: '#6366F1' },
-        { code: 'wealth', label: '财富', icon: '💧', color: '#F59E0B' },
-        { code: 'relationship', label: '社会性', icon: '🤝', color: '#10B981' },
-        { code: 'mental', label: '心理', icon: '💖', color: '#FF6B9D' }
+        { code: 'body', label: '健康', icon: '🟠', color: BrandColors.body },
+        { code: 'cognitive', label: '认知', icon: '🧠', color: BrandColors.wisdom },
+        { code: 'wealth', label: '财富', icon: '💧', color: BrandColors.wealth },
+        { code: 'relationship', label: '社会性', icon: '🤝', color: BrandColors.success },
+        { code: 'mental', label: '心理', icon: '💖', color: BrandColors.mind }
       ],
       ],
       quizzes: [
       quizzes: [
         { code: 'cognitive', label: '认知能力测评', icon: '🧠', score: null },
         { code: 'cognitive', label: '认知能力测评', icon: '🧠', score: null },
@@ -306,7 +307,7 @@ export default {
     },
     },
     currentColor: function() {
     currentColor: function() {
       var tab = this.tabs.filter(function(t) { return t.code === this.currentTab }.bind(this))[0]
       var tab = this.tabs.filter(function(t) { return t.code === this.currentTab }.bind(this))[0]
-      return tab ? tab.color : '#FF8C42'
+      return tab ? tab.color : BrandColors.body
     },
     },
     currentDimensions: function() {
     currentDimensions: function() {
       if (this.currentTab === 'cognitive') {
       if (this.currentTab === 'cognitive') {

+ 1 - 1
cfc-frontend/pages/health/components/ComprehensiveSurvey.vue

@@ -244,7 +244,7 @@
         <view class="card">
         <view class="card">
           <view class="card-head"><text class="card-title">辣度</text><text class="card-hint">{{ spiceLabels[innerDiet.spiceLevel || 0] }}</text></view>
           <view class="card-head"><text class="card-title">辣度</text><text class="card-hint">{{ spiceLabels[innerDiet.spiceLevel || 0] }}</text></view>
           <view class="slider-row">
           <view class="slider-row">
-            <slider :value="innerDiet.spiceLevel || 0" min="0" max="5" step="1" activeColor="#FF8C42"
+            <slider :value="innerDiet.spiceLevel || 0" min="0" max="5" step="1" activeColor=#FF8C42
                     @changing="onSpiceChanging" @change="onSpiceChange" />
                     @changing="onSpiceChanging" @change="onSpiceChange" />
           </view>
           </view>
         </view>
         </view>

+ 5 - 4
cfc-frontend/pages/health/components/TrendChart.vue

@@ -14,6 +14,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../../utils/brand-colors.js'
 /**
 /**
  * TrendChart - 多序列折线图 Canvas 组件
  * TrendChart - 多序列折线图 Canvas 组件
  * 用法:<TrendChart :series="[{name,color,points:[{reportDate,value,unit}]}]" height="360" />
  * 用法:<TrendChart :series="[{name,color,points:[{reportDate,value,unit}]}]" height="360" />
@@ -145,7 +146,7 @@ export default {
       var seriesList = this._safeSeries(this.series)
       var seriesList = this._safeSeries(this.series)
       if (seriesList.length === 0) {
       if (seriesList.length === 0) {
         ctx.clearRect(0, 0, w, h)
         ctx.clearRect(0, 0, w, h)
-        ctx.fillStyle = '#94A3B8'
+        ctx.fillStyle = BrandColors.appTextSubtle
         ctx.font = '12px sans-serif'
         ctx.font = '12px sans-serif'
         ctx.textAlign = 'center'
         ctx.textAlign = 'center'
         ctx.fillText('暂无趋势数据', w / 2, h / 2)
         ctx.fillText('暂无趋势数据', w / 2, h / 2)
@@ -180,7 +181,7 @@ export default {
         ctx.stroke()
         ctx.stroke()
       }
       }
       // Y 轴刻度文字
       // Y 轴刻度文字
-      ctx.fillStyle = '#94A3B8'
+      ctx.fillStyle = BrandColors.appTextSubtle
       ctx.font = '10px sans-serif'
       ctx.font = '10px sans-serif'
       ctx.textAlign = 'right'
       ctx.textAlign = 'right'
       for (var ti = 0; ti <= 3; ti++) {
       for (var ti = 0; ti <= 3; ti++) {
@@ -189,7 +190,7 @@ export default {
         ctx.fillText(self._fmtNum(tv), padL - 4, ty + 3)
         ctx.fillText(self._fmtNum(tv), padL - 4, ty + 3)
       }
       }
       // 折线 + 数据点 + 数值
       // 折线 + 数据点 + 数值
-      var palette = ['#F97316', '#0EA5E9', '#10B981', '#F97316', '#EF4444', '#F59E0B']
+      var palette = [BrandColors.primary, BrandColors.infoSky, BrandColors.success, BrandColors.primary, BrandColors.danger, BrandColors.wealth]
       seriesList.forEach(function(s, si) {
       seriesList.forEach(function(s, si) {
         var color = s.color || palette[si % palette.length]
         var color = s.color || palette[si % palette.length]
         ctx.strokeStyle = color
         ctx.strokeStyle = color
@@ -227,7 +228,7 @@ export default {
         }
         }
       })
       })
       // X 轴日期标签(首/中/末)
       // X 轴日期标签(首/中/末)
-      ctx.fillStyle = '#94A3B8'
+      ctx.fillStyle = BrandColors.appTextSubtle
       ctx.font = '10px sans-serif'
       ctx.font = '10px sans-serif'
       ctx.textAlign = 'center'
       ctx.textAlign = 'center'
       if (allDates.length > 0) {
       if (allDates.length > 0) {

+ 5 - 5
cfc-frontend/pages/health/daily-checkin.vue

@@ -10,7 +10,7 @@
             <text class="score-label">饮食评分</text>
             <text class="score-label">饮食评分</text>
             <view class="score-row">
             <view class="score-row">
               <text class="score-min">差</text>
               <text class="score-min">差</text>
-              <slider min="1" max="10" :value="form.dietScore" @change="function(e){form.dietScore=e.detail.value}" block-size="20" activeColor="#FF8C42" />
+              <slider min="1" max="10" :value="form.dietScore" @change="function(e){form.dietScore=e.detail.value}" block-size="20" activeColor=#FF8C42 />
               <text class="score-val">{{ form.dietScore }}</text>
               <text class="score-val">{{ form.dietScore }}</text>
             </view>
             </view>
           </view>
           </view>
@@ -19,7 +19,7 @@
             <text class="score-label">运动评分</text>
             <text class="score-label">运动评分</text>
             <view class="score-row">
             <view class="score-row">
               <text class="score-min">差</text>
               <text class="score-min">差</text>
-              <slider min="1" max="10" :value="form.exerciseScore" @change="function(e){form.exerciseScore=e.detail.value}" block-size="20" activeColor="#FF8C42" />
+              <slider min="1" max="10" :value="form.exerciseScore" @change="function(e){form.exerciseScore=e.detail.value}" block-size="20" activeColor=#FF8C42 />
               <text class="score-val">{{ form.exerciseScore }}</text>
               <text class="score-val">{{ form.exerciseScore }}</text>
             </view>
             </view>
           </view>
           </view>
@@ -28,7 +28,7 @@
             <text class="score-label">睡眠评分</text>
             <text class="score-label">睡眠评分</text>
             <view class="score-row">
             <view class="score-row">
               <text class="score-min">差</text>
               <text class="score-min">差</text>
-              <slider min="1" max="10" :value="form.sleepScore" @change="function(e){form.sleepScore=e.detail.value}" block-size="20" activeColor="#FF8C42" />
+              <slider min="1" max="10" :value="form.sleepScore" @change="function(e){form.sleepScore=e.detail.value}" block-size="20" activeColor=#FF8C42 />
               <text class="score-val">{{ form.sleepScore }}</text>
               <text class="score-val">{{ form.sleepScore }}</text>
             </view>
             </view>
           </view>
           </view>
@@ -37,7 +37,7 @@
             <text class="score-label">饮水评分</text>
             <text class="score-label">饮水评分</text>
             <view class="score-row">
             <view class="score-row">
               <text class="score-min">差</text>
               <text class="score-min">差</text>
-              <slider min="1" max="10" :value="form.waterScore" @change="function(e){form.waterScore=e.detail.value}" block-size="20" activeColor="#FF8C42" />
+              <slider min="1" max="10" :value="form.waterScore" @change="function(e){form.waterScore=e.detail.value}" block-size="20" activeColor=#FF8C42 />
               <text class="score-val">{{ form.waterScore }}</text>
               <text class="score-val">{{ form.waterScore }}</text>
             </view>
             </view>
           </view>
           </view>
@@ -46,7 +46,7 @@
             <text class="score-label">心情评分</text>
             <text class="score-label">心情评分</text>
             <view class="score-row">
             <view class="score-row">
               <text class="score-min">差</text>
               <text class="score-min">差</text>
-              <slider min="1" max="10" :value="form.moodScore" @change="function(e){form.moodScore=e.detail.value}" block-size="20" activeColor="#FF8C42" />
+              <slider min="1" max="10" :value="form.moodScore" @change="function(e){form.moodScore=e.detail.value}" block-size="20" activeColor=#FF8C42 />
               <text class="score-val">{{ form.moodScore }}</text>
               <text class="score-val">{{ form.moodScore }}</text>
             </view>
             </view>
           </view>
           </view>

+ 2 - 1
cfc-frontend/pages/health/indicator-curve.vue

@@ -71,6 +71,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import TrendChart from '@/pages/health/components/TrendChart.vue'
 import TrendChart from '@/pages/health/components/TrendChart.vue'
 import { getIndicatorTrend, getIndicatorChangeRanking, getIndicatorSourceTypes } from '@/utils/api'
 import { getIndicatorTrend, getIndicatorChangeRanking, getIndicatorSourceTypes } from '@/utils/api'
 import { getFamilyMemberList } from '@/utils/api'
 import { getFamilyMemberList } from '@/utils/api'
@@ -222,7 +223,7 @@ export default {
         var items = (res.data && res.data.items) || []
         var items = (res.data && res.data.items) || []
         var series = items.map(function(it) {
         var series = items.map(function(it) {
           var color = ''
           var color = ''
-          return { name: it.name, color: color || '#F97316', points: (it.points || []).map(function(p) { return { reportDate: String(p.reportDate).slice(0, 10), value: p.value, unit: p.unit } }) }
+          return { name: it.name, color: color || BrandColors.primary, points: (it.points || []).map(function(p) { return { reportDate: String(p.reportDate).slice(0, 10), value: p.value, unit: p.unit } }) }
         })
         })
         self.series = series
         self.series = series
       })
       })

+ 6 - 5
cfc-frontend/pages/health/nutrition-profile.vue

@@ -135,6 +135,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getChildNutritionProfile, getDeficiencyAnalysis } from '@/utils/api.js'
 import { getChildNutritionProfile, getDeficiencyAnalysis } from '@/utils/api.js'
 import { parseDate } from '@/utils/format.js'
 import { parseDate } from '@/utils/format.js'
 
 
@@ -242,8 +243,8 @@ export default {
         ctx.draw(true)
         ctx.draw(true)
       }
       }
 
 
-      drawLine('overall', '#F97316')
-      drawLine('gutHealth', '#10B981')
+      drawLine('overall', BrandColors.primary)
+      drawLine('gutHealth', BrandColors.success)
     },
     },
     getStatusEmoji: function(status) {
     getStatusEmoji: function(status) {
       if (status === '偏低') return '🔴'
       if (status === '偏低') return '🔴'
@@ -262,9 +263,9 @@ export default {
       return '未分类'
       return '未分类'
     },
     },
     getSeverityColor: function(severity) {
     getSeverityColor: function(severity) {
-      if (severity >= 0.7) return '#EF4444'
-      if (severity >= 0.3) return '#F59E0B'
-      return '#10B981'
+      if (severity >= 0.7) return BrandColors.danger
+      if (severity >= 0.3) return BrandColors.wealth
+      return BrandColors.success
     },
     },
     getReportTypeName: function(type) {
     getReportTypeName: function(type) {
       if (type === 'gut_flora') return '肠道检测'
       if (type === 'gut_flora') return '肠道检测'

+ 1 - 1
cfc-frontend/pages/health/report-blocks-renderer.vue

@@ -6,7 +6,7 @@
         <view class="block-title">{{ block.title }}</view>
         <view class="block-title">{{ block.title }}</view>
         <view class="score-grid">
         <view class="score-grid">
           <view class="score-item" v-for="(item, si) in block.items" :key="si">
           <view class="score-item" v-for="(item, si) in block.items" :key="si">
-            <view class="score-circle" :style="'border-color:' + (item.color || '#F97316')">
+            <view class="score-circle" :style="'border-color:' + (item.color || #F97316)">
               <text class="score-value">{{ item.value }}</text>
               <text class="score-value">{{ item.value }}</text>
             </view>
             </view>
             <text class="score-label">{{ item.label }}</text>
             <text class="score-label">{{ item.label }}</text>

+ 1 - 1
cfc-frontend/pages/health/sleep-index.vue

@@ -88,7 +88,7 @@
             <text class="form-label">睡眠质量(1-10)</text>
             <text class="form-label">睡眠质量(1-10)</text>
             <view class="slider-row">
             <view class="slider-row">
               <text class="slider-min">差</text>
               <text class="slider-min">差</text>
-              <slider min="1" max="10" :value="form.qualityScore" @change="function(e){form.qualityScore=e.detail.value}" block-size="20" activeColor="#FF8C42" />
+              <slider min="1" max="10" :value="form.qualityScore" @change="function(e){form.qualityScore=e.detail.value}" block-size="20" activeColor=#FF8C42 />
               <text class="slider-val">{{ form.qualityScore }}</text>
               <text class="slider-val">{{ form.qualityScore }}</text>
             </view>
             </view>
           </view>
           </view>

+ 4 - 3
cfc-frontend/pages/home-pages/components/ContactCard.vue

@@ -52,6 +52,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../../utils/brand-colors.js'
 import config from '@/config.js'
 import config from '@/config.js'
 import { parseDate } from '@/utils/format.js'
 import { parseDate } from '@/utils/format.js'
 
 
@@ -84,11 +85,11 @@ export default {
       return map[this.contact.relationshipType] || '其他'
       return map[this.contact.relationshipType] || '其他'
     },
     },
     typeColor: function() {
     typeColor: function() {
-      var map = { family: '#10B981', friend: '#F59E0B', partner: '#FF6B35', colleague: '#3B82F6', other: '#94A3B8' }
-      return map[this.contact.relationshipType] || '#94A3B8'
+      var map = { family: BrandColors.success, friend: BrandColors.wealth, partner: BrandColors.mindAccent, colleague: BrandColors.infoBlue, other: BrandColors.appTextSubtle }
+      return map[this.contact.relationshipType] || BrandColors.appTextSubtle
     },
     },
     avatarColor: function() {
     avatarColor: function() {
-      var colors = ['#FF6B35', '#667eea', '#10B981', '#F59E0B', '#8B5CF6', '#EC4899']
+      var colors = [BrandColors.mindAccent, '#667eea', BrandColors.success, BrandColors.wealth, BrandColors.violet, BrandColors.pink]
       var idx = (this.contact.id || 0) % colors.length
       var idx = (this.contact.id || 0) % colors.length
       return colors[idx]
       return colors[idx]
     },
     },

+ 6 - 5
cfc-frontend/pages/home-pages/member-home-detail.vue

@@ -62,6 +62,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import FamilyRelationGraph from '../../components/FamilyRelationGraph.vue'
 import FamilyRelationGraph from '../../components/FamilyRelationGraph.vue'
 import DimensionTasks from '../../components/DimensionTasks.vue'
 import DimensionTasks from '../../components/DimensionTasks.vue'
 import FamilyMemberStrip from '../../components/FamilyMemberStrip.vue'
 import FamilyMemberStrip from '../../components/FamilyMemberStrip.vue'
@@ -113,11 +114,11 @@ export default {
     },
     },
     energyList: function() {
     energyList: function() {
       var dims = [
       var dims = [
-        { code: 'body', icon: '🌏', label: '身', color: '#8D6E63' },
-        { code: 'mind', icon: '🔥', label: '心', color: '#FF6B35' },
-        { code: 'wisdom', icon: '⚔️', label: '智', color: '#F59E0B' },
-        { code: 'action', icon: '🌿', label: '行', color: '#4CAF50' },
-        { code: 'wealth', icon: '💧', label: '富', color: '#3B82F6' }
+        { code: 'body', icon: '🌏', label: '身', color: BrandColors.brownWarm },
+        { code: 'mind', icon: '🔥', label: '心', color: BrandColors.mindAccent },
+        { code: 'wisdom', icon: '⚔️', label: '智', color: BrandColors.wealth },
+        { code: 'action', icon: '🌿', label: '行', color: BrandColors.matGreen },
+        { code: 'wealth', icon: '💧', label: '富', color: BrandColors.infoBlue }
       ]
       ]
       var self = this
       var self = this
       return dims.map(function(d) {
       return dims.map(function(d) {

+ 1 - 1
cfc-frontend/pages/member-detail/components/member-detail-sections/body-section.vue

@@ -28,7 +28,7 @@
       <RadarChart
       <RadarChart
         :dimensions="dimensionOverview.dimensions.map(function(d) { return { label: d.label, key: d.dimension } })"
         :dimensions="dimensionOverview.dimensions.map(function(d) { return { label: d.label, key: d.dimension } })"
         :scores="dimensionOverview.dimensions.map(function(d) { return d.score })"
         :scores="dimensionOverview.dimensions.map(function(d) { return d.score })"
-        fillColor="#FF8C42"
+        fillColor=#FF8C42
         gridColor="#FED7AA"
         gridColor="#FED7AA"
         labelColor="#9A3412"
         labelColor="#9A3412"
         :width="580"
         :width="580"

+ 6 - 5
cfc-frontend/pages/mind-detail/articles.vue

@@ -87,16 +87,17 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getArticleCategories, getArticleList } from '../../utils/api.js'
 import { getArticleCategories, getArticleList } from '../../utils/api.js'
 import config from '@/config.js'
 import config from '@/config.js'
 
 
 var dimensionConfig = {
 var dimensionConfig = {
   all:   { label: '全部', color: '#64748B', theme: 'mind-wisdom', tagline: '探索知识,滋养成长', quote: '学而时习之,不亦说乎' },
   all:   { label: '全部', color: '#64748B', theme: 'mind-wisdom', tagline: '探索知识,滋养成长', quote: '学而时习之,不亦说乎' },
-  body:  { label: '身', color: '#FF8C42', theme: 'health',       tagline: '主动健康,从知识开始', quote: '健康是人生的第一财富' },
-  mind:  { label: '心', color: '#FF6B9D', theme: 'mind-wisdom',  tagline: '探索内心世界,培养健康心智', quote: '知己知彼,百战不殆' },
-  wisdom: { label: '智', color: '#6366F1', theme: 'wisdom',       tagline: '聪明学习,快乐成长', quote: '学而不思则罔,思而不学则殆' },
-  action:{ label: '行', color: '#10B981', theme: 'action',       tagline: '知行合一,方得始终', quote: '纸上得来终觉浅,绝知此事要躬行' },
-  wealth:{ label: '富', color: '#F59E0B', theme: 'wealth',       tagline: '理财智慧,从小培养', quote: '君子爱财,取之有道' }
+  body:  { label: '身', color: BrandColors.body, theme: 'health',       tagline: '主动健康,从知识开始', quote: '健康是人生的第一财富' },
+  mind:  { label: '心', color: BrandColors.mind, theme: 'mind-wisdom',  tagline: '探索内心世界,培养健康心智', quote: '知己知彼,百战不殆' },
+  wisdom: { label: '智', color: BrandColors.wisdom, theme: 'wisdom',       tagline: '聪明学习,快乐成长', quote: '学而不思则罔,思而不学则殆' },
+  action:{ label: '行', color: BrandColors.success, theme: 'action',       tagline: '知行合一,方得始终', quote: '纸上得来终觉浅,绝知此事要躬行' },
+  wealth:{ label: '富', color: BrandColors.wealth, theme: 'wealth',       tagline: '理财智慧,从小培养', quote: '君子爱财,取之有道' }
 }
 }
 
 
 export default {
 export default {

+ 10 - 9
cfc-frontend/pages/mind-detail/duo-compatibility.vue

@@ -148,6 +148,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import config from '../../config'
 import config from '../../config'
 
 
 export default {
 export default {
@@ -170,11 +171,11 @@ export default {
       ],
       ],
       dimensions: [],
       dimensions: [],
       wuxingColors: {
       wuxingColors: {
-        wood: '#10B981',
-        fire: '#FF6B9D',
-        earth: '#FF8C42',
-        metal: '#6366F1',
-        water: '#3B82F6'
+        wood: BrandColors.success,
+        fire: BrandColors.mind,
+        earth: BrandColors.body,
+        metal: BrandColors.wisdom,
+        water: BrandColors.infoBlue
       },
       },
       wuxingLabels: {
       wuxingLabels: {
         wood: '木', fire: '火', earth: '土', metal: '金', water: '水'
         wood: '木', fire: '火', earth: '土', metal: '金', water: '水'
@@ -262,16 +263,16 @@ export default {
     buildDimensions(d) {
     buildDimensions(d) {
       var dims = []
       var dims = []
       if (d.zodiacCompatibility && d.zodiacCompatibility.score !== undefined) {
       if (d.zodiacCompatibility && d.zodiacCompatibility.score !== undefined) {
-        dims.push({ key: 'zodiac', label: '生肖配对', score: d.zodiacCompatibility.score, color: '#8B5CF6' })
+        dims.push({ key: 'zodiac', label: '生肖配对', score: d.zodiacCompatibility.score, color: BrandColors.violet })
       }
       }
       if (d.wuxingComplementarity && d.wuxingComplementarity.score !== undefined) {
       if (d.wuxingComplementarity && d.wuxingComplementarity.score !== undefined) {
-        dims.push({ key: 'wuxing', label: '五行互补', score: d.wuxingComplementarity.score, color: '#10B981' })
+        dims.push({ key: 'wuxing', label: '五行互补', score: d.wuxingComplementarity.score, color: BrandColors.success })
       }
       }
       if (d.wuxingComplementarity && d.wuxingComplementarity.bloodTypeScore !== undefined) {
       if (d.wuxingComplementarity && d.wuxingComplementarity.bloodTypeScore !== undefined) {
-        dims.push({ key: 'blood', label: '血型兼容', score: d.wuxingComplementarity.bloodTypeScore, color: '#FF6B9D' })
+        dims.push({ key: 'blood', label: '血型兼容', score: d.wuxingComplementarity.bloodTypeScore, color: BrandColors.mind })
       }
       }
       if (d.lifeNumberRelationship && d.lifeNumberRelationship.score !== undefined) {
       if (d.lifeNumberRelationship && d.lifeNumberRelationship.score !== undefined) {
-        dims.push({ key: 'lifenumber', label: '灵数关系', score: d.lifeNumberRelationship.score, color: '#F59E0B' })
+        dims.push({ key: 'lifenumber', label: '灵数关系', score: d.lifeNumberRelationship.score, color: BrandColors.wealth })
       }
       }
       this.dimensions = dims
       this.dimensions = dims
     },
     },

+ 2 - 1
cfc-frontend/pages/mind-detail/emotion-report.vue

@@ -99,6 +99,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getEmiReport } from '../../utils/api.js'
 import { getEmiReport } from '../../utils/api.js'
 
 
 export default {
 export default {
@@ -111,7 +112,7 @@ export default {
       recommendations: [],
       recommendations: [],
       recLoading: false,
       recLoading: false,
       dimensions: [
       dimensions: [
-        { key: 'emotionStability', label: '情绪稳定性', icon: '\u{1F9E0}', color: '#FF6B35', desc: '情绪调节的综合能力(含自卑-自信、抑郁-愉悦、焦虑-安详、无力感-掌控感四个隐性指标)' }
+        { key: 'emotionStability', label: '情绪稳定性', icon: '\u{1F9E0}', color: BrandColors.mindAccent, desc: '情绪调节的综合能力(含自卑-自信、抑郁-愉悦、焦虑-安详、无力感-掌控感四个隐性指标)' }
       ]
       ]
     }
     }
   },
   },

+ 23 - 22
cfc-frontend/pages/mind-detail/index.vue

@@ -239,7 +239,7 @@
           :scores="getMindGroupScores(group)"
           :scores="getMindGroupScores(group)"
           :avg-scores="getMindGroupFamilyScores(group)"
           :avg-scores="getMindGroupFamilyScores(group)"
           :population-scores="getGroupPopulationScores(group)"
           :population-scores="getGroupPopulationScores(group)"
-          fillColor="#FF6B9D"
+          fillColor=#FF6B9D
           gridColor="#FCE7F3"
           gridColor="#FCE7F3"
           labelColor="#9D174D"
           labelColor="#9D174D"
           :width="540"
           :width="540"
@@ -257,6 +257,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import TabTransition from '../../components/tab-transition.vue'
 import TabTransition from '../../components/tab-transition.vue'
 import PageBanner from '../../components/PageBanner.vue'
 import PageBanner from '../../components/PageBanner.vue'
 import DimensionIntroCard from '../../components/DimensionIntroCard.vue'
 import DimensionIntroCard from '../../components/DimensionIntroCard.vue'
@@ -291,7 +292,7 @@ components: { TabTransition, PageBanner, RadarChart, FamilyEnergyBar, PsychCrisi
       emiData: null,
       emiData: null,
       emiLoading: true,
       emiLoading: true,
       emiDimensions: [
       emiDimensions: [
-        { key: 'emotionStability', label: '情绪稳定性', color: '#FF6B35' }
+        { key: 'emotionStability', label: '情绪稳定性', color: BrandColors.mindAccent }
       ],
       ],
       // 大五维度(用于雷达图)
       // 大五维度(用于雷达图)
       personalityDimensions: [
       personalityDimensions: [
@@ -325,11 +326,11 @@ components: { TabTransition, PageBanner, RadarChart, FamilyEnergyBar, PsychCrisi
       traditionalLoading: true,
       traditionalLoading: true,
       compatibilityData: null,
       compatibilityData: null,
       wuxingConfig: {
       wuxingConfig: {
-        wood: { label: '木', color: '#10B981' },
-        fire: { label: '火', color: '#FF6B9D' },
-        earth: { label: '土', color: '#FF8C42' },
-        metal: { label: '金', color: '#6366F1' },
-        water: { label: '水', color: '#3B82F6' }
+        wood: { label: '木', color: BrandColors.success },
+        fire: { label: '火', color: BrandColors.mind },
+        earth: { label: '土', color: BrandColors.body },
+        metal: { label: '金', color: BrandColors.wisdom },
+        water: { label: '水', color: BrandColors.infoBlue }
       },
       },
       pillarLabels: { year: '年柱', month: '月柱', day: '日柱', hour: '时柱' },
       pillarLabels: { year: '年柱', month: '月柱', day: '日柱', hour: '时柱' },
       familyScore: 0,
       familyScore: 0,
@@ -503,11 +504,11 @@ components: { TabTransition, PageBanner, RadarChart, FamilyEnergyBar, PsychCrisi
     },
     },
     luckyColorInfo: function() {
     luckyColorInfo: function() {
       var colorMap = {
       var colorMap = {
-        wood: { name: '绿', hex: '#10B981' },
-        fire: { name: '红', hex: '#FF6B9D' },
-        earth: { name: '黄', hex: '#FF8C42' },
-        metal: { name: '白', hex: '#6366F1' },
-        water: { name: '蓝', hex: '#3B82F6' }
+        wood: { name: '绿', hex: BrandColors.success },
+        fire: { name: '红', hex: BrandColors.mind },
+        earth: { name: '黄', hex: BrandColors.body },
+        metal: { name: '白', hex: BrandColors.wisdom },
+        water: { name: '蓝', hex: BrandColors.infoBlue }
       }
       }
       var elem = this.dominantElement
       var elem = this.dominantElement
       if (!elem) return null
       if (!elem) return null
@@ -584,12 +585,12 @@ var descList = descMap[this.dominantElement] || descMap.wood
       if (!this.isLoggedIn || !this.emiData) return null
       if (!this.isLoggedIn || !this.emiData) return null
       var e = this.emiData
       var e = this.emiData
       var dims = [
       var dims = [
-        { key: 'emotionStability', label: '情绪稳定性', color: '#FF6B9D', desc: '情绪识别与调控能力' },
-        { key: 'opennessScore', label: '开放性', color: '#6366F1', desc: '对新事物的接受程度' },
-        { key: 'conscientiousnessScore', label: '尽责性', color: '#F59E0B', desc: '做事有条理、自律程度' },
-        { key: 'extraversionScore', label: '外向性', color: '#10B981', desc: '社交活跃与外向程度' },
-        { key: 'agreeablenessScore', label: '宜人性', color: '#FF8C42', desc: '与人相处的和谐程度' },
-        { key: 'neuroticismScore', label: '神经质', color: '#F97316', desc: '情绪波动程度(反向)' }
+        { key: 'emotionStability', label: '情绪稳定性', color: BrandColors.mind, desc: '情绪识别与调控能力' },
+        { key: 'opennessScore', label: '开放性', color: BrandColors.wisdom, desc: '对新事物的接受程度' },
+        { key: 'conscientiousnessScore', label: '尽责性', color: BrandColors.wealth, desc: '做事有条理、自律程度' },
+        { key: 'extraversionScore', label: '外向性', color: BrandColors.success, desc: '社交活跃与外向程度' },
+        { key: 'agreeablenessScore', label: '宜人性', color: BrandColors.body, desc: '与人相处的和谐程度' },
+        { key: 'neuroticismScore', label: '神经质', color: BrandColors.primary, desc: '情绪波动程度(反向)' }
       ]
       ]
       var result = { overall: 0, tierLabel: '', summary: '', dims: [], tip: '' }
       var result = { overall: 0, tierLabel: '', summary: '', dims: [], tip: '' }
       var total = 0
       var total = 0
@@ -607,7 +608,7 @@ var descList = descMap[this.dominantElement] || descMap.wood
           code: key,
           code: key,
           name: matched ? matched.label : key,
           name: matched ? matched.label : key,
           score: Math.round(score),
           score: Math.round(score),
-          color: matched ? matched.color : '#FF6B9D',
+          color: matched ? matched.color : BrandColors.mind,
           desc: matched ? matched.desc : ''
           desc: matched ? matched.desc : ''
         })
         })
       }
       }
@@ -857,9 +858,9 @@ var descList = descMap[this.dominantElement] || descMap.wood
       })
       })
     },
     },
     indicatorColor: function(status) {
     indicatorColor: function(status) {
-      if (status === 'abnormal' || status === '偏高' || status === '偏低') return '#EF4444'
-      if (status === 'warning' || status === '偏高' || status === '偏低') return '#F59E0B'
-      return '#10B981'
+      if (status === 'abnormal' || status === '偏高' || status === '偏低') return BrandColors.danger
+      if (status === 'warning' || status === '偏高' || status === '偏低') return BrandColors.wealth
+      return BrandColors.success
     },
     },
     statusLabel: function(status) {
     statusLabel: function(status) {
       if (status === 'normal') return '正常'
       if (status === 'normal') return '正常'

+ 6 - 5
cfc-frontend/pages/mind-detail/innate-portrait.vue

@@ -64,6 +64,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getInnateReading } from '../../utils/api'
 import { getInnateReading } from '../../utils/api'
 export default {
 export default {
   data() {
   data() {
@@ -75,11 +76,11 @@ export default {
       report: null,
       report: null,
       loadError: '',
       loadError: '',
       wuxingConfig: {
       wuxingConfig: {
-        wood: { label: '木', color: '#10B981' },
-        fire: { label: '火', color: '#FF6B9D' },
-        earth: { label: '土', color: '#FF8C42' },
-        metal: { label: '金', color: '#6366F1' },
-        water: { label: '水', color: '#3B82F6' }
+        wood: { label: '木', color: BrandColors.success },
+        fire: { label: '火', color: BrandColors.mind },
+        earth: { label: '土', color: BrandColors.body },
+        metal: { label: '金', color: BrandColors.wisdom },
+        water: { label: '水', color: BrandColors.infoBlue }
       },
       },
       pillarLabels: { year: '年柱', month: '月柱', day: '日柱', hour: '时柱' }
       pillarLabels: { year: '年柱', month: '月柱', day: '日柱', hour: '时柱' }
     }
     }

+ 7 - 6
cfc-frontend/pages/mind-detail/traditional-mirror.vue

@@ -74,7 +74,7 @@
           <text class="section-title">生命灵数</text>
           <text class="section-title">生命灵数</text>
         </view>
         </view>
         <view class="numsoul-display">
         <view class="numsoul-display">
-          <view class="numsoul-number" :style="{ background: numSoulData.colorHex || '#FF6B9D' }">
+          <view class="numsoul-number" :style="{ background: numSoulData.colorHex || #FF6B9D }">
             <text class="numsoul-num">{{ lifeNumber }}</text>
             <text class="numsoul-num">{{ lifeNumber }}</text>
           </view>
           </view>
           <view class="numsoul-info">
           <view class="numsoul-info">
@@ -95,6 +95,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import config from '../../config'
 import config from '../../config'
 
 
 export default {
 export default {
@@ -109,11 +110,11 @@ export default {
       wuxingReading: null,
       wuxingReading: null,
       numSoulData: null,
       numSoulData: null,
       wuxingConfig: {
       wuxingConfig: {
-        wood: { label: '木', color: '#10B981' },
-        fire: { label: '火', color: '#FF6B9D' },
-        earth: { label: '土', color: '#FF8C42' },
-        metal: { label: '金', color: '#6366F1' },
-        water: { label: '水', color: '#3B82F6' }
+        wood: { label: '木', color: BrandColors.success },
+        fire: { label: '火', color: BrandColors.mind },
+        earth: { label: '土', color: BrandColors.body },
+        metal: { label: '金', color: BrandColors.wisdom },
+        water: { label: '水', color: BrandColors.infoBlue }
       },
       },
       pillarLabels: { year: '年柱', month: '月柱', day: '日柱', hour: '时柱' }
       pillarLabels: { year: '年柱', month: '月柱', day: '日柱', hour: '时柱' }
     }
     }

+ 6 - 5
cfc-frontend/pages/mind-detail/training.vue

@@ -90,6 +90,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getGameStats } from '../../utils/api.js'
 import { getGameStats } from '../../utils/api.js'
 
 
 var DIMENSION_MAP = {
 var DIMENSION_MAP = {
@@ -97,7 +98,7 @@ var DIMENSION_MAP = {
     key: 'perception',
     key: 'perception',
     name: '感知训练',
     name: '感知训练',
     icon: '\u{1F441}',
     icon: '\u{1F441}',
-    color: '#8B5CF6',
+    color: BrandColors.violet,
     lightColor: '#EDE9FE',
     lightColor: '#EDE9FE',
     desc: '通过图形匹配、颜色分辨等练习提升感知能力',
     desc: '通过图形匹配、颜色分辨等练习提升感知能力',
     tip: '感知力是认知的起点。多观察身边事物的细节,锻炼视觉辨识能力,能有效提升感知水平。',
     tip: '感知力是认知的起点。多观察身边事物的细节,锻炼视觉辨识能力,能有效提升感知水平。',
@@ -109,7 +110,7 @@ var DIMENSION_MAP = {
     key: 'focus',
     key: 'focus',
     name: '专注训练',
     name: '专注训练',
     icon: '\u{1F3AF}',
     icon: '\u{1F3AF}',
-    color: '#F97316',
+    color: BrandColors.primary,
     lightColor: '#FFF7ED',
     lightColor: '#FFF7ED',
     desc: '通过舒尔特方格、数字追踪等练习提升专注力',
     desc: '通过舒尔特方格、数字追踪等练习提升专注力',
     tip: '专注力是一切学习的基础。每天坚持10分钟专注训练,持续21天会有显著提升。',
     tip: '专注力是一切学习的基础。每天坚持10分钟专注训练,持续21天会有显著提升。',
@@ -121,7 +122,7 @@ var DIMENSION_MAP = {
     key: 'memory',
     key: 'memory',
     name: '记忆训练',
     name: '记忆训练',
     icon: '\u{1F9E0}',
     icon: '\u{1F9E0}',
-    color: '#10B981',
+    color: BrandColors.success,
     lightColor: '#ECFDF5',
     lightColor: '#ECFDF5',
     desc: '通过数字记忆、序列回忆等练习提升记忆力',
     desc: '通过数字记忆、序列回忆等练习提升记忆力',
     tip: '记忆力可以通过科学训练显著提升。联想记忆法和间隔重复是最有效的两种方法。',
     tip: '记忆力可以通过科学训练显著提升。联想记忆法和间隔重复是最有效的两种方法。',
@@ -133,7 +134,7 @@ var DIMENSION_MAP = {
     key: 'logic',
     key: 'logic',
     name: '逻辑训练',
     name: '逻辑训练',
     icon: '\u{1F9E9}',
     icon: '\u{1F9E9}',
-    color: '#3B82F6',
+    color: BrandColors.infoBlue,
     lightColor: '#EFF6FF',
     lightColor: '#EFF6FF',
     desc: '通过推理题、模式识别等练习提升逻辑思维',
     desc: '通过推理题、模式识别等练习提升逻辑思维',
     tip: '逻辑思维是解决复杂问题的关键。多做推理和归纳练习,能帮助建立清晰的思维框架。',
     tip: '逻辑思维是解决复杂问题的关键。多做推理和归纳练习,能帮助建立清晰的思维框架。',
@@ -146,7 +147,7 @@ var DIMENSION_MAP = {
     key: 'spatial',
     key: 'spatial',
     name: '空间训练',
     name: '空间训练',
     icon: '\u{1F9CA}',
     icon: '\u{1F9CA}',
-    color: '#8D6E63',
+    color: BrandColors.brownWarm,
     lightColor: '#EFEBE9',
     lightColor: '#EFEBE9',
     desc: '通过空间旋转、立体构建等练习提升空间思维能力',
     desc: '通过空间旋转、立体构建等练习提升空间思维能力',
     tip: '空间思维对数学和科学学习至关重要。拼图和积木是提升空间能力的最佳方式。',
     tip: '空间思维对数学和科学学习至关重要。拼图和积木是提升空间能力的最佳方式。',

+ 1 - 1
cfc-frontend/pages/profile/components/ProfileMenu.vue

@@ -81,7 +81,7 @@
         </view>
         </view>
         <view class="menu-item menu-item-switch" v-if="role === 'parent'">
         <view class="menu-item menu-item-switch" v-if="role === 'parent'">
           <text>👁 对家庭成员可见</text>
           <text>👁 对家庭成员可见</text>
-          <switch :checked="showToFamily === 1" @change="onShowToFamilyChange" color="#F97316" />
+          <switch :checked="showToFamily === 1" @change="onShowToFamilyChange" color=#F97316 />
         </view>
         </view>
         <view class="menu-item" @click="logout">
         <view class="menu-item" @click="logout">
           <text>🚪 退出登录</text>
           <text>🚪 退出登录</text>

+ 3 - 3
cfc-frontend/pages/profile/message-history.vue

@@ -70,7 +70,7 @@
           </view>
           </view>
           <view class="message-content">
           <view class="message-content">
             <text class="message-title">{{ msg.fullText || msg.description }}</text>
             <text class="message-title">{{ msg.fullText || msg.description }}</text>
-            <text v-if="msg.amount !== 0" class="message-amount" :style="{ color: msg.amount >= 0 ? '#10B981' : '#EF4444' }">
+            <text v-if="msg.amount !== 0" class="message-amount" :style="{ color: msg.amount >= 0 ? #10B981 : #EF4444 }">
               {{ msg.amount >= 0 ? '+' : '' }}{{ msg.amount }}
               {{ msg.amount >= 0 ? '+' : '' }}{{ msg.amount }}
             </text>
             </text>
           </view>
           </view>
@@ -91,7 +91,7 @@
           </view>
           </view>
           <view class="message-content">
           <view class="message-content">
             <text class="message-title">{{ msg.fullText || msg.description }}</text>
             <text class="message-title">{{ msg.fullText || msg.description }}</text>
-            <text v-if="msg.amount !== 0" class="message-amount" :style="{ color: msg.amount >= 0 ? '#10B981' : '#EF4444' }">
+            <text v-if="msg.amount !== 0" class="message-amount" :style="{ color: msg.amount >= 0 ? #10B981 : #EF4444 }">
               {{ msg.amount >= 0 ? '+' : '' }}{{ msg.amount }}
               {{ msg.amount >= 0 ? '+' : '' }}{{ msg.amount }}
             </text>
             </text>
           </view>
           </view>
@@ -112,7 +112,7 @@
           </view>
           </view>
           <view class="message-content">
           <view class="message-content">
             <text class="message-title">{{ msg.fullText || msg.description }}</text>
             <text class="message-title">{{ msg.fullText || msg.description }}</text>
-            <text v-if="msg.amount !== 0" class="message-amount" :style="{ color: msg.amount >= 0 ? '#10B981' : '#EF4444' }">
+            <text v-if="msg.amount !== 0" class="message-amount" :style="{ color: msg.amount >= 0 ? #10B981 : #EF4444 }">
               {{ msg.amount >= 0 ? '+' : '' }}{{ msg.amount }}
               {{ msg.amount >= 0 ? '+' : '' }}{{ msg.amount }}
             </text>
             </text>
           </view>
           </view>

+ 6 - 5
cfc-frontend/pages/profile/portrait-edit.vue

@@ -67,6 +67,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getPortrait, editPortrait, getEnergySandbox } from '../../utils/api.js'
 import { getPortrait, editPortrait, getEnergySandbox } from '../../utils/api.js'
 export default {
 export default {
   data() {
   data() {
@@ -120,11 +121,11 @@ export default {
       var count = 0
       var count = 0
 
 
       var defs = [
       var defs = [
-        { key: 'body', label: '身', icon: '💪', color: '#FF8C42', desc: '身体健康状况,体质好坏的综合反映' },
-        { key: 'mind', label: '心', icon: '💖', color: '#FF6B9D', desc: '情绪与心理状态,情绪波动与心理平衡' },
-        { key: 'wisdom', label: '智', icon: '📚', color: '#6366F1', desc: '智力与知识水平,认知能力与知识储备' },
-        { key: 'action', label: '行', icon: '🚀', color: '#10B981', desc: '行动力与执行力,计划与行动的落实情况' },
-        { key: 'wealth', label: '富', icon: '💰', color: '#F59E0B', desc: '财富与资源,物质丰富程度与创富能力' }
+        { key: 'body', label: '身', icon: '💪', color: BrandColors.body, desc: '身体健康状况,体质好坏的综合反映' },
+        { key: 'mind', label: '心', icon: '💖', color: BrandColors.mind, desc: '情绪与心理状态,情绪波动与心理平衡' },
+        { key: 'wisdom', label: '智', icon: '📚', color: BrandColors.wisdom, desc: '智力与知识水平,认知能力与知识储备' },
+        { key: 'action', label: '行', icon: '🚀', color: BrandColors.success, desc: '行动力与执行力,计划与行动的落实情况' },
+        { key: 'wealth', label: '富', icon: '💰', color: BrandColors.wealth, desc: '财富与资源,物质丰富程度与创富能力' }
       ]
       ]
 
 
       for (var i = 0; i < defs.length; i++) {
       for (var i = 0; i < defs.length; i++) {

+ 4 - 4
cfc-frontend/pages/promotion/components/SharePoster.vue

@@ -65,7 +65,7 @@ export default {
       // 1. Background gradient — warm orange
       // 1. Background gradient — warm orange
       var gradient = ctx.createLinearGradient(0, 0, w * 0.3, h)
       var gradient = ctx.createLinearGradient(0, 0, w * 0.3, h)
       gradient.addColorStop(0, 'BrandColors.primary')
       gradient.addColorStop(0, 'BrandColors.primary')
-      gradient.addColorStop(0.55, '#EA580C')
+      gradient.addColorStop(0.55, BrandColors.orangeDeep)
       gradient.addColorStop(1, '#D94F0A')
       gradient.addColorStop(1, '#D94F0A')
       ctx.setFillStyle(gradient)
       ctx.setFillStyle(gradient)
       ctx.fillRect(0, 0, w, h)
       ctx.fillRect(0, 0, w, h)
@@ -120,7 +120,7 @@ export default {
     // ============================================================
     // ============================================================
     _drawTopDecoration(ctx, w) {
     _drawTopDecoration(ctx, w) {
       var centerX = w / 2
       var centerX = w / 2
-      var dotColors = ['BrandColors.body', 'BrandColors.wisdom', '#F59E0B', 'BrandColors.success', '#FF6B9D']
+      var dotColors = ['BrandColors.body', 'BrandColors.wisdom', BrandColors.wealth, 'BrandColors.success', BrandColors.mind]
       var dotY = 28
       var dotY = 28
       var dotR = 5
       var dotR = 5
       var dotSpacing = 26
       var dotSpacing = 26
@@ -428,7 +428,7 @@ export default {
       ctx.fillText('长按识别二维码,了解浠艾福', centerX, bottomY)
       ctx.fillText('长按识别二维码,了解浠艾福', centerX, bottomY)
 
 
       // 5 dimension dots in the bottom area (outside card)
       // 5 dimension dots in the bottom area (outside card)
-      var dotColors = ['BrandColors.body', 'BrandColors.wisdom', '#F59E0B', 'BrandColors.success', '#FF6B9D']
+      var dotColors = ['BrandColors.body', 'BrandColors.wisdom', BrandColors.wealth, 'BrandColors.success', BrandColors.mind]
       var dotY = h - 22
       var dotY = h - 22
       var dotR = 4
       var dotR = 4
       var dotSpacing = 20
       var dotSpacing = 20
@@ -495,7 +495,7 @@ export default {
   }
   }
 }
 }
 </script>
 </script>
-import { body, primary, success, white, wisdom } from '@/utils/brand-colors.js'
+import { body, primary, success, white, wisdom, BrandColors } from '@/utils/brand-colors.js'
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">
 .poster-overlay {
 .poster-overlay {

+ 1 - 1
cfc-frontend/pages/promotion/index.vue

@@ -63,7 +63,7 @@
             <text class="member-amount available">={{ cfVal(m.availableAmount) }}</text>
             <text class="member-amount available">={{ cfVal(m.availableAmount) }}</text>
           </view>
           </view>
           <!-- 管理员可切换成员池权限 -->
           <!-- 管理员可切换成员池权限 -->
-          <switch v-if="isAdmin && !m.isAdmin" class="member-switch" :checked="m.canUseFamilyBalance" @change="toggleMemberAccess(m)" color="#F97316"></switch>
+          <switch v-if="isAdmin && !m.isAdmin" class="member-switch" :checked="m.canUseFamilyBalance" @change="toggleMemberAccess(m)" color=#F97316></switch>
         </view>
         </view>
       </view>
       </view>
     </view>
     </view>

+ 4 - 3
cfc-frontend/pages/promotion/team.vue

@@ -111,6 +111,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getCfRate, getTeamList, getTeamGrowthCurve, getTeamAllMembersConsumptionCurve, getTeamL1ConsumptionCurve } from '../../utils/api.js'
 import { getCfRate, getTeamList, getTeamGrowthCurve, getTeamAllMembersConsumptionCurve, getTeamL1ConsumptionCurve } from '../../utils/api.js'
 import { parseDate } from '../../utils/format.js'
 import { parseDate } from '../../utils/format.js'
 
 
@@ -248,7 +249,7 @@ export default {
 
 
       // 绘制折线图
       // 绘制折线图
       if (dataValues.length > 1) {
       if (dataValues.length > 1) {
-        ctx.setStrokeStyle('#F97316')
+        ctx.setStrokeStyle(BrandColors.primary)
         ctx.setLineWidth(2)
         ctx.setLineWidth(2)
         ctx.beginPath()
         ctx.beginPath()
 
 
@@ -334,7 +335,7 @@ export default {
 
 
       // 绘制折线图
       // 绘制折线图
       if (dataValues.length > 1) {
       if (dataValues.length > 1) {
-        ctx.setStrokeStyle('#0EA5E9')
+        ctx.setStrokeStyle(BrandColors.infoSky)
         ctx.setLineWidth(2)
         ctx.setLineWidth(2)
         ctx.beginPath()
         ctx.beginPath()
 
 
@@ -419,7 +420,7 @@ export default {
       }
       }
 
 
       // 绘制折线图 - 使用暖橙色
       // 绘制折线图 - 使用暖橙色
-      ctx.setStrokeStyle('#F97316')
+      ctx.setStrokeStyle(BrandColors.primary)
       ctx.setLineWidth(2)
       ctx.setLineWidth(2)
       ctx.beginPath()
       ctx.beginPath()
 
 

+ 6 - 5
cfc-frontend/pages/psych-assessment/index.vue

@@ -93,7 +93,7 @@
           <text class="score-unit">分</text>
           <text class="score-unit">分</text>
         </view>
         </view>
         <view class="score-bar">
         <view class="score-bar">
-          <view class="score-bar-fill" :style="{ width: getResesPercent(scores.reses) + '%', background: '#F59E0B' }"></view>
+          <view class="score-bar-fill" :style="{ width: getResesPercent(scores.reses) + '%', background: #F59E0B }"></view>
         </view>
         </view>
       </view>
       </view>
     </view>
     </view>
@@ -107,6 +107,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { getCognitiveChildScores, submitCognitiveSelfTest } from '../../utils/api.js'
 import { getCognitiveChildScores, submitCognitiveSelfTest } from '../../utils/api.js'
 import { getFamilyMemberList } from '../../utils/api.js'
 import { getFamilyMemberList } from '../../utils/api.js'
 
 
@@ -238,10 +239,10 @@ export default {
       return '极重度'
       return '极重度'
     },
     },
     getPhq9Color: function(score) {
     getPhq9Color: function(score) {
-      if (score <= 4) return '#10B981'
-      if (score <= 9) return '#F59E0B'
-      if (score <= 14) return '#F97316'
-      if (score <= 19) return '#EF4444'
+      if (score <= 4) return BrandColors.success
+      if (score <= 9) return BrandColors.wealth
+      if (score <= 14) return BrandColors.primary
+      if (score <= 19) return BrandColors.danger
       return '#7C3AED'
       return '#7C3AED'
     },
     },
     getPhq9Percent: function(score) {
     getPhq9Percent: function(score) {

+ 1 - 1
cfc-frontend/pages/rewards/rewards.vue

@@ -8,7 +8,7 @@
             <progress 
             <progress 
               :percent="(currentPoints / reward.pointsRequired) * 100" 
               :percent="(currentPoints / reward.pointsRequired) * 100" 
               stroke-width="6" 
               stroke-width="6" 
-              activeColor="#F97316"
+              activeColor=#F97316
               backgroundColor="#eee"
               backgroundColor="#eee"
             />
             />
             <text class="progress-text">{{ currentPoints }}/{{ reward.pointsRequired }}积分</text>
             <text class="progress-text">{{ currentPoints }}/{{ reward.pointsRequired }}积分</text>

+ 2 - 1
cfc-frontend/pages/shop/components/countdown-tag.vue

@@ -5,6 +5,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../../utils/brand-colors.js'
 import { parseDate } from '@/utils/format.js'
 import { parseDate } from '@/utils/format.js'
 
 
 export default {
 export default {
@@ -12,7 +13,7 @@ export default {
   props: {
   props: {
     endTime: { type: String, default: null },
     endTime: { type: String, default: null },
     color: { type: String, default: '#FF6B00' },
     color: { type: String, default: '#FF6B00' },
-    textColor: { type: String, default: '#FFFFFF' }
+    textColor: { type: String, default: BrandColors.white }
   },
   },
   data() {
   data() {
     return { remainingText: '' }
     return { remainingText: '' }

+ 3 - 2
cfc-frontend/pages/tianpan/annual-energy.vue

@@ -50,6 +50,7 @@
 </view>
 </view>
 </template>
 </template>
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 export default {
 export default {
   data: function() {
   data: function() {
     return { energy: null, loading: false, error: null, memberId: null, currentYear: new Date().getFullYear() }
     return { energy: null, loading: false, error: null, memberId: null, currentYear: new Date().getFullYear() }
@@ -108,11 +109,11 @@ export default {
         else ctx.lineTo(vx, vy)
         else ctx.lineTo(vx, vy)
       }
       }
       ctx.closePath(); ctx.fillStyle = 'rgba(249, 115, 22, 0.2)'; ctx.fill()
       ctx.closePath(); ctx.fillStyle = 'rgba(249, 115, 22, 0.2)'; ctx.fill()
-      ctx.strokeStyle = '#F97316'; ctx.lineWidth = 2; ctx.stroke()
+      ctx.strokeStyle = BrandColors.primary; ctx.lineWidth = 2; ctx.stroke()
       ctx.draw()
       ctx.draw()
     },
     },
     dimLabel: function(key) { var map = { body: '身', mind: '心', wisdom: '智', action: '行', wealth: '富' }; return map[key] || key },
     dimLabel: function(key) { var map = { body: '身', mind: '心', wisdom: '智', action: '行', wealth: '富' }; return map[key] || key },
-    dimColor: function(key) { var map = { body: '#10B981', mind: '#EC4899', wisdom: '#8B5CF6', action: '#F97316', wealth: '#3B82F6' }; return map[key] || '#F97316' }
+    dimColor: function(key) { var map = { body: BrandColors.success, mind: BrandColors.pink, wisdom: BrandColors.violet, action: BrandColors.primary, wealth: BrandColors.infoBlue }; return map[key] || BrandColors.primary }
   }
   }
 }
 }
 </script>
 </script>

+ 12 - 11
cfc-frontend/pages/tianpan/member-detail.vue

@@ -107,6 +107,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import { mapActions } from 'vuex'
 import { mapActions } from 'vuex'
 
 
 export default {
 export default {
@@ -122,30 +123,30 @@ export default {
   computed: {
   computed: {
     memberColor: function() {
     memberColor: function() {
       if (!this.member || !this.member.effectiveRole) {
       if (!this.member || !this.member.effectiveRole) {
-        return '#6B7280'
+        return BrandColors.textSlate
       }
       }
       var colorMap = {
       var colorMap = {
-        'parent': '#F97316',
-        'child': '#3B82F6',
-        'teacher': '#8B5CF6'
+        'parent': BrandColors.primary,
+        'child': BrandColors.infoBlue,
+        'teacher': BrandColors.violet
       }
       }
-      return colorMap[this.member.effectiveRole] || '#6B7280'
+      return colorMap[this.member.effectiveRole] || BrandColors.textSlate
     },
     },
     memberEnergy: function() {
     memberEnergy: function() {
       if (!this.member || !this.member.energy) {
       if (!this.member || !this.member.energy) {
         return []
         return []
       }
       }
       var energyMap = {
       var energyMap = {
-        'body': { label: '身', description: '身体健康', color: '#10B981' },
-        'mind': { label: '心', description: '心理健康', color: '#F59E0B' },
-        'wisdom': { label: '智', description: '智慧成长', color: '#3B82F6' },
-        'action': { label: '行', description: '行动力', color: '#8B5CF6' },
-        'wealth': { label: '富', description: '财富能量', color: '#F97316' }
+        'body': { label: '身', description: '身体健康', color: BrandColors.success },
+        'mind': { label: '心', description: '心理健康', color: BrandColors.wealth },
+        'wisdom': { label: '智', description: '智慧成长', color: BrandColors.infoBlue },
+        'action': { label: '行', description: '行动力', color: BrandColors.violet },
+        'wealth': { label: '富', description: '财富能量', color: BrandColors.primary }
       }
       }
       var result = []
       var result = []
       for (var key in this.member.energy) {
       for (var key in this.member.energy) {
         var energy = this.member.energy[key]
         var energy = this.member.energy[key]
-        var info = energyMap[key] || { label: key, description: '', color: '#6B7280' }
+        var info = energyMap[key] || { label: key, description: '', color: BrandColors.textSlate }
         result.push({
         result.push({
           type: key,
           type: key,
           label: info.label,
           label: info.label,

+ 2 - 1
cfc-frontend/pages/wealth/components/DimensionSubDims.vue

@@ -39,12 +39,13 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../../utils/brand-colors.js'
 export default {
 export default {
   name: 'DimensionSubDims',
   name: 'DimensionSubDims',
   props: {
   props: {
     title: { type: String, default: '维度评分' },
     title: { type: String, default: '维度评分' },
     subtitle: { type: String, default: '' },
     subtitle: { type: String, default: '' },
-    accentColor: { type: String, default: '#6366F1' },
+    accentColor: { type: String, default: BrandColors.wisdom },
     dims: { type: Array, default: () => [] }
     dims: { type: Array, default: () => [] }
   },
   },
   methods: {
   methods: {

+ 1 - 1
cfc-frontend/pages/wealth/components/WealthEnergyRing.vue

@@ -13,7 +13,7 @@
           :stroke-dasharray="circumference" :stroke-dashoffset="progressOffset" />
           :stroke-dasharray="circumference" :stroke-dashoffset="progressOffset" />
         <defs>
         <defs>
           <linearGradient id="ringGradient" x1="0%" y1="0%" x2="100%" y2="0%">
           <linearGradient id="ringGradient" x1="0%" y1="0%" x2="100%" y2="0%">
-            <stop offset="0%" stop-color="#F59E0B" />
+            <stop offset="0%" stop-color=#F59E0B />
             <stop offset="100%" stop-color="#FBBF24" />
             <stop offset="100%" stop-color="#FBBF24" />
           </linearGradient>
           </linearGradient>
         </defs>
         </defs>

+ 3 - 2
cfc-frontend/pages/wealth/index.vue

@@ -122,7 +122,7 @@
         v-if="isLoggedIn && wealthSubDims.length > 0"
         v-if="isLoggedIn && wealthSubDims.length > 0"
         title="💧 财富维度构成"
         title="💧 财富维度构成"
         subtitle="家庭财富能量的各个方面"
         subtitle="家庭财富能量的各个方面"
-        accent-color="#F59E0B"
+        accent-color=#F59E0B
         :dims="wealthSubDims" />
         :dims="wealthSubDims" />
 
 
       <!-- 财富强项与提升 -->
       <!-- 财富强项与提升 -->
@@ -266,6 +266,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import TabTransition from '../../components/tab-transition.vue'
 import TabTransition from '../../components/tab-transition.vue'
 import WealthEnergyRing from '@/pages/wealth/components/WealthEnergyRing.vue'
 import WealthEnergyRing from '@/pages/wealth/components/WealthEnergyRing.vue'
 import WealthSubScores from '@/pages/wealth/components/WealthSubScores.vue'
 import WealthSubScores from '@/pages/wealth/components/WealthSubScores.vue'
@@ -403,7 +404,7 @@ export default {
       var self = this
       var self = this
       if (!this.isLoggedIn || !this.wealthSubDims || this.wealthSubDims.length === 0) return null
       if (!this.isLoggedIn || !this.wealthSubDims || this.wealthSubDims.length === 0) return null
       var dims = this.wealthSubDims
       var dims = this.wealthSubDims
-      var colors = ['#F59E0B', '#FF8C42', '#6366F1', '#10B981']
+      var colors = [BrandColors.wealth, BrandColors.body, BrandColors.wisdom, BrandColors.success]
       var result = { overall: 0, tierLabel: '', summary: '', dims: [], tip: '' }
       var result = { overall: 0, tierLabel: '', summary: '', dims: [], tip: '' }
       var total = 0
       var total = 0
       var count = 0
       var count = 0

+ 13 - 12
cfc-frontend/pages/wisdom-detail/index.vue

@@ -28,7 +28,7 @@
         :avg-scores="cognitiveFamilyScores"
         :avg-scores="cognitiveFamilyScores"
         :population-scores="cognitivePopulationScores"
         :population-scores="cognitivePopulationScores"
         :childName="activeChildName"
         :childName="activeChildName"
-        fillColor="#6366F1"
+        fillColor=#6366F1
         gridColor="#E0E7FF"
         gridColor="#E0E7FF"
         labelColor="#3730A3" />
         labelColor="#3730A3" />
     </view>
     </view>
@@ -239,6 +239,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
+import { BrandColors } from '../../utils/brand-colors.js'
 import nav from '../../utils/nav'
 import nav from '../../utils/nav'
 import TabTransition from '../../components/tab-transition.vue'
 import TabTransition from '../../components/tab-transition.vue'
 import RadarChart from '../../components/RadarChart.vue'
 import RadarChart from '../../components/RadarChart.vue'
@@ -402,13 +403,13 @@ export default {
       if (!this.isLoggedIn || !this.cognitiveReport) return null
       if (!this.isLoggedIn || !this.cognitiveReport) return null
       var cognitiveReport = this.cognitiveReport
       var cognitiveReport = this.cognitiveReport
       var dims = [
       var dims = [
-        { key: 'perceptionScore', label: '感知能力', color: '#FF6B9D', desc: '感官获取信息的能力' },
-        { key: 'focusScore', label: '专注力', color: '#F59E0B', desc: '保持注意力集中的能力' },
-        { key: 'memoryScore', label: '记忆力', color: '#6366F1', desc: '记忆和回忆信息的能力' },
-        { key: 'logicScore', label: '逻辑思维', color: '#10B981', desc: '分析和推理能力' },
-        { key: 'spatialScore', label: '空间思维', color: '#F59E0B', desc: '操作空间关系的能力' },
-        { key: 'processingSpeedScore', label: '加工速度', color: '#FF8C42', desc: '快速处理信息的能力' },
-        { key: 'growthMindset', label: '成长型思维', color: '#EC4899', desc: '相信能力可提升的信念' }
+        { key: 'perceptionScore', label: '感知能力', color: BrandColors.mind, desc: '感官获取信息的能力' },
+        { key: 'focusScore', label: '专注力', color: BrandColors.wealth, desc: '保持注意力集中的能力' },
+        { key: 'memoryScore', label: '记忆力', color: BrandColors.wisdom, desc: '记忆和回忆信息的能力' },
+        { key: 'logicScore', label: '逻辑思维', color: BrandColors.success, desc: '分析和推理能力' },
+        { key: 'spatialScore', label: '空间思维', color: BrandColors.wealth, desc: '操作空间关系的能力' },
+        { key: 'processingSpeedScore', label: '加工速度', color: BrandColors.body, desc: '快速处理信息的能力' },
+        { key: 'growthMindset', label: '成长型思维', color: BrandColors.pink, desc: '相信能力可提升的信念' }
       ]
       ]
       var result = { overall: 0, tierLabel: '', summary: '', dims: [], tip: '' }
       var result = { overall: 0, tierLabel: '', summary: '', dims: [], tip: '' }
       var total = 0
       var total = 0
@@ -438,7 +439,7 @@ export default {
           code: key,
           code: key,
           name: matched ? matched.label : key,
           name: matched ? matched.label : key,
           score: Math.round(score),
           score: Math.round(score),
-          color: matched ? matched.color : '#FF6B9D',
+          color: matched ? matched.color : BrandColors.mind,
           desc: matched ? matched.desc : ''
           desc: matched ? matched.desc : ''
         })
         })
       }
       }
@@ -773,9 +774,9 @@ export default {
       return ''
       return ''
     },
     },
     indicatorColor: function(status) {
     indicatorColor: function(status) {
-      if (status === 'abnormal' || status === '偏高' || status === '偏低' || status === '过高' || status === '缺乏') return '#EF4444'
-      if (status === 'warning' || status === '注意' || status === '不足') return '#F59E0B'
-      return '#10B981'
+      if (status === 'abnormal' || status === '偏高' || status === '偏低' || status === '过高' || status === '缺乏') return BrandColors.danger
+      if (status === 'warning' || status === '注意' || status === '不足') return BrandColors.wealth
+      return BrandColors.success
     },
     },
     statusLabel: function(status) {
     statusLabel: function(status) {
       if (status === 'normal') return '正常'
       if (status === 'normal') return '正常'

+ 40 - 0
cfc-frontend/scripts/d31-fix-template-refs.js

@@ -0,0 +1,40 @@
+#!/usr/bin/env node
+/**
+ * D31 修正:撤销模板区(<script> 之前)被误替换的 BrandColors.* —— 模板无法访问模块级变量,
+ * 统一还原为原 hex 字面量;script/style 区的收编保留。
+ */
+const fs = require('fs');
+const { execSync } = require('child_process');
+
+const files = execSync('git -C .. diff --name-only -- cfc-frontend', { encoding: 'utf8' })
+  .split('\n').map(s => s.trim()).filter(s => s.endsWith('.vue')).map(s => s.replace('cfc-frontend/', ''));
+
+const KEY_TO_HEX = {
+  success: '#10B981', wealth: '#F59E0B', mind: '#FF6B9D', body: '#FF8C42',
+  primary: '#F97316', wisdom: '#6366F1', white: '#FFFFFF', infoBlue: '#3B82F6',
+  danger: '#EF4444', appTextSubtle: '#94A3B8', violet: '#8B5CF6', orangeDeep: '#EA580C',
+  infoSky: '#0EA5E9', pink: '#EC4899', textSlate: '#6B7280', matGreen: '#4CAF50',
+  mindAccent: '#FF6B35', brownWarm: '#8D6E63',
+};
+
+let touched = 0;
+let reverted = 0;
+for (const f of files) {
+  const s = fs.readFileSync(f, 'utf8');
+  const scriptIdx = s.search(/<script/);
+  if (scriptIdx === -1) continue;
+  let tpl = s.slice(0, scriptIdx);
+  const rest = s.slice(scriptIdx);
+  if (!/BrandColors\.\w+/.test(tpl)) continue;
+  tpl = tpl.replace(/BrandColors\.(\w+)/g, (m, key) => {
+    if (!KEY_TO_HEX[key]) {
+      console.warn('UNKNOWN KEY ' + key + ' in ' + f);
+      return m;
+    }
+    reverted++;
+    return KEY_TO_HEX[key];
+  });
+  fs.writeFileSync(f, tpl + rest, 'utf8');
+  touched++;
+}
+console.log('修正文件:', touched, '还原引用:', reverted);

+ 105 - 0
cfc-frontend/scripts/d31-script-hex-harvest.js

@@ -0,0 +1,105 @@
+#!/usr/bin/env node
+/**
+ * D31: script 段维度色批量收编 BrandColors
+ * 只替换「整段字符串就是 hex」的写法('#10B981' / "#10B981"),避免破坏模板字符串/渐变拼接。
+ * 自动按文件深度计算相对 import 路径;已 import 的文件不重复注入。
+ *
+ * 用法: node scripts/d31-script-hex-harvest.js [--dry]
+ */
+const fs = require('fs');
+const path = require('path');
+
+const ROOT = path.resolve(__dirname, '..');
+const DRY = process.argv.includes('--dry');
+const EXCLUDE_DIRS = new Set(['node_modules', 'dist', 'unpackage', '.git', 'scripts', '.tmp_equiv']);
+
+// hex -> BrandColors key(仅登记已存在于 utils/brand-colors.js 的键)
+const MAP = {
+  '#10B981': 'success',
+  '#F59E0B': 'wealth',
+  '#FF6B9D': 'mind',
+  '#FF8C42': 'body',
+  '#F97316': 'primary',
+  '#6366F1': 'wisdom',
+  '#FFFFFF': 'white',
+  '#3B82F6': 'infoBlue',
+  '#EF4444': 'danger',
+  '#94A3B8': 'appTextSubtle',
+  '#8B5CF6': 'violet',
+  '#EA580C': 'orangeDeep',
+  '#0EA5E9': 'infoSky',
+  '#EC4899': 'pink',
+  '#6B7280': 'textSlate',
+  '#4CAF50': 'matGreen',
+  '#FF6B35': 'mindAccent',
+  '#8D6E63': 'brownWarm',
+};
+
+const bcSrc = fs.readFileSync(path.join(ROOT, 'utils/brand-colors.js'), 'utf8');
+for (const key of Object.values(MAP)) {
+  if (!new RegExp('^\\s*' + key + ':', 'm').test(bcSrc)) {
+    console.error('缺少 BrandColors 键: ' + key);
+    process.exit(1);
+  }
+}
+
+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);
+let changedFiles = 0;
+let replacements = 0;
+const log = [];
+
+for (const abs of files) {
+  const src = fs.readFileSync(abs, 'utf8');
+  const styleIdx = src.search(/<style/);
+  if (styleIdx === -1) continue;
+  let head = src.slice(0, styleIdx);
+  const tail = src.slice(styleIdx);
+
+  let count = 0;
+  for (const [hex, key] of Object.entries(MAP)) {
+    const re = new RegExp("(['\"])" + hex + "\\1", 'g');
+    head = head.replace(re, () => {
+      count++;
+      return 'BrandColors.' + key;
+    });
+  }
+  if (count === 0) continue;
+
+  // 追加 import:已有 brand-colors 具名导入则并入 BrandColors,否则新增一行
+  if (!/\bBrandColors\b[^}]*\}\s*from\s*['"][^'"]*brand-colors/.test(head)) {
+    const existing = head.match(/import\s*\{([^}]*)\}\s*from\s*(['"][^'"]*brand-colors(?:\.js)?['"])/);
+    if (existing) {
+      head = head.replace(existing[0], 'import {' + existing[1].replace(/\s*$/, '') + (existing[1].trim().endsWith(',') ? ' ' : ', ') + 'BrandColors } from ' + existing[2]);
+    } else {
+      const rel = path.relative(path.dirname(abs), path.join(ROOT, 'utils/brand-colors.js')).split(path.sep).join('/');
+      const importLine = "import { BrandColors } from '" + (rel.startsWith('.') ? rel : './' + rel) + "'";
+      const m = head.match(/<script[^>]*>\r?\n/);
+      if (!m) {
+        console.warn('SKIP(no script tag): ' + path.relative(ROOT, abs));
+        continue;
+      }
+      head = head.replace(m[0], m[0] + importLine + (m[0].includes('\r\n') ? '\r\n' : '\n'));
+    }
+  }
+
+  if (!DRY) fs.writeFileSync(abs, head + tail, 'utf8');
+  changedFiles++;
+  replacements += count;
+  log.push(String(count).padStart(3) + '  ' + path.relative(ROOT, abs).split(path.sep).join('/'));
+}
+
+log.sort((a, b) => parseInt(b) - parseInt(a));
+console.log((DRY ? '[DRY] ' : '') + '文件: ' + changedFiles + '  替换: ' + replacements);
+log.slice(0, 40).forEach(l => console.log(l));
+if (log.length > 40) console.log('... 共 ' + log.length + ' 个文件');

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

@@ -84,6 +84,8 @@ export const BrandColors = {
   matBlue: '#2196F3',       // $mat-blue-base
   matBlue: '#2196F3',       // $mat-blue-base
   matRed: '#F44336',        // Material red-500
   matRed: '#F44336',        // Material red-500
   amber: '#FFC107',         // Material amber-500
   amber: '#FFC107',         // Material amber-500
+  mindAccent: '#FF6B35',    // 心智维度强调橙($mind-accent)
+  brownWarm: '#8D6E63',     // 暖棕($brown-warm,关系图/横幅)
   infoSky: '#0EA5E9',       // sky-500($uni-info;肠道菌群指标色)
   infoSky: '#0EA5E9',       // sky-500($uni-info;肠道菌群指标色)
   dangerStrong2: '#C62828', // red-800($status-danger-strong-2)
   dangerStrong2: '#C62828', // red-800($status-danger-strong-2)
   fill: '#F0F0F0',          // $facade-fill
   fill: '#F0F0F0',          // $facade-fill