pyt
2025-04-23 b30f2d8d7d4239e33109bde8f3ff1bd12fe487d0
feat
3个文件已修改
2个文件已添加
635 ■■■■■ 已修改文件
src/components/showDelConfirm/index.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataManagement/confirmation-sheet/components/add.vue 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataManagement/confirmation-sheet/components/confirm-dialog.vue 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataManagement/confirmation-sheet/components/review-dialog.vue 325 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dataManagement/confirmation-sheet/index.vue 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/showDelConfirm/index.vue
@@ -37,7 +37,7 @@
        },
        okText: {
            type: String,
            default: '确认',
            default: '确定',
        },
        btnType: {
            type: String,
@@ -102,5 +102,6 @@
.dialog-footer {
    display: flex;
    justify-content: end;
    gap: 10px;
}
</style>
src/views/dataManagement/confirmation-sheet/components/add.vue
@@ -38,7 +38,7 @@
      </template>
    </Table>
    <div class="btn_box flex ">
      <el-button type="primary" @click="onSubmit">提交确认单</el-button>
      <el-button type="primary" @click="handleSubmit">提交确认单</el-button>
      <el-button @click="$router.go(-1)">存草稿</el-button>
    </div>
    <experimentalScheduling :show="showScheduling"/>
@@ -47,24 +47,33 @@
      @close="handleTestItemDialogClose"
      @confirm="handleTestItemConfirm"
    />
    <confirm-dialog
      :visible.sync="confirmDialogVisible"
      :formData="confirmFormData"
      :sampleData="testItems"
      @confirm="handleConfirmSubmit"
    />
  </Card>
</template>
<script>
import experimentalScheduling from './experimental-scheduling.vue';
import AddTestItem from './add-test-item.vue'
import ConfirmDialog from './confirm-dialog.vue'
export default {
  name: 'AddConfirmationSheet',
  components: {
    experimentalScheduling,
    AddTestItem
    AddTestItem,
    ConfirmDialog
  },
  props: {},
  data() {
    return {
      showScheduling: false,
      tableData: [],
      testItems: [], // 检测项列表
      total: 0,
      form: {
        roleName: "",
@@ -76,7 +85,14 @@
        ],
      },
      menu: [],
      testItemDialogVisible: false
      testItemDialogVisible: false,
      confirmDialogVisible: false,
      confirmFormData: {
        planName: '', // 项目课题方案名称
        testCode: '', // 实验编号
        testName: '', // 实验名称
        sampleCode: '' // 取样单编号
      },
    };
  },
  computed: {
@@ -225,10 +241,30 @@
      this.testItemDialogVisible = false
    },
    handleTestItemConfirm(formData) {
      console.log('新增检测项数据:', formData)
      // TODO: 处理新增检测项的逻辑
      // 将新增的检测项添加到列表中
      this.testItems.push({
        ...formData,
        index: this.testItems.length + 1
      })
      this.testItemDialogVisible = false
      this.$message.success('添加成功')
    },
    handleSubmit() {
      // 这里可以添加表单验证逻辑
      this.confirmFormData = {
        planName: '项目名称示例',
        testCode: '实验编号示例',
        testName: '实验名称示例',
        sampleCode: '取样单编号示例'
      }
      this.confirmDialogVisible = true
    },
    handleConfirmSubmit(signatureImage) {
      // 处理最终提交逻辑
      console.log('提交确认单,签名图片:', signatureImage)
      // TODO: 调用提交API
      this.$message.success('提交成功')
      this.$router.push('/dataManagement/confirmation-sheet')
    }
  },
};
src/views/dataManagement/confirmation-sheet/components/confirm-dialog.vue
New file
@@ -0,0 +1,215 @@
<template>
  <el-dialog
    title="提交确认"
    :visible.sync="visible"
    width="80%"
    :close-on-click-modal="false"
    @close="handleClose"
    class="submit-confirm-dialog"
  >
    <div class="approval-content">
      <div class="sample-info">
        <div class="info-item" style="width: 100%">
          <span class="label">所属项目课题方案:</span>
          <span class="value">{{ formData.planName }}</span>
        </div>
        <div class="info-item">
          <span class="label">所属实验编号:</span>
          <span class="value">{{ formData.testCode }}</span>
        </div>
        <div class="info-item">
          <span class="label">所属实验名称:</span>
          <span class="value">{{ formData.testName }}</span>
        </div>
      </div>
      <Table :tableData="sampleData" :total="0" :height="null">
        <template>
          <el-table-column prop="index" label="序号" width="60" align="center"></el-table-column>
          <el-table-column prop="testName" label="检测项名称"></el-table-column>
          <el-table-column prop="testCode" label="检测项编号"></el-table-column>
          <el-table-column prop="testType" label="定性/定量" align="center">
            <template slot-scope="scope">
              {{ scope.row.testType === 1 ? '定性' : '定量' }}
            </template>
          </el-table-column>
          <el-table-column prop="methodCode" label="检测方法编号"></el-table-column>
          <el-table-column prop="methodName" label="检测方法"></el-table-column>
          <el-table-column prop="requirements" label="收样要求" show-overflow-tooltip></el-table-column>
        </template>
      </Table>
      <div class="signature-section">
        <div class="signature-header">
          <span class="required">*</span>
          <span class="title">签字确认</span>
          <el-button type="primary" @click="openSignature">签名</el-button>
        </div>
        <div v-if="imgSrc" class="signature-preview">
          <img :src="imgSrc" alt="签名" />
        </div>
      </div>
    </div>
    <div slot="footer" class="dialog-footer">
      <el-button @click="handleClose">取 消</el-button>
      <el-button type="primary" @click="handleConfirm" :disabled="!imgSrc">确 认</el-button>
    </div>
    <SignatureCanvas
      :visible="signatureDialogVisible"
      @close="handleSignatureClose"
      @confirm="handleSignatureConfirm"
    />
  </el-dialog>
