feat: add ASRS inventory check PDA page

This commit is contained in:
tsiji 2026-07-07 10:01:52 +08:00
parent dc590064fa
commit 546f8dd76e
3 changed files with 333 additions and 0 deletions

View File

@ -47,3 +47,35 @@ export function agvUnbind(carrier) {
data: { carrier },
});
}
export function inventoryCheckMaterialQuery(checkNo, orderType) {
return request({
url: "/mom-wms/asrs/api/inventoryCheck/material/query",
method: "post",
data: { checkNo, orderType },
});
}
export function inventoryCheckMaterialOutbound(checkNo, orderType) {
return request({
url: "/mom-wms/asrs/api/inventoryCheck/material/outbound",
method: "post",
data: { checkNo, orderType },
});
}
export function inventoryCheckBinQuery(checkNo, orderType) {
return request({
url: "/mom-wms/asrs/api/inventoryCheck/bin/query",
method: "post",
data: { checkNo, orderType },
});
}
export function inventoryCheckBinOutbound(checkNo, orderType) {
return request({
url: "/mom-wms/asrs/api/inventoryCheck/bin/outbound",
method: "post",
data: { checkNo, orderType },
});
}

View File

@ -354,6 +354,14 @@ export default [
meta: {
keepAlive: false
}
},{
path: '/mobile/wms/asrs-inventory-check',
component: () =>
import('@/views/mobile/wms/asrs-inventory-check'),
name: '立库盘点',
meta: {
keepAlive: false
}
},{
path: '/mobile/wms/stereo-warehouse-inbound',
component: () =>

View File

@ -0,0 +1,293 @@
<template>
<div class="mobile-home">
<div class="content">
<mobile-navbar title="立库盘点"></mobile-navbar>
<div style="margin: 10px">
<el-form ref="formObj" :model="formObj" label-width="auto" @submit.native.prevent>
<el-row :gutter="10">
<el-col :span="24">
<el-form-item label="盘点方式">
<el-radio-group v-model="mode" size="small" @change="onModeChange">
<el-radio-button label="material">物料盘点</el-radio-button>
<el-radio-button label="bin">立体库库位盘点</el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="盘点单号">
<el-input
v-model="formObj.checkNo"
placeholder="扫描或输入盘点单号"
ref="checkNoInput"
@change="onCheckNoScan"
clearable
></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="出库类型">
<el-select v-model="formObj.orderType" placeholder="请选择出库类型" style="width: 100%">
<el-option label="盘点出库" value="盘点出库"></el-option>
<el-option label="调拨出库" value="调拨出库"></el-option>
<el-option label="取样出库" value="取样出库"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div v-if="inventoryList.length > 0" class="summary-bar">
<span>共 <strong>{{ totalCount }}</strong> 卷</span>
<span>合计:<strong>{{ totalQty }}</strong></span>
</div>
<el-empty
v-if="inventoryList.length === 0"
:image-size="60"
description="请扫描盘点单号"
></el-empty>
<div class="card-container">
<el-card
v-for="(row, index) in inventoryList"
:key="row.inventoryId || index"
shadow="never"
class="reel-card"
>
<div class="card-row">
<span class="card-label">卷号</span>
<span class="card-value">{{ row.inventoryId }}</span>
</div>
<div class="card-row">
<span class="card-label">物料</span>
<span class="card-value">{{ row.item }}</span>
</div>
<div class="card-row">
<span class="card-label">托盘</span>
<span class="card-value">{{ row.carrier }}</span>
</div>
<div class="card-row">
<span class="card-label">立库库位</span>
<span class="card-value">{{ row.asrsBin }}</span>
</div>
<div class="card-row">
<span class="card-label">等级</span>
<span class="card-value">{{ row.qualityInspectionStatus }}</span>
</div>
<div class="card-row">
<span class="card-label">数量</span>
<span class="card-value"><strong style="color: #409eff">{{ row.qtyOnHand }}</strong></span>
</div>
</el-card>
</div>
</div>
<div class="form-footer">
<el-button
type="danger"
:disabled="inventoryList.length === 0 || !formObj.orderType"
:loading="submitting"
@click="onSubmit"
>出库提交</el-button>
<el-button type="warning" @click="doClear">清除</el-button>
</div>
</div>
</div>
</template>
<script>
import MobileNavbar from "@/components/top-bar/mobile-navbar.vue";
import {
inventoryCheckMaterialQuery,
inventoryCheckMaterialOutbound,
inventoryCheckBinQuery,
inventoryCheckBinOutbound,
} from "@/api/wms/asrs";
import { showLoading, hideLoading } from "@/const/loading";
import { isBlank } from "@/util/string";
export default {
name: "AsrsInventoryCheck",
components: { MobileNavbar },
data() {
return {
mode: "material",
formObj: {
checkNo: "",
orderType: "盘点出库",
},
inventoryList: [],
totalCount: 0,
totalQty: 0,
submitting: false,
};
},
computed: {
modeText() {
return this.mode === "material" ? "物料盘点" : "立体库库位盘点";
},
},
mounted() {
this.focusCheckNoInput();
},
methods: {
focusCheckNoInput() {
this.$nextTick(() => {
this.$refs.checkNoInput && this.$refs.checkNoInput.focus();
});
},
onModeChange() {
this.inventoryList = [];
this.totalCount = 0;
this.totalQty = 0;
this.focusCheckNoInput();
if (!isBlank(this.formObj.checkNo)) {
this.onCheckNoScan();
}
},
onCheckNoScan() {
if (isBlank(this.formObj.checkNo)) {
this.$message.error("盘点单号不可为空");
return;
}
const queryApi = this.mode === "material"
? inventoryCheckMaterialQuery
: inventoryCheckBinQuery;
showLoading();
this.inventoryList = [];
queryApi(this.formObj.checkNo, this.formObj.orderType)
.then((res) => {
if (res.data.code !== 0) {
this.$message.error(res.data.msg || "查询失败");
this.focusCheckNoInput();
return;
}
const data = res.data.data || {};
this.inventoryList = data.items || [];
this.totalCount = data.totalCount || this.inventoryList.length;
this.totalQty = data.totalQty || 0;
if (this.inventoryList.length === 0) {
this.$message.warning("未查询到立库库存");
}
})
.catch((err) => {
const msg = err.response && err.response.data && (err.response.data.message || err.response.data.msg);
this.$message.error(msg || "查询失败,请重试");
this.focusCheckNoInput();
})
.finally(() => hideLoading());
},
onSubmit() {
this.$confirm(
`确认将盘点单 ${this.formObj.checkNo}【${this.modeText}】共 ${this.totalCount} 卷提交出库?`,
"出库确认",
{ confirmButtonText: "确认", cancelButtonText: "取消", type: "warning" },
)
.then(() => {
this.submitting = true;
showLoading();
const outboundApi = this.mode === "material"
? inventoryCheckMaterialOutbound
: inventoryCheckBinOutbound;
outboundApi(this.formObj.checkNo, this.formObj.orderType)
.then((res) => {
if (res.data.code !== 0) {
this.$message.error(res.data.msg || "提交失败,请重试");
return;
}
this.$message.success("出库提交成功");
this.doClear();
})
.catch((err) => {
const msg = err.response && err.response.data && (err.response.data.message || err.response.data.msg);
this.$message.error(msg || "提交失败,请重试");
})
.finally(() => {
this.submitting = false;
hideLoading();
});
})
.catch(() => {});
},
doClear() {
this.formObj.checkNo = "";
this.inventoryList = [];
this.totalCount = 0;
this.totalQty = 0;
this.focusCheckNoInput();
},
},
};
</script>
<style scoped>
.summary-bar {
display: flex;
justify-content: space-between;
padding: 6px 4px;
margin-bottom: 6px;
font-size: 13px;
color: #606266;
border-bottom: 1px solid #ebeef5;
}
.card-container {
height: calc(100vh - 300px);
overflow-y: auto;
}
.card-container::-webkit-scrollbar {
display: none;
}
.reel-card {
margin-bottom: 6px;
}
.reel-card /deep/ .el-card__body {
padding: 8px 12px;
}
.card-row {
display: flex;
justify-content: space-between;
align-items: center;
line-height: 1.8;
font-size: 13px;
}
.card-label {
color: #909399;
min-width: 70px;
}
.card-value {
font-weight: 500;
text-align: right;
word-break: break-all;
}
.form-footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 10px 16px;
background: #fff;
box-shadow: 0 -1px 6px rgba(0, 0, 0, 0.08);
display: flex;
gap: 10px;
}
.form-footer .el-button {
flex: 1;
}
</style>