feat(wms): 优化发货单和钢卷管理功能

- 修改重量单位从kg为T
- 发货单增加仓库位置列和禁用已发货单操作
- 优化钢卷卡片UI样式
- 改进打印功能使用PDF格式
- 增加发货单状态判断和编辑控制
This commit is contained in:
砂糖
2026-01-27 15:41:29 +08:00
parent ad74b9df01
commit 522f3400fc
5 changed files with 220 additions and 133 deletions

View File

@@ -12,7 +12,7 @@
<input type="text" class="editable-input date-input transparent-input" v-model="localWaybill.deliveryYear" />
<span class="label date-label"></span>
<input type="text" class="editable-input date-input transparent-input" v-model="localWaybill.deliveryMonth" />
<span class="label date-label"></span>
<span class="label date-label"></span>
<input type="text" class="editable-input date-input transparent-input" v-model="localWaybill.deliveryDay" />
<span class="label date-label"></span>
</div>
@@ -22,7 +22,7 @@
</div>
</div>
<div class="waybill-header">
<div class="waybill-header">
<div class="header-left">
<span class="label">负责人</span>
<input type="text" class="editable-input transparent-input" v-model="localWaybill.principal" />
@@ -44,13 +44,14 @@
<th>品名</th>
<th>切边</th>
<th>包装</th>
<th>仓库位置</th>
<th>结算</th>
<th>原料厂家</th>
<th>卷号</th>
<th>规格</th>
<th>材质</th>
<th>数量</th>
<th>重量kg</th>
<th>重量T</th>
<th>单价</th>
<th>备注</th>
</tr>
@@ -58,7 +59,7 @@
<tbody>
<!-- 无明细提示 -->
<tr v-if="localWaybillDetails.length === 0">
<td colspan="12" class="no-data">
<td colspan="13" class="no-data">
<div class="no-data-content">
<el-empty description="暂无发货单明细" />
</div>
@@ -71,6 +72,8 @@
</td>
<td><input type="text" class="table-input transparent-input" v-model="item.packageType" />
</td>
<td><input type="text" class="table-input transparent-input" v-model="item.actualWarehouseName" />
</td>
<td><input type="text" class="table-input transparent-input" v-model="item.settlementType" />
</td>
<td><input type="text" class="table-input transparent-input" v-model="item.rawMaterialFactory" />
@@ -98,13 +101,15 @@
<!-- 备注说明 -->
<div class="waybill-remarks">
<p>1品名冷硬钢卷酸连轧冷轧钢卷脱脂退火火拉矫镀锌卷板镀锌管料镀锌分剪料2切边净边/毛边3包装裸包周三径四简包1周三径四内外护角简包2周三径四+防锈纸普包周三径四+内外护角+防锈纸+端护板精包1周三径四+内外护角+防锈纸+薄膜+端护板+内外护板精包2周三径四+内外护角+防锈纸+薄膜+端护板+内外护板+木托</p>
<p>
1品名冷硬钢卷酸连轧冷轧钢卷脱脂退火火拉矫镀锌卷板镀锌管料镀锌分剪料2切边净边/毛边3包装裸包周三径四简包1周三径四内外护角简包2周三径四+防锈纸普包周三径四+内外护角+防锈纸+端护板精包1周三径四+内外护角+防锈纸+薄膜+端护板+内外护板精包2周三径四+内外护角+防锈纸+薄膜+端护板+内外护板+木托
</p>
</div>
<div class="waybill-pickup-location">
<!-- <div class="pickup-location-item inline"> -->
<span class="label">取货地点</span>
<input type="text" class="editable-input full-input transparent-input" v-model="localWaybill.pickupLocation" />
<span class="label">取货地点</span>
<input type="text" class="editable-input full-input transparent-input" v-model="localWaybill.pickupLocation" />
<!-- </div> -->
</div>
@@ -134,7 +139,8 @@
<script>
import domtoimage from 'dom-to-image';
import printJS from 'print-js';
import { PDFDocument } from 'pdf-lib';
import html2canvas from 'html2canvas';
export default {
props: {
@@ -231,15 +237,15 @@ export default {
// 确保容器在保存图片时能完整显示所有内容
const originalWidth = node.style.width;
const originalOverflow = node.style.overflow;
// 临时调整容器样式,确保所有内容可见
node.style.width = 'auto';
node.style.overflow = 'visible';
// 获取实际内容宽度
const contentWidth = node.scrollWidth;
const contentHeight = node.scrollHeight;
domtoimage.toPng(node, {
width: contentWidth,
height: contentHeight,
@@ -266,32 +272,73 @@ export default {
});
},
// 打印发货单
printWaybill() {
async printWaybill() {
const node = this.$refs.waybillRef;
// 确保容器在打印时能完整显示所有内容
const originalWidth = node.style.width;
const originalHeight = node.style.height;
const paperWidthMm = 297;
const paperHeightMm = 180;
const originalOverflow = node.style.overflow;
// 临时调整容器样式,确保所有内容可见
node.style.width = 'auto';
node.style.overflow = 'visible';
// 获取实际内容宽度
const contentWidth = node.scrollWidth;
printJS({
printable: node,
maxWidth: contentWidth,
type: 'html',
scanStyles: true,
style: `
@page { size: A4 landscape; margin: 1cm; }
.waybill-container { width: 100%; max-width: none; overflow: visible; }
.waybill-table { width: 100%; table-layout: auto; }
`,
targetStyles: ['*']
const contentHeight = node.scrollHeight;
// console.log('contentWidth', contentWidth, originalWidth, originalHeight);
// 改用html2canvas + pdf-lib打印pdf
const canvas = await html2canvas(node, {
backgroundColor: '#ffffff',
scale: 3,
useCORS: true,
// 让 html2canvas 为频繁读回优化 Canvas与批量导出一致
willReadFrequently: true,
// 确保按元素尺寸截图,明确指定宽高
width: contentWidth,
height: contentHeight,
windowWidth: contentWidth,
windowHeight: contentHeight,
});
// 5. 使用 pdf-lib 生成单页 PDF占满整张纸无边距
const mmToPt = 72 / 25.4;
const pageWidthPt = paperWidthMm * mmToPt;
const pageHeightPt = paperHeightMm * mmToPt;
const pdfDoc = await PDFDocument.create();
console.log('canvas', canvas);
const png = canvas.toDataURL('image/png');
const imgPng = await pdfDoc.embedPng(png);
// 确保页面尺寸正确宽100mm高80mm横向
const page = pdfDoc.addPage([pageWidthPt, pageHeightPt]);
// 直接拉伸填充整个PDF页面不留边距确保占满整张纸
// 从(0,0)开始,直接填充整个页面尺寸
page.drawImage(imgPng, {
x: 0,
y: 0,
width: pageWidthPt,
height: pageHeightPt
});
const pdfBytes = await pdfDoc.save();
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const win = window.open(url, '_blank');
if (!win) {
const a = document.createElement('a');
a.href = url;
a.download = `标签_${new Date().getTime()}.pdf`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
// 恢复原始样式
setTimeout(() => {
node.style.width = originalWidth;
@@ -304,7 +351,7 @@ export default {
<style scoped>
.waybill-container {
width: 850px;
width: 960px;
max-width: none;
min-width: 850px;
margin: 0 auto;
@@ -407,62 +454,80 @@ export default {
/* 表格列宽设置 */
.waybill-table th:nth-child(1),
.waybill-table td:nth-child(1) {
width: 80px; /* 品名 */
width: 80px;
/* 品名 */
}
.waybill-table th:nth-child(2),
.waybill-table td:nth-child(2) {
width: 40px; /* 切边 */
width: 40px;
/* 切边 */
}
.waybill-table th:nth-child(3),
.waybill-table td:nth-child(3) {
width: 40px; /* 包装 */
width: 40px;
/* 包装 */
}
.waybill-table th:nth-child(4),
.waybill-table td:nth-child(4) {
width: 40px; /* 结算 */
width: 80px;
/* 仓库位置 */
}
.waybill-table th:nth-child(5),
.waybill-table td:nth-child(5) {
width: 80px; /* 原料厂家 */
width: 40px;
/* 结算 */
}
.waybill-table th:nth-child(6),
.waybill-table td:nth-child(6) {
width: 100px; /* 卷号 */
width: 80px;
/* 原料厂家 */
}
.waybill-table th:nth-child(7),
.waybill-table td:nth-child(7) {
width: 80px; /* 规格 */
width: 100px;
/* 卷号 */
}
.waybill-table th:nth-child(8),
.waybill-table td:nth-child(8) {
width: 40px; /* 材质 */
width: 80px;
/* 规格 */
}
.waybill-table th:nth-child(9),
.waybill-table td:nth-child(9) {
width: 60px; /* 数量(件) */
width: 40px;
/* 材质 */
}
.waybill-table th:nth-child(10),
.waybill-table td:nth-child(10) {
width: 60px; /* 重量kg */
width: 60px;
/* 数量(件) */
}
.waybill-table th:nth-child(11),
.waybill-table td:nth-child(11) {
width: 40px; /* 单价 */
width: 80px;
/* 重量kg */
}
.waybill-table th:nth-child(12),
.waybill-table td:nth-child(12) {
width: 100px; /* 备注 */
width: 40px;
/* 单价 */
}
.waybill-table th:nth-child(13),
.waybill-table td:nth-child(13) {
width: 100px;
/* 备注 */
}
.waybill-table th {
@@ -594,23 +659,23 @@ export default {
box-shadow: none;
padding: 0;
}
.waybill-header {
flex-wrap: nowrap;
justify-content: space-between;
}
.waybill-footer {
flex-wrap: nowrap;
justify-content: space-between;
}
.label {
width: 80px;
text-align: right;
white-space: nowrap;
}
.waybill-actions {
display: none;
}
@@ -623,26 +688,26 @@ export default {
gap: 15px;
align-items: flex-start;
}
.waybill-table {
font-size: 12px;
}
.waybill-table th,
.waybill-table td {
padding: 2px;
}
.waybill-footer {
flex-direction: column;
align-items: flex-start;
gap: 15px;
}
.footer-item.inline {
width: 100%;
}
.label {
width: auto;
text-align: left;