From 9cb1c3c39136c89974bc4049fca5e450e757b1be Mon Sep 17 00:00:00 2001
From: 13404089107 <puwei@sinata.cn>
Date: 星期五, 15 八月 2025 17:51:03 +0800
Subject: [PATCH] fix

---
 laboratory/src/views/dataManagement/dispatching/addDispatch.vue |  918 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 815 insertions(+), 103 deletions(-)

diff --git a/laboratory/src/views/dataManagement/dispatching/addDispatch.vue b/laboratory/src/views/dataManagement/dispatching/addDispatch.vue
index ca50dab..42f3159 100644
--- a/laboratory/src/views/dataManagement/dispatching/addDispatch.vue
+++ b/laboratory/src/views/dataManagement/dispatching/addDispatch.vue
@@ -15,14 +15,56 @@
           </div>
         </div>
         <div style="padding-left: 25px">
-          <el-form-item prop="name" label="项目课题方案名称">
-            <el-input v-model="form.name" placeholder="请输入" />
+          <el-form-item prop="projectName" label="项目课题方案名称">
+            <el-select
+              ref="projectNameSelect"
+              v-model="form.projectName"
+              filterable
+              remote
+              :remote-method="debouncedSearch"
+              :loading="projectLoading"
+              placeholder="请输入方案名称"
+              @change="handleProjectNameChange"
+              @focus="handleProjectFocus"
+            >
+              <el-option
+                v-for="item in projectOptions"
+                :key="item.id"
+                :label="item.projectName"
+                :value="item.id"
+              />
+            </el-select>
           </el-form-item>
-          <el-form-item prop="description" label="项目课题方案编号">
-            <el-input v-model="form.description" placeholder="请输入" />
+          <el-form-item prop="proposalId" label="项目课题方案编号">
+            <el-select
+              ref="proposalIdSelect"
+              v-model="form.proposalId"
+              filterable
+              remote
+              :remote-method="debouncedSearch"
+              :loading="projectLoading"
+              placeholder="请输入方案编号"
+              @change="handleProposalIdChange"
+              @focus="handleProjectFocus"
+            >
+              <el-option
+                v-for="item in projectOptions"
+                :key="item.id"
+                :label="item.projectCode"
+                :value="item.id"
+              />
+            </el-select>
           </el-form-item>
-          <el-form-item prop="description" label="项目阶段">
-            <el-input v-model="form.description" placeholder="请输入" />
+          <el-form-item prop="projectStage" label="项目阶段">
+            <el-select
+              v-model="form.projectStage"
+              disabled
+              placeholder="请选择"
+            >
+              <el-option label="实验室开发阶段" :value="1" />
+              <el-option label="中式试验阶段" :value="2" />
+              <el-option label="生产验证试验阶段" :value="3" />
+            </el-select>
           </el-form-item>
         </div>
 
@@ -33,20 +75,32 @@
           </div>
         </div>
         <div style="padding-left: 25px">
-          <el-form-item prop="name" label="试验日期">
-            <el-input v-model="form.name" placeholder="请输入" />
+          <el-form-item prop="experimentDate" label="试验日期">
+            <el-date-picker
+              name="data-test"
+              v-model="form.experimentDate"
+              type="date"
+              placeholder="选择日期"
+              @change="handleDateChange"
+            ></el-date-picker>
           </el-form-item>
-          <el-form-item prop="description" label="实验名称">
-            <el-input v-model="form.description" placeholder="请输入" />
+          <el-form-item prop="experimentName" label="实验名称">
+            <el-input v-model="form.experimentName" placeholder="请输入" />
           </el-form-item>
-          <el-form-item prop="description" label="实验编号">
-            <el-input v-model="form.description" placeholder="请输入" />
+          <el-form-item prop="experimentCode" label="实验编号">
+            <el-input
+              v-model="form.experimentCode"
+              placeholder="请输入"
+              disabled
+            />
           </el-form-item>
         </div>
 
         <div class="add-group">
           <span>实验分组</span>
