433 lines
12 KiB
Vue
433 lines
12 KiB
Vue
<template>
|
||
<div class="container">
|
||
<div class="left" v-show="isShow">
|
||
<img class="fold" v-show="isShow" src="@/assets/icons/折叠.png" @click="handleFold">
|
||
<div class="search">
|
||
<p class="rule-text">编号规则:任务类型_目标类型_4位编号</p>
|
||
<div class="input-bar">
|
||
<el-input
|
||
v-model="rescueCode"
|
||
style="width: 120px"
|
||
size="large"
|
||
placeholder="任务编号"
|
||
/>
|
||
<el-select
|
||
v-model="rescueType"
|
||
placeholder="任务类型"
|
||
size="large"
|
||
style="width: 120px"
|
||
>
|
||
<el-option label="应急搜捞" value="SAR" />
|
||
<el-option label="专项调查" value="SI" />
|
||
</el-select>
|
||
<el-select
|
||
v-model="rescueResponseLevel"
|
||
placeholder="响应等级"
|
||
size="large"
|
||
style="width: 120px"
|
||
>
|
||
<el-option label="一级" value="一级" />
|
||
<el-option label="二级" value="二级" />
|
||
<el-option label="三级" value="三级" />
|
||
</el-select>
|
||
</div>
|
||
</div>
|
||
<div class="btn-bar">
|
||
<el-button :icon="RefreshRight" @click="onReset">重置</el-button>
|
||
<el-button type="primary" :icon="Search" @click="onSearch">搜索</el-button>
|
||
</div>
|
||
<div class="line" />
|
||
<div class="list">
|
||
<div class="item" v-for="item in dataList" :key="item.id">
|
||
<div class="name">{{ item.rescue_code }}</div>
|
||
<div class="time">{{ item.fill_time }}</div>
|
||
<div class="row">
|
||
<div class="col">航次:<span>{{ item.voyage_name }}</span></div>
|
||
<div class="col">任务状态:<span>{{ item.rescue_status }}</span></div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col">快速响应等级:<span>{{ item.rescue_response_level }}</span></div>
|
||
<div class="col">目标名称:<span>{{ item.rescue_target_name }}</span></div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col">任务类型:<span>{{ item.rescue_type === 'SAR' ? '应急搜捞' : '专项调查' }}</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="pagination">
|
||
<el-pagination
|
||
v-model:current-page="currentPage"
|
||
v-model:page-size="pageSize"
|
||
layout="total, prev, pager, next"
|
||
:total="total"
|
||
@current-change="handleCurrentChange"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="map">
|
||
<div id="cesiumContainer" style="width: 100%; height: 100%;"></div>
|
||
<img class="unfold" v-show="!isShow" src="@/assets/icons/展开.png" alt="" @click="handleUnfold">
|
||
</div>
|
||
|
||
<el-dialog
|
||
v-model="dialogVisible"
|
||
title="任务详情"
|
||
width="500"
|
||
>
|
||
<div class="item">
|
||
<div class="name">{{ currentMarker.rescue_code }}</div>
|
||
<div class="time">{{ currentMarker.fill_time }}</div>
|
||
<div class="row">
|
||
<div class="col">航次:<span>{{ currentMarker.voyage_name }}</span></div>
|
||
<div class="col">任务状态:<span>{{ currentMarker.rescue_status }}</span></div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col">快速响应等级:<span>{{ currentMarker.rescue_response_level }}</span></div>
|
||
<div class="col">目标名称:<span>{{ currentMarker.rescue_target_name }}</span></div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col">任务类型:<span>{{ currentMarker.rescue_type === 'SAR' ? '应急搜捞' : '专项调查' }}</span></div>
|
||
</div>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import * as Cesium from "cesium";
|
||
import {ref, onMounted} from 'vue'
|
||
import { Search, RefreshRight } from '@element-plus/icons-vue'
|
||
import { regPage, getParam } from '@/api/task.js'
|
||
import { modifyCesiumMouseWheel, setImageryViewModels } from '@/utils/common'
|
||
|
||
// 导入静态图片icon
|
||
import markerIcon1 from "@/assets/icons/标注点1.png";
|
||
import markerIcon2 from "@/assets/icons/标注点2.png";
|
||
import markerIcon3 from "@/assets/icons/标注点3.png";
|
||
|
||
// 左侧数据栏展开与收缩
|
||
const isShow = ref(true)
|
||
|
||
const handleFold = () => {
|
||
isShow.value = false
|
||
}
|
||
|
||
const handleUnfold = () => {
|
||
isShow.value = true
|
||
}
|
||
|
||
const rescueCode = ref('')
|
||
const rescueType = ref('')
|
||
const rescueResponseLevel = ref('')
|
||
const currentPage = ref(1)
|
||
const pageSize = ref(10)
|
||
const start = ref(0)
|
||
const total = ref(0)
|
||
// 列表数据
|
||
const dataList = ref([])
|
||
const markers = ref([])
|
||
|
||
const handleCurrentChange = (val) => {
|
||
currentPage.value = val
|
||
start.value = pageSize.value * (val -1)
|
||
getDataList()
|
||
}
|
||
|
||
// 获取列表数据
|
||
const getDataList = () => {
|
||
regPage({
|
||
start: start.value,
|
||
limit: 10,
|
||
rescue_type: rescueType.value,
|
||
rescue_response_level: rescueResponseLevel.value,
|
||
rescue_code: rescueCode.value,
|
||
}).then(res => {
|
||
dataList.value = res.page.records
|
||
const data = []
|
||
dataList.value.forEach(item => {
|
||
if (item.rescue_status === '任务开始') {
|
||
data.push({
|
||
position: {
|
||
lng: item.rescue_target_lon,
|
||
lat: item.rescue_target_lat
|
||
},
|
||
icon: markerIcon1,
|
||
id: item.tsy_id
|
||
})
|
||
}
|
||
if (item.rescue_status === '任务处理中') {
|
||
data.push({
|
||
position: {
|
||
lng: item.rescue_target_lon,
|
||
lat: item.rescue_target_lat
|
||
},
|
||
icon: markerIcon2,
|
||
id: item.tsy_id
|
||
})
|
||
}
|
||
if (item.rescue_status === '任务已完成') {
|
||
data.push({
|
||
position: {
|
||
lng: item.rescue_target_lon,
|
||
lat: item.rescue_target_lat
|
||
},
|
||
icon: markerIcon3,
|
||
id: item.tsy_id
|
||
})
|
||
}
|
||
})
|
||
markers.value = data
|
||
total.value = res.page.total
|
||
})
|
||
}
|
||
|
||
const onReset = () => {
|
||
rescueType.value = ''
|
||
rescueResponseLevel.value = ''
|
||
rescueCode.value = ''
|
||
start.value = 0
|
||
getDataList()
|
||
}
|
||
|
||
const onSearch = () => {
|
||
start.value = 0
|
||
getDataList()
|
||
}
|
||
|
||
// 地图
|
||
const CesiumHostAddr = ref('')
|
||
// 获取系统参数列表
|
||
const getParamsList = () => {
|
||
// 判断当前环境
|
||
if (import.meta.env.VITE_APP_ENV === 'development') {
|
||
// 开发环境:直接使用环境变量中的值
|
||
CesiumHostAddr.value = import.meta.env.VITE_APP_DS_API
|
||
initMap();
|
||
} else {
|
||
// 生产环境:通过接口获取参数
|
||
getParam().then(res => {
|
||
const data = res.array.find(item => item.param_name === 'CesiumHostAddr')
|
||
|
||
if (data?.param_value) {
|
||
CesiumHostAddr.value = data.param_value
|
||
} else {
|
||
// 备用方案:基于当前窗口位置构建URL[1](@ref)
|
||
CesiumHostAddr.value = `${window.location.protocol}//${window.location.hostname}:${window.location.port}/tiles/`
|
||
}
|
||
initMap();
|
||
})
|
||
}
|
||
}
|
||
|
||
let viewer;
|
||
|
||
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkY2Y5NWY2Ni1mODQ1LTQ3YTUtYjc4Zi1jYzhjMGI2YzcxMWYiLCJpZCI6MTI5ODMwLCJpYXQiOjE2Nzk0Njk5NTd9.DTH54ioOH-HLqeNIetBe9hFyrPOX2Vp1AQmZzw8TIZ4';
|
||
const cesiumConfig = {
|
||
sceneMode: Cesium.SceneMode.SCENE2D,
|
||
// 主页按钮
|
||
homeButton: false,
|
||
// 场景模式选择器
|
||
sceneModePicker: false,
|
||
// 全屏按钮
|
||
fullscreenButton: false,
|
||
// 是否显示点击要素之后显示的信息
|
||
infoBox: false,
|
||
// 要素选中框
|
||
selectionIndicator: false,
|
||
// 影像切换
|
||
baseLayerPicker: false,
|
||
// 启用了阴影效果
|
||
shadows: true,
|
||
// 启用动画
|
||
shouldAnimate: true,
|
||
// 是否显示动画控件
|
||
animation: false,
|
||
// 是否显示时间线控件
|
||
timeline: false,
|
||
// 是否显示地名查找控件
|
||
geocoder: false,
|
||
// 是否显示帮助信息控件
|
||
navigationHelpButton: false,
|
||
contextOptions: {
|
||
contextType: 2, // Webgl2:2 ; WebGPU:3
|
||
},
|
||
// 版权信息
|
||
creditContainer: document.createElement('div')
|
||
}
|
||
|
||
const initMap = () => {
|
||
viewer = new Cesium.Viewer('cesiumContainer',cesiumConfig)
|
||
viewer._cesiumWidget._creditContainer.style.display = 'none'
|
||
viewer.scene.sun.show = false
|
||
viewer.scene.moon.show = false
|
||
viewer.scene.fog.enabled = false
|
||
viewer.scene.skyAtmosphere.show = false
|
||
viewer.scene.sun.show = false
|
||
viewer.scene.skyBox.show = false
|
||
viewer.scene.globe.enableLighting = false
|
||
viewer.shadowMap.darkness = 0.8
|
||
viewer.scene._sunBloom = false
|
||
viewer.scene.globe.showGroundAtmosphere = false
|
||
viewer.scene.postProcessStages.fxaa.enabled = true
|
||
viewer.camera.setView({
|
||
// 指定相机初始位置
|
||
destination: Cesium.Cartesian3.fromDegrees(112, 18, 4000000)
|
||
});
|
||
// 改写 Cesium 原生鼠标滚轮事件,地图缩放改为按下 Ctrl + 鼠标滚轮
|
||
modifyCesiumMouseWheel(viewer);
|
||
|
||
// 沉船摄影拼接图
|
||
const shipline = new Cesium.WebMapTileServiceImageryProvider(
|
||
{
|
||
url: CesiumHostAddr.value + 'geoserver/gwc/service/wmts/rest/ougp:正射影像图_GM输出_20240516/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/png',
|
||
layer: 'ougp:正射影像图_GM输出_20240516',
|
||
style: 'default',
|
||
format: 'image/png',
|
||
tileMatrixSetID: 'EPSG:4326',
|
||
tilingScheme: new Cesium.GeographicTilingScheme()
|
||
}
|
||
)
|
||
viewer.imageryLayers.addImageryProvider(shipline)
|
||
// 增加6000米等深线
|
||
const contour6000 = new Cesium.WebMapTileServiceImageryProvider(
|
||
{
|
||
url: CesiumHostAddr.value + 'geoserver/gwc/service/wmts/rest/ougp:contour6000/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/png',
|
||
layer: 'ougp:contour6000',
|
||
style: 'default',
|
||
format: 'image/png',
|
||
tileMatrixSetID: 'EPSG:4326',
|
||
tilingScheme: new Cesium.GeographicTilingScheme()
|
||
}
|
||
)
|
||
viewer.imageryLayers.addImageryProvider(contour6000)
|
||
|
||
const point_options = {
|
||
show: true, // 是否展示
|
||
pixelSize: 10, // 点的大小
|
||
color: Cesium.Color.RED, // 颜色
|
||
outlineColor: Cesium.Color.SKYBLUE, // 边框颜色
|
||
outlineWidth: 2 // 边框宽度
|
||
};
|
||
|
||
viewer.entities.add({
|
||
position: Cesium.Cartesian3.fromDegrees(113.27, 18.13),
|
||
point: point_options
|
||
});
|
||
}
|
||
|
||
onMounted(() => {
|
||
getParamsList()
|
||
getDataList()
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.container {
|
||
height: 820px;
|
||
display: flex;
|
||
|
||
.left {
|
||
width: 450px;
|
||
position: relative;
|
||
padding: 0 30px 30px;
|
||
box-sizing: border-box;
|
||
|
||
.fold {
|
||
position: absolute;
|
||
top: 350px;
|
||
right: 0;
|
||
}
|
||
|
||
.rule-text {
|
||
color: #000;
|
||
}
|
||
|
||
.search {
|
||
|
||
.input-bar {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
|
||
:deep(.el-input-group__append) {
|
||
background-color: #409eff;
|
||
color: white;
|
||
box-shadow: none;
|
||
}
|
||
}
|
||
}
|
||
|
||
.btn-bar {
|
||
margin-top: 10px;
|
||
display: flex;
|
||
justify-content: center;
|
||
}
|
||
|
||
.line {
|
||
margin-top: 10px;
|
||
width: 100%;
|
||
height: 1px;
|
||
background-color: #ddd;
|
||
}
|
||
|
||
.list {
|
||
color: #333;
|
||
height: 620px;
|
||
overflow-y: scroll;
|
||
scrollbar-width: none; /* Firefox */
|
||
-ms-overflow-style: none; /* IE/Edge */
|
||
|
||
.item {
|
||
padding: 30px 0;
|
||
border-bottom: 1px solid #dddddd;
|
||
|
||
&:hover .name {
|
||
color: #409eff;
|
||
}
|
||
|
||
.name {
|
||
padding-bottom: 5px;
|
||
color: #000;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.row {
|
||
padding: 5px 0;
|
||
display: flex;
|
||
gap: 20px;
|
||
|
||
.col {
|
||
flex: 1;
|
||
color: #999;
|
||
|
||
span {
|
||
color: #333;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.map {
|
||
flex: 1;
|
||
width: 100%;
|
||
height: 100%;
|
||
position: relative;
|
||
|
||
.unfold {
|
||
position: absolute;
|
||
top: 350px;
|
||
left: 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
.pagination {
|
||
margin: 10px 0 20px;
|
||
display: flex;
|
||
justify-content: center;
|
||
}
|
||
|
||
</style>
|