fix(frontend): relax system import limits

This commit is contained in:
fawney19
2026-05-16 19:00:20 +08:00
parent 328ac721ce
commit 56994d4c29
4 changed files with 182 additions and 9 deletions

View File

@@ -0,0 +1,76 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { ref } from 'vue'
const { errorMock, successMock } = vi.hoisted(() => ({
errorMock: vi.fn(),
successMock: vi.fn(),
}))
vi.mock('@/composables/useToast', () => ({
useToast: () => ({
error: errorMock,
success: successMock,
}),
}))
vi.mock('@/api/admin', () => ({
adminApi: {},
}))
import { useConfigExportImport } from '../composables/useConfigExportImport'
function buildFileInputEvent(file: File): Event {
return {
target: {
files: [file],
value: 'selected.json',
},
} as unknown as Event
}
function makeSizedFile(content: string, size: number): File {
const file = new File([content], 'config.json', { type: 'application/json' })
Object.defineProperty(file, 'size', { value: size })
return file
}
describe('useConfigExportImport file size limits', () => {
beforeEach(() => {
errorMock.mockReset()
successMock.mockReset()
})
it('accepts config import files larger than the old 10MB limit', async () => {
const state = useConfigExportImport(ref({ site_name: 'Aether' }))
const file = makeSizedFile(
JSON.stringify({
version: '1',
exported_at: '2026-01-01T00:00:00.000Z',
global_models: [],
providers: [],
}),
11 * 1024 * 1024
)
state.handleConfigFileSelect(buildFileInputEvent(file))
await vi.waitFor(() => expect(state.importDialogOpen.value).toBe(true))
expect(errorMock).not.toHaveBeenCalledWith('文件大小不能超过 10MB')
expect(state.importPreview.value).toEqual({
version: '1',
exported_at: '2026-01-01T00:00:00.000Z',
global_models: [],
providers: [],
})
expect(state.importDialogOpen.value).toBe(true)
})
it('shows the updated config import limit when the file is too large', () => {
const state = useConfigExportImport(ref({ site_name: 'Aether' }))
const file = makeSizedFile('{}', 501 * 1024 * 1024)
state.handleConfigFileSelect(buildFileInputEvent(file))
expect(errorMock).toHaveBeenCalledWith('文件大小不能超过 500MB')
})
})

View File

@@ -13,9 +13,12 @@ import { parseApiError } from '@/utils/errorParser'
import { log } from '@/utils/logger'
import type { SystemConfig } from './useSystemConfig'
// 文件大小限制:聚合数据包含配置和用户数据,允许更大的备份文件
const MAX_FILE_SIZE = 10 * 1024 * 1024
const MAX_AGGREGATE_FILE_SIZE = 20 * 1024 * 1024
// 文件大小限制:导出文件可能包含大量 Provider Key、模型和用户数据
const BYTES_PER_MB = 1024 * 1024
const MAX_FILE_SIZE_MB = 500
const MAX_AGGREGATE_FILE_SIZE_MB = 500
const MAX_FILE_SIZE = MAX_FILE_SIZE_MB * BYTES_PER_MB
const MAX_AGGREGATE_FILE_SIZE = MAX_AGGREGATE_FILE_SIZE_MB * BYTES_PER_MB
type JsonObject = Record<string, unknown>
@@ -49,6 +52,10 @@ function looksLikeAggregateExport(value: JsonObject): boolean {
&& asJsonObject(value.user_data) != null
}
function fileSizeLimitMessage(limitMb: number): string {
return `文件大小不能超过 ${limitMb}MB`
}
function downloadJson(data: unknown, filename: string) {
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' })
const url = URL.createObjectURL(blob)
@@ -126,7 +133,7 @@ export function useConfigExportImport(systemConfig: { value: SystemConfig }) {
if (!file) return
if (file.size > MAX_FILE_SIZE) {
error('文件大小不能超过 10MB')
error(fileSizeLimitMessage(MAX_FILE_SIZE_MB))
input.value = ''
return
}
@@ -223,7 +230,7 @@ export function useConfigExportImport(systemConfig: { value: SystemConfig }) {
if (!file) return
if (file.size > MAX_FILE_SIZE) {
error('文件大小不能超过 10MB')
error(fileSizeLimitMessage(MAX_FILE_SIZE_MB))
input.value = ''
return
}
@@ -325,7 +332,7 @@ export function useConfigExportImport(systemConfig: { value: SystemConfig }) {
if (!file) return
if (file.size > MAX_AGGREGATE_FILE_SIZE) {
error('文件大小不能超过 20MB')
error(fileSizeLimitMessage(MAX_AGGREGATE_FILE_SIZE_MB))
input.value = ''
return
}