董国庆
2025-07-25 0c9660562a03191d44fc779a889d3da0dc624b6d
laboratory/src/views/dataManagement/dispatching/editDispatch.vue
@@ -3,7 +3,9 @@
    <el-dialog
      :title="dialogTitle"
      :visible.sync="visible"
      width="80%"
      width="90%"
      @open='open'
      top="5vh"
      :close-on-click-modal="false"
      @close="handleClose"
    >
@@ -27,14 +29,30 @@
                  </div>
                </div>
                <div style="padding-left: 25px">
                  <el-form-item prop="planName" label="项目课题方案名称">
                    <el-input v-model="form.planName" placeholder="请输入" />
                  <el-form-item prop="projectName" label="项目课题方案名称">
                    <el-input
                      v-model="form.projectName"
                      placeholder="请输入"
                      :disabled="true"
                    />
                  </el-form-item>
                  <el-form-item prop="planCode" label="项目课题方案编号">
                    <el-input v-model="form.planCode" placeholder="请输入" />
                  <el-form-item prop="projectCode" label="项目课题方案编号">
                    <el-input
                      v-model="form.projectCode"
                      placeholder="请输入"
                      :disabled="true"
                    />
                  </el-form-item>
                  <el-form-item prop="stage" label="项目阶段">
                    <el-input v-model="form.stage" 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>
@@ -45,19 +63,30 @@
                  </div>
                </div>
                <div style="padding-left: 25px">
                  <el-form-item prop="testDate" label="试验日期">
                  <el-form-item prop="experimentDate" label="实验日期">
                    <el-date-picker
                      v-model="form.testDate"
                      name="data-test"
                      style="width: 100%"
                      v-model="form.experimentDate"
                      type="date"
                      placeholder="选择日期"
                      value-format="yyyy-MM-dd"
                      :disabled="true"
                    ></el-date-picker>
                  </el-form-item>
                  <el-form-item prop="experimentName" label="实验名称">
                    <el-input
                      v-model="form.experimentName"
                      placeholder="请输入"
                      :disabled="true"
                    />
                  </el-form-item>
                  <el-form-item prop="testName" label="实验名称">
                    <el-input v-model="form.testName" placeholder="请输入" />
                  </el-form-item>
                  <el-form-item prop="testCode" label="实验编号">
                    <el-input v-model="form.testCode" placeholder="请输入" />
                  <el-form-item prop="experimentCode" label="实验编号">
                    <el-input
                      v-model="form.experimentCode"
                      placeholder="请输入"
                      :disabled="true"
                    />
                  </el-form-item>
                </div>
@@ -89,50 +118,48 @@
                  </div>
                </div>
                <div style="padding-left: 25px">
                  <el-form-item prop="testTime" label="试验时间">
                  <el-form-item prop="experimentTime" label="试验时间">
                    <el-date-picker
                      v-model="form.testTime"
                      type="datetime"
                      placeholder="选择日期时间"
                      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']"
                      :disabled="true"
                    ></el-date-picker>
                  </el-form-item>
                </div>
                <div class="add-group">
                  <div>*</div>
                  <span>参加人员</span>
                </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 || item == 3
                            ? 'member-name-box'
                            : 'flex1'
                        "
                      >
                      <div :class="item == 3 ? 'member-name-box' : 'flex1'">
                        <div
                          :class="
                            item == 1 || item == 2 || item == 3
                              ? 'member-name-box'
                              : 'member-name-box-2'
                            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" v-if="type !== 'view'">
                        <div class="member-change-btn">修改</div>
                      </div>
                    </div>
                  </div>
@@ -161,7 +188,7 @@
                    label="任务名称"
                  ></el-table-column>
                  <el-table-column
                    prop="leader"
                    prop="personCharge"
                    label="负责人"
                  ></el-table-column>
                  <el-table-column
@@ -176,6 +203,14 @@
                    <span>五 、关键节点</span>
                  </div>
                </div>
                <div style="padding-left: 25px">
                  <AIEditor
                    ref="keyNodesEditor"
                    :readOnly="true"
                    :value="form.keyNodes"
                    height="200"
                  />
                </div>
              </el-form>
            </template>
          </Card>
@@ -183,13 +218,7 @@
        <!-- 右侧审批流程 -->
        <div class="approval-flow" v-if="type === 'view'">
          <div class="flow-content">
            <approval-process
              mode="card"
              :status="form.status"
              :submit-time="form.createTime"
              :approver="form.approver"
              :approve-time="form.approveTime"
            />
            <approval-process :processData="form.processData" />
          </div>
        </div>
      </div>
