Browse Source

新增航线的展示、可多选、查询航线的逻辑变动

master
menghao 2 months ago
parent
commit
9f1f028bee
  1. 20
      ruoyi-system/src/main/java/com/ruoyi/system/domain/RouteWaypoints.java
  2. 13
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/RoutesServiceImpl.java
  3. 1
      ruoyi-system/src/main/resources/mapper/system/RoutesMapper.xml
  4. 230
      ruoyi-ui/src/views/cesiumMap/index.vue
  5. 18
      ruoyi-ui/src/views/childRoom/RightPanel.vue
  6. 4
      ruoyi-ui/src/views/childRoom/TopHeader.vue
  7. 251
      ruoyi-ui/src/views/childRoom/index.vue
  8. 2
      ruoyi-ui/vue.config.js

20
ruoyi-system/src/main/java/com/ruoyi/system/domain/RouteWaypoints.java

@ -41,11 +41,11 @@ public class RouteWaypoints extends BaseEntity
/** 高度 (米) */ /** 高度 (米) */
@Excel(name = "高度 (米)") @Excel(name = "高度 (米)")
private Long alt; private Double alt;
/** 速度 (km/h) */ /** 速度 (km/h) */
@Excel(name = "速度 (km/h)") @Excel(name = "速度 (km/h)")
private Long speed; private Double speed;
/** 起始时间 (如: K+00:40:00) */ /** 起始时间 (如: K+00:40:00) */
@Excel(name = "起始时间 (如: K+00:40:00)") @Excel(name = "起始时间 (如: K+00:40:00)")
@ -53,7 +53,7 @@ public class RouteWaypoints extends BaseEntity
/** 转弯角度 (用于计算转弯半径) */ /** 转弯角度 (用于计算转弯半径) */
@Excel(name = "转弯角度 (用于计算转弯半径)") @Excel(name = "转弯角度 (用于计算转弯半径)")
private Long turnAngle; private Double turnAngle;
public void setId(Long id) public void setId(Long id)
{ {
@ -115,22 +115,22 @@ public class RouteWaypoints extends BaseEntity
return lng; return lng;
} }
public void setAlt(Long alt) public void setAlt(Double alt)
{ {
this.alt = alt; this.alt = alt;
} }
public Long getAlt() public Double getAlt()
{ {
return alt; return alt;
} }
public void setSpeed(Long speed) public void setSpeed(Double speed)
{ {
this.speed = speed; this.speed = speed;
} }
public Long getSpeed() public Double getSpeed()
{ {
return speed; return speed;
} }
@ -145,12 +145,12 @@ public class RouteWaypoints extends BaseEntity
return startTime; return startTime;
} }
public void setTurnAngle(Long turnAngle) public void setTurnAngle(Double turnAngle)
{ {
this.turnAngle = turnAngle; this.turnAngle = turnAngle;
} }
public Long getTurnAngle() public Double getTurnAngle()
{ {
return turnAngle; return turnAngle;
} }
@ -183,7 +183,7 @@ public class RouteWaypoints extends BaseEntity
// 单位换算:速度从 km/h 转为 m/s // 单位换算:速度从 km/h 转为 m/s
double v_mps = this.speed / 3.6; double v_mps = this.speed / 3.6;
// 单位换算:角度从 度(Degree) 转为 弧度(Radians) // 单位换算:角度从 度(Degree) 转为 弧度(Radians)
double radians = Math.toRadians(this.turnAngle.doubleValue()); double radians = Math.toRadians(this.turnAngle);
// 重力加速度 g // 重力加速度 g
double g = 9.8; double g = 9.8;
// 计算半径 // 计算半径

13
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/RoutesServiceImpl.java

