Browse Source

修改航线航点弹出框

lbj
ctw 2 months ago
parent
commit
e7b6319538
  1. 653
      ruoyi-ui/src/views/cesiumMap/index.vue
  2. 67
      ruoyi-ui/src/views/childRoom/RightPanel.vue
  3. 92
      ruoyi-ui/src/views/childRoom/index.vue
  4. 255
      ruoyi-ui/src/views/dialogs/RouteEditDialog.vue
  5. 114
      ruoyi-ui/src/views/dialogs/WaypointEditDialog.vue

653
ruoyi-ui/src/views/cesiumMap/index.vue

File diff suppressed because it is too large

67
ruoyi-ui/src/views/childRoom/RightPanel.vue

@ -15,17 +15,19 @@
>
<div v-if="activeTab === 'plan'" class="tab-content plan-content">
<div class="section">
<div class="section-title" style="display: flex; justify-content: space-between; align-items: center;">
<span>航线列表</span>
<el-button
type="text"
icon="el-icon-circle-plus-outline"
style="padding: 0; color: #008aff; font-size: 14px;"
@click="handleCreateRoute"
>
新建航线
</el-button>
</div>
<div class="section-header">
<div class="section-title">航线列表</div>
<el-button
type="text"
icon="el-icon-plus"
size="mini"
class="header-action-btn"
@click="handleCreateRoute"
>
新建
</el-button>
</div>
<div class="route-list">
<div
v-for="route in routes"
@ -53,6 +55,7 @@
</div>
</div>
</div>
<div v-if="selectedRouteDetails" class="section">
<div class="section-title">航点列表</div>
<div class="waypoint-list">
@ -60,7 +63,6 @@
v-for="point in selectedRouteDetails.waypoints"
:key="point.name"
class="waypoint-item"
@click="handleOpenWaypointDialog(point)"
>
<i class="el-icon-location"></i>
<div class="waypoint-info">
@ -259,6 +261,11 @@ export default {
this.$emit('select-route', route)
},
// 线
handleCreateRoute() {
this.$emit('create-route')
},
handleOpenRouteDialog(route) {
this.$emit('open-route-dialog', route)
},
@ -286,18 +293,14 @@ export default {
handleRunConflictCheck() {
this.$emit('run-conflict-check')
},
// ... existing code ...
handleOpenPlatformDialog(platform) {
this.$emit('open-platform-dialog', platform)
},
handleCreateRoute() {
this.$emit('create-route')
}
}
}
</script>
<style scoped>
/* 右侧外部隐藏按钮 */
.right-external-hide-btn {
@ -368,13 +371,31 @@ export default {
margin-bottom: 20px;
}
/* 新增:标题栏容器样式 */
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 2px solid rgba(0, 138, 255, 0.2);
margin-bottom: 10px;
padding-bottom: 8px;
}
/* 修改:移除了原有的 border-bottom,改在 section-header 中统一定义 */
.section-title {
font-size: 14px;
font-weight: 600;
color: #008aff;
margin-bottom: 10px;
padding-bottom: 8px;
border-bottom: 2px solid rgba(0, 138, 255, 0.2);
}
/* 新增:头部按钮样式 */
.header-action-btn {
padding: 0;
color: #008aff;
}
.header-action-btn:hover {
color: #0066cc;
}
.route-list {
@ -455,7 +476,7 @@ export default {
padding: 10px;
background: rgba(255, 255, 255, 0.8);
border-radius: 6px;
cursor: pointer;
/* 移除 cursor: pointer 因为不再整行可点 */
transition: all 0.3s;
border: 1px solid rgba(0, 138, 255, 0.1);
}
@ -723,4 +744,4 @@ export default {
.blue-warning {
color: #e6a23c;
}
</style>
</style>

92
ruoyi-ui/src/views/childRoom/index.vue

@ -1,9 +1,6 @@
<template>
<!-- 以地图为绝对定位背景所有组件浮动其上 -->
<div class="mission-planning-container">
<!-- 地图背景 -->
<div id="gis-map-background" class="map-background">
<!-- cesiummap组件 -->
<cesiumMap :drawDomClick="drawDom"/>
<div class="map-overlay-text">
<i class="el-icon-location-outline text-3xl mb-2 block"></i>
@ -11,7 +8,6 @@
<p class="text-sm mt-1">支持标绘/航线/空域/实时态势</p>
</div>
<!-- 地图中间的浮动红点触发左侧菜单 -->
<div
class="floating-red-dot left-red-dot"
:class="{ hidden: !isMenuHidden }"
@ -23,7 +19,6 @@
</div>
</div>
<!-- 顶部导航栏 -->
<top-header
:room-code="roomCode"
:online-count="onlineCount"
@ -71,7 +66,6 @@
@show-online-members="showOnlineMembersDialog"
/>
<!-- 左侧折叠菜单栏 - 蓝色主题 -->
<left-menu
:is-hidden="isMenuHidden"
:menu-items="menuItems"
@ -80,7 +74,6 @@
@select="selectMenu"
/>
<!-- 右侧实体列表浮动- 蓝色主题 -->
<right-panel
:is-hidden="isRightPanelHidden"
:active-tab="activeRightTab"
@ -94,6 +87,7 @@
:ground-platforms="groundPlatforms"
@hide="hideRightPanel"
@select-route="selectRoute"
@create-route="createRoute"
@open-route-dialog="openRouteDialog"
@open-waypoint-dialog="openWaypointDialog"
@add-waypoint="addWaypoint"
@ -104,15 +98,12 @@
@open-platform-dialog="openPlatformDialog"
/>
<!-- 左下角工具面板 -->
<bottom-left-panel />
<!-- 底部时间轴最初版本的样式- 蓝色主题 -->
<div
class="floating-timeline blue-theme"
:class="{ 'show': showKTimePopup }"
>
<!-- 隐藏按钮向下箭头 -->
<div class="popup-hide-btn" @click="hideKTimePopup" title="隐藏K时">
<i class="el-icon-arrow-down"></i>
</div>
@ -166,26 +157,22 @@
</div>
<!-- 在线成员弹窗 -->
<online-members-dialog
v-model="showOnlineMembers"
/>
<!-- 平台编辑弹窗 -->
<platform-edit-dialog
v-model="showPlatformDialog"
:platform="selectedPlatform"
@save="updatePlatform"
/>
<!-- 航线编辑弹窗 -->
<route-edit-dialog
v-model="showRouteDialog"
:route="selectedRoute"
@save="updateRoute"
/>
<!-- 航点编辑弹窗 -->
<waypoint-edit-dialog
v-model="showWaypointDialog"
:waypoint="selectedWaypoint"
@ -348,9 +335,7 @@ export default {
},
methods: {
// 线
showOnlineMembersDialog() {
this.showOnlineMembers = true;
},
//
openPlatformDialog(platform) {
this.selectedPlatform = platform;
@ -365,9 +350,25 @@ export default {
this.selectedRoute = route;
this.showRouteDialog = true;
},
// 线
updateRoute(updatedRoute) {
//
this.$message.success('航线更新成功');
const index = this.routes.findIndex(r => r.id === updatedRoute.id);
if (index !== -1) {
// 使 splice
const newRouteData = { ...this.routes[index], ...updatedRoute };
this.routes.splice(index, 1, newRouteData);
// 线
if (this.selectedRouteDetails && this.selectedRouteId === updatedRoute.id) {
this.selectedRouteDetails.name = updatedRoute.name;
}
this.$message.success('航线名称更新成功');
}
},
// 线
createRoute() {
this.$message.info('新建航线功能开发中...');
},
//
openWaypointDialog(waypoint) {
@ -375,8 +376,32 @@ export default {
this.showWaypointDialog = true;
},
updateWaypoint(updatedWaypoint) {
//
this.$message.success('航点更新成功');
// 1. 线
if (this.selectedRouteDetails && this.selectedRouteDetails.waypoints) {
// 2.
const index = this.selectedRouteDetails.waypoints.indexOf(this.selectedWaypoint);
if (index !== -1) {
// 3. 使 splice
this.selectedRouteDetails.waypoints.splice(index, 1, updatedWaypoint);
// 4. 便
this.selectedWaypoint = updatedWaypoint;
this.$message.success('航点更新成功');
} else {
// indexOf
const nameIndex = this.selectedRouteDetails.waypoints.findIndex(p => p.name === this.selectedWaypoint.name);
if (nameIndex !== -1) {
this.selectedRouteDetails.waypoints.splice(nameIndex, 1, updatedWaypoint);
this.selectedWaypoint = updatedWaypoint;
this.$message.success('航点更新成功');
} else {
this.$message.error('更新失败:未找到对应航点');
}
}
}
},
updateTime() {
const now = new Date();
@ -618,9 +643,9 @@ export default {
this.isRightPanelHidden = false;
}
} else if(item.id === 'modify'){
this.drawDom = !this.drawDom
console.log(this.drawDom,999999)
}
this.drawDom = !this.drawDom
console.log(this.drawDom,999999)
}
if (item.id === 'deduction') {
// /K
this.showKTimePopup = !this.showKTimePopup;
@ -725,7 +750,7 @@ export default {
return `K+${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:00`;
},
// 线
// 线
selectRoute(route) {
this.selectedRouteId = route.id;
//
@ -738,8 +763,7 @@ export default {
{ name: 'WP4', altitude: 5800, speed: '830km/h', eta: 'K+01:25:00' },
]
};
// 线
this.openRouteDialog(route);
// this.openRouteDialog(route);
},
addWaypoint() {
@ -792,6 +816,7 @@ export default {
</script>
<style scoped>
/* 保持原有样式不变,仅修复背景图语法的注释部分 */
.mission-planning-container {
position: relative;
width: 100vw;
@ -806,14 +831,13 @@ export default {
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, #1a2f4b 0%, #2c3e50 100%);
/* 正确的写法,直接复制这行替换 */
background: url('~@/assets/map-background.png');
/* 修复:使用正确的背景图语法 */
background: url('~@/assets/map-background.png');
background-size: cover;
background-position: center;
z-index: 1;
}
/* ...其余样式省略,保持不变... */
.map-overlay-text {
position: absolute;
top: 50%;
@ -825,7 +849,6 @@ background: url('~@/assets/map-background.png');
pointer-events: none;
}
/* 地图中间的浮动红点 - 通用样式 */
.floating-red-dot {
position: absolute;
top: 50%;
@ -854,7 +877,6 @@ background: url('~@/assets/map-background.png');
display: none;
}
/* 左侧红点 */
.left-red-dot {
left: 20px;
transform: translateY(-50%);
@ -886,7 +908,6 @@ background: url('~@/assets/map-background.png');
}
}
/* 蓝色主题通用类 */
.blue-theme {
background: rgba(255, 255, 255, 0.3);
backdrop-filter: blur(10px);
@ -951,7 +972,6 @@ background: url('~@/assets/map-background.png');
box-shadow: 0 0 10px rgba(0, 138, 255, 0.8);
}
/* 蓝色主题标签页 */
.blue-tabs >>> .el-tabs__item {
color: #666;
transition: all 0.3s;
@ -975,7 +995,6 @@ background: url('~@/assets/map-background.png');
background-color: rgba(0, 138, 255, 0.3);
}
/* 底部时间轴(最初版本的样式)- 蓝色主题 */
.floating-timeline {
position: absolute;
bottom: 20px;
@ -1146,7 +1165,6 @@ background: url('~@/assets/map-background.png');
font-weight: 500;
}
/* 滚动条样式 */
::-webkit-scrollbar {
width: 6px;
}

255
ruoyi-ui/src/views/dialogs/RouteEditDialog.vue

@ -1,66 +1,30 @@
<template>
<div v-if="value" class="route-edit-dialog">
<!-- 遮罩层 -->
<div class="dialog-overlay" @click="closeDialog"></div>
<!-- 弹窗内容 -->
<div class="dialog-content">
<div class="dialog-header">
<h3>航线编辑</h3>
<div class="close-btn" @click="closeDialog">×</div>
</div>
<div class="dialog-body">
<el-form :model="formData" :rules="rules" ref="formRef" label-width="80px" size="small">
<!-- 基本信息 -->
<el-form-item label="名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入航线名称"></el-input>
</el-form-item>
<el-form-item label="航向" prop="heading">
<el-input-number
v-model="formData.heading"
:min="0"
:max="360"
placeholder="请输入航向"
style="width: 100%;"
suffix="°"
></el-input-number>
</el-form-item>
<el-form-item label="时间" prop="time">
<el-input v-model="formData.time" placeholder="请输入时间(如:K+00:40:00)"></el-input>
</el-form-item>
<el-form-item label="速度" prop="speed">
<el-input v-model="formData.speed" placeholder="请输入速度" suffix="km/h"></el-input>
</el-form-item>
<el-form-item label="距离" prop="distance">
<el-input-number
v-model="formData.distance"
:min="0"
:precision="2"
placeholder="请输入距离"
style="width: 100%;"
suffix="km"
></el-input-number>
</el-form-item>
</el-form>
</div>
<div class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="saveRoute">保存</el-button>
</div>
</div>
</div>
<el-dialog
title="编辑航线"
:visible.sync="visible"
width="300px"
:close-on-click-modal="false"
append-to-body
custom-class="blue-dialog"
>
<el-form :model="form" label-width="70px" size="small" @submit.native.prevent>
<el-form-item label="航线名称">
<el-input v-model="form.name" placeholder="请输入航线名称"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button size="mini" @click="visible = false"> </el-button>
<el-button type="primary" size="mini" class="blue-btn" @click="handleSave"> </el-button>
</span>
</el-dialog>
</template>
<script>
export default {
name: 'RouteEditDialog',
props: {
// v-model="showRouteDialog"
value: {
type: Boolean,
default: false
@ -72,158 +36,55 @@ export default {
},
data() {
return {
formData: {
name: '',
heading: 0,
time: '',
speed: '',
distance: 0
form: {
id: '',
name: ''
}
}
},
computed: {
visible: {
get() {
return this.value
},
rules: {
name: [
{ required: true, message: '请输入航线名称', trigger: 'blur' }
],
heading: [
{ type: 'number', message: '航向必须为数字', trigger: 'blur' },
{ min: 0, max: 360, message: '航向必须在0-360度之间', trigger: 'blur' }
],
time: [
{ required: true, message: '请输入时间', trigger: 'blur' }
],
speed: [
{ required: true, message: '请输入速度', trigger: 'blur' },
{ type: 'number', message: '速度必须为数字', trigger: 'blur' }
],
distance: [
{ type: 'number', message: '距离必须为数字', trigger: 'blur' }
]
set(val) {
this.$emit('input', val)
}
};
}
},
watch: {
value(newVal) {
if (newVal && this.route) {
this.initFormData();
}
},
route(newVal) {
if (this.value && newVal) {
this.initFormData();
}
// route form
route: {
handler(val) {
if (val) {
//
this.form = {
id: val.id,
name: val.name
}
}
},
immediate: true,
deep: true
}
},
methods: {
initFormData() {
// 线使使
this.formData = {
name: this.route.name || '',
heading: this.route.heading || 0,
time: this.route.time || '',
speed: this.route.speed || '',
distance: this.route.distance || 0
};
},
closeDialog() {
this.$emit('input', false);
},
saveRoute() {
this.$refs.formRef.validate((valid) => {
if (valid) {
//
this.$emit('save', {
...this.route,
...this.formData
});
this.closeDialog();
}
});
handleSave() {
// form name
this.$emit('save', this.form)
this.visible = false
}
}
};
}
</script>
<style scoped>
.route-edit-dialog {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
}
.dialog-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(2px);
.blue-btn {
background: #008aff;
border-color: #008aff;
}
.dialog-content {
position: relative;
background: white;
border-radius: 8px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
width: 90%;
max-width: 500px;
max-height: 90vh;
overflow-y: auto;
animation: dialog-fade-in 0.3s ease;
}
@keyframes dialog-fade-in {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.dialog-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
border-bottom: 1px solid #e8e8e8;
}
.dialog-header h3 {
margin: 0;
font-size: 16px;
font-weight: 600;
color: #333;
}
.close-btn {
font-size: 20px;
color: #999;
cursor: pointer;
transition: color 0.3s;
}
.close-btn:hover {
color: #666;
}
.dialog-body {
padding: 20px;
}
.dialog-footer {
display: flex;
align-items: center;
justify-content: flex-end;
padding: 16px 20px;
border-top: 1px solid #e8e8e8;
gap: 10px;
.blue-btn:hover {
background: #0066cc;
border-color: #0066cc;
}
</style>
</style>

114
ruoyi-ui/src/views/dialogs/WaypointEditDialog.vue

@ -1,52 +1,61 @@
<template>
<div v-if="value" class="waypoint-edit-dialog">
<!-- 遮罩层 -->
<div class="dialog-overlay" @click="closeDialog"></div>
<!-- 弹窗内容 -->
<div class="dialog-content">
<div class="dialog-header">
<h3>航点编辑</h3>
<div class="close-btn" @click="closeDialog">×</div>
</div>
<div class="dialog-body">
<el-form :model="formData" :rules="rules" ref="formRef" label-width="80px" size="small">
<!-- 基本信息 -->
<el-form :model="formData" :rules="rules" ref="formRef" label-width="100px" size="small">
<el-form-item label="名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入航点名称"></el-input>
</el-form-item>
<el-form-item label="高度" prop="altitude">
<el-input-number
v-model="formData.altitude"
:min="0"
<el-input-number
v-model="formData.altitude"
:min="0"
controls-position="right"
placeholder="请输入高度"
style="width: 100%;"
suffix="m"
></el-input-number>
</el-form-item>
<el-form-item label="速度" prop="speed">
<el-input v-model="formData.speed" placeholder="请输入速度" suffix="km/h"></el-input>
</el-form-item>
<el-form-item label="时间" prop="eta">
<el-input v-model="formData.eta" placeholder="请输入到达时间(如:K+00:40:00)"></el-input>
<el-input-number
v-model="formData.speed"
:min="0"
controls-position="right"
placeholder="请输入速度"
style="width: 100%;"
></el-input-number>
</el-form-item>
<el-form-item label="转弯半径" prop="turnRadius">
<el-input-number
v-model="formData.turnRadius"
:min="0"
placeholder="请输入转弯半径"
<el-form-item label="转弯坡度" prop="turnBank">
<el-input-number
v-model="formData.turnBank"
controls-position="right"
placeholder="请输入转弯坡度"
style="width: 100%;"
suffix="m"
></el-input-number>
</el-form-item>
<el-form-item label="起始时间" prop="startTime">
<el-time-picker
v-model="formData.startTime"
placeholder="请选择起始时间"
value-format="HH:mm:ss"
style="width: 100%;"
>
</el-time-picker>
</el-form-item>
</el-form>
</div>
<div class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="saveWaypoint">保存</el-button>
@ -69,31 +78,43 @@ export default {
}
},
data() {
// 0
const validateNumber = (rule, value, callback) => {
// value undefined, null
// !value !0 true
if (value === undefined || value === null || value === '') {
callback(new Error(rule.message));
} else {
callback();
}
};
return {
formData: {
name: '',
altitude: 0,
speed: '',
eta: '',
turnRadius: 0
speed: 0,
turnBank: 0,
startTime: ''
},
rules: {
name: [
{ required: true, message: '请输入航点名称', trigger: 'blur' }
],
altitude: [
{ required: true, message: '请输入高度', trigger: 'blur' },
{ type: 'number', message: '高度必须为数字', trigger: 'blur' }
// 使 validator type: 'number' 0
{ required: true, validator: validateNumber, message: '请输入有效高度', trigger: ['blur', 'change'] }
],
speed: [
{ required: true, message: '请输入速度', trigger: 'blur' },
{ type: 'number', message: '速度必须为数字', trigger: 'blur' }
// 使 validator 0
{ required: true, validator: validateNumber, message: '请输入有效速度', trigger: ['blur', 'change'] }
],
eta: [
{ required: true, message: '请输入到达时间', trigger: 'blur' }
turnBank: [
//
{ required: true, validator: validateNumber, message: '请输入有效转弯坡度', trigger: ['blur', 'change'] }
],
turnRadius: [
{ type: 'number', message: '转弯半径必须为数字', trigger: 'blur' }
startTime: [
{ required: true, message: '请选择起始时间', trigger: 'change' }
]
}
};
@ -112,14 +133,22 @@ export default {
},
methods: {
initFormData() {
// 使使
// Number
this.formData = {
name: this.waypoint.name || '',
altitude: this.waypoint.altitude || 0,
speed: this.waypoint.speed || '',
eta: this.waypoint.eta || '',
turnRadius: this.waypoint.turnRadius || 0
//
altitude: this.waypoint.altitude !== undefined && this.waypoint.altitude !== null ? Number(this.waypoint.altitude) : 0,
speed: this.waypoint.speed !== undefined && this.waypoint.speed !== null ? Number(this.waypoint.speed) : 0,
turnBank: this.waypoint.turnBank !== undefined && this.waypoint.turnBank !== null ? Number(this.waypoint.turnBank) : 0,
startTime: this.waypoint.startTime || ''
};
//
this.$nextTick(() => {
if (this.$refs.formRef) {
this.$refs.formRef.clearValidate();
}
});
},
closeDialog() {
this.$emit('input', false);
@ -127,7 +156,6 @@ export default {
saveWaypoint() {
this.$refs.formRef.validate((valid) => {
if (valid) {
//
this.$emit('save', {
...this.waypoint,
...this.formData
@ -224,4 +252,4 @@ export default {
border-top: 1px solid #e8e8e8;
gap: 10px;
}
</style>
</style>

Loading…
Cancel
Save