From 11a9f5f2e4dd4bf88968975abc8fb8be233c9b27 Mon Sep 17 00:00:00 2001
From: peng <peng.com>
Date: 星期四, 16 十月 2025 13:47:46 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/send_coupon' into send_coupon
---
manager/src/views/statistics/order.vue | 406 ++++++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 296 insertions(+), 110 deletions(-)
diff --git a/manager/src/views/statistics/order.vue b/manager/src/views/statistics/order.vue
index a931028..842b373 100644
--- a/manager/src/views/statistics/order.vue
+++ b/manager/src/views/statistics/order.vue
@@ -6,84 +6,117 @@
</Card>
</Affix>
-<!-- <Card class="card">-->
-<!-- <div class="chart-wrapper">-->
-<!-- <div class="chart-header">-->
-<!-- <h2>PV/UV 瓒嬪娍鍥�</h2>-->
-<!-- </div>-->
-<!-- <div ref="chartDom" class="chart-container"></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">-->
-<!-- <!– 绗竴缁勶細鍟嗗搧/瑙嗛锛堥潬宸︼級 –>-->
-<!-- <ButtonGroup>-->
-<!-- <Button-->
-<!-- :type="currentType === 'goods' ? 'primary' : 'default'"-->
-<!-- @click="handleTypeChange('goods')"-->
-<!-- >-->
-<!-- 鍟嗗搧-->
-<!-- </Button>-->
-<!-- <Button-->
-<!-- :type="currentType === 'video' ? 'primary' : 'default'"-->
-<!-- @click="handleTypeChange('video')"-->
-<!-- >-->
-<!-- 瑙嗛-->
-<!-- </Button>-->
-<!-- </ButtonGroup>-->
+ <Card class="card">
+ <div class="chart-wrapper">
+ <div class="chart-header">
+ <h2>PV/UV 瓒嬪娍鍥�</h2>
+ </div>
+ <div ref="chartDom" class="chart-container"></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">
+ <!-- 绗竴缁勶細鍟嗗搧/瑙嗛锛堥潬宸︼級 -->
+ <ButtonGroup>
+ <Button
+ :type="currentType === 'goods' ? 'primary' : 'default'"
+ @click="handleTypeChange('goods')"
+ >
+ 鍟嗗搧
+ </Button>
+ <Button
+ :type="currentType === 'video' ? 'primary' : 'default'"
+ @click="handleTypeChange('video')"
+ >
+ 瑙嗛
+ </Button>
+ </ButtonGroup>
-<!-- <!– 绗簩缁勶細鍓�10/鍓�20/鍓�30锛堥潬鍙筹級 –>-->
-<!-- <ButtonGroup>-->
-<!-- <Button-->
-<!-- :type="currentLimit === 10 ? 'success' : 'default'"-->
-<!-- @click="handleLimitChange(10)"-->
-<!-- >-->
-<!-- 鍓�10-->
-<!-- </Button>-->
-<!-- <Button-->
-<!-- :type="currentLimit === 20 ? 'success' : 'default'"-->
-<!-- @click="handleLimitChange(20)"-->
-<!-- >-->
-<!-- 鍓�20-->
-<!-- </Button>-->
-<!-- <Button-->
-<!-- :type="currentLimit === 30 ? 'success' : 'default'"-->
-<!-- @click="handleLimitChange(30)"-->
-<!-- >-->
-<!-- 鍓�30-->
-<!-- </Button>-->
-<!-- </ButtonGroup>-->
-<!-- </div>-->
-<!-- <div ref="viewPrintChartDom" class="view-chart-container"></div>-->
-<!-- </div>-->
-<!-- </div>-->
-<!-- </Card>-->
-<!-- <Card class="card">-->
-<!-- <div class="my-chart-container">-->
-<!-- <div class="chart-wrapper">-->
-<!-- <div class="chart-header">-->
-<!-- <h2>璁㈠崟澧為暱 瓒嬪娍鍥�</h2>-->
-<!-- </div>-->
-<!-- <div ref="orderCountChartDom" class="chart-container"></div>-->
-<!-- </div>-->
-<!-- </div>-->
-<!-- </Card>-->
-<!-- <Card class="card">-->
-<!-- <div class="my-chart-container">-->
-<!-- <div class="chart-wrapper">-->
-<!-- <div class="chart-header">-->
-<!-- <h2>娴忚鏁版嵁/璁㈠崟鏃堕棿娈� 瓒嬪娍鍥�</h2>-->
-<!-- </div>-->
-<!-- <div ref="orderTimePeriodChartDom" class="chart-container"></div>-->
-<!-- </div>-->
-<!-- </div>-->
-
-<!-- </Card>-->
+ <!-- 绗簩缁勶細鍓�10/鍓�20/鍓�30锛堥潬鍙筹級 -->
+ <ButtonGroup>
+ <Button
+ :type="currentLimit === 10 ? 'success' : 'default'"
+ @click="handleLimitChange(10)"
+ >
+ 鍓�10
+ </Button>
+ <Button
+ :type="currentLimit === 20 ? 'success' : 'default'"
+ @click="handleLimitChange(20)"
+ >
+ 鍓�20
+ </Button>
+ <Button
+ :type="currentLimit === 30 ? 'success' : 'default'"
+ @click="handleLimitChange(30)"
+ >
+ 鍓�30
+ </Button>
+ </ButtonGroup>
+ </div>
+ <div ref="viewPrintChartDom" class="view-chart-container"></div>
+ </div>
+ </div>
+ </Card>
+ <Card class="card">
+ <div class="my-chart-container">
+ <div class="chart-wrapper">
+ <div class="chart-header">
+ <h2>璁㈠崟澧為暱 瓒嬪娍鍥�</h2>
+ </div>
+ <div ref="orderCountChartDom" class="chart-container"></div>
+ </div>
+ </div>
+ </Card>
+ <Card class="card">
+ <div class="my-chart-container">
+ <div class="chart-wrapper">
+ <div class="chart-header">
+ <h2>娴忚鏁版嵁/璁㈠崟鏃堕棿娈� 瓒嬪娍鍥�</h2>
+ </div>
+ <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>
<Card class="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
@@ -1028,7 +1070,7 @@
grid: {
left: '4%', // 瑙嗛绫诲瀷宸︾Щ锛岀粰瀹屾挱鐜囨爣绛剧暀绌洪棿
right: '12%',
- bottom: '0',
+ 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();
@@ -1311,15 +1488,20 @@
//鏇存柊琛ㄦ牸
- // this.updateChartData(this.orderParams)
- // this.updateOrderCountChartDate(this.orderParams)
- //
- // let form = {...this.orderParams};
- // form.currentType = this.currentType;
- // form.currentLimit = this.currentLimit;
- // this.updateViewAndCompletionRateData(form)
- //
- // this.updateOrderTimePeriodData(this.orderParams)
+ this.updateChartData(this.orderParams)
+ this.updateOrderCountChartDate(this.orderParams)
+
+ let form = {...this.orderParams};
+ form.currentType = this.currentType;
+ form.currentLimit = this.currentLimit;
+ this.updateViewAndCompletionRateData(form)
+
+ this.updateOrderTimePeriodData(this.orderParams)
+
+ let productRepurchaseDataForm ={...this.orderParams};
+ productRepurchaseDataForm.currentLimit = this.repurchaseCurrentLimit
+
+ this.updateProductRepurchaseData(productRepurchaseDataForm)//
},
// 瀹炰緥鍖栬鍗曟瑙�
@@ -1378,7 +1560,7 @@
mounted() {
console.log('ECharts 鏄惁瀛樺湪锛�', typeof echarts !== 'undefined'); // 搴旇緭鍑� true
- // this.initChart();
+ this.initChart();
this.initBaseParams();
window.addEventListener('resize', this.handleResize)
},
@@ -1724,6 +1906,10 @@
width: 100%;
height: 662px;
}
+.repurchase-chart-container{
+ width: 100%;
+ height: 662px;
+}
.chart-container {
width: 100%;
height: 400px;
--
Gitblit v1.8.0