update
This commit is contained in:
parent
8262f40232
commit
510985a735
@ -14,7 +14,7 @@
|
|||||||
height: ${heights[ri]}px; line-height: ${heights[ri]}px;
|
height: ${heights[ri]}px; line-height: ${heights[ri]}px;
|
||||||
background-color: ${mergedConfig[row.rowIndex % 2 === 0 ? 'evenRowBGC' : 'oddRowBGC']};`">
|
background-color: ${mergedConfig[row.rowIndex % 2 === 0 ? 'evenRowBGC' : 'oddRowBGC']};`">
|
||||||
<div class="ceil" :class="{'ceil-wrap':wraps[ci]}" v-for="(ceil, ci) in row.ceils" :key="`${ceil}${ri}${ci}`"
|
<div class="ceil" :class="{'ceil-wrap':wraps[ci]}" v-for="(ceil, ci) in row.ceils" :key="`${ceil}${ri}${ci}`"
|
||||||
:style="`width: ${widths[ci]}px;`" :align="aligns[ci]" v-html="ceil"
|
:style="`width: ${widths[ci]}px;justify-content:${wraps[ci]?align_hash[aligns[ci]]:''}`" :align="aligns[ci]" v-html="ceil"
|
||||||
@click="emitEvent('click', ri, ci, row, ceil)" @mouseenter="handleHover(true, ri, ci, row, ceil)"
|
@click="emitEvent('click', ri, ci, row, ceil)" @mouseenter="handleHover(true, ri, ci, row, ceil)"
|
||||||
@mouseleave="handleHover(false)" />
|
@mouseleave="handleHover(false)" />
|
||||||
|
|
||||||
@ -42,7 +42,12 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
ref: 'scroll-board',
|
ref: 'scroll-board',
|
||||||
|
align_hash: {
|
||||||
|
left: 'flex-start',
|
||||||
|
center: 'center',
|
||||||
|
right: 'flex-end',
|
||||||
|
justify: 'space-between'
|
||||||
|
},
|
||||||
defaultConfig: {
|
defaultConfig: {
|
||||||
/**
|
/**
|
||||||
* @description Board header
|
* @description Board header
|
||||||
@ -466,7 +471,6 @@ export default {
|
|||||||
white-space: normal;
|
white-space: normal;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.zd-scroll-board .rows .index {
|
.zd-scroll-board .rows .index {
|
||||||
|
@ -290,6 +290,11 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
name: "CHICExhibition",
|
name: "CHICExhibition",
|
||||||
component: () => import("../views/Exhibition/CHIC/index.vue"),
|
component: () => import("../views/Exhibition/CHIC/index.vue"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/SCISMAExhibition",
|
||||||
|
name: "SCISMAExhibition",
|
||||||
|
component: () => import("../views/Exhibition/SCISMA/index.vue"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/ExhibitionTable_:id",
|
path: "/ExhibitionTable_:id",
|
||||||
name: "ExhibitionTable",
|
name: "ExhibitionTable",
|
||||||
|
98
src/views/Exhibition/SCISMA/components/BarChart.vue
Normal file
98
src/views/Exhibition/SCISMA/components/BarChart.vue
Normal 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>
|
143
src/views/Exhibition/SCISMA/components/BoardBar.vue
Normal file
143
src/views/Exhibition/SCISMA/components/BoardBar.vue
Normal 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, true, false, false, false],
|
||||||
|
columnWidth: [80, 295, 145, 110, 110,85],
|
||||||
|
align: ['center', 'left', '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>
|
114
src/views/Exhibition/SCISMA/components/DevCard.vue
Normal file
114
src/views/Exhibition/SCISMA/components/DevCard.vue
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<template>
|
||||||
|
<div class="dev-card">
|
||||||
|
<div class="dev-left">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
<div class="dev-right">
|
||||||
|
<div class="dev-box">
|
||||||
|
<div class="dev-content dev-title">
|
||||||
|
<div class="key" v-for="item in dev_title">{{ item }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="dev-content" v-for="(items, index) in (dev_value as any)">
|
||||||
|
<div v-for="(item, index) in items" class="dev_value">
|
||||||
|
<div :class="{ status: index == (items.length - 1) }"
|
||||||
|
:style="{ background: index == (items.length - 1) ? status_color[item] : '' }">{{ index ==
|
||||||
|
(items.length - 1) ? '' : item }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang='ts'>
|
||||||
|
import { defineProps, ref } from 'vue'
|
||||||
|
const prop = defineProps({
|
||||||
|
dev_title: {
|
||||||
|
type: Array,
|
||||||
|
default: ['机架号', '状态', '布料层数', '裁片数量']
|
||||||
|
},
|
||||||
|
dev_value: {
|
||||||
|
type: Array,
|
||||||
|
default: [
|
||||||
|
[102014422, '待机', '40层', '0']
|
||||||
|
]
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const status_color = {
|
||||||
|
'0': '#FF6E76',
|
||||||
|
'1': '#FDDD60',
|
||||||
|
'2': '#7CFFB2',
|
||||||
|
'3': '#FDDD60',
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.dev-card {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-left {
|
||||||
|
width: 45%;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.dev-right {
|
||||||
|
width: 55%;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-title {
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-box {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 16px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-content {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.dev_value {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.key {
|
||||||
|
width: 75px;
|
||||||
|
height: 35px;
|
||||||
|
line-height: 35px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #02C1D7;
|
||||||
|
/* background: url(@/assets/img/title_bg.svg) no-repeat center center / 100% 100%; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.status {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
75
src/views/Exhibition/SCISMA/components/NewBoder.vue
Normal file
75
src/views/Exhibition/SCISMA/components/NewBoder.vue
Normal 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>
|
76
src/views/Exhibition/SCISMA/components/StepItem.vue
Normal file
76
src/views/Exhibition/SCISMA/components/StepItem.vue
Normal 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>
|
554
src/views/Exhibition/SCISMA/components/header2.vue
Normal file
554
src/views/Exhibition/SCISMA/components/header2.vue
Normal 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
|
||||||
|
// 判断弹窗是否打开如果打开并且我点击了非弹窗位置则ctrl为true否则为false
|
||||||
|
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>
|
89
src/views/Exhibition/SCISMA/components/ringChart.vue
Normal file
89
src/views/Exhibition/SCISMA/components/ringChart.vue
Normal 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>
|
BIN
src/views/Exhibition/SCISMA/images/bg.jpg
Normal file
BIN
src/views/Exhibition/SCISMA/images/bg.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 82 KiB |
BIN
src/views/Exhibition/SCISMA/images/step_item.png
Normal file
BIN
src/views/Exhibition/SCISMA/images/step_item.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
12
src/views/Exhibition/SCISMA/images/u290.svg
Normal file
12
src/views/Exhibition/SCISMA/images/u290.svg
Normal 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>
|
12
src/views/Exhibition/SCISMA/images/u305.svg
Normal file
12
src/views/Exhibition/SCISMA/images/u305.svg
Normal 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>
|
377
src/views/Exhibition/SCISMA/index.vue
Normal file
377
src/views/Exhibition/SCISMA/index.vue
Normal file
@ -0,0 +1,377 @@
|
|||||||
|
<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',status:item[5]}
|
||||||
|
}))
|
||||||
|
labelList.value.push(...banfang.value.value.map((item,i) => {
|
||||||
|
return { label: item[2],index:i,name:'banfang',status:item[5]}
|
||||||
|
}))
|
||||||
|
labelList.value.push(...caijian.value.value.map((item,i) => {
|
||||||
|
return { label: item[2],index:i,name:'caijian',status:item[5]}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//socket
|
||||||
|
function getWebsocket(val) {
|
||||||
|
try {
|
||||||
|
let data = JSON.parse(val)
|
||||||
|
|
||||||
|
|
||||||
|
if (data.type == 'WorkingState') {
|
||||||
|
let { RackNumber, WorkingState } = data.msg
|
||||||
|
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
|
||||||
|
labelList.value[index].status = WorkingState
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
devnum.on = labelList.value.filter((item) => item.status == '2').length
|
||||||
|
devnum.wait = labelList.value.filter((item) => item.status == '1'||item.status == '3').length
|
||||||
|
devnum.off = labelList.value.filter((item) => item.status == '0').length
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
function errWebsocket(val) {
|
||||||
|
// console.log(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getTopDeviceData()
|
||||||
|
getCismaListData()
|
||||||
|
timer = setInterval(()=>{
|
||||||
|
getTopDeviceData()
|
||||||
|
},1000*30)
|
||||||
|
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>
|
Loading…
Reference in New Issue
Block a user