董国庆
7 天以前 069ef85293bb4baa74dd9251e8b3fd8cc4355410
laboratory/src/views/dataManagement/schemeManagement/addPlan.vue
@@ -1,130 +1,120 @@
<template>
  <Card>
    <template style="position: relative">
      <el-form
        ref="form"
        :model="form"
        :rules="rules"
        inline
        label-position="top"
      >
        <div class="header-title" style="margin-bottom: 38px;justify-content: space-between;">
          <div style="display: flex;align-items: center;gap: 13px;">
      <el-form ref="form" :model="form" :rules="rules" inline label-position="top">
        <div v-if="!isEdit">
          <div class="header-title" style="margin-bottom: 38px">
            <div style="display: flex; align-items: center; gap: 13px">
              <div class="header-title-left">
                <img src="@/assets/public/headercard.png" />
                <div>所属实验调度</div>
              </div>
              <el-button @click="showScheduling = true" class="el-icon-plus" type="primary">
                选择实验调度</el-button>
            </div>
          </div>
          <!-- //换到详情弹窗 -->
          <!-- <el-button @click="handleStopExperiment" type="danger">
            申请终止实验</el-button> -->
          <Table :data="groupTableData" :total="0" :height="null" class="groupTable">
            <el-table-column type="index" label="序号" width="80"></el-table-column>
            <el-table-column prop="projectName" label="所属项目课题方案"></el-table-column>
            <el-table-column prop="experimentCode" label="实验编号"></el-table-column>
            <el-table-column prop="experimentName" label="实验名称"></el-table-column>
            <el-table-column prop="experimentDate" label="通知时间"></el-table-column>
            <el-table-column prop="experimentStartTime" label="实验开始时间"></el-table-column>
            <el-table-column prop="experimentEndTime" label="实验结束时间"></el-table-column>
            <el-table-column prop="participantsName" label="参加人员"></el-table-column>
            <el-table-column prop="status" label="状态">
              <template slot-scope="scope">
                <el-tag :type="getStatusType(scope.row.status)">
                  {{ getStatusText(scope.row.status) }}
                </el-tag>
              </template>
            </el-table-column>
          </Table>
          <div class="header-title" style="margin-bottom: 38px">
            <div class="header-title-left">
              <img src="@/assets/public/headercard.png" />
              <div>所属实验调度</div>
              <span>基础信息</span>
            </div>
            <el-button
              @click="showScheduling = true"
              class="el-icon-plus"
              type="primary"
            >
              选择实验调度</el-button
            >
          </div>
          <el-button
              @click="handleStopExperiment"
              type="danger"
            >
              申请终止实验</el-button
            >
        </div>
        <Table
          :data="groupTableData"
          :total="0"
          :height="null"
          class="groupTable"
        >
          <el-table-column
            type="index"
            label="序号"
            width="80"
          ></el-table-column>
          <el-table-column prop="groupName" label="组别"></el-table-column>
          <el-table-column prop="remark" label="备注"></el-table-column>
          <el-table-column label="操作" width="200">
            <template slot-scope="scope">
              <el-button type="text" @click="handleEditGroup(scope.row)"
                >编辑</el-button
              >
              <el-button type="text" @click="handleDeleteGroup(scope.row)"
                >移除</el-button
              >
            </template>
          </el-table-column>
        </Table>
        <div class="header-title" style="margin-bottom: 38px">
          <div class="header-title-left">
            <img src="@/assets/public/headercard.png" />
            <span>基础信息</span>
          <template v-if="groupData && groupData.length > 0">
            <div class="add-group">
              <span>组别列表</span>
            </div>
            <Table :data="groupData" :total="0" :height="null" class="groupTable">
              <el-table-column type="index" label="序号" width="80"></el-table-column>
              <el-table-column prop="groupName" label="组别"></el-table-column>
              <el-table-column prop="remark" label="备注"></el-table-column>
            </Table>
          </template>
          <div style="padding-left: 25px;margin-top: 28px;">
            <el-form-item prop="experimentDate" label="试验日期">
              <el-date-picker v-model="form.experimentDate" type="datetime" :disabled="isEdit" placeholder="选择日期时间">
              </el-date-picker>
            </el-form-item>
          </div>
        </div>
        <div v-else>
          <div class="header-title" style="margin-bottom: 18px">
            <div class="header-title-left">
              <img src="@/assets/public/headercard.png" />
              <div>所属项目课题方案</div>
            </div>
          </div>
          <div class="content-box">
            <div class="content-box-left">
              <div>项目课题方案名称:{{ groupTableData[0].projectName }}</div>
              <div>实验编号:{{ groupTableData[0].experimentCode }}</div>
            </div>
            <div class="content-box-right">
              <div>项目课题方案编号: {{ groupTableData[0].projectCode }}</div>
              <div>实验名称: {{ groupTableData[0].experimentName }}</div>
            </div>
          </div>
        </div>
        <div class="add-group">
          <span>组别列表</span>
          <!-- <el-button type="primary" class="el-icon-plus" @click="handleAddGroup">添加组别</el-button> -->
        </div>
        <Table
          :data="groupTableData"
          :total="0"
          :height="null"
          class="groupTable"
        >
          <el-table-column
            type="index"
            label="序号"
            width="80"
          ></el-table-column>
          <el-table-column prop="groupName" label="组别"></el-table-column>
          <el-table-column prop="remark" label="备注"></el-table-column>
        </Table>
        <div style="padding-left: 25px">
          <el-form-item prop="name" label="试验日期">
            <el-input v-model="form.name" placeholder="请输入" />
          </el-form-item>
        </div>
        <div class="add-group">
        <div class="add-group" v-if="!isEdit">
          <div>*</div>
          <span>参加人员</span>
          <el-button type="primary" class="el-icon-plus" @click="addMember"
            >选择参加人员</el-button
          >
          <el-button type="primary" class="el-icon-plus" @click="addMember" >选择参加人员</el-button>
        </div>
        <div class="add-group" v-else><span>实验人员</span> </div>
        <div class="member-list">
          <div v-for="item in 3" :key="item" class="member-list-card">
          <div class="member-list-card">
            <div class="member-item">
              <div class="member-title">
                {{ ["工艺工程师", "实验员", "化验师"][item - 1] }}
              </div>
              <div
                :class="item == 1 || item == 2 ? 'member-name-box' : 'flex1'"
              >
                <div
                  :class="
                    item == 1 || item == 2
                      ? 'member-name-box'
                      : 'member-name-box-2'
                  "
                >
                  <div
                    v-for="i in memberList(item)"
                    :key="i"
                    class="member-name"
                  >
                    张三
              <div class="member-title">实验员</div>
              <div class="flex">
                <div class="member-name-box-2">
                  <div v-for="i in selectedParticipants" :key="i.id" class="member-name">
                    {{ i.nickName }}
                  </div>
                </div>
              </div>
              <div class="member-change">
                <div class="member-change-btn">修改</div>
                <div class="member-change-btn" @click="handleEditMember" v-if="!isEdit">修改</div>
              </div>
            </div>
          </div>
        </div>
        <template v-if="groupData && groupData.length > 0 && isEdit">
          <div class="add-group">
            <span>组别列表</span>
          </div>
          <Table :data="groupData" :total="0" :height="null" class="groupTable">
            <el-table-column type="index" label="序号" width="80"></el-table-column>
            <el-table-column prop="groupName" label="组别"></el-table-column>
            <el-table-column prop="remark" label="备注"></el-table-column>
          </Table>
        </template>
        <div class="header-title" style="margin-bottom: 38px">
          <div class="header-title-left">
