让后端判断content_type

This commit is contained in:
2025-09-23 19:34:19 +08:00
parent c1ac0a17b2
commit ff3b0db02d

View File

@@ -21,7 +21,7 @@
<div>
<template v-if="!isSubPlan">
<el-button class="button" type="primary" @click="savePlanContent" v-if="isEditingContent">保存</el-button>
<el-button class="button" @click="cancelEdit" v-if="isEditingContent">取消</el-button>
<el-button class="button" type="danger" @click="cancelEdit" v-if="isEditingContent">取消</el-button>
<el-button class="button" @click="enterEditMode" v-else>编辑内容</el-button>
</template>
@@ -37,7 +37,7 @@
v-if="plan.content_type === 'tasks' || !plan.content_type"
type="primary"
size="small"
@click="showAddTaskDialog"
@click="showTaskEditorDialog()"
>增加子任务</el-button>
</template>
</div>
@@ -126,31 +126,31 @@
</template>
</el-dialog>
<!-- Add Task Dialog -->
<!-- Task Editor Dialog (for Add and Edit) -->
<el-dialog
v-model="addTaskDialogVisible"
title="增加子任务"
v-model="taskEditorDialogVisible"
:title="isEditingTask ? '编辑子任务' : '增加子任务'"
width="600px"
@close="resetAddTaskDialog"
@close="resetTaskEditorDialog"
>
<el-form :model="newTaskForm" ref="newTaskFormRef" :rules="newTaskRules" label-width="100px">
<el-form :model="currentTaskForm" ref="taskFormRef" :rules="taskFormRules" label-width="100px">
<el-form-item label="任务类型" prop="type">
<el-select v-model="newTaskForm.type" placeholder="请选择任务类型" style="width: 100%;">
<el-select v-model="currentTaskForm.type" placeholder="请选择任务类型" style="width: 100%;" :disabled="isEditingTask">
<!-- Only Delay Task for now -->
<el-option label="延时任务" value="delay_task"></el-option>
</el-select>
</el-form-item>
<el-form-item label="任务名称" prop="name">
<el-input v-model="newTaskForm.name" placeholder="请输入任务名称"></el-input>
<el-input v-model="currentTaskForm.name" placeholder="请输入任务名称"></el-input>
</el-form-item>
<el-form-item label="任务描述" prop="description">
<el-input type="textarea" v-model="newTaskForm.description" placeholder="请输入任务描述"></el-input>
<el-input type="textarea" v-model="currentTaskForm.description" placeholder="请输入任务描述"></el-input>
</el-form-item>
<!-- Dynamic task component for specific parameters -->
<template v-if="newTaskForm.type === 'delay_task'">
<template v-if="currentTaskForm.type === 'delay_task'">
<DelayTaskEditor
:parameters="newTaskForm.parameters"
@update:parameters="val => newTaskForm.parameters = val"
:parameters="currentTaskForm.parameters"
@update:parameters="val => currentTaskForm.parameters = val"
prop-path="parameters.delay_duration"
:is-editing="true"
/>
@@ -159,8 +159,8 @@
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="addTaskDialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmAddTask">确定</el-button>
<el-button @click="taskEditorDialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmTaskEdit">确定</el-button>
</span>
</template>
</el-dialog>
@@ -207,26 +207,26 @@ export default {
loading: false,
error: null,
isEditingContent: false,
originalPlanState: null,
// Add Sub-plan dialog
addSubPlanDialogVisible: false,
selectedSubPlanId: null,
availablePlans: [],
// Add Task dialog
addTaskDialogVisible: false,
newTaskForm: {
// Task Editor dialog (for Add and Edit)
taskEditorDialogVisible: false,
isEditingTask: false,
editingTaskOriginalId: null,
currentTaskForm: {
type: 'delay_task',
name: '',
description: '',
parameters: { delay_duration: 1 }, // Initialize with delay_duration
parameters: {},
},
newTaskRules: {
taskFormRules: {
type: [{ required: true, message: '请选择任务类型', trigger: 'change' }],
name: [{ required: true, message: '请输入任务名称', trigger: 'blur' }],
// Add rule for delay_duration directly here, as it's the default type
'parameters.delay_duration': [{ required: true, message: '请输入延时时间', trigger: 'blur' }],
// Rule for delay_duration will be added/removed dynamically
},
};
},
@@ -244,20 +244,22 @@ export default {
}
},
},
'newTaskForm.type'(newType) {
// This watch is less critical now since delay_task is the only option
// but kept for extensibility.
'currentTaskForm.type'(newType) {
console.log("PlanDetail: currentTaskForm.type changed to", newType);
if (newType === 'delay_task') {
this.newTaskRules['parameters.delay_duration'] = this.delayDurationRules;
if (!this.newTaskForm.parameters.delay_duration) {
this.newTaskForm.parameters.delay_duration = 1;
this.taskFormRules['parameters.delay_duration'] = this.delayDurationRules;
if (this.currentTaskForm.parameters.delay_duration === undefined) {
this.currentTaskForm.parameters.delay_duration = 1;
console.log("PlanDetail: Initialized currentTaskForm.parameters.delay_duration to", this.currentTaskForm.parameters.delay_duration);
}
} else {
if (this.newTaskRules['parameters.delay_duration']) {
delete this.newTaskRules['parameters.delay_duration'];
if (this.taskFormRules['parameters.delay_duration']) {
delete this.taskFormRules['parameters.delay_duration'];
console.log("PlanDetail: Removed delay_duration rule.");
}
if (this.newTaskForm.parameters.delay_duration) {
delete this.newTaskForm.parameters.delay_duration;
if (this.currentTaskForm.parameters.delay_duration !== undefined) {
delete this.currentTaskForm.parameters.delay_duration;
console.log("PlanDetail: Removed delay_duration parameter.");
}
}
},
@@ -292,7 +294,7 @@ export default {
},
enterEditMode() {
this.isEditingContent = true;
this.originalPlanState = JSON.parse(JSON.stringify(this.plan));
console.log("PlanDetail: Entered edit mode.");
},
async savePlanContent() {
this.updateContentType();
@@ -304,7 +306,6 @@ export default {
execution_type: this.plan.execution_type,
execute_num: this.plan.execute_num,
cron_expression: this.plan.cron_expression,
content_type: this.plan.content_type,
sub_plan_ids: this.plan.content_type === 'sub_plans'
? this.plan.sub_plans.map(sp => sp.child_plan_id)
: [],
@@ -312,8 +313,7 @@ export default {
? this.plan.tasks.map((task, index) => ({
name: task.name,
description: task.description,
// Set type to 'waiting' for delay_task
type: task.type === 'delay_task' ? 'waiting' : task.type,
type: task.type,
execution_order: index + 1,
parameters: task.parameters || {},
}))
@@ -323,20 +323,20 @@ export default {
delete submitData.execute_count;
delete submitData.status;
console.log("PlanDetail: Submitting data", submitData);
await apiClient.plans.update(this.planId, submitData);
ElMessage.success('计划内容已保存');
this.isEditingContent = false;
this.originalPlanState = null;
this.fetchPlan();
} catch (error) {
ElMessage.error('保存计划内容失败: ' + (error.message || '未知错误'));
console.error('保存计划内容失败:', error);
}
},
cancelEdit() {
this.plan = JSON.parse(JSON.stringify(this.originalPlanState));
async cancelEdit() {
console.log("PlanDetail: Cancelled edit, re-fetching plan.");
await this.fetchPlan();
this.isEditingContent = false;
this.originalPlanState = null;
ElMessage.info('已取消编辑');
},
@@ -409,54 +409,119 @@ export default {
},
// --- Task related methods ---
async showAddTaskDialog() {
if (this.plan.sub_plans.length > 0) {
try {
await ElMessageBox.confirm('当前计划包含子计划,添加任务将清空现有子计划。是否继续?', '警告', {
showTaskEditorDialog(task = null) {
console.log("PlanDetail: Showing task editor dialog.");
if (this.plan.sub_plans.length > 0 && !task) {
ElMessageBox.confirm('当前计划包含子计划,添加任务将清空现有子计划。是否继续?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.plan.sub_plans = [];
this.taskEditorDialogVisible = true;
this.prepareTaskForm(task);
}).catch(() => {
// User cancelled
});
this.plan.sub_plans = [];
} catch (e) {
return;
}
}
this.addTaskDialogVisible = true;
this.taskEditorDialogVisible = true;
this.prepareTaskForm(task);
},
confirmAddTask() {
this.$refs.newTaskFormRef.validate(async (valid) => {
if (valid) {
const newTask = {
id: Date.now(),
execution_order: this.plan.tasks.length + 1,
// Map 'delay_task' UI type to 'waiting' backend type
type: this.newTaskForm.type === 'delay_task' ? 'waiting' : this.newTaskForm.type,
name: this.newTaskForm.name,
description: this.newTaskForm.description,
parameters: this.newTaskForm.parameters,
};
prepareTaskForm(task = null) {
// Reset properties of the existing reactive object
this.currentTaskForm.type = 'delay_task';
this.currentTaskForm.name = '';
this.currentTaskForm.description = '';
this.currentTaskForm.parameters = {}; // Ensure parameters is reset
this.plan.tasks.push(newTask);
if (task) {
this.isEditingTask = true;
this.editingTaskOriginalId = task.id;
// Update properties of the existing reactive object
this.currentTaskForm.type = task.type === 'waiting' ? 'delay_task' : task.type; // Convert backend type to UI type
this.currentTaskForm.name = task.name;
this.currentTaskForm.description = task.description;
// Deep copy parameters to ensure reactivity for nested changes
this.currentTaskForm.parameters = JSON.parse(JSON.stringify(task.parameters || {}));
console.log("PlanDetail: Prepared currentTaskForm for editing:", JSON.parse(JSON.stringify(this.currentTaskForm)));
} else {
this.isEditingTask = false;
this.editingTaskOriginalId = null;
// Properties are already reset above for new task mode
console.log("PlanDetail: Prepared currentTaskForm for adding:", JSON.parse(JSON.stringify(this.currentTaskForm)));
}
// Manually trigger watch for type to ensure rules and default parameters are set
this.updateTaskFormRules();
// Also, ensure delay_duration is initialized if it's a delay_task
if (this.currentTaskForm.type === 'delay_task' && this.currentTaskForm.parameters.delay_duration === undefined) {
this.currentTaskForm.parameters.delay_duration = 1;
}
},
updateTaskFormRules() {
// Clear existing dynamic rules
if (this.taskFormRules['parameters.delay_duration']) {
delete this.taskFormRules['parameters.delay_duration'];
}
// Apply rules based on current type
if (this.currentTaskForm.type === 'delay_task') {
this.taskFormRules['parameters.delay_duration'] = this.delayDurationRules;
}
console.log("PlanDetail: Updated taskFormRules:", JSON.parse(JSON.stringify(this.taskFormRules)));
},
confirmTaskEdit() {
console.log("PlanDetail: confirmTaskEdit called. currentTaskForm before validation:", JSON.parse(JSON.stringify(this.currentTaskForm)));
this.$refs.taskFormRef.validate(async (valid) => {
console.log("PlanDetail: Form validation result:", valid);
if (valid) {
if (this.isEditingTask) {
// Find and update the existing task
const index = this.plan.tasks.findIndex(t => t.id === this.editingTaskOriginalId);
if (index !== -1) {
// Update properties of the existing task
this.plan.tasks[index].name = this.currentTaskForm.name;
this.plan.tasks[index].description = this.currentTaskForm.description;
this.plan.tasks[index].type = this.currentTaskForm.type === 'delay_task' ? 'waiting' : this.currentTaskForm.type;
this.plan.tasks[index].parameters = this.currentTaskForm.parameters;
ElMessage.success(`子任务 "${this.currentTaskForm.name}" 已更新`);
} else {
ElMessage.error('未找到要编辑的任务');
}
} else {
// Add a new task
const newTask = {
id: Date.now(),
execution_order: this.plan.tasks.length + 1,
type: this.currentTaskForm.type === 'delay_task' ? 'waiting' : this.currentTaskForm.type,
name: this.currentTaskForm.name,
description: this.currentTaskForm.description,
parameters: this.currentTaskForm.parameters,
};
this.plan.tasks.push(newTask);
ElMessage.success(`子任务 "${newTask.name}" 已添加`);
}
this.updateContentType();
ElMessage.success(`子任务 "${newTask.name}" 已添加`);
this.addTaskDialogVisible = false;
this.resetAddTaskDialog();
this.taskEditorDialogVisible = false;
this.resetTaskEditorDialog();
}
});
},
resetAddTaskDialog() {
this.$refs.newTaskFormRef.resetFields();
this.newTaskForm = {
type: 'delay_task',
name: '',
description: '',
parameters: { delay_duration: 1 }, // Reset with default delay_duration
};
resetTaskEditorDialog() {
console.log("PlanDetail: Resetting task editor dialog.");
this.$refs.taskFormRef.resetFields();
this.isEditingTask = false;
this.editingTaskOriginalId = null;
// Manually reset properties to ensure clean state for next use
this.currentTaskForm.type = 'delay_task';
this.currentTaskForm.name = '';
this.currentTaskForm.description = '';
this.currentTaskForm.parameters = {};
console.log("PlanDetail: currentTaskForm after full reset:", JSON.parse(JSON.stringify(this.currentTaskForm)));
this.updateTaskFormRules();
},
editTask(task) {
ElMessage.info('编辑任务功能正在开发中');
console.log('编辑任务:', task);
editTask(task) {
console.log('PlanDetail: Calling showTaskEditorDialog for editing task:', task);
this.showTaskEditorDialog(task);
},
deleteTask(taskToDelete) {
ElMessageBox.confirm(`确认删除任务 "${taskToDelete.name}" 吗?`, '提示', {