mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 23:56:42 +08:00
更新存储卡组件,添加自定义存储配置对话框,优化存储名称显示,并完善国际化文本
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -187,8 +187,8 @@ onUnmounted(() => {
|
|||||||
</VCardText>
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
</VHover>
|
</VHover>
|
||||||
<VDialog v-if="downloaderInfoDialog" v-model="downloaderInfoDialog" scrollable max-width="40rem" persistent>
|
<VDialog v-if="downloaderInfoDialog" v-model="downloaderInfoDialog" scrollable max-width="40rem">
|
||||||
<VCard :title="`${props.downloader.name} - ${t('downloader.title')}`" class="rounded-t">
|
<VCard :title="`${props.downloader.name} - ${t('downloader.title')}`">
|
||||||
<VDialogCloseBtn v-model="downloaderInfoDialog" />
|
<VDialogCloseBtn v-model="downloaderInfoDialog" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
@@ -329,7 +329,6 @@ onUnmounted(() => {
|
|||||||
v-model="downloaderInfo.name"
|
v-model="downloaderInfo.name"
|
||||||
:label="t('downloader.name')"
|
:label="t('downloader.name')"
|
||||||
:placeholder="t('downloader.nameRequired')"
|
:placeholder="t('downloader.nameRequired')"
|
||||||
:hint="t('downloader.name')"
|
|
||||||
persistent-hint
|
persistent-hint
|
||||||
active
|
active
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import alipan_png from '@images/misc/alipan.webp'
|
|||||||
import u115_png from '@images/misc/u115.png'
|
import u115_png from '@images/misc/u115.png'
|
||||||
import rclone_png from '@images/misc/rclone.png'
|
import rclone_png from '@images/misc/rclone.png'
|
||||||
import alist_png from '@images/misc/alist.svg'
|
import alist_png from '@images/misc/alist.svg'
|
||||||
|
import custom_png from '@images/misc/database.png'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import AliyunAuthDialog from '../dialog/AliyunAuthDialog.vue'
|
import AliyunAuthDialog from '../dialog/AliyunAuthDialog.vue'
|
||||||
import U115AuthDialog from '../dialog/U115AuthDialog.vue'
|
import U115AuthDialog from '../dialog/U115AuthDialog.vue'
|
||||||
@@ -14,7 +15,6 @@ import AlistConfigDialog from '../dialog/AlistConfigDialog.vue'
|
|||||||
import { useToast } from 'vue-toast-notification'
|
import { useToast } from 'vue-toast-notification'
|
||||||
import { isNullOrEmptyObject } from '@/@core/utils'
|
import { isNullOrEmptyObject } from '@/@core/utils'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { storageOptions } from '@/api/constants'
|
|
||||||
|
|
||||||
// 国际化
|
// 国际化
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
@@ -44,6 +44,12 @@ const used = computed(() => {
|
|||||||
return total.value - available.value
|
return total.value - available.value
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 存储
|
||||||
|
const storage_ref = ref(props.storage)
|
||||||
|
|
||||||
|
// 自定义存储名称
|
||||||
|
const customName = ref(props.storage.name)
|
||||||
|
|
||||||
// 阿里云盘认证对话框
|
// 阿里云盘认证对话框
|
||||||
const aliyunAuthDialog = ref(false)
|
const aliyunAuthDialog = ref(false)
|
||||||
// 115网盘认证对话框
|
// 115网盘认证对话框
|
||||||
@@ -52,6 +58,8 @@ const u115AuthDialog = ref(false)
|
|||||||
const rcloneConfigDialog = ref(false)
|
const rcloneConfigDialog = ref(false)
|
||||||
// AList配置对话框
|
// AList配置对话框
|
||||||
const aListConfigDialog = ref(false)
|
const aListConfigDialog = ref(false)
|
||||||
|
// 自定义存储配置对话框
|
||||||
|
const customConfigDialog = ref(false)
|
||||||
|
|
||||||
// 打开存储对话框
|
// 打开存储对话框
|
||||||
function openStorageDialog() {
|
function openStorageDialog() {
|
||||||
@@ -68,6 +76,9 @@ function openStorageDialog() {
|
|||||||
case 'alist':
|
case 'alist':
|
||||||
aListConfigDialog.value = true
|
aListConfigDialog.value = true
|
||||||
break
|
break
|
||||||
|
case 'custom':
|
||||||
|
customConfigDialog.value = true
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
$toast.info(t('storage.noConfigNeeded'))
|
$toast.info(t('storage.noConfigNeeded'))
|
||||||
break
|
break
|
||||||
@@ -87,6 +98,8 @@ const getIcon = computed(() => {
|
|||||||
return rclone_png
|
return rclone_png
|
||||||
case 'alist':
|
case 'alist':
|
||||||
return alist_png
|
return alist_png
|
||||||
|
case 'custom':
|
||||||
|
return custom_png
|
||||||
default:
|
default:
|
||||||
return storage_png
|
return storage_png
|
||||||
}
|
}
|
||||||
@@ -125,12 +138,9 @@ function handleDone() {
|
|||||||
u115AuthDialog.value = false
|
u115AuthDialog.value = false
|
||||||
rcloneConfigDialog.value = false
|
rcloneConfigDialog.value = false
|
||||||
aListConfigDialog.value = false
|
aListConfigDialog.value = false
|
||||||
emit('done')
|
customConfigDialog.value = false
|
||||||
}
|
storage_ref.value.name = customName.value
|
||||||
|
emit('done', storage_ref.value)
|
||||||
// 根据存储类型获取文本
|
|
||||||
function getStorageTypeText(type: string) {
|
|
||||||
return storageOptions.find(option => option.value === type)?.title
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -148,7 +158,7 @@ function onClose() {
|
|||||||
<VDialogCloseBtn v-if="storage.type == 'custom'" @click="onClose" />
|
<VDialogCloseBtn v-if="storage.type == 'custom'" @click="onClose" />
|
||||||
<VCardText class="flex justify-space-between align-center gap-3">
|
<VCardText class="flex justify-space-between align-center gap-3">
|
||||||
<div class="align-self-start flex-1">
|
<div class="align-self-start flex-1">
|
||||||
<h5 class="text-h6 mb-1">{{ getStorageTypeText(storage.type) }}</h5>
|
<h5 class="text-h6 mb-1">{{ storage.name }}</h5>
|
||||||
<template v-if="storage.type != 'custom'">
|
<template v-if="storage.type != 'custom'">
|
||||||
<div class="mb-3 text-sm" v-if="total">{{ formatBytes(used, 1) }} / {{ formatBytes(total, 1) }}</div>
|
<div class="mb-3 text-sm" v-if="total">{{ formatBytes(used, 1) }} / {{ formatBytes(total, 1) }}</div>
|
||||||
<div v-else-if="isNullOrEmptyObject(storage.config)">{{ t('storage.notConfigured') }}</div>
|
<div v-else-if="isNullOrEmptyObject(storage.config)">{{ t('storage.notConfigured') }}</div>
|
||||||
@@ -157,7 +167,7 @@ function onClose() {
|
|||||||
<div class="mb-3 text-sm">{{ t('storage.custom') }}</div>
|
<div class="mb-3 text-sm">{{ t('storage.custom') }}</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<VImg :src="getIcon" cover class="mt-5" max-width="3rem" min-width="3rem" />
|
<VImg :src="getIcon" cover class="mt-7" max-width="3rem" min-width="3rem" />
|
||||||
</VCardText>
|
</VCardText>
|
||||||
<div class="w-full absolute bottom-0">
|
<div class="w-full absolute bottom-0">
|
||||||
<VProgressLinear v-if="usage > 0" :model-value="usage" :bg-color="progressColor" :color="progressColor" />
|
<VProgressLinear v-if="usage > 0" :model-value="usage" :bg-color="progressColor" :color="progressColor" />
|
||||||
@@ -191,5 +201,26 @@ function onClose() {
|
|||||||
@close="aListConfigDialog = false"
|
@close="aListConfigDialog = false"
|
||||||
@done="handleDone"
|
@done="handleDone"
|
||||||
/>
|
/>
|
||||||
|
<VDialog v-if="customConfigDialog" v-model="customConfigDialog" scrollable max-width="30rem">
|
||||||
|
<VCard>
|
||||||
|
<VCardItem>
|
||||||
|
<VCardTitle>{{ t('storage.custom') }}</VCardTitle>
|
||||||
|
<VDialogCloseBtn v-model="customConfigDialog" />
|
||||||
|
</VCardItem>
|
||||||
|
<VDivider />
|
||||||
|
<VCardText>
|
||||||
|
<VRow>
|
||||||
|
<VCol cols="12" md="6">
|
||||||
|
<VTextField v-model="customName" :label="t('storage.name')" persistent-hint active />
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</VCardText>
|
||||||
|
<VCardActions class="pt-3">
|
||||||
|
<VBtn @click="handleDone" variant="elevated" prepend-icon="mdi-content-save" class="px-5">
|
||||||
|
{{ t('common.save') }}
|
||||||
|
</VBtn>
|
||||||
|
</VCardActions>
|
||||||
|
</VCard>
|
||||||
|
</VDialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -727,6 +727,7 @@ export default {
|
|||||||
episode: 'Episode {number}',
|
episode: 'Episode {number}',
|
||||||
},
|
},
|
||||||
storage: {
|
storage: {
|
||||||
|
name: 'Name',
|
||||||
usedPercent: '{percent}% Used',
|
usedPercent: '{percent}% Used',
|
||||||
noConfigNeeded: 'This storage type does not require configuration, please configure the directory directly!',
|
noConfigNeeded: 'This storage type does not require configuration, please configure the directory directly!',
|
||||||
notConfigured: 'Not Configured',
|
notConfigured: 'Not Configured',
|
||||||
|
|||||||
@@ -724,6 +724,7 @@ export default {
|
|||||||
episode: '第{number}集',
|
episode: '第{number}集',
|
||||||
},
|
},
|
||||||
storage: {
|
storage: {
|
||||||
|
name: '名称',
|
||||||
usedPercent: '已使用 {percent}%',
|
usedPercent: '已使用 {percent}%',
|
||||||
noConfigNeeded: '此存储类型无需配置参数,请直接配置目录!',
|
noConfigNeeded: '此存储类型无需配置参数,请直接配置目录!',
|
||||||
notConfigured: '未配置',
|
notConfigured: '未配置',
|
||||||
|
|||||||
@@ -725,6 +725,7 @@ export default {
|
|||||||
episode: '第{number}集',
|
episode: '第{number}集',
|
||||||
},
|
},
|
||||||
storage: {
|
storage: {
|
||||||
|
name: '名稱',
|
||||||
usedPercent: '已使用 {percent}%',
|
usedPercent: '已使用 {percent}%',
|
||||||
noConfigNeeded: '此存儲類型無需配置參數,請直接配置目錄!',
|
noConfigNeeded: '此存儲類型無需配置參數,請直接配置目錄!',
|
||||||
notConfigured: '未配置',
|
notConfigured: '未配置',
|
||||||
|
|||||||
@@ -102,11 +102,6 @@ async function saveStorages() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改后生效
|
|
||||||
async function updatedStorage() {
|
|
||||||
await loadStorages()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询目录
|
// 查询目录
|
||||||
async function loadDirectories() {
|
async function loadDirectories() {
|
||||||
try {
|
try {
|
||||||
@@ -177,7 +172,7 @@ async function loadMediaCategories() {
|
|||||||
// 添加存储
|
// 添加存储
|
||||||
function addStorage() {
|
function addStorage() {
|
||||||
storages.value.push({
|
storages.value.push({
|
||||||
name: '自定义存储',
|
name: `${t('storage.custom')} ${storages.value.length + 1}`,
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
config: {},
|
config: {},
|
||||||
})
|
})
|
||||||
@@ -191,6 +186,14 @@ function removeStorage(storage: StorageConf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新存储
|
||||||
|
async function updatedStorage(storage: StorageConf) {
|
||||||
|
const index = storages.value.indexOf(storage)
|
||||||
|
if (index > -1) {
|
||||||
|
storages.value[index] = storage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 保存设置
|
// 保存设置
|
||||||
async function saveSystemSettings(value: any) {
|
async function saveSystemSettings(value: any) {
|
||||||
try {
|
try {
|
||||||
@@ -229,7 +232,7 @@ onMounted(() => {
|
|||||||
:component-data="{ 'class': 'grid gap-3 grid-app-card' }"
|
:component-data="{ 'class': 'grid gap-3 grid-app-card' }"
|
||||||
>
|
>
|
||||||
<template #item="{ element }">
|
<template #item="{ element }">
|
||||||
<StorageCard :storage="element" @done="updatedStorage" @close="removeStorage(element)" />
|
<StorageCard :storage="element" @close="removeStorage(element)" @done="updatedStorage" />
|
||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
|
|||||||
Reference in New Issue
Block a user