@@ -133,12 +123,8 @@
          </div>
        </div>
        <div class="content-box">
          <AiEditor
            ref="purposeEditor"
            v-model="editorContents.purpose"
            height="200px"
            placeholder="请输入实验目的..."
          />
          <AiEditor ref="purposeEditor" :readOnly="isEdit" :value="editorContents.purpose" height="200px"
            placeholder="请输入实验目的..." />
        </div>
        <div class="header-title" style="margin-bottom: 38px">
@@ -148,12 +134,8 @@
          </div>
        </div>
        <div class="content-box">
          <AiEditor
            ref="processEditor"
            v-model="editorContents.process"
            height="200px"
            placeholder="请输入工艺参数及路线..."
          />
          <AiEditor ref="processEditor" :readOnly="isEdit" :value="editorContents.process" height="200px"
            placeholder="请输入工艺参数及路线..." />
        </div>
        <div class="header-title" style="margin-bottom: 38px">
@@ -162,25 +144,18 @@
            <div>三、实验材料及设备</div>
          </div>
        </div>
        <DynamicComponent
          ref="materialComponent"
          title="实验材料"
          @submit="handleMaterialSubmit"
        />
        <DynamicComponent
          ref="equipmentComponent"
          title="实验所用设备"
          @submit="handleEquipmentSubmit"
        />
        <DynamicComponent ref="materialComponent" title="实验材料" :participants="participantsData"
          @submit="handleMaterialSubmit" :dataSource="form.experimentMaterial" :editable="!isEdit" />
        <DynamicComponent ref="equipmentComponent" title="实验所用设备" :participants="participantsData"
          @submit="handleEquipmentSubmit" :dataSource="form.experimentDevice" :editable="!isEdit" />
        <div class="header-title" style="margin-bottom: 38px">
          <div class="header-title-left">
            <img src="@/assets/public/headercard.png" />
            <div>四、实验操作步骤记录</div>
          </div>
          <el-button @click="handleAddStep" class="el-icon-plus" type="primary">
            添加步骤</el-button
          >
          <el-button @click="handleAddStep" class="el-icon-plus" type="primary" v-if="!isEdit">
            添加步骤</el-button>
        </div>
        <div class="step-list" v-for="(item, idx) in stepList" :key="idx">
