From eb9cf34c620908c4c20300a25bbdb92bf8134ee4 Mon Sep 17 00:00:00 2001
From: zxl <763096477@qq.com>
Date: 星期四, 23 十月 2025 15:29:45 +0800
Subject: [PATCH] 统计
---
manager/src/views/statistics/order.vue | 243 +++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 215 insertions(+), 28 deletions(-)
diff --git a/manager/src/views/statistics/order.vue b/manager/src/views/statistics/order.vue
index 9433b56..842b373 100644
--- a/manager/src/views/statistics/order.vue
+++ b/manager/src/views/statistics/order.vue
@@ -5,6 +5,7 @@
<affixTime @selected="clickBreadcrumb" />
</Card>
</Affix>
+
<Card class="card">
<div class="chart-wrapper">
<div class="chart-header">
@@ -17,7 +18,7 @@
<div class="my-chart-container">
<div class="chart-wrapper" style="height: 800px">
<div class="chart-header">
- <h2>鍟嗗搧/瑙嗛娴忚閲忓畬鎾巼 瓒嬪娍鍥�</h2>
+ <h2>鍟嗗搧/瑙嗛娴忚閲忓畬鎾巼 鎺掑悕鍥�</h2>
</div>
<div class="button-group-wrapper">
<!-- 绗竴缁勶細鍟嗗搧/瑙嗛锛堥潬宸︼級 -->
@@ -72,7 +73,6 @@
</div>
</div>
</Card>
-
<Card class="card">
<div class="my-chart-container">
<div class="chart-wrapper">
@@ -82,7 +82,40 @@
<div ref="orderTimePeriodChartDom" class="chart-container"></div>
</div>
</div>
-
+ </Card>
+ <Card class="card">
+ <div class="my-chart-container">
+ <div class="chart-wrapper" style="height: 800px">
+ <div class="chart-header">
+ <h2>鍟嗗搧澶嶈喘鐜� 鎺掑悕鍥�</h2>
+ </div>
+ <div class="button-group-wrapper">
+ <!-- 椤甸潰鏍峰紡闇�瑕� -->
+ <div></div>
+ <ButtonGroup>
+ <Button
+ :type="repurchaseCurrentLimit === 10 ? 'success' : 'default'"
+ @click="handleRepurchaseLimitChange(10)"
+ >
+ 鍓�10
+ </Button>
+ <Button
+ :type="repurchaseCurrentLimit === 20 ? 'success' : 'default'"
+ @click="handleRepurchaseLimitChange(20)"
+ >
+ 鍓�20
+ </Button>
+ <Button
+ :type="repurchaseCurrentLimit === 30 ? 'success' : 'default'"
+ @click="handleRepurchaseLimitChange(30)"
+ >
+ 鍓�30
+ </Button>
+ </ButtonGroup>
+ </div>
+ <div ref="productRepurchaseRateChartDom" class="repurchase-chart-container"></div>
+ </div>
+ </div>
</Card>
@@ -284,7 +317,7 @@
import refundRow from "./order/refundOrder";
import affixTime from "@/components/affix-time";
import * as echarts from 'echarts';
-import {pvUvData,getOrderCount,getViewAndCompletionRateCount,getOrderTimePeriod} from "../../api/orderStatistics";
+import {pvUvData,getOrderCount,getViewAndCompletionRateCount,getOrderTimePeriod,gerProductRepurchase} from "../../api/orderStatistics";
export default {
components: { orderRow, refundRow, affixTime },
@@ -294,11 +327,16 @@
// 鍥捐〃瀹炰緥
chart: null, //pvuv
orderCountChart:null, //璁㈠崟鏃ヨ秼鍔�
- viewPrintChart:null,
- orderTimePeriodChart:null,
+ viewPrintChart:null, //瀹屾挱鐜�
+ orderTimePeriodChart:null, //璁㈠崟/娴忚鏃堕棿
+ productRepurchaseRateChart:null,//鍟嗗搧澶嶈喘鐜�
currentType:"goods",
currentLimit:10,
+
+ repurchaseCurrentLimit:10,
+
+
// 缁熻鏁版嵁
orderOrRefund: 1, // 璁㈠崟杩樻槸閫�鍗�
@@ -621,8 +659,6 @@
const dates = [];
const today = new Date();
let days = 1;
- console.log(param.year)
- console.log(param.month)
if(param.year !== null && param.year !== undefined && param.month !== null && param.month !== undefined && param.month !=='' ){
// 褰撲紶鍏ュ勾浠藉拰鏈堜唤鏃讹紝鐢熸垚璇ユ湀浠界殑鎵�鏈夋棩鏈�
const year = parseInt(param.year);
@@ -672,28 +708,34 @@
if (this.orderTimePeriodChart){
this.orderTimePeriodChart.resize();
}
+ if (this.productRepurchaseRateChart){
+ this.productRepurchaseRateChart.resize();
+ }
},
initChart(){
this.chart = echarts.init(this.$refs.chartDom)
this.viewPrintChart = echarts.init(this.$refs.viewPrintChartDom)
this.orderCountChart = echarts.init(this.$refs.orderCountChartDom)
this.orderTimePeriodChart = echarts.init(this.$refs.orderTimePeriodChartDom)
+ this.productRepurchaseRateChart = echarts.init(this.$refs.productRepurchaseRateChartDom)
- this.updateChartData(this.orderParams)
- this.updateOrderCountChartDate(this.orderParams)
+ this.updateChartData(this.orderParams)//鏇存柊 pvuv
- let form = {...this.orderParams};
- console.log(this.currentType)
- console.log(this.currentLimit)
- form.currentType = this.currentType;
- form.currentLimit = this.currentLimit;
- console.log(form)
- this.updateViewAndCompletionRateData(form)
+ this.updateOrderCountChartDate(this.orderParams)//鏇存柊鏃ヨ鍗�
- this.updateOrderTimePeriodData(this.orderParams)
+ let viewForm = {...this.orderParams};
+ viewForm.currentType = this.currentType;
+ viewForm.currentLimit = this.currentLimit;
+ this.updateViewAndCompletionRateData(viewForm)//鏇存柊瀹屾挱鐜�
+
+ this.updateOrderTimePeriodData(this.orderParams)//鏇存柊娴忚鏁版嵁锛屼笅璁㈠崟鏃ユ湡鏃堕棿娈靛垎鏋�
+
+ let productRepurchaseDataForm ={...this.orderParams};
+ productRepurchaseDataForm.currentLimit = this.repurchaseCurrentLimit
+ this.updateProductRepurchaseData(productRepurchaseDataForm)//
},
- // 鏇存柊鍥捐〃鏁版嵁
+ //------------鏇存柊鍥捐〃鏁版嵁pvuv start
async updateChartData(param) {
// 鐢熸垚鏃ユ湡鍜孭V鏁版嵁
const { pvData ,uvData} = await this.generateChartData(param)
@@ -851,8 +893,8 @@
// 3. 姝ゆ椂pvData鍜寀vData宸茶鎺ュ彛鏁版嵁濉厖锛屽啀杩斿洖
return { pvData, uvData };
},
- //-------------
- //-------------璁㈠崟鏃ヨ秼鍔�
+ //-------------end
+ //-------------璁㈠崟鏃ヨ秼鍔縮tart
async updateOrderCountChartDate(param){
const { orderCountData } = await this.generateOrderCountChartData(param)
this.orderCountChart.setOption(this.getOrderCountChartOption(this.getDates(param),orderCountData))
@@ -954,9 +996,9 @@
animationEasing: 'cubicOut' // 缂撳姩鏁堟灉锛屼紭鍖栧姩鐢绘祦鐣呭害
};
},
- //-------------
+ //-------------end
- //-------------娴忚閲忥紝瀹屾挱鐜囷紝
+ //-------------娴忚閲忥紝瀹屾挱鐜囷紝start
handleLimitChange(limit) {
if (this.currentLimit !== limit) {
this.currentLimit = limit
@@ -1026,9 +1068,9 @@
formatter:tooltipFormatter
},
grid: {
- left: '5%', // 瑙嗛绫诲瀷宸︾Щ锛岀粰瀹屾挱鐜囨爣绛剧暀绌洪棿
- right: '10%',
- bottom: '0',
+ left: '4%', // 瑙嗛绫诲瀷宸︾Щ锛岀粰瀹屾挱鐜囨爣绛剧暀绌洪棿
+ right: '12%',
+ bottom: '2%',
top: '5%',
containLabel: true
},
@@ -1043,6 +1085,7 @@
min: 0
},
yAxis: {
+ inverse: true,
type: 'category',
data: yData,
axisLine: { lineStyle: { color: '#ddd' } },
@@ -1090,8 +1133,8 @@
]
};
},
- //-------------
- //-------------娴忚鏁版嵁锛屼笅璁㈠崟鏃ユ湡鏃堕棿娈靛垎鏋�
+ //-------------end
+ //-------------娴忚鏁版嵁锛屼笅璁㈠崟鏃ユ湡鏃堕棿娈靛垎鏋恠tart
async updateOrderTimePeriodData(param){
const { viewData,countData,dateData} = await this.generateOrderTimePeriodChartData(param);
this.orderTimePeriodChart.setOption(this.getOrderTimePeriodChartOption(viewData,countData,dateData));
@@ -1243,7 +1286,141 @@
animationEasing: 'cubicOut'
};
},
+ //--------------ebd
+ //-------------澶嶈喘鐜� start
+ handleRepurchaseLimitChange(limit) {
+ if (this.repurchaseCurrentLimit !== limit) {
+ this.repurchaseCurrentLimit = limit
+ let form = {...this.orderParams}
+ form.currentLimit = this.repurchaseCurrentLimit;
+ this.updateProductRepurchaseData(form) // 閲嶆柊鍔犺浇鏁版嵁
+ }
+ },
+ async updateProductRepurchaseData(param){
+ const { rateData,goodsData} = await this.generateProductRepurchaseChartData(param);
+ this.productRepurchaseRateChart.setOption(this.getProductRepurchaseChartOption(this.getDates(param),rateData,goodsData));
+ },
+ async generateProductRepurchaseChartData(param){
+ let rateData = [];
+ let goodsData = [];
+ try{
+ const res = await gerProductRepurchase(param);
+ if (res.code === 200){
+ rateData = res.data.rateData;
+ goodsData = res.data.goodsData;
+ }
+ }catch (error){
+ console.error("鎺ュ彛璋冪敤澶辫触", error);
+ }
+ return {rateData,goodsData}
+ },
+ getProductRepurchaseChartOption(dates, rateData, goodsData) {
+ // 宸ュ叿鍑芥暟锛氬垽鏂暟鍊兼槸鍚︿负鏁存暟锛堥伩鍏�100.00鏄剧ず涓�100.00%锛�
+ const isInteger = (num) => {
+ return Math.abs(num - Math.round(num)) < Number.EPSILON;
+ };
+
+ return {
+ tooltip: {
+ trigger: 'axis',
+ backgroundColor: 'rgba(255, 255, 255, 0.9)',
+ borderColor: '#eee',
+ borderWidth: 1,
+ textStyle: { color: '#333' },
+ axisPointer: {
+ type: 'shadow'
+ },
+ formatter: (params) => {
+ const goodsName = params[0].name;
+ const rate = params[0].value;
+ // 鏁存暟鏄剧ず鏃犲皬鏁帮紝闈炴暣鏁颁繚鐣欎袱浣嶅皬鏁�
+ const displayRate = isInteger(rate) ? rate : rate.toFixed(2);
+ return `<div class="font-medium">${goodsName}</div>
+ <div>澶嶈喘鐜�: <span style="color: #722ED1; font-weight: bold">${displayRate}%</span></div>`;
+ },
+ },
+ grid: {
+ left: '3%',
+ right: '4%',
+ bottom: '3%',
+ top: '3%',
+ containLabel: true
+ },
+ xAxis: {
+ type: 'value',
+ axisLine: { show: false },
+ axisTick: { show: false },
+ axisLabel: {
+ color: '#86909C',
+ // 鍧愭爣杞存爣绛撅細鏁存暟鏄剧ず鏃犲皬鏁帮紝闈炴暣鏁颁繚鐣�0浣嶏紙鍙栨暣锛�
+ formatter: (value) => {
+ return isInteger(value) ? `${value}%` : `${Math.round(value)}%`;
+ }
+ },
+ splitLine: {
+ lineStyle: {
+ color: '#f2f3f5',
+ type: 'dashed'
+ }
+ },
+ min: 0,
+ max: (value) => {
+ // 闄愬埗鏈�澶у�间笉瓒呰繃100锛堝璐巼鏈�楂�100%锛夛紝鍚屾椂淇濈暀1.2鍊嶇殑闂磋窛
+ const calculatedMax = value.max * 1.2;
+ return Math.min(calculatedMax, 100);
+ }
+ },
+ yAxis: {
+ type: 'category',
+ data: goodsData,
+ axisLine: { lineStyle: { color: '#eee' } },
+ axisTick: { show: false },
+ axisLabel: {
+ color: '#86909C',
+ interval: 0,
+ formatter: (value) => {
+ return value.length > 10 ? value.substring(0, 10) + '...' : value;
+ }
+ },
+ splitLine: { show: false },
+ inverse: true
+ },
+ series: [
+ {
+ name: '鍟嗗搧澶嶈喘鐜�',
+ type: 'bar',
+ data: rateData,
+ barWidth: '60%',
+ itemStyle: {
+ color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+ { offset: 0, color: '#722ED1' },
+ { offset: 1, color: '#EB2F96' }
+ ]),
+ borderRadius: [0, 4, 4, 0]
+ },
+ emphasis: {
+ itemStyle: {
+ shadowBlur: 10,
+ shadowColor: 'rgba(114, 46, 209, 0.5)'
+ }
+ },
+ label: {
+ show: true,
+ position: 'right',
+ // 鏌辩姸鍥炬爣绛撅細鏁存暟鏄剧ず鏃犲皬鏁帮紝闈炴暣鏁颁繚鐣�1浣�
+ formatter: (params) => {
+ const value = params.value;
+ return isInteger(value) ? `${value}%` : value.toFixed(1) + '%';
+ },
+ color: '#722ED1',
+ fontWeight: 'bold'
+ }
+ }
+ ],
+ };
+ },
+ //-------------end
formatDate(date) {
const month = date.getMonth() + 1; // 鏈堜唤浠�0寮�濮嬶紝闇�+1
const day = date.getDate();
@@ -1310,6 +1487,7 @@
this.refundParams.pageSize = 10
//鏇存柊琛ㄦ牸
+
this.updateChartData(this.orderParams)
this.updateOrderCountChartDate(this.orderParams)
@@ -1319,6 +1497,11 @@
this.updateViewAndCompletionRateData(form)
this.updateOrderTimePeriodData(this.orderParams)
+
+ let productRepurchaseDataForm ={...this.orderParams};
+ productRepurchaseDataForm.currentLimit = this.repurchaseCurrentLimit
+
+ this.updateProductRepurchaseData(productRepurchaseDataForm)//
},
// 瀹炰緥鍖栬鍗曟瑙�
@@ -1723,6 +1906,10 @@
width: 100%;
height: 662px;
}
+.repurchase-chart-container{
+ width: 100%;
+ height: 662px;
+}
.chart-container {
width: 100%;
height: 400px;
--
Gitblit v1.8.0