首页数据看板接口对接

This commit is contained in:
zzyuan 2025-05-19 13:01:04 +08:00
parent 98b6b5e9ff
commit 84ced2e300
5 changed files with 930 additions and 9 deletions

81
src/api/index.js Normal file
View File

@ -0,0 +1,81 @@
import request from '@/utils/request'
// 获取数据总览(今日营业额、订单等)
export function getDataScreeningModelApi(data) {
return request({
url: '/smart-canteen/dataScreening/getDataScreeningModel',
method: 'post',
headers: {
"merchant-id":"378915229716713472",
},
data: data
})
}
// 获取食堂订单及销量趋势
export function getCanteenOrdersAndSalesTrendsApi(data) {
return request({
url: '/smart-canteen/dataScreening/getCanteenOrdersAndSalesTrends',
method: 'post',
headers: {
"merchant-id":"378915229716713472",
},
data: data
})
}
// 获取商超订单及销量趋势
export function getSupermarketOrderAndSalesTrendApi(data) {
return request({
url: '/smart-canteen/dataScreening/getSupermarketOrderAndSalesTrend',
method: 'post',
headers: {
"merchant-id":"378915229716713472",
},
data: data
})
}
// 获取近30天菜品销量排名
export function getThisMonthSDishSalesRankingApi(data) {
return request({
url: '/smart-canteen/dataScreening/getThisMonthSDishSalesRanking',
method: 'post',
headers: {
"merchant-id":"378915229716713472",
},
data: data
})
}
// 订单类型占比
export function getProportionOfOrderTypesApi(data) {
return request({
url: '/smart-canteen/dataScreening/getProportionOfOrderTypes',
method: 'post',
headers: {
"merchant-id":"378915229716713472",
},
data: data
})
}

BIN
src/assets/images/down.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

BIN
src/assets/images/up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

View File

