Browse Source

4T功能

mh
cuitw 1 month ago
parent
commit
e310220fce
  1. 44
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/RoutesController.java
  2. 2
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java
  3. 17
      ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java
  4. 19
      ruoyi-ui/src/api/system/routes.js
  5. 104
      ruoyi-ui/src/views/cesiumMap/index.vue
  6. 36
      ruoyi-ui/src/views/childRoom/index.vue

44
ruoyi-admin/src/main/java/com/ruoyi/web/controller/RoutesController.java

@ -23,6 +23,7 @@ import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.dto.PlatformStyleDTO; import com.ruoyi.system.domain.dto.PlatformStyleDTO;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
/** /**
* 实体部署与航线Controller * 实体部署与航线Controller
@ -40,6 +41,10 @@ public class RoutesController extends BaseController
@Autowired @Autowired
private RedisTemplate<String, Object> redisTemplate; private RedisTemplate<String, Object> redisTemplate;
@Autowired
@Qualifier("fourTRedisTemplate")
private RedisTemplate<String, String> fourTRedisTemplate;
/** /**
* 保存平台样式到 Redis * 保存平台样式到 Redis
*/ */
@ -74,6 +79,45 @@ public class RoutesController extends BaseController
} }
/** /**
* 保存4T数据到 Redis按房间存储
*/
@PreAuthorize("@ss.hasPermi('system:routes:edit')")
@PostMapping("/save4TData")
public AjaxResult save4TData(@RequestBody java.util.Map<String, Object> params)
{
Object roomId = params.get("roomId");
Object data = params.get("data");
if (roomId == null || data == null) {
return AjaxResult.error("参数不完整");
}
String key = "room:" + String.valueOf(roomId) + ":4t";
fourTRedisTemplate.opsForValue().set(key, data.toString());
return success();
}
/**
* Redis 获取4T数据
*/
@PreAuthorize("@ss.hasPermi('system:routes:query')")
@GetMapping("/get4TData")
public AjaxResult get4TData(Long roomId)
{
if (roomId == null) {
return AjaxResult.error("房间ID不能为空");
}
String key = "room:" + String.valueOf(roomId) + ":4t";
String val = fourTRedisTemplate.opsForValue().get(key);
if (val != null && !val.isEmpty()) {
try {
return success(JSON.parseObject(val));
} catch (Exception e) {
return success(val);
}
}
return success();
}
/**
* 查询实体部署与航线列表 * 查询实体部署与航线列表
*/ */
@PreAuthorize("@ss.hasPermi('system:routes:list')") @PreAuthorize("@ss.hasPermi('system:routes:list')")

2
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java

@ -9,6 +9,7 @@ import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@ -32,6 +33,7 @@ import com.ruoyi.system.domain.SysCache;
public class CacheController public class CacheController
{ {
@Autowired @Autowired
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> redisTemplate; private RedisTemplate<String, String> redisTemplate;
private final static List<SysCache> caches = new ArrayList<SysCache>(); private final static List<SysCache> caches = new ArrayList<SysCache>();

17
ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java

@ -63,6 +63,23 @@ public class RedisConfig extends CachingConfigurerSupport
return template; return template;
} }
/**
* 纯字符串 RedisTemplate用于存储 4T JSON 字符串避免 FastJson 序列化问题
* 命名为 fourTRedisTemplate 避免与 Spring Boot 自带的 stringRedisTemplate 冲突
*/
@Bean("fourTRedisTemplate")
public RedisTemplate<String, String> fourTRedisTemplate(RedisConnectionFactory connectionFactory)
{
RedisTemplate<String, String> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
@Bean @Bean
public DefaultRedisScript<Long> limitScript() public DefaultRedisScript<Long> limitScript()
{ {

19
ruoyi-ui/src/api/system/routes.js

@ -60,3 +60,22 @@ export function getPlatformStyle(query) {
params: query params: query
}) })
} }
// 保存4T数据到Redis(禁用防重复提交,因拖拽/调整大小可能快速连续触发保存)
export function save4TData(data) {
return request({
url: '/system/routes/save4TData',
method: 'post',
data,
headers: { repeatSubmit: false }
})
}
// 从Redis获取4T数据
export function get4TData(params) {
return request({
url: '/system/routes/get4TData',
method: 'get',
params
})
}

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

