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.

2577 lines
80 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 class="app-container">
<div class="top">
<div class="title">探测系统</div>
<div class="items">
<div
class="item"
:class="{ click: itemsId === 1 }"
@click="setItemsId(1)"
>
<span>主界面</span>
</div>
<div
class="item"
:class="{ click: itemsId === 5 }"
@click="setItemsId(5)"
>
<span>固定物</span>
</div>
<div
class="item"
:class="{ click: itemsId === 2 }"
@click="setItemsId(2)"
>
<span>区域标定</span>
</div>
<div
class="item"
:class="{ click: itemsId === 3 }"
@click="setItemsId(3)"
>
<span>软件设置</span>
</div>
<div
class="item"
:class="{ click: itemsId === 4 }"
@click="setItemsId(4)"
>
<span>历史记录</span>
</div>
</div>
</div>
<div class="left">
<div class="carPo">
{{ currentPosition?.lon?.toFixed(11) }}
<br>
{{ currentPosition?.lat?.toFixed(11) }}
</div>
<div class="dot1Show">
<el-switch
v-model="dot1Show"
class="ml-2"
inline-prompt
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
active-text="显示屏蔽数据"
inactive-text="不显示屏蔽数据"
@change="(e)=>{
dotIndex1 = -1
}"
/>
</div>
<Ruler
ref="rulerRef"
:width="areaData.width"
:height="areaData.height"
:boxPos="boxPos"
:dots="dots"
:dotIndex="dotIndex"
:dots1="dots1"
:dotIndex1="dotIndex1"
:dots2="dots2"
:dotIndex2="dotIndex2"
:dot1Show="dot1Show"
:scan="scan"
/>
</div>
<div class="right">
<div v-if="itemsId === 1" class="tabsItem">
<!-- 区域选择 -->
<el-card shadow="always">
<el-form inline :model="form1" class="demo-form-inline">
<el-form-item>
<el-select
v-model="form1.region"
placeholder="请选择机场名称"
style="width: 200px"
clearable
@change="selectUpdate"
>
<el-option
v-for="i in options1"
:key="i.id"
:label="i.name"
:value="i.id"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-select
v-model="form1.region1"
placeholder="请选择区域名称"
style="width: 200px"
clearable
>
<el-option
v-for="i in options2"
:key="i.id"
:label="i.name"
:value="i.id"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getAreaData">获取区域</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 雷达启动控制 -->
<el-card shadow="always" style="margin-top: 12px">
<el-button
type="primary"
:disabled="!(true || radarWorkState === 1)"
@click="StartWorkBtn"
>
启动雷达
</el-button>
<el-button
type="danger"
:disabled="!(true || radarWorkState === 0)"
@click="StopWorkBtn"
>
关闭雷达
</el-button>
<el-button type="warning" v-if="false" @click="RestartWorkBtn">重启雷达</el-button>
<el-button type="info" v-if="false" @click="ShutDownWorkBtn">关闭雷达</el-button>
</el-card>
<!-- 通讯状态 -->
<el-card shadow="always" style="margin-top: 12px">
<div
v-if="communicationState"
style="width: calc(50% - 60px); position: relative; border-radius: 5px; background-color: #01CE69; height: 44px; display: inline-block; padding: 0 20px; margin-right: 20px;"
>
<span
style="position: absolute; top: 50%; transform: translateY(-50%); left: 20%; color: #fff; letter-spacing: 2px;"
>雷达通讯状态</span
>
<el-icon
size="20px"
style="position: absolute; top: 50%; transform: translateY(-50%); right: 40px;"
>
<success-filled color="#fff"/>
</el-icon>
</div>
<div
v-if="!communicationState"
style="width: calc(50% - 60px); position: relative; border-radius: 5px; background-color: #E8370D; height: 44px; display: inline-block; padding: 0 20px; margin-right: 20px;"
>
<span
style="position: absolute; top: 50%; transform: translateY(-50%); left: 20%; color: #fff; letter-spacing: 2px;"
>雷达通讯状态</span
>
<el-icon
size="20px"
style="position: absolute; top: 50%; transform: translateY(-50%); right: 40px;"
>
<warning-filled color="#fff"/>
</el-icon>
</div>
<div
v-if="radarWorkState === 1"
style="width: calc(50% - 60px); position: relative; border-radius: 5px; background-color: #01CE69; height: 44px; display: inline-block; padding: 0 20px; margin-right: 20px;"
>
<span
style="position: absolute; top: 50%; transform: translateY(-50%); left: 20%; color: #fff; letter-spacing: 2px;"
>雷达扫描状态</span
>
<el-icon
size="20px"
style="position: absolute; top: 50%; transform: translateY(-50%); right: 40px;"
>
<success-filled color="#fff"/>
</el-icon>
</div>
<div
v-if="radarWorkState === 0"
style="width: calc(50% - 60px); position: relative; border-radius: 5px; background-color: #E8370D; height: 44px; display: inline-block; padding: 0 20px; margin-right: 20px;"
>
<span
style="position: absolute; top: 50%; transform: translateY(-50%); left: 20%; color: #fff; letter-spacing: 2px;"
>雷达扫描状态</span
>
<el-icon
size="20px"
style="position: absolute; top: 50%; transform: translateY(-50%); right: 40px;"
>
<warning-filled color="#fff"/>
</el-icon>
</div>
</el-card>
<!-- 目标表格1 -->
<el-card shadow="always" style="margin-top: 12px;position:relative;">
<div style="color: #999;margin-bottom: 8px;">
实时检测数据
</div>
<div style="position: absolute;right: 30px;top: 20px;z-index: 100;">
<el-popover placement="bottom" :width="300" trigger="click">
<template #reference>
<el-button style="margin-right: 16px">批量处理</el-button>
</template>
<el-button style="margin-right: 16px" @click="batchDisposal">处置</el-button>
<el-button style="margin-right: 16px" @click="batchDel">删除</el-button>
<el-button style="margin-right: 16px" @click="batchShild">固定物</el-button>
</el-popover>
</div>
<el-table
ref="table1Ref"
highlight-current-row
:data="table1Data.slice((currentPage1 - 1) * pageSize1, currentPage1 * pageSize1)"
style="width: 100%"
@row-click="table1Current"
>
<el-table-column type="selection" width="55"/>
<el-table-column label="序号" width="60">
<template #default="scope">
{{ (currentPage1 - 1) * pageSize1 + scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column prop="Lat" label="目标经纬度" width="100">
<template #default="scope">
{{ scope.row.Lon }},{{ scope.row.Lat }}
</template>
</el-table-column>
<el-table-column prop="Strength" label="强度信息" width="100"/>
<el-table-column label="处理方式" show-overflow-tooltip width="200" fixed="right">
<template #default="scope">
<el-button type="primary" @click.stop="openHandleObstacleDialog(scope)" link>处置</el-button>
<el-popconfirm
class="box-item"
title="确定删除这个点位吗?"
placement="top"
@confirm="delPoint(scope)"
>
<template #reference>
<el-button type="primary" @click.stop link>删除</el-button>
</template>
</el-popconfirm>
<el-button type="primary" @click.stop="openShildDialog(scope)" link>固定物</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="currentPage1"
v-model:page-size="pageSize1"
:pager-count="4"
:page-sizes="[10,20,50,100, 200, 300, 400]"
layout="total, sizes, prev, pager, next, jumper"
:total="table1Data.length"
/>
</el-card>
<!-- 目标表格2 -->
<el-card shadow="always" style="margin-top: 12px;position:relative;">
<div style="color: #999;margin-bottom: 8px;">
屏蔽数据
</div>
<div style="position: absolute;right: 30px;top: 20px;z-index: 100;">
<el-popover placement="bottom" :width="300" trigger="click">
<template #reference>
<el-button style="margin-right: 16px">批量处理</el-button>
</template>
<el-button style="margin-right: 16px" @click="batchDisposal1">处置</el-button>
<el-button style="margin-right: 16px" @click="batchDel1">删除</el-button>
<el-button style="margin-right: 16px" @click="batchShild1">固定物</el-button>
</el-popover>
</div>
<el-table
ref="table2Ref"
highlight-current-row
:data="table2Data.slice((currentPage2 - 1) * pageSize2, currentPage2 * pageSize2)"
style="width: 100%"
@row-click="table1Current1"
>
<el-table-column type="selection" width="55"/>
<el-table-column label="序号" width="60">
<template #default="scope">
{{ (currentPage2 - 1) * pageSize2 + scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column prop="Lon" label="目标经度" width="100"/>
<el-table-column prop="Lat" label="目标纬度" width="100"/>
<el-table-column prop="Strength" label="强度信息" width="100"/>
<el-table-column label="处理方式" show-overflow-tooltip width="200" fixed="right">
<template #default="scope">
<el-button type="primary" @click.stop="openHandleObstacleDialog1(scope)" link>处置</el-button>
<el-popconfirm
class="box-item"
title="确定删除这个点位吗?"
placement="top"
@confirm="delPoint1(scope)"
>
<template #reference>
<el-button type="primary" @click.stop link>删除</el-button>
</template>
</el-popconfirm>
<el-button type="primary" @click.stop="openShildDialog1(scope)" link>固定物</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="currentPage2"
v-model:page-size="pageSize2"
:pager-count="4"
:page-sizes="[10,20,50,100, 200, 300, 400]"
layout="total, sizes, prev, pager, next, jumper"
:total="table2Data.length"
@change="getShildTableList"
/>
</el-card>
</div>
<div v-if="itemsId === 2" class="tabsItem">
<el-card shadow="always">
<el-form inline :model="form5" class="demo-form-inline">
<el-form-item>
<el-input
v-model="form5.region"
placeholder="请输入机场名称"
style="width: 200px"
/>
</el-form-item>
<el-form-item>
<el-input
v-model="form5.region1"
placeholder="请输入区域名称"
style="width: 200px"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">添加</el-button>
</el-form-item>
</el-form>
<el-form
inline
:model="form6"
class="demo-form-inline"
style="margin-top: 12px"
>
<el-form-item>
<el-select
v-model="form6.region"
placeholder="请选择机场名称"
style="width: 200px"
clearable
@change="select2Update"
>
<el-option
v-for="i in options1"
:key="i.id"
:label="i.name"
:value="i.id"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-select
v-model="form6.region1"
placeholder="请选择区域名称"
style="width: 200px"
clearable
@change="select3Update"
>
<el-option
v-for="i in options2"
:key="i.id"
:label="i.name"
:value="i.id"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getArea2">确定</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card shadow="always" style="margin-top: 12px">
<div
v-for="(i, k) in regionLabeling"
:key="k"
style="margin-bottom: 12px"
>
<el-input
disabled
v-model="i.name"
placeholder="点位名称"
style="width: 100px"
/>
<el-input
v-model="i.lon"
placeholder="经度"
style="width: 150px; margin-left: 20px"
/>
<el-input
v-model="i.lat"
placeholder="纬度"
style="width: 150px; margin-left: 20px"
/>
<el-button
type="primary"
@click="getPoint(k)"
style="margin-left: 20px"
>
获取
</el-button>
<el-button
type="danger"
@click="DeleteCData({ id: parseFloat(i.id) }).then(() => getArea2())"
style="margin-left: 20px"
>
删除
</el-button>
</div>
<el-button
type="primary"
style="text-align: center"
@click=" InsertCListData([{
name: `点位${regionLabeling.length + 1}`,
lon: '1',
lat: '1',
fodAreaId: form6.region1,
fodAirId: form6.region
}]).then(() => {
getArea2()
}) "
>
添加
</el-button>
</el-card>
<div style="text-align: center; margin-top: 12px">
<el-button
type="primary"
style="margin-left: 20px"
@click="saveAreaPoint"
>
提交
</el-button>
</div>
</div>
<div v-if="itemsId === 3" class="tabsItem">
<!-- 成像设置 -->
<div>成像设置</div>
<el-form :model="parasSignalproForm" inline label-width="auto" label-position="top">
<el-form-item
v-for='(key, idx) in ["imaging_rangemin", "imaging_rangemax", "imaging_rangeres", "imaging_azimuthlength", "imaging_azimuthres"]'
:key="idx"
:label="key"
style="width: calc(33% - 32px)"
>
<el-input
v-model="parasSignalproForm.imaging[key]"
/>
</el-form-item>
</el-form>
<!-- 检测设置 -->
<div>检测设置</div>
<el-form :model="parasSignalproForm" inline label-width="auto" label-position="top">
<el-form-item
v-for='(key, idx) in ["alpha", "decstartr", "decwidth", "sk_r", "sk_a", "lk_r", "lk_a"]'
:key="idx"
:label="key"
style="width: calc(33% - 32px)"
>
<el-input
v-model="parasSignalproForm.dectection[key]"
/>
</el-form-item>
<el-form-item style="width: 100%">
<div style="text-align: center; width: 100%">
<el-button type="primary" @click="saveParasSignalproForm">保存</el-button>
</div>
</el-form-item>
</el-form>
<!-- 路线设置 -->
<div>路线设置</div>
<el-form :model="parasPosForm" inline label-width="auto" label-position="top">
<el-form-item style="width: calc(33% - 32px)" label="路线数量">
<el-input-number
v-model="parasPosForm.runwaynum.startpos_num"
:precision="0"
:step="1"
:min="0"
@change="updateRunwayNum"
/>
</el-form-item>
<div
v-for="(item, k) in parasPosForm.runwaynum.startpos_num ? Array(parasPosForm.runwaynum.startpos_num) : []"
:key="k"
style="width: 100%"
>
<div>路线{{ k + 1 }}设置</div>
<el-form-item
v-for='(field, idx) in ["startpos_lon_a", "startpos_lat_a", "startpos_alt_a", "startpos_lon_b", "startpos_lat_b", "startpos_alt_b", "startpos_ori"]'
:key="idx"
:label="field"
style="width: calc(33% - 32px); display: inline-block"
>
<el-input
v-model="parasPosForm.runwayedges[k][field]"
/>
</el-form-item>
</div>
<el-form-item style="width: 100%">
<div style="text-align: center; width: 100%">
<el-button type="primary" @click="saveParasPosForm">保存</el-button>
</div>
</el-form-item>
</el-form>
<!--屏蔽信息设置-->
<div>屏蔽信息设置</div>
<el-form :model="shieldInfoForm" inline label-width="auto" label-position="top">
<el-form-item style="width: calc(33% - 32px)" label="偏差值">
<el-input v-model="shieldInfoForm.deviation"/>
</el-form-item>
<el-form-item style="width: calc(33% - 32px)" label="范围">
<el-input v-model="shieldInfoForm.shielding"/>
</el-form-item>
<el-form-item style="width: 100%">
<div style="text-align: center; width: 100%">
<el-button type="primary" @click="saveShieldInfoForm">保存</el-button>
</div>
</el-form-item>
</el-form>
</div>
<div v-if="itemsId === 4" class="tabsItem">
<!-- 时间范围选择 -->
<el-card shadow="always">
<el-date-picker
v-model="date1"
type="datetimerange"
range-separator="到"
start-placeholder="选择开始时间"
end-placeholder="选择结束时间"
style="width: calc(100% - 20px)"
/>
</el-card>
<!-- 数据表格 -->
<el-card shadow="always" style="margin-top: 12px;position:relative">
<div style="position: absolute;right: 30px;top: 20px;z-index: 100;">
<el-popover placement="bottom" :width="300" trigger="click">
<template #reference>
<el-button style="margin-right: 16px">批量处理</el-button>
</template>
<el-button style="margin-right: 16px" @click="batchShild3">固定物</el-button>
<el-button style="margin-right: 16px" @click="batchDel3">删除</el-button>
</el-popover>
</div>
<el-table
@row-click="table2Current" ref="table4Ref" :data="tableData3" style="width: 100%">
<el-table-column type="selection" width="55"/>
<el-table-column label="序号" type="index" width="60"/>
<el-table-column prop="longitude" label="目标经度" width="100"/>
<el-table-column prop="latitude" label="目标纬度" width="100"/>
<el-table-column prop="strength" label="强度信息" width="100"/>
<el-table-column label="处理方式" show-overflow-tooltip width="200" fixed="right">
<template #default="scope">
<el-button type="primary" link @click.stop="openShildDialog3(scope)">固定物</el-button>
<el-button type="primary" link @click.stop="openHandleObstacleDialog3(scope)">修改</el-button>
<el-popconfirm
class="box-item"
title="确定删除这个点位吗?"
placement="top"
@confirm="delObstacleItem(scope)"
>
<template #reference>
<el-button type="primary" @click.stop link>删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="currentPage4"
v-model:page-size="pageSize4"
:pager-count="4"
:page-sizes="[10,20,50,100, 200, 300, 400]"
layout="total, sizes, prev, pager, next, jumper"
:total="total4"
/>
</el-card>
</div>
<div v-if="itemsId === 5" class="tabsItem">
<!-- 数据表格 -->
<el-card shadow="always" style="margin-top: 12px;position:relative">
<div style="position: absolute;right: 30px;top: 20px;z-index: 100;">
<el-popover placement="bottom" :width="300" trigger="click">
<template #reference>
<el-button style="margin-right: 16px">批量处理</el-button>
</template>
<el-button style="margin-right: 16px" @click="batchDisposal2">处置</el-button>
<el-button style="margin-right: 16px" @click="batchDel2">删除</el-button>
</el-popover>
</div>
<el-table
ref="table3Ref"
highlight-current-row
:data="tableData2"
style="width: 100%"
@row-click="table2Current"
>
<el-table-column type="selection" width="55"/>
<el-table-column label="序号" type="index" width="60"/>
<el-table-column prop="name" label="名称" width="100"/>
<el-table-column prop="lon" label="目标经度" width="100"/>
<el-table-column prop="lat" label="目标纬度" width="100"/>
<el-table-column prop="strength" label="强度信息" width="100"/>
<el-table-column label="处理方式" show-overflow-tooltip width="160" fixed="right">
<template #default="scope">
<el-button type="primary" link @click.stop="openHandleObstacleDialog2(scope)">处置</el-button>
<el-button type="primary" link @click.stop="openShildDialog2(scope)">修改</el-button>
<el-popconfirm
class="box-item"
title="确定删除这个点位吗?"
placement="top"
@confirm="delShildItem(scope)"
>
<template #reference>
<el-button type="primary" @click.stop link>删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="currentPage3"
v-model:page-size="pageSize3"
:pager-count="4"
:page-sizes="[10,20,50,100, 200, 300, 400]"
layout="total, sizes, prev, pager, next, jumper"
:total="total3"
@change="getShildTableList"
/>
</el-card>
</div>
</div>
<el-button style="position: fixed;top: 10px;right: 10px" type="primary" @click="toAdmin">管理</el-button>
<el-dialog v-model="dialog1" title="处置障碍物" width="500">
<el-form :model="dialog1Form">
<el-form-item label="发现时间" label-width="120px">
<el-input v-model="dialog1Form.time" disabled autocomplete="off"/>
</el-form-item>
<el-form-item label="处理信息描述" label-width="120px">
<el-input
v-model="dialog1Form.description"
style="width: 100%"
:rows="2"
type="textarea"
/>
</el-form-item>
<el-form-item label="处理照片" label-width="120px">
<el-upload @click.stop="onSubmit"
ref="uploadRef"
:http-request="uploadFiles"
:file-list="dialog1Form.fileList.concat({type:'camera'})"
list-type="picture-card">
<template #trigger>
<el-icon>
<Plus/>
</el-icon>
</template>
<template #file="{ file }">
<div v-if="file.type !=='camera'">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt=""/>
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="handlePictureCardPreview(file)"
>
<el-icon><zoom-in/></el-icon>
</span>
<span
class="el-upload-list__item-delete"
@click="handleDownload(file)"
>
<el-icon><Download/></el-icon>
</span>
<span
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<el-icon><Delete/></el-icon>
</span>
</span>
</div>
<div @click="openCamera" v-if="file.type ==='camera'" style="border:none" class="el-upload--picture-card">
<el-icon>
<Camera/>
</el-icon>
</div>
</template>
</el-upload>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialog1 = false">关闭</el-button>
<el-button type="primary" @click="handleObstacle">
处理
</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="dialog2" title="处置障碍物" width="500">
<el-form :model="dialog2Form">
<el-form-item label="发现时间" label-width="120px">
<el-input v-model="dialog2Form.time" disabled autocomplete="off"/>
</el-form-item>
<el-form-item label="处理信息描述" label-width="120px">
<el-input
v-model="dialog2Form.description"
style="width: 100%"
:rows="2"
type="textarea"
/>
</el-form-item>
<el-form-item label="处理照片" label-width="120px">
<el-upload @click.stop="onSubmit"
ref="uploadRef"
:http-request="uploadFiles1"
:file-list="dialog2Form.fileList.concat({type:'camera'})"
list-type="picture-card">
<template #trigger>
<el-icon>
<Plus/>
</el-icon>
</template>
<template #file="{ file }">
<div v-if="file.type !=='camera'">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt=""/>
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="handlePictureCardPreview1(file)"
>
<el-icon><zoom-in/></el-icon>
</span>
<span
class="el-upload-list__item-delete"
@click="handleDownload1(file)"
>
<el-icon><Download/></el-icon>
</span>
<span
class="el-upload-list__item-delete"
@click="handleRemove1(file)"
>
<el-icon><Delete/></el-icon>
</span>
</span>
</div>
<div @click="openCamera1" v-if="file.type ==='camera'" style="border:none"
class="el-upload--picture-card">
<el-icon>
<Camera/>
</el-icon>
</div>
</template>
</el-upload>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialog2 = false">关闭</el-button>
<el-button type="primary" @click="handleObstacle1">
处理
</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="dialog3" title="处置障碍物" width="500">
<el-form :model="dialog3Form">
<el-form-item label="发现时间" label-width="120px">
<el-input v-model="dialog3Form.time" disabled autocomplete="off"/>
</el-form-item>
<el-form-item label="处理信息描述" label-width="120px">
<el-input
v-model="dialog3Form.description"
style="width: 100%"
:rows="2"
type="textarea"
/>
</el-form-item>
<el-form-item label="处理照片" label-width="120px">
<el-upload @click.stop="onSubmit"
ref="uploadRef"
:http-request="uploadFiles2"
:file-list="dialog3Form.fileList.concat({type:'camera'})"
list-type="picture-card">
<template #trigger>
<el-icon>
<Plus/>
</el-icon>
</template>
<template #file="{ file }">
<div v-if="file.type !=='camera'">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt=""/>
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="handlePictureCardPreview2(file)"
>
<el-icon><zoom-in/></el-icon>
</span>
<span
class="el-upload-list__item-delete"
@click="handleDownload2(file)"
>
<el-icon><Download/></el-icon>
</span>
<span
class="el-upload-list__item-delete"
@click="handleRemove2(file)"
>
<el-icon><Delete/></el-icon>
</span>
</span>
</div>
<div @click="openCamera2" v-if="file.type ==='camera'" style="border:none"
class="el-upload--picture-card">
<el-icon>
<Camera/>
</el-icon>
</div>
</template>
</el-upload>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialog3 = false">关闭</el-button>
<el-button type="primary" @click="handleObstacle2">
处理
</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="dialog4" title="处置障碍物" width="500">
<el-form :model="dialog4Form">
<el-form-item label="发现时间" label-width="120px">
<el-input v-model="dialog4Form.time" disabled autocomplete="off"/>
</el-form-item>
<el-form-item label="处理信息描述" label-width="120px">
<el-input
v-model="dialog4Form.description"
style="width: 100%"
:rows="2"
type="textarea"
/>
</el-form-item>
<el-form-item label="处理照片" label-width="120px">
<el-upload @click.stop="onSubmit"
ref="uploadRef"
:http-request="uploadFiles3"
:file-list="dialog4Form.fileList.concat({type:'camera'})"
list-type="picture-card">
<template #trigger>
<el-icon>
<Plus/>
</el-icon>
</template>
<template #file="{ file }">
<div v-if="file.type !=='camera'">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt=""/>
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="handlePictureCardPreview3(file)"
>
<el-icon><zoom-in/></el-icon>
</span>
<span
class="el-upload-list__item-delete"
@click="handleDownload3(file)"
>
<el-icon><Download/></el-icon>
</span>
<span
class="el-upload-list__item-delete"
@click="handleRemove3(file)"
>
<el-icon><Delete/></el-icon>
</span>
</span>
</div>
<div @click="openCamera3" v-if="file.type ==='camera'" style="border:none"
class="el-upload--picture-card">
<el-icon>
<Camera/>
</el-icon>
</div>
</template>
</el-upload>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialog4 = false">关闭</el-button>
<el-button type="primary" @click="handleObstacle3">
处理
</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="shildDialog">
<el-form :model="shildForm">
<el-form-item label="固定物名称" label-width="120px">
<el-input v-model="shildForm.name" autocomplete="off"/>
</el-form-item>
<el-form-item label="偏差值" label-width="120px">
<el-input v-model="shildForm.deviation" autocomplete="off"/>
</el-form-item>
<el-form-item label="屏蔽范围" label-width="120px">
<el-input v-model="shildForm.shielding" autocomplete="off"/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="shildDialog = false">关闭</el-button>
<el-button type="primary" @click="addShildItem">
确定
</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="shildDialog1">
<el-form :model="shildForm1">
<el-form-item label="固定物名称" label-width="120px">
<el-input v-model="shildForm1.name" autocomplete="off"/>
</el-form-item>
<el-form-item label="偏差值" label-width="120px">
<el-input v-model="shildForm1.deviation" autocomplete="off"/>
</el-form-item>
<el-form-item label="屏蔽范围" label-width="120px">
<el-input v-model="shildForm1.shielding" autocomplete="off"/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="shildDialog1 = false">关闭</el-button>
<el-button type="primary" @click="addShildItem1">
确定
</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="shildDialog2">
<el-form :model="shildForm2">
<el-form-item label="固定物名称" label-width="120px">
<el-input v-model="shildForm2.name" autocomplete="off"/>
</el-form-item>
<el-form-item label="偏差值" label-width="120px">
<el-input v-model="shildForm2.deviation" autocomplete="off"/>
</el-form-item>
<el-form-item label="屏蔽范围" label-width="120px">
<el-input v-model="shildForm2.shielding" autocomplete="off"/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="shildDialog2 = false">关闭</el-button>
<el-button type="primary" @click="updateShildItem">
确定
</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="shildDialog3">
<el-form :model="shildForm3">
<el-form-item label="固定物名称" label-width="120px">
<el-input v-model="shildForm3.name" autocomplete="off"/>
</el-form-item>
<el-form-item label="偏差值" label-width="120px">
<el-input v-model="shildForm3.deviation" autocomplete="off"/>
</el-form-item>
<el-form-item label="屏蔽范围" label-width="120px">
<el-input v-model="shildForm3.shielding" autocomplete="off"/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="shildDialog3 = false">关闭</el-button>
<el-button type="primary" @click="addShildItem3">
确定
</el-button>
</div>
</template>
</el-dialog>
<input
ref="cameraInput"
type="file"
accept="image/*"
capture="camera"
style="display: none"
@change="handleCameraChange"
/>
<input
ref="cameraInput1"
type="file"
accept="image/*"
capture="camera"
style="display: none"
@change="handleCameraChange1"
/>
<input
ref="cameraInput2"
type="file"
accept="image/*"
capture="camera"
style="display: none"
@change="handleCameraChange2"
/>
<input
ref="cameraInput3"
type="file"
accept="image/*"
capture="camera"
style="display: none"
@change="handleCameraChange3"
/>
<el-dialog v-model="imgDialog">
<img width="100%" :src="dialogImageUrl" alt="Preview Image"/>
</el-dialog>
</div>
</template>
<script setup>
import Ruler from "@/components/ruler.vue";
import {computed, onMounted, ref, watch} from "vue";
import {
addShildData,
DeleteCData,
delShildData,
getAllAirPort,
GetAllCData,
getArea,
getParasPos,
getParasSignalpro,
GetSetting,
getShildList,
InserDealObstacleModel,
InsertCListData,
PosSetting,
PostDealObstacleModel,
RestartWork,
setParasPos,
setParasSignalpro,
ShutDownWork,
StartWork,
StopWork,
UpdateCData,
UpdateFodScopeData,
UpdateImage,
updateShildData
} from "@/api/api";
import {useRouter} from "vue-router";
import {ElMessage} from "element-plus";
import {
calcRectangleFromPoints,
correctDeviation,
getDeviationValue,
getLocalPositionRelativeToP4,
parseTime
} from '@/utils/tool'
const date1 = ref([])
const form1 = ref({})
const form5 = ref({})
const form6 = ref({})
const options1 = ref([])
const options2 = ref([])
const selectUpdate = (val) => {
form1.value.region = val
getArea({airId: val}).then(e => {
options2.value = e.data
})
}
const select2Update = (val) => {
form6.value.region = val
getArea({airId: val}).then(e => {
options2.value = e.data
})
}
const select3Update = (val) => {
form6.value.region1 = val
}
// 默认方法
const onSubmit = (e) => {
console.log(e)
}
// 跳转到管理界面
const toAdmin = () => {
router.push('/serve')
}
// 启动雷达
const StartWorkBtn = () => {
StartWork()
}
// 停止雷达
const StopWorkBtn = () => {
StopWork()
}
// 重启雷达
const RestartWorkBtn = () => {
RestartWork()
}
// 关闭雷达
const ShutDownWorkBtn = () => {
ShutDownWork()
}
// 检测&成像设置
const parasSignalproForm = ref({
imaging: {},
dectection: {}
})
// 路线设置
const parasPosForm = ref({
runwaynum: {
startpos_num: 1
},
runwayedges: [
{
startpos_lon_a: '',
startpos_lat_a: '',
startpos_alt_a: '',
startpos_lon_b: '',
startpos_lat_b: '',
startpos_alt_b: '',
startpos_ori: ''
}
]
})
// 屏蔽信息设置
const shieldInfoForm = ref({
deviation: '',
shielding: '',
})
// 获取配置文件
const getOption = () => {
getParasPos().then((e) => {
parasPosForm.value = {
runwaynum: e.runwaynum,
runwayedges: e.runwayedges,
}
})
getParasSignalpro().then((e) => {
parasSignalproForm.value = {
imaging: e.imaging,
dectection: e.dectection,
}
})
GetSetting().then((e) => {
shieldInfoForm.value = {
deviation: e.deviation,
shielding: e.shielding,
}
})
}
// 保存成像&检测设置
const saveParasSignalproForm = () => {
setParasSignalpro(parasSignalproForm.value).then(e => {
})
}
// 保存路线设置
const saveParasPosForm = () => {
setParasPos(parasPosForm.value).then(e => {
})
}
// 保存屏蔽信息
const saveShieldInfoForm = () => {
PosSetting(shieldInfoForm.value).then((e) => {
})
}
// 更新路线数量
const updateRunwayNum = (e) => {
let arr = new Array(e).fill(0)
.map((item, index) => {
if (index <= parasPosForm.value.runwayedges.length - 1) {
return JSON.parse(JSON.stringify(parasPosForm.value.runwayedges[index]))
} else {
return {
startpos_lon_a: '',
startpos_lat_a: '',
startpos_alt_a: '',
startpos_lon_b: '',
startpos_lat_b: '',
startpos_alt_b: '',
startpos_ori: ''
}
}
})
parasPosForm.value.runwayedges = JSON.parse(JSON.stringify(arr))
}
// 路由
const router = useRouter();
const rulerRef = ref()
// 当前菜单id
const itemsId = ref(1)
// 菜单id跳转
const setItemsId = (e) => {
itemsId.value = e
dotIndex2.index = -1
}
// 左侧区域宽高
const areaData = ref({
width: 100,
height: 1000,
angle: 0
})
// 雷达状态
const radarWorkState = ref(0)
const communicationState = ref(false)
// 扫描状态
const scan = ref(true)
// 车辆位置
const boxPos = ref({x: 10, y: 50, rotate: 0})
// 车辆实时位置
const currentPosition = ref({})
// 表格点击事件
const table1Current = (e,) => {
dotIndex1.value = -1
dotIndex2.value = -1
if (dotIndex.value === e.index) {
dotIndex.value = -1
} else {
dotIndex.value = e.index
}
}
const table1Current1 = (e,) => {
dotIndex.value = -1
dotIndex2.value = -1
if (!dot1Show.value) {
dotIndex1.value = -1
} else {
if (dotIndex1.value === e.index) {
dotIndex1.value = -1
} else {
dotIndex1.value = e.index
}
}
}
// ws连接
const getSocket = () => {
const socket = new WebSocket("ws://192.168.1.123:7789/ws");
socket.addEventListener("open", () => {
console.log("✅ WebSocket 连接成功");
});
socket.addEventListener("message", (event) => {
processData(JSON.parse(event.data))
});
socket.addEventListener("close", () => {
console.log("❌ WebSocket 已关闭");
setTimeout(() => {
getSocket()
}, 1000)
});
socket.addEventListener("error", (error) => {
console.error("⚠️ WebSocket 出错:", error);
});
}
// ws数据处理
let timer = setTimeout(()=>{
communicationState.value = false
},1000)
const processData = (data) => {
if (data.FodName === '雷达信息') {
radarWorkState.value = data.radar_work_state
scan.value = data.radar_work_state === 1
}
if (data.FodName === '图像数据') {
}
if (data.FodName === 'fod信息') {
console.log('障碍物信息', data)
setTable1Data(data)
}
if (data.ty === 3) {
}
if (data.FodName === '车辆信息') {
communicationState.value = true
clearTimeout(timer)
timer = null
timer = setTimeout(()=>{
communicationState.value = false
},1000)
currentPosition.value = {
lon: data.Longitude,
lat: data.Latitude,
}
const rectInfo = calcRectangleFromPoints(areaPoints.value);
const point = {
lon: data.Longitude,
lat: data.Latitude,
rotate: data.HeadingAngle
};
const local = correctDeviation(getLocalPositionRelativeToP4(point, areaPoints.value, rectInfo))
boxPos.value = local
}
};
// 设置表格1数据
const setTable1Data = (e) => {
let fodInfo = e.DarDatas.filter(v => v.Lon !== 0 && v.Lat !== 0)
tableData1.value = [...tableData1.value, ...fodInfo.map((v, k) => {
return {
...v,
time: parseTime(v.time || v.Time),
index: tableData1.value.length + k
}
})]
}
// 障碍物列表
const tableData1 = ref([])
const table1Data = computed(() => {
return tableData1.value.filter(e => e.Status == 0).map((v, k) => {
return {
...v,
index: k
}
})
});
// 当前页
const currentPage1 = ref(1)
// 每页数量
const pageSize1 = ref(10)
const table2Data = computed(() => {
return tableData1.value.filter(e => e.Status == 2).map((v, k) => {
return {
...v,
index: k
}
})
});
// 当前页
const currentPage2 = ref(1)
// 每页数量
const pageSize2 = ref(10)
// 固定物列表
const tableData2 = ref([])
// 当前页
const currentPage3 = ref(1)
// 每页数量
const pageSize3 = ref(10)
const total3 = ref(0)
// 处置列表
const tableData3 = ref([])
// 当前页
const currentPage4 = ref(1)
// 每页数量
const pageSize4 = ref(10)
const total4 = ref(0)
// 障碍物点位
const dots = computed(() => {
return table1Data.value.map((v, k) => {
if (v.Lon && v.Lat) {
const rectInfo = calcRectangleFromPoints(areaPoints.value);
const point = {
lon: v.Lon,
lat: v.Lat,
rotate: 0,
};
return {
...correctDeviation(getLocalPositionRelativeToP4(point, areaPoints.value, rectInfo)),
type: v.Status
}
} else {
return null
}
}).filter(v => v)
})
const dots1 = computed(() => {
return table2Data.value.map((v, k) => {
if (v.Lon && v.Lat) {
const rectInfo = calcRectangleFromPoints(areaPoints.value);
const point = {
lon: v.Lon,
lat: v.Lat,
rotate: 0,
};
return {
...correctDeviation(getLocalPositionRelativeToP4(point, areaPoints.value, rectInfo)),
type: v.Status
}
} else {
return null
}
}).filter(v => v)
})
// 当前的目标障碍物
const dotIndex = ref(-1)
const dotIndex1 = ref(-1)
const dots2 = computed(() => {
if (itemsId.value === 4) {
return tableData3.value.map((v, k) => {
if (v.longitude && v.latitude) {
const rectInfo = calcRectangleFromPoints(areaPoints.value);
const point = {
lon: v.longitude,
lat: v.latitude,
rotate: 0,
};
return {
...correctDeviation(getLocalPositionRelativeToP4(point, areaPoints.value, rectInfo)),
}
} else {
return null
}
}).filter(v => v)
} else if (itemsId.value === 5) {
return tableData2.value.map((v, k) => {
if (v.lon && v.lat) {
const rectInfo = calcRectangleFromPoints(areaPoints.value);
const point = {
lon: v.lon,
lat: v.lat,
rotate: 0,
};
return {
...correctDeviation(getLocalPositionRelativeToP4(point, areaPoints.value, rectInfo)),
}
} else {
return null
}
}).filter(v => v)
} else {
return []
}
})
const dotIndex2 = ref(-1)
const table2Current = (e) => {
console.log(e)
let index = -1
if (itemsId.value === 4) {
index = tableData3.value.findIndex(v => v.longitude === e.longitude && v.latitude === e.latitude)
}
if (itemsId.value === 5) {
index = tableData2.value.findIndex(v => v.id === e.id)
}
console.log(index)
dotIndex.value = -1
dotIndex1.value = -1
if (dotIndex2.value === index) {
dotIndex2.value = -1
} else {
dotIndex2.value = index
}
console.log(dotIndex2.value)
}
const dot1Show = ref(true)
const dialogImageUrl = ref('')
const imgDialog = ref(false)
const uploadRef = ref(null)
const shildDialog2 = ref(false)
const shildForm2 = ref({})
const openShildDialog2 = (e) => {
shildDialog2.value = true
shildForm2.value = e.row
}
// 修改固定物
const updateShildItem = () => {
dotIndex2.value = -1
updateShildData(shildForm1.value).then(e => {
shildDialog2.value = false
shildForm2.value = {}
getShildTableList()
})
}
// 处置模态框
const dialog3 = ref(false)
const dialog3Form = ref({})
// 上传图片
const uploadFiles2 = async (e) => {
const res = await UpdateImage({files: [e.file]})
}
// 图片放大
const handlePictureCardPreview2 = (file) => {
dialogImageUrl.value = file.url
imgDialog.value = true
}
// 图片下载
const handleDownload2 = (file) => {
console.log(file)
}
// 图片删除
const handleRemove2 = (file) => {
console.log(file)
dialog3Form.value.fileList = dialog3Form.value.fileList.filter(e => e.url !== file.url)
}
// 拍照
const cameraInput2 = ref(null)
const openCamera2 = () => {
cameraInput2.value?.click()
}
const handleCameraChange2 = (e) => {
const file = e.target.files[0]
if (!file) return
const url = URL.createObjectURL(file)
UpdateImage({files: [file]})
dialog3Form.fileList.value.push({
name: file.name,
url,
raw: file
})
// 重置 input
e.target.value = ''
}
// 打开处置模态框
const openHandleObstacleDialog2 = (e) => {
dialog3.value = true
dialog3Form.value = {
time: e.row.time,
longitude: e.row.lon,
latitude: e.row.lat,
strength: e.row.strength,
fileList: [],
description:''
}
}
// 删除固定物
const delShildItem = (e) => {
dotIndex2.value = -1
delShildData(e.row).then(e => {
getShildTableList()
})
}
// 确定处理
const handleObstacle2 = () => {
dotIndex2.value = -1
InserDealObstacleModel({
longitude: dialog3Form.value.longitude,
latitude: dialog3Form.value.latitude,
strength: dialog3Form.value.strength,
files: dialog3Form.value.fileList.map(e => e.url),
findTime: dialog3Form.value.time || '',
description: dialog3Form.value.description,
FodAirId: form1.value.region1
}).then(e => {
// delShildData(e.row).then(e => {
// getShildTableList()
// })
getShildTableList()
getObstacleList()
dialog3.value = false
})
}
const table3Ref = ref()
// 批量删除
const batchDel2 = () => {
dotIndex2.value = -1
let datas = table3Ref.value.getSelectionRows()
let promiseArr = []
datas.forEach((row) => {
promiseArr.push(delShildData(row))
})
Promise.allSettled(promiseArr).then(() => {
getShildTableList()
getObstacleList()
})
}
// 批量处置
const batchDisposal2 = () => {
dotIndex2.value = -1
let datas = table3Ref.value.getSelectionRows()
let promiseArr = []
datas.forEach((row) => {
promiseArr.push(InserDealObstacleModel({
longitude: row.longitude,
latitude: row.latitude,
strength: row.strength,
files: [],
findTime: row.time,
description: '',
FodAirId: form1.value.region1
}))
})
Promise.allSettled(promiseArr).then(() => {
getShildTableList()
getObstacleList()
})
}
// 固定物模态框
const shildDialog = ref(false)
const shildForm = ref({})
// 打开固定物模态框
const openShildDialog = (e) => {
shildDialog.value = true
shildForm.value = {
$index: e.row.$index,
lon: e.row.Lon,
lat: e.row.Lat,
strength: e.row.Strength,
name: Math.random().toString().split('.')[1],
deviation: shieldInfoForm.value.deviation,
shielding: shieldInfoForm.value.shielding,
}
}
// 设置固定物
const addShildItem = () => {
let data = null
if (dotIndex.value >= 0) {
data = table1Data.value[dotIndex.value]
}
tableData1.value = tableData1.value.filter(v => !(v.Lon === shildForm.value.lon && v.Lat === shildForm.value.lat && v.Strength === shildForm.value.strength))
if (data) {
dotIndex.value = table1Data.value.findIndex(v => v.Lon === data.Lon && v.Lat === data.Lat && v.Strength === data.Strength)
}
addShildData({...shildForm.value, FodAirId: form1.value.region1}).then(e => {
shildDialog.value = false
shildForm.value = {}
getShildTableList()
getObstacleList()
})
}
// 处置模态框
const dialog1 = ref(false)
const dialog1Form = ref({})
// 上传图片
const uploadFiles = async (e) => {
const res = await UpdateImage({files: [e.file]})
}
// 图片放大
const handlePictureCardPreview = (file) => {
dialogImageUrl.value = file.url
imgDialog.value = true
}
// 图片下载
const handleDownload = (file) => {
console.log(file)
}
// 图片删除
const handleRemove = (file) => {
console.log(file)
dialog1Form.value.fileList = dialog1Form.value.fileList.filter(e => e.url !== file.url)
}
// 拍照
const cameraInput = ref(null)
const openCamera = () => {
cameraInput.value?.click()
}
const handleCameraChange = (e) => {
const file = e.target.files[0]
if (!file) return
const url = URL.createObjectURL(file)
UpdateImage({files: [file]})
dialog1Form.fileList.value.push({
name: file.name,
url,
raw: file
})
// 重置 input
e.target.value = ''
}
// 删除
const delPoint = (e) => {
let data = null
if (dotIndex.value >= 0) {
data = table1Data.value[dotIndex.value]
}
tableData1.value = tableData1.value.filter(v => !(v.Lon === e.row.Lon && v.Lat === e.row.Lat && v.Strength === e.row.Strength))
if (data) {
dotIndex.value = table1Data.value.findIndex(v => v.Lon === data.Lon && v.Lat === data.Lat && v.Strength === data.Strength)
}
}
// 打开处置模态框
const openHandleObstacleDialog = (e) => {
dialog1.value = true
dialog1Form.value = {
dotIndex: e.index,
index: e.$index,
time: e.row.time,
longitude: e.row.Lon,
latitude: e.row.Lat,
strength: e.row.Strength,
fileList: [],
description:''
}
}
// 确定处理
const handleObstacle = () => {
InserDealObstacleModel({
longitude: dialog1Form.value.longitude,
latitude: dialog1Form.value.latitude,
strength: dialog1Form.value.strength,
files: dialog1Form.value.fileList.map(e => e.url),
findTime: dialog1Form.value.time || '',
description: dialog1Form.value.description,
FodAirId: form1.value.region1
}).then(e => {
let data = null
if (dotIndex.value >= 0) {
data = table1Data.value[dotIndex.value]
}
dialog1.value = false
tableData1.value = tableData1.value.filter(v => !(v.Lon === dialog1Form.value.longitude && v.Lat === dialog1Form.value.latitude && v.Strength === dialog1Form.value.strength))
if (data) {
dotIndex.value = table1Data.value.findIndex(v => v.Lon === data.Lon && v.Lat === data.Lat && v.Strength === data.Strength)
}
getShildTableList()
getObstacleList()
})
}
// 批量处理
const table1Ref = ref()
const batchDisposal = () => {
let data = null
if (dotIndex.value >= 0) {
data = table1Data.value[dotIndex.value]
}
let datas = table1Ref.value.getSelectionRows()
let arr = JSON.parse(JSON.stringify(tableData1.value))
datas.forEach((row) => {
InserDealObstacleModel({
longitude: row.Lon,
latitude: row.Lat,
strength: row.Strength,
files: [],
findTime: '',
description: '',
FodAirId: form1.value.region1
})
arr = arr.filter(v => !(v.Lon === row.Lon && v.Lat === row.Lat && v.Strength === row.Strength))
})
tableData1.value = arr.map((v, index) => {
return {
...v,
index
}
})
getShildTableList()
getObstacleList()
if (data) {
dotIndex.value = table1Data.value.findIndex(v => v.Lon === data.Lon && v.Lat === data.Lat && v.Strength === data.Strength)
}
}
// 批量删除
const batchDel = () => {
let data = null
if (dotIndex.value >= 0) {
data = table1Data.value[dotIndex.value]
}
let datas = table1Ref.value.getSelectionRows()
let arr = JSON.parse(JSON.stringify(tableData1.value))
datas.forEach((row) => {
arr = arr.filter(v => !(v.Lon === row.Lon && v.Lat === row.Lat && v.Strength === row.Strength))
})
tableData1.value = arr.map((v, index) => {
return {
...v,
index
}
})
if (data) {
dotIndex.value = table1Data.value.findIndex(v => v.Lon === data.Lon && v.Lat === data.Lat && v.Strength === data.Strength)
}
}
// 批量固定
const batchShild = () => {
let data = null
if (dotIndex.value >= 0) {
data = table1Data.value[dotIndex.value]
}
let datas = table1Ref.value.getSelectionRows()
let arr = JSON.parse(JSON.stringify(tableData1.value))
datas.forEach((row) => {
addShildData({
lon: row.Lon,
lat: row.Lat,
strength: row.Strength,
name: Math.random().toString().split('.')[1],
deviation: shieldInfoForm.value.deviation,
shielding: shieldInfoForm.value.shielding,
FodAirId: form1.value.region1
})
arr = arr.filter(v => !(v.Lon === row.Lon && v.Lat === row.Lat && v.Strength === row.Strength))
})
tableData1.value = arr.map((v, index) => {
return {
...v,
index
}
})
getShildTableList()
getObstacleList()
if (data) {
dotIndex.value = table1Data.value.findIndex(v => v.Lon === data.Lon && v.Lat === data.Lat && v.Strength === data.Strength)
}
}
// 固定物模态框
const shildDialog1 = ref(false)
const shildForm1 = ref({})
// 打开固定物模态框
const openShildDialog1 = (e) => {
shildDialog1.value = true
shildForm1.value = {
$index: e.row.$index,
lon: e.row.Lon,
lat: e.row.Lat,
strength: e.row.Strength,
name: Math.random().toString().split('.')[1],
deviation: shieldInfoForm.value.deviation,
shielding: shieldInfoForm.value.shielding,
}
}
// 设置固定物
const addShildItem1 = () => {
let data = null
if (dotIndex1.value >= 0) {
data = table2Data.value[dotIndex1.value]
}
tableData1.value = tableData1.value.filter(v => !(v.Lon === shildForm.value.lon && v.Lat === shildForm.value.lat && v.Strength === shildForm.value.strength))
if (data) {
dotIndex1.value = table2Data.value.findIndex(v => v.Lon === data.Lon && v.Lat === data.Lat && v.Strength === data.Strength)
}
addShildData({...shildForm1.value, FodAirId: form1.value.region1}).then(e => {
shildDialog1.value = false
shildForm1.value = {}
getShildTableList()
getObstacleList()
})
}
// 处置模态框
const dialog2 = ref(false)
const dialog2Form = ref({})
// 上传图片
const uploadFiles1 = async (e) => {
const res = await UpdateImage({files: [e.file]})
}
// 图片放大
const handlePictureCardPreview1 = (file) => {
dialogImageUrl.value = file.url
imgDialog.value = true
}
// 图片下载
const handleDownload1 = (file) => {
console.log(file)
}
// 图片删除
const handleRemove1 = (file) => {
console.log(file)
dialog2Form.value.fileList = dialog2Form.value.fileList.filter(e => e.url !== file.url)
}
// 拍照
const cameraInput1 = ref(null)
const openCamera1 = () => {
cameraInput1.value?.click()
}
const handleCameraChange1 = (e) => {
const file = e.target.files[0]
if (!file) return
const url = URL.createObjectURL(file)
UpdateImage({files: [file]})
dialog2Form.fileList.value.push({
name: file.name,
url,
raw: file
})
// 重置 input
e.target.value = ''
}
// 删除
const delPoint1 = (e) => {
let data = null
if (dotIndex1.value >= 0) {
data = table2Data.value[dotIndex1.value]
}
tableData1.value = tableData1.value.filter(v => !(v.Lon === e.row.Lon && v.Lat === e.row.Lat && v.Strength === e.row.Strength))
if (data) {
dotIndex1.value = table2Data.value.findIndex(v => v.Lon === data.Lon && v.Lat === data.Lat && v.Strength === data.Strength)
}
}
// 打开处置模态框
const openHandleObstacleDialog1 = (e) => {
dialog2.value = true
dialog2Form.value = {
dotIndex: e.index,
index: e.$index,
time: e.row.time,
longitude: e.row.Lon,
latitude: e.row.Lat,
strength: e.row.Strength,
fileList: [],
description:''
}
}
// 确定处理
const handleObstacle1 = () => {
InserDealObstacleModel({
longitude: dialog2Form.value.longitude,
latitude: dialog2Form.value.latitude,
strength: dialog2Form.value.strength,
files: dialog2Form.value.fileList.map(e => e.url),
findTime: dialog2Form.value.time || '',
description: dialog2Form.value.description,
FodAirId: form1.value.region1
}).then(e => {
let data = null
if (dotIndex1.value >= 0) {
data = table2Data.value[dotIndex1.value]
}
dialog2.value = false
tableData1.value = tableData1.value.filter(v => !(v.Lon === dialog2Form.value.longitude && v.Lat === dialog2Form.value.latitude && v.Strength === dialog2Form.value.strength))
if (data) {
dotIndex1.value = table2Data.value.findIndex(v => v.Lon === data.Lon && v.Lat === data.Lat && v.Strength === data.Strength)
}
})
}
// 批量处理
const table2Ref = ref()
const batchDisposal1 = () => {
let data = null
if (dotIndex1.value >= 0) {
data = table2Data.value[dotIndex1.value]
}
let datas = table2Ref.value.getSelectionRows()
let arr = JSON.parse(JSON.stringify(tableData1.value))
datas.forEach((row) => {
InserDealObstacleModel({
longitude: row.Lon,
latitude: row.Lat,
strength: row.Strength,
files: [],
findTime: '',
description: '',
FodAirId: form1.value.region1
})
arr = arr.filter(v => !(v.Lon === row.Lon && v.Lat === row.Lat && v.Strength === row.Strength))
})
tableData1.value = arr.map((v, index) => {
return {
...v,
index
}
})
getShildTableList()
getObstacleList()
if (data) {
dotIndex1.value = table2Data.value.findIndex(v => v.Lon === data.Lon && v.Lat === data.Lat && v.Strength === data.Strength)
}
}
// 批量删除
const batchDel1 = () => {
let data = null
if (dotIndex1.value >= 0) {
data = table2Data.value[dotIndex1.value]
}
let datas = table2Ref.value.getSelectionRows()
let arr = JSON.parse(JSON.stringify(tableData1.value))
datas.forEach((row) => {
arr = arr.filter(v => !(v.Lon === row.Lon && v.Lat === row.Lat && v.Strength === row.Strength))
})
tableData1.value = arr.map((v, index) => {
return {
...v,
index
}
})
if (data) {
dotIndex1.value = table2Data.value.findIndex(v => v.Lon === data.Lon && v.Lat === data.Lat && v.Strength === data.Strength)
}
}
// 批量固定
const batchShild1 = () => {
let data = null
if (dotIndex1.value >= 0) {
data = table1Data.value[dotIndex1.value]
}
let datas = table2Ref.value.getSelectionRows()
let arr = JSON.parse(JSON.stringify(tableData1.value))
datas.forEach((row) => {
addShildData({
lon: row.Lon,
lat: row.Lat,
strength: row.Strength,
name: Math.random().toString().split('.')[1],
deviation: shieldInfoForm.value.deviation,
shielding: shieldInfoForm.value.shielding,
FodAirId: form1.value.region1
})
arr = arr.filter(v => !(v.Lon === row.Lon && v.Lat === row.Lat && v.Strength === row.Strength))
})
tableData1.value = arr.map((v, index) => {
return {
...v,
index
}
})
getShildTableList()
getObstacleList()
if (data) {
dotIndex1.value = table2Data.value.findIndex(v => v.Lon === data.Lon && v.Lat === data.Lat && v.Strength === data.Strength)
}
}
// 固定物模态框
const shildDialog3 = ref(false)
const shildForm3 = ref({})
// 打开固定物模态框
const openShildDialog3 = (e) => {
shildDialog3.value = true
shildForm3.value = {
lon: e.row.longitude,
lat: e.row.latitude,
strength: e.row.strength,
name: Math.random().toString().split('.')[1],
deviation: shieldInfoForm.value.deviation,
shielding: shieldInfoForm.value.shielding,
}
}
// 设置固定物
const addShildItem3 = () => {
dotIndex2.value = -1
addShildData({...shildForm1.value, FodAirId: form1.value.region1}).then(e => {
shildDialog3.value = false
shildForm3.value = {}
getShildTableList()
getObstacleList()
})
}
// 处置模态框
const dialog4 = ref(false)
const dialog4Form = ref({})
// 上传图片
const uploadFiles3 = async (e) => {
const res = await UpdateImage({files: [e.file]})
}
// 图片放大
const handlePictureCardPreview3 = (file) => {
dialogImageUrl.value = file.url
imgDialog.value = true
}
// 图片下载
const handleDownload3 = (file) => {
console.log(file)
}
// 图片删除
const handleRemove3 = (file) => {
console.log(file)
dialog4Form.value.fileList = dialog4Form.value.fileList.filter(e => e.url !== file.url)
}
// 拍照
const cameraInput3 = ref(null)
const openCamera3 = () => {
cameraInput3.value?.click()
}
const handleCameraChange3 = (e) => {
const file = e.target.files[0]
if (!file) return
const url = URL.createObjectURL(file)
UpdateImage({files: [file]})
dialog4Form.fileList.value.push({
name: file.name,
url,
raw: file
})
// 重置 input
e.target.value = ''
}
// 删除
const delObstacleItem = (e) => {
}
// 打开处置模态框
const openHandleObstacleDialog3 = (e) => {
dialog4.value = true
dialog4Form.value = {
time: e.row.time,
longitude: e.row.longitude,
latitude: e.row.latitude,
strength: e.row.strength,
fileList: e.row.fileList,
description: e.row.description,
}
}
// 确定处理
const handleObstacle3 = () => {
dotIndex2.value = -1
InserDealObstacleModel({
longitude: dialog4Form.value.longitude,
latitude: dialog4Form.value.latitude,
strength: dialog4Form.value.strength,
files: dialog4Form.value.fileList.map(e => e.url),
findTime: dialog4Form.value.time || '',
description: dialog4Form.value.description,
FodAirId: form1.value.region1
}).then(e => {
})
}
// 批量处理
const table4Ref = ref()
// 批量删除
const batchDel3 = () => {
}
// 批量固定
const batchShild3 = () => {
dotIndex2.value = -1
let datas = table4Ref.value.getSelectionRows()
datas.forEach((row) => {
addShildData({
lon: row.longitude,
lat: row.latitude,
strength: row.strength,
name: Math.random().toString().split('.')[1],
deviation: shieldInfoForm.value.deviation,
shielding: shieldInfoForm.value.shielding,
FodAirId: form1.value.region1
})
})
getShildTableList()
getObstacleList()
}
// 获取固定物列表
const getShildTableList = () => {
getShildList({
pageIndex: currentPage3.value,
pageSize: pageSize3.value,
FodAirId: form1.value.region1
}).then((e) => {
tableData2.value = e.data
total3.value = e.totalCount
})
}
// 获取处置列表
const getObstacleList = () => {
PostDealObstacleModel({
pageIndex: currentPage4.value,
pageSize: pageSize4.value,
FodAirId: form1.value.region1
}).then(e => {
tableData3.value = e.data
total4.value = e.totalCount
})
}
// 区域标定页面获取区域信息
const getArea2 = () => {
GetAllCData({areaId: form6.value.region1}).then((res) => {
regionLabeling.value = res.data
})
}
// 区域标定信息
const regionLabeling = ref([])
// 区域点位信息
const areaPoints = ref([])
// 设置区域点位
const getPoint = (k) => {
regionLabeling.value[k].lon = currentPosition.value.lon || 0
regionLabeling.value[k].lat = currentPosition.value.lat || 0
}
// 保存区域信息
const saveAreaPoint = () => {
let arr = []
regionLabeling.value.forEach((v, k) => {
arr.push(UpdateCData(v))
})
Promise.all(arr).then(() => {
areaPoints.value = JSON.parse(JSON.stringify(regionLabeling.value))
ElMessage.success('保存成功')
let data = calcRectangleFromPoints(areaPoints.value)
areaData.value = data
getDeviationValue(areaPoints.value.find(e => e.name === '点位3'), areaPoints.value)
}).catch((err) => {
ElMessage.error(err)
})
}
const readLocalStorageData = () => {
// tableData1.value = [
// {"Lon": 119.68158733286303, "Lat": 25.929632812633325, "Status": 0},
// {"Lon": 119.68226426875183, "Lat": 25.930447575308917, "Status": 2},
// {"Lon": 119.68096665515995, "Lat": 25.92785426333515, "Status": 0},
// {"Lon": 119.68278645438862, "Lat": 25.931322676440597, "Status": 2},
// {"Lon": 119.6812308665526, "Lat": 25.92833823728329, "Status": 0},
// {"Lon": 119.68318456612818, "Lat": 25.93195533358216, "Status": 2},
// {"Lon": 119.68036755668337, "Lat": 25.926887965282527, "Status": 0},
// {"Lon": 119.68192384565978, "Lat": 25.92998287455529, "Status": 2},
// {"Lon": 119.68250211437338, "Lat": 25.930826764153685, "Status": 0},
// {"Lon": 119.68173244334253, "Lat": 25.92945659218239, "Status": 2},
// {"Lon": 119.68295065558712, "Lat": 25.93161275117524, "Status": 0},
// {"Lon": 119.68105985472717, "Lat": 25.92803513687375, "Status": 2},
// {"Lon": 119.68341837732858, "Lat": 25.932375885682826, "Status": 0},
// {"Lon": 119.68064788438357, "Lat": 25.927279242277973, "Status": 2},
// {"Lon": 119.68209525287522, "Lat": 25.93029711876587, "Status": 0},
// {"Lon": 119.68265453337758, "Lat": 25.931034055557433, "Status": 2},
// {"Lon": 119.68139455255315, "Lat": 25.928622731163285, "Status": 0},
// {"Lon": 119.6832675327453, "Lat": 25.93210835721747, "Status": 2},
// {"Lon": 119.68018322877646, "Lat": 25.92664065235554, "Status": 0},
// {"Lon": 119.68150073637315, "Lat": 25.929251557521317, "Status": 2},
// {"Lon": 119.68237556552133, "Lat": 25.93061626521737, "Status": 0},
// {"Lon": 119.68289878364453, "Lat": 25.93148441687782, "Status": 2},
// {"Lon": 119.68087065652437, "Lat": 25.927625231566176, "Status": 0},
// {"Lon": 119.68183456587315, "Lat": 25.92978651727634, "Status": 2},
// {"Lon": 119.68241653211357, "Lat": 25.93071232314118, "Status": 0},
// {"Lon": 119.68309635565385, "Lat": 25.93180587653187, "Status": 2},
// {"Lon": 119.68114278553872, "Lat": 25.92820365476537, "Status": 0},
// {"Lon": 119.68055145252318, "Lat": 25.92715353326578, "Status": 2},
// {"Lon": 119.6821865443212, "Lat": 25.93045772867326, "Status": 0},
// {"Lon": 119.68271563257338, "Lat": 25.93115482282882, "Status": 2},
// {"Lon": 119.6816754333553, "Lat": 25.92959862621233, "Status": 0},
// {"Lon": 119.68334676542355, "Lat": 25.932253615880354, "Status": 2},
// {"Lon": 119.68027543254352, "Lat": 25.92676543256789, "Status": 0},
// {"Lon": 119.68198765432156, "Lat": 25.93012345678901, "Status": 2},
// {"Lon": 119.68256789012345, "Lat": 25.93098765432156, "Status": 0},
// {"Lon": 119.68143215432156, "Lat": 25.92876543215678, "Status": 2},
// {"Lon": 119.6829123456789, "Lat": 25.9315432156789, "Status": 0},
// {"Lon": 119.68076543215678, "Lat": 25.92743215678901, "Status": 2},
// {"Lon": 119.68226543215678, "Lat": 25.93034567890123, "Status": 0},
// {"Lon": 119.6831123456789, "Lat": 25.93198765432156, "Status": 2},
// {"Lon": 119.68126543215678, "Lat": 25.92843215678901, "Status": 0},
// {"Lon": 119.68046543215678, "Lat": 25.92698765432156, "Status": 2},
// {"Lon": 119.68186543215678, "Lat": 25.92984567890123, "Status": 0},
// {"Lon": 119.68266543215678, "Lat": 25.93114567890123, "Status": 2},
// {"Lon": 119.68346543215678, "Lat": 25.93244567890123, "Status": 0},
// {"Lon": 119.68066543215678, "Lat": 25.92734567890123, "Status": 2},
// {"Lon": 119.68166543215678, "Lat": 25.92944567890123, "Status": 0},
// {"Lon": 119.68246543215678, "Lat": 25.93074567890123, "Status": 2},
// {"Lon": 119.68306543215678, "Lat": 25.93184567890123, "Status": 0},
// {"Lon": 119.68096543215678, "Lat": 25.92774567890123, "Status": 2},
// {"Lon": 119.68216543215678, "Lat": 25.93024567890123, "Status": 0},
// {"Lon": 119.68286543215678, "Lat": 25.93134567890123, "Status": 2},
// {"Lon": 119.68136543215678, "Lat": 25.92864567890123, "Status": 0},
// {"Lon": 119.68036543215678, "Lat": 25.92684567890123, "Status": 2},
// {"Lon": 119.68176543215678, "Lat": 25.92964567890123, "Status": 0},
// {"Lon": 119.68256543215678, "Lat": 25.93084567890123, "Status": 2},
// {"Lon": 119.68326543215678, "Lat": 25.93204567890123, "Status": 0},
// {"Lon": 119.68106543215678, "Lat": 25.92794567890123, "Status": 2},
// {"Lon": 119.68236543215678, "Lat": 25.93054567890123, "Status": 0},
// {"Lon": 119.68296543215678, "Lat": 25.93164567890123, "Status": 2},
// {"Lon": 119.68156543215678, "Lat": 25.92914567890123, "Status": 0},
// {"Lon": 119.68086543215678, "Lat": 25.92764567890123, "Status": 2},
// {"Lon": 119.68206543215678, "Lat": 25.92994567890123, "Status": 0},
// {"Lon": 119.68276543215678, "Lat": 25.93124567890123, "Status": 2},
// {"Lon": 119.68336543215678, "Lat": 25.93234567890123, "Status": 0},
// {"Lon": 119.68116543215678, "Lat": 25.92824567890123, "Status": 2},
// {"Lon": 119.68056543215678, "Lat": 25.92704567890123, "Status": 0},
// {"Lon": 119.68196543215678, "Lat": 25.93004567890123, "Status": 2},
// {"Lon": 119.68266543215678, "Lat": 25.93094567890123, "Status": 0},
// {"Lon": 119.68316543215678, "Lat": 25.93174567890123, "Status": 2},
// {"Lon": 119.68066543215678, "Lat": 25.92724567890123, "Status": 0},
// {"Lon": 119.68146543215678, "Lat": 25.92884567890123, "Status": 2},
// {"Lon": 119.68226543215678, "Lat": 25.93044567890123, "Status": 0},
// {"Lon": 119.68286543215678, "Lat": 25.93144567890123, "Status": 2},
// {"Lon": 119.68356543215678, "Lat": 25.93254567890123, "Status": 0},
// {"Lon": 119.68076543215678, "Lat": 25.92754567890123, "Status": 2},
// {"Lon": 119.68136543215678, "Lat": 25.92854567890123, "Status": 0},
// {"Lon": 119.68216543215678, "Lat": 25.93034567890123, "Status": 2},
// {"Lon": 119.68296543215678, "Lat": 25.93174567890123, "Status": 0},
// {"Lon": 119.68166543215678, "Lat": 25.92934567890123, "Status": 2},
// {"Lon": 119.68046543215678, "Lat": 25.92694567890123, "Status": 0},
// {"Lon": 119.68186543215678, "Lat": 25.92974567890123, "Status": 2},
// {"Lon": 119.68246543215678, "Lat": 25.93064567890123, "Status": 0},
// {"Lon": 119.68306543215678, "Lat": 25.93154567890123, "Status": 2},
// {"Lon": 119.68326543215678, "Lat": 25.93214567890123, "Status": 0},
// {"Lon": 119.68106543215678, "Lat": 25.92784567890123, "Status": 2},
// {"Lon": 119.68236543215678, "Lat": 25.93064567890123, "Status": 0},
// {"Lon": 119.68276543215678, "Lat": 25.93114567890123, "Status": 2},
// {"Lon": 119.68126543215678, "Lat": 25.92834567890123, "Status": 0},
// {"Lon": 119.68026543215678, "Lat": 25.92664567890123, "Status": 2}
// ].map((e, i) => {
// return {
// ...e,
// Strength: Math.ceil(Math.random() * 200),
// index: i
// }
// })
let areaData = localStorage.getItem('areaData')
if (areaData) {
let data = JSON.parse(areaData)
form1.value = data;
selectUpdate(data.region || '')
getAreaData()
const storedStr = localStorage.getItem(`${data.region}-${data.region1}`);
if (storedStr) {
const storedData = JSON.parse(storedStr);
if (!Array.isArray(storedData)) {
return;
}
tableData1.value.splice(0, tableData1.value.length, ...(storedData.map((e, index) => {
return {
...e,
index: index,
}
})));
}
}
}
const getTableData = async () => {
await getAllAirPort().then(e => {
options1.value = e.data
})
}
// 主界面获取区域信息
const getAreaData = () => {
GetAllCData({areaId: form1.value.region1}).then((res) => {
localStorage.setItem('areaData', JSON.stringify(form1.value));
areaPoints.value = res.data
let data = calcRectangleFromPoints(res.data)
areaData.value = data
getDeviationValue(res.data.find(e => e.name === '点位3'), areaPoints.value)
const sorted = res.data.sort((a, b) => {
const numA = parseInt(a.name.replace(/[^\d]/g, ''), 10);
const numB = parseInt(b.name.replace(/[^\d]/g, ''), 10);
return numA - numB;
});
const letters = ['a', 'b', 'c', 'd'];
const result = {};
sorted.forEach((item, index) => {
const key = letters[index];
result[`${key}Lon`] = item.lon;
result[`${key}Lat`] = item.lat;
});
UpdateFodScopeData(result)
const storedStr = localStorage.getItem(`${data.region}-${data.region1}`);
if (storedStr) {
tableData1.value = []
const storedData = JSON.parse(storedStr);
if (!Array.isArray(storedData)) {
return;
}
tableData1.value = storedData.map((e, index) => {
return {
...e,
index: index,
}
})
}
})
}
onMounted(() => {
readLocalStorageData()
getTableData()
getSocket()
getOption()
getShildTableList()
getObstacleList()
// testFun()
})
const testFun = () => {
let areaData111 = [
{
"id": 8,
"name": "点位4",
"lon": 119.684151,
"lat": 25.93293,
"isDel": 0,
"fodAreaId": 1,
"fodAirId": 1
},
{
"id": 7,
"name": "点位3",
"lon": 119.680298,
"lat": 25.9260902,
"isDel": 0,
"fodAreaId": 1,
"fodAirId": 1
},
{
"id": 6,
"name": "点位2",
"lon": 119.679855,
"lat": 25.9263058,
"isDel": 0,
"fodAreaId": 1,
"fodAirId": 1
},
{
"id": 5,
"name": "点位1",
"lon": 119.683708,
"lat": 25.9331474,
"isDel": 0,
"fodAreaId": 1,
"fodAirId": 1
}
]
areaPoints.value = areaData111
let data = calcRectangleFromPoints(areaData111)
areaData.value = data
getDeviationValue(areaData111.find(e => e.name === '点位3'), areaPoints.value)
let data1 = {
lon: 119.6820045,
lat: 25.92951,
rotate: 303
}
const getLocal = () => {
const rectInfo = calcRectangleFromPoints(areaPoints.value);
const local = correctDeviation(getLocalPositionRelativeToP4(data1, areaPoints.value, rectInfo))
boxPos.value = local
}
getLocal()
}
watch(() => JSON.stringify([tableData1.value, areaPoints.value]), (oldVal, newVal) => {
if (form1.value.region && form1.value.region1) {
localStorage.setItem(`${form1.value.region}-${form1.value.region1}`, JSON.stringify(tableData1.value));
}
}, {deep: true})
</script>
<style lang="less">
.app-container {
width: 1080px;
min-width: 1080px;
height: 100vh;
margin: 0 auto;
}
.top {
width: 100%;
height: 80px;
font-size: 24px;
background-color: #202227;
position: relative;
}
.items {
position: absolute;
top: 15%;
left: 50%;
transform: translateX(-50%);
white-space: nowrap;
}
.item {
display: inline-block;
width: 120px;
height: 100%;
color: #8C9A9C;
line-height: 56px;
cursor: pointer;
font-size: 18px;
font-weight: 600;
letter-spacing: 2px;
}
.item span {
display: inline-block;
height: 100%;
}
.item.click span,
.item:hover span {
color: #0D52BF;
border-bottom: 2px solid #0D52BF;
}
.title {
line-height: 80px;
color: #fff;
margin-left: 20px;
display: inline-block;
text-align: left;
}
.left {
display: inline-block;
height: calc(100vh - 80px);
width: 34%;
vertical-align: top;
position: relative;
.carPo {
position: absolute;
color: #fff;
z-index: 9;
left: 40px;
}
.dot1Show {
position: absolute;
color: #fff;
z-index: 9;
right: 0;
}
}
.right {
padding: 20px 20px 0 20px;
display: inline-block;
height: calc(100vh - 80px - 20px);
width: calc(66% - 40px);
background-color: #F6F7FB;
overflow: auto;
}
</style>