mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-05-11 18:10:49 +08:00
feat:系统设置面板
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "moviepilot",
|
||||
"version": "1.6.4",
|
||||
"version": "1.6.4-1",
|
||||
"private": true,
|
||||
"bin": "dist/service.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -8,6 +8,7 @@ import AccountSettingAbout from '@/views/setting/AccountSettingAbout.vue'
|
||||
import AccountSettingSearch from '@/views/setting/AccountSettingSearch.vue'
|
||||
import AccountSettingSubscribe from '@/views/setting/AccountSettingSubscribe.vue'
|
||||
import AccountSettingService from '@/views/setting/AccountSettingService.vue'
|
||||
import AccountSettingSystem from '@/views/setting/AccountSettingSystem.vue'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
@@ -20,6 +21,11 @@ const tabs = [
|
||||
icon: 'mdi-account',
|
||||
tab: 'account',
|
||||
},
|
||||
{
|
||||
title: '系统',
|
||||
icon: 'mdi-cog',
|
||||
tab: 'system',
|
||||
},
|
||||
{
|
||||
title: '站点',
|
||||
icon: 'mdi-web',
|
||||
@@ -83,6 +89,13 @@ const tabs = [
|
||||
</transition>
|
||||
</VWindowItem>
|
||||
|
||||
<!-- 系统 -->
|
||||
<VWindowItem value="system">
|
||||
<transition name="fade-slide" appear>
|
||||
<AccountSettingSystem />
|
||||
</transition>
|
||||
</VWindowItem>
|
||||
|
||||
<!-- 站点 -->
|
||||
<VWindowItem value="site">
|
||||
<transition name="fade-slide" appear>
|
||||
|
||||
@@ -5,6 +5,29 @@ import type { NotificationSwitch } from '@/api/types'
|
||||
|
||||
const messagemTypes = ref<NotificationSwitch[]>([])
|
||||
|
||||
// 选中的消息渠道
|
||||
const selectedChannels = ref([])
|
||||
|
||||
// 消息渠道
|
||||
const NotificationChannels = [
|
||||
{
|
||||
title: '微信',
|
||||
value: 'wechat',
|
||||
},
|
||||
{
|
||||
title: 'Telegram',
|
||||
value: 'telegram',
|
||||
},
|
||||
{
|
||||
title: 'Slack',
|
||||
value: 'slack',
|
||||
},
|
||||
{
|
||||
title: 'SynologyChat',
|
||||
value: 'synologychat',
|
||||
},
|
||||
]
|
||||
|
||||
// 提示框
|
||||
const $toast = useToast()
|
||||
|
||||
@@ -40,79 +63,147 @@ async function saveNotificationSwitchs() {
|
||||
}
|
||||
}
|
||||
|
||||
// 调用API查询消息渠道设置
|
||||
async function loadNotificationChannels() {
|
||||
try {
|
||||
const result: { [key: string]: any } = await api.get('system/setting/MESSAGER')
|
||||
if (result.success)
|
||||
selectedChannels.value = result.data?.value?.split(',')
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 调用API保存消息渠道设置
|
||||
async function saveNotificationChannels() {
|
||||
try {
|
||||
const result: { [key: string]: any } = await api.post(
|
||||
'system/setting/MESSAGER',
|
||||
selectedChannels.value.join(','),
|
||||
)
|
||||
|
||||
if (result.success)
|
||||
$toast.success('保存通知渠道设置成功')
|
||||
else
|
||||
$toast.error('保存通知渠道设置失败!')
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadNotificationSwitchs()
|
||||
loadNotificationChannels()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard title="消息通知">
|
||||
<VCardText> 对应消息类型只会发送给选中的消息渠道。 </VCardText>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VCard title="通知渠道">
|
||||
<VCardSubtitle>只有选中的渠道才会发送消息。</VCardSubtitle>
|
||||
<VCardText>
|
||||
<VForm>
|
||||
<VRow>
|
||||
<VCol cols="12" md="6">
|
||||
<VSelect
|
||||
v-model="selectedChannels"
|
||||
multiple
|
||||
chips
|
||||
:items="NotificationChannels"
|
||||
label="当前使用通知渠道"
|
||||
/>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
<VCardText>
|
||||
<VForm @submit.prevent="() => {}">
|
||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||
<VBtn
|
||||
mtype="submit"
|
||||
@click="saveNotificationChannels"
|
||||
>
|
||||
保存
|
||||
</VBtn>
|
||||
</div>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VCard title="消息类型">
|
||||
<VCardSubtitle> 对应消息类型只会发送给选中的消息渠道。 </VCardSubtitle>
|
||||
<VTable class="text-no-wrap">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
消息类型
|
||||
</th>
|
||||
<th scope="col">
|
||||
微信
|
||||
</th>
|
||||
<th scope="col">
|
||||
Telegram
|
||||
</th>
|
||||
<th scope="col">
|
||||
Slack
|
||||
</th>
|
||||
<th scope="col">
|
||||
SynologyChat
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="message in messagemTypes"
|
||||
:key="message.mtype"
|
||||
>
|
||||
<td>
|
||||
{{ message.mtype }}
|
||||
</td>
|
||||
<td>
|
||||
<VCheckbox v-model="message.wechat" />
|
||||
</td>
|
||||
<td>
|
||||
<VCheckbox v-model="message.telegram" />
|
||||
</td>
|
||||
<td>
|
||||
<VCheckbox v-model="message.slack" />
|
||||
</td>
|
||||
<td>
|
||||
<VCheckbox v-model="message.synologychat" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="messagemTypes.length === 0">
|
||||
<td
|
||||
colspan="4"
|
||||
class="text-center"
|
||||
>
|
||||
没有设置任何通知渠道
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</VTable>
|
||||
<VDivider />
|
||||
|
||||
<VTable class="text-no-wrap">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
消息类型
|
||||
</th>
|
||||
<th scope="col">
|
||||
微信
|
||||
</th>
|
||||
<th scope="col">
|
||||
Telegram
|
||||
</th>
|
||||
<th scope="col">
|
||||
Slack
|
||||
</th>
|
||||
<th scope="col">
|
||||
SynologyChat
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="message in messagemTypes"
|
||||
:key="message.mtype"
|
||||
>
|
||||
<td>
|
||||
{{ message.mtype }}
|
||||
</td>
|
||||
<td>
|
||||
<VCheckbox v-model="message.wechat" />
|
||||
</td>
|
||||
<td>
|
||||
<VCheckbox v-model="message.telegram" />
|
||||
</td>
|
||||
<td>
|
||||
<VCheckbox v-model="message.slack" />
|
||||
</td>
|
||||
<td>
|
||||
<VCheckbox v-model="message.synologychat" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="messagemTypes.length === 0">
|
||||
<td
|
||||
colspan="4"
|
||||
class="text-center"
|
||||
>
|
||||
没有设置任何通知渠道
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</VTable>
|
||||
<VDivider />
|
||||
|
||||
<VCardText>
|
||||
<VForm @submit.prevent="() => {}">
|
||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||
<VBtn
|
||||
mtype="submit"
|
||||
@click="saveNotificationSwitchs"
|
||||
>
|
||||
保存
|
||||
</VBtn>
|
||||
</div>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
<VCardText>
|
||||
<VForm @submit.prevent="() => {}">
|
||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||
<VBtn
|
||||
mtype="submit"
|
||||
@click="saveNotificationSwitchs"
|
||||
>
|
||||
保存
|
||||
</VBtn>
|
||||
</div>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
|
||||
@@ -78,7 +78,7 @@ onUnmounted(() => {
|
||||
|
||||
<template>
|
||||
<VCard title="定时作业">
|
||||
<VCardText> 手动执行不会影响作业正常的时间表。 </VCardText>
|
||||
<VCardSubtitle> 手动执行不会影响作业正常的时间表。 </VCardSubtitle>
|
||||
|
||||
<VTable class="text-no-wrap">
|
||||
<thead>
|
||||
|
||||
@@ -94,7 +94,7 @@ onMounted(() => {
|
||||
<VSelect
|
||||
v-model="selectedTorrentPriority"
|
||||
:items="TorrentPriorityItems"
|
||||
label="优先规则"
|
||||
label="当前使用下载优先规则"
|
||||
outlined
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
194
src/views/setting/AccountSettingSystem.vue
Normal file
194
src/views/setting/AccountSettingSystem.vue
Normal file
@@ -0,0 +1,194 @@
|
||||
<script lang="ts" setup>
|
||||
import { useToast } from 'vue-toast-notification'
|
||||
import api from '@/api'
|
||||
|
||||
// 选中的下载器
|
||||
const selectedDownloader = ref('')
|
||||
|
||||
// 选中的媒体服务器
|
||||
const selectedMediaServers = ref([])
|
||||
|
||||
// 是否下载器监控
|
||||
const downloaderMonitor = ref<boolean>(false)
|
||||
|
||||
// 下载器
|
||||
const Downloaders = [
|
||||
{
|
||||
title: 'Qbittorrent',
|
||||
value: 'qbittorrent',
|
||||
},
|
||||
{
|
||||
title: 'Transmission',
|
||||
value: 'transmission',
|
||||
},
|
||||
]
|
||||
|
||||
// 媒体服务器
|
||||
const MediaServers = [
|
||||
{
|
||||
title: 'Emby',
|
||||
value: 'emby',
|
||||
},
|
||||
{
|
||||
title: 'Jellyfin',
|
||||
value: 'jellyfin',
|
||||
},
|
||||
{
|
||||
title: 'Plex',
|
||||
value: 'plex',
|
||||
},
|
||||
]
|
||||
|
||||
// 提示框
|
||||
const $toast = useToast()
|
||||
|
||||
// 调用API查询下载器设置
|
||||
async function loadDownladerSetting() {
|
||||
try {
|
||||
const result1: { [key: string]: any } = await api.get('system/setting/DOWNLOADER')
|
||||
if (result1.success)
|
||||
selectedDownloader.value = result1.data?.value
|
||||
const result2: { [key: string]: any } = await api.get('system/setting/DOWNLOADER_MONITOR')
|
||||
if (result2.success)
|
||||
downloaderMonitor.value = result2.data?.value
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 调用API保存下载器设置
|
||||
async function saveDownloaderSetting() {
|
||||
try {
|
||||
const result1: { [key: string]: any } = await api.post(
|
||||
'system/setting/DOWNLOADER',
|
||||
selectedDownloader.value,
|
||||
)
|
||||
|
||||
const result2: { [key: string]: any } = await api.post(
|
||||
'system/setting/DOWNLOADER_MONITOR',
|
||||
downloaderMonitor.value,
|
||||
)
|
||||
|
||||
if (result1.success && result2.success)
|
||||
$toast.success('保存下载器设置成功')
|
||||
else
|
||||
$toast.error('保存下载器设置失败!')
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 调用API查询媒体服务器设置
|
||||
async function loadMediaServerSetting() {
|
||||
try {
|
||||
const result: { [key: string]: any } = await api.get('system/setting/MEDIASERVER')
|
||||
if (result.success)
|
||||
selectedMediaServers.value = result.data?.value?.split(',')
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 调用API保存媒体服务器设置
|
||||
async function saveMediaServerSetting() {
|
||||
try {
|
||||
const result: { [key: string]: any } = await api.post(
|
||||
'system/setting/MEDIASERVER',
|
||||
selectedMediaServers.value.join(','),
|
||||
)
|
||||
|
||||
if (result.success)
|
||||
$toast.success('保存媒体服务器设置成功')
|
||||
else
|
||||
$toast.error('保存媒体服务器设置失败!')
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadDownladerSetting()
|
||||
loadMediaServerSetting()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VCard title="下载器">
|
||||
<VCardSubtitle>只有选中的下载器才会被默认使用。</VCardSubtitle>
|
||||
<VCardText>
|
||||
<VForm>
|
||||
<VRow>
|
||||
<VCol cols="12" md="6">
|
||||
<VSelect
|
||||
v-model="selectedDownloader"
|
||||
:items="Downloaders"
|
||||
label="当前使用下载器"
|
||||
/>
|
||||
</VCol>
|
||||
</VRow>
|
||||
<VRow>
|
||||
<VCol cols="12" md="6">
|
||||
<VSwitch
|
||||
v-model="downloaderMonitor"
|
||||
label="监控下载器"
|
||||
/>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
<VCardText>
|
||||
<VForm @submit.prevent="() => {}">
|
||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||
<VBtn
|
||||
mtype="submit"
|
||||
@click="saveDownloaderSetting"
|
||||
>
|
||||
保存
|
||||
</VBtn>
|
||||
</div>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VCard title="媒体服务器">
|
||||
<VCardSubtitle>只有选中的媒体服务器才会被默认使用。</VCardSubtitle>
|
||||
<VCardText>
|
||||
<VForm>
|
||||
<VRow>
|
||||
<VCol cols="12" md="6">
|
||||
<VSelect
|
||||
v-model="selectedMediaServers"
|
||||
multiple
|
||||
chips
|
||||
:items="MediaServers"
|
||||
label="当前使用媒体服务器"
|
||||
/>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
<VCardText>
|
||||
<VForm @submit.prevent="() => {}">
|
||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||
<VBtn
|
||||
mtype="submit"
|
||||
@click="saveMediaServerSetting"
|
||||
>
|
||||
保存
|
||||
</VBtn>
|
||||
</div>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</template>
|
||||
Reference in New Issue
Block a user