Browse Source

分拣bug

dev
常熟吴彦祖 2 weeks ago
parent
commit
1c5e60692d
  1. 3
      src/api/haianAutoWarehouse/palletPacking.js
  2. 288
      src/views/modules/haianAutoWarehouse/haianPalletSorting.vue

3
src/api/haianAutoWarehouse/palletPacking.js

@ -51,6 +51,9 @@ export const callPalletToStationWithUpdateZuPan = data => createAPI(`/haiAnWcsIn
// 海安-调用空托盘 - rqrq
export const callEmptyPalletToStation = data => createAPI(`/haiAnWcsIntegration/callEmptyPalletToStation`, 'post', data)
// 海安手工分拣拆分特例:复用老PDA标签拆分接口,新标签由后端去掉预留,原标签数量回写栈板明细 - rqrq
export const splitLabel = data => createAPI(`/pda/label/split`, 'post', data)
// 海安-结束分拣 - rqrq
export const finishSorting = data => createAPI(`/haiAnWcsIntegration/finishSorting`, 'post', data)

288
src/views/modules/haianAutoWarehouse/haianPalletSorting.vue

@ -146,11 +146,21 @@
<div class="col-position">位置</div>
<div class="col-layer">层数</div>
<div class="col-serial">标签号</div>
<div v-if="showSplitAction" class="col-action">操作</div>
</div>
<div v-for="(item, index) in detailList" :key="index" class="table-row">
<div v-for="(item, index) in detailList" :key="'main-' + index" class="table-row">
<div class="col-position">{{ item.position }}</div>
<div class="col-layer">{{ item.layer }}</div>
<div class="col-serial">{{ item.serialNo }}</div>
<div v-if="showSplitAction" class="col-action">
<button
class="table-split-btn"
:disabled="interfaceBusy"
@click="showSplitDialog(item)"
>
拆分
</button>
</div>
</div>
<div v-if="detailList.length === 0" class="table-row empty-row">
<div class="empty-hint">暂无分拣明细数据</div>
@ -174,11 +184,21 @@
<div class="col-position">位置</div>
<div class="col-layer">层数</div>
<div class="col-serial">标签号</div>
<div v-if="showSplitAction" class="col-action">操作</div>
</div>
<div v-for="(item, index) in detailList" :key="index" class="table-row">
<div v-for="(item, index) in detailList" :key="'browse-' + index" class="table-row">
<div class="col-position">{{ item.position }}</div>
<div class="col-layer">{{ item.layer }}</div>
<div class="col-serial">{{ item.serialNo }}</div>
<div v-if="showSplitAction" class="col-action">
<button
class="table-split-btn"
:disabled="interfaceBusy"
@click="showSplitDialog(item)"
>
拆分
</button>
</div>
</div>
<div v-if="detailList.length === 0" class="table-row empty-row">
<div class="empty-hint">暂无分拣明细数据</div>
@ -190,6 +210,56 @@
</div>
</el-dialog>
<!-- 手工分拣拆分弹窗交互对齐 /labelQuery仅工作盘显示被分拣源盘不走这里 - rqrq -->
<el-dialog
title="标签拆分"
:visible.sync="splitDialogVisible"
width="90%"
:close-on-click-modal="false"
:append-to-body="true"
:show-close="false"
>
<div class="split-dialog-content">
<div class="split-info-row">
<span class="split-label">原标签编码:</span>
<span class="split-value">{{ splitRow ? splitRow.serialNo : '' }}</span>
</div>
<div class="split-info-row">
<span class="split-label">当前数量:</span>
<span class="split-value">{{ splitRow ? formatQty(splitRow.qty) : 0 }}</span>
</div>
<div class="split-input-group">
<label class="split-label required">拆分数量:</label>
<el-input
v-model="splitQty"
type="number"
placeholder="请输入拆分数量"
class="split-input"
ref="splitInput"
:disabled="splitLoading"
/>
<div class="split-hint" v-if="splitQty && !isValidSplitQty">
<i class="el-icon-warning"></i>
拆分数量必须大于0且小于当前数量
</div>
</div>
<div class="split-info-row">
<span class="split-label">拆分后原标签剩余:</span>
<span class="split-value split-remain">{{ calculateRemainQty }}</span>
</div>
</div>
<div slot="footer" class="dialog-footer">
<button class="dialog-btn cancel" @click="splitDialogVisible = false" :disabled="splitLoading">取消</button>
<button
class="dialog-btn confirm"
@click="confirmSplit"
:disabled="splitLoading || !isValidSplitQty"
>
{{ splitLoading ? '处理中...' : '确定拆分' }}
</button>
</div>
</el-dialog>
<!-- 扫码模态框网格层数与原PDA页面保持一致 - rqrq -->
<el-dialog
title="扫描标签"
@ -289,7 +359,8 @@ import {
getAvailablePositionsForLayer,
completePalletAssemblyForFenJian,
finishSorting,
getSortingList
getSortingList,
splitLabel
} from '../../../api/haianAutoWarehouse/palletPacking'
export default {
@ -340,6 +411,11 @@ export default {
palletScanLoading: false,
palletConfigLoading: false,
scanRequestLoading: false,
// - rqrq
splitDialogVisible: false,
splitQty: '',
splitLoading: false,
splitRow: null
}
},
computed: {
@ -366,9 +442,30 @@ export default {
}
return this.positionGrid.map((p) => ({ ...p, isPlaceholder: false }))
},
// sortedSourceFlag=true - rqrq
showSplitAction() {
return this.palletScanned && !this.sortedSourceFlag
},
// 0 - rqrq
isValidSplitQty() {
if (!this.splitQty || !this.splitRow) {
return false
}
const split = Number(this.splitQty)
const current = Number(this.splitRow.qty) || 0
return split > 0 && split < current
},
// 0 - rqrq
calculateRemainQty() {
if (!this.splitRow || !this.splitQty) {
return this.splitRow ? this.formatQty(this.splitRow.qty) : 0
}
const remain = (Number(this.splitRow.qty) || 0) - (Number(this.splitQty) || 0)
return remain > 0 ? this.formatQty(remain) : 0
},
// - rqrq
interfaceBusy() {
return this.palletScanLoading || this.palletConfigLoading || this.scanRequestLoading || this.submitSortingLoading || this.finishSortingLoading
return this.palletScanLoading || this.palletConfigLoading || this.scanRequestLoading || this.submitSortingLoading || this.finishSortingLoading || this.splitLoading
}
},
methods: {
@ -379,6 +476,82 @@ export default {
}
return true
},
// 0 - rqrq
formatQty(qty) {
const num = Number(qty)
if (!Number.isFinite(num)) {
return 0
}
return parseFloat(String(num))
},
// - rqrq
showSplitDialog(item) {
if (!this.showSplitAction) {
return
}
if (!item || !item.serialNo) {
this.$alert('没有可拆分的标签', '提示', { confirmButtonText: '确定' })
return
}
this.splitRow = item
this.splitQty = ''
this.splitDialogVisible = true
this.$nextTick(() => {
if (this.$refs.splitInput) {
this.$refs.splitInput.focus()
}
})
},
// /pda/label/splitsite subSite 54 site 54A - rqrq
confirmSplit() {
if (!this.ensureSite() || this.splitLoading) {
return
}
if (this.sortedSourceFlag) {
this.$alert('被分拣栈板不允许拆分标签', '提示', { confirmButtonText: '确定' })
return
}
if (!this.splitRow || !this.splitRow.serialNo) {
this.$alert('没有可拆分的标签', '提示', { confirmButtonText: '确定' })
return
}
if (!this.splitQty) {
this.$alert('请输入拆分数量', '提示', { confirmButtonText: '确定' })
return
}
const splitQty = Number(this.splitQty)
const currentQty = Number(this.splitRow.qty) || 0
if (!(splitQty > 0)) {
this.$alert('拆分数量必须大于0', '提示', { confirmButtonText: '确定' })
return
}
if (!(splitQty < currentQty)) {
this.$alert('拆分数量必须小于当前数量', '提示', { confirmButtonText: '确定' })
return
}
const labelSite = (this.splitRow.subSite || this.site || '').trim()
this.splitLoading = true
splitLabel({
site: labelSite,
unitId: this.splitRow.serialNo,
splitQty: splitQty,
operatorName: localStorage.getItem('userName') || ''
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message.success('拆分成功')
this.splitDialogVisible = false
this.splitRow = null
this.splitQty = ''
this.refreshTable()
} else {
this.$alert((data && data.msg) || '拆分失败', '错误', { confirmButtonText: '确定' })
}
}).catch((error) => {
this.$message.error(error.message || '拆分失败')
}).finally(() => {
this.splitLoading = false
})
},
handleBack() {
if (this.interfaceBusy) {
return
@ -431,6 +604,10 @@ export default {
this.palletScanLoading = false
this.palletConfigLoading = false
this.scanRequestLoading = false
this.splitDialogVisible = false
this.splitQty = ''
this.splitLoading = false
this.splitRow = null
if (needFocus) {
this.$nextTick(() => {
if (this.$refs.palletInput) {
@ -990,11 +1167,112 @@ export default {
}
.col-serial {
flex: 4;
flex: 3;
text-align: center;
word-break: break-all;
}
.col-action {
flex: 1.4;
text-align: center;
}
.table-split-btn {
min-height: 36px;
padding: 6px 10px;
border: none;
border-radius: 4px;
background: #17B3A3;
color: #fff;
font-size: 13px;
cursor: pointer;
}
.table-split-btn:disabled {
background: #ccc;
cursor: not-allowed;
}
.split-dialog-content {
padding: 8px 0;
}
.split-info-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 0;
border-bottom: 1px solid #f0f0f0;
}
.split-label {
font-size: 14px;
color: #666;
font-weight: 500;
}
.split-value {
font-size: 15px;
font-weight: 600;
color: #333;
}
.split-value.split-remain {
color: #17B3A3;
font-size: 16px;
}
.split-input-group {
margin: 16px 0;
}
.split-input-group .split-label {
display: block;
margin-bottom: 8px;
}
.split-input {
width: 100%;
}
.split-hint {
margin-top: 6px;
color: #e6a23c;
font-size: 12px;
}
.dialog-btn {
flex: 1;
padding: 12px 24px;
border: none;
border-radius: 6px;
font-size: 16px;
font-weight: 500;
cursor: pointer;
min-height: 44px;
}
.dialog-btn.confirm {
background: #17B3A3;
color: white;
}
.dialog-btn.confirm:disabled {
background: #ccc;
cursor: not-allowed;
}
.dialog-btn.cancel {
background: #f5f5f5;
color: #333;
border: 1px solid #ddd;
}
.dialog-btn.cancel:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.empty-row {
justify-content: center;
align-items: center;

Loading…
Cancel
Save