@@ -208,7 +237,7 @@
        <img
          v-if="imgSrc"
          style="width: 200px; height: 100px; margin-left: 25px"
          :src="imgSrc"
          :src="getFullUrl(imgSrc)"
          fit="fit"
        />
      </div>
@@ -225,6 +254,7 @@
    <SignatureCanvas
      :visible="signatureDialogVisible"
      @confirm="handleSignatureConfirm"
      @close="signatureDialogVisible = false"
    />
  </div>
</template>
@@ -232,12 +262,17 @@
<script>
import ApprovalProcess from "@/components/approvalProcess";
import SignatureCanvas from "@/components/SignatureCanvas.vue";
import AIEditor from "@/components/AiEditor";
import { getDetailById, sign } from "./service";
import {queryDetail} from '@/components/service.js'
import {getFullUrl} from '@/utils/utils.js'
export default {
  name: "ApprovalDialog",
  components: {
    ApprovalProcess,
    SignatureCanvas,
    AIEditor,
  },
  props: {
    visible: {
@@ -256,55 +291,57 @@
  data() {
    return {
      form: {
        planName: "",
        planCode: "",
        stage: "",
        testDate: "",
        testName: "",
        testCode: "",
        testTime: "",
        creator: "",
        createTime: "",
        approvalComment: "",
        status: "approved",
        approver: "",
        approveTime: "",
        projectName: "",
        projectCode: "",
        projectStage: "",
        experimentName: "",
        experimentCode: "",
        experimentDate: "",
        experimentTime: [],
        status: "",
        experimentDispatchGroups: [],
        experimentDispatchParticipants: [],
        experimentDispatchTasks: [],
        keyNodes: "",
        processData: [],
      },
      rules: {
        planName: [
        projectName: [
          {
            required: true,
            message: "请输入项目课题方案名称",
            trigger: "blur",
          },
        ],
        planCode: [
        projectCode: [
          {
            required: true,
            message: "请输入项目课题方案编号",
            trigger: "blur",
          },
        ],
        stage: [{ required: true, message: "请输入项目阶段", trigger: "blur" }],
        testDate: [
          { required: true, message: "请选择试验日期", trigger: "change" },
        ],
        testName: [
        experimentName: [
          { required: true, message: "请输入实验名称", trigger: "blur" },
        ],
        testCode: [
        experimentCode: [
          { required: true, message: "请输入实验编号", trigger: "blur" },
        ],
        testTime: [
          { required: true, message: "请选择试验时间", trigger: "change" },
        experimentDate: [
          { required: true, message: "请选择实验日期", trigger: "change" },
        ],
        experimentTime: [
          { required: true, message: "请选择实验时间范围", trigger: "change" },
        ],
      },
      imgSrc: "",
      signatureDialogVisible: false,
      status: "1",
      remark: "",
      groupTableData: [],
      taskTableData: [],
      members: {
        processEngineer: [], // 工艺工程师
        experimenter: [], // 实验员
        analyst: [], // 化验师
      },
    };
  },
  computed: {
@@ -316,75 +353,168 @@
    data: {
      handler(val) {
        if (val) {
          this.form = { ...val };
          this.getDetail(val.id);
        }
      },
      immediate: true,
    },
  },
  methods: {
    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];
    getFullUrl,
    open(){
      queryDetail().then(res=>{
        if(res){
          this.imgSrc=res.signPicture
        }
      })
    },
    // 获取详情
    getDetail(id) {
      getDetailById({ id })
        .then((res) => {
          if (res) {
            const data = res;
            // 设置表单数据
            this.form = {
              projectName: data.projectName,
              projectCode: data.projectCode,
              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,
              processData: [],
            };
            // 设置表格数据
            this.groupTableData = data.experimentDispatchGroups || [];
            this.taskTableData = data.experimentDispatchTasks || [];
            // 处理参与人员数据
            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
                ) || [],
            };
            // 组装流程数据
            let processData = [];
            // 提交节点
            processData.push({
              type: "primary",
              mode: "list",
              fields: [
                { label: "提交人:", value: data.createBy || "" },
                { label: "提交时间:", value: data.createTime || "" },
              ],
            });
            // 处理参与人员数据,按角色分类
            const participants = data.experimentDispatchParticipants || [];
            const analyst = participants.filter((p) => p.roleType === 4); // 化验师
            const experimenter = participants.filter((p) => p.roleType === 5); // 实验员
            // 添加确认节点
            processData.push({
              type: "success",
              mode: "card",
              groups: [
                {
                  title: "化验师",
                  members: analyst.map((item) => ({
                    name: item.nickName || "",
                    status: item.status === 2 ? "已确认" : "待确认",
                    approveTime: item.status === 2 ? item.signTime : "",
                    avatar: item.avatar,
                  })),
                },
                {
                  title: "实验员",
                  members: experimenter.map((item) => ({
                    name: item.nickName || "",
                    status: item.status === 2 ? "已确认" : "待确认",
                    approveTime: item.status === 2 ? item.signTime : "",
                    avatar: item.avatar,
                  })),
                },
              ],
            });
            this.form.processData = processData;
          }
        })
        .catch((err) => {
          // console.error("获取详情失败:", err);
          // this.$message.error("获取详情失败");
        });
    },
    memberList(type) {
      switch (type) {
        case 3: // 工艺工程师
          return this.members.processEngineer;
        case 5: // 实验员
          return this.members.experimenter;
        case 4: // 化验师
          return this.members.analyst;
        default:
          break;
          return [];
      }
    },
    handleClose() {
      this.$emit("update:visible", false);
      this.form.approvalComment = "";
      this.$emit("close", false);
      this.$emit("update:data", {}); // 触发事件通知父组件更新data
      this.signatureDialogVisible = false;
      this.imgSrc = '';
    },
    handleApprove() {
      if (!this.form.approvalComment) {
        this.$message.warning("请输入审批意见");
        return;
      if(!this.imgSrc){
        this.$message.error('请先签字在提交');
        return
      }
      this.$emit("approve", {
        ...this.form,
        status: "approved",
      // 组装签名数据
      const params = {
        dispatchId: this.data.id, // 传递当前调度id
        confirmSign: this.imgSrc, // 签名图片
      };
      sign(params).then(res => {
        if (res && res.code === 200) {
          this.$message.success('签字成功');
          this.handleClose();
          this.$emit('update:data')
        } else {
          this.$message.error(res.msg || '签字失败');
        }
      }).catch(() => {
        // this.$message.error('签字失败');
      });
    },
    handleReject() {
      if (!this.form.approvalComment) {
        this.$message.warning("请输入审批意见");
        return;
      }
      this.$emit("reject", {
        ...this.form,
        status: "rejected",
      });
    },
    memberList(item) {
      return item === 1 ? 2 : item === 2 ? 3 : 1;
    },
    openSignature() {
      this.signatureDialogVisible = true;
    },
    handleSignatureConfirm(imageData) {
      console.log("imageData imageData", imageData);
      this.signatureDialogVisible = false;
      this.imgSrc = imageData;
      // 这里处理签名确认后的逻辑
      // this.$confirm('确认该实验调度吗?', '提示', {
      //   confirmButtonText: '确定',
      //   cancelButtonText: '取消',
      //   type: 'warning'
      // }).then(() => {
      //   // 这里可以将签名图片数据(imageData)连同其他数据一起提交到后端
      //   this.$message.success('确认成功');
      //   this.signatureDialogVisible = false;
      //   this.getTableData();
      // }).catch(() => {
      //   this.signatureDialogVisible = false;
      // });
      this.imgSrc = ""; // 先清空
      this.$nextTick(() => {
        this.imgSrc = imageData;
      });
    },
  },
};
@@ -397,7 +527,7 @@
.approval-dialog {
  display: flex;
  height: 60vh;
  height: 70vh;
  .approval-content {
    flex: 1;
@@ -408,8 +538,8 @@
  }
  .approval-flow {
    padding: 40px 20px;
    width: 405px;
    padding: 20px 0px;
    width: 305px;
    background: #ffffff;
    box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08);
    border-radius: 10px;
@@ -432,11 +562,11 @@
  }
}
.approval-dialog-approve {
  margin-top: 26px;
  margin-top: 18px;
}
.approval-content-card {
  height: calc(100% - 100px) !important;
  height: calc(100% - 10px) !important;
  box-shadow: none !important;
}
@@ -488,6 +618,7 @@
}
.header-title:first-child {
  margin-top: 0;
  .header-title-left {
    margin-top: 0;
  }