教员系统,分队数据库,保存分队
This commit is contained in:
parent
8f2f953a14
commit
dcfdf8aca0
|
@ -43,16 +43,10 @@ export default class MyCesium {
|
||||||
}
|
}
|
||||||
|
|
||||||
viewer = null
|
viewer = null
|
||||||
// 选中模型
|
|
||||||
selectedModel = null
|
|
||||||
// 右鍵菜單
|
|
||||||
contextMenu = {
|
|
||||||
visible: false,
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
}
|
|
||||||
// 未完成的在地图上移动类的操作
|
// 未完成的在地图上移动类的操作
|
||||||
operations = []
|
operations = []
|
||||||
|
// 已添加的军标
|
||||||
|
plots = []
|
||||||
|
|
||||||
constructor(dom, options = {}) {
|
constructor(dom, options = {}) {
|
||||||
const imageryProvider = new Cesium.UrlTemplateImageryProvider({
|
const imageryProvider = new Cesium.UrlTemplateImageryProvider({
|
||||||
|
@ -127,144 +121,6 @@ export default class MyCesium {
|
||||||
// 用于启用或禁用指南针外环。true是启用,false是禁用。默认值为true。如果将选项设置为false,则该环将可见但无效。
|
// 用于启用或禁用指南针外环。true是启用,false是禁用。默认值为true。如果将选项设置为false,则该环将可见但无效。
|
||||||
enableCompassOuterRing: true,
|
enableCompassOuterRing: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
|
|
||||||
handler.setInputAction(({ position }) => {
|
|
||||||
if (this.selectedModel) {
|
|
||||||
this.deselectModel(this.selectedModel)
|
|
||||||
this.selectedModel = null
|
|
||||||
}
|
|
||||||
const pickedObject = viewer.scene.pick(position)
|
|
||||||
if (!Cesium.defined(pickedObject) || !pickedObject.id) {
|
|
||||||
window.Emit('pickedObject', null)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const entity = pickedObject.id
|
|
||||||
if (
|
|
||||||
!entity.properties ||
|
|
||||||
(entity.properties.type != MyCesium.ENTITY_TYPES.MODEL && entity.properties.type != MyCesium.ENTITY_TYPES.IMAGE)
|
|
||||||
) {
|
|
||||||
window.Emit('pickedObject', null)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.selectedModel = entity
|
|
||||||
this.selectModel(entity)
|
|
||||||
window.Emit('selectedModel', {
|
|
||||||
id: entity.id,
|
|
||||||
})
|
|
||||||
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
|
||||||
|
|
||||||
// 鼠标右键事件
|
|
||||||
handler.setInputAction(({ position }) => {
|
|
||||||
const pickedObject = viewer.scene.pick(position)
|
|
||||||
if (!Cesium.defined(pickedObject) || !pickedObject.id) return
|
|
||||||
const entity = pickedObject.id
|
|
||||||
const properties = entity.properties
|
|
||||||
if (
|
|
||||||
!properties ||
|
|
||||||
!properties.type ||
|
|
||||||
(properties.type != MyCesium.ENTITY_TYPES.MODEL && properties.type != MyCesium.ENTITY_TYPES.IMAGE)
|
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const nomove = properties.nomove
|
|
||||||
if (selectedModel && entity.id == selectedModel.id && !(nomove && nomove.valueOf())) {
|
|
||||||
this.showContextMenu(entity)
|
|
||||||
this.cancelPreviousOperation()
|
|
||||||
}
|
|
||||||
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
|
||||||
|
|
||||||
// shift + 左键事件
|
|
||||||
handler.setInputAction(
|
|
||||||
({ position }) => {
|
|
||||||
const pickedObject = viewer.scene.pick(position)
|
|
||||||
if (!Cesium.defined(pickedObject) || !pickedObject.id) return
|
|
||||||
const entity = pickedObject.id
|
|
||||||
if (!entity.properties || entity.properties.type != MyCesium.ENTITY_TYPES.MODEL) return
|
|
||||||
if (this.selectedModel) {
|
|
||||||
// 找到已有的properties中的from和to是选中的两个模型的id的线
|
|
||||||
const find = viewer.entities.values.find((item) => {
|
|
||||||
const props = item.properties
|
|
||||||
if (!props || !props.type || !props.from || !props.to) return false
|
|
||||||
return (
|
|
||||||
(props.from == this.selectedModel.id && props.to == entity.id) ||
|
|
||||||
(props.from == entity.id && props.to == this.selectedModel.id)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
// 如果已经有了,移除
|
|
||||||
if (find) {
|
|
||||||
viewer.entities.remove(find)
|
|
||||||
const { from, to } = find.properties
|
|
||||||
// 发送删除线的事件
|
|
||||||
window.Emit('removeLineBetwenModel', {
|
|
||||||
id: find.id,
|
|
||||||
from: from.valueOf(),
|
|
||||||
to: to.valueOf(),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
const id = Cesium.createGuid()
|
|
||||||
const currentTime = viewer.clock.currentTime
|
|
||||||
const positions = [this.selectedModel.position.getValue(currentTime), entity.position.getValue(currentTime)]
|
|
||||||
if (positions.some((item) => !item)) {
|
|
||||||
console.log('缺少位置信息')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.addLineBetwenModel(id, positions, selectedModel.id, entity.id)
|
|
||||||
// 发送添加线的事件
|
|
||||||
window.Emit('addLineBetwenModel', {
|
|
||||||
positions,
|
|
||||||
id,
|
|
||||||
from: selectedModel.id,
|
|
||||||
to: entity.id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Cesium.ScreenSpaceEventType.LEFT_CLICK,
|
|
||||||
Cesium.KeyboardEventModifier.SHIFT
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 选中模型
|
|
||||||
* @param {Cesium.Entity} entity
|
|
||||||
*/
|
|
||||||
selectModel(entity) {
|
|
||||||
if (!entity.model) return
|
|
||||||
|
|
||||||
const {
|
|
||||||
properties: { color: _color },
|
|
||||||
} = entity
|
|
||||||
const color = _color.valueOf()
|
|
||||||
// 设置模型轮廓效果
|
|
||||||
entity.model.silhouetteSize = 2 // 轮廓线宽度
|
|
||||||
entity.model.silhouetteColor = Cesium.Color.fromCssColorString(color)
|
|
||||||
entity.label.show = true
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 取消选中模型
|
|
||||||
* @param {Cesium.Entity} entity
|
|
||||||
*/
|
|
||||||
deselectModel(entity) {
|
|
||||||
if (!entity.model) return
|
|
||||||
|
|
||||||
entity.model.silhouetteSize = 0 // 设置为0取消轮廓
|
|
||||||
entity.label.show = false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示右键菜单
|
|
||||||
* @param {Cesium.Entity} entity
|
|
||||||
*/
|
|
||||||
showContextMenu(entity) {
|
|
||||||
const currentTime = viewer.clock.currentTime
|
|
||||||
// 获取entity中心点的屏幕坐标
|
|
||||||
const position = entity.position.getValue(currentTime)
|
|
||||||
const screenPosition = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, position)
|
|
||||||
|
|
||||||
this.contextMenu.left = screenPosition.x + 20
|
|
||||||
this.contextMenu.top = screenPosition.y
|
|
||||||
this.contextMenu.visible = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 取消未完成的在地图上移动类的操作(划线之类的)
|
// 取消未完成的在地图上移动类的操作(划线之类的)
|
||||||
|
@ -274,33 +130,13 @@ export default class MyCesium {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在模型之间添加线
|
* 根据四个角落坐标确定视口位置
|
||||||
* @param id
|
* @param leftUp
|
||||||
* @param { Cesium.Cartesian3[] } positions
|
* @param rightUp
|
||||||
* @param fromId
|
* @param rightDown
|
||||||
* @param toId
|
* @param leftDown
|
||||||
*/
|
*/
|
||||||
addLineBetwenModel(id, positions, fromId, toId) {
|
setClientByAllCorner(leftUp, rightUp, rightDown, leftDown) {
|
||||||
this.viewer.entities.add({
|
|
||||||
id,
|
|
||||||
polyline: {
|
|
||||||
positions,
|
|
||||||
width: 2,
|
|
||||||
material: new Cesium.PolylineDashMaterialProperty({
|
|
||||||
color: Cesium.Color.YELLOW,
|
|
||||||
dashLength: 20, //短划线长度
|
|
||||||
}),
|
|
||||||
clampToGround: true,
|
|
||||||
},
|
|
||||||
properties: {
|
|
||||||
type: MyCesium.ENTITY_TYPES.LINE,
|
|
||||||
from: fromId,
|
|
||||||
to: toId,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
setViewerByAllCorner(leftUp, rightUp, rightDown, leftDown) {
|
|
||||||
const [leftUpLon, leftUpLat] = leftUp
|
const [leftUpLon, leftUpLat] = leftUp
|
||||||
const [rightUpLon, rightUpLat] = rightUp
|
const [rightUpLon, rightUpLat] = rightUp
|
||||||
const [rightDownLon, rightDownLat] = rightDown
|
const [rightDownLon, rightDownLat] = rightDown
|
||||||
|
@ -328,18 +164,17 @@ export default class MyCesium {
|
||||||
* @param x
|
* @param x
|
||||||
* @param y
|
* @param y
|
||||||
*/
|
*/
|
||||||
addPlot(base64, { x, y }) {
|
addPlot(base64, screenPosition) {
|
||||||
this.cancelPreviousOperation()
|
this.cancelPreviousOperation()
|
||||||
|
|
||||||
const id = Cesium.createGuid()
|
const position = getCatesian3FromPX(this.viewer, screenPosition)
|
||||||
const position = getCatesian3FromPX(this.viewer, { x, y })
|
if (!position) return false
|
||||||
if (!position) return
|
|
||||||
|
|
||||||
|
const id = Cesium.createGuid()
|
||||||
const isEnemy = false
|
const isEnemy = false
|
||||||
const color = 'red'
|
const color = 'red'
|
||||||
const radius = 150000
|
const radius = 150000
|
||||||
|
const plot = {
|
||||||
this.viewer.entities.add({
|
|
||||||
id,
|
id,
|
||||||
position,
|
position,
|
||||||
billboard: {
|
billboard: {
|
||||||
|
@ -364,6 +199,19 @@ export default class MyCesium {
|
||||||
radius,
|
radius,
|
||||||
collisions: new Set(),
|
collisions: new Set(),
|
||||||
},
|
},
|
||||||
})
|
}
|
||||||
|
this.viewer.entities.add(plot)
|
||||||
|
this.plots.push(plot)
|
||||||
|
|
||||||
|
// 1. 将屏幕坐标转换为世界坐标(在椭球体表面)
|
||||||
|
const cartesian = this.viewer.camera.pickEllipsoid(screenPosition, this.viewer.scene.globe.ellipsoid)
|
||||||
|
if (Cesium.defined(cartesian)) {
|
||||||
|
// 2. 将世界坐标 (Cartesian3) 转换为地理坐标 Cartographic (弧度)
|
||||||
|
const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
|
||||||
|
// 3. 将弧度转换为度数
|
||||||
|
const longitude = Cesium.Math.toDegrees(cartographic.longitude)
|
||||||
|
const latitude = Cesium.Math.toDegrees(cartographic.latitude)
|
||||||
|
return { plotId: id, longitude, latitude }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,5 +42,6 @@ export default {
|
||||||
window.MyWebsocket = MyWebsocket
|
window.MyWebsocket = MyWebsocket
|
||||||
|
|
||||||
Vue.prototype.$bus = Bus
|
Vue.prototype.$bus = Bus
|
||||||
|
Vue.prototype.$console = window.console
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,6 +261,14 @@ export const constantRouterMap = [
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: '/simulationScene/instructor',
|
||||||
|
name: 'SimulationSceneInstructor',
|
||||||
|
component: () => import(/* webpackChunkName: "fail" */ '@/views/simulationScene/instructor/index.vue'),
|
||||||
|
meta: { title: '教员系统' },
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: '/simulationScene/systemSelect',
|
path: '/simulationScene/systemSelect',
|
||||||
name: 'SimulationSceneSystemSelect',
|
name: 'SimulationSceneSystemSelect',
|
||||||
|
|
120
src/views/simulationScene/database/fdsjk.vue
Normal file
120
src/views/simulationScene/database/fdsjk.vue
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
<template>
|
||||||
|
<page-header-wrapper>
|
||||||
|
<Grid>
|
||||||
|
<a-card class="my-card">
|
||||||
|
<AntQueryTable
|
||||||
|
height="100%"
|
||||||
|
ref="fd-table"
|
||||||
|
:queryConfig="fdTable.queryConfig"
|
||||||
|
:tableConfig="fdTable.tableConfig"
|
||||||
|
:pageConfig="fdTable.pageConfig"
|
||||||
|
:showTool="fdTable.showTool"
|
||||||
|
>
|
||||||
|
<template #toolbar-left>
|
||||||
|
<a-button type="primary" icon="plus" @click="handleOpenAddModal()">新增</a-button>
|
||||||
|
</template>
|
||||||
|
<template #tablecell-action="{ record }">
|
||||||
|
<a-button type="text-primary" icon="edit" @click="handleOpenEditModal(record)"></a-button>
|
||||||
|
<a-button type="text-danger" icon="delete" @click="handleDelete(record)"></a-button>
|
||||||
|
</template>
|
||||||
|
</AntQueryTable>
|
||||||
|
</a-card>
|
||||||
|
</Grid>
|
||||||
|
<AntFormModal
|
||||||
|
:visible.sync="AEModal.visible"
|
||||||
|
:title="AEModal.title"
|
||||||
|
width="900px"
|
||||||
|
:formConfig="{ labelCol: { span: 3 }, wrapperCol: { span: 19 } }"
|
||||||
|
:formItems="AEModal.formItems"
|
||||||
|
:formRules="AEModal.formRules"
|
||||||
|
:formData="AEModal.formData"
|
||||||
|
:onSubmit="handleSubmitAE"
|
||||||
|
@success="handleSubmitAESuccess"
|
||||||
|
></AntFormModal>
|
||||||
|
</page-header-wrapper>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getAction, postAction } from '@/api/manage'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
fdTable: {
|
||||||
|
queryConfig: false,
|
||||||
|
tableConfig: {
|
||||||
|
query: () => getAction('/team/list'),
|
||||||
|
columns: [
|
||||||
|
{ dataIndex: 'serial' },
|
||||||
|
{ dataIndex: 'name', title: '分队名称', width: 'auto', minWidth: 160 },
|
||||||
|
{
|
||||||
|
dataIndex: 'type',
|
||||||
|
title: '分队类型',
|
||||||
|
width: 'auto',
|
||||||
|
minWidth: 160,
|
||||||
|
align: 'center',
|
||||||
|
customRender: (text) => ['作战分队', '保障分队'][text],
|
||||||
|
},
|
||||||
|
{ dataIndex: 'action' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
pageConfig: true,
|
||||||
|
showTool: true,
|
||||||
|
},
|
||||||
|
AEModal: {
|
||||||
|
visible: false,
|
||||||
|
title: '',
|
||||||
|
formItems: [
|
||||||
|
{ label: '分队名称', prop: 'name' },
|
||||||
|
{
|
||||||
|
label: '分队类型',
|
||||||
|
prop: 'type',
|
||||||
|
component: 'AntOriginSelect',
|
||||||
|
options: {
|
||||||
|
dataSource: () => ({
|
||||||
|
data: [
|
||||||
|
{ title: '作战分队', id: 0 },
|
||||||
|
{ title: '保障分队', id: 1 },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ label: '分队军标', prop: 'iconId', component: 'IconSelector' },
|
||||||
|
],
|
||||||
|
formRules: {},
|
||||||
|
formData: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleOpenAddModal() {
|
||||||
|
this.AEModal.title = '新增分队'
|
||||||
|
this.AEModal.formData = {}
|
||||||
|
this.AEModal.visible = true
|
||||||
|
},
|
||||||
|
handleOpenEditModal(record) {
|
||||||
|
this.AEModal.title = '编辑分队'
|
||||||
|
this.AEModal.formData = { ...record }
|
||||||
|
this.AEModal.visible = true
|
||||||
|
},
|
||||||
|
handleSubmitAE(formData) {
|
||||||
|
return postAction('/team/save', formData)
|
||||||
|
},
|
||||||
|
handleSubmitAESuccess() {
|
||||||
|
this.$refs['fd-table'].commitAction('query')
|
||||||
|
},
|
||||||
|
async handleDelete(record) {
|
||||||
|
try {
|
||||||
|
await this.$confirm({ title: '温馨提示', content: '确定要删除该分队吗?' })
|
||||||
|
const res = await getAction('/team/remove/' + record.id)
|
||||||
|
this.$message.success(res.message)
|
||||||
|
this.$refs['fd-table'].commitAction('query')
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
24
src/views/simulationScene/instructor/AddRoom.vue
Normal file
24
src/views/simulationScene/instructor/AddRoom.vue
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<template>
|
||||||
|
<Grid
|
||||||
|
:columns="[5, 3, 2]"
|
||||||
|
:rows="[2, 3, 5]"
|
||||||
|
gap="0px"
|
||||||
|
:style="{ width: size, height: size, cursor: 'pointer' }"
|
||||||
|
title="新建房间"
|
||||||
|
v-on="$listeners"
|
||||||
|
>
|
||||||
|
<a-icon type="home" :style="{ fontSize: `calc(${size} * 8 / 10)`, gridColumn: '1 / 3', gridRow: '2 / 4' }" />
|
||||||
|
<a-icon type="plus" :style="{ fontSize: `calc(${size} * 5 / 10)`, gridColumn: '2 / 4', gridRow: '1 / 3' }" />
|
||||||
|
</Grid>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
size: { type: String, default: '30px' },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
</style>
|
305
src/views/simulationScene/instructor/index.vue
Normal file
305
src/views/simulationScene/instructor/index.vue
Normal file
|
@ -0,0 +1,305 @@
|
||||||
|
<template>
|
||||||
|
<Grid class="instructor-page" :columns="[1, 2, 2]">
|
||||||
|
<ModuleWrapper title="数据库子系统"> </ModuleWrapper>
|
||||||
|
<ModuleWrapper title="想定列表">
|
||||||
|
<template #extra>
|
||||||
|
<a-icon title="新建想定" type="plus" style="font-size: 30px" @click="handleOpenAddScenarioModal()" />
|
||||||
|
</template>
|
||||||
|
<Flex fd="co" class="normal">
|
||||||
|
<div class="scenario-list flex-1">
|
||||||
|
<Flex v-for="item in scenario.listData" :key="item.id" ai="c" class="scenario-item">
|
||||||
|
<div class="flex-1">
|
||||||
|
<div class="scenario-name">【{{ item.id }}】{{ item.name }}</div>
|
||||||
|
<Flex ai="c">
|
||||||
|
<div class="scenario-author">{{ item.author }}</div>
|
||||||
|
<div class="scenario-create-time">{{ item.createTime.replace('T', ' ') }}</div>
|
||||||
|
</Flex>
|
||||||
|
</div>
|
||||||
|
<a-icon
|
||||||
|
title="删除"
|
||||||
|
type="delete"
|
||||||
|
style="font-size: 30px; margin-right: 30px; color: red"
|
||||||
|
@click="handleDeleteScenario(item)"
|
||||||
|
/>
|
||||||
|
<a-icon
|
||||||
|
title="预设"
|
||||||
|
type="setting"
|
||||||
|
style="font-size: 30px; margin-right: 30px"
|
||||||
|
@click="handleOpenSetting(item)"
|
||||||
|
/>
|
||||||
|
<AddRoom @click="handleOpenAddRoomModal(item)" />
|
||||||
|
</Flex>
|
||||||
|
</div>
|
||||||
|
<Flex ai="c" jc="c">
|
||||||
|
<a-pagination
|
||||||
|
v-model="scenario.pagination.pageNum"
|
||||||
|
:total="scenario.pagination.total"
|
||||||
|
:pageSize="scenario.pagination.pageSize"
|
||||||
|
show-less-items
|
||||||
|
:showTotal="
|
||||||
|
(total) => `
|
||||||
|
共${total}条`
|
||||||
|
"
|
||||||
|
@change="getScenarioList"
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</ModuleWrapper>
|
||||||
|
<ModuleWrapper title="房间列表">
|
||||||
|
<Flex fd="co" class="normal">
|
||||||
|
<Flex fw="w" ac="fs" class="room-list flex-1">
|
||||||
|
<div class="room-item" v-for="item in room.listData" :key="item.id">
|
||||||
|
<Flex class="room-card">
|
||||||
|
<Flex fd="co" jc="c" class="room-info flex-1">
|
||||||
|
<div class="room-name"><a-icon type="home" style="margin-right: 10px" />{{ item.roomName }}</div>
|
||||||
|
<div class="room-scenario-relation">想定编号:{{ item.scenarioId }}</div>
|
||||||
|
<div class="room-create-time">{{ item.createTime.slice(0, 19).replace('T', ' ') }}</div>
|
||||||
|
</Flex>
|
||||||
|
<Flex class="room-enter" ai="c" title="开始训练" @click="handleEnterRoom(item)">
|
||||||
|
<a-icon type="right" style="font-size: 20px" />
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</div>
|
||||||
|
</Flex>
|
||||||
|
<Flex ai="c" jc="c">
|
||||||
|
<a-pagination
|
||||||
|
v-model="room.pagination.pageNum"
|
||||||
|
:total="room.pagination.total"
|
||||||
|
:pageSize="room.pagination.pageSize"
|
||||||
|
show-less-items
|
||||||
|
:showTotal="(total) => `共${total}条`"
|
||||||
|
@change="getRoomList"
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</ModuleWrapper>
|
||||||
|
<AntFormModal
|
||||||
|
:visible.sync="scenarioModal.visible"
|
||||||
|
:title="scenarioModal.title"
|
||||||
|
:formItems="scenarioModal.formItems"
|
||||||
|
:formRules="scenarioModal.formRules"
|
||||||
|
:formData="scenarioModal.formData"
|
||||||
|
:onSubmit="handleSubmitScenario"
|
||||||
|
@success="handleSubmitScenarioSuccess"
|
||||||
|
></AntFormModal>
|
||||||
|
<AntFormModal
|
||||||
|
:visible.sync="roomModal.visible"
|
||||||
|
:title="roomModal.title"
|
||||||
|
:formItems="roomModal.formItems"
|
||||||
|
:formRules="roomModal.formRules"
|
||||||
|
:formData="roomModal.formData"
|
||||||
|
:onSubmit="handleSubmitRoom"
|
||||||
|
@success="handleSubmitRoomSuccess"
|
||||||
|
></AntFormModal>
|
||||||
|
</Grid>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import AddRoom from './AddRoom.vue'
|
||||||
|
import { getAction, postAction } from '@/api/manage'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SimulationSceneInstructor',
|
||||||
|
components: {
|
||||||
|
AddRoom,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
scenario: {
|
||||||
|
listData: [],
|
||||||
|
pagination: {
|
||||||
|
total: 0,
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scenarioModal: {
|
||||||
|
visible: false,
|
||||||
|
title: '',
|
||||||
|
mode: '',
|
||||||
|
formItems: [
|
||||||
|
{ label: '想定名称', prop: 'name', required: true },
|
||||||
|
{ label: '想定区域(东)', prop: 'right', required: true, options: { type: 'number' } },
|
||||||
|
{ label: '想定区域(西)', prop: 'left', required: true, options: { type: 'number' } },
|
||||||
|
{ label: '想定区域(南)', prop: 'down', required: true, options: { type: 'number' } },
|
||||||
|
{ label: '想定区域(北)', prop: 'up', required: true, options: { type: 'number' } },
|
||||||
|
],
|
||||||
|
formRules: {},
|
||||||
|
formData: {},
|
||||||
|
},
|
||||||
|
room: {
|
||||||
|
listData: [],
|
||||||
|
pagination: {
|
||||||
|
total: 0,
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
roomModal: {
|
||||||
|
visible: false,
|
||||||
|
title: '',
|
||||||
|
mode: '',
|
||||||
|
formItems: [{ label: '房间名称', prop: 'roomName', required: true }],
|
||||||
|
formRules: {},
|
||||||
|
formData: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getScenarioList()
|
||||||
|
this.getRoomList()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getScenarioList() {
|
||||||
|
try {
|
||||||
|
const res = await this.$http({
|
||||||
|
url: '/baseData/scenario/list',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
pageNum: this.scenario.pagination.pageNum,
|
||||||
|
pageSize: this.scenario.pagination.pageSize,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
this.scenario.listData = res.data.data
|
||||||
|
this.scenario.pagination.total = res.data.totalCount
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getRoomList() {
|
||||||
|
try {
|
||||||
|
const res = await this.$http({
|
||||||
|
url: '/scenario/room/list',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
pageNum: this.room.pagination.pageNum,
|
||||||
|
pageSize: this.room.pagination.pageSize,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
this.room.listData = res.data.data
|
||||||
|
this.room.pagination.total = res.data.totalCount
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleOpenAddScenarioModal() {
|
||||||
|
this.scenarioModal.title = '新建想定'
|
||||||
|
this.scenarioModal.formData = {}
|
||||||
|
this.scenarioModal.visible = true
|
||||||
|
},
|
||||||
|
handleSubmitScenario(formData) {
|
||||||
|
const params = {
|
||||||
|
name: formData.name,
|
||||||
|
leftUpLng: formData.left,
|
||||||
|
leftUpLat: formData.up,
|
||||||
|
rightUpLng: formData.right,
|
||||||
|
rightUpLat: formData.up,
|
||||||
|
leftBottomLng: formData.left,
|
||||||
|
leftBottomLat: formData.down,
|
||||||
|
rightBottomLng: formData.right,
|
||||||
|
rightBottomLat: formData.down,
|
||||||
|
}
|
||||||
|
return postAction('/baseData/scenario/save', params)
|
||||||
|
},
|
||||||
|
handleSubmitScenarioSuccess() {
|
||||||
|
this.getScenarioList()
|
||||||
|
},
|
||||||
|
async handleDeleteScenario(scenarioItem) {
|
||||||
|
try {
|
||||||
|
await this.$confirm({ title: '温馨提示', content: '确定要删除该想定吗?' })
|
||||||
|
const res = await getAction(`/baseData/scenario/remove/${scenarioItem.id}`)
|
||||||
|
this.$message.success(res.message)
|
||||||
|
this.getScenarioList()
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleOpenSetting(scenarioItem) {
|
||||||
|
window.localStorage.setItem('scenarioId', scenarioItem.id)
|
||||||
|
window.localStorage.setItem('scenarioName', scenarioItem.name)
|
||||||
|
window.localStorage.setItem('scenarioRedirectUrl', 'SimulationSceneInstructor')
|
||||||
|
this.$router.push({ name: 'SimulationSceneSceneEditing' })
|
||||||
|
},
|
||||||
|
handleOpenAddRoomModal(scenarioItem) {
|
||||||
|
this.roomModal.title = '新建房间'
|
||||||
|
this.roomModal.formData = {}
|
||||||
|
this.roomModal.formData.scenarioId = scenarioItem.id
|
||||||
|
this.roomModal.visible = true
|
||||||
|
},
|
||||||
|
handleSubmitRoom(formData) {
|
||||||
|
return postAction('/scenario/room/save', formData)
|
||||||
|
},
|
||||||
|
handleSubmitRoomSuccess() {
|
||||||
|
this.getRoomList()
|
||||||
|
},
|
||||||
|
handleEnterRoom(roomItem) {
|
||||||
|
window.localStorage.setItem('instructorRoomId', roomItem.id)
|
||||||
|
window.localStorage.setItem('instructorRoomName', roomItem.roomName)
|
||||||
|
this.$router.push({ name: 'SimulationSceneInstructorMenu' })
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.instructor-page {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.scenario-item {
|
||||||
|
margin: 0 10px;
|
||||||
|
height: 10%;
|
||||||
|
border-bottom: 1px solid #ffffff22;
|
||||||
|
.scenario-name {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bolder;
|
||||||
|
margin-left: -10px;
|
||||||
|
}
|
||||||
|
.scenario-author {
|
||||||
|
font-size: 16px;
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
.scenario-create-time {
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: italic;
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.room-item {
|
||||||
|
width: 50%;
|
||||||
|
height: 20%;
|
||||||
|
padding: 10px;
|
||||||
|
.room-card {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid #00deff;
|
||||||
|
.room-info {
|
||||||
|
padding: 10px;
|
||||||
|
border-right: 1px solid #00deff;
|
||||||
|
}
|
||||||
|
.room-name {
|
||||||
|
font-size: 26px;
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
.room-create-time {
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: italic;
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
.room-enter {
|
||||||
|
border-radius: 0 10px 10px 0;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
.room-enter:hover {
|
||||||
|
background-color: #10475f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::v-deep {
|
||||||
|
.ant-pagination-total-text {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -44,13 +44,7 @@
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex class="flex-1 scroller-y" fw="w" ac="fs">
|
<Flex class="flex-1 scroller-y" fw="w" ac="fs">
|
||||||
<Flex v-for="item in model.listData" :key="item.id" class="model-item" fd="co" ai="c">
|
<Flex v-for="item in model.listData" :key="item.id" class="model-item" fd="co" ai="c">
|
||||||
<img
|
<img class="model-image" :src="item.imgBase64" :draggable="true" @dragend="dragend(item, $event)" />
|
||||||
class="model-image"
|
|
||||||
:src="item.imgBase64"
|
|
||||||
:draggable="true"
|
|
||||||
@dragstart="dragstart(item, $event)"
|
|
||||||
@dragend="dragend(item, $event)"
|
|
||||||
/>
|
|
||||||
<span class="model-name">{{ item.name }}</span>
|
<span class="model-name">{{ item.name }}</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -78,7 +72,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getAction } from '@/api/manage'
|
import { getAction, postAction } from '@/api/manage'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
@ -86,6 +80,7 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
scenarioDetail: {},
|
||||||
zzbzll: {
|
zzbzll: {
|
||||||
treeData: [],
|
treeData: [],
|
||||||
selectedKeys: [],
|
selectedKeys: [],
|
||||||
|
@ -117,14 +112,40 @@ export default {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
|
||||||
this.getZzbzllTreeData()
|
|
||||||
this.getZbysListData()
|
|
||||||
},
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.cesium = new window.MyCesium('cesium-container')
|
this.cesium = new window.MyCesium('cesium-container')
|
||||||
|
this.getScenarioDetail()
|
||||||
|
// this.getZzbzllTreeData()
|
||||||
|
this.getZbysListData()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async getScenarioDetail() {
|
||||||
|
try {
|
||||||
|
const res = await getAction(`/baseData/scenario/${this.scenarioId}`)
|
||||||
|
this.scenarioDetail = res.data
|
||||||
|
// this.setCesiumClient()
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setCesiumClient() {
|
||||||
|
const {
|
||||||
|
leftUpLng,
|
||||||
|
rightUpLng,
|
||||||
|
leftUpLat,
|
||||||
|
rightUpLat,
|
||||||
|
leftBottomLng,
|
||||||
|
rightBottomLng,
|
||||||
|
leftBottomLat,
|
||||||
|
rightBottomLat,
|
||||||
|
} = this.scenarioDetail
|
||||||
|
this.cesium.setClientByAllCorner(
|
||||||
|
[leftUpLng, leftUpLat],
|
||||||
|
[rightUpLng, rightUpLat],
|
||||||
|
[rightBottomLng, rightBottomLat],
|
||||||
|
[leftBottomLng, leftBottomLat]
|
||||||
|
)
|
||||||
|
},
|
||||||
async getZzbzllTreeData() {
|
async getZzbzllTreeData() {
|
||||||
try {
|
try {
|
||||||
const res = await getAction(`/scenario/power/${this.scenarioId}`)
|
const res = await getAction(`/scenario/power/${this.scenarioId}`)
|
||||||
|
@ -168,13 +189,26 @@ export default {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dragstart(item, e) {},
|
|
||||||
dragend(item, e) {
|
dragend(item, e) {
|
||||||
console.log(e.x, this.$refs['cesium-container'].offsetLeft, e.x - this.$refs['cesium-container'].offsetLeft)
|
|
||||||
console.log(e.y, this.$refs['cesium-container'].offsetTop, e.y - this.$refs['cesium-container'].offsetTop)
|
|
||||||
const x = e.x - this.$refs['cesium-container'].offsetLeft
|
const x = e.x - this.$refs['cesium-container'].offsetLeft
|
||||||
const y = e.y - this.$refs['cesium-container'].offsetTop
|
const y = e.y - this.$refs['cesium-container'].offsetTop
|
||||||
this.cesium.addPlot(item.imgBase64, { x, y })
|
const { plotId, longitude, latitude } = this.cesium.addPlot(item.imgBase64, { x, y })
|
||||||
|
this.savePlot(this.model.queryParams.force, item, { plotId, longitude, latitude })
|
||||||
|
},
|
||||||
|
async savePlot(force, item, { plotId, longitude, latitude }) {
|
||||||
|
try {
|
||||||
|
await postAction('/scenario/resource/save', {
|
||||||
|
scenarioId: this.scenarioId,
|
||||||
|
type: force,
|
||||||
|
resourceType: item.type,
|
||||||
|
resourceId: item.id,
|
||||||
|
lng: longitude,
|
||||||
|
lat: latitude,
|
||||||
|
})
|
||||||
|
// this.getZzbzllTreeData()
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,13 @@ export default {
|
||||||
visible: false,
|
visible: false,
|
||||||
title: '',
|
title: '',
|
||||||
mode: '',
|
mode: '',
|
||||||
formItems: [{ label: '想定名称', prop: 'name', required: true }],
|
formItems: [
|
||||||
|
{ label: '想定名称', prop: 'name', required: true },
|
||||||
|
{ label: '想定区域(东)', prop: 'right', required: true, options: { type: 'number' } },
|
||||||
|
{ label: '想定区域(西)', prop: 'left', required: true, options: { type: 'number' } },
|
||||||
|
{ label: '想定区域(南)', prop: 'down', required: true, options: { type: 'number' } },
|
||||||
|
{ label: '想定区域(北)', prop: 'up', required: true, options: { type: 'number' } },
|
||||||
|
],
|
||||||
formRules: {},
|
formRules: {},
|
||||||
formData: {},
|
formData: {},
|
||||||
},
|
},
|
||||||
|
@ -172,7 +178,18 @@ export default {
|
||||||
this.scenarioModal.visible = true
|
this.scenarioModal.visible = true
|
||||||
},
|
},
|
||||||
handleSubmitScenario(formData) {
|
handleSubmitScenario(formData) {
|
||||||
return postAction('/baseData/scenario/save', formData)
|
const params = {
|
||||||
|
name: formData.name,
|
||||||
|
leftUpLng: formData.left,
|
||||||
|
leftUpLat: formData.up,
|
||||||
|
rightUpLng: formData.right,
|
||||||
|
rightUpLat: formData.up,
|
||||||
|
leftBottomLng: formData.left,
|
||||||
|
leftBottomLat: formData.down,
|
||||||
|
rightBottomLng: formData.right,
|
||||||
|
rightBottomLat: formData.down,
|
||||||
|
}
|
||||||
|
return postAction('/baseData/scenario/save', params)
|
||||||
},
|
},
|
||||||
handleSubmitScenarioSuccess() {
|
handleSubmitScenarioSuccess() {
|
||||||
this.getScenarioList()
|
this.getScenarioList()
|
||||||
|
@ -265,4 +282,4 @@ export default {
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -109,7 +109,7 @@ export default {
|
||||||
this.$router.push({ name: 'SimulationSceneCentralControl' })
|
this.$router.push({ name: 'SimulationSceneCentralControl' })
|
||||||
},
|
},
|
||||||
openInstructorSystem() {
|
openInstructorSystem() {
|
||||||
this.$router.push({ name: 'SimulationSceneCentralControl' })
|
this.$router.push({ name: 'SimulationSceneInstructor' })
|
||||||
},
|
},
|
||||||
openTrainerSystem() {
|
openTrainerSystem() {
|
||||||
this.$router.push({ name: 'SimulationSceneTrainer' })
|
this.$router.push({ name: 'SimulationSceneTrainer' })
|
||||||
|
|
Loading…
Reference in New Issue
Block a user