Browse Source
feat(qc): 新增呆滞品临期品库存管理功能
feat(qc): 新增呆滞品临期品库存管理功能
- 新增呆滞品/临期品库存查询接口和API - 在质检结果录入页面增加批次明细查看功能 - 扩展质检数据模型增加批次和库位信息字段 - 实现批次明细查询参数传递和数据显示 - 新建呆滞品临期品库存管理页面组件 - 添加袋装明细查看和批量送检功能 - 实现库存按类型筛选和分页显示 - 集成库存管理和质检流程的关联功能master
3 changed files with 379 additions and 9 deletions
-
10src/api/pms/inventoryStock.js
-
45src/views/modules/qc/SQCResultEntry.vue
-
333src/views/modules/qc/stagnationExpiredStock.vue
@ -0,0 +1,10 @@ |
|||
import { createAPI } from "@/utils/httpRequest.js"; |
|||
|
|||
// 查询呆滞品/临期品库存列表
|
|||
export const queryStagnationExpiredStock = data => createAPI(`/pms/inventorystock/queryStagnationExpiredStock`, 'post', data); |
|||
|
|||
// 查询袋装明细列表
|
|||
export const queryPrintLabelBagList = data => createAPI(`/pms/inventorystock/queryPrintLabelBagList`, 'post', data); |
|||
|
|||
// 批量送检临期品
|
|||
export const batchSendExpiredForInspection = data => createAPI(`/pms/inventorystock/batchSendExpiredForInspection`, 'post', data); |
|||
@ -0,0 +1,333 @@ |
|||
<template> |
|||
<div> |
|||
<el-form :model="searchData" label-position="top" style="max-width: 1400px"> |
|||
<el-row :gutter="5"> |
|||
<el-col :span="2"> |
|||
<el-form-item label="工厂编码"> |
|||
<el-input v-model="searchData.site" clearable></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="3"> |
|||
<el-form-item label="物料编码"> |
|||
<el-input v-model="searchData.partNo" clearable></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="3"> |
|||
<el-form-item label="物料名称"> |
|||
<el-input v-model="searchData.partDescription" clearable></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="2"> |
|||
<el-form-item label="批次号"> |
|||
<el-input v-model="searchData.batchNo" clearable></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="2"> |
|||
<el-form-item label="仓库"> |
|||
<el-input v-model="searchData.warehouseName" clearable></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="2"> |
|||
<el-form-item label="库位"> |
|||
<el-input v-model="searchData.locationId" clearable></el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="2"> |
|||
<el-form-item label="临期天数"> |
|||
<el-input |
|||
v-model="searchData.daysToExpire" |
|||
oninput="value=value.replace(/[^\d]/g,'')" |
|||
clearable> |
|||
</el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="2"> |
|||
<el-form-item label="呆滞天数"> |
|||
<el-input |
|||
v-model="searchData.stagnationDays" |
|||
oninput="value=value.replace(/[^\d]/g,'')" |
|||
clearable> |
|||
</el-input> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="2"> |
|||
<el-form-item label="类型"> |
|||
<el-select v-model="searchData.type" clearable> |
|||
<el-option value="" label="全部"></el-option> |
|||
<el-option value="STAGNATION" label="呆滞品"></el-option> |
|||
<el-option value="EXPIRED" label="临期品"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
</el-col> |
|||
<el-col :span="4"> |
|||
<el-form-item label=" "> |
|||
<el-button type="primary" @click="search">查询</el-button> |
|||
<el-button @click="reset">重置</el-button> |
|||
<el-button type="success" @click="batchSendInspection">批量送检</el-button> |
|||
</el-form-item> |
|||
</el-col> |
|||
</el-row> |
|||
</el-form> |
|||
|
|||
<el-table :data="tableData" border v-loading="loading" height="calc(100vh - 190px)" @selection-change="handleSelectionChange"> |
|||
<el-table-column type="selection" width="55" align="center"/> |
|||
<el-table-column label="操作" width="100" align="center"> |
|||
<template slot-scope="scope"> |
|||
<a @click="showBagDetail(scope.row)">袋装明细</a> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="site" label="工厂编码" align="left" header-align="center" min-width="80"/> |
|||
<el-table-column prop="warehouseId" label="仓库ID" align="left" header-align="center" min-width="100"/> |
|||
<el-table-column prop="warehouseName" label="仓库名称" align="left" header-align="center" min-width="120"/> |
|||
<el-table-column prop="partNo" label="物料编码" align="left" header-align="center" min-width="120"/> |
|||
<el-table-column prop="partDescription" label="物料名称" align="left" header-align="center" min-width="200"/> |
|||
<el-table-column prop="batchNo" label="批次号" align="left" header-align="center" min-width="120"/> |
|||
<el-table-column prop="type" label="类型" align="center" header-align="center" min-width="100"> |
|||
<template slot-scope="scope"> |
|||
<el-tag |
|||
:type="scope.row.type === 'STAGNATION' ? 'warning' : 'danger'" |
|||
size="small"> |
|||
{{ scope.row.type === 'STAGNATION' ? '呆滞品' : '临期品' }} |
|||
</el-tag> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="locationId" label="库位" align="left" header-align="center" min-width="100"/> |
|||
<el-table-column prop="qtyOnHand" label="库存数量" align="right" header-align="center" min-width="100"/> |
|||
<el-table-column prop="firstInDate" label="入库日期" align="left" header-align="center" min-width="110"/> |
|||
<el-table-column prop="latestOutDate" label="最后出库日期" align="left" header-align="center" min-width="110"/> |
|||
<el-table-column prop="latestInDate" label="最后入库日期" align="left" header-align="center" min-width="110"/> |
|||
<el-table-column prop="expiredDate" label="失效日期" align="left" header-align="center" min-width="110"/> |
|||
<el-table-column prop="stagnationStartDate" label="呆滞起算日" align="left" header-align="center" min-width="120"/> |
|||
<el-table-column prop="stagnationDays" label="呆滞天数" align="right" header-align="center" min-width="100"/> |
|||
<el-table-column prop="daysToExpire" label="距过期天数" align="right" header-align="center" min-width="100"/> |
|||
|
|||
|
|||
<el-table-column prop="expireDateControlFlag" label="有效期管理" align="center" header-align="center" min-width="120"> |
|||
<template slot-scope="scope"> |
|||
{{ scope.row.expireDateControlFlag === 'Y' ? '是' : '否' }} |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="toExpireDays" label="有效期天数" align="right" header-align="center" min-width="100"/> |
|||
</el-table> |
|||
|
|||
|
|||
<el-pagination |
|||
@size-change="sizeChangeHandle" |
|||
@current-change="currentChangeHandle" |
|||
:current-page.sync="pageIndex" |
|||
:page-sizes="[10, 20, 50, 100, 200]" |
|||
:page-size="pageSize" |
|||
layout="total,sizes, prev, pager, next" |
|||
:total="totalPage"> |
|||
</el-pagination> |
|||
|
|||
<el-dialog :visible.sync="bagDetailVisible" v-drag top="5vh" title="袋装明细" width="80%" :close-on-click-modal="false"> |
|||
<el-table :data="bagDetailData" border v-loading="bagDetailLoading" height="400px"> |
|||
<el-table-column prop="site" label="工厂编码" align="left" header-align="center" min-width="80"/> |
|||
<el-table-column prop="partNo" label="物料编码" align="left" header-align="center" min-width="120"/> |
|||
<el-table-column prop="partDescription" label="物料名称" align="left" header-align="center" min-width="200"/> |
|||
<el-table-column prop="seqNo" label="Seq No" align="left" header-align="center" min-width="100"/> |
|||
<el-table-column prop="itemNo" label="序号" align="left" header-align="center" min-width="60"/> |
|||
<el-table-column prop="printQty" label="数量" align="right" header-align="center" min-width="80"/> |
|||
<el-table-column prop="batchNo" label="批次号" align="left" header-align="center" min-width="120"/> |
|||
<el-table-column prop="warehouseName" label="仓库" align="left" header-align="center" min-width="120"/> |
|||
<el-table-column prop="locationId" label="库位" align="left" header-align="center" min-width="100"/> |
|||
<el-table-column prop="status" label="状态" align="center" header-align="center" min-width="80"/> |
|||
<el-table-column prop="weight" label="重量" align="right" header-align="center" min-width="80"/> |
|||
<el-table-column prop="createTime" label="创建时间" align="center" header-align="center" min-width="120"/> |
|||
<el-table-column prop="updateTime" label="入库时间" align="center" header-align="center" min-width="120"/> |
|||
</el-table> |
|||
<span slot="footer" class="dialog-footer" style="text-align: center"> |
|||
<el-button type="primary" @click="bagDetailVisible = false">关闭</el-button> |
|||
</span> |
|||
</el-dialog> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { queryStagnationExpiredStock, queryPrintLabelBagList, batchSendExpiredForInspection } from '@/api/pms/inventoryStock' |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
searchData: { |
|||
site: '', |
|||
partNo: '', |
|||
partDescription: '', |
|||
batchNo: '', |
|||
warehouseName: '', |
|||
locationId: '', |
|||
daysToExpire: '', |
|||
stagnationDays: '', |
|||
type: '' |
|||
}, |
|||
tableData: [], |
|||
pageIndex: 1, |
|||
pageSize: 50, |
|||
totalPage: 0, |
|||
loading: false, |
|||
// 袋装明细相关 |
|||
bagDetailVisible: false, |
|||
bagDetailLoading: false, |
|||
bagDetailData: [], |
|||
currentRow: {}, |
|||
// 批量选择相关 |
|||
selectedRows: [] |
|||
} |
|||
}, |
|||
mounted() { |
|||
// 进入页面不默认查询数据 |
|||
}, |
|||
methods: { |
|||
search() { |
|||
// 验证工厂编码必填 |
|||
if (!this.searchData.site || this.searchData.site.trim() === '') { |
|||
this.$message.warning('工厂编码为必填项') |
|||
return |
|||
} |
|||
this.pageIndex = 1 |
|||
this.getDataList() |
|||
}, |
|||
reset() { |
|||
this.searchData = { |
|||
site: '', |
|||
partNo: '', |
|||
partDescription: '', |
|||
batchNo: '', |
|||
warehouseName: '', |
|||
locationId: '', |
|||
daysToExpire: '', |
|||
stagnationDays: '', |
|||
type: '' |
|||
} |
|||
this.pageIndex = 1 |
|||
this.getDataList() |
|||
}, |
|||
getDataList() { |
|||
this.loading = true |
|||
const params = { |
|||
...this.searchData, |
|||
page: this.pageIndex, |
|||
limit: this.pageSize |
|||
} |
|||
|
|||
queryStagnationExpiredStock(params).then(({ data: res }) => { |
|||
this.loading = false |
|||
if (res.code !== 0) { |
|||
return this.$message.error(res.msg) |
|||
} |
|||
this.tableData = res.page.list || [] |
|||
this.totalPage = res.page.totalCount || 0 |
|||
}).catch(() => { |
|||
this.loading = false |
|||
}) |
|||
}, |
|||
sizeChangeHandle(val) { |
|||
this.pageSize = val |
|||
this.pageIndex = 1 |
|||
this.getDataList() |
|||
}, |
|||
currentChangeHandle(val) { |
|||
this.pageIndex = val |
|||
this.getDataList() |
|||
}, |
|||
// 显示袋装明细 |
|||
showBagDetail(row) { |
|||
this.currentRow = row |
|||
this.bagDetailVisible = true |
|||
this.getBagDetailList() |
|||
}, |
|||
// 获取袋装明细列表 |
|||
getBagDetailList() { |
|||
this.bagDetailLoading = true |
|||
const params = { |
|||
site: this.currentRow.site, |
|||
partNo: this.currentRow.partNo, |
|||
batchNo: this.currentRow.batchNo, |
|||
warehouseId: this.currentRow.warehouseId, |
|||
locationId: this.currentRow.locationId, |
|||
page: 1, |
|||
limit: 100 |
|||
} |
|||
|
|||
queryPrintLabelBagList(params).then(({ data: res }) => { |
|||
this.bagDetailLoading = false |
|||
if (res.code !== 0) { |
|||
return this.$message.error(res.msg) |
|||
} |
|||
this.bagDetailData = res.page.list || [] |
|||
}).catch(() => { |
|||
this.bagDetailLoading = false |
|||
}) |
|||
}, |
|||
// 复选框选择变化 |
|||
handleSelectionChange(selection) { |
|||
this.selectedRows = selection |
|||
}, |
|||
// 批量送检 |
|||
batchSendInspection() { |
|||
// 验证是否有选中数据 |
|||
if (!this.selectedRows || this.selectedRows.length === 0) { |
|||
this.$message.warning('请至少选择一条数据进行送检') |
|||
return |
|||
} |
|||
|
|||
// 过滤出临期品 |
|||
const expiredRows = this.selectedRows.filter(row => row.type === 'EXPIRED') |
|||
|
|||
if (expiredRows.length === 0) { |
|||
this.$message.warning('只能选择临期品进行送检') |
|||
return |
|||
} |
|||
|
|||
// 如果有非临期品,给出提示 |
|||
if (expiredRows.length < this.selectedRows.length) { |
|||
this.$message.warning(`已自动过滤 ${this.selectedRows.length - expiredRows.length} 条非临期品数据,仅送检临期品`) |
|||
} |
|||
|
|||
// 确认送检 |
|||
this.$confirm(`确认将选中的 ${expiredRows.length} 条临期品数据进行送检?`, '提示', { |
|||
confirmButtonText: '确定', |
|||
cancelButtonText: '取消', |
|||
type: 'warning' |
|||
}).then(() => { |
|||
const sendParams = expiredRows.map(row => ({ |
|||
site: row.site, |
|||
partNo: row.partNo, |
|||
batchNo: row.batchNo, |
|||
warehouseId: row.warehouseId, |
|||
locationId: row.locationId |
|||
})) |
|||
|
|||
if (sendParams.length === 0) { |
|||
this.$message.error('选中的数据缺少有效信息') |
|||
return |
|||
} |
|||
|
|||
this.loading = true |
|||
batchSendExpiredForInspection(sendParams).then(({ data: res }) => { |
|||
this.loading = false |
|||
if (res.code === 0) { |
|||
this.$message.success(res.msg || '批量送检成功') |
|||
// 清空选择 |
|||
this.selectedRows = [] |
|||
// 重新查询 |
|||
this.getDataList() |
|||
} else { |
|||
this.$message.error(res.msg || '批量送检失败') |
|||
} |
|||
}).catch((error) => { |
|||
this.loading = false |
|||
this.$message.error('批量送检异常: ' + (error.message || '未知错误')) |
|||
}) |
|||
}).catch(() => { |
|||
// 用户取消操作 |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
|
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue