feat: 国际化 (i18n) 功能实现

This commit is contained in:
alger
2025-02-19 01:01:43 +08:00
parent da2a32e420
commit ead017e4b1
64 changed files with 1870 additions and 510 deletions
+194 -141
View File
@@ -9,7 +9,7 @@
:class="{ active: currentSection === section.id }"
@click="scrollToSection(section.id)"
>
{{ section.title }}
{{ t(`settings.sections.${section.id}`) }}
</div>
</div>
@@ -18,12 +18,12 @@
<div class="set-page">
<!-- 基础设置 -->
<div id="basic" ref="basicRef" class="settings-section">
<div class="settings-section-title">基础设置</div>
<div class="settings-section-title">{{ t('settings.sections.basic') }}</div>
<div class="settings-section-content">
<div class="set-item">
<div>
<div class="set-item-title">主题模式</div>
<div class="set-item-content">切换日间/夜间主题</div>
<div class="set-item-title">{{ t('settings.basic.themeMode') }}</div>
<div class="set-item-content">{{ t('settings.basic.themeModeDesc') }}</div>
</div>
<n-switch v-model:value="isDarkTheme">
<template #checked><i class="ri-moon-line"></i></template>
@@ -31,15 +31,28 @@
</n-switch>
</div>
<!-- 语言设置 -->
<div class="set-item">
<div>
<div class="set-item-title">字体设置</div>
<div class="set-item-content">选择字体优先使用排在前面的字体</div>
<div class="set-item-title">{{ t('settings.basic.language') }}</div>
<div class="set-item-content">{{ t('settings.basic.languageDesc') }}</div>
</div>
<language-switcher />
</div>
<div class="set-item">
<div>
<div class="set-item-title">{{ t('settings.basic.font') }}</div>
<div class="set-item-content">{{ t('settings.basic.fontDesc') }}</div>
</div>
<div class="flex gap-2">
<n-radio-group v-model:value="setData.fontScope" class="mt-2">
<n-radio key="global" value="global">全局</n-radio>
<n-radio key="lyric" value="lyric">仅歌词</n-radio>
<n-radio key="global" value="global">{{
t('settings.basic.fontScope.global')
}}</n-radio>
<n-radio key="lyric" value="lyric">{{
t('settings.basic.fontScope.lyric')
}}</n-radio>
</n-radio-group>
<n-select
v-model:value="selectedFonts"
@@ -55,52 +68,52 @@
</div>
<div v-if="selectedFonts.length > 0" class="font-preview-container">
<div class="font-preview-title">字体预览</div>
<div class="font-preview-title">{{ t('settings.basic.fontPreview.title') }}</div>
<div class="font-preview" :style="{ fontFamily: setData.fontFamily }">
<div class="preview-item">
<div class="preview-label">中文</div>
<div class="preview-text">静夜思 床前明月光 疑是地上霜</div>
<div class="preview-label">{{ t('settings.basic.fontPreview.chinese') }}</div>
<div class="preview-text">{{ t('settings.basic.fontPreview.chineseText') }}</div>
</div>
<div class="preview-item">
<div class="preview-label">English</div>
<div class="preview-text">The quick brown fox jumps over the lazy dog</div>
<div class="preview-label">{{ t('settings.basic.fontPreview.english') }}</div>
<div class="preview-text">{{ t('settings.basic.fontPreview.englishText') }}</div>
</div>
<div class="preview-item">
<div class="preview-label">日本語</div>
<div class="preview-text">あいうえお かきくけこ さしすせそ</div>
<div class="preview-label">{{ t('settings.basic.fontPreview.japanese') }}</div>
<div class="preview-text">{{ t('settings.basic.fontPreview.japaneseText') }}</div>
</div>
<div class="preview-item">
<div class="preview-label">한국어</div>
<div class="preview-text">가나다라마 바사아자차 카타파하</div>
<div class="preview-label">{{ t('settings.basic.fontPreview.korean') }}</div>
<div class="preview-text">{{ t('settings.basic.fontPreview.koreanText') }}</div>
</div>
</div>
</div>
<div class="set-item">
<div>
<div class="set-item-title">动画速度</div>
<div class="set-item-title">{{ t('settings.basic.animation') }}</div>
<div class="set-item-content">
<div class="flex items-center gap-2">
<n-switch v-model:value="setData.noAnimate">
<template #checked>关闭</template>
<template #unchecked>开启</template>
<template #checked>{{ t('common.off') }}</template>
<template #unchecked>{{ t('common.on') }}</template>
</n-switch>
<span>是否开启动画</span>
<span>{{ t('settings.basic.animationDesc') }}</span>
</div>
</div>
</div>
<div class="flex items-center gap-2">
<span class="text-sm text-gray-400">{{ setData.animationSpeed }}x</span>
<div class="w-40">
<div class="w-60">
<n-slider
v-model:value="setData.animationSpeed"
:min="0.1"
:max="3"
:step="0.1"
:marks="{
0.1: '极慢',
1: '正常',
3: '极快'
0.1: t('settings.basic.animationSpeed.slow'),
1: t('settings.basic.animationSpeed.normal'),
3: t('settings.basic.animationSpeed.fast')
}"
:disabled="setData.noAnimate"
class="w-40"
@@ -113,25 +126,25 @@
<!-- 播放设置 -->
<div id="playback" ref="playbackRef" class="settings-section">
<div class="settings-section-title">播放设置</div>
<div class="settings-section-title">{{ t('settings.sections.playback') }}</div>
<div class="settings-section-content">
<div class="set-item">
<div>
<div class="set-item-title">音质设置</div>
<div class="set-item-content">选择音乐播放音质VIP</div>
<div class="set-item-title">{{ t('settings.playback.quality') }}</div>
<div class="set-item-content">{{ t('settings.playback.qualityDesc') }}</div>
</div>
<n-select
v-model:value="setData.musicQuality"
:options="[
{ label: '标准', value: 'standard' },
{ label: '较高', value: 'higher' },
{ label: '极高', value: 'exhigh' },
{ label: '无损', value: 'lossless' },
{ label: 'Hi-Res', value: 'hires' },
{ label: '高清环绕声', value: 'jyeffect' },
{ label: '沉浸环绕声', value: 'sky' },
{ label: '杜比全景声', value: 'dolby' },
{ label: '超清母带', value: 'jymaster' }
{ label: t('settings.playback.qualityOptions.standard'), value: 'standard' },
{ label: t('settings.playback.qualityOptions.higher'), value: 'higher' },
{ label: t('settings.playback.qualityOptions.exhigh'), value: 'exhigh' },
{ label: t('settings.playback.qualityOptions.lossless'), value: 'lossless' },
{ label: t('settings.playback.qualityOptions.hires'), value: 'hires' },
{ label: t('settings.playback.qualityOptions.jyeffect'), value: 'jyeffect' },
{ label: t('settings.playback.qualityOptions.sky'), value: 'sky' },
{ label: t('settings.playback.qualityOptions.dolby'), value: 'dolby' },
{ label: t('settings.playback.qualityOptions.jymaster'), value: 'jymaster' }
]"
style="width: 160px"
/>
@@ -139,12 +152,12 @@
<div class="set-item">
<div>
<div class="set-item-title">自动播放</div>
<div class="set-item-content">重新打开应用时是否自动继续播放</div>
<div class="set-item-title">{{ t('settings.playback.autoPlay') }}</div>
<div class="set-item-content">{{ t('settings.playback.autoPlayDesc') }}</div>
</div>
<n-switch v-model:value="setData.autoPlay">
<template #checked>开启</template>
<template #unchecked>关闭</template>
<template #checked>{{ t('common.on') }}</template>
<template #unchecked>{{ t('common.off') }}</template>
</n-switch>
</div>
</div>
@@ -152,21 +165,19 @@
<!-- 应用设置 -->
<div v-if="isElectron" id="application" ref="applicationRef" class="settings-section">
<div class="settings-section-title">应用设置</div>
<div class="settings-section-title">{{ t('settings.sections.application') }}</div>
<div class="settings-section-content">
<div class="set-item">
<div>
<div class="set-item-title">关闭行为</div>
<div class="set-item-content">
{{ closeActionLabels[setData.closeAction] || '每次询问' }}
</div>
<div class="set-item-title">{{ t('settings.application.closeAction') }}</div>
<div class="set-item-content">{{ t('settings.application.closeActionDesc') }}</div>
</div>
<n-select
v-model:value="setData.closeAction"
:options="[
{ label: '每次询问', value: 'ask' },
{ label: '最小化到托盘', value: 'minimize' },
{ label: '直接退出', value: 'close' }
{ label: t('settings.application.closeOptions.ask'), value: 'ask' },
{ label: t('settings.application.closeOptions.minimize'), value: 'minimize' },
{ label: t('settings.application.closeOptions.close'), value: 'close' }
]"
style="width: 160px"
/>
@@ -174,40 +185,44 @@
<div class="set-item">
<div>
<div class="set-item-title">快捷键设置</div>
<div class="set-item-content">自定义全局快捷键</div>
<div class="set-item-title">{{ t('settings.application.shortcut') }}</div>
<div class="set-item-content">{{ t('settings.application.shortcutDesc') }}</div>
</div>
<n-button size="small" @click="showShortcutModal = true">配置</n-button>
<n-button size="small" @click="showShortcutModal = true">{{
t('common.configure')
}}</n-button>
</div>
<div v-if="isElectron" class="set-item">
<div>
<div class="set-item-title">下载管理</div>
<div class="set-item-title">{{ t('settings.application.download') }}</div>
<div class="set-item-content">
<n-switch v-model:value="setData.alwaysShowDownloadButton" class="mr-2">
<template #checked>显示</template>
<template #unchecked>隐藏</template>
<template #checked>{{ t('common.show') }}</template>
<template #unchecked>{{ t('common.hide') }}</template>
</n-switch>
是否始终显示下载列表按钮
{{ t('settings.application.downloadDesc') }}
</div>
</div>
<div class="flex items-center gap-2">
<n-button size="small" @click="store.commit('setShowDownloadDrawer', true)">
打开下载管理
{{ t('settings.application.download') }}
</n-button>
</div>
</div>
<div class="set-item">
<div>
<div class="set-item-title">下载目录</div>
<div class="set-item-title">{{ t('settings.application.downloadPath') }}</div>
<div class="set-item-content">
{{ setData.downloadPath || '默认下载目录' }}
{{ setData.downloadPath || t('settings.application.downloadPathDesc') }}
</div>
</div>
<div class="flex items-center gap-2">
<n-button size="small" @click="openDownloadPath">打开目录</n-button>
<n-button size="small" @click="selectDownloadPath">修改目录</n-button>
<n-button size="small" @click="openDownloadPath">{{ t('common.open') }}</n-button>
<n-button size="small" @click="selectDownloadPath">{{
t('common.modify')
}}</n-button>
</div>
</div>
</div>
@@ -215,42 +230,41 @@
<!-- 网络设置 -->
<div v-if="isElectron" id="network" ref="networkRef" class="settings-section">
<div class="settings-section-title">网络设置</div>
<div class="settings-section-title">{{ t('settings.sections.network') }}</div>
<div class="settings-section-content">
<div class="set-item">
<div>
<div class="set-item-title">音乐API端口</div>
<div class="set-item-content">修改后需要重启应用</div>
<div class="set-item-title">{{ t('settings.network.apiPort') }}</div>
<div class="set-item-content">{{ t('settings.network.apiPortDesc') }}</div>
</div>
<n-input-number v-model:value="setData.musicApiPort" />
</div>
<div class="set-item">
<div>
<div class="set-item-title">代理设置</div>
<div class="set-item-content">无法访问音乐时可以开启代理</div>
<div class="set-item-title">{{ t('settings.network.proxy') }}</div>
<div class="set-item-content">{{ t('settings.network.proxyDesc') }}</div>
</div>
<div class="flex items-center gap-2">
<n-switch v-model:value="setData.proxyConfig.enable">
<template #checked>开启</template>
<template #unchecked>关闭</template>
<template #checked>{{ t('common.on') }}</template>
<template #unchecked>{{ t('common.off') }}</template>
</n-switch>
<n-button size="small" @click="showProxyModal = true">配置</n-button>
<n-button size="small" @click="showProxyModal = true">{{
t('common.configure')
}}</n-button>
</div>
</div>
<div class="set-item">
<div>
<div class="set-item-title">realIP</div>
<div class="set-item-content">
由于限制,此项目在国外使用会受到限制可使用realIP参数,传进国内IP解决,:116.25.146.177
即可解决
</div>
<div class="set-item-title">{{ t('settings.network.realIP') }}</div>
<div class="set-item-content">{{ t('settings.network.realIPDesc') }}</div>
</div>
<div class="flex items-center gap-2">
<n-switch v-model:value="setData.enableRealIP">
<template #checked>开启</template>
<template #unchecked>关闭</template>
<template #checked>{{ t('common.on') }}</template>
<template #unchecked>{{ t('common.off') }}</template>
</n-switch>
<n-input
v-if="setData.enableRealIP"
@@ -266,48 +280,52 @@
<!-- 系统管理 -->
<div v-if="isElectron" id="system" ref="systemRef" class="settings-section">
<div class="settings-section-title">系统管理</div>
<div class="settings-section-title">{{ t('settings.sections.system') }}</div>
<div class="settings-section-content">
<div class="set-item">
<div>
<div class="set-item-title">缓存管理</div>
<div class="set-item-content">清除缓存</div>
<div class="set-item-title">{{ t('settings.system.cache') }}</div>
<div class="set-item-content">{{ t('settings.system.cacheDesc') }}</div>
</div>
<n-button size="small" @click="showClearCacheModal = true"> 清除缓存 </n-button>
<n-button size="small" @click="showClearCacheModal = true">
{{ t('settings.system.cacheDesc') }}
</n-button>
</div>
<div class="set-item">
<div>
<div class="set-item-title">重启</div>
<div class="set-item-content">重启应用</div>
<div class="set-item-title">{{ t('settings.system.restart') }}</div>
<div class="set-item-content">{{ t('settings.system.restartDesc') }}</div>
</div>
<n-button size="small" @click="restartApp">重启</n-button>
<n-button size="small" @click="restartApp">{{
t('settings.system.restart')
}}</n-button>
</div>
</div>
</div>
<!-- 关于 -->
<div id="about" ref="aboutRef" class="settings-section">
<div class="settings-section-title">关于</div>
<div class="settings-section-title">{{ t('settings.regard') }}</div>
<div class="settings-section-content">
<div class="set-item">
<div>
<div class="set-item-title">版本</div>
<div class="set-item-title">{{ t('settings.about.version') }}</div>
<div class="set-item-content">
{{ updateInfo.currentVersion }}
<template v-if="updateInfo.hasUpdate">
<n-tag type="success" class="ml-2"
>发现新版本 {{ updateInfo.latestVersion }}</n-tag
>
<n-tag type="success" class="ml-2">
{{ t('settings.about.hasUpdate') }} {{ updateInfo.latestVersion }}
</n-tag>
</template>
</div>
</div>
<div class="flex items-center gap-2">
<n-button size="small" :loading="checking" @click="checkForUpdates(true)">
{{ checking ? '检查中...' : '检查更新' }}
{{ checking ? t('settings.about.checking') : t('settings.about.checkUpdate') }}
</n-button>
<n-button v-if="updateInfo.hasUpdate" size="small" @click="openReleasePage">
前往更新
{{ t('settings.about.gotoUpdate') }}
</n-button>
</div>
</div>
@@ -318,13 +336,13 @@
>
<coffee>
<div>
<div class="set-item-title">作者</div>
<div class="set-item-content">algerkong 点个star🌟</div>
<div class="set-item-title">{{ t('settings.about.author') }}</div>
<div class="set-item-content">{{ t('settings.about.authorDesc') }}</div>
</div>
</coffee>
<div>
<n-button size="small" @click="openAuthor">
<i class="ri-github-line"></i>前往github
<i class="ri-github-line"></i>{{ t('settings.about.gotoGithub') }}
</n-button>
</div>
</div>
@@ -333,18 +351,18 @@
<!-- 捐赠支持 -->
<div id="donation" ref="donationRef" class="settings-section">
<div class="settings-section-title">捐赠支持</div>
<div class="settings-section-title">{{ t('settings.sections.donation') }}</div>
<div class="settings-section-content">
<div class="set-item">
<div>
<div class="set-item-title">捐赠支持</div>
<div class="set-item-content">感谢您的支持让我有动力能够持续改进</div>
<div class="set-item-title">{{ t('settings.sections.donation') }}</div>
<div class="set-item-content">{{ t('donation.message') }}</div>
</div>
<n-button text @click="toggleDonationList">
<template #icon>
<i :class="isDonationListVisible ? 'ri-eye-line' : 'ri-eye-off-line'" />
</template>
{{ isDonationListVisible ? '隐藏列表' : '显示列表' }}
{{ isDonationListVisible ? t('common.hide') : t('common.show') }}
</n-button>
</div>
<donation-list v-if="isDonationListVisible" />
@@ -361,9 +379,9 @@
<n-modal
v-model:show="showProxyModal"
preset="dialog"
title="代理设置"
positive-text="确认"
negative-text="取消"
:title="t('settings.network.proxy')"
:positive-text="t('common.confirm')"
:negative-text="t('common.cancel')"
:show-icon="false"
@positive-click="handleProxyConfirm"
@negative-click="showProxyModal = false"
@@ -376,7 +394,7 @@
label-width="80"
require-mark-placement="right-hanging"
>
<n-form-item label="代理协议" path="protocol">
<n-form-item :label="t('settings.network.proxy')" path="protocol">
<n-select
v-model:value="proxyForm.protocol"
:options="[
@@ -386,13 +404,16 @@
]"
/>
</n-form-item>
<n-form-item label="代理地址" path="host">
<n-input v-model:value="proxyForm.host" placeholder="请输入代理地址" />
<n-form-item :label="t('settings.network.proxyHost')" path="host">
<n-input
v-model:value="proxyForm.host"
:placeholder="t('settings.network.proxyHostPlaceholder')"
/>
</n-form-item>
<n-form-item label="代理端口" path="port">
<n-form-item :label="t('settings.network.proxyPort')" path="port">
<n-input-number
v-model:value="proxyForm.port"
placeholder="请输入代理端口"
:placeholder="t('settings.network.proxyPortPlaceholder')"
:min="1"
:max="65535"
/>
@@ -403,9 +424,9 @@
<n-modal
v-model:show="showClearCacheModal"
preset="dialog"
title="清除缓存"
positive-text="确认"
negative-text="取消"
:title="t('settings.system.cache')"
:positive-text="t('common.confirm')"
:negative-text="t('common.cancel')"
@positive-click="clearCache"
@negative-click="
() => {
@@ -414,7 +435,7 @@
"
>
<n-space vertical>
<p>请选择要清除的缓存类型:</p>
<p>{{ t('settings.system.cacheClearTitle') }}</p>
<n-checkbox-group v-model:value="selectedCacheTypes">
<n-space vertical>
<n-checkbox
@@ -425,8 +446,10 @@
>
<template #default>
<div>
<div>{{ option.label }}</div>
<div class="text-gray-400 text-sm">{{ option.description }}</div>
<div>{{ t(`settings.system.cacheTypes.${option.key}.label`) }}</div>
<div class="text-gray-400 text-sm">
{{ t(`settings.system.cacheTypes.${option.key}.description`) }}
</div>
</div>
</template>
</n-checkbox>
@@ -441,12 +464,14 @@
import type { FormRules } from 'naive-ui';
import { useMessage } from 'naive-ui';
import { computed, h, nextTick, onMounted, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useStore } from 'vuex';
import localData from '@/../main/set.json';
import Coffee from '@/components/Coffee.vue';
import DonationList from '@/components/common/DonationList.vue';
import PlayBottom from '@/components/common/PlayBottom.vue';
import LanguageSwitcher from '@/components/LanguageSwitcher.vue';
import ShortcutSettings from '@/components/settings/ShortcutSettings.vue';
import { isElectron } from '@/utils';
import { openDirectory, selectDirectory } from '@/utils/fileOperation';
@@ -463,11 +488,7 @@ const updateInfo = ref<UpdateResult>({
releaseInfo: null
});
const closeActionLabels = {
ask: '每次询问',
minimize: '最小化到托盘',
close: '直接退出'
} as const;
const { t } = useI18n();
const setData = computed(() => {
const data = store.state.setData;
@@ -515,15 +536,15 @@ const checkForUpdates = async (isClick = false) => {
if (result) {
updateInfo.value = result;
if (!result.hasUpdate && isClick) {
message.success('当前已是最新版本');
message.success(t('settings.about.latest'));
}
} else if (isClick) {
message.success('当前已是最新版本');
message.success(t('settings.about.latest'));
}
} catch (error) {
console.error('检查更新失败:', error);
if (isClick) {
message.error('检查更新失败,请稍后重试');
message.error(t('settings.about.messages.checkError'));
}
} finally {
checking.value = false;
@@ -559,12 +580,12 @@ const proxyForm = ref({
const proxyRules: FormRules = {
protocol: {
required: true,
message: '请选择代理协议',
message: t('settings.validation.selectProxyProtocol'),
trigger: ['blur', 'change']
},
host: {
required: true,
message: '请输入代理地址',
message: t('settings.validation.proxyHost'),
trigger: ['blur', 'change'],
validator: (_rule, value) => {
if (!value) return false;
@@ -576,7 +597,7 @@ const proxyRules: FormRules = {
},
port: {
required: true,
message: '请输入有效的端口号(1-65535)',
message: t('settings.validation.portNumber'),
trigger: ['blur', 'change'],
validator: (_rule, value) => {
return value >= 1 && value <= 65535;
@@ -675,9 +696,9 @@ const handleProxyConfirm = async () => {
}
});
showProxyModal.value = false;
message.success('代理设置已保存,重启应用后生效');
message.success(t('settings.network.messages.proxySuccess'));
} catch (err) {
message.error('请检查输入是否正确');
message.error(t('settings.network.messages.proxyError'));
}
};
@@ -690,10 +711,10 @@ const validateAndSaveRealIP = () => {
enableRealIP: true
});
if (setData.value.realIP) {
message.success('真实IP设置已保存');
message.success(t('settings.network.messages.realIPSuccess'));
}
} else {
message.error('请输入有效的IP地址');
message.error(t('settings.network.messages.realIPError'));
store.commit('setSetData', {
...setData.value,
realIP: ''
@@ -725,13 +746,41 @@ const toggleDonationList = () => {
// 清除缓存相关
const showClearCacheModal = ref(false);
const clearCacheOptions = ref([
{ label: '播放历史', key: 'history', description: '清除播放过的歌曲记录' },
{ label: '收藏记录', key: 'favorite', description: '清除本地收藏的歌曲记录(不会影响云端收藏)' },
{ label: '用户数据', key: 'user', description: '清除登录信息和用户相关数据' },
{ label: '应用设置', key: 'settings', description: '清除应用的所有自定义设置' },
{ label: '下载记录', key: 'downloads', description: '清除下载历史记录(不会删除已下载的文件)' },
{ label: '音乐资源', key: 'resources', description: '清除已加载的音乐文件、歌词等资源缓存' },
{ label: '歌词资源', key: 'lyrics', description: '清除已加载的歌词资源缓存' }
{
label: t('settings.system.cacheTypes.history.label'),
key: 'history',
description: t('settings.system.cacheTypes.history.description')
},
{
label: t('settings.system.cacheTypes.favorite.label'),
key: 'favorite',
description: t('settings.system.cacheTypes.favorite.description')
},
{
label: t('settings.system.cacheTypes.user.label'),
key: 'user',
description: t('settings.system.cacheTypes.user.description')
},
{
label: t('settings.system.cacheTypes.settings.label'),
key: 'settings',
description: t('settings.system.cacheTypes.settings.description')
},
{
label: t('settings.system.cacheTypes.downloads.label'),
key: 'downloads',
description: t('settings.system.cacheTypes.downloads.description')
},
{
label: t('settings.system.cacheTypes.resources.label'),
key: 'resources',
description: t('settings.system.cacheTypes.resources.description')
},
{
label: t('settings.system.cacheTypes.lyrics.label'),
key: 'lyrics',
description: t('settings.system.cacheTypes.lyrics.description')
}
]);
const selectedCacheTypes = ref<string[]>([]);
@@ -795,7 +844,7 @@ const clearCache = async () => {
});
await Promise.all(clearTasks);
message.success('清除成功,部分设置在重启后生效');
message.success(t('settings.system.messages.clearSuccess'));
showClearCacheModal.value = false;
selectedCacheTypes.value = [];
};
@@ -808,13 +857,13 @@ const handleShortcutsChange = (shortcuts: any) => {
// 定义设置分类
const settingSections = [
{ id: 'basic', title: '基础设置' },
{ id: 'playback', title: '播放设置' },
{ id: 'application', title: '应用设置', electron: true },
{ id: 'network', title: '网络设置', electron: true },
{ id: 'system', title: '系统管理', electron: true },
{ id: 'about', title: '关于' },
{ id: 'donation', title: '捐赠支持' }
{ id: 'basic', title: t('settings.sections.basic') },
{ id: 'playback', title: t('settings.sections.playback') },
{ id: 'application', title: t('settings.sections.application'), electron: true },
{ id: 'network', title: t('settings.sections.network'), electron: true },
{ id: 'system', title: t('settings.sections.system'), electron: true },
{ id: 'regard', title: t('settings.sections.regard') },
{ id: 'donation', title: t('settings.sections.donation') }
];
// 当前激活的分类
@@ -992,4 +1041,8 @@ onMounted(() => {
}
}
}
:deep(.n-select) {
width: 200px;
}
</style>