feat(wms): 优化发货单和钢卷管理功能
- 修改重量单位从kg为T - 发货单增加仓库位置列和禁用已发货单操作 - 优化钢卷卡片UI样式 - 改进打印功能使用PDF格式 - 增加发货单状态判断和编辑控制
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user