更新上海服博会大屏

This commit is contained in:
hzz 2024-02-23 17:01:59 +08:00
parent cb6214db78
commit f6cbb71fda
17 changed files with 1454 additions and 9 deletions

View File

@ -0,0 +1,12 @@
import {get,post} from "@/utils/http"
//获取设备在线状态、设备列表
export function chicDeviceList(){
return get('/screen/cisma/chicDeviceList')
}
//获取设备在线状态、设备列表
export function mjlDeviceProduction(){
return get('/screen/cisma/mjlDeviceProduction')
}

View File

@ -1,8 +1,8 @@
import {get,post} from "@/utils/http"
//获取设备在线状态、设备列表
export function getCismaList(){
return get('/screen/cisma/getCismaList')
export function getCismaList(data){
return get('/screen/cisma/getCismaList',data)
}
export function getFiveList(){

View File

@ -285,6 +285,11 @@ const routes: Array<RouteRecordRaw> = [
name: "BengalExhibition",
component: () => import("../views/Exhibition/Bengal/index.vue"),
},
{
path: "/CHICExhibition",
name: "CHICExhibition",
component: () => import("../views/Exhibition/CHIC/index.vue"),
},
{
path: "/ExhibitionTable_:id",
name: "ExhibitionTable",

View File

@ -0,0 +1,98 @@
<template>
<div ref="LChartRef" class="cc"></div>
</template>
<script setup lang='ts'>
import { ref, getCurrentInstance, onMounted, watch } from 'vue'
const prop = defineProps({
xData: {
type: Array,
default: ['1050910', '1050269']
},
seriesData: {
type: Array,
default: []
}
})
let LChartRef = ref(null);
const { proxy } = getCurrentInstance() as any;
let charts = null;
const setCharts = () => {
charts = proxy.$echarts.init(LChartRef.value, 'dark')
let option = {
// title: {
// text: ''
// },
backgroundColor: 'transparent',
legend: {
data: ['计划完成', '实际完成'],
textStyle: {
fontSize: 14
},
},
textStyle: {
fontSize:14
},
grid:{
left:'80',
right:'0',
bottom:'40',
},
color:['#2FC5D4','#FEDA81'],
xAxis: {
type: 'category',
data: prop.xData,
// axisLabel: {
// interval: 0, //X
// rotate: 45, //
// },
},
yAxis: [
{
type: 'value',
name: '日产量',
axisLabel:{
fontSize:14
}
}
],
series: prop.seriesData
};
charts.setOption(option);
}
watch(() => prop.seriesData, (newVal, oldVal) => {
charts.setOption({
series: newVal
});
}, { deep: true })
watch(() => prop.xData, (newVal, oldVal) => {
charts.setOption({
xAxis: {
type: 'category',
data: prop.xData,
// axisLabel: {
// interval: 0, //X
// rotate: 45, //
// },
},
});
}, { deep: true })
onMounted(() => {
setCharts()
})
</script>
<style scoped>
.cc {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,143 @@
<template>
<div class="board-bar">
<div class="bb-top">
<div class="dev-title">
<div class="title-item" v-for="(item, index) in header" :style="{ width: computedWidth(columnWidth[index]) }">
<text>{{ item }}</text></div>
</div>
<ZdScrollBoard ref="devList" class="dev-list" :config="config" />
</div>
<div class="bb-bottom">
<BarChart style="width: 100%;height: 100%;" :xData="prop.xData"
:seriesData="prop.seriesData"></BarChart>
</div>
</div>
</template>
<script setup lang='ts'>
import ZdScrollBoard from "@/components/data-view/index.vue";
import BarChart from './BarChart.vue'
import { getCurrentInstance, onMounted, reactive, ref, computed, watch } from "vue";
const devList = ref(null);
const prop = defineProps({
data: {
type: Array,
default: []
},
xData: {
type: Array,
default: ['1050910', '1050269']
},
seriesData: {
type: Array,
default: [ ]
},
rowNum: {
type: Number,
default: 2
}
})
let header = ['序号', '设备名称', '设备编码','完成率', '稼动率', '状态']
let columnWidth = [90, 295, 145, 110, 110,85];
let sum = 850;
let computedWidth = (width: number) => {
return width / sum * 100 + '%'
}
let config = reactive({
// header: ['', '', '', '', ''],//, ''
headerBGC: '#0E0E0E',
oddRowBGC: 'transparent',
evenRowBGC: 'transparent',
wrap: [false, false, false, false, false],
columnWidth: [80, 295, 145, 110, 110,85],
align: ['center', 'center', 'center', 'center', 'center', 'center'],
rowNum: prop.rowNum,
waitTime: 3000,
})
const handleData = () => {
let updateList = prop.data.map((items: any) => {
return items.map((item: any, index: number) => {
if (index == (items.length - 1)) {
return statusHtml(status_color[item])
}
return item
})
})
devList.value.updateRows(updateList,config)
}
watch(()=>prop.data, (newVal, oldVal) => {
handleData()
},{deep:true}
)
const status_color = {
'0': '#FF6E76',
'1': '#FDDD60',
'2': '#7CFFB2',
'3': '#FDDD60',
}
let statusHtml = (color) => {
return `<div style="width: 100%;height: 100%;display: flex;justify-content: center;align-items: center;"><div style="width:24px;height:24px;border-radius: 50%;background-color:${color}"></div></div>`
// return `<div style="display: inline-block;width:20px;height:20px;border-radius: 50%;background-color:${color}"></div>`
}
onMounted(() => {
handleData()
})
</script>
<style scoped>
.board-bar {
width: 100%;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.dev-title {
width: 100%;
height: 50px;
display: flex;
align-items: center;
justify-content: space-between;
}
.title-item {
height: 100%;
box-sizing: border-box;
}
.title-item text {
line-height: 50px;
text-align: center;
font-size: 18px;
font-weight: 700;
color: #fff;
padding: 5px 10px;
background: url(@/assets/img/title_bg.svg) no-repeat center center / 100% 100%;
}
.bb-top {
width: 100%;
height: 40%;
}
.dev-list {
width: 100%;
height: calc(100% - 50px);
}
.bb-bottom {
width: 100%;
height: 60%;
}</style>

View File

@ -0,0 +1,75 @@
<template>
<div class="newboder">
<img class="u305" src="./../images/u305.svg" alt="">
<img class="u290" src="./../images/u290.svg" alt="">
<div class="title">
<text class="title-text">{{ newTitle }}</text>
</div>
<div class="newboder-content">
<slot></slot>
</div>
</div>
</template>
<script setup lang='ts'>
import { computed} from 'vue'
let prop = defineProps({
title: {
type: String,
default: '裁剪设备'
}
})
let newTitle = computed(() => {
return prop.title.split('').join(' ')
})
</script>
<style scoped>
.newboder {
position: relative;
width: 100%;
height: 100%;
padding: 10px;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.u305 {
width: 73px;
position: absolute;
top: 0;
left: 0;
opacity: 0.5;
}
.u290 {
width: 61px;
position: absolute;
bottom: 0;
right: 0;
transform: rotate(180deg);
opacity: 0.5;
z-index: 2;
}
.title {
width: 100%;
height: 50px;
text-align: left;
font-size: 20px;
color: #02C1D7;
display: flex;
align-items: center;
}
.title-text {
margin-left: 30px;
padding-left: 20px;
border-left: #02C1D7 solid 5px;
font-weight: bold;
}
.newboder-content {
flex: 1;
}
</style>

View File

@ -0,0 +1,76 @@
<!--
* @Author: hzz hzz
* @Date: 2023-12-06 08:05:31
* @LastEditors: hzz hzz
* @LastEditTime: 2023-12-06 08:28:40
* @FilePath: \screenFront\src\views\MicroExhibition\component\StepItem.vue
* @Description:
*
* Copyright (c) 2023 by ${hzz}, All Rights Reserved.
-->
<template>
<div class="stepContainer">
<div class="step-top" :style="{'font-size':lang!='简体中文'?'24px':'22px'}">{{ prop.data.name }}</div>
<div class="step-bottom">
<div class="step-total">{{t("default.总数")}}{{ prop.data.total +' '+ t("default.台") }}</div>
<div class="step-online">{{t("default.在线")}}{{ prop.data.online +' '+ t("default.台") }}</div>
</div>
</div>
</template>
<script setup lang='ts'>
import {computed,ref } from 'vue'
import { getStoredLanguage, saveStoredLanguage } from "@/utils/languageStorage";
import { useI18n } from 'vue-i18n'
let lang = ref(getStoredLanguage());
let { t } = useI18n();
const prop = defineProps({
data: {
type: Object,
default: {
name: '裁剪',
total: 0,
online: 0,
}
}
})
</script>
<style scoped>
.stepContainer {
width: 170px;
height: 88px;
background: url('./../images/step_item.png') no-repeat;
background-size: 100% 100%;
font-family: "华文新魏", sans-serif;
font-weight: 400;
font-style: normal;
font-size: 14px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
}
.step-top {
width: 100%;
height: 36px;
text-align: center;
font-size: 28px;
color: #00FFFF;
padding-left: 20px;
}
.step-bottom {
width: 100%;
height: 51px;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
padding-left: 20px;
}
.step-online {
color: #7CFfB2FE;
}
</style>

View File

@ -0,0 +1,554 @@
<!--
* @FilePath: \code\gitscreenFront\src\components\headerBox\header2.vue
* @Author: 王路平
* @文件版本: V1.0.0
* @Date: 2023-02-16 11:04:06
* @Description:
*
* 版权信息 : 2023 by ${再登软件}, All Rights Reserved.
-->
<template>
<div class="header2" :style="{ width: props.width, height: props.height }">
<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
>
<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>
</el-badge>
</div>
<div v-show="typeObj.time" class="time">
<p ref="Timedom">{{ timeHtml }}</p>
</div>
</div>
<el-popover
ref="popoverRef"
:virtual-ref="AbnormalDataRef"
:visible="Abnormalpopovervisible"
trigger="click"
width="600px"
placement="bottom-start"
virtual-triggering
>
<ul
class="popoverBOX"
ref="popoverliDom"
v-click-outside="noClickAbnormalDataFun"
>
<li class="popoverHeader">
<!-- <span><i class="iconfont icon-lishijilu lishijilu"></i>历史记录</span> -->
</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>
</li>
</ul>
</el-popover>
</div>
</template>
<script setup lang="ts">
import useNowTime from "@/hook/nowTime";
import { ClickOutside as vClickOutside } from "element-plus";
import { useRoute, useRouter } from "vue-router";
import { devListType } from "@/type/InPlantProducts";
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 { Clock } from "@element-plus/icons-vue";
let { t } = useI18n();
const storeheader = useHeaderStore();
let { timeHtml } = useNowTime();
const router = useRouter();
//
let numkey = ref(0);
let popoverkey = ref(0);
//dom
let AbnormalDataRef = ref();
let popoverRef = ref();
let tipList = ref();
let popoverliDom = ref();
//
let Abnormalpopovervisible = ref(false);
let AbnormalpopovervisibleCtrl = ref(false); //
//dialog
let dialogdata = ref([]);
let onloadlist = computed(() => {
return storeheader.num > powerlist.length;
});
const listdata = reactive<devListType>({
data: [],
rowNum: 2,
oddRowBGC: "#100C2A",
evenRowBGC: "#100C2A",
hoverPause: true,
carousel: "page",
waitTime: 3000,
align: ["left"],
});
let AbnormalNum = ref(0);
//
let powerlist = reactive([]);
let props = defineProps<{
width: string;
height: string;
title: string;
titleTip: any;
typeFun: any[];
alarmType: any[];
}>();
const typeObj = reactive({
comback: false,
AbnormalData: false,
time: false,
});
const AbnormalType = reactive({
pageSize: 5,
pageNum: 1,
type: "",
});
let comeBackFun = () => {
router.go(-1);
};
const changeAbnormalData = (val: any) => {
tipList.value.updateRows(val.data, { ...val });
};
let AbnormalDataFun = () => {
//noClickAbnormalDataFun
//Abnormalpopovervisibled
//
if (Abnormalpopovervisible.value) {
Abnormalpopovervisible.value = false;
} else {
//
if (AbnormalpopovervisibleCtrl.value) {
Abnormalpopovervisible.value = false;
} else {
Abnormalpopovervisible.value = true;
}
}
};
let noClickAbnormalDataFun = () => {
//AbnormalDataFun
// ctrltruefalse
if (Abnormalpopovervisible.value) {
AbnormalpopovervisibleCtrl.value = true;
} else {
AbnormalpopovervisibleCtrl.value = false;
}
Abnormalpopovervisible.value ? (Abnormalpopovervisible.value = false) : "";
};
function typeStatus() {
if (props.typeFun.length == 0) {
return;
}
props.typeFun.forEach((res) => {
for (let key in typeObj) {
if (res == key) {
typeObj[key] = true;
}
}
});
}
function langJudge() {
let lang = getStoredLanguage();
if (lang) {
return lang;
} else {
return "简体中文";
}
}
//
watch(
() => typeObj,
(newVal, oldVal) => {
if (newVal.AbnormalData) {
AbnormalType.type = props.alarmType.join(",");
getAlarmListDatafun();
// connectWebsocket(null, null, getWebsocket, errWebsocket);
setAlarmscrollBoardList();
}
},
{ deep: true, flush: "post" }
);
//
async function getAlarmListDatafun() {
let result: any = await getAlarmListData(AbnormalType);
if (result.code == 200) {
storeheader.setDataList(result);
}
}
//
function clickNextPageAlarmList() {
// if(storeheader.num<=powerlist.length){
// onloadlist.value=false
// return
// }
AbnormalType.pageNum++;
getAlarmListDatafun();
}
//
watch(
() => storeheader.AlarmpopoverList,
(newVal, oldVal) => {
newVal.forEach((res) => {
powerlist.push(res);
});
},
{ deep: true, flush: "post" }
);
//
watch(
() => storeheader.AlarmscrollBoardList,
(newVal, oldVal) => {
// newVal.forEach(res=>{
// let e=res.context.split('')
// listdata.data.push([e[0]])
// listdata.data.push([e[1]])
// })
// changeAbnormalData(listdata)
// numkey.value++
},
{ deep: true, flush: "post" }
);
let AlarmscrollTime = null;
//15
function setAlarmscrollBoardList() {
let start = 0;
let end = 4;
let i = 0;
setTimeout(() => {
storeheader.AlarmscrollBoardList.slice(0, 5).forEach((element) => {
let e = element.context.split("");
listdata.data.push(...[[e[0]], [e[1]]]);
i++;
});
end = end + 5;
start = i >= 5 ? 5 : storeheader.AlarmscrollBoardList.length - 1;
start <= 0 ? (start = 0) : "";
}, 1000);
AlarmscrollTime = setInterval(() => {
if (i == 0) {
listdata.data = [];
}
i = 0;
if (storeheader.AlarmscrollBoardList.length == 0) {
return;
}
if (storeheader.AlarmscrollBoardList.length - 1 < end) {
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("");
listdata.data.push(...[[listcontent[0]], [listcontent[1]]]);
}
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;
}
//5
if (
end > storeheader.AlarmscrollBoardList.length - 1 &&
start <= storeheader.AlarmscrollBoardList.length - 1
) {
// console.log('3');
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;
}
}, 15000);
}
//
watch(
() => storeheader.num,
(newVal, oldVal) => {
AbnormalNum.value = newVal;
numkey.value++;
},
{ deep: true, flush: "post" }
);
function HeadergetWebsocket(val) {
let data = null;
try {
data = JSON.parse(val);
} catch (e) {
console.log(e);
return;
}
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);
}
}
function HeadererrWebsocket(val) {
// console.log(val);
}
onMounted(() => {
//
typeStatus();
});
onUnmounted(() => {
// closeWebsocket();
storeheader.resetData();
AlarmscrollTime ? clearInterval(AlarmscrollTime) : "";
});
defineExpose({
changeAbnormalData,
HeadergetWebsocket,
HeadererrWebsocket,
});
</script>
<style scoped>
@import "@/assets/css/iconfont.css";
.header2 {
width: 100%;
background-image: url(@/assets/header/header1.png);
background-size: 100% 100%;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.header2-title {
display: flex;
align-items: center;
justify-content: center;
position: relative;
/* height: 100%; */
width: 100%;
}
h1 {
position: absolute;
top: 10px;
z-index: 2;
}
.zh-title {
margin-top: 6px;
font-size: 3rem;
}
.en-title {
font-size: 2rem;
max-width: 600px;
height: 80px;
display: flex;
align-items: center;
overflow: hidden;
/* line-height: 80px; */
}
/* .header2 p {
position: absolute;
right: 50px;
bottom: 20px;
font-size: 20px;
} */
.slot {
display: flex;
justify-content: center;
align-items: center;
padding: 50px 10px 10px 10px;
}
/* .red {
background-color: rgb(228, 57, 97);
}
.blue {
background-color: rgb(32, 174, 197);
} */
.colortip {
width: 16px;
height: 16px;
border-radius: 8px;
}
.tipstring {
font-size: 20px;
color: #fff;
}
.tip {
margin-top: 15px;
}
.tipspan {
display: flex;
margin-left: 10px;
align-items: center;
}
.comeBack {
position: absolute;
/* width: 2rem;
height: 2rem; */
bottom: 10%;
left: 1.5rem;
font-size: 3rem;
color: #fff;
cursor: pointer;
}
.comeBack > i {
font-size: 3rem;
}
.AbnormalData {
position: absolute;
display: flex;
align-items: center;
/* width: 2rem;
height: 2rem; */
bottom: 20%;
right: 1%;
font-size: 3rem;
color: #fff;
}
.AbnormalData:hover {
cursor: pointer;
}
.AbnormalData > span {
font-size: 1rem;
}
.popoverBOX {
max-height: 15rem;
font-size: 18px;
overflow-y: auto;
}
.popoverBOX li {
padding: 10px 0 10px 0;
}
.lookdown {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #1c78c2;
}
.lookdown:hover {
cursor: pointer;
}
.time {
position: absolute;
width: 20rem;
height: 2rem;
bottom: 30%;
left: 4.2rem;
font-size: 25px;
}
.i-badge {
width: 3rem;
height: 3rem;
}
.i-badge > i {
font-size: 3rem;
position: relative;
top: -5px;
}
/* .dv-scroll-board /deep/ .ceil {
font-size: 1.2rem;
} */
.dv-scroll-boardclass :deep(.ceil) {
font-size: 20px;
}
.el-popper.is-dark:deep() {
background: #14274b !important;
}
.el-popover.el-popper:deep() {
background: #14274b !important;
}
.Abnormal-icon-yellow {
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

@ -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 ref="ringRef" class="ring" ></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: {
type: Array,
default: []
}
})
const init = () => {
ringChart = proxy.$echarts.init(ringRef.value, 'dark')
let option = {
tooltip: {
trigger: "item",
},
color:['#7CFFB2','#FF6E76','#FDDD60'],
backgroundColor: 'transparent',
legend: {
type: "scroll",
bottom: "0",
left: "center",
textStyle: {
color: "#fff",
fontSize: 16,
},
},
series: [
{
name: "",
type: "pie",
radius: ["40%", "70%"],
center: ["50%", "45%"],
label: {
show: true,
formatter(params) {
return `${params.name}:${params.value}`
},
fontSize: 18,
fontWeight: 500,
},
labelLine: {
show: true,
},
top: '5%',
data: prop.data,
},
],
}
ringChart.setOption(option)
}
onUpdated(() => {
ringChart.setOption({
series: [
{
data: prop.data
}
]
})
})
onMounted(() => {
init()
})
</script>
<style scoped>
.ring {
width: 100%;
height: 100%;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="61px" height="87px" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient gradientUnits="userSpaceOnUse" x1="0" y1="42" x2="58" y2="42" id="LinearGradient191">
<stop id="Stop192" stop-color="#0033ff" stop-opacity="0.5294117647058824" offset="0" />
<stop id="Stop193" stop-color="#00ffff" offset="1" />
</linearGradient>
</defs>
<g transform="matrix(1 0 0 1 -1847 -1012 )">
<path d="M 57.58803112269304 0.15649613942387075 L 26.45614035087719 1.6000000000000454 L 1 30.799999999999955 L 1 83.20000000000005 " stroke-width="2" stroke="url(#LinearGradient191)" fill="none" transform="matrix(1 0 0 1 1848 1013 )" />
</g>
</svg>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="73px" height="88px" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient gradientUnits="userSpaceOnUse" x1="0" y1="42.5" x2="70" y2="42.5" id="LinearGradient194">
<stop id="Stop195" stop-color="#0033ff" stop-opacity="0.5294117647058824" offset="0" />
<stop id="Stop196" stop-color="#00ffff" offset="1" />
</linearGradient>
</defs>
<g transform="matrix(1 0 0 1 -666 -592 )">
<path d="M 69.58823529411764 1 L 30.88235294117647 1 L 0 35.19718310049065 L 0 85 " stroke-width="2" stroke="url(#LinearGradient194)" fill="none" transform="matrix(1 0 0 1 667 593 )" />
</g>
</svg>

View File

@ -0,0 +1,370 @@
<template>
<div class="container">
<div class="header">
<div class="title">
<header2 ref="headerref" :width="'100%'" :height="'100px'" :title="'设备工况物联系统'" :titleTip="[]"
:typeFun="['time']" :alarmType="[]"></header2>
</div>
</div>
<div class="content">
<div class="left">
<NewBoder :title="'缝纫设备'">
<BoardBar :data="fengren.value" :xData="fengren.chart.xData" :seriesData="fengren.chart.series"
:rowNum="4"></BoardBar>
</NewBoder>
</div>
<div class="center">
<div class="ct">
<StepItem v-for="i in stepList" :data="i"></StepItem>
</div>
<div class="cc">
<NewBoder :title="'设备状态总览'">
<ringChart :data="ringData"></ringChart>
</NewBoder>
</div>
<div class="cb">
<NewBoder :title="'裁剪设备'">
<BoardBar :data="caijian.value" :xData="caijian.chart.xData" :seriesData="caijian.chart.series">
</BoardBar>
</NewBoder>
</div>
</div>
<div class="right">
<NewBoder :title="'板房设备'">
<BoardBar :data="banfang.value" :xData="banfang.chart.xData" :seriesData="banfang.chart.series"
:rowNum="4"></BoardBar>
</NewBoder>
</div>
</div>
<div class="left-tip-type">
<div class="left-tip-type-item">
<div class="yuan green"></div>
<div class="left-tip-type-item-text">工作</div>
</div>
<div class="left-tip-type-item">
<div class="yuan yello"></div>
<div class="left-tip-type-item-text">待机</div>
</div>
<div class="left-tip-type-item">
<div class="yuan red"></div>
<div class="left-tip-type-item-text">停机</div>
</div>
</div>
<div class="wrap"></div>
</div>
</template>
<script setup lang='ts'>
import { ref, reactive, onMounted, onUnmounted, getCurrentInstance, watch, onUpdated, computed } from 'vue'
import header2 from './components/header2.vue'
import NewBoder from './components/NewBoder.vue';
import BoardBar from "./components/BoardBar.vue";
import ringChart from "./components/ringChart.vue";
import StepItem from './components/StepItem.vue'
import { getTopDevice, getCismaList } from '@/http/cisma'
import {chicDeviceList} from '@/http/Exhibition/CHIC'
import { connectWebsocket, closeWebsocket } from "@/utils/websocket"
import { useI18n } from 'vue-i18n'
let { t } = useI18n();
let timer = null
let devnum = reactive({
on: 0,
off: 0,
wait: 0
})
let stepList = reactive([
{
name: '缝纫设备',
total: 0,
online: 0,
},
{
name: '裁剪设备',
total: 0,
online: 0,
},
{
name: '版房设备',
total: 0,
online: 0,
}
])
let fengren = ref({
value: [],
chart: {
xData: [],
series: []
}
})
let caijian = ref({
value: [],
chart: {
xData: [],
series: []
}
})
let banfang = ref({
value: [],
chart: {
xData: [],
series: []
}
})
watch(() => fengren.value, (newVal, oldVal) => {
stepList[0].total = newVal.value.length
stepList[0].online = newVal.value.filter((item) => item[5] !== '0').length
}, { deep: true })
watch(() => caijian.value, (newVal, oldVal) => {
stepList[1].total = newVal.value.length
stepList[1].online = newVal.value.filter((item) => item[5] !== '0').length
}, { deep: true })
watch(() => banfang.value, (newVal, oldVal) => {
stepList[2].total = newVal.value.length
stepList[2].online = newVal.value.filter((item) => item[5] !== '0').length
}, { deep: true })
let ringData = computed(() => {
return [
{ name: '工作', value: devnum.on },
{ name: '停机', value: devnum.off },
{ name: '待机', value: devnum.wait },
]
})
function setData(data:any) {
data.value = data.value.map((item, index) => {
item.unshift(index + 1)
return item
})
data.chart.series = data.chart.series.map((item) => {
item.type = 'bar'
item.barMaxWidth = 30
item.label = {
show: true,
position: 'top',
}
return item
})
return data
}
let labelList = ref()
async function getTopDeviceData() {
let res = await chicDeviceList() as any
if (res.code === 200) {
// setfengren(res.data.)
// setbanfang(res.data.)
// setcaijian(res.data.)
fengren.value = setData(res.data.缝纫设备)
banfang.value = setData(res.data.版房设备)
caijian.value = setData(res.data.裁剪设备)
labelList.value = [];
labelList.value.push(...fengren.value.value.map((item,i) => {
return { label: item[2],index:i,name:'fengren'}
}))
labelList.value.push(...banfang.value.value.map((item,i) => {
return { label: item[2],index:i,name:'banfang'}
}))
labelList.value.push(...caijian.value.value.map((item,i) => {
return { label: item[2],index:i,name:'caijian'}
}))
}
}
async function getCismaListData() {
let res = await getCismaList({s:'CHIC'}) as any
if (res.code === 200) {
devnum.on = res.data.devnum.on
devnum.off = res.data.devnum.off
devnum.wait = res.data.devnum.wait
}
}
function getWebsocket(val) {
try {
let data = JSON.parse(val)
if (data.type == 'WorkingState') {
let { RackNumber, WorkingState } = data
let index = labelList.value.findIndex((item, index) => {
return item['label'] == RackNumber
})
if (index !== -1) {
let name = labelList.value[index].name
let i = labelList.value[index].index
if (name == 'fengren') {
fengren.value.value[i][5] = WorkingState
} else if (name == 'banfang') {
banfang.value.value[i][5] = WorkingState
} else if (name == 'caijian') {
caijian.value.value[i][5] = WorkingState
}
}
}
} catch (err) {
console.log(err);
}
}
function errWebsocket(val) {
// console.log(val);
}
onMounted(() => {
getTopDeviceData()
getCismaListData()
// timer = setInterval(()=>{
// getTopDeviceData()
// },5000)
connectWebsocket(null, null, getWebsocket, errWebsocket)
document.getElementById('app').style.backgroundColor = '#0E0E0E'
})
onUnmounted(() => {
clearInterval(timer)
// closeWebsocket()
document.getElementById('app').style.backgroundColor = '#100c2a'
})
</script>
<style scoped>
.container {
height: 1080px;
width: 1920px;
color: #FFFFFF;
background: url('./images/bg.jpg') no-repeat center center / 100% 100%;
background-color: #0E0E0E;
position: relative;
}
.header {
height: 100px;
width: 1920px;
}
.content {
height: 980px;
width: 1920px;
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0 5px;
box-sizing: border-box;
}
.left,
.right {
height: 980px;
width: 600px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.center {
width: 670px;
height: 980px;
margin: 0 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.ct {
width: 100%;
height: 110px;
margin: 10px 0;
display: flex;
flex-direction: row;
justify-content: space-around;
}
.cc {
width: 100%;
height: 330px;
}
.cb {
width: 100%;
height: 500px;
}
h2 {
/* color: #fff; */
font-size: 18px;
line-height: 1.5rem;
color: #02C1D7;
}
.on {
color: #20AEC5;
font-size: 3.5rem;
}
.off {
color: #797979;
font-size: 3.5rem;
}
.left-tip-type {
position: absolute;
top: 69px;
left: 462px;
width: 160px;
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 14px;
font-weight: 700;
}
.left-tip-type-item {
width: 33%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.yuan {
width: 24px;
height: 24px;
border-radius: 50%;
}
.green {
background-color: #7CFFB2;
}
.yello {
background-color: #FDDD60;
}
.red {
background-color: #FF6E76;
}
.blue {
color: #20AEC5;
}
.err {
color: #FF6E76;
}
</style>

View File

@ -157,7 +157,7 @@ async function getTopDeviceData() {
}
async function getCismaListData() {
let res = await getCismaList() as any
let res = await getCismaList({s:'CISMA'}) as any
if (res.code === 200) {
store.setDevnum(res.data.devnum)
}

View File

@ -18,7 +18,7 @@ export default function getOriToData(ori_data: Object) {
top: [
{ key: data['activation']||0 + "%", val: "稼动率" },
{ key: data['in1'] == "0"?'停止':'启动', val: "设备状态" },
{ key: data['in3'] == "0"?'上电':'断电', val: "上电状态" },
{ key: data['in2'] == "0"?'上电':'断电', val: "上电状态" },
{ key: parseInt(data['speed0']) + "转", val: "设备转速" }
],
bottom: {
@ -42,9 +42,9 @@ export default function getOriToData(ori_data: Object) {
bottom: {
image: BASE_API + data['image'],
data: [
{ key: getRotateGear(), val: "设备状态" },
{ key: getRotateGear(), val: "正转反转" },
{ key: [data['adc1'] + 'mm', parseFloat(data['speed1']).toFixed(1)+'mm/s'], val: "平台X轴距原点位置和速度" },
{ key: getSpeedGear(), val: "设备状态" },
{ key: getSpeedGear(), val: "高速低速" },
{ key: data['adc2'] + 'mm', val: "平台y轴距原点位置" },
{ key: data['adc3'] + 'mm', val: "平台z轴距原点位置" }
]
@ -77,7 +77,7 @@ function getRotateGear() {
} else if(data['in3'] == "1") {
return '反转'
} else {
return '停止'
return '中间位'
}
}
@ -90,7 +90,7 @@ function getSpeedGear() {
} else if(data['in7'] == "1") {
return '低速'
} else {
return '停止'
return '中间位'
}
}

View File

@ -118,7 +118,6 @@ onMounted(() => {
background-size: cover;
background-position: center center;
color: #aeeefa;
}
.bj .text {