feat:库存报表页面字段修改

main
黄伟杰 7 days ago
parent 03ca612169
commit c742219141

@ -18,6 +18,10 @@ export interface StockVO {
warehouseName?: string
areaId?: number
areaName?: string
// 包装/换算规则
packagingRule?: string
// 库存展示
stockDisplay?: string
// 库存数量
count: number
latestInTime?: number | string

@ -348,12 +348,16 @@
code: 'Material Code',
name: 'Material Name',
category: 'Material Category',
subCategory: 'Material Subcategory',
area: 'Area',
packagingRule: 'Packaging / Conversion Rule',
stockDisplay: 'Stock Display',
unit: 'Unit',
count: 'Base Quantity',
latestInTime: 'Latest Inbound',
latestOutTime: 'Latest Outbound',
placeholderProduct: 'Please select product',
placeholderCategory: 'Please select material category',
placeholderWarehouse: 'Please select warehouse',
exportName: 'Product Stock.xls'
},

@ -348,12 +348,16 @@
code: '物料编码',
name: '物料名称',
category: '物料大类',
subCategory: '物料小类',
area: '库区',
packagingRule: '包装/换算规则',
stockDisplay: '库存展示',
unit: '单位',
count: '基本数量',
latestInTime: '最近入库',
latestOutTime: '最近出库',
placeholderProduct: '请选择产品',
placeholderCategory: '请选择物料大类',
placeholderWarehouse: '请选择仓库',
exportName: '产品库存.xls'
},

@ -27,6 +27,22 @@
</el-select>
</el-form-item>
<el-form-item :label="t('ErpStock.Stock.category')" prop="categoryType">
<el-select
v-model="queryParams.categoryType"
clearable
:placeholder="t('ErpStock.Stock.placeholderCategory')"
class="!w-240px"
>
<el-option
v-for="item in categoryTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('ErpStock.Stock.warehouse')" prop="warehouseId">
<el-select
v-model="queryParams.warehouseId"
@ -69,14 +85,6 @@
<!-- 列表 -->
<ContentWrap>
<el-tabs v-model="activeName" @tab-click="handleTabClick">
<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"
:data="list"
@ -92,9 +100,33 @@
{{ 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.category')" align="center" prop="categoryType" min-width="120" sortable>
<template #default="{ row }">
<dict-tag :type="DICT_TYPE.MATERIAL_CLASSIFICATION_TYPE" :value="row.categoryType" />
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Stock.subCategory')" align="center" prop="categoryName" min-width="120" sortable />
<el-table-column :label="t('ErpStock.Stock.packagingRule')" align="center" prop="packagingRule" min-width="180" />
<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.stockDisplay')" align="center" prop="stockDisplay" min-width="220">
<template #default="{ row }">
<span
v-if="formatStockDisplay(row.stockDisplay).length"
class="stock-display"
:style="getStockDisplayStyle(row.categoryType)"
>
<span
v-for="item in formatStockDisplay(row.stockDisplay)"
:key="item"
class="stock-display__item"
>
{{ item }}
</span>
</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Stock.count')" align="center" sortable prop="count" min-width="120">
<template #default="{ row }">
{{ formatStockCount(row.count) }}
@ -124,12 +156,13 @@
<script setup lang="ts">
import download from '@/utils/download'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { DICT_TYPE, getDictObj, 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 { useDictStoreWithOut } from '@/store/modules/dict'
import { formatDate } from '@/utils/formatTime'
import { isHexColor } from '@/utils/color'
/** ERP 产品库存列表 */
defineOptions({ name: 'ErpStock' })
@ -157,7 +190,7 @@ const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) //
const productList = ref<ProductVO[]>([]) //
const warehouseList = ref<WarehouseVO[]>([]) //
const categoryTabs = computed(() => getIntDictOptions(DICT_TYPE.MATERIAL_CLASSIFICATION_TYPE))
const categoryTypeOptions = computed(() => getIntDictOptions(DICT_TYPE.MATERIAL_CLASSIFICATION_TYPE))
const formatStockCount = (value: number | string | undefined) => {
if (value === undefined || value === null || value === '') return '-'
@ -169,6 +202,25 @@ const formatStockTime = (value: any) => {
return value ? formatDate(value, 'YYYY-MM-DD HH:mm:ss') : '-'
}
const formatStockDisplay = (value: string | undefined) => {
if (!value) return []
return value
.split(',')
.map((item) => item.trim())
.filter(Boolean)
}
const getStockDisplayStyle = (categoryType: number | string | undefined) => {
const dict = getDictObj(DICT_TYPE.MATERIAL_CLASSIFICATION_TYPE, categoryType)
if (dict?.cssClass && isHexColor(dict.cssClass)) {
return { color: dict.cssClass }
}
const colorType = dict?.colorType && !['primary', 'default'].includes(String(dict.colorType))
? dict.colorType
: 'primary'
return { color: `var(--el-color-${colorType})` }
}
const getLatestInTime = (row: any) => {
return row.latestInTime ?? row.lastInTime ?? row.recentInTime ?? row.latestStockInTime ?? row.lastStockInTime
}
@ -177,11 +229,17 @@ const getLatestOutTime = (row: any) => {
return row.latestOutTime ?? row.lastOutTime ?? row.recentOutTime ?? row.latestStockOutTime ?? row.lastStockOutTime
}
const buildQueryParams = () => {
return Object.fromEntries(
Object.entries(queryParams).filter(([, value]) => value !== undefined && value !== null && value !== '')
)
}
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await StockApi.getStockPage(queryParams)
const data = await StockApi.getStockPage(buildQueryParams())
list.value = data.list
total.value = data.total
} finally {
@ -229,7 +287,7 @@ const handleExport = async () => {
exportLoading.value = true
const ids = selectionList.value.map((item) => item.id).filter((v) => v != null)
const params = {
...queryParams,
...buildQueryParams(),
ids: ids.length ? ids.join(',') : undefined
}
const data = await StockApi.exportStock(params)
@ -249,23 +307,24 @@ const handleSelectionChange = (rows: StockVO[]) => {
/** 初始化 **/
onMounted(async () => {
await dictStore.setDictMap()
await loadCategoryTabs()
await getList()
//
productList.value = await ProductApi.getProductSimpleList()
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
})
</script>
/** tab 切换 */
const activeName = ref('')
const handleTabClick = (tab: TabsPaneContext) => {
queryParams.categoryType = tab.paneName ? Number(tab.paneName) : undefined
handleQuery()
<style scoped>
.stock-display {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 18px;
color: var(--el-color-primary);
font-weight: 500;
}
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) : ''
.stock-display__item {
white-space: nowrap;
}
</script>
</style>

Loading…
Cancel
Save