From b7e2ab9df65e13c6b9f24a6e57f4501967568edc Mon Sep 17 00:00:00 2001
From: peng <peng.com>
Date: 星期四, 23 十月 2025 17:45:55 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/send_coupon' into send_coupon

---
 seller/src/views/statistics/traffic.vue |  297 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 286 insertions(+), 11 deletions(-)

diff --git a/seller/src/views/statistics/traffic.vue b/seller/src/views/statistics/traffic.vue
index fc050b8..bce06fc 100644
--- a/seller/src/views/statistics/traffic.vue
+++ b/seller/src/views/statistics/traffic.vue
@@ -31,10 +31,18 @@
 
     </Card>
 
+    <!--    <Card class="card">-->
+    <!--      <div>-->
+    <!--        <h4>娴侀噺瓒嬪娍</h4>-->
+    <!--        <div id="orderChart"></div>-->
+    <!--      </div>-->
+    <!--    </Card>-->
     <Card class="card">
-      <div>
-        <h4>娴侀噺瓒嬪娍</h4>
-        <div id="orderChart"></div>
+      <div class="chart-wrapper">
+        <div class="chart-header">
+          <h2>PV/UV 瓒嬪娍鍥�</h2>
+        </div>
+        <div ref="chartDom" class="chart-container"></div>
       </div>
     </Card>
 
@@ -50,6 +58,8 @@
 import affixTime from "@/views/lili-components/affix-time";
 import * as API_Member from "@/api/member";
 import { Chart } from "@antv/g2";
+import * as echarts from 'echarts';
+import {pvUvData} from "../../api/orderStatistics";
 import Cookies from "js-cookie";
 export default {
   components: { affixTime },
@@ -108,6 +118,8 @@
       ],
 
       data: [], // 瀹㈡埛澧為暱鎶ヨ〃鏁版嵁
+      chart:null //鏂皃vuv
+
     };
   },
   watch: {
@@ -115,19 +127,56 @@
       handler(val) {
         this.uvs = 0;
         this.pvs = 0;
-        this.init();
+        // this.init();
       },
       deep: true,
     },
   },
   methods: {
-    // 璁㈠崟鍥�
-    initChart() {
-      // 榛樿宸茬粡鍔犺浇 legend-filter 浜や簰
-      /**
-       * 灏嗘暟鎹垎鎴愪笁缁勬潵杩涜灞曠ず
-       */
+    getDates(param){
+      const dates = [];
+      const today = new Date();
+      let days = 1;
+      if(param.year !== null && param.year !== undefined && param.month !== null && param.month !== undefined && param.month !=='' ){
+        // 褰撲紶鍏ュ勾浠藉拰鏈堜唤鏃讹紝鐢熸垚璇ユ湀浠界殑鎵�鏈夋棩鏈�
+        const year = parseInt(param.year);
+        const month = parseInt(param.month);
+        // 鑾峰彇璇ユ湀鐨勫ぉ鏁�
+        const daysInMonth = new Date(year, month, 0).getDate();
 
+        // 鐢熸垚璇ユ湀鎵�鏈夋棩鏈�
+        for (let day = 1; day <= daysInMonth; day++) {
+          const date = new Date(year, month - 1, day); // 鏈堜唤浠�0寮�濮嬶紝鎵�浠ヨ鍑�1
+          dates.push(this.formatDate(date, 'MM-dd'));
+        }
+
+      }else{
+        // 纭畾澶╂暟閫昏緫涓嶅彉
+        if (param.searchType === "TODAY") {
+          days = 1;
+        } else if (param.searchType === "YESTERDAY") {
+          days = 1;
+        } else if (param.searchType === "LAST_SEVEN") {
+          days = 7;
+        } else if (param.searchType === "LAST_THIRTY") {
+          days = 30;
+        }
+        for (let i = days - 1; i >= 0; i--) {
+          const date = new Date(today);
+          date.setDate(today.getDate() - i);
+          dates.push(this.formatDate(date, 'MM-dd'));
+        }
+      }
+      // 鐢熸垚鏃ユ湡鏁扮粍閫昏緫涓嶅彉
+
+      return dates;
+    },
+    // 璁㈠崟鍥�
+    initChart2(){
+      this.chart = echarts.init(this.$refs.chartDom)
+      this.updateChartData(this.params)//鏇存柊 pvuv
+    },
+    initChart() {
       let uv = [];
       let pv = [];
 
@@ -177,14 +226,211 @@
           stroke: "#fff",
           lineWidth: 1,
         });
+      this.orderChart.area().position("date*pv").color("title").shape("smooth");
 
       this.orderChart.render();
     },
