heli-mes/mes-ui/mes-ui-admin-vue3/src/views/heli/plan/printFinalDialog.vue
2025-08-08 17:58:23 +08:00

267 lines
7.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<Dialog
title="打印预览"
v-model="dialogVisible"
width="1000"
top="0%"
:before-close="(doClose) => beforeDialogClose(doClose)"
>
<el-button @click="outopen" style="float: right;margin-right: 0.5%;">取消</el-button>
<el-button @click="onPrint" type="primary" style="float: right;margin-right: 1%;">打印</el-button>
<!-- 打印预览 -->
<div class="print-wrap1 page" ref="print">
<div id="qrCodeContainer1"></div>
</div>
<template #footer>
<el-button @click="onPrint" type="primary">打印</el-button>
<el-button @click="outopen">取消</el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import QRCode from 'qrcode'
import {DICT_TYPE, getIntDictOptions} from "@/utils/dict";
const dialogVisible = ref(false)
let clauseId = null;
const startPageNum = ref(0);
const endPageNum = ref(0);
const onPrint = () => {
const printNode = document.querySelector('.print-wrap1')
if (!printNode) return
const newIframe: any = document.createElement('iframe')
newIframe.setAttribute(
'style',
'width:0px;height:0px;position:absolute;left:-9999px;top:-9999px;'
)
document.body.appendChild(newIframe)
const doc = newIframe.contentWindow.document
// 添加基础样式
doc.write(`
<!DOCTYPE html>
<html>
<head>
<style>
@page {
size: 60mm 40mm;
margin: 0;
}
body {
margin: 0;
padding: 0;
background-color: white;
color: black;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
.qr-page {
width: 60mm;
height: 40mm;
padding: 2mm;
box-sizing: border-box;
font-family: monospace;
position: relative;
background-color: white;
color: black;
}
.code-line {
font-size: 14px;
margin-bottom: 1.4mm;
margin-left: 0.8mm;
}
.code-line span {
display: inline-block;
width: 100%;
font-family: "SimHei", "Microsoft YaHei", "PingFang SC", sans-serif;
border-bottom: 1px solid black;
padding-bottom: 0.2mm;
font-weight: bold !important; /* 仅此处加粗 item.code */
color: black;
}
.name-line {
font-size: 14px;
margin-bottom: 1mm;
display: flex;
align-items: center;
}
.name-label {
white-space: nowrap;
margin-right: 1mm;
}
.name-underline {
flex-grow: 1;
border-bottom: 1px solid black;
height: 1em;
margin-left: -1.2mm;
}
.bottom-section {
display: flex;
position: absolute;
bottom: 2mm;
left: 2mm;
right: 2mm;
height: 22mm;
}
.qr-container {
width: 22mm;
height: 22mm;
margin-left: auto;
display: flex;
align-items: flex-end;
justify-content: flex-end;
}
.qr-code {
width: 100%;
height: 100%;
}
.quantity-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
width: 13mm;
margin-right: 1mm;
}
.quantity {
font-size: 14px;
margin-bottom: 0.5mm;
margin-top: 2mm;
white-space: nowrap;
}
.timestamp {
font-size: 14px;
line-height: 1;
margin-left: 0.5mm;
margin-top: auto;
white-space: nowrap;
}
</style>
</head>
<body>
${printNode.innerHTML}
</body>
</html>
`)
doc.close()
dialogVisible.value = false
setTimeout(() => {
newIframe.contentWindow.focus()
newIframe.contentWindow.print()
document.body.removeChild(newIframe)
dialogVisible.value = false
}, 100)
}
function beforeDialogClose(doClose: (shouldClose: boolean) => void): void {
outopen()
}
const outopen = () => {
dialogVisible.value = false
}
const getDictLabel = (dictType, value) => {
var intDictOptions = getIntDictOptions(dictType);
const dict = intDictOptions.find(item => item.value == value)
return dict?.label || value // 找不到时显示原始值
}
const printCodeName = ref([])
const datavals = ref([])
const specarr = ref([])
const cnenList = ref([])
const open = async ( vals) => {
cnenList.value = vals;
specarr.value = []
console.log(vals)
datavals.value = []
printCodeName.value = []
vals.forEach((item) => {
const row1 = {
code: item.projectSubCode,
name: item.name == null ? '' : item.name,
amount: item.amount == null ? '' : item.amount,
unit:getDictLabel(DICT_TYPE.HELI_MATERIAL_UNIT,item.unit)
}
printCodeName.value.push(row1)
})
dialogVisible.value = true
const currentDate = new Date()
// const formattedDate = `${currentDate.getFullYear()}-${String(currentDate.getMonth() + 1).padStart(2, '0')}-${String(currentDate.getDate()).padStart(2, '0')} ${String(currentDate.getHours()).padStart(2, '0')}:${String(currentDate.getMinutes()).padStart(2, '0')}:${String(currentDate.getSeconds()).padStart(2, '0')}`
const formattedDate = `${currentDate.getFullYear()}-${String(currentDate.getMonth() + 1).padStart(2, '0')}-${String(currentDate.getDate()).padStart(2, '0')} ${String(currentDate.getHours()).padStart(2, '0')}:${String(currentDate.getMinutes()).padStart(2, '0')}`
await Promise.all(
printCodeName.value.map(async (item) => {
const qrCodeData = await QRCode.toDataURL(item.name,{
errorCorrectionLevel: 'H'
})
const qrCodeElement = document.getElementById('qrCodeContainer1')
if (qrCodeElement) {
(qrCodeElement.innerHTML +=
`<div class="page qr-page">
<div class="code-line">
<span>${item.code}</span>
</div>
<div class="name-line">
<span class="name-label">名&thinsp;称:&thinsp;</span>
<span class="name-underline">${item.name}</span>
</div>
<div class="bottom-section">
<div class="quantity-container">
<span class="quantity">数&thinsp;量:&thinsp;${item.amount}&thinsp;${item.unit}</span>
<span class="timestamp">${formattedDate}</span>
</div>
<div class="qr-container">
<img class="qr-code" src="${qrCodeData}" alt="QR Code">
</div>
</div>
</div>`)
}
})
).then(res => {
onPrint()
})
}
defineExpose({ open })
</script>
<style scoped lang="scss">
/* 预览样式 - 仅用于屏幕显示 */
.page {
width: 60mm;
min-height: 40mm;
margin: auto;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
background-color: black;
color: white;
padding: 2mm;
box-sizing: border-box;
/* 临时隐藏下划线打印时会显示 */
.code-line span, .name-underline {
display: none;
}
}
/* 确保打印样式优先 */
@media print {
.page {
background-color: white !important;
color: black !important;
.code-line span, .name-underline {
display: inline-block;
}
}
}
</style>