mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-05-12 02:21:06 +08:00
优化配置向导
This commit is contained in:
@@ -10,7 +10,6 @@ const props = defineProps({
|
||||
root: {
|
||||
type: String,
|
||||
default: '/',
|
||||
required: true,
|
||||
},
|
||||
storage: {
|
||||
type: String,
|
||||
|
||||
@@ -232,12 +232,13 @@ export function useSetupWizard() {
|
||||
if (wizardData.value.downloader.type === type) {
|
||||
// 重复点击已选中的类型,取消选择
|
||||
wizardData.value.downloader.type = ''
|
||||
wizardData.value.downloader.name = ''
|
||||
wizardData.value.downloader.config = {}
|
||||
} else {
|
||||
wizardData.value.downloader.type = type
|
||||
wizardData.value.downloader.name = `${type} 下载器`
|
||||
wizardData.value.downloader.config = {}
|
||||
// 如果名称为空或为默认名称,则设置默认名称
|
||||
if (!wizardData.value.downloader.name || wizardData.value.downloader.name.includes('下载器')) {
|
||||
wizardData.value.downloader.name = `${type} 下载器`
|
||||
}
|
||||
// 不清空config,保留用户已输入的值
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,14 +247,13 @@ export function useSetupWizard() {
|
||||
if (wizardData.value.mediaServer.type === type) {
|
||||
// 重复点击已选中的类型,取消选择
|
||||
wizardData.value.mediaServer.type = ''
|
||||
wizardData.value.mediaServer.name = ''
|
||||
wizardData.value.mediaServer.config = {}
|
||||
wizardData.value.mediaServer.sync_libraries = []
|
||||
} else {
|
||||
wizardData.value.mediaServer.type = type
|
||||
wizardData.value.mediaServer.name = `${type} 服务器`
|
||||
wizardData.value.mediaServer.config = {}
|
||||
wizardData.value.mediaServer.sync_libraries = []
|
||||
// 如果名称为空或为默认名称,则设置默认名称
|
||||
if (!wizardData.value.mediaServer.name || wizardData.value.mediaServer.name.includes('服务器')) {
|
||||
wizardData.value.mediaServer.name = `${type} 服务器`
|
||||
}
|
||||
// 不清空config和sync_libraries,保留用户已输入的值
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,16 +262,14 @@ export function useSetupWizard() {
|
||||
if (wizardData.value.notification.type === type) {
|
||||
// 重复点击已选中的类型,取消选择
|
||||
wizardData.value.notification.type = ''
|
||||
wizardData.value.notification.name = ''
|
||||
wizardData.value.notification.enabled = false
|
||||
wizardData.value.notification.config = {}
|
||||
wizardData.value.notification.switchs = []
|
||||
} else {
|
||||
wizardData.value.notification.type = type
|
||||
wizardData.value.notification.name = `${type} 通知`
|
||||
// 如果名称为空或为默认名称,则设置默认名称
|
||||
if (!wizardData.value.notification.name || wizardData.value.notification.name.includes('通知')) {
|
||||
wizardData.value.notification.name = `${type} 通知`
|
||||
}
|
||||
wizardData.value.notification.enabled = true
|
||||
wizardData.value.notification.config = {}
|
||||
wizardData.value.notification.switchs = []
|
||||
// 不清空config和switchs,保留用户已输入的值
|
||||
}
|
||||
}
|
||||
|
||||
@@ -924,6 +922,7 @@ export function useSetupWizard() {
|
||||
const directory = {
|
||||
name: '默认目录',
|
||||
storage: 'local',
|
||||
library_storage: 'local',
|
||||
download_path: wizardData.value.storage.downloadPath,
|
||||
library_path: wizardData.value.storage.libraryPath,
|
||||
priority: 0,
|
||||
@@ -955,12 +954,15 @@ export function useSetupWizard() {
|
||||
async function saveDownloaderSettings() {
|
||||
if (wizardData.value.downloader.type) {
|
||||
try {
|
||||
// 只保存当前选中类型的配置
|
||||
const config = { ...wizardData.value.downloader.config }
|
||||
|
||||
const downloader = {
|
||||
name: wizardData.value.downloader.name,
|
||||
type: wizardData.value.downloader.type,
|
||||
default: true,
|
||||
enabled: true,
|
||||
config: wizardData.value.downloader.config,
|
||||
config: config,
|
||||
}
|
||||
|
||||
const response: { [key: string]: any } = await api.post('system/setting/Downloaders', [downloader])
|
||||
@@ -981,11 +983,16 @@ export function useSetupWizard() {
|
||||
async function saveMediaServerSettings() {
|
||||
if (wizardData.value.mediaServer.type) {
|
||||
try {
|
||||
// 只保存当前选中类型的配置
|
||||
const config = { ...wizardData.value.mediaServer.config }
|
||||
const sync_libraries = [...(wizardData.value.mediaServer.sync_libraries || [])]
|
||||
|
||||
const mediaServer = {
|
||||
name: wizardData.value.mediaServer.name,
|
||||
type: wizardData.value.mediaServer.type,
|
||||
enabled: true,
|
||||
config: wizardData.value.mediaServer.config,
|
||||
config: config,
|
||||
sync_libraries: sync_libraries,
|
||||
}
|
||||
|
||||
const response: { [key: string]: any } = await api.post('system/setting/MediaServers', [mediaServer])
|
||||
@@ -1006,11 +1013,16 @@ export function useSetupWizard() {
|
||||
async function saveNotificationSettings() {
|
||||
if (wizardData.value.notification.type) {
|
||||
try {
|
||||
// 只保存当前选中类型的配置
|
||||
const config = { ...wizardData.value.notification.config }
|
||||
const switchs = [...(wizardData.value.notification.switchs || [])]
|
||||
|
||||
const notification = {
|
||||
name: wizardData.value.notification.name,
|
||||
type: wizardData.value.notification.type,
|
||||
enabled: true,
|
||||
config: wizardData.value.notification.config,
|
||||
enabled: wizardData.value.notification.enabled,
|
||||
config: config,
|
||||
switchs: switchs,
|
||||
}
|
||||
|
||||
const response: { [key: string]: any } = await api.post('system/setting/Notifications', [notification])
|
||||
|
||||
@@ -526,7 +526,7 @@ onUnmounted(() => {
|
||||
<template #prepend>
|
||||
<VIcon :icon="isAdvancedMode ? 'mdi-cog-outline' : 'mdi-wizard-hat'" />
|
||||
</template>
|
||||
<VListItemTitle>{{ t('user.systemSettings') }}</VListItemTitle>
|
||||
<VListItemTitle>{{ isAdvancedMode ? t('user.systemSettings') : t('user.wizardSettings') }}</VListItemTitle>
|
||||
</VListItem>
|
||||
|
||||
<!-- 👉 Site Auth -->
|
||||
|
||||
@@ -372,6 +372,7 @@ export default {
|
||||
deleteFailed: 'Failed to delete user!',
|
||||
profile: 'Profile',
|
||||
systemSettings: 'System Settings',
|
||||
wizardSettings: 'Setup Wizard',
|
||||
siteAuth: 'User Authentication',
|
||||
helpDocs: 'Help Documents',
|
||||
restart: 'Restart',
|
||||
@@ -2948,7 +2949,7 @@ export default {
|
||||
apiTokenRequired: 'API Token is required',
|
||||
},
|
||||
storage: {
|
||||
title: 'Storage Configuration',
|
||||
title: 'Storage',
|
||||
description: 'Configure download directory and media library directory',
|
||||
info: 'Storage Configuration',
|
||||
infoDesc: 'Configure local storage directories for download and media library management',
|
||||
@@ -2960,7 +2961,7 @@ export default {
|
||||
libraryPathRequired: 'Media library directory is required',
|
||||
},
|
||||
downloader: {
|
||||
title: 'Downloader Configuration',
|
||||
title: 'Downloader',
|
||||
description: 'Configure downloader',
|
||||
info: 'Downloader Configuration',
|
||||
infoDesc: 'Configure downloader for resource download, can choose qBittorrent or Transmission',
|
||||
@@ -2992,7 +2993,7 @@ export default {
|
||||
token: 'Access Token',
|
||||
},
|
||||
notification: {
|
||||
title: 'Notification Settings',
|
||||
title: 'Notification',
|
||||
description: 'Configure notification channels',
|
||||
info: 'Notification Configuration',
|
||||
infoDesc: 'Configure notification channels for receiving system messages (optional)',
|
||||
|
||||
@@ -370,6 +370,7 @@ export default {
|
||||
deleteFailed: '用户删除失败!',
|
||||
profile: '个人信息',
|
||||
systemSettings: '系统设定',
|
||||
wizardSettings: '设置向导',
|
||||
siteAuth: '用户认证',
|
||||
helpDocs: '帮助文档',
|
||||
restart: '重启',
|
||||
@@ -1791,11 +1792,7 @@ export default {
|
||||
webPush: 'WebPush',
|
||||
creatingUser: '正在创建【{name}】用户,请稍后',
|
||||
updatingUser: '正在更新【{name}】用户,请稍后',
|
||||
usernameRequired: '用户名不能为空',
|
||||
usernameExists: '用户名已存在',
|
||||
passwordMinLength: '密码长度不能少于6位字符',
|
||||
confirmPasswordRequired: '请确认密码',
|
||||
passwordMismatch: '两次输入的密码不一致',
|
||||
userCreated: '用户【{name}】创建成功',
|
||||
userCreateFailed: '创建用户失败:{message}',
|
||||
userUpdateSuccess: '用户【{name}】更新成功',
|
||||
@@ -2939,7 +2936,7 @@ export default {
|
||||
apiTokenRequired: 'API Token不能为空',
|
||||
},
|
||||
storage: {
|
||||
title: '存储配置',
|
||||
title: '存储',
|
||||
description: '配置下载目录和媒体库目录',
|
||||
info: '存储配置说明',
|
||||
infoDesc: '配置本地存储目录,用于下载和媒体库管理',
|
||||
@@ -2951,7 +2948,7 @@ export default {
|
||||
libraryPathRequired: '媒体库目录不能为空',
|
||||
},
|
||||
downloader: {
|
||||
title: '下载器配置',
|
||||
title: '下载器',
|
||||
description: '配置下载器',
|
||||
info: '下载器配置说明',
|
||||
infoDesc: '配置下载器用于下载资源,可选择qBittorrent或Transmission',
|
||||
@@ -2983,7 +2980,7 @@ export default {
|
||||
token: '访问令牌',
|
||||
},
|
||||
notification: {
|
||||
title: '通知设置',
|
||||
title: '通知',
|
||||
description: '配置通知渠道',
|
||||
info: '通知配置说明',
|
||||
infoDesc: '配置通知渠道用于接收系统消息(可选)',
|
||||
|
||||
@@ -371,6 +371,7 @@ export default {
|
||||
deleteFailed: '用戶刪除失敗!',
|
||||
profile: '個人信息',
|
||||
systemSettings: '系統設定',
|
||||
wizardSettings: '設定向導',
|
||||
siteAuth: '用戶認證',
|
||||
helpDocs: '幫助文檔',
|
||||
restart: '重啟',
|
||||
@@ -2903,7 +2904,7 @@ export default {
|
||||
apiTokenRequired: 'API Token 不能為空',
|
||||
},
|
||||
storage: {
|
||||
title: '儲存配置',
|
||||
title: '儲存',
|
||||
description: '設定下載目錄和媒體庫目錄',
|
||||
info: '儲存設定說明',
|
||||
infoDesc: '設定本機儲存目錄,用於下載和媒體庫管理',
|
||||
@@ -2915,7 +2916,7 @@ export default {
|
||||
libraryPathRequired: '媒體庫目錄不能為空',
|
||||
},
|
||||
downloader: {
|
||||
title: '下載器配置',
|
||||
title: '下載器',
|
||||
description: '設定下載器',
|
||||
info: '下載器設定說明',
|
||||
infoDesc: '設定下載器用於下載資源,可選擇qBittorrent或Transmission',
|
||||
@@ -2947,7 +2948,7 @@ export default {
|
||||
token: '存取權杖',
|
||||
},
|
||||
notification: {
|
||||
title: '通知設定',
|
||||
title: '通知',
|
||||
description: '設定通知管道',
|
||||
info: '通知設定說明',
|
||||
infoDesc: '設定通知管道用於接收系統訊息(可選)',
|
||||
|
||||
@@ -10,10 +10,14 @@ import MediaServerSettingsStep from '@/views/setup/MediaServerSettingsStep.vue'
|
||||
import NotificationSettingsStep from '@/views/setup/NotificationSettingsStep.vue'
|
||||
import PreferencesSettingsStep from '@/views/setup/PreferencesSettingsStep.vue'
|
||||
import ConnectivityTest from '@/views/setup/ConnectivityTest.vue'
|
||||
import { useDisplay } from 'vuetify'
|
||||
|
||||
const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
|
||||
// 显示器宽度
|
||||
const display = useDisplay()
|
||||
|
||||
const { currentStep, totalSteps, stepTitles, connectivityTest, nextStep, prevStep, completeWizard, initialize } =
|
||||
useSetupWizard()
|
||||
|
||||
@@ -28,20 +32,27 @@ onMounted(async () => {
|
||||
<!-- 全屏头部 -->
|
||||
<div class="setup-wizard-header">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<div class="d-flex align-center text-center mx-auto">
|
||||
<!-- 左侧占位 -->
|
||||
<div style="inline-size: 40px"></div>
|
||||
|
||||
<!-- 中间标题 -->
|
||||
<div class="d-flex align-center text-center">
|
||||
<div>
|
||||
<h1 class="text-h3 font-weight-bold text-moviepilot mb-3">{{ t('setupWizard.title') }}</h1>
|
||||
<p class="text-body-1 text-medium-emphasis">{{ t('setupWizard.subtitle') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧关闭按钮 -->
|
||||
<VBtn variant="text" icon="mdi-close" @click="router.push('/')" size="small" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 向导内容 -->
|
||||
<div class="setup-wizard-content">
|
||||
<div class="setup-wizard">
|
||||
<VCard max-width="800px" class="mx-auto my-7">
|
||||
<VCardText>
|
||||
<!-- 使用 VStepper 组件 -->
|
||||
<VStepper v-model="currentStep" class="elevation-0" flat>
|
||||
<VStepper v-model="currentStep" class="elevation-0" flat alt-labels :mobile="display.smAndDown.value">
|
||||
<!-- 步骤标题 -->
|
||||
<VStepperHeader class="elevation-0">
|
||||
<template v-for="(step, index) in stepTitles" :key="index">
|
||||
@@ -49,6 +60,7 @@ onMounted(async () => {
|
||||
:value="index + 1"
|
||||
:complete="currentStep > index + 1"
|
||||
:color="currentStep >= index + 1 ? 'primary' : 'default'"
|
||||
complete-icon="mdi-check-circle"
|
||||
>
|
||||
<template #title>
|
||||
<span class="text-caption">{{ step }}</span>
|
||||
@@ -105,15 +117,6 @@ onMounted(async () => {
|
||||
>
|
||||
{{ t('common.previous') }}
|
||||
</VBtn>
|
||||
<VBtn
|
||||
v-else
|
||||
color="primary"
|
||||
prepend-icon="mdi-keyboard-return"
|
||||
@click="router.push('/')"
|
||||
:disabled="connectivityTest.isTesting"
|
||||
>
|
||||
{{ t('common.skip') }}
|
||||
</VBtn>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2">
|
||||
@@ -138,16 +141,15 @@ onMounted(async () => {
|
||||
</div>
|
||||
</VCardActions>
|
||||
</VStepper>
|
||||
</div>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.setup-wizard-fullscreen {
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
background-color: rgb(var(--v-theme-surface));
|
||||
background-color: rgb(var(--v-theme-background));
|
||||
inset: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
@@ -161,16 +163,4 @@ onMounted(async () => {
|
||||
padding-block: 16px;
|
||||
padding-inline: 24px;
|
||||
}
|
||||
|
||||
.setup-wizard-content {
|
||||
padding: 24px;
|
||||
min-block-size: calc(100vh - 80px);
|
||||
}
|
||||
|
||||
.setup-wizard {
|
||||
padding: 20px;
|
||||
margin-block: 0;
|
||||
margin-inline: auto;
|
||||
max-inline-size: 800px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -41,7 +41,7 @@ const overwriteModeItems = [
|
||||
</VAlert>
|
||||
</VCol>
|
||||
<VCol cols="12" md="6">
|
||||
<VTextField
|
||||
<VPathField
|
||||
v-model="wizardData.storage.downloadPath"
|
||||
:label="t('setupWizard.storage.downloadPath')"
|
||||
:hint="t('setupWizard.storage.downloadPathHint')"
|
||||
@@ -55,7 +55,7 @@ const overwriteModeItems = [
|
||||
/>
|
||||
</VCol>
|
||||
<VCol cols="12" md="6">
|
||||
<VTextField
|
||||
<VPathField
|
||||
v-model="wizardData.storage.libraryPath"
|
||||
:label="t('setupWizard.storage.libraryPath')"
|
||||
:hint="t('setupWizard.storage.libraryPathHint')"
|
||||
@@ -69,7 +69,7 @@ const overwriteModeItems = [
|
||||
/>
|
||||
</VCol>
|
||||
<VCol cols="12" md="6">
|
||||
<VAutocomplete
|
||||
<VSelect
|
||||
v-model="wizardData.storage.transferType"
|
||||
:label="t('directory.transferType')"
|
||||
:hint="t('directory.transferTypeHint')"
|
||||
@@ -79,7 +79,7 @@ const overwriteModeItems = [
|
||||
/>
|
||||
</VCol>
|
||||
<VCol cols="12" md="6">
|
||||
<VAutocomplete
|
||||
<VSelect
|
||||
v-model="wizardData.storage.overwriteMode"
|
||||
:label="t('directory.overwriteMode')"
|
||||
:hint="t('directory.overwriteModeHint')"
|
||||
|
||||
Reference in New Issue
Block a user