环境配置增加重启按钮
This commit is contained in:
parent
e0096da893
commit
bd214cc117
@ -935,6 +935,12 @@
|
|||||||
"Environment configuration saved": "环境配置已保存",
|
"Environment configuration saved": "环境配置已保存",
|
||||||
"Failed to load environment configuration": "加载环境配置失败",
|
"Failed to load environment configuration": "加载环境配置失败",
|
||||||
"Failed to save environment configuration": "保存环境配置失败",
|
"Failed to save environment configuration": "保存环境配置失败",
|
||||||
|
"Restart Environment": "重启环境",
|
||||||
|
"Restart": "重启",
|
||||||
|
"Only system administrators can restart environment": "仅系统管理员可以重启环境",
|
||||||
|
"Are you sure you want to restart the environment? This operation may cause service interruption.": "您确定要重启环境吗?此操作可能导致服务中断。",
|
||||||
|
"Environment restart request submitted. The system will restart shortly.": "环境重启请求已提交,系统将在稍后重启。",
|
||||||
|
"Failed to restart environment": "重启环境失败",
|
||||||
"Publish App": "发布应用",
|
"Publish App": "发布应用",
|
||||||
"Active": "活跃",
|
"Active": "活跃",
|
||||||
"View detailed information about the application": "查看应用的详细信息",
|
"View detailed information about the application": "查看应用的详细信息",
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { get_session_api_headers } from './auth'
|
import { get_session_api_headers } from './auth'
|
||||||
|
|
||||||
const jingrowServerUrl = import.meta.env.VITE_JINGROW_SERVER_URL || ''
|
|
||||||
|
|
||||||
export interface EnvironmentConfig {
|
export interface EnvironmentConfig {
|
||||||
jingrow_server_url: string
|
jingrow_server_url: string
|
||||||
jingrow_api_key: string
|
jingrow_api_key: string
|
||||||
@ -34,7 +32,7 @@ export interface EnvironmentConfig {
|
|||||||
export const getEnvironmentConfig = async (): Promise<{ success: boolean; data?: EnvironmentConfig; message?: string }> => {
|
export const getEnvironmentConfig = async (): Promise<{ success: boolean; data?: EnvironmentConfig; message?: string }> => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(
|
const response = await axios.get(
|
||||||
`${jingrowServerUrl}/jingrow/system/environment-config`,
|
`/jingrow/system/environment-config`,
|
||||||
{
|
{
|
||||||
headers: get_session_api_headers(),
|
headers: get_session_api_headers(),
|
||||||
withCredentials: true
|
withCredentials: true
|
||||||
@ -60,7 +58,7 @@ export const getEnvironmentConfig = async (): Promise<{ success: boolean; data?:
|
|||||||
export const updateEnvironmentConfig = async (config: Partial<EnvironmentConfig>): Promise<{ success: boolean; message?: string }> => {
|
export const updateEnvironmentConfig = async (config: Partial<EnvironmentConfig>): Promise<{ success: boolean; message?: string }> => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(
|
const response = await axios.post(
|
||||||
`${jingrowServerUrl}/jingrow/system/environment-config`,
|
`/jingrow/system/environment-config`,
|
||||||
config,
|
config,
|
||||||
{
|
{
|
||||||
headers: get_session_api_headers(),
|
headers: get_session_api_headers(),
|
||||||
@ -83,3 +81,30 @@ export const updateEnvironmentConfig = async (config: Partial<EnvironmentConfig>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 重启环境
|
||||||
|
export const restartEnvironment = async (): Promise<{ success: boolean; message?: string }> => {
|
||||||
|
try {
|
||||||
|
const response = await axios.post(
|
||||||
|
`/jingrow/system/restart-environment`,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
headers: get_session_api_headers(),
|
||||||
|
withCredentials: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (response.data?.success) {
|
||||||
|
return { success: true, message: response.data.message || '环境重启请求已提交' }
|
||||||
|
}
|
||||||
|
return { success: false, message: response.data?.message || '重启环境失败' }
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.response?.status === 403) {
|
||||||
|
return { success: false, message: '仅系统管理员可以访问此功能' }
|
||||||
|
}
|
||||||
|
if (error.response?.status === 401) {
|
||||||
|
return { success: false, message: '认证失败,请重新登录' }
|
||||||
|
}
|
||||||
|
return { success: false, message: error.response?.data?.detail || error.message || '重启环境失败' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -165,6 +165,12 @@
|
|||||||
</template>
|
</template>
|
||||||
{{ t('Refresh') }}
|
{{ t('Refresh') }}
|
||||||
</n-button>
|
</n-button>
|
||||||
|
<n-button type="warning" :loading="envConfigRestarting" @click="handleRestartEnvironment">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon><Icon icon="tabler:power" /></n-icon>
|
||||||
|
</template>
|
||||||
|
{{ t('Restart Environment') }}
|
||||||
|
</n-button>
|
||||||
<n-button type="primary" class="save-btn-brand" :loading="envConfigSaving" @click="saveEnvironmentConfig">
|
<n-button type="primary" class="save-btn-brand" :loading="envConfigSaving" @click="saveEnvironmentConfig">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<n-icon><Icon icon="tabler:check" /></n-icon>
|
<n-icon><Icon icon="tabler:check" /></n-icon>
|
||||||
@ -197,14 +203,16 @@ import {
|
|||||||
NCollapseItem,
|
NCollapseItem,
|
||||||
NSpace,
|
NSpace,
|
||||||
NIcon,
|
NIcon,
|
||||||
useMessage
|
useMessage,
|
||||||
|
useDialog
|
||||||
} from 'naive-ui'
|
} from 'naive-ui'
|
||||||
import { Icon } from '@iconify/vue'
|
import { Icon } from '@iconify/vue'
|
||||||
import { getCurrentLocale, setLocale, locales, initLocale, t } from '../shared/i18n'
|
import { getCurrentLocale, setLocale, locales, initLocale, t } from '../shared/i18n'
|
||||||
import { useAuthStore } from '../shared/stores/auth'
|
import { useAuthStore } from '../shared/stores/auth'
|
||||||
import { getEnvironmentConfig, updateEnvironmentConfig, type EnvironmentConfig } from '../shared/api/system'
|
import { getEnvironmentConfig, updateEnvironmentConfig, restartEnvironment, type EnvironmentConfig } from '../shared/api/system'
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
const dialog = useDialog()
|
||||||
const authStore = useAuthStore()
|
const authStore = useAuthStore()
|
||||||
|
|
||||||
// 检查是否为系统管理员
|
// 检查是否为系统管理员
|
||||||
@ -222,6 +230,7 @@ const isLocalMode = computed(() => {
|
|||||||
const envConfig = reactive<Partial<EnvironmentConfig>>({})
|
const envConfig = reactive<Partial<EnvironmentConfig>>({})
|
||||||
const envConfigLoading = ref(false)
|
const envConfigLoading = ref(false)
|
||||||
const envConfigSaving = ref(false)
|
const envConfigSaving = ref(false)
|
||||||
|
const envConfigRestarting = ref(false)
|
||||||
|
|
||||||
const systemSettings = reactive({
|
const systemSettings = reactive({
|
||||||
appName: localStorage.getItem('appName') || 'Jingrow',
|
appName: localStorage.getItem('appName') || 'Jingrow',
|
||||||
@ -359,13 +368,44 @@ const saveEnvironmentConfig = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 重启环境
|
||||||
|
const handleRestartEnvironment = () => {
|
||||||
|
if (!isAdmin.value) {
|
||||||
|
message.error(t('Only system administrators can restart environment'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认对话框
|
||||||
|
dialog.warning({
|
||||||
|
title: t('Restart Environment'),
|
||||||
|
content: t('Are you sure you want to restart the environment? This operation may cause service interruption.'),
|
||||||
|
positiveText: t('Restart'),
|
||||||
|
negativeText: t('Cancel'),
|
||||||
|
onPositiveClick: async () => {
|
||||||
|
envConfigRestarting.value = true
|
||||||
|
try {
|
||||||
|
const result = await restartEnvironment()
|
||||||
|
if (result.success) {
|
||||||
|
message.success(result.message || t('Environment restart request submitted. The system will restart shortly.'))
|
||||||
|
} else {
|
||||||
|
message.error(result.message || t('Failed to restart environment'))
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || t('Failed to restart environment'))
|
||||||
|
} finally {
|
||||||
|
envConfigRestarting.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
initLocale()
|
initLocale()
|
||||||
systemSettings.language = getCurrentLocale()
|
systemSettings.language = getCurrentLocale()
|
||||||
|
|
||||||
// 如果是系统管理员,加载环境配置
|
// 如果是系统管理员,加载环境配置(静默加载,不显示消息)
|
||||||
if (isAdmin.value) {
|
if (isAdmin.value) {
|
||||||
await loadEnvironmentConfig()
|
await loadEnvironmentConfig(false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -264,3 +264,56 @@ async def update_environment_config(request: Request, config_data: Dict[str, Any
|
|||||||
logger.error(f"更新环境配置失败: {str(e)}")
|
logger.error(f"更新环境配置失败: {str(e)}")
|
||||||
raise HTTPException(status_code=500, detail=f"更新环境配置失败: {str(e)}")
|
raise HTTPException(status_code=500, detail=f"更新环境配置失败: {str(e)}")
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/jingrow/system/restart-environment")
|
||||||
|
async def restart_environment(request: Request):
|
||||||
|
"""
|
||||||
|
重启环境
|
||||||
|
仅限系统管理员访问
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 检查管理员权限
|
||||||
|
check_admin_permission(request)
|
||||||
|
|
||||||
|
logger.info("收到环境重启请求")
|
||||||
|
|
||||||
|
# 使用后台任务在响应返回后执行重启
|
||||||
|
# 这样可以确保客户端能够收到响应
|
||||||
|
import asyncio
|
||||||
|
import os
|
||||||
|
import signal
|
||||||
|
|
||||||
|
async def delayed_restart():
|
||||||
|
# 等待一小段时间,确保响应已经返回
|
||||||
|
await asyncio.sleep(2)
|
||||||
|
logger.info("开始执行环境重启...")
|
||||||
|
|
||||||
|
# 获取当前进程ID
|
||||||
|
current_pid = os.getpid()
|
||||||
|
|
||||||
|
# 如果是开发模式,可以通过设置重启标志或发送信号
|
||||||
|
# 这里使用发送SIGTERM信号来触发重启(如果使用reload模式)
|
||||||
|
try:
|
||||||
|
# 发送SIGTERM信号给当前进程
|
||||||
|
# 如果使用uvicorn的reload模式,这会触发重启
|
||||||
|
os.kill(current_pid, signal.SIGTERM)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"发送重启信号失败: {str(e)}")
|
||||||
|
# 如果发送信号失败,尝试其他方法
|
||||||
|
# 可以通过修改配置文件或环境变量来触发重启
|
||||||
|
logger.warning("无法通过信号重启,请手动重启服务")
|
||||||
|
|
||||||
|
# 启动后台任务
|
||||||
|
asyncio.create_task(delayed_restart())
|
||||||
|
|
||||||
|
return {
|
||||||
|
"success": True,
|
||||||
|
"message": "环境重启请求已提交,系统将在稍后重启"
|
||||||
|
}
|
||||||
|
|
||||||
|
except HTTPException:
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"重启环境失败: {str(e)}")
|
||||||
|
raise HTTPException(status_code=500, detail=f"重启环境失败: {str(e)}")
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user