feat: 重构工作流组件,动态加载节点类型,移除旧的侧边栏和背景组件

This commit is contained in:
jxxghp
2025-02-27 13:55:06 +08:00
parent 5cd021ea85
commit b467bb6c56
16 changed files with 296 additions and 6 deletions

View File

@@ -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>

View 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>

View 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>

View File

@@ -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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View File

@@ -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>

View 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>