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