Files
tunnel-cloud-web/src/views/tunnel-manage/index.vue

978 lines
25 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="tunnel-bgc">
<div class="box-top">
<div class="back-tunnel" @click="handleGoSiteOrIndex">
<div class="back-icon"></div>
<span>返回</span>
</div>
<div class="site-name">
{{ siteName }}
</div>
<div class="model-change">
<div class="model" @click="clickModel=1">
<div class="card-bg"></div>
<span>卡片模式</span>
</div>
<div class="model" @click="clickModel=2">
<div class="img-bg"></div>
<span>图纸导航</span>
</div>
</div>
<tunnel-title/>
<div class="all-del-btn" v-if="showOperation">
<div class="all-btn" style=" margin-right: 40px;" v-if="!showAddIcon" @click="handleAdd">
添加
</div>
<div class="all-btn" @click="handleChooseAll">
全选
</div>
<div class="all-btn del-btn" @click="handleMoreDelete">
删除
</div>
</div>
</div>
<div class="box-content" v-if="clickModel===1">
<div class="site-box" v-for="item in tunnelList" :key="item.tunnelId">
<div class="top">
<span>{{ item.tunnelName }}</span>
<span>施工长度{{ item.constructionLength }} 隧道长度{{ item.totalLength }}</span>
<el-checkbox v-if="!item.isDefault" v-model="item.checked" size="large" @change="handleClickSite(item)"/>
<span v-else>默认</span>
</div>
<div class="box-center">
<div>
<div class="left-img" @click="handlePreview(item.tunnelId)"></div>
<div>
<div class="edit-btn" @click.stop="handleGoToEditTunnel(item.tunnelId)">
<div class="edit-icon"></div>
<div>隧道编辑</div>
</div>
<div class="edit-btn" @click.stop="handleEditDevice(item.tunnelId)">
<div class="edit-icon-two"></div>
<div>设备管理</div>
</div>
</div>
</div>
<div class="tunnel-right">
<div>
<!-- <div class="fan-icon"></div>-->
<!-- <span>风机异常</span>-->
</div>
<div class="icons-block">
<div v-for="equItem in iconsList" :key="item.icon" class="icon-text">
<div :style="{ backgroundImage: 'url(' +getImageUrl(equItem.icon)+')' }" class="icon"></div>
<span>{{ equItem.name }}{{ item.tunnelEquipmentAmountInfo[equItem.type] }}</span>
</div>
</div>
</div>
</div>
</div>
<div class="site-box add-box" @click="handleAdd" v-if="showOperation">
<div class="add-icon"></div>
<div style="cursor: pointer">添加隧道</div>
</div>
</div>
<div v-else>
<div class="img-box">
<!-- @/assets/images/tunnel/img.png-->
<img :src="'data:image/png;base64,'+siteImage" style="width:3500px;height:1789px" id="imgModel" usemap="#image"
alt="" @click="clickHandler">
<map name="image" id="image">
<area shape="poly" v-for="(item,index) in coordsList" :coords="item.coords" :key="index" alt=""
:title="item.tunnelId+'隧道'" :href="'/' + item.tunnelId + '/' + siteId" @click="clickHot(item.tunnelId)">
</map>
</div>
</div>
<el-dialog :close-on-click-modal="false" v-model="isVisited" width="1958px">
<div class="siteId">
<span>{{ title }}</span>
</div>
<el-form :model="form" :label-position="right" label-width="188px" :rules="formRules" ref="formInstance">
<el-form-item label="隧道名称" prop="tunnelName">
<el-input v-model="form.tunnelName" placeholder="请输入隧道名称"/>
</el-form-item>
<el-form-item label="隧道简称" prop="tunnelAlias">
<el-input v-model="form.tunnelAlias" placeholder="请输入隧道简称"/>
</el-form-item>
<el-form-item label="序列号" prop="serialNumber">
<el-input v-model="form.serialNumber" placeholder="请输入序列号"/>
</el-form-item>
<el-form-item label="隧道长度" prop="totalLength">
<el-input type="number" v-model="form.totalLength" placeholder="请输入隧道长度"/>
</el-form-item>
<el-form-item label="施工长度" prop="constructionLength">
<el-input type="number" v-model="form.constructionLength" placeholder="请输入施工长度"/>
</el-form-item>
<el-form-item label="基准频率" prop="referenceFrequency">
<el-input type="number" v-model="form.referenceFrequency" placeholder="请输入基准频率"/>
</el-form-item>
<div style="display: flex">
<el-form-item label="升频时间(分钟)" prop="upTime" label-width="300px">
<el-input-number v-model="form.upTime" :min="0" :max="60"/>
</el-form-item>
<el-form-item label="升频率" prop="upFrequency">
<el-input type="number" v-model="form.upFrequency" placeholder="请输入升频率">
<template #suffix>
<span>Hz</span>
</template>
</el-input>
</el-form-item>
</div>
<div style="display: flex">
<el-form-item label="降频时间(分钟)" prop="dropTime" label-width="300px">
<el-input-number v-model="form.dropTime" :min="0" :max="60"/>
</el-form-item>
<el-form-item label="降频率" prop="dropFrequency">
<el-input type="number" v-model="form.dropFrequency" placeholder="请输入降频率">
<template #suffix>
<span>Hz</span>
</template>
</el-input>
</el-form-item>
</div>
<el-form-item label="是否默认">
<el-radio-group v-model="form.isDefault">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="隧道备注">
<el-input v-model="form.remarks" placeholder="请输入隧道备注"/>
</el-form-item>
</el-form>
<div class="btns">
<div class="cancel-btn" @click="isVisited=false">
取消
</div>
<div class="sure-btn" @click="handleSubmit(formInstance)">
确定
</div>
</div>
</el-dialog>
<div class="pagination">
<span @click="firstPage" v-if="showFirst">首页</span>
<el-pagination background v-model:current-page="pageInfo.pageNum" v-model:page-size="pageInfo.pageSize"
:total="total" prev-text="上一页" next-text="下一页" layout="prev, pager, next"
@current-change="handleCurrentChange" :hide-on-single-page="true"/>
<span @click="lastPage" v-if="showFirst">尾页</span>
</div>
</div>
</template>
<script setup>
import {ElLoading, ElMessage, ElMessageBox} from "element-plus";
import {getTunnelList, addTunnel, deleteTunnel} from "@/api/tunnelManage";
import {getSiteDrawing, getSiteDetail} from "@/api/site";
import TunnelTitle from "@/components/tunnelTitle/index.vue";
import {getTunnelBySiteId} from "@/api/largeScreen";
const validateNumber = (rule, value) => {
const reg = /^[A-Za-z0-9]+$/;
return reg.test(value);
}
const router = useRouter()
const siteImage = ref()
const showAddIcon = ref(true)
const params = router.currentRoute.value.params;
const siteId = reactive(params.siteId)
const userId = reactive(params.userId)
const type = reactive(params.type)
const formRules = ref({
tunnelName: [{required: true, message: '请输入隧道名称', trigger: ['blur', 'change']}],
tunnelAlias: [{required: true, message: '请输入隧道简称', trigger: ['blur', 'change']}],
serialNumber: [
{required: true, message: '请输入序列号', trigger: ['blur', 'change']},
{validator: validateNumber, message: '请输入英文、数字、英文数字组合的用户名', trigger: ['blur', 'change']}
],
totalLength: [{required: true, message: '请输入隧道长度', trigger: ['blur', 'change']}],
constructionLength: [{required: true, message: '请输入施工长度', trigger: ['blur', 'change']}],
referenceFrequency: [{required: true, message: '请输入基准频率', trigger: ['blur', 'change']}],
upTime: [{required: true, message: '请选择升频时间', trigger: ['blur', 'change']}],
upFrequency: [{required: true, message: '请输入升频率', trigger: ['blur', 'change']}],
dropTime: [{required: true, message: '请选择降频时间', trigger: ['blur', 'change']}],
dropFrequency: [{required: true, message: '请输入降频率', trigger: ['blur', 'change']}]
})
let clickModel = ref(1)
const showFirst = ref(true)
const showOperation = ref(true)
const formInstance = ref()
const tunnelList = ref([])
const coordsList = ref([
{
tunnelId: 1,
coords: '767,1117,793,1182,2379,682,2437,454,2349,505,2298,666,2221,531,2153,578,2212,692,765,1126',
}, {
tunnelId: 1,
coords: '863,1475,1135,1494,2321,1078,3023,801,3214,703,3288,752,2300,1154,1560,1438,1170,1554,844,1529',
}, {
tunnelId: 94,
coords: '1181,1364,2105,622,2005,589,1116,1324'
}
])
const iconsList = ref([
{
icon: 'sd_icon_fj.png',
name: '风机',
type: 'frequency',
num: 0
},
{
icon: 'sd_icon_sd.png',
name: '湿度',
type: 'humidness',
num: 0
},
{
icon: 'sd_icon_fy.png',
name: '风压',
type: 'windPressure',
num: 0
},
{
icon: 'sd_icon_yq.png',
name: '氧气',
type: 'oxygen',
num: 0
},
{
icon: 'sd_icon_fs.png',
name: '风速',
type: 'windSpeed',
num: 0
},
{
icon: 'sd_icon_fc.png',
name: '粉尘',
type: 'dust',
num: 1
},
{
icon: 'sd_icon_wd.png',
name: '温度',
type: 'temperature',
num: 0
},
{
icon: 'sd_icon_qt.png',
name: '有害气体',
type: 'harmfulGas',
num: 0
},
])
const title = ref('新增隧道')
const isVisited = ref(false);
const tunnelIds = ref([])
const tunnelNameList = ref([])
const siteName = ref(localStorage.getItem('site'))
const form = ref({
tunnelName: '',
tunnelAlias: '',
serialNumber: '',
totalLength: '',
referenceFrequency: '',
upTime: '',
upFrequency: '',
dropTime: '',
dropFrequency: '',
remarks: '',
isDefault: false
});
const isEdit = ref(false)
const pageInfo = reactive({
pageNum: 1,
pageSize: 12
});
const total = ref(10);
onMounted(() => {
showOperation.value = localStorage.getItem('roleKey') !== 'tunnel_admin';
})
const getSiteImg = () => {
getSiteDrawing(siteId).then((res) => {
if (res.code === 1000) {
siteImage.value = res.data.drawingData
}
});
}
getSiteImg()
const clickHot = (id) => {
console.log('点击热区===============')
router.push('/' + id + '/' + siteId)
}
// const testArr=[]
const clickHandler = (id) => {
// let obj=e.offsetX+','+e.offsetY
// testArr.push(obj)
// console.log('正确数值',testArr.map(item=>item).join())
// console.log('点击',e.offsetX+','+e.offsetY+',')
// console.log('图纸', document.getElementById('imgModel').getBoundingClientRect().x,document.getElementById('imgModel').getBoundingClientRect().y)
}
const handleGoSiteOrIndex = () => {
if (type === 'bySite') {
router.push('/site/' + userId + '/' + localStorage.getItem('currentSiteId'))
} else if (type === 'byHome') {
router.push('/' + 'siteToHome/' + siteId)
}
}
//根据站点id获取隧道信息
const getTunnel = (id) => {
getSiteDetail(id).then((res) => {
if (res?.code === 1000) {
siteName.value = res.data.siteName
}
});
}
getTunnel(siteId)
const getList = () => {
const loading = ElLoading.service({
lock: true,
text: '正在加载系统资源...',
background: 'rgba(0, 0, 0, 0.7)',
customClass: 'allLoading'
})
getTunnelList({
siteId: siteId,
...pageInfo
}).then(res => {
if (res.code === 1000) {
total.value = res.data.total
tunnelList.value = res.data.rows
showFirst.value = total.value / pageInfo.pageSize >= 1;
// siteName.value = res.data.siteName
} else {
ElMessage.warning(res.msg)
}
loading.close()
})
}
getList()
const firstPage = () => {
pageInfo.pageNum = 1
getList()
}
const lastPage = () => {
pageInfo.pageNum = total.value / pageInfo.pageSize
getList()
}
//点击页码进行分页功能
const handleCurrentChange = (val) => {
pageInfo.pageNum = val
getList()
}
const handleSubmit = (instance) => {
console.log('form.value', form.value)
if (!instance) return
instance.validate(async (valid) => {
if (!valid) return
const data = {
siteId: siteId,
...form.value
}
addTunnel(data).then(res => {
if (res.code === 1000) {
ElMessage.success('新增成功')
getList()
isVisited.value = false
} else {
ElMessage.warning(res.msg)
}
})
})
}
//预览隧道
const handlePreview = (id) => {
console.log('预览')
if (id) {
getTunnelBySiteId(siteId).then((res) => {
if (res?.code === 1000) {
if (res.data.filter((item) => item.value == id).length === 0) {
ElMessage.warning('当前预览的隧道未准备好, 不予展示, 请添加设备后再试!')
} else {
router.push('/' + id + '/' + siteId)
}
}
});
}
}
const handleGoToEditTunnel = (tunnelId) => {
isEdit.value = true
if (type === 'bySite') {
router.push('/edit/' + tunnelId + '/bySite/' + userId)
} else if (type === 'byHome') {
router.push('/edit/' + tunnelId + '/byHome/' + userId)
}
}
const handleChooseAll = () => {
tunnelList.value.map(item => {
item.checked = !item.checked
if (item.checked && !item.isDefault) {
tunnelIds.value.push(item.tunnelId)
} else if (!item.checked && !item.isDefault) {
tunnelIds.value.map((newItem, index) => {
if (newItem === item.tunnelId) {
tunnelIds.value.splice(index, 1)
}
})
}
})
}
const handleEditDevice = (tunnelId) => {
if (type === 'bySite') {
router.push('/device/' + tunnelId + '/bySite/' + userId)
} else if (type === 'byHome') {
router.push('/device/' + tunnelId + '/byHome/' + userId)
}
}
const restFrom = () => {
form.value = {
tunnelName: '',
tunnelAlias: '',
serialNumber: '',
totalLength: '',
referenceFrequency: '',
upTime: '',
upFrequency: '',
dropTime: '',
dropFrequency: '',
remarks: '',
isDefault: false
}
}
const handleAdd = () => {
restFrom()
title.value = '新增隧道'
isVisited.value = true
nextTick(() => {
// 清空校验
formInstance.value.clearValidate()
})
}
const getImageUrl = (name) => {
return new URL(`../../assets/images/tunnel/${name}`, import.meta.url).href
}
const handleClickSite = (type) => {
if (type.checked) {
tunnelIds.value.push(type.tunnelId)
tunnelNameList.value.push(type.tunnelName)
} else {
tunnelIds.value.map((item, index) => {
if (item === type.tunnelId) {
tunnelIds.value.splice(index, 1)
}
})
tunnelNameList.value.map((item, index) => {
if (item === type.tunnelName) {
tunnelNameList.value.splice(index, 1)
}
})
}
}
const handleMoreDelete = () => {
if (tunnelIds.value.length === 0) {
ElMessage.warning('请先选择隧道进行删除')
} else {
ElMessageBox.confirm(`是否确定删除该隧道`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
customClass: 'delBox'
}).then(() => {
deleteTunnel(tunnelIds.value).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
tunnelIds.value = []
tunnelNameList.value = []
} else {
ElMessage.error(res.msg)
}
})
})
}
}
</script>
<style scoped lang="scss">
:deep(.el-form-item__error) {
font-size: 35px;
}
:deep(.el-form-item__content) {
.el-input-number {
width: 237px;
.el-input-number__decrease, .el-input-number__increase {
background-color: #08B7B8;
width: 50px;
.el-icon {
font-size: 40px;
color: #FFFFFF;
font-weight: bold;
}
}
}
}
.site-name {
position: absolute;
left: 250px;
z-index: 2;
margin-left: 120px;
height: 61px;
font-size: 46px;
font-weight: bold;
color: #FFFFFF;
line-height: 61px;
}
.model-change {
z-index: 55;
position: absolute;
left: 700px;
font-size: 46px;
color: #05FEFF;
display: flex;
//flex-direction: column;
.model {
display: flex;
align-items: center;
cursor: pointer;
&:last-child {
margin-left: 30px
}
> span:hover {
text-decoration: underline;
}
}
.card-bg {
width: 42px;
height: 44px;
background-image: url('@/assets/images/tunnel/sd_icon_tzdh.png');
margin-right: 16px;
}
.img-bg {
width: 42px;
height: 44px;
background-image: url('@/assets/images/tunnel/sd_icon_dtdh.png');
margin-right: 16px;
}
}
:deep(.el-radio-group) {
margin-top: 10px;
}
:deep(.el-radio__label) {
color: #FFFFFF;
font-size: 38px;
}
:deep(.el-radio__inner) {
width: 40px;
height: 40px;
border-radius: 25px;
border: 4px solid #05FEFF;
background-color: transparent;
}
:deep(.el-radio__input.is-checked+.el-radio__label) {
color: #FFFFFF;
}
:deep(.el-radio__input.is-checked .el-radio__inner ) {
background: #064B66;
border-color: #05FEFF !important;
}
:deep(.el-radio__inner::after) {
width: 18px;
height: 18px;
background: #05FEFF;
}
:deep(.el-dialog) {
border: 2px solid #05FEFF;
background: #0D6578;
border-radius: 20px;
padding: 30px 40px;
box-sizing: border-box;
//margin: 458px auto 0 auto;
.el-dialog__header {
padding: 0;
display: none;
}
}
:deep(.el-form-item) {
margin-top: 40px;
}
:deep(.el-form-item__label) {
font-size: 38px;
font-family: MicrosoftYaHei;
color: #FFFFFF;
margin-right: 12px;
line-height: 50px;
}
:deep(.el-input) {
height: 75px;
.el-input__wrapper {
background-color: transparent;
border: 1px solid #08B7B8;
.el-input__inner {
height: auto;
color: #fff;
font-size: 38px;
}
.el-input__suffix-inner {
font-size: 30px;
color: #08B7B8;
line-height: 40px;
font-weight: bold;
}
}
}
.siteId {
display: flex;
justify-content: center;
margin: 0 0 60px 0;
font-size: 50px;
color: #FFFFFF;
}
.tunnel-bgc {
background-color: #072348;
padding: 85px 0 0 0;
width: 100%;
height: 100%;
background-image: url('@/assets/images/tunnel/sd_bj.png');
.box-top {
display: flex;
justify-content: space-between;
.back-tunnel {
cursor: pointer;
margin: 0 0 0 70px;
display: flex;
align-items: center;
width: 178px;
height: 70px;
line-height: 70px;
border-radius: 11px;
border: 2px solid #08B7B8;
font-size: 38px;
color: #FFFFFF;
.back-icon {
margin-right: 20px;
margin-left: 23px;
width: 33px;
height: 33px;
background-image: url('@/assets/images/site/zdgl_icon_fh.png');
}
}
.all-del-btn {
display: flex;
.del-btn {
width: 168px;
height: 60px;
background: #08B7B8;
border-radius: 11px;
}
.all-btn {
cursor: pointer;
padding-left: 53px;
width: 178px;
height: 70px;
line-height: 70px;
border-radius: 11px;
border: 2px solid #08B7B8;
color: #FFFFFF;
font-size: 38px;
&:last-child {
margin-left: 40px;
margin-right: 70px;
}
}
}
}
.img-box {
margin: 100px;
}
.box-content {
height: 1850px;
display: flex;
flex-wrap: wrap;
padding-left: 67px;
padding-right: 70px;
//justify-content: space-between;
box-sizing: border-box;
overflow: hidden;
.add-box {
cursor: pointer;
font-weight: bold;
color: #60DDDE;
font-size: 38px;
display: flex;
flex-direction: column;
align-items: center;
.add-icon {
margin-top: 110px;
margin-bottom: 87px;
width: 220px;
height: 220px;
background-image: url('@/assets/images/site/zdgl_icon_tjz.png');
}
}
.site-box {
//cursor: pointer;
margin-top: 50px;
margin-right: 1.5%;
padding: 40px 30px;
width: 925px;
height: 550px;
background-image: url('@/assets/images/tunnel/zdgl_bj.png');
//box-sizing: border-box;
position: relative;
//&:hover {
// background-image: url('@/assets/images/tunnel/sdgl_bjtq.png');
//}
&:nth-child(4n) {
margin-right: 0;
}
.top {
display: flex;
justify-content: space-between;
font-size: 45px;
font-weight: bold;
color: #FFFFFF;
line-height: 50px;
> span {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
> span:nth-child(2) {
font-size: 38px;
color: #5CE4F2;
}
> span:last-child {
margin-left: 5px;
width: 95px;
padding: 1px 8px;
font-size: 32px;
border: 2px solid #05FEFF;
border-radius: 10px;
position: relative;
}
}
.box-center {
display: flex;
//flex-direction: column;
> div:first-child {
> div:nth-child(2) {
display: flex;
align-items: center;
justify-content: space-between;
margin-right: 30px;
}
}
.left-img {
cursor: pointer;
margin-top: 110px;
margin-right: 50px;
width: 340px;
height: 148px;
background-image: url('@/assets/images/tunnel/sdgl_sdt.png');
}
.edit-btn {
cursor: pointer;
margin-top: 100px;
display: flex;
align-items: center;
justify-content: flex-start;
font-size: 30px;
color: #60DDDE;
//margin-left: 175px;
.edit-icon {
width: 32px;
height: 34px;
background-image: url('@/assets/images/site/zdgl_icon_bj.png');
margin-right: 10px;
}
.edit-icon-two {
width: 32px;
height: 34px;
background-image: url('@/assets/images/tunnel/device.png');
margin-right: 10px;
}
}
.tunnel-right {
padding-top: 40px;
> div:first-child {
display: flex;
align-items: center;
font-size: 36px;
color: #FB3838;
.fan-icon {
margin-right: 10px;
width: 32px;
height: 32px;
background-image: url('@/assets/images/tunnel/sp_icon_yc.png');
}
}
.icons-block {
margin-top: 50px;
display: flex;
flex-wrap: wrap;
.icon-text {
display: flex;
justify-content: space-between;
align-items: center;
color: #FFFFFF;
font-size: 34px;
margin-right: 17px;
margin-bottom: 30px;
&:first-child {
margin-right: 37px;
}
&:nth-child(2n) {
margin-right: 0;
}
.icon {
width: 32px;
height: 32px;
margin-right: 10px;
}
}
}
}
}
}
}
.pagination {
display: flex;
align-items: center;
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
bottom: 50px;
color: #60DDDE;
font-size: 38px;
font-weight: bold;
:deep(.el-pagination.is-background ) {
.btn-next, .btn-prev {
background-color: transparent;
}
.el-pager {
li {
margin: 0 0 0 40px;
}
li.is-active {
background-color: #60DDDE;
}
}
}
> span:first-child {
margin-right: 60px;
}
> span:last-child {
margin-left: 71px;
}
:deep(.btn-prev) {
background-color: transparent;
font-size: 38px;
font-weight: bold;
color: #60DDDE;
margin-right: 20px;
}
:deep(.btn-next) {
background-color: transparent;
font-size: 38px;
font-weight: bold;
color: #60DDDE;
margin-left: 30px;
}
:deep(.el-pager li.is-active ) {
width: 70px;
height: 70px;
background: #60DDDE;
border-radius: 50%;
color: #071F40;
font-size: 38px;
font-weight: bold;
}
:deep(.el-pager li) {
margin-left: 40px;
}
:deep(.el-pager li:not(.is-active) ) {
width: 70px;
height: 70px;
border: 1px solid #60DDDE;
border-radius: 50%;
background-color: transparent;
font-size: 38px;
font-weight: bold;
color: #60DDDE;
}
}
}
</style>