feat: add bit sample warehouse web pages
parent
62d26cdc12
commit
86058e36d1
@ -0,0 +1,62 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
export interface BitWmsInboundReqVO {
|
||||
productId: number
|
||||
warehouseId: number
|
||||
areaId?: number
|
||||
count: number
|
||||
supplierId?: number
|
||||
remark?: string
|
||||
}
|
||||
|
||||
export interface BitWmsOutboundReqVO {
|
||||
productId: number
|
||||
warehouseId: number
|
||||
areaId?: number
|
||||
count: number
|
||||
outReason: string
|
||||
remark?: string
|
||||
}
|
||||
|
||||
export interface BitWmsMoveReqVO {
|
||||
productId: number
|
||||
fromWarehouseId: number
|
||||
fromAreaId?: number
|
||||
toWarehouseId: number
|
||||
toAreaId?: number
|
||||
count: number
|
||||
remark?: string
|
||||
}
|
||||
|
||||
export interface BitWmsLabelRespVO {
|
||||
title?: string
|
||||
printData: Record<string, any>
|
||||
templateJson?: Record<string, any>
|
||||
}
|
||||
|
||||
export const BitWmsApi = {
|
||||
getSamplePage: async (params: any) => {
|
||||
return await request.get({ url: '/erp/product/sample-page', params })
|
||||
},
|
||||
getSampleSimpleList: async (params?: any) => {
|
||||
return await request.get({ url: '/erp/product/sample-simple-list', params })
|
||||
},
|
||||
inbound: async (data: BitWmsInboundReqVO) => {
|
||||
return await request.post({ url: '/erp/bit-wms/inbound', data })
|
||||
},
|
||||
outbound: async (data: BitWmsOutboundReqVO) => {
|
||||
return await request.post({ url: '/erp/bit-wms/outbound', data })
|
||||
},
|
||||
move: async (data: BitWmsMoveReqVO) => {
|
||||
return await request.post({ url: '/erp/bit-wms/move', data })
|
||||
},
|
||||
scan: async (code: string) => {
|
||||
return await request.get({ url: '/erp/bit-wms/scan', params: { code } })
|
||||
},
|
||||
getSampleLabel: async (productId: number) => {
|
||||
return await request.get({ url: '/erp/bit-wms/sample-label', params: { productId } })
|
||||
},
|
||||
getLocationLabel: async (locationId: number) => {
|
||||
return await request.get({ url: '/erp/bit-wms/location-label', params: { locationId } })
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<el-button size="small" type="primary" :loading="loading" @click="openPrint">
|
||||
<Icon icon="ep:printer" class="mr-4px" />
|
||||
{{ buttonText }}
|
||||
</el-button>
|
||||
<HiprintPreviewDialog ref="printDialogRef" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import HiprintPreviewDialog from '@/components/HiprintPreviewDialog/index.vue'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
title: string
|
||||
buttonText?: string
|
||||
printData?: Record<string, any>
|
||||
templateJson?: Record<string, any>
|
||||
loadLabel?: () => Promise<{ printData: Record<string, any>; templateJson?: Record<string, any> }>
|
||||
}>(),
|
||||
{
|
||||
buttonText: '打印'
|
||||
}
|
||||
)
|
||||
|
||||
const printDialogRef = ref()
|
||||
const loading = ref(false)
|
||||
|
||||
const openPrint = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const label = props.loadLabel ? await props.loadLabel() : undefined
|
||||
const printData = label?.printData || props.printData || {}
|
||||
const templateJson = label?.templateJson || props.templateJson
|
||||
printDialogRef.value?.open({
|
||||
title: props.title,
|
||||
printData,
|
||||
templateJson,
|
||||
withDefaultQrcodeLayout: !templateJson,
|
||||
paperSize: { width: 80, height: 60 }
|
||||
})
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="110px" class="bit-wms-form">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="样品" prop="productId">
|
||||
<el-select v-model="formData.productId" placeholder="请选择样品" filterable clearable class="!w-full">
|
||||
<el-option v-for="item in sampleList" :key="item.id" :label="formatSampleLabel(item)" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="供应商" prop="supplierId">
|
||||
<el-select v-model="formData.supplierId" placeholder="请选择供应商" filterable clearable class="!w-full">
|
||||
<el-option v-for="item in supplierList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="仓库" prop="warehouseId">
|
||||
<el-select v-model="formData.warehouseId" placeholder="请选择仓库" filterable class="!w-full" @change="handleWarehouseChange">
|
||||
<el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="库区" prop="areaId">
|
||||
<el-select v-model="formData.areaId" placeholder="请选择库区" filterable clearable class="!w-full">
|
||||
<el-option v-for="item in filteredAreaList" :key="item.id" :label="item.areaName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="数量" prop="count">
|
||||
<el-input-number v-model="formData.count" :min="1" :precision="0" class="!w-full" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="submitLoading" v-hasPermi="['erp:bit-wms-in:create']" @click="submitForm">
|
||||
<Icon icon="ep:check" class="mr-5px" />确认入库
|
||||
</el-button>
|
||||
<el-button @click="resetForm"><Icon icon="ep:refresh" class="mr-5px" />重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { BitWmsApi } from '@/api/erp/bitwms'
|
||||
import { WarehouseApi } from '@/api/erp/stock/warehouse'
|
||||
import { WarehouseAreaApi } from '@/api/erp/stock/warehousearea'
|
||||
import { SupplierApi } from '@/api/erp/purchase/supplier'
|
||||
|
||||
defineOptions({ name: 'ErpBitWmsIn' })
|
||||
|
||||
const message = useMessage()
|
||||
const formRef = ref()
|
||||
const submitLoading = ref(false)
|
||||
const sampleList = ref<any[]>([])
|
||||
const warehouseList = ref<any[]>([])
|
||||
const areaList = ref<any[]>([])
|
||||
const supplierList = ref<any[]>([])
|
||||
const formData = reactive<any>({
|
||||
productId: undefined,
|
||||
warehouseId: undefined,
|
||||
areaId: undefined,
|
||||
count: 1,
|
||||
supplierId: undefined,
|
||||
remark: undefined
|
||||
})
|
||||
const formRules = reactive({
|
||||
productId: [{ required: true, message: '请选择样品', trigger: 'change' }],
|
||||
warehouseId: [{ required: true, message: '请选择仓库', trigger: 'change' }],
|
||||
count: [{ required: true, message: '请输入数量', trigger: 'blur' }]
|
||||
})
|
||||
const filteredAreaList = computed(() => {
|
||||
if (!formData.warehouseId) return areaList.value
|
||||
return areaList.value.filter((item) => item.warehouseId === formData.warehouseId)
|
||||
})
|
||||
|
||||
const formatSampleLabel = (item: any) => `${item.barCode || item.code || '-'} / ${item.name || '-'}`
|
||||
const handleWarehouseChange = () => {
|
||||
formData.areaId = undefined
|
||||
}
|
||||
const resetForm = () => {
|
||||
formRef.value?.resetFields()
|
||||
formData.count = 1
|
||||
}
|
||||
const submitForm = async () => {
|
||||
await formRef.value.validate()
|
||||
submitLoading.value = true
|
||||
try {
|
||||
await BitWmsApi.inbound(formData)
|
||||
message.success('入库成功')
|
||||
resetForm()
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const [samples, warehouses, areas, suppliers] = await Promise.all([
|
||||
BitWmsApi.getSampleSimpleList(),
|
||||
WarehouseApi.getWarehouseSimpleList(),
|
||||
WarehouseAreaApi.getWarehouseAreaPage({ pageNo: 1, pageSize: 100 }),
|
||||
SupplierApi.getSupplierSimpleList()
|
||||
])
|
||||
sampleList.value = samples || []
|
||||
warehouseList.value = warehouses || []
|
||||
areaList.value = areas.list || []
|
||||
supplierList.value = suppliers || []
|
||||
})
|
||||
</script>
|
||||
@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<div>
|
||||
<template v-if="!formVisible">
|
||||
<ContentWrap>
|
||||
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="auto">
|
||||
<el-form-item label="仓库" prop="warehouseId">
|
||||
<el-select v-model="queryParams.warehouseId" placeholder="请选择仓库" clearable filterable class="!w-220px" @change="handleWarehouseChange">
|
||||
<el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="库区" prop="areaId">
|
||||
<el-select v-model="queryParams.areaId" placeholder="请选择库区" clearable filterable class="!w-220px">
|
||||
<el-option v-for="item in filteredAreaList" :key="item.id" :label="item.areaName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="库位码" prop="code">
|
||||
<el-input v-model="queryParams.code" placeholder="请输入库位码" clearable class="!w-220px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="库位名称" prop="name">
|
||||
<el-input v-model="queryParams.name" placeholder="请输入库位名称" clearable class="!w-220px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<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-button type="primary" plain v-hasPermi="['erp:bit-wms-location:create']" @click="openForm('create')">
|
||||
<Icon icon="ep:plus" class="mr-5px" />新增库位
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" row-key="id">
|
||||
<el-table-column label="仓库" align="center" min-width="140">
|
||||
<template #default="{ row }">{{ getWarehouseName(row.warehouseId) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库区" align="center" min-width="120">
|
||||
<template #default="{ row }">{{ getAreaName(row.areaId) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库位码" align="center" prop="code" min-width="140" />
|
||||
<el-table-column label="库位名称" align="center" prop="name" min-width="140" />
|
||||
<el-table-column label="面积" align="center" prop="areaSize" width="100" />
|
||||
<el-table-column label="最大承重" align="center" prop="maxLoadWeight" width="110" />
|
||||
<el-table-column label="状态" align="center" prop="status" width="100">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="210" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" v-hasPermi="['erp:bit-wms-location:update']" @click="openForm('update', row.id)">编辑</el-button>
|
||||
<BitWmsPrintButton
|
||||
v-hasPermi="['erp:bit-wms-location:print']"
|
||||
title="库位标签"
|
||||
:load-label="() => loadLocationLabel(row.id)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</ContentWrap>
|
||||
</template>
|
||||
|
||||
<WarehouseLocationForm v-else ref="formRef" @success="getList" @closed="formVisible = false" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DICT_TYPE } from '@/utils/dict'
|
||||
import { WarehouseLocationApi } from '@/api/erp/stock/warehouselocation'
|
||||
import { WarehouseApi } from '@/api/erp/stock/warehouse'
|
||||
import { WarehouseAreaApi } from '@/api/erp/stock/warehousearea'
|
||||
import { BitWmsApi } from '@/api/erp/bitwms'
|
||||
import WarehouseLocationForm from '@/views/erp/warehouselocation/WarehouseLocationForm.vue'
|
||||
import BitWmsPrintButton from '../components/BitWmsPrintButton.vue'
|
||||
|
||||
defineOptions({ name: 'ErpBitWmsLocation' })
|
||||
|
||||
const loading = ref(true)
|
||||
const list = ref<any[]>([])
|
||||
const total = ref(0)
|
||||
const queryFormRef = ref()
|
||||
const formRef = ref()
|
||||
const formVisible = ref(false)
|
||||
const warehouseList = ref<any[]>([])
|
||||
const areaList = ref<any[]>([])
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
warehouseId: undefined,
|
||||
areaId: undefined,
|
||||
code: undefined,
|
||||
name: undefined
|
||||
})
|
||||
|
||||
const filteredAreaList = computed(() => {
|
||||
if (!queryParams.warehouseId) return areaList.value
|
||||
return areaList.value.filter((item) => item.warehouseId === queryParams.warehouseId)
|
||||
})
|
||||
|
||||
const buildQueryParams = () =>
|
||||
Object.fromEntries(Object.entries(queryParams).filter(([, value]) => value !== undefined && value !== null && value !== ''))
|
||||
|
||||
const getWarehouseName = (warehouseId: number) => warehouseList.value.find((item) => item.id === warehouseId)?.name || '-'
|
||||
const getAreaName = (areaId: number) => areaList.value.find((item) => item.id === areaId)?.areaName || '-'
|
||||
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await WarehouseLocationApi.getWarehouseLocationPage(buildQueryParams())
|
||||
list.value = data.list || []
|
||||
total.value = data.total || 0
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const loadBaseData = async () => {
|
||||
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
|
||||
const areaData = await WarehouseAreaApi.getWarehouseAreaPage({ pageNo: 1, pageSize: 100 })
|
||||
areaList.value = areaData.list || []
|
||||
}
|
||||
|
||||
const handleWarehouseChange = () => {
|
||||
queryParams.areaId = undefined
|
||||
}
|
||||
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
const openForm = async (type: string, id?: number) => {
|
||||
formVisible.value = true
|
||||
await nextTick()
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
const loadLocationLabel = async (id: number) => await BitWmsApi.getLocationLabel(id)
|
||||
|
||||
onMounted(async () => {
|
||||
await loadBaseData()
|
||||
await getList()
|
||||
})
|
||||
</script>
|
||||
@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="120px" class="bit-wms-form">
|
||||
<el-form-item label="样品" prop="productId">
|
||||
<el-select v-model="formData.productId" placeholder="请选择样品" filterable clearable class="!w-full">
|
||||
<el-option v-for="item in sampleList" :key="item.id" :label="formatSampleLabel(item)" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="来源仓库" prop="fromWarehouseId">
|
||||
<el-select v-model="formData.fromWarehouseId" placeholder="请选择来源仓库" filterable class="!w-full" @change="handleFromWarehouseChange">
|
||||
<el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="来源库区" prop="fromAreaId">
|
||||
<el-select v-model="formData.fromAreaId" placeholder="请选择来源库区" filterable clearable class="!w-full">
|
||||
<el-option v-for="item in fromAreaList" :key="item.id" :label="item.areaName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="目标仓库" prop="toWarehouseId">
|
||||
<el-select v-model="formData.toWarehouseId" placeholder="请选择目标仓库" filterable class="!w-full" @change="handleToWarehouseChange">
|
||||
<el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="目标库区" prop="toAreaId">
|
||||
<el-select v-model="formData.toAreaId" placeholder="请选择目标库区" filterable clearable class="!w-full">
|
||||
<el-option v-for="item in toAreaList" :key="item.id" :label="item.areaName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="数量" prop="count">
|
||||
<el-input-number v-model="formData.count" :min="1" :precision="0" class="!w-240px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="submitLoading" v-hasPermi="['erp:bit-wms-move:create']" @click="submitForm">
|
||||
<Icon icon="ep:check" class="mr-5px" />确认移库
|
||||
</el-button>
|
||||
<el-button @click="resetForm"><Icon icon="ep:refresh" class="mr-5px" />重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { BitWmsApi } from '@/api/erp/bitwms'
|
||||
import { WarehouseApi } from '@/api/erp/stock/warehouse'
|
||||
import { WarehouseAreaApi } from '@/api/erp/stock/warehousearea'
|
||||
|
||||
defineOptions({ name: 'ErpBitWmsMove' })
|
||||
|
||||
const message = useMessage()
|
||||
const formRef = ref()
|
||||
const submitLoading = ref(false)
|
||||
const sampleList = ref<any[]>([])
|
||||
const warehouseList = ref<any[]>([])
|
||||
const areaList = ref<any[]>([])
|
||||
const formData = reactive<any>({
|
||||
productId: undefined,
|
||||
fromWarehouseId: undefined,
|
||||
fromAreaId: undefined,
|
||||
toWarehouseId: undefined,
|
||||
toAreaId: undefined,
|
||||
count: 1,
|
||||
remark: undefined
|
||||
})
|
||||
const formRules = reactive({
|
||||
productId: [{ required: true, message: '请选择样品', trigger: 'change' }],
|
||||
fromWarehouseId: [{ required: true, message: '请选择来源仓库', trigger: 'change' }],
|
||||
toWarehouseId: [{ required: true, message: '请选择目标仓库', trigger: 'change' }],
|
||||
count: [{ required: true, message: '请输入数量', trigger: 'blur' }]
|
||||
})
|
||||
const fromAreaList = computed(() => {
|
||||
if (!formData.fromWarehouseId) return areaList.value
|
||||
return areaList.value.filter((item) => item.warehouseId === formData.fromWarehouseId)
|
||||
})
|
||||
const toAreaList = computed(() => {
|
||||
if (!formData.toWarehouseId) return areaList.value
|
||||
return areaList.value.filter((item) => item.warehouseId === formData.toWarehouseId)
|
||||
})
|
||||
|
||||
const formatSampleLabel = (item: any) => `${item.barCode || item.code || '-'} / ${item.name || '-'}`
|
||||
const handleFromWarehouseChange = () => {
|
||||
formData.fromAreaId = undefined
|
||||
}
|
||||
const handleToWarehouseChange = () => {
|
||||
formData.toAreaId = undefined
|
||||
}
|
||||
const resetForm = () => {
|
||||
formRef.value?.resetFields()
|
||||
formData.count = 1
|
||||
}
|
||||
const submitForm = async () => {
|
||||
await formRef.value.validate()
|
||||
submitLoading.value = true
|
||||
try {
|
||||
await BitWmsApi.move(formData)
|
||||
message.success('移库成功')
|
||||
resetForm()
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const [samples, warehouses, areas] = await Promise.all([
|
||||
BitWmsApi.getSampleSimpleList(),
|
||||
WarehouseApi.getWarehouseSimpleList(),
|
||||
WarehouseAreaApi.getWarehouseAreaPage({ pageNo: 1, pageSize: 100 })
|
||||
])
|
||||
sampleList.value = samples || []
|
||||
warehouseList.value = warehouses || []
|
||||
areaList.value = areas.list || []
|
||||
})
|
||||
</script>
|
||||
@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="110px" class="bit-wms-form">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="样品" prop="productId">
|
||||
<el-select v-model="formData.productId" placeholder="请选择样品" filterable clearable class="!w-full" @change="loadCurrentStock">
|
||||
<el-option v-for="item in sampleList" :key="item.id" :label="formatSampleLabel(item)" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="当前库存">
|
||||
<el-input :model-value="currentStockText" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="仓库" prop="warehouseId">
|
||||
<el-select v-model="formData.warehouseId" placeholder="请选择仓库" filterable class="!w-full" @change="handleWarehouseChange">
|
||||
<el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="库区" prop="areaId">
|
||||
<el-select v-model="formData.areaId" placeholder="请选择库区" filterable clearable class="!w-full" @change="loadCurrentStock">
|
||||
<el-option v-for="item in filteredAreaList" :key="item.id" :label="item.areaName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="数量" prop="count">
|
||||
<el-input-number v-model="formData.count" :min="1" :precision="0" class="!w-full" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="出库原因" prop="outReason">
|
||||
<el-select v-model="formData.outReason" placeholder="请选择出库原因" class="!w-full">
|
||||
<el-option v-for="dict in getStrDictOptions(DICT_TYPE.BIT_SAMPLE_OUT_REASON)" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="submitLoading" v-hasPermi="['erp:bit-wms-out:create']" @click="submitForm">
|
||||
<Icon icon="ep:check" class="mr-5px" />确认出库
|
||||
</el-button>
|
||||
<el-button @click="resetForm"><Icon icon="ep:refresh" class="mr-5px" />重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
|
||||
import { BitWmsApi } from '@/api/erp/bitwms'
|
||||
import { WarehouseApi } from '@/api/erp/stock/warehouse'
|
||||
import { WarehouseAreaApi } from '@/api/erp/stock/warehousearea'
|
||||
import { StockApi } from '@/api/erp/stock/stock'
|
||||
|
||||
defineOptions({ name: 'ErpBitWmsOut' })
|
||||
|
||||
const message = useMessage()
|
||||
const formRef = ref()
|
||||
const submitLoading = ref(false)
|
||||
const stockLoading = ref(false)
|
||||
const currentStock = ref<number | undefined>(undefined)
|
||||
const sampleList = ref<any[]>([])
|
||||
const warehouseList = ref<any[]>([])
|
||||
const areaList = ref<any[]>([])
|
||||
const formData = reactive<any>({
|
||||
productId: undefined,
|
||||
warehouseId: undefined,
|
||||
areaId: undefined,
|
||||
count: 1,
|
||||
outReason: undefined,
|
||||
remark: undefined
|
||||
})
|
||||
const formRules = reactive({
|
||||
productId: [{ required: true, message: '请选择样品', trigger: 'change' }],
|
||||
warehouseId: [{ required: true, message: '请选择仓库', trigger: 'change' }],
|
||||
count: [{ required: true, message: '请输入数量', trigger: 'blur' }],
|
||||
outReason: [{ required: true, message: '请选择出库原因', trigger: 'change' }]
|
||||
})
|
||||
const filteredAreaList = computed(() => {
|
||||
if (!formData.warehouseId) return areaList.value
|
||||
return areaList.value.filter((item) => item.warehouseId === formData.warehouseId)
|
||||
})
|
||||
const currentStockText = computed(() => {
|
||||
if (stockLoading.value) return '查询中...'
|
||||
return currentStock.value === undefined ? '-' : `${currentStock.value}`
|
||||
})
|
||||
|
||||
const formatSampleLabel = (item: any) => `${item.barCode || item.code || '-'} / ${item.name || '-'}`
|
||||
const handleWarehouseChange = () => {
|
||||
formData.areaId = undefined
|
||||
loadCurrentStock()
|
||||
}
|
||||
const loadCurrentStock = async () => {
|
||||
if (!formData.productId || !formData.warehouseId) {
|
||||
currentStock.value = undefined
|
||||
return
|
||||
}
|
||||
stockLoading.value = true
|
||||
try {
|
||||
const data = await StockApi.getStock2(formData.productId, formData.warehouseId, formData.areaId)
|
||||
currentStock.value = data?.count || 0
|
||||
} finally {
|
||||
stockLoading.value = false
|
||||
}
|
||||
}
|
||||
const resetForm = () => {
|
||||
formRef.value?.resetFields()
|
||||
formData.count = 1
|
||||
currentStock.value = undefined
|
||||
}
|
||||
const submitForm = async () => {
|
||||
await formRef.value.validate()
|
||||
submitLoading.value = true
|
||||
try {
|
||||
await BitWmsApi.outbound(formData)
|
||||
message.success('出库成功')
|
||||
await loadCurrentStock()
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const [samples, warehouses, areas] = await Promise.all([
|
||||
BitWmsApi.getSampleSimpleList(),
|
||||
WarehouseApi.getWarehouseSimpleList(),
|
||||
WarehouseAreaApi.getWarehouseAreaPage({ pageNo: 1, pageSize: 100 })
|
||||
])
|
||||
sampleList.value = samples || []
|
||||
warehouseList.value = warehouses || []
|
||||
areaList.value = areas.list || []
|
||||
})
|
||||
</script>
|
||||
@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="auto">
|
||||
<el-form-item label="样品" prop="productId">
|
||||
<el-select v-model="queryParams.productId" placeholder="请选择样品" clearable filterable class="!w-240px">
|
||||
<el-option v-for="item in sampleList" :key="item.id" :label="formatSampleLabel(item)" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="仓库" prop="warehouseId">
|
||||
<el-select v-model="queryParams.warehouseId" placeholder="请选择仓库" clearable filterable class="!w-220px" @change="handleWarehouseChange">
|
||||
<el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="库区" prop="areaId">
|
||||
<el-select v-model="queryParams.areaId" placeholder="请选择库区" clearable filterable class="!w-220px">
|
||||
<el-option v-for="item in filteredAreaList" :key="item.id" :label="item.areaName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="业务单号" prop="bizNo">
|
||||
<el-input v-model="queryParams.bizNo" placeholder="请输入业务单号" clearable class="!w-220px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<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>
|
||||
</ContentWrap>
|
||||
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" row-key="id">
|
||||
<el-table-column label="业务单号" align="center" prop="bizNo" min-width="170" />
|
||||
<el-table-column label="方向" align="center" prop="bizDirection" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.bizDirection" :type="getDirectionTagType(row.bizDirection)">{{ row.bizDirection }}</el-tag>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="样品名称" align="left" prop="productName" min-width="180" />
|
||||
<el-table-column label="分类" align="center" prop="categoryName" min-width="120" />
|
||||
<el-table-column label="仓库" align="center" prop="warehouseName" min-width="140" />
|
||||
<el-table-column label="库区" align="center" prop="areaName" min-width="120" />
|
||||
<el-table-column label="变动数量" align="center" prop="count" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<span :class="getDirectionClass(row.bizDirection)">{{ formatCount(row.count, row.unitName, true, row.bizDirection) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="结存" align="center" prop="totalCount" min-width="120">
|
||||
<template #default="{ row }">{{ formatCount(row.totalCount, row.unitName) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作人" align="center" prop="creatorName" min-width="110" />
|
||||
<el-table-column label="操作时间" align="center" prop="recordTime" :formatter="dateFormatter" width="180" />
|
||||
</el-table>
|
||||
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</ContentWrap>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import { BitWmsApi } from '@/api/erp/bitwms'
|
||||
import { StockRecordApi } from '@/api/erp/stock/record'
|
||||
import { WarehouseApi } from '@/api/erp/stock/warehouse'
|
||||
import { WarehouseAreaApi } from '@/api/erp/stock/warehousearea'
|
||||
|
||||
defineOptions({ name: 'ErpBitWmsRecord' })
|
||||
|
||||
const loading = ref(true)
|
||||
const list = ref<any[]>([])
|
||||
const total = ref(0)
|
||||
const queryFormRef = ref()
|
||||
const sampleList = ref<any[]>([])
|
||||
const warehouseList = ref<any[]>([])
|
||||
const areaList = ref<any[]>([])
|
||||
const queryParams = reactive<any>({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
productId: undefined,
|
||||
warehouseId: undefined,
|
||||
areaId: undefined,
|
||||
bizNo: undefined,
|
||||
isSample: true,
|
||||
bizUnit: 'BIT'
|
||||
})
|
||||
const filteredAreaList = computed(() => {
|
||||
if (!queryParams.warehouseId) return areaList.value
|
||||
return areaList.value.filter((item) => item.warehouseId === queryParams.warehouseId)
|
||||
})
|
||||
|
||||
const formatSampleLabel = (item: any) => `${item.barCode || item.code || '-'} / ${item.name || '-'}`
|
||||
const isStockIn = (direction?: string) => direction === '入库'
|
||||
const isStockOut = (direction?: string) => direction === '出库'
|
||||
const getDirectionTagType = (direction?: string) => {
|
||||
if (isStockIn(direction)) return 'success'
|
||||
if (isStockOut(direction)) return 'danger'
|
||||
return 'info'
|
||||
}
|
||||
const getDirectionClass = (direction?: string) => {
|
||||
if (isStockIn(direction)) return 'bit-wms-record-in'
|
||||
if (isStockOut(direction)) return 'bit-wms-record-out'
|
||||
return ''
|
||||
}
|
||||
const formatNumber = (value: number | string | undefined) => {
|
||||
if (value === undefined || value === null || value === '') return '-'
|
||||
const num = Number(value)
|
||||
return Number.isFinite(num) ? num.toLocaleString() : String(value)
|
||||
}
|
||||
const formatCount = (value: number | string | undefined, unit?: string, withSign = false, direction?: string) => {
|
||||
const unitText = unit ? ` ${unit}` : ''
|
||||
if (!withSign) return `${formatNumber(value)}${unitText}`
|
||||
const num = Number(value)
|
||||
if (!Number.isFinite(num)) return `${value ?? '-'}${unitText}`
|
||||
const absValue = Math.abs(num).toLocaleString()
|
||||
if (isStockIn(direction)) return `+${absValue}${unitText}`
|
||||
if (isStockOut(direction)) return `-${absValue}${unitText}`
|
||||
return `${formatNumber(value)}${unitText}`
|
||||
}
|
||||
const buildQueryParams = () =>
|
||||
Object.fromEntries(Object.entries(queryParams).filter(([, value]) => value !== undefined && value !== null && value !== ''))
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await StockRecordApi.getStockRecordPage(buildQueryParams())
|
||||
list.value = data.list || []
|
||||
total.value = data.total || 0
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
const handleWarehouseChange = () => {
|
||||
queryParams.areaId = undefined
|
||||
}
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
queryParams.isSample = true
|
||||
queryParams.bizUnit = 'BIT'
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const [samples, warehouses, areas] = await Promise.all([
|
||||
BitWmsApi.getSampleSimpleList(),
|
||||
WarehouseApi.getWarehouseSimpleList(),
|
||||
WarehouseAreaApi.getWarehouseAreaPage({ pageNo: 1, pageSize: 100 })
|
||||
])
|
||||
sampleList.value = samples || []
|
||||
warehouseList.value = warehouses || []
|
||||
areaList.value = areas.list || []
|
||||
await getList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.bit-wms-record-in {
|
||||
color: var(--el-color-success);
|
||||
}
|
||||
|
||||
.bit-wms-record-out {
|
||||
color: var(--el-color-danger);
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="auto">
|
||||
<el-form-item label="样品码" prop="barCode">
|
||||
<el-input v-model="queryParams.barCode" placeholder="请输入样品码" clearable class="!w-220px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="样品名称" prop="name">
|
||||
<el-input v-model="queryParams.name" placeholder="请输入样品名称" clearable class="!w-220px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="样品类型" prop="categoryType">
|
||||
<el-select v-model="queryParams.categoryType" placeholder="请选择样品类型" clearable class="!w-180px">
|
||||
<el-option v-for="dict in getIntDictOptions(DICT_TYPE.MATERIAL_CLASSIFICATION_TYPE)" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="样品分类" prop="sampleCategory">
|
||||
<el-select v-model="queryParams.sampleCategory" placeholder="请选择样品分类" clearable class="!w-180px">
|
||||
<el-option v-for="dict in getStrDictOptions(DICT_TYPE.BIT_SAMPLE_CATEGORY)" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="客户名称" prop="customerName">
|
||||
<el-input v-model="queryParams.customerName" placeholder="请输入客户名称" clearable class="!w-220px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<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-button type="primary" plain v-hasPermi="['erp:bit-wms-sample:create']" @click="openProductCreate">
|
||||
<Icon icon="ep:plus" class="mr-5px" />新增样品
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" row-key="id">
|
||||
<el-table-column label="样品码" align="center" prop="barCode" min-width="160" />
|
||||
<el-table-column label="样品名称" align="left" prop="name" min-width="180" />
|
||||
<el-table-column label="样品类型" align="center" prop="categoryType" min-width="110">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :type="DICT_TYPE.MATERIAL_CLASSIFICATION_TYPE" :value="row.categoryType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="样品分类" align="center" prop="sampleCategory" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :type="DICT_TYPE.BIT_SAMPLE_CATEGORY" :value="row.sampleCategory" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="规格" align="center" prop="standard" min-width="140" />
|
||||
<el-table-column label="客户名称" align="center" prop="customerName" min-width="140" />
|
||||
<el-table-column label="默认仓库" align="center" min-width="160">
|
||||
<template #default="{ row }">
|
||||
{{ row.defaultWarehouseName || row.warehouseName || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center" prop="status" width="100">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="210" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="openProductDetail(row.id)">详情</el-button>
|
||||
<el-button link type="primary" v-hasPermi="['erp:bit-wms-sample:update']" @click="openProductEdit(row.id)">编辑</el-button>
|
||||
<BitWmsPrintButton
|
||||
v-hasPermi="['erp:bit-wms-sample:print']"
|
||||
title="样品标签"
|
||||
:load-label="() => loadSampleLabel(row.id)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</ContentWrap>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DICT_TYPE, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
|
||||
import { BitWmsApi } from '@/api/erp/bitwms'
|
||||
import BitWmsPrintButton from '../components/BitWmsPrintButton.vue'
|
||||
|
||||
defineOptions({ name: 'ErpBitWmsSample' })
|
||||
|
||||
const router = useRouter()
|
||||
const loading = ref(true)
|
||||
const list = ref<any[]>([])
|
||||
const total = ref(0)
|
||||
const queryFormRef = ref()
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
barCode: undefined,
|
||||
name: undefined,
|
||||
categoryType: undefined,
|
||||
sampleCategory: undefined,
|
||||
customerName: undefined
|
||||
})
|
||||
|
||||
const buildQueryParams = () =>
|
||||
Object.fromEntries(Object.entries(queryParams).filter(([, value]) => value !== undefined && value !== null && value !== ''))
|
||||
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await BitWmsApi.getSamplePage(buildQueryParams())
|
||||
list.value = data.list || []
|
||||
total.value = data.total || 0
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
const loadSampleLabel = async (id: number) => await BitWmsApi.getSampleLabel(id)
|
||||
const openProductCreate = () => router.push({ path: '/erp/product/product' })
|
||||
const openProductEdit = (id: number) => router.push({ path: '/erp/product/product', query: { id, type: 'update' } })
|
||||
const openProductDetail = (id: number) => router.push({ path: '/erp/product/product', query: { id, type: 'detail' } })
|
||||
|
||||
onMounted(getList)
|
||||
</script>
|
||||
@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="auto">
|
||||
<el-form-item label="样品" prop="productId">
|
||||
<el-select v-model="queryParams.productId" placeholder="请选择样品" clearable filterable class="!w-240px">
|
||||
<el-option v-for="item in sampleList" :key="item.id" :label="formatSampleLabel(item)" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="仓库" prop="warehouseId">
|
||||
<el-select v-model="queryParams.warehouseId" placeholder="请选择仓库" clearable filterable class="!w-220px" @change="handleWarehouseChange">
|
||||
<el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="库区" prop="areaId">
|
||||
<el-select v-model="queryParams.areaId" placeholder="请选择库区" clearable filterable class="!w-220px">
|
||||
<el-option v-for="item in filteredAreaList" :key="item.id" :label="item.areaName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<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>
|
||||
</ContentWrap>
|
||||
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" row-key="id">
|
||||
<el-table-column label="样品码" align="center" prop="barCode" min-width="150" />
|
||||
<el-table-column label="样品名称" align="left" min-width="180">
|
||||
<template #default="{ row }">{{ row.name || row.productName || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="样品分类" align="center" prop="categoryName" min-width="130" />
|
||||
<el-table-column label="仓库" align="center" prop="warehouseName" min-width="140" />
|
||||
<el-table-column label="库区" align="center" prop="areaName" min-width="120" />
|
||||
<el-table-column label="库存" align="center" prop="count" min-width="120">
|
||||
<template #default="{ row }">{{ formatCount(row.count) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单位" align="center" prop="unitName" width="90" />
|
||||
<el-table-column label="库存展示" align="center" prop="stockDisplay" min-width="200">
|
||||
<template #default="{ row }">{{ row.stockDisplay || '-' }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</ContentWrap>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { BitWmsApi } from '@/api/erp/bitwms'
|
||||
import { StockApi } from '@/api/erp/stock/stock'
|
||||
import { WarehouseApi } from '@/api/erp/stock/warehouse'
|
||||
import { WarehouseAreaApi } from '@/api/erp/stock/warehousearea'
|
||||
|
||||
defineOptions({ name: 'ErpBitWmsStock' })
|
||||
|
||||
const loading = ref(true)
|
||||
const list = ref<any[]>([])
|
||||
const total = ref(0)
|
||||
const queryFormRef = ref()
|
||||
const sampleList = ref<any[]>([])
|
||||
const warehouseList = ref<any[]>([])
|
||||
const areaList = ref<any[]>([])
|
||||
const queryParams = reactive<any>({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
productId: undefined,
|
||||
warehouseId: undefined,
|
||||
areaId: undefined,
|
||||
isSample: true,
|
||||
bizUnit: 'BIT'
|
||||
})
|
||||
const filteredAreaList = computed(() => {
|
||||
if (!queryParams.warehouseId) return areaList.value
|
||||
return areaList.value.filter((item) => item.warehouseId === queryParams.warehouseId)
|
||||
})
|
||||
|
||||
const formatSampleLabel = (item: any) => `${item.barCode || item.code || '-'} / ${item.name || '-'}`
|
||||
const formatCount = (value: number | string | undefined) => {
|
||||
if (value === undefined || value === null || value === '') return '-'
|
||||
const num = Number(value)
|
||||
return Number.isFinite(num) ? num.toLocaleString() : String(value)
|
||||
}
|
||||
const buildQueryParams = () =>
|
||||
Object.fromEntries(Object.entries(queryParams).filter(([, value]) => value !== undefined && value !== null && value !== ''))
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await StockApi.getStockPage(buildQueryParams())
|
||||
list.value = data.list || []
|
||||
total.value = data.total || 0
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
const handleWarehouseChange = () => {
|
||||
queryParams.areaId = undefined
|
||||
}
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
queryParams.isSample = true
|
||||
queryParams.bizUnit = 'BIT'
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const [samples, warehouses, areas] = await Promise.all([
|
||||
BitWmsApi.getSampleSimpleList(),
|
||||
WarehouseApi.getWarehouseSimpleList(),
|
||||
WarehouseAreaApi.getWarehouseAreaPage({ pageNo: 1, pageSize: 100 })
|
||||
])
|
||||
sampleList.value = samples || []
|
||||
warehouseList.value = warehouses || []
|
||||
areaList.value = areas.list || []
|
||||
await getList()
|
||||
})
|
||||
</script>
|
||||
Loading…
Reference in New Issue