| | |
| | | @click="fullscreen = true;"></i> |
| | | <img v-else alt="" src="@/assets/images/no-full.svg" style="cursor: pointer;" @click="fullscreen = false;"> |
| | | </div> |
| | | <div v-if="approveVisible" style="height: 70vh;"> |
| | | <div v-if="approveVisible" class="approve-preview"> |
| | | <onlyoffice ref="onlyoffice" :options="option" style="width: 100%;height: 100%;"/> |
| | | </div> |
| | | <div class="seal-select-block" v-loading="sealLoading"> |
| | | <div class="seal-select-title"> |
| | | <span>按位置选择印章</span> |
| | | <span class="seal-select-tip">自动匹配 MA章 / 1号章 / 骑缝章,每项可单独调整或清空</span> |
| | | </div> |
| | | <div v-if="sealOptions.length" class="seal-position-grid"> |
| | | <div v-for="position in sealPositions" :key="position.key" class="seal-position-card"> |
| | | <div class="seal-position-name">{{ position.label }}</div> |
| | | <div class="seal-position-desc">{{ position.description }}</div> |
| | | <el-select |
| | | v-model="selectedSealPositions[position.key]" |
| | | clearable |
| | | placeholder="不盖章" |
| | | style="width: 100%" |
| | | > |
| | | <el-option |
| | | v-for="seal in sealOptions" |
| | | :key="seal.id" |
| | | :label="seal.name" |
| | | :value="Number(seal.id)" |
| | | /> |
| | | </el-select> |
| | | <div v-if="getSelectedSeal(position.key)" class="seal-position-preview"> |
| | | <img |
| | | :src="javaApi + '/img/' + getSelectedSeal(position.key).address" |
| | | :alt="getSelectedSeal(position.key).name" |
| | | > |
| | | <span>{{ getSelectedSeal(position.key).name }}</span> |
| | | </div> |
| | | <div v-else class="seal-position-empty">该位置不盖章</div> |
| | | </div> |
| | | </div> |
| | | <el-empty v-if="!sealLoading && sealOptions.length === 0" description="暂无启用印章,请先在印章管理中维护" :image-size="54" /> |
| | | </div> |
| | | <span slot="footer" class="dialog-footer"> |
| | | <el-button :disabled="loadingApprove" @click="approveReasonVisible = true">不批准</el-button> |
| | |
| | | import {selectUserCondition} from "@/api/business/inspectionTask"; |
| | | import limsTable from "@/components/Table/lims-table.vue"; |
| | | import {delFile, downFile, getFileList} from "@/api/business/rawMaterialOrder"; |
| | | import {selectEnabledSeals} from "@/api/structural/sealConfig"; |
| | | |
| | | export default { |
| | | name: 'ReportPreparation', |
| | |
| | | issuedReasonVisible: false, |
| | | approveVisible: false, |
| | | approveReasonVisible: false, |
| | | sealOptions: [], |
| | | sealPositions: [ |
| | | { key: 'maSealId', label: 'MA标志章', description: 'PDF 第1页左上角' }, |
| | | { key: 'reportSealId', label: '报告章', description: 'Word 模板各页 seal1 / seal2 预留位置' }, |
| | | { key: 'seamSealId', label: '骑缝章', description: 'PDF 每页右侧中间位置' } |
| | | ], |
| | | selectedSealPositions: { |
| | | maSealId: null, |
| | | reportSealId: null, |
| | | seamSealId: null |
| | | }, |
| | | sealLoading: false, |
| | | fullscreen: false, |
| | | loadingApproveReason: false, |
| | | loadingApprove: false, |
| | |
| | | {label: '原材料下单', value: 1}, |
| | | ], |
| | | orderTypeList: [ |
| | | {label: '委托试验', value: 'Customer-ordered test'}, |
| | | {label: '委托检测', value: 'Commissioned testing'}, |
| | | {label: '实验室间比对', value: 'Inter-laboratory comparison'}, |
| | | {label: '能力验证', value: 'Proficiency testing'}, |
| | | {label: '委托检验', value: 'Customer-ordered test'}, |
| | | {label: '抽检', value: '抽检'}, |
| | | // { label: '进厂检验', value: '进厂检验' }, |
| | | // { label: '季度检验', value: 'Quarterly inspection' }, |
| | |
| | | // 批准按钮 |
| | | handleApprove(row) { |
| | | this.currentInfo = row; |
| | | this.loadEnabledSeals(row); |
| | | let fileName = (row.urlS === null || row.urlS === '') ? row.url : row.urlS |
| | | let fileType = "docx" |
| | | if (row.tempUrlPdf != null || row.tempUrlPdf === '') { |
| | |
| | | }, |
| | | // 批准通过 |
| | | subApprove() { |
| | | const selectedIds = Object.values(this.selectedSealPositions).filter(id => id != null) |
| | | if (!selectedIds.length) { |
| | | return this.$message.error('请至少为一个位置选择印章') |
| | | } |
| | | this.loadingApprove = true; |
| | | ratifyReport({ |
| | | id: this.currentInfo.id, |
| | | isRatify: 1 |
| | | isRatify: 1, |
| | | ...this.selectedSealPositions, |
| | | sealIds: [...new Set(selectedIds)].join(',') |
| | | }).then(res => { |
| | | this.loadingApprove = false; |
| | | this.$message.success('已批准') |
| | |
| | | }).catch(() => { |
| | | this.loadingApprove = false; |
| | | }) |
| | | }, |
| | | loadEnabledSeals(row) { |
| | | this.sealLoading = true |
| | | this.sealOptions = [] |
| | | this.selectedSealPositions = { maSealId: null, reportSealId: null, seamSealId: null } |
| | | selectEnabledSeals().then(res => { |
| | | this.sealOptions = res.data || [] |
| | | const availableIds = this.sealOptions.map(item => Number(item.id)) |
| | | const legacyIds = String((row && row.sealIds) || '') |
| | | .split(',') |
| | | .map(item => Number(item.trim())) |
| | | .filter(id => availableIds.includes(id)) |
| | | const legacyId = legacyIds[0] || null |
| | | const maSeal = this.sealOptions.find(item => String(item.name).toUpperCase().includes('MA')) |
| | | const reportSeal = this.sealOptions.find(item => item.name === '1号章') |
| | | || this.sealOptions.find(item => !String(item.name).toUpperCase().includes('MA') && !String(item.name).includes('骑缝')) |
| | | || this.sealOptions[0] |
| | | const seamSeal = this.sealOptions.find(item => String(item.name).includes('骑缝')) |
| | | this.selectedSealPositions = { |
| | | maSealId: availableIds.includes(Number(row && row.maSealId)) |
| | | ? Number(row.maSealId) : (maSeal ? Number(maSeal.id) : null), |
| | | reportSealId: availableIds.includes(Number(row && row.reportSealId)) |
| | | ? Number(row.reportSealId) : (legacyId || (reportSeal ? Number(reportSeal.id) : null)), |
| | | seamSealId: availableIds.includes(Number(row && row.seamSealId)) |
| | | ? Number(row.seamSealId) : (seamSeal ? Number(seamSeal.id) : legacyId) |
| | | } |
| | | }).finally(() => { |
| | | this.sealLoading = false |
| | | }) |
| | | }, |
| | | getSelectedSeal(positionKey) { |
| | | const sealId = this.selectedSealPositions[positionKey] |
| | | return this.sealOptions.find(item => Number(item.id) === Number(sealId)) |
| | | }, |
| | | handle(row) { |
| | | this.getAuthorizedPerson() |
| | |
| | | ratifyReport({ |
| | | id: this.currentInfo.id, |
| | | isRatify: 0, |
| | | examineTell: this.reason |
| | | ratifyTell: this.reason |
| | | }).then(res => { |
| | | this.loadingApproveReason = false |
| | | this.$message.success('操作成功') |
| | |
| | | this.approveReasonVisible = false; |
| | | }).catch(e => { |
| | | this.$message.error('操作失败') |
| | | this.loadingIssuedReason = false; |
| | | this.loadingApproveReason = false; |
| | | }) |
| | | } |
| | | } |
| | |
| | | .fullscreen { |
| | | height: 82vh |
| | | } |
| | | |
| | | .approve-preview { |
| | | height: 52vh; |
| | | } |
| | | |
| | | .seal-select-block { |
| | | margin-top: 16px; |
| | | padding: 14px 16px; |
| | | border: 1px solid #ebeef5; |
| | | border-radius: 6px; |
| | | background: #fafafa; |
| | | } |
| | | |
| | | .seal-select-title { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | margin-bottom: 12px; |
| | | color: #303133; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .seal-select-tip { |
| | | color: #909399; |
| | | font-size: 12px; |
| | | font-weight: normal; |
| | | } |
| | | |
| | | .seal-position-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(3, minmax(0, 1fr)); |
| | | gap: 14px; |
| | | } |
| | | |
| | | .seal-position-card { |
| | | padding: 14px; |
| | | border: 1px solid #dcdfe6; |
| | | border-radius: 6px; |
| | | } |
| | | |
| | | .seal-position-name { |
| | | color: #303133; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .seal-position-desc { |
| | | margin: 4px 0 10px; |
| | | color: #909399; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .seal-position-preview { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-top: 12px; |
| | | color: #606266; |
| | | } |
| | | |
| | | .seal-position-preview img { |
| | | width: 70px; |
| | | height: 70px; |
| | | margin-right: 10px; |
| | | object-fit: contain; |
| | | } |
| | | |
| | | .seal-position-empty { |
| | | height: 70px; |
| | | margin-top: 12px; |
| | | color: #c0c4cc; |
| | | font-size: 12px; |
| | | line-height: 70px; |
| | | text-align: center; |
| | | } |
| | | </style> |