增加一键重启所有网关按钮
This commit is contained in:
@@ -111,6 +111,20 @@ export async function restartProfileRuntime(name: string): Promise<ProfileRuntim
|
||||
return res.status
|
||||
}
|
||||
|
||||
export interface BatchRestartResult {
|
||||
success: boolean
|
||||
restarted: string[]
|
||||
failed: Array<{ profile: string; error?: string }>
|
||||
}
|
||||
|
||||
export async function restartAllProfileGateways(): Promise<BatchRestartResult> {
|
||||
return request<BatchRestartResult>('/api/hermes/profiles/gateways/restart-all', { method: 'POST' })
|
||||
}
|
||||
|
||||
export async function restartAllProfileRuntimes(): Promise<BatchRestartResult> {
|
||||
return request<BatchRestartResult>('/api/hermes/profiles/restart-all', { method: 'POST' })
|
||||
}
|
||||
|
||||
export interface CreateProfileResult {
|
||||
success: boolean
|
||||
/** clone=true 时被清理的独占平台凭据 KEY 名 */
|
||||
|
||||
@@ -4,6 +4,8 @@ import { useMessage } from '@/composables/useMessage'
|
||||
import { useProfilesStore } from '@/stores/hermes/profiles'
|
||||
import {
|
||||
fetchProfileRuntimeStatusesWithMeta,
|
||||
restartAllProfileGateways,
|
||||
restartAllProfileRuntimes,
|
||||
restartProfileGateway,
|
||||
restartProfileRuntime,
|
||||
type HermesProfile,
|
||||
@@ -34,6 +36,8 @@ const fileInputRef = ref<HTMLInputElement | null>(null)
|
||||
const gatewayRestarting = ref<Record<string, boolean>>({})
|
||||
const profileRestarting = ref<Record<string, boolean>>({})
|
||||
const profileSwitching = ref<Record<string, boolean>>({})
|
||||
const allGatewaysRestarting = ref(false)
|
||||
const allProfilesRestarting = ref(false)
|
||||
const statusByProfile = computed(() => new Map(runtimeStatuses.value.map(status => [status.profile, status])))
|
||||
let runtimeRefreshToken = 0
|
||||
|
||||
@@ -193,6 +197,40 @@ async function handleRestartProfile(name: string) {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleRestartAllGateways() {
|
||||
allGatewaysRestarting.value = true
|
||||
try {
|
||||
const result = await restartAllProfileGateways()
|
||||
if (result.failed.length > 0) {
|
||||
message.error(t('profiles.runtime.allGatewaysRestartFailed', { names: result.failed.map(item => item.profile).join('、') }))
|
||||
} else {
|
||||
message.success(t('profiles.runtime.allGatewaysRestarted'))
|
||||
}
|
||||
await loadRuntimeStatuses({ background: true })
|
||||
} catch (err: any) {
|
||||
message.error(err?.message || t('profiles.runtime.gatewayRestartFailed'))
|
||||
} finally {
|
||||
allGatewaysRestarting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleRestartAllProfiles() {
|
||||
allProfilesRestarting.value = true
|
||||
try {
|
||||
const result = await restartAllProfileRuntimes()
|
||||
if (result.failed.length > 0) {
|
||||
message.error(t('profiles.runtime.allProfilesRestartFailed', { names: result.failed.map(item => item.profile).join('、') }))
|
||||
} else {
|
||||
message.success(t('profiles.runtime.allProfilesRestarted'))
|
||||
}
|
||||
await loadRuntimeStatuses({ background: true })
|
||||
} catch (err: any) {
|
||||
message.error(err?.message || t('profiles.runtime.profileRestartFailed'))
|
||||
} finally {
|
||||
allProfilesRestarting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSwitchProfile(name: string) {
|
||||
if (name === displayName.value) return
|
||||
profileSwitching.value = { ...profileSwitching.value, [name]: true }
|
||||
@@ -227,6 +265,7 @@ onMounted(() => {
|
||||
:visible="showProfileModal"
|
||||
:footer="false"
|
||||
:width="720"
|
||||
title-align="start"
|
||||
:modal-style="{ maxWidth: 'calc(100vw - 32px)' }"
|
||||
modal-class="profile-manager-modal"
|
||||
@update:visible="handleProfileModalShowChange"
|
||||
@@ -237,10 +276,26 @@ onMounted(() => {
|
||||
<span class="profile-popover-name">{{ t('sidebar.profiles') }}</span>
|
||||
<span class="profile-popover-subtitle">{{ t('profiles.runtime.activeProfile', { name: displayName }) }}</span>
|
||||
</div>
|
||||
<div class="profile-modal-bulk-actions">
|
||||
<a-button
|
||||
size="small"
|
||||
:loading="allGatewaysRestarting"
|
||||
@click="handleRestartAllGateways"
|
||||
>
|
||||
{{ t('profiles.runtime.restartAllGateways') }}
|
||||
</a-button>
|
||||
<a-button
|
||||
size="small"
|
||||
:loading="allProfilesRestarting"
|
||||
@click="handleRestartAllProfiles"
|
||||
>
|
||||
{{ t('profiles.runtime.restartAllProfiles') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<a-spin :loading="runtimeLoading" :size="14">
|
||||
<a-spin :loading="runtimeLoading" :size="14" class="profile-runtime-spin">
|
||||
<div class="profile-runtime-list">
|
||||
<div
|
||||
v-for="profile in profilesStore.profiles"
|
||||
@@ -426,6 +481,22 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.profile-modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
width: 100%;
|
||||
// 给 header 右侧的关闭按钮让位,否则批量按钮会压住关闭图标。
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
.profile-modal-bulk-actions {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.profile-popover-title {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
@@ -466,6 +537,13 @@ onMounted(() => {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
// Arco 的 .arco-spin 是 inline-block,会按内容宽度收缩,
|
||||
// 短标签下卡片不撑满弹窗,右侧留出大片空白。
|
||||
.profile-runtime-spin {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.profile-runtime-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -1500,6 +1500,12 @@ export default {
|
||||
gatewayRestartFailed: 'Failed to restart gateway',
|
||||
profileRestarted: 'Profile restarted: {name}',
|
||||
profileRestartFailed: 'Failed to restart profile',
|
||||
restartAllGateways: 'Restart All Gateways',
|
||||
restartAllProfiles: 'Restart All Profiles',
|
||||
allGatewaysRestarted: 'All gateways restarted',
|
||||
allGatewaysRestartFailed: 'Some gateways failed to restart: {names}',
|
||||
allProfilesRestarted: 'All profiles restarted',
|
||||
allProfilesRestartFailed: 'Some profiles failed to restart: {names}',
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -1492,6 +1492,12 @@ export default {
|
||||
gatewayRestartFailed: '重启网关失败',
|
||||
profileRestarted: '配置已重启:{name}',
|
||||
profileRestartFailed: '重启配置失败',
|
||||
restartAllGateways: '重启所有网关',
|
||||
restartAllProfiles: '重启所有配置',
|
||||
allGatewaysRestarted: '所有网关已重启',
|
||||
allGatewaysRestartFailed: '部分网关重启失败:{names}',
|
||||
allProfilesRestarted: '所有配置已重启',
|
||||
allProfilesRestartFailed: '部分配置重启失败:{names}',
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user