|
|
|
|
@ -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>
|
|
|
|
|
|