+    //------------鏇存柊鍥捐〃鏁版嵁pvuv start
+    async updateChartData(param) {
+      // 鐢熸垚鏃ユ湡鍜孭V鏁版嵁
+      const { pvData ,uvData} = await this.generateChartData(param)
+      // 璁剧疆鍥捐〃閰嶇疆
+      this.chart.setOption(this.getChartOption(this.getDates(param), pvData, uvData))
+    },
+    // 鑾峰彇鍥捐〃閰嶇疆椤�
+    // 鍥捐〃閰嶇疆椤癸紙鎭㈠鍘熷棰滆壊锛�
+    getChartOption(dates, pvData, uvData) {
+      return {
+        tooltip: {
+          trigger: 'axis',
+          backgroundColor: 'rgba(255, 255, 255, 0.9)',
+          borderColor: '#eee',
+          borderWidth: 1,
+          textStyle: { color: '#333' },
+          formatter: (params) => {
+            const date = params[0].name;
+            const pv = params.find(item => item.seriesName === '娴忚閲�(PV)')?.value || 0;
+            const uv = params.find(item => item.seriesName === '鐙珛璁垮(UV)')?.value || 0;
+            // 浼樺寲锛氭坊鍔犳崲琛岀杞箟锛岄伩鍏嶆綔鍦ㄦ牸寮忛棶棰橈紙鍙�夛紝涓嶅奖鍝嶅姛鑳斤級
+            return `<div class="font-medium">${date}</div>
+                <div>娴忚閲�(PV): <span style="color: #165DFF; font-weight: bold">${pv.toLocaleString()}</span></div>
+                <div>鐙珛璁垮(UV): <span style="color: #00b42a; font-weight: bold">${uv.toLocaleString()}</span></div>`;
+          },
+        },
+        legend: {
+          data: ['娴忚閲�(PV)', '鐙珛璁垮(UV)'],
+          top: 0,
+          textStyle: { color: '#666' }
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true,
+          top: '15%'
+        },
+        xAxis: {
+          type: 'category',
+          data: dates,
+          axisLine: { lineStyle: { color: '#eee' } },
+          axisTick: { show: false },
+          axisLabel: { interval: 'auto', rotate: 0, color: '#86909C' },
+          splitLine: { show: false }
+        },
+        yAxis: {
+          type: 'value',
+          axisLine: { show: false },
+          axisTick: { show: false },
+          axisLabel: { color: '#86909C', formatter: '{value}' },
+          splitLine: { lineStyle: { color: '#f2f3f5' } },
+          min: 0
+        },
+        series: [
+          // PV鎶樼嚎锛堜繚鐣欏師濮嬭摑鑹茬郴锛屼紭鍖栫偣绾胯鎺ワ級
+          {
+            name: '娴忚閲�(PV)',
+            type: 'line',
+            data: pvData,
+            symbol: 'circle',
+            symbolSize: 6, // 淇濈暀鍘熸湁鐐瑰ぇ灏�
+            emphasis: {
+              symbolSize: 8,
+              showSymbol: true
+            },
+            lineStyle: {
+              width: 3, // 淇濈暀鍘熸湁绾垮
+              color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+                { offset: 0, color: '#165DFF' }, // 鍘熷PV涓昏壊
+                { offset: 1, color: '#36CFC9' }  // 鍘熷娓愬彉杈呭姪鑹�
+              ]),
+              // 鍏抽敭浼樺寲1锛氱嚎鏉$鐐硅涓哄渾瑙掞紝閬垮厤鈥滃垏鍙b�濈┖鐧�
+              cap: 'round',
+              // 鍏抽敭浼樺寲2锛氱嚎鏉℃嫄瑙掕涓哄渾瑙掞紝閬垮厤琛旀帴闂撮殭
+              join: 'round',
+              // 杈呭姪锛氭帶鍒舵嫄瑙掑渾瑙掑ぇ灏忥紙涓庣嚎瀹藉尮閰嶏紝閬垮厤婧㈠嚭锛�
+              miterLimit: 3
+            },
+            itemStyle: {
+              color: '#165DFF', // 鍘熷鐐归鑹�
+              borderColor: '#fff', // 淇濈暀鐧借壊杈规锛堝寮哄眰娆℃劅锛�
+              // 鍏抽敭浼樺寲3锛氬噺灏忚竟妗嗗搴︼紝閬垮厤閬尅绾挎潯瀵艰嚧鏂眰
+              borderWidth: 0 // 浠�2璋冩暣涓�1.5
+            },
+            areaStyle: {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: 'rgba(22, 93, 255, 0.2)' }, // 鍘熷濉厖鑹�
+                { offset: 1, color: 'rgba(22, 93, 255, 0)' }
+              ])
+            },
+            smooth: true,
+            showSymbol: true, // 淇濈暀浣犺缃殑鈥滈粯璁ゆ樉绀烘墍鏈夌偣鈥�
+          },
+          // UV鎶樼嚎锛堜繚鐣欏師濮嬬豢鑹茬郴锛屽悓PV浼樺寲閫昏緫锛�
+          {
+            name: '鐙珛璁垮(UV)',
+            type: 'line',
+            data: uvData,
+            symbol: 'circle',
+            symbolSize: 6, // 淇濈暀鍘熸湁鐐瑰ぇ灏�
+            emphasis: {
+              symbolSize: 8,
+              showSymbol: true
+            },
+            lineStyle: {
+              width: 3, // 淇濈暀鍘熸湁绾垮
+              color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+                { offset: 0, color: '#00b42a' }, // 鍘熷UV涓昏壊
+                { offset: 1, color: '#72c140' }  // 鍘熷娓愬彉杈呭姪鑹�
+              ]),
+              // 鍚孭V浼樺寲锛氱鐐瑰渾瑙�+鎷愯鍦嗚
+              cap: 'round',
+              join: 'round',
+              miterLimit: 3
+            },
+            itemStyle: {
+              color: '#00b42a', // 鍘熷鐐归鑹�
+              borderColor: '#fff', // 淇濈暀鐧借壊杈规
+              // 鍚孭V浼樺寲锛氬噺灏忚竟妗嗗搴�
+              borderWidth: 0 // 浠�2璋冩暣涓�1.5
+            },
+            areaStyle: {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: 'rgba(0, 180, 42, 0.2)' }, // 鍘熷濉厖鑹�
+                { offset: 1, color: 'rgba(0, 180, 42, 0)' }
+              ])
+            },
+            smooth: true,
+            showSymbol: true, // 淇濈暀鈥滈粯璁ゆ樉绀烘墍鏈夌偣鈥�
+          }
+        ],
+        animation: true,
+        animationDuration: 1500,
+        animationEasing: 'cubicOut'
+      };
+    },
+    // 鐢熸垚pv/uv鍥捐〃鏁版嵁
+    async generateChartData(param) {
+      // 1. 澹版槑涓篴sync鍑芥暟
+      // 2. 浣跨敤await绛夊緟鎺ュ彛杩斿洖锛岀‘淇濇暟鎹幏鍙栧悗鍐嶇户缁�
+      let pvData = [];
+      let uvData = [];
+      try {
+        const res = await pvUvData(param); // 绛夊緟鎺ュ彛鍝嶅簲
+        if (res.code === 200) {
+          pvData = res.data.pvData;
+          uvData = res.data.uvData;
+          // 璁$畻pv鎬诲拰锛坧vs锛�
+          this.pvs = pvData.reduce((total, current) => {
+            // 纭繚current鏄暟瀛楋紙閬垮厤鎺ュ彛杩斿洖闈炴暟瀛楁牸寮忥級
+            return total + (Number(current) || 0);
+          }, 0);
+
+          // 璁$畻uv鎬诲拰锛坲vs锛�
+          this.uvs = uvData.reduce((total, current) => {
+            return total + (Number(current) || 0);
+          }, 0);
+          const dates = this.getDates(param); // 鑾峰彇褰撳墠绛涢�夋潯浠剁殑鏃ユ湡鏁扮粍
+          this.data = dates.map((date, index) => {
+            return {
+              date: date, // 鏃ユ湡
+              pvNum: Number(pvData[index]) || 0, // 瀵瑰簲绱㈠紩鐨勬祻瑙堥噺锛堝閿欎负0锛�
+              uvNum: Number(uvData[index]) || 0  // 瀵瑰簲绱㈠紩鐨勮瀹㈡暟锛堝閿欎负0锛�
+            };
+          });
+        }
+      } catch (error) {
+        console.error("鎺ュ彛璋冪敤澶辫触", error);
+        // 鍙牴鎹渶姹傛坊鍔犻敊璇鐞嗭紙濡傞粯璁ゆ暟鎹級
+        this.pvs = 0;
+        this.uvs = 0;
+      }
+
+      // 3. 姝ゆ椂pvData鍜寀vData宸茶鎺ュ彛鏁版嵁濉厖锛屽啀杩斿洖
+      return { pvData, uvData };
+    },
+    formatDate(date) {
+      const month = date.getMonth() + 1; // 鏈堜唤浠�0寮�濮嬶紝闇�+1
+      const day = date.getDate();
+      // 琛ラ浂锛氬鏋滄槸涓綅鏁帮紝鍓嶉潰鍔�0
+      const formattedMonth = month < 10 ? `0${month}` : month;
+      const formattedDay = day < 10 ? `0${day}` : day;
+      return `${formattedMonth}-${formattedDay}`;
+    },
+    handleResize() {
+      if (this.chart) {
+        this.chart.resize()
+      }
+    },
+    //-------------end
+    // 璁㈠崟鍥�
+
     // 鏃堕棿绛涢��
     clickBreadcrumb(item, index) {
       let callback = JSON.parse(JSON.stringify(item));
 
       this.params = callback;
+      console.log(this.params)
+      this.updateChartData(this.params)
     },
     // 鍒濆鍖�
     init() {
@@ -211,7 +457,11 @@
     },
   },
   mounted() {
-    this.init();
+    // this.init();
+    this.$nextTick(() => {
+      this.initChart2();
+    });
+    window.addEventListener('resize', this.handleResize)
   },
 };
 </script>
@@ -248,4 +498,29 @@
 .card {
   margin-bottom: 10px;
 }
+.chart-wrapper {
+  width: 100%;
+  height: 500px;
+  background-color: #fff;
+  border-radius: 8px;
+  padding: 20px;
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
+  margin-bottom: 15px;
+}
+.chart-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+}
+
+.chart-header h2 {
+  font-size: 18px;
+  font-weight: 600;
+  color: #1d2129;
+}
+.chart-container {
+  width: 100%;
+  height: 400px;
+}
 </style>

--
Gitblit v1.8.0