diff --git a/ruoyi-ui/src/views/childRoom/TopHeader.vue b/ruoyi-ui/src/views/childRoom/TopHeader.vue index 2b027a7..ffcca60 100644 --- a/ruoyi-ui/src/views/childRoom/TopHeader.vue +++ b/ruoyi-ui/src/views/childRoom/TopHeader.vue @@ -234,16 +234,22 @@
-
-
{{ $t('topHeader.info.combatTime') }}
-
- {{ combatTime }} - +
+
+ K 时 + {{ kTimeDisplay }} +
+
+ {{ $t('topHeader.info.combatTime') }} + + {{ combatTime }} + +
@@ -315,6 +321,11 @@ export default { type: String, default: 'K+01:30:45' }, + /** 格式化的 K 时基准时刻,如 "2025-02-06 08:00:00" */ + kTimeDisplay: { + type: String, + default: '' + }, astroTime: { type: String, default: '' @@ -877,9 +888,43 @@ export default { box-shadow: 0 4px 12px rgba(0, 138, 255, 0.1); } -.combat-info-group .info-box:nth-child(3) .info-value { - color: #409EFF; +/* 作战时间区域:显示 K 时 + 当前作战时间 */ +.combat-time-box { + min-width: 180px; +} +.combat-time-content { + gap: 6px; +} +.combat-k-time { + display: flex; + align-items: center; + gap: 6px; + font-size: 11px; + color: #666; +} +.combat-k-time .k-time-label { + color: #008aff; font-weight: 600; + flex-shrink: 0; +} +.combat-k-time .k-time-value { + color: #333; + font-weight: 500; +} +.combat-time-row { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; +} +.combat-time-row .info-label { + flex-shrink: 0; +} +.combat-time-value { + font-size: 14px; + color: #008aff; + font-weight: 700; + letter-spacing: 0.5px; } .combat-info-group .info-box:nth-child(4) .info-value { @@ -897,6 +942,12 @@ export default { color: #008aff; vertical-align: middle; } +.combat-time-box .set-k-hint { + opacity: 0.85; +} +.combat-time-box .set-k-hint:hover { + opacity: 1; +} .info-icon { font-size: 20px; diff --git a/ruoyi-ui/src/views/childRoom/index.vue b/ruoyi-ui/src/views/childRoom/index.vue index 4370af7..a1c8f6a 100644 --- a/ruoyi-ui/src/views/childRoom/index.vue +++ b/ruoyi-ui/src/views/childRoom/index.vue @@ -64,6 +64,7 @@ :room-code="roomCode" :online-count="onlineCount" :combat-time="combatTime" + :k-time-display="kTimeDisplay" :astro-time="astroTime" :room-detail="roomDetail" :can-set-k-time="canSetKTime" @@ -395,7 +396,7 @@ export default { // 作战信息 roomCode: 'JTF-7-ALPHA', onlineCount: 30, - combatTime: 'K+01:30:45', + combatTime: 'K+00:00:00', // 进入房间时固定作战时间,不随真实时间走 astroTime: '', roomDetail: null, showKTimeSetDialog: false, @@ -512,9 +513,9 @@ export default { seaPlatforms: [], groundPlatforms: [], - // 时间控制 - timeProgress: 45, - currentTime: 'K+01:15:30', + // 时间控制(与进入房间固定作战时间 K+00:00:00 一致) + timeProgress: 0, + currentTime: 'K+00:00:00', deductionMinutesFromK: 0, deductionWarnings: [], isPlaying: false, @@ -531,6 +532,19 @@ export default { this.updateTimeFromProgress(); }, immediate: true + }, + /** 点开航线时:用当前固定作战时间同步时间轴与图标位置 */ + activeRouteIds: { + handler(ids) { + if (!ids || ids.length === 0) return; + this.$nextTick(() => { + const minutes = this.combatTimeToMinutes(this.combatTime); + const { minMinutes, maxMinutes } = this.getDeductionTimeRange(); + const span = Math.max(0, maxMinutes - minMinutes) || 120; + const progress = Math.max(0, Math.min(100, ((minutes - minMinutes) / span) * 100)); + this.timeProgress = progress; + }); + } } }, computed: { @@ -552,6 +566,11 @@ export default { }, canSetKTime() { return this.isRoomOwner || this.isAdmin; + }, + /** 格式化的 K 时(基准时刻),供右上角显示 */ + kTimeDisplay() { + if (!this.roomDetail || !this.roomDetail.kAnchorTime) return ''; + return this.formatKTimeForPicker(this.roomDetail.kAnchorTime) || ''; } }, mounted() { @@ -1092,20 +1111,32 @@ export default { this.astroTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; }, + /** 是否有选中的航线用于推演(有则作战时间随推演时间轴变化) */ + hasDeductionRange() { + return this.activeRouteIds && this.activeRouteIds.length > 0; + }, updateCombatTime() { - if (this.roomDetail && this.roomDetail.kAnchorTime) { - const k0 = new Date(this.roomDetail.kAnchorTime).getTime(); - const now = Date.now(); - const offsetMs = now - k0; - const sign = offsetMs >= 0 ? '+' : '-'; - const absMs = Math.abs(offsetMs); - const hours = Math.floor(absMs / 3600000); - const minutes = Math.floor((absMs % 3600000) / 60000); - const seconds = Math.floor((absMs % 60000) / 1000); - this.combatTime = `K${sign}${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; - } else { - this.combatTime = '未设定'; + // 有推演航线时:作战时间 = 推演时间轴当前时间(由 updateTimeFromProgress 同步) + if (this.hasDeductionRange()) { + const sign = this.deductionMinutesFromK >= 0 ? '+' : '-'; + const absMin = Math.abs(Math.floor(this.deductionMinutesFromK)); + const hours = Math.floor(absMin / 60); + const minutes = absMin % 60; + this.combatTime = `K${sign}${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:00`; + return; } + // 无推演航线时:保持进入房间时的固定作战时间,不随真实时间变化 + this.combatTime = 'K+00:00:00'; + }, + /** 将作战时间字符串(如 K+01:30:00)解析为相对 K 的分钟数 */ + combatTimeToMinutes(str) { + if (!str || str === '未设定') return 0; + const m = String(str).match(/K([+-])(\d{1,2}):(\d{2})(?::(\d{2}))?/); + if (!m) return 0; + const sign = m[1] === '+' ? 1 : -1; + const h = parseInt(m[2], 10); + const min = parseInt(m[3], 10); + return sign * (h * 60 + min); }, getRoomDetail() { if (!this.currentRoomId) return; @@ -1709,6 +1740,10 @@ export default { const hours = Math.floor(absMin / 60); const minutes = absMin % 60; this.currentTime = `K${sign}${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:00`; + // 右上角作战时间与推演时间轴同步 + if (this.hasDeductionRange()) { + this.combatTime = this.currentTime; + } this.updateDeductionPositions(); },