486 lines
12 KiB
Vue
486 lines
12 KiB
Vue
<template>
|
|
<Grid class="central-control-page" :columns="[1, 1]" :rows="['331px', 1]">
|
|
<ModuleWrapper title="系统模块" style="grid-column: 1 / 3">
|
|
<Grid class="normal" :columns="[1, 1, 1, 1, 1]">
|
|
<div
|
|
v-for="block in systemModules"
|
|
:key="block.moduleCode"
|
|
:class="['system-block', 'flex-c', 'ai-c', 'jc-sb', `system-${block.moduleStatus}`]"
|
|
>
|
|
<img class="icon" :src="systemIconMap[block.moduleCode]" alt="" />
|
|
<div class="title">{{ block.moduleName }}</div>
|
|
<div :class="['status', `status-${block.moduleStatus}`]">
|
|
{{ systemStatusDesc[block.moduleStatus] }}
|
|
</div>
|
|
</div>
|
|
</Grid>
|
|
</ModuleWrapper>
|
|
<ModuleWrapper title="全部房间" style="grid-column: 1 / 3">
|
|
<template #extra>
|
|
<a-button type="primary" @click="handleOpenScenarioModal()">新建房间</a-button>
|
|
</template>
|
|
<div class="normal flex-c ai-c" v-loading="room.loading">
|
|
<Grid class="room-wrapper" :columns="[1, 1, 1, 1, 1]" :rows="[1, 1]">
|
|
<div v-for="item in room.list" :key="item.id" class="room-item">
|
|
<img class="room-image" :src="item.image || '/mockData/68ab3707-2552-4b78-bfc0-cec3502ec62f.png'" alt="" />
|
|
<div class="room-mask"></div>
|
|
<div class="room-brief">
|
|
<div class="room-name">{{ item.name }}</div>
|
|
<div class="room-author">{{ item.author }}</div>
|
|
</div>
|
|
<div class="room-reload" title="进入房间" @click="handleJoinRoom(item)">
|
|
<a-icon type="reload" />
|
|
</div>
|
|
</div>
|
|
</Grid>
|
|
<a-pagination
|
|
v-model="room.pagination.current"
|
|
:pageSize.sync="room.pagination.pageSize"
|
|
:total="room.pagination.total"
|
|
@change="getRoomList"
|
|
/>
|
|
</div>
|
|
</ModuleWrapper>
|
|
<a-modal
|
|
v-model="scenarioModal.visible"
|
|
title="选择想定"
|
|
width="900px"
|
|
:maskClosable="false"
|
|
:destroyOnClose="true"
|
|
@ok="handleConfirmScenario()"
|
|
>
|
|
<Grid style="height: 600px" :columns="[1, 1]">
|
|
<ModuleWrapper title="想定列表">
|
|
<template #extra>
|
|
<a-icon type="sync" style="font-size: 30px; color: #00deff" @click="getScenarioListData()" />
|
|
</template>
|
|
<div
|
|
class="normal"
|
|
v-loading="scenarioModal.scenarioLoading"
|
|
style="background-color: white; padding: 20px 0; overflow: auto"
|
|
>
|
|
<a-tree
|
|
:treeData="scenarioModal.scenarioList"
|
|
:replaceFields="{ title: 'name', key: 'id' }"
|
|
:selectedKeys.sync="scenarioModal.selectedKeys"
|
|
@select="handleChangeScenarioSelected"
|
|
>
|
|
</a-tree>
|
|
</div>
|
|
</ModuleWrapper>
|
|
<ModuleWrapper title="作战/保障力量">
|
|
<template #extra>
|
|
<a-icon type="sync" style="font-size: 30px; color: #00deff" @click="getZzbzllTreeData()" />
|
|
</template>
|
|
<div class="normal" v-loading="scenarioModal.zzbzllLoading" style="background-color: white; overflow: auto">
|
|
<a-tree
|
|
:treeData="scenarioModal.zzbzllTree"
|
|
:replaceFields="{ title: 'name', key: 'id' }"
|
|
:selected="false"
|
|
:expandedKeys.sync="scenarioModal.expandedKeys"
|
|
>
|
|
</a-tree>
|
|
</div>
|
|
</ModuleWrapper>
|
|
</Grid>
|
|
</a-modal>
|
|
</Grid>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapState, mapActions } from 'vuex'
|
|
|
|
export default {
|
|
name: 'SimulationSceneCentralControl',
|
|
data() {
|
|
return {
|
|
room: {
|
|
list: [],
|
|
loading: false,
|
|
pagination: {
|
|
current: 1,
|
|
pageSize: 10,
|
|
total: 0,
|
|
},
|
|
},
|
|
scenarioModal: {
|
|
visible: false,
|
|
scenarioList: [],
|
|
scenarioLoading: false,
|
|
selectedKeys: [],
|
|
zzbzllTree: [],
|
|
zzbzllLoading: false,
|
|
expandedKeys: [],
|
|
},
|
|
roomInfo: {
|
|
roomId: '',
|
|
},
|
|
}
|
|
},
|
|
computed: {
|
|
...mapState({
|
|
systemModules: (state) => state.simulation.systemModules,
|
|
systemStatusMap: (state) => state.simulation.systemStatusMap,
|
|
systemStatusDesc: (state) => state.simulation.systemStatusDesc,
|
|
systemIconMap: (state) => state.simulation.systemIconMap,
|
|
systemPathMap: (state) => state.simulation.systemPathMap,
|
|
}),
|
|
},
|
|
created() {
|
|
this.getSystemModules()
|
|
this.getRoomList()
|
|
},
|
|
methods: {
|
|
...mapActions(['getSystemModules']),
|
|
async getRoomList() {
|
|
try {
|
|
this.loading = true
|
|
const res = await this.$http({
|
|
url: '/baseData/room/list',
|
|
method: 'get',
|
|
params: {
|
|
pageNum: this.room.pagination.current,
|
|
pageSize: this.room.pagination.pageSize,
|
|
},
|
|
})
|
|
this.room.list = res.data.data
|
|
this.room.pagination.total = res.data.totalCount
|
|
} catch (error) {
|
|
console.log(error)
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
handleOpenScenarioModal() {
|
|
this.scenarioModal.visible = true
|
|
setTimeout(() => {
|
|
this.getScenarioListData()
|
|
}, 100)
|
|
},
|
|
async getScenarioListData() {
|
|
try {
|
|
this.scenarioModal.scenarioLoading = true
|
|
const res = await this.$http({
|
|
url: `/baseData/scenario/all`,
|
|
method: 'get',
|
|
})
|
|
this.scenarioModal.scenarioList = res.data
|
|
} catch (error) {
|
|
console.log(error)
|
|
} finally {
|
|
this.scenarioModal.scenarioLoading = false
|
|
}
|
|
},
|
|
handleChangeScenarioSelected() {
|
|
this.getZzbzllTreeData()
|
|
},
|
|
async getZzbzllTreeData() {
|
|
try {
|
|
this.scenarioModal.zzbzllLoading = true
|
|
const res = await this.$http({
|
|
url: `/scenario/power/${this.scenarioModal.selectedKeys[0]}`,
|
|
method: 'get',
|
|
})
|
|
this.scenarioModal.zzbzllTree = [
|
|
{
|
|
id: '1',
|
|
name: '红方',
|
|
children: [
|
|
{ id: '1-1', name: '作战力量', children: res.data.red.fight },
|
|
{ id: '1-2', name: '保障力量', children: res.data.red.guarantee },
|
|
{ id: '1-3', name: '指挥力量', children: res.data.red.command },
|
|
],
|
|
},
|
|
{
|
|
id: '2',
|
|
name: '蓝方',
|
|
children: [
|
|
{ id: '2-1', name: '作战力量', children: res.data.blue.fight },
|
|
{ id: '2-2', name: '保障力量', children: res.data.blue.guarantee },
|
|
{ id: '2-3', name: '指挥力量', children: res.data.blue.command },
|
|
],
|
|
},
|
|
]
|
|
this.scenarioModal.expandedKeys = ['1', '1-1', '1-2', '1-3', '2', '2-1', '2-2', '2-3']
|
|
} catch (error) {
|
|
console.log(error)
|
|
} finally {
|
|
this.scenarioModal.zzbzllLoading = false
|
|
}
|
|
},
|
|
async handleConfirmScenario() {
|
|
const scenarioId = this.scenarioModal.selectedKeys[0]
|
|
if (!scenarioId) {
|
|
return this.$message.warning('请先选择想定!')
|
|
}
|
|
try {
|
|
this.$message.info('正在创建新房间,请稍候')
|
|
const res = await this.$http({
|
|
url: '/room/scenario/create',
|
|
method: 'get',
|
|
params: { id: scenarioId },
|
|
})
|
|
this.scenarioModal.visible = false
|
|
this.clearScenarioModal()
|
|
const shifou = await new Promise((resolve) => {
|
|
this.$confirm({
|
|
content: `创建新房间成功,房间编号${res.data.roomCode},是否立即进入?`,
|
|
onOk() {
|
|
resolve(true)
|
|
},
|
|
onCancel() {
|
|
resolve(false)
|
|
},
|
|
})
|
|
})
|
|
if (shifou) {
|
|
this.handleJoinRoom(res.data)
|
|
}
|
|
} catch (error) {
|
|
console.log(error)
|
|
}
|
|
},
|
|
clearScenarioModal() {
|
|
this.scenarioModal.scenarioList = []
|
|
this.scenarioModal.selectedKeys = []
|
|
this.scenarioModal.zzbzllTree = []
|
|
this.scenarioModal.expandedKeys = []
|
|
},
|
|
handleJoinRoom(item) {
|
|
this.roomInfo.roomId = item.roomId
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.central-control-page {
|
|
padding: 20px;
|
|
}
|
|
.system-block {
|
|
border: 1px solid #06445f;
|
|
background-color: #062e45;
|
|
position: relative;
|
|
padding-bottom: 32px;
|
|
cursor: pointer;
|
|
.icon {
|
|
transform: translateY(calc(90px - 50%));
|
|
}
|
|
.title {
|
|
color: #9cd3f5;
|
|
font-size: 24px;
|
|
line-height: 26px;
|
|
}
|
|
.status {
|
|
position: absolute;
|
|
right: 10px;
|
|
top: 10px;
|
|
padding: 8px 10px;
|
|
font-size: 14px;
|
|
line-height: 1;
|
|
color: #ffffff;
|
|
}
|
|
.status-1 {
|
|
background-color: #11b740;
|
|
}
|
|
.status-0 {
|
|
background-color: #9d9d9d;
|
|
}
|
|
}
|
|
.system-0 {
|
|
cursor: not-allowed;
|
|
}
|
|
.system-1:hover {
|
|
border-color: #00f2fe;
|
|
}
|
|
|
|
.room-wrapper {
|
|
flex: 1;
|
|
width: 100%;
|
|
overflow: hidden;
|
|
margin-bottom: 20px;
|
|
}
|
|
.room-item {
|
|
position: relative;
|
|
cursor: pointer;
|
|
.room-image {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
.room-mask {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
}
|
|
.room-brief {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 60px;
|
|
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 1));
|
|
padding-left: 10px;
|
|
.room-name {
|
|
font-size: 20px;
|
|
line-height: 36px;
|
|
}
|
|
.room-author {
|
|
font-size: 12px;
|
|
line-height: 24px;
|
|
}
|
|
}
|
|
.room-reload {
|
|
position: absolute;
|
|
right: 20px;
|
|
bottom: 10px;
|
|
width: 40px;
|
|
height: 40px;
|
|
font-size: 40px;
|
|
line-height: 1;
|
|
display: none;
|
|
}
|
|
&:hover .room-reload {
|
|
display: block;
|
|
}
|
|
.room-reload:hover {
|
|
color: #00f2fe;
|
|
}
|
|
}
|
|
|
|
.scenario-wrapper {
|
|
flex: 1;
|
|
width: 100%;
|
|
overflow: hidden;
|
|
margin-bottom: 20px;
|
|
}
|
|
.scenario-item {
|
|
position: relative;
|
|
cursor: pointer;
|
|
.scenario-image {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
.scenario-mask {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
}
|
|
.scenario-brief {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 60px;
|
|
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 1));
|
|
padding-left: 10px;
|
|
.scenario-name {
|
|
font-size: 20px;
|
|
line-height: 36px;
|
|
}
|
|
.scenario-author {
|
|
font-size: 12px;
|
|
line-height: 24px;
|
|
}
|
|
}
|
|
.scenario-reload {
|
|
position: absolute;
|
|
right: 20px;
|
|
bottom: 10px;
|
|
width: 40px;
|
|
height: 40px;
|
|
font-size: 40px;
|
|
line-height: 1;
|
|
display: none;
|
|
}
|
|
&:hover .scenario-reload {
|
|
display: block;
|
|
}
|
|
.scenario-reload:hover {
|
|
color: #00f2fe;
|
|
}
|
|
}
|
|
|
|
.scenario-info-wrapper {
|
|
flex: 1;
|
|
border: 1px solid #06445f;
|
|
background-color: #0f3b4f;
|
|
overflow: auto;
|
|
.ant-row {
|
|
line-height: 26px;
|
|
.xdsm-wrapper {
|
|
background-color: #ffffff;
|
|
color: #666666;
|
|
}
|
|
}
|
|
*::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
::v-deep {
|
|
.ant-calendar-picker-input,
|
|
.ant-time-picker-input {
|
|
background-color: #0b293a;
|
|
border: solid 1px #1d5777;
|
|
color: #ffffff;
|
|
}
|
|
}
|
|
.ant-calendar-picker {
|
|
color: #ffffff;
|
|
margin: 5px 0;
|
|
}
|
|
.ant-time-picker {
|
|
margin: 5px 0;
|
|
}
|
|
.ant-calendar-picker::v-deep {
|
|
.anticon {
|
|
color: #ffffff;
|
|
}
|
|
}
|
|
.ant-calendar-picker:hover::v-deep {
|
|
.anticon {
|
|
background-color: transparent;
|
|
}
|
|
}
|
|
.ant-time-picker::v-deep {
|
|
.anticon {
|
|
color: #ffffff;
|
|
}
|
|
}
|
|
.ant-time-picker:hover::v-deep {
|
|
.anticon {
|
|
background-color: transparent;
|
|
}
|
|
}
|
|
.ant-input {
|
|
background-color: #0b293a;
|
|
border: solid 1px #1d5777;
|
|
color: #ffffff;
|
|
}
|
|
}
|
|
|
|
.io-event-list {
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: #082532;
|
|
padding: 20px;
|
|
overflow-y: scroll;
|
|
.io-event-item {
|
|
padding: 10px 0;
|
|
font-size: 16px;
|
|
line-height: 22px;
|
|
color: #a1c2d0;
|
|
}
|
|
}
|
|
|
|
.ant-btn + .ant-btn {
|
|
margin-left: 8px;
|
|
}
|
|
</style>
|