From 495c4a855accf138066df32773dedac144bfd656 Mon Sep 17 00:00:00 2001
From: zxl <763096477@qq.com>
Date: 星期四, 23 十月 2025 17:22:18 +0800
Subject: [PATCH] 商户端统计
---
seller/src/views/statistics/traffic.vue | 297 +++++++++++++++++++++++++++++++++++++++++++++++-
seller/package.json | 1
seller/src/api/orderStatistics.jsx | 39 ++++++
3 files changed, 326 insertions(+), 11 deletions(-)
diff --git a/seller/package.json b/seller/package.json
index 55f0ac0..053ab34 100644
--- a/seller/package.json
+++ b/seller/package.json
@@ -15,6 +15,7 @@
"axios": "^0.21.1",
"cos-js-sdk-v5": "^1.10.1",
"dplayer": "^1.27.1",
+ "echarts": "^6.0.0",
"js-cookie": "^2.2.1",
"node-sass": "^4.14.1",
"price-color": "^1.0.2",
diff --git a/seller/src/api/orderStatistics.jsx b/seller/src/api/orderStatistics.jsx
new file mode 100644
index 0000000..41c2aa4
--- /dev/null
+++ b/seller/src/api/orderStatistics.jsx
@@ -0,0 +1,39 @@
+import service from "../libs/axios";
+
+export const pvUvData = (param) =>{
+ return service({
+ url:"/lmk/statistics/pvUv",
+ method: "GET",
+ params: param
+ })
+}
+export const getOrderCount = (param) =>{
+ return service({
+ url:"/lmk/statistics/orderCount",
+ method: "GET",
+ params: param
+ })
+}
+export const getViewAndCompletionRateCount = (param) =>{
+ return service({
+ url:"/lmk/statistics/viewAndCompletionRateCount",
+ method: "GET",
+ params: param
+ })
+}
+
+export const getOrderTimePeriod = (param) =>{
+ return service({
+ url:"/lmk/statistics/orderTimePeriod",
+ method: "GET",
+ params: param
+ })
+}
+
+export const gerProductRepurchase = (param) =>{
+ return service({
+ url:"/lmk/statistics/productRepurchase",
+ method:"GET",
+ params:param
+ })
+}
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