mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 15:36:49 +08:00
工作流新增调用插件功能组件
This commit is contained in:
@@ -335,6 +335,10 @@ export const actionStepOptions = [
|
|||||||
title: i18n.global.t('actionStep.transferFile'),
|
title: i18n.global.t('actionStep.transferFile'),
|
||||||
value: '整理文件',
|
value: '整理文件',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: i18n.global.t('actionStep.invokePlugin'),
|
||||||
|
value: '调用插件',
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
// 操作步骤字典
|
// 操作步骤字典
|
||||||
|
|||||||
+2
-2
@@ -565,9 +565,9 @@ export interface NotExistMediaInfo {
|
|||||||
|
|
||||||
// 插件
|
// 插件
|
||||||
export interface Plugin {
|
export interface Plugin {
|
||||||
id?: string
|
id: string
|
||||||
// 插件名称
|
// 插件名称
|
||||||
plugin_name?: string
|
plugin_name: string
|
||||||
// 插件描述
|
// 插件描述
|
||||||
plugin_desc?: string
|
plugin_desc?: string
|
||||||
// 插件图标
|
// 插件图标
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ async function loadDownloaderSetting() {
|
|||||||
})),
|
})),
|
||||||
]
|
]
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载下载器设置失败:', error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ onMounted(() => {
|
|||||||
<VTextField
|
<VTextField
|
||||||
v-model="data.labels"
|
v-model="data.labels"
|
||||||
:label="t('workflow.addDownload.category')"
|
:label="t('workflow.addDownload.category')"
|
||||||
placeholder="多个使用,分隔"
|
:placeholder="t('workflow.addDownload.categoryPlaceholder')"
|
||||||
outlined
|
outlined
|
||||||
dense
|
dense
|
||||||
/>
|
/>
|
||||||
@@ -80,7 +80,7 @@ onMounted(() => {
|
|||||||
storage="local"
|
storage="local"
|
||||||
:label="t('workflow.addDownload.savePath')"
|
:label="t('workflow.addDownload.savePath')"
|
||||||
clearable
|
clearable
|
||||||
placeholder="留空自动"
|
:placeholder="t('workflow.addDownload.savePathPlaceholder')"
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import api from '@/api'
|
||||||
|
import { Handle, Position } from '@vue-flow/core'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import type { Plugin } from '@/api/types'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
interface ActionItem {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插件选项
|
||||||
|
const pluginOptions = ref<{ title: string; value: string }[]>([])
|
||||||
|
|
||||||
|
// 动作选项
|
||||||
|
const actionOptions = ref<{ title: string; value: string }[]>([])
|
||||||
|
|
||||||
|
// 用于在文本框显示和保存时转换action_params
|
||||||
|
const actionParamsText = computed({
|
||||||
|
get: () => {
|
||||||
|
try {
|
||||||
|
return typeof props.data.action_params === 'object'
|
||||||
|
? JSON.stringify(props.data.action_params, null, 2)
|
||||||
|
: props.data.action_params || ''
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set: (value: string) => {
|
||||||
|
try {
|
||||||
|
props.data.action_params = value ? JSON.parse(value) : {}
|
||||||
|
} catch (error) {
|
||||||
|
// 如果JSON解析失败,保留原始文本
|
||||||
|
props.data.action_params = value
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// 加载所有插件
|
||||||
|
async function loadPluginSetting() {
|
||||||
|
try {
|
||||||
|
const plugins: Plugin[] = await api.get('plugin/', {
|
||||||
|
params: {
|
||||||
|
state: 'installed',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
pluginOptions.value = plugins.map((item: Plugin) => ({
|
||||||
|
title: item.plugin_name,
|
||||||
|
value: item.id,
|
||||||
|
}))
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载动作选项
|
||||||
|
async function loadPluginActions(pluginId: string) {
|
||||||
|
try {
|
||||||
|
const actions: ActionItem[] = await api.get(`workflow/actions/${pluginId}`)
|
||||||
|
actionOptions.value = actions.map((item: ActionItem) => ({
|
||||||
|
title: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}))
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.data.plugin_id,
|
||||||
|
newVal => {
|
||||||
|
loadPluginActions(newVal)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadPluginSetting()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<VCard max-width="20rem">
|
||||||
|
<Handle id="edge_in" type="target" :position="Position.Left" />
|
||||||
|
<VCardItem>
|
||||||
|
<template v-slot:prepend>
|
||||||
|
<VAvatar>
|
||||||
|
<VIcon icon="mdi-run" size="x-large"></VIcon>
|
||||||
|
</VAvatar>
|
||||||
|
</template>
|
||||||
|
<VCardTitle>{{ t('workflow.invokePlugin.title') }}</VCardTitle>
|
||||||
|
<VCardSubtitle>{{ t('workflow.invokePlugin.subtitle') }}</VCardSubtitle>
|
||||||
|
</VCardItem>
|
||||||
|
<VDivider />
|
||||||
|
<VCardText>
|
||||||
|
<VRow>
|
||||||
|
<VCol cols="12">
|
||||||
|
<VSelect
|
||||||
|
v-model="data.plugin_id"
|
||||||
|
:items="pluginOptions"
|
||||||
|
:label="t('workflow.invokePlugin.plugin')"
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
<VCol cols="12">
|
||||||
|
<VSelect
|
||||||
|
v-model="data.action_id"
|
||||||
|
:items="actionOptions"
|
||||||
|
:label="t('workflow.invokePlugin.actionid')"
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
<VCol cols="12">
|
||||||
|
<VTextarea v-model="actionParamsText" :label="t('workflow.invokePlugin.actionParams')" outlined dense />
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</VCardText>
|
||||||
|
<Handle id="edge_out" type="source" :position="Position.Right" />
|
||||||
|
</VCard>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -71,6 +71,7 @@ function getActionIcon(type: string): string {
|
|||||||
'SendEventAction': 'mdi-send-check',
|
'SendEventAction': 'mdi-send-check',
|
||||||
'SendMessageAction': 'mdi-message-arrow-right',
|
'SendMessageAction': 'mdi-message-arrow-right',
|
||||||
'TransferFileAction': 'mdi-file-move',
|
'TransferFileAction': 'mdi-file-move',
|
||||||
|
'InvokePluginAction': 'mdi-run',
|
||||||
}
|
}
|
||||||
|
|
||||||
return iconMap[type] || 'mdi-puzzle-outline'
|
return iconMap[type] || 'mdi-puzzle-outline'
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ export default {
|
|||||||
sendEvent: 'Send Event',
|
sendEvent: 'Send Event',
|
||||||
sendMessage: 'Send Message',
|
sendMessage: 'Send Message',
|
||||||
transferFile: 'Transfer File',
|
transferFile: 'Transfer File',
|
||||||
|
invokePlugin: 'Invoke Plugin',
|
||||||
},
|
},
|
||||||
qualityOptions: {
|
qualityOptions: {
|
||||||
all: 'All',
|
all: 'All',
|
||||||
@@ -427,6 +428,8 @@ export default {
|
|||||||
forceResume: 'Force Resume',
|
forceResume: 'Force Resume',
|
||||||
firstLastPiece: 'First Last Piece',
|
firstLastPiece: 'First Last Piece',
|
||||||
onlyLack: 'Only Download Lack Resource',
|
onlyLack: 'Only Download Lack Resource',
|
||||||
|
categoryPlaceholder: 'Use comma to separate multiple',
|
||||||
|
savePathPlaceholder: 'Leave empty for auto',
|
||||||
},
|
},
|
||||||
addSubscribe: {
|
addSubscribe: {
|
||||||
title: 'Add Subscribe',
|
title: 'Add Subscribe',
|
||||||
@@ -534,6 +537,14 @@ export default {
|
|||||||
exclude: 'Exclude (Keywords, Regex)',
|
exclude: 'Exclude (Keywords, Regex)',
|
||||||
ruleGroups: 'Filter Rule Groups',
|
ruleGroups: 'Filter Rule Groups',
|
||||||
},
|
},
|
||||||
|
invokePlugin: {
|
||||||
|
title: 'Invoke Plugin',
|
||||||
|
subtitle: 'Call plugin to perform specific actions',
|
||||||
|
plugin: 'Plugin',
|
||||||
|
actionid: 'Action ID',
|
||||||
|
actionParams: 'Action Parameters',
|
||||||
|
loadPluginSettingFailed: 'Failed to load plugin settings',
|
||||||
|
},
|
||||||
title: 'Workflow',
|
title: 'Workflow',
|
||||||
noWorkflow: 'No Workflow',
|
noWorkflow: 'No Workflow',
|
||||||
noWorkflowDescription: 'Click the add button to create a workflow task.',
|
noWorkflowDescription: 'Click the add button to create a workflow task.',
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ export default {
|
|||||||
sendEvent: '发送事件',
|
sendEvent: '发送事件',
|
||||||
sendMessage: '发送消息',
|
sendMessage: '发送消息',
|
||||||
transferFile: '整理文件',
|
transferFile: '整理文件',
|
||||||
|
invokePlugin: '调用插件',
|
||||||
},
|
},
|
||||||
qualityOptions: {
|
qualityOptions: {
|
||||||
all: '全部',
|
all: '全部',
|
||||||
@@ -425,6 +426,8 @@ export default {
|
|||||||
forceResume: '强制继续',
|
forceResume: '强制继续',
|
||||||
firstLastPiece: '优先首尾文件',
|
firstLastPiece: '优先首尾文件',
|
||||||
onlyLack: '仅下载缺失资源',
|
onlyLack: '仅下载缺失资源',
|
||||||
|
categoryPlaceholder: '多个使用,分隔',
|
||||||
|
savePathPlaceholder: '留空自动',
|
||||||
},
|
},
|
||||||
addSubscribe: {
|
addSubscribe: {
|
||||||
title: '添加订阅',
|
title: '添加订阅',
|
||||||
@@ -532,6 +535,14 @@ export default {
|
|||||||
exclude: '排除(关键字、正则式)',
|
exclude: '排除(关键字、正则式)',
|
||||||
ruleGroups: '过滤规则组',
|
ruleGroups: '过滤规则组',
|
||||||
},
|
},
|
||||||
|
invokePlugin: {
|
||||||
|
title: '调用插件',
|
||||||
|
subtitle: '调用插件执行特定操作',
|
||||||
|
plugin: '插件',
|
||||||
|
actionid: '动作ID',
|
||||||
|
actionParams: '动作参数',
|
||||||
|
loadPluginSettingFailed: '加载插件设置失败',
|
||||||
|
},
|
||||||
title: '工作流',
|
title: '工作流',
|
||||||
noWorkflow: '没有工作流',
|
noWorkflow: '没有工作流',
|
||||||
noWorkflowDescription: '点击添加按钮创建工作流任务。',
|
noWorkflowDescription: '点击添加按钮创建工作流任务。',
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ export default {
|
|||||||
sendEvent: '發送事件',
|
sendEvent: '發送事件',
|
||||||
sendMessage: '發送消息',
|
sendMessage: '發送消息',
|
||||||
transferFile: '整理文件',
|
transferFile: '整理文件',
|
||||||
|
invokePlugin: '調用插件',
|
||||||
},
|
},
|
||||||
qualityOptions: {
|
qualityOptions: {
|
||||||
all: '全部',
|
all: '全部',
|
||||||
@@ -426,6 +427,8 @@ export default {
|
|||||||
forceResume: '强制继续',
|
forceResume: '强制继续',
|
||||||
firstLastPiece: '优先首尾文件',
|
firstLastPiece: '优先首尾文件',
|
||||||
onlyLack: '仅下载缺失资源',
|
onlyLack: '仅下载缺失资源',
|
||||||
|
categoryPlaceholder: '多個使用,分隔',
|
||||||
|
savePathPlaceholder: '留空自動',
|
||||||
},
|
},
|
||||||
addSubscribe: {
|
addSubscribe: {
|
||||||
title: '添加订阅',
|
title: '添加订阅',
|
||||||
@@ -533,6 +536,14 @@ export default {
|
|||||||
exclude: '排除(關鍵字、正則式)',
|
exclude: '排除(關鍵字、正則式)',
|
||||||
ruleGroups: '過濾規則組',
|
ruleGroups: '過濾規則組',
|
||||||
},
|
},
|
||||||
|
invokePlugin: {
|
||||||
|
title: '調用插件',
|
||||||
|
subtitle: '調用插件執行特定操作',
|
||||||
|
plugin: '插件',
|
||||||
|
actionid: '動作ID',
|
||||||
|
actionParams: '動作參數',
|
||||||
|
loadPluginSettingFailed: '加載插件設置失敗',
|
||||||
|
},
|
||||||
title: '工作流',
|
title: '工作流',
|
||||||
noWorkflow: '沒有工作流',
|
noWorkflow: '沒有工作流',
|
||||||
noWorkflowDescription: '點擊添加按鈕創建工作流任務。',
|
noWorkflowDescription: '點擊添加按鈕創建工作流任務。',
|
||||||
|
|||||||
Reference in New Issue
Block a user