@ -35,7 +35,18 @@ public class RoutesServiceImpl implements IRoutesService
@Override @Override
public Routes selectRoutesById(Long id) public Routes selectRoutesById(Long id)
{ {
return routesMapper.selectRoutesById(id); // 查出航线基本信息
Routes routes = routesMapper.selectRoutesById(id);
// 如果查到了航线,就再去查属于它的航点
if (routes != null) {
RouteWaypoints queryWp = new RouteWaypoints();
queryWp.setRouteId(id); // 根据航线ID查询
List<RouteWaypoints> wpList = routeWaypointsService.selectRouteWaypointsList(queryWp);
// 把查出来的航点列表塞进 routes 对象的 waypoints 属性里
routes.setWaypoints(wpList);
}
return routes;
} }
/** /**

1
ruoyi-system/src/main/resources/mapper/system/RoutesMapper.xml

@ -10,6 +10,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="platformId" column="platform_id" /> <result property="platformId" column="platform_id" />
<result property="callSign" column="call_sign" /> <result property="callSign" column="call_sign" />
<result property="attributes" column="attributes" /> <result property="attributes" column="attributes" />
<collection property="waypoints" javaType="java.util.List" resultMap="com.ruoyi.system.mapper.RouteWaypointsMapper.RouteWaypointsResult" />
</resultMap> </resultMap>
<sql id="selectRoutesVo"> <sql id="selectRoutesVo">

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

@ -100,6 +100,204 @@ export default {
}, },
methods: { methods: {
preventContextMenu(e) {
e.preventDefault();
},
clearRoute() {
// 1. allEntities
this.allEntities.forEach(item => {
this.viewer.entities.remove(item.entity);
});
this.allEntities = [];
// 2.
const entities = this.viewer.entities.values;
for (let i = entities.length - 1; i >= 0; i--) {
const entity = entities[i];
if (entity.properties && entity.properties.isMissionWaypoint) {
this.viewer.entities.remove(entity);
}
}
},
updateWaypointGraphic(oldName, newName) {
//
const entities = this.viewer.entities.values;
const target = entities.find(e => e.name === oldName && e.properties.isMissionWaypoint);
if (target) {
target.name = newName; //
target.label.text = newName; //
}
},
// 线
startMissionRouteDrawing() {
this.stopDrawing(); //
this.drawingPoints = [];
let activeCursorPosition = null;
this.isDrawing = true;
this.drawingHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
window.addEventListener('contextmenu', this.preventContextMenu, true);
//
this.drawingHandler.setInputAction((movement) => {
const newPosition = this.getClickPosition(movement.endPosition);
if (newPosition) {
activeCursorPosition = newPosition;
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
//
this.drawingHandler.setInputAction((click) => {
const position = this.getClickPosition(click.position);
if (!position) return;
this.drawingPoints.push(position);
const wpIndex = this.drawingPoints.length;
//
this.viewer.entities.add({
name: `WP${wpIndex}`,
position: position,
properties: {
isMissionWaypoint: true, //
originalIndex: wpIndex //
},
point: {
pixelSize: 10,
color: Cesium.Color.WHITE,
outlineColor: Cesium.Color.fromCssColorString('#0078FF'),
outlineWidth: 3,
disableDepthTestDistance: Number.POSITIVE_INFINITY //
},
label: {
text: `WP${wpIndex}`,
font: '12px MicroSoft YaHei',
pixelOffset: new Cesium.Cartesian2(0, -20),
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2,
style: Cesium.LabelStyle.FILL_AND_OUTLINE
}
});
// 线
if (this.drawingPoints.length === 1) {
this.tempPreviewEntity = this.viewer.entities.add({
polyline: {
positions: new Cesium.CallbackProperty(() => {
if (this.drawingPoints.length > 0 && activeCursorPosition) {
return [...this.drawingPoints, activeCursorPosition];
}
return this.drawingPoints;
}, false),
width: 4,
//
material: new Cesium.PolylineDashMaterialProperty({
color: Cesium.Color.WHITE, //
gapColor: Cesium.Color.BLACK, //
dashLength: 20.0 //
}),
clampToGround: true
}
});
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
//
this.drawingHandler.setInputAction(() => {
if (this.drawingPoints.length > 1) {
// childRoom/index.vue
const latLngPoints = this.drawingPoints.map((p, index) => {
const coords = this.cartesianToLatLng(p);
return {
id: index + 1,
name: `WP${index + 1}`,
lat: coords.lat,
lng: coords.lng,
alt: 500, //
speed: 600 //
};
});
this.$emit('draw-complete', latLngPoints);
} else {
this.$message.info('点数不足,航线已取消');
}
//
this.stopDrawing();
setTimeout(() => {
window.removeEventListener('contextmenu', this.preventContextMenu, true);
}, 200);
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
},
renderRouteWaypoints(waypoints, routeId = 'default') {
if (!waypoints || waypoints.length < 1) return;
const positions = [];
// 1.
waypoints.forEach((wp, index) => {
const lon = parseFloat(wp.lng);
const lat = parseFloat(wp.lat);
const pos = Cesium.Cartesian3.fromDegrees(lon, lat, parseFloat(wp.alt || 500));
positions.push(pos);
this.viewer.entities.add({
name: wp.name || `WP${index + 1}`,
position: pos,
properties: {
isMissionWaypoint: true,
routeId: routeId
},
point: {
pixelSize: 10,
color: Cesium.Color.WHITE,
outlineColor: Cesium.Color.fromCssColorString('#0078FF'),
outlineWidth: 3,
disableDepthTestDistance: Number.POSITIVE_INFINITY
},
label: {
text: wp.name || `WP${index + 1}`,
font: '12px MicroSoft YaHei',
pixelOffset: new Cesium.Cartesian2(0, -20),
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2,
style: Cesium.LabelStyle.FILL_AND_OUTLINE
}
});
});
// 2. 线 > 1
if (positions.length > 1) {
const routeEntity = this.viewer.entities.add({
id: `route-line-${routeId}`,
polyline: {
positions: positions,
width: 4,
material: new Cesium.PolylineDashMaterialProperty({
color: Cesium.Color.WHITE,
gapColor: Cesium.Color.BLACK,
dashLength: 20.0
}),
clampToGround: true
},
properties: { isMissionRouteLine: true, routeId: routeId }
});
this.allEntities.push({ id: `route-line-${routeId}`, entity: routeEntity, type: 'line' });
}
},
removeRouteById(routeId) {
// routeId
const entityList = this.viewer.entities.values;
for (let i = entityList.length - 1; i >= 0; i--) {
const entity = entityList[i];
// entity routeId
if (entity.properties && entity.properties.routeId) {
// Cesium getValue()
const id = entity.properties.routeId.getValue();
if (id === routeId) {
this.viewer.entities.remove(entity);
}
}
}
// allEntities
this.allEntities = this.allEntities.filter(item => item.id !== routeId);
},
checkCesiumLoaded() { checkCesiumLoaded() {
if (typeof Cesium === 'undefined') { if (typeof Cesium === 'undefined') {
console.error('Cesium未加载,请检查CDN链接'); console.error('Cesium未加载,请检查CDN链接');
@ -155,6 +353,23 @@ export default {
this.initScaleBar() this.initScaleBar()
console.log('Cesium离线二维地图已加载') console.log('Cesium离线二维地图已加载')
// 1.
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.handler.setInputAction((click) => {
// 线
if (this.isDrawing) return;
// 2.
const pickedObject = this.viewer.scene.pick(click.position);
if (Cesium.defined(pickedObject) && pickedObject.id) {
const entity = pickedObject.id;
// 3.
if (entity.properties && entity.properties.isMissionWaypoint) {
// name ID
this.$emit('open-waypoint-dialog', entity.name);
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
} catch (error) { } catch (error) {
console.error('地图错误:', error) console.error('地图错误:', error)
@ -625,6 +840,7 @@ export default {
this.drawingHandler.setInputAction(() => { this.drawingHandler.setInputAction(() => {
this.cancelDrawing(); this.cancelDrawing();
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK); }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}, },
finishRectangleDrawing() { finishRectangleDrawing() {
@ -1060,19 +1276,6 @@ export default {
return area return area
}, },
calculateRectangleArea(coordinates) {
const rect = coordinates.getValue ? coordinates.getValue() : coordinates
const width = Cesium.Cartesian3.distance(
Cesium.Cartesian3.fromRadians(rect.west, rect.north),
Cesium.Cartesian3.fromRadians(rect.east, rect.north)
)
const height = Cesium.Cartesian3.distance(
Cesium.Cartesian3.fromRadians(rect.west, rect.north),
Cesium.Cartesian3.fromRadians(rect.west, rect.south)
)
return width * height
},
// ================== ================== // ================== ==================
@ -1167,7 +1370,6 @@ export default {
} }
} }
}, },
clearAll() { clearAll() {
// 1. // 1.
if (this.allEntities && this.allEntities.length > 0) { if (this.allEntities && this.allEntities.length > 0) {

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

@ -32,8 +32,8 @@
v-for="route in routes" v-for="route in routes"
:key="route.id" :key="route.id"
class="route-item" class="route-item"
:class="{ selected: selectedRouteId === route.id }" :class="{ 'active': activeRouteIds.includes(route.id) }"
@click="handleSelectRoute(route)" @click="$emit('select-route', route)"
> >
<i class="el-icon-map-location"></i> <i class="el-icon-map-location"></i>
<div class="route-info"> <div class="route-info">
@ -222,9 +222,9 @@ export default {
type: Array, type: Array,
default: () => [] default: () => []
}, },
selectedRouteId: { activeRouteIds: {
type: [String, Number], type: Array,
default: null default: () => []
}, },
selectedRouteDetails: { selectedRouteDetails: {
type: Object, type: Object,
@ -261,11 +261,7 @@ export default {
this.$emit('hide') this.$emit('hide')
}, },
handleSelectRoute(route) { // 线
this.$emit('select-route', route)
},
// 线
handleCreateRoute() { handleCreateRoute() {
this.$emit('create-route') this.$emit('create-route')
}, },
@ -432,7 +428,7 @@ export default {
box-shadow: 0 2px 8px rgba(0, 138, 255, 0.15); box-shadow: 0 2px 8px rgba(0, 138, 255, 0.15);
} }
.route-item.selected { .route-item.active {
background: rgba(0, 138, 255, 0.15); background: rgba(0, 138, 255, 0.15);
border-color: rgba(0, 138, 255, 0.3); border-color: rgba(0, 138, 255, 0.3);
box-shadow: 0 2px 10px rgba(0, 138, 255, 0.25); box-shadow: 0 2px 10px rgba(0, 138, 255, 0.25);

4
ruoyi-ui/src/views/childRoom/TopHeader.vue

@ -342,9 +342,9 @@ export default {
} }
}, },
methods: { methods: {
selectTopNav(item) { /*selectTopNav(item) {
this.$emit('select-nav', item) this.$emit('select-nav', item)
}, },*/
// //
newPlan() { newPlan() {

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

@ -4,7 +4,8 @@
<!-- 地图背景 --> <!-- 地图背景 -->
<div id="gis-map-background" class="map-background"> <div id="gis-map-background" class="map-background">
<!-- cesiummap组件 --> <!-- cesiummap组件 -->
<cesiumMap :drawDomClick="drawDom"/> <cesiumMap ref="cesiumMap" :drawDomClick="drawDom" @draw-complete="handleMapDrawComplete"
@open-waypoint-dialog="handleOpenWaypointEdit" />
<div class="map-overlay-text"> <div class="map-overlay-text">
<i class="el-icon-location-outline text-3xl mb-2 block"></i> <i class="el-icon-location-outline text-3xl mb-2 block"></i>
<p>二维GIS地图区域</p> <p>二维GIS地图区域</p>
@ -21,6 +22,17 @@
<div class="red-dot"></div> <div class="red-dot"></div>
<i class="el-icon-s-unfold icon-inside"></i> <i class="el-icon-s-unfold icon-inside"></i>
</div> </div>
<el-dialog title="保存新航线" :visible.sync="showNameDialog" width="30%" :append-to-body="true">
<el-form label-width="80px">
<el-form-item label="航线名称">
<el-input v-model="newRouteName" placeholder="例如:航线一"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="showNameDialog = false"> </el-button>
<el-button type="primary" @click="confirmSaveNewRoute"> </el-button>
</div>
</el-dialog>
</div> </div>
<!-- 顶部导航栏 --> <!-- 顶部导航栏 -->
@ -30,7 +42,6 @@
:combat-time="combatTime" :combat-time="combatTime"
:astro-time="astroTime" :astro-time="astroTime"
:user-avatar="userAvatar" :user-avatar="userAvatar"
@select-nav="selectTopNav"
@save-plan="savePlan" @save-plan="savePlan"
@import-plan-file="importPlanFile" @import-plan-file="importPlanFile"
@import-acd="importACD" @import-acd="importACD"
@ -88,7 +99,7 @@
:is-hidden="isRightPanelHidden" :is-hidden="isRightPanelHidden"
:active-tab="activeRightTab" :active-tab="activeRightTab"
:routes="routes" :routes="routes"
:selected-route-id="selectedRouteId" :active-route-ids="activeRouteIds"
:selected-route-details="selectedRouteDetails" :selected-route-details="selectedRouteDetails"
:conflicts="conflicts" :conflicts="conflicts"
:conflict-count="conflictCount" :conflict-count="conflictCount"
@ -208,6 +219,8 @@ import LeftMenu from './LeftMenu'
import RightPanel from './RightPanel' import RightPanel from './RightPanel'
import BottomLeftPanel from './BottomLeftPanel' import BottomLeftPanel from './BottomLeftPanel'
import TopHeader from './TopHeader' import TopHeader from './TopHeader'
import { listRoutes, getRoutes, addRoutes } from "@/api/system/routes";
import { updateWaypoints } from "@/api/system/waypoints";
export default { export default {
name: 'MissionPlanningView', name: 'MissionPlanningView',
components: { components: {
@ -233,6 +246,9 @@ export default {
selectedRoute: null, selectedRoute: null,
showWaypointDialog: false, showWaypointDialog: false,
selectedWaypoint: null, selectedWaypoint: null,
showNameDialog: false,
newRouteName: '',
tempMapPoints: [],
// //
roomCode: 'JTF-7-ALPHA', roomCode: 'JTF-7-ALPHA',
@ -270,7 +286,7 @@ export default {
// //
activeRightTab: 'plan', activeRightTab: 'plan',
selectedRouteId: 101, activeRouteIds: [], // 线ID
selectedRouteDetails: null, selectedRouteDetails: null,
// //
@ -314,11 +330,7 @@ export default {
], ],
// 线 // 线
routes: [ routes: [],
{ id: 101, name: 'Alpha进场航线', points: 8, conflict: true },
{ id: 102, name: 'Beta巡逻航线', points: 6, conflict: false },
{ id: 103, name: '侦察覆盖区', points: 4, conflict: false },
],
// //
timeProgress: 45, timeProgress: 45,
@ -332,11 +344,11 @@ export default {
}; };
}, },
mounted() { mounted() {
this.getList();
// //
this.isMenuHidden = true; this.isMenuHidden = true;
// //
this.isRightPanelHidden = true; this.isRightPanelHidden = true;
// //
this.updateTime(); this.updateTime();
setInterval(this.updateTime, 1000); setInterval(this.updateTime, 1000);
@ -351,6 +363,25 @@ export default {
} }
}, },
methods: { methods: {
//
handleOpenWaypointEdit(wpName) {
// 1. 线
if (!this.selectedRouteDetails || !this.selectedRouteDetails.waypoints) {
this.$message.warning('请先在右侧列表选择一条航线');
return;
}
// 2.
const wpData = this.selectedRouteDetails.waypoints.find(item => item.name === wpName);
if (wpData) {
// 3.
this.selectedWaypoint = JSON.parse(JSON.stringify(wpData));
// 4.
this.showWaypointDialog = true;
}
else {
this.$message.info('未找到该航点的业务数据');
}
},
// 线 // 线
showOnlineMembersDialog() { showOnlineMembersDialog() {
this.showOnlineMembers = true; this.showOnlineMembers = true;
@ -385,41 +416,114 @@ export default {
this.$message.success('航线名称更新成功'); this.$message.success('航线名称更新成功');
} }
}, },
// 线 // 线
createRoute() { createRoute() {
this.$message.info('新建航线功能开发中...'); if (this.$refs.cesiumMap) {
this.$refs.cesiumMap.startMissionRouteDrawing();
this.$message.success('进入航线规划模式');
}
},
/** 从数据库拉取最新的航线列表数据 */
async getList() {
const query = { scenarioId: 1 };
try {
const response = await listRoutes(query);
if (response.code === 200) {
this.routes = response.rows.map(item => ({
id: item.id,
name: item.callSign,
points: item.waypoints ? item.waypoints.length : 0,
conflict: false
}));
}
} catch (error) {
this.$message.error("获取航线列表失败");
}
},
handleMapDrawComplete(points) {
if (!points || points.length < 2) {
this.$message.error('航点太少,无法生成航线');
this.drawDom = false;
return;
}
this.tempMapPoints = points; //
this.showNameDialog = true; //
},
/** 弹窗点击“确定”:正式将数据保存到后端数据库 */
async confirmSaveNewRoute() {
//
if (!this.newRouteName || this.newRouteName.trim() === '') {
this.$message.error('新增航线未命名,请输入名称后保存!');
return;
}
// Routes
const routeData = {
callSign: this.newRouteName,
scenarioId: 1, // ID
platformId: 1,
attributes: "{}",
waypoints: this.tempMapPoints.map((p, index) => ({
name: `WP${index + 1}`,
lat: p.lat,
lng: p.lng,
alt: 5000.0,
speed: 800.0,
startTime: 'K+00:00:00',
turnAngle: 0.0
}))
};
try {
// API
const response = await addRoutes(routeData);
if (response.code === 200) {
this.$message.success('航线及其航点已成功保存至数据库');
// UI
this.showNameDialog = false;
this.drawDom = false;
this.newRouteName = '';
this.tempMapPoints = [];
// 线
await this.getList();
}
} catch (error) {
console.error("保存航线失败:", error);
this.$message.error('保存失败,请检查后端服务');
}
}, },
// //
openWaypointDialog(waypoint) { openWaypointDialog(waypoint) {
this.selectedWaypoint = waypoint; this.selectedWaypoint = waypoint;
this.showWaypointDialog = true; this.showWaypointDialog = true;
}, },
updateWaypoint(updatedWaypoint) { /** 航点编辑保存:更新数据库并同步地图显示 */
// 1. 线 async updateWaypoint(updatedWaypoint) {
if (this.selectedRouteDetails && this.selectedRouteDetails.waypoints) { // 线
if (!this.selectedRouteDetails || !this.selectedRouteDetails.waypoints) return;
// 2. try {
const index = this.selectedRouteDetails.waypoints.indexOf(this.selectedWaypoint); const response = await updateWaypoints(updatedWaypoint);
if (response.code === 200) {
//
const index = this.selectedRouteDetails.waypoints.findIndex(p => p.id === updatedWaypoint.id);
if (index !== -1) { if (index !== -1) {
// 3. 使 splice // Entity
this.selectedRouteDetails.waypoints.splice(index, 1, updatedWaypoint); const oldName = this.selectedRouteDetails.waypoints[index].name;
const newName = updatedWaypoint.name;
// 4. 便 // 使 splice Vue UI
this.selectedWaypoint = updatedWaypoint; this.selectedRouteDetails.waypoints.splice(index, 1, { ...updatedWaypoint });
// 5.
if (this.$refs.cesiumMap) {
this.$refs.cesiumMap.updateWaypointGraphic(oldName, newName);
}
this.$message.success('航点更新成功'); this.showWaypointDialog = false;
} else { this.$message.success('航点信息已持久化至数据库');
// 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('更新失败:未找到对应航点');
} }
} }
} catch (error) {
console.error("更新航点失败:", error);
this.$message.error('数据库更新失败,请重试');
} }
}, },
updateTime() { updateTime() {
@ -774,23 +878,64 @@ export default {
const minutes = (val % 4) * 15; const minutes = (val % 4) * 15;
return `K+${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:00`; return `K+${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:00`;
}, },
/** 切换航线:实现多选/开关逻辑 */
async selectRoute(route) {
const index = this.activeRouteIds.indexOf(route.id);
// 线 // 线
selectRoute(route) { if (index > -1) {
this.selectedRouteId = route.id; this.activeRouteIds.splice(index, 1);
// if (this.$refs.cesiumMap) {
this.$refs.cesiumMap.removeRouteById(route.id);
}
if (this.selectedRouteDetails && this.selectedRouteDetails.id === route.id) {
if (this.activeRouteIds.length > 0) {
const lastId = this.activeRouteIds[this.activeRouteIds.length - 1];
try {
const res = await getRoutes(lastId);
if (res.code === 200 && res.data) {
this.selectedRouteDetails = {
id: res.data.id,
name: res.data.callSign,
waypoints: res.data.waypoints || []
};
}
} catch (e) {
console.error("回显剩余航线失败", e);
}
} else {
this.selectedRouteDetails = null;
}
}
this.$message.info(`已移除航线: ${route.name}`);
return;
}
// 线
try {
const response = await getRoutes(route.id);
if (response.code === 200 && response.data) {
const fullRouteData = response.data;
const waypoints = fullRouteData.waypoints || [];
this.activeRouteIds.push(route.id);
this.selectedRouteDetails = { this.selectedRouteDetails = {
name: route.name, id: fullRouteData.id,
waypoints: [ name: fullRouteData.callSign,
{ name: 'WP1', altitude: 5000, speed: '800km/h', eta: 'K+00:40:00' }, waypoints: waypoints
{ name: 'WP2', altitude: 6000, speed: '850km/h', eta: 'K+00:55:00' },
{ name: 'WP3', altitude: 5500, speed: '820km/h', eta: 'K+01:10:00' },
{ name: 'WP4', altitude: 5800, speed: '830km/h', eta: 'K+01:25:00' },
]
}; };
// this.openRouteDialog(route); if (waypoints.length > 0) {
//
if (this.$refs.cesiumMap) {
this.$refs.cesiumMap.renderRouteWaypoints(waypoints, route.id);
}
} else {
this.$message.warning('该航线暂无坐标数据,无法在地图展示');
}
}
} catch (error) {
console.error("获取航线详情失败:", error);
this.$message.error('无法加载该航线的详细航点数据');
}
}, },
addWaypoint() { addWaypoint() {
if (this.selectedRouteDetails) { if (this.selectedRouteDetails) {
const count = this.selectedRouteDetails.waypoints.length + 1; const count = this.selectedRouteDetails.waypoints.length + 1;
@ -805,9 +950,15 @@ export default {
}, },
cancelRoute() { cancelRoute() {
this.selectedRouteId = null; // 线
if (this.$refs.cesiumMap) {
this.activeRouteIds.forEach(id => {
this.$refs.cesiumMap.removeRouteById(id);
});
}
this.activeRouteIds = [];
this.selectedRouteDetails = null; this.selectedRouteDetails = null;
this.$message.info('已取消选中'); this.$message.info('已清空所有选中航线');
}, },
// //
@ -857,7 +1008,7 @@ export default {
height: 100%; height: 100%;
background: linear-gradient(135deg, #1a2f4b 0%, #2c3e50 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-size: cover;
background-position: center; background-position: center;
z-index: 1; z-index: 1;

2
ruoyi-ui/vue.config.js

@ -10,7 +10,7 @@ const CompressionPlugin = require('compression-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin')
const name = process.env.VUE_APP_TITLE || '若依管理系统' // 网页标题 const name = process.env.VUE_APP_TITLE || '若依管理系统' // 网页标题
const baseUrl = 'http://192.168.50.30:8080' // 后端接口 const baseUrl = 'http://127.0.0.1:8080' // 后端接口
const port = process.env.port || process.env.npm_config_port || 80 // 端口 const port = process.env.port || process.env.npm_config_port || 80 // 端口
// 定义 Cesium 源码路径 // 定义 Cesium 源码路径

Loading…
Cancel
Save