feat: 添加在线更新功能

This commit is contained in:
zhiqicloud
2026-05-20 22:02:47 +08:00
parent 754f672ee2
commit 9562295d8b
18 changed files with 1196 additions and 13 deletions

View File

@@ -55,6 +55,13 @@
>
新版本已发布建议更新以获得最新功能和安全修复
</p>
<p
v-if="updatePhase === 'restart'"
class="mt-1 text-xs text-primary"
>
更新包已下载点击立即重启完成安装
</p>
</div>
<template #footer>
@@ -62,16 +69,26 @@
<Button
variant="outline"
class="flex-1"
:disabled="updating"
@click="handleLater"
>
稍后提醒
</Button>
<Button
variant="outline"
class="flex-1"
:disabled="updating"
@click="handleViewRelease"
>
查看更新
</Button>
<Button
class="flex-1"
:disabled="updating"
@click="handleApplyUpdate"
>
{{ actionButtonLabel }}
</Button>
</div>
</template>
</Dialog>
@@ -93,13 +110,24 @@ const props = defineProps<{
releaseUrl: string | null
releaseNotes: string | null
publishedAt: string | null
updatePhase?: 'download' | 'restart'
updating?: boolean
}>()
const emit = defineEmits<{
'update:modelValue': [value: boolean]
applyUpdate: []
}>()
const isOpen = ref(props.modelValue)
const updating = computed(() => props.updating ?? false)
const updatePhase = computed(() => props.updatePhase ?? 'download')
const actionButtonLabel = computed(() => {
if (updating.value) {
return updatePhase.value === 'restart' ? '重启中...' : '下载中...'
}
return updatePhase.value === 'restart' ? '立即重启' : '立即更新'
})
watch(() => props.modelValue, (val) => {
isOpen.value = val
@@ -157,4 +185,8 @@ function handleViewRelease() {
}
isOpen.value = false
}
function handleApplyUpdate() {
emit('applyUpdate')
}
</script>

View File

@@ -92,6 +92,19 @@
<ExternalLink class="mr-2 h-3.5 w-3.5" />
查看更新
</Button>
<Button
v-if="status?.has_update"
size="sm"
class="flex-1"
:disabled="updating"
@click="handleApplyUpdate"
>
<RefreshCw
class="mr-2 h-3.5 w-3.5"
:class="updating ? 'animate-spin' : ''"
/>
{{ actionButtonLabel }}
</Button>
</div>
</div>
</div>
@@ -110,16 +123,21 @@ import { ExternalLink, Info, RefreshCw } from 'lucide-vue-next'
const props = defineProps<{
status: CheckUpdateResponse | null
loading?: boolean
updating?: boolean
updatePhase?: 'download' | 'restart'
}>()
const emit = defineEmits<{
refresh: []
openRelease: []
applyUpdate: []
}>()
const isOpen = ref(false)
const loading = computed(() => props.loading ?? false)
const updating = computed(() => props.updating ?? false)
const updatePhase = computed(() => props.updatePhase ?? 'download')
const buttonClass = computed(() => {
const classes = []
@@ -160,6 +178,12 @@ const buttonTitle = computed(() => {
if (!props.status) return '版本信息'
return `版本信息:${statusLabel.value}`
})
const actionButtonLabel = computed(() => {
if (updating.value) {
return updatePhase.value === 'restart' ? '重启中...' : '下载中...'
}
return updatePhase.value === 'restart' ? '立即重启' : '立即更新'
})
function handleRefresh() {
emit('refresh')
@@ -169,4 +193,8 @@ function handleOpenRelease() {
isOpen.value = false
emit('openRelease')
}
function handleApplyUpdate() {
emit('applyUpdate')
}
</script>