heli-mes/mes-ui/mes-ui-admin-vue3/src/views/heli/deliverorder/shipmentsPrint.vue

637 lines
20 KiB
Vue
Raw Normal View History

2025-01-09 18:29:48 +08:00
<template>
<Dialog title="打印预览" v-model="dialogVisible" width="1000" v-loading="formLoading">
<!-- 打印预览 -->
<div class="print-wrap page" ref="print">
<!-- 客户联 -->
<table border="2" cellspacing="0" id="table">
<tbody>
<tr>
<td colspan="10">
<div style="display: flex; align-items: center; justify-content: space-between">
<img :src="logoDataUrl" style="width: 100px" alt="" />
<span style="font-size: 20px; font-weight: 700">发货单</span>
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
</div>
</td>
</tr>
</tbody>
<tbody>
<tr>
<td colspan="2"> 发货编号 </td>
<td colspan="3">
<span>{{ formData.code }}</span>
</td>
<td>合同号</td>
<td colspan="2">{{ formData.contractNo }}</td>
<td> 性质 </td>
<td>{{ formData.property }} </td>
</tr>
</tbody>
<tr>
<td colspan="2"> 发货日期 </td>
<td colspan="3">
{{ formatDate(new Date(formData.deliverDate), 'YYYY-MM-DD') }}
</td>
<td> 联系人</td>
<td>{{ formData.receivePersonName }} </td>
<td> 电话 </td>
<td colspan="2">{{ formData.receivePersonMobile }} </td>
</tr>
<tr>
<td colspan="2"> 收货单位 </td>
<td colspan="8">{{ formData.customerName }}</td>
</tr>
<tr>
<td colspan="2"> 收货地址 </td>
<td colspan="8">{{ formData.receiveAddress }}</td>
</tr>
<tr>
<td colspan="2"> 项目名称</td>
<td colspan="4">{{ formData.projectName }}</td>
<td>重量(T)</td>
<td>{{ formData.transportWeight }}</td>
<td>位置()</td>
<td>{{ formData.transportSize }}</td>
</tr>
<tbody>
<tr>
<td colspan="4"> 内容清单 </td>
<td> 单位 </td>
<td> 数量 </td>
<td>重量(T)</td>
<td>尺寸()</td>
<td colspan="2"> 备注 </td>
</tr>
<tr v-show="subTotalAmount <= splitThreshold" v-for="(item, index) in formData.deliverOrderSubs" :key="index">
<td colspan="4">{{ item.name }}</td>
<td>{{ getDictLabel(DICT_TYPE.HELI_MATERIAL_UNIT, item.unit) }}</td>
<td>{{ item.amount }}</td>
<td>{{ item.weight }}</td>
<td>{{ item.size }}</td>
<td colspan="2">{{ item.remark }}</td>
</tr>
<tr v-if="subTotalAmount > splitThreshold">
<td colspan="4">工装模具详见清单附件</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td colspan="2"></td>
</tr>
<tr>
<td colspan="4">附光盘+各类报告</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td colspan="2"></td>
</tr>
</tbody>
<tbody v-if="subTotalAmount > splitThreshold">
<tr v-for="item in 4" :key="item">
<td colspan="4"> &nbsp;</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td colspan="2"></td>
</tr>
</tbody>
<tr>
<td colspan="2"> 发货单位 </td>
<td colspan="3">
{{ formData.deliverCompany }}
</td>
<td> 联系人</td>
<td>{{ formData.deliverPersonName }} </td>
<td> 电话 </td>
<td colspan="2">{{ formData.deliverPersonMobile }} </td>
</tr>
<tr>
<td colspan="2"> 司机姓名 </td>
<td colspan="2" v-if="formData.transportDriverName">
{{ formData.transportDriverName }}
</td>
<td colspan="2" v-else style="width: 60px"></td>
<td>车牌号</td>
<td colspan="2" v-if="formData.transportBusNumber">{{ formData.transportBusNumber }}</td>
<td colspan="2" v-else style="width: 50px"></td>
<td> 电话 </td>
<td colspan="2" v-if="formData.transportDriverMobile">{{ formData.transportDriverMobile }}
</td>
<td colspan="2" v-else style="width: 50px"></td>
</tr>
<tr>
<td colspan="5">
<div style="text-align: left">内部货物门点人签名:</div>
</td>
<td colspan="5">
<div style="text-align: left">收货人签名:</div>
</td>
</tr>
</table>
<div style="width: 100%; display: flex; justify-content: space-between; align-items: center">
<span>制单人{{ formData.creatorName }}</span>
<span>-客户联-</span>
</div>
<div class="divide_line" style="margin: 20px 0"></div>
<!-- 回单联 -->
<table border="2" cellspacing="0" id="table1" style="position: relative !important">
<tbody>
<tr>
<td colspan="10">
<div style="display: flex; align-items: center; justify-content: space-between">
<img :src="logoDataUrl" style="width: 100px" alt="" />
<span style="font-size: 20px; font-weight: 700">发货单</span>
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
</div>
</td>
</tr>
</tbody>
<tbody>
<tr>
<td colspan="2"> 发货编号 </td>
<td colspan="3">
<span>{{ formData.code }}</span>
</td>
<td>合同号</td>
<td colspan="2">{{ formData.contractNo }}</td>
<td> 性质 </td>
<td>{{ formData.property }} </td>
</tr>
</tbody>
<tr>
<td colspan="2"> 发货日期 </td>
<td colspan="3">
{{ formatDate(new Date(formData.deliverDate), 'YYYY-MM-DD') }}
</td>
<td> 联系人</td>
<td>{{ formData.receivePersonName }} </td>
<td> 电话 </td>
<td colspan="2">{{ formData.receivePersonMobile }} </td>
</tr>
<tr>
<td colspan="2"> 收货单位 </td>
<td colspan="8">{{ formData.customerName }}</td>
</tr>
<tr>
<td colspan="2"> 收货地址 </td>
<td colspan="8">{{ formData.receiveAddress }}</td>
</tr>
<tr>
<td colspan="2"> 项目名称</td>
<td colspan="4">{{ formData.projectName }}</td>
<td>重量(T)</td>
<td>{{ formData.transportWeight }}</td>
<td>位置()</td>
<td>{{ formData.transportSize }}</td>
</tr>
<tbody>
<tr>
<td colspan="4"> 内容清单 </td>
<td> 单位 </td>
<td> 数量 </td>
<td>重量(T)</td>
<td>尺寸()</td>
<td colspan="2"> 备注 </td>
</tr>
<tr v-show="subTotalAmount <= splitThreshold" v-for="(item, index) in formData.deliverOrderSubs" :key="index">
<td colspan="4">{{ item.name }}</td>
<td>{{ getDictLabel(DICT_TYPE.HELI_MATERIAL_UNIT, item.unit) }}</td>
<td>{{ item.amount }}</td>
<td>{{ item.weight }}</td>
<td>{{ item.size }}</td>
<td colspan="2">{{ item.remark }}</td>
</tr>
<tr v-if="subTotalAmount > splitThreshold">
<td colspan="4">工装模具详见清单附件</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td colspan="2"></td>
</tr>
<tr>
<td colspan="4">附光盘+各类报告</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td colspan="2"></td>
</tr>
</tbody>
<tbody v-if="subTotalAmount > splitThreshold">
<tr v-for="item in 4" :key="item">
<td colspan="4"> &nbsp;</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td colspan="2"></td>
</tr>
</tbody>
<tr>
<td colspan="2"> 发货单位 </td>
<td colspan="3">
{{ formData.deliverCompany }}
</td>
<td> 联系人</td>
<td>{{ formData.deliverPersonName }} </td>
<td> 电话 </td>
<td colspan="2">{{ formData.deliverPersonMobile }} </td>
</tr>
<tr>
<td colspan="2"> 司机姓名 </td>
<td colspan="2" v-if="formData.transportDriverName">
{{ formData.transportDriverName }}
</td>
<td colspan="2" v-else style="width: 60px"></td>
<td>车牌号</td>
<td colspan="2" v-if="formData.transportBusNumber">{{ formData.transportBusNumber }}</td>
<td colspan="2" v-else style="width: 50px"></td>
<td> 电话 </td>
<td colspan="2" v-if="formData.transportDriverMobile">{{ formData.transportDriverMobile }}
</td>
<td colspan="2" v-else style="width: 50px"></td>
</tr>
<tr>
<td colspan="5">
<div style="text-align: left">内部货物门点人签名:</div>
</td>
<td colspan="5">
<div style="text-align: left">收货人签名:</div>
</td>
</tr>
</table>
<div style="
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
">
<span>制单人{{ formData.creatorName }}</span>
<span>-回单联-</span>
</div>
<!-- 附件 -->
<!-- 附件需要判断 -->
<div v-if="subTotalAmount > splitThreshold">
<div class="divide_line1" style="margin-top: 40px"></div>
<table border="2" cellspacing="0" id="table1" style="height: 28cm">
<tbody>
<tr>
<td colspan="10">
<div style="display: flex; align-items: center; justify-content: space-between">
<img :src="logoDataUrl" style="width: 100px" alt="" />
<span style="font-size: 20px; font-weight: 700">清单附件</span>
<span style="font-size: 12px">发货编号{{ formData.code }}</span>
</div>
</td>
</tr>
</tbody>
<tbody>
<tr>
<td> 序号 </td>
<td colspan="3">
<span>模具名称</span>
</td>
<td colspan="3">模具图号</td>
<td> 数量() </td>
<td colspan="2">备注 </td>
</tr>
<tr>
<td colspan="10" style="background-color: rgb(255, 255, 0)">
<div style="text-align: left">模具清单</div>
</td>
</tr>
<tr v-for="(item, index) in formData.deliverOrderSubs" :key="index">
<td> {{ index + 1 }} </td>
<td colspan="3">{{ item.name }}</td>
<td colspan="3">{{ item.blueprintNo }}</td>
<td> {{ item.amount }} </td>
<td colspan="2">{{ item.remark }} </td>
</tr>
<tr>
<td colspan="10" style="background-color: rgb(255, 255, 0)">
<div style="text-align: left">备件清单</div>
</td>
</tr>
<tr v-for="(item, index) in formData.deliverOrderOtherSpareSubs" :key="index">
<td> {{ index + 1 }} </td>
<td colspan="3">
<span>{{ item.name }}</span>
</td>
<td colspan="3">{{ item.blueprintNo }}</td>
<td> {{ item.amount }} </td>
<td colspan="2">{{ item.remark }} </td>
</tr>
<tr>
<td colspan="10" style="background-color: rgb(255, 255, 0)">
<div style="text-align: left">刀具清单</div>
</td>
</tr>
<tr v-for="(item, index) in formData.deliverOrderOtherCutterSubs" :key="index">
<td> {{ index + 1 }} </td>
<td colspan="3">
<span>{{ item.name }}</span>
</td>
<td colspan="3">{{ item.blueprintNo }}</td>
<td> {{ item.amount }} </td>
<td colspan="2">{{ item.remark }} </td>
</tr>
</tbody>
<tbody v-if="subTotalAmount <20">
<tr v-for="item in (20-subTotalAmount)" :key="item">
<td> &nbsp;</td>
<td colspan="3">
</td>
<td colspan="3"></td>
<td></td>
<td colspan="2"></td>
</tr>
</tbody>
<tr>
<td colspan="10">
<div style="text-align: left">内部货物门点人签名:</div>
</td>
</tr>
</table>
<div style="
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
">
<span>制单人{{ formData.creatorName }}</span>
<span>-回单联-</span>
</div>
</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 { Check } from '@element-plus/icons-vue'
import { ref } from 'vue'
import { getDictLabel, DICT_TYPE } from '@/utils/dict'
import urlimg from '@/assets/imgs/exlogo.png'
import { getDeliverOrder, getDeliverOrderSubListByDeliveryOrderId } from '@/api/heli/deliverorder'
import { formatDate } from '@/utils/formatTime'
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: 21cm;
min-height: 29.7cm;
padding: 10mm;
margin: 20px auto;
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: A4;
margin: 5px 1cm;
}
@media print {
.page {
margin: 0;
border: initial;
border-radius: initial;
width: initial;
min-height: initial;
box-shadow: initial;
background: initial;
page-break-after: always;
}
}
table {
width: 100%; /* 让表格宽度100%占满其父元素宽度 */
height: auto; /* 高度根据内容自适应 */
font-size: 14px;
text-align: center;
border-collapse: collapse;
margin-top: 5mm; /* 添加顶部外边距,替代原先的页内边距 */
td {
padding: 5px 0;
border: 1px solid #333;
}
}
.divide_line {
justify-content: center;
border-bottom: 1px dashed rgba(51, 51, 51, 1);
}
.divide_line1 {
justify-content: center;
border-bottom: 1px dashed rgb(255, 255, 255);
}
</style>
<div>
${printNode.innerHTML}
</div>`)
doc.close()
// 浏览器打印页面打开渲染
setTimeout(() => {
newIframe.contentWindow.focus()
newIframe.contentWindow.print()
document.body.removeChild(newIframe) // 移除打印内框架,下次打印下次再挂载
dialogVisible.value = false
}, 100)
}
const outopen = () => {
dialogVisible.value = false
}
const queryParams: any = ref({
code: undefined
})
const formLoading = ref(false)
const formData: any = ref({
id: undefined,
code: undefined,
saleOrderIds: undefined,
saleOrderCode: undefined,
contractNo: undefined,
property: undefined,
customerId: undefined,
customerName: undefined,
projectName: undefined,
deliverDate: undefined,
deliverStatus: 1,
deliverPerson: undefined,
deliverPersonName: undefined,
deliverPersonMobile: undefined,
deliverMode: undefined,
receivePersonMobile: undefined,
transportDriverName: undefined,
transportDriverMobile: undefined,
transportBusNumber: undefined,
transportWeight: undefined,
transportSize: undefined,
remark: undefined,
status: 1,
receivePersonName: undefined,
receiveAddress: undefined,
deliverOrderSubs: [],
deliverOrderOtherSubs: [],
deliverOrderOtherSpareSubs: [],
deliverOrderOtherCutterSubs: [],
attachments: [],
operateLogs: [],
active: undefined,
deliverCompany: '杭州合立机械有限公司'
})
const subTotalAmount = ref(0)
const splitThreshold = 5
const logoDataUrl = ref('') // 存储Logo的Base64编码数据URL
/** 打开弹窗 */
const open = async (id: number) => {
dialogVisible.value = true
// 修改时,设置数据
formLoading.value = true
try {
formData.value = await getDeliverOrder(id)
formData.value.deliverCompany = '杭州合立机械有限公司'
// 性质
let properties = formData.value.property.split(',')
let property = ''
for (let i = 0; i < properties.length; i++) {
property += getDictLabel(DICT_TYPE.HELI_PROJECT_PROPERTY, properties[i]) + ','
}
formData.value.property = property.substring(0, property.length - 1)
// 子项列表
const subArr = await getDeliverOrderSubListByDeliveryOrderId(id)
subTotalAmount.value = subArr.length
if (subTotalAmount.value > splitThreshold) {
formData.value.deliverOrderSubs = subArr.filter((sub) => sub.category == 'DELIVER_LIST')
// 分类清单
formData.value.deliverOrderOtherSpareSubs = subArr.filter(
(sub) => sub.category == 'OTHER_LIST' && sub.subType == 1
)
formData.value.deliverOrderOtherCutterSubs = subArr.filter(
(sub) => sub.category == 'OTHER_LIST' && sub.subType == 2
)
} else {
formData.value.deliverOrderSubs = subArr
}
//图片
// 在组件挂载后将Logo图片转换为Base64编码数据URL
const logoImage = new Image()
logoImage.src = urlimg // 替换为Logo图片路径
logoImage.onload = () => {
const canvas = document.createElement('canvas')
canvas.width = logoImage.width
canvas.height = logoImage.height
const context = canvas.getContext('2d')
context.drawImage(logoImage, 0, 0)
const base64String = canvas.toDataURL('image/png')
logoDataUrl.value = base64String
}
} finally {
formLoading.value = false
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
onMounted(() => {})
</script>
<style scoped lang="scss">
.page {
width: 21cm;
min-height: 29.7cm;
padding: 10mm;
margin: 20px auto;
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: A4;
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;
}
}
table {
width: 100%; /* 让表格宽度100%占满其父元素宽度 */
height: auto; /* 高度根据内容自适应 */
font-size: 14px;
text-align: center;
border-collapse: collapse;
margin-top: 5mm; /* 添加顶部外边距,替代原先的页内边距 */
td {
padding: 5px 0;
border: 1px solid #333;
}
}
.divide_line {
justify-content: center;
border-bottom: 1px dashed rgba(51, 51, 51, 1);
}
.divide_line1 {
justify-content: center;
border-bottom: 1px dashed rgb(255, 255, 255);
}
#table {
position: relative;
}
/*
A4的大小21cm*29.7cmwidth:794px;
单位换算1 inch = 2.54 cm 1mm = 96 px 1 cm = 37.79528 px*/
</style>