Browse Source

导弹发射,导弹数据存redis

mh
menghao 1 month ago
parent
commit
631def63d0
  1. 58
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/RoutesController.java
  2. 18
      ruoyi-ui/src/api/system/routes.js
  3. 8
      ruoyi-ui/src/views/cesiumMap/ContextMenu.vue
  4. 419
      ruoyi-ui/src/views/cesiumMap/index.vue
  5. 23
      ruoyi-ui/src/views/childRoom/index.vue

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

@ -22,8 +22,12 @@ import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo; 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 com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import java.util.ArrayList;
/** /**
* 实体部署与航线Controller * 实体部署与航线Controller
* *
@ -74,6 +78,60 @@ public class RoutesController extends BaseController
} }
/** /**
* 获取导弹发射参数列表Redis房间+航线+平台为 key值为数组每项含 angle/distance/launchTimeMinutesFromK/startLng/startLat/platformHeadingDeg
*/
@PreAuthorize("@ss.hasPermi('system:routes:query')")
@GetMapping("/missile-params")
public AjaxResult getMissileParams(Long roomId, Long routeId, Long platformId)
{
if (roomId == null || routeId == null || platformId == null) {
return AjaxResult.error("参数不完整");
}
String key = "missile:params:" + roomId + ":" + routeId + ":" + platformId;
Object val = redisTemplate.opsForValue().get(key);
if (val == null) {
return success(new ArrayList<>());
}
String raw = val.toString();
if (raw.startsWith("[")) {
return success(JSON.parseArray(raw));
}
JSONObject single = JSON.parseObject(raw);
List<JSONObject> list = new ArrayList<>();
list.add(single);
return success(list);
}
/**
* 保存导弹发射参数到 Redis追加一条记录支持多次发射每条含 angle/distance/launchTimeMinutesFromK/startLng/startLat/platformHeadingDeg
*/
@PreAuthorize("@ss.hasPermi('system:routes:edit')")
@PostMapping("/missile-params")
public AjaxResult saveMissileParams(@RequestBody java.util.Map<String, Object> body)
{
Object roomId = body.get("roomId");
Object routeId = body.get("routeId");
Object platformId = body.get("platformId");
if (roomId == null || routeId == null || platformId == null) {
return AjaxResult.error("参数不完整");
}
String key = "missile:params:" + roomId + ":" + routeId + ":" + platformId;
Object val = redisTemplate.opsForValue().get(key);
JSONArray list = new JSONArray();
if (val != null) {
String raw = val.toString();
if (raw.startsWith("[")) {
list = JSON.parseArray(raw);
} else {
list.add(JSON.parseObject(raw));
}
}
list.add(body);
redisTemplate.opsForValue().set(key, list.toJSONString());
return success();
}
/**
* 查询实体部署与航线列表 * 查询实体部署与航线列表
*/ */
@PreAuthorize("@ss.hasPermi('system:routes:list')") @PreAuthorize("@ss.hasPermi('system:routes:list')")

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

@ -60,3 +60,21 @@ export function getPlatformStyle(query) {
params: query params: query
}) })
} }
// 获取导弹发射参数(Redis:房间+航线+平台为 key)
export function getMissileParams(params) {
return request({
url: '/system/routes/missile-params',
method: 'get',
params
})
}
// 保存导弹发射参数到 Redis
export function saveMissileParams(data) {
return request({
url: '/system/routes/missile-params',
method: 'post',
data
})
}

8
ruoyi-ui/src/views/cesiumMap/ContextMenu.vue

