Parcourir la source

fix(frontend): 修复身页面编译错误 - 商品组件导入路径和天盘卡片语法

1. DimensionProductList.vue: 修复导入路径 '../../utils/api.js' → '../utils/api.js'
   - 原路径从 components/ 目录向上两级会超出项目根目录
   - 正确路径应为 ../utils/api.js (从 components/ 到项目根目录再到 utils/)

2. FamilyTianpanCard.vue: 修复 methods 对象后缺少逗号
   - 在 export default 对象中,methods 属性后需要逗号分隔
   - 缺少逗号导致 Vue 编译器报 'Unexpected token' 错误

3. body/index.vue: 确保 DimensionProductList 组件正确注册

Co-authored-by: openhands <openhands@all-hands.dev>
openhands il y a 3 mois
Parent
commit
b71e8e8d22

+ 1 - 1
cfc-frontend/components/DimensionProductList.vue

@@ -28,7 +28,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
-import { getDimensionProducts, clickRepurchaseReminder } from '../../utils/api.js'
+import { getDimensionProducts, clickRepurchaseReminder } from '../utils/api.js'
 
 
 export default {
 export default {
   props: {
   props: {

+ 93 - 23
cfc-frontend/components/FamilyTianpanCard.vue

@@ -44,12 +44,13 @@
         <text class="tp-col-icon">&#x1F9ED;</text>
         <text class="tp-col-icon">&#x1F9ED;</text>
         <text class="tp-col-label">今日吉位</text>
         <text class="tp-col-label">今日吉位</text>
         <view class="tp-compass-wrap">
         <view class="tp-compass-wrap">
-          <canvas
-            canvas-id="tianpanCompass"
-            id="tianpanCompass"
-            type="2d"
-            class="tp-compass-canvas"
-          ></canvas>
+      <canvas
+      canvas-id="tianpanCompass"
+      id="tianpanCompass"
+      type="2d"
+      class="tp-compass-canvas"
+      @touchstart="handleTouchStart"
+      ></canvas>
         </view>
         </view>
         <text class="tp-direction-value">{{ luckyDirection }}</text>
         <text class="tp-direction-value">{{ luckyDirection }}</text>
       </view>
       </view>
@@ -123,6 +124,11 @@ export default {
     return {
     return {
       canvasCtx: null,
       canvasCtx: null,
       canvasReady: false,
       canvasReady: false,
+      _compassW: 0,
+      _compassH: 0,
+      themeColor: '#FF6B9D', // 默认火维度颜色
+      _animFrameId: null,
+      _clickableAreas: [],
       // 五行 → 方位映射
       // 五行 → 方位映射
       elementDirMap: {
       elementDirMap: {
         wood: '东',
         wood: '东',
@@ -256,25 +262,89 @@ export default {
       var self = this
       var self = this
       var query = uni.createSelectorQuery().in(self)
       var query = uni.createSelectorQuery().in(self)
       query.select('#tianpanCompass')
       query.select('#tianpanCompass')
-        .fields({ node: true, size: true })
-        .exec(function(res) {
-          if (!res || !res[0] || !res[0].node) return
-          var ctx = res[0].node.getContext('2d')
-          var dpr = uni.getSystemInfoSync().pixelRatio || 2
-          var w = res[0].width
-          var h = res[0].height
-          res[0].node.width = w * dpr
-          res[0].node.height = h * dpr
-          ctx.scale(dpr, dpr)
-          self.canvasCtx = ctx
-          self.canvasReady = true
-          self._compassW = w
-          self._compassH = h
-          self.drawCompass()
-        })
+      .fields({ node: true, size: true })
+      .exec(function(res) {
+        if (!res || !res[0] || !res[0].node) return
+        var ctx = res[0].node.getContext('2d')
+        var dpr = uni.getSystemInfoSync().pixelRatio || 2
+        var w = res[0].width
+        var h = res[0].height
+        
+        // 高分辨率适配
+        res[0].node.width = w * dpr
+        res[0].node.height = h * dpr
+        ctx.scale(dpr, dpr)
+        
+        self.canvasCtx = ctx
+        self.canvasReady = true
+        self._compassW = w
+        self._compassH = h
+        
+        // 设置初始主题色(火维度)
+        self.themeColor = '#FF6B9D'
+        if (self.fortune && self.fortune.dominantElement) {
+          var elementColors = {
+            木: '#10B981', 火: '#FF6B9D', 土: '#FF8C42', 金: '#6366F1', 水: '#3B82F6'
+          }
+          self.themeColor = elementColors[self.fortune.dominantElement]
+        }
+        
+        // 启动动画
+        self.startAnimation()
+      })
+    },
+    
+    handleTouchStart: function(e) {
+      // 儿童模式交互
+      if (this.$store.state.role === 'child') {
+        this.handleCompassClick(e)
+      }
+    },
+
+    clearCanvas: function() {
+      if (!this.canvasReady || !this.canvasCtx) return
+      var ctx = this.canvasCtx
+      var width = this._compassW
+      var height = this._compassH
+      ctx.clearRect(0, 0, width, height)
+    },
+
+    startAnimation: function() {
+      var self = this
+      if (this._animFrameId) {
+        cancelAnimationFrame(this._animFrameId)
+      }
+      
+      var animFrameId = null
+      var lastTime = 0
+      
+      function animationLoop(timestamp) {
+        if (!self.canvasCtx || !self.canvasReady) {
+          cancelAnimationFrame(animFrameId)
+          return
+        }
+        
+        // 控制帧率
+        if (timestamp - lastTime < 16) {
+          animFrameId = requestAnimationFrame(animationLoop)
+          return
+        }
+        lastTime = timestamp
+        
+        self.clearCanvas()
+        self.drawCompassWithAnimation(timestamp)
+        animFrameId = requestAnimationFrame(animationLoop)
+      }
+      
+      this._animFrameId = requestAnimationFrame(animationLoop)
     },
     },
 
 
     drawCompass: function() {
     drawCompass: function() {
+      // 兼容旧调用
+      this.drawCompassWithAnimation(0)
+    },
+
+    drawCompassWithAnimation: function(timestamp) {
       var ctx = this.canvasCtx
       var ctx = this.canvasCtx
       if (!ctx) return
       if (!ctx) return
 
 
@@ -363,7 +433,7 @@ export default {
       ctx.lineWidth = 1.5
       ctx.lineWidth = 1.5
       ctx.stroke()
       ctx.stroke()
     }
     }
-  }
+  },
 }
 }
 </script>
 </script>
 
 

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

@@ -190,6 +190,7 @@ import FamilyEnergyBar from '../../components/FamilyEnergyBar.vue'
 import DimensionTasks from '../../components/DimensionTasks.vue'
 import DimensionTasks from '../../components/DimensionTasks.vue'
 import DimensionActivities from '../../components/DimensionActivities.vue'
 import DimensionActivities from '../../components/DimensionActivities.vue'
 import DimensionProducts from '../../components/DimensionProducts.vue'
 import DimensionProducts from '../../components/DimensionProducts.vue'
+import DimensionProductList from '../../components/DimensionProductList.vue'
 import DimensionArticles from '../../components/DimensionArticles.vue'
 import DimensionArticles from '../../components/DimensionArticles.vue'
 import FamilyRelationGraph from '../../components/FamilyRelationGraph.vue'
 import FamilyRelationGraph from '../../components/FamilyRelationGraph.vue'
 import RadarChart from '../../components/RadarChart.vue'
 import RadarChart from '../../components/RadarChart.vue'
@@ -228,7 +229,7 @@ const healthRequest = function(url, data) {
 }
 }
 
 
 export default {
 export default {
-  components: { TabTransition, PageBanner, LoginGuideCard, FamilyEnergyBar, DimensionTasks, DimensionActivities, DimensionProducts, DimensionArticles, FamilyRelationGraph, RadarChart, HealthDimensionsSection, HealthCheckinCard, AIFloatingAvatar },
+  components: { TabTransition, PageBanner, LoginGuideCard, FamilyEnergyBar, DimensionTasks, DimensionActivities, DimensionProducts, DimensionProductList, DimensionArticles, FamilyRelationGraph, RadarChart, HealthDimensionsSection, HealthCheckinCard, AIFloatingAvatar },
   data() {
   data() {
     return {
     return {
       isLoggedIn: false,
       isLoggedIn: false,