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) { movePlotByCoordinates(plotId, coordinates) {
// 实体 // 实体
const targetPlot = this.viewer.entities.getById(plotId) const targetPlot = this.viewer.entities.getById(plotId)
if (!targetPlot) return
if (targetPlot._isMoving === true) { if (targetPlot._isMoving === true) {
// 1. 获取新的路线坐标点(假设是同步获取的,或者是在回调中) // 1. 获取新的路线坐标点(假设是同步获取的,或者是在回调中)
const positions = Cesium.Cartesian3.fromDegreesArray(coordinates.flat()) // 你的坐标路线 const positions = Cesium.Cartesian3.fromDegreesArray(coordinates.flat()) // 你的坐标路线

View File

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

View File

@ -5,12 +5,17 @@
<span class="page-display-title">推演想定{{ roomName }}-{{ scenarioName }}</span> <span class="page-display-title">推演想定{{ roomName }}-{{ scenarioName }}</span>
<span class="page-display-title">剩余 {{ roomInfo.remainTimeStr }}</span> <span class="page-display-title">剩余 {{ roomInfo.remainTimeStr }}</span>
</Flex> </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 <div
ref="display-cesium-container" ref="display-cesium-container"
class="display-cesium-container" class="display-cesium-container"
id="display-cesium-container" id="display-cesium-container"
style="grid-area: 1 / 1 / 2 / 2" style="grid-area: 2 / 1 / 3 / 2"
></div> ></div>
</Grid> </Grid>
</Flex> </Flex>
@ -21,6 +26,7 @@ export default {
name: 'SubsystemDisplay', name: 'SubsystemDisplay',
data() { data() {
return { return {
initial: false,
ws: null, ws: null,
roomInfo: { roomInfo: {
remainTimeStr: '', remainTimeStr: '',
@ -65,26 +71,36 @@ export default {
case 'path_update': case 'path_update':
this.cesium.movePlotByCoordinates(response.data.resourceId, response.data.points) this.cesium.movePlotByCoordinates(response.data.resourceId, response.data.points)
break break
case 'scenarioInfo': case 'editScenarioInfo':
this.roomInfo.roomData = response.data if (this.initial === false) {
// this.initPlots() 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 break
default: default:
console.log(response.cmdType, JSON.parse(response.data)) console.log(response.cmdType, response.data)
break break
} }
}) })
this.ws.send({ cmdType: 'scenarioInfo' }) this.ws.send({ cmdType: 'editScenarioInfo' })
}, },
closeWebsocket() { closeWebsocket() {
this.ws && this.ws.close() this.ws && this.ws.close()
this.ws = null this.ws = null
}, },
initPlots(plots) { initPlots() {
plots.forEach((item) => { this.roomInfo.roomData.forEach((item) => {
if (item.lng && item.lat) { if (item.sdzy.lng && item.sdzy.lat) {
this.cesium.addPlotByLonLat(item.imgBase64, { lon: +item.lng, lat: +item.lat }, item.id) 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; background-color: #022234;
} }
} }
.ant-menu-horizontal {
line-height: 30px;
}
.display-cesium-container { .display-cesium-container {
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

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

View File

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

View File

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

View File

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