This commit is contained in:
liaoboping 2025-09-20 22:24:04 +08:00
parent 42d7ca303a
commit 1903cb0124
7 changed files with 184 additions and 62 deletions

View File

@ -325,6 +325,7 @@ export default class MyCesium {
movePlotByCoordinates(plotId, coordinates) {
// 实体
const targetPlot = this.viewer.entities.getById(plotId)
if (!targetPlot) return
if (targetPlot._isMoving === true) {
// 1. 获取新的路线坐标点(假设是同步获取的,或者是在回调中)
const positions = Cesium.Cartesian3.fromDegreesArray(coordinates.flat()) // 你的坐标路线

View File

@ -47,6 +47,14 @@ export default {
columns: [
{ dataIndex: 'serial' },
{ dataIndex: 'name', title: '分队名称', width: 'auto', minWidth: 160 },
{
dataIndex: 'teamType',
title: '推演方',
width: 'auto',
minWidth: 160,
align: 'center',
customRender: (text) => ['红方', '蓝方'][text],
},
{
dataIndex: 'type',
title: '分队类型',
@ -66,6 +74,19 @@ export default {
title: '',
formItems: [
{ label: '分队名称', prop: 'name' },
{
label: '推演方',
prop: 'teamType',
component: 'AntOriginSelect',
options: {
dataSource: () => ({
data: [
{ title: '红方', id: 0 },
{ title: '蓝方', id: 1 },
],
}),
},
},
{
label: '分队类型',
prop: 'type',

View File

@ -5,12 +5,17 @@
<span class="page-display-title">推演想定{{ roomName }}-{{ scenarioName }}</span>
<span class="page-display-title">剩余 {{ roomInfo.remainTimeStr }}</span>
</Flex>
<Grid class="page-display-main flex-1 oh">
<Grid class="page-display-main flex-1 oh" :rows="['30px', 1]" gap="0px">
<div class="tool-wrapper" style="grid-area: 1 / 1 / 2 / 2">
<a-menu :selectedKeys="[]" mode="horizontal" theme="dark">
<a-menu-item @click="() => {}"> 统计分析 </a-menu-item>
</a-menu>
</div>
<div
ref="display-cesium-container"
class="display-cesium-container"
id="display-cesium-container"
style="grid-area: 1 / 1 / 2 / 2"
style="grid-area: 2 / 1 / 3 / 2"
></div>
</Grid>
</Flex>
@ -21,6 +26,7 @@ export default {
name: 'SubsystemDisplay',
data() {
return {
initial: false,
ws: null,
roomInfo: {
remainTimeStr: '',
@ -65,26 +71,36 @@ export default {
case 'path_update':
this.cesium.movePlotByCoordinates(response.data.resourceId, response.data.points)
break
case 'scenarioInfo':
this.roomInfo.roomData = response.data
// this.initPlots()
case 'editScenarioInfo':
if (this.initial === false) {
this.roomInfo.roomData = JSON.parse(response.data)
this.initPlots()
this.initial = true
}
break
case 'updScenarioInfo':
{
const data = JSON.parse(response.data)
const targetIndex = this.roomInfo.roomData.findIndex((item) => item.sdzy.id === data.sdzy.id)
this.$set(this.roomInfo.roomData, targetIndex, data)
}
break
default:
console.log(response.cmdType, JSON.parse(response.data))
console.log(response.cmdType, response.data)
break
}
})
this.ws.send({ cmdType: 'scenarioInfo' })
this.ws.send({ cmdType: 'editScenarioInfo' })
},
closeWebsocket() {
this.ws && this.ws.close()
this.ws = null
},
initPlots(plots) {
plots.forEach((item) => {
if (item.lng && item.lat) {
this.cesium.addPlotByLonLat(item.imgBase64, { lon: +item.lng, lat: +item.lat }, item.id)
initPlots() {
this.roomInfo.roomData.forEach((item) => {
if (item.sdzy.lng && item.sdzy.lat) {
this.cesium.addPlotByLonLat(item.imgBase64, { lon: +item.sdzy.lng, lat: +item.sdzy.lat }, item.sdzy.id)
}
})
},
@ -111,6 +127,9 @@ export default {
background-color: #022234;
}
}
.ant-menu-horizontal {
line-height: 30px;
}
.display-cesium-container {
width: 100%;
height: 100%;

View File

@ -6,7 +6,11 @@
<span class="page-scene-title">剩余 {{ roomInfo.remainTimeStr }}</span>
</Flex>
<Grid class="page-model-main flex-1 oh" :columns="['320px', 1, '320px']" :rows="['30px', 1]" gap="0px">
<div class="tool-wrapper" style="grid-area: 1 / 1 / 2 / 4"></div>
<div class="tool-wrapper" style="grid-area: 1 / 1 / 2 / 4">
<a-menu :selectedKeys="[]" mode="horizontal" theme="dark">
<a-menu-item @click="() => {}"> 统计分析 </a-menu-item>
</a-menu>
</div>
<div
ref="model-cesium-container"
class="model-cesium-container"
@ -20,7 +24,7 @@
class="simulation-tree"
:treeData="zzbzllTreeData"
:selectedKeys.sync="zzbzll.selectedKeys"
:replaceFields="{ children: 'children', title: 'title', key: 'id' }"
:replaceFields="{ children: 'children', title: 'resourceName', key: 'id' }"
@select="handleSelectZzbzll"
>
</a-tree>
@ -114,6 +118,7 @@ export default {
},
data() {
return {
initial: false,
ws: null,
roomInfo: {
remainTimeStr: '',
@ -164,13 +169,30 @@ export default {
},
computed: {
zzbzllTreeData() {
return []
const zzbzllTreeData = [
{
id: '0',
resourceName: '红方',
selectable: false,
children: [],
},
{
id: '1',
resourceName: '蓝方',
selectable: false,
children: [],
},
]
this.roomInfo.roomData.forEach((item) => {
zzbzllTreeData[item.sdzy.type].children.push(item.sdzy)
})
return zzbzllTreeData
},
zzbzllSelectedFd() {
if (this.zzbzll.selectedKeys.length === 0) {
return null
}
return null
return this.roomInfo.roomData.find((item) => item.sdzy.id === this.zzbzll.selectedKeys[0])
},
rightRows() {
switch (this.rightViewer) {
@ -185,7 +207,7 @@ export default {
}
},
blbzShowKeys() {
return []
return this.zzbzllSelectedFd?.orgPostList.map((item) => item.orgId) || []
},
showBlbzCheckedTreeData() {
const target = []
@ -193,10 +215,10 @@ export default {
return target
},
jcsxModelData() {
return {}
return this.zzbzllSelectedFd?.jbxx || {}
},
xdrwActionList() {
return []
return this.zzbzllSelectedFd?.scenarioTasks || []
},
},
created() {
@ -242,16 +264,26 @@ export default {
case 'path_update':
this.cesium.movePlotByCoordinates(response.data.resourceId, response.data.points)
break
case 'scenarioInfo':
this.roomInfo.roomData = response.data
// this.initPlots()
case 'editScenarioInfo':
if (this.initial === false) {
this.roomInfo.roomData = JSON.parse(response.data)
this.initPlots()
this.initial = true
}
break
case 'updScenarioInfo':
{
const data = JSON.parse(response.data)
const targetIndex = this.roomInfo.roomData.findIndex((item) => item.sdzy.id === data.sdzy.id)
this.$set(this.roomInfo.roomData, targetIndex, data)
}
break
default:
console.log(response.cmdType, JSON.parse(response.data))
console.log(response.cmdType, response.data)
break
}
})
this.ws.send({ cmdType: 'scenarioInfo' })
this.ws.send({ cmdType: 'editScenarioInfo' })
},
closeWebsocket() {
this.ws && this.ws.close()
@ -267,16 +299,19 @@ export default {
}
},
initPlots(plots) {
plots.forEach((item) => {
if (item.lng && item.lat) {
this.cesium.addPlotByLonLat(item.imgBase64, { lon: +item.lng, lat: +item.lat }, item.id)
initPlots() {
this.roomInfo.roomData.forEach((item) => {
if (item.sdzy.lng && item.sdzy.lat) {
this.cesium.addPlotByLonLat(item.imgBase64, { lon: +item.sdzy.lng, lat: +item.sdzy.lat }, item.sdzy.id)
}
})
},
handleSelectZzbzll(selectedKeys, { node }) {
this.cesium.setClientByCenter({ longitude: +node.dataRef.lng, latitude: +node.dataRef.lat })
this.cesium.setClientByCenter({
longitude: +this.zzbzllSelectedFd.sdzy.lng,
latitude: +this.zzbzllSelectedFd.sdzy.lat,
})
},
},
}
@ -301,6 +336,9 @@ export default {
background-color: #022234;
}
}
.ant-menu-horizontal {
line-height: 30px;
}
.model-cesium-container {
width: 100%;
height: 100%;

View File

@ -12,6 +12,7 @@
<AntFormModal
:visible.sync="scenarioModal.visible"
:title="scenarioModal.title"
width="900px"
:formItems="scenarioModal.formItems"
:formRules="scenarioModal.formRules"
:formData="scenarioModal.formData"
@ -148,6 +149,7 @@ export default {
{
label: '开始时间',
prop: 'startTime',
required: true,
component: 'a-date-picker',
options: {
showTime: true,
@ -158,6 +160,7 @@ export default {
{
label: '结束时间',
prop: 'endTime',
required: true,
component: 'a-date-picker',
options: {
showTime: true,
@ -165,10 +168,11 @@ export default {
valueFormat: 'YYYY-MM-DD HH:mm:ss',
},
},
{ label: '想定区域(东)', prop: 'right', required: true, options: { type: 'number' } },
{ label: '想定区域(西)', prop: 'left', required: true, options: { type: 'number' } },
{ label: '想定区域(南)', prop: 'down', required: true, options: { type: 'number' } },
{ label: '想定区域(北)', prop: 'up', required: true, options: { type: 'number' } },
{ label: '想定区域(东)', prop: 'right', required: true, component: 'LongitudeInput' },
{ label: '想定区域(西)', prop: 'left', required: true, component: 'LongitudeInput' },
{ label: '想定区域(南)', prop: 'down', required: true, component: 'LatitudeInput' },
{ label: '想定区域(北)', prop: 'up', required: true, component: 'LatitudeInput' },
{ label: '想定描述', prop: 'desc', required: true, component: 'a-textarea', options: { rows: 4 } },
],
formRules: {},
formData: {},

View File

@ -6,7 +6,11 @@
<span class="page-scene-title">剩余 {{ roomInfo.remainTimeStr }}</span>
</Flex>
<Grid class="page-scene-main flex-1 oh" :columns="['320px', 1, '320px']" :rows="['30px', 1]" gap="0px">
<div class="tool-wrapper" style="grid-area: 1 / 1 / 2 / 4"></div>
<div class="tool-wrapper" style="grid-area: 1 / 1 / 2 / 4">
<a-menu :selectedKeys="[]" mode="horizontal" theme="dark">
<a-menu-item @click="() => {}"> 统计分析 </a-menu-item>
</a-menu>
</div>
<div
ref="scene-cesium-container"
class="scene-cesium-container"
@ -20,7 +24,7 @@
class="simulation-tree"
:treeData="zzbzllTreeData"
:selectedKeys.sync="zzbzll.selectedKeys"
:replaceFields="{ children: 'children', title: 'title', key: 'id' }"
:replaceFields="{ children: 'children', title: 'resourceName', key: 'id' }"
@select="handleSelectZzbzll"
>
</a-tree>
@ -54,16 +58,16 @@
ref="jcsx"
v-if="zzbzllSelectedFd"
:scenarioId="scenarioId"
:resourceId="zzbzllSelectedFd.id"
:resourceName="zzbzllSelectedFd.title"
:resourceType="zzbzllSelectedFd.resourceType"
:type="zzbzllSelectedFd.type"
:resourceId="zzbzllSelectedFd.sdzy.id"
:resourceName="zzbzllSelectedFd.sdzy.resourceName"
:resourceType="zzbzllSelectedFd.sdzy.resourceType"
:type="zzbzllSelectedFd.sdzy.type"
:modelData="jcsxModelData"
:readonly="true"
/>
</div>
</ModuleWrapper>
<ModuleWrapper :title="xdrw.resourceTypeMapTitle[zzbzllSelectedFd?.resourceType] || '行动任务'">
<ModuleWrapper :title="xdrw.resourceTypeMapTitle[zzbzllSelectedFd?.sdzy.resourceType] || '行动任务'">
<template #extra>
<Zoom :max="rightViewer === 'xdrw'" @zoom-max="rightViewer = 'xdrw'" @zoom-min="rightViewer = ''" />
</template>
@ -72,8 +76,8 @@
ref="xdrw"
v-if="zzbzllSelectedFd"
:scenarioId="scenarioId"
:resourceId="zzbzllSelectedFd.id"
:resourceType="zzbzllSelectedFd.resourceType"
:resourceId="zzbzllSelectedFd.sdzy.id"
:resourceType="zzbzllSelectedFd.sdzy.resourceType"
:actionList="xdrwActionList"
:readonly="true"
/>
@ -99,6 +103,7 @@ export default {
},
data() {
return {
initial: false,
ws: null,
roomInfo: {
remainTimeStr: '',
@ -128,13 +133,30 @@ export default {
},
computed: {
zzbzllTreeData() {
return []
const zzbzllTreeData = [
{
id: '0',
resourceName: '红方',
selectable: false,
children: [],
},
{
id: '1',
resourceName: '蓝方',
selectable: false,
children: [],
},
]
this.roomInfo.roomData.forEach((item) => {
zzbzllTreeData[item.sdzy.type].children.push(item.sdzy)
})
return zzbzllTreeData
},
zzbzllSelectedFd() {
if (this.zzbzll.selectedKeys.length === 0) {
return null
}
return null
return this.roomInfo.roomData.find((item) => item.sdzy.id === this.zzbzll.selectedKeys[0])
},
rightRows() {
switch (this.rightViewer) {
@ -149,7 +171,7 @@ export default {
}
},
blbzShowKeys() {
return []
return this.zzbzllSelectedFd?.orgPostList.map((item) => item.orgId) || []
},
showBlbzCheckedTreeData() {
const target = []
@ -157,10 +179,10 @@ export default {
return target
},
jcsxModelData() {
return {}
return this.zzbzllSelectedFd?.jbxx || {}
},
xdrwActionList() {
return []
return this.zzbzllSelectedFd?.scenarioTasks || []
},
},
created() {
@ -206,16 +228,27 @@ export default {
case 'path_update':
this.cesium.movePlotByCoordinates(response.data.resourceId, response.data.points)
break
case 'scenarioInfo':
this.roomInfo.roomData = response.data
// this.initPlots()
case 'editScenarioInfo':
if (this.initial === false) {
this.roomInfo.roomData = JSON.parse(response.data)
this.initPlots()
this.initial = true
}
break
case 'updScenarioInfo':
{
console.log(response.cmdType, response.data, typeof response.data)
const data = JSON.parse(response.data)
const targetIndex = this.roomInfo.roomData.findIndex((item) => item.sdzy.id === data.sdzy.id)
this.$set(this.roomInfo.roomData, targetIndex, data)
}
break
default:
console.log(response.cmdType, JSON.parse(response.data))
// console.log(response.cmdType, response.data)
break
}
})
this.ws.send({ cmdType: 'scenarioInfo' })
this.ws.send({ cmdType: 'editScenarioInfo' })
},
closeWebsocket() {
this.ws && this.ws.close()
@ -231,16 +264,19 @@ export default {
}
},
initPlots(plots) {
plots.forEach((item) => {
if (item.lng && item.lat) {
this.cesium.addPlotByLonLat(item.imgBase64, { lon: +item.lng, lat: +item.lat }, item.id)
initPlots() {
this.roomInfo.roomData.forEach((item) => {
if (item.sdzy.lng && item.sdzy.lat) {
this.cesium.addPlotByLonLat(item.sdzy.imgBase64, { lon: +item.sdzy.lng, lat: +item.sdzy.lat }, item.sdzy.id)
}
})
},
handleSelectZzbzll(selectedKeys, { node }) {
this.cesium.setClientByCenter({ longitude: +node.dataRef.lng, latitude: +node.dataRef.lat })
this.cesium.setClientByCenter({
longitude: +this.zzbzllSelectedFd.sdzy.lng,
latitude: +this.zzbzllSelectedFd.sdzy.lat,
})
},
},
}
@ -265,6 +301,9 @@ export default {
background-color: #022234;
}
}
.ant-menu-horizontal {
line-height: 30px;
}
.scene-cesium-container {
width: 100%;
height: 100%;

View File

@ -71,7 +71,7 @@
</a-radio-group>
</template>
<template #extra>
<AntOriginSelect v-model="fd.force" :dataSource="forceSource" width="80px" />
<AntOriginSelect v-model="fd.teamType" :dataSource="forceSource" width="80px" @change="getFdListData" />
</template>
<Flex v-loading.dark="fd.loading" class="normal" fd="co" style="padding: 5px">
<Flex class="flex-1 scroller-y" fw="w" ac="fs">
@ -195,7 +195,7 @@ export default {
formData: {},
},
fd: {
force: 0,
teamType: 0,
type: 5,
loading: false,
listData: [],
@ -329,7 +329,7 @@ export default {
async getFdListData() {
try {
this.fd.loading = true
const res = await getAction(`/baseData/scenario/resources/${this.fd.type}`)
const res = await getAction(`/baseData/scenario/resources/${this.fd.type}/${this.fd.teamType}`)
this.fd.listData = res.data
} catch (error) {
console.log(error)
@ -359,14 +359,14 @@ export default {
const x = e.x - this.$refs['scene-presetting-cesium-container'].offsetLeft
const y = e.y - this.$refs['scene-presetting-cesium-container'].offsetTop
const { plotId, longitude, latitude } = this.cesium.addPlotByOffset(item.imgBase64, { x, y })
this.savePlot(this.fd.force, item, { plotId, longitude, latitude })
this.savePlot(this.fd.teamType, item, { plotId, longitude, latitude })
},
async savePlot(force, item, { plotId, longitude, latitude }) {
async savePlot(teamType, item, { plotId, longitude, latitude }) {
try {
await postAction('/scenario/resource/save', {
id: plotId,
scenarioId: this.scenarioId,
type: force,
type: teamType,
resourceType: item.type,
resourceId: item.id,
lng: longitude,