mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-05-26 02:39:43 +08:00
新增工作流触发类型和事件类型支持
This commit is contained in:
@@ -168,7 +168,7 @@ const resolveStatusVariant = (status: string | undefined) => {
|
||||
if (status === 'S') return { color: 'success', text: t('workflow.task.status.success') }
|
||||
else if (status === 'R') return { color: 'primary', text: t('workflow.task.status.running') }
|
||||
else if (status === 'F') return { color: 'error', text: t('workflow.task.status.failed') }
|
||||
else if (status === 'P') return { color: 'secondary', text: t('workflow.task.status.paused') }
|
||||
else if (status === 'P') return { color: 'warning', text: t('workflow.task.status.paused') }
|
||||
else return { color: 'info', text: t('workflow.task.status.waiting') }
|
||||
}
|
||||
|
||||
@@ -272,15 +272,28 @@ const resolveProgress = (item: Workflow) => {
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<VCardText class="pa-3">
|
||||
<div class="d-flex flex-column gap-y-2">
|
||||
<div class="d-flex flex-column gap-y-3">
|
||||
<div class="d-flex flex-wrap gap-x-3">
|
||||
<div class="flex-1">
|
||||
<div class="mb-1">{{ t('workflow.task.info.timer') }}</div>
|
||||
<h5 class="text-lg">{{ workflow?.timer }}</h5>
|
||||
<div class="mb-1">{{ t('workflow.task.info.trigger') }}</div>
|
||||
<h5>
|
||||
<span v-if="workflow?.trigger_type === 'timer' || !workflow?.trigger_type">
|
||||
<VIcon icon="mdi-clock-outline" size="small" class="me-1" />
|
||||
{{ workflow?.timer }}
|
||||
</span>
|
||||
<span v-else-if="workflow?.trigger_type === 'event'">
|
||||
<VIcon icon="mdi-calendar-check" size="small" class="me-1" />
|
||||
{{ workflow?.event_type }}
|
||||
</span>
|
||||
<span v-else-if="workflow?.trigger_type === 'manual'">
|
||||
<VIcon icon="mdi-hand-pointing-up" size="small" class="me-1" />
|
||||
{{ t('workflow.task.info.manualTrigger') }}
|
||||
</span>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="mb-1">{{ t('workflow.task.info.status') }}</div>
|
||||
<h5 class="text-lg" :class="`text-${resolveStatusVariant(workflow?.state).color}`">
|
||||
<h5 :class="`text-${resolveStatusVariant(workflow?.state).color}`">
|
||||
{{ resolveStatusVariant(workflow?.state).text }}
|
||||
</h5>
|
||||
</div>
|
||||
@@ -289,14 +302,14 @@ const resolveProgress = (item: Workflow) => {
|
||||
<div class="flex-1">
|
||||
<div class="mb-1">{{ t('workflow.task.info.actionCount') }}</div>
|
||||
<div>
|
||||
<VAvatar size="28" color="primary" variant="tonal">
|
||||
<span class="text-sm">{{ workflow?.actions?.length }}</span>
|
||||
<VAvatar size="24" color="primary" variant="tonal">
|
||||
<span class="text-xs">{{ workflow?.actions?.length }}</span>
|
||||
</VAvatar>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="mb-1">{{ t('workflow.task.info.runCount') }}</div>
|
||||
<h5 class="text-lg">{{ workflow?.run_count }}</h5>
|
||||
<h5>{{ workflow?.run_count }}</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-wrap gap-x-3">
|
||||
|
||||
@@ -190,10 +190,23 @@ async function doDelete() {
|
||||
<span class="text-body-1"> {{ props.workflow?.share_user }}</span>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
<VListItem class="ps-0" v-if="props.workflow?.timer">
|
||||
<VListItem class="ps-0" v-if="props.workflow?.trigger_type || props.workflow?.timer">
|
||||
<VListItemTitle class="text-center text-md-left">
|
||||
<span class="font-weight-medium">{{ t('workflow.timer') }}:</span>
|
||||
<span class="text-body-1"> {{ props.workflow?.timer }}</span>
|
||||
<span class="font-weight-medium">{{ t('workflow.trigger') }}:</span>
|
||||
<span class="text-body-1">
|
||||
<span v-if="props.workflow?.trigger_type === 'timer' || !props.workflow?.trigger_type">
|
||||
<VIcon icon="mdi-clock-outline" size="small" class="me-1" />
|
||||
{{ props.workflow?.timer }}
|
||||
</span>
|
||||
<span v-else-if="props.workflow?.trigger_type === 'event'">
|
||||
<VIcon icon="mdi-calendar-check" size="small" class="me-1" />
|
||||
{{ props.workflow?.event_type }}
|
||||
</span>
|
||||
<span v-else-if="props.workflow?.trigger_type === 'manual'">
|
||||
<VIcon icon="mdi-hand-pointing-up" size="small" class="me-1" />
|
||||
{{ t('workflow.manualTrigger') }}
|
||||
</span>
|
||||
</span>
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
<VListItem class="ps-0" v-if="parsedWorkflow?.actions">
|
||||
|
||||
@@ -33,20 +33,95 @@ const workflowForm = ref<Workflow>(
|
||||
name: undefined,
|
||||
timer: undefined,
|
||||
description: undefined,
|
||||
trigger_type: 'timer',
|
||||
event_type: undefined,
|
||||
state: 'P',
|
||||
run_count: 0,
|
||||
},
|
||||
)
|
||||
|
||||
// 监听props变化,处理存量数据
|
||||
watch(
|
||||
() => props.workflow,
|
||||
newWorkflow => {
|
||||
if (newWorkflow) {
|
||||
// 如果trigger_type为空,默认为timer
|
||||
if (!newWorkflow.trigger_type) {
|
||||
newWorkflow.trigger_type = 'timer'
|
||||
}
|
||||
workflowForm.value = { ...newWorkflow }
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
// 事件类型列表
|
||||
const eventTypes = ref<Array<{ title: string; value: string }>>([])
|
||||
|
||||
// 触发类型选项
|
||||
const triggerTypeOptions = computed(() => [
|
||||
{
|
||||
title: t('dialog.workflowAddEdit.triggerTypeTimer'),
|
||||
value: 'timer',
|
||||
prependIcon: 'mdi-clock-outline',
|
||||
},
|
||||
{
|
||||
title: t('dialog.workflowAddEdit.triggerTypeEvent'),
|
||||
value: 'event',
|
||||
prependIcon: 'mdi-calendar-check',
|
||||
},
|
||||
{
|
||||
title: t('dialog.workflowAddEdit.triggerTypeManual'),
|
||||
value: 'manual',
|
||||
prependIcon: 'mdi-hand-pointing-up',
|
||||
},
|
||||
])
|
||||
|
||||
// 加载事件类型列表
|
||||
async function loadEventTypes() {
|
||||
try {
|
||||
eventTypes.value = await api.get('workflow/event_types')
|
||||
} catch (error) {
|
||||
console.error('Failed to load event types:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 监听触发类型变化
|
||||
watch(
|
||||
() => workflowForm.value.trigger_type,
|
||||
newType => {
|
||||
if (newType !== 'event') {
|
||||
workflowForm.value.event_type = undefined
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// 提示框
|
||||
const $toast = useToast()
|
||||
|
||||
// 调用API 新增任务
|
||||
async function addWorkflow() {
|
||||
if (!workflowForm.value.name || !workflowForm.value.timer) {
|
||||
if (!workflowForm.value.name) {
|
||||
$toast.error(t('dialog.workflowAddEdit.nameRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
if (!workflowForm.value.trigger_type) {
|
||||
$toast.error(t('dialog.workflowAddEdit.triggerRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
// 根据触发类型验证必填字段
|
||||
if (workflowForm.value.trigger_type === 'timer' && !workflowForm.value.timer) {
|
||||
$toast.error(t('dialog.workflowAddEdit.timerRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
if (workflowForm.value.trigger_type === 'event' && !workflowForm.value.event_type) {
|
||||
$toast.error(t('dialog.workflowAddEdit.eventTypeRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
startNProgress()
|
||||
try {
|
||||
const result: { [key: string]: string } = await api.post('workflow/', workflowForm.value)
|
||||
@@ -64,10 +139,27 @@ async function addWorkflow() {
|
||||
|
||||
// 调用API 编辑任务
|
||||
async function editWorkflow() {
|
||||
if (!workflowForm.value.name || !workflowForm.value.timer) {
|
||||
if (!workflowForm.value.name) {
|
||||
$toast.error(t('dialog.workflowAddEdit.nameRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
if (!workflowForm.value.trigger_type) {
|
||||
$toast.error(t('dialog.workflowAddEdit.triggerRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
// 根据触发类型验证必填字段
|
||||
if (workflowForm.value.trigger_type === 'timer' && !workflowForm.value.timer) {
|
||||
$toast.error(t('dialog.workflowAddEdit.timerRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
if (workflowForm.value.trigger_type === 'event' && !workflowForm.value.event_type) {
|
||||
$toast.error(t('dialog.workflowAddEdit.eventTypeRequired'))
|
||||
return
|
||||
}
|
||||
|
||||
startNProgress()
|
||||
try {
|
||||
const result: { [key: string]: string } = await api.put(`workflow/${workflowForm.value.id}`, workflowForm.value)
|
||||
@@ -82,6 +174,11 @@ async function editWorkflow() {
|
||||
}
|
||||
doneNProgress()
|
||||
}
|
||||
|
||||
// 组件挂载时加载事件类型
|
||||
onMounted(() => {
|
||||
loadEventTypes()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -109,6 +206,25 @@ async function editWorkflow() {
|
||||
/>
|
||||
</VCol>
|
||||
<VCol cols="12">
|
||||
<VSelect
|
||||
v-model="workflowForm.trigger_type"
|
||||
:label="t('dialog.workflowAddEdit.triggerType')"
|
||||
:items="triggerTypeOptions"
|
||||
item-title="title"
|
||||
item-value="value"
|
||||
:rules="[requiredValidator]"
|
||||
prepend-inner-icon="mdi-run"
|
||||
>
|
||||
<template #item="{ item, props: itemProps }">
|
||||
<VListItem v-bind="itemProps">
|
||||
<template #prepend>
|
||||
<VIcon :icon="item.raw.prependIcon" />
|
||||
</template>
|
||||
</VListItem>
|
||||
</template>
|
||||
</VSelect>
|
||||
</VCol>
|
||||
<VCol v-if="workflowForm.trigger_type === 'timer'" cols="12">
|
||||
<VCronField
|
||||
v-model="workflowForm.timer"
|
||||
:label="t('dialog.workflowAddEdit.schedule')"
|
||||
@@ -119,6 +235,19 @@ async function editWorkflow() {
|
||||
prepend-inner-icon="mdi-clock-outline"
|
||||
/>
|
||||
</VCol>
|
||||
<VCol v-if="workflowForm.trigger_type === 'event'" cols="12">
|
||||
<VSelect
|
||||
v-model="workflowForm.event_type"
|
||||
:label="t('dialog.workflowAddEdit.eventType')"
|
||||
:items="eventTypes"
|
||||
item-title="title"
|
||||
item-value="value"
|
||||
:rules="[requiredValidator]"
|
||||
persistent-hint
|
||||
:hint="t('dialog.workflowAddEdit.eventTypePlaceholder')"
|
||||
prepend-inner-icon="mdi-calendar-check"
|
||||
/>
|
||||
</VCol>
|
||||
<VCol cols="12">
|
||||
<VTextarea
|
||||
v-model="workflowForm.description"
|
||||
|
||||
Reference in New Issue
Block a user