feat(标签打印): 添加镀铬卷标签类型支持

新增镀铬卷(DuGeTag)标签组件,包含对应的样式和布局
在do.vue和LabelRender/index.vue中增加镀铬卷类型判断逻辑
调整标签尺寸配置以适配镀铬卷标签规格
This commit is contained in:
砂糖
2026-03-09 15:24:04 +08:00
parent bd5e0ac5e9
commit 1038b17a66
3 changed files with 509 additions and 1 deletions

View File

@@ -0,0 +1,488 @@
<template>
<div class="label-container" :style="{ '--print-scale': printScale }">
<div class="label-box">
<!-- 顶部公司信息 -->
<div class="company-header">
<div style="display: flex; align-items: center;">
<img :src="logo" alt="Company Logo" class="company-logo" />
<div class="company-name">
科伦普<br />
<span class="english-name">KE LUN PU</span>
</div>
</div>
<div class="title">嘉祥科伦普重工有限公司</div>
<img src="@/assets/images/pashi.png" alt="怕湿" class="company-logo" />
</div>
<!-- 核心信息网格布局替代原表格 -->
<div class="info-grid">
<!-- 第一行订货单位 + 合同号 -->
<div class="info-grid-item label-cell">订货单位</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.orderUnit || ''" />
</div>
<div class="info-grid-item label-cell">合同号</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.contractNumber || ''" />
</div>
<!-- 第二行执行标准 + 钢卷号 -->
<div class="info-grid-item label-cell">产品名称</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.itemName || ''" />
</div>
<div class="info-grid-item label-cell">执行标准</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.executionStandard || ''" />
</div>
<div class="info-grid-item label-cell">钢卷号</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.currentCoilNo || ''" />
</div>
<!-- 第三行原料卷号 + 规格 -->
<div class="info-grid-item label-cell">原料卷号</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.enterCoilNo || ''" />
</div>
<div class="info-grid-item label-cell">规格</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.specification || ''" />
</div>
<!-- 第四行材质 + 表面质量 -->
<div class="info-grid-item label-cell">材质</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="materialWithManufacturer || ''" />
</div>
<div class="info-grid-item label-cell">表面状态</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.surfaceTreatmentDesc || ''" />
</div>
<div class="info-grid-item label-cell">调制度</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.temperGrade || ''" />
</div>
<div class="info-grid-item label-cell">产品等级</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.qualityStatus || ''" />
</div>
<!-- 第五行表面处理 + 剪切要求 -->
<!-- <div class="info-grid-item label-cell">表面处理</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.surfaceTreatmentDesc || ''" />
</div>
<div class="info-grid-item label-cell">切边要求</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.trimmingRequirement || ''" />
</div> -->
<!-- 第六行包装种类 + 毛重 -->
<div class="info-grid-item label-cell">镀层质量</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.zincLayer || ''" />
</div>
<div class="info-grid-item label-cell">毛重</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.grossWeight || ''" />
</div>
<!-- 第七行净重 + 参考长度 -->
<div class="info-grid-item label-cell">净重</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.netWeight || ''" />
</div>
<div class="info-grid-item label-cell">参考长度</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="content.length || ''" />
</div>
<!-- 第八行生产日期跨3列 -->
<div class="info-grid-item label-cell">生产日期</div>
<div class="info-grid-item value-cell">
<input type="text" class="nob" :value="parseTime(content.updateTime, '{y}-{m}-{d}')" />
</div>
</div>
<!-- 底部信息 -->
<div class="footer-info">
<div class="address">
地址山东省济宁市嘉祥县开发区生物产业园区新民路北<br />
<span class="english-address">Address: North Extension of Xinmin Road,Bio-Industrial Park,Development
Zone,<br />
Jiaxiang County,Jining City,Shandong Province</span>
<br />
<span>
TEL0537-6625068 0537-6625067
</span>
</div>
<div class="contact-timestamp">
<!-- 放大二维码占用更多下方空间弱化底部留白感 -->
<QRCode :content="content.qrcodeRecordId || ''" :size="90" />
</div>
</div>
</div>
</div>
</template>
<script>
import logo from '@/assets/logo/logo.png'
import QRCode from '../../../print/components/QRCode.vue';
export default {
name: 'MetalSheetLabel',
components: {
QRCode
},
props: {
content: {
type: Object,
default: () => ({
// form3 所有字段
orderUnit: '',
contractNumber: '',
productName: '镀锌卷板合格品(GI)',
executionStandard: '',
coilNumber: 'D2Z125031809202',
rawBlankNumber: '',
specification: '2.28*1250',
material: '',
qualityStatus: '',
surfaceTreatmentDesc: '环保钝化/不涂油',
trimmingRequirement: '',
packagingRequirement: 'A03',
grossWeight: '',
netWeight: '7080',
referenceLength: '320',
length: '320',
productionDate: '2025-03-19',
// 底部信息字段
address: '唐山市滦州市茨榆坨工业区',
englishAddress: 'Donghai special steel, ciyutuo Industrial Zone, Luanzhou, Tangshan, Hebei province, China.',
tel: '0315-7560777',
timestamp: '2025.04.12 10:14',
qrcodeRecordId: '',
})
},
paperWidthMm: {
type: Number,
default: 180
},
paperHeightMm: {
type: Number,
default: 100
}
},
computed: {
// 材质展示信息,额外带上厂家的首字母
materialWithManufacturer() {
return this.content.material
}
},
data() {
return {
logo,
printScale: 1,
}
},
mounted() {
// 使用 matchMedia 监听打印状态(更可靠)
this.printMediaQuery = window.matchMedia('print');
this.printMediaQuery.addListener(this.handlePrintMediaChange);
// 监听打印事件作为备用
window.addEventListener('beforeprint', this.handleBeforePrint);
window.addEventListener('afterprint', this.handleAfterPrint);
// 计算初始缩放比例
this.$nextTick(() => {
this.calculatePrintScale();
});
},
beforeDestroy() {
if (this.printMediaQuery) {
this.printMediaQuery.removeListener(this.handlePrintMediaChange);
}
window.removeEventListener('beforeprint', this.handleBeforePrint);
window.removeEventListener('afterprint', this.handleAfterPrint);
},
methods: {
handlePrintMediaChange(mq) {
if (mq.matches) {
// 进入打印模式
this.calculatePrintScale();
} else {
// 退出打印模式
this.resetPrintScale();
}
},
handleBeforePrint() {
// 延迟计算确保DOM已更新
setTimeout(() => {
this.calculatePrintScale();
}, 100);
},
handleAfterPrint() {
this.resetPrintScale();
},
calculatePrintScale() {
this.$nextTick(() => {
const container = this.$el;
if (!container) return;
// 纸张尺寸180mm x 100mm
// 在打印时,使用 mm 单位更准确
// 1mm = 3.779527559px (96 DPI) 或 1mm = 3.779527559px (72 DPI)
// 为了更准确,我们直接使用 mm 转 px 的通用计算
const dpi = 96; // 标准 DPI
const mmToPx = dpi / 25.4; // 1mm = 3.779527559px
const paperWidthMm = this.paperWidthMm || 180;
const paperHeightMm = this.paperHeightMm || 100;
const marginMm = 2;
const paperWidthPx = paperWidthMm * mmToPx;
const paperHeightPx = paperHeightMm * mmToPx;
const marginPx = marginMm * mmToPx;
// 获取内容实际尺寸(在屏幕上的尺寸)
const rect = container.getBoundingClientRect();
let contentWidth = rect.width;
let contentHeight = rect.height;
// 如果尺寸为0或无效尝试使用 scrollWidth/scrollHeight
if (contentWidth === 0 || contentHeight === 0) {
contentWidth = container.scrollWidth || contentWidth;
contentHeight = container.scrollHeight || contentHeight;
}
// 计算可用空间(减去边距)
const availableWidth = paperWidthPx - marginPx * 2;
const availableHeight = paperHeightPx - marginPx * 2;
// 计算缩放比例
const scaleX = contentWidth > 0 ? availableWidth / contentWidth : 1;
const scaleY = contentHeight > 0 ? availableHeight / contentHeight : 1;
// 取较小的缩放比例确保内容完全适配不超过1不放大
this.printScale = Math.min(scaleX, scaleY, 1);
// 设置CSS变量和内联样式
container.style.setProperty('--print-scale', this.printScale);
container.style.setProperty('--paper-width', `${paperWidthMm}mm`);
container.style.setProperty('--paper-height', `${paperHeightMm}mm`);
console.log('打印缩放计算:', {
contentSize: { width: contentWidth, height: contentHeight },
paperSize: { width: paperWidthPx, height: paperHeightPx },
scale: this.printScale
});
});
},
resetPrintScale() {
this.printScale = 1;
if (this.$el) {
this.$el.style.setProperty('--print-scale', 1);
this.$el.style.removeProperty('--paper-width');
this.$el.style.removeProperty('--paper-height');
}
}
}
}
</script>
<style scoped>
.label-container {
padding: 1em;
/* width: 680.315px; */
/* height: 377.953px; */
/* width: fit-content;
height: fit-content; */
/* 减少内边距避免生成PDF时上下留白不一致 */
/* padding: 0.1em;
font-size: 12px;
border: 1px solid #000;
box-sizing: border-box;
font-family: 'Arial', sans-serif; */
/* border: 1px solid #000; */
}
.label-box {
width: fit-content;
height: fit-content;
/* margin: 1em; */
padding: 0.1em;
font-size: 12px;
border: 1px solid #000;
box-sizing: border-box;
font-family: 'Arial', sans-serif;
}
.company-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 0.3em;
position: relative;
/* 为绝对定位的 title 提供定位上下文 */
}
.company-logo {
width: 5em;
height: 5em;
margin-right: 0.5em;
}
.company-name {
font-size: 1.2em;
font-weight: bold;
line-height: 1.1;
}
.title {
position: absolute;
/* 绝对定位,脱离 flex 流 */
left: 50%;
/* 从左边50%开始 */
transform: translateX(-50%);
/* 向左移动自身宽度的50%,实现居中 */
font-size: 2em;
font-weight: bold;
text-align: center;
white-space: nowrap;
/* 防止文字换行 */
}
.english-name {
width: 100%;
font-size: 1em;
opacity: 0.9;
letter-spacing: 0.08em;
}
.product-title {
font-size: 1.4em;
font-weight: bold;
text-align: center;
margin-bottom: 0.4em;
border-bottom: 1.5px solid #000;
padding-bottom: 0.2em;
}
/* 网格布局核心样式 */
.info-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
/* 4列等宽 */
gap: 0;
/* 消除网格间距,确保边框连贯 */
margin-bottom: 0.5em;
}
.info-grid-item {
border: 1px solid #000;
padding: 0.1em;
font-size: 1.05em;
height: 2em;
text-align: center;
vertical-align: middle;
word-break: break-all;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
}
/* 生产日期跨3列 */
.date-colspan {
grid-column: span 3;
/* 占据3列 */
}
.footer-info {
display: flex;
justify-content: space-between;
align-items: flex-start;
font-size: 0.85em;
margin-top: 0.2em;
}
.address {
line-height: 1.25;
width: 80%;
font-size: 1.3em;
}
.english-address {
opacity: 0.9;
font-size: 1.1em;
line-height: 1.15;
word-break: normal;
/* 正常换行,只在单词边界(空格)处换行 */
overflow-wrap: normal;
/* 不在单词内部断行,保持单词完整 */
}
.contact-timestamp {
text-align: right;
line-height: 1.2;
}
.nob {
width: 100%;
height: 100%;
border: none;
outline: none;
background: transparent;
text-align: center;
}
/* 打印样式 - 强制单页适配180mm x 100mm纸张保持原有样式不变 */
@media print {
@page {
size: 180mm 100mm;
margin: 0 !important;
padding: 0 !important;
}
* {
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
html,
body {
margin: 0 !important;
padding: 0 !important;
overflow: hidden !important;
}
/* 隐藏所有其他内容,只显示标签容器 */
body>*:not(.label-container) {
display: none !important;
}
.label-container {
/* 防止分页 - 多重保护 */
page-break-inside: avoid !important;
break-inside: avoid !important;
page-break-after: avoid !important;
break-after: avoid !important;
page-break-before: avoid !important;
break-before: avoid !important;
orphans: 999 !important;
widows: 999 !important;
/* 应用动态缩放,保持原有样式 */
transform: scale(var(--print-scale, 1)) !important;
transform-origin: top left !important;
/* 确保缩放后不超出纸张 */
max-width: var(--paper-width, 180mm) !important;
max-height: var(--paper-height, 100mm) !important;
overflow: hidden !important;
}
}
</style>

View File

@@ -29,8 +29,14 @@
<ZincRawTag
v-if="tagType === '5'"
:content="content"
:paperWidthMm="100"
:paperHeightMm="80"
/>
<DuGeTag
v-if="tagType === 'ge'"
:content="content"
:paperWidthMm="180"
:paperHeightMm="100"
:paperHeightMm="80"
/>
<!-- <SampleTagPreview v-if="labelType === '4'" :content="content" />
<ForgeTagPreview v-if="labelType === '5'" :content="content" />
@@ -54,6 +60,7 @@ import OuterTagPreview from './OuterTagPreview.vue';
import GalvanizedTag from './GalvanizedTag.vue';
import WhereTag from './WhereTag.vue';
import ZincRawTag from './ZincRawTag.vue';
import DuGeTag from './DuGeTag.vue';
// import SampleTagPreview from './SampleTagPreview.vue';
// import ForgeTagPreview from './ForgeTagPreview.vue';
@@ -67,6 +74,7 @@ export default {
GalvanizedTag,
WhereTag,
ZincRawTag,
DuGeTag,
// SampleTagPreview,
// ForgeTagPreview,
// SaltSprayTagPreview,
@@ -87,6 +95,10 @@ export default {
width: 180,
height: 100,
},
'ge': {
width: 180,
height: 100,
},
'where': {
width: 100,
height: 80,
@@ -141,6 +153,8 @@ export default {
this.labelType = '4';
} else if (itemType == 'product' && itemName == '冷轧卷') {
this.labelType = '3';
} else if (itemType == 'product' && itemName == '镀铬卷') {
this.labelType = 'ge'
} else {
this.labelType = '3';
}

View File

@@ -565,6 +565,10 @@ export default {
width: 180,
height: 100,
},
'ge': {
width: 180,
height: 80,
},
'where': {
width: 100,
height: 80,
@@ -669,6 +673,8 @@ export default {
this.labelRender.type = '4';
} else if (itemType == 'product' && itemName == '冷轧卷') {
this.labelRender.type = '3';
} else if (itemType == 'product' && itemName == '镀铬卷') {
this.labelRender.type = 'ge';
} else {
this.labelRender.type = '3';
}