-
{{ $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();
},