From add04dce2ad833ecbb7495a641f42fb835ddff62 Mon Sep 17 00:00:00 2001
From: 董国庆 <364620639@qq.com>
Date: 星期三, 14 五月 2025 15:24:00 +0800
Subject: [PATCH] 新增实验调度逻辑

---
 laboratory/src/views/dataManagement/schemeManagement/addPlan.vue |  390 +++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 319 insertions(+), 71 deletions(-)

diff --git a/laboratory/src/views/dataManagement/schemeManagement/addPlan.vue b/laboratory/src/views/dataManagement/schemeManagement/addPlan.vue
index a2605d2..23a85df 100644
--- a/laboratory/src/views/dataManagement/schemeManagement/addPlan.vue
+++ b/laboratory/src/views/dataManagement/schemeManagement/addPlan.vue
@@ -16,12 +16,18 @@
         </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">
+          <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-button type="text" @click="handleEditGroup(scope.row)">编辑</el-button>
-              <el-button type="text" @click="handleDeleteGroup(scope.row)">移除</el-button>
+              <el-tag :type="getStatusType(scope.row.status)">
+                {{ getStatusText(scope.row.status) }}
+              </el-tag>
             </template>
           </el-table-column>
         </Table>
@@ -38,15 +44,20 @@
           <!-- <el-button type="primary" class="el-icon-plus" @click="handleAddGroup">添加组别</el-button> -->
         </div>
 
-        <Table :data="groupTableData" :total="0" :height="null" class="groupTable">
+        <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>
 
-        <div style="padding-left: 25px">
-          <el-form-item prop="name" label="试验日期">
-            <el-input v-model="form.name" placeholder="请输入" />
+        <div style="padding-left: 25px;margin-top: 28px;">
+          <el-form-item prop="experimentDate" label="试验日期">
+          
+            <el-date-picker
+      v-model="form.experimentDate"
+      type="datetime"
+      placeholder="选择日期时间">
+    </el-date-picker>
           </el-form-item>
         </div>
 
@@ -56,20 +67,18 @@
           <el-button type="primary" class="el-icon-plus" @click="addMember">选择参加人员</el-button>
         </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">修改</div>
               </div>
             </div>
           </div>
@@ -82,7 +91,7 @@
           </div>
         </div>
         <div class="content-box">
-          <AiEditor ref="purposeEditor" v-model="editorContents.purpose" height="200px" placeholder="请输入实验目的..." />
+          <AiEditor ref="purposeEditor" :value="editorContents.purpose" height="200px" placeholder="请输入实验目的..." />
         </div>
 
         <div class="header-title" style="margin-bottom: 38px">
@@ -92,7 +101,7 @@
           </div>
         </div>
         <div class="content-box">
-          <AiEditor ref="processEditor" v-model="editorContents.process" height="200px" placeholder="请输入工艺参数及路线..." />
+          <AiEditor ref="processEditor" :value="editorContents.process" height="200px" placeholder="请输入工艺参数及路线..." />
         </div>
 
         <div class="header-title" style="margin-bottom: 38px">
@@ -101,8 +110,8 @@
             <div>三、实验材料及设备</div>
           </div>
         </div>
-        <DynamicComponent ref="materialComponent" title="实验材料" @submit="handleMaterialSubmit" />
-        <DynamicComponent ref="equipmentComponent" title="实验所用设备" @submit="handleEquipmentSubmit" />
+        <DynamicComponent ref="materialComponent" title="实验材料" :participants="participantsData" @submit="handleMaterialSubmit" />
+        <DynamicComponent ref="equipmentComponent" title="实验所用设备" :participants="participantsData" @submit="handleEquipmentSubmit" />
 
         <div class="header-title" style="margin-bottom: 38px">
           <div class="header-title-left">
@@ -138,23 +147,26 @@
         </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 } from "./service";
+import moment from 'moment';
+import { add } from "./service";
 
 export default {
   name: "AddProject",
   components: {
-    SelectMember,
+    SelectMemberSimple,
     experimentalScheduling,
     DynamicComponent,
     AddStep,
@@ -164,8 +176,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: "",
@@ -174,24 +194,28 @@
       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: [],
     };
   },
   methods: {
+    confirmAddRow() {
+      // 处理添加行的逻辑
+      console.log('添加行');
+    },
     submitForm() {
       this.$refs.form.validate((valid) => {
         if (valid) {
@@ -200,21 +224,16 @@
       });
     },
     addMember() {
-      this.$refs.selectMember.open();
+      this.$refs.selectMember.open(this.participantsData, []);
     },
     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;
-      }
+      const roleTypes = {
+        1: '工艺工程师',
+        2: '化验师',
+        3: '实验员'
+      };
+      
+      return this.selectedParticipants.filter(member => member.roleType === i) || [];
     },
     handleAddGroup() {
       this.$refs.addGroupDialog.open();
@@ -279,39 +298,164 @@
       }
     },
     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();
+      
+      // 获取所有步骤内容 - 添加错误检查
+      this.stepList.forEach((step, index) => {
+        const stepContentRef = this.$refs['stepContent' + index];
+        if (stepContentRef && typeof stepContentRef.submit === 'function') {
+          stepContentRef.submit();
+        }
+      });
 
-      const formData = {
-        ...this.form,
-        ...this.getAllEditorContent(),
-        steps: this.stepList,
-        status: "draft",
-      };
-      console.log("草稿数据:", formData);
-      this.$message.success("草稿保存成功");
+      // 然后进行表单校验
+      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();
@@ -346,6 +490,7 @@
       this.$refs.addStepDialog.setStepName(this.stepList[index].stepName);
     },
     handleStepContentSubmit(index, content) {
+      console.log('步骤内容',content)
       this.stepList[index].content = content;
     },
     getAllEditorContent() {
@@ -355,20 +500,123 @@
       };
     },
     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");
     },
+    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);
+    },
   },
 };
 </script>

--
Gitblit v1.7.1