微工厂环境大屏

This commit is contained in:
hzz 2023-08-15 14:59:32 +08:00
parent 0878434b03
commit 5c00f76020
11 changed files with 1199 additions and 2 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

View File

@ -33,3 +33,11 @@ export function getCuttingLineHistogramData(){
export function getActivationData(){
return get('/device/getActivation')
}
/**
*
*/
export function getSensorByDeptId(data){
return get('/device/getSensorByDeptId',data)
}

View File

@ -0,0 +1,67 @@
/*
* @FilePath: \wwwd:\code\screenFront\src\store\moduleSocketjixie.ts
* @Author:
* @文件版本: V1.0.0
* @Date: 2023-02-06 15:58:13
* @Description:
*
* 版权信息 : 2023 by ${}, All Rights Reserved.
*/
import { defineStore } from "pinia";
import { Names } from '@/store/storeName'
import { gettime, clacendTime } from "@/utils/time"
export const useSocketStore = defineStore(Names.socketMicEnvironment, {
// 使用方式
// const Index= useIndexStore()
// 1、Index.{数据}++
// 2、Index.$patch({数据:??})
// 3、Index.$patch((state)=>{ state.数据=??})
// 4、通过action修改
state: () => {
return {
humiture:
{ "devId": "", "name": "温湿度", "temp": "0", "humidity": "0" },
// humiture:{Humiture:[],bottom:{humidity:null,temp:null,name:null},top:{humidity:null,temp:null,name:null}}, //温湿度
pm: { "devId": "", "name": "粉尘", "pm25": "0", "pm10": "0" },
verticalArr:[]
}
},
//computed 修改一些值
//需要使用return将数据抛出
//getters内可相互使用计算结果
//使用时可直接放入标签内<div>Index.方法()</div>
getters: {
},
actions: {
//初始化
setVerticalArr(val){
this.verticalArr=val
},
sethumiture(val){
this.humiture=val
},
setpm(val){
this.pm=val
},
changehumiture(val){
this.humiture.temp = val.temp
this.humiture.humidity = val.humidity
},
changePm(val){
this.pm.pm25 = val.pm25
this.pm.pm10 = val.pm10
},
changeVerticalArr(val){
this.verticalArr.forEach(res=>{
if(res.id==val.devId&&res.item.type==val.type){
res.item.val=val.val
res.item.status = val.status
}
})
}
}
})

View File

@ -28,4 +28,5 @@ export const enum Names{
MechanicalViewJingjia="MechanicalViewJingjia",
MechanicalViewJingshi="MechanicalViewJingshi",
socketMechanics='socketMechanics',
socketMicEnvironment='socketMicEnvironment',
}

View File

@ -0,0 +1,232 @@
<template>
<border13>
<div class="container">
<div class="echartbox" ref="humiture"></div>
</div>
</border13>
</template>
<script setup lang='ts'>
import { getCurrentInstance, markRaw, onMounted, reactive, ref, watch, onUnmounted,computed } from "vue";
import { useSocketStore } from "@/store/moduleSocketMicEnvironment";
import border13 from '@/components/border/Border13.vue'
const { proxy } = getCurrentInstance() as any;
const store = useSocketStore();
let index = 0;
let humiture = ref();
let chart = null
// const props = defineProps<{
// top: any;
// bottom: any;
// }>();
const borderColor = ["#E43961","#E43961"]
function init() {
if (!chart) {
chart = proxy.$echarts.init(humiture.value, 'dark');
}
let option = {
title: {
text: store.humiture.name,
show: true,
textStyle: {
color: "#fff",
fontSize: 18,
},
top: '2%'
},
grid: {
//
top: "0px",
left: "0px",
right: "0px",
bottom: "0px",
},
series: [
{
type: "gauge",
center: ["50%", "90%"],
startAngle: 190,
endAngle: -10,
radius: "50%",
min: -30,
max: 50,
splitNumber: 10,
progress: {
show: false,
width: 5
},
pointer: {
itemStyle: {
color: 'inherit'
}
},
//
axisLine: {
lineStyle: {
width: 10,
color: [
[0.575, '#1089E7'],
[0.725, '#7CFFB2'],
[1, '#FF6E76']
]
}
},
//线
axisTick: {
show: false,
distance: -5,
splitNumber: 5,
lineStyle: {
width: 2,
color: '#999'
}
},
//线
splitLine: {
distance: 5,
length: 3,
lineStyle: {
width: 3,
color: '#999'
}
},
//
axisLabel: {
distance: 15,
color: '#999',
fontSize: 10
},
anchor: {
show: false
},
title: {
show: false
},
detail: {
valueAnimation: true,
// width: '10%',
// lineHeight: 5,
// borderRadius: 8,
offsetCenter: [0, '25%'],
fontSize: 15,
// fontWeight: 'bolder',
formatter: '{value} °C',
color: 'inherit'
},
data: [
{
value: store.humiture.temp
}
]
},
{
type: "gauge",
center: ["50%", "55%"],
startAngle: 200,
endAngle: -20,
min: 0,
max: 100,
progress: {
show: false,
width: 5
},
pointer: {
itemStyle: {
color: 'inherit'
}
},
//
axisLine: {
lineStyle: {
width: 10,
color: [
[0.4, '#FF6E76'],
[0.7, '#7CFFB2'],
[1, '#1089E7']
]
}
},
//线
axisTick: {
distance: 0,
splitNumber: 5,
lineStyle: {
width: 2,
color: '#999'
}
},
//线
splitLine: {
distance: 5,
length: 3,
lineStyle: {
width: 3,
color: '#999'
}
},
axisLabel: {
distance: 15,
color: '#999',
fontSize: 12
},
anchor: {
show: false
},
title: {
show: false
},
detail: {
valueAnimation: true,
offsetCenter: [0, '15%'],
fontSize: 20,
formatter: '{value} %RH',
color: 'inherit'
},
data: [
{
value: store.humiture.humidity
}
]
},
],
};
chart.setOption(option);
}
watch(
() => store.humiture,
(newData) => {
init()
},
{ deep: true }
);
onMounted(() => {
init();
});
onUnmounted(() => {
});
</script>
<style scoped>
.container {
width: 100%;
height: 100%;
}
.errList {
width: 100%;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
}
.echartbox {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,125 @@
<template>
<div class="container">
<div class="chart" ref="chart"></div>
<div class="math-box">
<div class="math-content">
<div style="height: 25%;"> </div>
<div class="key">最大值</div>
<div class="key">最小值</div>
<div class="key">平均值</div>
</div>
<div class="math-content" v-for="(item,index) in calc.math">
<div :style="{color:color[index]}">{{ item.key }}</div>
<div>{{ item.value.max }}</div>
<div>{{ item.value.min }}</div>
<div>{{ item.value.avg }}</div>
</div>
</div>
</div>
</template>
<script setup lang='ts'>
import { ref, onMounted, onUpdated, getCurrentInstance, watch } from "vue"
const prop = defineProps<{
calc: {
name: string,
math: {
key: string,
value: {
max: number,
min: number,
avg: number,
data: any[]
}
}[],
data: any
}
}>()
const { proxy } = getCurrentInstance() as any
const chart = ref()
let myChart = null
let data = prop.calc.data
let color = ['#4281E5','#78F7AE','#FF6E40']
function init() {
myChart = proxy.$echarts.init(chart.value, 'dark');
const option = {
title: {
text: prop.calc.name,
top: "5%",
left: "5%"
},
color: color,
tooltip: {
trigger: 'axis',
},
grid: {
top: "15%",
left: "5%",
right: "5%",
bottom: "5%",
containLabel: true,
},
xAxis: {
type: 'time',
splitLine: {
show: false
}
},
yAxis: {
type: 'value',
},
series: data
};
myChart.setOption(option);
}
watch(() => prop.calc.data, (newVal) => {
data = newVal
myChart.setOption({
series: data
})
})
onMounted(() => {
init()
})
</script>
<style scoped>
.container {
width: 100%;
height: 100%;
box-sizing: border-box;
font-size: 16px;
color: #fff;
box-shadow: rgb(2, 106, 181) 0px 8px 8px;
}
.container:hover {
box-shadow: rgb(2, 106, 181) 0px 8px 16px;
}
.chart {
height: calc(100% - 90px);
width: 100%;
}
.math-box {
height: 90px;
width: 100%;
display: flex;
justify-content: end;
align-items: center;
}
.math-content {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
}
.key {
color: #ff6e40;
}
</style>

View File

@ -0,0 +1,225 @@
<template>
<border13>
<div class="container">
<div class="echartbox" ref="dust">
</div>
</div>
</border13>
</template>
<script setup lang='ts'>
import { getCurrentInstance, markRaw, onMounted, onUnmounted, reactive, ref, watch,computed } from "vue";
import { useSocketStore } from "@/store/moduleSocketMicEnvironment";
import border13 from '@/components/border/Border13.vue'
import { number } from "echarts/core";
const { proxy } = getCurrentInstance() as any;
const store = useSocketStore();
let index = 0;
let dust = ref();
let chart = ref(null)
const props = defineProps({
pm10limit:{
type:Number,
default:150
},
pm25limit:{
type:Number,
default:75
}
})
const borderColor = ["#E43961","#E43961"]
function init() {
if (!chart.value) {
chart.value = proxy.$echarts.init(dust.value, 'dark');
}
let option = {
title: {
text: store.pm.name,
show: true,
textStyle: {
color: "#fff",
fontSize: 18,
},
top: '2%'
},
grid: {
//
top: "0px",
left: "0px",
right: "0px",
bottom: "0px",
},
series: [
{
type: "gauge",
center: ["50%", "90%"],
startAngle: 190,
endAngle: -10,
radius: "50%",
min: 0,
max: 100,
splitNumber: 10,
pointer: {
icon: "path://M12.8,0.7l12,40.1H0.7L12.8,0.7z",
length: "12%",
width: 10,
offsetCenter: [0, "-40%"],
itemStyle: {
color: "inherit",
},
},
axisLine: {
lineStyle: {
width: 8,
color: [
[0.35, "#7CFFB2"],
[0.75, "#FDDD60"],
[1, "#FF6E76"],
],
},
},
axisTick: {
distance: 0,
splitNumber: 5,
lineStyle: {
width: 2,
color: "#999",
},
},
splitLine: {
distance: 5,
length: 8,
lineStyle: {
width: 3,
color: "#999",
},
},
axisLabel: {
distance: 12,
color: "#999",
fontSize: 10,
},
anchor: {
show: false,
},
detail: {
valueAnimation: true,
width: "60%",
lineHeight: 20,
borderRadius: 8,
offsetCenter: [0, "20%"],
fontSize: 15,
fontWeight: "bolder",
formatter: "{value} μg/m3",
color: "inherit",
},
title: {
// show: false,
offsetCenter: [0, "-20%"],
},
data: [
{
value: store.pm.pm25,
name: "PM2.5",
},
],
},
{
type: "gauge",
center: ["50%", "55%"],
startAngle: 200,
endAngle: -20,
min: 0,
max: 200,
axisLine: {
lineStyle: {
width: 10,
color: [
[0.35, "#7CFFB2"],
[0.75, "#FDDD60"],
[1, "#FF6E76"],
],
},
},
pointer: {
itemStyle: {
color: "inherit",
},
},
axisTick: {
distance: -10,
length: 6,
lineStyle: {
color: "#fff",
width: 2,
},
},
splitLine: {
distance: -10,
length: 10,
lineStyle: {
color: "#fff",
width: 4,
},
},
axisLabel: {
color: "inherit",
distance: 20,
fontSize: 10,
},
detail: {
valueAnimation: true,
offsetCenter: [0, "20%"],
fontSize: 20,
formatter: "{value} μg/m3",
color: "inherit",
},
title: {
offsetCenter: [0, "-50%"],
},
data: [
{
value: store.pm.pm10,
name: "PM10",
},
],
},
],
};
chart.value.setOption(option);
}
watch(
() => store.pm,
(newData) => {
init()
},
{ deep: true }
);
onMounted(() => {
init();
});
onUnmounted(() => {
})
</script>
<style scoped>
.container {
width: 100%;
height: 100%;
}
.echartbox {
width: 100%;
height: 100%;
}
.icon-red {
color: #e43961;
animation: redstart 2s infinite;
font-size: 14px;
/* position: relative; */
/* top: -15px; */
}
</style>

View File

@ -0,0 +1,199 @@
<!--
* @FilePath: \gitscreenFront\src\views\PaintShopView\components\verticalNum.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-13 08:22:35
* @Description:
*
* 版权信息 : 2023 by ${再登软件}, All Rights Reserved.
-->
<template>
<div ref="numBox1" :style="{ height: '100%', width: '100%' }">
<border6 ref="refborder3">
<template v-slot>
<div class="box" ref="classBox1">
<h2>{{ props.title }}</h2>
<h5 v-if="props.unit">{{ `${t('messages.NormalValue')}0-${props.quota}${props.unit}` }}</h5>
<h5 v-else>&nbsp; </h5>
<i :class="['iconfont', 'iconbig-size', icon, iconcolor]"></i>
<p class="unit" v-if="props.unit && item.status">
<p class="num">{{ item.val }}&nbsp;</p>
<span>{{ props.unit }}</span>
</p>
<p class="unit" v-else>
<p class="num">&nbsp;</p>
<span>&nbsp;</span>
</p>
</div>
</template>
</border6>
</div>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref, watch, computed, onUnmounted } from "vue";
import border6 from "@/components/borderBox/border6.vue";
import { useI18n } from 'vue-i18n'
let { t } = useI18n();
type itemType = {
'id': string;
"name": string;
"val": string;
"type": string;
"status": boolean };
let props = defineProps<{
title: string;
item:itemType;
unit:string;
quota:number | null;
iconname:string;
}>();
let i = ref(0)
let icon = computed(() => {
return props.iconname
});
let iconcolor = computed(() => {
//
if (props.item) {
return props.item.status ? +props.item.val > +props.quota ? "icon-red" : "icon-blue" : "icon-grey";
} else {
return "icon-grey"
}
});
let refborder3 = ref();
let numBox1 = ref();
const classBox1 = ref()
onMounted(() => {
});
onUnmounted(() => {
})
</script>
<style scoped>
@import "@/assets/css/iconfont.css";
.box {
height: 50%;
width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
}
.box>h5 {
font-size: 15px;
/* margin-bottom: 20px; */
margin-top: 20px;
}
/* .contentbox{
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
} */
h2 {
color: #fff;
}
p {
color: #fff;
}
.icon-red {
font-size: 100px;
color: #E43961;
animation: redstart 2s infinite;
/* position: relative; */
/* top: -15px; */
}
.icon-blue {
font-size: 100px;
color: #20AEC5;
/* position: relative; */
/* top: -15px; */
}
.icon-grey {
color: rgb(167, 166, 189);
font-size: 100px;
/* position: relative; */
/* top: -15px; */
}
.iconsmall-size {
font-size: 20px;
}
.num {
font-size: 16px;
}
.unit {
display: flex;
justify-content: center;
align-items: center;
vertical-align: top;
font-size: 16px;
height: 5;
width: 100px;
}
.box>h2 {
font-size: 20px;
position: absolute;
top: 20px;
left: 20px;
}
.icontip {
display: flex;
margin-top: -60px;
width: 100px;
flex-wrap: wrap;
align-items: center;
justify-content: center;
height: 60px;
}
.icontipBox li {
display: flex;
align-items: center;
justify-content: flex-start;
margin-bottom: 5px;
}
.icontipBox li p:nth-child(1) {
width: 40%;
text-align: left;
}
.icontipBox li p:nth-child(2) {
flex: 1;
}
@keyframes redstart {
0% {}
50% {
text-shadow: #fff 1px 0 10px;
}
100% {}
}
</style>

View File

@ -0,0 +1,334 @@
<template>
<div class="container">
<div class="header">
<div class="title">
<header2 ref="headerref" :width="'100%'" :height="'150px'" :title="t('messages.微工厂环境实时监测系统')"
:titleTip="titleTip" :typeFun="['time']" :alarmType="[]"></header2>
</div>
</div>
<div class="content" ref="Acontent">
<div class="top">
<div v-for="items in store.verticalArr" class="top-box-item">
<verticalNum :title="items.name" :iconname="items.iconname" :item="items.item" :unit="items.unit"
:quota="items.quota"></verticalNum>
</div>
<div class="top-box-item">
<pm :pm10limit="150" :pm25limit="75"></pm>
</div>
<div class="top-box-item">
<humidity></humidity>
</div>
</div>
<div class="bottom">
<lineChart v-for="(calc, index) in calcArr"
:style="{ width: width + 'px', height: height + 'px', 'min-width': 'calc(25% - 20px)' }" :calc="calc">
</lineChart>
</div>
</div>
</div>
</template>
<script setup lang='ts'>
import header2 from '@/components/headerBox/header2.vue'
import verticalNum from './components/verticalNum.vue'
import pm from './components/pm.vue';
import humidity from './components/humidity.vue';
import lineChart from './components/lineChart.vue';
import { getSensorByDeptId } from '@/http/MicrofactoryDev'
import { getCurrent24Trend } from '@/http/Trend/index'
import { onMounted, onUnmounted, reactive, ref } from "vue"
import { connectWebsocket, closeWebsocket } from "@/utils/websocket";
import { useSocketStore } from "@/store/moduleSocketMicEnvironment";
import { useI18n } from 'vue-i18n'
let { t } = useI18n();
const store = useSocketStore();
let titleTip = [
{
color: "#E43961",
name: t('messages.abnormal'),
},
{
color: "#20AEC5",
name: t('messages.NoAbnormal'),
},
{
color: "#A7A6BD",
name: t('messages.disconnection'),
},
];
const sensor_config: any = {
'Noise_Reg': { 'icon': 'icon-shengyin', 'unit': 'dB', 'quota': 80, 'name': '噪声监测传感器', 'type': 'noise' },
'Smoke_Reg': { 'icon': 'icon-yanwubaojingqi', 'unit': 'ppm', 'quota': 100, 'name': '烟雾监测传感器', 'type': 'smoke' },
'CH2O': { 'icon': 'icon-app_icons--', 'unit': 'mg/m³', 'quota': 0.08, 'name': '甲醛监测传感器', 'type': 'CH2O' },
'TVOC': { 'icon': 'icon-TVOC-Outlined', 'unit': 'mg/m³', 'quota': 0.5, 'name': 'TVOC监测传感器', 'type': 'TVOC' },
'Methane_Reg': { 'icon': 'icon-ranqi', 'unit': '', 'quota': 0, 'name': '燃气监测传感器', 'type': 'Gas' },
}
let width = ref(1500)
let height = ref(580)
let trendObj = {}
let sensor_arr = [];
const sensor_keys = Object.keys(sensor_config)
let noise_id = ''
let timer = null;
//
type calcType = {
name: string,
math: {
key: string,
value: {
max: number,
min: number,
avg: number,
data: any[]
}
}[],
data: any[]
}
let calcArr = ref<calcType[]>()
async function getSensorData() {
let res: any = await getSensorByDeptId({ ids: '20' })
if (res.code === 200) {
let data = res.data
let temp_vertical = []
let humiture = { "devId": "", "name": "温湿度", "temp": "", "humidity": "" }
let pm = { "devId": "", "name": "粉尘", "pm25": "", "pm10": "" }
data.forEach(element => {
if (sensor_keys.includes(element.type)) {
sensor_arr.push(element.id)
temp_vertical.push({
id: element.id,
name: sensor_config[element.type].name,
iconname: sensor_config[element.type].icon,
item: { "name": element.name, "val": element.data, "type": sensor_config[element.type].type, "status": JSON.parse(element.status) },
unit: sensor_config[element.type].unit,
quota: sensor_config[element.type].quota,
})
if (sensor_config[element.type].type == 'noise') {
noise_id = element.id
trendObj[element.id] = sensor_config[element.type].unit
}
if (sensor_config[element.type].type == 'CH2O') {
trendObj[element.id] = sensor_config[element.type].unit
}
} else {
if (element.type == 'HIGH_PM10_Reg') {
pm.devId = element.id
pm.pm10 = element.data
trendObj[element.id] = 'μg/m3'
}
if (element.type == 'HIGH_PM25_Reg') {
pm.devId = element.id
pm.pm25 = element.data
}
if (element.type == 'AirHumi_Reg') {
humiture.devId = element.id
humiture.humidity = element.data
trendObj[element.id] = '℃/%RH'
}
if (element.type == 'AirTemp_Reg') {
humiture.devId = element.id
humiture.temp = element.data
}
}
});
store.setVerticalArr(temp_vertical)
store.sethumiture(humiture)
store.setpm(pm)
get24Trend()
}
}
async function get24Trend() {
let trendIds = Object.keys(trendObj).toString()
let trend: any = await getCurrent24Trend(trendIds)
if (trend.code === 200) {
let tempData = {}
trend.data.forEach((item: any) => {
if (trendObj[item.id]) {
item.name = item.name + '(' + trendObj[item.id] + ')'
}
if (tempData.hasOwnProperty(item.id)) {
let seriesData: any = {
name: item.type,
type: 'line',
showSymbol: false,
data: item.date.map((key, value) => [key, item.value[value]]),
smooth: true,
}
tempData[item.id].data.push(seriesData)
tempData[item.id].math.push({
key: item.type,
value: {
max: item.max,
min: item.min,
avg: item.avg
}
})
} else {
tempData[item.id] = {
name: item.name,
data: [{
name: item.type,
type: 'line',
showSymbol: false,
data: item.date.map((key, value) => [key, item.value[value]]),
smooth: true,
}],
math: [{
key: item.type,
value: {
max: item.max,
min: item.min,
avg: item.avg
}
}]
}
}
})
let data: any = Object.values(tempData)
calcArr.value = data
width.value = 1900 / data.length - (data.length - 1) * 20;
}
}
function getWebsocket(val) {
try {
let data = JSON.parse(val);
//
if (data.type == "Gas") {
if (sensor_arr.includes(data.msg.devId)) {
store.changeVerticalArr({ devId: data.msg.devId, val: data.msg.methane.value, type: "Gas", status: true })
}
}
//TVOC
if (data.type == "TVOC_CH2O") {
if (sensor_arr.includes(data.msg.CH2O.devId)) {
store.changeVerticalArr({ devId: data.msg.CH2O.devId, val: data.msg.CH2O.value, type: "CH2O", status: true })
store.changeVerticalArr({ devId: data.msg.TVOC.devId, val: data.msg.TVOC.value, type: "TVOC", status: true })
}
}
//
if (data.type == "noise") {
data.msg.listData.forEach(item => {
if (item.devId == noise_id) {
store.changeVerticalArr({ devId: item.devId, val: item.value, type: "noise", status: item.status })
}
})
}
//
if (data.type == "smoke") {
if (sensor_arr.includes(data.msg.devId)) {
store.changeVerticalArr({ devId: data.msg.devId, val: data.msg.smoke.value, type: "smoke", status: true })
}
}
//湿
if (data.type == "humiture") {
data.msg.Humiture.forEach(item => {
if (item.devId == store.humiture.devId) {
store.changehumiture(item)
}
})
}
//
if (data.type == "dust") {
if (data.msg.devId == store.pm.devId) {
store.changePm(data.msg)
}
}
} catch (err) {
console.log(err, "报错了大哥", console.log(val) );
}
}
function errWebsocket(val) {
// console.log(val);
}
onMounted(() => {
getSensorData()
connectWebsocket(null, null, getWebsocket, errWebsocket);
timer = setInterval(() => {
get24Trend()
}, 1000 * 60 * 10)
})
onUnmounted(() => {
clearInterval(timer)
closeWebsocket()
})
</script>
<style scoped>
.container {
height: 1080px;
width: 1920px;
color: #20aec5;
background-color: #100c2a;
}
.title {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.title>h1 {
font-size: 30px;
position: absolute;
top: 10px;
}
.header {
position: relative;
}
.header p {
position: absolute;
right: 50px;
bottom: 20px;
font-size: 20px;
}
.content {
width: 100%;
--header: 150px;
height: calc(1080px - var(--header))
}
.top {
display: flex;
width: 100%;
height: 330px;
}
.top-box-item {
width: 14%;
height: 100%;
margin: 0 5px 10px 5px;
display: flex;
align-items: center;
justify-content: space-evenly;
}
.bottom {
width: 100%;
height: 600px;
display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
box-sizing: border-box;
padding: 5px;
}
</style>

View File

@ -170,7 +170,7 @@ async function getWaterFlowInfoFun() {
if (code == 200) {
allData.in = data.in
allData.out = data.out
allData.use = data.use
allData.use = data.use.toFixed(2)
allData.currentCount = data.currentCount
allData.xl = data.xl.toFixed(1)
allData.xy = data.xy.toFixed(1)

View File

@ -286,6 +286,12 @@ let routerList = [
title: '智能货架物联管理系统',
url: require("../assets/indexImg/intelligentShelves.png"),
},
{
id: 33,
path: "/MicEnvironment",
title: '微工厂环境实时监测系统',
url: require("../assets/indexImg/MicEnvironment.png"),
},
];
let lang = ref(getStoredLanguage() || '简体中文')
function changelang(val) {
@ -314,7 +320,7 @@ onUnmounted(() => { });
}
.itemlist {
height: 1030px;
height: 990px;
width: 1920px;
color: #20aec5;
background-color: #100c2a;