Bladeren bron

feat: #update

wei.k.li 1 week geleden
bovenliggende
commit
312e2a7cc5
1 gewijzigde bestanden met toevoegingen van 155 en 17 verwijderingen
  1. 155 17
      src/assets/templates/prototype/customer/UserBehavior.vue

+ 155 - 17
src/assets/templates/prototype/customer/UserBehavior.vue

@@ -149,25 +149,30 @@
                 <td class="px-6 py-4">
                   <div class="flex items-center">
                     <div class="flex-shrink-0 h-10 w-10">
-                      <img class="h-10 w-10 rounded-full object-cover" :src="behavior.user.avatar" :alt="behavior.user.name">
+                      <img 
+                        class="h-10 w-10 rounded-full object-cover" 
+                        :src="behavior.userAvatar" 
+                        :alt="behavior.userName"
+                        @error="handleImageError"
+                      >
                     </div>
                     <div class="ml-4">
-                      <div class="text-sm font-medium text-gray-900 dark:text-white">{{ behavior.user.name }}</div>
-                      <div class="text-sm text-gray-500 dark:text-gray-400">{{ behavior.user.id }}</div>
+                      <div class="text-sm font-medium text-gray-900 dark:text-white">{{ behavior.userName }}</div>
+                      <div class="text-sm text-gray-500 dark:text-gray-400">{{ behavior.userId }}</div>
                     </div>
                   </div>
                 </td>
                 <td class="px-6 py-4">
-                  <span :class="['user-type-tag', `type-${behavior.user.type}`]">
-                    {{ behavior.user.type === 'new' ? '新用户' : 
-                       behavior.user.type === 'regular' ? '普通用户' : 'VIP用户' }}
+                  <span :class="['user-type-tag', `type-${behavior.userType}`]">
+                    {{ behavior.userType === 'new' ? '新用户' : 
+                       behavior.userType === 'regular' ? '普通用户' : 'VIP用户' }}
                   </span>
                 </td>
                 <td class="px-6 py-4">
-                  <span :class="['behavior-type-tag', `type-${behavior.type}`]">
-                    {{ behavior.type === 'browse' ? '浏览' : 
-                       behavior.type === 'search' ? '搜索' : 
-                       behavior.type === 'purchase' ? '购买' : '评论' }}
+                  <span :class="['behavior-type-tag', `type-${behavior.behaviorType}`]">
+                    {{ behavior.behaviorType === 'browse' ? '浏览' : 
+                       behavior.behaviorType === 'search' ? '搜索' : 
+                       behavior.behaviorType === 'purchase' ? '购买' : '评论' }}
                   </span>
                 </td>
                 <td class="px-6 py-4">
@@ -260,7 +265,7 @@
 </template>
 
 <script setup>
