优化添加商品问题 新增添加设备

This commit is contained in:
gyq
2024-03-13 09:05:08 +08:00
parent d0f69f9eb9
commit 87d084dfed
24 changed files with 1251 additions and 281 deletions

448
src/views/home/home.vue Normal file
View File

@@ -0,0 +1,448 @@
<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"></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.totalUser }}</div>
<div class="row"></div>
<div class="row">今日新增 {{ topData.userToday || 0 }} <i class="icon el-icon-caret-top"></i> </div>
</div>
</div>
<!-- 销售额 -->
<div class="chart_wrap">
<div class="item">
<div class="header">
<div class="tab_wrap">
<div class="item active">销售额</div>
</div>
<el-radio-group v-model="saleActive" @change="dateAmount">
<el-radio-button label="7">近7天</el-radio-button>
<el-radio-button label="30">30</el-radio-button>
</el-radio-group>
</div>
<div class="chart" ref="saleChart" v-loading="saleLoading" style="height: 400px;">
</div>
</div>
</div>
<div class="chart_wrap" style="display: flex;">
<!-- 商品销售排行 -->
<div class="item">
<div class="header">
<div class="tab_wrap">
<div class="item active">商品销售排行</div>
</div>
<el-radio-group v-model="saleTableActive" @change="dateProduct">
<el-radio-button label="7">近7天</el-radio-button>
<el-radio-button label="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>
<div class="card">
<div class="sale_data_header">
<div class="card_title">销售金额</div>
</div>
<div class="number">{{ productSum }}</div>
</div>
</div>
<div class="table">
<el-table :data="saleTable" v-loading="saleTableLoading">
<el-table-column label="排名" prop="productId"></el-table-column>
<el-table-column label="商品名称" prop="productName"></el-table-column>
<el-table-column label="数量" prop="productNum"></el-table-column>
<el-table-column label="金额" prop="amount"></el-table-column>
</el-table>
<div class="head-container" style="padding-top: 20px;display: flex;justify-content: flex-end;">
<el-pagination :total="saleTableTotal" :current-page="saleTablePage" @current-change="paginationChange"
layout="total, prev, pager, next, jumper"></el-pagination>
</div>
</div>
</div>
<!-- 支付类型占比 -->
<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 { summaryGet, summaryTodayGet, dateProduct, dateAmount, datePayType } from '@/api/home'
import echarts from 'echarts'
import { debounce } from '@/utils'
export default {
name: 'home',
data() {
return {
topData: '',
saleTab: 'sale',
saleActive: '7',
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,
__resizeHandler: null
}
},
mounted() {
this.summaryGet()
this.dateAmount()
this.dateProduct()
this.datePayType()
this.__resizeHandler = debounce(() => {
if (this.saleChart) {
this.saleChart.resize()
}
if (this.payChart) {
this.payChart.resize()
}
}, 100)
window.addEventListener('resize', this.__resizeHandler)
},
methods: {
// 初始化销售额图标
initSaleChart(time, data) {
this.saleChart = null
this.saleChart = echarts.init(this.$refs.saleChart)
this.saleChart.setOption({
title: {
text: '销售趋势',
x: 'center'
},
tooltip: {
trigger: 'axis'
},
xAxis: [{
type: 'category',
data: time,
axisTick: {
alignWithLabel: true
},
axisLine: {
lineStyle: {
color: '#999'
}
},
axisLabel: {
rotate: time.length <= 7 ? 0 : 45,
interval: 0,
textStyle: {
fontSize: '9'
}
}
}],
color: '#409eff',
yAxis: [
{
type: 'value',
axisLine: {
lineStyle: {
color: '#999'
}
},
splitLine: {
lineStyle: {
type: 'dashed',
color: '#ececec'
}
}
}
],
series: [
{
data: data,
type: 'bar',
barWidth: time.length <= 7 ? '50%' : '30%'
}
]
})
},
// 初始化销售额图表
initPayChart(data) {
this.payChart = echarts.init(this.$refs.payChart)
this.payChart.setOption({
tooltip: {
trigger: 'item'
},
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 dateAmount(this.saleActive)
const data = res.total.map(item => item.amount)
const time = res.total.map(item => item.tradeDay)
this.initSaleChart(time, data)
setTimeout(() => {
this.saleLoading = false
}, 300);
} catch (error) {
console.log(error)
}
},
paginationChange(e) {
this.saleTablePage = e
this.dateProduct()
},
// 获取销售额排行表格数据
async dateProduct() {
try {
this.saleTableLoading = true
const res = await dateProduct(this.saleTableActive, this.saleTablePage)
this.saleTable = res.totalProduct
this.saleTableTotal = res.productCount
this.productCount = res.productCount
this.productSum = res.productSum
setTimeout(() => {
this.saleTableLoading = false
}, 300);
} catch (error) {
console.log(error)
}
},
// 支付类型占比 饼图
async datePayType() {
try {
this.payChartLoading = true
const res = await datePayType(this.payChartDay)
const data = res.countPayType.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
}
} catch (error) {
console.log(error)
}
},
}
}
</script>
<style scoped lang="scss">
.app-container {
padding: 20px;
background-color: #F5F5F5;
}
.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: 40px;
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;
}
}
}
}
.chart_wrap {
margin-top: 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;
}
}
}
.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;
.tab_wrap {
display: flex;
$color: #1890FF;
.item {
padding: 0 10px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: $color;
&.active {
position: relative;
&::after {
content: "";
width: 100%;
border-bottom: 2px solid $color;
position: absolute;
bottom: 0;
left: 0;
}
}
}
}
}
.chart {
padding: 20px 0;
height: 300px;
}
.table {
padding: 20px;
}
}
}
</style>