Przeglądaj źródła

fix(cfc-frontend): 天盘 emoji 功能图标替换为 SVG 图标(CFC-TIANPAN-01)

tianpan/index.vue:相关事项缺省图标 📋 替换为 data-URI SVG 剪贴板图标(SCSS 令牌着色);canvas fillText 绘制 emoji 改为 drawItemGlyph 矢量兜底绘制,保持雷达/画布功能不变

mind-detail/FamilyTianpanCard.vue:罗盘/运势星/心情/吉位/星座日/灵数星芒/建议灯泡 emoji(含动态 moodEmoji)全部替换为内联 data-URI SVG 图标,沿用访客态重设计同款方案,颜色取自主题令牌(-primary / -gold-deep / -mind / -3-ink / -insight-ink)

移除 moodEmoji 动态 emoji 计算属性;跳转箭头 → 与宜/忌 ♦✖ 语义符号按规格保留

验收:verify-vue-compile 三段 PASS;audit-mp-antipatterns ERROR 0;build:mp-weixin EXIT=0
Agnes Agent 1 tydzień temu
rodzic
commit
29b9257a13

+ 53 - 17
cfc-frontend/pages/mind-detail/components/FamilyTianpanCard.vue

@@ -5,7 +5,7 @@
     <view class="tp-header">
       <view class="tp-header-left">
         <view class="tp-icon-badge">
-          <text class="tp-icon-text">&#x2637;</text>
+          <view class="tp-icon-glyph"></view>
         </view>
         <view class="tp-header-info">
           <text class="tp-title">家庭天盘</text>
@@ -21,7 +21,7 @@
     <view class="tp-body">
       <!-- 今日运势 -->
       <view class="tp-col tp-col-fortune">
-        <text class="tp-col-icon">&#x2B50;</text>
+        <view class="tp-col-icon"></view>
         <text class="tp-col-label">今日运势</text>
         <view class="tp-fortune-badge" :class="'fortune-level-' + fortuneLevel">
           <text class="tp-fortune-text">{{ fortuneText }}</text>
@@ -31,7 +31,7 @@
 
       <!-- 今日心情 -->
       <view class="tp-col tp-col-mood">
-        <text class="tp-col-icon">{{ moodEmoji }}</text>
+        <view class="tp-col-icon"></view>
         <text class="tp-col-label">今日心情</text>
         <text class="tp-mood-value">{{ moodText }}</text>
         <view class="tp-mood-bar-track">
@@ -41,7 +41,7 @@
 
       <!-- 吉位 -->
       <view class="tp-col tp-col-direction">
-        <text class="tp-col-icon">&#x1F9ED;</text>
+        <view class="tp-col-icon"></view>
         <text class="tp-col-label">今日吉位</text>
         <view class="tp-compass-wrap">
       <canvas
@@ -78,11 +78,11 @@
       <!-- 星座 + 灵数 -->
       <view class="tp-trad-row tp-trad-row-split">
         <view class="tp-trad-tag" v-if="traditionalData.zodiac">
-          <text class="tp-trad-tag-icon">&#x2600;</text>
+          <view class="tp-trad-tag-icon tp-trad-tag-icon-sun"></view>
           <text class="tp-trad-tag-text">{{ traditionalData.zodiac }}</text>
         </view>
         <view class="tp-trad-tag" v-if="traditionalData.lifeNumber">
-          <text class="tp-trad-tag-icon">&#x1F52E;</text>
+          <view class="tp-trad-tag-icon tp-trad-tag-icon-sparkle"></view>
           <text class="tp-trad-tag-text">灵数 {{ traditionalData.lifeNumber }}</text>
         </view>
       </view>
@@ -90,7 +90,7 @@
 
     <!-- 底部周报提示 -->
     <view class="tp-footer" v-if="weeklyTip">
-      <text class="tp-footer-icon">&#x1F4A1;</text>
+      <view class="tp-footer-icon"></view>
       <text class="tp-footer-text">{{ weeklyTip }}</text>
     </view>
 
@@ -207,10 +207,6 @@ export default {
       if (!this.fortune || !this.fortune.description) return '今日宜静心养性'
       return this.fortune.description
     },
