<template>
|
<div class="wrapper">
|
<Affix :offset-top="100">
|
<Card class="card fixed-bottom">
|
<affixTime @selected="clickBreadcrumb" />
|
</Card>
|
</Affix>
|
<!-- <Card class="card">-->
|
<!-- <div class="my-chart-container">-->
|
<!-- <!– 数据概览卡片 –>-->
|
<!--<!– <div class="stats-cards">–>-->
|
<!--<!– <div class="stat-card">–>-->
|
<!--<!– <div class="stat-header">–>-->
|
<!--<!– <span class="stat-title">总浏览量</span>–>-->
|
<!--<!– <i class="fa fa-eye stat-icon"></i>–>-->
|
<!--<!– </div>–>-->
|
<!--<!– <div class="stat-value">{{ totalPv }}</div>–>-->
|
<!--<!– <div class="stat-trend positive">–>-->
|
<!--<!– <i class="fa fa-arrow-up"></i> 12.5% 较上月–>-->
|
<!--<!– </div>–>-->
|
<!--<!– </div>–>-->
|
|
<!--<!– <div class="stat-card">–>-->
|
<!--<!– <div class="stat-header">–>-->
|
<!--<!– <span class="stat-title">平均日浏览量</span>–>-->
|
<!--<!– <i class="fa fa-calendar stat-icon"></i>–>-->
|
<!--<!– </div>–>-->
|
<!--<!– <div class="stat-value">{{ avgDailyPv }}</div>–>-->
|
<!--<!– <div class="stat-trend positive">–>-->
|
<!--<!– <i class="fa fa-arrow-up"></i> 8.3% 较上月–>-->
|
<!--<!– </div>–>-->
|
<!--<!– </div>–>-->
|
|
<!--<!– <div class="stat-card">–>-->
|
<!--<!– <div class="stat-header">–>-->
|
<!--<!– <span class="stat-title">最高单日浏览量</span>–>-->
|
<!--<!– <i class="fa fa-trophy stat-icon"></i>–>-->
|
<!--<!– </div>–>-->
|
<!--<!– <div class="stat-value">{{ maxDailyPv }}</div>–>-->
|
<!--<!– <div class="stat-trend">{{ maxPvDate }}</div>–>-->
|
<!--<!– </div>–>-->
|
<!--<!– </div>–>-->
|
|
<!-- <!– 图表区域 –>-->
|
<!-- <div class="chart-wrapper">-->
|
<!-- <div class="chart-header">-->
|
<!-- <h2>PV/UV 趋势图</h2>-->
|
<!-- </div>-->
|
<!-- <div ref="chartDom" class="chart-container"></div>-->
|
<!-- </div>-->
|
|
<!-- <!– 数据更新时间 –>-->
|
<!--<!– <div class="update-time">–>-->
|
<!--<!– 数据更新时间: {{ updateTime }}–>-->
|
<!--<!– </div>–>-->
|
<!-- </div>-->
|
<!-- </Card>-->
|
<!-- <Card class="card">-->
|
<!-- <div class="my-chart-container">-->
|
<!-- <div class="chart-wrapper">-->
|
<!-- <div class="chart-header">-->
|
<!-- <h2>订单增长 趋势图</h2>-->
|
<!-- </div>-->
|
<!-- <div ref="orderCount-chartDom" class="chart-container"></div>-->
|
<!-- </div>-->
|
<!-- </div>-->
|
<!-- </Card>-->
|
<Card class="card">
|
<div>
|
<h4>交易概况</h4>
|
<div class="flex">
|
<div class="transactionList">
|
<div
|
class="transaction-item"
|
v-for="(item, index) in transactionList"
|
:key="index"
|
>
|
<h4>{{ item.label }}</h4>
|
<div class="transaction-card" v-if="item.label == '转换'">
|
<div class="card-item">
|
<div class="card-item-label">访客数UV</div>
|
<div class="card-item-value">
|
{{ overViewList.uvNum || 0 }}
|
</div>
|
</div>
|
<div class="card-item">
|
<div class="card-item-label">下单转化率</div>
|
<div class="card-item-value">
|
{{ overViewList.orderConversionRate || "0%" }}
|
</div>
|
</div>
|
<div class="card-item">
|
<div class="card-item-label">付款转化率</div>
|
<div class="card-item-value">
|
{{ overViewList.paymentsConversionRate || "0%" }}
|
</div>
|
</div>
|
<div class="card-item">
|
<div class="card-item-label">全店转化率</div>
|
<div class="card-item-value">
|
{{ overViewList.overallConversionRate || "0%" }}
|
</div>
|
</div>
|
</div>
|
<div class="transaction-card" v-if="item.label == '订单'">
|
<div class="card-item">
|
<div class="card-item-label">下单笔数</div>
|
<div class="card-item-value">
|
{{ overViewList.orderNum || 0 }}
|
</div>
|
</div>
|
<div class="card-item">
|
<div class="card-item-label">下单人数</div>
|
<div class="card-item-value">
|
{{ overViewList.orderMemberNum || 0 }}
|
</div>
|
</div>
|
<div class="card-item">
|
<div class="card-item-label">下单金额</div>
|
<div class="card-item-value">
|
{{ overViewList.orderAmount || 0 | unitPrice("¥") }}
|
</div>
|
</div>
|
<div class="card-item">
|
<div class="card-item-label">付款笔数</div>
|
<div class="card-item-value">
|
{{ overViewList.paymentOrderNum || 0 }}
|
</div>
|
</div>
|
<div class="card-item">
|
<div class="card-item-label">付款人数</div>
|
<div class="card-item-value">
|
{{ overViewList.paymentsNum || 0 }}
|
</div>
|
</div>
|
<div class="card-item">
|
<div class="card-item-label">付款金额</div>
|
<div class="card-item-value">
|
{{ overViewList.paymentAmount || 0 | unitPrice("¥") }}
|
</div>
|
</div>
|
</div>
|
<div class="transaction-card" v-if="item.label == '退单'">
|
<div class="card-item">
|
<div class="card-item-label">退单笔数</div>
|
<div class="card-item-value">
|
{{ overViewList.refundOrderNum || 0 }}
|
</div>
|
</div>
|
<div class="card-item">
|
<div class="card-item-label">退单金额</div>
|
<div class="card-item-value">
|
{{ overViewList.refundOrderPrice || 0 | unitPrice("¥") }}
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="shap">
|
<div id="overViewChart">
|
<!-- 上 -->
|
<div class="block">
|
<div class="box">
|
<span>访客数</span>
|
<span>{{ overViewList.uvNum || 0 }}</span>
|
</div>
|
</div>
|
<!-- 中 -->
|
<div class="block">
|
<div class="box">
|
<span>下单笔数</span>
|
<span>{{ overViewList.orderNum || 0 }}</span>
|
</div>
|
</div>
|
<!-- 下 -->
|
<div class="block">
|
<div class="box">
|
<span>付款笔数</span>
|
<span>{{ overViewList.paymentOrderNum || 0 }}</span>
|
</div>
|
</div>
|
|
<!-- 线 -->
|
<div class="rightBorder"></div>
|
<div class="leftTopBorder"></div>
|
<div class="leftBottomBorder"></div>
|
<!--数据 -->
|
<div class="leftTopTips">
|
<div>下单转化率</div>
|
<div>{{ overViewList.orderConversionRate || "0%" }}</div>
|
</div>
|
<div class="leftBottomTips">
|
<div>付款转化率</div>
|
<div>{{ overViewList.paymentsConversionRate || "0%" }}</div>
|
</div>
|
<div class="rightTips">
|
<div>整体转换率</div>
|
<div>{{ overViewList.overallConversionRate || "0%" }}</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</Card>
|
|
<Card class="card">
|
<div>
|
<h4>交易趋势</h4>
|
<div></div>
|
</div>
|
|
<div>
|
<div id="orderChart"></div>
|
</div>
|
</Card>
|
|
<Card class="card">
|
<div>
|
<h4>订退单统计</h4>
|
<div class="breadcrumb" style="margin-bottom: 20px">
|
<RadioGroup
|
v-model="orderOrRefund"
|
type="button"
|
size="small"
|
button-style="solid"
|
>
|
<Radio :label="1">订单</Radio>
|
<Radio :label="0">退单</Radio>
|
</RadioGroup>
|
</div>
|
<div>
|
<Table stripe :columns="columns" :data="data"></Table>
|
</div>
|
<!-- (index) => {
|
refundParams.pageNumber = index;
|
} -->
|
<!-- (size) => {
|
(refundParams.pageSize = size), (refundParams.pageNumber = 1);
|
} -->
|
<Page
|
v-if="showRecords"
|
size="small"
|
@on-change="
|
pageNumberChange
|
"
|
@on-page-size-change="
|
pageSizeChange
|
"
|
class="mt_10"
|
show-total
|
show-sizer
|
show-elevator
|
:total="total"
|
/>
|
</div>
|
</Card>
|
</div>
|
</template>
|
<script>
|
import * as API_Goods from "@/api/goods";
|
import { Chart } from "@antv/g2";
|
import orderRow from "./order/orderDetail";
|
import refundRow from "./order/refundOrder";
|
import affixTime from "@/components/affix-time";
|
import * as echarts from 'echarts';
|
import {pvUvData} from "../../api/orderStatistics";
|
|
export default {
|
components: { orderRow, refundRow, affixTime },
|
|
data() {
|
return {
|
// 图表实例
|
chart: null, //pvuv
|
orderCountChart:null, //订单日趋势
|
|
// 统计数据
|
|
orderOrRefund: 1, // 订单还是退单
|
total: 0, // 总数
|
// 订单状态
|
orderStatusList: {
|
UNDELIVERED: "待发货",
|
UNPAID: "未付款",
|
PAID: "已付款",
|
DELIVERED: "已发货",
|
CANCELLED: "已关闭",
|
COMPLETED: "已完成",
|
TAKE: "已完成",
|
},
|
|
serviceTypeList: {
|
// 服务类型
|
CANCEL: "取消",
|
RETURN_GOODS: "退货",
|
EXCHANGE_GOODS: "换货",
|
RETURN_MONEY: "退款",
|
},
|
serviceStatusList: {
|
// 服务状态
|
APPLY: "申请售后",
|
PASS: "通过售后",
|
REFUSE: "拒绝售后",
|
BUYER_RETURN: "买家退货,待卖家收货",
|
SELLER_RE_DELIVERY: "商家换货/补发",
|
SELLER_CONFIRM: "卖家确认收货",
|
SELLER_TERMINATION: "卖家终止售后",
|
BUYER_CONFIRM: "买家确认收货",
|
BUYER_CANCEL: "买家取消售后",
|
WAIT_REFUND: "等待平台退款",
|
COMPLETE: "完成售后",
|
},
|
//
|
|
data: [], //定退单存储值
|
|
columns: [], // 定退单title
|
|
orderColumns: [
|
// 表头
|
{
|
type: "expand",
|
width: 50,
|
render: (h, params) => {
|
return h(orderRow, {
|
props: {
|
res: params.row,
|
},
|
});
|
},
|
},
|
{
|
title: "商家名称",
|
key: "storeName",
|
},
|
{
|
title: "用户名",
|
key: "memberName",
|
},
|
|
{
|
title: "订单状态",
|
key: "orderStatus",
|
render: (h, params) => {
|
return h("div", this.orderStatusList[params.row.orderStatus]);
|
},
|
},
|
{
|
title: "创建时间",
|
key: "createTime",
|
},
|
|
{
|
title: "支付时间",
|
key: "paymentTime",
|
render: (h, params) => {
|
return h("div", params.row.paymentTime || "暂无");
|
},
|
},
|
{
|
title: "价格",
|
key: "flowPrice",
|
render: (h, params) => {
|
return h("priceColorScheme", {props:{value:params.row.flowPrice,color:this.$mainColor}} );
|
},
|
},
|
{
|
title: "操作",
|
key: "action",
|
render: (h, params) => {
|
return h('Button',{
|
props:{
|
size:'small'
|
},
|
on:{
|
click: () => {
|
const { sn } = params.row
|
this.$router.push({
|
query: {sn},
|
path: this.orderOrRefund == 1 ? 'order-detail' : 'after-order-detail' + '?sn='+sn
|
})
|
}
|
}
|
},'查看')
|
},
|
},
|
],
|
refundColumns: [
|
// 表头
|
{
|
type: "expand",
|
width: 50,
|
render: (h, params) => {
|
return h(refundRow, {
|
props: {
|
res: params.row,
|
},
|
});
|
},
|
},
|
{
|
title: "商品图片",
|
key: "goodsImage",
|
render: (h, params) => {
|
return h("img", {
|
attrs: {
|
src: params.row.goodsImage,
|
},
|
style: {
|
width: "60px",
|
verticalAlign: "middle",
|
},
|
});
|
},
|
},
|
|
{
|
title: "商品名称",
|
key: "goodsName",
|
},
|
{
|
title: "商家名称",
|
key: "storeName",
|
},
|
{
|
title: "售后单类型",
|
key: "serviceType",
|
render: (h, params) => {
|
return h("div", this.serviceTypeList[params.row.serviceType]);
|
},
|
},
|
{
|
title: "售后单状态",
|
key: "serviceStatus",
|
render: (h, params) => {
|
return h("div", this.serviceStatusList[params.row.serviceStatus]);
|
},
|
},
|
{
|
title: "退款时间",
|
key: "refundTime",
|
render: (h, params) => {
|
return h("div", params.row.refundTime || "暂无");
|
},
|
},
|
{
|
title: "申请退款金额",
|
key: "applyRefundPrice",
|
render: (h, params) => {
|
return h("priceColorScheme", {props:{value:params.row.applyRefundPrice,color:this.$mainColor}} );
|
},
|
},
|
{
|
title: "申请原因",
|
key: "reason",
|
},
|
{
|
title: "实际金额",
|
key: "flowPrice",
|
render: (h, params) => {
|
return h(
|
"div",
|
this.$options.filters.unitPrice(params.row.flowPrice?params.row.flowPrice:0, "¥")
|
);
|
},
|
},
|
{
|
title: "操作",
|
key: "action",
|
render: (h, params) => {
|
return h('Button',{
|
props:{
|
size:'small'
|
},
|
on:{
|
click: () => {
|
const { sn } = params.row
|
this.$router.push({
|
query: {sn},
|
path: this.orderOrRefund == 1 ? 'order-detail' : 'after-order-detail' + '?sn='+sn
|
})
|
}
|
}
|
},'查看')
|
},
|
},
|
],
|
|
// 交易概况
|
transactionList: [
|
{
|
label: "转换",
|
value: "",
|
},
|
{
|
label: "订单",
|
value: "",
|
},
|
{
|
label: "退单",
|
value: "",
|
},
|
],
|
|
chartList: [], // 绘制订单图表数据
|
orderChart: "", //订单图表
|
|
overViewList: {}, // 绘制订单统计概览
|
overViewChart: "", //订单订单统计概览图标
|
|
// 时间
|
dateList: [
|
{
|
title: "今天",
|
selected: false,
|
value: "TODAY",
|
},
|
{
|
title: "昨天",
|
selected: false,
|
value: "YESTERDAY",
|
},
|
{
|
title: "过去7天",
|
selected: true,
|
value: "LAST_SEVEN",
|
},
|
{
|
title: "过去30天",
|
selected: false,
|
value: "LAST_THIRTY",
|
},
|
],
|
// 订单传参
|
orderParams: {
|
searchType: "LAST_SEVEN", // TODAY , YESTERDAY , LAST_SEVEN , LAST_THIRTY
|
year: "",
|
shopId: "",
|
memberId: "",
|
},
|
// 订单概念
|
overViewParams: {
|
month: "",
|
searchType: "LAST_SEVEN", // TODAY , YESTERDAY , LAST_SEVEN , LAST_THIRTY
|
storeId: "",
|
year: "",
|
},
|
defaultParams: {
|
month: "",
|
searchType: "LAST_SEVEN", // TODAY , YESTERDAY , LAST_SEVEN , LAST_THIRTY
|
storeId: "",
|
year: "",
|
},
|
// 退单订单
|
refundParams: {
|
pageNumber: 1,
|
pageSize: 10,
|
searchType: "LAST_SEVEN",
|
storeId: "",
|
year: "",
|
},
|
showRecords:false,
|
|
//
|
//
|
};
|
},
|
watch: {
|
refundParams: {
|
handler(val) {
|
this.getOrderList();
|
},
|
deep: true,
|
immediate: true,
|
},
|
orderOrRefund() {
|
this.showRecords = false;
|
this.$set(this.refundParams, "pageNumber", 1);
|
this.getOrderList();
|
},
|
orderParams: {
|
handler() {
|
this.initOrderChartList();
|
},
|
deep: true,
|
},
|
overViewParams: {
|
handler() {
|
this.initOrderOverViewList();
|
},
|
deep: true,
|
},
|
},
|
methods: {
|
//------------- puvu
|
handleResize() {
|
if (this.chart) {
|
this.chart.resize()
|
}
|
},
|
initChart(){
|
this.chart = echarts.init(this.$refs.chartDom)
|
this.updateChartData(this.orderParams)
|
},
|
// 更新图表数据
|
async updateChartData(param) {
|
// 生成日期和PV数据
|
const { dates, pvData ,uvData} = await this.generateChartData(param)
|
console.log(dates, pvData ,uvData)
|
// 更新统计数据
|
|
|
// 设置图表配置
|
this.chart.setOption(this.getChartOption(dates, 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:线条端点设为圆角,避免“切口”空白
|
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' } // 原始渐变辅助色
|
]),
|
// 同PV优化:端点圆角+拐角圆角
|
cap: 'round',
|
join: 'round',
|
miterLimit: 3
|
},
|
itemStyle: {
|
color: '#00b42a', // 原始点颜色
|
borderColor: '#fff', // 保留白色边框
|
// 同PV优化:减小边框宽度
|
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. 声明为async函数
|
const dates = [];
|
const today = new Date();
|
let days = 1;
|
|
// 确定天数逻辑不变
|
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'));
|
}
|
|
// 2. 使用await等待接口返回,确保数据获取后再继续
|
let pvData = [];
|
let uvData = [];
|
try {
|
const res = await pvUvData(param); // 等待接口响应
|
if (res.code === 200) {
|
pvData = res.data.pvData;
|
uvData = res.data.uvData;
|
}
|
} catch (error) {
|
console.error("接口调用失败", error);
|
// 可根据需求添加错误处理(如默认数据)
|
}
|
|
// 3. 此时pvData和uvData已被接口数据填充,再返回
|
return { dates, 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}`;
|
},
|
|
pageNumberChange(val){
|
this.refundParams.pageNumber = val
|
this.getOrderList();
|
},
|
pageSizeChange(val){
|
this.refundParams.pageSize = val
|
this.getOrderList();
|
},
|
// 订单图
|
initOrderChart() {
|
// 默认已经加载 legend-filter 交互
|
let data = this.chartList;
|
|
data.forEach((item) => {
|
item.createTime = item.createTime.split(" ")[0];
|
item.title = "交易额";
|
});
|
this.orderChart.data(data);
|
|
this.orderChart.tooltip({
|
showCrosshairs: true,
|
shared: true,
|
});
|
|
this.orderChart
|
.line()
|
.position("createTime*price")
|
.label("price")
|
.color("title")
|
.shape("smooth");
|
|
this.orderChart
|
.point()
|
.position("createTime*price")
|
.label("price")
|
.color("title")
|
.shape("circle")
|
.style({
|
stroke: "#fff",
|
lineWidth: 1,
|
});
|
this.orderChart.area().position("createTime*price").color("title").shape("smooth");
|
|
this.orderChart.render();
|
},
|
|
clickBreadcrumb(item, index) {
|
let callback = JSON.parse(JSON.stringify(item));
|
console.log("callback",callback)
|
this.orderParams = callback;
|
|
this.overViewParams = callback;
|
this.refundParams = callback;
|
this.refundParams.pageNumber = 1
|
this.refundParams.pageSize = 10
|
|
//更新表格
|
this.updateChartData(this.orderParams)
|
},
|
|
// 实例化订单概览
|
async initOrderOverViewList() {
|
const res = await API_Goods.getOrderOverView(this.overViewParams);
|
if (res.success) {
|
this.overViewList = res.result;
|
}
|
},
|
// 实例化订单图表
|
async initOrderChartList(name) {
|
this.orderChart ? this.orderChart.clear() : ''
|
const res = await API_Goods.getOrderChart(this.orderParams);
|
if (res.success) {
|
this.chartList = res.result;
|
|
if (!this.orderChart) {
|
this.orderChart = new Chart({
|
container: "orderChart",
|
autoFit: true,
|
height: 500,
|
padding: [70, 70, 70, 70],
|
});
|
}
|
|
this.initOrderChart(); //订单表
|
}
|
},
|
// 统计相关订单统计
|
async getOrderList() {
|
let res;
|
if (this.orderOrRefund == 1) {
|
// 订单
|
res = await API_Goods.statisticsOrderList(this.refundParams);
|
} else {
|
// 退单
|
res = await API_Goods.statisticsOrderRefundList(this.refundParams);
|
}
|
if (res.success) {
|
this.showRecords = true;
|
this.data = res.result.records;
|
this.columns =
|
this.orderOrRefund == 1 ? this.orderColumns : this.refundColumns;
|
this.total = res.result.total;
|
}
|
},
|
|
// 实例化初始值
|
initBaseParams() {
|
let data = new Date();
|
this.getOrderList();
|
this.orderParams.year = data.getFullYear();
|
this.overViewParams.year = data.getFullYear();
|
},
|
},
|
|
mounted() {
|
console.log('ECharts 是否存在:', typeof echarts !== 'undefined'); // 应输出 true
|
this.initChart();
|
this.initBaseParams();
|
window.addEventListener('resize', this.handleResize)
|
},
|
};
|
</script>
|
<style scoped lang="scss">
|
.active {
|
color: $theme_color;
|
position: relative;
|
|
&::before {
|
content: "";
|
position: absolute;
|
width: 100%;
|
height: 3px;
|
bottom: -5px;
|
left: 0;
|
background: $theme_color;
|
}
|
}
|
.breadcrumb {
|
span {
|
cursor: pointer;
|
}
|
}
|
|
.page-col {
|
text-align: right;
|
margin: 10px 0;
|
}
|
.wrapper {
|
padding-bottom: 200px;
|
}
|
.page {
|
text-align: right;
|
margin: 20px 0;
|
}
|
#overViewChart {
|
display: flex;
|
justify-content: center;
|
flex-direction: column;
|
align-items: center;
|
position: relative;
|
margin-left: 20px;
|
> .leftTopTips {
|
position: absolute;
|
top: 68px;
|
left: -2px;
|
width: 85px;
|
text-align: center;
|
background: rgb(255, 255, 255);
|
z-index: 1;
|
padding: 5px 0px;
|
}
|
> .leftBottomTips {
|
position: absolute;
|
bottom: 100px;
|
left: -2px;
|
width: 85px;
|
text-align: center;
|
background: rgb(255, 255, 255);
|
z-index: 1;
|
padding: 5px 0px;
|
}
|
> .rightTips {
|
position: absolute;
|
bottom: 240px;
|
right: 0px;
|
width: 85px;
|
text-align: center;
|
background: rgb(255, 255, 255);
|
z-index: 1;
|
padding: 5px 0px;
|
}
|
> .rightBorder {
|
width: 110px;
|
position: absolute;
|
top: 30px;
|
right: 40px;
|
border: 2px solid #d9d9d9;
|
border-left: 0;
|
height: 280px;
|
}
|
> .leftTopBorder {
|
border: 2px solid #d9d9d9;
|
height: 118px;
|
width: 56px;
|
position: absolute;
|
left: 40px;
|
top: 30px;
|
border-right: 0;
|
}
|
> .leftBottomBorder {
|
width: 108px;
|
border: 2px solid #d9d9d9;
|
height: 150px;
|
position: absolute;
|
bottom: 45px;
|
left: 40px;
|
border-right: 0;
|
}
|
> .block {
|
height: 0px;
|
border-left: 30px solid transparent;
|
border-right: 30px solid transparent;
|
position: relative;
|
background: rgb(255, 255, 255);
|
z-index: 1;
|
position: relative;
|
}
|
> .block:nth-of-type(1) {
|
width: 240px;
|
border-top: 90px solid #ff4646;
|
> .box {
|
left: -30px;
|
top: -90px;
|
width: 240px;
|
height: 90px;
|
}
|
}
|
> .block:nth-of-type(2) {
|
width: 172px;
|
border-top: 100px solid #ff8585;
|
margin-top: 10px;
|
> .box {
|
left: -29px;
|
top: -100px;
|
width: 172px;
|
height: 100px;
|
}
|
}
|
> .block:nth-of-type(3) {
|
width: 100px;
|
margin-top: 10px;
|
border-top: 150px solid #ffb396;
|
border-left: 50px solid transparent;
|
border-right: 50px solid transparent;
|
|
> .box {
|
left: -50px;
|
top: -150px;
|
width: 100px;
|
height: 120px;
|
z-index: 2;
|
}
|
}
|
/deep/ .box {
|
color: #fff;
|
position: absolute;
|
|
z-index: 2;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
> span {
|
font-size: 16px;
|
font-weight: bold;
|
}
|
}
|
}
|
|
.transaction-item {
|
margin: 10px 0;
|
}
|
h4 {
|
margin: 0 0 20px 0;
|
}
|
.transactionList {
|
flex: 7;
|
padding: 0 20px;
|
}
|
.shap {
|
width: 400px;
|
margin-left: 20px;
|
margin-top: 50px;
|
}
|
|
.transaction-card {
|
height: 120px;
|
border-radius: 0.4em;
|
display: flex;
|
background: #f3f5f7;
|
}
|
.card-item-label {
|
font-weight: bold;
|
font-size: #666;
|
font-size: 15px;
|
margin-bottom: 10px;
|
}
|
.card-item-value {
|
font-size: 15px;
|
font-weight: bold;
|
color: $theme_color;
|
}
|
.card-item {
|
height: 100%;
|
|
width: 20%;
|
align-items: center;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
flex-direction: column;
|
}
|
|
.order-col {
|
display: flex;
|
> div {
|
margin-right: 8px;
|
padding: 16px;
|
font-size: 15px;
|
}
|
}
|
.order-list {
|
display: flex;
|
}
|
.tips {
|
margin: 0 8px;
|
}
|
.card {
|
margin-bottom: 10px;
|
}
|
.my-chart-container {
|
padding: 20px;
|
background-color: #f9fafb;
|
}
|
|
.stats-cards {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 20px;
|
margin-bottom: 20px;
|
}
|
|
.stat-card {
|
flex: 1;
|
min-width: 250px;
|
background-color: #fff;
|
border-radius: 8px;
|
padding: 20px;
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
}
|
|
.stat-card:hover {
|
transform: translateY(-5px);
|
box-shadow: 0 10px 20px rgba(22, 93, 255, 0.1);
|
}
|
|
.stat-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 15px;
|
}
|
|
.stat-title {
|
color: #86909c;
|
font-size: 14px;
|
}
|
|
.stat-icon {
|
color: #165dff;
|
font-size: 18px;
|
}
|
|
.stat-value {
|
font-size: 28px;
|
font-weight: bold;
|
margin-bottom: 10px;
|
color: #1d2129;
|
}
|
|
.stat-trend {
|
font-size: 13px;
|
display: flex;
|
align-items: center;
|
}
|
|
.stat-trend.positive {
|
color: #00b42a;
|
}
|
|
.chart-wrapper {
|
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;
|
}
|
|
//.time-filters {
|
// display: flex;
|
// gap: 10px;
|
//}
|
|
//.time-filters button {
|
// padding: 6px 12px;
|
// border-radius: 4px;
|
// border: none;
|
// background-color: #f2f3f5;
|
// color: #1d2129;
|
// font-size: 14px;
|
// cursor: pointer;
|
// transition: all 0.2s ease;
|
//}
|
//
|
//.time-filters button.active {
|
// background-color: #ff4c16;
|
// color: #fff;
|
//}
|
|
.chart-container {
|
width: 100%;
|
height: 400px;
|
}
|
|
.update-time {
|
color: #86909c;
|
font-size: 12px;
|
text-align: right;
|
}
|
|
@media (max-width: 768px) {
|
.chart-header {
|
flex-direction: column;
|
align-items: flex-start;
|
gap: 10px;
|
}
|
|
.chart-container {
|
height: 300px;
|
}
|
}
|
</style>
|