feat:库存报表模块

main
黄伟杰 1 week ago
parent 32acd2f31b
commit 4c1d95010d

@ -6,10 +6,30 @@ export interface StockVO {
id: number
// 产品编号
productId: number
name?: string
productName?: string
barCode?: string
categoryName?: string
unitName?: string
// 产品分类类型
categoryType?: number
// 仓库编号
warehouseId: number
warehouseName?: string
areaId?: number
areaName?: string
// 库存数量
count: number
latestInTime?: number | string
lastInTime?: number | string
recentInTime?: number | string
latestStockInTime?: number | string
lastStockInTime?: number | string
latestOutTime?: number | string
lastOutTime?: number | string
recentOutTime?: number | string
latestStockOutTime?: number | string
lastStockOutTime?: number | string
}
// ERP 产品库存 API

@ -345,11 +345,14 @@ export default {
Stock: {
product: 'Product',
warehouse: 'Warehouse',
code: 'Code',
name: 'Name',
category: 'Category',
code: 'Material Code',
name: 'Material Name',
category: 'Material Category',
area: 'Area',
unit: 'Unit',
count: 'Stock Quantity',
count: 'Base Quantity',
latestInTime: 'Latest Inbound',
latestOutTime: 'Latest Outbound',
placeholderProduct: 'Please select product',
placeholderWarehouse: 'Please select warehouse',
exportName: 'Product Stock.xls'

@ -345,11 +345,14 @@ export default {
Stock: {
product: '产品',
warehouse: '仓库',
code: '编码',
name: '名称',
category: '分类',
code: '物料编码',
name: '物料名称',
category: '物料大类',
area: '库区',
unit: '单位',
count: '库存量',
count: '基本数量',
latestInTime: '最近入库',
latestOutTime: '最近出库',
placeholderProduct: '请选择产品',
placeholderWarehouse: '请选择仓库',
exportName: '产品库存.xls'

@ -69,22 +69,13 @@
<!-- 列表 -->
<ContentWrap>
<!-- <el-tabs v-model="activeName" @tab-click="handleTabClick">
<el-tab-pane label="产品" name="2" />
<el-tab-pane label="原料" name="1" />
<el-tab-pane label="备件" name="5" />
<el-tab-pane label="工具" name="3" />
<el-tab-pane label="耗材" name="4" />
<el-tab-pane label="其他" name="0" />
</el-tabs> -->
<el-tabs v-model="activeName" @tab-click="handleTabClick">
<!-- 使用 v-for 动态生成 el-tab-pane -->
<el-tab-pane
v-for="item in parentList"
:key="item.id"
:label="item.name"
:name="item.id.toString()"
/>
<el-tab-pane
v-for="item in categoryTabs"
:key="String(item.value)"
:label="item.label"
:name="String(item.value)"
/>
</el-tabs>
<el-table
v-loading="loading"
@ -95,19 +86,31 @@
@selection-change="handleSelectionChange"
>
<el-table-column width="30" :label="t('action.select')" type="selection" />
<el-table-column :label="t('ErpStock.Stock.code')" align="left" sortable prop="barCode" />
<el-table-column :label="t('ErpStock.Stock.name')" align="left" sortable prop="productName" />
<el-table-column :label="t('ErpStock.Stock.category')" align="center" prop="categoryName" sortable />
<el-table-column :label="t('ErpStock.Stock.unit')" align="center" prop="unitName" sortable />
<el-table-column
:label="t('ErpStock.Stock.count')"
align="right"
sortable
prop="count"
:formatter="erpCountTableColumnFormatter"
/>
<el-table-column :label="t('ErpStock.Stock.warehouse')" align="center" prop="warehouseName" sortable />
<el-table-column :label="t('ErpStock.Stock.code')" align="center" sortable prop="barCode" min-width="160" />
<el-table-column :label="t('ErpStock.Stock.name')" align="center" sortable prop="name" min-width="180">
<template #default="{ row }">
{{ row.name || row.productName || '-' }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Stock.category')" align="center" prop="categoryName" min-width="120" sortable />
<el-table-column :label="t('ErpStock.Stock.warehouse')" align="center" prop="warehouseName" min-width="140" sortable />
<el-table-column :label="t('ErpStock.Stock.area')" align="center" prop="areaName" min-width="120" sortable />
<el-table-column :label="t('ErpStock.Stock.count')" align="center" sortable prop="count" min-width="120">
<template #default="{ row }">
{{ formatStockCount(row.count) }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Stock.unit')" align="center" prop="unitName" min-width="90" sortable />
<el-table-column :label="t('ErpStock.Stock.latestInTime')" align="center" min-width="180">
<template #default="{ row }">
{{ formatStockTime(getLatestInTime(row)) }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Stock.latestOutTime')" align="center" min-width="180">
<template #default="{ row }">
{{ formatStockTime(getLatestOutTime(row)) }}
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
@ -121,34 +124,58 @@
<script setup lang="ts">
import download from '@/utils/download'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { StockApi, StockVO } from '@/api/erp/stock/stock'
import { ProductApi, ProductVO } from '@/api/erp/product/product'
import { WarehouseApi, WarehouseVO } from '@/api/erp/stock/warehouse'
import { erpCountTableColumnFormatter } from '@/utils'
import { ProductCategoryApi, ProductCategoryVO } from '@/api/erp/product/category'
import { handleTree } from '@/utils/tree'
import { useDictStoreWithOut } from '@/store/modules/dict'
import { formatDate } from '@/utils/formatTime'
/** ERP 产品库存列表 */
defineOptions({ name: 'ErpStock' })
const message = useMessage() //
const { t } = useI18n() //
const dictStore = useDictStoreWithOut()
const loading = ref(true) //
const list = ref<StockVO[]>([]) //
const total = ref(0) //
const queryParams = reactive({
const queryParams = reactive<{
pageNo: number
pageSize: number
productId?: number
warehouseId?: number
categoryType?: number
}>({
pageNo: 1,
pageSize: 10,
productId: undefined,
warehouseId: undefined,
categoryId: undefined
categoryType: undefined
})
const queryFormRef = ref() //
const exportLoading = ref(false) //
const productList = ref<ProductVO[]>([]) //
const warehouseList = ref<WarehouseVO[]>([]) //
const categoryList = ref<ProductCategoryVO[]>([]) //
const parentList = ref<ProductCategoryVO[]>([])
const categoryTabs = computed(() => getIntDictOptions(DICT_TYPE.MATERIAL_CLASSIFICATION_TYPE))
const formatStockCount = (value: number | string | undefined) => {
if (value === undefined || value === null || value === '') return '-'
const num = Number(value)
return Number.isFinite(num) ? num.toLocaleString() : String(value)
}
const formatStockTime = (value: any) => {
return value ? formatDate(value, 'YYYY-MM-DD HH:mm:ss') : '-'
}
const getLatestInTime = (row: any) => {
return row.latestInTime ?? row.lastInTime ?? row.recentInTime ?? row.latestStockInTime ?? row.lastStockInTime
}
const getLatestOutTime = (row: any) => {
return row.latestOutTime ?? row.lastOutTime ?? row.recentOutTime ?? row.latestStockOutTime ?? row.lastStockOutTime
}
/** 查询列表 */
const getList = async () => {
@ -221,28 +248,24 @@ const handleSelectionChange = (rows: StockVO[]) => {
/** 初始化 **/
onMounted(async () => {
queryParams.categoryId = 2
await dictStore.setDictMap()
await loadCategoryTabs()
await getList()
//
productList.value = await ProductApi.getProductSimpleList()
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
//
const categoryData = await ProductCategoryApi.getProductCategorySimpleList()
categoryList.value = handleTree(categoryData, 'id', 'parentId')
//
for (let i = 0; i < categoryData.length; i++) {
if (categoryData[i].parentId === 0) {
parentList.value.push(categoryData[i]);
}
}
//
parentList.value.sort((a, b) => a.sort - b.sort);
})
/** tab 切换 */
let activeName = '2'
const activeName = ref('')
const handleTabClick = (tab: TabsPaneContext) => {
queryParams.categoryId = tab.paneName
queryParams.categoryType = tab.paneName ? Number(tab.paneName) : undefined
handleQuery()
}
const loadCategoryTabs = async () => {
const defaultValue = categoryTabs.value[0]?.value
queryParams.categoryType = defaultValue !== undefined && defaultValue !== null ? Number(defaultValue) : undefined
activeName.value = defaultValue !== undefined && defaultValue !== null ? String(defaultValue) : ''
}
</script>

Loading…
Cancel
Save