实时库存

实时库存
pull/2/head
siontion 9 months ago
parent 159def12f6
commit cb51402301

@ -1,6 +1,7 @@
package com.chanko.yunxi.mes.module.heli.controller.admin.storagelog;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.storagelogAll.StorageLogAllDO;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.storagelogNow.StorageLogNowDO;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@ -80,6 +81,14 @@ public class StorageLogController {
return success(pageResult);
}
@GetMapping("/now")
@Operation(summary = "获得入/出库实时分页")
@PreAuthorize("@ss.hasPermission('heli:storage-log:query')")
public CommonResult<PageResult<StorageLogNowDO>> getStorageNowPage(@Valid StorageLogPageReqVO pageReqVO) {
PageResult<StorageLogNowDO> pageResult = storageLogService.getStorageNowPage(pageReqVO);
return success(pageResult);
}
@GetMapping("/export-excel")
@Operation(summary = "导出入/出库日志 Excel")
@PreAuthorize("@ss.hasPermission('heli:storage-log:export')")

@ -37,6 +37,15 @@ public class StorageLogPageReqVO extends PageParam {
@Schema(description = "出入库类型")
private Integer stockType;
@Schema(description = "仓库")
private Long whId;
@Schema(description = "库区")
private Long rgId;
@Schema(description = "库位")
private Long pnId;
}

@ -0,0 +1,59 @@
package com.chanko.yunxi.mes.module.heli.dal.dataobject.storagelogNow;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.chanko.yunxi.mes.framework.mybatis.core.dataobject.BaseDO;
import lombok.*;
import java.math.BigDecimal;
/**
* / DO
*
* @author
*/
@TableName("v_storage_material_now")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class StorageLogNowDO extends BaseDO {
/**
* id
*/
@TableId
private Long id;
/**
*
*/
private BigDecimal storageOkQty;
/**
*
*/
private String lotNo;
private String matName;
private String matCode;
private String matType;
private Long whId;
private String whName;
private Long rgId;
private String rgName;
private Long pnId;
private String pnName;
private String shortName;
private String matSpec;
private String matBrand;
private String matUnit;
}

@ -37,7 +37,7 @@ public interface PnMapper extends BaseMapperX<PnDO> {
}
default List<Map<String, Object>> selectSimpleList() {
return selectMaps(new QueryWrapper<PnDO>().select("id", "pn_name").lambda());
return selectMaps(new QueryWrapper<PnDO>().select("id", "pn_name","rg_id").lambda());
}
}

@ -35,7 +35,7 @@ public interface RgMapper extends BaseMapperX<RgDO> {
default List<Map<String, Object>> selectSimpleList() {
return selectMaps(new QueryWrapper<RgDO>().select("id", "rg_name").lambda());
return selectMaps(new QueryWrapper<RgDO>().select("id", "rg_name","wh_id").lambda());
}

@ -0,0 +1,36 @@
package com.chanko.yunxi.mes.module.heli.dal.mysql.storagelog;
import com.alibaba.druid.util.StringUtils;
import com.chanko.yunxi.mes.framework.common.pojo.PageResult;
import com.chanko.yunxi.mes.framework.mybatis.core.mapper.BaseMapperX;
import com.chanko.yunxi.mes.module.heli.controller.admin.storagelog.vo.StorageLogPageReqVO;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.storagelogNow.StorageLogNowDO;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.ibatis.annotations.Mapper;
/**
* / Mapper
*
* @author
*/
@Mapper
public interface StorageLogNowMapper extends BaseMapperX<StorageLogNowDO> {
default PageResult<StorageLogNowDO> selectPage(StorageLogPageReqVO reqVO) {
MPJLambdaWrapper<StorageLogNowDO> query = new MPJLambdaWrapper<>();
query.selectAll(StorageLogNowDO.class)
.orderByDesc(StorageLogNowDO::getId);
query.like(!StringUtils.isEmpty(reqVO.getMatType()),StorageLogNowDO::getMatType, reqVO.getMatType())
.eq(reqVO.getWhId()!= null,StorageLogNowDO::getWhId, reqVO.getWhId())
.eq(reqVO.getRgId()!= null,StorageLogNowDO::getRgId, reqVO.getRgId())
.eq(reqVO.getPnId()!= null,StorageLogNowDO::getPnId, reqVO.getPnId())
.like(!StringUtils.isEmpty(reqVO.getMatName()), StorageLogNowDO::getMatName, reqVO.getMatName())
.like(!StringUtils.isEmpty(reqVO.getMatCode()), StorageLogNowDO::getMatCode, reqVO.getMatCode())
.like(!StringUtils.isEmpty(reqVO.getLotNo()),StorageLogNowDO::getLotNo, reqVO.getLotNo());
return selectPage(reqVO,query);
}
PageResult<StorageLogNowDO> selectAllPage(StorageLogPageReqVO reqVO);
}

@ -7,6 +7,7 @@ import com.chanko.yunxi.mes.module.heli.dal.dataobject.storagelog.StorageLogDO;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.storagelogAll.StorageLogAllDO;
import com.chanko.yunxi.mes.framework.common.pojo.PageResult;
import com.chanko.yunxi.mes.framework.common.pojo.PageParam;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.storagelogNow.StorageLogNowDO;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.storagemat.StorageMatDO;
/**
@ -54,6 +55,8 @@ public interface StorageLogService {
*/
PageResult<StorageLogAllDO> getStorageLogPage(StorageLogPageReqVO pageReqVO);
PageResult<StorageLogNowDO> getStorageNowPage(StorageLogPageReqVO pageReqVO);
void createStorageLogBatch(List<StorageLogDO> storageLogDOs);
}

