|
|
@ -0,0 +1,239 @@
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
|
|
|
<Dialog
|
|
|
|
|
|
|
|
title="打印预览"
|
|
|
|
|
|
|
|
v-model="dialogVisible"
|
|
|
|
|
|
|
|
width="1000"
|
|
|
|
|
|
|
|
:before-close="(doClose) => beforeDialogClose(doClose)"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<!-- 打印预览 -->
|
|
|
|
|
|
|
|
<div class="print-wrap page" ref="print">
|
|
|
|
|
|
|
|
<div id="qrCodeContainer"></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 { ref, reactive } from 'vue'
|
|
|
|
|
|
|
|
// import { betweenDay, dateFormatter, formatDate } from '@/utils/formatTime'
|
|
|
|
|
|
|
|
import QRCode from 'qrcode'
|
|
|
|
|
|
|
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const onPrint = () => {
|
|
|
|
|
|
|
|
// 拿到打印页面dom节点
|
|
|
|
|
|
|
|
const printNode = document.querySelector('.print-wrap')
|
|
|
|
|
|
|
|
if (!printNode) return
|
|
|
|
|
|
|
|
// 页面文档创建一个空的内框架,用于挂载打印节点,并设置一定的样式
|
|
|
|
|
|
|
|
const newIframe: any = document.createElement('iframe')
|
|
|
|
|
|
|
|
newIframe.setAttribute(
|
|
|
|
|
|
|
|
'style',
|
|
|
|
|
|
|
|
'width:0px;height:0px;position:absolute;left:-9999px;top:-9999px;'
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
newIframe.setAttribute('align', 'center')
|
|
|
|
|
|
|
|
document.body.appendChild(newIframe)
|
|
|
|
|
|
|
|
// 将打印页面设置为内框架内容
|
|
|
|
|
|
|
|
let doc: any = null
|
|
|
|
|
|
|
|
doc = newIframe.contentWindow.document
|
|
|
|
|
|
|
|
doc.write(`
|
|
|
|
|
|
|
|
<style type="text/css">
|
|
|
|
|
|
|
|
/* 浏览器打印基本样式 */
|
|
|
|
|
|
|
|
.page {
|
|
|
|
|
|
|
|
width: 200mm;
|
|
|
|
|
|
|
|
min-height: 500px;
|
|
|
|
|
|
|
|
margin: auto;
|
|
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
|
|
border: 1px #d3d3d3 solid;
|
|
|
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
|
|
|
background: white;
|
|
|
|
|
|
|
|
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
|
|
font-size: 14px !important;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.qrCodeContainer {
|
|
|
|
|
|
|
|
width: 200mm;
|
|
|
|
|
|
|
|
height: 69mm;
|
|
|
|
|
|
|
|
border: 1px #d3d3d3 solid;
|
|
|
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
|
|
|
background: white;
|
|
|
|
|
|
|
|
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
|
|
font-size: 14px !important;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@page {
|
|
|
|
|
|
|
|
size: 200mm 70mm;
|
|
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@media print {
|
|
|
|
|
|
|
|
.page {
|
|
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
|
|
border: initial;
|
|
|
|
|
|
|
|
border-radius: initial;
|
|
|
|
|
|
|
|
width: initial;
|
|
|
|
|
|
|
|
min-height: initial;
|
|
|
|
|
|
|
|
box-shadow: initial;
|
|
|
|
|
|
|
|
background: initial;
|
|
|
|
|
|
|
|
page-break-after: always;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.qr-page {
|
|
|
|
|
|
|
|
page-break-after: always;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.qr-code-container {
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
|
|
|
flex-wrap: nowrap;
|
|
|
|
|
|
|
|
justify-content: flex-start;
|
|
|
|
|
|
|
|
width: 200mm;
|
|
|
|
|
|
|
|
height: 69mm;
|
|
|
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.qr-code-container-img {
|
|
|
|
|
|
|
|
width: 70mm;
|
|
|
|
|
|
|
|
height: 69mm;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.qr-code-container-item {
|
|
|
|
|
|
|
|
width: 100mm;
|
|
|
|
|
|
|
|
height: 69mm;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
|
|
${printNode.innerHTML}
|
|
|
|
|
|
|
|
</div>`)
|
|
|
|
|
|
|
|
doc.close()
|
|
|
|
|
|
|
|
// 浏览器打印页面打开渲染
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
|
|
newIframe.contentWindow.focus()
|
|
|
|
|
|
|
|
newIframe.contentWindow.print()
|
|
|
|
|
|
|
|
document.body.removeChild(newIframe) // 移除打印内框架,下次打印下次再挂载
|
|
|
|
|
|
|
|
dialogVisible.value = false
|
|
|
|
|
|
|
|
}, 100)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// / 关闭 Dialog 前的处理逻辑
|
|
|
|
|
|
|
|
function beforeDialogClose(doClose: (shouldClose: boolean) => void): void {
|
|
|
|
|
|
|
|
outopen()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 页面关闭重置
|
|
|
|
|
|
|
|
const outopen = () => {
|
|
|
|
|
|
|
|
dialogVisible.value = false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const printCodeName = ref([])
|
|
|
|
|
|
|
|
const datavals = ref([])
|
|
|
|
|
|
|
|
/** 打开弹窗 */
|
|
|
|
|
|
|
|
const open = async (code, vals, val) => {
|
|
|
|
|
|
|
|
console.log(code, vals, val)
|
|
|
|
|
|
|
|
datavals.value = []
|
|
|
|
|
|
|
|
printCodeName.value = []
|
|
|
|
|
|
|
|
vals.forEach((item) => {
|
|
|
|
|
|
|
|
const row = {
|
|
|
|
|
|
|
|
projectSubName: item.projectSubName,
|
|
|
|
|
|
|
|
spec: '规格' + item.spec,
|
|
|
|
|
|
|
|
sort: '序号' + item.sort,
|
|
|
|
|
|
|
|
amount: '数量' + item.amount
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
datavals.value.push(row)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 检查val是否在1到100范围内且不包含负号
|
|
|
|
|
|
|
|
// 删除可能存在的负号(虽然在这个例子中并不需要)
|
|
|
|
|
|
|
|
val = val.replace('-', ',')
|
|
|
|
|
|
|
|
val = val.split(',')
|
|
|
|
|
|
|
|
// console.log(val)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (let i = val[0] * 1; i <= val[1] * 1; i++) {
|
|
|
|
|
|
|
|
// 构建新的字符串并添加到printCodeName数组
|
|
|
|
|
|
|
|
const newName = `${code}-${vals[0].clauseId}-${i}`
|
|
|
|
|
|
|
|
printCodeName.value.push(newName)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// console.log(printCodeName.value)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dialogVisible.value = true
|
|
|
|
|
|
|
|
await Promise.all(
|
|
|
|
|
|
|
|
printCodeName.value.map(async (item) => {
|
|
|
|
|
|
|
|
const qrCodeData = await QRCode.toDataURL(item)
|
|
|
|
|
|
|
|
const qrCodeElement = document.getElementById('qrCodeContainer')
|
|
|
|
|
|
|
|
if (qrCodeElement) {
|
|
|
|
|
|
|
|
var tempString = ""
|
|
|
|
|
|
|
|
datavals.value.forEach(e=>{tempString+='<span style="margin-left:30px;">'+e.projectSubName+' , '+e.spec+' , '+e.sort+' , '+e.amount+'</span>'})
|
|
|
|
|
|
|
|
qrCodeElement.innerHTML += `<div class="page qr-page">
|
|
|
|
|
|
|
|
<div class="qr-code-container" style=" padding:0 5mm; border:1px #d3d3d3 solid;display:flex; justify-content: flex-start; font-size:16px;font-weight:700;">
|
|
|
|
|
|
|
|
<img src="${qrCodeData}" width="30%" alt="QR Code"/>
|
|
|
|
|
|
|
|
<div style="margin-left:5mm;text-align:left;" >
|
|
|
|
|
|
|
|
<p>订单名称(Order name):${code}</p>
|
|
|
|
|
|
|
|
<hr/>
|
|
|
|
|
|
|
|
<p>产品清单(Product name):</p>`+tempString+`
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div>`
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// <p>${datavals.value[0]?.projectSubName},${datavals.value[0].spec},${datavals.value[0].sort},${datavals.value[0].amount}</p>
|
|
|
|
|
|
|
|
// <div class="qr-code-name">${item}</div>
|
|
|
|
|
|
|
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
|
|
.page {
|
|
|
|
|
|
|
|
width: 200mm;
|
|
|
|
|
|
|
|
min-height: 70mm;
|
|
|
|
|
|
|
|
margin: auto;
|
|
|
|
|
|
|
|
border: 1px #d3d3d3 solid;
|
|
|
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
|
|
|
background: white;
|
|
|
|
|
|
|
|
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.qrCodeContainer {
|
|
|
|
|
|
|
|
width: 200mm;
|
|
|
|
|
|
|
|
height: 70mm;
|
|
|
|
|
|
|
|
border: 1px #d3d3d3 solid;
|
|
|
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
|
|
|
background: white;
|
|
|
|
|
|
|
|
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@page {
|
|
|
|
|
|
|
|
size: 200mm 70mm;
|
|
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@media print {
|
|
|
|
|
|
|
|
.page {
|
|
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
|
|
border: initial;
|
|
|
|
|
|
|
|
border-radius: initial;
|
|
|
|
|
|
|
|
width: initial;
|
|
|
|
|
|
|
|
min-height: initial;
|
|
|
|
|
|
|
|
box-shadow: initial;
|
|
|
|
|
|
|
|
background: initial;
|
|
|
|
|
|
|
|
page-break-after: always;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.qr-page {
|
|
|
|
|
|
|
|
page-break-after: always;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.qr-code-container {
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
justify-content: flex-start;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
border: 1px #d3d3d3 solid;
|
|
|
|
|
|
|
|
width: 200mm;
|
|
|
|
|
|
|
|
height: 69mm;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.qr-code-container-item {
|
|
|
|
|
|
|
|
width: 100mm;
|
|
|
|
|
|
|
|
height: 69mm;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
A4的大小:21cm*29.7cm(width:794px;)。
|
|
|
|
|
|
|
|
单位换算:1 inch = 2.54 cm 1mm = 96 px 1 cm = 37.79528 px*/
|
|
|
|
|
|
|
|
</style>
|