This commit is contained in:
hzz 2023-06-15 09:04:07 +08:00
commit 4a479185cf
96 changed files with 7530 additions and 853 deletions

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="">
<html lang="" class="dark">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">

View File

@ -45,4 +45,17 @@ nav a {
nav a.router-link-exact-active {
color: #42b983;
}
body {
/* --content:calc(100vh - var(--header)) */
overflow: hidden !important;
-ms-overflow-style: none;
/* IE + Edge */
scrollbar-width: none;
/* Firefox */
}
::-webkit-scrollbar {
display: none;
}
</style>

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 3879194 */
src: url('//at.alicdn.com/t/c/font_3879194_0vtcz1yxgvk.woff2?t=1683879014134') format('woff2'),
url('//at.alicdn.com/t/c/font_3879194_0vtcz1yxgvk.woff?t=1683879014134') format('woff'),
url('//at.alicdn.com/t/c/font_3879194_0vtcz1yxgvk.ttf?t=1683879014134') format('truetype');
src: url('//at.alicdn.com/t/c/font_3879194_xfchth53vyb.woff2?t=1686011466607') format('woff2'),
url('//at.alicdn.com/t/c/font_3879194_xfchth53vyb.woff?t=1686011466607') format('woff'),
url('//at.alicdn.com/t/c/font_3879194_xfchth53vyb.ttf?t=1686011466607') format('truetype');
}
.iconfont {
@ -13,6 +13,10 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-lishijilu:before {
content: "\eaf7";
}
.icon-zhongyingwen:before {
content: "\e607";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

@ -1,5 +1,5 @@
<!--
* @FilePath: \screenFront\src\components\assembly\RotationTable.vue
* @FilePath: \code\gitscreenFront\src\components\assembly\RotationTable.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-16 15:09:06
@ -38,7 +38,8 @@
v-model:visible="visible"
:content="tipcontent"
placement="top"
effect="dark"
effect="light"
popper-class="tooltip-class"
trigger="click"
virtual-triggering
:virtual-ref="triggerRef"
@ -171,4 +172,12 @@ h2 {
color: #fff;
font-size: 20px;
}
.el-popper{
color: #fff !important;
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -0,0 +1,284 @@
<!--
* @FilePath: \code\gitscreenFront\src\components\headerBox\dialog\headerDialog.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-06-06 09:23:12
* @Description:
*
* 版权信息 : 2023 by ${再登软件}, All Rights Reserved.
-->
<template>
<div>
<el-dialog title="历史报警记录" v-model="is_Show" ref="" destroy-on-close >
<div style="margin-bottom: 20px">
<el-row :gutter="20">
<el-col :span="15">
<span style="margin-right: 10px; font-size: 18px;">日期</span>
<el-date-picker
v-model="selectTime"
type="datetimerange"
:shortcuts="shortcuts"
range-separator="至"
format="YYYY/MM/DD HH:mm:ss"
start-placeholder="开始时间"
end-placeholder="结束时间"
size="large"
style="font-size: 18px;"
/>
</el-col>
<el-col :span="9">
<span style="margin-right: 10px; font-size: 18px;" >类型</span>
<el-select v-model="searchConfig.alarmType" clearable placeholder="请选择报警类型" style="font-size: 18px;" size="large">
<el-option
v-for="item in alarmTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="18"> </el-col>
<el-col :span="6">
<el-button type="primary" plain @click="searchpartData" size="large"
>搜索</el-button
>
<el-button type="primary" plain @click="searchpartReset" size="large"
>重置</el-button
>
</el-col>
</el-row>
</div>
<el-table
:data="tableData"
v-loading="dialogLoading"
size="large"
max-height="650px"
stripe
style="font-size: 18px;"
>
<el-table-column
type="index"
:index="(searchConfig.pageNum - 1) * searchConfig.pageSize + 1"
label="序号"
min-width="10px"
header-align="center"
align="center"
/>
<el-table-column
property="context"
label="报警详情"
header-align="center"
/>
</el-table>
<div class="pagination-class">
<el-pagination
v-model:current-page="searchConfig.pageNum"
v-model:page-size="searchConfig.pageSize"
:page-sizes="[5, 10, 50, 100]"
:small="small"
:disabled="disabled"
:background="background"
layout=" prev, pager, next, jumper,sizes"
:total="props.total"
size="large"
style="font-size: 18px;"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from "vue";
import { gettime } from "@/utils/time";
const props = defineProps({
tableData: {
type: Array,
default: () => [],
},
dialogTableVisible: {
type: Boolean,
default: false,
},
dialogLoading: {
type: Boolean,
default: true,
},
type: {
type: String,
default: "",
},
total: {
type: Number,
default: 0,
},
});
//
const searchConfig = reactive({
alarmType:'',
type: props.type,
startTime: "",
endTime: "",
pageSize: 10,
pageNum: 1,
});
const selectTime = ref("");
let small = ref(false);
let disabled = ref(false);
let background = ref(false);
//
const alarmTypeOptions = [
{
value: 'pm25',
label: '粉尘pm2.5超标报警',
},
{
value: 'pm10',
label: '粉尘pm10超标报警',
},
{
value: 'flame',
label: '明火报警',
},
{
value: 'TVOC',
label: 'tvoc报警',
},
{
value: 'CH2O',
label: 'CH2O甲醛报警',
},
{
value: 'smoke',
label: '烟雾报警',
},
{
value: 'methane',
label: '燃气报警',
},
{
value: 'pressure',
label: '管道压力报警',
},
{
value: 'noise',
label: '噪音报警',
},
{
value: 'huim',
label: '湿度报警',
},
{
value: 'temp',
label: '温度报警',
},
{
value: 'offline',
label: '离线提醒',
},
]
const emits = defineEmits(["update:dialogTableVisible", "getDialogdatafun"]);
const is_Show = computed({
get: () => props.dialogTableVisible,
set: (val) => {
emits("update:dialogTableVisible", val);
},
});
computed({
get: () => props.type,
set: (val) => {
searchConfig.type = val;
},
});
watch(()=>props.type,
(newVal, oldVal)=>{
searchConfig.type=newVal
}, { immediate: true, deep: true })
watch(
() => selectTime,
(newVal, oldVal) => {
//
if (newVal.value) {
searchConfig.startTime = gettime(newVal.value[0], 2);
searchConfig.endTime = gettime(newVal.value[1], 2);
} else {
searchConfig.startTime = null;
searchConfig.endTime = null;
}
},
{ immediate: true, deep: true }
);
const handleSizeChange = (val: number) => {
searchConfig.pageSize = val;
emits("getDialogdatafun", searchConfig);
};
const handleCurrentChange = (val: number) => {
searchConfig.pageNum = val;
emits("getDialogdatafun", searchConfig);
};
const shortcuts = [
{
text: "最近一周",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
return [start, end];
},
},
{
text: "最近一个月",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
return [start, end];
},
},
{
text: "最近三个月",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
return [start, end];
},
},
];
//
function searchpartData() {
emits("getDialogdatafun", searchConfig);
}
//
function searchpartReset(){
searchConfig.alarmType=''
selectTime.value=''
//startTimeendTime
searchConfig.startTime = null;
searchConfig.endTime = null;
emits("getDialogdatafun", searchConfig);
}
onMounted(() => {});
</script>
<style scoped>
.pagination-class {
margin-top: 20px;
}
:deep(.el-dialog__title){
font-size: 25px ;
}
.el-row {
margin-bottom: 20px;
}
</style>

View File

