feat(system): 添加系统版本查询和数据库迁移功能
- 移除 license-service 中 DeviceEntity 的 device_id 唯一约束注解 - 添加 /api/system/version 接口用于查询当前部署版本 - 实现数据库 schema 版本化迁移机制 - 添加自动执行数据库迁移的功能 - 在前端安全中心界面显示当前版本和迁移状态 - 优化配置文件修复逻辑和代码结构
这个提交包含在:
父节点
ee20767d57
当前提交
e999d4d443
@ -43,6 +43,16 @@ async function streamOperation(
|
|||||||
if (buf) onLine(buf)
|
if (buf) onLine(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getSystemVersion(): Promise<{ currentVersion: string }> {
|
||||||
|
const token = localStorage.getItem('token') ?? ''
|
||||||
|
const res = await fetch(`${BASE}/system/version`, {
|
||||||
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
|
})
|
||||||
|
if (!res.ok) throw new Error(`HTTP ${res.status}`)
|
||||||
|
const json = await res.json()
|
||||||
|
return json.data as { currentVersion: string }
|
||||||
|
}
|
||||||
|
|
||||||
export function streamSystemUpdate(onLine: (line: string) => void, signal?: AbortSignal) {
|
export function streamSystemUpdate(onLine: (line: string) => void, signal?: AbortSignal) {
|
||||||
return streamOperation('/system/update', onLine, signal)
|
return streamOperation('/system/update', onLine, signal)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -213,7 +213,15 @@
|
|||||||
<div v-if="!updating && !updateDone && !updateError" style="color:#606266;">
|
<div v-if="!updating && !updateDone && !updateError" style="color:#606266;">
|
||||||
<p v-if="operationType === 'update'">将拉取最新镜像并重建所有运行中的服务容器,用于升级到新版本。</p>
|
<p v-if="operationType === 'update'">将拉取最新镜像并重建所有运行中的服务容器,用于升级到新版本。</p>
|
||||||
<p v-else>将用当前本地镜像重建所有运行中的服务容器,无需下载新镜像,适合修复异常服务。</p>
|
<p v-else>将用当前本地镜像重建所有运行中的服务容器,无需下载新镜像,适合修复异常服务。</p>
|
||||||
<el-alert type="warning" :closable="false" show-icon style="margin-top:12px">
|
<el-descriptions v-if="operationType === 'update'" :column="1" border size="small" style="margin-top:12px;margin-bottom:12px">
|
||||||
|
<el-descriptions-item label="当前版本">
|
||||||
|
<el-skeleton v-if="versionLoading" :rows="1" animated style="width:160px" />
|
||||||
|
<el-tag v-else-if="currentVersion" type="info" size="small">{{ currentVersion }}</el-tag>
|
||||||
|
<span v-else style="color:#c0c4cc">—</span>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="数据库迁移">自动执行,新版本启动时应用变更</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<el-alert type="warning" :closable="false" show-icon>
|
||||||
<template #title>tenant-service 重启时页面连接会短暂中断(约 10–30 秒)</template>
|
<template #title>tenant-service 重启时页面连接会短暂中断(约 10–30 秒)</template>
|
||||||
<template #default>操作完成后请刷新页面。</template>
|
<template #default>操作完成后请刷新页面。</template>
|
||||||
</el-alert>
|
</el-alert>
|
||||||
@ -258,7 +266,7 @@ import { Loading } from '@element-plus/icons-vue'
|
|||||||
import { accountApi } from '@/api/account'
|
import { accountApi } from '@/api/account'
|
||||||
import { appApi, type App } from '@/api/app'
|
import { appApi, type App } from '@/api/app'
|
||||||
import { migrateApi } from '@/api/migrate'
|
import { migrateApi } from '@/api/migrate'
|
||||||
import { getDeploymentStatus, streamSystemUpdate, streamSystemReset } from '@/api/system'
|
import { getDeploymentStatus, getSystemVersion, streamSystemUpdate, streamSystemReset } from '@/api/system'
|
||||||
import { useAuthStore } from '@/stores/auth'
|
import { useAuthStore } from '@/stores/auth'
|
||||||
import { formatTime } from '@/utils/date'
|
import { formatTime } from '@/utils/date'
|
||||||
|
|
||||||
@ -451,10 +459,23 @@ const updateError = ref('')
|
|||||||
const selfRestarting = ref(false)
|
const selfRestarting = ref(false)
|
||||||
const updateLog = ref<string[]>([])
|
const updateLog = ref<string[]>([])
|
||||||
const logEl = ref<HTMLPreElement | null>(null)
|
const logEl = ref<HTMLPreElement | null>(null)
|
||||||
|
const currentVersion = ref('')
|
||||||
|
const versionLoading = ref(false)
|
||||||
|
|
||||||
function openOperationDialog(type: 'update' | 'reset') {
|
async function openOperationDialog(type: 'update' | 'reset') {
|
||||||
operationType.value = type
|
operationType.value = type
|
||||||
showUpdateDialog.value = true
|
showUpdateDialog.value = true
|
||||||
|
if (type === 'update' && !currentVersion.value) {
|
||||||
|
versionLoading.value = true
|
||||||
|
try {
|
||||||
|
const info = await getSystemVersion()
|
||||||
|
currentVersion.value = info.currentVersion
|
||||||
|
} catch {
|
||||||
|
currentVersion.value = ''
|
||||||
|
} finally {
|
||||||
|
versionLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetUpdateDialog() {
|
function resetUpdateDialog() {
|
||||||
@ -463,6 +484,7 @@ function resetUpdateDialog() {
|
|||||||
updateDone.value = false
|
updateDone.value = false
|
||||||
updateError.value = ''
|
updateError.value = ''
|
||||||
selfRestarting.value = false
|
selfRestarting.value = false
|
||||||
|
currentVersion.value = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
async function startOperation() {
|
async function startOperation() {
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户