264 lines
6.0 KiB
Vue
264 lines
6.0 KiB
Vue
<template>
|
||
<div class="page">
|
||
<div class="top-div">
|
||
<el-cascader
|
||
v-model="mapValue"
|
||
:options="list"
|
||
@change="handleChangeMap"
|
||
style="width: 160px"
|
||
/>
|
||
<div class="line"></div>
|
||
<el-button @click="createTask" icon="CirclePlus" style="color: #536387"> 新建任务 </el-button>
|
||
<el-button @click="editMap" icon="EditPen" style="color: #536387">地图编辑</el-button>
|
||
<el-button type="danger" @click="emergencyStop" icon="Remove" v-if="stopOrRestore === 0">
|
||
一键急停
|
||
</el-button>
|
||
<el-button type="success" @click="emergencyStop" icon="Remove" v-if="stopOrRestore === 1">
|
||
一键恢复
|
||
</el-button>
|
||
</div>
|
||
|
||
<div class="main-content">
|
||
<!-- <div @click="downAgv">导出zip</div> -->
|
||
<!-- 首页 -->
|
||
<indexPage ref="indexPageRef" :isFullScreen="false" />
|
||
</div>
|
||
|
||
<!-- 新建任务的弹窗 -->
|
||
<createTaskDialog
|
||
v-if="mapValue.length"
|
||
ref="createTaskDialogRef"
|
||
:positionMapId="mapValue[1]"
|
||
/>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import indexPage from './components/indexPage.vue'
|
||
import createTaskDialog from './components/createTaskDialog.vue'
|
||
import { ref, defineComponent, reactive, nextTick, onMounted } from 'vue'
|
||
import * as MapApi from '@/api/map/map'
|
||
import download from '@/utils/download'
|
||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||
|
||
defineOptions({ name: 'MapPageRealTimeMap' })
|
||
|
||
const message = useMessage() // 消息弹窗
|
||
const route = useRoute()
|
||
const { push } = useRouter()
|
||
|
||
const mapValue = ref([])
|
||
const list = ref([])
|
||
const indexPageRef = ref(null)
|
||
const stopOrRestore = ref(0) // 地图暂停/恢复 (0:未暂停, 1:暂停)
|
||
|
||
const downAgv = async () => {
|
||
const data = await MapApi.agvDownload()
|
||
download.zip(data, `agv-${new Date().getTime()}.zip`)
|
||
}
|
||
// 筛选出对应的区域对象
|
||
const findChildrenByValues = (tree, values) => {
|
||
if (!tree || tree.length === 0) {
|
||
return null
|
||
}
|
||
function traverse(node) {
|
||
if (node.children) {
|
||
for (let child of node.children) {
|
||
if (values.includes(child.value)) {
|
||
return child
|
||
}
|
||
let result = traverse(child)
|
||
if (result) {
|
||
return result
|
||
}
|
||
}
|
||
}
|
||
return null
|
||
}
|
||
|
||
for (let root of tree) {
|
||
if (values.includes(root.value)) {
|
||
if (root.children) {
|
||
for (let child of root.children) {
|
||
if (values.includes(child.value)) {
|
||
return child
|
||
}
|
||
let result = traverse(child)
|
||
if (result) {
|
||
return result
|
||
}
|
||
}
|
||
}
|
||
}
|
||
let result = traverse(root)
|
||
if (result) {
|
||
return result
|
||
}
|
||
}
|
||
return null
|
||
}
|
||
|
||
//获取地图区域
|
||
const getList = async () => {
|
||
let data = await MapApi.getPositionMapGetMap()
|
||
let mapList = []
|
||
for (let key in data) {
|
||
mapList.push({
|
||
floor: key,
|
||
label: key + '层',
|
||
value: key,
|
||
children: data[key]
|
||
})
|
||
}
|
||
if (mapList.length) {
|
||
mapList.forEach((item) => {
|
||
if (item.children.length) {
|
||
item.children.forEach((child) => {
|
||
child.label = child.area
|
||
child.value = child.id
|
||
})
|
||
}
|
||
})
|
||
}
|
||
list.value = mapList
|
||
|
||
if (query.mapId) {
|
||
let item = findDataById(data, Number(query.mapId))
|
||
mapValue.value = [String(item.floor), Number(item.id)]
|
||
}
|
||
|
||
if (mapValue.value.length) {
|
||
handleChangeMap(mapValue.value)
|
||
} else {
|
||
mapValue.value = [list.value[0].value, list.value[0].children[0].value]
|
||
indexPageRef.value.getMapData(JSON.parse(JSON.stringify(list.value[0].children[0])))
|
||
}
|
||
|
||
await getStopOrRestore()
|
||
}
|
||
const handleChangeMap = async (e) => {
|
||
let item = findChildrenByValues(list.value, e)
|
||
indexPageRef.value.getMapData(item)
|
||
router.replace({
|
||
name: 'MapPageRealTimeMap',
|
||
query: {
|
||
mapId: item.id
|
||
}
|
||
})
|
||
}
|
||
//新建任务
|
||
const createTaskDialogRef = ref()
|
||
const createTask = async () => {
|
||
ElMessageBox.confirm('是否发起拼接任务?', '提示', {
|
||
confirmButtonText: '是',
|
||
cancelButtonText: '否',
|
||
type: 'warning',
|
||
distinguishCancelAndClose: true
|
||
})
|
||
.then(() => {
|
||
push({ name: 'taskManagementCreateTask' })
|
||
})
|
||
.catch((action) => {
|
||
if (action === 'cancel') {
|
||
createTaskDialogRef.value.open()
|
||
}
|
||
})
|
||
}
|
||
|
||
//一键急停
|
||
const emergencyStop = async () => {
|
||
await getStopOrRestore()
|
||
let res = await MapApi.emergencyStopOrRecovery({
|
||
id: mapValue.value[1],
|
||
type: stopOrRestore.value === 0 ? 1 : 0
|
||
})
|
||
if (res === true) {
|
||
message.success('操作成功')
|
||
await getStopOrRestore()
|
||
}
|
||
}
|
||
|
||
const getStopOrRestore = async () => {
|
||
let res = await MapApi.getMapIsStop({
|
||
id: mapValue.value[1]
|
||
})
|
||
if (res && res.length > 0) {
|
||
//暂停状态
|
||
stopOrRestore.value = 1
|
||
} else {
|
||
//正常状态
|
||
stopOrRestore.value = 0
|
||
}
|
||
}
|
||
|
||
//地图编辑
|
||
const router = useRouter() // 路由
|
||
const editMap = async () => {
|
||
let res = await MapApi.checkHaveTask()
|
||
if (res) {
|
||
router.push({
|
||
name: 'editMapPageRealTimeMap',
|
||
query: {
|
||
mapId: mapValue.value[1]
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
const findDataById = (obj, id) => {
|
||
// 遍历 obj 的每一层
|
||
for (const floor in obj) {
|
||
// 遍历当前楼层的每个区域
|
||
for (const item of obj[floor]) {
|
||
// 如果找到匹配的 id,返回该数据
|
||
if (item.id === id) {
|
||
return item
|
||
}
|
||
}
|
||
}
|
||
// 如果没有找到,返回 null
|
||
return null
|
||
}
|
||
|
||
const { query } = useRoute() // 查询参数
|
||
onMounted(() => {
|
||
getList()
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.page {
|
||
position: absolute;
|
||
width: 100%;
|
||
-webkit-user-select: none;
|
||
-moz-user-select: none;
|
||
-ms-user-select: none;
|
||
user-select: none;
|
||
|
||
.top-div {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 0 12px;
|
||
height: 60px;
|
||
box-shadow: rgba(0, 0, 0, 0.06) 0px 2px 3px;
|
||
background-color: #fff;
|
||
position: absolute;
|
||
z-index: 999;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
|
||
.line {
|
||
width: 1px;
|
||
height: 25px;
|
||
background: #e5e5e5;
|
||
margin: 0 16px;
|
||
}
|
||
}
|
||
|
||
.main-content {
|
||
margin-top: 62px;
|
||
}
|
||
}
|
||
</style>
|