更新国际化支持

This commit is contained in:
jxxghp
2025-04-28 13:23:51 +08:00
parent 6b49464059
commit 8cf4b612d5
29 changed files with 3175 additions and 17187 deletions

View File

@@ -5,6 +5,10 @@ import FileNavigator from './filebrowser/FileNavigator.vue'
import type { EndPoints, FileItem, StorageConf } from '@/api/types'
import { storageOptions } from '@/api/constants'
import { useDisplay } from 'vuetify'
import { useI18n } from 'vue-i18n'
// 国际化
const { t } = useI18n()
// 输入参数
const props = defineProps({

View File

@@ -3,6 +3,10 @@ import type { TransferDirectoryConf } from '@/api/types'
import api from '@/api'
import { nextTick } from 'vue'
import { storageOptions } from '@/api/constants'
import { useI18n } from 'vue-i18n'
// 国际化
const { t } = useI18n()
// 输入参数
const props = defineProps({
@@ -23,11 +27,11 @@ const props = defineProps({
const isCollapsed = ref(true)
// 类型下拉字典
const typeItems = [
{ title: '全部', value: '' },
{ title: '电影', value: '电影' },
{ title: '电视剧', value: '电视剧' },
]
const typeItems = computed(() => [
{ title: t('common.all'), value: '' },
{ title: t('media.movie'), value: '电影' },
{ title: t('media.tv'), value: '电视剧' },
])
// 计算资源存储字典(整理方式为下载器时不能为远程存储)
const resourceStorageOptions = computed(() => {
@@ -35,18 +39,18 @@ const resourceStorageOptions = computed(() => {
})
// 自动整理方式下拉字典
const transferSourceItems = [
{ title: '不整理', value: '' },
{ title: '下载器监控', value: 'downloader' },
{ title: '目录监控', value: 'monitor' },
{ title: '手动整理', value: 'manual' },
]
const transferSourceItems = computed(() => [
{ title: t('directory.noTransfer'), value: '' },
{ title: t('directory.downloaderMonitor'), value: 'downloader' },
{ title: t('directory.directoryMonitor'), value: 'monitor' },
{ title: t('directory.manualTransfer'), value: 'manual' },
])
// 监控模式下拉字典
const MonitorModeItems = [
{ title: '性能模式', value: 'fast' },
{ title: '兼容模式', value: 'compatibility' },
]
const MonitorModeItems = computed(() => [
{ title: t('directory.performanceMode'), value: 'fast' },
{ title: t('directory.compatibilityMode'), value: 'compatibility' },
])
// 整理方式下拉字典
const transferTypeItems = ref<{ title: string; value: string }[]>([])
@@ -103,23 +107,23 @@ async function loadTransferTypeItems() {
// 整理方式无数据提示
const computedNoDataText = computed(() => {
if (!props.directory.library_storage && !props.directory.storage) {
return '请选择储存'
return t('directory.pleaseSelectStorage')
} else if (!props.directory.library_storage) {
return '请选择媒体库储存'
return t('directory.pleaseSelectLibraryStorage')
} else if (!props.directory.storage) {
return '请选择下载器储存'
return t('directory.pleaseSelectDownloadStorage')
} else {
return '选择的存储类型没有支持的整理方式'
return t('directory.noSupportedTransferType')
}
})
// 覆盖模式下拉字典
const overwriteModeItems = [
{ title: '从不', value: 'never' },
{ title: '总是', value: 'always' },
{ title: '按文件大小', value: 'size' },
{ title: '仅保留最新版本', value: 'latest' },
]
const overwriteModeItems = computed(() => [
{ title: t('directory.never'), value: 'never' },
{ title: t('directory.always'), value: 'always' },
{ title: t('directory.byFileSize'), value: 'size' },
{ title: t('directory.keepLatestOnly'), value: 'latest' },
])
// 定义触发的自定义事件
const emit = defineEmits(['close', 'changed', 'update:modelValue'])
@@ -131,7 +135,7 @@ function onClose() {
// 根据选中的媒体类型,获取对应的媒体类别
const getCategories = computed(() => {
const default_value = [{ title: '全部', value: '' }]
const default_value = [{ title: t('common.all'), value: '' }]
if (!props.categories || !props.categories[props.directory?.media_type ?? '']) return default_value
return default_value.concat(props.categories[props.directory.media_type ?? ''])
})
@@ -180,7 +184,7 @@ watch(
<VTextField
v-model="props.directory.name"
variant="underlined"
label="别名"
:label="t('directory.alias')"
class="me-20 text-high-emphasis font-weight-bold"
/>
<span class="absolute top-3 right-12">
@@ -197,7 +201,7 @@ watch(
v-model="props.directory.media_type"
variant="underlined"
:items="typeItems"
label="媒体类型"
:label="t('directory.mediaType')"
@update:modelValue="props.directory.media_category = ''"
/>
</VCol>
@@ -206,7 +210,7 @@ watch(
v-model="props.directory.media_category"
variant="underlined"
:items="getCategories"
label="媒体类别"
:label="t('directory.mediaCategory')"
/>
</VCol>
<VCol cols="4">
@@ -214,7 +218,7 @@ watch(
v-model="props.directory.storage"
variant="underlined"
:items="resourceStorageOptions"
label="资源存储"
:label="t('directory.resourceStorage')"
/>
</VCol>
<VCol cols="8">
@@ -222,14 +226,17 @@ watch(
v-model="props.directory.download_path"
:storage="props.directory.storage"
variant="underlined"
label="资源目录"
:label="t('directory.resourceDirectory')"
/>
</VCol>
<VCol cols="6" v-if="!props.directory.media_type || props.directory.media_type === ''">
<VSwitch v-model="props.directory.download_type_folder" label="按类型分类"></VSwitch>
<VSwitch v-model="props.directory.download_type_folder" :label="t('directory.sortByType')"></VSwitch>
</VCol>
<VCol cols="6" v-if="!props.directory.media_category || props.directory.media_category === ''">
<VSwitch v-model="props.directory.download_category_folder" label="按类别分类"></VSwitch>
<VSwitch
v-model="props.directory.download_category_folder"
:label="t('directory.sortByCategory')"
></VSwitch>
</VCol>
</VRow>
<VDivider v-if="$props.directory.monitor_type" class="my-3 bg-primary" />
@@ -239,7 +246,7 @@ watch(
v-model="props.directory.monitor_type"
variant="underlined"
:items="transferSourceItems"
label="自动整理"
:label="t('directory.autoTransfer')"
/>
</VCol>
</VRow>
@@ -249,7 +256,7 @@ watch(
v-model="props.directory.monitor_mode"
variant="underlined"
:items="MonitorModeItems"
label="监控模式"
:label="t('directory.monitorMode')"
/>
</VCol>
<VCol cols="4">
@@ -257,7 +264,7 @@ watch(
v-model="props.directory.library_storage"
variant="underlined"
:items="storageOptions"
label="媒体库存储"
:label="t('directory.libraryStorage')"
/>
</VCol>
<VCol cols="8">
@@ -265,7 +272,7 @@ watch(
v-model="props.directory.library_path"
:storage="props.directory.library_storage"
variant="underlined"
label="媒体库目录"
:label="t('directory.libraryDirectory')"
/>
</VCol>
<VCol cols="4">
@@ -273,7 +280,7 @@ watch(
v-model="props.directory.transfer_type"
variant="underlined"
:items="transferTypeItems"
label="整理方式"
:label="t('directory.transferType')"
:no-data-text="computedNoDataText"
/>
</VCol>
@@ -282,23 +289,23 @@ watch(
v-model="props.directory.overwrite_mode"
variant="underlined"
:items="overwriteModeItems"
label="覆盖模式"
:label="t('directory.overwriteMode')"
/>
</VCol>
<VCol cols="6" v-if="!props.directory.media_type || props.directory.media_type === ''">
<VSwitch v-model="props.directory.library_type_folder" label="按类型分类"></VSwitch>
<VSwitch v-model="props.directory.library_type_folder" :label="t('directory.sortByType')"></VSwitch>
</VCol>
<VCol cols="6" v-if="!props.directory.media_category || props.directory.media_category === ''">
<VSwitch v-model="props.directory.library_category_folder" label="按类别分类"></VSwitch>
<VSwitch v-model="props.directory.library_category_folder" :label="t('directory.sortByCategory')"></VSwitch>
</VCol>
<VCol cols="6">
<VSwitch v-model="props.directory.renaming" label="智能重命名"></VSwitch>
<VSwitch v-model="props.directory.renaming" :label="t('directory.smartRename')"></VSwitch>
</VCol>
<VCol cols="6">
<VSwitch v-model="props.directory.scraping" label="刮削元数据"></VSwitch>
<VSwitch v-model="props.directory.scraping" :label="t('directory.scrapingMetadata')"></VSwitch>
</VCol>
<VCol cols="6">
<VSwitch v-model="props.directory.notify" label="发送通知"></VSwitch>
<VSwitch v-model="props.directory.notify" :label="t('directory.sendNotification')"></VSwitch>
</VCol>
</VRow>
</VForm>

View File

@@ -118,14 +118,14 @@ function getMediaId() {
// 角标颜色
function getChipColor(type: string) {
if (type === t('media.movie')) return 'border-blue-500 bg-blue-600'
else if (type === t('media.tv')) return ' bg-indigo-500 border-indigo-600'
if (type === '电影') return 'border-blue-500 bg-blue-600'
else if (type === '电视剧') return ' bg-indigo-500 border-indigo-600'
else return 'border-purple-600 bg-purple-600'
}
// 添加订阅处理
async function handleAddSubscribe() {
if (props.media?.type === t('media.tv')) {
if (props.media?.type === '电视剧') {
// 弹出季选择列表,支持多选
seasonsSelected.value = []
subscribeSeasonDialog.value = true
@@ -141,7 +141,7 @@ async function addSubscribe(season: number = 0, best_version: number = 0) {
startNProgress()
try {
// 是否洗版
if (!best_version && props.media?.type == t('media.movie')) best_version = isExists.value ? 1 : 0
if (!best_version && props.media?.type == '电影') best_version = isExists.value ? 1 : 0
// 请求API
const result: { [key: string]: any } = await api.post('subscribe/', {
name: props.media?.title,
@@ -279,7 +279,7 @@ async function queryDefaultSubscribeConfig() {
if (!userStore.superUser) return false
try {
let subscribe_config_url = ''
if (props.media?.type === t('media.movie')) subscribe_config_url = 'system/setting/DefaultMovieSubscribeConfig'
if (props.media?.type === '电影') subscribe_config_url = 'system/setting/DefaultMovieSubscribeConfig'
else subscribe_config_url = 'system/setting/DefaultTvSubscribeConfig'
const result: { [key: string]: any } = await api.get(subscribe_config_url)
if (result.data?.value) return result.data.value.show_edit_dialog

View File

@@ -10,6 +10,10 @@ import api from '@/api'
import ProgressDialog from '../dialog/ProgressDialog.vue'
import { useDisplay } from 'vuetify'
import MediaInfoDialog from '../dialog/MediaInfoDialog.vue'
import { useI18n } from 'vue-i18n'
// 国际化
const { t } = useI18n()
// 显示器宽度
const display = useDisplay()
@@ -687,25 +691,31 @@ onMounted(() => {
</VCard>
<!-- 重命名弹窗 -->
<VDialog v-if="renamePopper" v-model="renamePopper" max-width="35rem">
<VCard title="重命名">
<VCard :title="t('file.rename')">
<VDialogCloseBtn @click="renamePopper = false" />
<VDivider />
<VCardText>
<VRow>
<VCol cols="12">
<VTextField v-model="newName" label="新名称" :loading="renameLoading" />
</VCol>
<VCol cols="12" v-if="currentItem && currentItem.type == 'dir'">
<VSwitch v-model="renameAll" label="自动重命名目录内所有媒体文件" />
</VCol>
</VRow>
<div class="mb-3">
<span>{{ t('file.currentName') }}: {{ currentItem?.name }}</span>
</div>
<VTextField v-model="newName" :label="t('file.newName')" />
<VCheckbox
v-if="false && currentItem?.type == 'dir'"
v-model="renameAll"
:label="t('file.includeSubfolders')"
></VCheckbox>
</VCardText>
<VCardActions>
<VBtn color="success" variant="elevated" @click="get_recommend_name" prepend-icon="mdi-magic" class="px-5 me-3">
自动识别名称
</VBtn>
<VBtn :disabled="!newName" variant="elevated" @click="rename" prepend-icon="mdi-check" class="px-5 me-3">
确定
<div class="flex-grow-1" />
<VBtn
:disabled="!newName"
variant="elevated"
:loading="renameLoading"
@click="rename"
prepend-icon="mdi-check"
class="px-5 me-3"
>
{{ t('common.save') }}
</VBtn>
</VCardActions>
</VCard>

View File

@@ -3,6 +3,10 @@ import type { PropType } from 'vue'
import type { FileItem } from '@/api/types'
import { useDisplay } from 'vuetify'
import type { AxiosRequestConfig } from 'axios'
import { useI18n } from 'vue-i18n'
// 国际化
const { t } = useI18n()
// 显示器宽度
const display = useDisplay()
@@ -276,7 +280,7 @@ function getIndentLevel(path: string, ancestorPath: string) {
>
<div class="folder-content">
<VIcon icon="mdi-home" class="me-2" color="primary" />
<span>根目录</span>
<span>{{ t('file.rootDirectory') }}</span>
</div>
</div>

View File

@@ -2,6 +2,10 @@
import type { AxiosRequestConfig } from 'axios'
import type { EndPoints, FileItem } from '@/api/types'
import { useDisplay } from 'vuetify'
import { useI18n } from 'vue-i18n'
// 国际化
const { t } = useI18n()
// 显示器宽度
const display = useDisplay()
@@ -167,16 +171,16 @@ const sortIcon = computed(() => {
<VIcon v-bind="props" icon="mdi-folder-plus-outline" />
</IconBtn>
</template>
<VCard title="新建文件夹">
<VCard :title="t('file.newFolder')">
<VDialogCloseBtn @click="newFolderPopper = false" />
<VDivider />
<VCardText>
<VTextField v-model="newFolderName" label="名称" />
<VTextField v-model="newFolderName" :label="t('common.name')" />
</VCardText>
<VCardActions>
<div class="flex-grow-1" />
<VBtn :disabled="!newFolderName" variant="elevated" @click="mkdir" prepend-icon="mdi-check" class="px-5 me-3">
新建
{{ t('common.create') }}
</VBtn>
</VCardActions>
</VCard>