yudao-dev/src/views/monitoring/equipmentVisualize/index.vue
‘937886381’ d77bebd375 修改
2025-07-04 09:14:09 +08:00

300 lines
7.0 KiB
Vue

<!--
* @Author: zwq
* @Date: 2025-02-10 09:15:55
* @LastEditors: zwq
* @LastEditTime: 2025-02-25 15:48:59
* @Description:
-->
<template>
<div class="app-container" style="overflow: auto">
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@select-changed="handleSearchBarChanged"
@headBtnClick="buttonClick" />
<div class="top-tip">
<div class="block" style="background: #5b8ff9" />
运行
<div class="block" style="background: #f4b183" />
停机
<div class="block" style="background: #ff4f3e" />
故障
</div>
<div class="canvas-line" v-for="(item, index) in lineArr" :key="index">
<div class="title">{{ item.name }}</div>
<canvas
style="
box-shadow: 1px 1px 2px 2px #909399;
padding: 0;
height: 210px;
width: 100%;
"
@click="getclient($event, index + 1, item.num)"
:id="'mycanvas' + (index + 1)"></canvas>
</div>
</div>
</template>
<script>
import { getPdList } from '@/api/core/monitoring/auto';
import { getFactoryPage, getLineEqStatus } from '@/api/core/base/factory';
import linePot from './line-pot';
export default {
data() {
return {
listQuery: {
factoryId: null,
lineId: null,
},
ctx: '', //canvas
lineArr: [],
formConfig: [
{
type: 'select',
label: '工厂',
selectOptions: [],
param: 'factoryId',
onchange: true,
},
{
type: 'select',
label: '产线',
selectOptions: [],
param: 'lineId',
multiple: true,
width: 410
},
{
type: 'button',
btnName: '搜索',
name: 'search',
color: 'primary',
},
],
linePot,
};
},
components: {},
created() {
this.getPdLineList();
},
methods: {
initCanvas(name) {
let canvas = document.getElementById(name);
canvas.width = canvas.clientWidth;
canvas.width = canvas.clientWidth;
canvas.height = 210;
this.ctx = canvas.getContext('2d');
this.ctx.lineWidth = 1;
this.ctx.strokeStyle = '#909399';
this.ctx.fillStyle = '#5b8ff9';
this.ctx.font = '12px 宋体'; //文字大小 字体样式
this.ctx.clearRect(0, 0, canvas.clientWidth, 210); //清空画布
},
//画长方形
fillRect(x, y, width, height, name, color) {
this.ctx.beginPath(); //开始
this.ctx.fillStyle = color ? color : '#5b8ff9'; //填充颜色
this.ctx.fillRect(x, y, width, height); //左上角点的坐标(x,y) 宽 高
this.ctx.strokeRect(x, y, width, height);
this.ctx.fillStyle = '#fff'; //填充颜色
if (height === 50) {
//判断是否特殊机器 机器文字y轴定位加10
this.ctx.fillText(name, x + 5, y + 30);
} else {
this.ctx.fillText(name, x + 5, y + 20);
}
this.ctx.closePath(); //结束
},
//画特殊形
fillLRect(LArr, name, color) {
this.ctx.beginPath(); //开始
LArr.forEach((item, index) => {
if (index === 0) {
this.ctx.moveTo(item[0], item[1]);
} else {
this.ctx.lineTo(item[0], item[1]);
}
});
this.ctx.closePath(); //结束 // 闭合路径
this.ctx.fillStyle = color ? color : '#5b8ff9'; //填充颜色
this.ctx.fill();
this.ctx.stroke();
this.ctx.fillStyle = '#fff'; //填充颜色
if (LArr[0][0] === LArr[1][0]) {
//判断L形第一截是竖着还是横着
this.ctx.fillText(name, LArr[1][0] + 5, LArr[1][1] + 20); //竖着
} else {
this.ctx.fillText(name, LArr[0][0] + 5, LArr[0][1] + 20);
}
},
setRect(item, index) {
const identifier = 'line' + item.num + 'canvas';
this.$nextTick(() => {
this.initCanvas('mycanvas' + (index + 1));
});
this.$nextTick(() => {
this.linePot[identifier].forEach((idItem) => {
item.children.forEach((eqItem) => {
if (eqItem.id === idItem.id) {
idItem.color = ['#5b8ff9', '#f4b183', '#ff4f3e'][
eqItem.equipmentStatus
];
}
});
if (idItem.isL) {
this.fillLRect(idItem.line, idItem.name, idItem.color);
} else {
this.fillRect(
idItem.x,
idItem.y,
idItem.width,
idItem.height,
idItem.name,
idItem.color
);
}
});
});
},
getclient(e, index, num) {
let canvas = document.getElementById('mycanvas' + index);
const rect = canvas.getBoundingClientRect();
const identifier = 'line' + num + 'canvas';
this.isEQ(e.clientX - rect.left, e.clientY - rect.top, identifier);
},
// 检查点击位置是否在设备内
isEQ(x, y, identifier) {
this.linePot[identifier].forEach((idItem) => {
if (idItem.isEQ) {
// 检查点击位置是否在矩形内
if (
x >= idItem.x &&
x <= idItem.x + idItem.width &&
y >= idItem.y &&
y <= idItem.y + idItem.height
) {
console.log(idItem.name, idItem.id);
this.$router.push({
path: '/equipment/analysis/timing-diagram/equipment-status',
query: { eqid: idItem.id },
});
}
}
});
},
getPdLineList() {
const params = {
pageSize: 100,
pageNo: 1,
};
getFactoryPage(params).then((res) => {
this.formConfig[0].selectOptions = res.data.list || [];
});
getPdList().then((res) => {
this.formConfig[1].selectOptions = res.data || [];
});
},
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 100;
this.listQuery.factoryId = val.factoryId || undefined;
this.listQuery.lineId = val.lineId ? val.lineId : [];
this.getDataList();
break;
default:
console.log(val);
}
},
handleSearchBarChanged({ param, value }) {
this.listQuery.lineId = [];
this.$refs.searchBarForm.formInline.lineId = undefined;
getPdList(value).then((res) => {
this.formConfig[1].selectOptions = res.data || [];
});
},
getDataList() {
// this.lineArr = [
// {
// num: 1,
// name: 'A1',
// children: [],
// },
// {
// num: 2,
// name: 'A2',
// children: [],
// },
// {
// num: 3,
// name: 'A3',
// children: [],
// },
// {
// num: 4,
// name: 'A4',
// children: [],
// },
// {
// num: 5,
// name: 'A5',
// children: [],
// },
// ];
getLineEqStatus(this.listQuery).then((response) => {
this.lineArr = response.data;
this.lineArr.forEach((item, index) => {
const num = [
'20001',
'20002',
'20003',
'20004',
'20005',
].indexOf(item.id);
if (num > 0) {
item.num = num;
item.name = item.lineName;
this.setRect(item, index);
} else {
this.$message.warning('没有对应的产线!');
}
});
});
},
},
};
</script>
<style scoped lang="scss">
.top-tip {
.block {
display: inline-block;
width: 20px;
height: 10px;
margin-left: 20px;
margin-right: 3px;
}
}
.canvas-line {
margin-top: 20px;
min-width: 1600px;
.title {
font-size: 20px;
font-weight: bolder;
&::before {
content: '';
background: rgb(39, 240, 17);
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
margin-right: 3px;
transform: translateY(-50%);
}
}
}
</style>