refactor: 移动电源操作倒计时逻辑至全局组件 GlobalPowerCountdown.vue[待测试]
This commit is contained in:
@@ -8,6 +8,7 @@ import AppLayout from './components/AppLayout.vue'
|
|||||||
import TitleBar from './components/TitleBar.vue'
|
import TitleBar from './components/TitleBar.vue'
|
||||||
import UpdateModal from './components/UpdateModal.vue'
|
import UpdateModal from './components/UpdateModal.vue'
|
||||||
import DevDebugPanel from './components/DevDebugPanel.vue'
|
import DevDebugPanel from './components/DevDebugPanel.vue'
|
||||||
|
import GlobalPowerCountdown from './components/GlobalPowerCountdown.vue'
|
||||||
import zhCN from 'ant-design-vue/es/locale/zh_CN'
|
import zhCN from 'ant-design-vue/es/locale/zh_CN'
|
||||||
import { logger } from '@/utils/logger'
|
import { logger } from '@/utils/logger'
|
||||||
|
|
||||||
@@ -49,6 +50,9 @@ onMounted(() => {
|
|||||||
|
|
||||||
<!-- 开发环境调试面板 -->
|
<!-- 开发环境调试面板 -->
|
||||||
<DevDebugPanel />
|
<DevDebugPanel />
|
||||||
|
|
||||||
|
<!-- 全局电源倒计时弹窗 -->
|
||||||
|
<GlobalPowerCountdown />
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
307
frontend/src/components/GlobalPowerCountdown.vue
Normal file
307
frontend/src/components/GlobalPowerCountdown.vue
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 电源操作倒计时全屏弹窗 -->
|
||||||
|
<div v-if="visible" class="power-countdown-overlay">
|
||||||
|
<div class="power-countdown-container">
|
||||||
|
<div class="countdown-content">
|
||||||
|
<div class="warning-icon">⚠️</div>
|
||||||
|
<h2 class="countdown-title">{{ title }}</h2>
|
||||||
|
<p class="countdown-message">{{ message }}</p>
|
||||||
|
<div class="countdown-timer" v-if="countdown !== undefined">
|
||||||
|
<span class="countdown-number">{{ countdown }}</span>
|
||||||
|
<span class="countdown-unit">秒</span>
|
||||||
|
</div>
|
||||||
|
<div class="countdown-timer" v-else>
|
||||||
|
<span class="countdown-text">等待后端倒计时...</span>
|
||||||
|
</div>
|
||||||
|
<a-progress
|
||||||
|
v-if="countdown !== undefined"
|
||||||
|
:percent="Math.max(0, Math.min(100, (60 - countdown) / 60 * 100))"
|
||||||
|
:show-info="false"
|
||||||
|
:stroke-color="(countdown || 0) <= 10 ? '#ff4d4f' : '#1890ff'"
|
||||||
|
:stroke-width="8"
|
||||||
|
class="countdown-progress"
|
||||||
|
/>
|
||||||
|
<div class="countdown-actions">
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
@click="handleCancel"
|
||||||
|
class="cancel-button"
|
||||||
|
>
|
||||||
|
取消操作
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
|
import { Service } from '@/api'
|
||||||
|
import { ExternalWSHandlers } from '@/composables/useWebSocket'
|
||||||
|
|
||||||
|
// 响应式状态
|
||||||
|
const visible = ref(false)
|
||||||
|
const title = ref('')
|
||||||
|
const message = ref('')
|
||||||
|
const countdown = ref<number | undefined>(undefined)
|
||||||
|
|
||||||
|
// 倒计时定时器
|
||||||
|
let countdownTimer: ReturnType<typeof setInterval> | null = null
|
||||||
|
|
||||||
|
// 启动倒计时
|
||||||
|
const startCountdown = (data: any) => {
|
||||||
|
console.log('[GlobalPowerCountdown] 启动倒计时:', data)
|
||||||
|
|
||||||
|
// 清除之前的计时器
|
||||||
|
if (countdownTimer) {
|
||||||
|
clearInterval(countdownTimer)
|
||||||
|
countdownTimer = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示倒计时弹窗
|
||||||
|
visible.value = true
|
||||||
|
|
||||||
|
// 设置倒计时数据,从60秒开始
|
||||||
|
title.value = data.title || '电源操作倒计时'
|
||||||
|
message.value = data.message || '程序将在倒计时结束后执行电源操作'
|
||||||
|
countdown.value = 60
|
||||||
|
|
||||||
|
// 启动每秒倒计时
|
||||||
|
countdownTimer = setInterval(() => {
|
||||||
|
if (countdown.value !== undefined && countdown.value > 0) {
|
||||||
|
countdown.value--
|
||||||
|
console.log('[GlobalPowerCountdown] 倒计时:', countdown.value)
|
||||||
|
|
||||||
|
// 倒计时结束
|
||||||
|
if (countdown.value <= 0) {
|
||||||
|
if (countdownTimer) {
|
||||||
|
clearInterval(countdownTimer)
|
||||||
|
countdownTimer = null
|
||||||
|
}
|
||||||
|
visible.value = false
|
||||||
|
console.log('[GlobalPowerCountdown] 倒计时结束,弹窗关闭')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消电源操作
|
||||||
|
const handleCancel = async () => {
|
||||||
|
console.log('[GlobalPowerCountdown] 用户取消电源操作')
|
||||||
|
|
||||||
|
// 清除倒计时器
|
||||||
|
if (countdownTimer) {
|
||||||
|
clearInterval(countdownTimer)
|
||||||
|
countdownTimer = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭倒计时弹窗
|
||||||
|
visible.value = false
|
||||||
|
|
||||||
|
// 调用取消电源操作的API
|
||||||
|
try {
|
||||||
|
await Service.cancelPowerTaskApiDispatchCancelPowerPost()
|
||||||
|
console.log('[GlobalPowerCountdown] 电源操作已取消')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[GlobalPowerCountdown] 取消电源操作失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理Main消息的函数
|
||||||
|
const handleMainMessage = (message: any) => {
|
||||||
|
if (!message || typeof message !== 'object') return
|
||||||
|
|
||||||
|
const { type, data } = message
|
||||||
|
|
||||||
|
if (type === 'Message' && data && data.type === 'Countdown') {
|
||||||
|
console.log('[GlobalPowerCountdown] 收到倒计时消息:', data)
|
||||||
|
startCountdown(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理函数
|
||||||
|
const cleanup = () => {
|
||||||
|
if (countdownTimer) {
|
||||||
|
clearInterval(countdownTimer)
|
||||||
|
countdownTimer = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生命周期
|
||||||
|
onMounted(() => {
|
||||||
|
// 替换全局Main消息处理器,添加倒计时处理
|
||||||
|
const originalMainHandler = ExternalWSHandlers.mainMessage
|
||||||
|
|
||||||
|
ExternalWSHandlers.mainMessage = (message: any) => {
|
||||||
|
// 先调用原有的处理逻辑
|
||||||
|
if (typeof originalMainHandler === 'function') {
|
||||||
|
try {
|
||||||
|
originalMainHandler(message)
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('[GlobalPowerCountdown] 原有Main消息处理器出错:', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 然后处理倒计时消息
|
||||||
|
handleMainMessage(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('[GlobalPowerCountdown] 全局电源倒计时组件已挂载')
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
cleanup()
|
||||||
|
console.log('[GlobalPowerCountdown] 全局电源倒计时组件已卸载')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 电源操作倒计时全屏弹窗样式 */
|
||||||
|
.power-countdown-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.8);
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
z-index: 10000; /* 确保在所有其他内容之上 */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
animation: fadeIn 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.power-countdown-container {
|
||||||
|
background: var(--ant-color-bg-container);
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 48px;
|
||||||
|
box-shadow: 0 24px 48px rgba(0, 0, 0, 0.2);
|
||||||
|
text-align: center;
|
||||||
|
max-width: 500px;
|
||||||
|
width: 90%;
|
||||||
|
animation: slideIn 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown-content .warning-icon {
|
||||||
|
font-size: 64px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
display: block;
|
||||||
|
animation: pulse 2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown-title {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--ant-color-text);
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown-message {
|
||||||
|
font-size: 16px;
|
||||||
|
color: var(--ant-color-text-secondary);
|
||||||
|
margin: 0 0 32px 0;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown-timer {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown-number {
|
||||||
|
font-size: 72px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--ant-color-primary);
|
||||||
|
line-height: 1;
|
||||||
|
margin-right: 8px;
|
||||||
|
font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown-unit {
|
||||||
|
font-size: 24px;
|
||||||
|
color: var(--ant-color-text-secondary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown-text {
|
||||||
|
font-size: 24px;
|
||||||
|
color: var(--ant-color-text-secondary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown-progress {
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-button {
|
||||||
|
padding: 12px 32px;
|
||||||
|
height: auto;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 动画效果 */
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-20px) scale(0.95);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0) scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0%, 100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式 - 移动端适配 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.power-countdown-container {
|
||||||
|
padding: 32px 24px;
|
||||||
|
margin: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown-title {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown-number {
|
||||||
|
font-size: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown-unit {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown-content .warning-icon {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -112,43 +112,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|
||||||
<!-- 电源操作倒计时全屏弹窗 -->
|
<!-- 电源操作倒计时弹窗已移至全局组件 GlobalPowerCountdown.vue -->
|
||||||
<div v-if="powerCountdownVisible" class="power-countdown-overlay">
|
|
||||||
<div class="power-countdown-container">
|
|
||||||
<div class="countdown-content">
|
|
||||||
<div class="warning-icon">⚠️</div>
|
|
||||||
<h2 class="countdown-title">{{ powerCountdownData.title || `${getPowerActionText(powerAction)}倒计时` }}</h2>
|
|
||||||
<p class="countdown-message">
|
|
||||||
{{ powerCountdownData.message || `程序将在倒计时结束后执行 ${getPowerActionText(powerAction)} 操作` }}
|
|
||||||
</p>
|
|
||||||
<div class="countdown-timer" v-if="powerCountdownData.countdown !== undefined">
|
|
||||||
<span class="countdown-number">{{ powerCountdownData.countdown }}</span>
|
|
||||||
<span class="countdown-unit">秒</span>
|
|
||||||
</div>
|
|
||||||
<div class="countdown-timer" v-else>
|
|
||||||
<span class="countdown-text">等待后端倒计时...</span>
|
|
||||||
</div>
|
|
||||||
<a-progress
|
|
||||||
v-if="powerCountdownData.countdown !== undefined"
|
|
||||||
:percent="Math.max(0, Math.min(100, (60 - powerCountdownData.countdown) / 60 * 100))"
|
|
||||||
:show-info="false"
|
|
||||||
:stroke-color="(powerCountdownData.countdown || 0) <= 10 ? '#ff4d4f' : '#1890ff'"
|
|
||||||
:stroke-width="8"
|
|
||||||
class="countdown-progress"
|
|
||||||
/>
|
|
||||||
<div class="countdown-actions">
|
|
||||||
<a-button
|
|
||||||
type="primary"
|
|
||||||
size="large"
|
|
||||||
@click="cancelPowerAction"
|
|
||||||
class="cancel-button"
|
|
||||||
>
|
|
||||||
取消操作
|
|
||||||
</a-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -346,127 +310,7 @@ onUnmounted(() => {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 电源操作倒计时全屏弹窗样式 */
|
/* 电源操作倒计时弹窗样式已移至 GlobalPowerCountdown.vue */
|
||||||
.power-countdown-overlay {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background: rgba(0, 0, 0, 0.8);
|
|
||||||
backdrop-filter: blur(8px);
|
|
||||||
z-index: 9999;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
animation: fadeIn 0.3s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.power-countdown-container {
|
|
||||||
background: var(--ant-color-bg-container);
|
|
||||||
border-radius: 16px;
|
|
||||||
padding: 48px;
|
|
||||||
box-shadow: 0 24px 48px rgba(0, 0, 0, 0.2);
|
|
||||||
text-align: center;
|
|
||||||
max-width: 500px;
|
|
||||||
width: 90%;
|
|
||||||
animation: slideIn 0.3s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.countdown-content .warning-icon {
|
|
||||||
font-size: 64px;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
display: block;
|
|
||||||
animation: pulse 2s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.countdown-title {
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--ant-color-text);
|
|
||||||
margin: 0 0 16px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.countdown-message {
|
|
||||||
font-size: 16px;
|
|
||||||
color: var(--ant-color-text-secondary);
|
|
||||||
margin: 0 0 32px 0;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.countdown-timer {
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
justify-content: center;
|
|
||||||
margin-bottom: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.countdown-number {
|
|
||||||
font-size: 72px;
|
|
||||||
font-weight: 700;
|
|
||||||
color: var(--ant-color-primary);
|
|
||||||
line-height: 1;
|
|
||||||
margin-right: 8px;
|
|
||||||
font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
.countdown-unit {
|
|
||||||
font-size: 24px;
|
|
||||||
color: var(--ant-color-text-secondary);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.countdown-text {
|
|
||||||
font-size: 24px;
|
|
||||||
color: var(--ant-color-text-secondary);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.countdown-progress {
|
|
||||||
margin-bottom: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.countdown-actions {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cancel-button {
|
|
||||||
padding: 12px 32px;
|
|
||||||
height: auto;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 动画效果 */
|
|
||||||
@keyframes fadeIn {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes slideIn {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-20px) scale(0.95);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0) scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes pulse {
|
|
||||||
0%, 100% {
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 响应式 - 移动端适配 */
|
/* 响应式 - 移动端适配 */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
@@ -499,27 +343,6 @@ onUnmounted(() => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 移动端倒计时弹窗适配 */
|
/* 移动端倒计时弹窗适配已移至 GlobalPowerCountdown.vue */
|
||||||
.power-countdown-container {
|
|
||||||
padding: 32px 24px;
|
|
||||||
margin: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.countdown-title {
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.countdown-number {
|
|
||||||
font-size: 56px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.countdown-unit {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.countdown-content .warning-icon {
|
|
||||||
font-size: 48px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -8,7 +8,6 @@ import schedulerHandlers from './schedulerHandlers'
|
|||||||
import type { ComboBoxItem } from '@/api/models/ComboBoxItem'
|
import type { ComboBoxItem } from '@/api/models/ComboBoxItem'
|
||||||
import type { QueueItem, Script } from './schedulerConstants'
|
import type { QueueItem, Script } from './schedulerConstants'
|
||||||
import {
|
import {
|
||||||
getPowerActionText,
|
|
||||||
type SchedulerTab,
|
type SchedulerTab,
|
||||||
type TaskMessage,
|
type TaskMessage,
|
||||||
type SchedulerStatus,
|
type SchedulerStatus,
|
||||||
@@ -94,13 +93,15 @@ export function useSchedulerLogic() {
|
|||||||
|
|
||||||
// 电源操作 - 从本地存储加载或使用默认值
|
// 电源操作 - 从本地存储加载或使用默认值
|
||||||
const powerAction = ref<PowerIn.signal>(loadPowerActionFromStorage())
|
const powerAction = ref<PowerIn.signal>(loadPowerActionFromStorage())
|
||||||
|
// 注意:电源倒计时弹窗已移至全局组件 GlobalPowerCountdown.vue
|
||||||
|
// 这里保留引用以避免破坏现有代码,但实际功能由全局组件处理
|
||||||
const powerCountdownVisible = ref(false)
|
const powerCountdownVisible = ref(false)
|
||||||
const powerCountdownData = ref<{
|
const powerCountdownData = ref<{
|
||||||
title?: string
|
title?: string
|
||||||
message?: string
|
message?: string
|
||||||
countdown?: number
|
countdown?: number
|
||||||
}>({})
|
}>({})
|
||||||
// 前端自己的60秒倒计时
|
// 前端自己的60秒倒计时 - 已移至全局组件
|
||||||
let powerCountdownTimer: ReturnType<typeof setInterval> | null = null
|
let powerCountdownTimer: ReturnType<typeof setInterval> | null = null
|
||||||
|
|
||||||
// 消息弹窗
|
// 消息弹窗
|
||||||
@@ -508,10 +509,10 @@ export function useSchedulerLogic() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleMessageDialog = (tab: SchedulerTab, data: any) => {
|
const handleMessageDialog = (tab: SchedulerTab, data: any) => {
|
||||||
// 处理倒计时消息
|
// 处理倒计时消息 - 已移至全局组件处理
|
||||||
if (data.type === 'Countdown') {
|
if (data.type === 'Countdown') {
|
||||||
console.log('[Scheduler] 收到倒计时消息,启动60秒倒计时:', data)
|
console.log('[Scheduler] 收到倒计时消息,由全局组件处理:', data)
|
||||||
startPowerCountdown(data)
|
// 不再在调度中心处理倒计时,由 GlobalPowerCountdown 组件处理
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,68 +655,16 @@ export function useSchedulerLogic() {
|
|||||||
console.log('[Scheduler] 电源操作显示已更新为:', newPowerAction)
|
console.log('[Scheduler] 电源操作显示已更新为:', newPowerAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动60秒倒计时
|
// 启动60秒倒计时 - 已移至全局组件,这里保留空函数避免破坏现有代码
|
||||||
const startPowerCountdown = (data: any) => {
|
// 移除自动执行电源操作,由后端完全控制
|
||||||
// 清除之前的计时器
|
|
||||||
if (powerCountdownTimer) {
|
|
||||||
clearInterval(powerCountdownTimer)
|
|
||||||
powerCountdownTimer = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// 显示倒计时弹窗
|
|
||||||
powerCountdownVisible.value = true
|
|
||||||
|
|
||||||
// 设置倒计时数据,从60秒开始
|
|
||||||
powerCountdownData.value = {
|
|
||||||
title: data.title || `${getPowerActionText(powerAction.value)}倒计时`,
|
|
||||||
message: data.message || `程序将在倒计时结束后执行 ${getPowerActionText(powerAction.value)} 操作`,
|
|
||||||
countdown: 60
|
|
||||||
}
|
|
||||||
|
|
||||||
// 启动每秒倒计时
|
|
||||||
powerCountdownTimer = setInterval(() => {
|
|
||||||
if (powerCountdownData.value.countdown && powerCountdownData.value.countdown > 0) {
|
|
||||||
powerCountdownData.value.countdown--
|
|
||||||
console.log('[Scheduler] 倒计时:', powerCountdownData.value.countdown)
|
|
||||||
|
|
||||||
// 倒计时结束
|
|
||||||
if (powerCountdownData.value.countdown <= 0) {
|
|
||||||
if (powerCountdownTimer) {
|
|
||||||
clearInterval(powerCountdownTimer)
|
|
||||||
powerCountdownTimer = null
|
|
||||||
}
|
|
||||||
powerCountdownVisible.value = false
|
|
||||||
console.log('[Scheduler] 倒计时结束,弹窗关闭')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 移除自动执行电源操作,由后端完全控制
|
|
||||||
// const executePowerAction = async () => {
|
// const executePowerAction = async () => {
|
||||||
// // 不再自己执行电源操作,完全由后端控制
|
// // 不再自己执行电源操作,完全由后端控制
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const cancelPowerAction = async () => {
|
const cancelPowerAction = async () => {
|
||||||
// 清除倒计时器
|
console.log('[Scheduler] cancelPowerAction 已移至全局组件,调度中心不再处理')
|
||||||
if (powerCountdownTimer) {
|
// 电源操作取消功能已移至 GlobalPowerCountdown 组件
|
||||||
clearInterval(powerCountdownTimer)
|
// 这里保留空函数以避免破坏现有的调用代码
|
||||||
powerCountdownTimer = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭倒计时弹窗
|
|
||||||
powerCountdownVisible.value = false
|
|
||||||
|
|
||||||
// 调用取消电源操作的API
|
|
||||||
try {
|
|
||||||
await Service.cancelPowerTaskApiDispatchCancelPowerPost()
|
|
||||||
message.success('已取消电源操作')
|
|
||||||
} catch (error) {
|
|
||||||
console.error('取消电源操作失败:', error)
|
|
||||||
message.error('取消电源操作失败')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注意:这里不重置 powerAction,保留用户选择
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 移除自动检查任务完成的逻辑,完全由后端控制
|
// 移除自动检查任务完成的逻辑,完全由后端控制
|
||||||
@@ -788,8 +737,8 @@ export function useSchedulerLogic() {
|
|||||||
},
|
},
|
||||||
onCountdown: (data) => {
|
onCountdown: (data) => {
|
||||||
try {
|
try {
|
||||||
// 直接启动前端倒计时
|
// 倒计时已移至全局组件处理,这里不再处理
|
||||||
startPowerCountdown(data)
|
console.log('[Scheduler] 倒计时消息由全局组件处理:', data)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('[Scheduler] registerSchedulerUI onCountdown error:', e)
|
console.warn('[Scheduler] registerSchedulerUI onCountdown error:', e)
|
||||||
}
|
}
|
||||||
@@ -814,7 +763,8 @@ export function useSchedulerLogic() {
|
|||||||
const pendingCountdown = schedulerHandlers.consumePendingCountdown()
|
const pendingCountdown = schedulerHandlers.consumePendingCountdown()
|
||||||
if (pendingCountdown) {
|
if (pendingCountdown) {
|
||||||
try {
|
try {
|
||||||
startPowerCountdown(pendingCountdown)
|
// 倒计时已移至全局组件处理,这里不再处理
|
||||||
|
console.log('[Scheduler] 待处理倒计时消息由全局组件处理:', pendingCountdown)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('[Scheduler] replay pending countdown error:', e)
|
console.warn('[Scheduler] replay pending countdown error:', e)
|
||||||
}
|
}
|
||||||
@@ -844,9 +794,9 @@ export function useSchedulerLogic() {
|
|||||||
console.log('[Scheduler] 收到Main消息:', { type, data })
|
console.log('[Scheduler] 收到Main消息:', { type, data })
|
||||||
|
|
||||||
if (type === 'Message' && data && data.type === 'Countdown') {
|
if (type === 'Message' && data && data.type === 'Countdown') {
|
||||||
// 收到倒计时消息,启动前端60秒倒计时
|
// 收到倒计时消息,由全局组件处理
|
||||||
console.log('[Scheduler] 收到倒计时消息,启动前端60秒倒计时:', data)
|
console.log('[Scheduler] 收到倒计时消息,由全局组件处理:', data)
|
||||||
startPowerCountdown(data)
|
// 不再在调度中心处理倒计时
|
||||||
} else if (type === 'Update' && data && data.PowerSign !== undefined) {
|
} else if (type === 'Update' && data && data.PowerSign !== undefined) {
|
||||||
// 收到电源操作更新消息,更新显示
|
// 收到电源操作更新消息,更新显示
|
||||||
console.log('[Scheduler] 收到电源操作更新消息:', data.PowerSign)
|
console.log('[Scheduler] 收到电源操作更新消息:', data.PowerSign)
|
||||||
@@ -856,7 +806,7 @@ export function useSchedulerLogic() {
|
|||||||
|
|
||||||
// 清理函数
|
// 清理函数
|
||||||
const cleanup = () => {
|
const cleanup = () => {
|
||||||
// 清理倒计时器
|
// 清理倒计时器 - 已移至全局组件,这里保留以避免错误
|
||||||
if (powerCountdownTimer) {
|
if (powerCountdownTimer) {
|
||||||
clearInterval(powerCountdownTimer)
|
clearInterval(powerCountdownTimer)
|
||||||
powerCountdownTimer = null
|
powerCountdownTimer = null
|
||||||
|
|||||||
Reference in New Issue
Block a user