库存修改

This commit is contained in:
z 2025-07-05 02:52:44 +08:00
parent 8ef746fbfc
commit 671150e40d
11 changed files with 183 additions and 132 deletions

View File

@ -123,5 +123,11 @@ public class StorageInventoryController {
PageResult<StorageInventoryDO> pageResult = storageInventoryService.getSupplementPage(pageReqVO); PageResult<StorageInventoryDO> pageResult = storageInventoryService.getSupplementPage(pageReqVO);
return success(pageResult); return success(pageResult);
} }
@GetMapping("/realTimeInventory")
@Operation(summary = "获得实时库存分页")
@PreAuthorize("@ss.hasPermission('heli:storage-inventory:query')")
public CommonResult<PageResult<StorageInventoryDO>> realTimeInventory(@Valid StorageInventoryPageReqVO pageReqVO) {
PageResult<StorageInventoryDO> pageResult = storageInventoryService.realTimeInventory(pageReqVO);
return success(pageResult);
}
} }

View File

@ -111,7 +111,8 @@ public class StorageInventoryDO extends BaseDO {
@TableField(exist = false) @TableField(exist = false)
private BigDecimal storageOkQty; private BigDecimal storageOkQty;
@TableField(exist = false)
private BigDecimal sumKcMoney;
@TableField(exist = false) @TableField(exist = false)
private String matName; private String matName;
@ -146,4 +147,5 @@ public class StorageInventoryDO extends BaseDO {
private String invSafe; private String invSafe;
@TableField(exist = false) @TableField(exist = false)
private Integer exist;//是否存在盘库使用 0存在 1不存在 private Integer exist;//是否存在盘库使用 0存在 1不存在
} }

View File