@ -1,16 +1,179 @@
<template> <template>
<el-row :gutter="36" class="panel-group"> <el-row :gutter="36" class="panel-group">
<el-col :span="4" class="card-panel-col"> <el-col :span="4" class="card-panel-col" v-for="(item,index) in topData" :key="index">
<div class="card-panel"> <div class="card-panel">
<div class="card-panel-description"> <div class="card-panel-description">
<div class="card-panel-text"> <div class="card-panel-text">
今日食堂营业额 {{item.name}}
</div>
<count-to :start-val="0" :end-val="item.num" :duration="2000" class="card-panel-num" />
</div>
<div>
<div style="display: flex;justify-content: space-between;width: 70%;" v-if="Number(item.rate)>=0">
<div style="font-size: 12px;color: #07B78A;">
同比上次 +{{item.rate}}
</div>
<div>
<img src="@/assets/images/up.png" style="width: 18px;height: 18px;">
</div>
</div>
<div style="display: flex;justify-content: space-between;width: 70%;" v-if="Number(item.rate)<0">
<div style="font-size: 12px;color: #d81e06;">
同比上次 {{item.rate}}
</div>
<div>
<img src="@/assets/images/down.png" style="width: 18px;height: 18px;">
</div>
</div> </div>
<count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
</div> </div>
</div> </div>
</el-col> </el-col>
<!-- <el-col :span="4" class="card-panel-col">
<div class="card-panel">
<div class="card-panel-description">
<div class="card-panel-text">
今日食堂订单量
</div>
<count-to :start-val="0" :end-val="360" :duration="2000" class="card-panel-num" />
</div>
<div>
<div style="display: flex;justify-content: space-between;width: 70%;">
<div style="font-size: 12px;color: #07B78A;">
同比昨日 +1.6
</div>
<div>
<img src="@/assets/images/up.png" style="width: 18px;height: 18px;">
</div>
</div>
<div style="display: flex;justify-content: space-between;width: 70%;">
<div style="font-size: 12px;color: #d81e06;">
同比昨日 -05
</div>
<div>
<img src="@/assets/images/down.png" style="width: 18px;height: 18px;">
</div>
</div>
</div>
</div>
</el-col>
<el-col :span="4" class="card-panel-col">
<div class="card-panel">
<div class="card-panel-description">
<div class="card-panel-text">
今日就餐人数
</div>
<count-to :start-val="0" :end-val="211" :duration="2000" class="card-panel-num" />
</div>
<div>
<div style="display: flex;justify-content: space-between;width: 70%;">
<div style="font-size: 12px;color: #07B78A;">
同比昨日 +1.6
</div>
<div>
<img src="@/assets/images/up.png" style="width: 18px;height: 18px;">
</div>
</div>
<div style="display: flex;justify-content: space-between;width: 70%;">
<div style="font-size: 12px;color: #d81e06;">
同比昨日 -05
</div>
<div>
<img src="@/assets/images/down.png" style="width: 18px;height: 18px;">
</div>
</div>
</div>
</div>
</el-col>
<el-col :span="4" class="card-panel-col">
<div class="card-panel">
<div class="card-panel-description">
<div class="card-panel-text">
今日菜品数量
</div>
<count-to :start-val="0" :end-val="14" :duration="2000" class="card-panel-num" />
</div>
<div>
<div style="display: flex;justify-content: space-between;width: 70%;">
<div style="font-size: 12px;color: #07B78A;">
同比昨日 +1.6
</div>
<div>
<img src="@/assets/images/up.png" style="width: 18px;height: 18px;">
</div>
</div>
<div style="display: flex;justify-content: space-between;width: 70%;">
<div style="font-size: 12px;color: #d81e06;">
同比昨日 -05
</div>
<div>
<img src="@/assets/images/down.png" style="width: 18px;height: 18px;">
</div>
</div>
</div>
</div>
</el-col>
<el-col :span="4" class="card-panel-col">
<div class="card-panel">
<div class="card-panel-description">
<div class="card-panel-text">
今日商超营业额
</div>
<count-to :start-val="0" :end-val="5200" :duration="2000" class="card-panel-num" />
</div>
<div>
<div style="display: flex;justify-content: space-between;width: 70%;">
<div style="font-size: 12px;color: #07B78A;">
同比昨日 +1.6
</div>
<div>
<img src="@/assets/images/up.png" style="width: 18px;height: 18px;">
</div>
</div>
<div style="display: flex;justify-content: space-between;width: 70%;">
<div style="font-size: 12px;color: #d81e06;">
同比昨日 -05
</div>
<div>
<img src="@/assets/images/down.png" style="width: 18px;height: 18px;">
</div>
</div>
</div>
</div>
</el-col>
<el-col :span="4" class="card-panel-col">
<div class="card-panel">
<div class="card-panel-description">
<div class="card-panel-text">
今日商超订单
</div>
<count-to :start-val="0" :end-val="435" :duration="2000" class="card-panel-num" />
</div>
<div>
<div style="display: flex;justify-content: space-between;width: 70%;">
<div style="font-size: 12px;color: #07B78A;">
同比昨日 +1.6
</div>
<div>
<img src="@/assets/images/up.png" style="width: 18px;height: 18px;">
</div>
</div>
<div style="display: flex;justify-content: space-between;width: 70%;">
<div style="font-size: 12px;color: #d81e06;">
同比昨日 -05
</div>
<div>
<img src="@/assets/images/down.png" style="width: 18px;height: 18px;">
</div>
</div>
</div>
</div>
</el-col> -->
</el-row> </el-row>
</template> </template>
@ -22,6 +185,12 @@ export default {
components: { components: {
CountTo CountTo
}, },
props: {
topData: {
type: Array,
default: []
}
},
methods: { methods: {
} }
@ -42,7 +211,7 @@ export default {
.card-panel { .card-panel {
height: 140px; height: 140px;
cursor: pointer; // cursor: pointer;
font-size: 12px; font-size: 12px;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
@ -65,10 +234,12 @@ export default {
font-weight: bold; font-weight: bold;
margin: 0px; margin: 0px;
margin-left: 0px; margin-left: 0px;
margin-bottom: 10px;
.card-panel-text { .card-panel-text {
line-height: 18px; line-height: 18px;
color: rgba(0, 0, 0, 0.5); // color: rgba(0, 0, 0, 0.5);
font-weight: normal;
font-size: 16px; font-size: 16px;
margin-bottom: 15px; margin-bottom: 15px;
} }

View File

@ -1,12 +1,36 @@
<template> <template>
<div class="dashboard-editor-container"> <div class="dashboard-editor-container">
<h3 style="font-weight: 600;">数据总览</h3> <h3 style="font-weight: 600;">数据总览</h3>
<panel-group/> <panel-group :topData="topAreaOptions"/>
<el-row>
<el-col :span="16">
<div style="background: #fff;padding: 10px;margin: 5px;margin-bottom: 10px;">
<div>食堂订单及销量趋势</div>
<div id="lineChartOne" style="width: 100%;height: 300px;margin-bottom: 20px;"></div>
</div>
<div style="background: #fff;padding: 10px;margin: 5px;margin-bottom: 10px;">
<div>商超订单及销量趋势</div>
<div id="lineChartTwo" style="width: 100%;height: 300px;margin-bottom: 20px;"></div>
</div>
</el-col>
<el-col :span="8">
<div style="background: #fff;padding: 10px;margin: 5px;margin-bottom: 10px;">
<div>本月菜品销量排名</div>
<div id="lineChartThree" style="width: 100%;height: 380px;margin-bottom: 20px;"></div>
</div>
<div style="background: #fff;padding: 10px;margin: 5px;margin-bottom: 10px;">
<div>订单类型占比</div>
<div id="barChartFour" style="width: 100%;height: 220px;margin-bottom: 20px;"></div>
</div>
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
<line-chart :chart-data="lineChartData" />
</el-col>
</el-row> </el-row>
<!-- <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
<line-chart :chart-data="lineChartData" />
</el-row>
<el-row :gutter="32"> <el-row :gutter="32">
<el-col :xs="24" :sm="24" :lg="8"> <el-col :xs="24" :sm="24" :lg="8">
<div class="chart-wrapper"> <div class="chart-wrapper">
@ -23,7 +47,7 @@
<bar-chart /> <bar-chart />
</div> </div>
</el-col> </el-col>
</el-row> </el-row> -->
</div> </div>
@ -31,6 +55,18 @@
<script> <script>
import PanelGroup from './dashboard/PanelGroup' import PanelGroup from './dashboard/PanelGroup'
import * as echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './dashboard/mixins/resize'
import { getDataScreeningModelApi,
getCanteenOrdersAndSalesTrendsApi,
getSupermarketOrderAndSalesTrendApi,
getThisMonthSDishSalesRankingApi,
getProportionOfOrderTypesApi
} from "@/api/index";
import LineChart from './dashboard/LineChart' import LineChart from './dashboard/LineChart'
import RaddarChart from './dashboard/RaddarChart' import RaddarChart from './dashboard/RaddarChart'
import PieChart from './dashboard/PieChart' import PieChart from './dashboard/PieChart'
@ -56,6 +92,7 @@ const lineChartData = {
} }
export default { export default {
mixins: [resize],
name: 'Index', name: 'Index',
components: { components: {
PanelGroup, PanelGroup,
@ -66,10 +103,642 @@ export default {
}, },
data() { data() {
return { return {
topAreaOptions:[
{
"num": 27,
"rate": "92.86",
"name": "今日食堂营业额(元)",
"lastDate": "2025-05-15"
},{
"num": 3,
"rate": "50.00",
"name": "今日食堂订单量(个)",
"lastDate": "2025-05-15"
},
{
"num": 1,
"rate": "0.00",
"name": "今日就餐人数(个)",
"lastDate": "2025-05-15"
},
{
"num": 6,
"rate": "0.00",
"name": "今日菜品数量(个)",
"lastDate": "2025-05-15"
},
{
"num": 0,
"rate": "0.0",
"name": "今日超市营业额(元)",
"lastDate": "2025-05-15"
},
{
"num": 0,
"rate": "0.0",
"name": "今日超市订单量(个)",
"lastDate": "2025-05-15"
}
],
lineChartData: lineChartData.newVisitis lineChartData: lineChartData.newVisitis
} }
}, },
mounted(){
this.getTopData()
this.InitEChartsOne()
this.InitEChartsTwo()
this.InitEChartsThree()
this.InitEChartsFour()
},
methods: { methods: {
getTopData(){
getDataScreeningModelApi({}).then((response) => {
this.topAreaOptions = response.data.data;
});
},
InitEChartsOne() {
let chartData=[]
let weekDate=["周一","周二","周三","周四","周五","周六","周日"]
let monthDate = []
let salesData = []
let orderData = []
getCanteenOrdersAndSalesTrendsApi({type:"1"}).then((response) => {
chartData = response.data;
chartData.forEach((item,index)=>{
monthDate.push(item.orderDate)
salesData.push(item.salesValue)
orderData.push(item.orderValue)
})
var option = {
// title: {
// text: "",
// },
tooltip: {
trigger: "axis",
},
legend: {
data: ["销售额", "订单量"],
bottom: "0%",
},
grid: {
left: "5%",
right: "5%",
top: "20%",
bottom: "10%",
containLabel: true,
},
color: ["#4FA7FF", "#58F5CE"],
calculable: true,
xAxis: [
{
type: "category",
boundaryGap: false,
data: weekDate,
},
],
yAxis: {
name: "销售额/订单量",
type: "value",
},
series: [
{
name: "销售额",
type: "line",
areaStyle: {
normal: {
type: "default",
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: "rgba(79, 167, 255, 1)",
},
{
offset: 1,
color: "rgba(79, 167, 255, 1)",
},
],
false
),
},
},
smooth: true,
itemStyle: {
normal: { areaStyle: { type: "default" } },
},
data: salesData,
},
{
name: "订单量",
type: "line",
areaStyle: {
normal: {
type: "default",
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: "rgba(92, 255, 214, 1)",
},
{
offset: 1,
color: "rgba(92, 255, 214, 1)",
},
],
false
),
},
},
smooth: true,
itemStyle: { normal: { areaStyle: { type: "default" } } },
data: orderData,
},
],
};
let myCharts = echarts.init(document.querySelector('#lineChartOne'));
myCharts.setOption(option)
//
window.addEventListener("resize", function () {
myCharts.resize();
});
});
},
InitEChartsTwo() {
let chartData=[]
let weekDate=["周一","周二","周三","周四","周五","周六","周日"]
let monthDate = []
let salesData = []
let orderData = []
getSupermarketOrderAndSalesTrendApi({type:"1"}).then((response) => {
chartData = response.data;
chartData.forEach((item,index)=>{
monthDate.push(item.orderDate)
salesData.push(item.salesValue)
orderData.push(item.orderValue)
})
var option = {
// title: {
// text: "",
// },
tooltip: {
trigger: "axis",
},
legend: {
data: ["销售额", "订单量"],
bottom: "0%",
},
grid: {
left: "5%",
right: "5%",
top: "20%",
bottom: "10%",
containLabel: true,
},
color: ["#4FA7FF", "#58F5CE"],
calculable: true,
xAxis: [
{
type: "category",
boundaryGap: false,
data: weekDate,
},
],
yAxis: {
name: "销售额/订单量",
type: "value",
},
series: [
{
name: "销售额",
type: "line",
areaStyle: {
normal: {
type: "default",
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: "rgba(79, 167, 255, 1)",
},
{
offset: 1,
color: "rgba(79, 167, 255, 1)",
},
],
false
),
},
},
smooth: true,
itemStyle: {
normal: { areaStyle: { type: "default" } },
},
data: salesData,
},
{
name: "订单量",
type: "line",
areaStyle: {
normal: {
type: "default",
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: "rgba(92, 255, 214, 1)",
},
{
offset: 1,
color: "rgba(92, 255, 214, 1)",
},
],
false
),
},
},
smooth: true,
itemStyle: { normal: { areaStyle: { type: "default" } } },
data: orderData,
},
],
};
let myCharts = echarts.init(document.querySelector('#lineChartTwo'));
myCharts.setOption(option)
//
window.addEventListener("resize", function () {
myCharts.resize();
});
});
},
InitEChartsThree() {
var getName = [];
var getValue = [];
var chartData=[]
getThisMonthSDishSalesRankingApi({type:"2"}).then((response) => {
chartData = response.data;
chartData.forEach((item,index)=>{
getName.push(item.name)
getValue.push(item.num)
})
var max = Math.max.apply(null, getValue);
var getMax = [];
for (var i = 0; i < getName.length; i++) {
getMax.push(max+20);
}
var option = {
backgroundColor: "#fff",
grid: {
left: "4%",
right: "2%",
bottom: "2%",
top: "2%",
containLabel: true,
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "none",
},
formatter: function (params) {
return params[0].name + " : " + params[0].value;
},
},
xAxis: {
show: false,
type: "value",
},
yAxis: [
{
type: "category",
inverse: true,
offset: 100,
axisLabel: {
show: true,
align: "left",
textStyle: {
color: "#66cc00",
},
formatter: function (value, index) {
var num = "";
var str = "";
var no = "NO.";
num = index + 1;
if (index === 0) {
str = " {num1|" + num + "} {title1|" + value + "}";
} else if (index === 1) {
str = " {num2|" + num + "} {title2|" + value + "}";
} else if (index === 2) {
str = " {num3|" + num + "} {title3|" + value + "}";
} else {
str = " {num|" + num + "} {title|" + value + "}";
}
return str;
},
rich: {
no: {
color: "#333",
fontSize: 14,
},
no1: {
color: "#333",
fontSize: 14,
},
no2: {
color: "#333",
fontSize: 14,
},
no3: {
color: "#333",
fontSize: 14,
},
num: {
color: "#fff",
backgroundColor: "#5281F8",
width: 20,
height: 20,
fontSize: 14,
align: "center",
borderRadius: 100,
},
num1: {
color: "#fff",
backgroundColor: "#EDA54F",
width: 20,
height: 20,
fontSize: 14,
align: "center",
borderRadius: 100,
},
num2: {
color: "#fff",
backgroundColor: "#EDA54F",
width: 20,
height: 20,
fontSize: 14,
align: "center",
borderRadius: 100,
},
num3: {
color: "#fff",
backgroundColor: "#EDA54F",
width: 20,
height: 20,
fontSize: 14,
align: "center",
borderRadius: 100,
},
title: {
color: "#333333",
},
title1: {
color: "#333333",
},
title2: {
color: "#333333",
},
title3: {
color: "#333333",
},
},
},
splitLine: {
show: false,
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
data: getName,
},
{
type: "category",
inverse: true,
offset: -50,
axisTick: "none",
axisLine: "none",
show: true,
axisLabel: {
interval: 0,
color: "#666",
align: "left",
margin: 20,
fontSize: 13,
formatter: function (value, index) {
return (
getValue[index]
);
},
},
data: getValue,
},
],
series: [
{
name: "值",
type: "bar",
zlevel: 1,
itemStyle: {
normal: {
barBorderRadius: 30,
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{
offset: 0,
color: "rgb(0, 111, 104, 1)",
},
{
offset: 1,
color: "rgb(0, 111, 104, 1)",
},
]),
},
},
barWidth: 14,
data: getValue,
},
{
name: "背景",
type: "bar",
barWidth: 14,
barGap: "-100%",
data: getMax,
itemStyle: {
normal: {
color: "rgba(224, 233, 255, 1)",
barBorderRadius: 30,
},
},
},
],
};
let myCharts = echarts.init(document.querySelector('#lineChartThree'));
myCharts.setOption(option)
//
window.addEventListener("resize", function () {
myCharts.resize();
});
});
},
InitEChartsFour() {
var chartData=[]
getProportionOfOrderTypesApi({type:"2"}).then((response) => {
chartData = response.data;
var m2R2Data = []
var sumNum = 0
chartData.forEach((item,index)=>{
let obj = {}
sumNum=sumNum+item.num
if(index==0){
obj = {
value: item.num,
legendname: item.name,
name: item.name+' '+ item.num,
itemStyle: { color: "#5085f2" },
}
}
if(index==1){
obj = {
value: item.num,
legendname: item.name,
name: item.name+' '+ item.num,
itemStyle: { color: "#f2719a" },
}
}
if(index==2){
obj = {
value: item.num,
legendname: item.name,
name: item.name+' '+ item.num,
itemStyle: { color: "#fdb301" },
}
}
m2R2Data.push(obj)
})
// var m2R2Data = [
// {
// value: 310,
// legendname: "02",
// name: "02 310",
// itemStyle: { color: "#5085f2" },
// },
// {
// value: 335,
// legendname: "05",
// name: "05 335",
// itemStyle: { color: "#f2719a" },
// },
// {
// value: 335,
// legendname: "08",
// name: "08 335",
// itemStyle: { color: "#fdb301" },
// }
// ];
var option = {
title: [
{
text: "订单总数",
subtext: sumNum + "个",
textStyle: {
fontSize: 20,
color: "black",
},
subtextStyle: {
fontSize: 20,
color: "black",
},
textAlign: "center",
x: "34.5%",
y: "44%",
},
],
tooltip: {
trigger: "item",
formatter: function (parms) {
var str =
parms.seriesName +
"</br>" +
parms.marker +
"" +
parms.data.legendname +
"</br>" +
"数量:" +
parms.data.value +
"</br>" +
"占比:" +
parms.percent +
"%";
return str;
},
},
legend: {
type: "scroll",
orient: "vertical",
left: "70%",
align: "left",
top: "middle",
textStyle: {
color: "#8C8C8C",
},
height: 250,
},
series: [
{
name: "标题",
type: "pie",
center: ["35%", "50%"],
radius: ["65%", "90%"],
clockwise: false, //
avoidLabelOverlap: false,
label: {
normal: {
show: false,
position: "outter",
formatter: function (parms) {
return parms.data.legendname;
},
},
},
labelLine: {
normal: {
length: 5,
length2: 3,
smooth: true,
},
},
data: m2R2Data,
},
],
};
let myCharts = echarts.init(document.querySelector('#barChartFour'));
myCharts.setOption(option)
//
window.addEventListener("resize", function () {
myCharts.resize();
});
});
},
handleSetLineChartData(type) { handleSetLineChartData(type) {
this.lineChartData = lineChartData[type] this.lineChartData = lineChartData[type]
} }