-          <el-button type="primary" class="el-icon-plus" @click="handleAddGroup">添加组别</el-button>
+          <el-button type="primary" class="el-icon-plus" @click="handleAddGroup"
+            >添加组别</el-button
+          >
         </div>
         <Table
           :data="groupTableData"
@@ -54,13 +108,21 @@
           :height="null"
           class="groupTable"
         >
-          <el-table-column type="index" label="序号" width="80"></el-table-column>
+          <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>
+              <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>
@@ -72,42 +134,54 @@
           </div>
         </div>
         <div style="padding-left: 25px">
-          <el-form-item prop="name" label="试验时间">
-            <el-input v-model="form.name" placeholder="请输入" />
+          <el-form-item prop="experimentTime" label="试验时间">
+            <el-date-picker
+              style="width: 100%"
+              v-model="form.experimentTime"
+              type="datetimerange"
+              range-separator="至"
+              start-placeholder="开始时间"
+              end-placeholder="结束时间"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              :default-time="['00:00:00', '23:59:59']"
+              @change="handleTimeRangeChange"
+            ></el-date-picker>
           </el-form-item>
         </div>
         <div class="add-group">
           <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="member-list">
-          <div v-for="item in 3" :key="item" class="member-list-card">
+          <div v-for="item in [3, 4, 5]" :key="item" class="member-list-card">
             <div class="member-item">
               <div class="member-title">
-                {{ ["工艺工程师", "实验员", "化验师"][item - 1] }}
+                {{ ["工艺工程师", "化验师", "实验员"][item - 3] }}
               </div>
-              <div
-                :class="item == 1 || item == 2 ? 'member-name-box' : 'flex1'"
-              >
+              <div :class="item == 3 ? 'member-name-box' : 'flex1'">
                 <div
-                  :class="
-                    item == 1 || item == 2
-                      ? 'member-name-box'
-                      : 'member-name-box-2'
-                  "
+                  :class="item == 3 ? 'member-name-box' : 'member-name-box-2'"
                 >
                   <div
                     v-for="i in memberList(item)"
-                    :key="i"
+                    :key="i.userId"
                     class="member-name"
                   >
-                    张三
+                    {{ i.nickName }}
                   </div>
                 </div>
               </div>
               <div class="member-change">
-                <div class="member-change-btn">修改</div>
+                <div
+                  class="member-change-btn"
+                  @click="editUserList(item)"
+                  v-if="item == 4 || item == 5"
+                >
+                  修改
+                </div>
               </div>
             </div>
           </div>
@@ -118,23 +192,36 @@
             <img src="@/assets/public/headercard.png" />
             <span>四 、任务分解</span>
           </div>
-          <el-button type="primary" class="el-icon-plus" @click="handleAddTask">新增任务</el-button>
+          <el-button type="primary" class="el-icon-plus" @click="handleAddTask"
+            >新增任务</el-button
+          >
         </div>
 
         <Table
           :data="taskTableData"
-          :total="0"
+          :total="allTaskTableData.length"
           :height="null"
+          :queryForm="{ pageNum: taskPageNum, pageSize: taskPageSize }"
+          :disAblePagination="true"
+          @handleCurrentChange="handleCurrentChange"
           class="rwuTable"
         >
-          <el-table-column type="index" label="序号" width="80"></el-table-column>
+          <el-table-column
+            type="index"
+            label="序号"
+            width="80"
+          ></el-table-column>
           <el-table-column prop="taskName" label="任务名称"></el-table-column>
-          <el-table-column prop="leader" label="负责人"></el-table-column>
+          <el-table-column prop="personCharge" label="负责人"></el-table-column>
           <el-table-column prop="startTime" label="开始时间"></el-table-column>
           <el-table-column label="操作" width="200">
             <template slot-scope="scope">
-              <el-button type="text" @click="handleEditTask(scope.row)">编辑</el-button>
-              <el-button type="text" @click="handleDeleteTask(scope.row)">移除</el-button>
+              <el-button type="text" @click="handleEditTask(scope.row)"
+                >编辑</el-button
+              >
+              <el-button type="text" @click="handleDeleteTask(scope.row)"
+                >移除</el-button
+              >
             </template>
           </el-table-column>
         </Table>