@ -35,6 +35,10 @@
<span class="menu-icon"></span> <span class="menu-icon"></span>
<span>威力区</span> <span>威力区</span>
</div> </div>
<div class="menu-item" @click="handleLaunchMissile">
<span class="menu-icon">🚀</span>
<span>发射导弹</span>
</div>
</div> </div>
<!-- 线段特有选项 --> <!-- 线段特有选项 -->
@ -441,6 +445,10 @@ export default {
this.$emit('power-zone') this.$emit('power-zone')
}, },
handleLaunchMissile() {
this.$emit('launch-missile')
},
toggleColorPicker(property) { toggleColorPicker(property) {
if (this.showColorPickerFor === property) { if (this.showColorPickerFor === property) {
this.showColorPickerFor = null this.showColorPickerFor = null

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

@ -45,6 +45,7 @@
@copy-route="handleCopyRouteFromMenu" @copy-route="handleCopyRouteFromMenu"
@edit-platform="openEditPlatformDialog" @edit-platform="openEditPlatformDialog"
@power-zone="openPowerZoneDialog" @power-zone="openPowerZoneDialog"
@launch-missile="openLaunchMissileDialog"
/> />
<!-- 定位弹窗 --> <!-- 定位弹窗 -->
@ -142,6 +143,43 @@
</span> </span>
</el-dialog> </el-dialog>
<!-- 导弹发射参数弹窗可拖动 -->
<el-dialog
ref="missileDialog"
title="导弹发射参数"
:visible.sync="missileDialogVisible"
:modal="false"
width="300px"
custom-class="missile-params-dialog dialog-draggable"
@open="onMissileDialogOpen"
>
<el-form :model="missileForm" label-width="80px" size="small">
<el-form-item label="角度(°)">
<el-input-number
v-model="missileForm.angle"
:min="-180"
:max="180"
controls-position="right"
style="width: 100%;"
@change="updateMissilePreview"
/>
</el-form-item>
<el-form-item label="距离(km)">
<el-input-number
v-model="missileForm.distance"
:min="1"
controls-position="right"
style="width: 100%;"
@change="updateMissilePreview"
/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="missileDialogVisible = false"> </el-button>
<el-button type="primary" @click="launchMissile"> </el-button>
</span>
</el-dialog>
<!-- 地图右下角比例尺 + 经纬度 --> <!-- 地图右下角比例尺 + 经纬度 -->
<div class="map-info-panel"> <div class="map-info-panel">
<div class="scale-bar" @click="handleScaleClick"> <div class="scale-bar" @click="handleScaleClick">
@ -169,7 +207,7 @@ import RadiusDialog from '../dialogs/RadiusDialog.vue'
import axios from 'axios' import axios from 'axios'
import request from '@/utils/request' import request from '@/utils/request'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import { savePlatformStyle, getRoutes, getPlatformStyle } from '@/api/system/routes' import { savePlatformStyle, getRoutes, getPlatformStyle, getMissileParams, saveMissileParams } from '@/api/system/routes'
export default { export default {
name: 'CesiumMap', name: 'CesiumMap',
@ -207,6 +245,16 @@ export default {
routeLocked: { routeLocked: {
type: Object, type: Object,
default: () => ({}) default: () => ({})
},
/** 推演时间轴:相对 K 的分钟数(用于导弹按时间轴显示/隐藏与位置插值) */
deductionTimeMinutes: {
type: Number,
default: 0
},
/** 当前房间 ID(用于 Redis 存储导弹参数 key:房间+航线+平台) */
roomId: {
type: [String, Number],
default: null
} }
}, },
watch: { watch: {
@ -231,6 +279,21 @@ export default {
handler(newVal) { handler(newVal) {
this.updateCoordinatesDisplay() this.updateCoordinatesDisplay()
} }
},
deductionTimeMinutes: {
immediate: true,
handler(val) {
this.currentDeductionMinutes = (val != null && Number.isFinite(Number(val))) ? Number(val) : 0
this.updateMissilesByTime()
}
},
missileDialogVisible(val) {
if (!val) {
this.clearMissilePreview()
if (this._missileDialogDragCleanup) {
this._missileDialogDragCleanup()
}
}
} }
}, },
data() { data() {
@ -288,6 +351,19 @@ export default {
radius: 1000, radius: 1000,
color: 'rgba(255, 0, 0, 0.3)' color: 'rgba(255, 0, 0, 0.3)'
}, },
missileDialogVisible: false,
missileForm: {
angle: 0,
distance: 100,
platformHeadingDeg: 0
},
/** 导弹预览:弹窗打开时显示的轨迹线与朝向图标,关闭时移除 */
missilePreviewLine: null,
missilePreviewIcon: null,
/** 导弹实体列表:每项 { entity, launchKMinutes, endKMinutes, startPoint, endPoint },用于按推演时间轴显示/隐藏与插值位置 */
missileEntities: [],
/** 当前推演时间(相对K的分钟数),从 prop 同步,供导弹 CallbackProperty 读取确保拿到最新值 */
currentDeductionMinutes: 0,
// 线routeId -> true / false // 线routeId -> true / false
routeLabelVisible: {}, routeLabelVisible: {},
// 线routeId -> { fontSize, fontColor } // 线routeId -> { fontSize, fontColor }
@ -2434,6 +2510,334 @@ export default {
} }
} }
}, },
openLaunchMissileDialog() {
this.contextMenu.visible = false
const entityData = this.contextMenu.entityData
if (entityData && entityData.entity) {
if (entityData.lat == null || entityData.lng == null) {
const pos = entityData.entity.position && entityData.entity.position.getValue
? entityData.entity.position.getValue(Cesium.JulianDate.now())
: null
if (pos) {
const ll = this.cartesianToLatLng(pos)
if (ll) {
entityData.lat = ll.lat
entityData.lng = ll.lng
}
}
}
const rot = entityData.entity.billboard && entityData.entity.billboard.rotation
const rotVal = rot && rot.getValue ? rot.getValue(Cesium.JulianDate.now()) : rot
if (rotVal != null && Number.isFinite(Number(rotVal))) {
const headingRad = Math.PI / 2 - Number(rotVal)
this.missileForm.platformHeadingDeg = ((headingRad * 180 / Math.PI) % 360 + 360) % 360
} else {
this.missileForm.platformHeadingDeg = 0
}
} else {
this.missileForm.platformHeadingDeg = 0
}
this.missileDialogVisible = true
this.$nextTick(() => {
this.updateMissilePreview()
this.fetchMissileParamsFromRedis()
})
},
/** 从 Redis 拉取当前房间+航线+平台的导弹参数并回填表单(支持返回数组时取最后一条作为默认) */
fetchMissileParamsFromRedis() {
if (!this.roomId || !this.contextMenu.entityData || this.contextMenu.entityData.type !== 'routePlatform') return
const routeId = this.contextMenu.entityData.routeId
const platformId = this.contextMenu.entityData.platformId != null ? this.contextMenu.entityData.platformId : 0
getMissileParams({ roomId: this.roomId, routeId, platformId }).then(res => {
let data = res.data
if (Array.isArray(data) && data.length > 0) data = data[data.length - 1]
if (data && (data.angle != null || data.distance != null)) {
if (data.angle != null) this.missileForm.angle = Number(data.angle)
if (data.distance != null) this.missileForm.distance = Number(data.distance)
this.updateMissilePreview()
}
}).catch(() => {})
},
/** 导弹参数弹窗打开后绑定标题栏拖动 */
onMissileDialogOpen() {
this.$nextTick(() => {
const dialog = document.querySelector('.missile-params-dialog')
const wrapper = dialog && dialog.closest('.el-dialog__wrapper')
if (!wrapper || !dialog) return
const header = wrapper.querySelector('.el-dialog__header')
if (!header) return
header.style.cursor = 'move'
let startX, startY, startLeft, startTop
const onMouseDown = (e) => {
if (e.button !== 0) return
startX = e.clientX
startY = e.clientY
const rect = wrapper.getBoundingClientRect()
startLeft = rect.left
startTop = rect.top
wrapper.style.position = 'fixed'
wrapper.style.left = startLeft + 'px'
wrapper.style.top = startTop + 'px'
wrapper.style.margin = '0'
document.addEventListener('mousemove', onMouseMove)
document.addEventListener('mouseup', onMouseUp)
}
const onMouseMove = (e) => {
const dx = e.clientX - startX
const dy = e.clientY - startY
wrapper.style.left = (startLeft + dx) + 'px'
wrapper.style.top = (startTop + dy) + 'px'
startLeft += dx
startTop += dy
startX = e.clientX
startY = e.clientY
}
const onMouseUp = () => {
document.removeEventListener('mousemove', onMouseMove)
document.removeEventListener('mouseup', onMouseUp)
}
header.addEventListener('mousedown', onMouseDown)
this._missileDialogDragCleanup = () => {
header.removeEventListener('mousedown', onMouseDown)
header.style.cursor = ''
delete this._missileDialogDragCleanup
}
})
},
/** 清除导弹预览(轨迹线 + 朝向图标) */
clearMissilePreview() {
if (this.viewer && this.viewer.entities) {
if (this.missilePreviewLine) {
this.viewer.entities.remove(this.missilePreviewLine)
this.missilePreviewLine = null
}
if (this.missilePreviewIcon) {
this.viewer.entities.remove(this.missilePreviewIcon)
this.missilePreviewIcon = null
}
if (this.viewer.scene) this.viewer.scene.requestRender()
}
},
/** 根据当前角度、距离与平台位置/航向更新导弹预览(弹窗打开时显示) */
updateMissilePreview() {
if (!this.missileDialogVisible || !this.viewer || !this.viewer.entities) {
this.clearMissilePreview()
return
}
const entityData = this.contextMenu.entityData
if (!entityData || entityData.lat == null || entityData.lng == null) {
this.clearMissilePreview()
return
}
const platformHeadingDeg = Number(this.missileForm.platformHeadingDeg) || 0
const angle = Number(this.missileForm.angle) || 0
const distance = Number(this.missileForm.distance) || 100
const actualBearingDeg = ((platformHeadingDeg + angle) % 360 + 360) % 360
const brng = Cesium.Math.toRadians(actualBearingDeg)
const R = 6371000
const d = distance * 1000
const lat1 = Cesium.Math.toRadians(Number(entityData.lat))
const lon1 = Cesium.Math.toRadians(Number(entityData.lng))
const lat2 = Math.asin(Math.sin(lat1) * Math.cos(d / R) + Math.cos(lat1) * Math.sin(d / R) * Math.cos(brng))
const lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(d / R) * Math.cos(lat1), Math.cos(d / R) - Math.sin(lat1) * Math.sin(lat2))
const startPoint = Cesium.Cartesian3.fromDegrees(Number(entityData.lng), Number(entityData.lat), 1000)
const endPoint = Cesium.Cartesian3.fromDegrees(Cesium.Math.toDegrees(lon2), Cesium.Math.toDegrees(lat2), 1000)
this.clearMissilePreview()
this.missilePreviewLine = this.viewer.entities.add({
polyline: {
positions: [startPoint, endPoint],
width: 3,
material: Cesium.Color.PURPLE.withAlpha(0.8)
},
show: true
})
this.missilePreviewIcon = this.viewer.entities.add({
position: startPoint,
billboard: {
image: require('@/assets/images/missile.png'),
width: 28,
height: 28,
rotation: -brng
},
show: true
})
if (this.viewer.scene) this.viewer.scene.requestRender()
},
launchMissile() {
this.missileDialogVisible = false
this.clearMissilePreview()
const angle = this.missileForm.angle
const distance = this.missileForm.distance
const entityData = this.contextMenu.entityData
if (!entityData) {
this.$message.error('无法获取发射平台信息')
return
}
if (entityData.lat == null || entityData.lng == null) {
if (entityData.entity && entityData.entity.position) {
const pos = entityData.entity.position.getValue(Cesium.JulianDate.now())
if (pos) {
const ll = this.cartesianToLatLng(pos)
if (ll) {
entityData.lat = ll.lat
entityData.lng = ll.lng
}
}
}
}
if (entityData.lat == null || entityData.lng == null) {
this.$message.error('无法获取平台位置信息')
return
}
const launchK = Number.isFinite(Number(this.deductionTimeMinutes)) ? Number(this.deductionTimeMinutes) : 0
if (this.roomId != null && entityData.routeId != null) {
const platformId = entityData.platformId != null ? entityData.platformId : 0
saveMissileParams({
roomId: this.roomId,
routeId: entityData.routeId,
platformId,
angle,
distance,
launchTimeMinutesFromK: launchK,
startLng: entityData.lng,
startLat: entityData.lat,
platformHeadingDeg: Number(this.missileForm.platformHeadingDeg) || 0
}).catch(() => {})
}
const platformHeadingDeg = Number(this.missileForm.platformHeadingDeg) || 0
const actualBearingDeg = ((platformHeadingDeg + Number(angle)) % 360 + 360) % 360
const R = 6371000
const d = Number(distance) * 1000
const brng = Cesium.Math.toRadians(actualBearingDeg)
const lat1 = Cesium.Math.toRadians(Number(entityData.lat))
const lon1 = Cesium.Math.toRadians(Number(entityData.lng))
const lat2 = Math.asin(Math.sin(lat1) * Math.cos(d / R) +
Math.cos(lat1) * Math.sin(d / R) * Math.cos(brng))
const lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(d / R) * Math.cos(lat1),
Math.cos(d / R) - Math.sin(lat1) * Math.sin(lat2))
const endLat = Cesium.Math.toDegrees(lat2)
const endLng = Cesium.Math.toDegrees(lon2)
const durationSec = d / 1000
const durationMinutes = durationSec / 60
const endK = launchK + durationMinutes
const startPoint = Cesium.Cartesian3.fromDegrees(Number(entityData.lng), Number(entityData.lat), 1000)
const endPoint = Cesium.Cartesian3.fromDegrees(endLng, endLat, 0)
const headingRad = brng
const billboardRotation = -headingRad
const entity = this.viewer.entities.add({
position: startPoint,
show: false,
billboard: {
image: require('@/assets/images/missile.png'),
width: 32,
height: 32,
rotation: billboardRotation
}
})
this.missileEntities.push({ entity, launchKMinutes: launchK, endKMinutes: endK, startPoint, endPoint })
this.updateMissilesByTime()
},
/** 根据当前推演时间直接更新所有导弹的显隐和位置。可由父组件调用并传入当前分钟数 minutesFromK,保证与时间轴一致 */
updateMissilesByTime(minutesFromK) {
if (!this.viewer || !this.viewer.entities || !this.missileEntities.length) return
const curNum = (minutesFromK !== undefined && minutesFromK !== null && Number.isFinite(Number(minutesFromK)))
? Number(minutesFromK)
: ((this.deductionTimeMinutes != null && Number.isFinite(Number(this.deductionTimeMinutes)))
? Number(this.deductionTimeMinutes)
: this.currentDeductionMinutes)
const cur = Number.isFinite(curNum) ? curNum : 0
this.missileEntities.forEach(({ entity, launchKMinutes, endKMinutes, startPoint, endPoint }) => {
if (cur < launchKMinutes) {
entity.show = false
entity.position = new Cesium.ConstantPositionProperty(startPoint)
} else if (cur > endKMinutes) {
entity.show = false
entity.position = new Cesium.ConstantPositionProperty(endPoint)
} else {
entity.show = true
const span = endKMinutes - launchKMinutes
const t = span <= 0 ? 1 : Math.max(0, Math.min(1, (cur - launchKMinutes) / span))
const pos = Cesium.Cartesian3.lerp(startPoint, endPoint, t, new Cesium.Cartesian3())
entity.position = new Cesium.ConstantPositionProperty(pos)
}
})
if (this.viewer.scene) this.viewer.scene.requestRender()
},
/**
* Redis 加载指定房间+航线列表的导弹数据并创建实体会先清空当前导弹实体
* routePlatforms: [{ routeId, platformId }]
*/
async loadMissilesFromRedis(roomId, routePlatforms) {
if (!this.viewer || !this.viewer.entities || !roomId || !Array.isArray(routePlatforms) || routePlatforms.length === 0) return
while (this.missileEntities.length) {
const { entity } = this.missileEntities.pop()
this.viewer.entities.remove(entity)
}
for (const { routeId, platformId } of routePlatforms) {
try {
const res = await getMissileParams({ roomId, routeId, platformId: platformId != null ? platformId : 0 })
let data = res.data
if (!data) continue
const arr = Array.isArray(data) ? data : [data]
for (const item of arr) {
const launchK = item.launchTimeMinutesFromK != null ? Number(item.launchTimeMinutesFromK) : null
const startLng = item.startLng != null ? Number(item.startLng) : null
const startLat = item.startLat != null ? Number(item.startLat) : null
if (launchK == null || startLng == null || startLat == null) continue
const angle = Number(item.angle) || 0
const distance = Number(item.distance) || 100
const platformHeadingDeg = Number(item.platformHeadingDeg) || 0
const actualBearingDeg = ((platformHeadingDeg + angle) % 360 + 360) % 360
const R = 6371000
const d = distance * 1000
const brng = Cesium.Math.toRadians(actualBearingDeg)
const lat1 = Cesium.Math.toRadians(startLat)
const lon1 = Cesium.Math.toRadians(startLng)
const lat2 = Math.asin(Math.sin(lat1) * Math.cos(d / R) + Math.cos(lat1) * Math.sin(d / R) * Math.cos(brng))
const lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(d / R) * Math.cos(lat1), Math.cos(d / R) - Math.sin(lat1) * Math.sin(lat2))
const endLng = Cesium.Math.toDegrees(lon2)
const endLat = Cesium.Math.toDegrees(lat2)
const durationSec = d / 1000
const durationMinutes = durationSec / 60
const endK = launchK + durationMinutes
const startPoint = Cesium.Cartesian3.fromDegrees(startLng, startLat, 1000)
const endPoint = Cesium.Cartesian3.fromDegrees(endLng, endLat, 0)
const billboardRotation = -brng
const entity = this.viewer.entities.add({
position: startPoint,
show: false,
billboard: {
image: require('@/assets/images/missile.png'),
width: 32,
height: 32,
rotation: billboardRotation
}
})
this.missileEntities.push({ entity, launchKMinutes: launchK, endKMinutes: endK, startPoint, endPoint })
}
} catch (e) {
// ignore per-platform errors
}
}
this.updateMissilesByTime(this.deductionTimeMinutes != null ? this.deductionTimeMinutes : 0)
if (this.viewer.scene) this.viewer.scene.requestRender()
},
checkCesiumLoaded() { checkCesiumLoaded() {
if (typeof Cesium === 'undefined') { if (typeof Cesium === 'undefined') {
console.error('Cesium未加载,请检查CDN链接'); console.error('Cesium未加载,请检查CDN链接');
@ -2791,6 +3195,19 @@ export default {
platformName, platformName,
labelVisible: this.routeLabelVisible[routeId] !== false labelVisible: this.routeLabelVisible[routeId] !== false
} }
// 便使
const now = Cesium.JulianDate.now();
if (pickedEntity.position) {
const pos = pickedEntity.position.getValue(now);
if (pos) {
const ll = this.cartesianToLatLng(pos);
if (ll) {
entityData.lat = ll.lat;
entityData.lng = ll.lng;
}
}
}
} }
if (!entityData) { if (!entityData) {
// //

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

@ -14,6 +14,8 @@
:scaleConfig="scaleConfig" :scaleConfig="scaleConfig"
:coordinateFormat="coordinateFormat" :coordinateFormat="coordinateFormat"
:route-locked="routeLocked" :route-locked="routeLocked"
:deduction-time-minutes="deductionMinutesFromK"
:room-id="currentRoomId"
@draw-complete="handleMapDrawComplete" @draw-complete="handleMapDrawComplete"
@route-lock-changed="handleRouteLockChanged" @route-lock-changed="handleRouteLockChanged"
@drawing-points-update="missionDrawingPointsCount = $event" @drawing-points-update="missionDrawingPointsCount = $event"
@ -639,6 +641,8 @@ export default {
isPlaying: false, isPlaying: false,
playbackSpeed: 1, playbackSpeed: 1,
playbackInterval: null, playbackInterval: null,
/** 导弹从 Redis 加载过的房间+航线组合 key,避免重复加载 */
_missilesLoadKey: null,
// //
userAvatar: 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png', userAvatar: 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png',
@ -2220,6 +2224,25 @@ export default {
// 线 // 线
this.combatTime = this.currentTime; this.combatTime = this.currentTime;
this.updateDeductionPositions(); this.updateDeductionPositions();
// 线+线 Redis
const roomId = this.currentRoomId;
const routeIds = (this.activeRouteIds || []).slice().sort((a, b) => (a - b));
if (roomId != null && routeIds.length > 0 && this.$refs.cesiumMap && typeof this.$refs.cesiumMap.loadMissilesFromRedis === 'function') {
const loadKey = roomId + '-' + routeIds.join(',');
if (this._missilesLoadKey !== loadKey) {
this._missilesLoadKey = loadKey;
const routePlatforms = this.routes
.filter(r => routeIds.includes(r.id))
.map(r => ({ routeId: r.id, platformId: r.platformId != null ? r.platformId : 0 }));
if (routePlatforms.length > 0) {
this.$refs.cesiumMap.loadMissilesFromRedis(roomId, routePlatforms);
}
}
}
//
if (this.$refs.cesiumMap && typeof this.$refs.cesiumMap.updateMissilesByTime === 'function') {
this.$refs.cesiumMap.updateMissilesByTime(this.deductionMinutesFromK);
}
}, },
/** 仅针对当前展示的航线(activeRouteIds):从这些航线的航点中取推演时间范围(相对 K 的分钟数) */ /** 仅针对当前展示的航线(activeRouteIds):从这些航线的航点中取推演时间范围(相对 K 的分钟数) */

Loading…
Cancel
Save