@@ -189,55 +164,46 @@
              步骤{{ idx + 1 }}:{{ item.stepName }}
            </div>
            <div class="step-list-item-control">
              <div class="controlBtn edit" @click="handleEditStep(idx)">
                <img
                  src="@/assets/public/edit.png"
                  alt="编辑"
                  class="edit-icon"
                />
              <div class="controlBtn edit" @click="handleEditStep(idx)" v-if="!isEdit">
                <img src="@/assets/public/edit.png" alt="编辑" class="edit-icon" />
                编辑
              </div>
              <div class="controlBtn delete" @click="handleDeleteStep(idx)">
                <img
                  src="@/assets/public/delete.png"
                  alt="删除"
                  class="delete-icon"
                />
              <div class="controlBtn delete" @click="handleDeleteStep(idx)" v-if="!isEdit">
                <img src="@/assets/public/delete.png" alt="删除" class="delete-icon" />
                删除
              </div>
            </div>
          </div>
          <DynamicComponent
            :ref="'stepContent' + idx"
            @submit="(content) => handleStepContentSubmit(idx, content)"
          />
          <DynamicComponent :ref="'stepContent' + idx" @submit="(content) => handleStepContentSubmit(idx, content)"
            :dataSource="item.content" :editable="!isEdit" />
        </div>
        <div class="add-project-footer">
          <el-button type="primary" class="save-btn" @click="handleSave"
            >发送</el-button
          >
          <el-button type="primary" class="save-btn" @click="handleSave">发送</el-button>
          <el-button @click="handleSaveDraft">存草稿</el-button>
        </div>
      </el-form>
    </template>
    <SelectMember ref="selectMember" />
    <experimentalScheduling :show="showScheduling" />
    <SelectMemberSimple ref="selectMember" @submit="handleMemberSubmit" />
    <experimentalScheduling :show="showScheduling" @submit="handleSchedulingSubmit" @close="handleSchedulingClose" />
    <AddStep ref="addStepDialog" @submit="handleStepSubmit" />
  </Card>