@@ -145,129 +232,756 @@
             <span>五 、关键节点</span>
           </div>
         </div>
+        <div style="padding: 20px 55px 20px 25px">
+          <AIEditor
+            ref="keyNodesEditor"
+            :value="form.keyNodes"
+            :min-height="200"
+            placeholder="请输入关键节点内容"
+          />
+        </div>
 
         <div class="add-project-footer">
-          <el-button type="primary" class="save-btn">发送</el-button>
-          <el-button>存草稿</el-button>
+          <el-button type="primary" class="save-btn" @click="sendDispatch"
+            >保存</el-button
+          >
+          <el-button @click="saveDraft">存草稿</el-button>
         </div>
       </el-form>
     </template>
-    <SelectMember ref="selectMember" />
+    <SelectMember ref="selectMember" @submit="selectUser" />
     <AddGroupDialog ref="addGroupDialog" @submit="handleGroupSubmit" />
     <AddTaskDialog ref="addTaskDialog" @submit="handleTaskSubmit" />
   </Card>
 </template>
 
 <script>
-import SelectMember from '@/components/SelectMember'
-import AddGroupDialog from './components/AddGroupDialog'
-import AddTaskDialog from './components/AddTaskDialog'
+import SelectMember from "@/components/SelectMember/index.vue";
+import AddGroupDialog from "./components/AddGroupDialog";
+import AddTaskDialog from "./components/AddTaskDialog";
+import AIEditor from "@/components/AiEditor";
+import {
+  getProposalList,
+  addDispatch,
+  updateDispatch,
+  getDetailById,
+} from "./service";
+import { mapState } from "vuex";
 export default {
   name: "AddProject",
   components: {
     SelectMember,
     AddGroupDialog,
-    AddTaskDialog
+    AddTaskDialog,
+    AIEditor,
   },
   data() {
     return {
-      form: {},
+      id: "", // 用于编辑时存储id
+      form: {
+        projectName: "", // 课题方案名称
+        proposalId: "", // 项目课题方案id
+        projectStage: "", // 项目阶段
+        experimentName: "", // 实验名称
+        experimentCode: "", // 实验编号
+        experimentDate: "", // 实验日期
+        experimentTime: [], // 实验时间范围
+        status: -1, // 状态 -1=草稿箱 1=待确认 2=已确认 3=已封存
+        experimentDispatchGroups: [], // 组别列表
+        experimentDispatchParticipants: [], // 参与人员
+        experimentDispatchTasks: [], // 任务列表
+        keyNodes: "", // 关键节点
+      },
       rules: {
-        name: [
-          { required: true, message: "请输入项目组名称", trigger: "blur" },
+        projectName: [
+          {
+            required: true,
+            message: "请输入项目课题方案名称",
+            trigger: "blur",
+          },
         ],
-        description: [
-          { required: true, message: "请输入项目组描述", trigger: "blur" },
+        proposalId: [
+          {
+            required: true,
+            message: "请输入项目课题方案编号",
+            trigger: "blur",
+          },
+        ],
+        experimentName: [
+          { required: true, message: "请输入实验名称", trigger: "blur" },
+        ],
+        experimentDate: [
+          { required: true, message: "请选择实验日期", trigger: "change" },
+        ],
+        experimentTime: [
+          { required: true, message: "请选择实验时间范围", trigger: "change" },
         ],
       },
       groupTableData: [],
-      taskTableData: []
+      taskTableData: [], // 当前页展示的数据
+      allTaskTableData: [], // 全部任务数据
+      taskPageNum: 1,
+      taskPageSize: 15,
+      members: {
+        processEngineer: [], // 工艺工程师
+        experimenter: [], // 实验员
+        analyst: [], // 化验师
+      },
+      selectMemberData: [],
+      ROLE_CONFIG: {
+        3: { label: "工艺工程师", limit: 1, default: true }, // 工艺工程师
+        5: { label: "实验员", limit: 8 }, // 实验员
+        4: { label: "化验师", limit: 8 }, // 化验师
+      },
+      currentEditRoleId: null,
+      // 下拉框数据
+      projectOptions: [], // 所有方案数据
+      projectLoading: false, // 加载状态
+      // 缓存数据
+      projectDataMap: new Map(), // 缓存方案数据,key为方案ID
     };
   },
+  computed: {
+    ...mapState(["tagList", "isFold"]),
+  },
   methods: {
+    // 获取当前用户信息
+    getCurrentUser() {
+      const userInfo = sessionStorage.getItem("userInfo");
+      return userInfo ? JSON.parse(userInfo) : null;
+    },
+    addMember() {
+      // 判断是否选择了项目课题方案
+      if (!this.form.proposalId) {
+        this.$message.warning("请先选择项目课题方案");
+        return;
+      }
+
+      // 获取当前用户信息
+      const currentUser = this.getCurrentUser();
+      // 如果当前用户是工艺工程师,则自动添加到工艺工程师列表中
+      if (currentUser && !this.members.processEngineer.length) {
+        this.members.processEngineer = [
+          {
+            userId: currentUser.userId,
+            nickName: currentUser.nickName,
+            avatar: currentUser.avatar,
+            roleId: 3,
+            roleName: "工艺工程师",
+          },
+        ];
+        // 同时更新selectMemberData
+        this.selectMemberData = [...this.members.processEngineer];
+      }
+
+      // 设置当前编辑角色为null,表示是新增操作
+      this.currentEditRoleId = null;
+
+      // 打开选择弹窗,并传入项目ID
+      this.$refs.selectMember.open();
+      // 设置项目ID
+      this.$refs.selectMember.projectId = this.form.proposalId;
+      // 设置已选中的成员
+      this.$nextTick(() => {
+        const selectedMembers = [
+          ...this.members.processEngineer,
+          ...this.members.experimenter,
+          ...this.members.analyst,
+        ];
+        this.$refs.selectMember.setSelection(selectedMembers);
+      });
+    },
+    editUserList(roleId) {
+      // 判断是否选择了项目课题方案
+      if (!this.form.proposalId) {
+        this.$message.warning("请先选择项目课题方案");
+        return;
+      }
+
+      // 如果是工艺工程师,不允许修改
+      if (roleId === 3) {
+        this.$message.warning("工艺工程师不可修改");
+        return;
+      }
+
+      // 保存当前正在编辑的角色ID
+      this.currentEditRoleId = roleId;
+
+      // 打开选择弹窗,并传入项目ID
+      this.$refs.selectMember.open();
+      // 设置项目ID
+      this.$refs.selectMember.projectId = this.form.proposalId;
+
+      // 设置已选中的成员(只设置当前角色的成员)
+      this.$nextTick(() => {
+        let selectedMembers = [];
+        switch (roleId) {
+          case 5: // 实验员
+            selectedMembers = [...this.members.experimenter];
+            break;
+          case 4: // 化验师
+            selectedMembers = [...this.members.analyst];
+            break;
+        }
+        this.$refs.selectMember.setSelection(selectedMembers);
+      });
+    },
+    selectUser(data) {
+      // 检查每个角色的选择数量限制
+      for (const [roleId, config] of Object.entries(this.ROLE_CONFIG)) {
+        const members = data.filter((item) => item.roleId === parseInt(roleId));
+        if (members.length > config.limit) {
+          this.$message.error(`${config.label}最多只能选择${config.limit}个`);
+          return;
+        }
+      }
+
+      // 获取当前正在编辑的角色ID
+      const currentRoleId = this.currentEditRoleId;
+
+      if (currentRoleId === null) {
+        // 如果是新增操作,更新所有角色的数据
+        this.members = {
+          processEngineer: this.members.processEngineer, // 保持工艺工程师不变
+          experimenter: data.filter((item) => item.roleId === 5), // 实验员
+          analyst: data.filter((item) => item.roleId === 4), // 化验师
+        };
+      } else {
+        // 如果是编辑操作,只更新当前编辑的角色数据
+        if (currentRoleId === 5) {
+          // 实验员
+          this.members.experimenter = data.filter((item) => item.roleId === 5);
+        } else if (currentRoleId === 4) {
+          // 化验师
+          this.members.analyst = data.filter((item) => item.roleId === 4);
+        }
+      }
+
+      // 更新selectMemberData,合并所有角色的数据
+      this.selectMemberData = [
+        ...this.members.processEngineer,
+        ...this.members.experimenter,
+        ...this.members.analyst,
+      ];
+
+      this.$refs.selectMember.close();
+      // 清理选择数据
+      this.$nextTick(() => {
+        this.$refs.selectMember.setSelection([]);
+      });
+    },
+    memberList(type) {
+      switch (type) {
+        case 3: // 工艺工程师
+          return this.members.processEngineer;
+        case 5: // 实验员
+          return this.members.experimenter;
+        case 4: // 化验师
+          return this.members.analyst;
+        default:
+          return [];
+      }
+    },
     submitForm() {
       this.$refs.form.validate((valid) => {
         if (valid) {
-          console.log("submit!");
+          // 构建提交数据
+          const submitData = {
+            ...this.form,
+            experimentDispatchGroups: this.groupTableData.map((item) => ({
+              groupName: item.groupName,
+              remark: item.remark,
+            })),
+            experimentDispatchTasks: this.taskTableData.map((item) => ({
+              taskName: item.taskName,
+              personCharge: item.leader,
+              startTime: item.startTime,
+            })),
+            experimentDispatchParticipants: [
+              ...this.members.processEngineer.map((userId) => ({
+                userId,
+                roleType: 3, // 工艺工程师
+                status: 1, // 待确认
+              })),
+              ...this.members.experimenter.map((userId) => ({
+                userId,
+                roleType: 5, // 实验员
+                status: 1, // 待确认
+              })),
+              ...this.members.analyst.map((userId) => ({
+                userId,
+                roleType: 4, // 化验师
+                status: 1, // 待确认
+              })),
+            ],
+          };
         }
       });
     },
-    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()
+      this.$refs.addGroupDialog.open();
     },
     handleEditGroup(row) {
-      this.$refs.addGroupDialog.open(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(() => {})
+      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)
+      const index = this.groupTableData.findIndex(
+        (item) => item.id === form.id
+      );
+      console.log('groupTableData',this.groupTableData,'form',form)
       if (index > -1) {
-        this.groupTableData.splice(index, 1, form)
+        this.groupTableData.splice(index, 1, form);
       } else {
-        this.groupTableData.push(form)
+        this.groupTableData.push(form);
       }
+      // 更新表单数据
+      this.form.experimentDispatchGroups = this.groupTableData;
     },
     handleAddTask() {
-      this.$refs.addTaskDialog.open()
+      // 获取所有参与人员数据
+      const allParticipants = [
+        ...this.members.processEngineer,
+        ...this.members.experimenter,
+        ...this.members.analyst,
+      ];
+      this.$refs.addTaskDialog.open(null, allParticipants);
     },
     handleEditTask(row) {
-      this.$refs.addTaskDialog.open(row)
+      // 获取所有参与人员数据
+      const allParticipants = [
+        ...this.members.processEngineer,
+        ...this.members.experimenter,
+        ...this.members.analyst,
+      ];
+      this.$refs.addTaskDialog.open(row, allParticipants);
     },
     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(() => {})
+      this.$confirm("确认删除该任务吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          const index = this.allTaskTableData.findIndex((item) => item === row);
+          if (index > -1) {
+            this.allTaskTableData.splice(index, 1);
+            // 删除后判断是否需要跳页
+            const maxPage =
+              Math.ceil(this.allTaskTableData.length / this.taskPageSize) || 1;
+            if (this.taskPageNum > maxPage) {
+              this.taskPageNum = maxPage;
+            }
+            this.updateTaskTableData();
+            this.$message.success("删除成功");
+          }
+        })
+        .catch(() => {});
     },
     handleTaskSubmit(form) {
-      const index = this.taskTableData.findIndex(item => item.taskName === form.taskName)
+      const index = this.allTaskTableData.findIndex(
+        (item) => item.taskName === form.taskName
+      );
+      const taskData = {
+        id: form.id || "",
+        taskName: form.taskName,
+        personCharge: form.leader,
+        startTime: form.startTime,
+        dispatchId: this.id || "",
+        selectedUsers: form.selectedUsers,
+      };
       if (index > -1) {
-        this.taskTableData.splice(index, 1, form)
+        this.allTaskTableData.splice(index, 1, taskData);
       } else {
-        this.taskTableData.push(form)
+        this.allTaskTableData.push(taskData);
+        this.taskPageNum = 1; // 新增后回到第一页
       }
+      this.updateTaskTableData();
+      // 更新表单数据
+      this.form.experimentDispatchTasks = this.allTaskTableData;
+    },
+    // 获取所有编辑器的内容
+    getAllEditorContent() {
+      return {
+        keyNodes: this.$refs.keyNodesEditor.getContent(),
+      };
+    },
+    // 统一处理方法
+    handleSubmit(type) {
+      this.$refs.form.validate((valid) => {
+        if (valid) {
+          // 获取所有编辑器内容
+          const editorContents = this.getAllEditorContent();
+
+          // 检查编辑器内容是否为空
+          const isEmptyContent = (content) => {
+            return (
+              !content || content === "<p></p>" || content.trim() === "<p></p>"
+            );
+          };
+
+          if (isEmptyContent(editorContents.keyNodes)) {
+            this.$message.warning("请填写关键节点");
+            return false;
+          }
+
+          // 构建提交数据
+          const formData = {
+            ...this.form,
+            keyNodes: editorContents.keyNodes,
+            // 移除不需要传递给后端的字段
+            projectStage: undefined,
+            experimentDispatchGroups: this.groupTableData.map((item) => ({
+              groupName: item.groupName,
+              remark: item.remark,
+              dispatchId: this.id || "",
+              id: item.id || "",
+            })),
+            experimentDispatchTasks: this.taskTableData.map((item) => ({
+              taskName: item.taskName,
+              personCharge: item.personCharge,
+              startTime: item.startTime,
+              dispatchId: this.id || "",
+              id: item.id || "",
+            })),
+            experimentDispatchParticipants: [
+              ...this.members.processEngineer.map((user) => ({
+                userId: user.userId,
+                roleType: 3, // 工艺工程师
+                status: 1, // 待确认
+                dispatchId: this.id || "",
+                id: user.id || "",
+                nickName: user.nickName,
+                avatar: user.avatar,
+              })),
+              ...this.members.experimenter.map((user) => ({
+                userId: user.userId,
+                roleType: 5, // 实验员
+                status: 1, // 待确认
+                dispatchId: this.id || "",
+                id: user.id || "",
+                nickName: user.nickName,
+                avatar: user.avatar,
+              })),
+              ...this.members.analyst.map((user) => ({
+                userId: user.userId,
+                roleType: 4, // 化验师
+                status: 1, // 待确认
+                dispatchId: this.id || "",
+                id: user.id || "",
+                nickName: user.nickName,
+                avatar: user.avatar,
+              })),
+            ],
+            status: type === "draft" ? -1 : 1, // 草稿箱:-1, 待确认:1
+            experimentStartTime: this.form.experimentTime
+              ? this.form.experimentTime[0]
+              : "",
+            experimentEndTime: this.form.experimentTime
+              ? this.form.experimentTime[1]
+              : "",
+          };
+
+          if (this.id) {
+            formData.id = this.id;
+          }
+
+          const request = this.id ? updateDispatch : addDispatch;
+
+          request(formData)
+            .then((res) => {
+              if (res.code === 200) {
+                const successMsg =
+                  type === "draft"
+                    ? "草稿保存成功"
+                    : this.id
+                    ? "更新成功"
+                    : "保存成功";
+                this.$message.success(successMsg);
+                this.$router.back();
+                this.$store.commit(
+                  "SET_TAGLIST",
+                  this.tagList.filter((item) => item.path !== this.$route.path)
+                );
+              } else {
+                const errorMsg =
+                  type === "draft"
+                    ? "草稿保存失败"
+                    : this.id
+                    ? "更新失败"
+                    : "保存失败";
+                this.$message.error(res.msg || errorMsg);
+              }
+            })
+            .catch((err) => {
+              console.error("接口错误:", err);
+              const errorMsg =
+                type === "draft"
+                  ? "草稿保存失败"
+                  : this.id
+                  ? "更新失败"
+                  : "保存失败";
+              this.$message.error(errorMsg);
+            });
+        } else {
+          this.$message.warning("请填写必填项");
+          return false;
+        }
+      });
+    },
+
+    // 保存
+    sendDispatch() {
+      this.handleSubmit("save");
+    },
+
+    // 保存草稿
+    saveDraft() {
+      this.handleSubmit("draft");
+    },
+    handleDateChange(value) {
+      // 处理日期变化后的逻辑
+    },
+    handleTimeRangeChange(value) {
+      if (value) {
+        this.form.experimentStartTime = value[0];
+        this.form.experimentEndTime = value[1];
+      } else {
+        this.form.experimentStartTime = "";
+        this.form.experimentEndTime = "";
+      }
+    },
+    // 统一的搜索方法
+    async handleProjectSearch(query) {
+      if (query) {
+        this.projectLoading = true;
+        try {
+          // 根据当前激活的输入框决定使用哪个参数
+          const params = {};
+          if (
+            this.$refs.projectNameSelect &&
+            this.$refs.projectNameSelect.$el.contains(document.activeElement)
+          ) {
+            params.projectName = query;
+          } else if (
+            this.$refs.proposalIdSelect &&
+            this.$refs.proposalIdSelect.$el.contains(document.activeElement)
+          ) {
+            params.projectCode = query;
+          }
+
+          const res = await getProposalList(params);
+          if (res) {
+            this.projectOptions = res.map((item) => ({
+              id: item.id,
+              projectName: item.projectName,
+              projectCode: item.projectCode,
+              projectStage: item.projectStage,
+            }));
+            // 更新缓存
+            this.projectOptions.forEach((item) => {
+              this.projectDataMap.set(item.id, item);
+            });
+          }
+        } catch (error) {
+          // console.error("获取方案列表失败:", error);
+          // this.$message.error("获取方案列表失败");
+        } finally {
+          this.projectLoading = false;
+        }
+      } else {
+        this.projectOptions = [];
+      }
+    },
+
+    // 方案名称选择变化
+    handleProjectNameChange(value) {
+      const selectedProject = this.projectOptions.find(
+        (item) => item.id === value
+      );
+      if (selectedProject) {
+        this.updateFormWithProject(selectedProject);
+      }
+    },
+
+    // 方案编号选择变化
+    handleProposalIdChange(value) {
+      const selectedProject = this.projectOptions.find(
+        (item) => item.id === value
+      );
+      if (selectedProject) {
+        this.updateFormWithProject(selectedProject);
+      }
+    },
+
+    // 统一的表单更新方法
+    updateFormWithProject(project) {
+      this.form.projectName = project.projectName;
+      this.form.proposalId = project.id;
+      this.form.projectStage = project.projectStage;
+    },
+
+    // 防抖处理
+    debounce(fn, delay) {
+      let timer = null;
+      return function (...args) {
+        if (timer) clearTimeout(timer);
+        timer = setTimeout(() => {
+          fn.apply(this, args);
+        }, delay);
+      };
+    },
+
+    // 获取详情
+    getDetail() {
+      if (this.id) {
+        getDetailById({ id: this.id })
+          .then((res) => {
+            if (res) {
+              const data = res;
+              // 设置表单数据
+              this.form = {
+                projectName: data.projectName,
+                proposalId: data.proposalId,
+                projectStage: data.projectStage,
+                experimentName: data.experimentName,
+                experimentCode: data.experimentCode,
+                experimentDate: data.experimentDate,
+                experimentTime: [
+                  data.experimentStartTime,
+                  data.experimentEndTime,
+                ],
+                status: data.status,
+                experimentDispatchGroups: data.experimentDispatchGroups || [],
+                experimentDispatchParticipants:
+                  data.experimentDispatchParticipants || [],
+                experimentDispatchTasks: data.experimentDispatchTasks || [],
+                keyNodes: data.keyNodes || "",
+              };
+              // 设置表格数据
+              this.groupTableData = data.experimentDispatchGroups || [];
+              this.allTaskTableData = data.experimentDispatchTasks || [];
+              this.updateTaskTableData();
+
+              // 处理参与人员数据
+              this.members = {
+                processEngineer:
+                  data.experimentDispatchParticipants.filter(
+                    (p) => p.roleType === 3
+                  ) || [],
+                experimenter:
+                  data.experimentDispatchParticipants.filter(
+                    (p) => p.roleType === 5
+                  ) || [],
+                analyst:
+                  data.experimentDispatchParticipants.filter(
+                    (p) => p.roleType === 4
+                  ) || [],
+              };
+
+              // 更新selectMemberData
+              this.selectMemberData = [
+                ...this.members.processEngineer,
+                ...this.members.experimenter,
+                ...this.members.analyst,
+              ];
+            }
+          })
+          .catch((err) => {
+            console.error("获取详情失败:", err);
+          });
+      }
+    },
+
+    // 处理项目选择框获得焦点
+    async handleProjectFocus() {
+      // 如果已经有数据,则不重复请求
+      if (this.projectOptions.length > 0) {
+        return;
+      }
+      this.projectLoading = true;
+      try {
+        const res = await getProposalList({});
+        if (res) {
+          this.projectOptions = res.map((item) => ({
+            id: item.id,
+            projectName: item.projectName,
+            projectCode: item.projectCode,
+            projectStage: item.projectStage,
+          }));
+          // 更新缓存
+          this.projectOptions.forEach((item) => {
+            this.projectDataMap.set(item.id, item);
+          });
+        }
+      } catch (error) {
+        // console.error("获取方案列表失败:", error);
+        // this.$message.error("获取方案列表失败");
+      } finally {
+        this.projectLoading = false;
+      }
+    },
+    updateTaskTableData() {
+      const start = (this.taskPageNum - 1) * this.taskPageSize;
+      const end = this.taskPageNum * this.taskPageSize;
+      this.taskTableData = this.allTaskTableData.slice(start, end);
+    },
+    handleCurrentChange(page) {
+      this.taskPageNum = page;
+      this.updateTaskTableData();
+    },
+  },
+  created() {
+    // 从路由参数中获取id
+    this.id = this.$route.query.id;
+    if (this.id) {
+      // TODO: 获取详情
+      this.getDetail();
     }
+    // 创建防抖的搜索方法
+    this.debouncedSearch = this.debounce(this.handleProjectSearch, 300);
+    // 初始化时自动添加当前用户为工艺工程师(如果是工艺工程师角色)
+    const currentUser = this.getCurrentUser();
+    if (currentUser) {
+      this.members.processEngineer = [
+        {
+          userId: currentUser.userId,
+          nickName: currentUser.nickName,
+          avatar: currentUser.avatar,
+          roleId: 3,
+          roleName: "工艺工程师",
+        },
+      ];
+      // 同时更新selectMemberData
+      this.selectMemberData = [...this.members.processEngineer];
+    }
+    this.updateTaskTableData(); // 初始化时同步一次
   },
 };
 </script>
 
 <style scoped lang="less">
+.data-test {
+  .el-input__inner {
+    background-color: #f5f7fa;
+    padding-left: 20px !important;
+  }
+}
 .el-form--inline .el-form-item {
   margin-right: 83px;
 }
@@ -492,11 +1206,9 @@
 
 .add-project-footer {
   margin-top: 43px;
-
   button {
     width: 220px;
   }
-
   .save-btn {
     margin-right: 20px;
   }

--
Gitblit v1.7.1