<!--
|
* @Date: 2024-01-05 23:47:53
|
* @LastEditors: Sneed
|
* @LastEditTime: 2024-03-08 09:12:51
|
* @FilePath: /belleson-frontend/Users/mache/Documents/demo/mdc/src/container/mapPreview/mapPreview.vue
|
-->
|
<template>
|
<div class="map">
|
<div class="map-container" v-if="!addStatus">
|
<div class="table-tool" v-if="status !== 2">
|
<el-button style="width: 150px;" type="primary" size="mini" @click="save">保存</el-button>
|
<el-button style="width: 150px;" size="mini" @click="out">退出</el-button>
|
<el-input v-show="status !==2" v-model="rows" />
|
<el-input v-show="status !==2" v-model="cols" />
|
<el-button size="mini" v-show="status !==2" @click="createMap">生成地图</el-button>
|
<div class="plant-name" v-if="status===2">{{plantName}}</div>
|
<el-input class="plant-name" v-if="status!==2" v-model="plantName" placeholder="请输入厂名"/>
|
</div>
|
<div class="table" :class="$route.name ==='preview' ? 'active' : ''" >
|
<div class="table-action" :style="position" v-show="showAction && status !== 2">
|
<div @click="merge">合并</div>
|
<div @click="split">拆分</div>
|
<div @click="sign(1)">过道</div>
|
<div @click="sign(2)">机床</div>
|
<div @click="sign(0)">取消</div>
|
<div @click="edit" v-if="showEdit">修改机床</div>
|
<!-- <div>增加行</div> -->
|
<!-- <div>删除行</div> -->
|
<!-- <div>增加列</div> -->
|
<!-- <div>删除列</div> -->
|
</div>
|
<div :style="{width: (cols * height + 'px'),height: rows * height + 'px'}">
|
<table >
|
<tr v-for="(item, index) in map" :key="index">
|
<td v-if="v.rowspan !==0 && v.colspan!==0"
|
:width="v.colspan* height + 'px'"
|
:height="v.rowspan* height + 'px'"
|
:class="{'active': (range.x !=='' && v.rowIndex >=range.x && v.rowIndex<=range.x1 && v.colIndex>=range.y && v.colIndex<=range.y1),aisle: v.type ===1}" @mousedown="e => onMousedown(e, v)" @mousemove="e => onMouseMove(e, v)" v-for="v in item"
|
:rowspan="v.rowspan" :colspan="v.colspan" :key="v.rowIndex + '-' + v.colIndex">
|
<img @click="addDevice($event,v)" @mousedown="e => e.stopPropagation()" v-if="v.type ===2 && status!==2 && !v.id" src="./img/+.png" alt="">
|
<!-- <div v-show="v.id" class="machine">
|
<p>YKX123123213</p>
|
<div>
|
<div class="img">
|
<img src="./img/machine.png" alt="">
|
</div>
|
<ul>
|
<li>
|
<img src="./img/sd.png" alt="">
|
<div>
|
<p>0.00%</p>
|
<p>能力利用率</p>
|
</div>
|
</li>
|
<li>
|
<img src="./img/sd.png" alt="">
|
<div>
|
<p>0.00%</p>
|
<p>能力利用率</p>
|
</div>
|
</li>
|
<li>
|
<img src="./img/sd.png" alt="">
|
<div>
|
<p>0.00%</p>
|
<p>能力利用率</p>
|
</div>
|
</li>
|
</ul>
|
</div>
|
</div> -->
|
<Device v-if="v.id" :id="v.id" style="width: 100%;height: 100%;"></Device>
|
</td>
|
</tr>
|
</table>
|
</div>
|
</div>
|
</div>
|
<addMachine :id="id" :machineid="machineid" @setmachineId="setmachineId" v-else @close="close"/>
|
</div>
|
|
</template>
|
<script>
|
const getParent = (v, layout) => {
|
if (v.rowspan === 0) {
|
return getParent(layout[v.parent[0]][v.parent[1]], layout)
|
} else {
|
return v
|
}
|
}
|
import mixins from '@/mixins/index'
|
import AddMachine from './addMachine.vue'
|
import Device from '../workshop/device.vue'
|
import {mapGetters} from 'vuex'
|
export default {
|
mixins: [mixins],
|
components: {
|
AddMachine,
|
Device
|
},
|
props: {
|
status: {
|
type: Number,
|
default: 0
|
},
|
currentMap: {
|
default: []
|
},
|
name: {
|
type: String,
|
},
|
id: {
|
type: [Number,String]
|
}
|
},
|
computed: {
|
showEdit() {
|
try {
|
const { x, x1, y, y1 } = this.range
|
if (this.range && x && x1 && y && y1) {
|
let start = this.map[x][y]
|
return this.map[x][y].id && (start.rowIndex + start.rowspan -1) === x1 && (start.colIndex + start.colspan -1) === y1
|
}
|
} catch (error) {
|
return false
|
}
|
},
|
machineid () {
|
try {
|
const { x, x1, y, y1 } = this.range
|
if (this.range && x && x1 && y && y1) {
|
let start = this.map[x][y]
|
if (this.map[x][y].id && (start.rowIndex + start.rowspan -1) === x1 && (start.colIndex + start.colspan -1) === y1) {
|
return start.id
|
} else {
|
return ''
|
}
|
}
|
} catch (error) {
|
return ''
|
}
|
}
|
},
|
data() {
|
return {
|
height: 0,
|
plantName: '',
|
rows: 20,
|
cols: 50,
|
map: null, // 地图数据
|
addStatus: false,
|
position: {},
|
selection:[],
|
showAction: false,
|
tdMounseDown: false,
|
range: {x: '',x1: '',y: '',y1: ''},
|
currentAdd: {},
|
colgroups:[]
|
}
|
},
|
watch: {
|
selection(val) {
|
let select = this.selection
|
let range = {}
|
if (val.length === 0) {
|
range = {}
|
} else if (val.length === 1) {
|
let x = select[0].rowIndex
|
let y = select[0].colIndex
|
let x1 = select[0].rowIndex + select[0].rowspan - 1
|
let y1 = select[0].colIndex + select[0].colspan - 1
|
range = { x, y, x1, y1 }
|
} else {
|
// 起始行号 不包含合并
|
let x = Math.min(select[0].rowIndex, select[1].rowIndex)
|
let x1 = Math.max(select[0].rowIndex + select[0].rowspan - 1, select[1].rowIndex + select[1].rowspan - 1)
|
let y = Math.min(select[0].colIndex, select[1].colIndex)
|
let y1 = Math.max(select[0].colIndex + select[0].colspan - 1, select[1].colIndex + select[1].colspan - 1)
|
// 范围内碰到合并格
|
for (var i = x; i <= x1; i++) {
|
for (var j = y; j <= y1; j++) {
|
let v = getParent(this.map[i][j], this.map)
|
x = Math.min(x, v.rowIndex)
|
y = Math.min(y, v.colIndex)
|
x1 = Math.max(x1, v.rowIndex + v.rowspan - 1)
|
y1 = Math.max(y1, v.colIndex + v.colspan - 1)
|
}
|
}
|
range = { x, y, x1, y1 }
|
}
|
this.$set(this.range,'x',range.x)
|
this.$set(this.range,'x1',range.x1)
|
this.$set(this.range,'y',range.y)
|
this.$set(this.range,'y1',range.y1)
|
},
|
name: {
|
handler () {
|
this.plantName = this.name
|
},
|
immediate: true
|
},
|
currentMap: {
|
handler () {
|
if (!this.currentMap || this.currentMap.length === 0) return
|
if (this.currentMap.length > 0) this.map = this.currentMap
|
this.rows = this.currentMap.length;
|
this.cols = this.currentMap[0].length;
|
if (this.$route.name === 'preview') {
|
this.$nextTick(() => {
|
let {width} = document.querySelector('.table div').getBoundingClientRect()
|
console.log(document.querySelector('.table div').getBoundingClientRect())
|
// document.querySelector('.table').scrollLeft
|
// document.querySelector('.table').scrollTo({left: })
|
})
|
}
|
|
},
|
immediate: true
|
},
|
map () {
|
this.height = (document.querySelector('.table').getBoundingClientRect().height - 30) / 20
|
}
|
},
|
mounted() {
|
this.$el.querySelector('table').addEventListener('contextmenu', this.contextmenu)
|
this.$el.addEventListener('mouseup',e => {
|
if(this.status ===2) return
|
this.tdMounseDown = false
|
})
|
try {
|
this.height = (document.querySelector('.table').getBoundingClientRect().height - 30) / 20
|
} catch (error) {
|
}
|
console.log(this.$route.name)
|
},
|
beforeUpdate() {
|
try {
|
this.$el.querySelector('table').removeEventListener('contextmenu', this.contextmenu)
|
} catch (error) {
|
|
}
|
|
},
|
updated() {
|
try {
|
this.$el.querySelector('table').addEventListener('contextmenu', this.contextmenu)
|
} catch (error) {
|
|
}
|
},
|
methods: {
|
createMap() {
|
let data = []
|
for (var i = 0; i < this.rows; i++) {
|
let arr = []
|
for (var j = 0; j < this.cols; j++) {
|
arr.push({
|
rowspan: 1,
|
colspan: 1,
|
rowIndex: i,
|
colIndex: j,
|
type: ''
|
})
|
}
|
data.push(arr)
|
}
|
this.map = data
|
},
|
contextmenu(e) {
|
console.log(e)
|
if(this.status ===2) return
|
if (!this.range.x) return
|
// if (this.range.x !=='') return
|
e.preventDefault()
|
e.stopPropagation()
|
let { pageX: left, pageY: top } = e
|
this.showAction = true
|
let { top: t } = document.querySelector('.table').getBoundingClientRect()
|
if (window.innerWidth - left < 100) {
|
this.position = {
|
right: 0,
|
top: top + 10 + 'px'
|
}
|
} else {
|
this.position = {
|
left: left + 'px',
|
top: top + 10 + 'px'
|
}
|
}
|
|
},
|
onMousedown(e, v) {
|
if(this.status ===2) return
|
if (e.button !== 0) return
|
this.tdMounseDown = true
|
this.showAction = false
|
this.selection = [v]
|
},
|
onMouseMove(e,v) {
|
if(this.status ===2) return
|
if(!this.tdMounseDown) return
|
this.$set(this.selection,1,v)
|
},
|
merge(e) {
|
const { x, x1, y, y1 } = this.range
|
for (var i = x; i <= x1; i++) {
|
for (var j = y; j <= y1; j++) {
|
if (i == x && j == y) {
|
let arr = [...(this.map[i])]
|
arr[j].rowspan = x1 - x + 1
|
arr[j].colspan = y1 - y + 1
|
this.$set(this.map,i,arr)
|
} else {
|
let arr = [...(this.map[i])]
|
arr[j].rowspan = 0
|
arr[j].colspan = 0
|
arr[j].parent = [x, y]
|
this.$set(this.map,i,arr)
|
}
|
}
|
}
|
this.$set(this.range,'x',this.range.x)
|
this.$set(this.range,'x1',this.range.x)
|
this.$set(this.range,'y',this.range.y)
|
this.$set(this.range,'y1',this.range.y)
|
this.showAction = false
|
},
|
split () {
|
const { x, x1, y, y1 } = this.range
|
for(var i=x;i<=x1;i++) {
|
for(var j=y;j<=y1;j++) {
|
if (i==x && j==y) {
|
let arr = [...(this.map[i])]
|
arr[j].rowspan = 1
|
arr[j].colspan = 1
|
this.$set(this.map,i,arr)
|
} else {
|
let arr = [...(this.map[i])]
|
arr[j].rowspan = 1
|
arr[j].colspan = 1
|
arr[j].parent = ''
|
this.$set(this.map,i,arr)
|
}
|
}
|
}
|
this.showAction = false
|
// setData(layoutNew)
|
// setRange({x,y,x1:x,y1: y})
|
// setShowMenu(false)
|
},
|
sign (type) {
|
const { x, x1, y, y1 } = this.range
|
for(var i=x;i<=x1;i++) {
|
for(var j=y;j<=y1;j++) {
|
let arr = [...(this.map[i])]
|
arr[j].type = type
|
this.$set(this.map,i,arr)
|
}
|
}
|
this.showAction = false
|
this.$forceUpdate()
|
},
|
addDevice (e,v) {
|
if(this.status ===2) return
|
e.stopPropagation()
|
this.addStatus = true
|
this.currentAdd = v
|
},
|
save () {
|
if (this.status === 0) {
|
this.$http.postJson('/plant/save',{
|
name: this.plantName,
|
gridSetting: JSON.stringify(this.map)
|
}).then(res => {
|
this.$emit('out')
|
console.log(res)
|
})
|
} else if(this.status === 1) {
|
this.$http.postJson('/plant/modify',{
|
name: this.plantName,
|
gridSetting: JSON.stringify(this.map),
|
id: this.id
|
}).then(res => {
|
this.$emit('out')
|
console.log(res)
|
})
|
}
|
|
},
|
out () {
|
this.$emit('out')
|
},
|
close () {
|
this.addStatus = false
|
},
|
edit (e) {
|
if(this.status ===2) return
|
e.stopPropagation()
|
this.addStatus = true
|
},
|
setmachineId (id) {
|
console.log(id)
|
if (!id) return
|
let i = this.currentAdd.rowIndex
|
let j = this.currentAdd.colIndex
|
let arr = [...(this.map[i])];
|
arr[j].id = id
|
this.$set(this.map,i,arr)
|
this.close()
|
}
|
},
|
}
|
</script>
|
<style lang="scss" scoped>
|
|
@keyframes move {
|
0% {
|
// left: 100%;
|
// transform: translate(0,0);
|
// scrollTop: 0
|
}
|
100% {
|
// left: 100%;
|
// transform: translate(-100%,0);
|
// scrollTop: 100%
|
}
|
}
|
.map {
|
width: 100%;
|
height: 100%;
|
position: relative;
|
.map-container {
|
width: 100%;
|
height: 100%;
|
padding: 20px;
|
overflow: hidden;
|
position: relative;
|
display: flex;
|
flex-direction: column;
|
background: rgba(0,0,0,.6);
|
}
|
}
|
|
.table-tool {
|
padding-bottom: 50px;
|
display: flex;
|
justify-content: flex-start;
|
|
&>div {
|
width: 80px;
|
margin-inline: 10px;
|
}
|
.plant-name {
|
width: 120px;
|
margin-left: auto;
|
margin-right: 30px;
|
text-align: center;
|
line-height: 28px;
|
background: rgba(23,38,67,0.6);
|
border-radius: 14px;
|
overflow: hidden;
|
color: #F7F8FA;
|
font-size: 12px;
|
border: 1px solid;
|
border-image: linear-gradient(180deg, rgba(154, 254, 254, 1), rgba(75, 120, 205, 1)) 1 1;
|
}
|
}
|
|
.table.active {
|
// position: relative;
|
// left: 100%;
|
// animation: move 6s infinite alternate;
|
}
|
.table {
|
// margin-top: 10px;
|
// display: flex;
|
// justify-content: flex-start;
|
width: 100%;
|
height: 100%;
|
position: relative;
|
overflow-x: scroll;
|
|
.table-action {
|
position: fixed;
|
z-index: 999;
|
color: #fff;
|
width: 100px;
|
div {
|
margin-top: 4px;
|
cursor: pointer;
|
}
|
div:hover {
|
color: #68D9FF;
|
}
|
}
|
|
table {
|
width: 100%;
|
border-collapse: collapse;
|
// table-layout: fixed;
|
// word-wrap: break-word;
|
overflow: hidden;
|
border-radius: 10px;
|
// box-sizing: border-box;
|
td {
|
// width: 50px;
|
// height: 50px;
|
box-sizing: border-box;
|
border: 1px solid #1662DB;
|
vertical-align: middle;
|
text-align: center;
|
& > img {
|
width: 20px;
|
height: 20px;
|
cursor: pointer;
|
}
|
.machine {
|
width: 100%;
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
& > p {
|
margin-top: 20px;
|
color: #E9FFFF;
|
text-shadow: 0px 1px 11px #549BD4;
|
background: linear-gradient(180deg, #9AFEFE 0%, #4B78CD 100%);
|
-webkit-background-clip: text;
|
-webkit-text-fill-color: transparent;
|
text-align: center;
|
}
|
& > div {
|
flex: 1 1 auto;
|
margin-top: 20px;
|
display: flex;
|
align-items: center;
|
margin-bottom: 20px;
|
|
overflow: hidden;
|
.img {
|
width: 50%;
|
height: 100%;
|
margin-left: 20px;
|
border: 1px solid #444C55;
|
border-radius: 10px;
|
position: relative;
|
img {
|
position: absolute;
|
top: 50%;
|
left: 50%;
|
transform: translate(-50%, -50%);
|
width: 80%;
|
}
|
}
|
ul {
|
flex: 1 1 auto;
|
height: 100%;
|
margin-left: 20px;
|
list-style: none;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: space-around;
|
li {
|
width: 100%;
|
display: flex;
|
font-size: 12px;
|
align-items: center;
|
& > div {
|
margin-left: 20px;;
|
}
|
p {
|
color: #E9FFFF;
|
text-shadow: 0px 1px 11px #549BD4;
|
}
|
img {
|
width: 40px;
|
height: 40px;
|
}
|
}
|
}
|
}
|
|
}
|
}
|
td.active {
|
background: #68D9FF!important;
|
}
|
td.aisle {
|
// width: 20px;
|
// height: 20px;
|
background: #1662DB;
|
div {
|
// width: 20px;
|
// height: 20px;
|
}
|
}
|
td.device {
|
// width: 400px;
|
// height: 400px;
|
overflow: hidden;
|
div {
|
// width: 400px;
|
}
|
}
|
}
|
}
|
.grid {
|
width: 100%;
|
height: 100%;
|
div {
|
border: 1px solid red;
|
}
|
}
|
</style>
|