董国庆
9 天以前 095fc5a71d094deccd5c5aecf79517ac01c0e598
laboratory/src/views/dataManagement/confirmation-sheet/components/review-dialog.vue
@@ -1,11 +1,6 @@
<template>
  <el-dialog
    title="审核检测方法确认单"
    :visible.sync="visible"
    width="80%"
    :close-on-click-modal="false"
    @close="handleClose"
  >
  <el-dialog title="审核检测方法确认单" :visible="dialogVisible" width="80%" :close-on-click-modal="false" @close="handleClose"
    v-loading="loading">
    <div class="approval-dialog">
      <div class="approval-content">
        <div class="approval-content-card">
@@ -14,39 +9,46 @@
            <div class="basic-info">
              <div class="info-header">
                <div class="info-item">
                  <span class="label">所属项目课题方案:{{ formData.planName }}</span>
                  <span class="label">所属项目课题方案:{{ formData.projectName }}</span>
                </div>
                <div class="info-item">
                  <span class="label">实验名称:{{ formData.testName }}</span>
                  <span class="label">实验名称:{{ formData.experimentName }}</span>
                </div>
                <div class="info-item">
                  <span class="label">所属实验编号:{{ formData.testCode }}</span>
                  <span class="label">所属实验编号:{{ formData.experimentCode }}</span>
                </div>
              </div>
              <div class="info-header">
                <div class="info-item">
                  <span class="label">提交人:{{ formData.submitter }}</span>
                  <span class="label">提交人:{{ formData.createBy }}</span>
                </div>
                <div class="info-item">
                  <span class="label">提交人签名:{{ formData.submitterSignature }}</span>
                  <span class="label">提交人签名:</span>
                  <el-image style="width: 50px; height: 50px" v-if="formData.confirmSign" :src="formData.confirmSign"
                    :preview-src-list="[formData.confirmSign]">
                  </el-image>
                </div>
                <div class="info-item">
                  <span class="label">提交时间:{{ formData.submitTime }}</span>
                  <span class="label">提交时间:{{ formData.signTime }}</span>
                </div>
              </div>
            </div>
            <!-- 检测项表格 -->
            <div class="table-wrapper">
              <Table :tableData="sampleData" :total="0" :height="null">
              <Table :data="formData.testMethodConfirmSheetTerms" :total="0" :height="null">
                <template>
                  <el-table-column prop="index" label="序号" width="60" fixed></el-table-column>
                  <el-table-column prop="processTime" label="检验项名称"></el-table-column>
                  <el-table-column prop="sampleName" label="检验项编号"></el-table-column>
                  <el-table-column prop="sampleCode" label="定性/定量"></el-table-column>
                  <el-table-column prop="temperature" label="检测方法编号"></el-table-column>
                  <el-table-column prop="ph" label="检测方法"></el-table-column>
                  <el-table-column prop="waterAmount" label="收样要求"></el-table-column>
                  <el-table-column type="index" label="序号" width="60" fixed></el-table-column>
                  <el-table-column prop="termName" label="检验项名称"></el-table-column>
                  <el-table-column prop="termCode" label="检验项编号"></el-table-column>
                  <el-table-column prop="termType" label="定性/定量">
                    <template slot-scope="scope">
                      {{ scope.row.termType === 1 ? '定性' : '定量' }}
                    </template>
                  </el-table-column>
                  <el-table-column prop="termMethodCode" label="检测方法编号"></el-table-column>
                  <el-table-column prop="termMethod" label="检测方法"></el-table-column>
                  <el-table-column prop="sampleRequire" label="收样要求"></el-table-column>
                </template>
              </Table>
            </div>
@@ -56,12 +58,7 @@
      <div class="approval-flow">
        <div class="flow-content">
          <approval-process
            :status="formData.status"
            :submit-time="formData.submitTime"
            :approver="formData.approver"
            :approve-time="formData.approveTime"
          />
          <approval-process :processData="formData.processData" />
        </div>
      </div>
    </div>
@@ -72,29 +69,22 @@
        <span>签字确认</span>
        <el-button type="primary" class="el-icon-plus" @click="openSignature">签名</el-button>
      </div>
      <img
        v-if="imgSrc"
        :src="imgSrc"
        alt="签名"
        class="signature-preview"
      />
      <img v-if="imgSrc" :src="imgSrc" alt="签名" class="signature-preview" />
    </div>
    <div slot="footer" class="dialog-footer">
      <el-button @click="handleClose">取 消</el-button>
      <el-button type="primary" @click="handleConfirm" :disabled="!imgSrc">确 认</el-button>
      <el-button type="primary" @click="handleConfirm" :disabled="!imgSrc" v-if="type === 'review'">确 认</el-button>
    </div>
    <SignatureCanvas
      :visible="signatureDialogVisible"
      @confirm="handleSignatureConfirm"
    />
    <SignatureCanvas :visible="signatureDialogVisible" @confirm="handleSignatureConfirm" />
  </el-dialog>
