feat:库存总览-库存明细列表字段调整

main
黄伟杰 4 days ago
parent 44abffdc3e
commit 056862f6c0

@ -62,44 +62,82 @@ v-for="item in summaryCards" :key="item.title" class="stock-overview__card-wrap"
<div class="stock-overview__tables">
<ContentWrap :title="t('ErpStock.Overview.stockDetail')" class="stock-overview__stock">
<el-tabs v-model="activeName" @tab-click="handleTabClick">
<el-tab-pane label="全部" name="" />
<el-tab-pane
v-for="item in categoryTypeOptions"
:key="item.value"
:label="item.label"
:name="String(item.value)"
/>
</el-tabs>
<el-table
v-loading="stockLoading" :data="stockList" :stripe="true" :show-overflow-tooltip="true" row-key="id"
height="520">
<el-table-column :label="t('ErpStock.Stock.code')" align="center" sortable prop="barCode" min-width="130" />
<el-table-column :label="t('ErpStock.Stock.name')" align="center" sortable prop="name" min-width="150">
<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.Overview.materialCategory')" align="center" prop="categoryType"
min-width="100">
<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.stockDisplay')" align="center" prop="stockDisplay" min-width="220">
<template #default="{ row }">
<el-tag :type="getCategoryTagType(row.categoryType)">
{{ getCategoryLabel(row.categoryType) }}
</el-tag>
<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.subCategory')" align="center" prop="categoryName"
min-width="110" />
<el-table-column :label="t('ErpStock.Stock.warehouse')" align="center" prop="warehouseName" min-width="110" />
<el-table-column :label="t('ErpStock.Overview.location')" align="center" prop="areaName" min-width="110" />
<el-table-column :label="t('ErpStock.Stock.stockDisplay')" align="center" prop="stockDisplay" min-width="180">
<el-table-column :label="t('ErpStock.Stock.areaStockDisplay')" align="center" min-width="260">
<template #default="{ row }">
<span v-if="row.stockDisplay" class="stock-overview__display">{{ row.stockDisplay }}</span>
<div
v-if="getAreaStockDisplayList(row.areaStocks).length"
class="area-stock-list"
:style="getStockDisplayStyle(row.categoryType)"
>
<div
v-for="item in getAreaStockDisplayList(row.areaStocks)"
:key="item"
class="area-stock-list__item"
>
{{ item }}
</div>
</div>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Stock.count')" align="center" sortable prop="count" min-width="110">
<el-table-column :label="t('ErpStock.Stock.totalPackageCount')" align="center" sortable prop="totalPackageCount" min-width="120">
<template #default="{ row }">
{{ formatStockCount(row.totalPackageCount) }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Stock.totalBaseCount')" align="center" sortable prop="totalBaseCount" min-width="120">
<template #default="{ row }">
{{ formatStockCount(row.totalBaseCount) }}
</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 }">
{{ formatNumber(row.count) }}
{{ formatStockTime(getLatestInTime(row)) }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Stock.unit')" align="center" prop="unitName" min-width="80" />
<el-table-column :label="t('ErpStock.Overview.latestChangeTime')" align="center" min-width="170">
<el-table-column :label="t('ErpStock.Stock.latestOutTime')" align="center" min-width="180">
<template #default="{ row }">
{{ formatStockTime(getLatestChangeTime(row)) }}
{{ formatStockTime(getLatestOutTime(row)) }}
</template>
</el-table-column>
</el-table>
@ -161,6 +199,7 @@ v-loading="recordLoading" :data="recordList" :stripe="true" :show-overflow-toolt
<script setup lang="ts">
import { DICT_TYPE, getDictObj, getIntDictOptions } from '@/utils/dict'
import { isHexColor } from '@/utils/color'
import { formatDate } from '@/utils/formatTime'
import { StockApi, StockVO } from '@/api/erp/stock/stock'
import { StockRecordApi, StockRecordVO } from '@/api/erp/stock/record'
@ -175,6 +214,7 @@ const dictStore = useDictStoreWithOut()
const queryFormRef = ref()
const warehouseList = ref<WarehouseVO[]>([])
const activeName = ref('')
const categoryTypeOptions = computed(() => getIntDictOptions(DICT_TYPE.MATERIAL_CLASSIFICATION_TYPE))
const queryParams = reactive<{
categoryType?: number
@ -345,6 +385,7 @@ const getList = async () => {
}
const handleQuery = () => {
activeName.value = queryParams.categoryType !== undefined ? String(queryParams.categoryType) : ''
stockQuery.pageNo = 1
recordQuery.pageNo = 1
getList()
@ -352,24 +393,23 @@ const handleQuery = () => {
const resetQuery = () => {
queryFormRef.value?.resetFields()
activeName.value = ''
queryParams.categoryType = undefined
handleQuery()
}
const goRecordPage = () => {
router.push({ path: '/warehouse/record' })
}
const getCategoryLabel = (value?: number | string) => {
return getDictObj(DICT_TYPE.MATERIAL_CLASSIFICATION_TYPE, value)?.label || '-'
const handleTabClick = (tab: any) => {
const value = String(tab.paneName || '')
activeName.value = value
queryParams.categoryType = value ? Number(value) : undefined
handleQuery()
}
const getCategoryTagType = (value?: number | string) => {
const dict = getDictObj(DICT_TYPE.MATERIAL_CLASSIFICATION_TYPE, value)
const colorType = String(dict?.colorType || '')
return ['success', 'info', 'warning', 'danger'].includes(colorType) ? colorType : 'primary'
const goRecordPage = () => {
router.push({ path: '/warehouse/record' })
}
const formatNumber = (value: number | string | undefined) => {
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)
@ -379,20 +419,38 @@ const formatStockTime = (value: any) => {
return value ? formatDate(value, 'YYYY-MM-DD HH:mm:ss') : '-'
}
const getLatestChangeTime = (row: any) => {
return (
row.latestChangeTime ??
row.latestInTime ??
row.lastInTime ??
row.recentInTime ??
row.latestStockInTime ??
row.lastStockInTime ??
row.latestOutTime ??
row.lastOutTime ??
row.recentOutTime ??
row.latestStockOutTime ??
row.lastStockOutTime
)
const formatStockDisplay = (value: string | undefined) => {
if (!value) return []
return value
.split(',')
.map((item) => item.trim())
.filter(Boolean)
}
const getAreaStockDisplayList = (value: StockVO['areaStocks']) => {
if (!Array.isArray(value)) return []
return value
.map((item) => item?.stockDisplay?.trim())
.filter((item): item is string => Boolean(item))
}
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
}
const getLatestOutTime = (row: any) => {
return row.latestOutTime ?? row.lastOutTime ?? row.recentOutTime ?? row.latestStockOutTime ?? row.lastStockOutTime
}
const isStockIn = (direction?: string) => ['入库', 'Inbound'].includes(String(direction || ''))
@ -519,9 +577,30 @@ onMounted(async () => {
font-weight: 600;
}
.stock-overview__display {
.stock-display {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 18px;
color: var(--el-color-primary);
font-weight: 600;
font-weight: 500;
}
.stock-display__item {
white-space: nowrap;
}
.area-stock-list {
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
line-height: 20px;
}
.area-stock-list__item {
max-width: 100%;
word-break: break-all;
}
.stock-overview__material {

Loading…
Cancel
Save