</template>
<script>
import SignatureCanvas from "@/components/SignatureCanvas.vue";
export default {
  name: "ConfirmDialog",
  components: {
    SignatureCanvas,
  },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    formData: {
      type: Object,
      default: () => ({
        planName: '',
        planCode: '',
        testCode: '',
        testName: '',
        sampleCode: ''
      }),
    },
    sampleData: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      signatureDialogVisible: false,
      imgSrc: "",
    };
  },
  methods: {
    handleClose() {
      this.$emit("update:visible", false);
      this.imgSrc = "";
    },
    openSignature() {
      this.signatureDialogVisible = true;
    },
    handleSignatureClose() {
      this.signatureDialogVisible = false;
    },
    handleSignatureConfirm(imageData) {
      this.signatureDialogVisible = false;
      this.imgSrc = imageData;
    },
    handleConfirm() {
      if (!this.imgSrc) {
        this.$message.warning("请先完成签名确认");
        return;
      }
      this.$emit("confirm", this.imgSrc);
      this.handleClose();
    },
  },
};
</script>
<style lang="less" scoped>
.submit-confirm-dialog {
  :deep(.el-dialog__header) {
    padding: 15px 20px;
    border-bottom: 1px solid #e4e7ed;
    margin-right: 0;
  }
  :deep(.el-dialog__body) {
    padding: 20px;
  }
}
.approval-content {
  background: #ffffff;
}
.sample-info {
  margin-bottom: 25px;
  display: flex;
  flex-wrap: wrap;
  row-gap: 15px;
  .info-item {
    width: 50%;
    display: flex;
    align-items: center;
    padding-right: 20px;
    box-sizing: border-box;
    .label {
      color: #606266;
      margin-right: 10px;
      white-space: nowrap;
    }
    .value {
      color: #303133;
      font-weight: 500;
    }
  }
}
.signature-section {
  margin-top: 25px;
  padding: 0 20px;
  .signature-header {
    display: flex;
    align-items: center;
    margin-bottom: 15px;
    .required {
      color: #f56c6c;
      margin-right: 5px;
    }
    .title {
      font-size: 14px;
      color: #606266;
      margin-right: 15px;
    }
  }
  .signature-preview {
    img {
      width: 200px;
      height: 100px;
      border: 2px dashed #009688;
      border-radius: 4px;
    }
  }
}
.dialog-footer {
  padding: 15px 20px;
  text-align: center;
  border-top: 1px solid #e4e7ed;
  .el-button {
    width: 120px;
    & + .el-button {
      margin-left: 12px;
    }
  }
}
</style>
src/views/dataManagement/confirmation-sheet/components/review-dialog.vue
New file
@@ -0,0 +1,325 @@
<template>
  <el-dialog
    title="审核检测方法确认单"
    :visible.sync="visible"
    width="80%"
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <div class="approval-dialog">
      <div class="approval-content">
        <div class="approval-content-card">
          <template>
            <!-- 基本信息 -->
            <div class="basic-info">
              <div class="info-header">
                <div class="info-item">
                  <span class="label">所属项目课题方案:{{ formData.planName }}</span>
                </div>
                <div class="info-item">
                  <span class="label">实验名称:{{ formData.testName }}</span>
                </div>
                <div class="info-item">
                  <span class="label">所属实验编号:{{ formData.testCode }}</span>
                </div>
              </div>
              <div class="info-header">
                <div class="info-item">
                  <span class="label">提交人:{{ formData.submitter }}</span>
                </div>
                <div class="info-item">
                  <span class="label">提交人签名:{{ formData.submitterSignature }}</span>
                </div>
                <div class="info-item">
                  <span class="label">提交时间:{{ formData.submitTime }}</span>
                </div>
              </div>
            </div>
            <!-- 检测项表格 -->
            <div class="table-wrapper">
              <Table :tableData="sampleData" :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>
                </template>
              </Table>
            </div>
          </template>
        </div>
      </div>
      <div class="approval-flow">
        <div class="flow-content">
          <approval-process
            :status="formData.status"
            :submit-time="formData.submitTime"
            :approver="formData.approver"
            :approve-time="formData.approveTime"
          />
        </div>
      </div>
    </div>
    <div class="approval-dialog-approve" v-if="type === 'review'">
      <div class="add-group">
        <div class="required">*</div>
        <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"
      />
    </div>
    <div slot="footer" class="dialog-footer">
      <el-button @click="handleClose">取 消</el-button>
      <el-button type="primary" @click="handleConfirm" :disabled="!imgSrc">确 认</el-button>
    </div>
    <SignatureCanvas
      :visible="signatureDialogVisible"
      @confirm="handleSignatureConfirm"
    />
  </el-dialog>