@ -1,5 +1,5 @@
<!--
* @FilePath: \screenFront\src\components\headerBox\header2.vue
* @FilePath: \code\gitscreenFront\src\components\headerBox\header2.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-16 11:04:06
@ -10,21 +10,44 @@
<template>
<div class="header2" :style="{ width: props.width, height: props.height }">
<h1 :class="langJudge()=='简体中文'?'zh-title':'en-title'">{{ props.title }}</h1>
<h1 :class="langJudge() == '简体中文' ? 'zh-title' : 'en-title'">
{{ props.title }}
</h1>
<div class="slot">
<div class="tip" style="display: flex">
<span class="tipspan" v-for="item in props.titleTip">
<div class="colortip" :style="{ backgroundColor: item.color }"></div>
<span class="tipstring">{{item.name}}</span></span>
<span class="tipstring">{{ item.name }}</span></span
>
<slot></slot>
</div>
<div v-show="typeObj.comback" class="comeBack" @click="comeBackFun">
<i class="iconfont icon-back"></i>
</div>
<div v-show="typeObj.AbnormalData" ref="AbnormalDataRef" class="AbnormalData" @click="AbnormalDataFun" >
<dv-scroll-board class="dv-scroll-boardclass" ref="tipList" :config="listdata" style="width:30rem;height:50px" />
<el-badge :value="AbnormalNum" class="i-badge" :hidden="AbnormalNum==0">
<i :class="AbnormalNum>0?'iconfont icon-baojingxinxi Abnormal-icon-yellow':'iconfont icon-baojingxinxi'"></i>
<div
v-show="typeObj.AbnormalData"
ref="AbnormalDataRef"
class="AbnormalData"
@click="AbnormalDataFun"
>
<dv-scroll-board
class="dv-scroll-boardclass"
ref="tipList"
:config="listdata"
style="width: 30rem; height: 50px"
/>
<el-badge
:value="AbnormalNum"
class="i-badge"
:hidden="AbnormalNum == 0"
>
<i
:class="
AbnormalNum > 0
? 'iconfont icon-baojingxinxi Abnormal-icon-yellow'
: 'iconfont icon-baojingxinxi'
"
></i>
</el-badge>
</div>
<div v-show="typeObj.time" class="time">
@ -35,85 +58,121 @@
ref="popoverRef"
:virtual-ref="AbnormalDataRef"
:visible="Abnormalpopovervisible"
effect="dark"
trigger="click"
width="600px"
placement="bottom-start"
virtual-triggering
>
<ul class="popoverBOX" ref="popoverliDom" v-click-outside="noClickAbnormalDataFun">
<li v-for="item in powerlist" :key="item.deviceId" >{{item.context}}</li>
<ul
class="popoverBOX"
ref="popoverliDom"
v-click-outside="noClickAbnormalDataFun"
>
<li class="popoverHeader">
<!-- <span><i class="iconfont icon-lishijilu lishijilu"></i>历史记录</span> -->
<el-button type="primary" :icon="Clock" text @click="showDialog"
>历史记录</el-button
>
</li>
<li v-for="item in powerlist" :key="item.deviceId">
{{ item.context }}
</li>
<li class="lookdown" v-show="onloadlist">
<span @click="clickNextPageAlarmList">{{ t('messages.加载更多') }}</span>
<span @click="clickNextPageAlarmList">{{
t("messages.加载更多")
}}</span>
</li>
</ul>
</el-popover>
<HDialog
:tableData="dialogdata"
v-model:dialogTableVisible="dialogTableVisible"
:dialogLoading="dialogLoading"
@getDialogdatafun="getDialogdatafun"
:type="AbnormalType.type"
:total="dialogtotal"
></HDialog>
</div>
</template>
<script setup lang="ts">
import useNowTime from "@/hook/nowTime";
import { ClickOutside as vClickOutside } from 'element-plus'
import { ClickOutside as vClickOutside } from "element-plus";
import { useRoute, useRouter } from "vue-router";
import { devListType } from "@/type/InPlantProducts";
import { getAlarmListData} from "@/http/index";
import { onMounted, onUnmounted, reactive, ref ,unref, watch,computed } from "vue";
import { getAlarmListData,getAlarmListHistoryData } from "@/http/index";
import {
onMounted,
onUnmounted,
reactive,
ref,
unref,
watch,
computed,
} from "vue";
import { connectWebsocket, closeWebsocket } from "@/utils/websocket";
import { useHeaderStore } from "@/store/components/header";
import { getStoredLanguage } from "@/utils/languageStorage"
import { useI18n } from 'vue-i18n'
import { getStoredLanguage } from "@/utils/languageStorage";
import { useI18n } from "vue-i18n";
import { Clock } from "@element-plus/icons-vue";
import HDialog from "./dialog/headerDialog.vue";
let { t } = useI18n();
const storeheader = useHeaderStore();
let { timeHtml } = useNowTime();
const router=useRouter()
const router = useRouter();
//
let numkey=ref(0)
let popoverkey=ref(0)
let numkey = ref(0);
let popoverkey = ref(0);
//dom
let AbnormalDataRef=ref()
let popoverRef=ref()
let tipList=ref()
let popoverliDom=ref()
let AbnormalDataRef = ref();
let popoverRef = ref();
let tipList = ref();
let popoverliDom = ref();
//
let Abnormalpopovervisible=ref(false)
let AbnormalpopovervisibleCtrl=ref(false)//
let Abnormalpopovervisible = ref(false);
let AbnormalpopovervisibleCtrl = ref(false); //
//dialog
let dialogdata = ref([]);
let dialogTableVisible = ref(false);
let dialogLoading = ref(true);
let dialogtotal=ref(0)
let onloadlist = computed(() => {
return storeheader.num>powerlist.length
})
const listdata = reactive<devListType>({data: [],
return storeheader.num > powerlist.length;
});
const listdata = reactive<devListType>({
data: [],
rowNum: 2,
oddRowBGC:'#100C2A',
evenRowBGC:'#100C2A',
oddRowBGC: "#100C2A",
evenRowBGC: "#100C2A",
hoverPause: true,
carousel:'page',
carousel: "page",
waitTime: 3000,
align:['left']});
let AbnormalNum=ref(0)
align: ["left"],
});
let AbnormalNum = ref(0);
//
let powerlist=reactive([])
let powerlist = reactive([]);
let props = defineProps<{
width: string;
height: string;
title: string;
titleTip: any;
typeFun: any[];
alarmType:any[]
alarmType: any[];
}>();
const typeObj = reactive({
comback: false,
AbnormalData: false,
time: false,
})
});
const AbnormalType = reactive({
pageSize: 5,
pageNum: 1,
type:''
})
type: "",
});
let comeBackFun = () => {
router.go(-1)
}
router.go(-1);
};
const changeAbnormalData = (val: any) => {
tipList.value.updateRows(val.data, { ...val });
};
@ -122,51 +181,73 @@ let AbnormalDataFun=()=>{
//Abnormalpopovervisibled
//
if (Abnormalpopovervisible.value) {
Abnormalpopovervisible.value=false
Abnormalpopovervisible.value = false;
} else {
//
if (AbnormalpopovervisibleCtrl.value) {
Abnormalpopovervisible.value=false
Abnormalpopovervisible.value = false;
} else {
Abnormalpopovervisible.value=true
Abnormalpopovervisible.value = true;
}
}
}
};
let noClickAbnormalDataFun = () => {
//AbnormalDataFun
// ctrltruefalse
if (Abnormalpopovervisible.value) {
AbnormalpopovervisibleCtrl.value=true
AbnormalpopovervisibleCtrl.value = true;
} else {
AbnormalpopovervisibleCtrl.value=false
AbnormalpopovervisibleCtrl.value = false;
}
Abnormalpopovervisible.value?Abnormalpopovervisible.value=false:''
}
Abnormalpopovervisible.value ? (Abnormalpopovervisible.value = false) : "";
};
function typeStatus() {
if (props.typeFun.length == 0) {
return
return;
}
props.typeFun.forEach(res=>{
props.typeFun.forEach((res) => {
for (let key in typeObj) {
if (res == key) {
typeObj[key]=true
typeObj[key] = true;
}
}
})
});
}
function langJudge() {
let lang = getStoredLanguage()
let lang = getStoredLanguage();
if (lang) {
return lang
return lang;
} else {
return "简体中文"
return "简体中文";
}
}
function showDialog() {
if (dialogTableVisible.value == false) {
getDialogdatafun({
type: AbnormalType.type,
pageSize: 10,
pageNum: 1,
});
}
Abnormalpopovervisible.value = false;
dialogTableVisible.value = true;
}
async function getDialogdatafun(config) {
dialogLoading.value = true;
let result: any = await getAlarmListHistoryData(config);
if (result.code == 200) {
dialogtotal.value=result.total
dialogdata.value=result.rows
dialogLoading.value = false;
}else{
setTimeout(() => {
if(dialogLoading.value){
dialogLoading.value = false;
}
}, 0);
}
}
//
@ -174,10 +255,10 @@ watch(
() => typeObj,
(newVal, oldVal) => {
if (newVal.AbnormalData) {
AbnormalType.type=props.alarmType.join(',')
getAlarmListDatafun()
AbnormalType.type = props.alarmType.join(",");
getAlarmListDatafun();
// connectWebsocket(null, null, getWebsocket, errWebsocket);
setAlarmscrollBoardList()
setAlarmscrollBoardList();
}
},
{ deep: true, flush: "post" }
@ -188,27 +269,24 @@ async function getAlarmListDatafun(){
if (result.code == 200) {
storeheader.setDataList(result);
}
}
//
function clickNextPageAlarmList() {
// if(storeheader.num<=powerlist.length){
// onloadlist.value=false
// return
// }
AbnormalType.pageNum++
getAlarmListDatafun()
AbnormalType.pageNum++;
getAlarmListDatafun();
}
//
watch(
() => storeheader.AlarmpopoverList,
(newVal, oldVal) => {
newVal.forEach(res=>{
powerlist.push(res)
})
newVal.forEach((res) => {
powerlist.push(res);
});
},
{ deep: true, flush: "post" }
);
@ -226,96 +304,99 @@ watch(
},
{ deep: true, flush: "post" }
);
let AlarmscrollTime = null
let AlarmscrollTime = null;
//15
function setAlarmscrollBoardList() {
let start=0
let end=4
let start = 0;
let end = 4;
let i = 0;
setTimeout(() => {
storeheader.AlarmscrollBoardList.slice(0, 5).forEach(element => {
storeheader.AlarmscrollBoardList.slice(0, 5).forEach((element) => {
let e = element.context.split("");
listdata.data.push(...[[e[0]], [e[1]]])
i++
listdata.data.push(...[[e[0]], [e[1]]]);
i++;
});
end = end + 5
start = i >= 5 ? 5 : storeheader.AlarmscrollBoardList.length - 1
start<=0?start=0:''
}, 1000)
end = end + 5;
start = i >= 5 ? 5 : storeheader.AlarmscrollBoardList.length - 1;
start <= 0 ? (start = 0) : "";
}, 1000);
AlarmscrollTime = setInterval(() => {
if (i == 0) {
listdata.data=[]
listdata.data = [];
}
i=0
i = 0;
if (storeheader.AlarmscrollBoardList.length == 0) {
return
return;
}
if (storeheader.AlarmscrollBoardList.length - 1 < end) {
end=storeheader.AlarmscrollBoardList.length-1
end = storeheader.AlarmscrollBoardList.length - 1;
}
for (start; start <= end; start++) {
// console.log(storeheader.AlarmscrollBoardList[start],start,end);
// console.log(storeheader.AlarmscrollBoardList.length-1);
let listcontent = storeheader.AlarmscrollBoardList[start]?.context.split('')
let listcontent =
storeheader.AlarmscrollBoardList[start]?.context.split("");
listdata.data.push(...[[listcontent[0]],[listcontent[1]]])
listdata.data.push(...[[listcontent[0]], [listcontent[1]]]);
}
changeAbnormalData(listdata)
numkey.value++
end=end+5
changeAbnormalData(listdata);
numkey.value++;
end = end + 5;
//
if (start == storeheader.AlarmscrollBoardList.length - 1) {
// console.log('2');
start=storeheader.AlarmscrollBoardList.length-1
end=storeheader.AlarmscrollBoardList.length-1
start = storeheader.AlarmscrollBoardList.length - 1;
end = storeheader.AlarmscrollBoardList.length - 1;
}
//5
if(end>storeheader.AlarmscrollBoardList.length-1&&start<=storeheader.AlarmscrollBoardList.length-1){
if (
end > storeheader.AlarmscrollBoardList.length - 1 &&
start <= storeheader.AlarmscrollBoardList.length - 1
) {
// console.log('3');
end=storeheader.AlarmscrollBoardList.length-1
end = storeheader.AlarmscrollBoardList.length - 1;
}
//
if(start>storeheader.AlarmscrollBoardList.length-1&&end>storeheader.AlarmscrollBoardList.length-1){
if (
start > storeheader.AlarmscrollBoardList.length - 1 &&
end > storeheader.AlarmscrollBoardList.length - 1
) {
// console.log('4',start,end,storeheader.AlarmscrollBoardList.length-1,storeheader.AlarmscrollBoardList);
start=0
end=4
start = 0;
end = 4;
}
},15000)
}, 15000);
}
//
watch(
() => storeheader.num,
(newVal, oldVal) => {
AbnormalNum.value=newVal
numkey.value++
AbnormalNum.value = newVal;
numkey.value++;
},
{ deep: true, flush: "post" }
);
function HeadergetWebsocket(val) {
let data = null
let data = null;
try {
data = JSON.parse(val);
} catch (e) {
console.log(e);
return
return;
}
if (props.alarmType.some(e=>{return e==data.type})) {
if (
props.alarmType.some((e) => {
return e == data.type;
})
) {
// console.log(props.alarmType);
// console.log(props.alarmType.some(e=>{return e==data.type}));
storeheader.changeDataList(data)
storeheader.changeDataList(data);
}
}
function HeadererrWebsocket(val) {
@ -323,19 +404,17 @@ function HeadererrWebsocket(val) {
}
onMounted(() => {
//
typeStatus()
})
typeStatus();
});
onUnmounted(() => {
// closeWebsocket();
storeheader.resetData()
AlarmscrollTime?clearInterval(AlarmscrollTime):''
})
storeheader.resetData();
AlarmscrollTime ? clearInterval(AlarmscrollTime) : "";
});
defineExpose({
changeAbnormalData,
HeadergetWebsocket,
HeadererrWebsocket
HeadererrWebsocket,
});
</script>
@ -359,10 +438,8 @@ defineExpose({
width: 100%;
}
h1 {
position: absolute;
top: 10px;
}
.zh-title {
margin-top: 6px;
@ -376,7 +453,6 @@ h1 {
align-items: center;
overflow: hidden;
/* line-height: 80px; */
}
/* .header2 p {
position: absolute;
@ -422,6 +498,7 @@ h1 {
left: 1.5rem;
font-size: 3rem;
color: #fff;
cursor: pointer;
}
.comeBack > i {
font-size: 3rem;
@ -457,7 +534,7 @@ padding: 10px 0 10px 0;
display: flex;
align-items: center;
justify-content: center;
color: #1C78C2;
color: #1c78c2;
}
.lookdown:hover {
cursor: pointer;
@ -492,7 +569,26 @@ padding: 10px 0 10px 0;
background: #14274b !important;
}
.Abnormal-icon-yellow {
color: #DDB14F;
color: #ddb14f;
}
.lishijilu {
font-size: 2rem;
color: #fff;
}
.popoverHeader {
padding: 0 !important;
display: flex;
justify-content: flex-end;
align-items: center;
line-height: 1.5rem;
}
.popoverHeader span {
display: flex;
justify-content: center;
align-items: center;
padding: 5px;
/* border-radius: 50px;
background: linear-gradient(315deg, #404040, #4c4c4c); */
/* box-shadow: -20px -20px 60px #3c3c3c, 20px 20px 60px #525252; */
}
</style>

View File

@ -29,3 +29,15 @@ export function gatcountsOfMachineryFactoryInStatusTime(){
export function gatdeviceStatusInfoMF(data:any){
return get('/device/deviceStatusInfoMF',data)
}
/**newIndex */
//设备列表
export function reqDeviceTotelListMF(){
return get('/device/deviceTotelListMF')
}
//状态数量
export function reqDeviceTotelStatusMF() {
return get('/device/deviceTotelStatusMF')
}

15
src/http/Trend/index.ts Normal file
View File

@ -0,0 +1,15 @@
/*
* @FilePath: \wwwd:\code\screenFront\src\http\realtimeSecurity\index.ts
* @Author:
* @文件版本: V1.0.0
* @Date: 2023-02-14 08:45:45
* @Description:
*
* 版权信息 : 2023 by ${}, All Rights Reserved.
*/
import {get,post} from "@/utils/http"
//气压
export function getCurrent24Trend(id:string){
return get('/dataTrend/getCurrent24Trend',{id})
}

View File

@ -1,5 +1,5 @@
/*
* @FilePath: \wwwd:\code\screenFront\src\http\index.ts
* @FilePath: \code\gitscreenFront\src\http\index.ts
* @Author:
* @文件版本: V1.0.0
* @Date: 2023-03-14 11:14:41
@ -13,3 +13,7 @@ import {get,post} from "@/utils/http"
export function getAlarmListData(data:any){
return get('/alarm/getAlarmList',data)
}
//报警历史数据查询
export function getAlarmListHistoryData(data:any){
return get('/alarm/getAlarmListHistory',data)
}

View File

@ -271,5 +271,7 @@ export default {
'料场':'Raw Material Area',
'危废暂存间':'dangerous waste temporary storage room',
'历史数据':'Historical Data',
'环境 实时监测系统':'环境 实时监测系统',
'传感器监测走势图':'传感器监测走势图',
}
}

View File

@ -271,5 +271,7 @@ export default {
'料场':'料场',
'危废暂存间':'危废暂存间',
'历史数据':'历史数据',
'环境 实时监测系统':'环境 实时监测系统',
'传感器监测走势图':'传感器监测走势图',
}
}

View File

@ -1,5 +1,5 @@
/*
* @FilePath: \screenFront\src\main.ts
* @FilePath: \code\gitscreenFront\src\main.ts
* @Author:
* @文件版本: V1.0.0
* @Date: 2023-01-29 15:16:36
@ -11,7 +11,9 @@ import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import 'element-plus/theme-chalk/dark/css-vars.css'
import 'dayjs/locale/zh-cn'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
// import echarts from '@/utils/echarts.js'
import echarts from '@/utils/echarts'
import {createPinia} from 'pinia'
@ -26,4 +28,4 @@ const store = createPinia()
app.config.globalProperties.$echarts = echarts;//vue3的挂载方式
app.use(store)
app.use(i18n)
app.use(router).use(ElementPlus).use(dataV).mount('#app')
app.use(router).use(ElementPlus, {locale: zhCn,}).use(dataV).mount('#app')

View File

@ -155,11 +155,22 @@ const routes: Array<RouteRecordRaw> = [
component: () =>
import("../views/generalEnvironmentjixiefenchang/index.vue"),
},
{
path: "/generalEnvironmentMechanical",
name: "generalEnvironmentMechanical",
component: () =>
import("../views/generalEnvironmentMechanical/index.vue"),
},
{
path: "/FactoryView",
name: "FactoryView",
component: () => import("../views/FactoryView/index.vue"),
},
{
path: "/FactoryViewTopo",
name: "FactoryViewTopo",
component: () => import("../views/FactoryViewTopo/index.vue"),
},
{
path: "/FactoryView/:type",
name: "FactoryViewEdit",
@ -237,6 +248,17 @@ const routes: Array<RouteRecordRaw> = [
component: () => import("../views/Waterhouse/index.vue"),
},
{
path: "/TrendChart",
name: "TrendChart",
component: () => import("../views/TrendChart/index.vue"),
},
//理论二级
{
path: "/Mechanics/:id",

View File

@ -1,5 +1,5 @@
/*
* @FilePath: \wwwd:\code\screenFront\src\store\module\Mechanics.ts
* @FilePath: \code\gitscreenFront\src\store\module\Mechanics.ts
* @Author:
* @文件版本: V1.0.0
* @Date: 2023-02-06 15:58:13
@ -102,7 +102,11 @@ export const useMechanicsStore = defineStore(Names.Mechanics, {
//需要使用return将数据抛出
//getters内可相互使用计算结果
//使用时可直接放入标签内<div>Index.方法()</div>
getters: {},
getters: {
getmechanicsData(state){
return state.mechanicsData
}
},
//methods 可同步/异步提交state
//actions内获取state数据使用this
// 使用方式

View File

@ -172,17 +172,36 @@ export const useSocketStore = defineStore(Names.socket, {
* @函数备注:
*/
changePM(val) {
if (val.enName == 'welding') {
let arr = ['083e3900-3435-11ed-a7e1-fd42bca6c8c6', 'bcbfb530-88b2-11ed-a926-570995ad0254', '01336fd0-1fa0-11ed-9223-7db1174970a8']
// if (arr.indexOf(val.devId) > -1) {
// console.log(val,'这三个设备');
// }
if (val.devId == '083e3900-3435-11ed-a7e1-fd42bca6c8c6') {
this.pm.welding.two = val.pm25
this.pm.welding.ten = val.pm10
} else if (val.enName == 'stuff') {
this.pm.stuff.two = val.pm25
this.pm.stuff.ten = val.pm10
} else if (val.enName == 'ornaments') {
} else if (val.devId == 'bcbfb530-88b2-11ed-a926-570995ad0254') {
this.pm.ornaments.two = val.pm25
this.pm.ornaments.ten = val.pm10
} else if (val.devId == '01336fd0-1fa0-11ed-9223-7db1174970a8') {
this.pm.stuff.two = val.pm25
this.pm.stuff.ten = val.pm10
}
// if (val.enName == 'welding') {
// this.pm.welding.two = val.pm25
// this.pm.welding.ten = val.pm10
// } else if (val.enName == 'stuff') {
// this.pm.stuff.two = val.pm25
// this.pm.stuff.ten = val.pm10
// } else if (val.enName == 'ornaments') {
// this.pm.ornaments.two = val.pm25
// this.pm.ornaments.ten = val.pm10
// }
},
/**
* @函数功能:
@ -322,7 +341,7 @@ export const useSocketStore = defineStore(Names.socket, {
let pIndex = this.newVerticalNum.findIndex(item => item.type == val.type)
let cIndex = null
if (pIndex != -1) {
cIndex = this.newVerticalNum[pIndex].value.findIndex(item => item.name == val.data.name)
cIndex = this.newVerticalNum[pIndex].value.findIndex(item => item.devId == val.data.devId)
}
if (cIndex != -1) {
if (val.data.val > this.newVerticalNum[pIndex].limit) {

View File

@ -0,0 +1,239 @@
/*
* @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.socketMechanics, {
// 使用方式
// const Index= useIndexStore()
// 1、Index.{数据}++
// 2、Index.$patch({数据:??})
// 3、Index.$patch((state)=>{ state.数据=??})
// 4、通过action修改
state: () => {
return {
humiture: [
{ "devId": "c6f036c0-33fc-11ed-a7e1-fd42bca6c8c6", "name": "精饰车间", "temp": "33.4", "humidity": "30.9" },
{ "devId": "c651b930-3b15-11ed-b6af-15994988a6b3", "name": "精加车间", "temp": "26.1", "humidity": "47" },
{ "devId": "9c4be1e0-33fb-11ed-a7e1-fd42bca6c8c6", "name": "焊接车间", "temp": "29.3", "humidity": "37.6" },
{ "devId": "0e77f0b0-33fc-11ed-a7e1-fd42bca6c8c6", "name": "大件车间", "temp": "28.6", "humidity": "38.4" },
{ "devId": "91f6d000-33fc-11ed-a7e1-fd42bca6c8c6", "name": "机加车间", "temp": "29.9", "humidity": "36.2" }
],
// humiture:{Humiture:[],bottom:{humidity:null,temp:null,name:null},top:{humidity:null,temp:null,name:null}}, //温湿度
pm: [
{
"devId": "01336fd0-1fa0-11ed-9223-7db1174970a8",
"name": "大件车间中部粉尘",
"pm25": "45",
"pm10": "53"
},
{
"devId": "083e3900-3435-11ed-a7e1-fd42bca6c8c6",
"name": "焊接车间粉尘",
"pm25": "30",
"pm10": "36"
},
{
"devId": "270e1500-eee1-11ed-b2ee-2d727e0cafab",
"name": "精加车间粉尘",
"pm25": "71",
"pm10": "84"
},
{
"devId": "54058c30-eee3-11ed-b2ee-2d727e0cafab",
"name": "机加车间粉尘",
"pm25": "22",
"pm10": "26"
},
{
"devId": "76efb040-eee3-11ed-b2ee-2d727e0cafab",
"name": "大件车间东部粉尘",
"pm25": "53",
"pm10": "60"
},
{
"devId": "a6020310-eee3-11ed-b2ee-2d727e0cafab",
"name": "大件车间西部粉尘",
"pm25": "66",
"pm10": "75"
},
{
"devId": "bcbfb530-88b2-11ed-a926-570995ad0254",
"name": "精饰车间粉尘",
"pm25": "6",
"pm10": "7"
}
],
newVerticalNum: [
{
"type": "TVOC",
"icon": "icon-TVOC-Outlined",
"title": "TVOC检测",
"limit": "0.5",
"unit": "mg/m³",
"value": [
{
"name": "精饰车间TVOC/甲醛监测传感器",
"val": null,
"type": "TVOC_CH2O",
"field": "TVOC"
}
]
},
{
"type": "Smoke",
"icon": "icon-yanwubaojingqi",
"title": "烟雾检测",
"limit": "100",
"unit": null,
"value": [
{
"name": "精饰车间烟雾传感器",
"val": null,
"type": "Smoke",
"field": "Smoke_Reg"
}
]
},
{
"type": "Methane",
"icon": "icon-ranqi",
"title": "燃气检测",
"limit": "0",
"unit": null,
"value": [
{
"name": "精饰车间燃气监测",
"val": null,
"type": "Methane",
"field": "Methane_Reg"
},
{
"name": "食堂燃气监测",
"val": null,
"type": "Methane",
"field": "Methane_Reg"
},
{
"name": "锅炉房燃气监测",
"val": null,
"type": "Methane",
"field": "Methane_Reg"
}
]
},
{
"type": "CH2O",
"icon": "icon-app_icons--",
"title": "甲醛检测",
"limit": "0.08",
"unit": "mg/m³",
"value": [
{
"name": "精饰车间TVOC/甲醛监测传感器",
"val": null,
"type": "TVOC_CH2O",
"field": "CH2O"
}
]
},
{
"type": "FIRE",
"icon": "icon-weibiaoti1",
"title": "明火检测",
"limit": "0",
"unit": null,
"value": [
{
"name": "精饰车间火花传感器",
"val": null,
"type": "FIRE",
"field": "Fire_Reg"
}
]
}
]
}
},
//computed 修改一些值
//需要使用return将数据抛出
//getters内可相互使用计算结果
//使用时可直接放入标签内<div>Index.方法()</div>
getters: {
},
actions: {
//设置新的安全检测数据
setNewVerticalNum(val) {
this.newVerticalNum = val
},
//更新 新的安全检测数据
changeNewVerticalNum(val) {
//{"type":"Smoke","data":{"name":"精饰车间烟雾传感器","val":"100"}}
let pIndex = this.newVerticalNum.findIndex(item => item.type == val.type)
let cIndex = null
if (pIndex != -1) {
cIndex = this.newVerticalNum[pIndex].value.findIndex(item => item.devId == val.data.devId)
}
if (cIndex != -1) {
if (val.data.val > this.newVerticalNum[pIndex].limit) {
let now = new Date().getTime()
if (this.newVerticalNum[pIndex].value[cIndex].date == null) {
this.newVerticalNum[pIndex].value[cIndex].date = gettime()
this.newVerticalNum[pIndex].value[cIndex].time = now
}
let time = this.newVerticalNum[pIndex].value[cIndex].time
this.newVerticalNum[pIndex].value[cIndex].continuous = clacendTime(now, time)
} else {
this.newVerticalNum[pIndex].value[cIndex].date = null
this.newVerticalNum[pIndex].value[cIndex].time = null
}
this.newVerticalNum[pIndex].value[cIndex].val = val.data.val
this.newVerticalNum[pIndex].value[cIndex].status = true
}
},
/**
* @函数功能:
* @param {*} val 湿
* @出口参数:
* @函数备注:
*/
changeHumiture(val) {
// console.log(this.humiture.Humiture);
val.Humiture.forEach(res => {
this.humiture.forEach(ele => {
if (res.devId == ele.devId) {
ele.humidity = res.humidity
ele.temp = res.temp
}
})
})
},
/**
*
*/
changeDust(val) {
this.pm.forEach(res => {
if (res.devId == val.devId) {
res.pm25 = val.pm25
res.pm10 = val.pm10
}
})
}
}
})

View File

