|
|
|
@@ -473,6 +473,119 @@
|
|
|
|
|
<!-- 系统管理 -->
|
|
|
|
|
<div v-show="currentSection === 'system'" class="animate-fade-in">
|
|
|
|
|
<setting-section v-if="isElectron" :title="t('settings.sections.system')">
|
|
|
|
|
<!-- 磁盘缓存开关 -->
|
|
|
|
|
<setting-item
|
|
|
|
|
:title="t('settings.system.diskCache')"
|
|
|
|
|
:description="t('settings.system.diskCacheDesc')"
|
|
|
|
|
>
|
|
|
|
|
<n-switch v-model:value="setData.enableDiskCache">
|
|
|
|
|
<template #checked>{{ t('common.on') }}</template>
|
|
|
|
|
<template #unchecked>{{ t('common.off') }}</template>
|
|
|
|
|
</n-switch>
|
|
|
|
|
</setting-item>
|
|
|
|
|
|
|
|
|
|
<!-- 缓存目录 -->
|
|
|
|
|
<setting-item
|
|
|
|
|
:title="t('settings.system.cacheDirectory')"
|
|
|
|
|
:description="
|
|
|
|
|
setData.diskCacheDir ||
|
|
|
|
|
diskCacheStats.directory ||
|
|
|
|
|
t('settings.system.cacheDirectoryDesc')
|
|
|
|
|
"
|
|
|
|
|
>
|
|
|
|
|
<template #action>
|
|
|
|
|
<div class="flex items-center gap-2 max-md:flex-wrap">
|
|
|
|
|
<n-button size="small" @click="selectCacheDirectory">
|
|
|
|
|
{{ t('settings.system.selectDirectory') }}
|
|
|
|
|
</n-button>
|
|
|
|
|
<n-button size="small" @click="openCacheDirectory">
|
|
|
|
|
{{ t('settings.system.openDirectory') }}
|
|
|
|
|
</n-button>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</setting-item>
|
|
|
|
|
|
|
|
|
|
<!-- 缓存上限 -->
|
|
|
|
|
<setting-item
|
|
|
|
|
:title="t('settings.system.cacheMaxSize')"
|
|
|
|
|
:description="t('settings.system.cacheMaxSizeDesc')"
|
|
|
|
|
>
|
|
|
|
|
<template #action>
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
<n-input-number
|
|
|
|
|
v-model:value="setData.diskCacheMaxSizeMB"
|
|
|
|
|
:min="256"
|
|
|
|
|
:max="102400"
|
|
|
|
|
:step="256"
|
|
|
|
|
class="max-md:w-32"
|
|
|
|
|
/>
|
|
|
|
|
<span class="text-xs text-neutral-500">MB</span>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</setting-item>
|
|
|
|
|
|
|
|
|
|
<!-- 清理策略 -->
|
|
|
|
|
<setting-item
|
|
|
|
|
:title="t('settings.system.cleanupPolicy')"
|
|
|
|
|
:description="t('settings.system.cleanupPolicyDesc')"
|
|
|
|
|
>
|
|
|
|
|
<n-select
|
|
|
|
|
v-model:value="setData.diskCacheCleanupPolicy"
|
|
|
|
|
:options="cleanupPolicyOptions"
|
|
|
|
|
class="w-40"
|
|
|
|
|
/>
|
|
|
|
|
</setting-item>
|
|
|
|
|
|
|
|
|
|
<!-- 缓存状态 -->
|
|
|
|
|
<setting-item
|
|
|
|
|
:title="t('settings.system.cacheStatus')"
|
|
|
|
|
:description="
|
|
|
|
|
t('settings.system.cacheStatusDesc', {
|
|
|
|
|
used: formatBytes(diskCacheStats.totalSizeBytes),
|
|
|
|
|
limit: `${setData.diskCacheMaxSizeMB || diskCacheStats.maxSizeMB || 0} MB`
|
|
|
|
|
})
|
|
|
|
|
"
|
|
|
|
|
>
|
|
|
|
|
<template #action>
|
|
|
|
|
<div class="flex items-center gap-3 max-md:flex-wrap">
|
|
|
|
|
<div class="w-40 max-md:w-32">
|
|
|
|
|
<n-progress type="line" :percentage="diskCacheUsagePercent" />
|
|
|
|
|
</div>
|
|
|
|
|
<span class="text-xs text-neutral-500">
|
|
|
|
|
{{
|
|
|
|
|
t('settings.system.cacheStatusDetail', {
|
|
|
|
|
musicCount: diskCacheStats.musicFiles,
|
|
|
|
|
lyricCount: diskCacheStats.lyricFiles
|
|
|
|
|
})
|
|
|
|
|
}}
|
|
|
|
|
</span>
|
|
|
|
|
<n-button size="small" @click="refreshDiskCacheStats()">{{
|
|
|
|
|
t('common.refresh')
|
|
|
|
|
}}</n-button>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</setting-item>
|
|
|
|
|
|
|
|
|
|
<!-- 手动清理磁盘缓存 -->
|
|
|
|
|
<setting-item
|
|
|
|
|
:title="t('settings.system.manageDiskCache')"
|
|
|
|
|
:description="t('settings.system.manageDiskCacheDesc')"
|
|
|
|
|
>
|
|
|
|
|
<template #action>
|
|
|
|
|
<div class="flex items-center gap-2 max-md:flex-wrap">
|
|
|
|
|
<n-button size="small" @click="clearDiskCacheByScope('music')">
|
|
|
|
|
{{ t('settings.system.clearMusicCache') }}
|
|
|
|
|
</n-button>
|
|
|
|
|
<n-button size="small" @click="clearDiskCacheByScope('lyrics')">
|
|
|
|
|
{{ t('settings.system.clearLyricCache') }}
|
|
|
|
|
</n-button>
|
|
|
|
|
<n-button type="error" size="small" @click="clearDiskCacheByScope('all')">
|
|
|
|
|
{{ t('settings.system.clearAllCache') }}
|
|
|
|
|
</n-button>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</setting-item>
|
|
|
|
|
|
|
|
|
|
<!-- 清除缓存 -->
|
|
|
|
|
<setting-item
|
|
|
|
|
:title="t('settings.system.cache')"
|
|
|
|
@@ -567,7 +680,7 @@
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { useDebounceFn } from '@vueuse/core';
|
|
|
|
|
import { useMessage } from 'naive-ui';
|
|
|
|
|
import { useDialog, useMessage } from 'naive-ui';
|
|
|
|
|
import { computed, h, onMounted, onUnmounted, ref, watch } from 'vue';
|
|
|
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
|
import { useRouter } from 'vue-router';
|
|
|
|
@@ -611,11 +724,40 @@ const fontPreviews = [
|
|
|
|
|
{ key: 'korean' }
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
type DiskCacheScope = 'all' | 'music' | 'lyrics';
|
|
|
|
|
type DiskCacheCleanupPolicy = 'lru' | 'fifo';
|
|
|
|
|
type CacheSwitchAction = 'migrate' | 'destroy' | 'keep';
|
|
|
|
|
|
|
|
|
|
type DiskCacheConfig = {
|
|
|
|
|
enabled: boolean;
|
|
|
|
|
directory: string;
|
|
|
|
|
maxSizeMB: number;
|
|
|
|
|
cleanupPolicy: DiskCacheCleanupPolicy;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type DiskCacheStats = DiskCacheConfig & {
|
|
|
|
|
totalSizeBytes: number;
|
|
|
|
|
musicSizeBytes: number;
|
|
|
|
|
lyricSizeBytes: number;
|
|
|
|
|
totalFiles: number;
|
|
|
|
|
musicFiles: number;
|
|
|
|
|
lyricFiles: number;
|
|
|
|
|
usage: number;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type SwitchCacheDirectoryResult = {
|
|
|
|
|
success: boolean;
|
|
|
|
|
config: DiskCacheConfig;
|
|
|
|
|
migratedFiles: number;
|
|
|
|
|
destroyedFiles: number;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// ==================== 平台和Store ====================
|
|
|
|
|
const platform = window.electron ? window.electron.ipcRenderer.sendSync('get-platform') : 'web';
|
|
|
|
|
const settingsStore = useSettingsStore();
|
|
|
|
|
const userStore = useUserStore();
|
|
|
|
|
const message = useMessage();
|
|
|
|
|
const dialog = useDialog();
|
|
|
|
|
const { t } = useI18n();
|
|
|
|
|
const router = useRouter();
|
|
|
|
|
|
|
|
|
@@ -764,6 +906,268 @@ const openDownloadPath = () => {
|
|
|
|
|
openDirectory(setData.value.downloadPath, message);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// ==================== 磁盘缓存设置 ====================
|
|
|
|
|
const diskCacheStats = ref<DiskCacheStats>({
|
|
|
|
|
enabled: true,
|
|
|
|
|
directory: '',
|
|
|
|
|
maxSizeMB: 4096,
|
|
|
|
|
cleanupPolicy: 'lru',
|
|
|
|
|
totalSizeBytes: 0,
|
|
|
|
|
musicSizeBytes: 0,
|
|
|
|
|
lyricSizeBytes: 0,
|
|
|
|
|
totalFiles: 0,
|
|
|
|
|
musicFiles: 0,
|
|
|
|
|
lyricFiles: 0,
|
|
|
|
|
usage: 0
|
|
|
|
|
});
|
|
|
|
|
const applyingDiskCacheConfig = ref(false);
|
|
|
|
|
const switchingCacheDirectory = ref(false);
|
|
|
|
|
|
|
|
|
|
const cleanupPolicyOptions = computed(() => [
|
|
|
|
|
{ label: t('settings.system.cleanupPolicyOptions.lru'), value: 'lru' },
|
|
|
|
|
{ label: t('settings.system.cleanupPolicyOptions.fifo'), value: 'fifo' }
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
const diskCacheUsagePercent = computed(() =>
|
|
|
|
|
Math.min(100, Math.max(0, Math.round((diskCacheStats.value.usage || 0) * 100)))
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const formatBytes = (bytes: number) => {
|
|
|
|
|
if (!Number.isFinite(bytes) || bytes <= 0) return '0 B';
|
|
|
|
|
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
|
|
|
let value = bytes;
|
|
|
|
|
let unitIndex = 0;
|
|
|
|
|
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
|
|
|
value /= 1024;
|
|
|
|
|
unitIndex++;
|
|
|
|
|
}
|
|
|
|
|
return `${value.toFixed(value >= 10 ? 0 : 1)} ${units[unitIndex]}`;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const readDiskCacheConfigFromUI = (): DiskCacheConfig => {
|
|
|
|
|
const cleanupPolicy: DiskCacheCleanupPolicy =
|
|
|
|
|
setData.value.diskCacheCleanupPolicy === 'fifo' ? 'fifo' : 'lru';
|
|
|
|
|
const maxSizeMB = Math.max(256, Math.floor(Number(setData.value.diskCacheMaxSizeMB || 4096)));
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
enabled: setData.value.enableDiskCache !== false,
|
|
|
|
|
directory: String(setData.value.diskCacheDir || ''),
|
|
|
|
|
maxSizeMB,
|
|
|
|
|
cleanupPolicy
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const refreshDiskCacheStats = async (silent: boolean = true) => {
|
|
|
|
|
if (!window.electron) return;
|
|
|
|
|
try {
|
|
|
|
|
const stats = (await window.electron.ipcRenderer.invoke(
|
|
|
|
|
'get-disk-cache-stats'
|
|
|
|
|
)) as DiskCacheStats;
|
|
|
|
|
if (stats) {
|
|
|
|
|
diskCacheStats.value = stats;
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('读取磁盘缓存统计失败:', error);
|
|
|
|
|
if (!silent) {
|
|
|
|
|
message.error(t('settings.system.messages.diskCacheStatsLoadFailed'));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const loadDiskCacheConfig = async () => {
|
|
|
|
|
if (!window.electron) return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const config = (await window.electron.ipcRenderer.invoke(
|
|
|
|
|
'get-disk-cache-config'
|
|
|
|
|
)) as DiskCacheConfig;
|
|
|
|
|
if (config) {
|
|
|
|
|
setData.value = {
|
|
|
|
|
...setData.value,
|
|
|
|
|
enableDiskCache: config.enabled,
|
|
|
|
|
diskCacheDir: config.directory,
|
|
|
|
|
diskCacheMaxSizeMB: config.maxSizeMB,
|
|
|
|
|
diskCacheCleanupPolicy: config.cleanupPolicy
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('读取磁盘缓存配置失败:', error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const applyDiskCacheConfig = async () => {
|
|
|
|
|
if (!window.electron || applyingDiskCacheConfig.value) return;
|
|
|
|
|
|
|
|
|
|
applyingDiskCacheConfig.value = true;
|
|
|
|
|
try {
|
|
|
|
|
const config = readDiskCacheConfigFromUI();
|
|
|
|
|
const updated = (await window.electron.ipcRenderer.invoke(
|
|
|
|
|
'set-disk-cache-config',
|
|
|
|
|
config
|
|
|
|
|
)) as DiskCacheConfig;
|
|
|
|
|
|
|
|
|
|
if (updated) {
|
|
|
|
|
setData.value = {
|
|
|
|
|
...setData.value,
|
|
|
|
|
enableDiskCache: updated.enabled,
|
|
|
|
|
diskCacheDir: updated.directory,
|
|
|
|
|
diskCacheMaxSizeMB: updated.maxSizeMB,
|
|
|
|
|
diskCacheCleanupPolicy: updated.cleanupPolicy
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
await refreshDiskCacheStats();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('更新磁盘缓存配置失败:', error);
|
|
|
|
|
} finally {
|
|
|
|
|
applyingDiskCacheConfig.value = false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const applyDiskCacheConfigDebounced = useDebounceFn(() => {
|
|
|
|
|
void applyDiskCacheConfig();
|
|
|
|
|
}, 500);
|
|
|
|
|
|
|
|
|
|
watch(
|
|
|
|
|
() => [
|
|
|
|
|
setData.value.enableDiskCache,
|
|
|
|
|
setData.value.diskCacheDir,
|
|
|
|
|
setData.value.diskCacheMaxSizeMB,
|
|
|
|
|
setData.value.diskCacheCleanupPolicy
|
|
|
|
|
],
|
|
|
|
|
() => {
|
|
|
|
|
if (!window.electron || applyingDiskCacheConfig.value || switchingCacheDirectory.value) return;
|
|
|
|
|
applyDiskCacheConfigDebounced();
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const askCacheSwitchMigrate = (): Promise<boolean> => {
|
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
let resolved = false;
|
|
|
|
|
const finish = (value: boolean) => {
|
|
|
|
|
if (resolved) return;
|
|
|
|
|
resolved = true;
|
|
|
|
|
resolve(value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
dialog.warning({
|
|
|
|
|
title: t('settings.system.switchDirectoryMigrateTitle'),
|
|
|
|
|
content: t('settings.system.switchDirectoryMigrateContent'),
|
|
|
|
|
positiveText: t('settings.system.switchDirectoryMigrateConfirm'),
|
|
|
|
|
negativeText: t('settings.system.switchDirectoryKeepOld'),
|
|
|
|
|
onPositiveClick: () => finish(true),
|
|
|
|
|
onNegativeClick: () => finish(false),
|
|
|
|
|
onClose: () => finish(false)
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const askCacheSwitchDestroy = (): Promise<boolean> => {
|
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
let resolved = false;
|
|
|
|
|
const finish = (value: boolean) => {
|
|
|
|
|
if (resolved) return;
|
|
|
|
|
resolved = true;
|
|
|
|
|
resolve(value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
dialog.warning({
|
|
|
|
|
title: t('settings.system.switchDirectoryDestroyTitle'),
|
|
|
|
|
content: t('settings.system.switchDirectoryDestroyContent'),
|
|
|
|
|
positiveText: t('settings.system.switchDirectoryDestroyConfirm'),
|
|
|
|
|
negativeText: t('settings.system.switchDirectoryKeepOld'),
|
|
|
|
|
onPositiveClick: () => finish(true),
|
|
|
|
|
onNegativeClick: () => finish(false),
|
|
|
|
|
onClose: () => finish(false)
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const selectCacheDirectory = async () => {
|
|
|
|
|
if (!window.electron) return;
|
|
|
|
|
|
|
|
|
|
const selectedPath = await selectDirectory(message);
|
|
|
|
|
if (!selectedPath) return;
|
|
|
|
|
|
|
|
|
|
const currentDirectory = setData.value.diskCacheDir || diskCacheStats.value.directory;
|
|
|
|
|
if (currentDirectory && selectedPath === currentDirectory) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let action: CacheSwitchAction = 'keep';
|
|
|
|
|
if (currentDirectory && diskCacheStats.value.totalFiles > 0) {
|
|
|
|
|
const shouldMigrate = await askCacheSwitchMigrate();
|
|
|
|
|
if (shouldMigrate) {
|
|
|
|
|
action = 'migrate';
|
|
|
|
|
} else {
|
|
|
|
|
const shouldDestroy = await askCacheSwitchDestroy();
|
|
|
|
|
action = shouldDestroy ? 'destroy' : 'keep';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switchingCacheDirectory.value = true;
|
|
|
|
|
try {
|
|
|
|
|
const result = (await window.electron.ipcRenderer.invoke('switch-disk-cache-directory', {
|
|
|
|
|
directory: selectedPath,
|
|
|
|
|
action
|
|
|
|
|
})) as SwitchCacheDirectoryResult;
|
|
|
|
|
|
|
|
|
|
if (!result?.success) {
|
|
|
|
|
message.error(t('settings.system.messages.switchDirectoryFailed'));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setData.value = {
|
|
|
|
|
...setData.value,
|
|
|
|
|
enableDiskCache: result.config.enabled,
|
|
|
|
|
diskCacheDir: result.config.directory,
|
|
|
|
|
diskCacheMaxSizeMB: result.config.maxSizeMB,
|
|
|
|
|
diskCacheCleanupPolicy: result.config.cleanupPolicy
|
|
|
|
|
};
|
|
|
|
|
await refreshDiskCacheStats();
|
|
|
|
|
|
|
|
|
|
if (action === 'migrate') {
|
|
|
|
|
message.success(
|
|
|
|
|
t('settings.system.messages.switchDirectoryMigrated', { count: result.migratedFiles })
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (action === 'destroy') {
|
|
|
|
|
message.success(
|
|
|
|
|
t('settings.system.messages.switchDirectoryDestroyed', { count: result.destroyedFiles })
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
message.success(t('settings.system.messages.switchDirectorySuccess'));
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('切换缓存目录失败:', error);
|
|
|
|
|
message.error(t('settings.system.messages.switchDirectoryFailed'));
|
|
|
|
|
} finally {
|
|
|
|
|
switchingCacheDirectory.value = false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const openCacheDirectory = () => {
|
|
|
|
|
const targetPath = setData.value.diskCacheDir || diskCacheStats.value.directory;
|
|
|
|
|
openDirectory(targetPath, message);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const clearDiskCacheByScope = async (scope: DiskCacheScope) => {
|
|
|
|
|
if (!window.electron) return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const success = await window.electron.ipcRenderer.invoke('clear-disk-cache', scope);
|
|
|
|
|
if (success) {
|
|
|
|
|
await refreshDiskCacheStats();
|
|
|
|
|
message.success(t('settings.system.messages.diskCacheClearSuccess'));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
message.error(t('settings.system.messages.diskCacheClearFailed'));
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('手动清理磁盘缓存失败:', error);
|
|
|
|
|
message.error(t('settings.system.messages.diskCacheClearFailed'));
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// ==================== 代理设置 ====================
|
|
|
|
|
const showProxyModal = ref(false);
|
|
|
|
|
const proxyForm = ref({ protocol: 'http', host: '127.0.0.1', port: 7890 });
|
|
|
|
@@ -883,6 +1287,7 @@ const clearCache = async (selectedCacheTypes: string[]) => {
|
|
|
|
|
case 'resources':
|
|
|
|
|
if (window.electron) {
|
|
|
|
|
window.electron.ipcRenderer.send('clear-audio-cache');
|
|
|
|
|
await window.electron.ipcRenderer.invoke('clear-disk-cache', 'music');
|
|
|
|
|
}
|
|
|
|
|
localStorage.removeItem('lyricCache');
|
|
|
|
|
localStorage.removeItem('musicUrlCache');
|
|
|
|
@@ -897,11 +1302,15 @@ const clearCache = async (selectedCacheTypes: string[]) => {
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'lyrics':
|
|
|
|
|
window.api.invoke('clear-lyrics-cache');
|
|
|
|
|
if (window.electron) {
|
|
|
|
|
await window.electron.ipcRenderer.invoke('clear-disk-cache', 'lyrics');
|
|
|
|
|
}
|
|
|
|
|
await window.api.invoke('clear-lyrics-cache');
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
await Promise.all(clearTasks);
|
|
|
|
|
await refreshDiskCacheStats();
|
|
|
|
|
message.success(t('settings.system.messages.clearSuccess'));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@@ -997,6 +1406,18 @@ onMounted(async () => {
|
|
|
|
|
if (setData.value.enableRealIP === undefined) {
|
|
|
|
|
setData.value = { ...setData.value, enableRealIP: false };
|
|
|
|
|
}
|
|
|
|
|
if (setData.value.enableDiskCache === undefined) {
|
|
|
|
|
setData.value = { ...setData.value, enableDiskCache: true };
|
|
|
|
|
}
|
|
|
|
|
if (!setData.value.diskCacheMaxSizeMB) {
|
|
|
|
|
setData.value = { ...setData.value, diskCacheMaxSizeMB: 4096 };
|
|
|
|
|
}
|
|
|
|
|
if (!['lru', 'fifo'].includes(setData.value.diskCacheCleanupPolicy)) {
|
|
|
|
|
setData.value = { ...setData.value, diskCacheCleanupPolicy: 'lru' };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await loadDiskCacheConfig();
|
|
|
|
|
await refreshDiskCacheStats();
|
|
|
|
|
|
|
|
|
|
if (window.electron) {
|
|
|
|
|
window.electron.ipcRenderer.on('gpu-acceleration-updated', (_, enabled: boolean) => {
|
|
|
|
|