Browse Source

添加外箱标签打印功能

master
shenzhouyu 9 hours ago
parent
commit
1c2276cd95
  1. 3
      src/api/labelSetting/label_setting.js
  2. 2
      src/api/shipment/shipmentIssue.js
  3. 614
      src/views/modules/shipment/shipmentNotification.vue

3
src/api/labelSetting/label_setting.js

@ -21,6 +21,9 @@ export const printLabel = data => createAPI('/label/setting/printLabel','post',d
// 打印标签 // 打印标签
export const printLabelTest = data => createAPI('/label/setting/printLabelTest','post',data) export const printLabelTest = data => createAPI('/label/setting/printLabelTest','post',data)
// 通用打印标签
export const printLabelCommon = data => createAPI('/label/setting/printLabelCommon', 'post', data)
// 使用真实数据预览标签 // 使用真实数据预览标签
export const previewLabelWithRealData = data => createAPI('/label/setting/previewLabelWithRealData','post',data) export const previewLabelWithRealData = data => createAPI('/label/setting/previewLabelWithRealData','post',data)

2
src/api/shipment/shipmentIssue.js

@ -52,6 +52,8 @@ export const searchNotifyMaterialList = data => createAPI(`/shipmentIssue/search
export const closeInboundNotification = data => createAPI(`/shipmentIssue/closeInboundNotification`,'post',data) export const closeInboundNotification = data => createAPI(`/shipmentIssue/closeInboundNotification`,'post',data)
export const getShipmentLine = data => createAPI(`/shipmentIssue/getShipmentLine`,'post',data)
export const getShipmentAndLineForIssure = data => createAPI(`/shipmentIssue/getShipmentAndLineForIssure`,'post',data) export const getShipmentAndLineForIssure = data => createAPI(`/shipmentIssue/getShipmentAndLineForIssure`,'post',data)
export const saveNewShipmentAndLine = data => createAPI(`/shipmentIssue/saveNewShipmentAndLine`,'post',data) export const saveNewShipmentAndLine = data => createAPI(`/shipmentIssue/saveNewShipmentAndLine`,'post',data)

614
src/views/modules/shipment/shipmentNotification.vue

@ -138,6 +138,7 @@
<el-button type="primary" @click="deleteInboundDetail()" icon="el-icon-delete">删除</el-button> <el-button type="primary" @click="deleteInboundDetail()" icon="el-icon-delete">删除</el-button>
</el-form> --> </el-form> -->
<el-table :data="detailList" :height="secondHeight - 68" border @selection-change="selectionInboundDetail" <el-table :data="detailList" :height="secondHeight - 68" border @selection-change="selectionInboundDetail"
@row-dblclick="handleShipmentRowDblClick"
v-loading="searchLoading" style="width: 100%;"> v-loading="searchLoading" style="width: 100%;">
<!-- <el-table-column type="selection" header-align="center" align="center" width="50"> <!-- <el-table-column type="selection" header-align="center" align="center" width="50">
</el-table-column> --> </el-table-column> -->
@ -221,6 +222,37 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="shipmentline打印" name="shipmentLinePrint">
<div v-if="currentShipmentId" style="margin-bottom: 5px; font-size: 12px;">
当前SHIPMENTID{{ currentShipmentId }}
</div>
<el-table
:data="shipmentLineList"
:height="secondHeight - 68"
border
v-loading="shipmentLineLoading"
style="width: 100%;">
<el-table-column
v-for="(item,index) in columnShipmentLineList" :key="index"
:sortable="item.columnSortable"
:prop="item.columnProp"
:header-align="item.headerAlign"
:show-overflow-tooltip="item.showOverflowTooltip"
:align="item.align"
:fixed="item.fixed==''?false:item.fixed"
:min-width="item.columnWidth"
:label="item.columnLabel">
<template slot-scope="scope">
<span v-if="!item.columnHidden">{{ scope.row[item.columnProp] }}</span>
</template>
</el-table-column>
<el-table-column fixed="right" header-align="center" align="center" width="80" label="操作">
<template slot-scope="scope">
<el-link type="primary" style="cursor: pointer" @click="printShipmentLine(scope.row)">打印</el-link>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs> </el-tabs>
<!-- 收获入库单明细新增 --> <!-- 收获入库单明细新增 -->
@ -604,6 +636,116 @@
<Chooselist ref="baseList" @getBaseData="getBaseData"></Chooselist> <Chooselist ref="baseList" @getBaseData="getBaseData"></Chooselist>
<!-- shipmentline打印设置 -->
<el-dialog
title="标签打印设置"
:visible.sync="shipmentLinePrintDialogVisible"
width="480px"
:close-on-click-modal="false"
@close="resetShipmentLinePrintForm"
>
<el-alert
type="info"
:closable="false"
show-icon
:title="`已选择 1 个标签,请配置打印参数`"
style="margin-bottom: 16px;"
/>
<el-form label-position="top" size="small" class="shipment-line-print-form">
<div class="print-qty-row">
<div class="print-qty-item">
<span class="print-qty-label">打印份数</span>
<el-input
v-model="printForm.copies"
:min="1"
:max="99"
controls-position="right"
class="print-input-number"
/>
</div>
<div class="print-qty-item">
<span class="print-qty-label">分配数量</span>
<el-input
v-model="printForm.assignQty"
:min="0"
:precision="2"
:step="1"
controls-position="right"
class="print-input-number"
/>
</div>
</div>
<div class="form-hint">此数量为打印到标签上的数量</div>
<el-form-item label="标签类型">
<el-select
v-model="printForm.labelType"
placeholder="请选择标签类型"
style="width: 100%;"
@change="handlePrintLabelTypeChange"
>
<el-option label="外箱标签" value="外箱标签" />
<el-option label="内箱标签" value="内箱标签" />
</el-select>
</el-form-item>
<el-form-item label="根据物料自动匹配模板">
<el-select
v-model="printForm.reportId"
placeholder="请选择标签模板"
style="width: 100%;"
filterable
@change="handlePrintTemplateChange"
>
<el-option
v-for="item in labelTemplateList"
:key="item.labelNo"
:label="`${item.labelName} (${item.labelNo})`"
:value="item.labelNo"
/>
</el-select>
</el-form-item>
<el-form-item :label="`已经探测到 ${printerList.length} 台打印机`">
<el-select
v-model="printForm.printerName"
placeholder="请选择打印机"
style="width: 100%;"
>
<el-option
v-for="item in printerList"
:key="`${item.labelNo}-${item.printerName}`"
:label="`${item.printerName}${item.ipAddress ? ' (' + item.ipAddress + ')' : ''}`"
:value="item.printerName"
/>
</el-select>
</el-form-item>
<div class="shipment-line-print-summary">
<div class="summary-item">
<span class="summary-label">打印总数</span>
<span class="summary-value">{{ printForm.copies }} </span>
</div>
<div class="summary-item">
<span class="summary-label">物料数量</span>
<span class="summary-value">1 </span>
</div>
<div class="summary-item">
<span class="summary-label">每标签份数</span>
<span class="summary-value">{{ printForm.copies }} </span>
</div>
</div>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="shipmentLinePrintDialogVisible = false">取消</el-button>
<el-button
type="success"
icon="el-icon-printer"
:loading="printLoading"
:disabled="!canStartShipmentLinePrint"
@click="confirmShipmentLinePrint"
>
开始打印
</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
@ -621,7 +763,8 @@ import {
pushShipmentInventoryToWcs, pushShipmentInventoryToWcs,
deleteNotifyUnissue, deleteNotifyUnissue,
saveShipmentMaterialDetail, saveShipmentMaterialDetail,
searchUnissueNotifyMaterialList
searchUnissueNotifyMaterialList,
getShipmentLine
} from '@/api/shipment/shipmentIssue.js' } from '@/api/shipment/shipmentIssue.js'
// rqrq - API // rqrq - API
import { searchMaterialListDetail } from '@/api/orderIssure/soIssueNotify.js' import { searchMaterialListDetail } from '@/api/orderIssure/soIssueNotify.js'
@ -631,6 +774,11 @@ import {
getTableDefaultListLanguage, getTableDefaultListLanguage,
getTableUserListLanguage, getTableUserListLanguage,
} from '@/api/table.js' } from '@/api/table.js'
import {
getLabelSettingList,
getUserLabelPrinters,
printLabelCommon,
} from '@/api/labelSetting/label_setting.js'
export default { export default {
components: { components: {
Chooselist, Chooselist,
@ -1819,9 +1967,148 @@ export default {
pushLoading: false, pushLoading: false,
previewData: [], previewData: [],
currentNotifyRow: null, currentNotifyRow: null,
shipmentLineList: [],
shipmentLineLoading: false,
currentShipmentId: '',
shipmentLinePrintDialogVisible: false,
printLoading: false,
printShipmentLineRow: null,
labelTemplateList: [],
printerList: [],
printForm: {
copies: 1,
assignQty: 0,
labelType: '外箱标签',
reportId: '',
printerName: '',
},
columnShipmentLineList: [
{
columnProp: 'shipmentId',
headerAlign: 'center',
align: 'center',
columnLabel: 'SHIPMENTID',
columnHidden: false,
columnSortable: false,
columnWidth: 120,
},
{
columnProp: 'shipmentLineNo',
headerAlign: 'center',
align: 'right',
columnLabel: '行号',
columnHidden: false,
columnSortable: false,
columnWidth: 60,
},
{
columnProp: 'inventoryPartNo',
headerAlign: 'center',
align: 'left',
columnLabel: '库存物料号',
columnHidden: false,
columnSortable: false,
columnWidth: 120,
},
{
columnProp: 'sourcePartDescription',
headerAlign: 'center',
align: 'left',
columnLabel: '物料描述',
columnHidden: false,
columnSortable: false,
columnWidth: 150,
showOverflowTooltip: true,
},
{
columnProp: 'inventoryQty',
headerAlign: 'center',
align: 'right',
columnLabel: '库存数量',
columnHidden: false,
columnSortable: false,
columnWidth: 100,
},
{
columnProp: 'qtyAssigned',
headerAlign: 'center',
align: 'right',
columnLabel: '已分配数量',
columnHidden: false,
columnSortable: false,
columnWidth: 100,
},
{
columnProp: 'qtyPicked',
headerAlign: 'center',
align: 'right',
columnLabel: '已拣货数量',
columnHidden: false,
columnSortable: false,
columnWidth: 100,
},
{
columnProp: 'qtyShipped',
headerAlign: 'center',
align: 'right',
columnLabel: '已发货数量',
columnHidden: false,
columnSortable: false,
columnWidth: 100,
},
{
columnProp: 'inventoryUom',
headerAlign: 'center',
align: 'center',
columnLabel: '单位',
columnHidden: false,
columnSortable: false,
columnWidth: 60,
},
{
columnProp: 'sourceRef1',
headerAlign: 'center',
align: 'center',
columnLabel: '源引用1',
columnHidden: false,
columnSortable: false,
columnWidth: 100,
},
{
columnProp: 'sourceRef2',
headerAlign: 'center',
align: 'right',
columnLabel: '源引用2',
columnHidden: false,
columnSortable: false,
columnWidth: 80,
},
{
columnProp: 'sourceRef3',
headerAlign: 'center',
align: 'center',
columnLabel: '源引用3',
columnHidden: false,
columnSortable: false,
columnWidth: 80,
},
],
} }
}, },
computed: {
canStartShipmentLinePrint() {
console.log("this.printForm",this.printForm.reportId,this.printForm.printerName,this.printForm.copies,this.printForm.assignQty,this.printShipmentLineRow);
return !!(
this.printForm.reportId &&
this.printForm.copies > 0 &&
this.printForm.assignQty > 0 &&
this.printShipmentLineRow
)
},
},
mounted() { mounted() {
this.$nextTick(() => { this.$nextTick(() => {
this.height = window.innerHeight / 2 - 100 this.height = window.innerHeight / 2 - 100
@ -2902,6 +3189,223 @@ export default {
} }
return {} return {}
}, },
handleShipmentRowDblClick(row) {
const shipmentId = row.soorderNo
if (!shipmentId) {
this.$message.warning('该行没有SHIPMENTID')
return
}
this.currentShipmentId = shipmentId
this.loadShipmentLineList(row)
},
normalizeShipmentLineRow(row) {
return {
shipmentId: row.shipmentId || row.SHIPMENT_ID,
shipmentLineNo: row.shipmentLineNo != null ? row.shipmentLineNo : row.SHIPMENT_LINE_NO,
inventoryPartNo: row.inventoryPartNo || row.INVENTORY_PART_NO,
sourcePartDescription: row.sourcePartDescription || row.SOURCE_PART_DESCRIPTION,
inventoryQty: row.inventoryQty != null ? row.inventoryQty : row.INVENTORY_QTY,
qtyAssigned: row.qtyAssigned != null ? row.qtyAssigned : row.QTY_ASSIGNED,
qtyPicked: row.qtyPicked != null ? row.qtyPicked : row.QTY_PICKED,
qtyShipped: row.qtyShipped != null ? row.qtyShipped : row.QTY_SHIPPED,
inventoryUom: row.inventoryUom || row.INVENTORY_UOM,
sourceRef1: row.sourceRef1 || row.SOURCE_REF1,
sourceRef2: row.sourceRef2 || row.SOURCE_REF2,
sourceRef3: row.sourceRef3 || row.SOURCE_REF3,
}
},
loadShipmentLineList(row) {
const params = {
site: row.site || this.currentRow.site || this.$store.state.user.site,
orderNo: row.soorderNo,
}
this.shipmentLineLoading = true
getShipmentLine(params)
.then(({ data }) => {
if (data && data.code === 0) {
this.shipmentLineList = (data.rows || []).map(item => this.normalizeShipmentLineRow(item))
this.activeTable = 'shipmentLinePrint'
if (this.shipmentLineList.length === 0) {
this.$message.warning('未查询到ShipmentLine数据')
}
} else {
this.shipmentLineList = []
this.$message.error(data.msg || '获取ShipmentLine失败')
}
})
.catch(() => {
this.shipmentLineList = []
this.$message.error('获取ShipmentLine失败')
})
.finally(() => {
this.shipmentLineLoading = false
})
},
printShipmentLine(row) {
this.printShipmentLineRow = row
this.resetShipmentLinePrintForm()
this.printForm.assignQty = row.qtyAssigned != null ? row.qtyAssigned : 0
this.shipmentLinePrintDialogVisible = true
this.loadShipmentLinePrintOptions(row)
},
resetShipmentLinePrintForm() {
this.printForm = {
copies: 1,
assignQty: 0,
labelType: '外箱标签',
reportId: '',
printerName: '',
}
this.labelTemplateList = []
this.printerList = []
},
async loadShipmentLinePrintOptions(row) {
await this.loadLabelTemplateList(row)
await this.loadPrinterList()
},
async loadLabelTemplateList(row) {
try {
const { data } = await getLabelSettingList({
searchFlag: 'Y',
labelType: this.printForm.labelType,
})
this.labelTemplateList = (data && data.rows) ? data.rows : []
if (this.labelTemplateList.length === 0) {
this.printForm.reportId = ''
return
}
const partNo = (row && row.inventoryPartNo) || ''
const matchedTemplate = this.labelTemplateList.find(item => {
const labelName = item.labelName || ''
return partNo && labelName.includes(partNo)
})
const selectedTemplate = matchedTemplate || this.labelTemplateList[0]
this.printForm.reportId = selectedTemplate.labelNo
this.printForm.labelType = selectedTemplate.labelType || this.printForm.labelType
} catch (error) {
this.labelTemplateList = []
this.printForm.reportId = ''
this.$message.error('获取标签模板失败')
}
},
async loadPrinterList() {
if (!this.printForm.reportId) {
this.printerList = []
this.printForm.printerName = ''
return
}
try {
const { data } = await getUserLabelPrinters({
userId: localStorage.getItem('userName'),
username: localStorage.getItem('userName'),
site: this.currentRow.site || this.$store.state.user.site,
searchFlag: 'Y',
labelNo: this.printForm.reportId,
})
this.printerList = (data && data.rows) ? data.rows : []
this.printForm.printerName = this.printerList.length > 0
? this.printerList[0].printerName
: ''
} catch (error) {
this.printerList = []
this.printForm.printerName = ''
this.$message.error('获取打印机列表失败')
}
},
async handlePrintLabelTypeChange() {
if (!this.printShipmentLineRow) {
return
}
await this.loadLabelTemplateList(this.printShipmentLineRow)
await this.loadPrinterList()
},
async handlePrintTemplateChange() {
const selectedTemplate = this.labelTemplateList.find(
item => item.labelNo === this.printForm.reportId
)
if (selectedTemplate && selectedTemplate.labelType) {
this.printForm.labelType = selectedTemplate.labelType
}
await this.loadPrinterList()
},
buildShipmentLinePrintRequest() {
const row = this.printShipmentLineRow
const customFields = {
QTY: this.printForm.assignQty,
}
if (row.inventoryPartNo) {
customFields.partNo = row.inventoryPartNo
}
if (row.sourcePartDescription) {
customFields.partDesc = row.sourcePartDescription
}
const printRequest = {
reportId: this.printForm.reportId,
labelType: this.printForm.labelType,
printerName: this.printForm.printerName,
copies: this.printForm.copies,
site: this.currentRow.site || this.$store.state.user.site,
userId: localStorage.getItem('userName'),
username: localStorage.getItem('userName'),
consignmentId: String(row.shipmentId || ''),
jobNo: String(row.sourceRef1 || ''),
lineNo: String(row.sourceRef2 || ''),
relNo: String(row.sourceRef3 || ''),
lineItemNo: 0,
customFields,
}
if (this.currentRow && this.currentRow.receiver) {
printRequest.customerId = this.currentRow.receiver
}
return printRequest
},
async confirmShipmentLinePrint() {
if (!this.canStartShipmentLinePrint) {
this.$message.warning('请完善打印参数')
return
}
const row = this.printShipmentLineRow
if (!row.shipmentId || !row.sourceRef1 || row.sourceRef2 == null || row.sourceRef3 == null || row.shipmentLineNo == null) {
this.$message.warning('当前行缺少打印所需的IFS参数')
return
}
if (!this.printForm.assignQty || this.printForm.assignQty <= 0) {
this.$message.warning('分配数量必须大于0')
return
}
this.printLoading = true
try {
const printRequest = this.buildShipmentLinePrintRequest()
const { data } = await printLabelCommon(printRequest)
if (data && (data.code === 200 || data.code === 0)) {
this.$message.success(data.msg || '打印任务已发送成功')
this.shipmentLinePrintDialogVisible = false
} else {
this.$message.error((data && data.msg) || '打印失败')
}
} catch (error) {
this.$message.error(`打印失败: ${error.message || error}`)
} finally {
this.printLoading = false
}
},
}, },
} }
</script> </script>
@ -2910,6 +3414,114 @@ export default {
padding: 5px !important; padding: 5px !important;
} }
.shipment-line-print-form .el-form-item {
margin-bottom: 14px;
}
.print-qty-row {
display: flex;
align-items: center;
gap: 20px;
margin-bottom: 6px;
}
.print-qty-item {
flex: 1;
display: flex;
align-items: center;
min-width: 0;
}
.print-qty-label {
flex-shrink: 0;
margin-right: 8px;
font-size: 13px;
font-weight: 600;
color: #303133;
white-space: nowrap;
}
.shipment-line-print-form .print-input-number {
flex: 1;
width: 0;
min-width: 110px;
}
.shipment-line-print-form .print-input-number /deep/ .el-input {
width: 100%;
}
.shipment-line-print-form .print-input-number /deep/ .el-input__inner {
height: 32px;
line-height: 32px;
padding-left: 10px;
padding-right: 40px;
text-align: left;
}
.shipment-line-print-form .print-input-number /deep/ .el-input-number__increase,
.shipment-line-print-form .print-input-number /deep/ .el-input-number__decrease {
width: 32px;
height: 16px;
line-height: 16px;
font-size: 12px;
background: #f5f7fa;
border-left: 1px solid #dcdfe6;
}
.shipment-line-print-form .print-input-number /deep/ .el-input-number__increase {
border-bottom: 1px solid #dcdfe6;
border-radius: 0 4px 0 0;
}
.shipment-line-print-form .print-input-number /deep/ .el-input-number__decrease {
border-radius: 0 0 4px 0;
}
.shipment-line-print-form .print-input-number /deep/ .el-input-number__increase:hover,
.shipment-line-print-form .print-input-number /deep/ .el-input-number__decrease:hover {
color: #409eff;
}
.shipment-line-print-form .el-form-item__label {
padding-bottom: 4px;
line-height: 20px;
font-weight: 600;
color: #303133;
}
.shipment-line-print-form .form-hint {
margin: 0 0 14px;
font-size: 12px;
color: #909399;
line-height: 1.4;
}
.shipment-line-print-summary {
display: flex;
justify-content: space-between;
padding: 12px 16px;
background: #ecf5ff;
border-radius: 4px;
}
.shipment-line-print-summary .summary-item {
text-align: center;
}
.shipment-line-print-summary .summary-label {
display: block;
font-size: 12px;
color: #909399;
margin-bottom: 4px;
}
.shipment-line-print-summary .summary-value {
font-size: 16px;
font-weight: 600;
color: #409eff;
}
.el-table /deep/ .cell { .el-table /deep/ .cell {
height: auto; height: auto;
line-height: 1.5; line-height: 1.5;

Loading…
Cancel
Save