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