@ -473,6 +473,8 @@ export default {
waypointDragging: null, waypointDragging: null,
waypointDragPending: null, waypointDragPending: null,
WAYPOINT_DRAG_THRESHOLD_PX: 8, WAYPOINT_DRAG_THRESHOLD_PX: 8,
/** 虚拟点(entry/exit)拖拽时的实时预览:{ routeId, dbId, position },拖拽时用 position 作为航点中心重算弧线 */
waypointDragPreview: null,
/** 拖拽航点前相机 enableInputs 状态,松开时恢复 */ /** 拖拽航点前相机 enableInputs 状态,松开时恢复 */
waypointDragCameraInputsEnabled: undefined, waypointDragCameraInputsEnabled: undefined,
lastClickWasDrag: false, lastClickWasDrag: false,
@ -1840,6 +1842,7 @@ export default {
//线 //线
renderRouteWaypoints(waypoints, routeId = 'default', platformId, platform, style) { renderRouteWaypoints(waypoints, routeId = 'default', platformId, platform, style) {
if (!waypoints || waypoints.length < 1) return; if (!waypoints || waypoints.length < 1) return;
this.waypointDragPreview = null;
// 线 // 线
const lineId = `route-line-${routeId}`; const lineId = `route-line-${routeId}`;
const existingLine = this.viewer.entities.getById(lineId); const existingLine = this.viewer.entities.getById(lineId);
@ -1909,11 +1912,12 @@ export default {
}); });
if (!this._routeWaypointIdsByRoute) this._routeWaypointIdsByRoute = {}; if (!this._routeWaypointIdsByRoute) this._routeWaypointIdsByRoute = {};
this._routeWaypointIdsByRoute[routeId] = waypoints.map((wp) => wp.id); this._routeWaypointIdsByRoute[routeId] = waypoints.map((wp) => wp.id);
// i 线 // i 线 45°
const isTurnWaypointWithArc = (i) => { const isTurnWaypointWithArc = (i) => {
if (i < 1 || i >= waypoints.length - 1) return false; if (i < 1 || i >= waypoints.length - 1) return false;
const wp = waypoints[i]; const wp = waypoints[i];
if (this.getWaypointRadius(wp) <= 0) return false; const effectiveAngle = this.getEffectiveTurnAngle(wp, i, waypoints.length);
if (this.getWaypointRadius({ ...wp, turnAngle: effectiveAngle }) <= 0) return false;
const nextPos = originalPositions[i + 1]; const nextPos = originalPositions[i + 1];
let nextLogical = nextPos; let nextLogical = nextPos;
if (this.isHoldWaypoint(waypoints[i + 1])) { if (this.isHoldWaypoint(waypoints[i + 1])) {
@ -1924,7 +1928,7 @@ export default {
} }
return !!nextLogical; return !!nextLogical;
}; };
// ++ // + entry/exit 线
waypoints.forEach((wp, index) => { waypoints.forEach((wp, index) => {
const pos = originalPositions[index]; const pos = originalPositions[index];
if (this.isHoldWaypoint(wp)) { if (this.isHoldWaypoint(wp)) {
@ -1956,6 +1960,8 @@ export default {
}); });
return; return;
} }
// 线 entry/exit dbId
if (isTurnWaypointWithArc(index)) return;
this.viewer.entities.add({ this.viewer.entities.add({
id: `wp_${routeId}_${wp.id}`, id: `wp_${routeId}_${wp.id}`,
name: wp.name || `WP${index + 1}`, name: wp.name || `WP${index + 1}`,
@ -2250,7 +2256,8 @@ export default {
}); });
lastPos = exit; lastPos = exit;
} else { } else {
const radius = this.getWaypointRadius(wp); const effectiveAngle = this.getEffectiveTurnAngle(wp, i, waypoints.length);
const radius = this.getWaypointRadius({ ...wp, turnAngle: effectiveAngle });
let nextLogical = nextPos; let nextLogical = nextPos;
if (nextPos && i + 1 < waypoints.length && this.isHoldWaypoint(waypoints[i + 1])) { if (nextPos && i + 1 < waypoints.length && this.isHoldWaypoint(waypoints[i + 1])) {
const holdParams = this.parseHoldParams(waypoints[i + 1]); const holdParams = this.parseHoldParams(waypoints[i + 1]);
@ -2259,22 +2266,42 @@ export default {
: this.getEllipseEntryPoint(originalPositions[i + 1], currPos, holdParams.semiMajor ?? 500, holdParams.semiMinor ?? 300, ((holdParams.headingDeg || 0) * Math.PI) / 180); : this.getEllipseEntryPoint(originalPositions[i + 1], currPos, holdParams.semiMajor ?? 500, holdParams.semiMinor ?? 300, ((holdParams.headingDeg || 0) * Math.PI) / 180);
} }
if (i < waypoints.length - 1 && radius > 0 && nextLogical) { if (i < waypoints.length - 1 && radius > 0 && nextLogical) {
const arcPoints = this.computeArcPositions(lastPos, currPos, nextLogical, radius); const lastPosCloned = Cesium.Cartesian3.clone(lastPos);
const currPosCloned = Cesium.Cartesian3.clone(currPos);
const nextLogicalCloned = Cesium.Cartesian3.clone(nextLogical);
const routeIdCloned = routeId;
const dbIdCloned = wp.id;
const that = this;
const getArcPoints = () => {
const center = (that.waypointDragPreview && that.waypointDragPreview.routeId === routeIdCloned && that.waypointDragPreview.dbId === dbIdCloned)
? that.waypointDragPreview.position : currPosCloned;
return that.computeArcPositions(lastPosCloned, center, nextLogicalCloned, radius);
};
// 线 CallbackProperty
this.viewer.entities.add({ this.viewer.entities.add({
id: `arc-line-${routeId}-${i}`, id: `arc-line-${routeId}-${i}`,
polyline: { positions: arcPoints, width: lineWidth, material: lineMaterial, arcType: Cesium.ArcType.NONE, zIndex: 20 }, show: false,
polyline: {
positions: new Cesium.CallbackProperty(getArcPoints, false),
width: lineWidth,
material: lineMaterial,
arcType: Cesium.ArcType.NONE,
zIndex: 20
},
properties: { routeId: routeId } properties: { routeId: routeId }
}); });
// 线dbId wp.id // CallbackProperty线
const wpName = wp.name || `WP${i + 1}`; const wpName = wp.name || `WP${i + 1}`;
const arcEntry = arcPoints[0]; [0, 1].forEach((idx) => {
const arcExit = arcPoints[arcPoints.length - 1];
[arcEntry, arcExit].forEach((pos, idx) => {
const suffix = idx === 0 ? '_entry' : '_exit'; const suffix = idx === 0 ? '_entry' : '_exit';
const getPos = () => {
const pts = getArcPoints();
return idx === 0 ? pts[0] : pts[pts.length - 1];
};
this.viewer.entities.add({ this.viewer.entities.add({
id: `wp_${routeId}_${wp.id}${suffix}`, id: `wp_${routeId}_${wp.id}${suffix}`,
name: wpName, name: wpName,
position: pos, position: new Cesium.CallbackProperty(getPos, false),
properties: { properties: {
isMissionWaypoint: true, isMissionWaypoint: true,
routeId: routeId, routeId: routeId,
@ -2298,6 +2325,7 @@ export default {
} }
}); });
}); });
const arcPoints = getArcPoints();
finalPathPositions.push(...arcPoints); finalPathPositions.push(...arcPoints);
lastPos = arcPoints[arcPoints.length - 1]; lastPos = arcPoints[arcPoints.length - 1];
} else { } else {
@ -2326,14 +2354,14 @@ export default {
} }
} }
}, },
/** 从各航点/弧线/盘旋实体取当前位置,供主航线折线实时连线(拖拽时动态跟随) */ /** 从各航点/弧线/盘旋实体取当前位置,供主航线折线实时连线(拖拽时动态跟随)。转弯处优先用弧线,不经过航点中心,只展示转弯半径 */
getRouteLinePositionsFromWaypointEntities(routeId) { getRouteLinePositionsFromWaypointEntities(routeId) {
const ids = this._routeWaypointIdsByRoute && this._routeWaypointIdsByRoute[routeId]; const ids = this._routeWaypointIdsByRoute && this._routeWaypointIdsByRoute[routeId];
if (!ids || !ids.length || !this.viewer) return null; if (!ids || !ids.length || !this.viewer) return null;
const now = Cesium.JulianDate.now(); const now = Cesium.JulianDate.now();
const positions = []; const positions = [];
for (let i = 0; i < ids.length; i++) { for (let i = 0; i < ids.length; i++) {
// 线线穿线 // 线
const holdEnt = this.viewer.entities.getById(`hold-line-${routeId}-${i}`); const holdEnt = this.viewer.entities.getById(`hold-line-${routeId}-${i}`);
if (holdEnt && holdEnt.polyline && holdEnt.polyline.positions) { if (holdEnt && holdEnt.polyline && holdEnt.polyline.positions) {
const arr = holdEnt.polyline.positions.getValue(now); const arr = holdEnt.polyline.positions.getValue(now);
@ -2342,14 +2370,7 @@ export default {
continue; continue;
} }
} }
const ent = this.viewer.entities.getById(`wp_${routeId}_${ids[i]}`); // 线线线线
if (ent && ent.position) {
const pos = ent.position.getValue(now);
if (pos) {
positions.push(Cesium.Cartesian3.clone(pos));
continue;
}
}
const arcEnt = this.viewer.entities.getById(`arc-line-${routeId}-${i}`); const arcEnt = this.viewer.entities.getById(`arc-line-${routeId}-${i}`);
if (arcEnt && arcEnt.polyline && arcEnt.polyline.positions) { if (arcEnt && arcEnt.polyline && arcEnt.polyline.positions) {
const arr = arcEnt.polyline.positions.getValue(now); const arr = arcEnt.polyline.positions.getValue(now);
@ -2358,10 +2379,23 @@ export default {
continue; continue;
} }
} }
const ent = this.viewer.entities.getById(`wp_${routeId}_${ids[i]}`);
if (ent && ent.position) {
const pos = ent.position.getValue(now);
if (pos) {
positions.push(Cesium.Cartesian3.clone(pos));
continue;
}
}
} }
return positions.length > 0 ? positions : null; return positions.length > 0 ? positions : null;
}, },
/** 渲染/路径用:非首尾航点默认转弯坡度 45°,首尾为 0 */
getEffectiveTurnAngle(wp, index, waypointsLength) {
if (index === 0 || index === waypointsLength - 1) return wp.turnAngle != null ? wp.turnAngle : 0;
return wp.turnAngle != null ? wp.turnAngle : 45;
},
// //
getWaypointRadius(wp) { getWaypointRadius(wp) {
const speed = wp.speed || 800; const speed = wp.speed || 800;
@ -2733,7 +2767,8 @@ export default {
? this.getCircleEntryPoint(originalPositions[i + 1], currPos, holdParams.radius) ? this.getCircleEntryPoint(originalPositions[i + 1], currPos, holdParams.radius)
: this.getEllipseEntryPoint(originalPositions[i + 1], currPos, holdParams.semiMajor ?? 500, holdParams.semiMinor ?? 300, ((holdParams.headingDeg || 0) * Math.PI) / 180); : this.getEllipseEntryPoint(originalPositions[i + 1], currPos, holdParams.semiMajor ?? 500, holdParams.semiMinor ?? 300, ((holdParams.headingDeg || 0) * Math.PI) / 180);
} }
const radius = this.getWaypointRadius(wp); const effectiveAngle = this.getEffectiveTurnAngle(wp, i, waypoints.length);
const radius = this.getWaypointRadius({ ...wp, turnAngle: effectiveAngle });
if (i < waypoints.length - 1 && radius > 0 && nextLogical) { if (i < waypoints.length - 1 && radius > 0 && nextLogical) {
const arcPoints = this.computeArcPositions(lastPos, currPos, nextLogical, radius); const arcPoints = this.computeArcPositions(lastPos, currPos, nextLogical, radius);
arcPoints.forEach(p => path.push(toLngLatAlt(p))); arcPoints.forEach(p => path.push(toLngLatAlt(p)));
@ -3187,7 +3222,12 @@ export default {
} }
const pos = this.getClickPositionWithHeight(movement.endPosition, this.waypointDragging.originalAlt); const pos = this.getClickPositionWithHeight(movement.endPosition, this.waypointDragging.originalAlt);
if (pos) { if (pos) {
this.waypointDragging.entity.position = pos; const entityId = this.waypointDragging.entity.id || '';
if (entityId.endsWith('_entry') || entityId.endsWith('_exit')) {
this.waypointDragPreview = { routeId: this.waypointDragging.routeId, dbId: this.waypointDragging.dbId, position: pos };
} else {
this.waypointDragging.entity.position = pos;
}
if (this.viewer.scene.requestRender) this.viewer.scene.requestRender(); if (this.viewer.scene.requestRender) this.viewer.scene.requestRender();
} }
} }
@ -3196,7 +3236,12 @@ export default {
if (this.waypointDragging) { if (this.waypointDragging) {
const pos = this.getClickPositionWithHeight(movement.endPosition, this.waypointDragging.originalAlt); const pos = this.getClickPositionWithHeight(movement.endPosition, this.waypointDragging.originalAlt);
if (pos) { if (pos) {
this.waypointDragging.entity.position = pos; const entityId = this.waypointDragging.entity.id || '';
if (entityId.endsWith('_entry') || entityId.endsWith('_exit')) {
this.waypointDragPreview = { routeId: this.waypointDragging.routeId, dbId: this.waypointDragging.dbId, position: pos };
} else {
this.waypointDragging.entity.position = pos;
}
if (this.viewer.scene.requestRender) this.viewer.scene.requestRender(); if (this.viewer.scene.requestRender) this.viewer.scene.requestRender();
} }
return; return;
@ -3229,7 +3274,15 @@ export default {
const entity = this.waypointDragging.entity; const entity = this.waypointDragging.entity;
const routeId = this.waypointDragging.routeId; const routeId = this.waypointDragging.routeId;
const dbId = this.waypointDragging.dbId; const dbId = this.waypointDragging.dbId;
const pos = entity.position.getValue(Cesium.JulianDate.now()); const entityId = entity.id || '';
let pos;
if (entityId.endsWith('_entry') || entityId.endsWith('_exit')) {
pos = this.waypointDragPreview && this.waypointDragPreview.routeId === routeId && this.waypointDragPreview.dbId === dbId
? this.waypointDragPreview.position : entity.position.getValue(Cesium.JulianDate.now());
this.waypointDragPreview = null;
} else {
pos = entity.position.getValue(Cesium.JulianDate.now());
}
const ll = this.cartesianToLatLngAlt(pos); const ll = this.cartesianToLatLngAlt(pos);
if (ll) { if (ll) {
this.$emit('waypoint-position-changed', { dbId, routeId, lat: ll.lat, lng: ll.lng, alt: ll.alt }); this.$emit('waypoint-position-changed', { dbId, routeId, lat: ll.lat, lng: ll.lng, alt: ll.alt });
@ -3237,6 +3290,7 @@ export default {
this.lastClickWasDrag = true; this.lastClickWasDrag = true;
this.waypointDragging = null; this.waypointDragging = null;
} }
this.waypointDragPreview = null;
this.waypointDragPending = null; this.waypointDragPending = null;
}, Cesium.ScreenSpaceEventType.LEFT_UP); }, Cesium.ScreenSpaceEventType.LEFT_UP);
} catch (error) { } catch (error) {

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

@ -367,6 +367,13 @@
@confirm="handleImportConfirm" @confirm="handleImportConfirm"
/> />
<!-- 4T悬浮窗THREAT/TASK/TARGET/TACTIC- 仅点击方案或4T时渲染 -->
<four-t-panel
v-if="show4TPanel && !screenshotMode"
:visible.sync="show4TPanel"
:room-id="currentRoomId"
/>
<el-dialog <el-dialog
title="新建方案" title="新建方案"
:visible.sync="showPlanNameDialog" :visible.sync="showPlanNameDialog"
@ -424,6 +431,7 @@ 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 FourTPanel from './FourTPanel'
import { listScenario, addScenario, delScenario } from "@/api/system/scenario"; import { listScenario, addScenario, delScenario } from "@/api/system/scenario";
import { listRoutes, getRoutes, addRoutes, updateRoutes, delRoutes, getPlatformStyle } from "@/api/system/routes"; import { listRoutes, getRoutes, addRoutes, updateRoutes, delRoutes, getPlatformStyle } from "@/api/system/routes";
import { updateWaypoints, addWaypoints, delWaypoints } from "@/api/system/waypoints"; import { updateWaypoints, addWaypoints, delWaypoints } from "@/api/system/waypoints";
@ -447,7 +455,8 @@ export default {
LeftMenu, LeftMenu,
RightPanel, RightPanel,
BottomLeftPanel, BottomLeftPanel,
TopHeader TopHeader,
FourTPanel
}, },
data() { data() {
return { return {
@ -515,6 +524,7 @@ export default {
// //
defaultMenuItems: [ defaultMenuItems: [
{ id: 'file', name: '方案', icon: 'plan' }, { id: 'file', name: '方案', icon: 'plan' },
{ id: '4t', name: '4T', icon: 'T' },
{ id: 'start', name: '冲突', icon: 'chongtu' }, { id: 'start', name: '冲突', icon: 'chongtu' },
{ id: 'insert', name: '平台', icon: 'el-icon-s-platform' }, { id: 'insert', name: '平台', icon: 'el-icon-s-platform' },
{ id: 'pattern', name: '空域', icon: 'ky' }, { id: 'pattern', name: '空域', icon: 'ky' },
@ -578,6 +588,8 @@ export default {
isRightPanelHidden: true, // isRightPanelHidden: true, //
// K // K
showKTimePopup: false, showKTimePopup: false,
// 4T4T
show4TPanel: false,
// / // /
showAirport: true, showAirport: true,
@ -2108,6 +2120,18 @@ export default {
} catch (e) { /* 解析失败保留默认 */ } } catch (e) { /* 解析失败保留默认 */ }
if (Array.isArray(arr) && arr.length > 0) { if (Array.isArray(arr) && arr.length > 0) {
const defaultMap = (this.defaultMenuItems || []).reduce((m, it) => { m[it.id] = it; return m }, {}) const defaultMap = (this.defaultMenuItems || []).reduce((m, it) => { m[it.id] = it; return m }, {})
const savedIds = new Set(arr.map(i => i.id))
// 4T defaultMenuItems
const defaultOrder = (this.defaultMenuItems || []).map(d => d.id)
defaultOrder.forEach(defId => {
if (!savedIds.has(defId) && defaultMap[defId]) {
const insertAfterId = defaultOrder[defaultOrder.indexOf(defId) - 1]
const refIdx = insertAfterId ? arr.findIndex(i => i.id === insertAfterId) : -1
const insertIdx = refIdx >= 0 ? refIdx + 1 : 0
arr.splice(insertIdx, 0, { ...defaultMap[defId] })
savedIds.add(defId)
}
})
this.menuItems = arr.map(item => { this.menuItems = arr.map(item => {
const def = defaultMap[item.id] const def = defaultMap[item.id]
if (def) return { ...item, name: def.name, icon: def.icon, action: def.action } if (def) return { ...item, name: def.name, icon: def.icon, action: def.action }
@ -2399,21 +2423,25 @@ export default {
this.handleMenuAction(item.action) this.handleMenuAction(item.action)
} }
// // 4T
if (item.id === 'file' || item.id === 'start' || item.id === 'insert') { if (item.id === 'file' || item.id === 'start' || item.id === 'insert' || item.id === '4t') {
this.drawDom = false; this.drawDom = false;
this.airspaceDrawDom = false; this.airspaceDrawDom = false;
} }
// //
if (item.id === 'file') { if (item.id === 'file') {
// // 4T
this.show4TPanel = true;
if (this.activeRightTab === 'plan' && !this.isRightPanelHidden) { if (this.activeRightTab === 'plan' && !this.isRightPanelHidden) {
this.isRightPanelHidden = true; this.isRightPanelHidden = true;
} else { } else {
this.activeRightTab = 'plan'; this.activeRightTab = 'plan';
this.isRightPanelHidden = false; this.isRightPanelHidden = false;
} }
} else if (item.id === '4t') {
// 4T4T
this.show4TPanel = !this.show4TPanel;
} else if (item.id === 'start') { } else if (item.id === 'start') {
// //
if (this.activeRightTab === 'conflict' && !this.isRightPanelHidden) { if (this.activeRightTab === 'conflict' && !this.isRightPanelHidden) {

Loading…
Cancel
Save