mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-05-27 03:09:45 +08:00
feat: 添加工作流组件的边缘处理和循环执行功能,优化订阅和RSS获取操作
This commit is contained in:
@@ -208,4 +208,22 @@ onMounted(() => {
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.vue-flow__handle {
|
||||
height: 24px;
|
||||
width: 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.vue-flow__edges {
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
.vue-flow__handle-left {
|
||||
background-color: rgb(var(--v-theme-info));
|
||||
}
|
||||
|
||||
.vue-flow__handle-right {
|
||||
background-color: rgb(var(--v-theme-error));
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
import api from '@/api'
|
||||
import { DownloaderConf } from '@/api/types'
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -9,14 +13,53 @@ const props = defineProps({
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 下载器选项
|
||||
const downloaderOptions = ref<{ title: string; value: string }[]>([])
|
||||
|
||||
// 加载所有下载器
|
||||
async function loadDownloaderSetting() {
|
||||
try {
|
||||
const downloaders: DownloaderConf[] = await api.get('download/clients')
|
||||
downloaderOptions.value = [
|
||||
{ title: '默认', value: '' },
|
||||
...downloaders.map((item: { name: any }) => ({
|
||||
title: item.name,
|
||||
value: item.name,
|
||||
})),
|
||||
]
|
||||
} catch (error) {
|
||||
console.error('加载下载器设置失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadDownloaderSetting()
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-download">
|
||||
<VCard max-width="20rem">
|
||||
<Handle id="edge_in" type="target" :position="Position.Left" />
|
||||
<VCardItem>
|
||||
<template v-slot:prepend>
|
||||
<VAvatar>
|
||||
<VIcon icon="mdi-download-box-outline" size="x-large"></VIcon>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>添加下载</VCardTitle>
|
||||
<VCardSubtitle>根据资源列表添加下载任务</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VSelect v-model="data.downloader" :items="downloaderOptions" label="下载器" outlined dense />
|
||||
</VCol>
|
||||
<VCol cols="12">
|
||||
<VTextField v-model="data.save_path" label="保存路径" outlined dense clearable placeholder="留空自动" />
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -12,11 +14,16 @@ const props = defineProps({
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-star-check">
|
||||
<Handle id="edge_in" type="target" :position="Position.Left" />
|
||||
<VCardItem>
|
||||
<template v-slot:prepend>
|
||||
<VAvatar>
|
||||
<VIcon icon="mdi-star-check" size="x-large"></VIcon>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>添加订阅</VCardTitle>
|
||||
<VCardSubtitle>根据媒体列表添加订阅</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -11,12 +13,35 @@ const props = defineProps({
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-download-circle-outline">
|
||||
<VCard max-width="20rem">
|
||||
<Handle id="edge_in" type="target" :position="Position.Left" />
|
||||
<VCardItem>
|
||||
<template v-slot:prepend>
|
||||
<VAvatar>
|
||||
<VIcon icon="mdi-progress-download" size="x-large"></VIcon>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>获取下载任务</VCardTitle>
|
||||
<VCardSubtitle>获取下载任务,更新任务状态</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VSwitch v-model="data.loop" label="循环执行" />
|
||||
</VCol>
|
||||
<VCol cols="12">
|
||||
<VTextField
|
||||
v-model="data.loop_interval"
|
||||
:disabled="!data.loop"
|
||||
type="number"
|
||||
label="循环间隔 (秒)"
|
||||
outlined
|
||||
dense
|
||||
clearable
|
||||
/>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
import api from '@/api'
|
||||
import { RecommendSource } from '@/api/types'
|
||||
|
||||
defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -9,14 +13,110 @@ const props = defineProps({
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 内置榜单
|
||||
const innerList = [
|
||||
{
|
||||
'api_path': 'recommend/tmdb_trending',
|
||||
'name': '流行趋势',
|
||||
},
|
||||
{
|
||||
'api_path': 'recommend/douban_showing',
|
||||
'name': '正在热映',
|
||||
},
|
||||
{
|
||||
'api_path': 'bangumi/calendar',
|
||||
'name': 'Bangumi每日放送',
|
||||
},
|
||||
{
|
||||
'api_path': 'recommend/tmdb_movies',
|
||||
'name': 'TMDB热门电影',
|
||||
},
|
||||
{
|
||||
'api_path': 'recommend/tmdb_tvs?with_original_language=zh|en|ja|ko',
|
||||
'name': 'TMDB热门电视剧',
|
||||
},
|
||||
{
|
||||
'api_path': 'recommend/douban_movie_hot',
|
||||
'name': '豆瓣热门电影',
|
||||
},
|
||||
{
|
||||
'api_path': 'recommend/douban_tv_hot',
|
||||
'name': '豆瓣热门电视剧',
|
||||
},
|
||||
{
|
||||
'api_path': 'recommend/douban_tv_animation',
|
||||
'name': '豆瓣热门动漫',
|
||||
},
|
||||
{
|
||||
'api_path': 'recommend/douban_movies',
|
||||
'name': '豆瓣最新电影',
|
||||
},
|
||||
{
|
||||
'api_path': 'recommend/douban_tvs',
|
||||
'name': '豆瓣最新电视剧',
|
||||
},
|
||||
{
|
||||
'api_path': 'recommend/douban_movie_top250',
|
||||
'name': '豆瓣电影TOP250',
|
||||
},
|
||||
{
|
||||
'api_path': 'recommend/douban_tv_weekly_chinese',
|
||||
'name': '豆瓣国产剧集榜',
|
||||
},
|
||||
{
|
||||
'api_path': 'recommend/douban_tv_weekly_global',
|
||||
'name': '豆瓣全球剧集榜',
|
||||
},
|
||||
]
|
||||
|
||||
// 额外的数据源
|
||||
const extraRecommendSources = ref<RecommendSource[]>([])
|
||||
|
||||
// 加载额外的发现数据源
|
||||
async function loadExtraRecommendSources() {
|
||||
try {
|
||||
extraRecommendSources.value = await api.get('recommend/source')
|
||||
if (extraRecommendSources.value.length > 0) {
|
||||
innerList.push(
|
||||
...extraRecommendSources.value.map(source => ({
|
||||
api_path: source.api_path,
|
||||
name: source.name,
|
||||
})),
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 计算下拉框
|
||||
const sourceOptions = computed(() => innerList.map(item => item.name))
|
||||
|
||||
onMounted(() => {
|
||||
loadExtraRecommendSources()
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-multimedia">
|
||||
<VCard max-width="20rem">
|
||||
<Handle id="edge_in" type="target" :position="Position.Left" />
|
||||
<VCardItem>
|
||||
<template v-slot:prepend>
|
||||
<VAvatar>
|
||||
<VIcon icon="mdi-multimedia" size="x-large"></VIcon>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>获取媒体数据</VCardTitle>
|
||||
<VCardSubtitle>获取榜单等媒体数据列表</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VSelect v-model="data.sources" :items="sourceOptions" label="榜单" chips multiple outlined dense clearable />
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -11,12 +13,34 @@ const props = defineProps({
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-rss-box">
|
||||
<VCard max-width="20rem">
|
||||
<Handle id="edge_in" type="target" :position="Position.Left" />
|
||||
<VCardItem>
|
||||
<template v-slot:prepend>
|
||||
<VAvatar>
|
||||
<VIcon icon="mdi-rss" size="x-large"></VIcon>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>获取RSS资源</VCardTitle>
|
||||
<VCardSubtitle>请求RSS地址获取数据,并解析为资源列表</VCardSubtitle>
|
||||
<VCardSubtitle>订阅RSS地址获取资源</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VTextField v-model="data.url" label="RSS地址" outlined dense clearable />
|
||||
</VCol>
|
||||
<VCol cols="12">
|
||||
<VTextField v-model="data.ua" label="User-Agent" outlined dense clearable />
|
||||
</VCol>
|
||||
<VCol cols="12">
|
||||
<VTextField v-model="data.timeout" type="number" label="超时时间" outlined dense clearable />
|
||||
</VCol>
|
||||
<VCol cols="12">
|
||||
<VSwitch v-model="data.proxy" label="使用代理" />
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -11,12 +13,19 @@ const props = defineProps({
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-search-web">
|
||||
<VCard max-width="20rem">
|
||||
<Handle id="edge_in" type="target" :position="Position.Left" />
|
||||
<VCardItem>
|
||||
<template v-slot:prepend>
|
||||
<VAvatar>
|
||||
<VIcon icon="mdi-search-web" size="x-large"></VIcon>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>搜索站点资源</VCardTitle>
|
||||
<VCardSubtitle>根据关键字搜索站点种子资源</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -11,12 +13,19 @@ const props = defineProps({
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-filter-check">
|
||||
<VCard max-width="20rem">
|
||||
<Handle id="edge_in" type="target" :position="Position.Left" />
|
||||
<VCardItem>
|
||||
<template v-slot:prepend>
|
||||
<VAvatar>
|
||||
<VIcon icon="mdi-filter-check" size="x-large"></VIcon>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>过滤媒体数据</VCardTitle>
|
||||
<VCardSubtitle>对媒体数据列表进行过滤</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -11,12 +13,19 @@ const props = defineProps({
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-filter-multiple">
|
||||
<VCard max-width="20rem">
|
||||
<Handle id="edge_in" type="target" :position="Position.Left" />
|
||||
<VCardItem>
|
||||
<template v-slot:prepend>
|
||||
<VAvatar>
|
||||
<VIcon icon="mdi-filter-multiple" size="x-large"></VIcon>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>过滤资源</VCardTitle>
|
||||
<VCardSubtitle>对资源列表数据进行过滤</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -11,12 +13,19 @@ const props = defineProps({
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-file-find">
|
||||
<VCard max-width="20rem">
|
||||
<Handle id="edge_in" type="target" :position="Position.Left" />
|
||||
<VCardItem>
|
||||
<template v-slot:prepend>
|
||||
<VAvatar>
|
||||
<VIcon icon="mdi-file-find" size="x-large"></VIcon>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>刮削文件</VCardTitle>
|
||||
<VCardSubtitle>刮削媒体信息和图片</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -11,12 +13,19 @@ const props = defineProps({
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-send-check">
|
||||
<VCard max-width="20rem">
|
||||
<Handle id="edge_in" type="target" :position="Position.Left" />
|
||||
<VCardItem>
|
||||
<template v-slot:prepend>
|
||||
<VAvatar>
|
||||
<VIcon icon="mdi-send-check" size="x-large"></VIcon>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>发送事件</VCardTitle>
|
||||
<VCardSubtitle>发送特定事件</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -11,12 +13,19 @@ const props = defineProps({
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-message-arrow-right">
|
||||
<VCard max-width="20rem">
|
||||
<Handle id="edge_in" type="target" :position="Position.Left" />
|
||||
<VCardItem>
|
||||
<template v-slot:prepend>
|
||||
<VAvatar>
|
||||
<VIcon icon="mdi-message-arrow-right" size="x-large"></VIcon>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>发送消息</VCardTitle>
|
||||
<VCardSubtitle>发送特定消息</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
import { Handle, Position } from '@vue-flow/core'
|
||||
|
||||
defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -11,12 +13,19 @@ const props = defineProps({
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-file-move">
|
||||
<VCard max-width="20rem">
|
||||
<Handle id="edge_in" type="target" :position="Position.Left" />
|
||||
<VCardItem>
|
||||
<template v-slot:prepend>
|
||||
<VAvatar>
|
||||
<VIcon icon="mdi-file-move" size="x-large"></VIcon>
|
||||
</VAvatar>
|
||||
</template>
|
||||
<VCardTitle>整理文件</VCardTitle>
|
||||
<VCardSubtitle>转移和重命名文件</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user