1.数味智餐实时就餐数据看板页面完成60%
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 709 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
@@ -112,6 +112,15 @@ const routes = [
|
||||
},
|
||||
component: () => import('@/views/dataBoard/dataBoard.vue')
|
||||
},
|
||||
{
|
||||
path: '/dataBoard1',
|
||||
name: 'dataBoard1',
|
||||
meta: {
|
||||
title: '数据看板',
|
||||
rootValue: 192
|
||||
},
|
||||
component: () => import('@/views/dataBoard/dataBoard1.vue')
|
||||
},
|
||||
{
|
||||
path: '/dishesDetails',
|
||||
name: 'dishesDetails',
|
||||
|
||||
@@ -1,495 +1,325 @@
|
||||
<template>
|
||||
<div id="dataBoard">
|
||||
<div class="title"></div>
|
||||
<div class="times">
|
||||
<div>{{ currentDate }}</div>
|
||||
<div>
|
||||
{{ city }}
|
||||
<template v-if="weathersIcon">
|
||||
<img :src="weathersIcon" :alt="weathersIcon">
|
||||
</template>
|
||||
{{ weathers }}℃
|
||||
</div>
|
||||
<div class="outer-d">
|
||||
<div class="title">
|
||||
<img src="@/assets/images/dataBoard/title.png" alt="" />
|
||||
</div>
|
||||
<div class="total">
|
||||
<div>
|
||||
<div class="total-left">{{ preTime(nowTime) }}</div>
|
||||
<div class="total-d">
|
||||
<div>
|
||||
<countTo
|
||||
:startVal="dataBoard.num_ ? dataBoard.num_ : 0"
|
||||
:endVal="dataBoard.num"
|
||||
separator=""
|
||||
:duration="1500"
|
||||
@count-to-finish="handleFinish('num')" />
|
||||
<p>人</p>
|
||||
<div>
|
||||
<span>108</span>
|
||||
<span>人</span>
|
||||
</div>
|
||||
<div>用餐总人数</div>
|
||||
</div>
|
||||
<div>当餐用餐人数</div>
|
||||
<div>
|
||||
<div>
|
||||
<span>919</span>
|
||||
<span>千卡</span>
|
||||
</div>
|
||||
<div>人均热量</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<span>80</span>
|
||||
<span>分</span>
|
||||
</div>
|
||||
<div>人均营养分</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="total-right">午餐(10:30~13:30)</div>
|
||||
</div>
|
||||
<div class="table-top">
|
||||
<div>
|
||||
<img class="voice-img" src="@/assets/images/bigScreen/voice.png" alt="" />
|
||||
<span class="voice-span">
|
||||
实时播报:
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<countTo
|
||||
:startVal="dataBoard.aveEnergy_ ? dataBoard.aveEnergy_ : 0"
|
||||
:endVal="dataBoard.aveEnergy"
|
||||
separator=""
|
||||
:duration="1500"
|
||||
@count-to-finish="handleFinish('aveEnergy')" />
|
||||
<p>千卡</p>
|
||||
<img src="@/assets/images/bigScreen/boy.png" alt="" />
|
||||
陈*夏 89分 第一名;
|
||||
</div>
|
||||
<div>人均热量</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<countTo
|
||||
:startVal="dataBoard.aveFraction_ ? dataBoard.aveFraction_ : 0"
|
||||
:endVal="dataBoard.aveFraction"
|
||||
separator=""
|
||||
:duration="1500"
|
||||
@count-to-finish="handleFinish('aveFraction')" />
|
||||
<p>分</p>
|
||||
<img src="@/assets/images/bigScreen/girl.png" alt="" />
|
||||
张* 88分 第一名;
|
||||
</div>
|
||||
<div>
|
||||
<img src="@/assets/images/dataBoard/user.png" alt="" />
|
||||
陈知夏 86分 第一名;
|
||||
</div>
|
||||
<div>人均营养分</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="contentHead">
|
||||
<div>排名</div>
|
||||
<div>餐盘号</div>
|
||||
<div>
|
||||
得分
|
||||
<template v-if="type === 1">
|
||||
<img src="@/assets/images/dataBoard/down.png" />
|
||||
</template>
|
||||
<div class="bottom-d">
|
||||
<div class="table-d">
|
||||
<div class="table-title">
|
||||
<div>排名</div>
|
||||
<div>
|
||||
<div>用户信息</div>
|
||||
<div>健康得分</div>
|
||||
<div>下单时间</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>热量 (kcal)</div>
|
||||
<div>
|
||||
时间
|
||||
<template v-if="type === 2">
|
||||
<img src="@/assets/images/dataBoard/down.png" />
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contentBody">
|
||||
<template v-if="dataBoard.sortVos && dataBoard.sortVos.length">
|
||||
<template v-for="(item, index) in dataBoard.sortVos">
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<div>{{ index + 1 }}</div>
|
||||
<div>
|
||||
<template v-if="index < 3">
|
||||
<img :src="require('@/assets/images/dataBoard/' + (index + 1) + '.png')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<img src="@/assets/images/dataBoard/4.png">
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<template v-if="item.faceUrl">
|
||||
<img :src="item.faceUrl" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<img src="@/assets/images/dataBoard/user.png" />
|
||||
</template>
|
||||
</div>
|
||||
<div class="table-item" v-for="(item, index) in 10" :key="`list-data-${index}`">
|
||||
<div class="index-item">
|
||||
<template v-if="index === 0">
|
||||
<img src="@/assets/images/bigScreen/1.png" alt="" />
|
||||
</template>
|
||||
<template v-else-if="index === 1">
|
||||
<img src="@/assets/images/bigScreen/2.png" alt="" />
|
||||
</template>
|
||||
<template v-else-if="index === 2">
|
||||
<img src="@/assets/images/bigScreen/3.png" alt="" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="img-d">
|
||||
{{index+1}}
|
||||
</div>
|
||||
<div>{{ item.plateNumber }}</div>
|
||||
<div :class="type === 1 ? 'typeActive' : ''">{{ item.fraction }}</div>
|
||||
<div>{{ item.energy }}</div>
|
||||
<div :class="type === 2 ? 'typeActive' : ''">{{ item.time }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
<img class="title-img" src="@/assets/images/bigScreen/boy.png" alt="" />
|
||||
</div>
|
||||
<div>
|
||||
<div>用户信息</div>
|
||||
<div>健康得分</div>
|
||||
<div>下单时间</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-right-d"></div>
|
||||
</div>
|
||||
<div class="footer-d">
|
||||
数智餐厅
|
||||
</div>
|
||||
<div class="subtitle">数味智餐</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {onBeforeUnmount, onMounted, ref} from "vue";
|
||||
import * as dayjs from "dayjs";
|
||||
import 'dayjs/locale/zh-cn';
|
||||
|
||||
<script>
|
||||
import countTo from "vue-count-to";
|
||||
import AMapLoader from '@amap/amap-jsapi-loader';
|
||||
import {getCurrentDate} from "@/utils/times";
|
||||
import {weatherList} from "@/utils/weather";
|
||||
import {list} from "./api";
|
||||
const nowTimeInterval = ref()
|
||||
const nowTime = ref(dayjs())
|
||||
const listData = ref([
|
||||
{
|
||||
name: '',
|
||||
point: '',
|
||||
time: '',
|
||||
}
|
||||
])
|
||||
|
||||
export default {
|
||||
name: "dataBoard",
|
||||
components: {
|
||||
countTo
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentDate: getCurrentDate(),
|
||||
city: '',
|
||||
weathersIcon: '',
|
||||
weathers: '',
|
||||
onMounted(() => {
|
||||
getNowTime();
|
||||
})
|
||||
|
||||
setTimeoutParams: {
|
||||
status: true,
|
||||
times: 10
|
||||
},
|
||||
type: 1,
|
||||
dataBoard: {
|
||||
num: 0,
|
||||
aveEnergy: 0,
|
||||
aveFraction: 0,
|
||||
sortVos: []
|
||||
function getNowTime() {
|
||||
nowTimeInterval.value = setInterval(() => {
|
||||
nowTime.value = dayjs(nowTime.value).add(1, 'seconds')
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
function preTime(time) {
|
||||
return `${dayjs(time).format('YYYY年MM月DD日 HH:mm:ss')} ${dayjs(time).locale('zh-cn').format('dddd')}`
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
nowTimeInterval.value && clearInterval(nowTimeInterval.value)
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.outer-d {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: url("@/assets/images/bigScreen/bigBg.png") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
padding-top: 13px;
|
||||
text-align: center;
|
||||
img {
|
||||
width: 500px;
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initAMap();
|
||||
this.loadData();
|
||||
},
|
||||
methods: {
|
||||
initAMap() {
|
||||
window._AMapSecurityConfig = {
|
||||
securityJsCode: "eda729515c8d2c3fe5981f0a1616ff40",
|
||||
};
|
||||
AMapLoader.load({
|
||||
key: "a9c8316986c542c6624a7343712d2d18",
|
||||
version: "2.0",
|
||||
plugins: ["AMap.CitySearch","AMap.Geolocation", "AMap.Weather"],
|
||||
resizeEnable: true,
|
||||
}).then((AMap) => {
|
||||
new AMap.CitySearch().getLocalCity((status, result) => {
|
||||
if (status === 'complete' && result.info === 'OK') {
|
||||
this.city = result.city;
|
||||
new AMap.Weather().getLive(result.city, (err, data) => {
|
||||
if(!err && data.info === 'OK') {
|
||||
weatherList.map(item => {
|
||||
if(data.weather === item.name) {
|
||||
this.weathersIcon = item.url;
|
||||
|
||||
.total {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 20px;
|
||||
padding: 0 140px;
|
||||
.total-left, .total-right {
|
||||
color: #8CCAFF;
|
||||
font-size: 20px;
|
||||
flex: 1;
|
||||
}
|
||||
.total-left {
|
||||
text-align: left;
|
||||
}
|
||||
.total-right {
|
||||
text-align: right;
|
||||
}
|
||||
.total-d {
|
||||
width: 800px;
|
||||
background: url("@/assets/images/dataBoard/total.png") no-repeat;
|
||||
background-size: 100% 70%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background-position: center bottom;
|
||||
padding: 10px 120px 18px;
|
||||
> div {
|
||||
> div {
|
||||
&:nth-child(1) {
|
||||
color: #FFB99C;
|
||||
font-weight: bold;
|
||||
span {
|
||||
font-family: 'HarmonyOS Sans SC';
|
||||
&:nth-child(1) {
|
||||
font-size: 36px;
|
||||
}
|
||||
});
|
||||
this.weathers = data.temperature;
|
||||
&:nth-child(2) {
|
||||
font-size: 24px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:nth-child(2) {
|
||||
color: #8CCAFF;
|
||||
font-size: 18px;
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}).catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
},
|
||||
|
||||
handleFinish(k) {
|
||||
let newKey = k + '_';
|
||||
this.dataBoard[newKey] = this.dataBoard[k];
|
||||
},
|
||||
|
||||
setTimePlay() {
|
||||
let times = this.setTimeoutParams.times * 1000;
|
||||
setTimeout(() => {
|
||||
this.type = this.type === 1 ? 2 : 1;
|
||||
this.loadData();
|
||||
}, times);
|
||||
},
|
||||
|
||||
loadData() {
|
||||
let params = {
|
||||
type: this.type
|
||||
};
|
||||
list(params).then(res => {
|
||||
if (res.success) {
|
||||
this.dataBoard.num = res.data.num;
|
||||
this.dataBoard.aveEnergy = res.data.aveEnergy;
|
||||
this.dataBoard.aveFraction = res.data.aveFraction;
|
||||
this.dataBoard.sortVos = res.data.sortVos.slice(0, 9);
|
||||
}
|
||||
|
||||
if (this.setTimeoutParams.status) {
|
||||
this.setTimePlay();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
#dataBoard {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background-color: #060F1E;
|
||||
background-size: cover;
|
||||
background-position: center top;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("@/assets/images/dataBoard/bg.png");
|
||||
|
||||
.title {
|
||||
width: 506px;
|
||||
height: 48px;
|
||||
margin: 12px auto 18px;
|
||||
background-size: cover;
|
||||
background-position: center top;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("@/assets/images/dataBoard/title.png");
|
||||
}
|
||||
|
||||
.times {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
margin-bottom: 3px;
|
||||
padding: 0 120px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
|
||||
> div {
|
||||
color: #8CCAFF;
|
||||
height: 40px;
|
||||
font-size: 20px;
|
||||
line-height: 40px;
|
||||
.table-top {
|
||||
padding: 5px 140px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.total {
|
||||
width: 840px;
|
||||
height: 85px;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
margin: 0 auto 16px;
|
||||
padding: 0 93px 0 100px;
|
||||
box-sizing: border-box;
|
||||
background-size: cover;
|
||||
background-position: center top;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("@/assets/images/dataBoard/total.png");
|
||||
|
||||
> div {
|
||||
|
||||
> div:nth-of-type(1) {
|
||||
color: #FFB99C;
|
||||
height: 36px;
|
||||
font-size: 36px;
|
||||
line-height: 36px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
|
||||
> p {
|
||||
font-size: 20px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
> div:nth-of-type(2) {
|
||||
color: #8CCAFF;
|
||||
height: 18px;
|
||||
font-size: 18px;
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 820px;
|
||||
padding: 0 202px 0 258px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.contentHead {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
padding-left: 100px;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
background-color: #2D4374;
|
||||
box-shadow: 0 3px 12px 0 rgba(11,26,56,0.44);
|
||||
|
||||
> div {
|
||||
color: #8CCAFF;
|
||||
height: 60px;
|
||||
font-size: 24px;
|
||||
line-height: 60px;
|
||||
|
||||
&:nth-of-type(1) {
|
||||
width: 170px;
|
||||
}
|
||||
|
||||
&:nth-of-type(2) {
|
||||
width: 290px;
|
||||
text-align: center;
|
||||
margin-right: 145px;
|
||||
}
|
||||
|
||||
&:nth-of-type(3) {
|
||||
width: 195px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-of-type(4) {
|
||||
width: 290px;
|
||||
text-align: center;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
&:nth-of-type(5) {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.contentBody {
|
||||
width: 100%;
|
||||
padding: 24px 50px 0 100px;
|
||||
box-sizing: border-box;
|
||||
|
||||
> div {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
|
||||
> div:nth-of-type(1) {
|
||||
width: 170px;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
> div:nth-of-type(1) {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
position: relative;
|
||||
|
||||
> div:nth-of-type(1) {
|
||||
color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
line-height: 38px;
|
||||
z-index: 2;
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
> div:nth-of-type(2) {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
&:nth-child(1) {
|
||||
.voice-img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
> div:nth-of-type(2) {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
overflow: hidden;
|
||||
border-radius: 50%;
|
||||
.voice-span {
|
||||
color: #8CCAFF;
|
||||
font-size: 20px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
&:nth-child(2) {
|
||||
display: flex;
|
||||
padding-left: 5px;
|
||||
color: #FFB99C;
|
||||
font-size: 22px;
|
||||
|
||||
img {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
> div {
|
||||
padding: 0 45px 0 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> div:nth-of-type(2) {
|
||||
color: #8CCAFF;
|
||||
width: 290px;
|
||||
height: 60px;
|
||||
font-size: 36px;
|
||||
line-height: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
> div:nth-of-type(3) {
|
||||
color: #8CCAFF;
|
||||
width: 340px;
|
||||
height: 60px;
|
||||
font-size: 36px;
|
||||
line-height: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
> div:nth-of-type(4) {
|
||||
color: #8CCAFF;
|
||||
width: 290px;
|
||||
height: 60px;
|
||||
font-size: 36px;
|
||||
line-height: 60px;
|
||||
text-align: right;
|
||||
padding-right: 115px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
> div:nth-of-type(5) {
|
||||
flex: 1;
|
||||
color: #8CCAFF;
|
||||
height: 60px;
|
||||
font-size: 36px;
|
||||
line-height: 60px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&:nth-of-type(n + 4) > div:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(1) {
|
||||
color: #717B86 !important;
|
||||
line-height: 50px !important;
|
||||
}
|
||||
|
||||
.typeActive {
|
||||
color: #FFB99C !important;
|
||||
font-weight: bold !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: #8CCAFF;
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
font-size: 24px;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
.bottom-d {
|
||||
flex: 1;
|
||||
padding: 10px 100px 20px;
|
||||
|
||||
> div {
|
||||
&:nth-child(1) {
|
||||
width: 67%;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
width: 33%;
|
||||
}
|
||||
}
|
||||
|
||||
.table-d {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.table-title {
|
||||
background: #6F9DFF;
|
||||
border-radius: 5px;
|
||||
padding: 3px 40px;
|
||||
color: #8CCAFF;
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
> div {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
&:nth-child(1) {
|
||||
width: calc(100% / 3);
|
||||
}
|
||||
&:nth-child(2) {
|
||||
width: calc(100% / 3 * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
.table-item {
|
||||
flex: 1;
|
||||
padding: 15px 40px 3px;
|
||||
color: #8CCAFF;
|
||||
font-size: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> div {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
&:nth-child(1) {
|
||||
width: calc(100% / 3);
|
||||
}
|
||||
&:nth-child(2) {
|
||||
width: calc(100% / 3 * 2);
|
||||
}
|
||||
}
|
||||
|
||||
.index-item {
|
||||
img {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
.img-d {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: url("@/assets/images/bigScreen/4.png") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.title-img {
|
||||
width: 35px !important;
|
||||
height: 35px !important;
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.footer-d {
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
padding-bottom: 10px;
|
||||
color: #8CCAFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -0,0 +1,496 @@
|
||||
<template>
|
||||
<div id="dataBoard">
|
||||
<div class="title"></div>
|
||||
<div class="times">
|
||||
<div>{{ currentDate }}</div>
|
||||
<div>
|
||||
{{ city }}
|
||||
<template v-if="weathersIcon">
|
||||
<img :src="weathersIcon" :alt="weathersIcon">
|
||||
</template>
|
||||
{{ weathers }}℃
|
||||
</div>
|
||||
</div>
|
||||
<div class="total">
|
||||
<div>
|
||||
<div>
|
||||
<countTo
|
||||
:startVal="dataBoard.num_ ? dataBoard.num_ : 0"
|
||||
:endVal="dataBoard.num"
|
||||
separator=""
|
||||
:duration="1500"
|
||||
@count-to-finish="handleFinish('num')" />
|
||||
<p>人</p>
|
||||
</div>
|
||||
<div>当餐用餐人数</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<countTo
|
||||
:startVal="dataBoard.aveEnergy_ ? dataBoard.aveEnergy_ : 0"
|
||||
:endVal="dataBoard.aveEnergy"
|
||||
separator=""
|
||||
:duration="1500"
|
||||
@count-to-finish="handleFinish('aveEnergy')" />
|
||||
<p>千卡</p>
|
||||
</div>
|
||||
<div>人均热量</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<countTo
|
||||
:startVal="dataBoard.aveFraction_ ? dataBoard.aveFraction_ : 0"
|
||||
:endVal="dataBoard.aveFraction"
|
||||
separator=""
|
||||
:duration="1500"
|
||||
@count-to-finish="handleFinish('aveFraction')" />
|
||||
<p>分</p>
|
||||
</div>
|
||||
<div>人均营养分</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="contentHead">
|
||||
<div>排名</div>
|
||||
<div>餐盘号</div>
|
||||
<div>
|
||||
得分
|
||||
<template v-if="type === 1">
|
||||
<img src="@/assets/images/dataBoard/down.png" />
|
||||
</template>
|
||||
</div>
|
||||
<div>热量 (kcal)</div>
|
||||
<div>
|
||||
时间
|
||||
<template v-if="type === 2">
|
||||
<img src="@/assets/images/dataBoard/down.png" />
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contentBody">
|
||||
<template v-if="dataBoard.sortVos && dataBoard.sortVos.length">
|
||||
<template v-for="(item, index) in dataBoard.sortVos">
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<div>{{ index + 1 }}</div>
|
||||
<div>
|
||||
<template v-if="index < 3">
|
||||
<img :src="require('@/assets/images/dataBoard/' + (index + 1) + '.png')" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<img src="@/assets/images/dataBoard/4.png">
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<template v-if="item.faceUrl">
|
||||
<img :src="item.faceUrl" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<img src="@/assets/images/dataBoard/user.png" />
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div>{{ item.plateNumber }}</div>
|
||||
<div :class="type === 1 ? 'typeActive' : ''">{{ item.fraction }}</div>
|
||||
<div>{{ item.energy }}</div>
|
||||
<div :class="type === 2 ? 'typeActive' : ''">{{ item.time }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="subtitle">数味智餐</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import countTo from "vue-count-to";
|
||||
import AMapLoader from '@amap/amap-jsapi-loader';
|
||||
import {getCurrentDate} from "@/utils/times";
|
||||
import {weatherList} from "@/utils/weather";
|
||||
import {list} from "./api";
|
||||
|
||||
export default {
|
||||
name: "dataBoard",
|
||||
components: {
|
||||
countTo
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentDate: getCurrentDate(),
|
||||
city: '',
|
||||
weathersIcon: '',
|
||||
weathers: '',
|
||||
|
||||
setTimeoutParams: {
|
||||
status: true,
|
||||
times: 10
|
||||
},
|
||||
type: 1,
|
||||
dataBoard: {
|
||||
num: 0,
|
||||
aveEnergy: 0,
|
||||
aveFraction: 0,
|
||||
sortVos: []
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initAMap();
|
||||
this.loadData();
|
||||
},
|
||||
methods: {
|
||||
initAMap() {
|
||||
window._AMapSecurityConfig = {
|
||||
securityJsCode: "eda729515c8d2c3fe5981f0a1616ff40",
|
||||
};
|
||||
AMapLoader.load({
|
||||
key: "a9c8316986c542c6624a7343712d2d18",
|
||||
version: "2.0",
|
||||
plugins: ["AMap.CitySearch","AMap.Geolocation", "AMap.Weather"],
|
||||
resizeEnable: true,
|
||||
}).then((AMap) => {
|
||||
new AMap.CitySearch().getLocalCity((status, result) => {
|
||||
if (status === 'complete' && result.info === 'OK') {
|
||||
this.city = result.city;
|
||||
new AMap.Weather().getLive(result.city, (err, data) => {
|
||||
if(!err && data.info === 'OK') {
|
||||
weatherList.map(item => {
|
||||
if(data.weather === item.name) {
|
||||
this.weathersIcon = item.url;
|
||||
}
|
||||
});
|
||||
this.weathers = data.temperature;
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}).catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
},
|
||||
|
||||
handleFinish(k) {
|
||||
let newKey = k + '_';
|
||||
this.dataBoard[newKey] = this.dataBoard[k];
|
||||
},
|
||||
|
||||
setTimePlay() {
|
||||
let times = this.setTimeoutParams.times * 1000;
|
||||
setTimeout(() => {
|
||||
this.type = this.type === 1 ? 2 : 1;
|
||||
this.loadData();
|
||||
}, times);
|
||||
},
|
||||
|
||||
loadData() {
|
||||
let params = {
|
||||
type: this.type
|
||||
};
|
||||
list(params).then(res => {
|
||||
if (res.success) {
|
||||
this.dataBoard.num = res.data.num;
|
||||
this.dataBoard.aveEnergy = res.data.aveEnergy;
|
||||
this.dataBoard.aveFraction = res.data.aveFraction;
|
||||
this.dataBoard.sortVos = res.data.sortVos.slice(0, 9);
|
||||
}
|
||||
|
||||
if (this.setTimeoutParams.status) {
|
||||
this.setTimePlay();
|
||||
}
|
||||
})
|
||||
.catch((err) => {})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
#dataBoard {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background-color: #060F1E;
|
||||
background-size: cover;
|
||||
background-position: center top;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("@/assets/images/dataBoard/bg.png");
|
||||
|
||||
.title {
|
||||
width: 506px;
|
||||
height: 48px;
|
||||
margin: 12px auto 18px;
|
||||
background-size: cover;
|
||||
background-position: center top;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("@/assets/images/dataBoard/title.png");
|
||||
}
|
||||
|
||||
.times {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
margin-bottom: 3px;
|
||||
padding: 0 120px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
|
||||
> div {
|
||||
color: #8CCAFF;
|
||||
height: 40px;
|
||||
font-size: 20px;
|
||||
line-height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.total {
|
||||
width: 840px;
|
||||
height: 85px;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
margin: 0 auto 16px;
|
||||
padding: 0 93px 0 100px;
|
||||
box-sizing: border-box;
|
||||
background-size: cover;
|
||||
background-position: center top;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("@/assets/images/dataBoard/total.png");
|
||||
|
||||
> div {
|
||||
|
||||
> div:nth-of-type(1) {
|
||||
color: #FFB99C;
|
||||
height: 36px;
|
||||
font-size: 36px;
|
||||
line-height: 36px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
|
||||
> p {
|
||||
font-size: 20px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
> div:nth-of-type(2) {
|
||||
color: #8CCAFF;
|
||||
height: 18px;
|
||||
font-size: 18px;
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 820px;
|
||||
padding: 0 202px 0 258px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.contentHead {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
padding-left: 100px;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
background-color: #2D4374;
|
||||
box-shadow: 0 3px 12px 0 rgba(11,26,56,0.44);
|
||||
|
||||
> div {
|
||||
color: #8CCAFF;
|
||||
height: 60px;
|
||||
font-size: 24px;
|
||||
line-height: 60px;
|
||||
|
||||
&:nth-of-type(1) {
|
||||
width: 170px;
|
||||
}
|
||||
|
||||
&:nth-of-type(2) {
|
||||
width: 290px;
|
||||
text-align: center;
|
||||
margin-right: 145px;
|
||||
}
|
||||
|
||||
&:nth-of-type(3) {
|
||||
width: 195px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-of-type(4) {
|
||||
width: 290px;
|
||||
text-align: center;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
&:nth-of-type(5) {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.contentBody {
|
||||
width: 100%;
|
||||
padding: 24px 50px 0 100px;
|
||||
box-sizing: border-box;
|
||||
|
||||
> div {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
|
||||
> div:nth-of-type(1) {
|
||||
width: 170px;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
> div:nth-of-type(1) {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
position: relative;
|
||||
|
||||
> div:nth-of-type(1) {
|
||||
color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
line-height: 38px;
|
||||
z-index: 2;
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
> div:nth-of-type(2) {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> div:nth-of-type(2) {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
overflow: hidden;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> div:nth-of-type(2) {
|
||||
color: #8CCAFF;
|
||||
width: 290px;
|
||||
height: 60px;
|
||||
font-size: 36px;
|
||||
line-height: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
> div:nth-of-type(3) {
|
||||
color: #8CCAFF;
|
||||
width: 340px;
|
||||
height: 60px;
|
||||
font-size: 36px;
|
||||
line-height: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
> div:nth-of-type(4) {
|
||||
color: #8CCAFF;
|
||||
width: 290px;
|
||||
height: 60px;
|
||||
font-size: 36px;
|
||||
line-height: 60px;
|
||||
text-align: right;
|
||||
padding-right: 115px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
> div:nth-of-type(5) {
|
||||
flex: 1;
|
||||
color: #8CCAFF;
|
||||
height: 60px;
|
||||
font-size: 36px;
|
||||
line-height: 60px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&:nth-of-type(n + 4) > div:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(1) {
|
||||
color: #717B86 !important;
|
||||
line-height: 50px !important;
|
||||
}
|
||||
|
||||
.typeActive {
|
||||
color: #FFB99C !important;
|
||||
font-weight: bold !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: #8CCAFF;
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
font-size: 24px;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||