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