</template>
<script>
import SelectMember from "@/components/SelectMember";
import experimentalScheduling from "../confirmation-sheet/components/experimental-scheduling.vue";
import SelectMemberSimple from "@/components/SelectMemberSimple/index.vue";
import experimentalScheduling from "./components/experimental-scheduling.vue";
import DynamicComponent from "@/components/DynamicComponent";
import AddStep from "./components/add-step.vue";
import AiEditor from "@/components/AiEditor";
import { getGroupByDispatchId, getParticipantsByDispatchId, getDetail } from "./service";
import moment from 'moment';
import { add,update } from "./service";
export default {
  name: "AddProject",
  components: {
    SelectMember,
    SelectMemberSimple,
    experimentalScheduling,
    DynamicComponent,
    AddStep,
@@ -247,8 +213,16 @@
    return {
      showScheduling: false,
      form: {
        material: null,
        equipment: null,
        experimentDate: '', // 实验日期
        experimentMaterial: null,
        experimentDevice: null,
        experimentObjective: '', // 实验目的
        experimentParamRoute: '', // 工艺参数及路线
        experimentStepRecord: [], // 实验步骤记录
        experimentSchemePersons: [], // 实验方案人员
        dispatchId: '', // 实验调度id
        status: -1, // 状态:-1=草稿箱 1=已发送
        commitTime: '', // 提交时间
      },
      editorContents: {
        purpose: "",
@@ -257,144 +231,198 @@
      stepList: [],
      editingStepIndex: -1,
      rules: {
        name: [
          { required: true, message: "请输入项目组名称", trigger: "blur" },
        experimentDate: [
          { required: true, message: "请输入实验日期", trigger: "blur" },
        ],
        description: [
          { required: true, message: "请输入项目组描述", trigger: "blur" },
        ],
        material: [
        experimentMaterial: [
          { required: true, message: "请添加实验材料", trigger: "change" },
        ],
        equipment: [
        experimentDevice: [
          { required: true, message: "请添加实验设备", trigger: "change" },
        ],
      },
      groupTableData: [],
      groupData: [],
      taskTableData: [],
      participantsData: [],
      selectedParticipants: [],
      isEdit: false, // 是否为编辑模式
      editId: null, // 编辑的ID
      viewMaterialData: [], // 查看模式的材料数据
      viewEquipmentData: [], // 查看模式的设备数据
    };
  },
  async created() {
    // 检查是否为编辑模式
    if (this.$route.query.type === 'edit' && this.$route.query.id) {
      this.isEdit = true;
      this.editId = this.$route.query.id;
      await this.loadEditData();
    }
  },
  methods: {
    submitForm() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          console.log("submit!");
        }
      });
    },
    addMember() {
      this.$refs.selectMember.open();
    },
    memberList(i) {
      switch (i) {
        case 1:
          return [1];
        case 2:
          return [1];
        case 3:
          return [1, 2, 3, 4, 5, 6, 7, 8];
        case 4:
          return [1, 2, 3, 4, 5, 6, 7, 8];
        default:
          break;
      }
    },
    handleAddGroup() {
      this.$refs.addGroupDialog.open();
    },
    handleEditGroup(row) {
      this.$refs.addGroupDialog.open(row);
    },
    handleDeleteGroup(row) {
      this.$confirm("确认删除该组别吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          const index = this.groupTableData.findIndex((item) => item === row);
          if (index > -1) {
            this.groupTableData.splice(index, 1);
            this.$message.success("删除成功");
          }
        })
        .catch(() => {});
    },
    handleGroupSubmit(form) {
      const index = this.groupTableData.findIndex(
        (item) => item.groupName === form.groupName
      );
      if (index > -1) {
        this.groupTableData.splice(index, 1, form);
      } else {
        this.groupTableData.push(form);
      }
    },
    handleAddTask() {
      this.$refs.addTaskDialog.open();
    },
    handleEditTask(row) {
      this.$refs.addTaskDialog.open(row);
    },
    handleDeleteTask(row) {
      this.$confirm("确认删除该任务吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          const index = this.taskTableData.findIndex((item) => item === row);
          if (index > -1) {
            this.taskTableData.splice(index, 1);
            this.$message.success("删除成功");
          }
        })
        .catch(() => {});
    },
    handleTaskSubmit(form) {
      const index = this.taskTableData.findIndex(
        (item) => item.taskName === form.taskName
      );
      if (index > -1) {
        this.taskTableData.splice(index, 1, form);
      } else {
        this.taskTableData.push(form);
      }
      this.$refs.selectMember.open(this.participantsData, []);
    },
    handleMaterialSubmit(data) {
      this.form.material = data;
      // 处理实验材料数据
      this.form.experimentMaterial = data;
    },
    handleEquipmentSubmit(data) {
      this.form.equipment = data;
      // 处理实验设备数据
      this.form.experimentDevice = data;
    },
    handleSave() {
      // 先获取所有动态组件的数据
      this.$refs.materialComponent.submit();
      this.$refs.equipmentComponent.submit();
      // 获取所有步骤内容 - 添加错误检查
      this.stepList.forEach((step, index) => {
        const stepContentRef = this.$refs['stepContent' + index];
        console.log('stepContentRef', stepContentRef)
        const editor = Array.isArray(stepContentRef) ? stepContentRef[0] : stepContentRef;
        if (editor && typeof editor.submit === 'function') {
          editor.submit();
        }
      });
      console.log('材料数据', this.form.experimentMaterial)
      console.log('设备数据', this.form.experimentDevice)
      console.log('步骤数据', this.form.stepList)
      // 然后进行表单校验
      this.$refs.form.validate((valid) => {
        if (valid && this.validateContent()) {
          this.$refs.materialComponent.submit();
          this.$refs.equipmentComponent.submit();
          // 构建提交数据
          const formData = {
            ...this.form,
            ...this.getAllEditorContent(),
            steps: this.stepList,
            // 实验日期,使用 moment 格式化为指定格式
            experimentDate: moment(this.form.experimentDate).format('YYYY-MM-DD HH:mm:ss'),
            // 实验调度ID,从选中的调度数据中获取
            dispatchId: this.groupTableData[0]?.id,
            // 实验设备,转换为JSON字符串
            experimentDevice: this.form.experimentDevice,
            // 实验材料,转换为JSON字符串
            experimentMaterial: this.form.experimentMaterial,
            // 实验目的,从富文本编辑器获取内容
            experimentObjective: this.$refs.purposeEditor.getContent(),
            // 工艺参数及路线,从富文本编辑器获取内容
            experimentParamRoute: this.$refs.processEditor.getContent(),
            // 实验方案人员,包含用户ID、昵称和角色类型
            experimentSchemePersons: this.selectedParticipants.map(person => ({
              userId: person.userId,    // 用户ID
              nickName: person.nickName, // 用户昵称
              roleType: person.roleType,  // 角色类型
              commitTime: moment().format('YYYY-MM-DD HH:mm:ss'),
            })),
            // 实验步骤记录,转换为JSON字符串,包含步骤名称和内容
            experimentStepRecord: this.stepList.map(step => ({
              stepName: step.stepName,  // 步骤名称
              content: step.content     // 步骤内容
            })),
            // 状态:1=已发送
            status: 1,
            // 提交时间,使用 moment 格式化为指定格式
            commitTime: moment().format('YYYY-MM-DD HH:mm:ss'),
          };
          console.log("提交的数据:", formData);
          this.$message.success("保存成功");
          console.log('formData 提交数据', formData)
          // 调用添加接口
          add(formData).then(res => {
            if (res.code === 200) {
              this.$message.success('保存成功');
              this.$router.go(-1)
              // 可以在这里添加跳转逻辑
            } else {
              this.$message.error(res.msg || '保存失败');
            }
          }).catch(err => {
            this.$message.error('保存失败');
            console.error('保存失败:', err);
          });
        } else {
          // 获取第一个错误字段
          const firstError = this.$refs.form.fields.find(field => field.validateState === 'error');
          if (firstError) {
            // 滚动到错误字段
            this.$nextTick(() => {
              firstError.$el.scrollIntoView({ behavior: 'smooth', block: 'center' });
            });
          }
        }
      });
    },
    handleSaveDraft() {
      // 先获取所有动态组件的数据
      this.$refs.materialComponent.submit();
      this.$refs.equipmentComponent.submit();
      const formData = {
        ...this.form,
        ...this.getAllEditorContent(),
        steps: this.stepList,
        status: "draft",
      };
      console.log("草稿数据:", formData);
      this.$message.success("草稿保存成功");
      // 获取所有步骤内容 - 添加错误检查
      this.stepList.forEach((step, index) => {
        const stepContentRef = this.$refs['stepContent' + index];
        if (stepContentRef && typeof stepContentRef.submit === 'function') {
          stepContentRef.submit();
        }
      });
      // 然后进行表单校验
      this.$refs.form.validate((valid) => {
        if (valid && this.validateContent()) {
          // 构建草稿数据
          const formData = {
            ...this.form,
            // 实验日期,使用 moment 格式化为指定格式
            experimentDate: moment(this.form.experimentDate).format('YYYY-MM-DD HH:mm:ss'),
            // 实验调度ID,从选中的调度数据中获取
            dispatchId: this.groupTableData[0]?.id,
            // 实验设备,转换为JSON字符串
            experimentDevice: JSON.stringify(this.form.experimentDevice),
            // 实验材料,转换为JSON字符串
            experimentMaterial: JSON.stringify(this.form.experimentMaterial),
            // 实验目的,从富文本编辑器获取内容
            experimentObjective: this.$refs.purposeEditor.getContent(),
            // 工艺参数及路线,从富文本编辑器获取内容
            experimentParamRoute: this.$refs.processEditor.getContent(),
            // 实验方案人员,包含用户ID、昵称和角色类型
            experimentSchemePersons: this.selectedParticipants.map(person => ({
              userId: person.userId,    // 用户ID
              nickName: person.nickName, // 用户昵称
              roleType: person.roleType  // 角色类型
            })),
            // 实验步骤记录,转换为JSON字符串,包含步骤名称和内容
            experimentStepRecord: JSON.stringify(this.stepList.map(step => ({
              stepName: step.stepName,  // 步骤名称
              content: step.content     // 步骤内容
            }))),
            // 状态:-1=草稿箱
            status: -1,
            // 提交时间,使用 moment 格式化为指定格式
            commitTime: moment().format('YYYY-MM-DD HH:mm:ss'),
          };
          // 调用添加接口
          add(formData).then(res => {
            if (res.code === 200) {
              this.$message.success('草稿保存成功');
              // 可以在这里添加跳转逻辑
            } else {
              this.$message.error(res.msg || '草稿保存失败');
            }
          }).catch(err => {
            this.$message.error('草稿保存失败');
            console.error('草稿保存失败:', err);
          });
        } else {
          // 获取第一个错误字段
          const firstError = this.$refs.form.fields.find(field => field.validateState === 'error');
          if (firstError) {
            // 滚动到错误字段
            this.$nextTick(() => {
              firstError.$el.scrollIntoView({ behavior: 'smooth', block: 'center' });
            });
          }
        }
      });
    },
    handleAddStep() {
      this.$refs.addStepDialog.open();
@@ -421,7 +449,7 @@
          this.stepList.splice(index, 1);
          this.$message.success("删除成功");
        })
        .catch(() => {});
        .catch(() => { });
    },
    handleEditStep(index) {
      this.editingStepIndex = index;
@@ -429,6 +457,7 @@
      this.$refs.addStepDialog.setStepName(this.stepList[index].stepName);
    },
    handleStepContentSubmit(index, content) {
      console.log('步骤内容', content)
      this.stepList[index].content = content;
    },
    getAllEditorContent() {
@@ -438,19 +467,260 @@
      };
    },
    validateContent() {
      const contents = this.getAllEditorContent();
      if (!contents.purpose) {
        this.$message.error("请填写实验目的");
      // // 校验实验调度
      // if (!this.groupTableData || this.groupTableData.length === 0) {
      //   this.$message.error("请选择实验调度");
      //   return false;
      // }
      // // 校验实验日期
      // if (!this.form.experimentDate) {
      //   this.$message.error("请填写实验日期");
      //   return false;
      // }
      // // 校验参与人员
      // if (!this.selectedParticipants || this.selectedParticipants.length === 0) {
      //   this.$message.error("请选择参与人员");
      //   return false;
      // }
      // // 校验实验目的
      // const purpose = this.$refs.purposeEditor.getContent();
      // if (!purpose || purpose === '<p></p>' || purpose.trim() === '<p></p>') {
      //   this.$message.error("请填写实验目的");
      //   return false;
      // }
      // // 校验工艺参数及路线
      // const process = this.$refs.processEditor.getContent();
      // if (!process || process === '<p></p>' || process.trim() === '<p></p>') {
      //   this.$message.error("请填写工艺参数及路线");
      //   return false;
      // }
      // 校验实验材料
      if (!this.form.experimentMaterial) {
        this.$message.error("请添加实验材料");
        return false;
      }
      if (!contents.process) {
        this.$message.error("请填写工艺参数及路线");
      // 校验实验设备
      if (!this.form.experimentDevice) {
        this.$message.error("请添加实验设备");
        return false;
      }
      // 校验实验步骤记录
      if (!this.stepList || this.stepList.length === 0) {
        this.$message.error("请添加实验操作步骤");
        return false;
      }
      // 校验每个步骤是否都有内容
      for (let i = 0; i < this.stepList.length; i++) {
        if (!this.stepList[i].content) {
          this.$message.error(`请完善第${i + 1}个步骤的内容`);
          return false;
        }
      }
      return true;
    },
    handleStopExperiment() {
      this.$router.push('/dataManagement/scheme-management/stop-experiment')
      this.$router.push("/dataManagement/scheme-management/stop-experiment");
    },
    getStatusType(status) {
      const statusMap = {
        "-1": "info",
        "1": "warning",
        "2": "success",
        "3": "info"
      };
      return statusMap[status] || "info";
    },
    getStatusText(status) {
      const statusMap = {
        "-1": "草稿箱",
        "1": "待确认",
        "2": "已确认",
        "3": "已封存"
      };
      return statusMap[status] || "未知";
    },
    handleSchedulingSubmit(data) {
      this.groupTableData = data;
      if (data && data.length > 0) {
        getGroupByDispatchId({ dispatchId: data[0].id }).then(res => {
          if (res) {
            this.groupData = res || [];
          } else {
            this.$message.error(res.msg || '获取组别列表失败');
          }
        }).catch(err => {
          this.$message.error('获取组别列表失败');
          console.error('获取组别列表失败:', err);
        });
        getParticipantsByDispatchId({ dispatchId: data[0].id }).then(res => {
          console.log("获取参加人员列表:", res);
          if (res) {
            this.participantsData = res || [];
          } else {
            this.$message.error(res.msg || '获取参加人员列表失败');
          }
        }).catch(err => {
          this.$message.error('获取参加人员列表失败');
          console.error('获取参加人员列表失败:', err);
        });
      }
    },
    handleSchedulingClose() {
      this.showScheduling = false;
    },
    handleMemberSubmit(selectedMembers) {
      this.selectedParticipants = selectedMembers;
      this.$refs.selectMember.close();
    },
    handleEditMember() {
      this.$refs.selectMember.open(this.participantsData, this.selectedParticipants);
    },
    // 加载编辑数据
    async loadEditData() {
      try {
        const res = await getDetail({ id: this.editId });
        console.log('编辑数据', res);
        if (res) {
          const data = res;
          // 填充基本表单数据
          this.form.experimentDate = data.experimentDate;
          // 填充实验调度信息
          if (data.experimentDispatch && data.experimentDispatch.id) {
            this.form.dispatchId = data.experimentDispatch.id;
            // 获取组别信息
            try {
              const groupRes = await getGroupByDispatchId({ dispatchId: data.experimentDispatch.id });
              if (groupRes) {
                this.groupData = groupRes || [];
              }
            } catch (err) {
              console.error('获取组别列表失败:', err);
            }
            // 构建调度表格数据
            this.groupTableData = [{ ...data.experimentDispatch }];
          }
          // 填充参与人员
          if (data.experimentSchemePersons) {
            this.selectedParticipants = Array.isArray(data.experimentSchemePersons)
              ? data.experimentSchemePersons
              : JSON.parse(data.experimentSchemePersons || '[]');
          }
          // 填充富文本编辑器内容
          this.editorContents.purpose = data.experimentObjective || '';
          this.editorContents.process = data.experimentParamRoute || '';
          // 填充实验材料和设备(编辑模式下转换为查看格式)
          if (data.experimentMaterial) {
            try {
              const materialData = typeof data.experimentMaterial === 'string'
                ? JSON.parse(data.experimentMaterial)
                : data.experimentMaterial;
              this.form.experimentMaterial = materialData;
            } catch (err) {
              console.error('解析实验材料数据失败:', err);
              this.viewMaterialData = [];
            }
          }
          if (data.experimentDevice) {
            try {
              const deviceData = typeof data.experimentDevice === 'string'
                ? JSON.parse(data.experimentDevice)
                : data.experimentDevice;
              this.form.experimentDevice = deviceData;
            } catch (err) {
              console.error('解析实验设备数据失败:', err);
              this.viewEquipmentData = [];
            }
          }
          // 填充实验步骤(编辑模式下步骤内容也要转换为查看格式)
          if (data.experimentStepRecord) {
            try {
              const stepsData = typeof data.experimentStepRecord === 'string'
                ? JSON.parse(data.experimentStepRecord)
                : data.experimentStepRecord;
              this.stepList = (stepsData || []).map(step => ({
                stepName: step.stepName,
                // 编辑模式下步骤内容转换为查看格式
                content: step.content
              }));
            } catch (err) {
              console.error('解析实验步骤数据失败:', err);
              this.stepList = [];
            }
          }
          // 等待组件渲染完成后设置编辑器内容
          this.$nextTick(() => {
            // 设置富文本编辑器内容
            if (this.$refs.purposeEditor) {
              this.$refs.purposeEditor.setContent(this.editorContents.purpose);
            }
            if (this.$refs.processEditor) {
              this.$refs.processEditor.setContent(this.editorContents.process);
            }
            // 新增模式下设置动态组件的初始数据
            if (!this.isEdit) {
              if (this.$refs.materialComponent && this.form.experimentMaterial) {
                this.$refs.materialComponent.setInitialData(this.form.experimentMaterial);
              }
              if (this.$refs.equipmentComponent && this.form.experimentDevice) {
                this.$refs.equipmentComponent.setInitialData(this.form.experimentDevice);
              }
              // 设置步骤内容的初始数据
              this.stepList.forEach((step, index) => {
                const stepContentRef = this.$refs['stepContent' + index];
                if (stepContentRef && step.content) {
                  const editor = Array.isArray(stepContentRef) ? stepContentRef[0] : stepContentRef;
                  if (editor && typeof editor.setInitialData === 'function') {
                    editor.setInitialData(step.content);
                  }
                }
              });
            }
          });
        } else {
          this.$message.error(res.msg || '获取详情失败');
          // this.$router.go(-1);
        }
      } catch (error) {
        this.$message.error('获取详情失败');
        console.error('获取详情失败:', error);
        // this.$router.go(-1);
      }
    },
    // 转换数据格式为ViewDynamicComponent需要的格式
    convertToViewFormat(data) {
      if (!data || !Array.isArray(data)) return [];
      return data.map(item => ({
        id: item.id || Math.random().toString(36).substr(2, 9),
        type: item.type,
        data: item.data
      }));
    },
  },
};
@@ -467,6 +737,7 @@
  flex-wrap: wrap;
  gap: 13px;
  margin-top: 38px;
  .header-title-left {
    display: flex;
    align-items: center;
@@ -529,6 +800,7 @@
.header-title:first-child {
  margin-top: 0px;
  .header-title-left {
    margin-top: 0;
  }
@@ -558,6 +830,7 @@
  width: 65%;
  padding-left: 40px;
}
.rwuTable {
  width: 85%;
  padding-left: 40px;
@@ -577,35 +850,27 @@
    border: 1px solid #dcdfe6;
    &:nth-child(1) {
      background: linear-gradient(
        to bottom,
        rgba(4, 156, 154, 0.2) 0%,
        rgba(5, 242, 194, 0) 70%
      );
      background: linear-gradient(to bottom,
          rgba(4, 156, 154, 0.2) 0%,
          rgba(5, 242, 194, 0) 70%);
    }
    &:nth-child(2) {
      background: linear-gradient(
        to bottom,
        rgba(5, 160, 193, 0.2) 0%,
        rgba(5, 242, 194, 0) 70%
      );
      background: linear-gradient(to bottom,
          rgba(5, 160, 193, 0.2) 0%,
          rgba(5, 242, 194, 0) 70%);
    }
    &:nth-child(3) {
      background: linear-gradient(
        to bottom,
        rgba(255, 77, 79, 0.2) 0%,
        rgba(255, 242, 194, 0) 70%
      );
      background: linear-gradient(to bottom,
          rgba(255, 77, 79, 0.2) 0%,
          rgba(255, 242, 194, 0) 70%);
    }
    &:nth-child(4) {
      background: linear-gradient(
        to bottom,
        rgba(250, 199, 20, 0.21) 0%,
        rgba(255, 242, 194, 0) 70%
      );
      background: linear-gradient(to bottom,
          rgba(250, 199, 20, 0.21) 0%,
          rgba(255, 242, 194, 0) 70%);
    }
    .member-item {
@@ -623,6 +888,7 @@
        line-height: 16px;
        text-align: center;
      }
      .flex1 {
        flex: 1;
      }
@@ -664,6 +930,7 @@
        padding: 10px 0;
        margin-top: auto;
        cursor: pointer;
        .member-change-btn {
          background: #fff1f0;
          border-radius: 4px;
@@ -695,14 +962,17 @@
  padding: 20px;
  margin-top: 37px;
}
.step-list {
  background: #eff8fa;
  padding: 20px;
  .step-list-item {
    display: flex;
    justify-content: space-between;
    padding: 25px;
    background: #ffffff;
    .step-list-item-title {
      font-weight: 500;
      font-size: 14px;
@@ -711,9 +981,11 @@
      flex-wrap: wrap;
      flex: 1;
    }
    .step-list-item-control {
      display: flex;
      align-items: center;
      .controlBtn {
        height: 24px;
        background: #ffffff;
@@ -722,6 +994,7 @@
        display: flex;
        align-items: center;
      }
      .edit {
        border: 1px solid #44be09;
        font-family: PingFangSC, PingFang SC;
@@ -731,6 +1004,7 @@
        line-height: 24px;
        margin-right: 50px;
      }
      .delete {
        border: 1px solid #ff4d4f;
        font-family: PingFangSC, PingFang SC;
@@ -739,11 +1013,13 @@
        color: #ff4d4f;
        line-height: 24px;
      }
      .edit-icon {
        width: 14px;
        height: 14px;
        margin-right: 8px;
      }
      .delete-icon {
        width: 13px;
        height: 13px;
@@ -755,7 +1031,20 @@
.content-box {
  padding: 0 25px;
  margin-bottom: 30px;
  margin-bottom: 20px;
  width: 65%;
  display: flex;
  .content-box-left{
    flex: 1;
    div{
      padding: 10px 0;
    }
  }
  .content-box-right{
    flex: 1;
    div{
      padding: 10px 0;
    }
  }
}
</style>