refactor: 拆分更新类型(全量/补丁)和更新方式(自动/手动),移除force_update字段

This commit is contained in:
2026-05-08 23:34:14 +08:00
parent de0de10b8d
commit 65fa7146e8
12 changed files with 157 additions and 61 deletions
+32 -9
View File
@@ -44,7 +44,8 @@ const formData = ref({
version: '',
description: '',
update_strategy: 'optional' as 'optional' | 'forced',
update_method: 'manual' as 'manual' | 'hot' | 'full',
update_type: 'full' as 'full' | 'patch',
update_method: 'auto' as 'auto' | 'manual',
changelog: '',
entry_file: '',
file: null as File | null,
@@ -94,7 +95,8 @@ async function fetchVersion() {
formData.value.version = ver.version || ''
formData.value.description = ver.description || ''
formData.value.update_strategy = ver.update_strategy || 'optional'
formData.value.update_method = ver.update_method || 'manual'
formData.value.update_type = ver.update_type || 'full'
formData.value.update_method = ver.update_method || 'auto'
formData.value.changelog = ver.changelog || ''
formData.value.entry_file = ver.entry_file || ''
}
@@ -180,6 +182,7 @@ async function handleSubmit() {
version: formData.value.version,
description: formData.value.description,
update_strategy: formData.value.update_strategy,
update_type: formData.value.update_type,
update_method: formData.value.update_method,
changelog: formData.value.changelog,
entry_file: formData.value.entry_file,
@@ -423,6 +426,23 @@ onMounted(() => {
/>
</div>
<div class="space-y-2">
<UiLabel>{{ t('admin.versions.createForm.updateType') }}</UiLabel>
<UiSelect v-model="formData.update_type" :disabled="saving">
<UiSelectTrigger>
<UiSelectValue />
</UiSelectTrigger>
<UiSelectContent>
<UiSelectItem value="full">
{{ t('admin.versions.types.full') }}
</UiSelectItem>
<UiSelectItem value="patch">
{{ t('admin.versions.types.patch') }}
</UiSelectItem>
</UiSelectContent>
</UiSelect>
</div>
<div class="space-y-2">
<UiLabel>{{ t('admin.versions.createForm.updateMethod') }}</UiLabel>
<UiSelect v-model="formData.update_method" :disabled="saving">
@@ -430,11 +450,8 @@ onMounted(() => {
<UiSelectValue />
</UiSelectTrigger>
<UiSelectContent>
<UiSelectItem value="full">
{{ t('admin.versions.methods.full') }}
</UiSelectItem>
<UiSelectItem value="hot">
{{ t('admin.versions.methods.hot') }}
<UiSelectItem value="auto">
{{ t('admin.versions.methods.auto') }}
</UiSelectItem>
<UiSelectItem value="manual">
{{ t('admin.versions.methods.manual') }}
@@ -485,11 +502,17 @@ onMounted(() => {
<span class="text-muted-foreground">{{ t('admin.versions.createForm.previewForcedUpdate') }}</span>
<span>{{ formData.update_strategy === 'forced' ? t('common.yes') : t('common.no') }}</span>
</div>
<div class="flex justify-between text-sm">
<span class="text-muted-foreground">{{ t('admin.versions.createForm.previewUpdateType') }}</span>
<span>{{
formData.update_type === 'full' ? t('admin.versions.types.full')
: t('admin.versions.types.patch')
}}</span>
</div>
<div class="flex justify-between text-sm">
<span class="text-muted-foreground">{{ t('admin.versions.createForm.previewUpdateMethod') }}</span>
<span>{{
formData.update_method === 'full' ? t('admin.versions.methods.full')
: formData.update_method === 'hot' ? t('admin.versions.methods.hot')
formData.update_method === 'auto' ? t('admin.versions.methods.auto')
: t('admin.versions.methods.manual')
}}</span>
</div>
@@ -69,21 +69,34 @@ export function getColumns(options: ColumnOptions, t: (key: string) => string):
return h(Badge, { class: strategyClasses[row.original.update_strategy] }, () => strategyLabels[row.original.update_strategy])
},
},
{
accessorKey: 'update_type',
header: () => t('admin.versions.columns.type'),
cell: ({ row }) => {
const typeClasses: Record<string, string> = {
full: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',
patch: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400',
}
const typeLabels: Record<string, string> = {
full: t('admin.versions.types.full'),
patch: t('admin.versions.types.patch'),
}
return h(Badge, { class: typeClasses[row.original.update_type] || typeClasses.full }, () => typeLabels[row.original.update_type] || row.original.update_type)
},
},
{
accessorKey: 'update_method',
header: () => t('admin.versions.columns.method'),
cell: ({ row }) => {
const methodClasses: Record<string, string> = {
auto: 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400',
manual: 'bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400',
hot: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400',
full: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',
}
const methodLabels: Record<string, string> = {
auto: t('admin.versions.methods.auto'),
manual: t('admin.versions.methods.manual'),
hot: t('admin.versions.methods.hot'),
full: t('admin.versions.methods.full'),
}
return h(Badge, { class: methodClasses[row.original.update_method] }, () => methodLabels[row.original.update_method])
return h(Badge, { class: methodClasses[row.original.update_method] || methodClasses.manual }, () => methodLabels[row.original.update_method] || row.original.update_method)
},
},
{
+35 -8
View File
@@ -43,7 +43,8 @@ const formData = ref({
version: '',
description: '',
update_strategy: 'optional' as 'optional' | 'forced',
update_method: 'manual' as 'manual' | 'hot' | 'full',
update_type: 'full' as 'full' | 'patch',
update_method: 'auto' as 'auto' | 'manual',
changelog: '',
entry_file: '',
file: null as File | null,
@@ -85,10 +86,17 @@ function formatFileSize(size: number): string {
return `${(size / (1024 * 1024)).toFixed(2)} MB`
}
const typeLabel = computed(() => {
const map: Record<string, string> = {
full: t('admin.versions.types.full'),
patch: t('admin.versions.types.patch'),
}
return map[formData.value.update_type] || formData.value.update_type
})
const methodLabel = computed(() => {
const map: Record<string, string> = {
full: t('admin.versions.methods.full'),
hot: t('admin.versions.methods.hot'),
auto: t('admin.versions.methods.auto'),
manual: t('admin.versions.methods.manual'),
}
return map[formData.value.update_method] || formData.value.update_method
@@ -178,6 +186,7 @@ async function handleSubmit() {
version: formData.value.version,
description: formData.value.description,
update_strategy: formData.value.update_strategy,
update_type: formData.value.update_type,
update_method: formData.value.update_method,
changelog: formData.value.changelog,
entry_file: formData.value.entry_file,
@@ -411,6 +420,23 @@ onMounted(() => {
/>
</div>
<div class="space-y-2">
<UiLabel>{{ t('admin.versions.createForm.updateType') }}</UiLabel>
<UiSelect v-model="formData.update_type" :disabled="saving">
<UiSelectTrigger>
<UiSelectValue />
</UiSelectTrigger>
<UiSelectContent>
<UiSelectItem value="full">
{{ t('admin.versions.types.full') }}
</UiSelectItem>
<UiSelectItem value="patch">
{{ t('admin.versions.types.patch') }}
</UiSelectItem>
</UiSelectContent>
</UiSelect>
</div>
<div class="space-y-2">
<UiLabel>{{ t('admin.versions.createForm.updateMethod') }}</UiLabel>
<UiSelect v-model="formData.update_method" :disabled="saving">
@@ -418,11 +444,8 @@ onMounted(() => {
<UiSelectValue />
</UiSelectTrigger>
<UiSelectContent>
<UiSelectItem value="full">
{{ t('admin.versions.methods.full') }}
</UiSelectItem>
<UiSelectItem value="hot">
{{ t('admin.versions.methods.hot') }}
<UiSelectItem value="auto">
{{ t('admin.versions.methods.auto') }}
</UiSelectItem>
<UiSelectItem value="manual">
{{ t('admin.versions.methods.manual') }}
@@ -485,6 +508,10 @@ onMounted(() => {
<span class="text-muted-foreground">{{ t('admin.versions.createForm.previewForcedUpdate') }}</span>
<span>{{ formData.update_strategy === 'forced' ? t('common.yes') : t('common.no') }}</span>
</div>
<div class="flex justify-between text-sm">
<span class="text-muted-foreground">{{ t('admin.versions.createForm.previewUpdateType') }}</span>
<span>{{ typeLabel }}</span>
</div>
<div class="flex justify-between text-sm">
<span class="text-muted-foreground">{{ t('admin.versions.createForm.previewUpdateMethod') }}</span>
<span>{{ methodLabel }}</span>
@@ -1,7 +1,8 @@
import { z } from 'zod'
export const updateStrategySchema = z.enum(['optional', 'forced'])
export const updateMethodSchema = z.enum(['manual', 'hot', 'full'])
export const updateTypeSchema = z.enum(['full', 'patch'])
export const updateMethodSchema = z.enum(['auto', 'manual'])
export const versionStatusSchema = z.enum(['active', 'superseded'])
export const versionSchema = z.object({
@@ -12,8 +13,8 @@ export const versionSchema = z.object({
description: z.string(),
file_path: z.string(),
file_size: z.number(),
force_update: z.boolean(),
update_strategy: updateStrategySchema,
update_type: updateTypeSchema,
update_method: updateMethodSchema,
status: versionStatusSchema,
changelog: z.string(),
+18 -3
View File
@@ -30,6 +30,7 @@ const tableRef = ref()
const appFilter = ref<string>('')
const strategyFilter = ref<string>('')
const typeFilter = ref<string>('')
const methodFilter = ref<string>('')
const searchFilter = ref<string>('')
const currentPage = ref(1)
@@ -56,10 +57,14 @@ const strategyOptions = computed(() => [
{ label: t('admin.versions.strategies.forced'), value: 'forced' },
])
const typeOptions = computed(() => [
{ label: t('admin.versions.types.full'), value: 'full' },
{ label: t('admin.versions.types.patch'), value: 'patch' },
])
const methodOptions = computed(() => [
{ label: t('admin.versions.methods.auto'), value: 'auto' },
{ label: t('admin.versions.methods.manual'), value: 'manual' },
{ label: t('admin.versions.methods.hot'), value: 'hot' },
{ label: t('admin.versions.methods.full'), value: 'full' },
])
const totalSize = computed(() => {
@@ -113,6 +118,9 @@ async function fetchVersions() {
if (strategyFilter.value) {
params.append('update_strategy', strategyFilter.value)
}
if (typeFilter.value) {
params.append('update_type', typeFilter.value)
}
if (methodFilter.value) {
params.append('update_method', methodFilter.value)
}
@@ -179,6 +187,8 @@ function handleExport() {
params.append('application_id', appFilter.value)
if (strategyFilter.value)
params.append('update_strategy', strategyFilter.value)
if (typeFilter.value)
params.append('update_type', typeFilter.value)
if (methodFilter.value)
params.append('update_method', methodFilter.value)
@@ -230,7 +240,7 @@ watch([currentPage, pageSize], () => {
fetchVersions()
})
watch([appFilter, strategyFilter, methodFilter, searchFilter], () => {
watch([appFilter, strategyFilter, typeFilter, methodFilter, searchFilter], () => {
currentPage.value = 1
fetchVersions()
})
@@ -336,6 +346,11 @@ watch([appFilter, strategyFilter, methodFilter, searchFilter], () => {
:title="t('admin.versions.strategy')"
:options="strategyOptions"
/>
<SingleFilter
v-model="typeFilter"
:title="t('admin.versions.columns.type')"
:options="typeOptions"
/>
<SingleFilter
v-model="methodFilter"
:title="t('admin.versions.method')"