教员系统进入房间,基本信息,作战行动
This commit is contained in:
parent
5fd2a19d7d
commit
cf2fd95acc
|
@ -13,7 +13,7 @@ export const asyncRouterMap = [
|
|||
name: 'index',
|
||||
component: BasicLayout,
|
||||
meta: { title: 'menu.home' },
|
||||
redirect: '/dashboard/workplace',
|
||||
redirect: '/user/thirdLogin',
|
||||
children: [
|
||||
// dashboard
|
||||
{
|
||||
|
@ -217,7 +217,7 @@ export const constantRouterMap = [
|
|||
path: '/simulationScene',
|
||||
name: 'SimulationScene',
|
||||
component: () => import(/* webpackChunkName: "fail" */ '@/views/simulationScene/index.vue'),
|
||||
// redirect: '/simulationScene/systemSelect',
|
||||
redirect: '/simulationScene/centralControl',
|
||||
children: [
|
||||
{
|
||||
path: '/simulationScene/trainer',
|
||||
|
@ -263,6 +263,37 @@ export const constantRouterMap = [
|
|||
component: () => import(/* webpackChunkName: "fail" */ '@/views/simulationScene/instructor/index.vue'),
|
||||
meta: { title: '教员系统' },
|
||||
},
|
||||
{
|
||||
path: '/simulationScene/instructorSystem',
|
||||
name: 'SimulationSceneInstructorSystem',
|
||||
component: () => import(/* webpackChunkName: "fail" */ '@/views/simulationScene/instructor/system/index.vue'),
|
||||
children: [
|
||||
{
|
||||
path: '/simulationScene/instructorSystem/simulationModel',
|
||||
name: 'SimulationSceneInstructorSystemSimulationModel',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "fail" */ '@/views/simulationScene/instructor/system/simulationModel/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/simulationScene/instructorSystem/sceneEditing',
|
||||
name: 'SimulationSceneInstructorSystemSceneEditing',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "fail" */ '@/views/simulationScene/instructor/system/sceneEditing/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/simulationScene/instructorSystem/display',
|
||||
name: 'SimulationSceneInstructorSystemDisplay',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "fail" */ '@/views/simulationScene/instructor/system/display/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/simulationScene/instructorSystem/evaluation',
|
||||
name: 'SimulationSceneInstructorSystemEvaluation',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "fail" */ '@/views/simulationScene/instructor/system/evaluation/index.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
path: '/simulationScene/systemSelect',
|
||||
|
|
|
@ -235,7 +235,7 @@ export default {
|
|||
handleEnterRoom(roomItem) {
|
||||
window.localStorage.setItem('instructorRoomId', roomItem.id)
|
||||
window.localStorage.setItem('instructorRoomName', roomItem.roomName)
|
||||
this.$router.push({ name: 'SimulationSceneInstructorMenu' })
|
||||
this.$router.push({ name: 'SimulationSceneInstructorSystemDisplay' })
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<template>
|
||||
<div class="disply-page">
|
||||
<div class="cesium-container" id="cesium-container"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SimulationSceneDisplay',
|
||||
created() {
|
||||
this.$bus.$emit('set-instructor-system-title', '显示子系统')
|
||||
},
|
||||
mounted() {
|
||||
this.cesium = new window.MyCesium('cesium-container')
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.cesium-container {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div>SimulationSceneEvaluation</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SimulationSceneEvaluation',
|
||||
created() {
|
||||
this.$bus.$emit('set-instructor-system-title', '评估子系统')
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
102
src/views/simulationScene/instructor/system/index.vue
Normal file
102
src/views/simulationScene/instructor/system/index.vue
Normal file
|
@ -0,0 +1,102 @@
|
|||
<template>
|
||||
<ModuleWrapper :title="title + ' - ' + roomName">
|
||||
<template #extra>
|
||||
<a-icon type="logout" title="退出房间" style="font-size: 18px" @click="handleQuitRoom" />
|
||||
</template>
|
||||
<Flex class="menu-bar">
|
||||
<Flex ai="c" v-for="menu in showMenus" :key="menu.moduleCode" class="menu-item" @click="handleClickMenu(menu)">
|
||||
<img class="menu-icon" :src="systemIconMap[menu.moduleCode]" alt="" />
|
||||
<div class="menu-title">{{ menu.title }}</div>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<router-view></router-view>
|
||||
</ModuleWrapper>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '',
|
||||
roomName: '',
|
||||
allMenu: [
|
||||
{ moduleCode: 'display_system', title: '显示子系统', name: 'SimulationSceneInstructorSystemDisplay' },
|
||||
{
|
||||
moduleCode: 'simulation_system',
|
||||
title: '仿真模型子系统',
|
||||
name: 'SimulationSceneInstructorSystemSimulationModel',
|
||||
},
|
||||
{ moduleCode: 'scenario_system', title: '场景编辑子系统', name: 'SimulationSceneInstructorSystemSceneEditing' },
|
||||
{ moduleCode: 'evaluation_system', title: '评估子系统', name: 'SimulationSceneInstructorSystemEvaluation' },
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
systemIconMap: (state) => state.simulation.systemIconMap,
|
||||
}),
|
||||
showMenus() {
|
||||
return this.allMenu.filter((menu) => menu.name !== this.$route.name)
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('set-instructor-system-title', (title) => {
|
||||
this.title = title
|
||||
})
|
||||
const roomId = window.localStorage.getItem('instructorRoomId')
|
||||
this.roomName = window.localStorage.getItem('instructorRoomName')
|
||||
if (!roomId) {
|
||||
this.$router.push({ name: 'SimulationSceneInstructor' })
|
||||
return
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleQuitRoom() {
|
||||
window.localStorage.removeItem('instructorRoomId')
|
||||
window.localStorage.removeItem('instructorRoomName')
|
||||
this.$router.push({ name: 'SimulationSceneInstructor' })
|
||||
},
|
||||
handleClickMenu(menu) {
|
||||
this.$router.push({ name: menu.name })
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.menu-bar {
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
transform: translateX(-50%);
|
||||
height: 50px !important;
|
||||
.menu-item {
|
||||
padding: 0 16px;
|
||||
margin: 0 8px;
|
||||
cursor: pointer;
|
||||
.menu-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
object-fit: contain;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.menu-title {
|
||||
font-size: 18px;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
.menu-item:hover {
|
||||
background-color: #00deff22;
|
||||
.menu-title {
|
||||
color: #00deff;
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep {
|
||||
.module-wrapper-main > div {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,143 @@
|
|||
<template>
|
||||
<div class="lon-lat-input">
|
||||
<div class="lon-input" style="padding: 10px 0">
|
||||
<a-select v-model="lonSelect" style="width: 76px; margin-right: 20px">
|
||||
<a-select-option :value="1">东经</a-select-option>
|
||||
<a-select-option :value="-1">西经</a-select-option>
|
||||
</a-select>
|
||||
<a-input-number v-model="lonNumber" :min="0" :max="180" :precision="8" style="width: 152px" />
|
||||
<span style="margin: 0 8px">°</span>
|
||||
<span style="margin: 0 12px">或</span>
|
||||
<a-input-number v-model="lonDegree" :min="0" :max="180" :step="1" :precision="0" style="width: 60px" />
|
||||
<span style="margin: 0 8px">°</span>
|
||||
<a-input-number v-model="lonMinute" :min="0" :max="60" :step="1" :precision="0" style="width: 60px" />
|
||||
<span style="margin: 0 8px">′</span>
|
||||
<a-input-number v-model="lonSecond" :min="0" :max="60" :step="1" :precision="0" style="width: 60px" />
|
||||
<span style="margin: 0 8px">″</span>
|
||||
</div>
|
||||
<div class="lat-input" style="padding: 10px 0">
|
||||
<a-select v-model="latSelect" style="width: 76px; margin-right: 20px">
|
||||
<a-select-option :value="1">北纬</a-select-option>
|
||||
<a-select-option :value="-1">南纬</a-select-option>
|
||||
</a-select>
|
||||
<a-input-number v-model="latNumber" :min="0" :max="180" :precision="8" style="width: 152px" />
|
||||
<span style="margin: 0 8px">°</span>
|
||||
<span style="margin: 0 12px">或</span>
|
||||
<a-input-number v-model="latDegree" :min="0" :max="180" :step="1" :precision="0" style="width: 60px" />
|
||||
<span style="margin: 0 8px">°</span>
|
||||
<a-input-number v-model="latMinute" :min="0" :max="60" :step="1" :precision="0" style="width: 60px" />
|
||||
<span style="margin: 0 8px">′</span>
|
||||
<a-input-number v-model="latSecond" :min="0" :max="60" :step="1" :precision="0" style="width: 60px" />
|
||||
<span style="margin: 0 8px">″</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
lon: { type: Number, required: true },
|
||||
lat: { type: Number, required: true },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
EWSelect: 1,
|
||||
NSSelect: 1,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
lonSelect: {
|
||||
get() {
|
||||
return this.lon ? this.lon / this.lonNumber : this.EWSelect
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('update:lon', this.lonNumber * v)
|
||||
this.EWSelect = v
|
||||
},
|
||||
},
|
||||
lonNumber: {
|
||||
get() {
|
||||
return Math.abs(this.lon)
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('update:lon', Math.abs(v) * this.lonSelect)
|
||||
},
|
||||
},
|
||||
lonDegree: {
|
||||
get() {
|
||||
return Math.floor(this.lonNumber)
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('update:lon', Math.abs(v) * this.lonSelect + this.lonMinute / 60 + this.lonSecond / 3600)
|
||||
},
|
||||
},
|
||||
lonMinute: {
|
||||
get() {
|
||||
return Math.floor(this.lonNumber * 60) % 60
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('update:lon', this.lonDegree * this.lonSelect + Math.abs(v) / 60 + this.lonSecond / 3600)
|
||||
},
|
||||
},
|
||||
lonSecond: {
|
||||
get() {
|
||||
return Math.floor(this.lonNumber * 3600) % 60
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('update:lon', this.lonDegree * this.lonSelect + this.lonMinute / 60 + Math.abs(v) / 3600)
|
||||
},
|
||||
},
|
||||
latSelect: {
|
||||
get() {
|
||||
return this.lat ? this.lat / this.latNumber : this.NSSelect
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('update:lat', this.latNumber * v)
|
||||
this.NSSelect = v
|
||||
},
|
||||
},
|
||||
latNumber: {
|
||||
get() {
|
||||
return Math.abs(this.lat)
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('update:lat', Math.abs(v) * this.latSelect)
|
||||
},
|
||||
},
|
||||
latDegree: {
|
||||
get() {
|
||||
return Math.floor(this.latNumber)
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('update:lat', Math.abs(v) * this.latSelect + this.latMinute / 60 + this.latSecond / 3600)
|
||||
},
|
||||
},
|
||||
latMinute: {
|
||||
get() {
|
||||
return Math.floor(this.latNumber * 60) % 60
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('update:lat', this.latDegree * this.latSelect + Math.abs(v) / 60 + this.latSecond / 3600)
|
||||
},
|
||||
},
|
||||
latSecond: {
|
||||
get() {
|
||||
return Math.floor(this.latNumber * 3600) % 60
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('update:lat', this.latDegree * this.latSelect + this.latMinute / 60 + Math.abs(v) / 3600)
|
||||
},
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (this.lon < 0) {
|
||||
this.EWSelect = 'W'
|
||||
}
|
||||
if (this.lat < 0) {
|
||||
this.NSSelect = 'S'
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
|
@ -0,0 +1,810 @@
|
|||
<template>
|
||||
<Grid class="scene-editing-page" :columns="['320px', 1, '320px']" :rows="[45, 30, 25]" gap="0px">
|
||||
<ModuleWrapper title="作战/保障力量" style="grid-column: 1 / 2; grid-row: 1 / 2">
|
||||
<div class="normal" style="padding: 5px; overflow-y: auto">
|
||||
<a-tree
|
||||
class="simulation-tree"
|
||||
:treeData="zb.zbTreeData"
|
||||
:selectedKeys.sync="zb.selectedKeys"
|
||||
:replaceFields="{ children: 'children', title: 'name', key: 'id' }"
|
||||
@select="handleSelectTree"
|
||||
></a-tree>
|
||||
</div>
|
||||
</ModuleWrapper>
|
||||
<ModuleWrapper title="装备元素" style="grid-column: 1 / 2; grid-row: 2 / 4">
|
||||
<div class="normal flex-c" style="padding: 5px">
|
||||
<a-input-search v-model="ys.keyword" placeholder="输入关键词搜索..." @search="onSearch" />
|
||||
<div style="height: 0; flex: 1; overflow-y: auto">
|
||||
<a-row>
|
||||
<template v-for="item in ys.ysList">
|
||||
<a-col :key="item.id" :span="24">{{ item.title }}</a-col>
|
||||
<a-col v-for="it in item.children" :key="it.id" :span="12" class="flex-c ai-c">
|
||||
<img class="ys-image" :src="it.image" alt="" @click="addModel" />
|
||||
<span>{{ it.title }}</span>
|
||||
</a-col>
|
||||
</template>
|
||||
</a-row>
|
||||
</div>
|
||||
</div>
|
||||
</ModuleWrapper>
|
||||
<div
|
||||
class="cesium-container"
|
||||
id="cesium-container"
|
||||
style="grid-column: 2 / 3; grid-row: 1 / 7; overflow: hidden"
|
||||
></div>
|
||||
<ModuleWrapper style="grid-column: 3 / 4; grid-row: 1 / 4">
|
||||
<template #title>
|
||||
<a-radio-group v-model="right.radioType" button-style="solid">
|
||||
<a-radio-button value="jcsx">基础属性</a-radio-button>
|
||||
<a-radio-button value="zzxd">作战行动</a-radio-button>
|
||||
<!-- <a-radio-button value="dzsx">单装属性</a-radio-button> -->
|
||||
</a-radio-group>
|
||||
</template>
|
||||
<div class="normal" style="padding: 15px 0">
|
||||
<div style="height: 100%; padding: 0 15px; overflow-y: auto">
|
||||
<div v-if="right.radioType === 'jcsx'">
|
||||
<a-collapse class="simulation-collapse" :defaultActiveKey="['1', '2', '3', '4', '5', '6', '7', '8', '9']">
|
||||
<a-collapse-panel class="simulation-collapse-item" key="1" header="基础信息">
|
||||
<img class="image" :src="right.detail.image || '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png'" />
|
||||
<div class="name">
|
||||
{{ right.detail.name }}
|
||||
<a-button v-if="hasDetail" type="text-primary" icon="edit" @click="handleOpenMcModal"></a-button>
|
||||
</div>
|
||||
<!-- <div class="zt-item flex ai-c jc-sb">
|
||||
<span style="min-width: 100px">推演方:</span>
|
||||
<a-select
|
||||
style="width: 120px"
|
||||
class="simulation-select"
|
||||
defaultValue="1"
|
||||
dropdownClassName="simulation-select-dropdown"
|
||||
>
|
||||
<a-select-option value="1">红方</a-select-option>
|
||||
<a-select-option value="2">蓝方</a-select-option>
|
||||
</a-select>
|
||||
</div> -->
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">推演方:</span>
|
||||
<span>{{ right.detail.position.deduceTypeName }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">类型:</span>
|
||||
<span>{{ right.detail.position.logisticType | logisticTypeFormat }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">方向:</span>
|
||||
<span>{{ right.detail.position.direction | numberFormat }}°</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">速度:</span>
|
||||
<span>{{ right.detail.position.speed }} 公里/时</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">经度:</span>
|
||||
<span class="flex-1">{{ right.detail.position.lng | lonFormat }}</span>
|
||||
<a-button v-if="hasDetail" type="text-primary" icon="edit" @click="handleOpenLonlatModal"></a-button>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">纬度:</span>
|
||||
<span class="flex-1">{{ right.detail.position.lat | latFormat }}</span>
|
||||
<a-button v-if="hasDetail" type="text-primary" icon="edit" @click="handleOpenLonlatModal"></a-button>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">高度/深度:</span>
|
||||
<span class="flex-1">{{ right.detail.position.height | numberFormat }} 米(海拔)</span>
|
||||
<a-button v-if="hasDetail" type="text-primary" icon="edit" @click="handleOpenHdModal()"></a-button>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="2" header="人员状态属性">
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">人员编制数:</span>
|
||||
<span>{{ right.detail.personStatistic.total }} 人</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">当前人数:</span>
|
||||
<span>{{ right.detail.personStatistic.current }} 人</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">死亡人数:</span>
|
||||
<span>{{ right.detail.personStatistic.death }} 人</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">受伤人数:</span>
|
||||
<span>{{ right.detail.personStatistic.injured }} 人</span>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="3" header="野战食品状态属性">
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">野战食物初始量(份):</span>
|
||||
<span>{{ right.detail.foodInfo.startNum }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">野战食物当前量(份):</span>
|
||||
<span>{{ right.detail.foodInfo.currentNum }}</span>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="4" header="用水状态属性">
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">用水初始量(吨):</span>
|
||||
<span>{{ right.detail.waterInfo.startNum }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">用水当前量(吨):</span>
|
||||
<span>{{ right.detail.waterInfo.currentNum }}</span>
|
||||
<span></span>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="5" header="油料状态属性">
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">油料初始量(份):</span>
|
||||
<span>{{ right.detail.oilInfo.startNum }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">油料当前量(份):</span>
|
||||
<span>{{ right.detail.oilInfo.currentNum }}</span>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="6" header="药材状态属性">
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">药材初始量(份):</span>
|
||||
<span>{{ right.detail.medicalInfo.startNum }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">药材当前量(份):</span>
|
||||
<span>{{ right.detail.medicalInfo.currentNum }}</span>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="7" header="武器弹药状态属性">
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">轻武器弹药量(吨):</span>
|
||||
<span>{{ right.detail.ammunition.lightArms }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">压制武器弹药量(吨):</span>
|
||||
<span>{{ right.detail.ammunition.suppressing }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">反坦克武器弹药量(吨):</span>
|
||||
<span>{{ right.detail.ammunition.antiTank }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">防空反导武器弹药量(吨):</span>
|
||||
<span>{{ right.detail.ammunition.antiAircraft }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">布扫雷装备弹药量(吨):</span>
|
||||
<span>{{ right.detail.ammunition.mineLaying }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">爆破器材弹药量(吨):</span>
|
||||
<span>{{ right.detail.ammunition.explosiveDevice }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">烟火装备弹药量(吨):</span>
|
||||
<span>{{ right.detail.ammunition.smokeDevice }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">防化消耗弹药量(吨):</span>
|
||||
<span>{{ right.detail.ammunition.antiChemical }}</span>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="8" header="保障标准信息">
|
||||
<div class="zt-item flex ai-c jc-sb">
|
||||
<span style="min-width: 100px">保障分配类型:</span>
|
||||
<a-select
|
||||
style="width: 120px"
|
||||
class="simulation-select"
|
||||
defaultValue="1"
|
||||
dropdownClassName="simulation-select-dropdown"
|
||||
>
|
||||
<a-select-option value="1">自动分配</a-select-option>
|
||||
<a-select-option value="2">手动分配</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="9" header="保障配置">
|
||||
<div class="zt-item flex ai-c jc-sb">
|
||||
<a-button type="primary">兵力编组</a-button>
|
||||
<!-- <a-button type="primary">关注</a-button> -->
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
</div>
|
||||
<div v-if="right.radioType === 'zzxd'" class="zzxd-wrapper flex-v">
|
||||
<div class="zzxd-header flex ai-c jc-sb">
|
||||
<div class="zzxd-title">作战行动</div>
|
||||
<div>
|
||||
<a-button type="text-primary" icon="menu"></a-button>
|
||||
<a-button type="text-primary" icon="plus" @click="handleOpenAddActionModal"></a-button>
|
||||
<a-button type="text-primary" icon="edit" @click="handleOpenEditActionModal"></a-button>
|
||||
<a-button type="text-primary" icon="delete" @click="handleDeleteAction"></a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1" style="overflow-y: auto">
|
||||
<div
|
||||
v-for="item in right.detail.actionList"
|
||||
:key="item.id"
|
||||
class="action-item flex"
|
||||
@click="right.checkedAction = item"
|
||||
>
|
||||
<div class="action-icon">
|
||||
<div class="action-line"></div>
|
||||
<a-radio
|
||||
:checked="right.checkedAction && right.checkedAction.id === item.id"
|
||||
style="margin-right: 0"
|
||||
></a-radio>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="action-title">{{ item.typeName || '- -' }}</div>
|
||||
<div class="action-time">开始时间:{{ item.beginDateTime }}</div>
|
||||
<div class="action-time">结束时间:{{ item.endDateTime }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div v-if="right.radioType === 'dzsx'">
|
||||
<div>
|
||||
<a-collapse>
|
||||
<a-collapse-panel v-for="item in right.detail.equipmentList" :key="item.id" :header="item.name">
|
||||
<a-collapse>
|
||||
<a-collapse-panel header="无损伤">
|
||||
<div v-for="(value, label) in item.equipmentParts" :key="label">
|
||||
<span>{{ label }}:{{ value }}</span>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</ModuleWrapper>
|
||||
<a-modal
|
||||
v-model="mcModal.visible"
|
||||
title="编辑单元名称"
|
||||
:maskClosable="false"
|
||||
width="400px"
|
||||
:destroyOnClose="true"
|
||||
@ok="handleSubmilMc"
|
||||
>
|
||||
<a-row>
|
||||
<a-col :span="6">
|
||||
<span>名称</span>
|
||||
</a-col>
|
||||
<a-col :span="18">
|
||||
<a-input v-model="mcModal.mc" style="width: 100%" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
<a-modal
|
||||
v-model="lonlatModal.visible"
|
||||
title="修改单元经纬度"
|
||||
:maskClosable="false"
|
||||
width="600px"
|
||||
:destroyOnClose="true"
|
||||
@ok="handleSubmilLonlat"
|
||||
>
|
||||
<LonLatInput :lon.sync="lonlatModal.lon" :lat.sync="lonlatModal.lat" />
|
||||
</a-modal>
|
||||
<a-modal
|
||||
v-model="hdModal.visible"
|
||||
title="设置单元高度/深度"
|
||||
:maskClosable="false"
|
||||
width="400px"
|
||||
:destroyOnClose="true"
|
||||
@ok="handleSubmilHd"
|
||||
>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<span>高度/深度</span>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-input-number v-model="hdModal.hd" :min="0" style="width: 100%" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
<a-modal
|
||||
v-model="actionModal.visible"
|
||||
:title="actionModal.title"
|
||||
:maskClosable="false"
|
||||
:destroyOnClose="true"
|
||||
@ok="handleSubmilAction"
|
||||
>
|
||||
<a-form-model
|
||||
:model="actionModal.formData"
|
||||
layout="horizontal"
|
||||
:labelCol="{ span: 6 }"
|
||||
:wrapperCol="{ span: 15 }"
|
||||
>
|
||||
<a-form-model-item v-for="item in actionModal.formItems" :key="item.prop" v-bind="item">
|
||||
<component
|
||||
:is="item.component || 'a-input'"
|
||||
v-model="actionModal.formData[item.prop]"
|
||||
v-bind="item.options"
|
||||
/>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</a-modal>
|
||||
</Grid>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LonLatInput from './components/LonLatInput.vue'
|
||||
|
||||
export default {
|
||||
name: 'SimulationSceneSceneEditing',
|
||||
components: {
|
||||
LonLatInput,
|
||||
},
|
||||
filters: {
|
||||
logisticTypeFormat(v) {
|
||||
return {
|
||||
1: '信息对抗分队',
|
||||
2: '边防作战分队',
|
||||
3: '防化保障分队',
|
||||
4: '火力打击分队',
|
||||
5: '餐饮保障分队',
|
||||
6: '运输保障分队',
|
||||
7: '医疗分队',
|
||||
8: '工兵分队',
|
||||
}[v]
|
||||
},
|
||||
numberFormat(v) {
|
||||
if (typeof v === 'number' && v) {
|
||||
return +v.toFixed(2)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
},
|
||||
lonFormat(v) {
|
||||
const originValue = Number(v)
|
||||
if (originValue) {
|
||||
let result = ''
|
||||
result += originValue > 0 ? '东经 ' : '西经 '
|
||||
const num = Math.abs(originValue)
|
||||
const d = Math.floor(num)
|
||||
result += `${d}°`
|
||||
const m = Math.floor(num * 60) % 60
|
||||
result += `${m}′`
|
||||
const s = Math.floor(num * 3600) % 60
|
||||
result += `${s}″`
|
||||
return result
|
||||
} else {
|
||||
return '0°0′0″'
|
||||
}
|
||||
},
|
||||
latFormat(v) {
|
||||
const originValue = Number(v)
|
||||
if (originValue) {
|
||||
let result = ''
|
||||
result += originValue > 0 ? '北纬 ' : '南纬 '
|
||||
const num = Math.abs(originValue)
|
||||
const d = Math.floor(num)
|
||||
result += `${d}°`
|
||||
const m = Math.floor(num * 60) % 60
|
||||
result += `${m}′`
|
||||
const s = Math.floor(num * 3600) % 60
|
||||
result += `${s}″`
|
||||
return result
|
||||
} else {
|
||||
return '0°0′0″'
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
cesium: null,
|
||||
scenarioId: null,
|
||||
zb: { zbTreeData: [], selectedKeys: [] },
|
||||
ys: {
|
||||
keyword: '',
|
||||
ysList: [
|
||||
{
|
||||
id: '1',
|
||||
title: '红方',
|
||||
children: [
|
||||
{ id: '1-1', title: '反坦克导弹', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
{ id: '1-2', title: '红箭10反坦克导弹', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
{ id: '1-3', title: '装甲突击车', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
{ id: '1-4', title: 'VT5坦克', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
{ id: '1-5', title: '餐饮车', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
{ id: '1-6', title: '物资运输车', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
{ id: '1-7', title: '油罐车', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
{ id: '1-8', title: '雷达车', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: '蓝方',
|
||||
children: [
|
||||
{ id: '2-1', title: '反坦克导弹', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
{ id: '2-2', title: '红箭10反坦克导弹', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
{ id: '2-3', title: '装甲突击车', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
{ id: '2-4', title: 'VT5坦克', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
{ id: '2-5', title: '餐饮车', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
{ id: '2-6', title: '物资运输车', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
{ id: '2-7', title: '油罐车', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
{ id: '2-8', title: '雷达车', image: '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
right: {
|
||||
radioType: 'jcsx',
|
||||
detail: {
|
||||
position: {},
|
||||
personStatistic: {},
|
||||
foodInfo: {},
|
||||
waterInfo: {},
|
||||
oilInfo: {},
|
||||
medicalInfo: {},
|
||||
ammunition: {},
|
||||
actionList: [],
|
||||
// equipmentList: [],
|
||||
},
|
||||
checkedAction: null,
|
||||
},
|
||||
mcModal: {
|
||||
visible: false,
|
||||
mc: '',
|
||||
},
|
||||
lonlatModal: {
|
||||
visible: false,
|
||||
lon: 0,
|
||||
lat: 0,
|
||||
},
|
||||
hdModal: {
|
||||
visible: false,
|
||||
hd: 0,
|
||||
},
|
||||
actionModal: {
|
||||
visible: false,
|
||||
formItems: [
|
||||
{ label: '事件名称', prop: 'typeName' },
|
||||
{
|
||||
label: '事件类型',
|
||||
prop: 'typeType',
|
||||
component: 'AntOriginSelect',
|
||||
options: {
|
||||
dataSource: () => ({
|
||||
data: [
|
||||
{ id: '1', title: '阵地进攻' },
|
||||
{ id: '2', title: '机动进攻' },
|
||||
{ id: '3', title: '城镇进攻' },
|
||||
{ id: '4', title: '山地进攻' },
|
||||
{ id: '5', title: '阵地防御' },
|
||||
{ id: '6', title: '机动防御' },
|
||||
{ id: '7', title: '城镇防御' },
|
||||
{ id: '8', title: '山地防御' },
|
||||
],
|
||||
}),
|
||||
},
|
||||
},
|
||||
{ label: '开始时间', prop: 'beginDateTime', component: 'a-date-picker', options: { showTime: true } },
|
||||
{ label: '结束时间', prop: 'endDateTime', component: 'a-date-picker', options: { showTime: true } },
|
||||
{ label: '目标经度', prop: 'lon', component: 'a-input-number' },
|
||||
{ label: '目标纬度', prop: 'lat', component: 'a-input-number' },
|
||||
],
|
||||
formData: {},
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasDetail() {
|
||||
return Boolean(this.right.detail.id)
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$bus.$emit('set-instructor-system-title', '场景编辑子系统')
|
||||
},
|
||||
mounted() {
|
||||
this.cesium = new window.MyCesium('cesium-container')
|
||||
this.scenarioId = 2733
|
||||
this.getZbTree()
|
||||
},
|
||||
methods: {
|
||||
async getZbTree() {
|
||||
try {
|
||||
const res = await this.$http({
|
||||
url: `/scenario/power/${this.scenarioId}`,
|
||||
method: 'get',
|
||||
})
|
||||
this.zb.zbTreeData = [
|
||||
{
|
||||
id: '1',
|
||||
name: '红方',
|
||||
selectable: false,
|
||||
children: [
|
||||
{ id: '1-1', name: '作战力量', selectable: false, children: res.data.red.fight },
|
||||
{ id: '1-2', name: '保障力量', selectable: false, children: res.data.red.guarantee },
|
||||
{ id: '1-3', name: '指挥力量', selectable: false, children: res.data.red.command },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: '蓝方',
|
||||
selectable: false,
|
||||
children: [
|
||||
{ id: '2-1', name: '作战力量', selectable: false, children: res.data.blue.fight },
|
||||
{ id: '2-2', name: '保障力量', selectable: false, children: res.data.blue.guarantee },
|
||||
{ id: '2-3', name: '指挥力量', selectable: false, children: res.data.blue.command },
|
||||
],
|
||||
},
|
||||
]
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
|
||||
addModel() {
|
||||
this.cesium.addModel({
|
||||
scale: 3000,
|
||||
x: 600,
|
||||
y: 350,
|
||||
modelName: `xinxiduikang.glb`,
|
||||
label: `xinxiduikang\n其他`,
|
||||
radius: 150000,
|
||||
})
|
||||
this.cesium.addModel({
|
||||
scale: 3000,
|
||||
x: 600,
|
||||
y: 350,
|
||||
modelName: `F-16.ive`,
|
||||
label: `xinxiduikang\n其他`,
|
||||
radius: 150000,
|
||||
})
|
||||
},
|
||||
|
||||
handleSelectTree(selectedKeys, { node }) {
|
||||
this.right.detail = node.dataRef
|
||||
this.right.checkedAction = null
|
||||
},
|
||||
onSearch(e) {
|
||||
console.log('----', e, e.target.value)
|
||||
},
|
||||
|
||||
handleOpenMcModal() {
|
||||
this.mcModal.mc = this.right.detail.name
|
||||
this.mcModal.visible = true
|
||||
},
|
||||
async handleSubmilMc() {
|
||||
try {
|
||||
this.$http({
|
||||
url: `/scenario/power/modifyUnit/${this.scenarioId}`,
|
||||
method: 'post',
|
||||
data: {
|
||||
id: this.right.detail.id,
|
||||
name: this.mcModal.mc,
|
||||
},
|
||||
})
|
||||
this.$message.success('编辑单元名称成功')
|
||||
this.right.detail.name = this.mcModal.mc
|
||||
this.mcModal.visible = false
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
|
||||
handleOpenLonlatModal() {
|
||||
this.lonlatModal.lon = Number(this.right.detail.position.lng) || 0
|
||||
this.lonlatModal.lat = Number(this.right.detail.position.lat) || 0
|
||||
this.lonlatModal.visible = true
|
||||
},
|
||||
async handleSubmilLonlat() {
|
||||
try {
|
||||
this.$http({
|
||||
url: `/scenario/power/modifyUnit/${this.scenarioId}`,
|
||||
method: 'post',
|
||||
data: {
|
||||
id: this.right.detail.id,
|
||||
position: {
|
||||
lng: this.lonlatModal.lon,
|
||||
lat: this.lonlatModal.lat,
|
||||
},
|
||||
},
|
||||
})
|
||||
this.$message.success('修改单元经纬度成功')
|
||||
this.right.detail.position.lng = '' + this.lonlatModal.lon
|
||||
this.right.detail.position.lat = '' + this.lonlatModal.lat
|
||||
this.lonlatModal.visible = false
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
|
||||
handleOpenHdModal() {
|
||||
this.hdModal.hd = Number(this.right.detail.position.height) || 0
|
||||
this.hdModal.visible = true
|
||||
},
|
||||
async handleSubmilHd() {
|
||||
try {
|
||||
this.$http({
|
||||
url: `/scenario/power/modifyUnit/${this.scenarioId}`,
|
||||
method: 'post',
|
||||
data: {
|
||||
id: this.right.detail.id,
|
||||
position: {
|
||||
height: this.hdModal.hd,
|
||||
},
|
||||
},
|
||||
})
|
||||
this.$message.success('修改单元高度/深度成功')
|
||||
this.right.detail.position.height = this.hdModal.hd
|
||||
this.hdModal.visible = false
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
|
||||
handleOpenAddActionModal() {
|
||||
this.actionModal.title = '添加事件信息'
|
||||
this.actionModal.formData = {}
|
||||
this.actionModal.visible = true
|
||||
},
|
||||
handleOpenEditActionModal() {
|
||||
this.actionModal.title = '修改事件信息'
|
||||
this.actionModal.formData = { ...this.right.checkedAction }
|
||||
this.actionModal.visible = true
|
||||
},
|
||||
async handleSubmilAction() {
|
||||
try {
|
||||
await this.$http({
|
||||
url: '/save',
|
||||
method: 'post',
|
||||
data: this.actionModal.formData,
|
||||
})
|
||||
this.$message.success(`${this.actionModal.title}成功`)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
async handleDeleteAction() {
|
||||
try {
|
||||
await this.$confirm('确认删除所选事件吗?')
|
||||
await this.$http({
|
||||
url: '/delete',
|
||||
method: 'delete',
|
||||
params: { id: this.right.checkedAction.id },
|
||||
})
|
||||
this.$message.success(`删除事件成功`)
|
||||
} catch (error) {
|
||||
this.$message.success(`删除事件失败`)
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.scene-editing-page {
|
||||
padding-top: 20px;
|
||||
}
|
||||
.simulation-tree::v-deep {
|
||||
color: #a1c2d0;
|
||||
li .ant-tree-node-content-wrapper {
|
||||
color: #a1c2d0;
|
||||
}
|
||||
li .ant-tree-node-content-wrapper.ant-tree-node-selected {
|
||||
background-color: #bae7ff44;
|
||||
}
|
||||
li .ant-tree-node-content-wrapper:hover {
|
||||
background-color: #bae7ff22;
|
||||
}
|
||||
}
|
||||
.ys-image {
|
||||
width: 74px;
|
||||
height: 62px;
|
||||
object-fit: cover;
|
||||
margin: 16px 0 8px;
|
||||
}
|
||||
.simulation-collapse::v-deep {
|
||||
background-color: transparent;
|
||||
color: #bbdded;
|
||||
font-size: 16px;
|
||||
line-height: 30px;
|
||||
border: none;
|
||||
}
|
||||
.simulation-collapse-item::v-deep {
|
||||
.ant-collapse-content {
|
||||
background-color: transparent;
|
||||
color: #bbdded;
|
||||
border-top-color: #00baff66;
|
||||
> .ant-collapse-content-box {
|
||||
padding: 15px 0 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.simulation-collapse > .simulation-collapse-item::v-deep {
|
||||
border: none;
|
||||
> .ant-collapse-header {
|
||||
padding: 0;
|
||||
color: #00baff;
|
||||
font-size: 16px;
|
||||
line-height: 38px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-between;
|
||||
.ant-collapse-arrow {
|
||||
position: initial;
|
||||
font-size: 16px;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
.image {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
background-color: #0c3040;
|
||||
}
|
||||
.name {
|
||||
color: #00baff;
|
||||
text-decoration: underline;
|
||||
font-size: 16px;
|
||||
}
|
||||
.simulation-select::v-deep {
|
||||
.ant-select-selection {
|
||||
background-color: #10475f;
|
||||
border: solid 1px #1d5777;
|
||||
color: #bbdded;
|
||||
}
|
||||
.ant-select-arrow {
|
||||
color: #bbdded;
|
||||
}
|
||||
}
|
||||
.zzxd-wrapper {
|
||||
height: 100%;
|
||||
.zzxd-header {
|
||||
padding: 5px 0;
|
||||
border-bottom: 1px solid #00baff22;
|
||||
.zzxd-title {
|
||||
color: #00baff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.action-item {
|
||||
cursor: pointer;
|
||||
padding: 5px 0;
|
||||
.action-icon {
|
||||
padding: 5px 16px;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
.action-line {
|
||||
position: absolute;
|
||||
right: 50%;
|
||||
top: 21px;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
background-color: #00baff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.action-item:last-of-type {
|
||||
.action-line {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.action-item:hover {
|
||||
background-color: #bae7ff44;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
.simulation-select-dropdown {
|
||||
background-color: #10475f;
|
||||
border: solid 1px #1d5777;
|
||||
.ant-select-dropdown-menu-item {
|
||||
color: #bbdded;
|
||||
}
|
||||
.ant-select-dropdown-menu-item-selected {
|
||||
background-color: #bbdded33;
|
||||
color: #ffffff;
|
||||
font-weight: normal;
|
||||
}
|
||||
.ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled) {
|
||||
background-color: #bbdded33;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,246 @@
|
|||
<template>
|
||||
<Grid class="simulation-model-page" :columns="['320px', 1, '320px']" :rows="[45, 15, 40]" gap="0px">
|
||||
<ModuleWrapper title="作战/保障力量" style="grid-column: 1 / 2; grid-row: 1 / 2">
|
||||
<div class="normal" style="padding: 5px; overflow-y: auto">
|
||||
<a-tree
|
||||
class="simulation-tree"
|
||||
:treeData="zb.zbTreeData"
|
||||
:selectedKeys.sync="zb.selectedKeys"
|
||||
:replaceFields="{ children: 'children', title: 'name', key: 'id' }"
|
||||
@select="handleSelectTree"
|
||||
>
|
||||
</a-tree>
|
||||
</div>
|
||||
</ModuleWrapper>
|
||||
<ModuleWrapper style="grid-column: 1 / 2; grid-row: 2 / 4">
|
||||
<template #title>
|
||||
<a-radio-group v-model="qd.qdlx" button-style="solid">
|
||||
<a-radio-button value="xqqd">需求清单</a-radio-button>
|
||||
<a-radio-button value="bzqd">保障清单</a-radio-button>
|
||||
</a-radio-group>
|
||||
</template>
|
||||
<div class="normal" style="padding: 5px">
|
||||
<a-table
|
||||
class="simulation-table-plain"
|
||||
rowKey="id"
|
||||
:columns="qd.qdColumns"
|
||||
:dataSource="qd.qdList"
|
||||
:pagination="false"
|
||||
:bordered="true"
|
||||
></a-table>
|
||||
</div>
|
||||
</ModuleWrapper>
|
||||
<div
|
||||
class="cesium-container"
|
||||
id="cesium-container"
|
||||
style="grid-column: 2 / 3; grid-row: 1 / 4; overflow: hidden"
|
||||
></div>
|
||||
<ModuleWrapper title="保障实体属性" style="grid-column: 3 / 4; grid-row: 1 / 3">
|
||||
<div class="normal" style="padding: 15px 0">
|
||||
<div style="height: 100%; padding: 0 15px; overflow-y: auto">
|
||||
<img class="image" :src="sx.image" />
|
||||
<div class="name">{{ sx.name }}</div>
|
||||
<div v-for="item in sx.sxList" :key="item.label" class="sx-item">
|
||||
<span>{{ item.label }}:</span>
|
||||
<img :src="item.icon" alt="" />
|
||||
<span>{{ item.text }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ModuleWrapper>
|
||||
<ModuleWrapper title="资源" style="grid-column: 3 / 4; grid-row: 3 / 4">
|
||||
<div class="normal" style="padding: 15px 0">
|
||||
<div style="height: 100%; padding: 0 15px; overflow-y: auto">
|
||||
<div v-for="item in zy.zyList" :key="item.label" class="zy-item flex">
|
||||
<span>{{ item.label }}:</span>
|
||||
<span style="flex: 1; white-space: nowrap; overflow: hidden" v-html="zy.placeholder"></span>
|
||||
<span>{{ item.text }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ModuleWrapper>
|
||||
</Grid>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SimulationSceneSimulationModel',
|
||||
data() {
|
||||
return {
|
||||
cesium: null,
|
||||
zb: {
|
||||
zbTreeData: [
|
||||
{
|
||||
id: '1',
|
||||
name: '红方',
|
||||
children: [
|
||||
{
|
||||
id: '1-1',
|
||||
name: '作战力量',
|
||||
children: [
|
||||
{ id: '1-1-1', name: '左翼夺控群火力分队' },
|
||||
{ id: '1-1-2', name: '左翼攻击分队' },
|
||||
{ id: '1-1-3', name: '右翼攻击分队' },
|
||||
{ id: '1-1-4', name: '右翼夺控群反装甲分队' },
|
||||
{ id: '1-1-5', name: '防空火力队' },
|
||||
{ id: '1-1-6', name: '左翼牵制群右翼攻击分队' },
|
||||
{ id: '1-1-7', name: '电子对抗兵队超短波干扰分队' },
|
||||
{ id: '1-1-8', name: '纵深夺控群火力分队' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '1-2',
|
||||
name: '保障力量',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: '蓝方',
|
||||
children: [
|
||||
{ id: '1-1', name: '作战力量' },
|
||||
{ id: '1-2', name: '保障力量' },
|
||||
],
|
||||
},
|
||||
],
|
||||
selectedKeys: [],
|
||||
},
|
||||
qd: {
|
||||
qdlx: 'xqqd',
|
||||
qdColumns: [
|
||||
{
|
||||
dataIndex: 'dj',
|
||||
title: '等级',
|
||||
width: '62px',
|
||||
align: 'center',
|
||||
customRender: (text) => ['', '紧急', '加急', '一般'][text],
|
||||
customCell: (record) => ({ style: { color: ['', '#ff3838', '#feba29', '#ffffff'][record.dj] } }),
|
||||
},
|
||||
{ dataIndex: 'bzxq', title: '保障需求' },
|
||||
],
|
||||
qdList: [
|
||||
{ id: '1', dj: '1', bzxq: '500枚防空导弹、6辆装甲车' },
|
||||
{ id: '2', dj: '2', bzxq: '5吨汽油、100套军装' },
|
||||
{ id: '3', dj: '3', bzxq: '15箱消炎药、6箱葡萄糖滴' },
|
||||
{ id: '4', dj: '3', bzxq: '一吨饮用水' },
|
||||
{ id: '5', dj: '3', bzxq: '1吨燃油、厨房抽烟机设备一' },
|
||||
],
|
||||
},
|
||||
sx: {
|
||||
image: '/mockData/cb8917d8-6658-cf7f-dd4e-ea2e670edea8.png',
|
||||
name: '医院',
|
||||
sxList: [
|
||||
{ label: '推演方', text: `红方` },
|
||||
{ label: '经度', text: `东经120°12'03″` },
|
||||
{ label: '纬度', text: `北纬24°51'09″` },
|
||||
{ label: '高度/深度', text: `326米` },
|
||||
{ label: '图标', icon: '/mockData/9d47c8c8-30d8-3e78-944f-d48ca8084c58.png' },
|
||||
{ label: '医师', text: `36人` },
|
||||
{ label: '护士', text: `100人` },
|
||||
],
|
||||
},
|
||||
zy: {
|
||||
placeholder: ' '.repeat(100),
|
||||
zyList: [
|
||||
{ label: '血液', text: `100L` },
|
||||
{ label: '药材', text: `1.5吨` },
|
||||
{ label: '氧气', text: `100m3` },
|
||||
{ label: '床位', text: `56个` },
|
||||
{ label: '手术台', text: `10台` },
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$emit('set-instructor-system-title', '仿真模型子系统')
|
||||
},
|
||||
mounted() {
|
||||
this.cesium = new window.MyCesium('cesium-container')
|
||||
},
|
||||
methods: {
|
||||
handleSelectTree() {},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.simulation-model-page {
|
||||
padding-top: 20px;
|
||||
}
|
||||
.simulation-tree::v-deep {
|
||||
color: #a1c2d0;
|
||||
li .ant-tree-node-content-wrapper {
|
||||
color: #a1c2d0;
|
||||
}
|
||||
li .ant-tree-node-content-wrapper.ant-tree-node-selected {
|
||||
background-color: #bae7ff44;
|
||||
}
|
||||
li .ant-tree-node-content-wrapper:hover {
|
||||
background-color: #bae7ff22;
|
||||
}
|
||||
}
|
||||
.simulation-table-plain::v-deep {
|
||||
.ant-table {
|
||||
color: #a1c2d0;
|
||||
}
|
||||
.ant-table-body > table {
|
||||
border: none;
|
||||
}
|
||||
.ant-table-thead > tr > th {
|
||||
background-color: #083a52;
|
||||
color: #ffffff;
|
||||
border-bottom-color: #05628e;
|
||||
border-top: 1px solid #05628e;
|
||||
&:last-child {
|
||||
border-right-color: #05628e;
|
||||
}
|
||||
&:not(:last-child) {
|
||||
border-right-color: #05628e3b;
|
||||
}
|
||||
&:first-child {
|
||||
border-left: 1px solid #05628e;
|
||||
}
|
||||
&:not(:first-child) {
|
||||
}
|
||||
}
|
||||
.ant-table-tbody > tr > td {
|
||||
border-bottom-color: #064766;
|
||||
&:last-child {
|
||||
border-right-color: #064766;
|
||||
}
|
||||
&:not(:last-child) {
|
||||
border-right-color: #05628e3b;
|
||||
}
|
||||
&:first-child {
|
||||
border-left: 1px solid #064766;
|
||||
}
|
||||
&:not(:first-child) {
|
||||
}
|
||||
}
|
||||
}
|
||||
.image {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
background-color: #0c3040;
|
||||
}
|
||||
.name {
|
||||
color: #00baff;
|
||||
text-decoration: underline;
|
||||
font-size: 16px;
|
||||
line-height: 26px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.sx-item {
|
||||
font-size: 16px;
|
||||
line-height: 30px;
|
||||
letter-spacing: 2px;
|
||||
color: #bbdded;
|
||||
}
|
||||
.zy-item {
|
||||
text-decoration: underline;
|
||||
font-size: 16px;
|
||||
line-height: 26px;
|
||||
letter-spacing: 0px;
|
||||
color: #00baff;
|
||||
}
|
||||
</style>
|
446
src/views/simulationScene/sceneEditing/components/Jcsx.vue
Normal file
446
src/views/simulationScene/sceneEditing/components/Jcsx.vue
Normal file
|
@ -0,0 +1,446 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-collapse class="simulation-collapse" :defaultActiveKey="['1', '2', '3', '4', '5', '6', '7', '8', '9']">
|
||||
<a-collapse-panel class="simulation-collapse-item" key="1" header="基础信息">
|
||||
<img class="image" :src="modelData.image || '/mockData/fe6ad2d8-da11-04d8-f447-0d8175826e28.png'" />
|
||||
<div class="name">
|
||||
{{ modelData.team.teamName }}
|
||||
<a-button v-if="hasDetail" type="text-primary" icon="edit" @click="handleOpenMcModal"></a-button>
|
||||
</div>
|
||||
<a-modal
|
||||
v-model="mcModal.visible"
|
||||
title="编辑单元名称"
|
||||
:maskClosable="false"
|
||||
width="400px"
|
||||
:destroyOnClose="true"
|
||||
@ok="handleSubmilMc"
|
||||
>
|
||||
<a-row>
|
||||
<a-col :span="6">
|
||||
<span>名称</span>
|
||||
</a-col>
|
||||
<a-col :span="18">
|
||||
<a-input v-model="mcModal.mc" style="width: 100%" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">推演方:</span>
|
||||
<span>{{ modelData.team.type | forceFormat }}</span>
|
||||
</div>
|
||||
<!-- <div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">类型:</span>
|
||||
<span>{{ modelData.position.logisticType | logisticTypeFormat }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">方向:</span>
|
||||
<span>{{ modelData.position.direction | numberFormat }}°</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">速度:</span>
|
||||
<span>{{ modelData.position.speed }} 公里/时</span>
|
||||
</div> -->
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">经度:</span>
|
||||
<span class="flex-1">{{ modelData.team.lng | lonFormat }}</span>
|
||||
<a-button v-if="hasDetail" type="text-primary" icon="edit" @click="handleOpenLonlatModal"></a-button>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">纬度:</span>
|
||||
<span class="flex-1">{{ modelData.team.lat | latFormat }}</span>
|
||||
<a-button v-if="hasDetail" type="text-primary" icon="edit" @click="handleOpenLonlatModal"></a-button>
|
||||
</div>
|
||||
<a-modal
|
||||
v-model="lonlatModal.visible"
|
||||
title="修改单元经纬度"
|
||||
:maskClosable="false"
|
||||
width="600px"
|
||||
:destroyOnClose="true"
|
||||
@ok="handleSubmilLonlat"
|
||||
>
|
||||
<LonLatInput :lon.sync="lonlatModal.lon" :lat.sync="lonlatModal.lat" />
|
||||
</a-modal>
|
||||
<!-- <div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">高度/深度:</span>
|
||||
<span class="flex-1">{{ modelData.position.height | numberFormat }} 米(海拔)</span>
|
||||
<a-button v-if="hasDetail" type="text-primary" icon="edit" @click="handleOpenHdModal()"></a-button>
|
||||
</div>
|
||||
<a-modal
|
||||
v-model="hdModal.visible"
|
||||
title="设置单元高度/深度"
|
||||
:maskClosable="false"
|
||||
width="400px"
|
||||
:destroyOnClose="true"
|
||||
@ok="handleSubmilHd"
|
||||
>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<span>高度/深度</span>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-input-number v-model="hdModal.hd" :min="0" style="width: 100%" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-modal> -->
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="2" header="人员状态属性">
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">人员编制数:</span>
|
||||
<span>{{ modelData.person.total }} 人</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">当前人数:</span>
|
||||
<span>{{ modelData.person.current }} 人</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">死亡人数:</span>
|
||||
<span>{{ modelData.person.death }} 人</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">受伤人数:</span>
|
||||
<span>{{ modelData.person.injured }} 人</span>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="3" header="野战食品状态属性">
|
||||
<!-- <div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">野战食物初始量(份):</span>
|
||||
<span>{{ modelData.foodInfo.startNum }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">野战食物当前量(份):</span>
|
||||
<span>{{ modelData.foodInfo.currentNum }}</span>
|
||||
</div> -->
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="4" header="用水状态属性">
|
||||
<!-- <div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">用水初始量(吨):</span>
|
||||
<span>{{ modelData.waterInfo.startNum }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">用水当前量(吨):</span>
|
||||
<span>{{ modelData.waterInfo.currentNum }}</span>
|
||||
<span></span>
|
||||
</div> -->
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="5" header="油料状态属性">
|
||||
<!-- <div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">油料初始量(份):</span>
|
||||
<span>{{ modelData.oilInfo.startNum }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">油料当前量(份):</span>
|
||||
<span>{{ modelData.oilInfo.currentNum }}</span>
|
||||
</div> -->
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="6" header="药材状态属性">
|
||||
<!-- <div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">药材初始量(份):</span>
|
||||
<span>{{ modelData.medicalInfo.startNum }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">药材当前量(份):</span>
|
||||
<span>{{ modelData.medicalInfo.currentNum }}</span>
|
||||
</div> -->
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="7" header="武器弹药状态属性">
|
||||
<!-- <div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">轻武器弹药量(吨):</span>
|
||||
<span>{{ modelData.ammunition.lightArms }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">压制武器弹药量(吨):</span>
|
||||
<span>{{ modelData.ammunition.suppressing }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">反坦克武器弹药量(吨):</span>
|
||||
<span>{{ modelData.ammunition.antiTank }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">防空反导武器弹药量(吨):</span>
|
||||
<span>{{ modelData.ammunition.antiAircraft }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">布扫雷装备弹药量(吨):</span>
|
||||
<span>{{ modelData.ammunition.mineLaying }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">爆破器材弹药量(吨):</span>
|
||||
<span>{{ modelData.ammunition.explosiveDevice }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">烟火装备弹药量(吨):</span>
|
||||
<span>{{ modelData.ammunition.smokeDevice }}</span>
|
||||
</div>
|
||||
<div class="zt-item flex ai-c">
|
||||
<span style="min-width: 100px">防化消耗弹药量(吨):</span>
|
||||
<span>{{ modelData.ammunition.antiChemical }}</span>
|
||||
</div> -->
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel class="simulation-collapse-item" key="8" header="保障标准信息">
|
||||
<!-- <div class="zt-item flex ai-c jc-sb">
|
||||
<span style="min-width: 100px">保障分配类型:</span>
|
||||
<a-select
|
||||
style="width: 120px"
|
||||
class="simulation-select"
|
||||
defaultValue="1"
|
||||
dropdownClassName="simulation-select-dropdown"
|
||||
>
|
||||
<a-select-option value="1">自动分配</a-select-option>
|
||||
<a-select-option value="2">手动分配</a-select-option>
|
||||
</a-select>
|
||||
</div> -->
|
||||
</a-collapse-panel>
|
||||
<!-- <a-collapse-panel class="simulation-collapse-item" key="9" header="保障配置">
|
||||
<div class="zt-item flex ai-c jc-sb">
|
||||
<a-button type="primary">兵力编组</a-button>
|
||||
<a-button type="primary">关注</a-button>
|
||||
</div>
|
||||
</a-collapse-panel> -->
|
||||
</a-collapse>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LonLatInput from './LonLatInput.vue'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
scenarioId: { type: String, required: true },
|
||||
modelData: { type: Object, default: () => ({}) },
|
||||
},
|
||||
components: {
|
||||
LonLatInput,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
cesium: null,
|
||||
mcModal: {
|
||||
visible: false,
|
||||
mc: '',
|
||||
},
|
||||
lonlatModal: {
|
||||
visible: false,
|
||||
lon: 0,
|
||||
lat: 0,
|
||||
},
|
||||
hdModal: {
|
||||
visible: false,
|
||||
hd: 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasDetail() {
|
||||
return Boolean(this.modelData.id)
|
||||
},
|
||||
},
|
||||
filters: {
|
||||
logisticTypeFormat(v) {
|
||||
return {
|
||||
1: '信息对抗分队',
|
||||
2: '边防作战分队',
|
||||
3: '防化保障分队',
|
||||
4: '火力打击分队',
|
||||
5: '餐饮保障分队',
|
||||
6: '运输保障分队',
|
||||
7: '医疗分队',
|
||||
8: '工兵分队',
|
||||
}[v]
|
||||
},
|
||||
forceFormat(v) {
|
||||
return ['红方', '蓝方'][v]
|
||||
},
|
||||
numberFormat(v) {
|
||||
if (typeof v === 'number' && v) {
|
||||
return +v.toFixed(2)
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
},
|
||||
lonFormat(v) {
|
||||
const originValue = Number(v)
|
||||
if (originValue) {
|
||||
let result = ''
|
||||
result += originValue > 0 ? '东经 ' : '西经 '
|
||||
const num = Math.abs(originValue)
|
||||
const d = Math.floor(num)
|
||||
result += `${d}°`
|
||||
const m = Math.floor(num * 60) % 60
|
||||
result += `${m}′`
|
||||
const s = Math.floor(num * 3600) % 60
|
||||
result += `${s}″`
|
||||
return result
|
||||
} else {
|
||||
return '0°0′0″'
|
||||
}
|
||||
},
|
||||
latFormat(v) {
|
||||
const originValue = Number(v)
|
||||
if (originValue) {
|
||||
let result = ''
|
||||
result += originValue > 0 ? '北纬 ' : '南纬 '
|
||||
const num = Math.abs(originValue)
|
||||
const d = Math.floor(num)
|
||||
result += `${d}°`
|
||||
const m = Math.floor(num * 60) % 60
|
||||
result += `${m}′`
|
||||
const s = Math.floor(num * 3600) % 60
|
||||
result += `${s}″`
|
||||
return result
|
||||
} else {
|
||||
return '0°0′0″'
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleOpenMcModal() {
|
||||
this.mcModal.mc = this.modelData.team.teamName
|
||||
this.mcModal.visible = true
|
||||
},
|
||||
async handleSubmilMc() {
|
||||
try {
|
||||
this.$http({
|
||||
url: `/scenario/power/modifyUnit/${this.scenarioId}`,
|
||||
method: 'post',
|
||||
data: {
|
||||
id: this.modelData.id,
|
||||
name: this.mcModal.mc,
|
||||
},
|
||||
})
|
||||
this.$message.success('编辑单元名称成功')
|
||||
this.modelData.team.teamName = this.mcModal.mc
|
||||
this.mcModal.visible = false
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
|
||||
handleOpenLonlatModal() {
|
||||
this.lonlatModal.lon = Number(this.modelData.position.lng) || 0
|
||||
this.lonlatModal.lat = Number(this.modelData.position.lat) || 0
|
||||
this.lonlatModal.visible = true
|
||||
},
|
||||
async handleSubmilLonlat() {
|
||||
try {
|
||||
this.$http({
|
||||
url: `/scenario/power/modifyUnit/${this.scenarioId}`,
|
||||
method: 'post',
|
||||
data: {
|
||||
id: this.modelData.id,
|
||||
position: {
|
||||
lng: this.lonlatModal.lon,
|
||||
lat: this.lonlatModal.lat,
|
||||
},
|
||||
},
|
||||
})
|
||||
this.$message.success('修改单元经纬度成功')
|
||||
this.modelData.position.lng = '' + this.lonlatModal.lon
|
||||
this.modelData.position.lat = '' + this.lonlatModal.lat
|
||||
this.lonlatModal.visible = false
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
|
||||
handleOpenHdModal() {
|
||||
this.hdModal.hd = Number(this.modelData.position.height) || 0
|
||||
this.hdModal.visible = true
|
||||
},
|
||||
async handleSubmilHd() {
|
||||
try {
|
||||
this.$http({
|
||||
url: `/scenario/power/modifyUnit/${this.scenarioId}`,
|
||||
method: 'post',
|
||||
data: {
|
||||
id: this.modelData.id,
|
||||
position: {
|
||||
height: this.hdModal.hd,
|
||||
},
|
||||
},
|
||||
})
|
||||
this.$message.success('修改单元高度/深度成功')
|
||||
this.modelData.position.height = this.hdModal.hd
|
||||
this.hdModal.visible = false
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.simulation-collapse::v-deep {
|
||||
background-color: transparent;
|
||||
color: #bbdded;
|
||||
font-size: 16px;
|
||||
line-height: 30px;
|
||||
border: none;
|
||||
}
|
||||
.simulation-collapse-item::v-deep {
|
||||
.ant-collapse-content {
|
||||
background-color: transparent;
|
||||
color: #bbdded;
|
||||
border-top-color: #00baff66;
|
||||
> .ant-collapse-content-box {
|
||||
padding: 15px 0 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.simulation-collapse > .simulation-collapse-item::v-deep {
|
||||
border: none;
|
||||
> .ant-collapse-header {
|
||||
padding: 0;
|
||||
color: #00baff;
|
||||
font-size: 16px;
|
||||
line-height: 38px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-between;
|
||||
.ant-collapse-arrow {
|
||||
position: initial;
|
||||
font-size: 16px;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
.image {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
background-color: #0c3040;
|
||||
}
|
||||
.name {
|
||||
color: #00baff;
|
||||
text-decoration: underline;
|
||||
font-size: 16px;
|
||||
}
|
||||
.simulation-select::v-deep {
|
||||
.ant-select-selection {
|
||||
background-color: #10475f;
|
||||
border: solid 1px #1d5777;
|
||||
color: #bbdded;
|
||||
}
|
||||
.ant-select-arrow {
|
||||
color: #bbdded;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="less">
|
||||
.simulation-select-dropdown {
|
||||
background-color: #10475f;
|
||||
border: solid 1px #1d5777;
|
||||
.ant-select-dropdown-menu-item {
|
||||
color: #bbdded;
|
||||
}
|
||||
.ant-select-dropdown-menu-item-selected {
|
||||
background-color: #bbdded33;
|
||||
color: #ffffff;
|
||||
font-weight: normal;
|
||||
}
|
||||
.ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled) {
|
||||
background-color: #bbdded33;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -141,10 +141,10 @@
|
|||
</Grid>
|
||||
</a-modal>
|
||||
</template>
|
||||
<div class="normal">
|
||||
<div class="normal" style="padding: 5px; overflow-y: auto">
|
||||
<a-tree
|
||||
class="simulation-tree"
|
||||
:treeData="blbz.treeData"
|
||||
:treeData="showBlbzCheckedTreeData"
|
||||
:selectable="false"
|
||||
:replaceFields="{ children: 'children', title: 'title', key: 'id' }"
|
||||
>
|
||||
|
@ -153,13 +153,16 @@
|
|||
</ModuleWrapper>
|
||||
<ModuleWrapper height="70%">
|
||||
<template #title>
|
||||
<a-radio-group v-model="modelInfo.type" button-style="solid">
|
||||
<a-radio-group v-model="modelInfoType" button-style="solid">
|
||||
<a-radio-button value="jcsx">基础属性</a-radio-button>
|
||||
<a-radio-button value="zzxd">作战行动</a-radio-button>
|
||||
</a-radio-group>
|
||||
</template>
|
||||
<div class="normal" style="padding: 15px 0">
|
||||
<div style="height: 100%; padding: 0 15px; overflow-y: auto"></div>
|
||||
<div style="height: 100%; padding: 0 15px; overflow-y: auto">
|
||||
<Jcsx v-if="modelInfoType === 'jcsx'" :scenarioId="scenarioId" :modelData="jcsx.data" />
|
||||
<Zzxd v-if="modelInfoType === 'zzxd'" :actionList="zzxd.data" />
|
||||
</div>
|
||||
</div>
|
||||
</ModuleWrapper>
|
||||
</div>
|
||||
|
@ -168,11 +171,17 @@
|
|||
|
||||
<script>
|
||||
import { getAction, postAction } from '@/api/manage'
|
||||
import Jcsx from './Jcsx.vue'
|
||||
import Zzxd from './Zzxd.vue'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
scenarioId: { validator: () => true, required: true },
|
||||
},
|
||||
components: {
|
||||
Jcsx,
|
||||
Zzxd,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
scenarioDetail: {},
|
||||
|
@ -214,6 +223,7 @@ export default {
|
|||
blbz: {
|
||||
modelData: null,
|
||||
treeData: [],
|
||||
checkedKeys: [],
|
||||
},
|
||||
blbzModal: {
|
||||
visible: false,
|
||||
|
@ -259,12 +269,35 @@ export default {
|
|||
showTool: false,
|
||||
},
|
||||
},
|
||||
modelInfo: {
|
||||
type: 'jcsx',
|
||||
data: {},
|
||||
modelInfoType: 'jcsx',
|
||||
jcsx: {
|
||||
data: {
|
||||
team: {},
|
||||
person: {},
|
||||
},
|
||||
},
|
||||
zzxd: {
|
||||
data: [
|
||||
{
|
||||
id: '1',
|
||||
typeName: '机动',
|
||||
typeType: '1',
|
||||
beginDateTime: '2000-01-01 00:00:00',
|
||||
endDateTime: '2000-01-01 00:00:00',
|
||||
lon: '120',
|
||||
lat: '20',
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showBlbzCheckedTreeData() {
|
||||
const target = []
|
||||
this.getTree(target, this.blbz.treeData, this.blbz.checkedKeys)
|
||||
return target
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.cesium = new window.MyCesium('cesium-container')
|
||||
this.getScenarioDetail()
|
||||
|
@ -272,6 +305,17 @@ export default {
|
|||
this.getZbysListData()
|
||||
},
|
||||
methods: {
|
||||
getTree(target, treeData, checkedKeys) {
|
||||
treeData.forEach((item) => {
|
||||
const newChildren = []
|
||||
if (item.children && item.children.length > 0) {
|
||||
this.getTree(newChildren, item.children, checkedKeys)
|
||||
}
|
||||
if (newChildren.length > 0 || checkedKeys.includes(item.key)) {
|
||||
target.push({ ...item, children: newChildren })
|
||||
}
|
||||
})
|
||||
},
|
||||
async getScenarioDetail() {
|
||||
try {
|
||||
const res = await getAction(`/baseData/scenario/${this.scenarioId}`)
|
||||
|
@ -401,12 +445,19 @@ export default {
|
|||
this.cesium.setClientByCenter({ longitude: +node.dataRef.lng, latitude: +node.dataRef.lat })
|
||||
this.blbz.modelData = node.dataRef
|
||||
this.getBlbzTreeData()
|
||||
this.getJcsxData()
|
||||
},
|
||||
async getBlbzTreeData() {
|
||||
try {
|
||||
const res = await getAction('/tree/organization')
|
||||
this.blbz.treeData = res.data
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
try {
|
||||
const { type, id: resourceId, scenarioId } = this.blbz.modelData
|
||||
const res = await postAction('/scenarioOrgPost/getPost', { type, resourceId, scenarioId })
|
||||
this.blbz.treeData = res.data
|
||||
this.blbz.checkedKeys = res.data
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
|
@ -416,13 +467,9 @@ export default {
|
|||
this.$message.error('未选择分队!')
|
||||
return
|
||||
}
|
||||
try {
|
||||
const res = await getAction('/tree/organization')
|
||||
this.blbzModal.treeData = res.data
|
||||
this.blbzModal.visible = true
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
this.blbzModal.treeData = this.blbz.treeData
|
||||
this.blbzModal.checkedKeys = [...this.blbz.checkedKeys]
|
||||
this.blbzModal.visible = true
|
||||
},
|
||||
async handleSubmitBlbz() {
|
||||
try {
|
||||
|
@ -440,6 +487,15 @@ export default {
|
|||
console.log(error)
|
||||
}
|
||||
},
|
||||
async getJcsxData() {
|
||||
try {
|
||||
const { type, id: resourceId, scenarioId } = this.blbz.modelData
|
||||
const res = await getAction('/statistic/info', { type, resourceId, scenarioId })
|
||||
this.jcsx.data = res.data
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
167
src/views/simulationScene/sceneEditing/components/Zzxd.vue
Normal file
167
src/views/simulationScene/sceneEditing/components/Zzxd.vue
Normal file
|
@ -0,0 +1,167 @@
|
|||
<template>
|
||||
<Flex fd="co" class="zzxd-wrapper">
|
||||
<Flex class="zzxd-header" ai="c" jc="sb">
|
||||
<div class="zzxd-title">作战行动</div>
|
||||
<div>
|
||||
<a-button type="text-primary" icon="menu"></a-button>
|
||||
<a-button type="text-primary" icon="plus" @click="handleOpenAddActionModal"></a-button>
|
||||
<a-button type="text-primary" icon="edit" @click="handleOpenEditActionModal"></a-button>
|
||||
<a-button type="text-primary" icon="delete" @click="handleDeleteAction"></a-button>
|
||||
</div>
|
||||
<a-modal
|
||||
v-model="actionModal.visible"
|
||||
:title="actionModal.title"
|
||||
:maskClosable="false"
|
||||
:destroyOnClose="true"
|
||||
@ok="handleSubmilAction"
|
||||
>
|
||||
<a-form-model
|
||||
:model="actionModal.formData"
|
||||
layout="horizontal"
|
||||
:labelCol="{ span: 6 }"
|
||||
:wrapperCol="{ span: 15 }"
|
||||
>
|
||||
<a-form-model-item v-for="item in actionModal.formItems" :key="item.prop" v-bind="item">
|
||||
<component
|
||||
:is="item.component || 'a-input'"
|
||||
v-model="actionModal.formData[item.prop]"
|
||||
v-bind="item.options"
|
||||
/>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</a-modal>
|
||||
</Flex>
|
||||
<div class="flex-1 scroller-y">
|
||||
<div v-for="item in actionList" :key="item.id" class="action-item flex" @click="checkedAction = item">
|
||||
<div class="action-icon">
|
||||
<div class="action-line"></div>
|
||||
<a-radio :checked="checkedAction && checkedAction.id === item.id" style="margin-right: 0"></a-radio>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="action-title">{{ item.typeName || '- -' }}</div>
|
||||
<div class="action-time">开始时间:{{ item.beginDateTime }}</div>
|
||||
<div class="action-time">结束时间:{{ item.endDateTime }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Flex>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
actionList: { type: Array, default: () => [] },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
checkedAction: null,
|
||||
actionModal: {
|
||||
visible: false,
|
||||
formItems: [
|
||||
{ label: '事件名称', prop: 'typeName' },
|
||||
{
|
||||
label: '事件类型',
|
||||
prop: 'typeType',
|
||||
component: 'AntOriginSelect',
|
||||
options: {
|
||||
dataSource: () => ({
|
||||
data: [
|
||||
{ id: '1', title: '阵地进攻' },
|
||||
{ id: '2', title: '机动进攻' },
|
||||
{ id: '3', title: '城镇进攻' },
|
||||
{ id: '4', title: '山地进攻' },
|
||||
{ id: '5', title: '阵地防御' },
|
||||
{ id: '6', title: '机动防御' },
|
||||
{ id: '7', title: '城镇防御' },
|
||||
{ id: '8', title: '山地防御' },
|
||||
],
|
||||
}),
|
||||
},
|
||||
},
|
||||
{ label: '开始时间', prop: 'beginDateTime', component: 'a-date-picker', options: { showTime: true } },
|
||||
{ label: '结束时间', prop: 'endDateTime', component: 'a-date-picker', options: { showTime: true } },
|
||||
{ label: '目标经度', prop: 'lon', component: 'a-input-number' },
|
||||
{ label: '目标纬度', prop: 'lat', component: 'a-input-number' },
|
||||
],
|
||||
formData: {},
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleOpenAddActionModal() {
|
||||
this.actionModal.title = '添加事件信息'
|
||||
this.actionModal.formData = {}
|
||||
this.actionModal.visible = true
|
||||
},
|
||||
handleOpenEditActionModal() {
|
||||
this.actionModal.title = '修改事件信息'
|
||||
this.actionModal.formData = { ...this.checkedAction }
|
||||
this.actionModal.visible = true
|
||||
},
|
||||
async handleSubmilAction() {
|
||||
try {
|
||||
await this.$http({
|
||||
url: '/save',
|
||||
method: 'post',
|
||||
data: this.actionModal.formData,
|
||||
})
|
||||
this.$message.success(`${this.actionModal.title}成功`)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
async handleDeleteAction() {
|
||||
try {
|
||||
await this.$confirm('确认删除所选事件吗?')
|
||||
await this.$http({
|
||||
url: '/delete',
|
||||
method: 'delete',
|
||||
params: { id: this.checkedAction.id },
|
||||
})
|
||||
this.$message.success(`删除事件成功`)
|
||||
} catch (error) {
|
||||
this.$message.success(`删除事件失败`)
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.zzxd-wrapper {
|
||||
height: 100%;
|
||||
.zzxd-header {
|
||||
padding: 5px 0;
|
||||
border-bottom: 1px solid #00baff22;
|
||||
.zzxd-title {
|
||||
color: #00baff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.action-item {
|
||||
cursor: pointer;
|
||||
padding: 5px 0;
|
||||
.action-icon {
|
||||
padding: 5px 16px;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
.action-line {
|
||||
position: absolute;
|
||||
right: 50%;
|
||||
top: 21px;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
background-color: #00baff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.action-item:last-of-type {
|
||||
.action-line {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.action-item:hover {
|
||||
background-color: #bae7ff44;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user