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.

761 lines
20 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div>
<div class="bg">
<div class="bg1"></div>
<div class="title1">白坯车间生产监控看板</div>
<div class="subTitle" style="left: 27%">成型区</div>
<div class="subTitle" style="left: 48.9%;">烘房区</div>
<div class="subTitle" style="left: 70.8%;">收坯区</div>
<div class="floorNum floorNum1">1F</div>
<div class="floorNum floorNum2" @click="$router.push('/cs')">2F</div>
<div class="floorNum floorNum3">3F</div>
<div class="floorNum floorNum4">4F</div>
<div class="floorNum floorNum5">5F</div>
<div class="floorNum floorNum6">6F</div>
<div v-if="isRun.includes(1)">
<div class="arrow" style="top: 34%;left: 22.1%;transform: rotate(15deg);"></div>
<div class="arrow" style="top: 39.6%;left: 21.3%;transform: rotate(15deg);"></div>
<div class="arrow" style="top: 33.6%;left: 15%;transform: rotate(15deg)"></div>
<div class="arrow" style="top: 39.6%;left: 14.1%;transform: rotate(15deg);"></div>
</div>
<div v-if="isRun.includes(2)">
<div class="arrow" style="top: 57.4%;left: 18.6%;transform: rotate(15deg);"></div>
<div class="arrow" style="top: 57.4%;left: 10.9%;transform: rotate(15deg);"></div>
<div class="arrow" style="top: 66.4%;left: 17.3%;transform: rotate(15deg);"></div>
<div class="arrow" style="top: 66.4%;left: 9.2%;transform: rotate(15deg);"></div>
</div>
<div v-if="isRun.includes(3)">
<div class="arrow" style="top: 36.3%;left: 68.2%;transform: rotate(348deg);"></div>
<div class="arrow" style="top: 36.6%;left: 74.5%;transform: rotate(348deg);"></div>
<div class="arrow1" style="top: 42%;left: 68.7%;transform: rotate(348deg);"></div>
<div class="arrow1" style="top: 41.7%;left: 75%;transform: rotate(348deg);"></div>
</div>
<div v-if="isRun.includes(4)">
<div class="arrow" style="top: 54.9%;left: 70.1%;transform: rotate(348deg);"></div>
<div class="arrow" style="top: 54.7%;left: 76.6%;transform: rotate(348deg);"></div>
<div class="arrow1" style="top: 61.5%;left: 70.7%;transform: rotate(348deg);"></div>
</div>
<div class="box" style="top: 24.3%;left: 7.7%;"></div>
<div class="box" style="top: 30.6%;left: 7.7%;"></div>
<div class="box" style="top: 39.1%;left: 7.7%;"></div>
<div class="box" style="top: 45.4%;left: 7.7%;"></div>
<div class="box" style="top: 24.3%;left: 16.8%;"></div>
<div class="box" style="top: 30.6%;left: 16.8%;"></div>
<div class="box" style="top: 39.1%;left: 16.8%;"></div>
<div class="box" style="top: 45.4%;left: 16.8%;"></div>
<div class="box" style="top: 64%;left: 7.7%;"></div>
<div class="box" style="top: 70.3%;left: 7.7%;"></div>
<div class="box" style="top: 78.8%;left: 7.7%;"></div>
<div class="box" style="top: 85.1%;left: 7.7%;;"></div>
<div class="box" style="top: 64%;left: 16.8%;"></div>
<div class="box" style="top: 70.3%;left: 16.8%;"></div>
<div class="box" style="top: 78.8%;left: 16.8%;"></div>
<div class="box" style="top: 85.1%;left: 16.8%;"></div>
<div class="box" style="top: 26.8%;left: 78.5%;"></div>
<div class="box" style="top: 33.1%;left: 78.5%;"></div>
<div class="box" style="top: 38.8%;left: 78.5%;"></div>
<div class="box" style="top: 45.1%;left: 78.5%;"></div>
<div class="box" style="top: 26.8%;left: 85.3%;"></div>
<div class="box" style="top: 33.1%;left: 85.3%;"></div>
<div class="box" style="top: 38.8%;left: 85.3%;"></div>
<div class="box" style="top: 45.1%;left: 85.3%;"></div>
<div class="box" style="top: 64.3%;left: 78.5%;"></div>
<div class="box" style="top: 70.6%;left: 78.5%;"></div>
<div class="box" style="top: 76.3%;left: 78.5%;"></div>
<div class="box" style="top: 82.6%;left: 78.5%;"></div>
<div class="box" style="top: 64.3%;left: 85.3%;"></div>
<div class="box" style="top: 70.6%;left: 85.3%;"></div>
<div v-for="(i,k) in hfData" :class="(hfLocation[k].isProd || parseFloat(i.quantity))? 'hf1':'hf'"
:style="`top: ${hfLocation[k].top}%;`">
<span>
烘房{{ k + 1 }} (产量:{{ i.quantity }}车)
</span>
<div v-if="hfLocation[k].isProd || parseFloat(i.quantity)" class="inProd">
<svg t="1723106843182" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="1501">
<path
d="M148.361503 873.076215a33.27639 33.27639 0 0 1 0.204778-47.150084 33.583556 33.583556 0 0 1 47.354862 0.204778A444.316592 444.316592 0 0 0 511.944454 957.291078c104.436669 0 203.293143-35.938501 280.852728-99.317224l35.580139-32.81564a33.583556 33.583556 0 0 1 47.303668 1.791806 33.27639 33.27639 0 0 1-1.791806 47.09889l-37.064778 34.146695A511.176537 511.176537 0 0 1 511.944454 1023.99744a511.43251 511.43251 0 0 1-363.582951-150.921225z m863.49671-248.497838a33.481167 33.481167 0 0 1-65.426501-14.385639 443.139119 443.139119 0 0 0-299.129144-518.394954A33.327584 33.327584 0 1 1 667.575568 28.265477a509.58951 509.58951 0 0 1 344.180256 596.3129zM275.374922 138.640701a443.036731 443.036731 0 0 0-198.788032 467.456481 33.481167 33.481167 0 0 1-65.52889 13.771306A509.999065 509.999065 0 0 1 279.624061 59.596478C328.821923 31.439533 431.415591-4.191801 507.336954 0.620477c8.549472-1.689417 17.96925 0 25.597223 5.938555 6.4505 5.119445 9.982917 12.081889 11.109194 20.273001 0.255972 2.713306-0.409556 5.221833-1.023889 8.037528a22.832723 22.832723 0 0 1-7.781555 12.133083L341.262173 263.759926a28.208139 28.208139 0 0 1-29.999945 6.91125 30.204723 30.204723 0 0 1-20.836139-23.703028l-15.051167-108.378641z m-4.965861 785.322793c-2.969278-0.46075-7.269611 31.740556-34.402668 17.918056-48.225168-24.624528-138.225003-97.781391-174.93142-168.736892a31.331001 31.331001 0 0 1-8.037528-24.931695c1.023889-8.191111 5.221833-14.846389 11.62114-19.965834 2.201361-1.638222 4.658695-2.354944 7.423194-3.276444a22.832723 22.832723 0 0 1 14.385639 0.409555l285.7162 54.675668c10.392472 1.945389 18.839556 10.750834 21.399278 22.116a30.204723 30.204723 0 0 1-9.573361 30.102334l-113.651669 91.689252z m716.671041-436.688619c1.126278 2.815694 30.921445-10.085306 33.020417 20.273 3.737195 54.061334-12.542639 168.890475-54.522084 236.825504a31.331001 31.331001 0 0 1-17.201334 19.812251 29.999945 29.999945 0 0 1-23.139889 0.307167c-2.559722-1.023889-4.402722-2.815694-6.655278-4.709889a22.832723 22.832723 0 0 1-7.013639-12.54264l-100.341113-273.071171a28.208139 28.208139 0 0 1 7.986333-29.692779 30.204723 30.204723 0 0 1 30.716668-7.320805l137.149919 50.170556z"
fill="#fff" p-id="1502">
</path>
</svg>
生产中
</div>
<div class="infoModel" :style="`display:${loopIndex === k?'inline-block':''}`">
<div class="title">{{ i.equName }}</div>
<div class="equipmentOutput"><span style="color: #fff9">设备产量:</span> {{ i.quantity }}</div>
<div class="equipmentInfo"><span style="color: #fff9">设备状态:</span> {{ parseFloat(i.quantity) > 0 ? '运行' : '停机' }}</div>
</div>
</div>
<div class="equipment" v-for="(i,k) in equipmentData"
:style="`top: ${equipmentLocation[k].top}%;left: ${equipmentLocation[k].left}%;`">
<div :class="equipmentLocation[k].isRight?`equipmentName1`:`equipmentName`"
:style="`display:${loopIndex === 18+k?'inline-block':''}`">
<div class="title">{{ i.equName }}</div>
<div class="equipmentOutput"><span style="color: #fff9">设备产量:</span> {{ i.quantity }}</div>
<div class="equipmentInfo"><span style="color: #fff9">设备状态:</span> {{ parseFloat(i.quantity) > 0 ? '运行' : '停机' }}
</div>
</div>
</div>
<div :class="((equipmentData||[])[k]||{}).quantity>0 ? 'ring':'ring1'" :style="`top:${i.top}%;left:${i.left}%`" v-for="(i,k) in ringLocation"></div>
<div :class="`${i.isGoods? 'agv2':'agv1'}`" v-for="i in agvData" v-show="i.show"
:style="`${getLocation(i.x,i.y)}transform: rotate(${parseFloat(i.rotate )- 180}deg);`"></div>
</div>
</div>
</template>
<script>
import * as TWEEN from '@tweenjs/tween.js'
import {getAgvData, getHourProductionList} from "../../api/board/cs2";
export default {
data() {
return {
loopIndex: 0,
hfLocation: [
{
top: 27.5,
isProd: false
},
{
top: 29.1,
isProd: false
},
{
top: 30.6,
isProd: false
},
{
top: 33.6,
isProd: false
},
{
top: 35.1,
isProd: false
},
{
top: 36.8,
isProd: false
},
{
top: 40.1,
isProd: false
},
{
top: 41.8,
isProd: false
},
{
top: 45.5,
isProd: true
},
{
top: 49.1,
isProd: true
},
{
top: 50.8,
isProd: false
},
{
top: 54.7,
isProd: false
},
{
top: 58.7,
isProd: false
},
{
top: 60.8,
isProd: false
},
{
top: 62.9,
isProd: false
},
{
top: 65,
isProd: false
},
{
top: 67.1,
isProd: false
},
{
top: 69.4,
isProd: false
},
],
ringLocation: [
{
top: 72,
left: 9.9,
isRun: true
},
{
top: 62.5,
left: 11.5,
isRun: true
},
{
top: 44.5,
left: 14.7,
isRun: false
},
{
top: 37.5,
left: 16,
isRun: false
},
{
top: 71.5,
left: 18,
isRun: true
},
{
top: 62.5,
left: 19.5,
isRun: true
},
{
top: 44.5,
left: 22,
isRun: true
},
{
top: 37.5,
left: 23,
isRun: true
},
],
isRun: [1, 2, 3, 4],
equipmentLocation: [
{
top: 63.5,
left: 6.4,
isRight: true
},
{
top: 54,
left: 8,
isRight: true
},
{
top: 36,
left: 11,
isRight: false
},
{
top: 29,
left: 12,
isRight: false
},
{
top: 63,
left: 14.5,
isRight: true
},
{
top: 54,
left: 16,
isRight: true
},
{
top: 36,
left: 18,
isRight: true
},
{
top: 29,
left: 19,
isRight: true
},
],
hfData: [],
equipmentData: [],
agvData: [],
siteData: {
x: 121000,
y: 82000
}
}
},
methods: {
getLocation(x, y) {
let a = (66 + (90 - 66) * y) * x
let b = 12 * y
let xLocation = 16 - b + a
let yLocation = 22 + (84 - 22) * y
return ` left: ${xLocation}%;top: ${yLocation}%;`
},
getAgvLocation() {
let agvArr = []
getAgvData().then(e => {
console.log(Math.max(...e.Data.map(v => v.X)), Math.max(...e.Data.map(v => v.Y)))
e.Data.forEach(v => {
agvArr.push({
id: v.AgvId,
x: (v.X - 126000) / this.siteData.x,
y: (72000 - (v.Y - 116000)) / this.siteData.y,
rotate: v.Angle,
isGoods: false,
show: v.X < 245000 && v.X > 126000 && v.Y < 187000 && v.Y > 116000
// show: true
})
})
this.agvData = agvArr
})
},
updateAGVLocation(time) {
getAgvData().then(e => {
e.Data.forEach(v => {
if (this.agvData.filter(r => r.id === v.AgvId).length >= 1) {
let f1 = new TWEEN.Tween(this.agvData.find(r => r.id === v.AgvId)).to({
rotate: v.Angle,
}, 100).start().onComplete(()=>{
f1 = null
})
let f2 = new TWEEN.Tween(this.agvData.find(r => r.id === v.AgvId)).to({
x: (v.X - 126000) / this.siteData.x,
y: (72000 - (v.Y - 116000)) / this.siteData.y,
show: v.X < 245000 && v.X > 126000 && v.Y < 187000 && v.Y > 116000
// show: true
}, time - 100).start().onComplete(()=>{
f2 = null
})
} else {
this.agvData.push({
id: v.AgvId,
x: (v.X - 126000) / this.siteData.x,
y: (72000 - (v.Y - 116000)) / this.siteData.y,
rotate: v.Angle,
isGoods: false,
show: v.X < 245000 && v.X > 126000 && v.Y < 187000 && v.Y > 116000
// show: true
})
}
})
})
},
getData() {
getHourProductionList().then(e => {
let hfArr = []
let equipmentArr = []
for (let i = 0; i < 18; i++) {
hfArr.push(e.filter(v => v.equName.includes('烘房')).filter(v => v.equCode === `H${i + 1}`)?.[0])
}
for (let i = 0; i < 8; i++) {
equipmentArr.push(e.filter(v => v.equName.includes('成型机')).filter(v => v.equCode === `C${i + 1}`)?.[0])
}
this.hfData = hfArr
this.equipmentData = equipmentArr
})
}
},
mounted() {
this.getData()
this.getAgvLocation()
let time = 2 * 1000
setInterval(() => {
this.updateAGVLocation(time)
}, time)
setInterval(() => {
this.loopIndex = (this.loopIndex + 1) % 26
}, 1000 * 5)
function animate() {
requestAnimationFrame(animate)
TWEEN.update()
}
animate()
}
}
</script>
<style scoped lang="less">
.agv1, .agv2 {
background-size: 100% 100%;
background-repeat: no-repeat;
position: absolute;
width: 1vw;
height: 0.62vw;
}
.agv1 {
background-image: url("~@/assets/board/agv1.png");
top: 30%;
left: 30%;
}
.agv2 {
background-image: url("~@/assets/board/agv2.png");
top: 40%;
left: 40%;
}
.bg {
overflow: hidden;
background-image: url("~@/assets/board/bg.jpg");
//background-image: url("~@/assets/board/ - 04-2.jpg");
background-size: 100% 100%;
background-repeat: no-repeat;
position: absolute;
width: 100%;
height: 100%;
}
.bg1 {
background-image: url("~@/assets/board/ - 04.png");
background-size: 101.9% 102.2%;
background-repeat: no-repeat;
position: absolute;
width: 100%;
height: 100%;
top: 9.3%;
left: -0.8%;
}
.title1 {
position: absolute;
top: 1%;
left: 50%;
font-weight: 700;
letter-spacing: 0.1vw;
font-size: 2.1vw;
color: #fff;
transform: translateX(-50%);
}
.subTitle {
position: absolute;
top: 14%;
letter-spacing: 0.1vw;
font-size: 1.1vw;
color: #fff;
transform: translateX(-50%);
}
.floorNum {
background-size: 100% 100%;
background-repeat: no-repeat;
position: absolute;
top: 96.2%;
width: 4.6%;
height: 2.4%;
color: #fff6;
text-align: center;
line-height: 2.4vh;
font-size: 1.5vh;
}
.floorNum1 {
background-image: url("~@/assets/board/-.png");
left: 35.5%;
}
.floorNum2 {
background-image: url("~@/assets/board/-.png");
left: 39.9%;
}
.floorNum3 {
background-image: url("~@/assets/board/-.png");
left: 44.3%;
}
.floorNum4 {
background-image: url("~@/assets/board/- .png");
left: 51%;
color: #fff;
}
.floorNum5 {
background-image: url("~@/assets/board/-.png");
left: 55.4%;
}
.floorNum6 {
background-image: url("~@/assets/board/-.png");
left: 59.8%;
}
@keyframes arrowAn1 {
from {
top: -100%;
}
to {
top: 100%;
}
}
.arrow, .arrow1 {
position: absolute;
width: 0.5%;
height: 2.5%;
overflow: hidden;
&::after {
content: "";
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-repeat: no-repeat;
background-size: 100% 100%;
animation-name: arrowAn1;
animation-duration: 2s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
}
.arrow {
&::after {
background-image: url("~@/assets/board/ .png");
}
}
.arrow1 {
&::after {
animation-direction: reverse;
background-image: url("~@/assets/board/ .png");
}
}
.box {
position: absolute;
background-image: url("~@/assets/board/.png");
background-repeat: no-repeat;
background-size: 100% 100%;
width: 1.2%;
height: 2.3%;
display: none;
}
.hf, .hf1 {
position: absolute;
left: 48%;
transform: translateX(-50%);
width: 30.6%;
height: 1%;
text-align: center;
font-size: 0.5vw;
line-height: 1vh;
//&:hover .infoModel {
// display: inline-block;
//}
.infoModel {
position: absolute;
width: 14.1vw;
height: 14.7vh;
left: -10%;
top: -365%;
color: #fff;
display: none;
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url("~@/assets/board/1-.png");
background-repeat: no-repeat;
background-size: 100% 100%;
}
.title {
position: absolute;
top: 10%;
left: 7%;
font-size: 1vw;
letter-spacing: 3px;
}
.equipmentOutput {
color: #fff;
position: absolute;
top: 45%;
left: 7%;
font-size: 0.9vw;
letter-spacing: 3px;
}
.equipmentInfo {
color: #fff;
position: absolute;
top: 70%;
left: 7%;
font-size: 0.9vw;
letter-spacing: 3px;
}
//display: none;
}
}
.hf {
color: #000;
}
.hf1 {
color: #4e9b6d;
.inProd {
svg {
width: 0.4vw;
height: 0.4vw;
}
position: absolute;
left: 33%;
height: 100%;
top: 0%;
color: #fff;
padding: 0 0.2vw;
font-size: 0.4vw;
line-height: 1vh;
background-color: #559e70;
border-radius: 0.5vh;
}
}
.equipment {
position: absolute;
width: 9%;
height: 10%;
//&:hover .equipmentName, &:hover .equipmentName1 {
// display: inline-block;
//}
.equipmentName, .equipmentName1 {
position: absolute;
width: 14.1vw;
height: 14.7vh;
display: none;
.equipmentOutput {
color: #fff;
position: absolute;
top: 45%;
font-size: 0.9vw;
letter-spacing: 3px;
white-space: nowrap;
}
.equipmentInfo {
color: #fff;
position: absolute;
top: 70%;
font-size: 0.9vw;
letter-spacing: 3px;
white-space: nowrap;
}
.title {
position: absolute;
line-height: 4.4vh;
color: #fff;
font-size: 0.9vw;
letter-spacing: 3px;
}
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url("~@/assets/board/1-.png");
background-repeat: no-repeat;
background-size: 100% 100%;
}
}
.equipmentName {
top: 4%;
left: -92%;
.equipmentOutput {
left: 7%;
}
.equipmentInfo {
left: 7%;
}
.title {
left: 5%;
}
}
.equipmentName1 {
top: 9%;
left: 73%;
.equipmentOutput {
text-align: right;
left: 25%;
}
.equipmentInfo {
text-align: right;
left: 25%;
}
.title {
text-align: right;
right: 5%;
}
&::before {
transform-style: preserve-3d;
transform: rotateY(180deg)
}
}
}
.ring, .ring1 {
position: absolute;
width: 10px;
height: 10px;
border-radius: 50%; /* 使 */
box-sizing: border-box; /* */
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 50%;
height: 50%;
background: #fff0; /* */
border-radius: 50%;
}
}
.ring {
border: 1px solid #90EE90; /* 5px */
box-shadow: 0 0 3px 3px #90EE9099;
}
.ring1 {
border: 1px solid #ff603b; /* 5px */
box-shadow: 0 0 3px 3px #ff603b99;
}
</style>