Merge remote-tracking branch 'origin/0.8.X' into 0.8.X
This commit is contained in:
@@ -48,6 +48,7 @@
|
|||||||
"dom-to-image": "^2.6.0",
|
"dom-to-image": "^2.6.0",
|
||||||
"echarts": "5.4.0",
|
"echarts": "5.4.0",
|
||||||
"element-ui": "2.15.12",
|
"element-ui": "2.15.12",
|
||||||
|
"exceljs": "^4.4.0",
|
||||||
"file-saver": "2.0.5",
|
"file-saver": "2.0.5",
|
||||||
"flv.js": "^1.6.2",
|
"flv.js": "^1.6.2",
|
||||||
"fuse.js": "6.4.3",
|
"fuse.js": "6.4.3",
|
||||||
|
|||||||
44
klp-ui/src/views/wms/coil/allocation.vue
Normal file
44
klp-ui/src/views/wms/coil/allocation.vue
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<el-tabs class="app-container" v-model="activeTab">
|
||||||
|
<el-tab-pane label="待收卷" name="second">
|
||||||
|
<BasePage :qrcode="qrcode" :querys="querys2" :labelType="labelType" :hideWarehouseQuery="hideWarehouseQuery"
|
||||||
|
:hideType="hideType" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="已收卷" name="first">
|
||||||
|
<BasePage :qrcode="qrcode" :querys="querys" :labelType="labelType" :hideWarehouseQuery="hideWarehouseQuery"
|
||||||
|
:hideType="hideType" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BasePage from './panels/base.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
BasePage
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
qrcode: false,
|
||||||
|
activeTab: 'second',
|
||||||
|
querys: {
|
||||||
|
dataType: 1,
|
||||||
|
status: 0,
|
||||||
|
warehouseIds: '2019583656787259393,2019583325311414274,2019583137616310273,2019583429955104769', // 技术部逻辑库
|
||||||
|
// materialType: '废品'
|
||||||
|
},
|
||||||
|
querys2: {
|
||||||
|
dataType: 1,
|
||||||
|
status: 0,
|
||||||
|
nextWarehouseIds: '2019583656787259393,2019583325311414274,2019583137616310273,2019583429955104769', // 技术部逻辑库
|
||||||
|
// materialType: '废品'
|
||||||
|
},
|
||||||
|
hideWarehouseQuery: true,
|
||||||
|
showAbnormal: true,
|
||||||
|
labelType: '2',
|
||||||
|
hideType: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
297
klp-ui/src/views/wms/coil/panels/LabelRender/WhereTag.vue
Normal file
297
klp-ui/src/views/wms/coil/panels/LabelRender/WhereTag.vue
Normal file
@@ -0,0 +1,297 @@
|
|||||||
|
<template>
|
||||||
|
<div class="label-container" :style="{ '--print-scale': printScale }">
|
||||||
|
<table class="material-label-table">
|
||||||
|
<tr>
|
||||||
|
<td class="label-cell" style="width: 16.67%; padding: 4px;">卷号</td>
|
||||||
|
<td class="value-cell" colspan="2" style="width: 33.33%; padding: 4px;">
|
||||||
|
<div class="nob" contenteditable>{{ content.currentCoilNo || '' }}</div>
|
||||||
|
</td>
|
||||||
|
<td class="label-cell" style="width: 16.67%; padding: 4px;">来源</td>
|
||||||
|
<td class="value-cell" colspan="2" style="width: 33.33%; padding: 4px;">
|
||||||
|
<div class="nob" contenteditable>{{ content.warehouseName || '' }}</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="label-cell" style="width: 16.67%; padding: 4px;">班组</td>
|
||||||
|
<td class="value-cell" colspan="2" style="width: 33.33%; padding: 4px;">
|
||||||
|
<div class="nob" contenteditable>{{ content.team || '' }}</div>
|
||||||
|
</td>
|
||||||
|
<td class="label-cell" style="width: 16.67%; padding: 4px;">净重</td>
|
||||||
|
<td class="value-cell" colspan="2" style="width: 33.33%; padding: 4px;">
|
||||||
|
<div class="nob" contenteditable>{{ content.netWeight || '' }}</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="label-cell" style="width: 16.67%; padding: 4px;">规格</td>
|
||||||
|
<td class="value-cell" colspan="2" style="width: 33.33%; padding: 4px;">
|
||||||
|
<div class="nob" contenteditable>{{ content.specification || '' }}</div>
|
||||||
|
</td>
|
||||||
|
<td class="label-cell" style="width: 16.67%; padding: 4px;">材质</td>
|
||||||
|
<td class="value-cell" colspan="2" style="width: 33.33%; padding: 4px;">
|
||||||
|
<div class="nob" contenteditable>{{ content.material || '' }}</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="label-cell" style="width: 16.67%; padding: 4px;">卷名</td>
|
||||||
|
<td class="value-cell" colspan="2" style="width: 33.33%; padding: 4px;">
|
||||||
|
<div class="nob" contenteditable>{{ content.itemName || '' }}</div>
|
||||||
|
</td>
|
||||||
|
<td class="label-cell" style="width: 16.67%; padding: 4px;">厂家</td>
|
||||||
|
<td class="value-cell" colspan="2" style="width: 33.33%; padding: 4px;">
|
||||||
|
<div class="nob" contenteditable>{{ content.manufacturer || '' }}</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="label-cell" style="width: 16.67%; padding: 4px;">时间</td>
|
||||||
|
<td class="value-cell" colspan="2" style="width: 33.33%; padding: 4px;">
|
||||||
|
<div class="nob" contenteditable>{{ content.updateTime || '' }}</div>
|
||||||
|
</td>
|
||||||
|
<td class="label-cell" style="width: 16.67%; padding: 4px;">去向</td>
|
||||||
|
<td class="value-cell" colspan="2" style="width: 33.33%; padding: 4px;">
|
||||||
|
<div class="nob" contenteditable>{{ content.nextWarehouseName || '' }}</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'WhereTag',
|
||||||
|
props: {
|
||||||
|
content: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
coilNumber: '',
|
||||||
|
specification: '',
|
||||||
|
netWeight: '',
|
||||||
|
material: '',
|
||||||
|
nextProcess: '',
|
||||||
|
productionTeam: '',
|
||||||
|
productionDate: '',
|
||||||
|
qrcodeRecordId: '',
|
||||||
|
})
|
||||||
|
},
|
||||||
|
paperWidthMm: {
|
||||||
|
type: Number,
|
||||||
|
default: 100 // 原料码:100mm x 80mm(宽100,高80)
|
||||||
|
},
|
||||||
|
paperHeightMm: {
|
||||||
|
type: Number,
|
||||||
|
default: 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
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
|
||||||
|
const dpi = 96; // 标准 DPI
|
||||||
|
const mmToPx = dpi / 25.4; // 1mm = 3.779527559px
|
||||||
|
|
||||||
|
const paperWidthMm = this.paperWidthMm || 100;
|
||||||
|
const paperHeightMm = this.paperHeightMm || 80;
|
||||||
|
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`);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
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 {
|
||||||
|
width: 25em;
|
||||||
|
height: 20em;
|
||||||
|
padding: 0px;
|
||||||
|
display: flex;
|
||||||
|
/* 启用Flex布局 */
|
||||||
|
flex-direction: column;
|
||||||
|
/* 子元素垂直排列 */
|
||||||
|
font-family: "SimSun", serif;
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* 确保内边距/边框不影响总尺寸 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-label-table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
table-layout: fixed;
|
||||||
|
flex-grow: 1;
|
||||||
|
/* 让表格拉伸,占满剩余垂直空间 */
|
||||||
|
height: 0;
|
||||||
|
/* 配合flex-grow,自动计算高度 */
|
||||||
|
border: 1px solid #333;
|
||||||
|
/* 确保表格有最外层边框 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 四列均分宽度,每列占25% */
|
||||||
|
.material-label-table td {
|
||||||
|
border: 1px solid #333;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
/* width: 25%; */
|
||||||
|
box-sizing: border-box;
|
||||||
|
text-align: center;
|
||||||
|
word-break: break-all;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
white-space: normal;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-cell {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value-cell {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nob {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
background: transparent;
|
||||||
|
text-align: center;
|
||||||
|
font-size: inherit;
|
||||||
|
word-break: break-all;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 打印样式 - 强制单页,适配100mm x 80mm纸张,保持原有样式不变 */
|
||||||
|
@media print {
|
||||||
|
@page {
|
||||||
|
size: 100mm 80mm;
|
||||||
|
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(.material-label-container) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-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, 100mm) !important;
|
||||||
|
max-height: var(--paper-height, 80mm) !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -3,23 +3,29 @@
|
|||||||
<!-- 标签预览容器 -->
|
<!-- 标签预览容器 -->
|
||||||
<div class="preview-container" :id="hideActions ? undefined : 'label-preview-container'" ref="labelRef">
|
<div class="preview-container" :id="hideActions ? undefined : 'label-preview-container'" ref="labelRef">
|
||||||
<MaterialTag
|
<MaterialTag
|
||||||
v-if="labelType === '2'"
|
v-if="tagType === '2'"
|
||||||
:content="content"
|
:content="content"
|
||||||
:paperWidthMm="100"
|
:paperWidthMm="100"
|
||||||
:paperHeightMm="80"
|
:paperHeightMm="80"
|
||||||
/>
|
/>
|
||||||
<OuterTagPreview
|
<OuterTagPreview
|
||||||
v-if="labelType === '3'"
|
v-if="tagType === '3'"
|
||||||
:content="content"
|
:content="content"
|
||||||
:paperWidthMm="180"
|
:paperWidthMm="180"
|
||||||
:paperHeightMm="100"
|
:paperHeightMm="100"
|
||||||
/>
|
/>
|
||||||
<GalvanizedTag
|
<GalvanizedTag
|
||||||
v-if="labelType === '4'"
|
v-if="tagType === '4'"
|
||||||
:content="content"
|
:content="content"
|
||||||
:paperWidthMm="180"
|
:paperWidthMm="180"
|
||||||
:paperHeightMm="100"
|
:paperHeightMm="100"
|
||||||
/>
|
/>
|
||||||
|
<WhereTag
|
||||||
|
v-if="tagType === 'where'"
|
||||||
|
:content="content"
|
||||||
|
:paperWidthMm="100"
|
||||||
|
:paperHeightMm="80"
|
||||||
|
/>
|
||||||
<!-- <SampleTagPreview v-if="labelType === '4'" :content="content" />
|
<!-- <SampleTagPreview v-if="labelType === '4'" :content="content" />
|
||||||
<ForgeTagPreview v-if="labelType === '5'" :content="content" />
|
<ForgeTagPreview v-if="labelType === '5'" :content="content" />
|
||||||
<SaltSprayTagPreview v-if="labelType === '6'" :content="content" /> -->
|
<SaltSprayTagPreview v-if="labelType === '6'" :content="content" /> -->
|
||||||
@@ -40,6 +46,7 @@ import { PDFDocument } from 'pdf-lib';
|
|||||||
import MaterialTag from './MaterialTag.vue';
|
import MaterialTag from './MaterialTag.vue';
|
||||||
import OuterTagPreview from './OuterTagPreview.vue';
|
import OuterTagPreview from './OuterTagPreview.vue';
|
||||||
import GalvanizedTag from './GalvanizedTag.vue';
|
import GalvanizedTag from './GalvanizedTag.vue';
|
||||||
|
import WhereTag from './WhereTag.vue';
|
||||||
// import SampleTagPreview from './SampleTagPreview.vue';
|
// import SampleTagPreview from './SampleTagPreview.vue';
|
||||||
// import ForgeTagPreview from './ForgeTagPreview.vue';
|
// import ForgeTagPreview from './ForgeTagPreview.vue';
|
||||||
// import SaltSprayTagPreview from './SaltSprayTagPreview.vue';
|
// import SaltSprayTagPreview from './SaltSprayTagPreview.vue';
|
||||||
@@ -50,6 +57,7 @@ export default {
|
|||||||
MaterialTag,
|
MaterialTag,
|
||||||
OuterTagPreview,
|
OuterTagPreview,
|
||||||
GalvanizedTag,
|
GalvanizedTag,
|
||||||
|
WhereTag,
|
||||||
// SampleTagPreview,
|
// SampleTagPreview,
|
||||||
// ForgeTagPreview,
|
// ForgeTagPreview,
|
||||||
// SaltSprayTagPreview,
|
// SaltSprayTagPreview,
|
||||||
@@ -57,6 +65,32 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
labelType: '2',
|
labelType: '2',
|
||||||
|
tagSizeMap: {
|
||||||
|
'2': {
|
||||||
|
width: 100,
|
||||||
|
height: 80,
|
||||||
|
},
|
||||||
|
'3': {
|
||||||
|
width: 180,
|
||||||
|
height: 100,
|
||||||
|
},
|
||||||
|
'4': {
|
||||||
|
width: 180,
|
||||||
|
height: 100,
|
||||||
|
},
|
||||||
|
'where': {
|
||||||
|
width: 100,
|
||||||
|
height: 80,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
tagType() {
|
||||||
|
if (this.forceSpecialTag) {
|
||||||
|
return this.forceSpecialTag;
|
||||||
|
}
|
||||||
|
return this.labelType;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
@@ -64,6 +98,10 @@ export default {
|
|||||||
// type: String,
|
// type: String,
|
||||||
// required: true,
|
// required: true,
|
||||||
// },
|
// },
|
||||||
|
forceSpecialTag: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
content: {
|
content: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
@@ -139,8 +177,8 @@ export default {
|
|||||||
// 2. 计算纸张尺寸(与批量导出保持一致)
|
// 2. 计算纸张尺寸(与批量导出保持一致)
|
||||||
// 根据 labelType 判断:'2' 是材料标签(100x80,宽100高80),'3' 是外标(180x100)
|
// 根据 labelType 判断:'2' 是材料标签(100x80,宽100高80),'3' 是外标(180x100)
|
||||||
const isMaterial = this.labelType === '2';
|
const isMaterial = this.labelType === '2';
|
||||||
const paperWidthMm = isMaterial ? 100 : 180;
|
const paperWidthMm = this.tagSizeMap[this.tagType].width || 100;
|
||||||
const paperHeightMm = isMaterial ? 80 : 100;
|
const paperHeightMm = this.tagSizeMap[this.tagType].height || 80;
|
||||||
|
|
||||||
// 使用合适的scale值生成高清Canvas(但不超过纸张尺寸)
|
// 使用合适的scale值生成高清Canvas(但不超过纸张尺寸)
|
||||||
const canvasScale = 3; // 提高清晰度(单张打印)
|
const canvasScale = 3; // 提高清晰度(单张打印)
|
||||||
|
|||||||
267
klp-ui/src/views/wms/coil/panels/abnormal.vue
Normal file
267
klp-ui/src/views/wms/coil/panels/abnormal.vue
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="位置" prop="position">
|
||||||
|
<el-select v-model="queryParams.position" placeholder="请选择位置" clearable>
|
||||||
|
<el-option v-for="dict in dict.type.coil_abnormal_position" :key="dict.value" :label="dict.label"
|
||||||
|
:value="dict.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="缺陷代码" prop="defectCode">
|
||||||
|
<el-select v-model="queryParams.defectCode" placeholder="请选择缺陷代码" clearable>
|
||||||
|
<el-option v-for="dict in dict.type.coil_abnormal_code" :key="dict.value" :label="dict.label"
|
||||||
|
:value="dict.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="程度" prop="degree">
|
||||||
|
<el-select v-model="queryParams.degree" placeholder="请选择程度" clearable>
|
||||||
|
<el-option v-for="dict in dict.type.coil_abnormal_degree" :key="dict.value" :label="dict.label"
|
||||||
|
:value="dict.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="coilAbnormalList">
|
||||||
|
<el-table-column label="位置" align="center" prop="position">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.coil_abnormal_position" :value="scope.row.position" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="长度坐标" align="center" prop="lengthCoord" />
|
||||||
|
<el-table-column label="缺陷代码" align="center" prop="defectCode">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.coil_abnormal_code" :value="scope.row.defectCode" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="程度" align="center" prop="degree">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<dict-tag :options="dict.type.coil_abnormal_degree" :value="scope.row.degree" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList" />
|
||||||
|
|
||||||
|
<!-- 添加或修改钢卷异常信息对话框 -->
|
||||||
|
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
|
||||||
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="位置" prop="position">
|
||||||
|
<el-radio-group v-model="form.position">
|
||||||
|
<el-radio-button v-for="dict in dict.type.coil_abnormal_position" :key="dict.value" :label="dict.value">{{
|
||||||
|
dict.label }}</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="长度坐标" prop="lengthCoord">
|
||||||
|
<el-input v-model="form.lengthCoord" placeholder="请输入长度坐标" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="缺陷代码" prop="defectCode">
|
||||||
|
<el-radio-group v-model="form.defectCode">
|
||||||
|
<el-radio-button v-for="dict in dict.type.coil_abnormal_code" :key="dict.value" :label="dict.value">{{
|
||||||
|
dict.label }}</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="程度" prop="degree">
|
||||||
|
<el-radio-group v-model="form.degree">
|
||||||
|
<el-radio-button v-for="dict in dict.type.coil_abnormal_degree" :key="dict.value" :label="dict.value">{{
|
||||||
|
dict.label }}</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input type="textarea" v-model="form.remark" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { listCoilAbnormal, getCoilAbnormal, delCoilAbnormal, addCoilAbnormal, updateCoilAbnormal } from "@/api/wms/coilAbnormal";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "CoilAbnormal",
|
||||||
|
dicts: ['coil_abnormal_code', 'coil_abnormal_position', 'coil_abnormal_degree'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 按钮loading
|
||||||
|
buttonLoading: false,
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 选中数组
|
||||||
|
ids: [],
|
||||||
|
// 非单个禁用
|
||||||
|
single: true,
|
||||||
|
// 非多个禁用
|
||||||
|
multiple: true,
|
||||||
|
// 显示搜索条件
|
||||||
|
showSearch: true,
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
// 钢卷异常信息表格数据
|
||||||
|
coilAbnormalList: [],
|
||||||
|
// 弹出层标题
|
||||||
|
title: "",
|
||||||
|
// 是否显示弹出层
|
||||||
|
open: false,
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
coilId: undefined,
|
||||||
|
position: undefined,
|
||||||
|
lengthCoord: undefined,
|
||||||
|
defectCode: undefined,
|
||||||
|
degree: undefined,
|
||||||
|
judgeLevel: undefined,
|
||||||
|
judgeBy: undefined,
|
||||||
|
},
|
||||||
|
// 表单参数
|
||||||
|
form: {},
|
||||||
|
// 表单校验
|
||||||
|
rules: {
|
||||||
|
},
|
||||||
|
judgeOpen: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
coilId: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
coilId: {
|
||||||
|
handler(newVal, oldVal) {
|
||||||
|
if (!newVal) {
|
||||||
|
this.coilAbnormalList = [];
|
||||||
|
this.total = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.queryParams.coilId = newVal
|
||||||
|
this.handleQuery()
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询钢卷异常信息列表 */
|
||||||
|
getList() {
|
||||||
|
this.loading = true;
|
||||||
|
listCoilAbnormal(this.queryParams).then(response => {
|
||||||
|
this.coilAbnormalList = response.rows;
|
||||||
|
this.total = response.total;
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 取消按钮
|
||||||
|
cancel() {
|
||||||
|
this.open = false;
|
||||||
|
this.reset();
|
||||||
|
},
|
||||||
|
// 表单重置
|
||||||
|
reset() {
|
||||||
|
this.form = {
|
||||||
|
abnormalId: undefined,
|
||||||
|
coilId: this.coilId,
|
||||||
|
position: undefined,
|
||||||
|
lengthCoord: undefined,
|
||||||
|
defectCode: undefined,
|
||||||
|
degree: undefined,
|
||||||
|
judgeLevel: undefined,
|
||||||
|
judgeBy: undefined,
|
||||||
|
judgeTime: undefined,
|
||||||
|
remark: undefined,
|
||||||
|
delFlag: undefined,
|
||||||
|
createTime: undefined,
|
||||||
|
createBy: undefined,
|
||||||
|
updateTime: undefined,
|
||||||
|
updateBy: undefined
|
||||||
|
};
|
||||||
|
this.resetForm("form");
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNum = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.resetForm("queryForm");
|
||||||
|
this.handleQuery();
|
||||||
|
},
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
handleAdd() {
|
||||||
|
this.reset();
|
||||||
|
this.open = true;
|
||||||
|
this.title = "添加钢卷异常信息";
|
||||||
|
},
|
||||||
|
/** 修改按钮操作 */
|
||||||
|
handleUpdate(row) {
|
||||||
|
this.loading = true;
|
||||||
|
this.reset();
|
||||||
|
const abnormalId = row.abnormalId || this.ids
|
||||||
|
getCoilAbnormal(abnormalId).then(response => {
|
||||||
|
this.loading = false;
|
||||||
|
this.form = response.data;
|
||||||
|
this.open = true;
|
||||||
|
this.title = "修改钢卷异常信息";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 提交按钮 */
|
||||||
|
submitForm() {
|
||||||
|
this.$refs["form"].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
this.buttonLoading = true;
|
||||||
|
if (this.form.abnormalId != null) {
|
||||||
|
updateCoilAbnormal(this.form).then(response => {
|
||||||
|
this.$modal.msgSuccess("修改成功");
|
||||||
|
this.open = false;
|
||||||
|
this.getList();
|
||||||
|
}).finally(() => {
|
||||||
|
this.buttonLoading = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
addCoilAbnormal(this.form).then(response => {
|
||||||
|
this.$modal.msgSuccess("新增成功");
|
||||||
|
this.open = false;
|
||||||
|
this.getList();
|
||||||
|
}).finally(() => {
|
||||||
|
this.buttonLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
handleDelete(row) {
|
||||||
|
const abnormalIds = row.abnormalId || this.ids;
|
||||||
|
this.$modal.confirm('是否确认删除钢卷异常信息编号为"' + abnormalIds + '"的数据项?').then(() => {
|
||||||
|
this.loading = true;
|
||||||
|
return delCoilAbnormal(abnormalIds);
|
||||||
|
}).then(() => {
|
||||||
|
this.loading = false;
|
||||||
|
this.getList();
|
||||||
|
this.$modal.msgSuccess("删除成功");
|
||||||
|
}).catch(() => {
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -146,7 +146,17 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
|
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
|
||||||
|
<el-table-column label="钢卷去向" align="center" prop="nextWarehouseId" v-if="editNext" width="150">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-select v-model="scope.row.nextWarehouseId" placeholder="钢卷去向" filterable
|
||||||
|
@change="handleNextWarehouseChange(scope.row)">
|
||||||
|
<el-option v-for="item in dict.type.warehouse_sync" :key="item.value" :value="item.value"
|
||||||
|
:label="item.label" />
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<!-- <el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip/> -->
|
<!-- <el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip/> -->
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
@@ -274,10 +284,10 @@
|
|||||||
|
|
||||||
<!-- 标签预览弹窗 -->
|
<!-- 标签预览弹窗 -->
|
||||||
<el-dialog title="标签预览" :visible.sync="labelRender.visible" append-to-body>
|
<el-dialog title="标签预览" :visible.sync="labelRender.visible" append-to-body>
|
||||||
<label-render :content="labelRender.data" :labelType="labelRender.type" />
|
<label-render :forceSpecialTag="forceSpecialTag" :content="labelRender.data" :labelType="labelRender.type" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<label-render ref="labelRender" v-show="false" :content="labelRender.data" :labelType="labelRender.type" />
|
<label-render :forceSpecialTag="forceSpecialTag" ref="labelRender" v-show="false" :content="labelRender.data" :labelType="labelRender.type" />
|
||||||
|
|
||||||
<!-- 批量导出标签PDF弹窗 -->
|
<!-- 批量导出标签PDF弹窗 -->
|
||||||
<el-dialog title="批量导出标签PDF" :visible.sync="batchPrint.visible" width="520px" append-to-body>
|
<el-dialog title="批量导出标签PDF" :visible.sync="batchPrint.visible" width="520px" append-to-body>
|
||||||
@@ -293,10 +303,14 @@
|
|||||||
<!-- 渲染容器:屏幕隐藏,仅用于截图生成PDF -->
|
<!-- 渲染容器:屏幕隐藏,仅用于截图生成PDF -->
|
||||||
<div ref="batchPdfContainer" class="batch-pdf-root" aria-hidden="true">
|
<div ref="batchPdfContainer" class="batch-pdf-root" aria-hidden="true">
|
||||||
<div v-for="(item, idx) in batchPrint.list" :key="item.coilId || idx" class="batch-pdf-page">
|
<div v-for="(item, idx) in batchPrint.list" :key="item.coilId || idx" class="batch-pdf-page">
|
||||||
<label-render :content="item" :hideActions="true" />
|
<label-render :content="item" :hideActions="true" :forceSpecialTag="forceSpecialTag" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog title="异常信息" :visible.sync="abnormalOpen" width="90%" append-to-body>
|
||||||
|
<abnormal-list :coil-id="currentCoilId"></abnormal-list>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -335,6 +349,7 @@ import MutiSelect from "@/components/MutiSelect";
|
|||||||
import html2canvas from 'html2canvas';
|
import html2canvas from 'html2canvas';
|
||||||
import { PDFDocument } from 'pdf-lib';
|
import { PDFDocument } from 'pdf-lib';
|
||||||
import { listUser } from "@/api/system/user";
|
import { listUser } from "@/api/system/user";
|
||||||
|
import AbnormalList from "./abnormal.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MaterialCoil",
|
name: "MaterialCoil",
|
||||||
@@ -354,8 +369,9 @@ export default {
|
|||||||
MemoInput,
|
MemoInput,
|
||||||
MutiSelect,
|
MutiSelect,
|
||||||
OuterTagPreview,
|
OuterTagPreview,
|
||||||
|
AbnormalList,
|
||||||
},
|
},
|
||||||
dicts: ['product_coil_status', 'coil_material', 'coil_itemname', 'coil_manufacturer', 'coil_quality_status'],
|
dicts: ['product_coil_status', 'coil_material', 'coil_itemname', 'coil_manufacturer', 'coil_quality_status', 'warehouse_sync'],
|
||||||
props: {
|
props: {
|
||||||
qrcode: {
|
qrcode: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -405,6 +421,14 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
editNext: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
forceSpecialTag: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -568,6 +592,8 @@ export default {
|
|||||||
],
|
],
|
||||||
title: '详细信息'
|
title: '详细信息'
|
||||||
},
|
},
|
||||||
|
abnormalOpen: false,
|
||||||
|
currentCoilId: '',
|
||||||
userList: [],
|
userList: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -598,6 +624,24 @@ export default {
|
|||||||
this.userList = res.rows || [];
|
this.userList = res.rows || [];
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
handleNextWarehouseChange(row) {
|
||||||
|
if (!this.editNext) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateMaterialCoilSimple(row).then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.$message({
|
||||||
|
message: '更新成功',
|
||||||
|
type: 'success',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$message({
|
||||||
|
message: res.msg || '更新失败',
|
||||||
|
type: 'error',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
// 打印标签
|
// 打印标签
|
||||||
handlePrintLabel(row) {
|
handlePrintLabel(row) {
|
||||||
const item = row.itemType === 'product' ? row.product : row.rawMaterial;
|
const item = row.itemType === 'product' ? row.product : row.rawMaterial;
|
||||||
@@ -701,12 +745,14 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleAbnormal(row) {
|
handleAbnormal(row) {
|
||||||
this.$router.push({
|
// this.$router.push({
|
||||||
path: '/quality/detail',
|
// path: '/quality/detail',
|
||||||
query: {
|
// query: {
|
||||||
coilId: row.coilId,
|
// coilId: row.coilId,
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
|
this.currentCoilId = row.coilId;
|
||||||
|
this.abnormalOpen = true;
|
||||||
},
|
},
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
cancel() {
|
cancel() {
|
||||||
|
|||||||
28
klp-ui/src/views/wms/coil/views/jishu.vue
Normal file
28
klp-ui/src/views/wms/coil/views/jishu.vue
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<BasePage :qrcode="qrcode" :querys="querys" :labelType="labelType" :hideWarehouseQuery="hideWarehouseQuery" :hideType="hideType" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BasePage from '../panels/base.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
BasePage
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
qrcode: false,
|
||||||
|
querys: {
|
||||||
|
dataType: 1,
|
||||||
|
status: 0,
|
||||||
|
warehouseId: '2019583656787259393', // 技术部逻辑库
|
||||||
|
// materialType: '废品'
|
||||||
|
},
|
||||||
|
hideWarehouseQuery: true,
|
||||||
|
showAbnormal: true,
|
||||||
|
labelType: '2',
|
||||||
|
hideType: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
28
klp-ui/src/views/wms/coil/views/mini.vue
Normal file
28
klp-ui/src/views/wms/coil/views/mini.vue
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<BasePage :qrcode="qrcode" :querys="querys" :labelType="labelType" :hideWarehouseQuery="hideWarehouseQuery" :hideType="hideType" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BasePage from '../panels/base.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
BasePage
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
qrcode: false,
|
||||||
|
querys: {
|
||||||
|
dataType: 1,
|
||||||
|
status: 0,
|
||||||
|
warehouseId: '2019583325311414274', // 小钢卷仓
|
||||||
|
// materialType: '废品'
|
||||||
|
},
|
||||||
|
hideWarehouseQuery: true,
|
||||||
|
showAbnormal: true,
|
||||||
|
labelType: '2',
|
||||||
|
hideType: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
28
klp-ui/src/views/wms/coil/views/return.vue
Normal file
28
klp-ui/src/views/wms/coil/views/return.vue
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<BasePage :qrcode="qrcode" :querys="querys" :labelType="labelType" :hideWarehouseQuery="hideWarehouseQuery" :hideType="hideType" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BasePage from '../panels/base.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
BasePage
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
qrcode: false,
|
||||||
|
querys: {
|
||||||
|
dataType: 1,
|
||||||
|
status: 0,
|
||||||
|
warehouseId: '2019583137616310273', // 退货仓
|
||||||
|
// materialType: '废品'
|
||||||
|
},
|
||||||
|
hideWarehouseQuery: true,
|
||||||
|
showAbnormal: true,
|
||||||
|
labelType: '2',
|
||||||
|
hideType: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
28
klp-ui/src/views/wms/coil/views/scrap.vue
Normal file
28
klp-ui/src/views/wms/coil/views/scrap.vue
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<BasePage :qrcode="qrcode" :querys="querys" :labelType="labelType" :hideWarehouseQuery="hideWarehouseQuery" :hideType="hideType" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BasePage from '../panels/base.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
BasePage
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
qrcode: false,
|
||||||
|
querys: {
|
||||||
|
dataType: 1,
|
||||||
|
status: 0,
|
||||||
|
warehouseId: '2019583429955104769', // 废品仓
|
||||||
|
// materialType: '废品'
|
||||||
|
},
|
||||||
|
hideWarehouseQuery: true,
|
||||||
|
showAbnormal: true,
|
||||||
|
labelType: '2',
|
||||||
|
hideType: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
41
klp-ui/src/views/wms/coil/where.vue
Normal file
41
klp-ui/src/views/wms/coil/where.vue
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<template>
|
||||||
|
<BasePage
|
||||||
|
:editNext="editNext"
|
||||||
|
:qrcode="qrcode"
|
||||||
|
:querys="querys"
|
||||||
|
:labelType="labelType"
|
||||||
|
:hideWarehouseQuery="hideWarehouseQuery"
|
||||||
|
:forceSpecialTag="forceSpecialTag"
|
||||||
|
:showControl="showControl"
|
||||||
|
:showAbnormal="showAbnormal"
|
||||||
|
:hideType="hideType"></BasePage>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BasePage from './panels/base.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
BasePage
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
qrcode: false,
|
||||||
|
querys: {
|
||||||
|
dataType: 1,
|
||||||
|
status: 0,
|
||||||
|
// OnlyScrap: true,
|
||||||
|
// materialType: '废品'
|
||||||
|
},
|
||||||
|
// 强制使用特殊标签
|
||||||
|
forceSpecialTag: 'where',
|
||||||
|
editNext: true,
|
||||||
|
hideWarehouseQuery: true,
|
||||||
|
labelType: '2',
|
||||||
|
hideType: false,
|
||||||
|
showControl: false,
|
||||||
|
showAbnormal: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -18,6 +18,17 @@
|
|||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="warning" plain icon="el-icon-refresh" size="mini" @click="getList">刷新</el-button>
|
<el-button type="warning" plain icon="el-icon-refresh" size="mini" @click="getList">刷新</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="6" style="float: right;" size="medium">
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="总卷数">
|
||||||
|
{{ totalCoilCount }} 卷
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="总重量">
|
||||||
|
{{ totalWeight }} 吨
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-table :data="deliveryWaybillDetailList">
|
<el-table :data="deliveryWaybillDetailList">
|
||||||
@@ -173,7 +184,7 @@ export default {
|
|||||||
// 查询参数
|
// 查询参数
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 999,
|
||||||
waybillId: this.waybillId,
|
waybillId: this.waybillId,
|
||||||
coilId: undefined,
|
coilId: undefined,
|
||||||
productName: undefined,
|
productName: undefined,
|
||||||
@@ -194,6 +205,14 @@ export default {
|
|||||||
autoFillForm: true,
|
autoFillForm: true,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
totalCoilCount() {
|
||||||
|
return this.total;
|
||||||
|
},
|
||||||
|
totalWeight() {
|
||||||
|
return this.deliveryWaybillDetailList.reduce((acc, item) => acc + Number(item.weight), 0).toFixed(3);
|
||||||
|
}
|
||||||
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getList();
|
this.getList();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -186,6 +186,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<el-button type="primary" @click="saveAsImage">保存为图片</el-button>
|
<el-button type="primary" @click="saveAsImage">保存为图片</el-button>
|
||||||
<el-button type="success" @click="printWaybill">打印</el-button>
|
<el-button type="success" @click="printWaybill">打印</el-button>
|
||||||
|
<el-button type="warning" @click="exportExcel">导出Excel</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -194,6 +195,8 @@
|
|||||||
import domtoimage from 'dom-to-image';
|
import domtoimage from 'dom-to-image';
|
||||||
import { PDFDocument } from 'pdf-lib';
|
import { PDFDocument } from 'pdf-lib';
|
||||||
import html2canvas from 'html2canvas';
|
import html2canvas from 'html2canvas';
|
||||||
|
import * as XLSX from 'xlsx';
|
||||||
|
import ExcelJS from 'exceljs';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
@@ -289,6 +292,26 @@ export default {
|
|||||||
}
|
}
|
||||||
return pageRows;
|
return pageRows;
|
||||||
},
|
},
|
||||||
|
readWaybill() {
|
||||||
|
const file = this.$refs.file.files[0];
|
||||||
|
if (!file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.readAsArrayBuffer(file);
|
||||||
|
reader.onload = (e) => {
|
||||||
|
const data = e.target.result;
|
||||||
|
const wb = XLSX.read(data, { type: 'array' });
|
||||||
|
const ws = wb.Sheets[wb.SheetNames[0]];
|
||||||
|
const json = XLSX.utils.sheet_to_eth(ws);
|
||||||
|
console.log(json);
|
||||||
|
// this.localWaybillDetails = json;
|
||||||
|
// this.refreshPagination();
|
||||||
|
};
|
||||||
|
reader.onerror = (e) => {
|
||||||
|
console.error('读取文件失败:', e);
|
||||||
|
};
|
||||||
|
},
|
||||||
refreshPagination() {
|
refreshPagination() {
|
||||||
const src = Array.isArray(this.localWaybillDetails) ? this.localWaybillDetails : [];
|
const src = Array.isArray(this.localWaybillDetails) ? this.localWaybillDetails : [];
|
||||||
this.totalPages = Math.max(1, Math.ceil(src.length / this.perPage));
|
this.totalPages = Math.max(1, Math.ceil(src.length / this.perPage));
|
||||||
@@ -460,6 +483,449 @@ export default {
|
|||||||
a.click();
|
a.click();
|
||||||
document.body.removeChild(a);
|
document.body.removeChild(a);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
async exportExcelByXLSX() {
|
||||||
|
try {
|
||||||
|
// ===== 1. 构建真实数据(替换占位符,使用实际明细)=====
|
||||||
|
const headerData = [
|
||||||
|
['科伦普发货单'], // 标题行(r=0)
|
||||||
|
[
|
||||||
|
`收货单位:${this.localWaybill.consigneeUnit || ''}`,
|
||||||
|
undefined, undefined, undefined,
|
||||||
|
`${this.localWaybill.deliveryYear || ''}年${this.localWaybill.deliveryMonth || ''}月${this.localWaybill.deliveryDay || ''}日`,
|
||||||
|
undefined, undefined, undefined,
|
||||||
|
`发货单位:${this.localWaybill.senderUnit || ''}`
|
||||||
|
], // 收货/日期/发货单位行(r=1)
|
||||||
|
[
|
||||||
|
`负责人:${this.localWaybill.principal || ''}`,
|
||||||
|
undefined, undefined,
|
||||||
|
`电话:${this.localWaybill.principalPhone || ''}`,
|
||||||
|
undefined, undefined,
|
||||||
|
`合同号:${this.localWaybill.contractCode || ''}`,
|
||||||
|
undefined, undefined,
|
||||||
|
`车牌:${this.localWaybill.licensePlate || ''}`
|
||||||
|
], // 负责人/电话/合同号/车牌行(r=2)
|
||||||
|
["品名", '切边', '包装', '仓库位置', '结算', '原料厂家', '卷号', '规格', '材质', '重量(t)', '单价', '备注'], // 表格表头(r=3)
|
||||||
|
];
|
||||||
|
|
||||||
|
// 表格明细行(替换原有E1/F1等占位符,使用真实明细)
|
||||||
|
const detailRows = this.displayWaybillDetails.map(item => [
|
||||||
|
item.productName || '',
|
||||||
|
item.edgeType || '',
|
||||||
|
item.packageType || '',
|
||||||
|
item.actualWarehouseName || '',
|
||||||
|
item.settlementType || '',
|
||||||
|
item.rawMaterialFactory || '',
|
||||||
|
item.coilNumber || '',
|
||||||
|
item.specification || '',
|
||||||
|
item.material || '',
|
||||||
|
item.weight || '',
|
||||||
|
item.unitPrice || '',
|
||||||
|
item.remark || ''
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 底部备注/取货地点/签名栏
|
||||||
|
const footerData = [
|
||||||
|
[
|
||||||
|
'1、品名:冷硬钢卷(酸连轧)、冷轧钢卷(脱脂退火火拉矫)、镀锌卷板,镀锌管料(镀锌分剪料);2、切边:净边/毛边;3、包装:裸包:周三径四;简包1:周三径四内外护角;简包2:周三径四+防锈纸;普包:周三径四+内外护角+防锈纸+端护板;精包1:周三径四+内外护角+防锈纸+薄膜+端护板+内外护板;精包2:周三径四+内外护角+防锈纸+薄膜+端护板+内外护板+木托。'
|
||||||
|
], // 备注行(r=3+明细行数)
|
||||||
|
[`取货地点:${this.localWaybill.pickupLocation || ''}`], // 取货地点行
|
||||||
|
[
|
||||||
|
`发货:${this.localWaybill.deliveryman || ''}`,
|
||||||
|
undefined, undefined, undefined,
|
||||||
|
`司机:${this.localWaybill.driver || ''}`,
|
||||||
|
undefined, undefined, undefined,
|
||||||
|
`磅房:${this.localWaybill.weightRoom || ''}`
|
||||||
|
] // 签名栏行
|
||||||
|
];
|
||||||
|
|
||||||
|
// 合并所有数据行
|
||||||
|
const data = [...headerData, ...detailRows, ...footerData];
|
||||||
|
const titleRowIdx = 0; // 标题行索引
|
||||||
|
const headerRow1Idx = 1; // 收货单位行索引
|
||||||
|
const headerRow2Idx = 2; // 负责人行索引
|
||||||
|
const tableHeaderIdx = 3; // 表格表头行索引
|
||||||
|
const remarkRowIdx = 3 + detailRows.length; // 备注行索引
|
||||||
|
const pickupRowIdx = remarkRowIdx + 1; // 取货地点行索引
|
||||||
|
const footerRowIdx = pickupRowIdx + 1; // 签名栏行索引
|
||||||
|
|
||||||
|
// ===== 2. 创建工作表并配置基础合并 =====
|
||||||
|
const ws = XLSX.utils.aoa_to_sheet(data);
|
||||||
|
ws["!cellStyles"] = true; // 必须开启才能设置单元格样式
|
||||||
|
ws["!merges"] = [
|
||||||
|
{ s: { c: 0, r: titleRowIdx }, e: { c: 11, r: titleRowIdx } }, // 标题跨列合并(A1-L1)
|
||||||
|
{ s: { c: 0, r: headerRow1Idx }, e: { c: 3, r: headerRow1Idx } }, // 收货单位(A2-D2)
|
||||||
|
{ s: { c: 4, r: headerRow1Idx }, e: { c: 7, r: headerRow1Idx } }, // 日期(E2-H2)
|
||||||
|
{ s: { c: 8, r: headerRow1Idx }, e: { c: 11, r: headerRow1Idx } }, // 发货单位(I2-L2)
|
||||||
|
{ s: { c: 0, r: headerRow2Idx }, e: { c: 2, r: headerRow2Idx } }, // 负责人(A3-C3)
|
||||||
|
{ s: { c: 3, r: headerRow2Idx }, e: { c: 5, r: headerRow2Idx } }, // 电话(D3-F3)
|
||||||
|
{ s: { c: 6, r: headerRow2Idx }, e: { c: 8, r: headerRow2Idx } }, // 合同号(G3-I3)
|
||||||
|
{ s: { c: 9, r: headerRow2Idx }, e: { c: 11, r: headerRow2Idx } }, // 车牌(J3-L3)
|
||||||
|
{ s: { c: 0, r: remarkRowIdx }, e: { c: 11, r: remarkRowIdx } }, // 备注跨列合并(A*_L*)
|
||||||
|
{ s: { c: 0, r: pickupRowIdx }, e: { c: 11, r: pickupRowIdx } }, // 取货地点跨列合并
|
||||||
|
{ s: { c: 0, r: footerRowIdx }, e: { c: 3, r: footerRowIdx } }, // 发货(A*_D*)
|
||||||
|
{ s: { c: 4, r: footerRowIdx }, e: { c: 7, r: footerRowIdx } }, // 司机(E*_H*)
|
||||||
|
{ s: { c: 8, r: footerRowIdx }, e: { c: 11, r: footerRowIdx } }, // 磅房(I*_L*)
|
||||||
|
];
|
||||||
|
|
||||||
|
// ===== 3. 配置列宽(完全匹配Web端表格列宽)=====
|
||||||
|
ws['!cols'] = [
|
||||||
|
{ wpx: 70 }, // 品名
|
||||||
|
{ wpx: 40 }, // 切边
|
||||||
|
{ wpx: 50 }, // 包装
|
||||||
|
{ wpx: 90 }, // 仓库位置
|
||||||
|
{ wpx: 60 }, // 结算
|
||||||
|
{ wpx: 70 }, // 原料厂家
|
||||||
|
{ wpx: 110 }, // 卷号
|
||||||
|
{ wpx: 90 }, // 规格
|
||||||
|
{ wpx: 80 }, // 材质
|
||||||
|
{ wpx: 70 }, // 重量(t)
|
||||||
|
{ wpx: 50 }, // 单价
|
||||||
|
{ wpx: 130 }, // 备注
|
||||||
|
];
|
||||||
|
|
||||||
|
// ===== 4. 逐个配置单元格样式(核心:匹配Web端)=====
|
||||||
|
// 工具函数:生成单元格样式
|
||||||
|
const createCellStyle = (options = {}) => {
|
||||||
|
const defaultStyle = {
|
||||||
|
font: {
|
||||||
|
name: "SimSun", // 宋体(匹配Web端SimSun)
|
||||||
|
sz: options.sz || 16, // 默认字号16px(表格单元格)
|
||||||
|
bold: options.bold ?? true, // 默认加粗(匹配Web端font-weight:900)
|
||||||
|
},
|
||||||
|
alignment: {
|
||||||
|
horizontal: options.horizontal || "center", // 默认水平居中
|
||||||
|
vertical: options.vertical || "center", // 默认垂直居中
|
||||||
|
wrapText: options.wrapText || false, // 默认不换行
|
||||||
|
},
|
||||||
|
border: options.border || {
|
||||||
|
top: { style: "thin", color: { rgb: "000000" } },
|
||||||
|
bottom: { style: "thin", color: { rgb: "000000" } },
|
||||||
|
left: { style: "thin", color: { rgb: "000000" } },
|
||||||
|
right: { style: "thin", color: { rgb: "000000" } },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return defaultStyle;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 4.1 标题单元格(A1):24px、宋体、加粗、居中、无边框
|
||||||
|
const titleCell = XLSX.utils.encode_cell({ r: titleRowIdx, c: 0 });
|
||||||
|
ws[titleCell].s = {
|
||||||
|
...createCellStyle({
|
||||||
|
sz: 24, // Web端title的24px
|
||||||
|
border: null, // 标题无边框
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
// 4.2 头部信息行(收货单位/负责人行):18px、宋体、加粗、居中、无边框
|
||||||
|
const headerCells = [
|
||||||
|
// 收货单位行(A2/E2/I2)
|
||||||
|
XLSX.utils.encode_cell({ r: headerRow1Idx, c: 0 }),
|
||||||
|
XLSX.utils.encode_cell({ r: headerRow1Idx, c: 4 }),
|
||||||
|
XLSX.utils.encode_cell({ r: headerRow1Idx, c: 8 }),
|
||||||
|
// 负责人行(A3/D3/G3/J3)
|
||||||
|
XLSX.utils.encode_cell({ r: headerRow2Idx, c: 0 }),
|
||||||
|
XLSX.utils.encode_cell({ r: headerRow2Idx, c: 3 }),
|
||||||
|
XLSX.utils.encode_cell({ r: headerRow2Idx, c: 6 }),
|
||||||
|
XLSX.utils.encode_cell({ r: headerRow2Idx, c: 9 }),
|
||||||
|
];
|
||||||
|
headerCells.forEach(cellAddr => {
|
||||||
|
if (ws[cellAddr]) {
|
||||||
|
ws[cellAddr].s = {
|
||||||
|
...createCellStyle({
|
||||||
|
sz: 18, // Web端label的18px
|
||||||
|
border: null, // 头部信息无边框
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 4.3 表格表头(A4-L4):16px、宋体、加粗、居中、带边框
|
||||||
|
for (let c = 0; c < 12; c++) {
|
||||||
|
const cellAddr = XLSX.utils.encode_cell({ r: tableHeaderIdx, c });
|
||||||
|
if (ws[cellAddr]) {
|
||||||
|
ws[cellAddr].s = createCellStyle({ sz: 16 }); // 匹配Web表格16px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4.4 表格明细行:16px、宋体、加粗、居中、带边框
|
||||||
|
for (let r = tableHeaderIdx + 1; r < remarkRowIdx; r++) {
|
||||||
|
for (let c = 0; c < 12; c++) {
|
||||||
|
const cellAddr = XLSX.utils.encode_cell({ r, c });
|
||||||
|
if (ws[cellAddr]) {
|
||||||
|
ws[cellAddr].s = createCellStyle({ sz: 16 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4.5 备注行:18px、宋体、加粗、居中、自动换行、无边框
|
||||||
|
const remarkCell = XLSX.utils.encode_cell({ r: remarkRowIdx, c: 0 });
|
||||||
|
if (ws[remarkCell]) {
|
||||||
|
ws[remarkCell].s = {
|
||||||
|
...createCellStyle({
|
||||||
|
sz: 18, // Web端备注18px
|
||||||
|
wrapText: true, // 自动换行(匹配Web端text-align: justify)
|
||||||
|
border: null, // 备注无边框
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4.6 取货地点行:18px、宋体、加粗、居中、无边框
|
||||||
|
const pickupCell = XLSX.utils.encode_cell({ r: pickupRowIdx, c: 0 });
|
||||||
|
if (ws[pickupCell]) {
|
||||||
|
ws[pickupCell].s = {
|
||||||
|
...createCellStyle({
|
||||||
|
sz: 18, // Web端取货地点18px
|
||||||
|
border: null, // 无边框
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4.7 签名栏行:18px、宋体、加粗、居中、无边框
|
||||||
|
const footerCells = [
|
||||||
|
XLSX.utils.encode_cell({ r: footerRowIdx, c: 0 }), // 发货
|
||||||
|
XLSX.utils.encode_cell({ r: footerRowIdx, c: 4 }), // 司机
|
||||||
|
XLSX.utils.encode_cell({ r: footerRowIdx, c: 8 }), // 磅房
|
||||||
|
];
|
||||||
|
footerCells.forEach(cellAddr => {
|
||||||
|
if (ws[cellAddr]) {
|
||||||
|
ws[cellAddr].s = {
|
||||||
|
...createCellStyle({
|
||||||
|
sz: 18, // Web端签名栏18px
|
||||||
|
border: null, // 无边框
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(ws);
|
||||||
|
|
||||||
|
// ===== 5. 生成Excel并下载 =====
|
||||||
|
const wb = XLSX.utils.book_new();
|
||||||
|
XLSX.utils.book_append_sheet(wb, ws, "科伦普发货单"); // 工作表名称更贴合业务
|
||||||
|
|
||||||
|
// 生成Excel文件(启用样式配置)
|
||||||
|
const excelBuffer = XLSX.write(wb, {
|
||||||
|
bookType: "xlsx",
|
||||||
|
type: "array",
|
||||||
|
cellStyles: true, // 必须开启才能导出样式
|
||||||
|
sheetStubs: true
|
||||||
|
});
|
||||||
|
const blob = new Blob([excelBuffer], {
|
||||||
|
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8",
|
||||||
|
});
|
||||||
|
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = url;
|
||||||
|
link.download = `科伦普发货单_${this.waybill.waybillNo || Date.now()}.xlsx`; // 文件名更规范
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
|
||||||
|
// 清理资源
|
||||||
|
setTimeout(() => {
|
||||||
|
document.body.removeChild(link);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Excel导出失败:", error);
|
||||||
|
this.$message.error("导出失败,请重试"); // 替换为Vue的message提示
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async exportExcel() {
|
||||||
|
try {
|
||||||
|
// 1. 创建工作簿和工作表
|
||||||
|
const workbook = new ExcelJS.Workbook();
|
||||||
|
const worksheet = workbook.addWorksheet('科伦普发货单');
|
||||||
|
worksheet.properties.defaultRowHeight = 25; // 设置默认行高(匹配Web端行高)
|
||||||
|
|
||||||
|
// 2. 构建数据(复用原有业务数据)
|
||||||
|
const title = `科伦普发货单`; // 标题
|
||||||
|
const header1 = { // 收货单位+日期+发货单位
|
||||||
|
consignee: `收货单位:${this.localWaybill.consigneeUnit || ''}`,
|
||||||
|
date: `${this.localWaybill.deliveryYear || ''}年${this.localWaybill.deliveryMonth || ''}月${this.localWaybill.deliveryDay || ''}日`,
|
||||||
|
sender: `发货单位:${this.localWaybill.senderUnit || ''}`
|
||||||
|
};
|
||||||
|
const header2 = { // 负责人+电话+合同号+车牌
|
||||||
|
principal: `负责人:${this.localWaybill.principal || ''}`,
|
||||||
|
phone: `电话:${this.localWaybill.principalPhone || ''}`,
|
||||||
|
contract: `合同号:${this.localWaybill.contractCode || ''}`,
|
||||||
|
license: `车牌:${this.localWaybill.licensePlate || ''}`
|
||||||
|
};
|
||||||
|
const tableHeader = ["品名", '切边', '包装', '仓库位置', '结算', '原料厂家', '卷号', '规格', '材质', '重量(t)', '单价', '备注']; // 表格表头
|
||||||
|
const tableData = this.displayWaybillDetails.map(item => [ // 表格明细
|
||||||
|
item.productName || '',
|
||||||
|
item.edgeType || '',
|
||||||
|
item.packageType || '',
|
||||||
|
item.actualWarehouseName || '',
|
||||||
|
item.settlementType || '',
|
||||||
|
item.rawMaterialFactory || '',
|
||||||
|
item.coilNumber || '',
|
||||||
|
item.specification || '',
|
||||||
|
item.material || '',
|
||||||
|
item.weight || '',
|
||||||
|
item.unitPrice || '',
|
||||||
|
item.remark || ''
|
||||||
|
]);
|
||||||
|
const remark = '1、品名:冷硬钢卷(酸连轧)、冷轧钢卷(脱脂退火火拉矫)、镀锌卷板,镀锌管料(镀锌分剪料);2、切边:净边/毛边;3、包装:裸包:周三径四;简包1:周三径四内外护角;简包2:周三径四+防锈纸;普包:周三径四+内外护角+防锈纸+端护板;精包1:周三径四+内外护角+防锈纸+薄膜+端护板+内外护板;精包2:周三径四+内外护角+防锈纸+薄膜+端护板+内外护板+木托。';
|
||||||
|
const pickupLocation = `取货地点:${this.localWaybill.pickupLocation || ''}`;
|
||||||
|
const footer = { // 签名栏
|
||||||
|
deliveryman: `发货:${this.localWaybill.deliveryman || ''}`,
|
||||||
|
driver: `司机:${this.localWaybill.driver || ''}`,
|
||||||
|
weightRoom: `磅房:${this.localWaybill.weightRoom || ''}`
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3. 写入数据到工作表(按行写入)
|
||||||
|
let rowIdx = 1; // exceljs行号从1开始
|
||||||
|
// 3.1 标题行(第1行)
|
||||||
|
const titleCell = worksheet.getCell(`A${rowIdx}`);
|
||||||
|
titleCell.value = title;
|
||||||
|
worksheet.mergeCells(`A${rowIdx}:L${rowIdx}`); // 合并A1-L1
|
||||||
|
// 3.2 收货单位行(第2行)
|
||||||
|
rowIdx++;
|
||||||
|
worksheet.getCell(`A${rowIdx}`).value = header1.consignee;
|
||||||
|
worksheet.getCell(`E${rowIdx}`).value = header1.date;
|
||||||
|
worksheet.getCell(`I${rowIdx}`).value = header1.sender;
|
||||||
|
worksheet.mergeCells(`A${rowIdx}:D${rowIdx}`); // 收货单位:A2-D2
|
||||||
|
worksheet.mergeCells(`E${rowIdx}:H${rowIdx}`); // 日期:E2-H2
|
||||||
|
worksheet.mergeCells(`I${rowIdx}:L${rowIdx}`); // 发货单位:I2-L2
|
||||||
|
// 3.3 负责人行(第3行)
|
||||||
|
rowIdx++;
|
||||||
|
worksheet.getCell(`A${rowIdx}`).value = header2.principal;
|
||||||
|
worksheet.getCell(`D${rowIdx}`).value = header2.phone;
|
||||||
|
worksheet.getCell(`G${rowIdx}`).value = header2.contract;
|
||||||
|
worksheet.getCell(`J${rowIdx}`).value = header2.license;
|
||||||
|
worksheet.mergeCells(`A${rowIdx}:C${rowIdx}`); // 负责人:A3-C3
|
||||||
|
worksheet.mergeCells(`D${rowIdx}:F${rowIdx}`); // 电话:D3-F3
|
||||||
|
worksheet.mergeCells(`G${rowIdx}:I${rowIdx}`); // 合同号:G3-I3
|
||||||
|
worksheet.mergeCells(`J${rowIdx}:L${rowIdx}`); // 车牌:J3-L3
|
||||||
|
// 3.4 表格表头(第4行)
|
||||||
|
rowIdx++;
|
||||||
|
tableHeader.forEach((text, colIdx) => {
|
||||||
|
const colLetter = String.fromCharCode(65 + colIdx); // A=65, B=66...
|
||||||
|
worksheet.getCell(`${colLetter}${rowIdx}`).value = text;
|
||||||
|
});
|
||||||
|
// 3.5 表格明细行
|
||||||
|
tableData.forEach(item => {
|
||||||
|
rowIdx++;
|
||||||
|
item.forEach((text, colIdx) => {
|
||||||
|
const colLetter = String.fromCharCode(65 + colIdx);
|
||||||
|
worksheet.getCell(`${colLetter}${rowIdx}`).value = text;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// 3.6 备注行
|
||||||
|
rowIdx++;
|
||||||
|
const remarkCell = worksheet.getCell(`A${rowIdx}`);
|
||||||
|
remarkCell.value = remark;
|
||||||
|
worksheet.mergeCells(`A${rowIdx}:L${rowIdx}`); // 合并A*_L*
|
||||||
|
// 3.7 取货地点行
|
||||||
|
rowIdx++;
|
||||||
|
const pickupCell = worksheet.getCell(`A${rowIdx}`);
|
||||||
|
pickupCell.value = pickupLocation;
|
||||||
|
worksheet.mergeCells(`A${rowIdx}:L${rowIdx}`); // 合并A*_L*
|
||||||
|
// 3.8 签名栏行
|
||||||
|
rowIdx++;
|
||||||
|
worksheet.getCell(`A${rowIdx}`).value = footer.deliveryman;
|
||||||
|
worksheet.getCell(`E${rowIdx}`).value = footer.driver;
|
||||||
|
worksheet.getCell(`I${rowIdx}`).value = footer.weightRoom;
|
||||||
|
worksheet.mergeCells(`A${rowIdx}:D${rowIdx}`); // 发货:A*_D*
|
||||||
|
worksheet.mergeCells(`E${rowIdx}:H${rowIdx}`); // 司机:E*_H*
|
||||||
|
worksheet.mergeCells(`I${rowIdx}:L${rowIdx}`); // 磅房:I*_L*
|
||||||
|
|
||||||
|
// 4. 配置列宽(完全匹配Web端)
|
||||||
|
const columnWidths = [70, 40, 50, 90, 60, 70, 110, 90, 80, 70, 50, 130];
|
||||||
|
worksheet.columns = columnWidths.map((width, idx) => ({
|
||||||
|
key: `col${idx + 1}`,
|
||||||
|
width: width / 5 // exceljs的width单位是字符宽度,转换为px(约1px=0.072字符)
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 5. 配置样式(核心:匹配Web端)
|
||||||
|
// 工具函数:设置单元格样式
|
||||||
|
const setCellStyle = (cell, options = {}) => {
|
||||||
|
// 默认样式:宋体、加粗、居中
|
||||||
|
cell.font = {
|
||||||
|
name: 'SimSun', // 宋体(匹配Web端)
|
||||||
|
size: options.size || 16, // 默认16px(表格单元格)
|
||||||
|
bold: options.bold ?? true // 默认加粗
|
||||||
|
};
|
||||||
|
cell.alignment = {
|
||||||
|
horizontal: options.horizontal || 'left', // 水平居中
|
||||||
|
vertical: options.vertical || 'middle', // 垂直居中
|
||||||
|
wrapText: options.wrapText || false // 自动换行
|
||||||
|
};
|
||||||
|
// 边框:表格单元格带边框,其他区域无边框
|
||||||
|
if (options.border) {
|
||||||
|
cell.border = {
|
||||||
|
top: { style: 'thin', color: { argb: 'FF000000' } },
|
||||||
|
bottom: { style: 'thin', color: { argb: 'FF000000' } },
|
||||||
|
left: { style: 'thin', color: { argb: 'FF000000' } },
|
||||||
|
right: { style: 'thin', color: { argb: 'FF000000' } }
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
cell.border = null; // 无边框
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 5.1 标题样式(24px、宋体、加粗、居中、无边框)
|
||||||
|
setCellStyle(worksheet.getCell('A1'), { size: 24, border: false, horizontal: 'center' });
|
||||||
|
// 5.2 头部信息样式(18px、宋体、加粗、居中、无边框)
|
||||||
|
setCellStyle(worksheet.getCell(`A2`), { size: 18, border: false });
|
||||||
|
setCellStyle(worksheet.getCell(`E2`), { size: 18, border: false });
|
||||||
|
setCellStyle(worksheet.getCell(`I2`), { size: 18, border: false });
|
||||||
|
setCellStyle(worksheet.getCell(`A3`), { size: 18, border: false });
|
||||||
|
setCellStyle(worksheet.getCell(`D3`), { size: 18, border: false });
|
||||||
|
setCellStyle(worksheet.getCell(`G3`), { size: 18, border: false });
|
||||||
|
setCellStyle(worksheet.getCell(`J3`), { size: 18, border: false });
|
||||||
|
// 5.3 表格表头样式(16px、宋体、加粗、居中、带边框)
|
||||||
|
for (let col = 0; col < 12; col++) {
|
||||||
|
const colLetter = String.fromCharCode(65 + col);
|
||||||
|
setCellStyle(worksheet.getCell(`${colLetter}4`), { size: 16, border: true, horizontal: 'center' });
|
||||||
|
}
|
||||||
|
// 5.4 表格明细样式(16px、宋体、加粗、居中、带边框)
|
||||||
|
for (let r = 5; r < rowIdx - 2; r++) { // 明细行范围:第5行到备注行前一行
|
||||||
|
for (let col = 0; col < 12; col++) {
|
||||||
|
const colLetter = String.fromCharCode(65 + col);
|
||||||
|
setCellStyle(worksheet.getCell(`${colLetter}${r}`), { size: 16, border: true, horizontal: 'center' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 5.5 备注样式(18px、宋体、加粗、居中、自动换行、无边框)
|
||||||
|
setCellStyle(remarkCell, { size: 18, border: false, wrapText: true });
|
||||||
|
// 5.6 取货地点样式(18px、宋体、加粗、居中、无边框)
|
||||||
|
setCellStyle(pickupCell, { size: 18, border: false });
|
||||||
|
// 5.7 签名栏样式(18px、宋体、加粗、居中、无边框)
|
||||||
|
setCellStyle(worksheet.getCell(`A${rowIdx}`), { size: 18, border: false });
|
||||||
|
setCellStyle(worksheet.getCell(`E${rowIdx}`), { size: 18, border: false });
|
||||||
|
setCellStyle(worksheet.getCell(`I${rowIdx}`), { size: 18, border: false });
|
||||||
|
|
||||||
|
// 第一行的行高
|
||||||
|
const row1 = worksheet.getRow(1);
|
||||||
|
row1.height = 30;
|
||||||
|
// 备注行的行高
|
||||||
|
const remarkRow = worksheet.getRow(12);
|
||||||
|
remarkRow.height = 100;
|
||||||
|
|
||||||
|
// 6. 生成Excel文件并下载
|
||||||
|
const buffer = await workbook.xlsx.writeBuffer(); // 生成二进制buffer
|
||||||
|
const blob = new Blob([buffer], {
|
||||||
|
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||||
|
});
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
link.download = `科伦普发货单_${this.waybill.waybillNo || Date.now()}.xlsx`;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
// 清理资源
|
||||||
|
setTimeout(() => {
|
||||||
|
document.body.removeChild(link);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Excel导出失败:', error);
|
||||||
|
this.$message.error('导出失败,请重试');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,6 +205,8 @@ export default {
|
|||||||
}
|
}
|
||||||
listCoilWithIds({
|
listCoilWithIds({
|
||||||
...this.queryParams,
|
...this.queryParams,
|
||||||
|
byCreateTimeStart: undefined,
|
||||||
|
byCreateTimeEnd: undefined,
|
||||||
coilIds: coilIds,
|
coilIds: coilIds,
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
this.list = res.rows
|
this.list = res.rows
|
||||||
|
|||||||
@@ -205,6 +205,8 @@ export default {
|
|||||||
}
|
}
|
||||||
listCoilWithIds({
|
listCoilWithIds({
|
||||||
...this.queryParams,
|
...this.queryParams,
|
||||||
|
byCreateTimeStart: undefined,
|
||||||
|
byCreateTimeEnd: undefined,
|
||||||
coilIds: coilIds,
|
coilIds: coilIds,
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
this.list = res.rows
|
this.list = res.rows
|
||||||
|
|||||||
Reference in New Issue
Block a user