@ -3,6 +3,7 @@ package com.chanko.yunxi.mes.module.heli.dal.mysql.storageinventory;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import cn.hutool.core.util.ObjectUtil;
import com.chanko.yunxi.mes.framework.common.pojo.PageResult; import com.chanko.yunxi.mes.framework.common.pojo.PageResult;
import com.chanko.yunxi.mes.framework.mybatis.core.query.LambdaQueryWrapperX; import com.chanko.yunxi.mes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.chanko.yunxi.mes.framework.mybatis.core.mapper.BaseMapperX; import com.chanko.yunxi.mes.framework.mybatis.core.mapper.BaseMapperX;
@ -169,10 +170,10 @@ public interface StorageInventoryMapper extends BaseMapperX<StorageInventoryDO>
default PageResult<StorageInventoryDO> getSupplementPage(StorageInventoryPageReqVO pageReqVO){ default PageResult<StorageInventoryDO> getSupplementPage(StorageInventoryPageReqVO pageReqVO){
MPJLambdaWrapper<StorageInventoryDO> subQuery = new MPJLambdaWrapper<>(); MPJLambdaWrapper<StorageInventoryDO> subQuery = new MPJLambdaWrapper<>();
subQuery.select(StorageInventoryDO::getMatCode) subQuery.select(StorageInventoryDO::getMaterialId)
.leftJoin(MaterialDO.class, "m", MaterialDO::getId, StorageInventoryDO::getMaterialId) .leftJoin(MaterialDO.class, "m", MaterialDO::getId, StorageInventoryDO::getMaterialId)
.groupBy(StorageInventoryDO::getMaterialId) .groupBy(StorageInventoryDO::getMaterialId)
.having("SUM(yard_amount) < COALESCE(MAX(m.inv_safe), 0)"); .having("SUM(t.yard_amount) < COALESCE(MAX(m.inv_safe), 0)");
//执行子查询获取符合条件的matCode //执行子查询获取符合条件的matCode
List<Long> qualifiedMatCodes = this.selectList(subQuery) List<Long> qualifiedMatCodes = this.selectList(subQuery)
.stream() .stream()
@ -217,4 +218,40 @@ public interface StorageInventoryMapper extends BaseMapperX<StorageInventoryDO>
return selectPage(pageReqVO, query); return selectPage(pageReqVO, query);
} }
default PageResult<StorageInventoryDO> realTimeInventory(StorageInventoryPageReqVO pageReqVO){
MPJLambdaWrapper<StorageInventoryDO> query = new MPJLambdaWrapper<>();
query.selectAll(StorageInventoryDO.class)
.select("ifnull(sum(t.yard_amount),0) storageOkQty")
.select("ROUND(ifnull(t.yard_amount * t.price,0), 2) as sumKcMoney")
.select("m.name as matName,m.code as matCode,d.label as matType,m.spec as matSpec,m.brand as matBrand")
.select("d1.label as matUnit")
.select("w.wh_name as whName","r.rg_name as rgName","p.pn_name as pnName")
.select("m.material_type as materialTypeId","m.unit as matUnitId")
.leftJoin(MaterialDO.class, "m", MaterialDO::getId, StorageInventoryDO::getMaterialId)
.leftJoin(DictDataDO.class,"d",DictDataDO::getValue, MaterialDO::getMaterialType)
.leftJoin(DictDataDO.class,"d1",DictDataDO::getValue, MaterialDO::getUnit)
.leftJoin(WarehouseDO.class,"w",WarehouseDO::getId, StorageInventoryDO::getWhId)
.leftJoin(RgDO.class,"r",RgDO::getId, StorageInventoryDO::getRgId)
.leftJoin(PnDO.class,"p",PnDO::getId, StorageInventoryDO::getPnId)
.disableSubLogicDel()
.groupBy(StorageInventoryDO::getId)
.orderByDesc(StorageInventoryDO::getId);
query.like(!com.alibaba.druid.util.StringUtils.isEmpty(pageReqVO.getMatSpec()),MaterialDO::getSpec, pageReqVO.getMatSpec())
.like(!com.alibaba.druid.util.StringUtils.isEmpty(pageReqVO.getMatName()), MaterialDO::getName, pageReqVO.getMatName())
.like(!com.alibaba.druid.util.StringUtils.isEmpty(pageReqVO.getMatCode()), MaterialDO::getCode, pageReqVO.getMatCode())
.like(!com.alibaba.druid.util.StringUtils.isEmpty(pageReqVO.getShortName()), MaterialDO::getShortName, pageReqVO.getShortName())
.eq(ObjectUtil.isNotEmpty(pageReqVO.getMatType()),MaterialDO::getMaterialType, pageReqVO.getMatType())
.eq(ObjectUtil.isNotEmpty(pageReqVO.getLotNo()),StorageInventoryDO::getLotNo, pageReqVO.getLotNo())
.eq(true,MaterialDO::getVirtualPart, YesOrNoEnum.N.name())
.ne(StorageInventoryDO::getYardAmount,0)
.eq(MaterialDO::getStatus,1)
.eq(pageReqVO.getWhId()!= null,StorageInventoryDO::getWhId, pageReqVO.getWhId())
.eq(pageReqVO.getRgId()!= null,StorageInventoryDO::getRgId, pageReqVO.getRgId())
.eq(pageReqVO.getPnId()!= null,StorageInventoryDO::getPnId, pageReqVO.getPnId())
.eq("d.dict_type","heli_material_type")
.eq("d1.dict_type","heli_material_unit");
return selectPage(pageReqVO, query);
}
} }

View File

@ -57,4 +57,6 @@ public interface StorageInventoryService {
List<StorageInventoryDO> getStorageNowList(StorageInventoryPageReqVO queryReqVO); List<StorageInventoryDO> getStorageNowList(StorageInventoryPageReqVO queryReqVO);
StorageInventoryDO selectNowByMatPnId(Long matId, Long pnId); StorageInventoryDO selectNowByMatPnId(Long matId, Long pnId);
PageResult<StorageInventoryDO> realTimeInventory(StorageInventoryPageReqVO pageReqVO);
} }

View File

