Compare commits

..
21 Commits
Author SHA1 Message Date
jxxghp 236440be52 fix form 2024-02-27 15:23:07 +08:00
jxxghp 6f7e4bb272 release 2024-02-26 13:21:37 +08:00
jxxghp 38dcd3635a fix text 2024-02-25 17:17:53 +08:00
jxxghp a3f3330dad fix 2024-02-25 08:58:46 +08:00
jxxghp bbc6c57c08 Merge pull request #77 from cikezhu/main 2024-02-24 06:47:02 +08:00
叮叮当 2f36a8edef fix 2024-02-23 22:27:01 +08:00
叮叮当 df637fb887 定时作业添加提供者条目 2024-02-23 22:26:16 +08:00
jxxghp be74c92a35 更新 package.json 2024-02-23 16:22:57 +08:00
jxxghp a219a64e20 Merge pull request #76 from alkalixin/main 2024-02-23 16:22:19 +08:00
alkalixin 25c22a276a 给部分按钮增加浮动提示 2024-02-23 15:07:01 +08:00
jxxghp 6e6be057ca fix ui 2024-02-23 10:45:21 +08:00
jxxghp af69efa48b feat:插件日志单独查看 2024-02-22 13:32:23 +08:00
jxxghp c551083fa4 优化插件页面加载速度 2024-02-21 17:50:02 +08:00
jxxghp 9767feed29 更新 package.json 2024-02-18 15:19:52 +08:00
jxxghp 4392818e92 Merge pull request #75 from honue/main 2024-02-18 15:17:53 +08:00
honue 8d22bafeb6 订阅卡片增加剧集详情跳转功能 2024-02-18 15:08:22 +08:00
jxxghp 89ddd1fb78 更新 package.json 2024-02-17 13:19:04 +08:00
jxxghp 24513fa22b Merge pull request #74 from honue/main 2024-02-17 13:18:46 +08:00
honue cddde0c2a0 fix 2024-02-17 13:09:48 +08:00
jxxghp 9c674e0018 更新 package.json 2024-02-15 21:06:19 +08:00
jxxghp 0c6476d283 更新 AccountSettingSystem.vue 2024-02-15 21:05:58 +08:00
13 changed files with 236 additions and 84 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "moviepilot", "name": "moviepilot",
"version": "1.6.4-3", "version": "1.6.8-1",
"private": true, "private": true,
"bin": "dist/service.js", "bin": "dist/service.js",
"scripts": { "scripts": {
+5 -1
View File
@@ -121,7 +121,11 @@ function themeTransition() {
<template> <template>
<IconBtn @click="changeTheme"> <IconBtn @click="changeTheme">
<VIcon :icon="props.themes[currentThemeIndex].icon" /> <VTooltip text="切换主题">
<template #activator="{ props: _props }">
<VIcon v-bind="_props" :icon="props.themes[currentThemeIndex].icon" />
</template>
</VTooltip>
</IconBtn> </IconBtn>
</template> </template>
+3
View File
@@ -877,6 +877,9 @@ export interface ScheduleInfo {
// 名称 // 名称
name: string name: string
// 提供者
provider: string
// 状态 // 状态
status: string status: string
+20 -1
View File
@@ -8,6 +8,7 @@ import PageRender from '@/components/render/PageRender.vue'
import { isNullOrEmptyObject } from '@core/utils' import { isNullOrEmptyObject } from '@core/utils'
import noImage from '@images/logos/plugin.png' import noImage from '@images/logos/plugin.png'
import { getDominantColor } from '@/@core/utils/image' import { getDominantColor } from '@/@core/utils/image'
import store from '@/store'
// 输入参数 // 输入参数
const props = defineProps({ const props = defineProps({
@@ -225,6 +226,13 @@ function visitAuthorPage() {
window.open(props.plugin?.author_url, '_blank') window.open(props.plugin?.author_url, '_blank')
} }
// 查看日志URL
function openLoggerWindow() {
const token = store.state.auth.token
const url = `${import.meta.env.VITE_API_BASE_URL}system/logging?token=${token}&length=-1&logfile=plugins/${props.plugin?.id?.toLowerCase()}.log`
window.open(url, '_blank')
}
// 弹出菜单 // 弹出菜单
const dropdownItems = ref([ const dropdownItems = ref([
{ {
@@ -265,9 +273,20 @@ const dropdownItems = ref([
click: uninstallPlugin, click: uninstallPlugin,
}, },
}, },
{
title: '查看日志',
value: 5,
show: true,
props: {
prependIcon: 'mdi-file-document-outline',
click: () => {
openLoggerWindow()
},
},
},
{ {
title: '作者主页', title: '作者主页',
value: 4, value: 5,
show: true, show: true,
props: { props: {
prependIcon: 'mdi-home-circle-outline', prependIcon: 'mdi-home-circle-outline',
+27 -5
View File
@@ -1,10 +1,11 @@
<script lang="ts" setup> <script lang='ts' setup>
import { useToast } from 'vue-toast-notification' import { useToast } from 'vue-toast-notification'
import SubscribeEditForm from '../form/SubscribeEditForm.vue' import SubscribeEditForm from '../form/SubscribeEditForm.vue'
import { calculateTimeDifference } from '@/@core/utils' import { calculateTimeDifference } from '@/@core/utils'
import { formatSeason } from '@/@core/utils/formatters' import { formatSeason } from '@/@core/utils/formatters'
import api from '@/api' import api from '@/api'
import type { Subscribe } from '@/api/types' import type { Subscribe } from '@/api/types'
import router from '@/router'
// 输入参数 // 输入参数
const props = defineProps({ const props = defineProps({
@@ -55,7 +56,7 @@ function getPercentage() {
return Math.round( return Math.round(
(((props.media?.total_episode ?? 0) - (props.media?.lack_episode ?? 0)) (((props.media?.total_episode ?? 0) - (props.media?.lack_episode ?? 0))
/ (props.media?.total_episode ?? 1)) / (props.media?.total_episode ?? 1))
* 100, * 100,
) )
} }
@@ -126,8 +127,28 @@ const dropdownItems = ref([
}, },
}, },
{ {
title: '取消订阅', title: '查看详情',
value: 3, value: 3,
props: {
prependIcon: 'mdi-open-in-new',
click: () => {
router.push({
path: '/media',
query: {
mediaid: `${
props.media?.tmdbid
? `tmdb:${props.media?.tmdbid}`
: `douban:${props.media?.doubanid}`
}`,
type: props.media?.type,
},
})
},
},
},
{
title: '取消订阅',
value: 4,
props: { props: {
prependIcon: 'mdi-trash-can-outline', prependIcon: 'mdi-trash-can-outline',
color: 'error', color: 'error',
@@ -162,7 +183,7 @@ const dropdownItems = ref([
</template> </template>
<VCardTitle :class="getTextClass()"> <VCardTitle :class="getTextClass()">
{{ props.media?.name }} {{ props.media?.name }}
{{ formatSeason(props.media?.season ? props.media?.season.toString() : "") }} {{ formatSeason(props.media?.season ? props.media?.season.toString() : '') }}
</VCardTitle> </VCardTitle>
<template #append> <template #append>
<div class="me-n3"> <div class="me-n3">
@@ -252,7 +273,8 @@ const dropdownItems = ref([
<VIcon <VIcon
icon="mdi-download" icon="mdi-download"
class="me-1" class="me-1"
/> {{ lastUpdateText }} />
{{ lastUpdateText }}
</VCardText> </VCardText>
<VProgressLinear <VProgressLinear
v-if="getPercentage() > 0" v-if="getPercentage() > 0"
+70 -30
View File
@@ -416,21 +416,41 @@ onMounted(() => {
</VMenu> </VMenu>
</IconBtn> </IconBtn>
<span v-show="hover.isHovering" class="flex"> <span v-show="hover.isHovering" class="flex">
<IconBtn class="d-none d-sm-block" @click.stop="recognize(item.path)"> <VTooltip text="识别">
<VIcon icon="mdi-text-recognition" /> <template #activator="{ props }">
</IconBtn> <IconBtn v-bind="props" class="d-none d-sm-block" @click.stop="recognize(item.path)">
<IconBtn class="d-none d-sm-block" @click.stop="scrape(item.path)"> <VIcon icon="mdi-text-recognition" />
<VIcon icon="mdi-auto-fix" /> </IconBtn>
</IconBtn> </template>
<IconBtn class="d-none d-sm-block" @click.stop="showRenmae(item)"> </VTooltip>
<VIcon icon="mdi-rename" /> <VTooltip text="刮削">
</IconBtn> <template #activator="{ props }">
<IconBtn class="d-none d-sm-block" @click.stop="showTransfer(item)"> <IconBtn v-bind="props" class="d-none d-sm-block" @click.stop="scrape(item.path)">
<VIcon icon="mdi-folder-arrow-right" /> <VIcon icon="mdi-auto-fix" />
</IconBtn> </IconBtn>
<IconBtn class="d-none d-sm-block" @click.stop="deleteItem(item)"> </template>
<VIcon icon="mdi-delete-outline" /> </VTooltip>
</IconBtn> <VTooltip text="重命名">
<template #activator="{ props }">
<IconBtn v-bind="props" class="d-none d-sm-block" @click.stop="showRenmae(item)">
<VIcon icon="mdi-rename" />
</IconBtn>
</template>
</VTooltip>
<VTooltip text="整理">
<template #activator="{ props }">
<IconBtn v-bind="props" class="d-none d-sm-block" @click.stop="showTransfer(item)">
<VIcon icon="mdi-folder-arrow-right" />
</IconBtn>
</template>
</VTooltip>
<VTooltip text="删除">
<template #activator="{ props }">
<IconBtn v-bind="props" class="d-none d-sm-block" @click.stop="deleteItem(item)">
<VIcon icon="mdi-delete-outline" color="error" />
</IconBtn>
</template>
</VTooltip>
</span> </span>
</template> </template>
</VListItem> </VListItem>
@@ -483,21 +503,41 @@ onMounted(() => {
</VMenu> </VMenu>
</IconBtn> </IconBtn>
<span v-show="hover.isHovering" class="flex"> <span v-show="hover.isHovering" class="flex">
<IconBtn class="d-none d-sm-block" @click.stop="recognize(item.path)"> <VTooltip text="识别">
<VIcon icon="mdi-text-recognition" /> <template #activator="{ props }">
</IconBtn> <IconBtn v-bind="props" class="d-none d-sm-block" @click.stop="recognize(item.path)">
<IconBtn class="d-none d-sm-block" @click.stop="scrape(item.path)"> <VIcon icon="mdi-text-recognition" />
<VIcon icon="mdi-auto-fix" /> </IconBtn>
</IconBtn> </template>
<IconBtn class="d-none d-sm-block" @click.stop="showRenmae(item)"> </VTooltip>
<VIcon icon="mdi-rename" /> <VTooltip text="刮削">
</IconBtn> <template #activator="{ props }">
<IconBtn class="d-none d-sm-block" @click.stop="showTransfer(item)"> <IconBtn v-bind="props" class="d-none d-sm-block" @click.stop="scrape(item.path)">
<VIcon icon="mdi-folder-arrow-right" /> <VIcon icon="mdi-auto-fix" />
</IconBtn> </IconBtn>
<IconBtn class="d-none d-sm-block" @click.stop="deleteItem(item)"> </template>
<VIcon icon="mdi-delete-outline" /> </VTooltip>
</IconBtn> <VTooltip text="重命名">
<template #activator="{ props }">
<IconBtn v-bind="props" class="d-none d-sm-block" @click.stop="showRenmae(item)">
<VIcon icon="mdi-rename" />
</IconBtn>
</template>
</VTooltip>
<VTooltip text="整理">
<template #activator="{ props }">
<IconBtn v-bind="props" class="d-none d-sm-block" @click.stop="showTransfer(item)">
<VIcon icon="mdi-folder-arrow-right" />
</IconBtn>
</template>
</VTooltip>
<VTooltip text="删除">
<template #activator="{ props }">
<IconBtn v-bind="props" class="d-none d-sm-block" @click.stop="deleteItem(item)">
<VIcon icon="mdi-delete-outline" color="error" />
</IconBtn>
</template>
</VTooltip>
</span> </span>
</template> </template>
</VListItem> </VListItem>
+20 -8
View File
@@ -144,19 +144,31 @@ const sortIcon = computed(() => {
</template> </template>
</VToolbarItems> </VToolbarItems>
<div class="flex-grow-1" /> <div class="flex-grow-1" />
<IconBtn @click="changeSort"> <VTooltip text="调整排序">
<VIcon :icon="sortIcon" /> <template #activator="{ props }">
</IconBtn> <IconBtn v-bind="props" @click="changeSort">
<IconBtn v-if="pathSegments.length > 0" @click="goUp"> <VIcon :icon="sortIcon" />
<VIcon icon="mdi-arrow-up-bold-outline" /> </IconBtn>
</IconBtn> </template>
</VTooltip>
<VTooltip text="返回上一级" v-if="pathSegments.length > 0">
<template #activator="{ props }">
<IconBtn v-bind="props" @click="goUp">
<VIcon icon="mdi-arrow-up-bold-outline" />
</IconBtn>
</template>
</VTooltip>
<VDialog <VDialog
v-model="newFolderPopper" v-model="newFolderPopper"
max-width="50rem" max-width="50rem"
> >
<template #activator="{ props }"> <template #activator="{ props }">
<IconBtn title="新建文件夹" v-bind="props"> <IconBtn v-bind="props">
<VIcon icon="mdi-folder-plus-outline" /> <VTooltip text="新建文件夹">
<template #activator="{ props: _props }">
<VIcon v-bind="_props" icon="mdi-folder-plus-outline" />
</template>
</VTooltip>
</IconBtn> </IconBtn>
</template> </template>
<VCard title="新建文件夹"> <VCard title="新建文件夹">
+5 -1
View File
@@ -44,7 +44,11 @@ function allLoggingUrl() {
class="me-2" class="me-2"
v-bind="props" v-bind="props"
> >
<VIcon icon="mdi-checkbox-multiple-blank-outline" /> <VTooltip text="捷径">
<template #activator="{ props: _props }">
<VIcon v-bind="_props" icon="mdi-checkbox-multiple-blank-outline" />
</template>
</VTooltip>
</IconBtn> </IconBtn>
</template> </template>
<!-- Menu Content --> <!-- Menu Content -->
+53 -23
View File
@@ -5,25 +5,21 @@ import NoDataFound from '@/components/NoDataFound.vue'
import PluginAppCard from '@/components/cards/PluginAppCard.vue' import PluginAppCard from '@/components/cards/PluginAppCard.vue'
import PluginCard from '@/components/cards/PluginCard.vue' import PluginCard from '@/components/cards/PluginCard.vue'
// 数据列表 // 已安装插件列表
const dataList = ref<Plugin[]>([]) const dataList = ref<Plugin[]>([])
// 未安装插件列表
const uninstalledList = ref<Plugin[]>([])
// 是否刷新过 // 是否刷新过
const isRefreshed = ref(false) const isRefreshed = ref(false)
// APP市场是否加载完成
const isAppMarketLoaded = ref(false)
// APP市场窗口 // APP市场窗口
const PluginAppDialog = ref(false) const PluginAppDialog = ref(false)
// 获取已安装的插件列表
const getInstalledPluginList = computed(() => {
return dataList.value.filter(item => item.installed)
})
// 获取未安装或者有更新的插件列表
const getUninstalledPluginList = computed(() => {
return dataList.value.filter(item => !item.installed || item.has_update)
})
// 关闭插件市场窗口 // 关闭插件市场窗口
function pluginDialogClose() { function pluginDialogClose() {
PluginAppDialog.value = false PluginAppDialog.value = false
@@ -31,14 +27,19 @@ function pluginDialogClose() {
// 新安装了插件 // 新安装了插件
function pluginInstalled() { function pluginInstalled() {
fetchData() fetchInstalledPlugins()
pluginDialogClose() pluginDialogClose()
fetchUninstalledPlugins()
} }
// 获取插件列表数据 // 获取插件列表数据
async function fetchData() { async function fetchInstalledPlugins() {
try { try {
dataList.value = await api.get('plugin/') dataList.value = await api.get('plugin/', {
params: {
state: 'installed',
},
})
isRefreshed.value = true isRefreshed.value = true
} }
catch (error) { catch (error) {
@@ -46,8 +47,26 @@ async function fetchData() {
} }
} }
// 获取未安装插件列表数据
async function fetchUninstalledPlugins() {
try {
uninstalledList.value = await api.get('plugin/', {
params: {
state: 'market',
},
})
isAppMarketLoaded.value = true
}
catch (error) {
console.error(error)
}
}
// 加载时获取数据 // 加载时获取数据
onBeforeMount(fetchData) onBeforeMount(() => {
fetchInstalledPlugins()
fetchUninstalledPlugins()
})
</script> </script>
<template> <template>
@@ -63,19 +82,19 @@ onBeforeMount(fetchData)
/> />
</div> </div>
<div <div
v-if="getInstalledPluginList.length > 0" v-if="dataList.length > 0"
class="grid gap-4 grid-plugin-card" class="grid gap-4 grid-plugin-card"
> >
<PluginCard <PluginCard
v-for="data in getInstalledPluginList" v-for="data in dataList"
:key="data.id" :key="data.id"
:plugin="data" :plugin="data"
@remove="fetchData" @remove="fetchInstalledPlugins"
@save="fetchData" @save="fetchInstalledPlugins"
/> />
</div> </div>
<NoDataFound <NoDataFound
v-if="getInstalledPluginList.length === 0 && isRefreshed" v-if="dataList.length === 0 && isRefreshed"
error-code="404" error-code="404"
error-title="没有安装插件" error-title="没有安装插件"
error-description="点击右下角按钮前往插件市场安装插件" error-description="点击右下角按钮前往插件市场安装插件"
@@ -121,16 +140,27 @@ onBeforeMount(fetchData)
</VToolbar> </VToolbar>
</div> </div>
<VCardText> <VCardText>
<div class="grid gap-4 grid-plugin-card"> <div
v-if="!isAppMarketLoaded"
class="mt-12 w-full text-center text-gray-500 text-sm flex flex-col items-center"
>
<VProgressCircular
v-if="!isAppMarketLoaded"
size="48"
indeterminate
color="primary"
/>
</div>
<div v-if="isAppMarketLoaded" class="grid gap-4 grid-plugin-card">
<PluginAppCard <PluginAppCard
v-for="data in getUninstalledPluginList" v-for="data in uninstalledList"
:key="data.id" :key="data.id"
:plugin="data" :plugin="data"
@install="pluginInstalled" @install="pluginInstalled"
/> />
</div> </div>
<NoDataFound <NoDataFound
v-if="getUninstalledPluginList.length === 0 && isRefreshed" v-if="uninstalledList.length === 0 && isAppMarketLoaded"
error-code="404" error-code="404"
error-title="没有未安装插件" error-title="没有未安装插件"
error-description="所有可用插件均已安装" error-description="所有可用插件均已安装"
+11 -3
View File
@@ -357,7 +357,7 @@ const dropdownItems = ref([
<VIcon :icon="getIcon(item.value.type || '')" /> <VIcon :icon="getIcon(item.value.type || '')" />
</VAvatar> </VAvatar>
<div class="d-flex flex-column ms-1"> <div class="d-flex flex-column ms-1">
<span class="d-block whitespace-nowrap text-high-emphasis"> <span class="d-block text-high-emphasis">
{{ item.value.title }} {{ item.value.seasons }}{{ item.value.episodes }} {{ item.value.title }} {{ item.value.seasons }}{{ item.value.episodes }}
</span> </span>
<small>{{ item.value.category }}</small> <small>{{ item.value.category }}</small>
@@ -415,8 +415,16 @@ const dropdownItems = ref([
</VCard> </VCard>
<!-- 底部操作按钮 --> <!-- 底部操作按钮 -->
<span v-if="selected.length > 0" class="fixed right-5 bottom-5"> <span v-if="selected.length > 0" class="fixed right-5 bottom-5">
<VBtn icon="mdi-redo-variant" class="me-2" color="primary" size="x-large" @click="retransferBatch" /> <VTooltip text="批量重新整理">
<VBtn icon="mdi-trash-can-outline" color="error" size="x-large" @click="removeHistoryBatch" /> <template #activator="{ props }">
<VBtn v-bind="props" icon="mdi-redo-variant" class="me-2" color="primary" size="x-large" @click="retransferBatch" />
</template>
</VTooltip>
<VTooltip text="批量删除">
<template #activator="{ props }">
<VBtn v-bind="props" icon="mdi-trash-can-outline" color="error" size="x-large" @click="removeHistoryBatch" />
</template>
</VTooltip>
</span> </span>
<!-- 底部弹窗 --> <!-- 底部弹窗 -->
<VBottomSheet v-model="deleteConfirmDialog" inset> <VBottomSheet v-model="deleteConfirmDialog" inset>
+7 -1
View File
@@ -78,11 +78,14 @@ onUnmounted(() => {
<template> <template>
<VCard title="定时作业"> <VCard title="定时作业">
<VCardSubtitle> 手动执行不会影响作业正常的时间表 </VCardSubtitle> <VCardSubtitle> 包含系统内置服务以及插件提供的服务手动执行不会影响作业正常的时间表 </VCardSubtitle>
<VTable class="text-no-wrap"> <VTable class="text-no-wrap">
<thead> <thead>
<tr> <tr>
<th scope="col">
提供者
</th>
<th scope="col"> <th scope="col">
任务名称 任务名称
</th> </th>
@@ -100,6 +103,9 @@ onUnmounted(() => {
v-for="scheduler in schedulerList" v-for="scheduler in schedulerList"
:key="scheduler.id" :key="scheduler.id"
> >
<td>
{{ scheduler.provider }}
</td>
<td> <td>
{{ scheduler.name }} {{ scheduler.name }}
</td> </td>
@@ -1,4 +1,4 @@
<script lang="ts" setup> <script lang='ts' setup>
import { useToast } from 'vue-toast-notification' import { useToast } from 'vue-toast-notification'
import api from '@/api' import api from '@/api'
import FilterRuleCard from '@/components/cards/FilterRuleCard.vue' import FilterRuleCard from '@/components/cards/FilterRuleCard.vue'
@@ -94,7 +94,7 @@ async function saveSelectedRssSites() {
const result2: { [key: string]: any } = await api.post( const result2: { [key: string]: any } = await api.post(
'system/setting/SUBSCRIBE_SEARCH', 'system/setting/SUBSCRIBE_SEARCH',
enableIntervalSearch.value, enableIntervalSearch.value ? 'True' : 'False',
) )
const result3: { [key: string]: any } = await api.post( const result3: { [key: string]: any } = await api.post(
@@ -469,7 +469,7 @@ onMounted(() => {
</VMenu> </VMenu>
</IconBtn> </IconBtn>
</template> </template>
<VCardSubtitle> 设置在正常订阅时默认使用的优先级未在优先级中的资源将不会自动下载 </VCardSubtitle> <VCardSubtitle> 设置在正常订阅时默认使用的优先级未在优先级中的资源将不会自动下载</VCardSubtitle>
<VCardItem> <VCardItem>
<div class="grid gap-3 grid-filterrule-card"> <div class="grid gap-3 grid-filterrule-card">
<FilterRuleCard <FilterRuleCard
@@ -535,7 +535,7 @@ onMounted(() => {
</VMenu> </VMenu>
</IconBtn> </IconBtn>
</template> </template>
<VCardSubtitle> 设置在订阅洗版时使用的优先级匹配优先级1时洗版完成 </VCardSubtitle> <VCardSubtitle> 设置在订阅洗版时使用的优先级匹配优先级1时洗版完成</VCardSubtitle>
<VCardItem> <VCardItem>
<div class="grid gap-3 grid-filterrule-card"> <div class="grid gap-3 grid-filterrule-card">
<FilterRuleCard <FilterRuleCard
@@ -571,7 +571,7 @@ onMounted(() => {
</VCol> </VCol>
<VCol cols="12"> <VCol cols="12">
<VCard title="默认过滤规则"> <VCard title="默认过滤规则">
<VCardSubtitle> 设置在订阅时默认使用的过滤规则 </VCardSubtitle> <VCardSubtitle> 设置在订阅时默认使用的过滤规则</VCardSubtitle>
<VCardText> <VCardText>
<VForm> <VForm>
<VRow> <VRow>
@@ -638,7 +638,7 @@ onMounted(() => {
</VDialog> </VDialog>
</template> </template>
<style lang="scss"> <style lang='scss'>
.grid-filterrule-card { .grid-filterrule-card {
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr)); grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
padding-block-end: 1rem; padding-block-end: 1rem;
+8 -4
View File
@@ -3,6 +3,7 @@
import { useToast } from 'vue-toast-notification' import { useToast } from 'vue-toast-notification'
import { VRow } from 'vuetify/lib/components/index.mjs' import { VRow } from 'vuetify/lib/components/index.mjs'
import api from '@/api' import api from '@/api'
import { requiredValidator } from '@/@validators'
// 选中的媒体服务器 // 选中的媒体服务器
const selectedMediaServers = ref([]) const selectedMediaServers = ref([])
@@ -532,8 +533,8 @@ onMounted(() => {
<VCol cols="12" md="4"> <VCol cols="12" md="4">
<VTextField <VTextField
v-model="mediaServerSettings.EMBY_PLAY_HOST" v-model="mediaServerSettings.EMBY_PLAY_HOST"
label="播放地址" label="外网播放地址"
placeholder="IP:PORT" placeholder="http(s)://domain:port"
/> />
</VCol> </VCol>
<VCol cols="12" md="4"> <VCol cols="12" md="4">
@@ -559,7 +560,7 @@ onMounted(() => {
<VTextField <VTextField
v-model="mediaServerSettings.JELLYFIN_PLAY_HOST" v-model="mediaServerSettings.JELLYFIN_PLAY_HOST"
label="外网播放地址" label="外网播放地址"
placeholder="IP:PORT" placeholder="http(s)://domain:port"
/> />
</VCol> </VCol>
<VCol cols="12" md="4"> <VCol cols="12" md="4">
@@ -585,7 +586,7 @@ onMounted(() => {
<VTextField <VTextField
v-model="mediaServerSettings.PLEX_PLAY_HOST" v-model="mediaServerSettings.PLEX_PLAY_HOST"
label="外网播放地址" label="外网播放地址"
placeholder="IP:PORT" placeholder="http(s)://domain:port"
/> />
</VCol> </VCol>
<VCol cols="12" md="4"> <VCol cols="12" md="4">
@@ -628,6 +629,7 @@ onMounted(() => {
<VTextField <VTextField
v-model="mediaSettings.DOWNLOAD_PATH" v-model="mediaSettings.DOWNLOAD_PATH"
label="下载目录" label="下载目录"
:rules="[requiredValidator]"
/> />
</VCol> </VCol>
<VCol cols="12" md="6"> <VCol cols="12" md="6">
@@ -682,6 +684,8 @@ onMounted(() => {
<VTextField <VTextField
v-model="mediaSettings.LIBRARY_PATH" v-model="mediaSettings.LIBRARY_PATH"
label="媒体库目录" label="媒体库目录"
placeholder="多个目录使用,分隔"
:rules="[requiredValidator]"
/> />
</VCol> </VCol>
<VCol cols="12" md="6"> <VCol cols="12" md="6">