</template>
<script>
import SignatureCanvas from "@/components/SignatureCanvas.vue";
import ApprovalProcess from "@/components/approvalProcess";
import { getDetail, sign } from '../service';
export default {
  name: "ReviewDialog",
@@ -111,63 +101,149 @@
      type: String,
      default: "review",
    },
    formData: {
      type: Object,
      default: () => ({
        planName: '',
        testCode: '',
        testName: '',
        submitter: '',
        submitterSignature: '',
        submitTime: '',
        status: '',
        approver: '',
        approveTime: ''
      }),
    },
    sampleData: {
      type: Array,
      default: () => [],
    },
    id: {
      type: String,
      default: '',
    }
  },
  data() {
    return {
      dialogVisible: false,
      signatureDialogVisible: false,
      imgSrc: "",
      formData: {
        projectName: '',
        experimentCode: '',
        experimentName: '',
        auditPersonId: '',
        auditSign: '',
        auditStatus: '',
        auditTime: '',
        confirmSign: '',
        dispatchId: '',
        signTime: '',
        testMethodConfirmSheetTerms: [],
        processData: []
      },
      loading: false
    };
  },
  watch: {
    visible(val) {
      this.dialogVisible = val;
      if (val && this.id) {
        this.getDetailData();
      }
    }
  },
  methods: {
    async getDetailData() {
      try {
        this.loading = true;
        const res = await getDetail({ id: this.id });
        console.log('res', res)
        if (res) {
          this.formData = res
          // 组装流程数据
          let processData = [];
          // 提交节点
          processData.push({
            type: "primary",
            mode: "list",
            fields: [
              { label: "提交人:", value: res.createBy || "" },
              { label: ' ', value: res.confirmSign || "", type: 'img' },
              { label: "提交时间:", value: res.createTime || "" },
            ],
          });
          if (res.auditStatus == 2) {
            processData.push({
              type: "primary",
              mode: "list",
              fields: [
                { label: "审核人:", value: res.auditPersonName || "" },
                { label: ' ', value: res.auditSign || "", type: 'img' },
                { label: "审核时间:", value: res.auditTime || "" },
              ],
            });
          } else if (res.auditStatus == 1) {
            processData.push({
              type: "warning",
              mode: "list",
              fields: [
                { label: "等待审核" },
              ],
            });
          }
          this.formData.processData = processData
        } else {
          this.$message.error(res.msg || '获取详情失败');
        }
      } catch (error) {
        console.error('获取详情失败:', error);
        this.$message.error('获取详情失败');
      } finally {
        this.loading = false;
      }
    },
    handleClose() {
      this.$emit("update:visible", false);
      this.dialogVisible = false;
      this.$emit("close", false);
      this.imgSrc = "";
      this.formData = {
        projectName: '',
        experimentCode: '',
        experimentName: '',
        auditPersonId: '',
        auditSign: '',
        auditStatus: '',
        auditTime: '',
        confirmSign: '',
        dispatchId: '',
        signTime: '',
        testMethodConfirmSheetTerms: [],
        processData: []
      };
    },
    openSignature() {
      this.signatureDialogVisible = true;
    },
    handleSignatureConfirm(imageData) {
      this.signatureDialogVisible = false;
      this.imgSrc = imageData;
      this.imgSrc = 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg';
    },
    handleConfirm() {
      if (!this.imgSrc) {
        this.$message.warning("请先完成签名确认");
        return;
      }
      this.$emit("confirm", this.imgSrc);
      this.handleClose();
      // 组装签名数据
      const params = {
        testMethodConfirmSheetId: this.id, // 传递当前确认单id
        confirmSign: this.imgSrc, // 签名图片
      };
      sign(params).then(res => {
        if (res && res.code === 200) {
          this.$message.success('签字成功');
          this.handleClose();
        } else {
          this.$message.error(res.msg || '签字失败');
        }
      }).catch(() => {
        this.$message.error('签字失败');
      });
    },
  },
};
</script>
<style lang="less" scoped>
.approval-dialog {
  display: flex;
  min-height: 60vh;
  max-height: 80vh;
  overflow: hidden;
  @media screen and (max-width: 1024px) {
    flex-direction: column;
  }
@@ -176,7 +252,7 @@
    flex: 1;
    margin: 20px;
    background: #ffffff;
    box-shadow: 0px 4px 12px 4px rgba(0,0,0,0.08);
    box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08);
    border-radius: 10px;
    overflow-y: auto;
@@ -190,11 +266,12 @@
  .approval-flow {
    width: 405px;
    background: #ffffff;
    box-shadow: 0px 4px 12px 4px rgba(0,0,0,0.08);
    box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08);
    border-radius: 10px;
    padding: 40px 20px;
    margin: 20px;
    margin-left: 0;
    @media screen and (max-width: 1024px) {
      width: 100%;
      padding: 20px;
@@ -209,7 +286,7 @@
.basic-info {
  padding: 28px 20px;
  background: linear-gradient( 180deg, #05A0C1 0%, #05F2C2 100%);
  background: linear-gradient(180deg, #05A0C1 0%, #05F2C2 100%);
  border-radius: 10px 10px 0 0;
  color: #fff;
@@ -231,6 +308,7 @@
    .info-item {
      flex: 1;
      min-width: 250px;
      display: flex;
      @media screen and (max-width: 768px) {
        min-width: 100%;
@@ -238,8 +316,8 @@
      .label {
        font-size: 14px;
        white-space: normal;
        word-break: break-all;
        // white-space: normal;
        // word-break: break-all;
      }
    }
  }
@@ -250,6 +328,7 @@
  background: #ffffff;
  border-radius: 4px;
  overflow-x: auto;
  ::v-deep .el-table {
    width: 100%;
    min-width: 800px;
@@ -302,8 +381,10 @@
  height: calc(100% - 100px) !important;
  box-shadow: none !important;
}
::v-deep .el-dialog__body {
  padding: 0;
  @media screen and (max-width: 768px) {
    padding: 15px;
  }
@@ -322,4 +403,12 @@
    line-height: 1.5;
  }
}
</style>
.signature-image {
  max-width: 200px;
  max-height: 100px;
  margin-top: 8px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
}
</style>