@ -101,4 +101,9 @@ public class StorageInventoryServiceImpl implements StorageInventoryService {
.eq(StorageInventoryDO::getPnId, pnId)); .eq(StorageInventoryDO::getPnId, pnId));
} }
@Override
public PageResult<StorageInventoryDO> realTimeInventory(StorageInventoryPageReqVO pageReqVO) {
return storageInventoryMapper.realTimeInventory(pageReqVO);
}
} }

View File

@ -6,7 +6,7 @@
"private": false, "private": false,
"scripts": { "scripts": {
"i": "pnpm install", "i": "pnpm install",
"dev": "vite --mode dev", "dev": "vite --mode base",
"front": "vite --mode front", "front": "vite --mode front",
"ts:check": "vue-tsc --noEmit", "ts:check": "vue-tsc --noEmit",
"build:pro": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode pro", "build:pro": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode pro",

View File

@ -58,3 +58,7 @@ export const exportStorageInventory = async (params) => {
export const getSupplementPage = async (params) => { export const getSupplementPage = async (params) => {
return await request.get({ url: `/heli/storage-inventory/getSupplementPage`, params }) return await request.get({ url: `/heli/storage-inventory/getSupplementPage`, params })
} }
// 查询入/出库实时分页
export const realTimeInventory = async (params) => {
return await request.get({ url: `/heli/storage-inventory/realTimeInventory`, params })
}

View File

@ -255,14 +255,14 @@ const handleExportDetail = async () => {
exportLoading.value = false exportLoading.value = false
} }
} }
const getMat = async (rowids,amount,ids,matCodes,name) => { const getMat = async (data) => {
//formData.value.boomItemDOList = arrBoom //formData.value.boomItemDOList = arrBoom
for(var i = 0 ; i < list.value.length ; i ++){ for(var i = 0 ; i < list.value.length ; i ++){
if(list.value[i].id == rowids){ if(list.value[i].id == data.rowid){
list.value[i].matRest = amount list.value[i].matRest = data.matRest
list.value[i].matCode = matCodes list.value[i].matCode = data.matCode
list.value[i].materialId = ids list.value[i].materialId = data.materialId
list.value[i].materialName = name list.value[i].materialName =data.matName
// await updateRow(2,list.value[i]); // await updateRow(2,list.value[i]);
break; break;
} }

View File

@ -1,54 +1,66 @@
<template> <template>
<Dialog title="实时库存" v-model="dialogVisible" width="80%"> <Dialog title="实时库存" v-model="dialogVisible" width="80%">
<el-card class="hl-card"> <el-card class="hl-card">
<ContentWrap class="borderxx"> <ContentWrap class="borderxx">
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="120px"> <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="120px">
<el-form-item label="物料名称" prop="matName" > <el-form-item label="物料名称" prop="matName" >
<el-input v-model="queryParams.matName" placeholder="物料名称" clearable @keyup.enter="handleQuery" class="!w-240px" /> <el-input v-model="queryParams.matName" placeholder="物料名称" clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item> </el-form-item>
<el-form-item label="规格型号" prop="matSpec" >
<el-input v-model="queryParams.matSpec" placeholder="规格型号" clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<el-form-item label="物料简称" prop="shortName" >
<el-input v-model="queryParams.shortName" placeholder="物料简称" clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<el-form-item >
<el-button @click="handleQuery" type="primary">
<Icon icon="ep:search" class="mr-5px" /> 搜索
</el-button>
<el-button @click="resetQuery">
<Icon icon="ep:refresh" class="mr-5px" /> 重置
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<el-form-item > <ContentWrap>
<el-button @click="handleQuery" type="primary"> <el-table ref="multipleTableRef" v-loading="loading" :data="list" :stripe="true" @row-click="clickRow" @selection-change="handleCurrentChange" :show-overflow-tooltip="true" class="hl-table">
<Icon icon="ep:search" class="mr-5px" /> 搜索 <el-table-column
</el-button> type="selection"
<el-button @click="resetQuery"> width="55"/>
<Icon icon="ep:refresh" class="mr-5px" /> 重置 <el-table-column type="index" width="100" fixed label="序号" align="center" />
</el-button> <el-table-column prop="matCode" label="物料编码" :fixed="left" min-width="120" align="center" />
</el-form-item> <el-table-column prop="matName" label="物料名称" :fixed="left" min-width="140" align="center" />
</el-form> <el-table-column prop="matType" label="物料类型" min-width="120" align="center" />
</ContentWrap> <el-table-column prop="shortName" label="物料简称" min-width="120" align="center" />
<el-table-column prop="matSpec" label="规格/型号" min-width="120" align="center" />
<!-- 列表 --> <el-table-column prop="matBrand" label="品牌" min-width="120" align="center" />
<ContentWrap> <el-table-column prop="whName" label="仓库" min-width="120" align="center" >
<el-table <template #default="scope">
ref="multipleTableRef" v-loading="loading" :data="list" :stripe="true" {{scope.row.whName}}
@row-click="clickRow" @selection-change="handleCurrentChange" :show-overflow-tooltip="true" class="hl-table"> </template>
<el-table-column </el-table-column>
type="selection" <el-table-column prop="rgName" label="库区" min-width="120" align="center" >
width="55"/> <template #default="scope">
<el-table-column type="index" width="100" fixed label="序号" align="center" /> {{scope.row.rgName}}
<el-table-column label="物料编码" align="center" prop="matCode" fixed min-width="120" /> </template>
<el-table-column label="物料名称" align="center" prop="matName" fixed min-width="120"/> </el-table-column>
<el-table-column label="物料类型" align="center" prop="matType" min-width="120"/> <el-table-column prop="pnName" label="库位" min-width="140" align="center" >
<el-table-column label="物料简称" align="center" prop="shortName" min-width="120"/> <template #default="scope">
<el-table-column label="规格/型号" align="center" prop="matSpec" min-width="120"/> {{scope.row.pnName}}
<el-table-column label="品牌" align="center" prop="matBrand" min-width="120"/> </template>
<el-table-column label="仓库" align="center" prop="whName" min-width="120"/> </el-table-column>
<el-table-column label="库区" align="center" prop="rgName" min-width="120"/> <el-table-column prop="matRest" label="库存数量" min-width="120" align="center" />
<el-table-column label="库位" align="center" prop="pnName" min-width="120"/> <el-table-column prop="matUnit" label="库存单位" min-width="120" align="center" />
<el-table-column label="批次号" align="center" prop="lotNo" min-width="120" v-if="false"/> </el-table>
<el-table-column label="库存数量" align="center" prop="storageOkQty" min-width="120"/> <!-- 分页 -->
<el-table-column label="金额(元)" align="center" prop="sumKcMoney" min-width="120"/> <Pagination
<el-table-column label="库存单位" align="center" prop="matUnit" min-width="120"/> :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
</el-table> @pagination="getList" />
<!-- 分页 --> </ContentWrap>
<Pagination </el-card>
:total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
@pagination="getList" />
</ContentWrap>
</el-card>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button> <el-button @click="dialogVisible = false">取消</el-button>
@ -57,45 +69,43 @@ ref="multipleTableRef" v-loading="loading" :data="list" :stripe="true"
</el-button> </el-button>
</span> </span>
</template> </template>
</Dialog> </Dialog>
<printDialog ref="printref" :minAmount="minAmount" :formData="formData" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import download from '@/utils/download' import {DICT_TYPE} from "@/utils/dict";
import * as StorageLogApi from '@/api/heli/storagelog' import * as MaterialApi from "@/api/heli/material";
import * as StorageInventoryApi from "@/api/heli/storageinventory";
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import * as WarehouseApi from '@/api/heli/warehouse'
import * as RgApi from '@/api/heli/rg'
import * as PnApi from '@/api/heli/pn'
defineOptions({ name: 'StorageLog' }) defineOptions({ name: 'StorageLog' })
const printref = ref() const printref = ref()
const whList = ref([]) const whList = ref([])
const rgList = ref([]) const rgList = ref([])
const pnList = ref([]) const pnList = ref([])
const dialogVisible = ref(false) const dialogVisible = ref(false)
const rgCurrentList = ref([])
const pnCurrentList = ref([])
const message = useMessage() // const message = useMessage() //
const { t } = useI18n() // const { t } = useI18n() //
const loading = ref(true) // const loading = ref(true) //
const list = ref([]) // const list = ref([]) //
const total = ref(0) // const total = ref(0) //
const queryParams = reactive({ const queryParams = reactive({
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
matCode: undefined, code: undefined,
matName: undefined, name: undefined,
matType: undefined, matType: undefined,
lotNo: undefined, lotNo: undefined,
whId: undefined, whId: undefined,
rgId:undefined, rgId:undefined,
pnId: undefined, pnId: undefined,
headerNo: undefined, headerNo: undefined,
spec:undefined,
shortName:undefined,
matName:undefined,
matSpec:undefined,
}) })
@ -107,7 +117,7 @@ const multipleTableRef = ref()
const getList = async () => { const getList = async () => {
loading.value = true loading.value = true
try { try {
const data = await StorageLogApi.getStorageNowPage(queryParams) const data = await StorageInventoryApi.getStorageInventoryPage(queryParams)
list.value = data.list list.value = data.list
total.value = data.total total.value = data.total
} finally { } finally {
@ -116,95 +126,79 @@ const getList = async () => {
} }
const clickItem = ref([]) const clickItem = ref([])
const handleCurrentChange = (val) => { const handleCurrentChange = (val) => {
clickItem.value = val; clickItem.value = val;
if(val.length > 1){ if(val.length > 1){
multipleTableRef.value!.clearSelection() multipleTableRef.value!.clearSelection()
multipleTableRef.value!.toggleRowSelection(val.pop()) multipleTableRef.value!.toggleRowSelection(val.pop())
} }
};
}
const clickRow = (row) => { const clickRow = (row) => {
// if (clickItem.value==null){
if ( clickItem.value[0] == row) { clickItem.value = [];
//
clickItem.value = [];
multipleTableRef.value!.clearSelection()
} else {
//
clickItem.value.push(row);
multipleTableRef.value!.clearSelection()
multipleTableRef.value!.toggleRowSelection(row, true);
}
}
}
//
if ( clickItem.value[0] == row) {
//
clickItem.value = [];
multipleTableRef.value!.clearSelection()
} else {
//
clickItem.value.push(row);
multipleTableRef.value!.clearSelection()
multipleTableRef.value!.toggleRowSelection(row, true);
}
}
/** 搜索按钮操作 */ /** 搜索按钮操作 */
const handleQuery = () => { const handleQuery = () => {
queryParams.pageNo = 1 queryParams.pageNo = 1
getList() getList()
} }
const printfClick = () =>{
if(clickItem.value == null || clickItem.value.length == 0){
message.error("至少选择一项后,打印!")
return
}
printref.value.open(clickItem.value.storageOkQty)
}
/** 重置按钮操作 */ /** 重置按钮操作 */
const resetQuery = () => { const resetQuery = () => {
queryFormRef.value.resetFields() queryFormRef.value.resetFields()
handleQuery() handleQuery()
} }
const handleWh = async (wid) => {
queryParams.rgId = undefined
queryParams.pnId = undefined
rgCurrentList.value =[]
pnCurrentList.value =[]
rgCurrentList.value = rgList.value.filter( (item) => { return item.wh_id == wid})
}
const rowid = ref() const rowid = ref()
const open = async (rowids,matCode) => { const open = async (rowids,matCode) => {
clickItem.value = null; clickItem.value = null;
//multipleTableRef.value!.clearSelection() //multipleTableRef.value!.clearSelection()
dialogVisible.value = true dialogVisible.value = true
queryParams.matName = matCode; // queryParams.matName = matCode;
rowid.value = rowids rowid.value = rowids
queryParams.matName = matCode;
console.log(rowids)
console.log(rowid.value)
await getList(); await getList();
} }
defineExpose({ open }) // open defineExpose({ open }) // open
const emit = defineEmits(['success']) const emit = defineEmits(['success'])
// emit('success', multipleSelection.value) // emit('success', multipleSelection.value)
const success = () =>{ const success = () => {
dialogVisible.value = false; dialogVisible.value = false;
console.log(clickItem.value) const data={
emit('success',rowid.value,clickItem.value[0].storageOkQty,clickItem.value[0].id,clickItem.value[0].matCode,clickItem.value[0].matName) rowid:rowid.value,
materialId:clickItem.value[0].materialId,
matCode:clickItem.value[0].matCode,
matName: clickItem.value[0].matName,
whId:clickItem.value[0].whId,
rgId:clickItem.value[0].rgId,
pnId:clickItem.value[0].pnId,
rgName:clickItem.value[0].rgName,
pnName:clickItem.value[0].pnName,
matRest:clickItem.value[0].matRest
}
emit('success', data)
} }
const handleRg = async (rgid) => {
pnCurrentList.value =[]
pnCurrentList.value = pnList.value.filter( (item) => { return item.rg_id == rgid})
}
//
const init_page_wh = (async ()=>{
whList.value = await WarehouseApi.getSimpList()
})
//
const init_page_rg = (async ()=>{
rgList.value = await RgApi.getSimpList()
})
//
const init_page_pn = (async ()=>{
pnList.value = await PnApi.getSimpList()
})
/** 初始化 **/ /** 初始化 **/
onMounted(async () => { onMounted(async () => {
await init_page_wh()
await init_page_rg()
await init_page_pn()
await getList() await getList()
}) })
</script> </script>

View File

@ -95,6 +95,7 @@ v-for="dict in pnCurrentList" :key="dict.id" :label="dict.pn_name"
<script setup lang="ts"> <script setup lang="ts">
import download from '@/utils/download' import download from '@/utils/download'
import * as StorageLogApi from '@/api/heli/storagelog' import * as StorageLogApi from '@/api/heli/storagelog'
import * as StorageInventoryApi from '@/api/heli/storageinventory'
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict' import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
@ -135,7 +136,7 @@ const queryFormRef = ref() // 搜索的表单
const getList = async () => { const getList = async () => {
loading.value = true loading.value = true
try { try {
const data = await StorageLogApi.getStorageNowPage(queryParams) const data = await StorageInventoryApi.realTimeInventory(queryParams)
list.value = data.list list.value = data.list
total.value = data.total total.value = data.total
} finally { } finally {

View File

@ -84,7 +84,7 @@ v-for="dict in pnCurrentList" :key="dict.id" :label="dict.pn_name"
<el-table-column label="库区" align="center" prop="rgName" min-width="120"/> <el-table-column label="库区" align="center" prop="rgName" min-width="120"/>
<el-table-column label="库位" align="center" prop="pnName" min-width="120"/> <el-table-column label="库位" align="center" prop="pnName" min-width="120"/>
<el-table-column label="库存数量" align="center" prop="matRest" min-width="100"/> <el-table-column label="库存数量" align="center" prop="matRest" min-width="100"/>
<el-table-column label="安全库存" align="center" prop="invSafe" min-width="100"/> <el-table-column label="安全库存" align="center" prop="invSafe" min-width="120"/>
<el-table-column label="系统单位" align="center" prop="matUnit" min-width="100"/> <el-table-column label="系统单位" align="center" prop="matUnit" min-width="100"/>
<el-table-column min-width="200px" align="center" fixed="right"> <el-table-column min-width="200px" align="center" fixed="right">
<template #header><span class="hl-table_header">*</span>补充数量</template> <template #header><span class="hl-table_header">*</span>补充数量</template>