-import { ref, computed, onMounted, onUnmounted } from 'vue'
+import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue'
 import * as echarts from 'echarts'
 import { 
   LineChart,
@@ -321,14 +326,13 @@ let trendChart = null
 let distributionChart = null
 
 // Mock data
-// 模拟数据
 const mockUserBehaviors = ref([
   {
     id: 'B1001',
     userId: 'U1001',
     userName: '张三',
     userType: 'vip',
-    userAvatar: 'https://images.unsplash.com/photo-1695048133148-1e0e1b0b0b0b',
+    userAvatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=张三',
     behaviorType: 'browse',
     targetId: 'P1001',
     targetName: '智能手表 Pro',
@@ -344,7 +348,7 @@ const mockUserBehaviors = ref([
     userId: 'U1002',
     userName: '李四',
     userType: 'normal',
-    userAvatar: 'https://images.unsplash.com/photo-1695048133148-1e0e1b0b0b0c',
+    userAvatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=李四',
     behaviorType: 'search',
     targetId: null,
     targetName: '无线耳机',
@@ -360,7 +364,7 @@ const mockUserBehaviors = ref([
     userId: 'U1003',
     userName: '王五',
     userType: 'vip',
-    userAvatar: 'https://images.unsplash.com/photo-1695048133148-1e0e1b0b0b0d',
+    userAvatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=王五',
     behaviorType: 'add_to_cart',
     targetId: 'P1002',
     targetName: '无线耳机 Air',
@@ -376,7 +380,7 @@ const mockUserBehaviors = ref([
     userId: 'U1004',
     userName: '赵六',
     userType: 'normal',
-    userAvatar: 'https://images.unsplash.com/photo-1695048133148-1e0e1b0b0b0e',
+    userAvatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=赵六',
     behaviorType: 'purchase',
     targetId: 'P1003',
     targetName: '智能音箱 Mini',
@@ -392,7 +396,7 @@ const mockUserBehaviors = ref([
     userId: 'U1005',
     userName: '钱七',
     userType: 'vip',
-    userAvatar: 'https://images.unsplash.com/photo-1695048133148-1e0e1b0b0b0f',
+    userAvatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=钱七',
     behaviorType: 'review',
     targetId: 'P1004',
     targetName: '运动相机 4K',
@@ -519,11 +523,145 @@ const handleExportReport = () => {
   console.log('导出报表')
 }
 
+// 初始化图表
+const initCharts = () => {
+  // 销毁已存在的图表实例
+  if (trendChart) {
+    trendChart.dispose()
+  }
+  if (distributionChart) {
+    distributionChart.dispose()
+  }
+
+  // 初始化趋势图表
+  if (trendChartRef.value) {
+    trendChart = echarts.init(trendChartRef.value)
+    const trendOption = {
+      title: {
+        text: '用户行为趋势'
+      },
+      tooltip: {
+        trigger: 'axis'
+      },
+      legend: {
+        data: ['行为数', '用户数', '平均时长(分钟)']
+      },
+      xAxis: {
+        type: 'category',
+        data: behaviorTrends.value.map(item => item.date)
+      },
+      yAxis: [
+        {
+          type: 'value',
+          name: '数量'
+        },
+        {
+          type: 'value',
+          name: '时长',
+          position: 'right'
+        }
+      ],
+      series: [
+        {
+          name: '行为数',
+          type: 'line',
+          data: behaviorTrends.value.map(item => item.behaviors)
+        },
+        {
+          name: '用户数',
+          type: 'line',
+          data: behaviorTrends.value.map(item => item.users)
+        },
+        {
+          name: '平均时长(分钟)',
+          type: 'line',
+          yAxisIndex: 1,
+          data: behaviorTrends.value.map(item => item.duration)
+        }
+      ]
+    }
+    trendChart.setOption(trendOption)
+  }
+
+  // 初始化分布图表
+  if (distributionChartRef.value) {
+    distributionChart = echarts.init(distributionChartRef.value)
+    const distributionOption = {
+      title: {
+        text: '行为类型分布'
+      },
+      tooltip: {
+        trigger: 'item'
+      },
+      legend: {
+        orient: 'vertical',
+        left: 'left'
+      },
+      series: [
+        {
+          name: '行为类型',
+          type: 'pie',
+          radius: '50%',
+          data: behaviorTypeDistribution.value.map(item => ({
+            name: item.type === 'browse' ? '浏览' : 
+                  item.type === 'search' ? '搜索' : 
+                  item.type === 'purchase' ? '购买' : '评论',
+            value: item.value
+          })),
+          emphasis: {
+            itemStyle: {
+              shadowBlur: 10,
+              shadowOffsetX: 0,
+              shadowColor: 'rgba(0, 0, 0, 0.5)'
+            }
+          }
+        }
+      ]
+    }
+    distributionChart.setOption(distributionOption)
+  }
+}
+
+// 处理图片加载错误
+const handleImageError = (event) => {
+  event.target.src = 'https://via.placeholder.com/40' // 使用默认头像
+}
+
 // 生命周期钩子
 onMounted(() => {
   // 初始化数据
   console.log('用户行为分析页面已加载')
+  
+  // 初始化图表
+  nextTick(() => {
+    initCharts()
+  })
+
+  // 监听窗口大小变化,重新调整图表大小
+  window.addEventListener('resize', handleResize)
+})
+
+onUnmounted(() => {
+  // 销毁图表实例
+  if (trendChart) {
+    trendChart.dispose()
+  }
+  if (distributionChart) {
+    distributionChart.dispose()
+  }
+  // 移除事件监听
+  window.removeEventListener('resize', handleResize)
 })
+
+// 处理窗口大小变化
+const handleResize = () => {
+  if (trendChart) {
+    trendChart.resize()
+  }
+  if (distributionChart) {
+    distributionChart.resize()
+  }
+}
 </script>
 
 <style scoped>