Files
cashier-web/src/views/data/index.vue

2129 lines
63 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="app-container" style="padding-bottom: 100px">
<!-- <div class="card_wrap">
<div class="card">
<div class="header">
<div class="card_title">总销售额</div>
<el-tooltip effect="dark" content="订单支付金额" placement="top">
<i class="icon el-icon-warning-outline"></i>
</el-tooltip>
</div>
<div class="number">{{ topData.totalSales || 0 }}</div>
<div class="row">平均每单{{ topData.averageSales || 0 }}</div>
<div class="row">今日销售额{{ topData.totalSalesToday || 0 }}</div>
</div>
<div class="card">
<div class="header">
<div class="card_title">支付笔数</div>
</div>
<div class="number">{{ topData.paymentsNumber }}</div>
<div class="row" ref="cardPayChart" style="padding-bottom: 2px;"></div>
<div class="row">
今日支付笔数{{ topData.paymentsNumberToday || 0 }}
</div>
</div>
<div class="card">
<div class="header">
<div class="card_title">访问量</div>
</div>
<div class="number">{{ topData.totalVisits }}</div>
<div class="row" ref="cardCountChart" style="padding-bottom: 2px;"></div>
<div class="row">
<div class="dot"></div>
今日访问 {{ topData.totalVisitsToday || 0 }}
</div>
</div>
<div class="card">
<div class="header">
<div class="card_title">用户数</div>
</div>
<div class="number">{{ topData.totalUser }}</div>
<div class="row" ref="cardUserChart" style="padding-bottom: 2px;"></div>
<div class="row">
今日新增 {{ topData.userToday || 0 }}
<i class="icon el-icon-caret-top"></i>
</div>
</div>
</div> -->
<div class="h_card_wrap">
<div class="status_wrap">
<div class="left" style="flex-shrink: 0">
<div class="dot" />
<span>营业</span>
</div>
<div class="u-flex" style="flex-wrap: wrap">
<el-select v-if="isHeadShop == 1 && loginType == 0" v-model="shopId" placeholder="选择分店"
style="width: 200px; margin-right: 10px;" @change="shopChange">
<el-option v-for="item in branchList" :key="item.shopId" :label="item.shopName" :value="item.shopId" />
</el-select>
<div class="time_wrap u-flex" style="flex-shrink: 0">
<div class="date_list">
<div class="item" :class="{ active: dataListActive == index }" v-for="(item, index) in dateList"
:key="item.value" @click="timeChange(item.value, index)">
<!-- 标签文本 -->
<span class="date-tab-item">{{ item.label }}</span>
<!-- 分隔符非最后一项才显示 -->
<span class="separator" v-if="index < dateList.length - 1">|</span>
</div>
</div>
<div class="u-flex">
<el-date-picker v-if="timeValue == 'custom'" v-model="query.createdAt" type="daterange"
range-separator="" start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD"
@change="summarytrade" />
</div>
</div>
</div>
</div>
<div v-loading="tradeLoading" class="content">
<div class="top">
<div class="item earnings">
<div class="num_wrap">
<div class="num">{{ formatDecimal(trade.payAmount + trade.rechargeAmount || 0) }}</div>
<div class="tips">
营业额()
<el-tooltip popper-class="popper" effect="light" placement="bottom">
<template #content>
<div class="tips_row">
<div class="item">
<div class="left">
<img class="icon" src="@/assets/images/data/wx.png" />
<span>微信小程序</span>
</div>
<span class="num">{{ trade.wechatPayAmount || 0 }}</span>
</div>
<div class="item">
<div class="left">
<img class="icon" src="@/assets/images/data/ali.png" />
<span>支付宝小程序</span>
</div>
<span class="num">{{ trade.aliPayAmount || 0 }}</span>
</div>
<div class="item">
<div class="left">
<img class="icon" src="@/assets/images/data/scan.png" />
<span>主扫收款</span>
</div>
<span class="num">{{ trade.backScanPayAmount || 0 }}</span>
</div>
<div class="item">
<div class="left">
<img class="icon" src="@/assets/images/data/cash.png" />
<span>现金</span>
</div>
<span class="num">{{ trade.cashPayAmount || 0 }}</span>
</div>
<div class="item">
<div class="left">
<img class="icon" src="@/assets/images/data/cash.png" />
<span>充值</span>
</div>
<span class="num">{{ trade.rechargeAmount || 0 }}</span>
</div>
<div class="item">
<div class="left">
<img class="icon" src="@/assets/images/data/cash.png" />
<span>挂账</span>
</div>
<span class="num">{{ trade.creditPayAmount || 0 }}</span>
</div>
<div class="item">
<div class="left">
<img class="icon" src="@/assets/images/data/cash.png" />
<span>余额支付</span>
</div>
<span class="num">{{ trade.memberPayAmount || 0 }}</span>
</div>
</div>
</template>
<el-icon>
<QuestionFilled />
</el-icon>
</el-tooltip>
</div>
</div>
<div class="line_wrap">
<div class="line_item">
<div class="line_item_top">
<div>销售金额</div>
<!-- <div class="t">{{ formatDecimal(tradeSale.totalpayAmount || 0) }}</div> -->
</div>
<div class="line_gropress">
<div class="gropress l" :style="{
width: `${trade.payAmount
? (trade.payAmount / (trade.payAmount * 1 + trade.refundAmount * 1)) *
100
: 0
}%`,
}" />
<div class="gropress r" :style="{
width: `${trade.refundAmount
? (trade.refundAmount / (trade.payAmount * 1 + trade.refundAmount * 1)) *
100
: 0
}%`,
}" />
</div>
<div class="line_btm">
<el-icon class="icon el-icon-caret-right" />
<div class="info">
<span class="l_t">{{ formatDecimal(trade.payAmount || 0) }}</span>
<span class="l_r">退{{ formatDecimal(trade.refundAmount || 0) }}</span>
</div>
</div>
</div>
<div class="line_item">
<div class="line_item_top">
<div>充值金额</div>
<!-- <div class="t">{{ formatDecimal(tradeSale.totalVipAmount || 0) }}</div> -->
</div>
<div class="line_gropress">
<div class="gropress l" :style="{
width: `${trade.rechargeAmount
? (trade.rechargeAmount /
(trade.memberPayAmount + trade.rechargeRefundAmount * 1)) *
100
: 0
}%`,
}" />
<div class="gropress r" :style="{
width: `${trade.rechargeRefundAmount
? (trade.rechargeRefundAmount /
(trade.memberPayAmount + trade.rechargeRefundAmount * 1)) *
100
: 0
}%`,
}" />
</div>
<div class="line_btm">
<el-icon class="icon el-icon-caret-right" />
<div class="info">
<span class="l_t">{{ formatDecimal(trade.rechargeAmount || 0) }}</span>
<span class="l_r">
退{{ formatDecimal(trade.rechargeRefundAmount || 0) }}
</span>
</div>
</div>
</div>
</div>
</div>
<div class="item data">
<div class="right_data_wrap">
<div class="item">
<div class="num">{{ formatDecimal(trade.memberPayAmount || 0) }}</div>
<div class="tips">余额支付金额</div>
</div>
<div class="item">
<div class="num">{{ trade.memberPayCount || 0 }}</div>
<div class="tips">余额支付</div>
</div>
<div class="item">
<div class="num">{{ trade.newMemberCount || 0 }}</div>
<div class="tips">新增会员数</div>
</div>
</div>
<!-- <div class="data_item">
<div class="num_wrap">
<div class="num">{{ formatDecimal(trade.memberPayAmount || 0) }}</div>
<div class="tips">会员消费</div>
</div>
</div>
<div class="data_item_right">
<div class="t">
<span>新增会员数</span>
<span class="n">{{ trade.newMemberCount || 0 }}()</span>
</div>
<div class="t">
<span>会员消费笔数</span>
<span class="n">{{ trade.memberPayCount || 0 }}</span>
</div>
</div> -->
</div>
</div>
<div class="btm">
<div class="item item1">
<div class="title">
客单价
<el-tooltip effect="dark" :content="`订单实付金额(${trade.payAmount}/就餐人数(${trade.customerCount || 0}`"
placement="top">
<el-icon>
<QuestionFilled />
</el-icon>
</el-tooltip>
</div>
<div class="icon_wrap">
<img class="img" src="@/assets/images/data_home_item1_icon.png" />
<div class="t" style="color: #0080FF;">{{ formatDecimal(trade.avgPayAmount || 0) }}</div>
</div>
</div>
<div class="item item2">
<div class="title">
翻台率
<el-tooltip effect="dark"
:content="`翻台率=(客单数(${trade.customerCount || 0}-桌台数(${trade.tableCount || 0}/桌台数*100%`"
placement="top">
<el-icon>
<QuestionFilled />
</el-icon>
</el-tooltip>
</div>
<div class="icon_wrap">
<img class="img" src="@/assets/images/data_home_item2_icon.png" />
<div class="t" style="color: #FFB200;">{{ trade.turnoverRate || 0 }}%</div>
</div>
</div>
<div class="item item3">
<div class="title">
优惠金额
<el-tooltip popper-class="popper" effect="light" placement="bottom">
<template #content>
<div class="tips_row">
<div class="item">
<div class="left">
<span>优惠类目</span>
</div>
<span class="num">优惠金额</span>
</div>
<div class="item">
<div class="left">
<span>新客立减</span>
</div>
<span class="num">{{ multiplyAndFormat(trade.newCustomerDiscountAmount || 0) }}</span>
</div>
<div class="item">
<div class="left">
<span>满减活动</span>
</div>
<span class="num">{{ multiplyAndFormat(trade.fullDiscountAmount || 0) }}</span>
</div>
<div class="item">
<div class="left">
<span>优惠券抵扣</span>
</div>
<span class="num">{{ multiplyAndFormat(trade.couponDiscountAmount || 0) }}</span>
</div>
<div class="item">
<div class="left">
<span>积分抵扣</span>
</div>
<span class="num">{{ multiplyAndFormat(trade.pointDiscountAmount || 0) }}</span>
</div>
<div class="item">
<div class="left">
<span>霸王餐</span>
</div>
<span class="num">{{ multiplyAndFormat(trade.backDiscountAmount || 0) }}</span>
</div>
<div class="item">
<div class="left">
<span>会员折扣</span>
</div>
<span class="num">{{ multiplyAndFormat(trade.memberDiscountAmount || 0) }}</span>
</div>
<div class="item">
<div class="left">
<span>订单改价</span>
</div>
<span class="num">{{ multiplyAndFormat(trade.orderPriceDiscountAmount || 0) }}</span>
</div>
</div>
</template>
<el-icon>
<QuestionFilled />
</el-icon>
</el-tooltip>
</div>
<div class="icon_wrap">
<img class="img" src="@/assets/images/data_home_item3_icon.png" />
<div class="t" style="color: #FF8000;">{{ formatDecimal(trade.discountAmount || 0) }}</div>
</div>
</div>
<div class="item item4">
<div class="title">优惠笔数</div>
<div class="icon_wrap">
<img class="img" src="@/assets/images/data_home_item4_icon.png" />
<div class="t" style="color: #00CB71;">{{ trade.discountCount || 0 }}</div>
</div>
</div>
<div class="item item5">
<div class="row_wrap">
<div class="row">
<div class="title">毛利润</div>
<div class="icon_wrap">
<div class="t" style="color: #0000C2;">{{ trade.profitAmount || 0 }}</div>
</div>
</div>
<div class="row">
<div class="title">毛利率</div>
<div class="icon_wrap">
<div class="t" style="color: #0000C2;">{{ trade.profitRate || 0 }}%</div>
</div>
</div>
</div>
</div>
<!-- <div class="item item6">
<div class="row_wrap">
<div class="row">
<div class="title">净利润</div>
<div class="icon_wrap">
<div class="t" style="color: #E30675;">{{ trade.netProfitAmount || 0 }}</div>
</div>
</div>
<div class="row">
<div class="title">净利率</div>
<div class="icon_wrap">
<div class="t" style="color: #E30675;">{{ trade.netProfitRate || 0 }}%</div>
</div>
</div>
</div>
</div> -->
</div>
</div>
</div>
<!-- 销售额 -->
<div class="chart_wrap" style="display: flex">
<div class="item">
<div class="header">
<div class="tab_wrap">
<div class="item" :class="{ active: lineChartType == 0 }" @click="lineChartTypeChange(0)">
销售趋势
</div>
<div class="item" :class="{ active: lineChartType == 1 }" @click="lineChartTypeChange(1)">
支付占比
</div>
</div>
<el-radio-group v-model="saleActive" @change="lineChartTypeChange(lineChartType)">
<el-radio-button value="7">近7天</el-radio-button>
<el-radio-button value="30">30</el-radio-button>
</el-radio-group>
</div>
<div v-show="lineChartType == 0" ref="saleChart" v-loading="saleLoading" class="chart" style="height: 350px" />
<div v-show="lineChartType == 1" ref="payChart" v-loading="payChartLoading" class="chart"
style="height: 350px" />
</div>
<!-- 商品销售排行 -->
<div class="item">
<div class="header">
<div class="tab_wrap">
<div class="item active">商品销售排行</div>
</div>
<el-radio-group v-model="saleTableActive" @change="rankChange">
<!-- <el-radio-button label="1">今天</el-radio-button> -->
<el-radio-button value="7">近7天</el-radio-button>
<el-radio-button value="30">30</el-radio-button>
</el-radio-group>
</div>
<div class="sale_data">
<!-- <div class="card">
<div class="sale_data_header">
<div class="card_title">销售数量</div>
</div>
<div class="number">{{ productCount }}</div>
<div class="product_chart_wrap" ref="productCountChart"></div>
</div> -->
<!-- <div class="card">
<div class="sale_data_header">
<div class="card_title">销售金额</div>
</div>
<div class="number">{{ productSum }}</div>
<div class="product_chart_wrap" ref="productSumChart"></div>
</div> -->
</div>
<div class="table w-full">
<el-table v-loading="saleTableLoading" :data="saleTable" style="width: 100%">
<!-- <el-table-column label="排名" prop="productId"></el-table-column> -->
<el-table-column label="商品名称" prop="productName" />
<el-table-column label="数量" prop="saleCount" />
<el-table-column label="金额" prop="saleAmount" />
</el-table>
<!-- <div class="head-container" style="padding-top: 20px; display: flex; justify-content: flex-end">
<el-pagination :total="saleTableTotal" :page-size="saleTableSize" :current-page="saleTablePage"
layout="total, prev, pager, next, jumper" @current-change="paginationChange" />
</div> -->
</div>
</div>
</div>
<div class="chart_wrap">
<!-- 毛利率/净利率 -->
<div class="item">
<div class="header">
<div class="rate_title">
<div class="column">
<span class="t1">毛利率</span>
<span class="t2">今天 {{ initInterestRateTime }} 更新</span>
</div>
<!-- <span class="t1">毛利率/净利率</span> -->
<el-radio-group v-model="interestRateDay" @change="profitRateBarChart">
<el-radio-button value="7">近7天</el-radio-button>
<el-radio-button value="30">30</el-radio-button>
</el-radio-group>
</div>
</div>
<div ref="initInterestRate" v-loading="initInterestRateLoading" class="chart" style="height: 350px" />
</div>
<!-- 成本 -->
<div class="item">
<div class="header">
<div class="rate_title">
<div class="column">
<span class="t1">成本</span>
<span class="t2">今天 {{ costUpdateTime }} 更新</span>
</div>
<el-radio-group v-model="costDay" @change="costLineChart">
<el-radio-button value="7">近7天</el-radio-button>
<el-radio-button value="30">30</el-radio-button>
</el-radio-group>
</div>
</div>
<div ref="costRef" v-loading="costLoading" class="chart" style="height: 350px" />
</div>
</div>
<!-- <div class="chart_wrap" style="display: flex;">
<div class="item" style="margin-left: 20px;">
<div class="header">
<div class="tab_wrap">
<div class="item active">支付占比类型</div>
</div>
<el-radio-group v-model="payChartDay" @change="datePayType">
<el-radio-button label="7">近7天</el-radio-button>
<el-radio-button label="30">30</el-radio-button>
</el-radio-group>
</div>
<div style="height: 400px;margin-top: 30px;" ref="payChart" v-loading="payChartLoading"></div>
</div>
</div> -->
</div>
</template>
<script>
import dataSummaryApi from "@/api/order/data-summary";
import ShopApi from "@/api/account/shop";
import dayjs from "dayjs";
import * as echarts from "echarts";
import { debounce, formatDecimal } from "@/utils/tools";
import { formatDateRange } from './utils/index.js'
import { multiplyAndFormat } from '@/utils/index.js'
export default {
name: "home",
data() {
return {
multiplyAndFormat,
dataListActive: 0,
dateList: [
{
label: "今天",
value: "today",
},
{
label: "昨天",
value: "yesterday",
},
{
label: "最近7天",
value: "last_7_days",
},
{
label: "最近30天",
value: "last_30_days",
},
{
label: "本周",
value: "this_week",
},
{
label: "本月",
value: "this_month",
},
{
label: "自定义",
value: "custom",
},
],
payCount: [
{
icon: "https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/wx.png",
isAmount: "1",
payAmount: 0,
payType: "微信小程序",
saveAmount: null,
},
{
icon: "https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/ali.png",
isAmount: "1",
payAmount: 0,
payType: "支付宝小程序",
saveAmount: null,
},
{
icon: "https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/scan.png",
isAmount: "1",
payAmount: 0,
payType: "主扫收款",
saveAmount: null,
},
{
icon: "https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/bscan.png",
isAmount: "1",
payAmount: 0,
payType: "收款码收款",
saveAmount: null,
},
{
icon: "https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/cash.png",
isAmount: "1",
payAmount: 0,
payType: "现金",
saveAmount: null,
},
{
icon: "https://cashier-oss.oss-cn-beijing.aliyuncs.com/static/vipIn.png",
isAmount: "1",
payAmount: 0,
payType: "充值",
saveAmount: null,
},
],
branchList: [],
shopId: null,
trade: {},
formatDecimal,
topData: "",
saleTab: "sale",
saleActive: "7",
cardPayChart: null,
cardCountChart: null,
cardUserChart: null,
saleLoading: false,
saleChart: null,
payChartDay: "7",
payChartLoading: false,
payChart: null,
chartType: 1,
productCount: 0,
productSum: 0,
saleTableActive: "7",
saleTable: [],
saleTableLoading: false,
saleTablePage: 1,
saleTableTotal: 0,
saleTableSize: 5,
__resizeHandler: null,
productCountChart: null,
productSumChart: null,
lineChartType: 0,
timeValue: "today",
query: {
createdAt: [dayjs().format("YYYY-MM-DD"), dayjs().format("YYYY-MM-DD")],
},
tradeLoading: false,
tradeSale: {
payCount: [],
},
tradeVip: "",
tradeCount: "",
isHeadShop: JSON.parse(localStorage.getItem("userInfo")).isHeadShop,
loginType: localStorage.getItem("loginType"),
shopInfo: JSON.parse(localStorage.getItem("userInfo")),
initInterestRateLoading: true,
initInterestRate: null,
initInterestRateTime: '',
costLoading: true,
costRef: null,
costUpdateTime: '',
interestRateDay: '7',
costDay: '7'
};
},
computed: {
yingyeShiShou() {
if (!this.trade) {
return 0;
}
return (
this.trade.wechatPayAmount * 1 +
this.trade.aliPayAmount * 1 +
this.trade.aliPayAmount * 1 +
this.trade.memberPayAmount * 1 +
this.trade.scanPayAmount * 1 +
this.trade.cashPayAmount * 1 +
this.trade.rechargeAmount * 1
);
},
},
mounted() {
let shopInfo = JSON.parse(localStorage.getItem('userInfo'))
if (shopInfo.isHeadShop) {
this.shopId = shopInfo.id
} else {
this.shopId = localStorage.getItem('shopId')
}
// 增加首页提示是否账号30天过期
let date = dayjs(localStorage.getItem("expireDate")).diff(dayjs().format("YYYY-MM-DD"), "day");
if (date <= 30 && date >= 0) {
this.$alert(
`店铺账号有限期至${localStorage.getItem("expireDate")},店铺账号到期剩余${date}天!`,
"提示"
);
}
// this.summaryGet();
this.dateAmount();
this.dateProduct();
// this.summaryDateGet();
this.timeChange(this.timeValue);
this.profitRateBarChart()
this.costLineChart()
this.__resizeHandler = debounce(() => {
if (this.saleChart) {
this.saleChart.resize();
}
if (this.payChart) {
this.payChart.resize();
}
if (this.cardPayChart) {
this.cardPayChart.resize();
}
if (this.cardUserChart) {
this.cardUserChart.resize();
}
if (this.productCountChart) {
this.productCountChart.resize();
}
if (this.initInterestRate) {
this.initInterestRate.resize();
}
if (this.costRef) {
this.costRef.resize();
}
// if (this.productSumChart) {
// this.productSumChart.resize();
// }
}, 100);
window.addEventListener("resize", this.__resizeHandler);
this.geiShopList()
// this.initCardUserChart();
},
methods: {
/**
* 获取分店列表
*/
async geiShopList() {
try {
let shopInfo = JSON.parse(localStorage.getItem('userInfo'))
if (shopInfo.isHeadShop) {
let res = await ShopApi.getBranchList()
this.branchList = res;
this.shopId = res[0].shopId
}
} catch (error) {
console.log('获取分店列表===', error);
}
},
shopChange() {
this.summarytrade();
this.lineChartTypeChange(this.lineChartType)
this.dateProduct()
this.profitRateBarChart()
this.costLineChart()
},
// 切换时间
timeChange(e, index = 0) {
this.dataListActive = index;
this.timeValue = e;
this.query.createdAt = formatDateRange(e)
if (e != "custom") {
this.summarytrade();
}
},
// 获取营业板块数据
async summarytrade() {
try {
this.tradeLoading = true;
// if( this.query.createdAt[1] ){
// this.query.createdAt.splice(1,1,this.query.createdAt[1].replace("00:00:00","23:59:59"))
// }
const res = await dataSummaryApi.trade({
beginDate: this.query.createdAt[0],
endDate: this.query.createdAt[1],
rangeType: this.timeValue,
shopId: this.shopId
});
this.trade = res;
this.tradeSale = res.sale;
this.tradeVip = res.vip;
this.tradeCount = res.count;
} catch (error) {
console.log(error);
}
setTimeout(() => {
this.tradeLoading = false;
}, 500);
},
lineChartTypeChange(i) {
this.lineChartType = i;
if (i == 0) {
this.dateAmount();
} else {
this.datePayType();
}
},
// 初始化支付笔数柱状图
initCardPayChart(time = [], data = []) {
this.cardPayChart = echarts.init(this.$refs.cardPayChart);
this.cardPayChart.setOption({
tooltip: {
trigger: "axis",
},
grid: {
x: 0,
y: 0,
x2: 0,
y2: 0,
},
xAxis: [
{
type: "category",
data: time,
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
axisTick: {
show: false, // 不显示坐标轴刻度线
},
axisLine: {
show: false, // 不显示坐标轴线
},
axisLabel: {
show: false, // 不显示坐标轴上的文字
},
splitLine: {
show: false, // 不显示网格线
},
},
],
color: "#409eff",
yAxis: [
{
type: "value",
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
axisTick: {
show: false, // 不显示坐标轴刻度线
},
axisLine: {
show: false, // 不显示坐标轴线
},
axisLabel: {
show: false, // 不显示坐标轴上的文字
},
splitLine: {
show: false, // 不显示网格线
},
},
],
series: [
{
data: data,
type: "bar",
barWidth: "30%",
},
],
});
},
// 初始化访问量柱状图
initCardCountChart(time = [], data = []) {
this.cardCountChart = echarts.init(this.$refs.cardCountChart);
this.cardCountChart.setOption({
tooltip: {
trigger: "axis",
},
grid: {
x: 0,
y: 0,
x2: 0,
y2: 0,
},
xAxis: [
{
type: "category",
data: time,
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
axisTick: {
show: false, // 不显示坐标轴刻度线
},
axisLine: {
show: false, // 不显示坐标轴线
},
axisLabel: {
show: false, // 不显示坐标轴上的文字
},
splitLine: {
show: false, // 不显示网格线
},
},
],
color: "#409eff",
yAxis: [
{
type: "value",
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
axisTick: {
show: false, // 不显示坐标轴刻度线
},
axisLine: {
show: false, // 不显示坐标轴线
},
axisLabel: {
show: false, // 不显示坐标轴上的文字
},
splitLine: {
show: false, // 不显示网格线
},
},
],
series: [
{
data: data,
type: "bar",
barWidth: "30%",
},
],
});
},
// 初始化用户数折线图
initCardUserChart(time = [], data = []) {
this.cardUserChart = echarts.init(this.$refs.cardUserChart);
this.cardUserChart.setOption({
tooltip: {
trigger: "axis",
},
grid: {
x: 0,
y: 10,
x2: 0,
y2: 2,
},
xAxis: [
{
type: "category",
data: time,
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
axisTick: {
show: false, // 不显示坐标轴刻度线
},
axisLine: {
show: false, // 不显示坐标轴线
},
axisLabel: {
show: false, // 不显示坐标轴上的文字
},
splitLine: {
show: false, // 不显示网格线
},
},
],
color: "#409eff",
yAxis: [
{
type: "value",
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
axisTick: {
show: false, // 不显示坐标轴刻度线
},
axisLine: {
show: false, // 不显示坐标轴线
},
axisLabel: {
show: false, // 不显示坐标轴上的文字
},
splitLine: {
show: false, // 不显示网格线
},
},
],
series: [
{
data: data,
type: "line",
symbol: "none",
},
],
});
},
// 初始化成本折线图
initCostChart(time = [], data = []) {
// 销毁旧实例,避免重复创建
if (this.costRef) {
this.costRef.dispose();
}
this.costRef = echarts.init(this.$refs.costRef);
this.costRef.setOption({
tooltip: {
trigger: "item",
// 核心1显示「时间 + 数量」时间取X轴分类数量取当前数值
formatter: (params) => {
// params.name 是X轴时间params.value 是对应数值保留2位小数可按需调整
return `${params.name}<br/>${params.value.toFixed(2)}`;
},
// 优化提示框样式(可选)
padding: 10,
textStyle: { fontSize: 11 },
backgroundColor: "#fff",
borderColor: "#eee",
borderWidth: 1,
boxShadow: "0 2px 8px rgba(0,0,0,0.08)"
},
xAxis: [
{
type: "category",
data: time,
axisTick: { alignWithLabel: true },
axisLine: { lineStyle: { color: "#999" } },
axisLabel: {
rotate: time.length <= 7 ? 0 : 45,
interval: 0,
fontSize: "9",
},
},
],
grid: {
top: '5%',
right: '5%',
bottom: '8%',
left: '8%',
containLabel: true // 确保标签不溢出,不影响点的显示
},
color: "#165DFF", // 折线和默认点的颜色
yAxis: [
{
type: "value",
axisLine: { lineStyle: { color: "#999" } },
splitLine: { lineStyle: { type: "dashed", color: "#ececec" } },
},
],
series: [
{
data: data,
type: "line",
symbol: "circle", // 核心2X轴每个数据点显示圆形标记默认是none不显示
symbolSize: 6, // 固定点的大小(默认尺寸,可调整)
lineStyle: { width: 2 }, // 折线宽度(优化视觉)
// 核心3鼠标悬浮时点变大 + 黑色边框
emphasis: {
symbol: "circle", // 悬浮时仍为圆形
symbolSize: 10, // 悬浮时点的大小(比默认大)
itemStyle: {
borderColor: "#000", // 黑色边框
borderWidth: 2, // 边框宽度
// 悬浮时填充色不变(仍为 #165DFF
color: "#165DFF"
}
},
// 确保所有数据点都显示(避免自动隐藏)
showAllSymbol: true,
// 点的基础样式(默认状态)
itemStyle: {
color: "#165DFF", // 点的填充色(与折线一致)
borderWidth: 1, // 基础状态可加细边框(可选,不加则无)
borderColor: "#fff" // 基础状态边框颜色(与背景区分,可选)
}
},
],
});
},
// 初始化销售额图标
initSaleChart(time, data) {
this.saleChart = null;
this.saleChart = echarts.init(this.$refs.saleChart);
this.saleChart.setOption({
title: {
text: "销售趋势",
x: "center",
},
tooltip: {
trigger: "item",
formatter: (params) => {
return `${params.value}`;
},
},
xAxis: [
{
type: "category",
data: time,
axisTick: {
alignWithLabel: true,
},
axisLine: {
lineStyle: {
color: "#999",
},
},
axisLabel: {
rotate: time.length <= 7 ? 0 : 45,
interval: 0,
fontSize: "9",
},
},
],
color: ["#409eff", "#FFC83A", "#F98B26"],
yAxis: [
{
type: "value",
axisLine: {
lineStyle: {
color: "#999",
},
},
splitLine: {
lineStyle: {
type: "dashed",
color: "#ececec",
},
},
},
],
series: [
{
name: "订单金额",
type: "bar",
barWidth: time.length <= 7 ? "50%" : "30%",
data: data.map((item) => item.orderAmount),
},
// {
// name: '实收金额',
// type: "bar",
// barWidth: time.length <= 7 ? "30%" : "20%",
// data: data.map(item => item.actualAmount),
// },
// {
// name: '优惠金额',
// type: "bar",
// barWidth: time.length <= 7 ? "30%" : "20%",
// data: data.map(item => item.discountAmount),
// }
],
});
},
initInterestRateChart(time, data) {
// 销毁旧实例,避免重复创建
if (this.initInterestRate) {
this.initInterestRate.dispose();
}
this.initInterestRate = echarts.init(this.$refs.initInterestRate);
// 预处理数据:将毛利率和净利率按索引对应(关键,用于手动匹配)
const profitRateData = data.map(item => item.profitRate || 0);
const netProfitRateData = data.map(item => item.netProfitRate || 0);
this.initInterestRate.setOption({
tooltip: {
trigger: "item", // 保留 item 模式(确保能触发,之前已验证有效)
// 核心:手动查找当前 X 轴索引对应的另一个系列数据,拼接显示
formatter: (params) => {
const index = params.dataIndex; // 获取当前数据的索引X轴位置
const xName = time[index]; // 当前 X 轴分类名称(如时间)
const color1 = "#165DFF"; // 毛利率颜色(与 series 一致)
const color2 = "#14C9C9"; // 净利率颜色(与 series 一致)
// 当前系列数据 + 另一个系列数据(按索引匹配)
const profitRate = profitRateData[index].toFixed(2);
const netProfitRate = netProfitRateData[index].toFixed(2);
// 拼接提示框内容(彩色方块 + 两个指标)
return `
<div style="margin-bottom:4px;">${xName}</div>
<div><span style="display:inline-block;width:8px;height:8px;background:${color1};margin-right:6px;border-radius:2px;"></span>毛利率:${profitRate}%</div>
`;
},
// 保留你原有的提示框样式
padding: 10,
textStyle: { fontSize: 11 },
backgroundColor: "#fff",
borderColor: "#eee",
borderWidth: 1,
boxShadow: "0 2px 8px rgba(0,0,0,0.08)"
},
xAxis: [
{
type: "category",
data: time,
axisTick: { alignWithLabel: true },
axisLine: { lineStyle: { color: "#999" } },
axisLabel: {
rotate: time.length <= 7 ? 0 : 45,
interval: 0,
fontSize: "9",
},
},
],
color: ["#165DFF", "#14C9C9", "#F98B26"], // 系列颜色不变
yAxis: [
{
type: "value",
axisLine: { lineStyle: { color: "#999" } },
splitLine: { lineStyle: { type: "dashed", color: "#ececec" } },
axisLabel: { formatter: "{value}%" }, // Y轴加百分号
},
],
grid: {
top: '5%',
right: '5%',
bottom: '8%',
left: '8%',
},
series: [
{
name: "毛利率",
type: "bar",
barGap: "0%", // 保持柱子紧贴
barWidth: time.length <= 7 ? "50%" : "30%",
data: profitRateData, // 预处理后的毛利率数据
}
],
});
},
// 初始化毛利率/净利率图表
// initInterestRateChart(time, data) {
// // 销毁旧实例,避免重复创建
// if (this.initInterestRate) {
// this.initInterestRate.dispose();
// }
// this.initInterestRate = echarts.init(this.$refs.initInterestRate);
// // 预处理数据:将毛利率和净利率按索引对应(关键,用于手动匹配)
// const profitRateData = data.map(item => item.profitRate || 0);
// const netProfitRateData = data.map(item => item.netProfitRate || 0);
// this.initInterestRate.setOption({
// tooltip: {
// trigger: "item", // 保留 item 模式(确保能触发,之前已验证有效)
// // 核心:手动查找当前 X 轴索引对应的另一个系列数据,拼接显示
// formatter: (params) => {
// const index = params.dataIndex; // 获取当前数据的索引X轴位置
// const xName = time[index]; // 当前 X 轴分类名称(如时间)
// const color1 = "#165DFF"; // 毛利率颜色(与 series 一致)
// const color2 = "#14C9C9"; // 净利率颜色(与 series 一致)
// // 当前系列数据 + 另一个系列数据(按索引匹配)
// const profitRate = profitRateData[index].toFixed(2);
// const netProfitRate = netProfitRateData[index].toFixed(2);
// // 拼接提示框内容(彩色方块 + 两个指标)
// return `
// <div style="margin-bottom:4px;">${xName}</div>
// <div><span style="display:inline-block;width:8px;height:8px;background:${color1};margin-right:6px;border-radius:2px;"></span>毛利率:${profitRate}%</div>
// <div><span style="display:inline-block;width:8px;height:8px;background:${color2};margin-right:6px;border-radius:2px;"></span>净利率:${netProfitRate}%</div>
// `;
// },
// // 保留你原有的提示框样式
// padding: 10,
// textStyle: { fontSize: 11 },
// backgroundColor: "#fff",
// borderColor: "#eee",
// borderWidth: 1,
// boxShadow: "0 2px 8px rgba(0,0,0,0.08)"
// },
// xAxis: [
// {
// type: "category",
// data: time,
// axisTick: { alignWithLabel: true },
// axisLine: { lineStyle: { color: "#999" } },
// axisLabel: {
// rotate: time.length <= 7 ? 0 : 45,
// interval: 0,
// fontSize: "9",
// },
// },
// ],
// color: ["#165DFF", "#14C9C9", "#F98B26"], // 系列颜色不变
// yAxis: [
// {
// type: "value",
// axisLine: { lineStyle: { color: "#999" } },
// splitLine: { lineStyle: { type: "dashed", color: "#ececec" } },
// axisLabel: { formatter: "{value}%" }, // Y轴加百分号
// },
// ],
// grid: {
// top: '5%',
// right: '5%',
// bottom: '8%',
// left: '8%',
// },
// series: [
// {
// name: "毛利率",
// type: "bar",
// barGap: "0%", // 保持柱子紧贴
// barWidth: time.length <= 7 ? "50%" : "30%",
// data: profitRateData, // 预处理后的毛利率数据
// },
// {
// name: '净利率',
// type: "bar",
// barGap: "0%",
// barWidth: time.length <= 7 ? "50%" : "30%",
// data: netProfitRateData, // 预处理后的净利率数据
// },
// ],
// });
// },
// 初始化销售额图表
initPayChart(data) {
this.payChart = echarts.init(this.$refs.payChart);
this.payChart.setOption({
tooltip: {
trigger: "item",
formatter: (params) => {
return `${params.name}${params.value}`;
},
},
legend: {
top: "5%",
left: "center",
},
color: [
"#409eff",
"#91cc75",
"#fac858",
"#ee6666",
"#73c0de",
"#3ba272",
"#fc8452",
"#9a60b4",
"#ea7ccc",
],
series: [
{
type: "pie",
radius: ["40%", "70%"],
avoidLabelOverlap: false,
label: {
show: false,
position: "center",
},
emphasis: {
label: {
show: true,
fontSize: 20,
},
},
labelLine: {
show: false,
},
data: data,
},
],
});
},
// 获取销售额柱状图数据
async dateAmount() {
try {
this.saleLoading = true;
const res = await dataSummaryApi.dateAmount({ day: this.saleActive, shopId: this.shopId });
const data = res.map((item) => {
return {
orderAmount: item.orderAmount,
// actualAmount: item.actualAmount,
// discountAmount: item.discountAmount
};
});
const time = res.map((item) => item.tradeDay);
this.initSaleChart(time, data);
} catch (error) {
console.log(error);
}
setTimeout(() => {
this.saleLoading = false;
}, 300);
},
// 获取毛利率/净利率柱状图数据
async profitRateBarChart() {
try {
this.initInterestRateLoading = true;
const res = await dataSummaryApi.profitRateBarChart({ day: this.interestRateDay, shopId: this.shopId });
this.initInterestRateTime = dayjs().format('HH:mm')
const data = res.map((item) => {
return {
profitRate: item.profitRate || 0,
netProfitRate: item.netProfitRate || 0,
// discountAmount: item.discountAmount
};
});
const time = res.map((item) => item.tradeDay);
this.initInterestRateChart(time, data);
} catch (error) {
console.log(error);
}
setTimeout(() => {
this.initInterestRateLoading = false;
}, 300);
},
// 获取成本折线图数据
async costLineChart() {
try {
this.costLoading = true;
const res = await dataSummaryApi.costLineChart({ day: this.costDay, shopId: this.shopId });
this.costUpdateTime = dayjs().format('HH:mm')
const data = res.map((item) => item.productCostAmount || 0);
const time = res.map((item) => item.tradeDay);
this.initCostChart(time, data);
} catch (error) {
console.log(error);
}
setTimeout(() => {
this.costLoading = false;
}, 300);
},
paginationChange(e) {
this.saleTablePage = e;
this.dateProduct();
},
// 获取销售额排行表格数据
async dateProduct() {
try {
this.saleTableLoading = true;
const res = await dataSummaryApi.productSaleDate({
day: this.saleTableActive,
shopId: this.shopId,
});
this.saleTable = res;
this.saleTableTotal = res.length;
// this.summaryDateGet(res.countList);
setTimeout(() => {
this.saleTableLoading = false;
}, 300);
} catch (error) {
console.log(error);
}
},
// 支付类型占比 饼图
async datePayType() {
try {
this.payChartLoading = true;
const res = await dataSummaryApi.datePayType({ day: this.saleActive, shopId: this.shopId });
const data = res.map((item) => {
return {
value: item.count,
name: item.payType,
};
});
setTimeout(() => {
this.payChartLoading = false;
}, 300);
this.initPayChart(data);
} catch (error) {
console.log(error);
}
},
// 汇总数据
async summaryGet() {
try {
const res1 = await summaryGet();
const res2 = await summaryTodayGet();
this.topData = {
...res1,
...res2,
};
let payTime = res1.countDateList.map((item) => item.tradeDay);
let payData = res1.countDateList.map((item) => item.count);
let countTime = res1.visitsCountList.map((item) => item.tradeDay);
let countData = res1.visitsCountList.map((item) => item.count);
this.initCardPayChart(payTime, payData);
this.initCardCountChart(countTime, countData);
console.log(this.topData);
} catch (error) {
console.log(error);
}
},
rankChange() {
this.dateProduct();
// this.summaryDateGet();
},
// 初始化销售图标
initProduceChart(p1, p2) {
this.productCountChart = echarts.init(this.$refs.productCountChart);
// this.productSumChart = echarts.init(this.$refs.productSumChart);
this.productCountChart.setOption({
tooltip: {
trigger: "axis",
},
grid: {
x: 0,
y: 0,
x2: 0,
y2: 0,
},
xAxis: [
{
boundaryGap: false,
type: "category",
data: p1[0],
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
axisTick: {
show: false, // 不显示坐标轴刻度线
},
axisLine: {
show: false, // 不显示坐标轴线
},
axisLabel: {
show: false, // 不显示坐标轴上的文字
},
splitLine: {
show: false, // 不显示网格线
},
},
],
color: "#409eff",
yAxis: [
{
type: "value",
show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
axisTick: {
show: false, // 不显示坐标轴刻度线
},
axisLine: {
show: false, // 不显示坐标轴线
},
axisLabel: {
show: false, // 不显示坐标轴上的文字
},
splitLine: {
show: false, // 不显示网格线
},
},
],
series: [
{
data: p1[1],
type: "line",
symbol: "none",
smooth: true,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#409eff", // 渐变颜色
},
{
offset: 1,
color: "#409eff", // 渐变颜色
},
]),
},
},
],
});
// this.productSumChart.setOption({
// tooltip: {
// trigger: "axis"
// },
// grid: {
// x: 0,
// y: 0,
// x2: 0,
// y2: 0
// },
// xAxis: [
// {
// boundaryGap: false,
// type: "category",
// data: p2[0],
// show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
// axisTick: {
// show: false // 不显示坐标轴刻度线
// },
// axisLine: {
// show: false // 不显示坐标轴线
// },
// axisLabel: {
// show: false // 不显示坐标轴上的文字
// },
// splitLine: {
// show: false // 不显示网格线
// }
// }
// ],
// color: "#409eff",
// yAxis: [
// {
// type: "value",
// show: false, // 不显示坐标轴线、坐标轴刻度线和坐标轴上的文字
// axisTick: {
// show: false // 不显示坐标轴刻度线
// },
// axisLine: {
// show: false // 不显示坐标轴线
// },
// axisLabel: {
// show: false // 不显示坐标轴上的文字
// },
// splitLine: {
// show: false // 不显示网格线
// }
// }
// ],
// series: [
// {
// data: p2[1],
// type: "line",
// symbol: "none",
// smooth: true,
// areaStyle: {
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// {
// offset: 0,
// color: "#409eff" // 渐变颜色
// },
// {
// offset: 1,
// color: "#409eff" // 渐变颜色
// }
// ])
// }
// }
// ]
// });
},
// 日期汇总数据
async summaryDateGet(res) {
try {
console.log(res);
// this.initProduceChart(p1, p2);
} catch (error) {
console.log(error);
}
},
},
};
</script>
<style>
.popper {
border: 1px solid #d9d9d9 !important;
}
</style>
<style scoped lang="scss">
.tips_row {
width: 300px;
padding: 0 10px;
.item {
height: 40px;
display: flex;
align-items: center;
color: #666;
justify-content: space-between;
&:not(:last-child) {
border-bottom: 1px solid #d9d9d9;
}
.left {
display: flex;
align-items: center;
.icon {
font-size: 20px;
margin-right: 10px;
}
}
.num {
color: #1890ff;
}
}
}
.app-container {
padding: 20px;
background-color: #f5f5f5;
}
.h_card_wrap {
.status_wrap {
display: flex;
align-items: center;
justify-content: space-between;
.left {
display: flex;
align-items: center;
.dot {
$size: 6px;
width: $size;
height: $size;
border-radius: 50%;
background-color: #1890ff;
margin-right: 10px;
}
}
.time {
display: flex;
align-items: center;
}
}
.content {
background-color: #fff;
margin-top: 15px;
padding: 20px;
.top {
display: flex;
.item {
flex: 1;
&.earnings {
display: flex;
}
&.data {
margin-left: 40px;
background: url("../../assets/images/data_home_bg1.png") no-repeat center center / cover;
display: flex;
align-items: center;
}
.data_item {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.data_item_right {
flex: 1;
display: flex;
flex-direction: column;
.t {
width: 200px;
color: #333;
display: flex;
&:not(:first-child) {
margin-top: 20px;
}
}
.n {
color: #1890ff;
margin-left: 20px;
}
}
.num_wrap {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.num {
font-size: 30px;
color: #1890ff;
}
.tips {
font-size: 12px;
margin-top: 10px;
}
}
.line_wrap {
flex: 1;
padding-left: 20px;
.line_item {
&:not(:first-child) {
margin-top: 20px;
}
.line_item_top {
display: flex;
justify-content: space-between;
font-size: 12px;
.t {
color: #999;
}
}
.line_gropress {
display: flex;
margin-top: 6px;
background-color: #f6f6f6;
.gropress {
height: 5px;
&.l {
background-color: #1890ff;
}
&.r {
background-color: #ff3f3f;
}
}
}
.line_btm {
display: flex;
justify-content: space-between;
margin-top: 5px;
.icon {
color: #a2a2a2;
position: relative;
left: -5px;
font-size: 12px;
}
.info {
font-size: 12px;
.l_t {
color: #1890ff;
}
.l_r {
color: #ff3f3f;
margin-left: 10px;
}
}
}
}
}
}
}
.btm {
display: flex;
justify-content: space-between;
margin-top: 20px;
.item {
width: 200px;
height: 83px;
background-repeat: no-repeat;
background-position: center center;
background-size: 100% 100%;
display: flex;
flex-direction: column;
justify-content: center;
padding-left: 18px;
&.item1 {
background-image: url("../../assets/images/data_home_item1.png");
}
&.item2 {
background-image: url("../../assets/images/data_home_item2.png");
}
&.item3 {
background-image: url("../../assets/images/data_home_item3.png");
}
&.item4 {
background-image: url("../../assets/images/data_home_item4.png");
}
&.item5 {
background-image: url("../../assets/images/data_home_item5.png");
}
&.item6 {
background-image: url("../../assets/images/data_home_item6.png");
}
.row_wrap {
display: flex;
width: 100%;
height: 100%;
.row {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
.t {
margin-left: 0;
}
}
}
.title {
display: flex;
align-items: center;
color: #333;
font-size: 14px;
gap: 8px;
.icon {
font-size: 12px;
color: #999;
margin-left: 6px;
}
}
.icon_wrap {
display: flex;
align-items: center;
margin-top: 10px;
.img {
width: 36px;
height: 36px;
}
.t {
font-size: 24px;
margin-left: 10px;
font-weight: bold;
}
}
}
}
}
}
.card_wrap {
display: flex;
flex-wrap: wrap;
gap: 20px;
.card {
flex: 1;
background-color: #fff;
border-radius: 2px;
padding: 0 20px;
.header {
display: flex;
justify-content: space-between;
color: #999;
padding-top: 20px;
.card_title {
font-size: 14px;
flex: 1;
}
}
.number {
padding: 20px 0 10px 0;
font-size: 24px;
height: 60px;
}
.row {
height: 50px;
color: #555;
font-size: 14px;
display: flex;
align-items: center;
&:not(:last-child) {
border-bottom: 1px solid #ececec;
}
.icon {
color: rgb(255, 85, 85);
margin-left: 4px;
}
.dot {
$size: 6px;
width: $size;
height: $size;
border-radius: 50%;
background-color: #1890ff;
margin-right: 6px;
}
}
}
}
.chart_wrap {
margin-top: 20px;
display: flex;
gap: 20px;
.sale_data {
display: flex;
.card {
flex: 1;
background-color: #fff;
border-radius: 2px;
padding: 0 20px;
.sale_data_header {
display: flex;
justify-content: space-between;
color: #999;
padding-top: 20px;
.card_title {
font-size: 14px;
flex: 1;
}
}
.number {
padding-top: 10px;
font-size: 24px;
height: 60px;
}
.product_chart_wrap {
height: 50px;
}
}
}
.item {
flex: 1;
background-color: #fff;
border-radius: 2px;
.header {
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #ececec;
padding: 0 20px;
.rate_title {
flex: 1;
padding: 20px 0;
display: flex;
align-items: center;
justify-content: space-between;
.column {
display: flex;
flex-direction: column;
}
.t1 {
font-size: 16px;
color: #111;
}
.t2 {
font-size: 12px;
color: #999;
}
}
.tab_wrap {
display: flex;
$color: #1890ff;
.item {
padding: 0 10px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
margin-right: 20px;
&.active {
position: relative;
color: $color;
&::after {
content: "";
width: 100%;
border-bottom: 2px solid $color;
position: absolute;
bottom: 0;
left: 0;
}
}
}
}
}
.chart {
padding: 20px 0;
height: 300px;
}
.table {
padding: 20px;
}
}
}
.right_data_wrap {
width: 100%;
height: 100%;
display: flex;
align-items: center;
.item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
.num {
font-size: 32px;
color: var(--el-color-primary);
font-weight: bold;
}
.tips {
font-size: 14px;
color: #666666;
}
}
}
.date_list {
display: flex;
margin-right: 10px;
.item {
font-size: 14px;
color: #999999;
display: flex;
align-items: center;
&.active {
.date-tab-item {
color: var(--el-color-primary);
}
}
.date-tab-item {
cursor: pointer;
&:hover {
color: var(--el-color-primary-light-3);
}
}
.separator {
margin: 0 6px;
position: relative;
top: -1px;
}
}
}
</style>