feat:盘点执行/托盘管理模块

main
黄伟杰 5 days ago
parent a536ee7603
commit 68c61dbf81

@ -26,8 +26,8 @@ export const PalletApi = {
return await request.get({ url: `/erp/pallet/page`, params })
},
createPallet: async (params: PalletVO) => {
return await request.post({ url: `/erp/pallet/create`, params })
createPallet: async (data: PalletVO) => {
return await request.post({ url: `/erp/pallet/create`, data })
},
updatePallet: async (params: PalletVO) => {

@ -597,6 +597,7 @@
validatorSelectCheckItem: 'Please select check item',
validatorAuditUserRequired: 'Please select auditor',
validatorCompleteCheckInfo: 'Please complete check information first',
confirmActualCountZero: ' actual count is 0. Confirm submit?',
confirmApprove: 'Are you sure to approve this check order?',
confirmReverseApprove: 'Are you sure to reverse approve this check order?',
submitSuccess: 'Submit success',
@ -729,13 +730,18 @@
productCount: 'Product Quantity',
qrcode: 'QR Code',
viewQrcode: 'View QR Code',
qrcodeEmpty: 'No QR code',
qrcodeRefreshConfirm: 'Confirm to refresh this pallet QR code?',
purchaseDate: 'Purchase Date',
useDate: 'Use Date',
remark: 'Remark',
createTime: 'Create Time',
placeholderCode: 'Please enter pallet code',
placeholderPalletType: 'Please enter pallet type',
placeholderSpecification: 'Please select pallet specification',
placeholderSpecification: 'Please enter pallet specification',
placeholderLength: 'Length',
placeholderWidth: 'Width',
placeholderHeight: 'Height',
placeholderRatedLoadWeight: 'Please enter rated load',
placeholderUnit: 'Please enter unit',
placeholderStatus: 'Please select pallet status',
@ -744,7 +750,6 @@
placeholderPlanCode: 'Please enter production task no.',
placeholderProductId: 'Please select product',
placeholderProductCount: 'Please enter product quantity',
placeholderQrcode: 'Please enter QR code URL',
placeholderPurchaseDate: 'Please select purchase date',
placeholderUseDate: 'Please select use date',
placeholderRemark: 'Please enter remark',

@ -597,6 +597,7 @@
validatorSelectCheckItem: '请选择盘点项',
validatorAuditUserRequired: '请选择审核人',
validatorCompleteCheckInfo: '请先完善盘点信息',
confirmActualCountZero: '实盘数量为0确认提交吗',
confirmApprove: '确定审批该盘点单吗?',
confirmReverseApprove: '确定反审批该盘点单吗?',
submitSuccess: '提交成功',
@ -729,13 +730,18 @@
productCount: '产品数量',
qrcode: '二维码',
viewQrcode: '查看二维码',
qrcodeEmpty: '暂无二维码',
qrcodeRefreshConfirm: '确认刷新该托盘二维码吗?',
purchaseDate: '采购日期',
useDate: '启用日期',
remark: '备注',
createTime: '创建时间',
placeholderCode: '请输入托盘编码',
placeholderPalletType: '请输入托盘类型',
placeholderSpecification: '请选择托盘规格',
placeholderSpecification: '请输入托盘规格',
placeholderLength: '长',
placeholderWidth: '宽',
placeholderHeight: '高',
placeholderRatedLoadWeight: '请输入额定载重',
placeholderUnit: '请输入单位',
placeholderStatus: '请选择托盘状态',
@ -744,7 +750,6 @@
placeholderPlanCode: '请输入生产任务单号',
placeholderProductId: '请选择产品',
placeholderProductCount: '请输入产品数量',
placeholderQrcode: '请输入二维码地址',
placeholderPurchaseDate: '请选择采购日期',
placeholderUseDate: '请选择投入使用日期',
placeholderRemark: '请输入备注',

@ -235,7 +235,6 @@ export enum DICT_TYPE {
WAREHOUSE_OUTBOUND_PURPOSE = 'warehouse_outbound_purpose', // 出库用途
STORAGE_PALLET_TYPES = 'storage_pallet_types', // 仓储托盘类型
STORAGE_PALLET_STATUS = 'storage_pallet_status', // 仓储托盘状态
STORAGE_PALLET_SPECIFICATIONS = 'storage_pallet_specifications', // 仓储托盘规格
SUBMOLD_TYPE = 'submold_type', // 子模具类型
ERP_MAINTAIN_TYPE = 'maintain_type',// ERP 保养类型

@ -354,6 +354,8 @@ const isActualCountEmpty = (value: unknown) => value === undefined || value ===
const hasIncompleteActualCount = computed(() =>
(formData.value.items || []).some((item) => isActualCountEmpty(item.actualCount))
)
const getCheckItemName = (item: StockCheckItemVO) =>
item.productBarCode || item.productName || `${t('ErpStock.Check.checkItem')}${item.id ? `-${item.id}` : ''}`
const selectedWarehouses = ref<WarehouseVO[]>([])
const selectedAreas = ref<WarehouseAreaVO[]>([])
@ -811,6 +813,13 @@ const submitForm = async (checkStatus?: 0 | 1) => {
message.warning(t('ErpStock.Check.validatorCompleteCheckInfo'))
return
}
if (checkStatus === 1) {
const zeroCountItems = (formData.value.items || []).filter((item) => Number(item.actualCount) === 0)
if (zeroCountItems.length > 0) {
const itemNames = zeroCountItems.map((item) => getCheckItemName(item)).join('、')
await message.confirm(`${itemNames}${t('ErpStock.Check.confirmActualCountZero')}`)
}
}
if (isInventoryCheck.value) {
formData.value.checkStatus = checkStatus
formData.value.items.forEach((item) => {

@ -46,19 +46,31 @@
</el-col>
<el-col :span="12">
<el-form-item :label="t('ErpStock.Pallet.specification')" prop="specification">
<el-select
v-model="formData.specification"
:placeholder="t('ErpStock.Pallet.placeholderSpecification')"
clearable
class="!w-1/1"
>
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.STORAGE_PALLET_SPECIFICATIONS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
<div class="pallet-spec-input">
<el-input-number
v-model="specificationParts.length"
:min="0"
:precision="0"
:controls="false"
:placeholder="t('ErpStock.Pallet.placeholderLength')"
/>
</el-select>
<span>x</span>
<el-input-number
v-model="specificationParts.width"
:min="0"
:precision="0"
:controls="false"
:placeholder="t('ErpStock.Pallet.placeholderWidth')"
/>
<span>x</span>
<el-input-number
v-model="specificationParts.height"
:min="0"
:precision="0"
:controls="false"
:placeholder="t('ErpStock.Pallet.placeholderHeight')"
/>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
@ -95,37 +107,20 @@
</el-col>
<el-col :span="12">
<el-form-item :label="t('ErpStock.Pallet.warehouseId')" prop="warehouseId">
<el-select
v-model="formData.warehouseId"
:placeholder="t('ErpStock.Pallet.placeholderWarehouseId')"
clearable
class="!w-1/1"
@change="handleWarehouseChange"
>
<el-option
v-for="item in warehouseList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
<el-input :model-value="selectedWarehouseText" readonly :placeholder="t('ErpStock.Pallet.placeholderWarehouseId')">
<template #append>
<el-button @click="openWarehouseDialog">{{ t('common.select') }}</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('ErpStock.Pallet.areaId')" prop="areaId">
<el-select
v-model="formData.areaId"
:placeholder="t('ErpStock.Pallet.placeholderAreaId')"
clearable
class="!w-1/1"
>
<el-option
v-for="item in filteredAreaList"
:key="item.id"
:label="item.areaName"
:value="item.id"
/>
</el-select>
<el-input :model-value="selectedAreaText" readonly :placeholder="t('ErpStock.Pallet.placeholderAreaId')">
<template #append>
<el-button @click="openAreaDialog">{{ t('common.select') }}</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
@ -184,9 +179,19 @@
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-col v-if="formType === 'update'" :span="24">
<el-form-item :label="t('ErpStock.Pallet.qrcode')" prop="qrcode">
<el-input v-model="formData.qrcode" :placeholder="t('ErpStock.Pallet.placeholderQrcode')" />
<QrcodeActionCard
:image-url="formData.qrcode"
:print-id="formData.id"
:print-title="`${formData.code || t('ErpStock.Pallet.code')}二维码打印预览`"
:empty-text="t('ErpStock.Pallet.qrcodeEmpty')"
:refresh-url="getQrcodeRefreshUrl()"
:refresh-disabled="!formData.id || !formData.code"
:refresh-confirm-text="t('ErpStock.Pallet.qrcodeRefreshConfirm')"
:print-data="buildPrintData()"
@refresh-success="handleQrcodeRefreshSuccess"
/>
</el-form-item>
</el-col>
<el-col :span="24">
@ -205,14 +210,156 @@
<el-button @click="dialogVisible = false">{{ t('common.cancel') }}</el-button>
</template>
</Dialog>
<Dialog :title="t('ErpStock.Check.selectWarehouseDialogTitle')" v-model="warehouseDialogVisible" width="1000px">
<el-form :model="warehouseQueryParams" :inline="true" label-width="auto" class="-mb-15px">
<el-form-item :label="t('ErpStock.Warehouse.name')">
<el-input
v-model="warehouseQueryParams.name"
clearable
:placeholder="t('ErpStock.Warehouse.placeholderName')"
class="!w-240px"
@keyup.enter="handleWarehouseQuery"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleWarehouseQuery">
<Icon icon="ep:search" class="mr-5px" />{{ t('common.query') }}
</el-button>
<el-button @click="resetWarehouseQuery">
<Icon icon="ep:refresh" class="mr-5px" />{{ t('common.reset') }}
</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="warehouseLoading"
:data="warehouseTableList"
row-key="id"
highlight-current-row
@row-click="handleWarehouseRowClick"
>
<el-table-column align="center" width="55">
<template #default="scope">
<el-radio
:model-value="warehouseSelection?.id"
:value="scope.row.id"
@change="handleWarehouseRowClick(scope.row)"
/>
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Warehouse.name')" align="center" prop="name" min-width="160" sortable />
<el-table-column :label="t('ErpStock.Warehouse.categoryType')" align="center" prop="categoryType" min-width="120">
<template #default="scope">
<dict-tag :type="DICT_TYPE.MATERIAL_CLASSIFICATION_TYPE" :value="scope.row.categoryType" />
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Warehouse.address')" align="center" prop="address" min-width="180" show-overflow-tooltip />
<el-table-column :label="t('ErpStock.Warehouse.principal')" align="center" prop="principal" min-width="110" />
<el-table-column :label="t('ErpStock.Warehouse.status')" align="center" prop="status" min-width="100" sortable>
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Warehouse.createTime')" align="center" prop="createTime" :formatter="dateFormatter" min-width="180" sortable />
</el-table>
<div class="pallet-dialog-pagination">
<Pagination
:total="warehouseTotal"
v-model:page="warehouseQueryParams.pageNo"
v-model:limit="warehouseQueryParams.pageSize"
@pagination="getWarehouseTableList"
/>
</div>
<template #footer>
<el-button type="primary" @click="confirmWarehouseSelection">{{ t('common.ok') }}</el-button>
<el-button @click="warehouseDialogVisible = false">{{ t('common.cancel') }}</el-button>
</template>
</Dialog>
<Dialog :title="t('ErpStock.Check.selectAreaDialogTitle')" v-model="areaDialogVisible" width="1000px">
<el-form :model="areaQueryParams" :inline="true" label-width="auto" class="-mb-15px">
<el-form-item :label="t('ErpStock.WarehouseArea.areaCode')">
<el-input
v-model="areaQueryParams.areaCode"
clearable
:placeholder="t('ErpStock.WarehouseArea.placeholderAreaCode')"
class="!w-240px"
@keyup.enter="handleAreaQuery"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseArea.areaName')">
<el-input
v-model="areaQueryParams.areaName"
clearable
:placeholder="t('ErpStock.WarehouseArea.placeholderAreaName')"
class="!w-240px"
@keyup.enter="handleAreaQuery"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleAreaQuery">
<Icon icon="ep:search" class="mr-5px" />{{ t('common.query') }}
</el-button>
<el-button @click="resetAreaQuery">
<Icon icon="ep:refresh" class="mr-5px" />{{ t('common.reset') }}
</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="areaLoading"
:data="areaTableList"
row-key="id"
highlight-current-row
@row-click="handleAreaRowClick"
>
<el-table-column align="center" width="55">
<template #default="scope">
<el-radio
:model-value="areaSelection?.id"
:value="scope.row.id"
@change="handleAreaRowClick(scope.row)"
/>
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.WarehouseArea.warehouseId')" align="center" prop="warehouseId" min-width="140" sortable>
<template #default="scope">
{{ getWarehouseName(scope.row.warehouseId) }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.WarehouseArea.areaCode')" align="center" prop="areaCode" min-width="130" sortable />
<el-table-column :label="t('ErpStock.WarehouseArea.areaName')" align="center" prop="areaName" min-width="130" sortable />
<el-table-column :label="t('ErpStock.WarehouseArea.areaSize')" align="center" prop="areaSize" min-width="100" />
<el-table-column :label="t('ErpStock.WarehouseArea.description')" align="center" prop="description" min-width="160" show-overflow-tooltip />
<el-table-column :label="t('ErpStock.WarehouseArea.status')" align="center" prop="status" min-width="100" sortable>
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.WarehouseArea.createTime')" align="center" prop="createTime" :formatter="dateFormatter" min-width="180" sortable />
</el-table>
<div class="pallet-dialog-pagination">
<Pagination
:total="areaTotal"
v-model:page="areaQueryParams.pageNo"
v-model:limit="areaQueryParams.pageSize"
@pagination="getAreaTableList"
/>
</div>
<template #footer>
<el-button type="primary" @click="confirmAreaSelection">{{ t('common.ok') }}</el-button>
<el-button @click="areaDialogVisible = false">{{ t('common.cancel') }}</el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { PalletApi, PalletVO } from '@/api/erp/stock/pallet'
import { WarehouseApi } from '@/api/erp/stock/warehouse'
import { WarehouseAreaApi } from '@/api/erp/stock/warehousearea'
import { dateFormatter } from '@/utils/formatTime'
import { WarehouseApi, WarehouseVO } from '@/api/erp/stock/warehouse'
import { WarehouseAreaApi, WarehouseAreaVO } from '@/api/erp/stock/warehousearea'
import { ProductApi, ProductVO } from '@/api/erp/product/product'
import QrcodeActionCard from '@/components/QrcodeActionCard/index.vue'
defineOptions({ name: 'PalletForm' })
@ -224,9 +371,34 @@ const dialogTitle = ref('')
const formLoading = ref(false)
const formType = ref('')
const formRef = ref()
const warehouseList = ref<any[]>([])
const areaList = ref<any[]>([])
const warehouseOptions = ref<WarehouseVO[]>([])
const areaOptions = ref<WarehouseAreaVO[]>([])
const productList = ref<ProductVO[]>([])
const selectedWarehouse = ref<WarehouseVO | undefined>()
const selectedArea = ref<WarehouseAreaVO | undefined>()
const warehouseDialogVisible = ref(false)
const warehouseLoading = ref(false)
const warehouseTableList = ref<WarehouseVO[]>([])
const warehouseTotal = ref(0)
const warehouseSelection = ref<WarehouseVO | undefined>()
const warehouseQueryParams = reactive({
pageNo: 1,
pageSize: 10,
name: undefined as string | undefined
})
const areaDialogVisible = ref(false)
const areaLoading = ref(false)
const areaTableList = ref<WarehouseAreaVO[]>([])
const areaTotal = ref(0)
const areaSelection = ref<WarehouseAreaVO | undefined>()
const areaQueryParams = reactive({
pageNo: 1,
pageSize: 10,
areaCode: undefined as string | undefined,
areaName: undefined as string | undefined
})
const formData = ref<PalletVO>({
code: undefined,
@ -246,12 +418,15 @@ const formData = ref<PalletVO>({
useDate: undefined,
remark: undefined
})
const filteredAreaList = computed(() => {
if (!formData.value.warehouseId) return areaList.value
return areaList.value.filter((item) => item.warehouseId === formData.value.warehouseId)
const specificationParts = reactive({
length: undefined as number | undefined,
width: undefined as number | undefined,
height: undefined as number | undefined
})
const selectedWarehouseText = computed(() => selectedWarehouse.value?.name ?? '')
const selectedAreaText = computed(() => selectedArea.value?.areaName ?? '')
const validateCode = (_rule, value, callback) => {
if (Boolean(formData.value.isCode)) {
callback()
@ -275,12 +450,14 @@ const open = async (type: string, row?: PalletVO) => {
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
await Promise.all([getWarehouseList(), getAreaList(), getProductList()])
await Promise.all([getWarehouseOptions(), getAreaOptions(), getProductList()])
if (type === 'update' && row) {
formData.value = {
...row,
isCode: false
}
parseSpecification(row.specification)
await hydrateSelectedWarehouseArea()
}
}
defineExpose({ open })
@ -291,6 +468,8 @@ const submitForm = async () => {
formLoading.value = true
try {
const data = { ...formData.value }
delete data.qrcode
data.specification = buildSpecification()
if (data.isCode) {
data.code = undefined
}
@ -308,21 +487,173 @@ const submitForm = async () => {
}
}
const getWarehouseList = async () => {
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
const getWarehouseOptions = async () => {
warehouseOptions.value = await WarehouseApi.getWarehouseSimpleList()
}
const getAreaList = async () => {
const getAreaOptions = async () => {
const data = await WarehouseAreaApi.getWarehouseAreaPage({ pageNo: 1, pageSize: 100 })
areaList.value = data.list ?? []
areaOptions.value = data.list ?? []
}
const getProductList = async () => {
productList.value = await ProductApi.getProductSimpleList()
}
const handleWarehouseChange = () => {
const buildPrintData = () => {
return {
id: formData.value.id,
code: formData.value.code,
palletType: formData.value.palletType,
specification: buildSpecification() || formData.value.specification,
warehouseId: formData.value.warehouseId,
areaId: formData.value.areaId,
qrcodeUrl: formData.value.qrcode
}
}
const getQrcodeRefreshUrl = () => {
if (!formData.value.id || !formData.value.code) return ''
return `/erp/pallet/regenerate-code?id=${formData.value.id}&code=${encodeURIComponent(String(formData.value.code))}`
}
const handleQrcodeRefreshSuccess = (data: any) => {
const qrcode = data?.qrcode ?? data?.qrcodeUrl
if (qrcode) {
formData.value.qrcode = qrcode
}
}
const parseSpecification = (value?: string) => {
const [length, width, height] = String(value || '')
.split(/[xX×*]/)
.map((item) => Number(item.trim()))
specificationParts.length = Number.isFinite(length) ? length : undefined
specificationParts.width = Number.isFinite(width) ? width : undefined
specificationParts.height = Number.isFinite(height) ? height : undefined
}
const buildSpecification = () => {
const { length, width, height } = specificationParts
const isEmpty = (value?: number | null) => value === undefined || value === null
if (isEmpty(length) && isEmpty(width) && isEmpty(height)) {
return undefined
}
return `${length ?? ''}x${width ?? ''}x${height ?? ''}`
}
const hydrateSelectedWarehouseArea = async () => {
selectedWarehouse.value = warehouseOptions.value.find((item) => item.id === formData.value.warehouseId)
selectedArea.value = areaOptions.value.find((item) => item.id === formData.value.areaId)
if (!selectedArea.value && formData.value.warehouseId && formData.value.areaId) {
const data = await WarehouseAreaApi.getWarehouseAreaPage({
pageNo: 1,
pageSize: 100,
warehouseId: formData.value.warehouseId
})
const areas = data?.list ?? []
areaOptions.value = areas
selectedArea.value = areas.find((item) => item.id === formData.value.areaId)
}
}
const getWarehouseName = (warehouseId?: number) => {
return warehouseOptions.value.find((item) => item.id === warehouseId)?.name ?? '-'
}
const clearAreaSelection = () => {
formData.value.areaId = undefined
selectedArea.value = undefined
}
const getWarehouseTableList = async () => {
warehouseLoading.value = true
try {
const data = await WarehouseApi.getWarehousePage(warehouseQueryParams)
warehouseTableList.value = data?.list ?? []
warehouseTotal.value = data?.total ?? 0
} finally {
warehouseLoading.value = false
}
}
const openWarehouseDialog = async () => {
warehouseDialogVisible.value = true
warehouseSelection.value = selectedWarehouse.value
await getWarehouseTableList()
}
const handleWarehouseQuery = () => {
warehouseQueryParams.pageNo = 1
getWarehouseTableList()
}
const resetWarehouseQuery = () => {
warehouseQueryParams.pageNo = 1
warehouseQueryParams.name = undefined
getWarehouseTableList()
}
const handleWarehouseRowClick = (row: WarehouseVO) => {
warehouseSelection.value = row
}
const confirmWarehouseSelection = () => {
if (!warehouseSelection.value) return
const oldWarehouseId = formData.value.warehouseId
selectedWarehouse.value = warehouseSelection.value
formData.value.warehouseId = warehouseSelection.value.id
if (oldWarehouseId !== formData.value.warehouseId) {
clearAreaSelection()
}
warehouseDialogVisible.value = false
}
const getAreaTableList = async () => {
areaLoading.value = true
try {
const data = await WarehouseAreaApi.getWarehouseAreaPage({
...areaQueryParams,
warehouseId: formData.value.warehouseId
})
areaTableList.value = data?.list ?? []
areaTotal.value = data?.total ?? 0
} finally {
areaLoading.value = false
}
}
const openAreaDialog = async () => {
if (!formData.value.warehouseId) {
message.warning(t('ErpStock.Check.validatorSelectWarehouseFirst'))
return
}
areaDialogVisible.value = true
areaSelection.value = selectedArea.value
await getAreaTableList()
}
const handleAreaQuery = () => {
areaQueryParams.pageNo = 1
getAreaTableList()
}
const resetAreaQuery = () => {
areaQueryParams.pageNo = 1
areaQueryParams.areaCode = undefined
areaQueryParams.areaName = undefined
getAreaTableList()
}
const handleAreaRowClick = (row: WarehouseAreaVO) => {
areaSelection.value = row
}
const confirmAreaSelection = () => {
if (!areaSelection.value) return
selectedArea.value = areaSelection.value
formData.value.areaId = areaSelection.value.id
areaDialogVisible.value = false
}
const handleCodeAutoChange = (value: boolean) => {
@ -351,6 +682,35 @@ const resetForm = () => {
useDate: undefined,
remark: undefined
}
specificationParts.length = undefined
specificationParts.width = undefined
specificationParts.height = undefined
selectedWarehouse.value = undefined
selectedArea.value = undefined
formRef.value?.resetFields()
}
</script>
<style scoped lang="scss">
.pallet-dialog-pagination {
display: flex;
justify-content: flex-end;
padding: 16px 0 8px;
}
.pallet-spec-input {
display: grid;
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr) auto minmax(0, 1fr);
align-items: center;
gap: 8px;
width: 100%;
:deep(.el-input-number) {
width: 100%;
}
span {
color: var(--el-text-color-secondary);
}
}
</style>

@ -1,90 +1,39 @@
<template>
<ContentWrap>
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="auto"
>
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="auto">
<el-form-item :label="t('ErpStock.Pallet.code')" prop="code">
<el-input
v-model="queryParams.code"
:placeholder="t('ErpStock.Pallet.placeholderCode')"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
<el-input v-model="queryParams.code" :placeholder="t('ErpStock.Pallet.placeholderCode')" clearable
@keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<el-form-item :label="t('ErpStock.Pallet.palletType')" prop="palletType">
<el-select
v-model="queryParams.palletType"
:placeholder="t('ErpStock.Pallet.placeholderPalletType')"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.STORAGE_PALLET_TYPES)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
<el-select v-model="queryParams.palletType" :placeholder="t('ErpStock.Pallet.placeholderPalletType')" clearable
class="!w-240px">
<el-option v-for="dict in getIntDictOptions(DICT_TYPE.STORAGE_PALLET_TYPES)" :key="dict.value"
:label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item :label="t('ErpStock.Pallet.status')" prop="status">
<el-select
v-model="queryParams.status"
:placeholder="t('ErpStock.Pallet.placeholderStatus')"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.STORAGE_PALLET_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
<el-select v-model="queryParams.status" :placeholder="t('ErpStock.Pallet.placeholderStatus')" clearable
class="!w-240px">
<el-option v-for="dict in getIntDictOptions(DICT_TYPE.STORAGE_PALLET_STATUS)" :key="dict.value"
:label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item :label="t('ErpStock.Pallet.warehouseId')" prop="warehouseId" v-show="showAllFilters">
<el-select
v-model="queryParams.warehouseId"
:placeholder="t('ErpStock.Pallet.placeholderWarehouseId')"
clearable
class="!w-240px"
@change="handleWarehouseChange"
>
<el-option
v-for="item in warehouseList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
<el-select v-model="queryParams.warehouseId" :placeholder="t('ErpStock.Pallet.placeholderWarehouseId')"
clearable class="!w-240px" @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="t('ErpStock.Pallet.areaId')" prop="areaId" v-show="showAllFilters">
<el-select
v-model="queryParams.areaId"
:placeholder="t('ErpStock.Pallet.placeholderAreaId')"
clearable
class="!w-240px"
>
<el-option
v-for="item in filteredAreaList"
:key="item.id"
:label="item.areaName"
:value="item.id"
/>
<el-select v-model="queryParams.areaId" :placeholder="t('ErpStock.Pallet.placeholderAreaId')" clearable
class="!w-240px">
<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="t('ErpStock.Pallet.planCode')" prop="planCode" v-show="showAllFilters">
<el-input
v-model="queryParams.planCode"
:placeholder="t('ErpStock.Pallet.placeholderPlanCode')"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
<el-input v-model="queryParams.planCode" :placeholder="t('ErpStock.Pallet.placeholderPlanCode')" clearable
@keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<el-form-item v-if="filterCount > 3">
<el-button type="text" class="text-primary" @click="toggleFilters">
@ -94,14 +43,13 @@
</el-button>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> {{ t('common.query') }}</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> {{ t('common.reset') }}</el-button>
<el-button
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['erp:pallet:create']"
>
<el-button @click="handleQuery">
<Icon icon="ep:search" class="mr-5px" /> {{ t('common.query') }}
</el-button>
<el-button @click="resetQuery">
<Icon icon="ep:refresh" class="mr-5px" /> {{ t('common.reset') }}
</el-button>
<el-button type="primary" plain @click="openForm('create')" v-hasPermi="['erp:pallet:create']">
<Icon icon="ep:plus" class="mr-5px" /> {{ t('action.add') }}
</el-button>
</el-form-item>
@ -109,24 +57,15 @@
</ContentWrap>
<ContentWrap>
<el-table
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
row-key="id"
>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" row-key="id">
<el-table-column :label="t('ErpStock.Pallet.code')" align="center" prop="code" min-width="150" sortable />
<el-table-column :label="t('ErpStock.Pallet.palletType')" align="center" prop="palletType" min-width="100">
<template #default="scope">
<dict-tag :type="DICT_TYPE.STORAGE_PALLET_TYPES" :value="scope.row.palletType" />
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Pallet.specification')" align="center" prop="specification" min-width="140">
<template #default="scope">
<dict-tag :type="DICT_TYPE.STORAGE_PALLET_SPECIFICATIONS" :value="scope.row.specification" />
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Pallet.specification')" align="center" prop="specification"
min-width="140" />
<el-table-column :label="t('ErpStock.Pallet.ratedLoadWeight')" align="center" min-width="120">
<template #default="scope">
{{ formatWeight(scope.row) }}
@ -150,52 +89,25 @@
<el-table-column :label="t('ErpStock.Pallet.planCode')" align="center" prop="planCode" min-width="160" />
<el-table-column :label="t('ErpStock.Pallet.productId')" align="center" prop="productId" min-width="100" />
<el-table-column :label="t('ErpStock.Pallet.productCount')" align="center" prop="productCount" min-width="100" />
<el-table-column :label="t('ErpStock.Pallet.qrcode')" align="center" prop="qrcode" min-width="120">
<template #default="scope">
<el-link v-if="scope.row.qrcode" :href="scope.row.qrcode" target="_blank" type="primary">
{{ t('ErpStock.Pallet.viewQrcode') }}
</el-link>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Pallet.purchaseDate')" align="center" prop="purchaseDate" min-width="120" />
<el-table-column :label="t('ErpStock.Pallet.useDate')" align="center" prop="useDate" min-width="120" />
<el-table-column :label="t('ErpStock.Pallet.remark')" align="center" prop="remark" min-width="160" />
<el-table-column
:label="t('ErpStock.Pallet.createTime')"
align="center"
prop="createTime"
:formatter="dateFormatter"
width="180px"
sortable
/>
<el-table-column :label="t('ErpStock.Pallet.createTime')" align="center" prop="createTime"
:formatter="dateFormatter" width="180px" sortable />
<el-table-column :label="t('common.operate')" align="center" width="150px">
<template #default="scope">
<el-button
link
type="primary"
@click="openForm('update', scope.row)"
v-hasPermi="['erp:pallet:update']"
>
<el-button link type="primary" @click="openForm('update', scope.row)" v-hasPermi="['erp:pallet:update']">
{{ t('action.edit') }}
</el-button>
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['erp:pallet:delete']"
>
<el-button link type="danger" @click="handleDelete(scope.row.id)" v-hasPermi="['erp:pallet:delete']">
{{ t('action.del') }}
</el-button>
</template>
</el-table-column>
</el-table>
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
@pagination="getList" />
</ContentWrap>
<PalletForm ref="formRef" @success="getList" />
@ -300,7 +212,7 @@ const handleDelete = async (id: number) => {
await PalletApi.deletePallet(id)
message.success(t('common.delSuccess'))
await getList()
} catch {}
} catch { }
}
onMounted(() => {

Loading…
Cancel
Save