@ -1,7 +1,9 @@
package com.chanko.yunxi.mes.module.heli.service.storagelog;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.storagelogAll.StorageLogAllDO;
import com.chanko.yunxi.mes.module.heli.dal.dataobject.storagelogNow.StorageLogNowDO;
import com.chanko.yunxi.mes.module.heli.dal.mysql.storagelog.StorageLogAllMapper;
import com.chanko.yunxi.mes.module.heli.dal.mysql.storagelog.StorageLogNowMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@ -34,6 +36,9 @@ public class StorageLogServiceImpl implements StorageLogService {
@Resource
private StorageLogAllMapper storageLogAllMapper;
@Resource
private StorageLogNowMapper storageLogNowMapper;
@Override
public Long createStorageLog(StorageLogSaveReqVO createReqVO) {
// 插入
@ -76,6 +81,11 @@ public class StorageLogServiceImpl implements StorageLogService {
return storageLogAllMapper.selectPage(pageReqVO);
}
@Override
public PageResult<StorageLogNowDO> getStorageNowPage(StorageLogPageReqVO pageReqVO) {
return storageLogNowMapper.selectPage(pageReqVO);
}
@Override
public void createStorageLogBatch(List<StorageLogDO> storageLogDOs) {
for (StorageLogDO storageLogDo : storageLogDOs){

@ -12,6 +12,11 @@ export interface StorageLogVO {
description: string
}
// 查询入/出库实时分页
export const getStorageNowPage = async (params) => {
return await request.get({ url: `/heli/storage-log/now`, params })
}
// 查询入/出库日志分页
export const getStorageLogPage = async (params) => {
return await request.get({ url: `/heli/storage-log/page`, params })

@ -1,128 +1,170 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-form-item label="入/出库Id" prop="stockId">
<el-input v-model="formData.stockId" placeholder="请输入入/出库Id" />
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
<el-form-item label="物料编码" prop="matCode">
<el-input v-model="queryParams.matCode" placeholder="物料编码" clearable @keyup.enter="handleQuery"
class="!w-240px" />
</el-form-item>
<el-form-item label="物料 Id,对应 base_material表中的 Id 列" prop="matId">
<el-input v-model="formData.matId" placeholder="请输入物料 Id,对应 base_material表中的 Id 列" />
<el-form-item label="物料名称" prop="matName">
<el-input v-model="queryParams.matName" placeholder="物料名称" clearable @keyup.enter="handleQuery"
class="!w-240px" />
</el-form-item>
<el-form-item label="仓库 Id对应 wms_wh 表中的Id" prop="whId">
<el-input v-model="formData.whId" placeholder="请输入仓库 Id对应 wms_wh 表中的Id" />
<el-form-item label="物料类型" prop="matType">
<el-select v-model="queryParams.matType" placeholder="下拉选择" clearable class="!w-240px">
<el-option v-for="dict in getIntDictOptions(DICT_TYPE.HELI_MATERIAL_TYPE)" :key="dict.label" :label="dict.label"
:value="dict.label" />
</el-select>
</el-form-item>
<el-form-item label="库区 Id对应 wms_rg 表中的Id" prop="rgId">
<el-input v-model="formData.rgId" placeholder="请输入库区 Id对应 wms_rg 表中的Id" />
<el-form-item label="批次号" prop="lotNo">
<el-input v-model="queryParams.lotNo" placeholder="批次号" clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<el-form-item label="库区 Id对应 wms_rg 表中的Id" prop="pnId">
<el-input v-model="formData.pnId" placeholder="请输入库区 Id对应 wms_rg 表中的Id" />
<el-form-item label="仓库" prop="whId">
<el-select v-model="queryParams.whId" placeholder="下拉选择" clearable class="!w-240px" @change="handleWh">
<el-option v-for="dict in whList" :key="dict.id" :label="dict.wh_name"
:value="dict.id" />
</el-select>
</el-form-item>
<el-form-item label="库存良品数量" prop="storageOkQty">
<el-input v-model="formData.storageOkQty" placeholder="请输入库存良品数量" />
<el-form-item label="库区" prop="rgId">
<el-select v-model="queryParams.rgId" placeholder="下拉选择" clearable class="!w-240px" @change="handleRg">
<el-option v-for="dict in rgCurrentList" :key="dict.id" :label="dict.rg_name"
:value="dict.id" />
</el-select>
</el-form-item>
<el-form-item label="批次号" prop="lotNo">
<el-input v-model="formData.lotNo" placeholder="请输入批次号" />
<el-form-item label="库位" prop="pnId">
<el-select v-model="queryParams.pnId" placeholder="下拉选择" clearable class="!w-240px">
<el-option v-for="dict in pnCurrentList" :key="dict.id" :label="dict.pn_name"
:value="dict.id" />
</el-select>
</el-form-item>
<el-form-item label="备注" prop="description">
<el-input v-model="formData.description" type="textarea" placeholder="请输入备注" />
<el-form-item>
<el-button @click="handleQuery">
<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>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="物料编码" align="center" prop="matCode" />
<el-table-column label="物料名称" align="center" prop="matName" />
<el-table-column label="物料类型" align="center" prop="matType" />
<el-table-column label="物料简称" align="center" prop="shortName" />
<el-table-column label="规格/型号" align="center" prop="matSpec" />
<el-table-column label="品牌" align="center" prop="matBrand" />
<el-table-column label="仓库" align="center" prop="whName" />
<el-table-column label="库区" align="center" prop="rgName" />
<el-table-column label="库位" align="center" prop="pnName" />
<el-table-column label="批次号" align="center" prop="lotNo" />
<el-table-column label="变动数量" align="center" prop="storageOkQty" />
<el-table-column label="库存单位" align="center" prop="matUnit" />
</el-table>
<!-- 分页 -->
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
@pagination="getList" />
</ContentWrap>
</template>
<script setup lang="ts">
import download from '@/utils/download'
import * as StorageLogApi from '@/api/heli/storagelog'
const { t } = useI18n() //
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' })
const whList = ref([])
const rgList = ref([])
const pnList = ref([])
const rgCurrentList = ref([])
const pnCurrentList = ref([])
const message = useMessage() //
const { t } = useI18n() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
id: undefined,
stockId: undefined,
matId: undefined,
const loading = ref(true) //
const list = ref([]) //
const total = ref(0) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
matCode: undefined,
matName: undefined,
matType: undefined,
lotNo: undefined,
whId: undefined,
rgId:undefined,
pnId: undefined,
storageOkQty: undefined,
lotNo: undefined,
description: undefined,
headerNo: undefined,
})
const formRules = reactive({
stockId: [{ required: true, message: '入/出库Id不能为空', trigger: 'blur' }],
matId: [{ required: true, message: '物料 Id,对应 base_material表中的 Id 列不能为空', trigger: 'blur' }],
whId: [{ required: true, message: '仓库 Id对应 wms_wh 表中的Id不能为空', trigger: 'blur' }],
rgId: [{ required: true, message: '库区 Id对应 wms_rg 表中的Id不能为空', trigger: 'blur' }],
pnId: [{ required: true, message: '库区 Id对应 wms_rg 表中的Id不能为空', trigger: 'blur' }],
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
if (id) {
formLoading.value = true
const queryFormRef = ref() //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
formData.value = await StorageLogApi.getStorageLog(id)
const data = await StorageLogApi.getStorageNowPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
formLoading.value = false
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
await formRef.value.validate()
//
formLoading.value = true
try {
const data = formData.value as unknown as StorageLogApi.StorageLogVO
if (formType.value === 'create') {
await StorageLogApi.createStorageLog(data)
message.success(t('common.createSuccess'))
} else {
await StorageLogApi.updateStorageLog(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
emit('success')
} finally {
formLoading.value = false
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
stockId: undefined,
matId: undefined,
whId: undefined,
rgId: undefined,
pnId: undefined,
storageOkQty: undefined,
lotNo: undefined,
description: undefined,
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})
}
formRef.value?.resetFields()
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 () => {
await init_page_wh()
await init_page_rg()
await init_page_pn()
await getList()
})
</script>

@ -70,26 +70,23 @@
@pagination="getList" />
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<StorageLogForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts">
import download from '@/utils/download'
import * as StorageLogApi from '@/api/heli/storagelog'
import StorageLogForm from './StorageLogForm.vue'
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'
// import * as WarehouseApi from '@/api/heli/warehouse'
// import * as RgApi from '@/api/heli/rg'
// import * as PnApi from '@/api/heli/pn'
defineOptions({ name: 'StorageLog' })
const whList = ref([])
const rgList = ref([])
const pnList = ref([])
// const whList = ref([])
// const rgList = ref([])
// const pnList = ref([])
const message = useMessage() //
const { t } = useI18n() //
@ -134,24 +131,24 @@ const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
//
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()
})
// //
// 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 () => {
await init_page_wh()
await init_page_rg()
await init_page_pn()
// await init_page_wh()
// await init_page_rg()
// await init_page_pn()
await getList()
})
</script>
Loading…
Cancel
Save