更新国际化支持:为转移历史视图添加多语言文本,增强用户体验

This commit is contained in:
jxxghp
2025-04-28 17:46:58 +08:00
parent b6b19f628c
commit 434543ce41
4 changed files with 201 additions and 40 deletions
+49
View File
@@ -1565,4 +1565,53 @@ export default {
enterVerificationCode: 'Enter verification code to confirm enabling two-factor authentication', enterVerificationCode: 'Enter verification code to confirm enabling two-factor authentication',
avatarFormatTip: 'JPG, PNG, GIF, WEBP formats allowed, maximum size 800KB.', avatarFormatTip: 'JPG, PNG, GIF, WEBP formats allowed, maximum size 800KB.',
}, },
transferHistory: {
title: 'Transfer History',
searchPlaceholder: 'Search transfer records',
titleColumn: 'Title',
pathColumn: 'Path',
modeColumn: 'Mode',
sizeColumn: 'Size',
dateColumn: 'Date',
statusColumn: 'Status',
actionsColumn: 'Actions',
seasonEpisode: 'Season/Episode',
transferQueue: 'Transfer Queue',
groupMode: 'Group Mode',
listMode: 'List Mode',
deleteConfirm: 'Confirm delete {title} {seasons}{episodes}?',
deleteConfirmBatch: 'Confirm delete {count} records?',
deleteRecordOnly: 'Delete Record Only',
deleteSourceOnly: 'Delete Record and Source File',
deleteDestOnly: 'Delete Record and Media Library File',
deleteAll: 'Delete All',
transferMode: {
copy: 'Copy',
move: 'Move',
link: 'Hard Link',
softlink: 'Soft Link',
rclone_copy: 'Rclone Copy',
rclone_move: 'Rclone Move',
},
status: {
success: 'Success',
failed: 'Failed',
unknown: 'Unknown',
},
noData: 'No Data',
loading: 'Loading...',
pageSize: 'Items Per Page',
pageInfo: '{begin} - {end} / {total}',
actions: {
redo: 'Reorganize',
delete: 'Delete',
},
progress: {
processing: 'Processing',
pleaseWait: 'Please wait...',
},
table: {
emptyTitle: 'Actions',
},
},
} }
+49
View File
@@ -1543,4 +1543,53 @@ export default {
enterVerificationCode: '输入验证码以确认开启双重验证', enterVerificationCode: '输入验证码以确认开启双重验证',
avatarFormatTip: '允许 JPG、PNG、GIF、WEBP 格式, 最大尺寸 800KB。', avatarFormatTip: '允许 JPG、PNG、GIF、WEBP 格式, 最大尺寸 800KB。',
}, },
transferHistory: {
title: '转移历史',
searchPlaceholder: '搜索转移记录',
titleColumn: '标题',
pathColumn: '路径',
modeColumn: '转移方式',
sizeColumn: '大小',
dateColumn: '时间',
statusColumn: '状态',
actionsColumn: '操作',
seasonEpisode: '季集/类别',
transferQueue: '转移队列',
groupMode: '分组模式',
listMode: '列表模式',
deleteConfirm: '确认删除 {title} {seasons}{episodes} ?',
deleteConfirmBatch: '确认删除 {count} 条记录 ?',
deleteRecordOnly: '仅删除转移记录',
deleteSourceOnly: '删除转移记录和源文件',
deleteDestOnly: '删除转移记录和媒体库文件',
deleteAll: '删除转移记录、源文件和媒体库文件',
transferMode: {
copy: '复制',
move: '移动',
link: '硬链接',
softlink: '软链接',
rclone_copy: 'Rclone复制',
rclone_move: 'Rclone移动',
},
status: {
success: '成功',
failed: '失败',
unknown: '未知',
},
noData: '没有数据',
loading: '加载中...',
pageSize: '每页条数',
pageInfo: '{begin} - {end} / {total}',
actions: {
redo: '重新整理',
delete: '删除',
},
progress: {
processing: '处理中',
pleaseWait: '请稍候...',
},
table: {
emptyTitle: '操作',
},
},
} }
+49
View File
@@ -1540,4 +1540,53 @@ export default {
enterVerificationCode: '輸入驗證碼以確認開啟雙重驗證', enterVerificationCode: '輸入驗證碼以確認開啟雙重驗證',
avatarFormatTip: '允許 JPG、PNG、GIF、WEBP 格式, 最大尺寸 800KB。', avatarFormatTip: '允許 JPG、PNG、GIF、WEBP 格式, 最大尺寸 800KB。',
}, },
transferHistory: {
title: '轉移歷史',
searchPlaceholder: '搜索轉移記錄',
titleColumn: '標題',
pathColumn: '路徑',
modeColumn: '轉移方式',
sizeColumn: '大小',
dateColumn: '時間',
statusColumn: '狀態',
actionsColumn: '操作',
seasonEpisode: '季集/類別',
transferQueue: '轉移隊列',
groupMode: '分組模式',
listMode: '列表模式',
deleteConfirm: '確認刪除 {title} {seasons}{episodes}?',
deleteConfirmBatch: '確認刪除 {count} 條記錄?',
deleteRecordOnly: '僅刪除轉移記錄',
deleteSourceOnly: '刪除轉移記錄和源文件',
deleteDestOnly: '刪除轉移記錄和媒體庫文件',
deleteAll: '刪除所有',
transferMode: {
copy: '複製',
move: '移動',
link: '硬鏈接',
softlink: '軟鏈接',
rclone_copy: 'Rclone複製',
rclone_move: 'Rclone移動',
},
status: {
success: '成功',
failed: '失敗',
unknown: '未知',
},
noData: '沒有數據',
loading: '加載中...',
pageSize: '每頁條數',
pageInfo: '{begin} - {end} / {total}',
actions: {
redo: '重新整理',
delete: '刪除',
},
progress: {
processing: '處理中',
pleaseWait: '請稍候...',
},
table: {
emptyTitle: '操作',
},
},
} }
+54 -40
View File
@@ -11,6 +11,10 @@ import router from '@/router'
import { useDisplay } from 'vuetify' import { useDisplay } from 'vuetify'
import { storageDict } from '@/api/constants' import { storageDict } from '@/api/constants'
import { formatFileSize } from '@/@core/utils/formatters' import { formatFileSize } from '@/@core/utils/formatters'
import { useI18n } from 'vue-i18n'
// i18n
const { t } = useI18n()
// APP // APP
const display = useDisplay() const display = useDisplay()
@@ -44,32 +48,32 @@ const selected = ref<TransferHistory[]>([])
// 表头 // 表头
const headers = [ const headers = [
{ {
title: '标题', title: t('transferHistory.titleColumn'),
key: 'title', key: 'title',
sortable: true, sortable: true,
}, },
{ {
title: '路径', title: t('transferHistory.pathColumn'),
key: 'src', key: 'src',
sortable: true, sortable: true,
}, },
{ {
title: '转移方式', title: t('transferHistory.modeColumn'),
key: 'mode', key: 'mode',
sortable: true, sortable: true,
}, },
{ {
title: '大小', title: t('transferHistory.sizeColumn'),
key: 'size', key: 'size',
sortable: true, sortable: true,
}, },
{ {
title: '时间', title: t('transferHistory.dateColumn'),
key: 'date', key: 'date',
sortable: true, sortable: true,
}, },
{ {
title: '状态', title: t('transferHistory.statusColumn'),
key: 'status', key: 'status',
sortable: true, sortable: true,
}, },
@@ -83,32 +87,32 @@ const headers = [
// 分组表头 // 分组表头
const groupHeaders = [ const groupHeaders = [
{ {
title: '季集/类别', title: t('transferHistory.seasonEpisode'),
key: 'title', key: 'title',
sortable: true, sortable: true,
}, },
{ {
title: '路径', title: t('transferHistory.pathColumn'),
key: 'src', key: 'src',
sortable: true, sortable: true,
}, },
{ {
title: '转移方式', title: t('transferHistory.modeColumn'),
key: 'mode', key: 'mode',
sortable: true, sortable: true,
}, },
{ {
title: '大小', title: t('transferHistory.sizeColumn'),
key: 'size', key: 'size',
sortable: true, sortable: true,
}, },
{ {
title: '时间', title: t('transferHistory.dateColumn'),
key: 'date', key: 'date',
sortable: true, sortable: true,
}, },
{ {
title: '状态', title: t('transferHistory.statusColumn'),
key: 'status', key: 'status',
sortable: true, sortable: true,
}, },
@@ -163,7 +167,7 @@ const currentPage = ref<number>(ensureNumber(route.query.currentPage, 1))
const progressDialog = ref(false) const progressDialog = ref(false)
// 进度文本 // 进度文本
const progressText = ref('请稍候 ...') const progressText = ref(t('transferHistory.progress.pleaseWait'))
// 进度值 // 进度值
const progressValue = ref(0) const progressValue = ref(0)
@@ -179,12 +183,12 @@ const confirmTitle = ref('')
// 转移方式字典 // 转移方式字典
const TransferDict: { [key: string]: string } = { const TransferDict: { [key: string]: string } = {
copy: '复制', copy: t('transferHistory.transferMode.copy'),
move: '移动', move: t('transferHistory.transferMode.move'),
link: '硬链接', link: t('transferHistory.transferMode.link'),
softlink: '软链接', softlink: t('transferHistory.transferMode.softlink'),
rclone_copy: 'Rclone复制', rclone_copy: t('transferHistory.transferMode.rclone_copy'),
rclone_move: 'Rclone移动', rclone_move: t('transferHistory.transferMode.rclone_move'),
} }
const tableStyle = computed(() => { const tableStyle = computed(() => {
@@ -262,7 +266,11 @@ function getIcon(type: string) {
// 删除历史记录 // 删除历史记录
async function removeHistory(item: TransferHistory) { async function removeHistory(item: TransferHistory) {
currentHistory.value = item currentHistory.value = item
confirmTitle.value = `确认删除 ${item.title} ${item.seasons}${item.episodes} ?` confirmTitle.value = t('transferHistory.deleteConfirm', {
title: item.title,
seasons: item.seasons || '',
episodes: item.episodes || '',
})
deleteConfirmDialog.value = true deleteConfirmDialog.value = true
} }
@@ -335,7 +343,9 @@ async function removeHistoryBatch() {
// 清空当前操作记录 // 清空当前操作记录
currentHistory.value = undefined currentHistory.value = undefined
confirmTitle.value = `确认删除 ${selected.value.length} 条记录 ?` confirmTitle.value = t('transferHistory.deleteConfirmBatch', {
count: selected.value.length,
})
// 打开确认弹窗 // 打开确认弹窗
deleteConfirmDialog.value = true deleteConfirmDialog.value = true
} }
@@ -365,7 +375,7 @@ function transferDone() {
// 弹出菜单 // 弹出菜单
const dropdownItems = ref([ const dropdownItems = ref([
{ {
title: '重新整理', title: t('transferHistory.actions.redo'),
value: 1, value: 1,
props: { props: {
prependIcon: 'mdi-redo-variant', prependIcon: 'mdi-redo-variant',
@@ -377,7 +387,7 @@ const dropdownItems = ref([
}, },
}, },
{ {
title: '删除', title: t('transferHistory.actions.delete'),
value: 2, value: 2,
props: { props: {
prependIcon: 'mdi-trash-can-outline', prependIcon: 'mdi-trash-can-outline',
@@ -439,7 +449,7 @@ onMounted(fetchData)
@compositionend="isComposing = false" @compositionend="isComposing = false"
class="text-disabled" class="text-disabled"
density="compact" density="compact"
label="搜索整理记录" :label="t('transferHistory.searchPlaceholder')"
prepend-inner-icon="mdi-magnify" prepend-inner-icon="mdi-magnify"
variant="solo-filled" variant="solo-filled"
max-width="25rem" max-width="25rem"
@@ -471,12 +481,12 @@ onMounted(fetchData)
return-object return-object
fixed-header fixed-header
show-select show-select
loading-text="加载中..." :loading-text="t('transferHistory.loading')"
hover hover
:style="tableStyle" :style="tableStyle"
> >
<template #header.data-table-group> <template #header.data-table-group>
<span>标题</span> <span>{{ t('transferHistory.titleColumn') }}</span>
</template> </template>
<template v-slot:group-header="{ item, columns, toggleGroup, isGroupOpen }"> <template v-slot:group-header="{ item, columns, toggleGroup, isGroupOpen }">
<tr> <tr>
@@ -520,14 +530,14 @@ onMounted(fetchData)
</template> </template>
<template #item.mode="{ item }"> <template #item.mode="{ item }">
<VChip variant="outlined" color="primary" size="small"> <VChip variant="outlined" color="primary" size="small">
{{ TransferDict[item?.mode ?? ''] || '未知' }} {{ TransferDict[item?.mode ?? ''] || t('common.unknown') }}
</VChip> </VChip>
</template> </template>
<template #item.status="{ item }"> <template #item.status="{ item }">
<VChip v-if="item?.status" color="success" size="small"> 成功 </VChip> <VChip v-if="item?.status" color="success" size="small"> {{ t('transferHistory.status.success') }} </VChip>
<VTooltip v-else :text="item?.errmsg"> <VTooltip v-else :text="item?.errmsg">
<template #activator="{ props }"> <template #activator="{ props }">
<VChip v-bind="props" color="error" size="small"> 失败 </VChip> <VChip v-bind="props" color="error" size="small"> {{ t('transferHistory.status.failed') }} </VChip>
</template> </template>
</VTooltip> </VTooltip>
</template> </template>
@@ -557,7 +567,7 @@ onMounted(fetchData)
</VMenu> </VMenu>
</IconBtn> </IconBtn>
</template> </template>
<template #no-data> 没有数据 </template> <template #no-data> {{ t('transferHistory.noData') }} </template>
</VDataTableVirtual> </VDataTableVirtual>
<!-- 列表模式 --> <!-- 列表模式 -->
<VDataTableVirtual <VDataTableVirtual
@@ -570,7 +580,7 @@ onMounted(fetchData)
return-object return-object
fixed-header fixed-header
show-select show-select
loading-text="加载中..." :loading-text="t('transferHistory.loading')"
hover hover
:style="tableStyle" :style="tableStyle"
> >
@@ -606,14 +616,14 @@ onMounted(fetchData)
</template> </template>
<template #item.mode="{ item }"> <template #item.mode="{ item }">
<VChip variant="outlined" color="primary" size="small"> <VChip variant="outlined" color="primary" size="small">
{{ TransferDict[item?.mode ?? ''] || '未知' }} {{ TransferDict[item?.mode ?? ''] || t('common.unknown') }}
</VChip> </VChip>
</template> </template>
<template #item.status="{ item }"> <template #item.status="{ item }">
<VChip v-if="item?.status" color="success" size="small"> 成功 </VChip> <VChip v-if="item?.status" color="success" size="small"> {{ t('transferHistory.status.success') }} </VChip>
<VTooltip v-else :text="item?.errmsg"> <VTooltip v-else :text="item?.errmsg">
<template #activator="{ props }"> <template #activator="{ props }">
<VChip v-bind="props" color="error" size="small"> 失败 </VChip> <VChip v-bind="props" color="error" size="small"> {{ t('transferHistory.status.failed') }} </VChip>
</template> </template>
</VTooltip> </VTooltip>
</template> </template>
@@ -643,14 +653,14 @@ onMounted(fetchData)
</VMenu> </VMenu>
</IconBtn> </IconBtn>
</template> </template>
<template #no-data> 没有数据 </template> <template #no-data> {{ t('transferHistory.noData') }} </template>
</VDataTableVirtual> </VDataTableVirtual>
<VDivider /> <VDivider />
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div class="w-auto"> <div class="w-auto">
<VSelect v-model="itemsPerPage" :items="pageRange" density="compact" flat /> <VSelect v-model="itemsPerPage" :items="pageRange" density="compact" flat />
</div> </div>
<div class="w-auto text-sm">{{ pageTip.begin }} - {{ pageTip.end }} / {{ totalItems }}</div> <div class="w-auto text-sm">{{ t('transferHistory.pageInfo', pageTip) }}</div>
<VPagination <VPagination
v-model="currentPage" v-model="currentPage"
show-first-last-page show-first-last-page
@@ -695,13 +705,17 @@ onMounted(fetchData)
{{ confirmTitle }} {{ confirmTitle }}
</VCardTitle> </VCardTitle>
<div class="d-flex flex-column flex-lg-row justify-center my-3"> <div class="d-flex flex-column flex-lg-row justify-center my-3">
<VBtn color="primary" class="mb-2 mx-2" @click="deleteConfirmHandler(false, false)"> 仅删除整理记录 </VBtn> <VBtn color="primary" class="mb-2 mx-2" @click="deleteConfirmHandler(false, false)">
<VBtn color="warning" class="mb-2 mx-2" @click="deleteConfirmHandler(true, false)"> 删除整理记录和源文件 </VBtn> {{ t('transferHistory.deleteRecordOnly') }}
</VBtn>
<VBtn color="warning" class="mb-2 mx-2" @click="deleteConfirmHandler(true, false)">
{{ t('transferHistory.deleteSourceOnly') }}
</VBtn>
<VBtn color="info" class="mb-2 mx-2" @click="deleteConfirmHandler(false, true)"> <VBtn color="info" class="mb-2 mx-2" @click="deleteConfirmHandler(false, true)">
删除整理记录和媒体库文件 {{ t('transferHistory.deleteDestOnly') }}
</VBtn> </VBtn>
<VBtn color="error" class="mb-2 mx-2" @click="deleteConfirmHandler(true, true)"> <VBtn color="error" class="mb-2 mx-2" @click="deleteConfirmHandler(true, true)">
删除整理记录源文件和媒体库文件 {{ t('transferHistory.deleteAll') }}
</VBtn> </VBtn>
</div> </div>
</VCard> </VCard>