让后端判断content_type
This commit is contained in:
		@@ -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}" 吗?`, '提示', {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user