| | |
| | | }, |
| | | okText: { |
| | | type: String, |
| | | default: '确认', |
| | | default: '确定', |
| | | }, |
| | | btnType: { |
| | | type: String, |
| | |
| | | .dialog-footer { |
| | | display: flex; |
| | | justify-content: end; |
| | | gap: 10px; |
| | | } |
| | | </style> |
| | |
| | | </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"/> |
| | |
| | | @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: "", |
| | |
| | | ], |
| | | }, |
| | | menu: [], |
| | | testItemDialogVisible: false |
| | | testItemDialogVisible: false, |
| | | confirmDialogVisible: false, |
| | | confirmFormData: { |
| | | planName: '', // 项目课题方案名称 |
| | | testCode: '', // 实验编号 |
| | | testName: '', // 实验名称 |
| | | sampleCode: '' // 取样单编号 |
| | | }, |
| | | }; |
| | | }, |
| | | computed: { |
| | |
| | | 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') |
| | | } |
| | | }, |
| | | }; |
New file |
| | |
| | | <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> |
New file |
| | |
| | | <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> |
| | |
| | | <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 { |
| | |
| | | approver: "", |
| | | status: "", |
| | | }, |
| | | showRevoke:false, |
| | | tableData: [], |
| | | total: 0, |
| | | editorContent: '', // 编辑器内容 |
| | | reviewDialogVisible: true, |
| | | dialogType: 'review', |
| | | currentRow: {}, |
| | | sampleData: [], |
| | | }; |
| | | }, |
| | | mounted() { |
| | |
| | | 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> |