2025年6月9日10:23:02
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
import { getRequest } from '@/axios';
|
||||
|
||||
let url = {
|
||||
ct: "/shuwei-zhct/swLargeScreenFood/foodInfoByDeviceId", // 餐厅
|
||||
st: "/local/zhstapi/zhst/tv/foodInfoByDeviceId", // 食堂
|
||||
};
|
||||
|
||||
export const info = (type, params) => getRequest(type + 'Request', url[type], params);
|
||||
@@ -0,0 +1,384 @@
|
||||
<template>
|
||||
<div id="dishesDetails-info">
|
||||
<div class="personTime">
|
||||
<div>取餐人次</div>
|
||||
<div>
|
||||
<template v-if="dishesDetails && dishesDetails.foodId">
|
||||
<countTo
|
||||
:startVal="dishesDetails.num_ ? dishesDetails.num_ : 0"
|
||||
:endVal="dishesDetails.num"
|
||||
separator=""
|
||||
:duration="1500"
|
||||
@count-to-finish="handleFinish('num')" />
|
||||
</template>
|
||||
<template v-else>-</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dishesPictures">
|
||||
<template v-if="dishesDetails && dishesDetails.foodId && dishesDetails.relativeUrl">
|
||||
<img :src="dishesDetails.relativeUrl" :alt="dishesDetails.relativeUrl" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<img src="@/assets/images/dishesDetails/null.png" />
|
||||
</template>
|
||||
</div>
|
||||
<div class="dishesInfo">
|
||||
<div>
|
||||
<template v-if="dishesDetails && dishesDetails.foodId">
|
||||
<div>
|
||||
<div>{{ dishesDetails.foodName }}</div>
|
||||
<div :style="{'color': dishesDetails.initialStatus ? '#FF2222' : '#161616'}">
|
||||
(
|
||||
<countTo
|
||||
:startVal="dishesDetails.initial_ ? dishesDetails.initial_ : 0"
|
||||
:endVal="dishesDetails.initial"
|
||||
separator=""
|
||||
:decimals="2"
|
||||
:duration="1500"
|
||||
@count-to-finish="handleFinish('initial')" />
|
||||
)
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div>
|
||||
<div style="color: #77849E">暂无数据</div>
|
||||
</div>
|
||||
</template>
|
||||
<div>
|
||||
<template v-if="dishesDetails && dishesDetails.foodId">
|
||||
<template v-for="item in dishesDetails.itemTexts">
|
||||
<div>{{ item }}</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<template v-if="dishesDetails && dishesDetails.foodId">
|
||||
<div>
|
||||
<countTo
|
||||
:startVal="dishesDetails.surplus ? dishesDetails.surplus_ : 0"
|
||||
:endVal="dishesDetails.surplus"
|
||||
separator=""
|
||||
:decimals="2"
|
||||
:duration="1500"
|
||||
@count-to-finish="handleFinish('surplus')" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div style="color: #77849E">-</div>
|
||||
</template>
|
||||
<div>余量(kg)</div>
|
||||
</div>
|
||||
<div>
|
||||
<template v-if="dishesDetails && dishesDetails.foodId">
|
||||
<div>
|
||||
<countTo
|
||||
:startVal="dishesDetails.eatWeight_ ? dishesDetails.eatWeight_ : 0"
|
||||
:endVal="dishesDetails.eatWeight"
|
||||
separator=""
|
||||
:decimals="2"
|
||||
:duration="1500"
|
||||
@count-to-finish="handleFinish('eatWeight')" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div style="color: #77849E">-</div>
|
||||
</template>
|
||||
<div>实名取餐(kg)</div>
|
||||
</div>
|
||||
<div>
|
||||
<template v-if="dishesDetails && dishesDetails.foodId">
|
||||
<div :style="{'color': dishesDetails.anonymityWeight > 0 ? '#FF2222' : '#161616'}">
|
||||
<countTo
|
||||
:startVal="dishesDetails.anonymityWeight_ ? dishesDetails.anonymityWeight_ : 0"
|
||||
:endVal="dishesDetails.anonymityWeight"
|
||||
separator=""
|
||||
:decimals="2"
|
||||
:duration="1500"
|
||||
@count-to-finish="handleFinish('anonymityWeight')" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div style="color: #77849E">-</div>
|
||||
</template>
|
||||
<div>丢失餐量(kg)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import countTo from "vue-count-to";
|
||||
import {initMqtt, callBackMqttMessage} from "@/utils/mqtt";
|
||||
import {info} from "../api";
|
||||
|
||||
export default {
|
||||
name: "info",
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
keyName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
countTo
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
deviceId: "",
|
||||
|
||||
dishesDetails: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
let deviceId = this.$route.query[this.keyName];
|
||||
if(deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
initMqtt('deviceId-' + Math.random().toString(16).substring(2, 8), "sw_device_msg", this.type).then((res) => {
|
||||
console.log(res);
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
this.loadData(deviceId);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadData(deviceId) {
|
||||
if(deviceId === this.deviceId) {
|
||||
let params = {
|
||||
deviceId: deviceId
|
||||
};
|
||||
info(this.type, params).then(res => {
|
||||
if (res.success) {
|
||||
let data = this.type === 'ct' ? res.data : res.result;
|
||||
data.initialStatus = this.isAOutOf10PercentOfB(data);
|
||||
this.dishesDetails = data;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
isAOutOf10PercentOfB(data) {
|
||||
let initial = Number((data.surplus + data.eatWeight + data.anonymityWeight).toFixed(2));
|
||||
let lowerBound = data.initial * 0.9;
|
||||
let upperBound = data.initial * 1.1;
|
||||
return initial <= lowerBound || initial >= upperBound;
|
||||
},
|
||||
|
||||
handleFinish(k) {
|
||||
let newKey = k + '_';
|
||||
this.dishesDetails[newKey] = this.dishesDetails[k];
|
||||
},
|
||||
|
||||
mqttMessage(data) {
|
||||
this.loadData(data.deviceId);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
callBackMqttMessage((data) => {
|
||||
this.mqttMessage(data.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
#dishesDetails-info {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
border-radius: 24px;
|
||||
background-color: #FFFFFF;
|
||||
|
||||
.personTime {
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
width: 500px;
|
||||
height: 168px;
|
||||
padding-top: 20px;
|
||||
box-sizing: border-box;
|
||||
background-size: cover;
|
||||
background-position: center top;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("@/assets/images/dishesDetails/personTime.png");
|
||||
|
||||
> div:nth-of-type(1) {
|
||||
color: #FFFFFF;
|
||||
height: 30px;
|
||||
font-size: 30px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
> div:nth-of-type(2) {
|
||||
color: #FFFFFF;
|
||||
height: 80px;
|
||||
font-size: 80px;
|
||||
line-height: 80px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.dishesPictures {
|
||||
width: 100%;
|
||||
height: 800px;
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
background: linear-gradient(0deg, #FFFFFF 0%, #1B2E54 0%, #FFFFFF 0%, rgba(255,255,255,0) 100%);
|
||||
}
|
||||
}
|
||||
|
||||
.dishesInfo {
|
||||
position: absolute;
|
||||
z-index: 4;
|
||||
left: 24px;
|
||||
right: 24px;
|
||||
bottom: 24px;
|
||||
margin: auto;
|
||||
height: 500px;
|
||||
overflow: hidden;
|
||||
border-radius: 24px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #FFFFFF;
|
||||
|
||||
> div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 76px 15px 0;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
> div:nth-of-type(1) {
|
||||
width: 100%;
|
||||
height: 64px;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: center;
|
||||
margin-bottom: 45px;
|
||||
|
||||
> div:nth-of-type(1) {
|
||||
color: #161616;
|
||||
height: 64px;
|
||||
font-size: 64px;
|
||||
font-weight: bold;
|
||||
line-height: 64px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
> div:nth-of-type(2) {
|
||||
color: #161616;
|
||||
height: 64px;
|
||||
font-size: 64px;
|
||||
font-weight: bold;
|
||||
line-height: 64px;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> div:nth-of-type(2) {
|
||||
width: 100%;
|
||||
height: 64px;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: center;
|
||||
margin-bottom: 70px;
|
||||
|
||||
> div {
|
||||
color: #04A777;
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
height: 62px;
|
||||
padding: 0 22px;
|
||||
line-height: 62px;
|
||||
border-radius: 6px;
|
||||
margin: 0 12px;
|
||||
background-color: #DBF6EE;
|
||||
border: 1px solid #BCEFE1;
|
||||
}
|
||||
}
|
||||
|
||||
> div:nth-of-type(3) {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
> div {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
|
||||
> div:nth-of-type(1) {
|
||||
color: #161616;
|
||||
height: 80px;
|
||||
font-size: 80px;
|
||||
line-height: 80px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
> div:nth-of-type(2) {
|
||||
color: #999999;
|
||||
height: 30px;
|
||||
font-size: 30px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:before {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
content: "";
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
opacity: 0.67;
|
||||
background-color: #EEF6FD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.nullData {
|
||||
width: 100%;
|
||||
padding-top: 30vh;
|
||||
font-size: 36px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div id="dishesDetails">
|
||||
<div>
|
||||
<Info :type="type" keyName="l" />
|
||||
</div>
|
||||
<div>
|
||||
<Info :type="type" keyName="r" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Info from "./components/info.vue";
|
||||
|
||||
export default {
|
||||
name: "dishesDetails",
|
||||
components: {
|
||||
Info
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
type: this.$route.query.type,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
#dishesDetails {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
padding: 48px 107px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
background-color: #000000;
|
||||
|
||||
> div {
|
||||
width: 800px;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user