</template>
<script>
import SignatureCanvas from "@/components/SignatureCanvas.vue";
import ApprovalProcess from "@/components/approvalProcess";
export default {
  name: "ReviewDialog",
  components: {
    SignatureCanvas,
    ApprovalProcess
  },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    type: {
      type: String,
      default: "review",
    },
    formData: {
      type: Object,
      default: () => ({
        planName: '',
        testCode: '',
        testName: '',
        submitter: '',
        submitterSignature: '',
        submitTime: '',
        status: '',
        approver: '',
        approveTime: ''
      }),
    },
    sampleData: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      signatureDialogVisible: false,
      imgSrc: "",
    };
  },
  methods: {
    handleClose() {
      this.$emit("update:visible", false);
      this.imgSrc = "";
    },
    openSignature() {
      this.signatureDialogVisible = true;
    },
    handleSignatureConfirm(imageData) {
      this.signatureDialogVisible = false;
      this.imgSrc = imageData;
    },
    handleConfirm() {
      if (!this.imgSrc) {
        this.$message.warning("请先完成签名确认");
        return;
      }
      this.$emit("confirm", this.imgSrc);
      this.handleClose();
    },
  },
};
</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;
  }
  .approval-content {
    flex: 1;
    margin: 20px;
    background: #ffffff;
    box-shadow: 0px 4px 12px 4px rgba(0,0,0,0.08);
    border-radius: 10px;
    overflow-y: auto;
    @media screen and (max-width: 1024px) {
      margin-right: 0;
      margin-bottom: 20px;
      max-height: calc(60vh - 200px);
    }
  }
  .approval-flow {
    width: 405px;
    background: #ffffff;
    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;
    }
    .flow-content {
      height: calc(100% - 40px);
      overflow-y: auto;
    }
  }
}
.basic-info {
  padding: 28px 20px;
  background: linear-gradient( 180deg, #05A0C1 0%, #05F2C2 100%);
  border-radius: 10px 10px 0 0;
  color: #fff;
  .info-header {
    display: flex;
    flex-wrap: wrap;
    margin-bottom: 28px;
    gap: 15px;
    @media screen and (max-width: 768px) {
      flex-direction: column;
      gap: 10px;
    }
    &:last-child {
      margin-bottom: 0;
    }
    .info-item {
      flex: 1;
      min-width: 250px;
      @media screen and (max-width: 768px) {
        min-width: 100%;
      }
      .label {
        font-size: 14px;
        white-space: normal;
        word-break: break-all;
      }
    }
  }
}
.table-wrapper {
  padding: 20px;
  background: #ffffff;
  border-radius: 4px;
  overflow-x: auto;
  ::v-deep .el-table {
    width: 100%;
    min-width: 800px;
  }
}
.approval-dialog-approve {
  margin-top: 26px;
  padding: 0 20px;
  .add-group {
    display: flex;
    align-items: center;
    margin-bottom: 15px;
    .required {
      color: #f56c6c;
      margin-right: 4px;
    }
    span {
      margin-right: 15px;
      font-size: 14px;
      color: #303133;
    }
  }
  .signature-preview {
    width: 200px;
    height: 100px;
    border: 2px dashed #049c9a;
    border-radius: 4px;
    object-fit: contain;
  }
}
.dialog-footer {
  display: flex;
  justify-content: center;
  align-items: center;
  padding-top: 20px;
  .el-button {
    width: 150px;
    margin: 0 10px;
  }
}
.approval-content-card {
  height: calc(100% - 100px) !important;
  box-shadow: none !important;
}
::v-deep .el-dialog__body {
  padding: 0;
  @media screen and (max-width: 768px) {
    padding: 15px;
  }
}
::v-deep .el-dialog {
  @media screen and (max-width: 1024px) {
    width: 95% !important;
    margin-top: 20px !important;
  }
}
::v-deep .el-table {
  .cell {
    white-space: normal;
    line-height: 1.5;
  }
}
</style>
src/views/dataManagement/confirmation-sheet/index.vue
@@ -45,23 +45,33 @@
                <el-table-column prop="stage" label="提交时间"></el-table-column>
                <el-table-column prop="creator" label="状态"></el-table-column>
                <el-table-column label="操作" width="150">
                    <!-- 撤销、详情、编辑、删除 -->
                    <template slot-scope="scope">
                        <el-button type="text" @click="handleDetail(scope.row)">撤销</el-button>
                        <el-button type="text" @click="handleReview(scope.row)">审核</el-button>
                        <el-button type="text" @click="handleRevoke(scope.row)">撤销</el-button>
                        <el-button type="text" @click="handleDetail(scope.row)">详情</el-button>
                        <el-button type="text" @click="handleDetail(scope.row)">编辑</el-button>
                        <el-button type="text" @click="handleDetail(scope.row)">删除</el-button>
                        <el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>
                        <el-button type="text" @click="handleDelete(scope.row)">删除</el-button>
                    </template>
                </el-table-column>
            </template>
        </TableCustom>
        <ShowDelConfirm :show="showRevoke" btnType="primary" @close="showRevoke = false" tip="撤销后,工艺工程师将无法收到此审批信息" okText="确定" title="确认要撤销这条确认单吗?"/>
        <review-dialog
            :visible.sync="reviewDialogVisible"
            :type="dialogType"
            :formData="currentRow"
            :sampleData="sampleData"
            @confirm="handleConfirmSubmit"
        />
    </div>
</template>
<script>
import reviewDialog from './components/review-dialog.vue';
export default {
    name: "ConfirmationSheet",
    components: {
        reviewDialog
    },
    data() {
        return {
@@ -73,9 +83,14 @@
                approver: "",
                status: "",
            },
            showRevoke:false,
            tableData: [],
            total: 0,
            editorContent: '', // 编辑器内容
            reviewDialogVisible: true,
            dialogType: 'review',
            currentRow: {},
            sampleData: [],
        };
    },
    mounted() {
@@ -119,14 +134,31 @@
                path: "/dataManagement/confirmation-sheet/add",
            });
        },
        handleApprove(row) {
            // 实现审批逻辑
            console.log("审批数据:", row);
        handleReview(row) {
            this.currentRow = row;
            this.dialogType = 'review';
            this.reviewDialogVisible = true;
        },
        handleRevoke(row) {
            this.currentRow = row;
            this.showRevoke = true;
        },
        handleDetail(row) {
            // 实现查看详情逻辑
            console.log("查看详情:", row);
        },
        handleEdit(row) {
            // 实现编辑逻辑
            console.log("编辑:", row);
        },
        handleDelete(row) {
            // 实现删除逻辑
            console.log("删除:", row);
        },
        handleConfirmSubmit(data) {
            // 处理确认提交后的逻辑
            console.log("确认提交:", data);
        },
    },
};
</script>