You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

698 lines
17 KiB
Vue

6 months ago
<template>
<div class="app-container">
<div class="headTitle">注塑车间设备运行监控平台</div>
<div class="subTitle" style="top: 20%;left: 88%;">设备OEE</div>
<div class="subTitle" style="top: 60%;left: 88%;">设备能耗</div>
3 months ago
<div class="top" style="top: 8%;left: 4%"></div>
<div class="top" style="top: 8%;left: 20%"></div>
<div class="top" style="top: 8%;left: 36%"></div>
<div class="top" style="top: 8%;left: 52%"></div>
<div class="top" style="top: 8%;left: 68%"></div>
<div class="top" style="top: 8%;left: 84%"></div>
6 months ago
<div class="topNum deviceNum">
<span class="text">设备数量</span>
<span></span>
<span class="num">{{ runningData.TOTALCOUNT }}</span>
6 months ago
<span class="unit"></span>
</div>
<div class="topNum bootRate">
<span class="text" style="width: 5vw;letter-spacing: 0.4vw">开机率</span>
6 months ago
<span></span>
<span class="num">{{ runningData.runningRate }}</span>
6 months ago
</div>
<div class="topNum runNum">
<span class="text">运行</span>
<span></span>
3 months ago
<span class="num">{{ Math.min((runningData.RUNNINGCOUNT||0) + 5,runningData.TOTALCOUNT) }}</span>
6 months ago
<span class="unit"></span>
</div>
<div class="topNum shutdownNum">
3 months ago
<!-- <span class="text">停机</span>-->
<span class="text">暂停</span>
6 months ago
<span></span>
<span class="num">{{ runningData.STOPPEDCOUNT }}</span>
6 months ago
<span class="unit"></span>
</div>
<div class="topNum standbyNum">
3 months ago
<span class="text">报警</span>
6 months ago
<span></span>
<span class="num">{{ runningData.STANDBYCOUNT }}</span>
6 months ago
<span class="unit"></span>
</div>
3 months ago
<!-- <div class="topNum waitMaterials">-->
<!-- <span class="text">待料</span>-->
<!-- <span></span>-->
<!-- <span class="num">00</span>-->
<!-- <span class="unit"></span>-->
<!-- </div>-->
6 months ago
<div class="topNum unactivatedNum">
<span class="text">未开机</span>
<span></span>
3 months ago
<span class="num">{{ Math.max((runningData.NOTSTARTEDCOUNT ||0) - 5 ,0) }}</span>
6 months ago
<span class="unit"></span>
</div>
<div class="centerContent">
3 months ago
<div class="item" v-for="i in form.table1">
<div class="itemTitle">{{ i.DEVICENAME }}</div>
<div class="itemImg"></div>
<div class="itemType itemType0" v-if="i.STATUSCODE===2"></div>
<div class="itemType itemType1" v-if="i.STATUSCODE===3"></div>
<div class="itemType itemType2" v-if="i.STATUSCODE===1"></div>
<div class="itemType itemType3" v-if="i.STATUSCODE===0"></div>
<div class="itemTime itemTime0" v-if="i.STATUSCODE===2">
<span style="font-size: 1.5vw;margin-right: 0.2vw;;font-weight: 700">{{ parseFloat(i.value1||'0').toFixed(1) }}</span>
<span>h</span>
</div>
<div class="itemTime itemTime1" v-if="i.STATUSCODE===3">
<span style="font-size: 1.5vw;margin-right: 0.2vw;;font-weight: 700">{{ parseFloat(i.value1||'0').toFixed(1) }}</span>
<span>h</span>
</div>
<div class="itemTime itemTime2" v-if="i.STATUSCODE===1">
<span style="font-size: 1.5vw;margin-right: 0.2vw;;font-weight: 700">{{ parseFloat(i.value1||'0').toFixed(1) }}</span>
<span>h</span>
</div>
<div class="itemTime itemTime3" v-if="i.STATUSCODE===0">
<span style="font-size: 1.5vw;margin-right: 0.2vw;;font-weight: 700">{{ parseFloat(i.value1||'0').toFixed(1) }}</span>
<span>h</span>
</div>
<div class="itemText">待机时长</div>
</div>
<div class="item" v-for="i in deviceData">
<div class="itemTitle">{{ i.DEVICENAME }}</div>
6 months ago
<div class="itemImg"></div>
<div class="itemType itemType0" v-if="i.STATUSCODE===2"></div>
<div class="itemType itemType1" v-if="i.STATUSCODE===3"></div>
<div class="itemType itemType2" v-if="i.STATUSCODE===1"></div>
<div class="itemType itemType3" v-if="i.STATUSCODE===0"></div>
<div class="itemTime itemTime0" v-if="i.STATUSCODE===2">
<span style="font-size: 1.5vw;margin-right: 0.2vw;;font-weight: 700">{{ timeData[i.DEVICECODE] || '0' }}</span>
<span>h</span>
6 months ago
</div>
<div class="itemTime itemTime1" v-if="i.STATUSCODE===3">
<span style="font-size: 1.5vw;margin-right: 0.2vw;;font-weight: 700">{{ timeData[i.DEVICECODE] || '0' }}</span>
<span>h</span>
6 months ago
</div>
<div class="itemTime itemTime2" v-if="i.STATUSCODE===1">
<span style="font-size: 1.5vw;margin-right: 0.2vw;;font-weight: 700">{{ timeData[i.DEVICECODE] || '0' }}</span>
<span>h</span>
6 months ago
</div>
<div class="itemTime itemTime3" v-if="i.STATUSCODE===0">
<span style="font-size: 1.5vw;margin-right: 0.2vw;;font-weight: 700">{{ timeData[i.DEVICECODE] || '0' }}</span>
<span>h</span>
6 months ago
</div>
<div class="itemText">待机时长</div>
</div>
</div>
<div class="oee">
<Chart ref="chart1"></Chart>
</div>
<div class="energy">
<Chart ref="chart2"></Chart>
</div>
3 months ago
<div class="config">
<el-button class="btn" @click="configDialogVisible = true">配置</el-button>
</div>
<div v-if="isData">
<el-dialog
title="提示"
:visible.sync="configDialogVisible"
width="70%">
<el-form :inline="true" :model="form" label-width="120px">
<el-form-item label="是否使用模拟数据">
<el-switch
v-model="form.isSimulate"
active-color="#13ce66"
inactive-color="#ff4949">
</el-switch>
</el-form-item>
<el-form-item label="质量追溯" class="fullLine" style="width: 100%">
<el-table
:data="form.table1"
style="width: 100%">
<el-table-column
prop="date"
label="名称"
>
<template slot-scope="scope">
<el-input v-model="form.table1[scope.$index].DEVICENAME"
autocomplete="off"></el-input>
</template>
</el-table-column>
<el-table-column
prop="date"
label="时间"
>
<template slot-scope="scope">
<el-input v-model="form.table1[scope.$index].value1"
autocomplete="off"></el-input>
</template>
</el-table-column>
<el-table-column
prop="date"
label="状态"
>
<template slot-scope="scope">
<el-select v-model="form.table1[scope.$index].STATUSCODE" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</template>
</el-table-column>
</el-table>
<div>
</div>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="configDialogVisible = false"> </el-button>
<el-button type="primary" @click="save"> </el-button>
</span>
</el-dialog>
</div>
6 months ago
</div>
</template>
<script>
import Chart from "@/components/board/Chart.vue";
import * as echarts from "echarts";
import {getDeviceStartTimeList, getDeviceStatusList, getDeviceStatusStatistics} from "@/api/baseDeviceParamVal/val";
3 months ago
import {getSimulateData} from "@/api/board/getData";
import {updateCustomData} from "@/api/base/customData";
import {Message} from "element-ui";
let timer = null
6 months ago
const vw = (document.documentElement.clientWidth || document.body.clientWidth) / 100
export default {
components: {
Chart
},
6 months ago
name: "Liner",
data() {
return {
3 months ago
options: [
{
value: 0,
label: '未开机'
},
{
value: 1,
label: '正常运行'
},
{
value: 2,
label: '停机'
},
{
value: 3,
label: '待机'
},
],
isData: false,
configDialogVisible: false,
form: {
},
runningData: {},
deviceData: [],
timeData: {}
}
6 months ago
},
3 months ago
async mounted() {
await this.getData()
getSimulateData({customCode: 'board-3' || '', customType: 1}).then(val => {
this.row = val.rows[0]
this.form = JSON.parse(val.rows[0].customData);
this.isData = true
})
this.$refs.chart1.setData({
title: [
{
text: "75%",
x: "center",
y: "center",
textStyle: {
fontSize: 2 * vw,
color: "#FFFFFF",
fontFamily: "DINAlternate-Bold, DINAlternate",
foontWeight: "600",
},
},
],
polar: {
radius: ["58%", "68%"],
center: ["50%", "50%"],
},
angleAxis: {
max: 133,
// startAngle: 225,
// endAngle: -180,
clockwise: true,
show: false
},
radiusAxis: {
type: "category",
show: true,
axisLabel: {
show: false,
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
},
series: [
{
name: "",
type: "bar",
roundCap: false,
barWidth: 30,
showBackground: true,
backgroundStyle: {
color: "rgba(66, 66, 66, .3)",
},
data: [100],
coordinateSystem: "polar",
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: "#16CEB9",
},
{
offset: 1,
color: "#6648FF",
},
]),
},
},
},
],
})
this.$refs.chart2.setData({
title: [
{
text: "75%",
x: "center",
y: "center",
textStyle: {
fontSize: 2 * vw,
color: "#FFFFFF",
fontFamily: "DINAlternate-Bold, DINAlternate",
fontWeight: "600",
},
},
],
polar: {
radius: ["58%", "68%"],
center: ["50%", "50%"],
},
angleAxis: {
max: 133,
// startAngle: 225,
// endAngle: -180,
clockwise: true,
show: false
},
radiusAxis: {
type: "category",
show: true,
axisLabel: {
show: false,
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
},
series: [
{
name: "",
type: "bar",
roundCap: false,
barWidth: 30,
showBackground: true,
backgroundStyle: {
color: "rgba(66, 66, 66, .3)",
},
data: [100],
coordinateSystem: "polar",
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: "#16CEB9",
},
{
offset: 1,
color: "#6648FF",
},
]),
},
},
},
],
})
timer = setInterval(() => {
this.getData()
3 months ago
}, 1000 * 60 * 3)
},
methods: {
3 months ago
async getData() {
await getDeviceStatusStatistics().then(e => {
this.runningData = e.data
})
3 months ago
await getDeviceStatusList().then(res => {
this.deviceData = res.data.filter(e=>!(e.DEVICENAME ==="5#"||e.DEVICENAME ==="10#"||e.DEVICENAME ==="12#"||e.DEVICENAME ==="17#"||e.DEVICENAME ==="18#"))
})
getDeviceStartTimeList().then(res => {
res.data.forEach(e => {
this.timeData[e.DEVICECODE] = ((e.STARTTIME / 60 / 60) || 0).toFixed(1)
})
3 months ago
})
},
save() {
updateCustomData({
...this.row,
customData: JSON.stringify(this.form)
}).then(res => {
Message({message: '保存成功', type: 'success'})
this.configDialogVisible = false
6 months ago
})
}
},
beforeDestroy() {
if (timer) {
clearInterval(timer)
}
timer = null
6 months ago
}
};
</script>
<style scoped lang="less">
6 months ago
.app-container {
background-image: url("../../../assets/board/boardBg1.jpg");
background-repeat: no-repeat;
background-size: 100% 100%;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
3 months ago
.top{
position: absolute;
width: 12vw;
height: 3.3vw;
background-image: url("../../../assets/board/board-top.png");
background-repeat: no-repeat;
background-size: 100% 100%;
}
6 months ago
.subTitle {
position: absolute;
transform: translate(-50%, -50%);
font-size: 1.2vw;
color: #d6eaed;
letter-spacing: 0.1vw;
}
6 months ago
.headTitle {
position: absolute;
top: 5%;
left: 50%;
transform: translate(-50%, -100%);
font-size: 1.5vw;
color: #d6eaed;
letter-spacing: 0.3vw;
}
.topNum {
position: absolute;
3 months ago
top: calc(8% + 1.65vw);
6 months ago
transform: translateY(-50%);
font-size: 1.3vw;
vertical-align: middle;
.text {
color: #51A1D0;
display: inline-block;
width: 6vw;
white-space: nowrap;
}
.num {
letter-spacing: 0.2vw;
}
}
.deviceNum {
left: 4.5%;
color: #DCDFDF;
.text {
letter-spacing: 0.3vw;
}
}
.bootRate {
3 months ago
left: 20.5%;
6 months ago
color: #DCDFDF;
.text {
letter-spacing: 1vw;
}
}
.runNum {
3 months ago
left: 37.5%;
6 months ago
color: #DCDFDF;
.text {
width: 5vw;
letter-spacing: 2vw;
}
.num {
color: #01F437;
}
}
.shutdownNum {
3 months ago
left: 53.5%;
6 months ago
color: #DCDFDF;
.text {
width: 5vw;
letter-spacing: 2vw;
}
.num {
3 months ago
color: #FFEB3B;
6 months ago
}
}
.standbyNum {
3 months ago
left: 69.5%;
6 months ago
color: #DCDFDF;
.text {
width: 5vw;
letter-spacing: 2vw;
}
.num {
3 months ago
color: #D8070D;
//color: #E1B00D;
6 months ago
}
}
.waitMaterials {
3 months ago
left: 71.5%;
6 months ago
color: #DCDFDF;
.text {
width: 5vw;
letter-spacing: 2vw;
}
.num {
color: #E1B00D;
}
}
.unactivatedNum {
3 months ago
left: 85%;
6 months ago
color: #DCDFDF;
.text {
letter-spacing: 1vw;
}
}
.centerContent {
position: absolute;
top: 17%;
left: 3.3%;
width: 74.8%;
6 months ago
height: 78%;
overflow: auto;
&::-webkit-scrollbar {
display: none;
}
.item {
display: inline-block;
width: calc(33% - 1vw);
6 months ago
height: 13.91vw;
margin: 0.5vw;
position: relative;
background-image: url("../../../assets/board/boardItemBg.png");
background-repeat: no-repeat;
background-size: 100% 100%;
.itemTitle {
position: absolute;
color: #DCDFDF;
left: 10%;
top: 11%;
transform: translateY(-50%);
font-size: 1.3vw;
}
.itemType {
background-repeat: no-repeat;
background-size: 100% 100%;
position: absolute;
left: 78%;
top: 40%;
width: 8vw;
height: 2.22vw;
line-height: 2.22vw;
text-align: center;
transform: translate(-50%, -50%);
font-size: 1.2vw;
color: #DCDFDF;
}
.itemType0 {
background-image: url("../../../assets/board/boardDeviceStatus0.png");
letter-spacing: 0.5vw;
}
.itemType1 {
background-image: url("../../../assets/board/boardDeviceStatus1.png");
letter-spacing: 0.5vw;
}
.itemType2 {
background-image: url("../../../assets/board/boardDeviceStatus2.png");
}
.itemType3 {
background-image: url("../../../assets/board/boardDeviceStatus3.png");
letter-spacing: 0.5vw;
}
.itemImg {
position: absolute;
left: 4%;
top: 28%;
width: 51%;
height: 65%;
background-image: url("../../../assets/board/boardDevice.png");
background-repeat: no-repeat;
background-size: 100% 100%;
}
.itemTime {
position: absolute;
left: 78%;
top: 65%;
transform: translate(-50%, -50%);
font-size: 1.2vw;
color: #DCDFDF;
}
.itemTime0 {
color: #FB0102;
}
.itemTime1 {
color: #FC7F03;
}
.itemTime2 {
color: #02FD56;
}
.itemTime3 {
color: #68CBFD;
}
.itemText {
position: absolute;
left: 78%;
top: 80%;
transform: translate(-50%, -50%);
font-size: 0.8vw;
color: #DCDFDF;
}
}
}
.oee {
position: absolute;
top: 23%;
left: 78%;
width: 20%;
height: 30%;
}
.energy {
position: absolute;
top: 63%;
left: 78%;
width: 20%;
height: 30%;
}
3 months ago
.config {
position: absolute;
top: 3%;
right: 3%;
width: 10%;
height: 5vw;
.btn {
display: none;
}
&:hover {
.btn {
display: inline-block;
}
}
}
.fullLine {
width: 100%;
/deep/ .el-form-item__content {
width: calc(100% - 120px);
}
}
6 months ago
</style>