-    moodEmoji: function() {
-      if (this.mood && this.mood.emoji) return this.mood.emoji
-      return '\u{1F60A}' // 默认笑脸
-    },
     moodText: function() {
       if (this.mood && this.mood.text) return this.mood.text
       return '平静'
@@ -581,6 +577,13 @@ export default {
 $c-col-bg:     #FAFBFC;   // 三栏列背景(蓝灰近白)
 $c-footer-tint:#FFF5F0;   // 底部提示浅底(暖调)
 $c-detail-tint:#FFE0E8;   // 查看详情按钮渐变终点(粉)
+// 天盘卡片功能图标:内联 data-URI SVG 图标(与访客态重设计同款方案),
+// 颜色取自主题令牌(str-slice 去 # 前缀供 SVG 内嵌),避免硬编码色值
+$tp-glyph-white:  str-slice('#{$app-surface}', 2);     // 头部徽标罗盘(白)
+$tp-glyph-gold:   str-slice('#{$accent-gold-deep}', 2); // 运势星 / 星座日(金)
+$tp-glyph-mind:   str-slice('#{$dim-mind}', 2);        // 心情笑脸 / 吉位导航(心·玫红)
+$tp-glyph-violet: str-slice('#{$fortune-3-ink}', 2);   // 灵数星芒(紫)
+$tp-glyph-insight: str-slice('#{$mind-insight-ink}', 2); // 周报建议灯泡(棕金)
 // 运势五级 ramp 与洞察棕已提全局(fortune 系 / mind-insight-ink,与 mind-detail index 共用)
 
 .tianpan-card {
@@ -621,9 +624,13 @@ $c-detail-tint:#FFE0E8;   // 查看详情按钮渐变终点(粉)
   margin-right: 16rpx;
   box-shadow: 0 4rpx 12rpx var(--theme-shadow, rgba(255, 107, 157, 0.30));
 }
-.tp-icon-text {
-  font-size: calc(32rpx * var(--font-scale, 1));
-  color: $app-surface;
+.tp-icon-glyph {
+  width: 36rpx;
+  height: 36rpx;
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: contain;
+  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23#{$tp-glyph-white}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M15.5 8.5l-2.4 4.6-4.6 2.4 2.4-4.6z'/%3E%3C/svg%3E");
 }
 .tp-header-info {
   display: flex;
@@ -685,8 +692,21 @@ $c-detail-tint:#FFE0E8;   // 查看详情按钮渐变终点(粉)
 
 /* 列通用 */
 .tp-col-icon {
-  font-size: calc(36rpx * var(--font-scale, 1));
+  width: 36rpx;
+  height: 36rpx;
   margin-bottom: 8rpx;
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: contain;
+}
+.tp-col-fortune .tp-col-icon {
+  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23#{$tp-glyph-gold}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3.5l2.5 5.5 6 .4-4.3 3.9 1.3 5.8L12 16.1l-5.5 3 1.3-5.8L3.5 9.4l6-.4z'/%3E%3C/svg%3E");
+}
+.tp-col-mood .tp-col-icon {
+  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23#{$tp-glyph-mind}' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M8.5 14.5a5 5 0 0 0 7 0'/%3E%3Cpath d='M9 9.5h.01M15 9.5h.01'/%3E%3C/svg%3E");
+}
+.tp-col-direction .tp-col-icon {
+  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23#{$tp-glyph-mind}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 11l18-8-8 18-2.5-7.5z'/%3E%3C/svg%3E");
 }
 .tp-col-label {
   font-size: calc(22rpx * var(--font-scale, 1));
@@ -790,9 +810,14 @@ $c-detail-tint:#FFE0E8;   // 查看详情按钮渐变终点(粉)
   border-radius: 16rpx;
 }
 .tp-footer-icon {
-  font-size: calc(24rpx * var(--font-scale, 1));
+  width: 24rpx;
+  height: 24rpx;
   margin-right: 8rpx;
   flex-shrink: 0;
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: contain;
+  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23#{$tp-glyph-insight}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 18h6M10 21h4'/%3E%3Cpath d='M12 3a6 6 0 0 1 3.6 10.8c-.7.5-1.1 1.2-1.2 2H9.6c-.1-.8-.5-1.5-1.2-2A6 6 0 0 1 12 3z'/%3E%3C/svg%3E");
 }
 .tp-footer-text {
   font-size: calc(22rpx * var(--font-scale, 1));
@@ -911,8 +936,19 @@ $c-detail-tint:#FFE0E8;   // 查看详情按钮渐变终点(粉)
   border-radius: 24rpx;
 }
 .tp-trad-tag-icon {
-  font-size: calc(24rpx * var(--font-scale, 1));
+  width: 24rpx;
+  height: 24rpx;
   margin-right: 8rpx;
+  flex-shrink: 0;
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: contain;
+}
+.tp-trad-tag-icon-sun {
+  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23#{$tp-glyph-gold}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2.5v2.5M12 19v2.5M2.5 12h2.5M19 12h2.5M5.3 5.3l1.8 1.8M16.9 16.9l1.8 1.8M18.7 5.3l-1.8 1.8M7.1 16.9l-1.8 1.8'/%3E%3C/svg%3E");
+}
+.tp-trad-tag-icon-sparkle {
+  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23#{$tp-glyph-violet}' stroke='none'%3E%3Cpath d='M12 3.5c.5 4.6 3.4 7.5 8 8-4.6.5-7.5 3.4-8 8-.5-4.6-3.4-7.5-8-8 4.6-.5 7.5-3.4 8-8z'/%3E%3C/svg%3E");
 }
 .tp-trad-tag-text {
   font-size: calc(24rpx * var(--font-scale, 1));

+ 42 - 7
cfc-frontend/pages/tianpan/index.vue

@@ -63,7 +63,7 @@
         :key="item.id"
         @click="onItemClick(item)"
       >
-        <view class="item-icon">{{ item.icon || '📋' }}</view>
+        <view class="item-icon"></view>
         <view class="item-content">
           <text class="item-title">{{ item.title }}</text>
           <text class="item-desc">{{ item.description || '' }}</text>
@@ -469,11 +469,8 @@ export default {
         var x = cx + r * Math.cos(angle)
         var y = cy + r * Math.sin(angle)
         
-        // 绘制 emoji
-        ctx.font = '16px sans-serif'
-        ctx.textAlign = 'center'
-        ctx.textBaseline = 'middle'
-        ctx.fillText(item.icon || '📋', x, y)
+        // 绘制事项图标(canvas 无法渲染 SVG 字符串,用矢量图形兜底绘制剪贴板徽标)
+        this.drawItemGlyph(ctx, x, y, 14)
         
         // 存储点击区域
         if (!this.itemHitAreas) {
@@ -489,6 +486,37 @@ export default {
       }
     },
     
+    drawItemGlyph: function(ctx, x, y, size) {
+      // 相关事项缺省图标:剪贴板徽标(canvas 无法直接渲染 SVG 字符串,用矢量图形绘制,
+      // 视觉与列表 item-icon 的 data-URI SVG 剪贴板一致;颜色沿用画布主色 BrandColors.primary)
+      var s = size || 14
+      var bodyW = s * 0.7
+      var bodyH = s * 0.92
+      var clipW = bodyW * 0.44
+      var clipH = s * 0.2
+      var l = x - bodyW / 2
+      var t = y - bodyH / 2
+      ctx.save()
+      ctx.strokeStyle = BrandColors.primary
+      ctx.lineWidth = 1.3
+      ctx.lineCap = 'round'
+      ctx.lineJoin = 'round'
+
+      // 顶部夹子
+      ctx.strokeRect(x - clipW / 2, t - clipH * 0.55, clipW, clipH)
+      // 单据主体
+      ctx.strokeRect(l, t + clipH * 0.35, bodyW, bodyH - clipH * 0.35)
+      // 文本行
+      ctx.beginPath()
+      ctx.moveTo(l + 2, y - s * 0.16)
+      ctx.lineTo(x + bodyW / 2 - 2, y - s * 0.16)
+      ctx.moveTo(l + 2, y + s * 0.08)
+      ctx.lineTo(x + bodyW / 2 - 3, y + s * 0.08)
+      ctx.stroke()
+
+      ctx.restore()
+    },
+
     drawRelationshipLines: function(ctx, cx, cy, relationships) {
       for (var i = 0; i < relationships.length; i++) {
         var rel = relationships[i]
@@ -703,6 +731,7 @@ $c-tp-brown-deep:   $mat-orange-900; // 深棕文字(暖卡内)
 $c-tp-brown:        $mat-orange-deep; // 棕橙文字(橙卡内)
 $c-tp-violet-soft:  #E0D4FF; // 紫罗兰软底渐变终
 $c-tp-violet-text:  $violet-700; // 紫罗兰文字
+$c-tp-item-glyph:   str-slice('#{$brand-primary}', 2); // 相关事项缺省图标色(去 # 前缀,供 data-URI SVG 内嵌)
 
 .tianpan-container {
   min-height: 100vh;
@@ -801,8 +830,14 @@ $c-tp-violet-text:  $violet-700; // 紫罗兰文字
 }
 
 .item-icon {
-  font-size: calc(48rpx * var(--font-scale, 1));
+  width: calc(48rpx * var(--font-scale, 1));
+  height: calc(48rpx * var(--font-scale, 1));
+  flex-shrink: 0;
   margin-right: 24rpx;
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: 100% 100%;
+  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23#{$c-tp-item-glyph}' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='8' y='2.5' width='8' height='4' rx='1'/%3E%3Cpath d='M16 4.5h2a2 2 0 0 1 2 2V19a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6.5a2 2 0 0 1 2-2h2'/%3E%3Cpath d='M9 12h6M9 16h4'/%3E%3C/svg%3E");
 }
 
 .item-content {