feat(heli-storage): 新增入库管理打印功能和表单页面
- 创建 print.vue 组件实现入库单打印功能 - 添加针式打印机样式适配和打印逻辑
This commit is contained in:
parent
4625705ce1
commit
626e4286ef
@ -390,98 +390,7 @@ link type="primary" size="small" :disabled="ctrView || ctrDelete"
|
||||
<purchaseorderDialog ref="projectPurchaseorderDialog" @success="handleSelectedProjectPurchaseorder" />
|
||||
<!-- 表单弹窗:新增物料 -->
|
||||
<MaterialForm ref="materialOpenFormRef" @success="getList" />
|
||||
<el-dialog v-model="printDialogVisible" width="80%" title="入库单打印" :close-on-click-modal="false">
|
||||
<div id="printArea" class="print-content">
|
||||
<div class="print-header">
|
||||
<div class="order-info">
|
||||
<div style="display: flex;">
|
||||
<span style="width: 210px;">编号:{{ printData.stockNo}}</span>
|
||||
<span style="margin-left:20px; width: 170px;">入库日期:{{ formatDate(printData.createTime) }}</span>
|
||||
<span style="margin-left:20px;width: 250px">供应商:{{ printData.supplierName }}</span>
|
||||
</div>
|
||||
<!-- <div style="display: flex;">
|
||||
<span style="margin-left:20px;width: 110px">联系人:{{ printData.contactName }}</span>
|
||||
<span style="margin-left:20px;width: 150px">电话:{{ printData.contactMobile }}</span>
|
||||
</div> -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<table class="print-table">
|
||||
<colgroup>
|
||||
<col style="width: 10%;" />
|
||||
<col style="width: 10%;" />
|
||||
<col style="width: 10%;" />
|
||||
<col style="width: 10%;" />
|
||||
<col style="width: 10%;" />
|
||||
<col style="width: 10%;" />
|
||||
<col style="width: 10%;" />
|
||||
<col style="width: 10%;" />
|
||||
<col style="width: 10%;" />
|
||||
<col style="width: 10%;" />
|
||||
|
||||
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>物料号</th>
|
||||
<th>零件名称</th>
|
||||
<th>规格</th>
|
||||
<th>单位</th>
|
||||
<th>入库数量</th>
|
||||
<th>单价(元)</th>
|
||||
<th>小计(元)</th>
|
||||
<th>项目名称</th>
|
||||
<th>备注</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in 17" :key="index">
|
||||
<td>{{ index + 1 }}</td>
|
||||
<td>{{ printData.storageMatDOList[index]?.matCode || '' }}</td>
|
||||
<td>{{ printData.storageMatDOList[index]?.matName ? limitTo20Chars(printData.storageMatDOList[index].matName) : '' }}</td>
|
||||
<td>{{ printData.storageMatDOList[index]?.mtSpec || '' }}</td>
|
||||
<td>{{ printData.storageMatDOList[index]?.matUnit || '' }}</td>
|
||||
<td>{{ printData.storageMatDOList[index]?.storageOkQty || '' }}</td>
|
||||
<td>{{ printData.storageMatDOList[index]?.unitPrice || '' }}</td>
|
||||
<td>{{ printData.storageMatDOList[index]?.totalPrice || '' }}</td>
|
||||
<td>{{ printData.storageMatDOList[index]?.projectName || '' }}</td>
|
||||
<td>{{ printData.storageMatDOList[index]?.description || '' }}</td>
|
||||
</tr>
|
||||
<!-- <tr>
|
||||
<td colspan="9"></td>
|
||||
<td style="font-weight: bold;">合计</td>
|
||||
<td style="font-weight: bold;">{{ printData.estimatedPriceSum }}</td>
|
||||
</tr> -->
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
<div class="order-info" style="margin-top: 10px;border-bottom: 1px solid #ccc;padding-bottom: 10px;">
|
||||
<div style="display: flex;width: 40%;">
|
||||
<span >经手人:{{ printData.userName }}</span>
|
||||
|
||||
</div>
|
||||
<div style="display: flex;width: 20%;justify-content: center;">
|
||||
<!-- <span style="margin-left:20px;width: 150px">审核:{{ printData.auditorName }}</span> -->
|
||||
<!-- <span style="margin-left:20px;width: 120px">仓库签字:</span> -->
|
||||
|
||||
</div>
|
||||
<div style="display: flex; width: 40%;justify-content: right;">
|
||||
<span style="margin-left:20px;width: 150px">仓库签字:{{ printData.signature }}</span>
|
||||
|
||||
<span style="margin-left:20px;width: 150px">日期:{{ printData.date }}</span>
|
||||
<!-- <span style="margin-left:20px;width: 150px">接收人:{{ printData.username }}</span> -->
|
||||
<!-- <span style="margin-left:20px;width: 150px">电话:{{ printData.userMobile }}</span> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="printDialogVisible = false">关闭</el-button>
|
||||
<el-button type="primary" @click="doPrint">打印</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<PrintRef ref="printFormRef" />
|
||||
|
||||
</template>
|
||||
|
||||
@ -512,6 +421,7 @@ import projects from './subproject.vue'
|
||||
import {Search} from "@element-plus/icons-vue";
|
||||
import purchaseorderDialog from '@/views/heli/outsourcestock/purchaseorderDialog.vue'
|
||||
import MaterialForm from '@/views/heli/material/MaterialForm.vue'
|
||||
import PrintRef from './print.vue'
|
||||
import * as StorageinApi from "@/api/heli/storagein";
|
||||
import * as storageInventoryApi from "@/api/heli/storageinventory";
|
||||
|
||||
@ -628,120 +538,33 @@ function formatDate(val) {
|
||||
}
|
||||
|
||||
const printLoading = ref(false)
|
||||
// 打印弹窗内容
|
||||
const printDialogVisible = ref(false)
|
||||
const printData = ref({})
|
||||
const printFormRef = ref()
|
||||
|
||||
function openPrintDialog(data) {
|
||||
printData.value = data
|
||||
printDialogVisible.value = true
|
||||
}
|
||||
const isPrint = async () => {
|
||||
printLoading.value = true
|
||||
printLoading.value = true
|
||||
try {
|
||||
var newVar = await StorageApi.isPrint(query.id);
|
||||
console.log(newVar)
|
||||
openPrintDialog(newVar)
|
||||
const newVar = await StorageApi.isPrint(query.id)
|
||||
const data = newVar.storageMatDOList?.map((item, idx) => ({
|
||||
编号: idx + 1,
|
||||
物料号: item.matCode || '',
|
||||
零件名称: item.matName ? (item.matName.length > 20 ? item.matName.slice(0, 20) : item.matName) : '',
|
||||
规格: item.mtSpec || '',
|
||||
单位: item.matUnit || '',
|
||||
入库数量: item.storageOkQty || '',
|
||||
单价: item.unitPrice || '',
|
||||
小计: item.totalPrice || '',
|
||||
项目名称: item.projectName || '',
|
||||
备注: item.description || ''
|
||||
})) || []
|
||||
// 补齐到17行
|
||||
const emptyRow = { 编号: '', 物料号: '', 零件名称: '', 规格: '', 单位: '', 入库数量: '', 单价: '', 小计: '', 项目名称: '', 备注: '' }
|
||||
while (data.length < 17) {
|
||||
data.push({ ...emptyRow, 编号: data.length + 1 })
|
||||
}
|
||||
printFormRef.value?.open(data, '', 'detail')
|
||||
} finally {
|
||||
printLoading.value = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function doPrint() {
|
||||
// 创建新的打印窗口
|
||||
const printContent = document.getElementById('printArea')
|
||||
if (!printContent) return
|
||||
|
||||
const iframe = document.createElement('iframe')
|
||||
iframe.style.position = 'absolute'
|
||||
iframe.style.width = '0'
|
||||
iframe.style.height = '0'
|
||||
iframe.style.border = 'none'
|
||||
document.body.appendChild(iframe)
|
||||
|
||||
const doc = iframe.contentWindow?.document
|
||||
doc?.open()
|
||||
doc?.write(`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title >入库单</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.print-content {
|
||||
width: 100%;
|
||||
padding-top: 15px;
|
||||
}
|
||||
.order-info {
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
|
||||
.stamp-info {
|
||||
margin-top: 10px;
|
||||
|
||||
}
|
||||
.stamp-info span{
|
||||
font-size: 15px !important;
|
||||
|
||||
}
|
||||
.order-info span{
|
||||
font-size: 15px !important;
|
||||
|
||||
}
|
||||
.print-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.print-table th, .print-table td {
|
||||
border: 1px solid #ddd;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
height: 20px; /* 设置固定高度 */
|
||||
line-height: 20px; /* 垂直居中 */
|
||||
}
|
||||
.print-table th {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
@media print {
|
||||
body { margin: 0; }
|
||||
.print-content {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
${printContent.innerHTML}
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
doc?.close()
|
||||
|
||||
iframe.onload = () => {
|
||||
iframe.contentWindow?.focus()
|
||||
iframe.contentWindow?.print()
|
||||
setTimeout(() => document.body.removeChild(iframe), 1000)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function limitTo20Chars(input) {
|
||||
if (typeof input !== 'string') return '';
|
||||
return input.length > 20 ? input.slice(0, 20) : input;
|
||||
}
|
||||
|
||||
|
||||
@ -1444,77 +1267,4 @@ a {
|
||||
color: #409eff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* 打印样式 */
|
||||
@media print {
|
||||
/* 隐藏所有非打印内容 */
|
||||
body * {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/* 只显示打印区域 */
|
||||
#printArea, #printArea * {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* 打印区域定位 */
|
||||
#printArea {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 隐藏弹窗相关元素 */
|
||||
.el-dialog, .el-dialog__wrapper, .el-dialog__header, .el-dialog__footer {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.order-info {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
}
|
||||
|
||||
.order-info span {
|
||||
font-size: 15px !important;
|
||||
margin-right: 10px !important;
|
||||
}
|
||||
.stamp-info {
|
||||
margin-top: 10px;
|
||||
|
||||
}
|
||||
.stamp-info span{
|
||||
font-size: 15px !important;
|
||||
|
||||
}
|
||||
.print-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 10px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.print-table th,
|
||||
.print-table td {
|
||||
border: 1px solid #ccc;
|
||||
padding: 6px 8px;
|
||||
text-align: center;
|
||||
font-size: 13px !important;
|
||||
height: 30px; /* 设置固定高度 */
|
||||
line-height: 30px; /* 垂直居中 */
|
||||
|
||||
}
|
||||
|
||||
.print-table th {
|
||||
background-color: #f5f7fa;
|
||||
color: #303133;
|
||||
font-weight: 600;
|
||||
font-size: 13px !important;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
@ -4,52 +4,28 @@
|
||||
<div class="header header-grid">
|
||||
<div class="cell company-title">
|
||||
<span class="company">杭州合立模具有限公司</span>
|
||||
<span class="title">入库管理单</span>
|
||||
<span class="title">{{ titleText }}</span>
|
||||
</div>
|
||||
<div class="cell audit"> 审核:<span class="sign-space"></span> </div>
|
||||
<div class="cell handler"> 委外加工经手人:<span class="sign-space"></span> </div>
|
||||
<div class="cell receiver"> 收货人:<span class="sign-space"></span> </div>
|
||||
<div class="cell handler" v-if="handlerLabel"> {{ handlerLabel }}:<span class="sign-space"></span> </div>
|
||||
<div class="cell receiver" v-if="receiverLabel"> {{ receiverLabel }}:<span class="sign-space"></span> </div>
|
||||
<div class="cell order-no" v-if="purchaseNo"> 订单编号:<span class="sign-space">{{ purchaseNo }}</span> </div>
|
||||
</div>
|
||||
|
||||
<table class="sheet" border="1" cellspacing="0" cellpadding="0">
|
||||
<!-- 固定列宽,总计 100% -->
|
||||
<colgroup>
|
||||
<col style="width: 4%" />
|
||||
<col style="width: 9%" />
|
||||
<col style="width: 7.5%" />
|
||||
<col style="width: 10%" />
|
||||
<col style="width: 5.5%" />
|
||||
<col style="width: 6%" />
|
||||
<col style="width: 6%" />
|
||||
<col style="width: 6%" />
|
||||
<col style="width: 6%" />
|
||||
<col v-for="col in columns" :key="col.key" :style="{ width: col.width }" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>编号</th>
|
||||
<th>入库单号</th>
|
||||
<th>入库类型</th>
|
||||
<th>上游单号</th>
|
||||
<th>入库仓库</th>
|
||||
<th>即入即出</th>
|
||||
<th>单据状态</th>
|
||||
<th>创建时间</th>
|
||||
<th>提交时间</th>
|
||||
<th v-for="col in columns" :key="col.key">{{ col.label }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="row in rows" :key="row['编号']">
|
||||
<td>{{ row['编号'] }}</td>
|
||||
<td class="text-left">{{ row['入库单号'] }}</td>
|
||||
<td class="text-left">{{ row['入库类型'] }}</td>
|
||||
<td class="text-left">{{ row['上游单号'] }}</td>
|
||||
<td class="text-left">{{ row['入库仓库'] }}</td>
|
||||
<td>{{ row['即入即出'] }}</td>
|
||||
<td>{{ row['单据状态'] }}</td>
|
||||
<td>{{ fmtDate(row['创建时间']) }}</td>
|
||||
<td>{{ fmtDate(row['提交时间']) }}</td>
|
||||
|
||||
<tr v-for="(row, idx) in rows" :key="idx">
|
||||
<td v-for="col in columns" :key="col.key" :class="col.align === 'left' ? 'text-left' : ''">
|
||||
{{ col.formatter ? col.formatter(row[col.key]) : row[col.key] }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -60,7 +36,7 @@
|
||||
<span class="name">{{ duEmpName }}</span>
|
||||
</div>
|
||||
<div class="sign-item"> 审核人:<span class="sign-space"></span> </div>
|
||||
<div class="sign-item"> 委外加工经手人:<span class="sign-space"></span> </div>
|
||||
<div class="sign-item" v-if="handlerLabel"> {{ handlerLabel }}:<span class="sign-space"></span> </div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -77,13 +53,15 @@ import { useRoute } from 'vue-router'
|
||||
import dayjs from 'dayjs'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
const userStore = useUserStore();
|
||||
const userName = userStore.getUser.nickname//nickname
|
||||
const userName = userStore.getUser.nickname
|
||||
console.log(userStore,`userStore`);
|
||||
|
||||
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const rows = ref<Record<string, any>[]>([])
|
||||
const columns = ref<any[]>([])
|
||||
const titleText = ref('入库管理单')
|
||||
const handlerLabel = ref('')
|
||||
const receiverLabel = ref('')
|
||||
|
||||
const duEmpName = computed(() => userName)
|
||||
|
||||
@ -91,16 +69,55 @@ const fmtDate = (v: any) => (v ? dayjs(v).format('YYYY-MM-DD') : '')
|
||||
const purchaseNo = ref('')
|
||||
const { query } = useRoute()
|
||||
import * as PurchaseOrderNoApi from '@/api/heli/purchaseorderno'
|
||||
|
||||
// 列表打印列配置(index.vue 用)
|
||||
const listColumns = [
|
||||
{ key: '编号', label: '编号', width: '4%', align: 'center' },
|
||||
{ key: '入库单号', label: '入库单号', width: '13%', align: 'left' },
|
||||
{ key: '入库类型', label: '入库类型', width: '8%', align: 'left' },
|
||||
{ key: '上游单号', label: '上游单号', width: '12%', align: 'left' },
|
||||
{ key: '入库仓库', label: '入库仓库', width: '8%', align: 'left' },
|
||||
{ key: '即入即出', label: '即入即出', width: '6%', align: 'center' },
|
||||
{ key: '单据状态', label: '单据状态', width: '7%', align: 'center' },
|
||||
{ key: '创建时间', label: '创建时间', width: '11%', align: 'center', formatter: fmtDate },
|
||||
{ key: '提交时间', label: '提交时间', width: '11%', align: 'center', formatter: fmtDate },
|
||||
]
|
||||
|
||||
// 单据详情打印列配置(StorageForm.vue 用)
|
||||
const detailColumns = [
|
||||
{ key: '编号', label: '序号', width: '6%', align: 'center' },
|
||||
{ key: '物料号', label: '物料号', width: '12%', align: 'left' },
|
||||
{ key: '零件名称', label: '零件名称', width: '10%', align: 'left' },
|
||||
{ key: '规格', label: '规格', width: '8%', align: 'left' },
|
||||
{ key: '单位', label: '单位', width: '6%', align: 'center' },
|
||||
{ key: '入库数量', label: '入库数量', width: '8%', align: 'center' },
|
||||
{ key: '单价', label: '单价(元)', width: '8%', align: 'center' },
|
||||
{ key: '小计', label: '小计(元)', width: '8%', align: 'center' },
|
||||
{ key: '项目名称', label: '项目名称', width: '12%', align: 'left' },
|
||||
{ key: '备注', label: '备注', width: '12%', align: 'left' },
|
||||
]
|
||||
|
||||
/**
|
||||
*
|
||||
* @param data 打印数据
|
||||
* @param str 采购订单号=订单编号 零件采购收货时,订单编号为空。 零件采购订单管理 不为空
|
||||
* @param data 打印数据(数组)
|
||||
* @param str 采购订单号(列表打印用)
|
||||
* @param mode 'list' 列表打印 | 'detail' 单据详情打印
|
||||
*/
|
||||
const open = (data: Record<string, any>[],str: string) => {
|
||||
const open = (data: Record<string, any>[], str: string, mode: string = 'list') => {
|
||||
rows.value = Array.isArray(data) ? data : []
|
||||
dialogVisible.value = true;
|
||||
purchaseNo.value = str;
|
||||
console.log(query.id);
|
||||
purchaseNo.value = str
|
||||
dialogVisible.value = true
|
||||
|
||||
if (mode === 'detail') {
|
||||
columns.value = detailColumns
|
||||
titleText.value = '入库管理单'
|
||||
handlerLabel.value = '委外加工经手人'
|
||||
receiverLabel.value = '收货人'
|
||||
} else {
|
||||
columns.value = listColumns
|
||||
titleText.value = '入库管理单'
|
||||
handlerLabel.value = '委外加工经手人'
|
||||
receiverLabel.value = '收货人'
|
||||
}
|
||||
}
|
||||
defineExpose({ open })
|
||||
|
||||
@ -201,7 +218,7 @@ const onPrint = () => {
|
||||
iframe.contentWindow!.focus()
|
||||
iframe.contentWindow!.print()
|
||||
setTimeout(() => document.body.removeChild(iframe), 500)
|
||||
if(query.id){//用来判断零件采购订单管理 id=true,=false零件采购收货
|
||||
if(query.id){
|
||||
PurchaseOrderNoApi.updateIsPrint(query.id);
|
||||
}
|
||||
}
|
||||
@ -209,7 +226,6 @@ const onPrint = () => {
|
||||
|
||||
<style scoped lang="less">
|
||||
.print-wrap {
|
||||
/* 预览时也按目标纸张尺寸展示,便于校对 */
|
||||
width: 100%;
|
||||
min-height: 140mm;
|
||||
background: #fff;
|
||||
@ -245,12 +261,10 @@ const onPrint = () => {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/* 签字空间样式 */
|
||||
.sign-space {
|
||||
display: inline-block;
|
||||
width: 70px;
|
||||
height: 18px;
|
||||
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user