@ -172,15 +172,15 @@ export const useSocketStore = defineStore(Names.socketjixiefenchang,{
* @函数备注:
*/
changePM(val){
if(val.enName=='welding'){
if (val.devId == '083e3900-3435-11ed-a7e1-fd42bca6c8c6') {
this.pm.welding.two = val.pm25
this.pm.welding.ten = val.pm10
}else if(val.enName=='stuff'){
this.pm.stuff.two=val.pm25
this.pm.stuff.ten=val.pm10
}else if(val.enName=='ornaments'){
} else if (val.devId == 'bcbfb530-88b2-11ed-a926-570995ad0254') {
this.pm.ornaments.two = val.pm25
this.pm.ornaments.ten = val.pm10
} else if (val.devId == '01336fd0-1fa0-11ed-9223-7db1174970a8') {
this.pm.stuff.two = val.pm25
this.pm.stuff.ten = val.pm10
}
},
@ -324,7 +324,7 @@ export const useSocketStore = defineStore(Names.socketjixiefenchang,{
let pIndex = this.newVerticalNum.findIndex(item => item.type == val.type)
let cIndex = null
if (pIndex != -1) {
cIndex = this.newVerticalNum[pIndex].value.findIndex(item => item.name == val.data.name)
cIndex = this.newVerticalNum[pIndex].value.findIndex(item => item.devId == val.data.devId)
}
if (cIndex != -1) {
if (val.data.val>this.newVerticalNum[pIndex].limit) {
@ -343,6 +343,7 @@ export const useSocketStore = defineStore(Names.socketjixiefenchang,{
this.newVerticalNum[pIndex].value[cIndex].time = null
}
this.newVerticalNum[pIndex].value[cIndex].val = val.data.val
this.newVerticalNum[pIndex].value[cIndex].status = true
}
}
}

View File

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

View File

@ -1,5 +1,5 @@
/*
* @FilePath: \screenFront\src\utils\devSever.ts
* @FilePath: \gitscreenFront\src\utils\devSever.ts
* @Author:
* @文件版本: V1.0.0
* @Date: 2023-03-03 08:59:37

View File

@ -1,5 +1,5 @@
/*
* @FilePath: \daping\src\utils\time.ts
* @FilePath: \code\gitscreenFront\src\utils\time.ts
* @Author:
* @文件版本: V1.0.0
* @Date: 2023-02-07 13:43:31
@ -9,10 +9,10 @@
*/
import { getStoredLanguage } from "../utils/languageStorage";
export function gettime(data = null) {
export function gettime(data = null,type = 1) {
var time
if (data) {
time = new Date(data);
data instanceof Date? time=data : time = new Date(data);
} else {
time = new Date();
}
@ -38,7 +38,14 @@ export function gettime(data = null) {
if (minutes < 10) minutes = "0" + minutes;
if (seconds < 10) seconds = "0" + seconds;
if(type==1){
return year + "-" + month + "-" + dates + " " + hours + ':' + minutes + ':' + seconds + ' ' + arr[day];
}else if (type == 2){
return year + "-" + month + "-" + dates + " " + hours + ':' + minutes + ':' + seconds;
}else{
return year + "-" + month + "-" + dates + " " + hours + ':' + minutes + ':' + seconds + ' ' + arr[day];
}
}
export function clacendTime(endtime, nowtime) {
let newDate = Math.abs(endtime - nowtime)

View File

@ -1,5 +1,5 @@
/*
* @FilePath: \daping\src\utils\websocket.ts
* @FilePath: \gitscreenFront\src\utils\websocket.ts
* @Author:
* @文件版本: V1.0.0
* @Date: 2023-02-24 13:14:26
@ -58,7 +58,7 @@ export const closeWebsocket = () => {
if (wsObj) {
writeToScreen('手动关闭websocket')
wsObj.close() // 关闭websocket
// wsObj.onclose() // 关闭websocket(如果上面的关闭不生效就加上这一条)
wsObj.onclose() // 关闭websocket(如果上面的关闭不生效就加上这一条)
// 关闭重连
lockReconnect = true
wsCreateHandler && clearTimeout(wsCreateHandler)
@ -153,6 +153,8 @@ const onWsClose = (event) => {
}
const onWsError = (event) => {
// writeToScreen('onWsError: ', event.data)
console.log(event);
errorCallback()
}

View File

@ -11,9 +11,10 @@
<div class="tip-box-logo" :key="keynum">
<el-tooltip
class="box-item"
popper-class="tooltip-class"
:content="content"
raw-content
effect="dark"
effect="light"
placement="top-start"
>
<!-- <template #content> {{ props.val.tiptext}} </template> -->
@ -88,6 +89,9 @@ onMounted(() => {
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
@ -113,3 +117,8 @@ onMounted(() => {
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -16,8 +16,9 @@
<el-tooltip
class="box-item"
:content="`${item.name}:${JSON.parse(item.status) ? t('messages.onLine') : t('messages.offline')}`"
popper-class="tooltip-class"
raw-content
effect="dark"
effect="light"
placement="top-start"
>
<i
@ -95,6 +96,9 @@ onMounted(() => {});
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
}
@ -116,3 +120,8 @@ onMounted(() => {});
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -414,22 +414,22 @@ const init = () => {
/*创建wifi */
//
createWifi({ x: -46.96, y: 2, z: 156.57 })
createWifi({ x: -46.96, y: 3, z: 156.57 })
//
createWifi({ x: 52.60, y: 2, z: 96.44 })
createWifi({ x: 52.60, y: 2, z: 157.07 })
createWifi({ x: 52.60, y: 3, z: 96.44 })
createWifi({ x: 52.60, y: 3, z: 157.07 })
//
createWifi({ x: 133.14, y: 2, z: 107.43 })
createWifi({ x: 133.14, y: 2, z: 156.25 })
createWifi({ x: 133.14, y: 3, z: 107.43 })
createWifi({ x: 133.14, y: 3, z: 156.25 })
//
createWifi({ x: 305.73, y: 2, z: 110.45 })
createWifi({ x: 305.73, y: 2, z: 238.67 })
createWifi({ x: 305.73, y: 3, z: 110.45 })
createWifi({ x: 305.73, y: 3, z: 238.67 })
//
createWifi({ x: -89.13, y: 4, z: -245.33 })
createWifi({ x: -132.07, y: 2, z: -245.33 })
createWifi({ x: -222.31, y: 2, z: -245.33 })
createWifi({ x: -119.3, y: 2, z: -114.15 })
createWifi({ x: -176.45, y: 2, z: -114.40 })
createWifi({ x: -132.07, y: 3, z: -245.33 })
createWifi({ x: -222.31, y: 3, z: -245.33 })
createWifi({ x: -119.3, y: 3, z: -114.15 })
createWifi({ x: -176.45, y: 3, z: -114.40 })
//
createWifi({ x: 140.83, y: 2, z: -197.34 })
@ -771,7 +771,7 @@ function createWifi(position: positionType) {
loader.load('/models/glb/tothefuture_wifi.glb', function (gltf) {
const mesh = gltf.scene.children[0];
const s = 0.3;
const s = 0.5;
mesh.scale.set(s, s, s);
mesh.position.set(position.x, position.y, position.z);
// mesh.rotation.x = THREE.MathUtils.degToRad(270)

View File

@ -0,0 +1,138 @@
<template>
<div :class="$style['container']" ref="Acontent">
<threeMap ref="mapdomref"/>
<statusBar :width="size.oWidth" :height="size.oHeight" :iconList="store.iconList" :devList="store.devList"></statusBar>
</div>
</template>
<script setup lang='ts'>
import {ref,reactive,onMounted,onUnmounted} from 'vue'
import { calcWH } from "@/components/ts/selfAdaption";
import threeMap from './threeMap.vue';
import { getSensorInfodata , deviceDistributeInMachineryFactorydata} from "@/http/AerialView";
import { connectWebsocket, closeWebsocket } from "@/utils/websocket";
import { useFactoryStore } from '@/store/module/Factory';
import statusBar from './statusBar.vue';
const store = useFactoryStore();
let Acontent = ref();
let mapdomref=ref()
let size = reactive({
oWidth: 0,
oHeight: 0,
});
let timer = null
function WH(div: HTMLElement) {
let a = calcWH(div.offsetHeight, div.offsetWidth, 1, 5, 0);
size.oWidth = a.oWidth;
size.oHeight = a.oHeight;
if(mapdomref.value){
mapdomref.value.reset({oWidth:size.oWidth*5,oHeight:size.oHeight})
}
}
//
async function getSensorInfodatafun() {
let result: any = await getSensorInfodata();
if (result.code == 200) {
store.setDataList(result.data);
}
}
//
async function deviceDistributeInMachineryFactorydatafun() {
let result: any = await deviceDistributeInMachineryFactorydata();
if (result.code == 200) {
store.setdevList(result.data);
}
}
function getWebsocket(val) {
// try{
let data = null
try{
data = JSON.parse(val);
}catch(e){
console.log(e);
return
}
if (data.type == "SensorInfo") {
// console.log(data.msg,"");
store.updateSensorList(data.msg);
// store.changedevList(data.msg)
// store.changepaintingGas(data.msg);
}
// }catch(err){
// console.log(err,"");
// }
}
// getSensorInfodatafun()
// deviceDistributeInMachineryFactorydatafun()
function errWebsocket(val) {
// console.log(val);
}
onMounted(()=>{
// // todo
// windowDraw()
// calcRate()
let contentBox = Acontent.value;
// let Timedombox=Timedom.value
window.document.title = "传感器分布图";
WH(contentBox);
window.addEventListener("resize", () => {
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(() => {
WH(contentBox);
}, 1000);
});
// connectWebsocket(null, null, getWebsocket, errWebsocket);
})
onUnmounted(()=>{// todo
// unWindowDraw()
clearTimeout(timer)
closeWebsocket();
})
</script>
<style module>
.container {
height: 1080px;
width: 1920px;
color: #20aec5;
background-color: #100c2a;
}
</style>
<style scoped></style>
<style>
body {
/* --content:calc(100vh - var(--header)) */
overflow: hidden !important;
-ms-overflow-style:none; /* IE + Edge */
scrollbar-width: none; /* Firefox */
}
::-webkit-scrollbar {
display: none;
}
</style>

View File

@ -0,0 +1,189 @@
<!--
* @FilePath: \screenFront\src\views\FactoryView\statusBar.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-04-04 08:11:07
* @Description:
*
* 版权信息 : 2023 by ${再登软件}, All Rights Reserved.
-->
<template>
<div ref="statusbarref" :key="numkey">
<div class="tip-box-border" :class="{show}" @click="rtract" :style="{width: mapSize.width+'px',height:mapSize.height+'px'}" >
<!-- <div class="DirectionalSign">
</div> -->
<div class="iconTip">
<ul>
<!-- <li v-for="item in prop.iconList" :key="item.id" >
<i :class="'iconfont ' + item.name + ' icon-logo'"></i
>{{ "&nbsp&nbsp&nbsp" + item.value }}
<div>{{ `&nbsp${item.counts}/${item.allnum}` }}</div> -->
<!-- </li> -->
<!-- <li v-for="item in prop.devList" :key="item.id" >
<i :class="'iconfont ' + item.name + ' icon-logo SSCBar'"></i
>{{ "&nbsp&nbsp&nbsp" + item.value }}
<div>{{ `&nbsp${item.counts}/${item.allnum}` }}</div>
</li> -->
<li>
<i class="iconfont icon-WIFI icon-logo"></i> &nbsp;&nbsp;&nbsp;
WIFI
<div> &nbsp; 16/16</div>
</li>
<li>
<i class="iconfont icon-guangmao icon-logo"></i> &nbsp;&nbsp;&nbsp;
光猫
<div> &nbsp; 9/9</div>
</li>
<li>
<i class="iconfont icon-zhongduananquanjierukongzhiqi icon-logo"></i> &nbsp;&nbsp;&nbsp;
AC
<div> &nbsp; 3/3</div>
</li>
</ul>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { number } from "echarts/core";
import {reactive, ref, watch,defineProps} from "vue"
const prop = defineProps({
iconList: {
type: Object,
default: {},
},
devList: {
type: Object,
default: {},
},
width: {
type: Number,
default: 0,
},
height: {
type: Number,
default: 0,
},
});
const afterDisplay = ref("none")
const beforeDisplay = ref("block")
const show = ref(true)
let numkey=ref(0)
let statusbarref=ref()
let mapSize = reactive({
width: 0,
height: 0,
});
function rtract() {
show.value = !show.value;
if (show.value) {
afterDisplay.value = "none";
beforeDisplay.value = "block";
} else {
afterDisplay.value = "block";
beforeDisplay.value = "none";
}
}
watch(
() => prop,
(newVal, oldVal) => {
//
reset(newVal);
console.log(newVal);
},
{ immediate: true, deep: true, flush: "post" }
);
function reset(val: any) {
//0
if (!val.width && !val.height) return;
mapSize.width=val.width
mapSize.height=val.height
numkey.value++
// statusbarref.value.style.width=val.width
// statusbarref.value.style.height=val.height
//
}
</script>
<style scoped>
@import url("@/assets/css/iconfont.css");
@import url("@/assets/css/newicon/iconfont.css");
.tip-box-border{
position: fixed;
top: 0;
bottom: 0;
left: 0;
height: 97%;
width: 99%;
padding-top: 100px;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
z-index: 999;
background-color:rgba(0,0,0,0.5);
transition: transform 0.5s;
}
.show {
transform: translateX(-90%);
}
.tip-box-border::after{
content: "\e84f";
position: absolute;
top: 50%;
right: 0;
font-size: 24px;
font-family: 'iconfont' !important;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
display: v-bind(afterDisplay);
color: #fff;
box-sizing: border-box;
}
.tip-box-border::before{
content: '\e84e';
/* content: "\e84e"; */
position: absolute;
top: 50%;
right: 0;
font-size: 24px;
font-family: 'iconfont' !important;
font-style: normal;
display: v-bind(beforeDisplay);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #fff;
box-sizing: border-box;
}
.DirectionalSign{
width: 60%;
height: 20%;
background-image: url(@/assets/img/AerialView/direction.png);
background-size: 100% 100%;
}
.iconTip{
width: 100%;
height: 80%;
}
.iconTip>ul>li{
padding-left: 10%;
margin-top: 10px;
display: flex;
justify-content: flex-start;
align-items: center;
font-size: 1.5rem;
color: #fff;
}
.iconTip>ul>li>i{
font-size: 1.5rem;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
<!--
* @FilePath: \wwwd:\code\screenFront\src\views\InPlantProducts\child\component\Details.vue
* @FilePath: \code\gitscreenFront\src\views\InPlantProducts\child\component\Details.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-16 11:51:32
@ -37,7 +37,8 @@
v-model:visible="visible"
:content="tipcontent"
placement="top"
effect="dark"
effect="light"
popper-class="tooltip-class"
trigger="click"
virtual-triggering
:virtual-ref="triggerRef"
@ -186,6 +187,9 @@ p {
justify-content: center;
align-items: center;
}
.el-popper{
color: #fff !important;
}
/* .dv-scroll-board :deep(.row-item) {
line-height: normal !important;
align-items: center;
@ -194,3 +198,8 @@ p {
margin:0px 50px 0px 50px
} */
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -1,5 +1,5 @@
<!--
* @FilePath: \wwwd:\code\screenFront\src\views\InPlantProducts\child\component\RotationTable.vue
* @FilePath: \code\gitscreenFront\src\views\InPlantProducts\child\component\RotationTable.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-16 15:09:06
@ -38,7 +38,8 @@
v-model:visible="visible"
:content="tipcontent"
placement="top"
effect="dark"
effect="light"
popper-class="tooltip-class"
trigger="click"
virtual-triggering
:virtual-ref="triggerRef"
@ -168,4 +169,12 @@ defineExpose({
h2 {
color: #fff;
}
.el-popper{
color: #fff !important;
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -31,7 +31,8 @@
v-model:visible="visible"
:content="tipcontent"
placement="top"
effect="dark"
effect="light"
popper-class="tooltip-class"
trigger="click"
virtual-triggering
:virtual-ref="triggerRef"
@ -219,4 +220,12 @@ p {
justify-content: center;
align-items: center;
}
.el-popper{
color: #fff !important;
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -1,5 +1,5 @@
<!--
* @FilePath: \screenFront\src\views\InPlantProducts\content\chart\deviceslist.vue
* @FilePath: \code\gitscreenFront\src\views\InPlantProducts\content\chart\deviceslist.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-16 15:09:06
@ -30,7 +30,8 @@
v-model:visible="visible"
:content="tipcontent"
placement="top"
effect="dark"
effect="light"
popper-class="tooltip-class"
trigger="click"
virtual-triggering
:virtual-ref="triggerRef"
@ -200,10 +201,19 @@ defineExpose({
h2 {
color: #fff;
}
.el-popper{
color: #fff !important;
}
.dv-scroll-board :deep(.ceil) {
font-size: 1.2rem;
}
.dv-scroll-board :deep(.header-item) {
font-size: 1.2rem;
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -8,8 +8,8 @@
:height="'150px'"
:title="t('messages.InPlantProducts')"
:titleTip="titleTip"
:typeFun="['AbnormalData','time']"
:alarmType="['inplant']"
:typeFun="['time']"
:alarmType="[]"
></header2>
<!-- <div class="tip" style="display: flex;">
<span class="tipspan"><div class="red"></div><span class="tipstring">网关离线</span></span>

View File

@ -1,5 +1,5 @@
<!--
* @FilePath: \wwwd:\code\screenFront\src\views\AerialView\content\tip.vue
* @FilePath: \code\gitscreenFront\src\views\MechanicalView\content\tip.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-03-20 09:12:05
@ -13,7 +13,8 @@
class="box-item"
:content="content"
raw-content
effect="dark"
effect="light"
popper-class="tooltip-class"
placement="top-start"
>
<!-- <template #content> {{ props.val.tiptext}} </template> -->
@ -88,6 +89,9 @@ onMounted(() => {
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
@ -113,3 +117,8 @@ onMounted(() => {
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -17,7 +17,8 @@
class="box-item"
:content="`${item.name}:${JSON.parse(item.status) ? t('messages.onLine') : t('messages.offline')}`"
raw-content
effect="dark"
effect="light"
popper-class="tooltip-class"
placement="top-start"
>
<i
@ -95,6 +96,9 @@ onMounted(() => {});
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
}
@ -116,3 +120,8 @@ onMounted(() => {});
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -13,7 +13,8 @@
class="box-item"
:content="content"
raw-content
effect="dark"
effect="light"
popper-class="tooltip-class"
placement="top-start"
>
<!-- <template #content> {{ props.val.tiptext}} </template> -->
@ -88,6 +89,9 @@ onMounted(() => {
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
@ -113,3 +117,8 @@ onMounted(() => {
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -17,7 +17,8 @@
class="box-item"
:content="`${item.name}:${JSON.parse(item.status) ? t('messages.onLine') : t('messages.offline')}`"
raw-content
effect="dark"
effect="light"
popper-class="tooltip-class"
placement="top-start"
>
<i
@ -94,6 +95,9 @@ onMounted(() => {});
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
}
@ -115,3 +119,8 @@ onMounted(() => {});
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -13,7 +13,8 @@
class="box-item"
:content="content"
raw-content
effect="dark"
effect="light"
popper-class="tooltip-class"
placement="top-start"
>
<!-- <template #content> {{ props.val.tiptext}} </template> -->
@ -88,6 +89,9 @@ onMounted(() => {
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
@ -113,3 +117,8 @@ onMounted(() => {
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -17,7 +17,8 @@
class="box-item"
:content="`${item.name}:${JSON.parse(item.status) ? t('messages.onLine') : t('messages.offline')}`"
raw-content
effect="dark"
effect="light"
popper-class="tooltip-class"
placement="top-start"
>
<i
@ -95,6 +96,9 @@ onMounted(() => {});
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
}
@ -116,3 +120,8 @@ onMounted(() => {});
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -13,7 +13,8 @@
class="box-item"
:content="content"
raw-content
effect="dark"
effect="light"
popper-class="tooltip-class"
placement="top-start"
>
<!-- <template #content> {{ props.val.tiptext}} </template> -->
@ -88,6 +89,9 @@ onMounted(() => {
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
@ -113,3 +117,8 @@ onMounted(() => {
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -17,7 +17,8 @@
class="box-item"
:content="`${item.name}:${JSON.parse(item.status) ? t('messages.onLine') : t('messages.offline')}`"
raw-content
effect="dark"
effect="light"
popper-class="tooltip-class"
placement="top-start"
>
<i
@ -95,6 +96,9 @@ onMounted(() => {});
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
}
@ -116,3 +120,8 @@ onMounted(() => {});
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -13,7 +13,8 @@
class="box-item"
:content="content"
raw-content
effect="dark"
effect="light"
popper-class="tooltip-class"
placement="top-start"
>
<!-- <template #content> {{ props.val.tiptext}} </template> -->
@ -90,6 +91,9 @@ onMounted(() => {
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
@ -115,3 +119,8 @@ onMounted(() => {
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -17,7 +17,8 @@
class="box-item"
:content="`${item.name}:${JSON.parse(item.status) ? t('messages.onLine') : t('messages.offline')}`"
raw-content
effect="dark"
effect="light"
popper-class="tooltip-class"
placement="top-start"
>
<i
@ -95,6 +96,9 @@ onMounted(() => {});
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
}
@ -116,3 +120,8 @@ onMounted(() => {});
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -13,7 +13,8 @@
class="box-item"
:content="content"
raw-content
effect="dark"
effect="light"
popper-class="tooltip-class"
placement="top-start"
>
<!-- <template #content> {{ props.val.tiptext}} </template> -->
@ -88,6 +89,9 @@ onMounted(() => {
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
@ -113,3 +117,8 @@ onMounted(() => {
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -17,7 +17,8 @@
class="box-item"
:content="`${item.name}:${JSON.parse(item.status) ? t('messages.onLine') : t('messages.offline')}`"
raw-content
effect="dark"
effect="light"
popper-class="tooltip-class"
placement="top-start"
>
<i
@ -94,6 +95,9 @@ onMounted(() => {});
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
}
@ -115,3 +119,8 @@ onMounted(() => {});
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -13,7 +13,8 @@
class="box-item"
:content="content"
raw-content
effect="dark"
effect="light"
popper-class="tooltip-class"
placement="top-start"
>
<!-- <template #content> {{ props.val.tiptext}} </template> -->
@ -88,6 +89,9 @@ onMounted(() => {
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
@ -113,3 +117,8 @@ onMounted(() => {
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -17,7 +17,8 @@
class="box-item"
:content="`${item.name}:${JSON.parse(item.status) ? t('messages.onLine') : t('messages.offline')}`"
raw-content
effect="dark"
effect="light"
popper-class="tooltip-class"
placement="top-start"
>
<i
@ -94,6 +95,9 @@ onMounted(() => {});
/* position: relative; */
/* top: -15px; */
}
.el-popper{
color: #fff !important;
}
@keyframes redstart {
0% {
}
@ -115,3 +119,8 @@ onMounted(() => {});
}
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -127,7 +127,7 @@ let data={
stoptime:val.stoptime,//
data:'2020-05-06',//
src:imgurlAddXhr(val.data),//
timeguagu:95,//
timeguagu:Math.abs((val.ontime)/(val.ontime+val.offtime)*100).toFixed(1)||0,//
MTBF:2724,//MTBF
MTTR:169,//MTTR
MTTF:2555,//MTTF

View File

@ -0,0 +1,116 @@
<!--
* @FilePath: \code\gitscreenFront\src\views\Mechanics\components\DevOverview.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-06-09 14:29:11
* @Description:
*
* 版权信息 : 2023 by ${再登软件}, All Rights Reserved.
-->
<template>
<div class="devItem-box">
<h2>{{ props.title }}</h2>
<div class="devItem-content">
<div class="content-value" v-if="props.title == '设备总数'">
<h2>{{ value.total }}</h2>
</div>
<div class="content-value-cheijan " v-else>
<el-row>
<el-col :span="7">
<div class="chejian-online on-status">{{ value.onLine }} <div>在线</div>
</div>
</el-col>
<el-col :span="17"></el-col>
</el-row>
<el-row>
<el-col :span="17"></el-col>
<el-col :span="7">
<div class="chejian-offline on-status">{{ value.total - value.onLine }}<div>离线</div>
</div>
</el-col>
</el-row>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue"
// props.value01线2线
const props = defineProps({
title: {
type: String,
default: ''
},
value: {
type: Object,
default: { onLine: 0, total: 0 }
}
})
</script>
<style scoped>
.devItem-box h2 {
color: #fff;
font-size: 18px;
padding-left: 20px;
text-align: left;
}
.devItem-box {
width: 48%;
height: 30%;
}
.devItem-content {
width: 100%;
height: 75%;
display: flex;
justify-content: flex-end;
}
.content-value {
width: 70%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 2px solid;
border-image: linear-gradient(to right, #00D0FE, #2969E8) 1;
}
.on-status {
width: 50px;
font-size: 25px;
}
.chejian-online {
color: #7CFFB2;
}
.chejian-offline {
color: #4992FF;
}
.content-value-cheijan {
width: 70%;
height: 100%;
border-bottom: 2px solid;
border-image: linear-gradient(to right, #00D0FE, #2969E8) 1;
}
.content-value-cheijan::after {
content: '';
display: block;
border-bottom: 2px dashed #2969E8;
transform: rotate(-45deg);
margin-top: -40%;
}
.content-value>h2 {
display: block;
margin-top: 20px;
font-size: 50px;
color: #64A1FC;
}</style>

View File

@ -0,0 +1,134 @@
<!--
* @FilePath: \code\gitscreenFront\src\views\Mechanics\components\devFaultTip.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-06-12 08:52:40
* @Description:
*
* 版权信息 : 2023 by ${再登软件}, All Rights Reserved.
-->
<template>
<div style="height: 100%; width: 100%">
<h2 class="components-header">{{title}}</h2>
<div class="components-content" :key="keynum">
<swiper-container
:slidesPerView="per_view"
:initialSlide="0"
:loop="true"
:spaceBetween="0"
direction="vertical"
:autoplay="{
delay: 3000,
disableOnInteraction: false,
}"
@progress="onProgress"
@slidechange="onSlideChange"
>
<swiper-slide v-for="(res, index) in props.tipList" :key="index">
<div class="itemclass">
<el-row :gutter="5" class="row-flex">
<el-col :span="2" class="col-flex" style="color: #fff; font-size: 18px;">
{{ index + 1 }}
</el-col>
<el-col :span="18" class="col-flex" style="flex-direction: column; font-size: 18px; color: #fff; align-items: flex-start;">
<p><span>机架号</span><span>{{ res.label }}</span></p>
<p><span>设备位置及名称</span><span> {{ res.devName }}</span></p>
</el-col>
<el-col :span="4" class="col-flex" style="font-size: 25px; color: red;"> 故障 </el-col>
</el-row>
</div>
</swiper-slide>
</swiper-container>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive, ref, watch } from "vue";
import { register } from "swiper/element/bundle";
import { useI18n } from "vue-i18n";
let { t } = useI18n();
register();
const props = defineProps({
title: {
type: String,
default: "",
},
tipList: {
type: Array,
default: [],
},
});
let per_view = ref(3);
let useSwiper: any = ref(null);
let swiperRef = ref(null);
let listVal = ref([]);
let keynum = ref(0);
// space-between:
// slides-per-view:
// initialSlide
// height:,
// direction:
// autoplay{
// delay
// disableOnInteraction
// }
// let swiperConfig= reactive({
// perView:3,
// initialSlide:1,
// loop:true,
// spaceBetween:0,
// swiperHeight:200,
// direction:'vertical',
// autoplay:{ delay: 3000,disableOnInteraction: false,height:200}
// })
watch(
() => props.tipList,
(val) => {
keynum.value++;
},
{ deep: true }
);
const onProgress = (e) => {};
const onSlideChange = (e) => {};
</script>
<style scoped>
.components-header {
width: 100%;
text-align: center;
color: #fff;
font-size: 20px;
margin-bottom: 10px;
}
.components-content {
height: 90%;
width: 100%;
}
.itemclass {
display: flex;
height: 100%;
width: 100%;
align-items: center;
border-bottom: #0545a1 1px solid;
}
.row-flex{
width: 100%;
height: 100%;
}
.col-flex{
display: flex;
justify-content: center;
align-items: center;
}
.swiper,
swiper-container {
width: 100%;
height: 100%;
display: inline-block !important;
}
</style>

View File

@ -0,0 +1,136 @@
<!--
* @FilePath: \code\gitscreenFront\src\views\Mechanics\components\devStatusTip.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-06-12 08:52:40
* @Description:
*
* 版权信息 : 2023 by ${再登软件}, All Rights Reserved.
-->
<template>
<div style="height: 100%; width: 100%">
<h2 class="components-header">{{title}}</h2>
<div class="components-content" :key="keynum">
<swiper-container
:slidesPerView="per_view"
:loop="true"
:spaceBetween="0"
direction="vertical"
:autoplay="{
delay: 3000,
disableOnInteraction: false,
}"
autoHeight=true
observer=true
observeParents=true
@progress="onProgress"
@slidechange="onSlideChange"
>
<swiper-slide v-for="(res, index) in props.tipList" :key="index">
<div class="itemclass">
<el-row :gutter="5" class="row-flex">
<el-col :span="2" class="col-flex" style="color: #fff; font-size: 18px;">
{{ index + 1 }}
</el-col>
<el-col :span="18" class="col-flex" style="flex-direction: column; font-size: 18px; color: #fff; align-items: flex-start;">
<p><span>设备名称</span><span>{{ res.label }}</span></p>
<p><span>保养日期</span><span>{{ res.on }}</span> &nbsp; <span>保养时长</span><span>{{ res.on }}</span> </p>
</el-col>
<el-col :span="4" class="col-flex" style="font-size: 25px; color: red;"> 未进行 </el-col>
</el-row>
</div>
</swiper-slide>
</swiper-container>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive, ref, watch } from "vue";
import { register } from "swiper/element/bundle";
import { useI18n } from "vue-i18n";
let { t } = useI18n();
register();
const props = defineProps({
title: {
type: String,
default: "",
},
tipList: {
type: Array,
default: [],
},
});
let per_view = ref(5);
let useSwiper: any = ref(null);
let swiperRef = ref(null);
let listVal = ref([]);
let keynum = ref(0);
// space-between:
// slides-per-view:
// initialSlide
// height:,
// direction:
// autoplay{
// delay
// disableOnInteraction
// }
// let swiperConfig= reactive({
// perView:3,
// initialSlide:1,
// loop:true,
// spaceBetween:0,
// swiperHeight:200,
// direction:'vertical',
// autoplay:{ delay: 3000,disableOnInteraction: false,height:200}
// })
watch(
() => props.tipList,
(val) => {
keynum.value++;
},
{ deep: true }
);
const onProgress = (e) => {};
const onSlideChange = (e) => {};
</script>
<style scoped>
.components-header {
width: 100%;
text-align: center;
color: #fff;
font-size: 20px;
margin-bottom: 10px;
}
.components-content {
height: 90%;
width: 100%;
}
.itemclass {
display: flex;
height: 100%;
width: 100%;
align-items: center;
border-bottom: #0545a1 1px solid;
}
.row-flex{
width: 100%;
height: 100%;
}
.col-flex{
display: flex;
justify-content: center;
align-items: center;
}
.swiper,swiper-container {
width: 100%;
height: 100%;
display: inline-block !important;
}
</style>

View File

@ -0,0 +1,163 @@
<!--
* @FilePath: \code\gitscreenFront\src\views\Mechanics\components\gateway.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-16 11:51:32
* @Description:
*
* 版权信息 : 2023 by ${再登软件}, All Rights Reserved.
-->
<template>
<div class="box" :style="{ width: '100%', height: '100%' }">
<div class="title-box" >
<h2>{{ props.title }}</h2>
<div class="colorTip">
<div><i class="iconfont icon-beikongshuiwupingtaimenhu-tubiao_zhinengwangguan icon-blue"></i> {{t('messages.onLine')}}</div>
<div style="color:#e43961"><i class="iconfont icon-beikongshuiwupingtaimenhu-tubiao_zhinengwangguan icon-red"></i>
{{t('messages.offline')}}</div>
</div>
</div>
<ul class="gatewaystatus">
<li v-for="item in props.data" @click="clickBotton(item)">
<i :class="JSON.parse(item.gateway)
? 'iconfont icon-beikongshuiwupingtaimenhu-tubiao_zhinengwangguan online'
: 'iconfont icon-beikongshuiwupingtaimenhu-tubiao_zhinengwangguan noonline'
"></i>
<h2 class="titlesize-name">{{ item.title+'车间' }}</h2>
</li>
</ul>
</div>
</template>
<script setup lang="ts">
import { getCurrentInstance, onMounted, reactive, ref } from "vue";
import border13 from "@/components/border/Border13.vue";
import { useI18n } from 'vue-i18n'
import { useMechanicsStore } from "@/store/module/Mechanics";
import { useRouter } from "vue-router";
const router=useRouter()
const store = useMechanicsStore();
let {t} = useI18n();
let props = defineProps<{
title: string;
data: any
}>();
const clickBotton=(item:any)=>{
store.changePage(item.index)
router.push({
name:'Mechanicschild',
params:{
id:item.index
}
})
}
onMounted(() => { });
</script>
<style scoped>
h2 {
color: #fff;
font-size: 20px;
flex: 1;
}
p {
margin: 0 10px 0 10px;
color: #fff;
font-weight: 800;
font-size: 2rem;
}
.box {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
padding: 0;
}
.gatewaystatus {
margin: auto;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.gatewaystatus>li {
width: 50%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.gatewaystatus>li {
flex-direction: column;
}
.noonline {
font-size: 5rem;
color: rgb(228, 57, 97);
position: relative;
/* top: -20px; */
}
.online {
font-size: 5rem;
color: rgb(32, 174, 197);
position: relative;
/* top: -20px; */
}
.colorTip {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
right: 0;
}
.colorTip span {
margin-right: 1rem;
}
.colorTip>div {
margin-right: 1rem;
font-size: 1rem;
}
.colorTip .icon-red {
display: inline-block;
/* background-color: #e43961; */
/* border-radius: 1rem; */
color: #e43961;
width: 1rem;
height: 1rem;
}
.colorTip .icon-blue {
display: inline-block;
/* background-color: #20aec5; */
/* border-radius: 1rem; */
color: #20aec5;
width: 1rem;
height: 1rem;
}
.titlesize-name {
font-size: 1.5rem;
}
.title-box {
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
}
</style>

View File

@ -0,0 +1,89 @@
<!--
* @FilePath: \code\gitscreenFront\src\views\Mechanics\components\ringChart.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-04-28 08:01:55
* @Description:
*
* 版权信息 : 2023 by ${再登软件}, All Rights Reserved.
-->
<template>
<div class="ring" ref="ringRef"></div>
</template>
<script setup lang='ts'>
import { ref, onMounted, onUnmounted, getCurrentInstance,watch,onUpdated } from 'vue'
const { proxy } = getCurrentInstance() as any;
import { useI18n } from 'vue-i18n'
let {t} = useI18n();
let ringRef = ref();
let ringChart = null;
const prop = defineProps({
data: []
})
const init = () => {
ringChart = proxy.$echarts.init(ringRef.value, 'dark')
let option = {
title: {
text: t('messages.DevType'),
show: true,
textStyle: {
color: "#fff",
fontSize: 20,
},
left:'center'
},
tooltip: {
trigger: "item",
},
legend: {
type: "scroll",
bottom: "5%",
left: "center",
},
series: [
{
name: "",
type: "pie",
radius: ["20%", "50%"],
center: ["50%", "45%"],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 5,
// borderColor: '#fff',
borderWidth: 2,
},
label: {
show: true,
formatter: "{b}: {c}",
},
labelLine: {
show: true,
},
data: prop.data,
},
],
}
ringChart.setOption(option)
}
onUpdated(() => {
ringChart.setOption({
series: [
{
data: prop.data
}
]
})
})
onMounted(() => {
init()
})
</script>
<style scoped>
.ring {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,107 @@
<!--
* @FilePath: \code\gitscreenFront\src\views\Mechanics\components\scrollBoard.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-06-13 08:33:37
* @Description:
*
* 版权信息 : 2023 by ${再登软件}, All Rights Reserved.
-->
<template>
<div class="box">
<div class="box-title">{{t('messages.LegionDevList')}}</div>
<div class="box-body">
<dv-scroll-board ref="devList" :config="prop.config" @mouseover="dvMouseover" @mouseend="dvmouseleave" :style="{
width: '100%',
height: '100%',
}" />
<el-tooltip v-model:visible="visible" :content="tipcontent" placement="top" effect="light" trigger="click" popper-class="tooltip-class"
virtual-triggering :virtual-ref="triggerRef" />
</div>
</div>
</template>
<script setup lang='ts'>
import { getCurrentInstance, onMounted, reactive, ref } from "vue";
import { devListType } from "@/type/InPlantProducts";
import { useRouter } from "vue-router"
import { useI18n } from 'vue-i18n'
let {t} = useI18n();
const prop = defineProps({
config: Object,
})
const router = useRouter()
//
let tipcontent = ref(null)
//
let visible = ref(false)
//dom
let triggerRef = ref(null)
/**
* @函数功能: 鼠标移入组件方法
* @param {*} value
* @出口参数:
* @函数备注:
*/
const dvMouseover = (value) => {
if (value.toElement && value.toElement.innerHTML&&value.toElement.className == 'ceil') {
triggerRef.value = value.toElement
tipcontent.value = value.toElement.innerText
visible.value = true
}
};
/**
* @函数功能: 鼠标移出组件方法
* @出口参数:
* @函数备注:
*/
const dvmouseleave = () => {
triggerRef.value = null
tipcontent.value = null
visible.value = false
};
</script>
<style scoped>
.box {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.box-title {
width: 100%;
padding: 10px;
font-size: 20px;
color: #fff;
text-align: center;
font-weight: bold;
}
.box-body {
width: 100%;
height: 90%;
display: flex;
justify-content: space-around;
align-items: center;
}
:deep(.dv-scroll-board .rows .ceil) {
overflow: auto;
white-space: pre-wrap;
text-overflow: none
}
:deep(.dv-scroll-board .rows .row-item) {
font-size: 16px;
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -0,0 +1,313 @@
<template>
<div :class="$style['container']">
<div class="header">
<div class="title">
<header2 ref="headerref" :width="'100%'" :height="'100px'" :title="t('messages.Mechanics')" :titleTip="[]"
:typeFun="['AbnormalData', 'time']" :alarmType="['machinefactory']">
</header2>
</div>
</div>
<div class="content" ref="Acontent">
<el-row class="layout" :gutter="20">
<el-col :span="7" class="flex-left">
<div style="width: 100%; height: 68%;">
<border13>
<div style="width: 100%;height: 100%;">
<h2 class="module-header">设备总览</h2>
<div class="module-content">
<DevOverview :title="'设备总数'" :value="{ onLine: facTotal.onLine, total: facTotal.total }"></DevOverview>
<DevOverview :title="item.name" :value="{ onLine: item.onLine, total: item.total }"
v-for="(item) in facList"></DevOverview>
</div>
</div>
</border13>
</div>
<div style="width: 100%; height: 28%;">
<border13>
<div style="width: 98%;height: 100%;">
<devFaultTip :title="'设备故障提醒'" :tipList="devFaultTipData"></devFaultTip>
</div>
</border13>
</div>
</el-col>
<el-col :span="10" class="flex-left">
<div style="width: 100%; height: 18%;">
<gateway :title="'物联网关状态'" :data="gatewayData"></gateway>
</div>
<div style="width: 100%; height: 78%;">
<border13>
<scrollBoard :config="scrollBoardConfig"></scrollBoard>
</border13>
</div>
</el-col>
<el-col :span="7" class="flex-left">
<div style="width: 100%; height: 48%;">
<border13>
<ringChart :data="ringData"></ringChart>
</border13>
</div>
<div style="width: 100%; height: 48%;">
<border13>
<div style="width: 100%;height: 100%;">
<devStatusTip :title="'设备保养提醒'" :tipList="devStatusTipData"></devStatusTip>
</div>
</border13>
</div>
</el-col>
</el-row>
</div>
</div>
</template>
<script setup lang="ts">
import { nextTick, onMounted, onUnmounted, reactive, ref } from "vue";
import header2 from "@/components/headerBox/header2.vue";
import border13 from '@/components/border/Border13.vue'
import DevOverview from "./components/DevOverview.vue";
import devFaultTip from "./components/devFaultTip.vue";
import devStatusTip from "./components/devStatusTip.vue";
import ringChart from "./components/ringChart.vue";
import scrollBoard from "./components/scrollBoard.vue";
import gateway from "./components/gateway.vue";
import { connectWebsocket, closeWebsocket } from "@/utils/websocket";
import { ElRow, ElCol } from "element-plus";
import { useMechanicsStore } from "@/store/module/Mechanics";
import { gatewayOfMachineryFactory, gatcountsOfMachineryFactory, reqDeviceTotelListMF, reqDeviceTotelStatusMF } from "@/http/Mechanics";
import { useI18n } from "vue-i18n";
let { t } = useI18n();
const store = useMechanicsStore();
let Acontent = ref();
let headerref = ref();
let DevOverviewData = ref([])
let devFaultTipData = ref([])
let devStatusTipData = ref([])
let ringData = ref([])
let scrollBoardConfig = reactive({
header: ['序号', '设备名称', '所属车间', '设备状态', '稼动率', '故障率'],
headerBGC: 'rgb(52, 105, 243)',
oddRowBGC: '#100c2a',
evenRowBGC: '#100c2a',
rowNum: 10,
columnWidth: [80, 290, 120, 120, 120, 120],
align: ['center', 'center', 'center', 'center', 'center', 'center'],
data: []
})
let gatewayData = ref([])
let devNumTimer: any = null
//
let facList = ref([])
//
let facTotal = reactive({
total: 0,
onLine: 0,
offLine: 0
})
function getWebsocket(val) {
headerref.value.HeadergetWebsocket(val);
try {
let data = JSON.parse(val);
if (data.type == "CountsOfMachineryFactoryInStatusTime") {
store.changedevstatus(data.msg);
}
if (data.type == "gatewayMF") {
store.changegateway(data.msg);
gatewayData.value = store.getmechanicsData
store.changegatewaynum(data.msg);
// store.changePM(data.msg)
}
} catch (err) {
console.log(err);
}
}
function errWebsocket(val) {
headerref.value ? headerref.value.HeadererrWebsocket(val) : "";
// console.log(val);
}
//
async function gatewayOfMachineryFactoryfun() {
let result: any = await gatewayOfMachineryFactory()
if (result.code == 200) {
store.changegateway(result.data)
gatewayData.value = store.getmechanicsData
}
}
// async function gatcountsOfMachineryFactoryfun() {
// let result: any = await gatcountsOfMachineryFactory()
// if (result.code == 200) {
// store.changegatewaynum(result.data)
// }
// }
//
async function reqDeviceTotelListMFfun() {
let result: any = await reqDeviceTotelListMF()
if (result.code == 200) {
scrollBoardConfig.data = result.data.map((item, index) => {
return [
index + 1,
item.name,
item.dept,
item.status == 'false' ? '离线' : '在线',
item.activation+'%',
item.failure+'%'
]
})
}
}
//
async function getDeviceTotelStatusMF() {
let result: any = await reqDeviceTotelStatusMF()
if (result.code == 200) {
facList.value = result.data.list
facTotal.total = result.data.total
facTotal.onLine = result.data.list.reduce((total, item) => {
return total + item.onLine
}, 0)
facTotal.offLine = facTotal.total - facTotal.onLine
ringData.value = [
{ name: '在线', value: facTotal.onLine },
{ name: '离线', value: facTotal.offLine }
]
}
}
onMounted(() => {
// let Timedombox=Timedom.value
window.document.title = t("messages.Mechanics");
setTimeout(() => {
devFaultTipData.value = [
{ label: '111111', devName: '富怡精密绣花机', status: '故障' },
{ label: '222222', devName: '富怡精密绣花机', status: '故障' },
{ label: '333333', devName: '富怡精密绣花机', status: '故障' },
{ label: '444444', devName: '富怡精密绣花机', status: '故障' },
{ label: '555555', devName: '富怡精密绣花机', status: '故障' },
{ label: '666666', devName: '富怡精密绣花机', status: '故障' },
{ label: '777777', devName: '富怡精密绣花机', status: '故障' }]
devStatusTipData.value = [{ label: '111111', devName: '富怡精密绣花机', on: 111, off: 222, stop: 333 },
{ label: '222222', devName: '富怡精密绣花机', on: 111, off: 222, stop: 333 },
{ label: '333333', devName: '富怡精密绣花机', on: 111, off: 222, stop: 333 },
{ label: '444444', devName: '富怡精密绣花机', on: 111, off: 222, stop: 333 },
{ label: '555555', devName: '富怡精密绣花机', on: 111, off: 222, stop: 333 },
{ label: '666666', devName: '富怡精密绣花机', on: 111, off: 222, stop: 333 },
{ label: '777777', devName: '富怡精密绣花机', on: 111, off: 222, stop: 333 }, { label: '111111', devName: '富怡精密绣花机', on: 111, off: 222, stop: 333 },
{ label: '222222', devName: '富怡精密绣花机', on: 111, off: 222, stop: 333 },
{ label: '333333', devName: '富怡精密绣花机', on: 111, off: 222, stop: 333 },
{ label: '444444', devName: '富怡精密绣花机', on: 111, off: 222, stop: 333 },
{ label: '555555', devName: '富怡精密绣花机', on: 111, off: 222, stop: 333 },
{ label: '666666', devName: '富怡精密绣花机', on: 111, off: 222, stop: 333 },
{ label: '777777', devName: '富怡精密绣花机', on: 111, off: 222, stop: 333 }]
}, 1000)
devNumTimer = setInterval(() => {
getDeviceTotelStatusMF()
}, 1000*60)
gatewayOfMachineryFactoryfun()
// gatcountsOfMachineryFactoryfun()
//
getDeviceTotelStatusMF()
//
reqDeviceTotelListMFfun()
connectWebsocket(null, null, getWebsocket, errWebsocket);
});
onUnmounted(() => {
closeWebsocket();
clearInterval(devNumTimer)
});
</script>
<style module>
.container {
height: 1080px;
width: 1920px;
color: #20aec5;
background-color: #100c2a;
}
</style>
<style scoped>
.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;
}
.module-header {
width: 100%;
text-align: center;
color: #fff;
font-size: 20px;
margin-bottom: 10px;
}
.module-content {
display: flex;
flex-wrap: wrap;
height: 98%;
width: 100%;
}
.layout {
height: 100%;
}
.flex-left {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.content {
width: 100%;
--header: 100px;
height: calc(1080px - var(--header));
}
</style>
<style>
body {
/* --content:calc(100vh - var(--header)) */
overflow: hidden !important;
-ms-overflow-style: none;
/* IE + Edge */
scrollbar-width: none;
/* Firefox */
}
::-webkit-scrollbar {
display: none;
}
</style>

View File

@ -32,7 +32,8 @@
v-model:visible="visible"
:content="tipcontent"
placement="top"
effect="dark"
effect="light"
popper-class="tooltip-class"
trigger="click"
virtual-triggering
:virtual-ref="triggerRef"
@ -229,6 +230,9 @@ h2 {
color: #fff;
font-size: 20px;
}
.el-popper{
color: #fff !important;
}
.dv-scroll-board :deep(.ceil) {
font-size: 1rem;
}
@ -236,3 +240,8 @@ h2 {
font-size: 1rem;
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -1,5 +1,5 @@
<!--
* @FilePath: \gitscreenFront\src\views\PaintShopView\View1\bottom.vue
* @FilePath: \code\gitscreenFront\src\views\PaintShopView\View1\bottom.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-13 14:43:28
@ -14,6 +14,7 @@
<div style="display: flex;justify-content: space-evenly; align-items: center; margin-bottom: 10px;">
<chart :title="powerOption.title" :option="powerOption.option" ref="powerref"></chart>
<chart :title="powerOption.title" :option="powerOption.option" ref="Productionref"></chart>
<div>
<border6 ref="borderref">
<template v-slot>
@ -21,6 +22,12 @@
</template>
</border6>
</div>
<div>
<gas ref="gasref" :title="t('messages.gasto2023')"></gas>
<!-- 调整高度间距div -->
<div style="width: 100%;height: 10px;"></div>
<water ref="waterref" :title="t('messages.waterto2023')"></water>
</div>
</div>
</el-col>
</el-row>
@ -37,6 +44,8 @@ import border3 from "@/components/borderBox/border3.vue";
import pm from "./../components/pm.vue";
import power from "./chart/power2023.vue";
import chart from "@/components/assembly/chart2.vue";
import gas from "./chart/gas.vue";
import water from "./chart/water.vue";
import { useRoute, useRouter } from "vue-router";
import { useEnergyConsumeStore } from "@/store/module/energyConsume";
import { useI18n } from 'vue-i18n'
@ -49,6 +58,9 @@ let Productionref = ref();
let borderref = ref()
let pmref = ref()
let pm_timer = null
let gasref = ref();
let waterref = ref();
let props = defineProps<{
width: number;
height: number;
@ -72,12 +84,13 @@ function reset(val: any) {
}
const powerBox = (width: any, height: any) => {
let a = calcWH(height, width, 1, 3, 0);
let a = calcWH(height, width, 1, 24, 0);
//
powerref.value.setchartWH(a.oWidth - 20, a.oHeight - 20);
Productionref.value.setchartWH(a.oWidth - 20, a.oHeight - 20);
pmref.value.setchartWH(a.oWidth - 40, a.oHeight - 40)
// yields.value.setchartWH(a.oWidth, a.oHeight - 30);
powerref.value.setchartWH(a.oWidth*7 - 20, a.oHeight - 20);
Productionref.value.setchartWH(a.oWidth*7 - 20, a.oHeight - 20);
pmref.value.setchartWH(a.oWidth*7 - 40, a.oHeight - 40)
gasref.value.setchartWH(a.oWidth*3-20, a.oHeight/2 - 20);
waterref.value.setchartWH(a.oWidth*3-20, a.oHeight/2 - 20);
};
let powerOption = reactive({
title: "",
@ -103,9 +116,9 @@ let powerOption = reactive({
right: 20,
},
grid: {
top: "8%",
top: "13%",
left: "3%",
right: "0%",
right: "5%",
bottom: "3%",
containLabel: true,
},
@ -146,9 +159,9 @@ let ProductionOption = reactive({
right: 20,
},
grid: {
top: "8%",
top: "13%",
left: "3%",
right: "0%",
right: "5%",
bottom: "3%",
containLabel: true,
},
@ -166,20 +179,6 @@ let ProductionOption = reactive({
},
});
let Data = { power: { "1月": 11, "2月": 22, "3月": 11, "4月": 22 }, Production: { "1月": 11, "2月": 22, "3月": 11, "4月": 22 } }
// async function getpower() {
// let result: any = await getPowerData({ time: 1 });
// if (result.code == 200) {
// result.data.name = result.data.name.reverse();
// result.data.listData.forEach((res) => {
// for (let key in res.month) {
// res.month[key] = res.month[key].reverse();
// }
// });
// power1.value.setData(result.data);
// // yields.value.setData(result.data);
// }
// }
let pm_index = 0
function setcontentData(val) {
clearInterval(pm_timer)
@ -279,6 +278,20 @@ function setcontentData(val) {
}
}, 3000)
}
}
//
function setWaterGas(val:any){
console.log(val);
val.forEach(res=>{
if(res.deptName=='喷漆车间' && res.type=='GasDetail'){
gasref.value.setData(res.usageNum);
}
if(res.deptName=='生产区' && res.type=='WaterDetail'){
waterref.value.setData(res.usageNum);
}
})
}
onMounted(() => {
});
@ -287,6 +300,7 @@ onUnmounted(() => {
});
defineExpose({
setcontentData,
setWaterGas
});
</script>

View File

@ -0,0 +1,169 @@
<!--
* @FilePath: \code\gitscreenFront\src\views\PaintShopView\View1\chart\gas.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-14 13:24:12
* @Description:
*
* 版权信息 : 2023 by ${再登软件}, All Rights Reserved.
-->
<template>
<div class="gasborder">
<border6 ref="refborder4">
<template v-slot>
<!-- <h1>{{props.title}}</h1> -->
<div ref="gas" ></div>
</template>
</border6>
</div>
</template>
<script setup lang="ts">
import {getCurrentInstance, onMounted, reactive, ref} from "vue"
import {EDataPerson,EDataPersonItem} from '@/type/energyConsume'
import 'echarts-liquidfill'
import border6 from "@/components/borderBox/border6.vue";
const { proxy } = getCurrentInstance() as any;
let props=defineProps<{
title:string,
}>()
let gas=ref()
let refborder4=ref()
const echartsData = reactive<EDataPerson>({
gas:{
div:null,
data:null,
title:'',
box:null
},
})
const setData=(value:any)=>{
echartsData.gas!.div=gas.value
echartsData.gas!.title=props.title
echartsData.gas!.data=({
title: {
//
text: echartsData.gas!.title,
textStyle:{
color:'#fff',
fontSize:20
},
top:'2%'
},
series: [{
type: 'liquidFill',
radius: '80%', //
shape:'rect',
center: ['50%', '55%'],
waveAnimation: true,
color: [
{
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: '#186945',
},
{
offset: 1,
color: '#1b7a4f',
},
],
globalCoord: false,
},
],
data: [0.7,0.7], // data
amplitude: 10, //
backgroundStyle: {
borderWidth: 2, //
borderColor:'rgba(8, 206, 120, 0.8)',//
color: 'rgba(8, 206, 120, 0.4)',
},
label: {
normal: {
textStyle: {
fontSize: 24,
fontWeight: 'bold',
color: '#fff',
},
formatter:function(params){
return value
}
},
},
outline: {
borderDistance: 0,
itemStyle: {
borderWidth: 4,
borderColor: 'transparent',
},
},
}],
})
change(echartsData.gas)
}
const change = (item:EDataPersonItem) => {
let Ebox=proxy.$echarts.init(
item.div,
"dark"
);
Ebox.setOption(item.data);
item.box = Ebox
};
function setchartWH(width:any,height:any){
// echartsData.water!.div=water.value
gas.value.style.height=height-20+'px'
gas.value.style.width=width+'px'
refborder4.value.resetWH()
if(echartsData.gas.box){
echartsData.gas.box.resize()
}
}
onMounted(() => {
// setData()
})
// return{setchartWH}
defineExpose({
setchartWH,
setData
})
</script>
<style scoped>
.gasBox{
/* border-radius: 50%; */
background-color: #8CE78D;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
margin: 20px;
font-size: 20px;
}
.gasborder{
position: relative;
}
.gasborder h1{
position: absolute;
top: 20px;
left:20px;
color: #fff;
}
</style>

View File

@ -0,0 +1,169 @@
<!--
* @FilePath: \code\gitscreenFront\src\views\PaintShopView\View1\chart\water.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-14 13:24:12
* @Description:
*
* 版权信息 : 2023 by ${再登软件}, All Rights Reserved.
-->
<template>
<div class="gasborder">
<border6 ref="refborder4">
<template v-slot>
<!-- <h1>{{props.title}}</h1> -->
<div ref="gas" ></div>
</template>
</border6>
</div>
</template>
<script setup lang="ts">
import {getCurrentInstance, onMounted, reactive, ref} from "vue"
import {EDataPerson,EDataPersonItem} from '@/type/energyConsume'
import 'echarts-liquidfill'
import border6 from "@/components/borderBox/border6.vue";
const { proxy } = getCurrentInstance() as any;
let props=defineProps<{
title:string,
}>()
let gas=ref()
let refborder4=ref()
const echartsData = reactive<EDataPerson>({
gas:{
div:null,
data:null,
title:'',
box:null
},
})
const setData=(value:any)=>{
echartsData.gas!.div=gas.value
echartsData.gas!.title=props.title
echartsData.gas!.data=({
title: {
//
text: echartsData.gas!.title,
textStyle:{
color:'#fff',
fontSize:20
},
top:'2%'
},
series: [{
type: 'liquidFill',
radius: '80%', //
shape:'rect',
center: ['50%', '55%'],
waveAnimation: true,
color: [
{
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: '#138FE2',
},
{
offset: 1,
color: '#126ABC',
},
],
globalCoord: false,
},
],
data: [0.7,0.7], // data
amplitude: 10, //
backgroundStyle: {
borderWidth: 2, //
borderColor:'rgba(17, 94, 176, 0.8)',//
color: 'rgba(17, 94, 176, 0.4)',
},
label: {
normal: {
textStyle: {
fontSize: 24,
fontWeight: 'bold',
color: '#fff',
},
formatter:function(params){
return value
}
},
},
outline: {
borderDistance: 0,
itemStyle: {
borderWidth: 4,
borderColor: 'transparent',
},
},
}],
})
change(echartsData.gas)
}
const change = (item:EDataPersonItem) => {
let Ebox=proxy.$echarts.init(
item.div,
"dark"
);
Ebox.setOption(item.data);
item.box = Ebox
};
function setchartWH(width:any,height:any){
// echartsData.water!.div=water.value
gas.value.style.height=height-20+'px'
gas.value.style.width=width+'px'
refborder4.value.resetWH()
if(echartsData.gas.box){
echartsData.gas.box.resize()
}
}
onMounted(() => {
// setData()
})
// return{setchartWH}
defineExpose({
setchartWH,
setData
})
</script>
<style scoped>
.gasBox{
/* border-radius: 50%; */
background-color: #8CE78D;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
margin: 20px;
font-size: 20px;
}
.gasborder{
position: relative;
}
.gasborder h1{
position: absolute;
top: 20px;
left:20px;
color: #fff;
}
</style>

View File

@ -36,6 +36,7 @@ import { calcWH } from '@/components/ts/selfAdaption'
import { Offsite } from "@/store/module/offsite";
import { connectWebsocket, closeWebsocket } from "@/utils/websocket";
import { getSensorByDept } from "@/http/PaintShopView/index";
import {getconsumeDetail} from '@/http/energyConsume'
import bottom from "./bottom.vue"
import top from "./top.vue"
import { useI18n } from 'vue-i18n'
@ -77,6 +78,15 @@ async function getSensorByDeptfun() {
bottomref.value.setcontentData(result.data)
}
}
async function getconsumeDetailfun(){
let result:any = await getconsumeDetail()
if(result.code==200){
bottomref.value.setWaterGas(result.data)
}
}
function getWebsocket(val) {
// headerref.value.HeadergetWebsocket(val)
try {
@ -108,6 +118,7 @@ onMounted(() => {
}, 1000);
})
getSensorByDeptfun()
getconsumeDetailfun()
connectWebsocket(null, null, getWebsocket, errWebsocket);
})
onUnmounted(() => {

View File

@ -268,7 +268,7 @@ function setcontentData(val) {
return { name: item.name, val: item.data,status:item.status };
});
verticalNum3.value.setData(val.FIRE, 'icon-weibiaoti1', 0, "")
verticalNum4.value.setData(noise, 'icon-shengyin', 120, "dB")
verticalNum4.value.setData(noise, 'icon-shengyin', 85, "dB")
verticalNum5.value.setData(Smoke, 'icon-yanwubaojingqi', 100, "PPM")
verticalNum6.value.setData(CH2O, 'icon-app_icons--', 0.08, "mg/m3")
verticalNum7.value.setData(TVOC, 'icon-TVOC-Outlined', 0.5, "mg/m3")

View File

@ -281,7 +281,7 @@ let temp_humi_index = 0
return { name: item.name, val: item.data,status:item.status };
});
// verticalNum3.value.setData(val.FIRE,'icon-ranqi',5,"")
verticalNum4.value.setData(noise,'icon-shengyin',120,"dB")
verticalNum4.value.setData(noise,'icon-shengyin',85,"dB")
// verticalNum5.value.setData(val.Smoke,'icon-yanwubaojingqi',200,"")
verticalNum6.value.setData(CH2O,'icon-app_icons--',0.08,"mg/m3")
verticalNum7.value.setData(TVOC,'icon-TVOC-Outlined',0.5,"mg/m3")

View File

@ -281,7 +281,7 @@ let temp_humi_index = 0
return { name: item.name, val: item.data,status:item.status };
});
// verticalNum3.value.setData(val.FIRE,'icon-ranqi',5,"")
verticalNum4.value.setData(noise,'icon-shengyin',120,"dB")
verticalNum4.value.setData(noise,'icon-shengyin',85,"dB")
// verticalNum5.value.setData(val.Smoke,'icon-yanwubaojingqi',200,"")
verticalNum6.value.setData(CH2O,'icon-app_icons--',0.08,"mg/m3")
verticalNum7.value.setData(TVOC,'icon-TVOC-Outlined',0.5,"mg/m3")

View File

@ -281,7 +281,7 @@ function setcontentData(val) {
return { name: item.name, val: item.data,status:item.status };
});
// verticalNum3.value.setData(val.FIRE,'icon-ranqi',5,"")
verticalNum4.value.setData(noise, 'icon-shengyin', 120, "dB")
verticalNum4.value.setData(noise, 'icon-shengyin', 85, "dB")
// verticalNum5.value.setData(val.Smoke,'icon-yanwubaojingqi',200,"")
verticalNum6.value.setData(CH2O, 'icon-app_icons--', 0.08, "mg/m3")
verticalNum7.value.setData(TVOC, 'icon-TVOC-Outlined', 0.5, "mg/m3")

View File

@ -280,7 +280,7 @@ function setcontentData(val) {
return { name: item.name, val: item.data,status:item.status };
});
// verticalNum3.value.setData(val.FIRE,'icon-ranqi',5,"")
verticalNum4.value.setData(noise, 'icon-shengyin', 120, "dB")
verticalNum4.value.setData(noise, 'icon-shengyin', 85, "dB")
// verticalNum5.value.setData(val.Smoke,'icon-yanwubaojingqi',200,"")
verticalNum6.value.setData(CH2O, 'icon-app_icons--', 0.08, "mg/m3")
verticalNum7.value.setData(TVOC, 'icon-TVOC-Outlined', 0.5, "mg/m3")

View File

@ -38,8 +38,9 @@
v-model:visible="visible"
:content="tipcontent"
placement="top"
effect="dark"
effect="light"
trigger="click"
popper-class="tooltip-class"
virtual-triggering
:virtual-ref="triggerRef"
/>
@ -187,6 +188,9 @@ p {
justify-content: center;
align-items: center;
}
.el-popper{
color: #fff !important;
}
/* .dv-scroll-board :deep(.row-item) {
line-height: normal !important;
align-items: center;
@ -195,3 +199,8 @@ p {
margin:0px 50px 0px 50px
} */
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -1,5 +1,5 @@
<!--
* @FilePath: \wwwd:\code\screenFront\src\views\InPlantProducts\child\component\RotationTable.vue
* @FilePath: \code\gitscreenFront\src\views\Temp\Large_Format\component\RotationTable.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-16 15:09:06
@ -38,7 +38,8 @@
v-model:visible="visible"
:content="tipcontent"
placement="top"
effect="dark"
effect="light"
popper-class="tooltip-class"
trigger="click"
virtual-triggering
:virtual-ref="triggerRef"
@ -168,4 +169,12 @@ defineExpose({
h2 {
color: #fff;
}
.el-popper{
color: #fff !important;
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -32,8 +32,9 @@
v-model:visible="visible"
:content="tipcontent"
placement="top"
effect="dark"
effect="light"
trigger="click"
popper-class="tooltip-class"
virtual-triggering
:virtual-ref="triggerRef"
/>
@ -221,4 +222,12 @@ p {
justify-content: center;
align-items: center;
}
.el-popper{
color: #fff !important;
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -0,0 +1,150 @@
<template>
<div :class="$style['container']">
<div class="header">
<div class="title">
<header2 ref="headerref" :width="'100%'" :height="'100px'" :title="t('messages.传感器监测走势图')" :titleTip="[]"
:typeFun="['comback', 'time']" :alarmType="[]"></header2>
</div>
</div>
<div class="content">
<lineChart v-for="(calc, index) in calcArr"
:style="{ width: width + 'px', height: height + 'px', 'min-width': 'calc(25% - 20px)' }" :calc="calc">
</lineChart>
</div>
</div>
</template>
<script setup lang='ts'>
import { ref, reactive, onMounted, onUnmounted } from "vue"
import Header2 from "@/components/headerBox/header2.vue"
import lineChart from "./lineChart.vue";
import { getCurrent24Trend } from '@/http/Trend/index'
import { useRoute } from "vue-router";
import { useI18n } from 'vue-i18n'
let { t } = useI18n();
let route = useRoute()
let ids = route.query.ids as string
let unit = route.query.unit as string
let timer = null
document.title = t('messages.传感器监测走势图')
type calcType = {
name: string,
math: {
key: string,
value: {
max: number,
min: number,
avg: number,
data: any[]
}
}[],
data: any[]
}
let calcArr = ref<calcType[]>()
let width = ref(1500)
let height = ref(700)
async function ajax() {
const res: any = await getCurrent24Trend(ids);
let data = []
if (res.code == 200) {
// data = res.data.map((item: any) => {
// if (unit) {
// item.name = item.name + '(' + unit + ')'
// }
// return {
// name: item.name,
// type: item.type,
// max: item.max,
// min: item.min,
// avg: item.avg,
// data: item.date.map((key, value) => [key, item.value[value]])
// }
// })
let tempData = {}
res.data.forEach((item: any) => {
if (unit) {
item.name = item.name + '(' + unit + ')'
}
if (tempData.hasOwnProperty(item.id)) {
tempData[item.id].data.push({
name: item.type,
type: 'line',
showSymbol: false,
data: item.date.map((key, value) => [key, item.value[value]]),
smooth: true,
})
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
}
}]
}
}
})
data = Object.values(tempData)
calcArr.value = data
if (data.length <= 4) {
width.value = 1900 / data.length - (data.length - 1) * 20;
} else if (data.length > 4 && data.length <= 8) {
width.value = width.value / 4 - 3 * 20;
height.value = 950 / 2 - 40;
} else {
width.value = width.value / 4 - 3 * 20;
height.value = 950 / 3 - 60;
}
}
}
onMounted(() => {
ajax()
timer = setInterval(() => {
ajax()
}, 1000 * 60 * 10)
})
onUnmounted(() => {
clearInterval(timer)
})
</script>
<style module>
.container {
height: 1080px;
width: 1920px;
color: #20aec5;
background-color: #100c2a;
box-sizing: border-box;
}
</style>
<style scoped>
.content {
height: 980px;
width: 1920px;
display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
box-sizing: border-box;
padding: 5px;
}
</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

@ -261,7 +261,7 @@ function setcontentData(val) {
});
// verticalNum3.value.setData(val.FIRE,'icon-ranqi',5,"")
verticalNum4.value.setData(noise, 'icon-shengyin', 120, "dB")
verticalNum4.value.setData(noise, 'icon-shengyin', 85, "dB")
// verticalNum5.value.setData(val.Smoke,'icon-yanwubaojingqi',200,"")
// verticalNum6.value.setData(val.TVOC_CH2O.CH2O,'icon-app_icons--',5,"mg/m3")
// verticalNum7.value.setData(val.TVOC_CH2O.TVOC,'icon-TVOC-Outlined',5,"PPM")

View File

@ -1,5 +1,5 @@
<!--
* @FilePath: \wang-vue-worke:\demo\daping\src\views\energyConsume\content\chart\water.vue
* @FilePath: \code\gitscreenFront\src\views\energyConsumeJixiefenchang\content\chart\water.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-14 13:24:12
@ -9,13 +9,13 @@
-->
<template>
<div class="waterborder">
<border4 ref="refborder4">
<div class="gasborder">
<border6 ref="refborder4">
<template v-slot>
<!-- <h1>{{props.title}}</h1> -->
<div ref="water"></div>
<div ref="gas" ></div>
</template>
</border4>
</border6>
</div>
</template>
@ -23,19 +23,17 @@
import {getCurrentInstance, onMounted, reactive, ref} from "vue"
import {EDataPerson,EDataPersonItem} from '@/type/energyConsume'
import 'echarts-liquidfill'
import border4 from "@/components/borderBox/border4.vue"
import border6 from "@/components/borderBox/border6.vue";
const { proxy } = getCurrentInstance() as any;
let props=defineProps<{
title:string,
data:any
}>()
let water=ref()
let gas=ref()
let refborder4=ref()
const echartsData = reactive<EDataPerson>({
water:{
gas:{
div:null,
data:null,
title:'',
@ -43,22 +41,24 @@ const echartsData = reactive<EDataPerson>({
},
})
const setData=()=>{
const setData=(value:any)=>{
echartsData.water!.div=water.value
echartsData.water!.title=props.title
echartsData.water!.data=({
echartsData.gas!.div=gas.value
echartsData.gas!.title=props.title
echartsData.gas!.data=({
title: {
//
text: echartsData.water!.title,
text: echartsData.gas!.title,
textStyle:{
color:'#fff',
fontSize:20
}
},
top:'2%'
},
series: [{
type: 'liquidFill',
radius: '80%', //
shape:'rect',
center: ['50%', '50%'],
waveAnimation: true,
color: [
@ -95,7 +95,9 @@ const setData=()=>{
fontWeight: 'bold',
color: '#fff',
},
formatter:props.data
formatter:function(params){
return value
}
},
},
@ -109,8 +111,7 @@ const setData=()=>{
}],
})
change(echartsData.water)
change(echartsData.gas)
}
const change = (item:EDataPersonItem) => {
@ -123,32 +124,32 @@ item.box = Ebox
};
function setchartWH(width:any,height:any){
echartsData.water!.div=water.value
water.value.style.height=height+'px'
water.value.style.width=width+'px'
// echartsData.water!.div=water.value
gas.value.style.height=height-20+'px'
gas.value.style.width=width+'px'
refborder4.value.resetWH()
if(echartsData.water.box){
echartsData.water.box.resize()
if(echartsData.gas.box){
echartsData.gas.box.resize()
}
}
onMounted(() => {
setData()
// setData()
})
// return{setchartWH}
defineExpose({
setchartWH,
// setData
setData
})
</script>
<style scoped>
.waterBox{
border-radius: 50%;
background-color: #526DC1;
.gasBox{
/* border-radius: 50%; */
background-color: #8CE78D;
color: #fff;
display: flex;
justify-content: center;
@ -156,10 +157,10 @@ defineExpose({
margin: 20px;
font-size: 20px;
}
.waterborder{
.gasborder{
position: relative;
}
.waterborder h1{
.gasborder h1{
position: absolute;
top: 20px;
left:20px;

View File

@ -1,5 +1,5 @@
<!--
* @FilePath: \gitscreenFront\src\views\energyConsumeJixiefenchang\content\top.vue
* @FilePath: \code\gitscreenFront\src\views\energyConsumeJixiefenchang\content\top.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-13 14:43:28
@ -23,7 +23,8 @@
:option="gasOption.option"
ref="ratio"
></chart>
<gas ref="gasref" :title="t('messages.GasConsumption_2023JiXie')"></gas>
<gas ref="gasref" :title="t('messages.gasto2023')"></gas>
<water ref="waterref" :title="t('messages.waterto2023')"></water>
</div>
</el-col>
</el-row>
@ -40,6 +41,7 @@ import chart from "./chart/chartRatio.vue";
import { useRoute, useRouter } from "vue-router";
import { useEnergyConsumeStore } from "@/store/module/energyConsume";
import gas from "./chart/gas.vue";
import water from "./chart/water.vue";
import { useI18n } from 'vue-i18n'
let {t} = useI18n();
const store = useEnergyConsumeStore();
@ -47,6 +49,7 @@ const router = useRouter();
let ratio = ref();
let gasref = ref();
let waterref = ref();
let props = defineProps<{
width: number;
@ -155,8 +158,9 @@ function reset(val: any) {
const powerBox = (width: any, height: any) => {
let a = calcWH(height, width, 1, 4, 0);
//
ratio.value.setchartWH(a.oWidth * 3, a.oHeight);
ratio.value.setchartWH(a.oWidth * 2, a.oHeight);
gasref.value.setchartWH(a.oWidth-20, a.oHeight);
waterref.value.setchartWH(a.oWidth-20, a.oHeight);
};
const clickPowerChart = () => {
router.push({
@ -301,9 +305,29 @@ function changeGas(val) {
}
});
// gasOption.option.xAxis.data=x
// gasOption.option.series[0].data=y
// gas1.value.changeData(gasOption.option)
}
watch(
() => store.nowYearWater,
(newVal, oldVal) => {
if (!newVal) {
return;
} else {
if (newVal.length == 0) {
return;
}
}
changeWater(newVal);
},
{ deep: true, flush: "post" }
);
function changeWater(val) {
val.forEach((res) => {
if(res.deptName=='生产区'){
waterref.value.setData(res.usageNum);
}
});
}
onMounted(() => {

View File

@ -1,6 +1,6 @@
<template>
<div class="content-right">
<el-row >
<el-row @click="toPmData">
<el-col :span="8">
<border2 ref="borderElectriccontrol">
<template v-slot>
@ -44,9 +44,11 @@
// import { getHumitureData,getPmtenData, getPmtwoData } from "@/http/environment";
import { onMounted, reactive, ref, watch } from "vue"
import { useSocketStore } from "@/store/moduleSocket"
import { useRouter } from "vue-router";
import { useI18n } from 'vue-i18n'
let { t } = useI18n();
const store = useSocketStore()
const router = useRouter()
let props = defineProps<{
width: number,
height: number,
@ -155,20 +157,47 @@ async function getPmtenDatafun(){
async function getPmData() {
// let resulttwo:any = await getPmtwoData()
// let resultten:any = await getPmtenData()
// 083e3900-3435-11ed-a7e1-fd42bca6c8c6
// bcbfb530-88b2-11ed-a926-570995ad0254
// 01336fd0-1fa0-11ed-9223-7db1174970a8
let arr = ['01336fd0-1fa0-11ed-9223-7db1174970a8', '083e3900-3435-11ed-a7e1-fd42bca6c8c6', 'bcbfb530-88b2-11ed-a926-570995ad0254']
let data = reactive({ welding: { two: null, ten: null }, stuff: { two: null, ten: null }, ornaments: { two: null, ten: null } })
Promise.all([getPmtwoDatafun(), getPmtenDatafun()]).then((res) => {
if (res) {
res[0].data.forEach(ele => {
if(data[ele.enName]){
data[ele.enName].two=ele.value
switch (ele.devId) {
case '083e3900-3435-11ed-a7e1-fd42bca6c8c6':
data.welding.two = ele.value
break;
case 'bcbfb530-88b2-11ed-a926-570995ad0254':
data.ornaments.two = ele.value
break;
case '01336fd0-1fa0-11ed-9223-7db1174970a8':
data.stuff.two = ele.value
break;
default:
break;
}
})
}
if (res) {
res[1].data.forEach(ele => {
if(data[ele.enName]){
data[ele.enName].ten=ele.value
switch (ele.devId) {
case '083e3900-3435-11ed-a7e1-fd42bca6c8c6':
data.welding.ten = ele.value
break;
case 'bcbfb530-88b2-11ed-a926-570995ad0254':
data.ornaments.ten = ele.value
break;
case '01336fd0-1fa0-11ed-9223-7db1174970a8':
data.stuff.ten = ele.value
break;
default:
break;
}
})
}
@ -201,6 +230,10 @@ async function getPmData(){
}
function toPmData() {
router.push({ path: '/pmData' })
}
onMounted(() => {
gethumitureData()
getPmData()
@ -211,6 +244,5 @@ onMounted(()=>{
.content-right {
width: 100%;
}
</style>

View File

@ -0,0 +1,168 @@
<!--
* @FilePath: \code\gitscreenFront\src\views\generalEnvironmentMechanical\components\gas.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-14 13:24:12
* @Description:
*
* 版权信息 : 2023 by ${再登软件}, All Rights Reserved.
-->
<template>
<!-- <h1>{{props.title}}</h1> -->
<div ref="gas" class="gas-echarts-class"></div>
</template>
<script setup lang="ts">
import {getCurrentInstance, onMounted, onUpdated, reactive, ref, watch} from "vue"
import {EDataPerson,EDataPersonItem} from '@/type/energyConsume'
import 'echarts-liquidfill'
const { proxy } = getCurrentInstance() as any;
let props=defineProps<{
title:string,
value:any;
color:{
step0:string,
step1:string,
border:string
color:string
};
}>()
let gas=ref()
let refborder4=ref()
const echartsData = reactive<EDataPerson>({
gas:{
div:null,
data:null,
title:'',
box:null
},
})
const setData=()=>{
echartsData.gas!.div=gas.value
echartsData.gas!.title=props.title
echartsData.gas!.data=({
title: {
//
text: echartsData.gas!.title,
textStyle:{
color:'#fff',
fontSize:20
},
top:'2%'
},
series: [{
type: 'liquidFill',
radius: '80%', //
shape:'rect',
center: ['50%', '50%'],
waveAnimation: true,
color: [
{
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: props.color.step0,
},
{
offset: 1,
color: props.color.step1,
},
],
globalCoord: false,
},
],
data: [0.7,0.7], // data
amplitude: 10, //
backgroundStyle: {
borderWidth: 2, //
borderColor:props.color.border,//
color: props.color.color, //
},
label: {
normal: {
textStyle: {
fontSize: 24,
fontWeight: 'bold',
color: '#fff',
},
formatter:function(params){
return props.value
}
},
},
outline: {
borderDistance: 0,
itemStyle: {
borderWidth: 4,
borderColor: 'transparent',
},
},
}],
})
change(echartsData.gas)
}
const change = (item:EDataPersonItem) => {
let Ebox;
if (!item.box) {
Ebox = proxy.$echarts.init(item.div, "dark");
} else {
Ebox = item.box;
}
Ebox.setOption(item.data);
item.box = Ebox;
};
onUpdated(() => {
setData()
})
// watch(() => props.value, (val) => {
// console.log(val);
// setData()
// }, { deep: true })
onMounted(() => {
setData()
})
</script>
<style scoped>
.gasBox{
/* border-radius: 50%; */
background-color: #8CE78D;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
margin: 20px;
font-size: 20px;
}
.gasborder{
position: relative;
}
.gasborder h1{
position: absolute;
top: 20px;
left:20px;
color: #fff;
}
.gas-echarts-class{
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,266 @@
<template>
<border13 :color="errList.length>0?borderColor:[]">
<div class="container">
<div class="errList">
<div class="err-item icon-red" v-for="item in errList">{{ item.name }}</div>
</div>
<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/moduleSocketMechanics";
import border13 from '@/components/border/Border13.vue'
const { proxy } = getCurrentInstance() as any;
const store = useSocketStore();
let index = 0;
let humiture = ref();
let chart = null
let timer = null
const props = defineProps<{
top: any;
bottom: any;
}>();
let errList = computed(() => {
let arr = JSON.parse(JSON.stringify(store.humiture.filter(item=>{
return item.temp>props.top.temp||item.temp<props.bottom.temp||item.humidity>props.top.hum||item.humidity<props.bottom.hum
}))).map(item=>{
item.name = item.name.split('车间')[0]
return item
})
return arr;
})
const borderColor = ["#E43961","#E43961"]
function init() {
if (!chart) {
chart = proxy.$echarts.init(humiture.value, 'dark');
}
let option = {
title: {
text: store.humiture[index].name+"温湿度",
show: true,
textStyle: {
color: "#fff",
fontSize: 18,
},
top: 5
},
grid: {
//
top: "0px",
left: "0px",
right: "0px",
bottom: "0px",
},
series: [
{
type: "gauge",
center: ["50%", "85%"],
startAngle: 190,
endAngle: -10,
radius: "50%",
min: -30,
max: 70,
splitNumber: 10,
progress: {
show: false,
width: 5
},
pointer: {
itemStyle: {
color: 'inherit'
}
},
//
axisLine: {
lineStyle: {
width: 10,
color: [
[0.15, '#FF6E76'],
[0.75, '#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[index].temp
}
]
},
{
type: "gauge",
center: ["50%", "50%"],
startAngle: 200,
endAngle: -20,
min: 0,
max: 100,
progress: {
show: false,
width: 5
},
pointer: {
itemStyle: {
color: 'inherit'
}
},
//
axisLine: {
lineStyle: {
width: 10,
color: [
[0.15, '#FF6E76'],
[0.75, '#7CFFB2'],
[1, '#FF6E76']
]
}
},
//线
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[index].humidity
}
]
},
],
};
chart.setOption(option);
}
onMounted(() => {
init();
timer = setInterval(() => {
index = index + 1;
if (index >= store.humiture.length) {
index = 0;
}
init();
}, 5000);
});
onUnmounted(() => {
clearInterval(timer);
});
</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: calc(100% - 50px);
}
.icon-red {
color: #e43961;
animation: redstart 2s infinite;
font-size: 14px;
/* position: relative; */
/* top: -15px; */
}
.err-item {
margin: 0 10px;
}
@keyframes redstart {
0% {}
50% {
text-shadow: #fff 1px 0 10px;
}
100% {}
}
</style>

View File

@ -0,0 +1,198 @@
<template>
<div class="content-big" ref="humiture"></div>
</template>
<script setup lang='ts'>
import { getCurrentInstance, onMounted, reactive, ref, watch } from "vue";
import { useI18n } from 'vue-i18n'
let { t } = useI18n();
const { proxy } = getCurrentInstance() as any;
const props = defineProps<{
title: any;
data: any;
bottom: any;
top: any;
}>();
let humiture = ref();
let chart = null
watch(() => props, (val) => {
init()
}, { deep: true })
function init() {
if (!chart) {
chart = proxy.$echarts.init(humiture.value, "dark");
}
let option = {
title: {
text: props.title,
top: '2%'
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
},
legend: {
// bottom: "3%",
top: '6%'
},
grid: {
top: "15%",
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
color: ["#4992FF", "#7CFFB2", "#FF6E76"],
xAxis: {
type: "category",
data: props.data.list,
axisLabel: {
interval: 0
}
},
yAxis: {
type: "value",
boundaryGap: [0, 0.01],
axisLabel: {
formatter: "{value} (°C/%RH)",
},
},
series: [
{
name: `${t('messages.TemperatureRange')}(°C)(${t('messages.fanwei')}${props.bottom.temp}°C - ${props.top.temp}°C)`,
type: "bar",
data: props.data.temp,
barWidth: '30%',
itemStyle: {
color: function (params) {
var index_color = params.value;
if (
index_color <= props.bottom.temp ||
index_color >= props.top.temp
) {
return "#FF6E76";
} else {
return "#4992FF";
}
},
},
label: {
formatter: "{c} °C",
show: true,
position: "top",
textStyle: {
color: "rgb(255,255,255,0.9)",
},
},
markLine: {
//
silent: true, //线
symbol: "none", //
data: [
{
name: t('messages.TemperatureRange'),
yAxis: props.bottom.temp,
label: {
formatter: `${t('messages.TemperatureRange')}${t('messages.TemperatureRange_down')} ${props.bottom.temp} °C`,
position: "middle",
},
lineStyle: {
color: "yellow", // 线
},
},
{
name: t('messages.TemperatureRange'),
yAxis: props.top.temp,
label: {
formatter: `${t('messages.TemperatureRange')}${t('messages.TemperatureRange_up')}${props.top.temp} °C`,
position: "middle",
},
lineStyle: {
color: "yellow", // 线
},
},
],
},
},
{
name: `${t('messages.HumidityRange')}(%RH)(${t('messages.fanwei')}${props.bottom.humidity}%RH - ${props.top.humidity}%RH)`,
type: "bar",
data: props.data.humidity,
barWidth: '30%',
itemStyle: {
color: function (params) {
var index_color = params.value;
if (
index_color <= props.bottom.humidity ||
index_color >= props.top.humidity
) {
return "#FF6E76";
} else {
return "#7CFFB2";
}
},
},
label: {
formatter: "{c} %RH",
show: true,
position: "top",
textStyle: {
color: "rgb(255,255,255,0.9)",
},
},
markLine: {
//
silent: true, //线
symbol: "none", //
data: [
{
name: "湿度",
yAxis: props.bottom.humidity,
label: {
formatter: `${t('messages.HumidityRange')}${t('messages.TemperatureRange_down')}` + props.bottom.humidity + "%RH",
position: "middle",
},
lineStyle: {
color: "red", // 线
},
},
{
name: "湿度",
yAxis: props.top.humidity,
label: {
formatter: `${t('messages.HumidityRange')}${t('messages.TemperatureRange_up')}` + props.top.humidity + "%RH",
position: "middle",
},
lineStyle: {
color: "red", // 线
},
},
],
},
},
{
name: t('messages.TemperatureHumidityexceeded'),
type: "bar",
color: '#FF6E76'
}
],
};
chart.setOption(option);
}
onMounted(() => {
// init()
})
</script>
<style scoped>
.content-big {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,288 @@
<template>
<div ref="pipe" class="pipebox"></div>
</template>
<script setup lang="ts">
import { getCurrentInstance, nextTick, onMounted, onUpdated, reactive, ref, watch } from "vue";
import { EDataPerson, EDataPersonItem } from "@/type/realtimeSecurity";
import border6 from "@/components/borderBox/border6.vue";
import { useI18n } from "vue-i18n";
let { t } = useI18n();
const { proxy } = getCurrentInstance() as any;
let props = defineProps<{
title: string;
value: any;
}>();
let pipe = ref();
let refborder3 = ref();
const echartsData = reactive<EDataPerson>({
pipe: {
div: null,
data: null,
title: "",
box: null,
},
});
const setData = () => {
let x = [];
let y = [];
let sumx = [];
props.value.listData.forEach((res) => {
x.push(res.name);
});
let newx = [...new Set(x)];
newx.forEach((ele) => {
let count = 0;
props.value.listData.forEach((res) => {
if (ele == res.name) {
count++;
}
});
sumx.push({ name: ele, val: 1, sum: count });
count = 0;
});
sumx.forEach((ele) => {
props.value.listData.forEach((res) => {
let color1 = rgb();
if (ele.name == res.name)
y.push({
name: res.devName,
value: [
newx.map((item) => item).indexOf(res.name),
0,
res.value,
ele.val++,
ele.sum,
],
});
});
});
echartsData.pipe!.div = pipe.value;
echartsData.pipe!.title = props.title;
echartsData.pipe!.data = {
title: {
text: echartsData.pipe!.title,
show: true,
textStyle: {
color: "#fff",
fontSize: 20,
},
top: "1%",
},
grid: {
top: "15%",
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
tooltip: {
trigger: "item",
axisPointer: {
type: "shadow",
},
},
legend: {
top: "5%",
},
xAxis: {
type: "category",
data: newx,
},
yAxis: {
type: "value",
// axisLabel: {
// formatter: "{value} mpa",
// },
},
// dataset:{
// dimensions: x,
// source: y
// },
// series:server
series: [
{
type: "custom",
renderItem: renderItem1,
itemStyle: {
color: function (params) {
var index_color = params.value[2];
if (index_color >= props.value.top.value) {
return "#FF6E76";
} else {
return "#4992FF";
}
},
},
label: {
show: true,
normal: {
formatter: function (params) {
return params.value[2];
},
show: true,
position: "top",
textStyle: {
color: "rgb(255,255,255,0.9)",
},
},
},
tooltip: {
trigger: "item",
axisPointer: {
type: "shadow",
},
formatter: function (params) {
return !(params.value[2] == "0.0")
? params.name + ":" + params.value[2] + "Mpa"
: "";
},
},
// labelLayout: (params, api) => {
// console.log(params, api);
// return {
// x: params.rect.x ,
// y: params.rect.y + params.rect.height / 2,
// verticalAlign: "middle",
// align: "left",
// text:'1'
// };
// },
// itemStyle: { normal: { opacity: 0.8 } },
encode: {
y: 2,
x: 0,
tooltip: [0, 1, 2], //
itemName: 3,
},
data: y,
},
{
type: "bar",
name: `${t("messages.normal_Tip")}(0mpa - ` + props.value.top.value + "mpa)",
color: "#4992FF",
},
{
type: "bar",
name: `${t("messages.abnormal_Tip")}(${props.value.top.value}mpa ${t(
"messages.abnormal_Tip_yishang"
)})`,
color: "#FF6E76",
},
],
};
change(echartsData.pipe);
};
let renderItem1 = (params, api) => {
// console.log(params,"?????????????????");
let categoryIndex = api.value(0);
let start = api.coord([categoryIndex, api.value(1)]);
let end = api.coord([categoryIndex, api.value(2)]);
let width = api.size([0, api.value(4)])[0] * 0.6;
const num = api.value(4); //
const currentIndex = api.value(3);
const isOdd = num % 2 === 0;
const midN = isOdd ? num / 2 : (num + 1) / 2;
var rect = null;
width = width / num;
let rectX = start[0] - width / 2;
const FIXED_WIDTH = 2; //
// { itemStyle: { normal: { color: 'lightgreen' } }, name: '2011', value: [0, 0, 150, 2, 5] }
// value {}0y(0)1
if (num > 1) {
if (isOdd) {
if (currentIndex <= midN) {
//
rectX =
start[0] -
width / 2 -
width / 2 +
(currentIndex - midN) * width -
FIXED_WIDTH * (midN + 1 - currentIndex);
} else {
//
rectX =
start[0] -
width / 2 +
width / 2 +
(currentIndex - midN - 1) * width +
FIXED_WIDTH * (currentIndex - midN);
}
} else {
rectX =
start[0] - width / 2 + (currentIndex - midN) * (width + FIXED_WIDTH);
}
}
rect = {
type: "rect",
shape: proxy.$echarts.graphic.clipRectByRect(
{ x: rectX, y: end[1], width: width, height: start[1] - end[1] },
{
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height,
}
),
style: api.style(),
};
return rect;
};
function rgb() {
//rgb
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
return `rgb(${r},${g},${b})`;
}
const change = (item: EDataPersonItem) => {
let Ebox;
if (!item.box) {
Ebox = proxy.$echarts.init(item.div, "dark");
} else {
Ebox = item.box;
}
Ebox.setOption(item.data);
item.box = Ebox;
};
onUpdated(() => {
setData()
})
watch(() => props.value, (val) => {
setData()
}, { deep: true })
onMounted(() => {
setData()
});
// return{setchartWH}
</script>
<style scoped>
.pipebox {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,273 @@
<template>
<border13 :color="errList.length>0?borderColor:[]">
<div class="container">
<div class="errList">
<div class="err-item icon-red" v-for="item in errList">{{ item.name }}</div>
</div>
<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/moduleSocketMechanics";
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)
let timer = null
const props = defineProps({
pm10limit:{
type:Number,
default:150
},
pm25limit:{
type:Number,
default:75
}
})
let errList = computed(() => {
let arr = JSON.parse(JSON.stringify(store.pm.filter(item=>{
return +item.pm10>props.pm10limit||+item.pm25>props.pm25limit
}))).map(item=>{
item.name = item.name.split('车间')[0]
return item
})
if (arr.length>0) {
//name
let nameArr = []
arr = arr.filter(item=>{
if (nameArr.indexOf(item.name)===-1) {
nameArr.push(item.name)
return true
}else{
return false
}
})
}
return arr;
})
const borderColor = ["#E43961","#E43961"]
function init() {
if (!chart.value) {
chart.value = proxy.$echarts.init(dust.value, 'dark');
}
let option = {
title: {
text: store.pm[index].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[index].pm25,
name: "PM2.5",
},
],
},
{
type: "gauge",
center: ["50%", "50%"],
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[index].pm10,
name: "PM10",
},
],
},
],
};
chart.value.setOption(option);
}
onMounted(() => {
init();
timer = setInterval(() => {
index = index + 1;
if (index >= store.pm.length) {
index = 0;
}
init();
}, 5000);
});
onUnmounted(() => {
clearInterval(timer);
})
</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: calc(100% - 50px);
}
.icon-red {
color: #e43961;
animation: redstart 2s infinite;
font-size: 14px;
/* position: relative; */
/* top: -15px; */
}
.err-item {
margin: 0 10px;
}
@keyframes redstart {
0% {}
50% {
text-shadow: #fff 1px 0 10px;
}
100% {}
}
</style>

View File

@ -0,0 +1,92 @@
<template>
<div class="container">
<border4 ref="refborder4">
<template v-slot>
<div ref="power"></div>
</template>
</border4>
</div>
</template>
<script setup lang='ts'>
import { getCurrentInstance, onMounted, reactive, ref,watch,onUpdated } from "vue"
import border4 from "@/components/borderBox/border6.vue"
const { proxy } = getCurrentInstance() as any;
let props = defineProps<{
title: string,
series: any,
listName:string[]
}>()
let power = ref()
let Ebox = null
function init() {
Ebox = proxy.$echarts.init(power.value, "dark");
let option = {
title: {
text: props.title,
show: true,
textStyle: {
color: '#fff',
fontSize: 20
},
top: '3%',
},
tooltip: {
trigger: 'item',
axisPointer: {
// Use axis to trigger tooltip
type: 'shadow', // 'shadow' as default; can also be 'line' or 'shadow',
axis: 'auto',
},
},
// color:color,
legend: {
type: 'scroll',
// width:400,
// right:20,
top: '11%',
// itemStyle:{
// data:yue
// },
},
grid: {
top: "20%",
left: "3%",
right: "10%",
bottom: "3%",
containLabel: true,
},
xAxis: {
type: 'value',
splitLine: {
show: false
}
},
yAxis: {
type: 'category',
data: props.listName
},
series: props.series
};
Ebox.setOption(option)
}
watch(props,(newVal)=>{
},{deep:true})
onMounted(()=>{
init()
})
</script>
<style scoped>
.container {
width: 100%;
height: 100%;
box-sizing: border-box;
}
</style>

View File

@ -0,0 +1,276 @@
<!--
* @FilePath: \code\gitscreenFront\src\views\generalEnvironmentMechanical\components\power2023.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-13 15:04:23
* @Description:
*
* 版权信息 : 2023 by ${再登软件}, All Rights Reserved.
-->
<template>
<div ref="power" class="power-class"></div>
</template>
<script setup lang="ts">
import { getCurrentInstance, onMounted, onUpdated, reactive, ref } from "vue";
import { EDataPerson, EDataPersonItem } from "@/type/energyConsume";
import { accAdd } from "@/utils/precision";
import border4 from "@/components/borderBox/border6.vue";
const { proxy } = getCurrentInstance() as any;
let props = defineProps<{
title: string;
seriesVal: any[];
httpValue: any;
}>();
let power = ref();
let refborder4 = ref();
const echartsData = reactive<EDataPerson>({
power: {
div: null,
data: null,
title: "",
box: null,
},
});
const initEchart = () => {
if (props.httpValue.listData) {
let series = [];
props.httpValue.listData.forEach((res) => {
if (res.years == 2023) {
for (let key in res.month) {
series.push({
name: key + "月",
type: "bar",
stack: res.years,
emphasis: {
focus: "coordinateSystem",
label: {
show: true,
formatter: function (value, index) {
return value.value.toLocaleString();
},
},
},
data: res.month[key],
});
}
}
});
//data0
let data0 = [];
for (let i = 1; i <= props.httpValue.name.length; i++) {
data0.push(0);
}
series.push({
name: "",
type: "bar",
data: data0,
color: "#bbf",
stack: props.httpValue.listData[1].years,
barWidth: 40,
label: {
show: true,
position: "right",
color: "#fff",
},
});
}
echartsData.power!.div = power.value;
echartsData.power!.title = props.title;
echartsData.power!.data = {
title: {
text: echartsData.power!.title,
show: true,
textStyle: {
color: "#fff",
fontSize: 20,
},
top: "3%",
},
tooltip: {
trigger: "item",
axisPointer: {
// Use axis to trigger tooltip
type: "shadow", // 'shadow' as default; can also be 'line' or 'shadow',
axis: "auto",
},
},
// color:color,
legend: {
type: "scroll",
// width:400,
// right:20,
top: "11%",
// itemStyle:{
// data:yue
// },
},
grid: {
top: "20%",
left: "3%",
right: "10%",
bottom: "3%",
containLabel: true,
},
xAxis: {
type: "value",
splitLine: {
show: false,
},
},
yAxis: {
type: "category",
data: props.httpValue?.name,
},
series: props.seriesVal,
};
change(echartsData.power, props.httpValue);
};
const change = (item: EDataPersonItem, value: any) => {
let Ebox;
if (!item.box) {
Ebox = proxy.$echarts.init(item.div, "dark");
} else {
Ebox = item.box;
}
clacChartsSum(item.data, value);
Ebox.setOption(item.data);
item.box = Ebox;
changeecharts(item.data, value);
};
/**
* @函数功能: 修改用电量总数数值的标签
* @param {*} option echarts数据
* @param {*} value api接收数据
* @出口参数:
* @函数备注:
*/
const clacChartsSum = (option: any, value: any) => {
var series = option.series;
// function getSum1 (params) {
// let stack=value.listData[0].years
// var datavalue = 0
// for (var i = 0; i < series.length; i++) {
// if(series[i].stack==stack){
// // datavalue += series[i].data[params.dataIndex]
// datavalue=accAdd(datavalue,series[i].data[params.dataIndex])
// }
// }
// return datavalue ? stack+'/'+ datavalue+'kw.h' : null
// }
function getSum2(params) {
let stack = value.listData[1].years;
var datavalue = 0;
for (var i = 0; i < series.length; i++) {
if (series[i].stack == stack) {
// datavalue += series[i].data[params.dataIndex]
datavalue = accAdd(datavalue, series[i].data[params.dataIndex]);
}
}
return datavalue ? datavalue.toLocaleString() : null;
}
if (series.length) {
series[series.length - 1].label.formatter = getSum2;
}
// series[series.length - 2].label.formatter = getSum1
};
/**
* @函数功能: 修改用电量总数数值的标签
* @param {*} option echarts数据
* @param {*} value api接收数据
* @出口参数:
* @函数备注:
*/
const changeecharts = (option: any, value: any) => {
var series = option.series;
echartsData.power.box.on("legendselectchanged", (obj) => {
//
function getSum2(params) {
let stack = value.listData[1].years;
var datavalue = 0;
for (var i = 0; i < series.length; i++) {
if (obj.selected[series[i].name]) {
if (series[i].stack == stack) {
// datavalue += series[i].data[params.dataIndex]
datavalue = accAdd(datavalue, series[i].data[params.dataIndex]);
}
}
}
return datavalue ? datavalue.toLocaleString() : null;
}
if(series.length){
series[series.length - 1].label.formatter = getSum2;
}
// series[series.length - 2].label.formatter = getSum1
echartsData.power.box.setOption(option);
});
function getSum2(params) {
let stack = value.listData[1].years;
var datavalue = 0;
for (var i = 0; i < series.length; i++) {
if (series[i].stack == stack) {
// datavalue += series[i].data[params.dataIndex]
datavalue = accAdd(datavalue, series[i].data[params.dataIndex]);
}
}
return datavalue ? datavalue.toLocaleString() : null;
}
if (series.length) {
series[series.length - 1].label.formatter = getSum2;
}
// series[series.length - 2].label.formatter = getSum1
};
let boxWH = reactive({
width: "0px",
height: "0px",
});
function setchartWH(width: any, height: any) {
echartsData.power!.div = power.value;
power.value.style.height = height + "px";
power.value.style.width = width + "px";
boxWH.height = height + 30 + "px";
boxWH.width = width + "px";
refborder4.value.resetWH();
if (echartsData.power.box) {
echartsData.power.box.resize();
}
}
onUpdated(() => {
initEchart();
});
onMounted(() => {
initEchart();
});
// return{setchartWH}
defineExpose({
setchartWH,
});
</script>
<style scoped>
.power-class {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,238 @@
<template>
<div ref="numBox1" :key="keynum" :style="{ height: '100%', width: '97%' }">
<border6 ref="refborder3" :color="borderColor">
<template v-slot>
<div class="box" ref="classBox1">
<div class="icontip">
<div v-for="items in value" style="margin: auto 5px;" v-show="(+items.val > +limit)&&items.status">
<el-popover placement="bottom" :width="250" trigger="hover"
:popper-style="{ 'background-color': 'rgba(0,0,0,.8)' }">
<ul class="icontipBox">
<li>
<p class="t-right">{{t('messages.position')}}</p>
<p>{{ items.name }}</p>
</li>
<li>
<p class="t-right">{{t('messages.NormalRange')}}</p>
<p>{{ limit }} {{unit}}</p>
</li>
<li>
<p class="t-right">{{t('messages.CurrentValue')}}</p>
<p>{{ items.val }} {{unit}}</p>
</li>
<li>
<p class="t-right">{{t('messages.AlarmTime')}}</p>
<p>{{ items.date }}</p>
</li>
<li>
<p class="t-right">{{t('messages.duration')}}</p>
<p>{{ items.continuous }}</p>
</li>
</ul>
<template #reference>
<!-- <i :class="+items.val > +limit
? 'iconfont ' + icon + ' icon-red iconsmall-size'
: 'iconfont ' + icon + ' icon-blue iconsmall-size'
"></i> -->
<text :class="+items.val > +limit
? ' icon-red iconsmall-size cursor'
: ' icon-blue iconsmall-size'
">{{ items.name.split('车间')[0]}}</text>
</template>
</el-popover>
</div>
</div>
<!-- <h2>{{ `${t(item.i18n[0])}${t(item.i18n[1])}`}}</h2> -->
<h2>{{ item.name}}</h2>
<i :class="['iconfont',icon,iconcolor,'iconbig-size']"></i>
<p class="unit" v-if="unit&&item.status">
<p class="num">{{item.val}}</p>
<span>{{ unit }}</span>
</p>
<!-- <p class="unit"><p v-show="value.data&&value.unit" :class="'num'">{{value.data}}</p><span>{{value.unit}}</span></p> -->
<!-- </div> -->
</div>
</template>
</border6>
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch,onUnmounted } from "vue";
// import border3 from "@/components/borderBox/border3.vue";
import border6 from "@/components/borderBox/border6.vue";
import { useI18n } from 'vue-i18n'
let {t} = useI18n();
let i =ref(0)
let timer = null;
let item:any = computed(() => {
return props.value[i.value];
});
let iconcolor = computed(() => {
return props.value[i.value].status?props.value[i.value].val > props.limit ? "icon-red" : "icon-blue":"icon-grey";
});
let borderColor = computed(() => {
let type = props.value.find((items: any) => {
if (+items.val > +props.limit&&items.status) {
return true;
}
});
return type ? ["#E43961","#E43961"] : [];
});
let props = defineProps<{
title: string;
icon: string;
limit: string | number;
unit: string|null;
value: Array<any>;
}>();
let keynum = ref(0);
let refborder3 = ref();
let numBox1 = ref();
const classBox1 = ref();
onMounted(() => {
timer = setInterval(() => {
i.value++;
if (i.value >= props.value.length) {
i.value = 0;
}
}, 5000);
});
onUnmounted(() => {
clearInterval(timer);
})
const boxSize = reactive({
height: "",
width: "",
});
</script>
<style scoped>
@import "@/assets/css/iconfont.css";
.box {
height: 50%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
}
/* .contentbox{
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
} */
h2 {
color: #fff;
}
p {
color: #fff;
}
.iconbig-size {
font-size: 70px;
}
.iconsmall-size {
font-size: 14px;
}
.cursor {
cursor: pointer;
}
.icon-red {
color: #e43961;
animation: redstart 2s infinite;
/* position: relative; */
/* top: -15px; */
}
.icon-grey {
color: rgb(167, 166, 189);
/* position: relative; */
/* top: -15px; */
}
.icon-blue {
color: #20aec5;
/* position: relative; */
/* top: -15px; */
}
/* .icon-red, .icon-blue { */
/* margin-bottom: 20%; */
/* } */
.num {
font-size: 16px;
}
.unit {
display: flex;
justify-content: center;
align-items: center;
vertical-align: top;
font-size: 16px;
height: 0;
width: 100px;
}
.icontip {
display: flex;
margin-top: -60px;
width: 150px;
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;
}
.t-center {
text-align: center;
}
.t-left {
text-align: left;
}
/* .icontipBox li p:nth-child(1) {
min-width:80px;
display: flex;
font-size: 18px;
}
.icontipBox li:nth-child(2) {
} */
@keyframes redstart {
0% {}
50% {
text-shadow: #fff 1px 0 10px;
}
100% {}
}
</style>

View File

@ -0,0 +1,476 @@
<template>
<div :class="$style['container']">
<div class="header">
<div class="title">
<header2 ref="headerref" :width="'100%'" :height="'150px'" :title="t('messages.环境 实时监测系统')"
:titleTip="titleTip" :typeFun="['AbnormalData', 'time']"
:alarmType="['noiseAlarm', 'temphuim', 'dustAlarm', 'saving']"></header2>
</div>
</div>
<div class="content" ref="Acontent">
<div class="top-box">
<div class="top-box-item" v-for="item in store.newVerticalNum">
<verticalNumLoop @click="gotoTrendChart(item.value, item.unit)" :title="item.title" :icon="item.icon"
:limit="item.limit" :unit="item.unit" :value="item.value"></verticalNumLoop>
</div>
<div class="top-box-item" @click="gotoTrendChart(store.pm, 'μg/m3')">
<pm :pm10limit="150" :pm25limit="75"></pm>
</div>
<div class="top-box-item" @click="gotoTrendChart(store.humiture, '℃/%RH')">
<humidity :top="humidityTop" :bottom="humidityBottom"></humidity>
</div>
</div>
<div class="bottom-box">
<div style="width: 33%;height: 100%;">
<border13>
<pipe :title="t('messages.PipelinePressure_Mpa')" :value="pipeData"></pipe>
</border13>
</div>
<div style="width: 33%;height: 100%;">
<border13>
<power :title="powerData.title" :seriesVal="powerData.seriesVal" :httpValue="powerData.value">
</power>
</border13>
</div>
<div style="width: 16%;height: 100%;">
<border13>
<!-- <humidityBar :title="'温湿度'" :data="humidityData" :bottom="humidityBottom" :top="humidityTop">
</humidityBar> -->
<gas :title="t('messages.gashistory')" :value="gasData"
:color="gascolor"></gas>
</border13>
</div>
<div style="width: 16%;height: 100%;">
<border13>
<!-- <humidityBar :title="'温湿度'" :data="humidityData" :bottom="humidityBottom" :top="humidityTop">
</humidityBar> -->
<gas :title="t('messages.waterhistory')" :value="waterData"
:color="watercolor"></gas>
</border13>
</div>
</div>
</div>
</div>
</template>
<script setup lang='ts'>
import { ElMessage, ElMessageBox } from 'element-plus'
import { onMounted, onUnmounted, reactive, ref, watch } from 'vue'
import header2 from '@/components/headerBox/header2.vue'
import verticalNumLoop from './components/verticalNumLoop.vue'
import power from './components/power2023.vue';
import pm from './components/pm.vue';
import humidityBar from './components/humidityBar.vue';
import humidity from './components/humidity.vue';
import gas from './components/gas.vue'
import pipe from './components/pipe.vue'
import border13 from '@/components/border/Border13.vue'
import { getSafeWarningData, getpipeData } from "@/http/realtimeSecurity";
import { getnoiseData } from "@/http/generalEnvironment";
import { getHumitureData, getPmtenData, getPmtwoData } from "@/http/generalEnvironment";
import { getPowerData, getconsumeDetail } from "@/http/energyConsume";
import { useSocketStore } from "@/store/moduleSocketMechanics";
import { connectWebsocket, closeWebsocket } from "@/utils/websocket";
import { gettime, clacendTime } from "@/utils/time"
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { hu } from 'element-plus/es/locale';
let { t } = useI18n();
let router = useRouter()
const store = useSocketStore();
let deptIds = '6,7,9,10,11'
document.title = t('messages.环境 实时监测系统')
let titleTip = [
{
color: "#E43961",
name: t('messages.abnormal'),
},
{
color: "#20AEC5",
name: t('messages.NoAbnormal'),
},
{
color: "#A7A6BD",
name: t('messages.disconnection'),
},
];
const verticalType = {
'TVOC': { icon: 'icon-TVOC-Outlined', title: t('messages.TVOCDetection'), unit: 'mg/m³' },
'Smoke': { icon: 'icon-yanwubaojingqi', title: t('messages.smokeDetection'), unit: "ppm" },
'Methane': { icon: 'icon-ranqi', title: t('messages.gasDetection'), unit: null },
'CH2O': { icon: 'icon-app_icons--', title: t('messages.CH2ODetection'), unit: 'mg/m³' },
'FIRE': { icon: 'icon-weibiaoti1', title: t('messages.flameDetection'), unit: null },
'noise': { icon: 'icon-shengyin', title: t('messages.noiseDetection'), unit: 'dB' },
}
/**用电量 */
let powerData = ref({ value: { name: [] }, seriesVal: [], title: t('messages.Powerto2023') })
let gasData = ref(0)
let waterData = ref(0)
let pipeData = ref({ listData: [], top: 0 })
let headerref = ref()
let verticalList: any[] = reactive([])
let pmtimer = null
let humidityTop = ref({})
let humidityBottom = ref({})
/**
* 跳转到趋势图
*/
function gotoTrendChart(value, unit) {
let ids = value.map((item) => item.devId).toString();
ElMessageBox.confirm(
'即将跳转到传感器监测走势图页面,是否继续?',
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'info',
}
)
.then(() => {
router.push({ path: '/TrendChart', query: { ids: ids, unit: unit } })
})
.catch(() => {
})
}
//
async function getSensorData() {
let list = []
const res: any = await Promise.all([
getnoiseData({ deptIds }),
getSafeWarningData({ deptIds }),
])
let noiseData = {
limit: res[0].data.top.value,
type: 'noise',
value: res[0].data.listData.map((item: any) => {
return {
devId: item.devId,
name: item.name + '噪音监测',
type: 'noise',
status: true,
val: item.value,
}
})
}
list.push(noiseData);
list.push(...res[1].data)
let datetime = new Date().getTime();
let handle_vertical = list.map((item: any) => {
item.value.forEach(element => {
if (element.name.includes("TVOC")) {
element.name = element.name.split('TVOC')[0] + verticalType[item.type].title
}
if (element.val > item.limit) {
element.date = gettime(element.ts),
element.time = element.ts || datetime
element.continuous = clacendTime(datetime, element.ts || datetime)
} else {
element.date = null
element.time = null
element.continuous = null
}
});
return {
type: item.type,
icon: verticalType[item.type].icon,
title: verticalType[item.type].title,
limit: item.limit,
unit: verticalType[item.type].unit,
value: item.value
}
})
store.setNewVerticalNum(handle_vertical)
}
//湿
async function gethumitureData() {
let result: any = await getHumitureData({ deptIds })
if (result.code == 200) {
store.$patch((state) => {
state.humiture = result.data.Humiture
})
humidityBottom.value = result.data.bottom
humidityTop.value = result.data.top
}
}
/**
let humidityData = ref({})
let humidityBottom = ref({})
let humidityTop = ref({})
watch(() => store.humiture, (newVal, oldVal) => {
let data = { list: [], temp: [], humidity: [] }
newVal.Humiture.forEach((res) => {
data.list.push(res.name);
data.temp.push(res.temp);
data.humidity.push(res.humidity);
});
humidityData.value = data;
humidityBottom.value = newVal.bottom;
humidityTop.value = newVal.top;
}, { deep: true, immediate: true })
*/
//
let pmindex = ref(0);
async function getPmData() {
let resulttwo: any = await getPmtwoData()
let resultten: any = await getPmtenData()
let arr = [
'01336fd0-1fa0-11ed-9223-7db1174970a8',
'083e3900-3435-11ed-a7e1-fd42bca6c8c6',
'270e1500-eee1-11ed-b2ee-2d727e0cafab',
'54058c30-eee3-11ed-b2ee-2d727e0cafab',
'76efb040-eee3-11ed-b2ee-2d727e0cafab',
'a6020310-eee3-11ed-b2ee-2d727e0cafab',
'bcbfb530-88b2-11ed-a926-570995ad0254'
]
let data = {}
if (resulttwo) {
resulttwo.data.forEach(ele => {
if (arr.indexOf(ele.devId) > -1) {
data[ele.devId] = {
devId: ele.devId,
name: ele.devName.split('监测')[0],
pm25: ele.value,
pm10: null
}
}
})
}
if (resultten) {
resultten.data.forEach(ele => {
if (data.hasOwnProperty(ele.devId)) {
data[ele.devId].pm10 = ele.value
}
})
}
store.$patch((state) => {
state.pm = Object.values(data)
})
}
//
async function getPower_data() {
let result: any = await getPowerData({ time: 1 });
if (result.code == 200) {
let series = [];
result.data.listData.forEach((res) => {
if (res.years == 2023) {
for (let key in res.month) {
series.push({
name: key + "月",
type: "bar",
stack: res.years,
emphasis: {
focus: "coordinateSystem",
label: {
show: true,
formatter: function (value, index) {
return value.value.toLocaleString();
},
},
},
data: res.month[key],
});
}
}
});
//data0
let data0 = [];
for (let i = 1; i <= result.data.name.length; i++) {
data0.push(0);
}
series.push({
name: "",
type: "bar",
data: data0,
color: "#bbf",
stack: result.data.listData[1].years,
barWidth: 40,
label: {
show: true,
position: "right",
color: "#fff",
},
});
powerData.value.value = result.data
powerData.value.seriesVal = series
powerData.value.title = '机械分厂用电量'
}
}
let gascolor = {step0:'#186945',step1:'#1b7a4f',border:'rgba(8, 206, 120, 0.8)',color:'rgba(8, 206, 120, 0.4)'}
let watercolor = {step0:'#0D73B3',step1:'#1176C6',border:'#1E4D7B',color:'#0F2A57'}
//
async function getconsumeDetailfun() {
let result: any = await getconsumeDetail()
if (result.code == 200) {
result.data.forEach(res => {
if (res.deptName == '喷漆车间' && res.type == 'GasDetail') {
gasData.value = res.usageNum
}
if (res.deptName == '生产区' && res.type == 'WaterDetail') {
waterData.value = res.usageNum
}
})
}
}
async function getpipeDatafun() {
let pageValue = '6,7,9,10,11'
let result: any = await getpipeData({ deptIds: pageValue })
if (result.code == 200) {
pipeData.value.listData = result.data.listData
pipeData.value.top = result.data.top
}
}
/************************************************************ */
let noiseData = [
'55aaf760-4e88-11ed-b6af-15994988a6b3',
'8733fe40-4e82-11ed-b6af-15994988a6b3',
'cae16000-4e88-11ed-b6af-15994988a6b3',
'08144ba0-4e88-11ed-b6af-15994988a6b3',
'2a5f6600-4e87-11ed-b6af-15994988a6b3'
]
//socket
function getWebsocket(val) {
headerref.value.HeadergetWebsocket(val)
try {
let data = JSON.parse(val);
if (data.type == "noise") {
data.msg.listData.forEach(ele => {
if (noiseData.indexOf(ele.devId) > -1) {
let verticalData = { name: ele.name, val: ele.value, devId: ele.devId }
store.changeNewVerticalNum({ type: 'noise', data: verticalData })
}
})
}
//
if (data.type == "paintingGas") {
let verticalData = { name: data.msg.devName, val: data.msg.paintingGas.value, devId: data.msg.devId }
store.changeNewVerticalNum({ type: 'Methane', data: verticalData })
}
//TVOC
if (data.type == "TVOC_CH2O") {
let verticalData_TVOC = { name: data.msg.TVOC.name, val: data.msg.TVOC.value, devId: data.msg.TVOC.devId }
store.changeNewVerticalNum({ type: 'TVOC', data: verticalData_TVOC })
let verticalData_CH2O = { name: data.msg.CH2O.name, val: data.msg.CH2O.value, devId: data.msg.CH2O.devId }
store.changeNewVerticalNum({ type: 'CH2O', data: verticalData_CH2O })
}
//
if (data.type == "flame") {
let verticalData = { name: data.msg.devName, val: data.msg.flame.value, devId: data.msg.devId }
store.changeNewVerticalNum({ type: 'FIRE', data: verticalData })
}
//
if (data.type == "smoke") {
let verticalData = { name: data.msg.devName, val: data.msg.smoke.value, devId: data.msg.devId }
store.changeNewVerticalNum({ type: 'Smoke', data: verticalData })
// console.log(JSON.stringify({type:'Smoke',data:verticalData}),"");
}
// if (data.type == "airPressure") {
// store.changePressure(data.msg);
// }
// if (data.type == "waterPressure") {
// store.changePipe(data.msg);
// }
if (data.type == "humiture") {
store.changeHumiture(data.msg);
}
if (data.type == "dust") {
store.changeDust(data.msg);
}
} catch (err) {
console.log(err, "报错了大哥", console.log(val));
}
}
function errWebsocket(val) {
headerref.value ? headerref.value.HeadererrWebsocket(val) : ''
// console.log(val);
}
onMounted(() => {
getSensorData()
getPower_data()
getpipeDatafun()
getconsumeDetailfun()
gethumitureData()
getPmData()
connectWebsocket(null, null, getWebsocket, errWebsocket);
})
onUnmounted(() => {
closeWebsocket();
})
</script>
<style module>
.container {
height: 1080px;
width: 1920px;
color: #20aec5;
background-color: #100c2a;
box-sizing: border-box;
}
</style>
<style scoped>
.content {
width: 1920px;
height: 930px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.top-box {
width: 1920px;
height: 340px;
display: flex;
justify-content: space-between;
align-items: center;
}
.top-box-item {
width: 12%;
height: 300px;
margin-bottom: 10px;
display: flex;
align-items: center;
justify-content: space-evenly;
}
.bottom-box {
width: 1920px;
height: 580px;
display: flex;
justify-content: space-between;
align-items: center;
/* background-color: #afb; */
}
</style>

View File

@ -1,6 +1,6 @@
<template>
<div class="content-right">
<el-row >
<el-row @click="toPmData">
<el-col :span="8">
<border2 ref="borderElectriccontrol">
<template v-slot>
@ -43,9 +43,12 @@
import { getHumitureData, getPmtenData, getPmtwoData } from "@/http/generalEnvironment";
// import { getHumitureData,getPmtenData, getPmtwoData } from "@/http/environment";
import { onMounted, ref, watch } from "vue"
import { useRouter } from "vue-router";
import { useSocketStore } from "@/store/moduleSocketjixie";
import { useI18n } from 'vue-i18n'
let { t } = useI18n();
const router = useRouter()
const store = useSocketStore()
let props = defineProps<{
width: number,
@ -142,18 +145,40 @@ async function getPmData(){
let resulttwo: any = await getPmtwoData()
let resultten: any = await getPmtenData()
let data = { welding: { two: null, ten: null }, stuff: { two: null, ten: null }, ornaments: { two: null, ten: null } }
if(resulttwo.code==200){
resulttwo.data.forEach(res=>{
if(data[res.enName]){
data[res.enName].two=res.value
}
if (resulttwo) {
resulttwo.data.forEach(ele => {
switch (ele.devId) {
case '083e3900-3435-11ed-a7e1-fd42bca6c8c6':
data.welding.two = ele.value
break;
case 'bcbfb530-88b2-11ed-a926-570995ad0254':
data.ornaments.two = ele.value
break;
case '01336fd0-1fa0-11ed-9223-7db1174970a8':
data.stuff.two = ele.value
break;
default:
break;
}
})
}
if(resultten.code==200){
resultten.data.forEach(res=>{
if(data[res.enName]){
data[res.enName].ten=res.value
if (resultten) {
resultten.data.forEach(ele => {
switch (ele.devId) {
case '083e3900-3435-11ed-a7e1-fd42bca6c8c6':
data.welding.ten = ele.value
break;
case 'bcbfb530-88b2-11ed-a926-570995ad0254':
data.ornaments.ten = ele.value
break;
case '01336fd0-1fa0-11ed-9223-7db1174970a8':
data.stuff.ten = ele.value
break;
default:
break;
}
})
}
@ -168,6 +193,10 @@ async function getPmData(){
})
}
function toPmData() {
router.push({ path: '/pmData' })
}
onMounted(() => {
gethumitureData()
getPmData()
@ -178,6 +207,5 @@ onMounted(()=>{
.content-right {
width: 100%;
}
</style>

View File

@ -1,5 +1,5 @@
<!--
* @FilePath: \wwwd:\code\screenFront\src\views\index.vue
* @FilePath: \code\gitscreenFront\src\views\index.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-01-29 15:34:48
@ -11,7 +11,7 @@
<template>
<div :class="$style['container']" ref="appRef">
<div class="navbar">
<el-dropdown effect="dark" @command="changelang" >
<el-dropdown @command="changelang" >
<span class="el-dropdown-link">
<!-- <img src="../assets/svg/gateway.svg" alt="" class="langimg" height="20px" width="20px"> -->
<i class="iconfont icon-zhongyingwen langimg"></i>
@ -23,7 +23,7 @@
</el-dropdown-menu>
</template>
</el-dropdown>
<!-- <el-select class="m-2" v-model="lang" effect="dark" placeholder="Select" size="large" @change="changelang">
<!-- <el-select class="m-2" v-model="lang" placeholder="Select" size="large" @change="changelang">
<el-option
:label="'简体中文'"
:value="'简体中文'"
@ -218,6 +218,13 @@ let routerList = [
title: t("messages.generalEnvironmentjixiefenchang"),
url: require("../assets/indexImg/generalEnvironment.png"),
},
{
id: 31,
isLink: false,
path: "/generalEnvironmentMechanical",
title: t("messages.环境 实时监测系统"),
url: require("../assets/indexImg/generalEnvironmentMechanical.png"),
},
{
id: 24,
isLink: false,

View File

@ -7,7 +7,7 @@
width: '100%',
height: '100%',
}" />
<el-tooltip v-model:visible="visible" :content="tipcontent" placement="top" effect="dark" trigger="click"
<el-tooltip v-model:visible="visible" :content="tipcontent" placement="top" effect="light" trigger="click" popper-class="tooltip-class"
virtual-triggering :virtual-ref="triggerRef" />
</div>
</div>
@ -107,3 +107,8 @@ const dvClick = (value) => {
text-overflow: none
}
</style>
<style>
.el-popper.tooltip-class{
color: #fff !important;
}
</style>

View File

@ -7,16 +7,28 @@
</div>
</div>
<div class="content">
<div class="test" v-for="item in pmData">
<div class="box">
<Border12>
<PM :title="item.title" :value="item.value"></PM>
</Border12>
</div>
<div class="test" v-for="item in pmData">
<Border12>
<PM :title="item.title" :value="item.value"></PM>
<div style="width: 100%;height: 100%;overflow: hidden;" ref="boxRef">
<ul ref="ulRef" :style="{transform:`translateY(-${index * boxHeight}px)`}">
<li class="item-box" v-for="item in list" :key="item.id" :style="{height:`${boxHeight}px`}">
<div class="item-left">{{ item.id }}</div>
<div class="item-right">
<div class="b-top">
<text>机架号<i>{{item.label}}</i></text> <text>设备位置及名称<i>{{ item.position }}</i></text>
</div>
<div class="b-bottom">
<text>工作时长<i>{{ item.workTime }}</i></text>
<text>待机时长<i>{{ item.standbyTime }}</i></text>
<text>停机时长<i>{{ item.downtime }}</i></text>
</div>
</div>
</li>
</ul>
</div>
</Border12>
</div>
</div>
</div>
@ -24,81 +36,40 @@
<script setup lang='ts'>
import { ref, reactive, onMounted, onUnmounted } from "vue"
import PM from "@/components/PM/PM.vue"
import Border12 from "@/components/border/Border12.vue"
import Header2 from "@/components/headerBox/header2.vue"
import { getPmtenData, getPmtwoData } from "@/http/generalEnvironment";
import { connectWebsocket, closeWebsocket } from "@/utils/websocket";
let pmtest = ref({
title: 'PM测试',
value: { two: '44', ten: '51' }
})
type pmData = {
title: string,
value: {
two: string,
ten: string
let list = ref([])
let rowNum =6;
const boxRef = ref(null)
const ulRef = ref(null)
let boxHeight = ref(0)
let interval = 3000;
let index = ref(0);
let timer = null
for (let i = 1; i <= 10; i++) {
let item = {
id: i,
label: `机架号${i}`,
position: `设备位置及名称${i}`,
workTime: `65664 分钟`,
standbyTime: `57244 分钟`,
downtime: `6708 分钟`
}
list.value.push(item)
}
let pmData = reactive<pmData[]>([]);
/**
* 请求数据
*/
async function getData() {
let resulttwo: any = await getPmtwoData()
let resultten: any = await getPmtenData()
if (resulttwo.code == 200) {
resulttwo.data.forEach(res => {
let temp = {
title: res.name + "(PM2.5/PM10)",
value: {
two: res.value,
ten: '0'
}
}
pmData.push(temp)
})
}
if (resultten.code == 200) {
resultten.data.forEach(res => {
let index = pmData.findIndex(item => item.title == res.name + "(PM2.5/PM10)")
if (index != -1) {
pmData[index].value.ten = res.value
}
})
}
}
//websocket
function getWebsocket(val) {
try {
let data = JSON.parse(val);
if (data.type == "dust") {
let index = pmData.findIndex(item => item.title == data.msg.enName + "(PM2.5/PM10)")
if (index != -1) {
pmData[index].value.ten = data.msg.pm10
pmData[index].value.two = data.msg.pm25
}
}
} catch (err) { }
}
function errWebsocket(val) {
console.log(val);
}
getData();
onMounted(() => {
connectWebsocket(null, null, getWebsocket, errWebsocket);
boxHeight.value = boxRef.value.clientHeight / rowNum
//
timer = setInterval(() => {
index.value++;
if (index.value >= (list.value.length - rowNum + 1)) {
index.value = 0;
}
}, interval);
});
onUnmounted(() => {
closeWebsocket();
clearInterval(timer)
});
</script>
@ -123,12 +94,43 @@ onUnmounted(() => {
align-items: center;
padding: 20px;
}
.box {
width: 600px;
height: 400px;
}
ul {
transition: all 1s;
}
.test {
width: 20%;
height: 30%;
margin: 20px 47px;
}
ul {
width: 100%;
}
.item-box {
width: 100%;
height: 50px;
color: #fff;
font-size: 14px;
display: flex;
justify-content: space-between;
align-items: center;
}
.item-left {
width: 10%;
margin-right: 10px;
}
.item-right {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: start;
}
</style>
<style>
body {

View File

@ -1,5 +1,5 @@
<!--
* @FilePath: \gitscreenFront\src\views\realtimeSecurity\content\chart\verticalNum.vue
* @FilePath: \code\gitscreenFront\src\views\realtimeSecurity\content\chart\verticalNum.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-13 08:22:35
@ -15,7 +15,7 @@
<!-- <div class="contentbox"> -->
<div class="icontip">
<div v-for="item in value" style="margin: auto 5px;">
<el-popover placement="bottom" :width="220" trigger="hover" effect="dark"
<el-popover placement="bottom" :width="220" trigger="hover"
:popper-style="{ 'background-color': 'rgba(0,0,0,.8)' }">
<ul class="icontipBox">
<li>

View File

@ -5,7 +5,7 @@
<div class="box" ref="classBox1">
<div class="icontip">
<div v-for="items in value" style="margin: auto 5px;" v-show="(+items.val > +limit)&&items.status">
<el-popover placement="bottom" :width="250" trigger="hover" effect="dark"
<el-popover placement="bottom" :width="250" trigger="hover"
:popper-style="{ 'background-color': 'rgba(0,0,0,.8)' }">
<ul class="icontipBox">
<li>

View File

@ -4,8 +4,11 @@
<toptip ref="toptip1"></toptip>
</div> -->
<div style="display: flex;">
<div style="width: 20%; height: 250px; margin-bottom: 10px; display: flex; align-items: center; justify-content: space-evenly;" v-for="item in store.newVerticalNum">
<verticalNumLoop :title="item.title" :icon="item.icon" :limit="item.limit" :unit="item.unit" :value="item.value"></verticalNumLoop>
<div
style="width: 20%; height: 250px; margin-bottom: 10px; display: flex; align-items: center; justify-content: space-evenly;"
v-for="item in store.newVerticalNum">
<verticalNumLoop @click="gotoTrendChart(item.value, item.unit)" :title="item.title" :icon="item.icon"
:limit="item.limit" :unit="item.unit" :value="item.value"></verticalNumLoop>
</div>
</div>
<div>
@ -26,6 +29,7 @@
</template>
<script setup lang="ts">
import { ElMessage, ElMessageBox } from 'element-plus'
import pressure from "./chart/pressure.vue"
import pipe from "./chart/pipe.vue"
// import toptip from "./chart/toptip.vue"
@ -35,9 +39,11 @@ import verticalNumLoop from './chart/verticalNumLoop.vue'
// import { getPressureData,getSafeWarningData } from "@/http/environment";
import { getPressureData, getSafeWarningData, getpipeData } from "@/http/realtimeSecurity";
import { useSocketStore } from "@/store/moduleSocket"
import { useRouter } from "vue-router"
import { gettime, clacendTime } from "@/utils/time"
import { useI18n } from 'vue-i18n'
let { t } = useI18n();
let router = useRouter()
const store = useSocketStore()
let props = defineProps<{
width: number,
@ -62,6 +68,29 @@ const verticalType = {
'FIRE': { icon: 'icon-weibiaoti1', title: t('messages.flameDetection'), unit: null },
}
/**
* 跳转到趋势图
*/
function gotoTrendChart(value, unit) {
let ids = value.map((item) => item.devId).toString();
ElMessageBox.confirm(
'即将跳转到趋势图页面,是否继续?',
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'info',
}
)
.then(() => {
router.push({ path: '/TrendChart', query: { ids: ids, unit: unit } })
})
.catch(() => {
})
}
function reset(val: any) {
//0
@ -180,5 +209,4 @@ onMounted(()=>{
.topTip {
width: 100%;
height: 150px;
}
</style>
}</style>

View File

@ -77,7 +77,7 @@ function getWebsocket(val) {
//
if (data.type == "paintingGas") {
store.changepaintingGas(data.msg);
let verticalData = {name:data.msg.devName,val:data.msg.paintingGas.value}
let verticalData = {name:data.msg.devName,val:data.msg.paintingGas.value,devId:data.msg.devId}
store.changeNewVerticalNum({type:'Methane',data:verticalData})
}
@ -85,7 +85,7 @@ function getWebsocket(val) {
if (data.type == "boilerGas") {
// store.changePM(data.msg)
store.changeboilerGas(data.msg.boilerGas);
let verticalData = {name:data.msg.devName,val:data.msg.boilerGas.value}
let verticalData = {name:data.msg.devName,val:data.msg.boilerGas.value,devId:data.msg.devId}
store.changeNewVerticalNum({type:'Methane',data:verticalData})
}
@ -93,15 +93,15 @@ function getWebsocket(val) {
if (data.type == "canteenGas") {
// store.changeHumiture(data.msg)
store.changecanteenGas(data.msg.canteenGas);
let verticalData = {name:data.msg.devName,val:data.msg.canteenGas.value}
let verticalData = {name:data.msg.devName,val:data.msg.canteenGas.value,devId:data.msg.devId}
store.changeNewVerticalNum({type:'Methane',data:verticalData})
}
//TVOC
if (data.type == "TVOC_CH2O") {
store.changeTVOC_CH2O(data.msg);
let verticalData_TVOC = {name:data.msg.TVOC.name,val:data.msg.TVOC.value}
let verticalData_TVOC = {name:data.msg.TVOC.name,val:data.msg.TVOC.value,devId:data.msg.TVOC.devId}
store.changeNewVerticalNum({type:'TVOC',data:verticalData_TVOC})
let verticalData_CH2O = {name:data.msg.CH2O.name,val:data.msg.CH2O.value}
let verticalData_CH2O = {name:data.msg.CH2O.name,val:data.msg.CH2O.value,devId:data.msg.CH2O.devId}
store.changeNewVerticalNum({type:'CH2O',data:verticalData_CH2O})
}
@ -109,7 +109,7 @@ function getWebsocket(val) {
if (data.type == "flame") {
// store.changeHumiture(data.msg)
store.changeflame(data.msg.flame);
let verticalData = {name:data.msg.devName,val:data.msg.flame.value}
let verticalData = {name:data.msg.devName,val:data.msg.flame.value,devId:data.msg.devId}
store.changeNewVerticalNum({type:'FIRE',data:verticalData})
@ -119,7 +119,7 @@ function getWebsocket(val) {
// store.changeHumiture(data.msg)
// store.changepaintingGas(data.msg)
store.changesmoke(data.msg.smoke);
let verticalData = {name:data.msg.devName,val:data.msg.smoke.value}
let verticalData = {name:data.msg.devName,val:data.msg.smoke.value,devId:data.msg.devId}
store.changeNewVerticalNum({type:'Smoke',data:verticalData})
// console.log(JSON.stringify({type:'Smoke',data:verticalData}),"");
}

View File

@ -15,7 +15,7 @@
<div class="box" ref="classBox1">
<div class="icontip">
<div v-for="items in value.data" style="margin: auto 5px;" v-show="(+items.val > +value.quota)&&items.status">
<el-popover placement="bottom" :width="250" trigger="hover" effect="dark"
<el-popover placement="bottom" :width="250" trigger="hover"
:popper-style="{ 'background-color': 'rgba(0,0,0,.8)' }">
<ul class="icontipBox">
<li>

View File

@ -5,7 +5,7 @@
<div class="box" ref="classBox1">
<div class="icontip">
<div v-for="items in value" style="margin: auto 5px;" v-show="+items.val > +limit">
<el-popover placement="bottom" :width="250" trigger="hover" effect="dark"
<el-popover placement="bottom" :width="250" trigger="hover"
:popper-style="{ 'background-color': 'rgba(0,0,0,.8)' }">
<ul class="icontipBox">
<li>

View File

@ -77,7 +77,7 @@ function getWebsocket(val) {
//
if (data.type == "paintingGas") {
store.changepaintingGas(data.msg);
let verticalData = {name:data.msg.devName,val:data.msg.paintingGas.value}
let verticalData = {name:data.msg.devName,val:data.msg.paintingGas.value,devId:data.msg.devId}
store.changeNewVerticalNum({type:'Methane',data:verticalData})
}
@ -85,7 +85,7 @@ function getWebsocket(val) {
if (data.type == "boilerGas") {
// store.changePM(data.msg)
store.changeboilerGas(data.msg.boilerGas);
let verticalData = {name:data.msg.devName,val:data.msg.boilerGas.value}
let verticalData = {name:data.msg.devName,val:data.msg.boilerGas.value,devId:data.msg.devId}
store.changeNewVerticalNum({type:'Methane',data:verticalData})
}
@ -93,15 +93,17 @@ function getWebsocket(val) {
if (data.type == "canteenGas") {
// store.changeHumiture(data.msg)
store.changecanteenGas(data.msg.canteenGas);
let verticalData = {name:data.msg.devName,val:data.msg.canteenGas.value}
let verticalData = {name:data.msg.devName,val:data.msg.canteenGas.value,devId:data.msg.devId}
store.changeNewVerticalNum({type:'Methane',data:verticalData})
}
//TVOC
if (data.type == "TVOC_CH2O") {
console.log(data.msg,"TVOC_CH2O");
store.changeTVOC_CH2O(data.msg);
let verticalData_TVOC = {name:data.msg.TVOC.name,val:data.msg.TVOC.value}
let verticalData_TVOC = {name:data.msg.TVOC.name,val:data.msg.TVOC.value,devId:data.msg.TVOC.devId}
store.changeNewVerticalNum({type:'TVOC',data:verticalData_TVOC})
let verticalData_CH2O = {name:data.msg.CH2O.name,val:data.msg.CH2O.value}
let verticalData_CH2O = {name:data.msg.CH2O.name,val:data.msg.CH2O.value,devId:data.msg.CH2O.devId}
store.changeNewVerticalNum({type:'CH2O',data:verticalData_CH2O})
}
@ -109,7 +111,7 @@ function getWebsocket(val) {
if (data.type == "flame") {
// store.changeHumiture(data.msg)
store.changeflame(data.msg.flame);
let verticalData = {name:data.msg.devName,val:data.msg.flame.value}
let verticalData = {name:data.msg.devName,val:data.msg.flame.value,devId:data.msg.devId}
store.changeNewVerticalNum({type:'FIRE',data:verticalData})
@ -119,7 +121,7 @@ function getWebsocket(val) {
// store.changeHumiture(data.msg)
// store.changepaintingGas(data.msg)
store.changesmoke(data.msg.smoke);
let verticalData = {name:data.msg.devName,val:data.msg.smoke.value}
let verticalData = {name:data.msg.devName,val:data.msg.smoke.value,devId:data.msg.devId}
store.changeNewVerticalNum({type:'Smoke',data:verticalData})
// console.log(JSON.stringify({type:'Smoke',data:verticalData}),"");
}