mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-05-30 21:00:43 +08:00
feat: 重构工作流组件,动态加载节点类型,移除旧的侧边栏和背景组件
This commit is contained in:
@@ -6,8 +6,8 @@ import useDragAndDrop from '@core/utils/workflow'
|
||||
import { Workflow } from '@/api/types'
|
||||
import { useToast } from 'vue-toast-notification'
|
||||
import api from '@/api'
|
||||
import Sidebar from '../workflow/Sidebar.vue'
|
||||
import DropzoneBackground from '../workflow/DropzoneBackground.vue'
|
||||
import WorkflowSidebar from '@/layouts/components/WorkflowSidebar.vue'
|
||||
import DropzoneBackground from '@/layouts/components/DropzoneBackground.vue'
|
||||
|
||||
const { onConnect, addEdges, nodes, edges } = useVueFlow()
|
||||
|
||||
@@ -15,6 +15,32 @@ const { onDragOver, onDrop, onDragLeave, isDragOver } = useDragAndDrop()
|
||||
|
||||
onConnect(addEdges)
|
||||
|
||||
// 自定义节点类型
|
||||
const nodeTypes: Record<string, any> = ref({})
|
||||
|
||||
// 自动扫描目录下所有的 .vue 文件
|
||||
const components = import.meta.glob('../workflow/*Action.vue')
|
||||
|
||||
// 动态加载某个组件
|
||||
const loadComponent = async (componentName: string) => {
|
||||
const component = components[`../workflow/${componentName}.vue`]
|
||||
if (component) {
|
||||
return ((await component()) as any).default
|
||||
}
|
||||
throw new Error(`组件 ${componentName} 未找到`)
|
||||
}
|
||||
|
||||
// 将所有components中的组件加载到nodeTypes中
|
||||
for (const path in components) {
|
||||
const componentName = path.match(/\.\/workflow\/(.*).vue$/)?.[1]
|
||||
if (!componentName) {
|
||||
continue
|
||||
}
|
||||
loadComponent(componentName).then(component => {
|
||||
nodeTypes.value[componentName] = markRaw(component)
|
||||
})
|
||||
}
|
||||
|
||||
// 定义输入参数
|
||||
const props = defineProps({
|
||||
workflow: Object as PropType<Workflow>,
|
||||
@@ -80,6 +106,7 @@ onMounted(() => {
|
||||
<VueFlow
|
||||
:nodes="nodes"
|
||||
:edges="edges"
|
||||
:nodeTypes="nodeTypes"
|
||||
:default-edge-options="{ type: 'animation', animated: true }"
|
||||
@dragover="onDragOver"
|
||||
@dragleave="onDragLeave"
|
||||
@@ -93,7 +120,7 @@ onMounted(() => {
|
||||
>
|
||||
</DropzoneBackground>
|
||||
</VueFlow>
|
||||
<Sidebar />
|
||||
<WorkflowSidebar />
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
|
||||
22
src/components/workflow/AddDownloadAction.vue
Normal file
22
src/components/workflow/AddDownloadAction.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-download">
|
||||
<VCardTitle>添加下载</VCardTitle>
|
||||
<VCardSubtitle>根据资源列表添加下载任务</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
22
src/components/workflow/AddSubscribeAction.vue
Normal file
22
src/components/workflow/AddSubscribeAction.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-star-check">
|
||||
<VCardTitle>添加订阅</VCardTitle>
|
||||
<VCardSubtitle>根据媒体列表添加订阅</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -1,12 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { Background } from '@vue-flow/background'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="dropzone-background">
|
||||
<Background :size="2" :gap="20" pattern-color="#BDBDBD" />
|
||||
<div class="overlay">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
22
src/components/workflow/FetchDownloadsAction.vue
Normal file
22
src/components/workflow/FetchDownloadsAction.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-download-circle-outline">
|
||||
<VCardTitle>获取下载任务</VCardTitle>
|
||||
<VCardSubtitle>获取下载任务,更新任务状态</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
22
src/components/workflow/FetchMediasAction.vue
Normal file
22
src/components/workflow/FetchMediasAction.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-multimedia">
|
||||
<VCardTitle>获取媒体数据</VCardTitle>
|
||||
<VCardSubtitle>获取榜单等媒体数据列表</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
22
src/components/workflow/FetchRssAction.vue
Normal file
22
src/components/workflow/FetchRssAction.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-rss-box">
|
||||
<VCardTitle>获取RSS资源</VCardTitle>
|
||||
<VCardSubtitle>请求RSS地址获取数据,并解析为资源列表</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
22
src/components/workflow/FetchTorrentsAction.vue
Normal file
22
src/components/workflow/FetchTorrentsAction.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-search-web">
|
||||
<VCardTitle>搜索站点资源</VCardTitle>
|
||||
<VCardSubtitle>根据关键字搜索站点种子资源</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
22
src/components/workflow/FilterMediasAction.vue
Normal file
22
src/components/workflow/FilterMediasAction.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-filter-check">
|
||||
<VCardTitle>过滤媒体数据</VCardTitle>
|
||||
<VCardSubtitle>对媒体数据列表进行过滤</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
22
src/components/workflow/FilterTorrentsAction.vue
Normal file
22
src/components/workflow/FilterTorrentsAction.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-filter-multiple">
|
||||
<VCardTitle>过滤资源</VCardTitle>
|
||||
<VCardSubtitle>对资源列表数据进行过滤</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
22
src/components/workflow/ScrapeFileAction.vue
Normal file
22
src/components/workflow/ScrapeFileAction.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-file-find">
|
||||
<VCardTitle>刮削文件</VCardTitle>
|
||||
<VCardSubtitle>刮削媒体信息和图片</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
22
src/components/workflow/SendEventAction.vue
Normal file
22
src/components/workflow/SendEventAction.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-send-check">
|
||||
<VCardTitle>发送事件</VCardTitle>
|
||||
<VCardSubtitle>发送特定事件</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
22
src/components/workflow/SendMessageAction.vue
Normal file
22
src/components/workflow/SendMessageAction.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-message-arrow-right">
|
||||
<VCardTitle>发送消息</VCardTitle>
|
||||
<VCardSubtitle>发送特定消息</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
@@ -1,39 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import api from '@/api'
|
||||
import useDragAndDrop from '@core/utils/workflow'
|
||||
|
||||
const { onDragStart } = useDragAndDrop()
|
||||
|
||||
// 组件列表
|
||||
const actions = ref([])
|
||||
|
||||
// 加载组件列表
|
||||
async function load_actions() {
|
||||
try {
|
||||
actions.value = await api.get('workflow/actions')
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
load_actions()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<aside>
|
||||
<div class="mb-3"><VLabel>可选动作组件:</VLabel></div>
|
||||
|
||||
<div class="nodes">
|
||||
<div
|
||||
class="vue-flow__node-default"
|
||||
v-for="action in actions"
|
||||
:draggable="true"
|
||||
@dragstart="onDragStart($event, action)"
|
||||
>
|
||||
{{ action['name'] }}
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</template>
|
||||
22
src/components/workflow/TransferFileAction.vue
Normal file
22
src/components/workflow/TransferFileAction.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem prepend-icon="mdi-file-move">
|
||||
<VCardTitle>整理文件</VCardTitle>
|
||||
<VCardSubtitle>转移和重命名文件</VCardSubtitle>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText></VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
Reference in New Issue
Block a user