feat:入库单据/出库单据调整

main
黄伟杰 7 days ago
parent 490353b811
commit a1ed91963d

@ -30,8 +30,8 @@ export const PalletApi = {
return await request.post({ url: `/erp/pallet/create`, data })
},
updatePallet: async (params: PalletVO) => {
return await request.put({ url: `/erp/pallet/update`, params })
updatePallet: async (data: PalletVO) => {
return await request.put({ url: `/erp/pallet/update`, data })
},
deletePallet: async (id: number) => {

@ -575,6 +575,9 @@
availablePallets: 'Available Pallets',
selectedPallets: 'Selected Pallets',
packageCount: 'Package Count',
outPackageCount: 'Outbound Package Count',
outCount: 'Outbound Count',
packageCountWithItems: 'Package Count ({count} per package)',
itemCount: 'Item Count',
productInfo: 'Product Info',
productName: 'Product Name',

@ -575,6 +575,9 @@
availablePallets: '可选托盘',
selectedPallets: '已选托盘',
packageCount: '包数',
outPackageCount: '出库包数',
outCount: '出库个数',
packageCountWithItems: '包数(每包{count}个)',
itemCount: '个数',
productInfo: '产品信息',
productName: '产品名称',

@ -1,22 +1,25 @@
<template>
<el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="0px"
:inline-message="true" :disabled="disabled">
:inline-message="true" :disabled="false">
<el-table :data="formData" size="small" class="-mt-10px">
<el-table-column :label="t('common.index')" type="index" align="center" width="60" />
<el-table-column :label="t('ErpStock.Item.warehouse')" min-width="125">
<el-table-column v-if="!isProductStockIn" :label="t('ErpStock.Item.warehouse')" min-width="125">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.warehouseId`" :rules="formRules.warehouseId" class="mb-0px!">
<el-select v-model="row.warehouseId" clearable filterable
<el-input v-if="disabled" :model-value="getWarehouseName(row.warehouseId)" readonly />
<el-select v-else v-model="row.warehouseId" clearable filterable
:placeholder="t('ErpStock.Item.placeholderWarehouse')" @change="onChangeWarehouse($event, row)">
<el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column v-if="isProductMaterialStockIn" :label="t('ErpStock.Item.area')" min-width="140">
<el-table-column v-if="isProductMaterialStockIn && !isProductStockIn" :label="t('ErpStock.Item.area')" min-width="140">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.areaId`" :rules="formRules.areaId" class="mb-0px!">
<el-input v-if="disabled" :model-value="getAreaName(row.areaId)" readonly />
<el-select
v-else
v-model="row.areaId"
clearable
filterable
@ -32,7 +35,8 @@
</el-table-column>
<el-table-column v-if="isProductStockIn" :label="t('ErpStock.Item.relatedTask')" min-width="120">
<template #default="{ row }">
<el-select v-model="row.relateTask" :placeholder="t('common.selectText')" @change="handleRelatedTaskChange(row)">
<el-input v-if="disabled" :model-value="formatRelatedTask(row)" readonly />
<el-select v-else v-model="row.relateTask" :placeholder="t('common.selectText')" @change="handleRelatedTaskChange(row)">
<el-option :label="t('common.yes')" :value="true" />
<el-option :label="t('common.no')" :value="false" />
</el-select>
@ -50,17 +54,17 @@
<el-input
:model-value="formatTaskSelection(row)"
readonly
clearable
:clearable="!disabled"
:placeholder="t('ErpStock.Item.placeholderTaskOrder')"
@click="openTaskSelectDialog(row)"
@click="handleTaskInputClick(row)"
@clear="clearTask(row)"
/>
</el-form-item>
</div>
<el-form-item v-else :prop="`${$index}.productId`" :rules="formRules.productId" class="mb-0px!">
<div class="product-code-select">
<el-input v-model="row.productBarCode" readonly clearable
:placeholder="t('ErpStock.Item.placeholderBarcode')" @click="openProductSelectDialog(row)"
<el-input v-model="row.productBarCode" readonly :clearable="!disabled"
:placeholder="t('ErpStock.Item.placeholderBarcode')" @click="handleProductInputClick(row)"
@clear="handleProductClear(row)" />
</div>
</el-form-item>
@ -76,11 +80,11 @@
<el-input :model-value="row.packagingSchemeName || '-'" readonly />
</template>
</el-table-column>
<el-table-column v-if="isProductStockIn" :label="t('ErpStock.PackagingScheme.palletPackageQuantity')" min-width="120">
<!-- <el-table-column v-if="isProductStockIn" :label="t('ErpStock.PackagingScheme.palletPackageQuantity')" min-width="120">
<template #default="{ row }">
<el-input :model-value="row.palletPackageQuantity ?? '-'" readonly />
</template>
</el-table-column>
</el-table-column> -->
<el-table-column v-if="isProductStockIn" :label="t('ErpStock.Item.packageItemCount')" min-width="120">
<template #default="{ row }">
<el-input :model-value="row.packageQuantity ?? '-'" readonly />
@ -92,7 +96,7 @@
<el-input
v-model="row.palletCode"
readonly
clearable
:clearable="!disabled"
:placeholder="t('ErpStock.Item.placeholderPalletCode')"
@click="openPalletSelectDialog(row)"
@clear="clearPallet(row)"
@ -103,25 +107,26 @@
<el-table-column v-if="isPurchaseUnitStockIn" :label="t('ErpStock.Item.purchaseUnit')" min-width="100">
<template #default="{ row }">
<el-form-item class="mb-0px!">
<el-input disabled v-model="row.purchaseUnitName" />
<el-input readonly v-model="row.purchaseUnitName" />
</el-form-item>
</template>
</el-table-column>
<el-table-column v-if="isPurchaseUnitStockIn" :label="t('ErpStock.Item.defaultSupplier')" min-width="130">
<template #default="{ row }">
<el-form-item class="mb-0px!">
<el-input disabled v-model="row.supplierName" />
<el-input readonly v-model="row.supplierName" />
</el-form-item>
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Item.count')" prop="count" min-width="140">
<el-table-column v-if="!isProductStockIn" :label="t('ErpStock.Item.count')" prop="count" min-width="140">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.count`" :rules="formRules.count" class="mb-0px!">
<el-input v-if="isProductStockIn" :model-value="row.count ?? '-'" readonly />
<el-input v-if="disabled || isProductStockIn" :model-value="row.count ?? '-'" readonly />
<el-input-number v-else v-model="row.count" controls-position="right" :min="0.001" :precision="3" class="!w-100%" />
</el-form-item>
</template>
</el-table-column>
<!-- <el-table-column :label="t('ErpStock.Item.price')" fixed="right" min-width="120">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.productPrice`" class="mb-0px!">
@ -145,11 +150,11 @@
<el-table-column :label="t('ErpStock.Item.remark')" fixed="right" min-width="150">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.remark`" class="mb-0px!">
<el-input v-model="row.remark" :placeholder="t('ErpStock.In.placeholderRemark')" />
<el-input v-model="row.remark" :readonly="disabled" :placeholder="t('ErpStock.In.placeholderRemark')" />
</el-form-item>
</template>
</el-table-column>
<el-table-column align="center" fixed="right" :label="t('ErpStock.Item.action')" width="60">
<el-table-column v-if="!disabled" align="center" fixed="right" :label="t('ErpStock.Item.action')" width="60">
<template #default="{ $index }">
<el-button type="danger" @click="handleDelete($index)" link>
<Icon icon="ep:delete" />
@ -297,111 +302,164 @@
</template>
</Dialog>
<Dialog :title="t('ErpStock.Item.selectPalletCode')" v-model="palletDialogVisible" width="1280px">
<el-form :model="palletQueryParams" :inline="true" class="-mb-15px">
<el-form-item :label="t('ErpStock.Pallet.code')">
<el-input
v-model="palletQueryParams.code"
clearable
:placeholder="t('ErpStock.Pallet.placeholderCode')"
@keyup.enter="handlePalletDialogQuery"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.Pallet.status')">
<el-select v-model="palletQueryParams.status" clearable :placeholder="t('ErpStock.Pallet.placeholderStatus')" class="!w-180px">
<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>
<el-button type="primary" @click="handlePalletDialogQuery">
<Icon icon="ep:search" class="mr-5px" /> {{ t('common.query') }}
</el-button>
</el-form-item>
</el-form>
<div class="pallet-transfer">
<div class="pallet-transfer__panel">
<div class="pallet-transfer__title">{{ t('ErpStock.Item.availablePallets') }}</div>
<el-table
ref="availablePalletTableRef"
v-loading="palletDialogLoading"
:data="availablePalletList"
row-key="id"
height="340"
:stripe="true"
:show-overflow-tooltip="true"
@selection-change="handleAvailablePalletSelectionChange"
@row-click="toggleAvailablePallet"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column :label="t('ErpStock.Pallet.code')" prop="code" min-width="150" />
<el-table-column :label="t('ErpStock.Pallet.palletType')" prop="palletType" min-width="100">
<template #default="{ row }">
<dict-tag :type="DICT_TYPE.STORAGE_PALLET_TYPES" :value="row.palletType" />
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Pallet.status')" prop="status" min-width="100">
<template #default="{ row }">
<dict-tag :type="DICT_TYPE.STORAGE_PALLET_STATUS" :value="row.status" />
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Pallet.planCode')" prop="planCode" min-width="150" />
</el-table>
<div class="product-dialog-pagination">
<Pagination
:total="palletDialogTotal"
v-model:page="palletQueryParams.pageNo"
v-model:limit="palletQueryParams.pageSize"
@pagination="getPalletDialogList"
<Dialog :title="t('ErpStock.Item.selectPalletCode')" v-model="palletDialogVisible" :width="disabled ? '900px' : '1800px'">
<component :is="palletDialogGuardTag" v-bind="disabled ? formEnabledAttrs : {}">
<el-form v-if="!disabled" :model="palletQueryParams" :inline="true" class="-mb-15px">
<el-form-item :label="t('ErpStock.Pallet.code')">
<el-input
v-model="palletQueryParams.code"
clearable
:placeholder="t('ErpStock.Pallet.placeholderCode')"
@keyup.enter="handlePalletDialogQuery"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.Pallet.status')">
<el-select v-model="palletQueryParams.status" clearable :placeholder="t('ErpStock.Pallet.placeholderStatus')" class="!w-180px">
<el-option v-for="dict in palletStatusOptions" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handlePalletDialogQuery">
<Icon icon="ep:search" class="mr-5px" /> {{ t('common.query') }}
</el-button>
<el-button type="primary" plain @click="openPalletCreateForm">
<Icon icon="ep:plus" class="mr-5px" /> {{ t('action.add') }}
</el-button>
</el-form-item>
</el-form>
<div class="pallet-transfer" :class="{ 'pallet-transfer--readonly': disabled }">
<div v-if="!disabled" class="pallet-transfer__panel">
<div class="pallet-transfer__title">{{ t('ErpStock.Item.availablePallets') }}</div>
<el-table
ref="availablePalletTableRef"
v-loading="palletDialogLoading"
:data="availablePalletList"
row-key="id"
height="340"
:stripe="true"
:show-overflow-tooltip="true"
@selection-change="handleAvailablePalletSelectionChange"
@row-click="toggleAvailablePallet"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column :label="t('ErpStock.Pallet.code')" prop="code" min-width="120" />
<el-table-column :label="t('ErpStock.Pallet.palletType')" prop="palletType" min-width="80">
<template #default="{ row }">
<dict-tag :type="DICT_TYPE.STORAGE_PALLET_TYPES" :value="row.palletType" />
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Pallet.status')" prop="status" min-width="80">
<template #default="{ row }">
<dict-tag :type="DICT_TYPE.STORAGE_PALLET_STATUS" :value="row.status" />
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Item.warehouse')" min-width="130">
<template #default="{ row }">
{{ getWarehouseName(row.warehouseId) }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Item.productName')" min-width="130" prop="productName"/>
<el-table-column :label="t('ErpStock.Item.area')" min-width="130">
<template #default="{ row }">
{{ getAreaName(row.areaId) }}
</template>
</el-table-column>
</el-table>
<div class="product-dialog-pagination">
<Pagination
:total="palletDialogTotal"
v-model:page="palletQueryParams.pageNo"
v-model:limit="palletQueryParams.pageSize"
@pagination="getPalletDialogList"
/>
</div>
</div>
<div v-if="!disabled" class="pallet-transfer__actions">
<el-button type="primary" :disabled="availablePalletSelection.length === 0" @click="addSelectedPallets">
<Icon icon="ep:arrow-right" />
</el-button>
<el-button :disabled="rightPalletSelection.length === 0" @click="removeSelectedPallets">
<Icon icon="ep:arrow-left" />
</el-button>
</div>
<div class="pallet-transfer__panel">
<div class="pallet-transfer__title">{{ t('ErpStock.Item.selectedPallets') }}</div>
<el-table
ref="rightPalletTableRef"
:data="selectedPalletRows"
row-key="id"
height="340"
:stripe="true"
:show-overflow-tooltip="true"
@selection-change="handleRightPalletSelectionChange"
@row-click="handleRightPalletRowClick"
>
<el-table-column v-if="!disabled" type="selection" width="55" align="center" />
<el-table-column :label="t('ErpStock.Pallet.code')" prop="code" min-width="150" />
<el-table-column :label="t('ErpStock.Item.warehouse')" min-width="160">
<template #default="{ row }">
<el-input v-if="disabled" :model-value="getWarehouseName(row.warehouseId)" readonly />
<el-select
v-else
v-model="row.warehouseId"
clearable
filterable
:placeholder="t('ErpStock.Item.placeholderWarehouse')"
@change="handleSelectedPalletWarehouseChange($event, row)"
@click.stop
>
<el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Item.area')" min-width="160">
<template #default="{ row }">
<el-input v-if="disabled" :model-value="getAreaName(row.areaId)" readonly />
<el-select
v-else
v-model="row.areaId"
clearable
filterable
:placeholder="t('ErpStock.Item.placeholderArea')"
:disabled="!row.warehouseId"
@click.stop
>
<el-option v-for="item in getAreaOptions(row.warehouseId)" :key="item.id" :label="getAreaLabel(item)" :value="item.id" />
</el-select>
</template>
</el-table-column>
<el-table-column :label="selectedPalletPackageCountLabel" min-width="160">
<template #default="{ row }">
<el-input v-if="disabled" :model-value="row.packageCount ?? '-'" readonly />
<el-input-number
v-else
v-model="row.packageCount"
controls-position="right"
:min="0"
:precision="3"
class="!w-100%"
@click.stop
/>
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Item.itemCount')" min-width="130">
<template #default="{ row }">
<el-input :model-value="getSelectedPalletItemCount(row)" readonly />
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="pallet-transfer__actions">
<el-button type="primary" :disabled="availablePalletSelection.length === 0" @click="addSelectedPallets">
<Icon icon="ep:arrow-right" />
</el-button>
<el-button :disabled="rightPalletSelection.length === 0" @click="removeSelectedPallets">
<Icon icon="ep:arrow-left" />
</el-button>
</div>
<div class="pallet-transfer__panel">
<div class="pallet-transfer__title">{{ t('ErpStock.Item.selectedPallets') }}</div>
<el-table
ref="rightPalletTableRef"
:data="selectedPalletRows"
row-key="id"
height="340"
:stripe="true"
:show-overflow-tooltip="true"
@selection-change="handleRightPalletSelectionChange"
@row-click="toggleRightPallet"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column :label="t('ErpStock.Pallet.code')" prop="code" min-width="150" />
<el-table-column :label="t('ErpStock.Item.packageCount')" min-width="130">
<template #default="{ row }">
<el-input-number
v-model="row.packageCount"
controls-position="right"
:min="0"
:precision="3"
class="!w-100%"
@click.stop
/>
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Item.itemCount')" min-width="130">
<template #default="{ row }">
<el-input :model-value="getSelectedPalletItemCount(row)" readonly />
</template>
</el-table-column>
</el-table>
</div>
</div>
</component>
<template #footer>
<el-button type="primary" @click="confirmPalletSelect">{{ t('common.ok') }}</el-button>
<el-button @click="palletDialogVisible = false">{{ t('common.cancel') }}</el-button>
<component :is="palletDialogGuardTag" v-bind="disabled ? formEnabledAttrs : {}">
<el-button v-if="!disabled" type="primary" @click="confirmPalletSelect">{{ t('common.ok') }}</el-button>
<el-button @click="palletDialogVisible = false">{{ t('common.cancel') }}</el-button>
</component>
</template>
</Dialog>
<PalletForm ref="palletFormRef" @success="handlePalletCreateSuccess" />
</template>
<script setup lang="ts">
import { Icon } from '@/components/Icon'
@ -411,6 +469,7 @@ import { WarehouseAreaApi, WarehouseAreaVO } from '@/api/erp/stock/warehousearea
import { StockApi } from '@/api/erp/stock/stock'
import { TaskApi, TaskVO } from '@/api/mes/task'
import { PalletApi, PalletVO } from '@/api/erp/stock/pallet'
import PalletForm from '../../pallet/PalletForm.vue'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { dateFormatter2 } from '@/utils/formatTime'
import { erpPriceMultiply } from '@/utils'
@ -486,17 +545,29 @@ const palletQueryParams = reactive({
pageNo: 1,
pageSize: 10,
code: undefined,
status: undefined
status: undefined,
productId: undefined,
excludeStatus: 3
})
const availablePalletSelection = ref<PalletVO[]>([])
const rightPalletSelection = ref<any[]>([])
const selectedPalletRows = ref<any[]>([])
const availablePalletTableRef = ref()
const rightPalletTableRef = ref()
const palletFormRef = ref()
const palletStatusOptions = computed(() =>
getIntDictOptions(DICT_TYPE.STORAGE_PALLET_STATUS).filter((dict) => Number(dict.value) !== 3)
)
const availablePalletList = computed(() => {
const selectedIds = new Set(selectedPalletRows.value.map((item) => item.id))
return palletDialogList.value.filter((item) => !selectedIds.has(item.id))
})
const selectedPalletPackageCountLabel = computed(() => {
const packageQuantity = currentSelectRow.value?.packageQuantity ?? '-'
return t('ErpStock.Item.packageCountWithItems', { count: packageQuantity })
})
const formEnabledAttrs = { disabled: false, labelWidth: '0px' }
const palletDialogGuardTag = computed(() => (props.disabled ? 'el-form' : 'div'))
function validatePallets(_: any, value: any[], callback: (error?: Error) => void) {
if (!Array.isArray(value) || value.length === 0) {
@ -642,6 +713,10 @@ const isRowRelatedTask = (row: any) => {
return row?.relatedTask === true || row?.relatedTask === 1 || row?.relatedTask === '1'
}
const formatRelatedTask = (row: any) => {
return isRowRelatedTask(row) ? t('common.yes') : t('common.no')
}
const handleRelatedTaskChange = (row: any) => {
row.relatedTask = undefined
if (isRowRelatedTask(row)) {
@ -742,10 +817,16 @@ const clearProduct = (row: any) => {
}
const handleProductClear = (row: any) => {
if (props.disabled) return
clearProduct(row)
setStockCount(row)
}
const handleProductInputClick = (row: any) => {
if (props.disabled) return
openProductSelectDialog(row)
}
const openProductSelectDialog = async (row: any) => {
if (!activeCategoryType.value) return
currentSelectRow.value = row
@ -780,6 +861,7 @@ const handleProductDialogRowClick = (row: any) => {
}
const confirmProductSelect = async () => {
if (props.disabled) return
const product = productDialogList.value.find((item) => item.id === selectedProductId.value)
if (!product || !currentSelectRow.value) return
let finalProduct = product
@ -807,6 +889,11 @@ const openTaskSelectDialog = async (row: any) => {
}
}
const handleTaskInputClick = (row: any) => {
if (props.disabled) return
openTaskSelectDialog(row)
}
const getTaskDialogList = async () => {
taskDialogLoading.value = true
try {
@ -834,6 +921,7 @@ const handleTaskDialogRowClick = async (row: TaskVO) => {
}
const confirmTaskSelect = async () => {
if (props.disabled) return
const task = taskDialogList.value.find((item) => item.id === selectedTaskId.value)
|| ({ id: selectedTaskData.value?.taskId, code: selectedTaskData.value?.taskName } as TaskVO)
const product = taskProductDialogList.value.find((item) => item.productId === selectedTaskProductId.value)
@ -929,6 +1017,7 @@ const clearTaskProduct = (row: any) => {
}
const clearTask = (row: any) => {
if (props.disabled) return
row.taskId = undefined
row.taskCode = undefined
row.taskName = undefined
@ -939,12 +1028,15 @@ const clearTask = (row: any) => {
const openPalletSelectDialog = async (row: any) => {
currentSelectRow.value = row
selectedPalletRows.value = getInitialSelectedPalletRows(row)
await loadRowsWarehouseAreas(selectedPalletRows.value)
availablePalletSelection.value = []
rightPalletSelection.value = []
palletQueryParams.pageNo = 1
palletQueryParams.code = undefined
palletQueryParams.status = undefined
palletQueryParams.productId = row.productId
palletDialogVisible.value = true
if (props.disabled) return
await getPalletDialogList()
}
@ -954,6 +1046,7 @@ const getPalletDialogList = async () => {
const data = await PalletApi.getPalletPage(palletQueryParams)
palletDialogList.value = data?.list || []
palletDialogTotal.value = data?.total || 0
await loadRowsWarehouseAreas(palletDialogList.value)
availablePalletSelection.value = []
availablePalletTableRef.value?.clearSelection()
} finally {
@ -966,6 +1059,20 @@ const handlePalletDialogQuery = () => {
getPalletDialogList()
}
const openPalletCreateForm = () => {
if (props.disabled) return
const row = currentSelectRow.value
palletFormRef.value?.open('create', undefined, {
productId: row?.productId,
productCount: row?.palletPackageQuantity
})
}
const handlePalletCreateSuccess = async () => {
palletQueryParams.pageNo = 1
await getPalletDialogList()
}
const handleAvailablePalletSelectionChange = (rows: PalletVO[]) => {
availablePalletSelection.value = rows
}
@ -975,14 +1082,30 @@ const handleRightPalletSelectionChange = (rows: any[]) => {
}
const toggleAvailablePallet = (row: PalletVO) => {
if (props.disabled) return
availablePalletTableRef.value?.toggleRowSelection(row)
}
const toggleRightPallet = (row: any) => {
if (props.disabled) return
rightPalletTableRef.value?.toggleRowSelection(row)
}
const handleRightPalletRowClick = (row: any) => {
if (props.disabled) return
toggleRightPallet(row)
}
const handleSelectedPalletWarehouseChange = (warehouseId: number, row: any) => {
if (props.disabled) return
row.areaId = undefined
if (warehouseId) {
loadWarehouseAreas(warehouseId)
}
}
const addSelectedPallets = () => {
if (props.disabled) return
const row = currentSelectRow.value
const selectedIds = new Set(selectedPalletRows.value.map((item) => item.id))
const nextRows = availablePalletSelection.value
@ -997,6 +1120,7 @@ const addSelectedPallets = () => {
}
const removeSelectedPallets = () => {
if (props.disabled) return
const removeIds = new Set(rightPalletSelection.value.map((item) => item.id))
selectedPalletRows.value = selectedPalletRows.value.filter((item) => !removeIds.has(item.id))
rightPalletSelection.value = []
@ -1004,11 +1128,15 @@ const removeSelectedPallets = () => {
}
const confirmPalletSelect = () => {
if (props.disabled) return
if (!currentSelectRow.value) return
const row = currentSelectRow.value
row.pallets = selectedPalletRows.value.map((pallet) => ({
palletId: pallet.id,
packageCount: pallet.packageCount
packageCount: pallet.packageCount,
warehouseId: pallet.warehouseId,
areaId: pallet.areaId,
count: getSelectedPalletItemCountValue(pallet)
}))
row.palletCode = selectedPalletRows.value.map((pallet) => pallet.code).filter(Boolean).join(', ')
syncCountByPallets(row)
@ -1016,6 +1144,7 @@ const confirmPalletSelect = () => {
}
const clearPallet = (row: any) => {
if (props.disabled) return
row.pallets = []
row.palletCode = undefined
if (isProductStockIn.value) {
@ -1028,7 +1157,10 @@ const getInitialSelectedPalletRows = (row: any) => {
return (row?.pallets || []).map((item: any, index: number) => ({
id: item.palletId,
code: item.palletCode || palletCodes[index] || String(item.palletId),
packageCount: item.packageCount
packageCount: item.packageCount,
warehouseId: item.warehouseId,
areaId: item.areaId,
count: item.count
}))
}
@ -1036,13 +1168,17 @@ const getPalletPackageCount = (row: any, pallet: PalletVO) => {
return pallet.productCount ?? row?.palletPackageQuantity ?? row?.packageQuantity ?? row?.count
}
const getSelectedPalletItemCount = (pallet: any) => {
const getSelectedPalletItemCountValue = (pallet: any) => {
const packageQuantity = Number(currentSelectRow.value?.packageQuantity)
const packageCount = Number(pallet?.packageCount)
if (!Number.isFinite(packageQuantity) || !Number.isFinite(packageCount)) return '-'
if (!Number.isFinite(packageQuantity) || !Number.isFinite(packageCount)) return undefined
return packageQuantity * packageCount
}
const getSelectedPalletItemCount = (pallet: any) => {
return getSelectedPalletItemCountValue(pallet) ?? '-'
}
const syncCountByPallets = (row: any) => {
const packageQuantity = Number(row?.packageQuantity)
if (!Array.isArray(row?.pallets) || !Number.isFinite(packageQuantity)) {
@ -1107,6 +1243,15 @@ const getAreaLabel = (item: WarehouseAreaVO) => {
return item.areaCode ? `${item.areaCode} - ${item.areaName}` : item.areaName
}
const getWarehouseName = (warehouseId: number | string | undefined) => {
return warehouseList.value.find((item) => String(item.id) === String(warehouseId))?.name ?? warehouseId ?? '-'
}
const getAreaName = (areaId: number | string | undefined) => {
const areaList = Object.values(warehouseAreaMap.value).flat()
return areaList.find((item) => String(item.id) === String(areaId))?.areaName ?? areaId ?? '-'
}
const fillProductNames = (rows: any[]) => {
if (!productList.value.length) return
rows.forEach((row) => {
@ -1199,11 +1344,15 @@ onMounted(async () => {
.pallet-transfer {
display: grid;
grid-template-columns: minmax(520px, 1fr) 72px minmax(420px, 0.85fr);
grid-template-columns: minmax(420px, 1fr) 72px minmax(420px, 1fr);
gap: 18px;
align-items: center;
}
.pallet-transfer--readonly {
grid-template-columns: 1fr;
}
.pallet-transfer__panel {
min-width: 0;
}

@ -1,33 +1,26 @@
<template>
<el-form
ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="0px"
:inline-message="true" :disabled="disabled">
<el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="0px"
:inline-message="true" :disabled="false">
<el-table :data="formData" size="small" show-summary :summary-method="getSummaries" class="-mt-10px">
<el-table-column :label="t('common.index')" type="index" align="center" width="60" />
<el-table-column :label="t('ErpStock.Item.warehouse')" min-width="125">
<el-table-column v-if="!isProductStockOut" :label="t('ErpStock.Item.warehouse')" min-width="125">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.warehouseId`" :rules="formRules.warehouseId" class="mb-0px!">
<el-select
v-model="row.warehouseId" clearable filterable
<el-input v-if="disabled" :model-value="getWarehouseName(row.warehouseId)" readonly />
<el-select v-else v-model="row.warehouseId" clearable filterable
:placeholder="t('ErpStock.Item.placeholderWarehouse')" @change="onChangeWarehouse($event, row)">
<el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column v-if="isProductMaterialStockOut" :label="t('ErpStock.Item.area')" min-width="140">
<el-table-column v-if="isProductMaterialStockOut && !isProductStockOut" :label="t('ErpStock.Item.area')" min-width="140">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.areaId`" :rules="formRules.areaId" class="mb-0px!">
<el-select
v-model="row.areaId"
clearable
filterable
:placeholder="t('ErpStock.Item.placeholderArea')"
:disabled="!row.warehouseId"
@change="handleAreaChange(row)"
>
<el-option
v-for="item in getAreaOptions(row.warehouseId)" :key="item.id" :label="getAreaLabel(item)"
<el-input v-if="disabled" :model-value="getAreaName(row.areaId)" readonly />
<el-select v-else v-model="row.areaId" clearable filterable :placeholder="t('ErpStock.Item.placeholderArea')"
:disabled="!row.warehouseId" @change="handleAreaChange(row)">
<el-option v-for="item in getAreaOptions(row.warehouseId)" :key="item.id" :label="getAreaLabel(item)"
:value="item.id" />
</el-select>
</el-form-item>
@ -42,9 +35,8 @@ v-for="item in getAreaOptions(row.warehouseId)" :key="item.id" :label="getAreaLa
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.productBarCode`" class="mb-0px!">
<div class="product-code-select">
<el-input
v-model="row.productBarCode" readonly clearable
:placeholder="t('ErpStock.Item.placeholderBarcode')" @click="openProductSelectDialog(row)"
<el-input v-model="row.productBarCode" readonly :clearable="!disabled"
:placeholder="t('ErpStock.Item.placeholderBarcode')" @click="handleProductInputClick(row)"
@clear="handleProductClear(row)" />
</div>
</el-form-item>
@ -52,20 +44,20 @@ v-model="row.productBarCode" readonly clearable
</el-table-column>
<el-table-column :label="t('ErpStock.Item.product')" min-width="180">
<template #default="{ row, $index }">
<el-form-item
v-if="isProductMaterialStockOut" :prop="`${$index}.productId`" :rules="formRules.productId"
<el-form-item v-if="isProductMaterialStockOut" :prop="`${$index}.productId`" :rules="formRules.productId"
class="mb-0px!">
<el-input v-model="row.productName" disabled :placeholder="t('ErpStock.Item.placeholderProduct')" />
</el-form-item>
<el-form-item v-else :prop="`${$index}.productId`" :rules="formRules.productId" class="mb-0px!">
<el-cascader
v-model="row.productId" :options="productCascaderOptions" :props="productCascaderProps"
<el-input v-if="disabled" :model-value="row.productName || '-'" readonly />
<el-cascader v-model="row.productId" :options="productCascaderOptions" :props="productCascaderProps"
v-else
:show-all-levels="false" clearable filterable @change="onChangeProduct($event, row)"
:placeholder="t('ErpStock.Item.placeholderProduct')" class="!w-100%" />
</el-form-item>
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Item.stock')" min-width="100">
<el-table-column v-if="!isProductStockOut" :label="t('ErpStock.Item.stock')" min-width="100">
<template #default="{ row }">
<el-form-item class="mb-0px!">
<el-input disabled v-model="row.stockCount" :formatter="erpCountInputFormatter" />
@ -106,7 +98,8 @@ v-model="row.productId" :options="productCascaderOptions" :props="productCascade
<template #content>
{{ purchaseUnitConvertTipText }}
</template>
<Icon icon="ep:question-filled" class="ml-4px" style="vertical-align: middle; color: #909399; cursor: pointer;" />
<Icon icon="ep:question-filled" class="ml-4px"
style="vertical-align: middle; color: #909399; cursor: pointer;" />
</el-tooltip>
</template>
<template #default="{ row }">
@ -118,18 +111,11 @@ v-model="row.productId" :options="productCascaderOptions" :props="productCascade
<el-table-column v-if="isSparePartStockOut" :label="t('ErpStock.Item.outboundPurpose')" min-width="140">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.outUsageType`" :rules="formRules.outUsageType" class="mb-0px!">
<el-select
v-model="row.outUsageType"
clearable
:placeholder="t('ErpStock.Item.placeholderOutboundPurpose')"
@change="handleOutboundPurposeChange(row)"
>
<el-option
v-for="dict in outboundPurposeOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
<el-input v-if="disabled" :model-value="getOutboundPurposeLabel(row.outUsageType)" readonly />
<el-select v-else v-model="row.outUsageType" clearable :placeholder="t('ErpStock.Item.placeholderOutboundPurpose')"
@change="handleOutboundPurposeChange(row)">
<el-option v-for="dict in outboundPurposeOptions" :key="dict.value" :label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
</template>
@ -137,7 +123,8 @@ v-model="row.productId" :options="productCascaderOptions" :props="productCascade
<el-table-column v-if="isProductStockOut" :label="t('ErpStock.Item.outMode')" width="200">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.outMode`" :rules="formRules.outMode" class="mb-0px!">
<el-radio-group v-model="row.outMode" class="out-mode-radio-group" @change="handleOutModeChange(row)">
<el-input v-if="disabled" :model-value="getOutModeLabel(row.outMode)" readonly />
<el-radio-group v-else v-model="row.outMode" class="out-mode-radio-group" @change="handleOutModeChange(row)">
<el-radio-button :label="1">{{ t('ErpStock.Item.outModeWholePallet') }}</el-radio-button>
<el-radio-button :label="2">{{ t('ErpStock.Item.outModeSplitPallet') }}</el-radio-button>
</el-radio-group>
@ -147,34 +134,17 @@ v-model="row.productId" :options="productCascaderOptions" :props="productCascade
<el-table-column v-if="isProductStockOut" :label="t('ErpStock.Item.palletCode')" min-width="180">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.pallets`" :rules="formRules.pallets" class="mb-0px!">
<el-input
v-model="row.palletCode"
readonly
clearable
:placeholder="t('ErpStock.Item.placeholderPalletCode')"
@click="openPalletSelectDialog(row)"
@clear="clearPallet(row)"
/>
<el-input v-model="row.palletCode" readonly :clearable="!disabled"
:placeholder="t('ErpStock.Item.placeholderPalletCode')" @click="openPalletSelectDialog(row)"
@clear="clearPallet(row)" />
</el-form-item>
</template>
</el-table-column>
<el-table-column
v-if="showRelatedRepairColumn"
:label="t('ErpStock.Item.relatedRepairOrder')"
min-width="190"
>
<el-table-column v-if="showRelatedRepairColumn" :label="t('ErpStock.Item.relatedRepairOrder')" min-width="190">
<template #default="{ row, $index }">
<el-form-item
v-if="isRepairPurpose(row.outUsageType)"
:prop="`${$index}.relatedOrderNo`"
class="mb-0px!"
>
<el-input
v-model="row.relatedOrderNo"
readonly
:placeholder="getRelatedOrderPlaceholder(row.outUsageType)"
>
<template #append>
<el-form-item v-if="isRepairPurpose(row.outUsageType)" :prop="`${$index}.relatedOrderNo`" class="mb-0px!">
<el-input v-model="row.relatedOrderNo" readonly :placeholder="getRelatedOrderPlaceholder(row.outUsageType)">
<template v-if="!disabled" #append>
<el-button @click="openRelatedOrderDialog(row)">
<Icon icon="ep:search" />
</el-button>
@ -183,23 +153,14 @@ v-model="row.productId" :options="productCascaderOptions" :props="productCascade
</el-form-item>
</template>
</el-table-column>
<el-table-column
v-if="showRelatedMaintainColumn"
:label="t('ErpStock.Item.relatedMaintainRecord')"
min-width="190"
>
<el-table-column v-if="showRelatedMaintainColumn" :label="t('ErpStock.Item.relatedMaintainRecord')"
min-width="190">
<template #default="{ row, $index }">
<el-form-item
v-if="isMaintainPurpose(row.outUsageType)"
:prop="`${$index}.relatedMaintenanceNo`"
class="mb-0px!"
>
<el-input
v-model="row.relatedMaintenanceNo"
readonly
:placeholder="getRelatedOrderPlaceholder(row.outUsageType)"
>
<template #append>
<el-form-item v-if="isMaintainPurpose(row.outUsageType)" :prop="`${$index}.relatedMaintenanceNo`"
class="mb-0px!">
<el-input v-model="row.relatedMaintenanceNo" readonly
:placeholder="getRelatedOrderPlaceholder(row.outUsageType)">
<template v-if="!disabled" #append>
<el-button @click="openRelatedOrderDialog(row)">
<Icon icon="ep:search" />
</el-button>
@ -208,16 +169,13 @@ v-model="row.productId" :options="productCascaderOptions" :props="productCascade
</el-form-item>
</template>
</el-table-column>
<el-table-column v-if="isProductMaterialStockOut" :label="t('ErpStock.Item.count')" prop="inputCount" min-width="140">
<el-table-column v-if="isProductMaterialStockOut" :label="t('ErpStock.Item.count')" prop="inputCount"
min-width="140">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.inputCount`" :rules="formRules.inputCount" class="mb-0px!">
<el-input v-if="isProductStockOut" :model-value="row.inputCount ?? '-'" disabled />
<el-input-number
v-else
v-model="row.inputCount" controls-position="right" :min="0.001" :precision="3"
class="!w-100%"
@blur="handleInputCountBlur(row)"
/>
<el-input v-if="disabled || isProductStockOut" :model-value="row.pieceCount ?? row.inputCount ?? '-'" readonly />
<el-input-number v-else v-model="row.inputCount" controls-position="right" :min="0.001" :precision="3"
class="!w-100%" @blur="handleInputCountBlur(row)" />
</el-form-item>
</template>
</el-table-column>
@ -244,11 +202,11 @@ v-model="row.inputCount" controls-position="right" :min="0.001" :precision="3"
<el-table-column :label="t('ErpStock.Item.remark')" fixed="right" min-width="150">
<template #default="{ row, $index }">
<el-form-item :prop="`${$index}.remark`" class="mb-0px!">
<el-input v-model="row.remark" :placeholder="t('ErpStock.Out.placeholderRemark')" />
<el-input v-model="row.remark" :readonly="disabled" :placeholder="t('ErpStock.Out.placeholderRemark')" />
</el-form-item>
</template>
</el-table-column>
<el-table-column align="center" fixed="right" :label="t('ErpStock.Item.action')" width="60">
<el-table-column v-if="!disabled" align="center" fixed="right" :label="t('ErpStock.Item.action')" width="60">
<template #default="{ $index }">
<el-button type="danger" @click="handleDelete($index)" link>
<Icon icon="ep:delete" />
@ -264,13 +222,11 @@ v-model="row.inputCount" controls-position="right" :min="0.001" :precision="3"
<Dialog :title="t('ErpStock.Item.selectCode')" v-model="productDialogVisible" width="900px">
<el-form :model="productQueryParams" :inline="true" class="-mb-15px">
<el-form-item :label="t('ErpStock.Item.code')">
<el-input
v-model="productQueryParams.barCode" clearable :placeholder="t('ErpStock.Item.placeholderCode')"
<el-input v-model="productQueryParams.barCode" clearable :placeholder="t('ErpStock.Item.placeholderCode')"
@keyup.enter="handleProductDialogQuery" />
</el-form-item>
<el-form-item :label="t('ErpStock.Item.name')">
<el-input
v-model="productQueryParams.name" clearable :placeholder="t('ErpStock.Item.placeholderName')"
<el-input v-model="productQueryParams.name" clearable :placeholder="t('ErpStock.Item.placeholderName')"
@keyup.enter="handleProductDialogQuery" />
</el-form-item>
<el-form-item>
@ -279,8 +235,7 @@ v-model="productQueryParams.name" clearable :placeholder="t('ErpStock.Item.place
</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="productDialogLoading" :data="productDialogList" row-key="id" :stripe="true"
<el-table v-loading="productDialogLoading" :data="productDialogList" row-key="id" :stripe="true"
:show-overflow-tooltip="true" @row-click="handleProductDialogRowClick">
<el-table-column width="55" align="center">
<template #default="{ row }">
@ -292,17 +247,18 @@ v-loading="productDialogLoading" :data="productDialogList" row-key="id" :stripe=
<el-table-column :label="t('ErpStock.Item.spec')" prop="standard" min-width="120" />
<el-table-column :label="t('ErpStock.Item.category')" prop="subCategoryName" min-width="120" />
<el-table-column :label="t('ErpStock.Item.unit')" prop="unitName" min-width="80" />
<el-table-column v-if="isPurchaseUnitStockOut" :label="t('ErpStock.Item.purchaseUnit')" prop="purchaseUnitName" min-width="100" />
<el-table-column v-if="isPurchaseUnitStockOut" :label="t('ErpStock.Item.purchaseUnit')" prop="purchaseUnitName"
min-width="100" />
<el-table-column v-if="isPurchaseUnitStockOut" :label="t('ErpStock.Item.defaultSupplier')" min-width="130">
<template #default="{ row }">
{{ getDefaultSupplierName(row) || '-' }}
</template>
</el-table-column>
<el-table-column v-if="isPurchaseUnitStockOut" :label="t('ErpStock.Item.purchaseUnitConvertQuantity')" prop="purchaseUnitConvertQuantity" min-width="120" />
<el-table-column v-if="isPurchaseUnitStockOut" :label="t('ErpStock.Item.purchaseUnitConvertQuantity')"
prop="purchaseUnitConvertQuantity" min-width="120" />
</el-table>
<div class="product-dialog-pagination">
<Pagination
:total="productDialogTotal" v-model:page="productQueryParams.pageNo"
<Pagination :total="productDialogTotal" v-model:page="productQueryParams.pageNo"
v-model:limit="productQueryParams.pageSize" @pagination="getProductDialogList" />
</div>
<template #footer>
@ -311,29 +267,16 @@ v-loading="productDialogLoading" :data="productDialogList" row-key="id" :stripe=
</template>
</Dialog>
<Dialog :title="t('ErpStock.Item.selectPalletCode')" v-model="palletDialogVisible" width="980px">
<el-form :model="palletQueryParams" :inline="true" class="-mb-15px">
<Dialog :title="t('ErpStock.Item.selectPalletCode')" v-model="palletDialogVisible" :width="disabled ? '900px' : '1280px'">
<el-form v-if="!disabled" :model="palletQueryParams" :inline="true" class="-mb-15px">
<el-form-item :label="t('ErpStock.Pallet.code')">
<el-input
v-model="palletQueryParams.code"
clearable
:placeholder="t('ErpStock.Pallet.placeholderCode')"
@keyup.enter="handlePalletDialogQuery"
/>
<el-input v-model="palletQueryParams.code" clearable :placeholder="t('ErpStock.Pallet.placeholderCode')"
@keyup.enter="handlePalletDialogQuery" />
</el-form-item>
<el-form-item :label="t('ErpStock.Pallet.status')">
<el-select
v-model="palletQueryParams.status"
clearable
:placeholder="t('ErpStock.Pallet.placeholderStatus')"
class="!w-180px"
>
<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="palletQueryParams.status" clearable :placeholder="t('ErpStock.Pallet.placeholderStatus')"
class="!w-180px">
<el-option v-for="dict in palletStatusOptions" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item>
@ -342,16 +285,32 @@ v-loading="productDialogLoading" :data="productDialogList" row-key="id" :stripe=
</el-button>
</el-form-item>
</el-form>
<el-table
ref="palletTableRef"
v-loading="palletDialogLoading"
:data="palletDialogList"
row-key="id"
:stripe="true"
:show-overflow-tooltip="true"
@row-click="handlePalletDialogRowClick"
@selection-change="handlePalletDialogSelectionChange"
>
<el-table v-if="disabled" :data="selectedPalletRows" row-key="id" :stripe="true" :show-overflow-tooltip="true">
<el-table-column :label="t('ErpStock.Pallet.code')" prop="code" min-width="150" />
<el-table-column :label="t('ErpStock.Item.warehouse')" min-width="130">
<template #default="{ row }">
{{ getWarehouseName(row.warehouseId) }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Item.area')" min-width="130">
<template #default="{ row }">
{{ getAreaName(row.areaId) }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Item.outPackageCount')" min-width="130">
<template #default="{ row }">
<el-input :model-value="row.packageCount ?? '-'" readonly />
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Item.outCount')" min-width="120">
<template #default="{ row }">
<el-input :model-value="getSelectedPalletOutCount(row)" readonly />
</template>
</el-table-column>
</el-table>
<el-table v-else ref="palletTableRef" v-loading="palletDialogLoading" :data="palletDialogList" row-key="id" :stripe="true"
:show-overflow-tooltip="true" @row-click="handlePalletDialogRowClick"
@selection-change="handlePalletDialogSelectionChange">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true" />
<el-table-column :label="t('ErpStock.Pallet.code')" prop="code" min-width="150" />
<el-table-column :label="t('ErpStock.Pallet.palletType')" prop="palletType" min-width="100">
@ -364,54 +323,53 @@ v-loading="productDialogLoading" :data="productDialogList" row-key="id" :stripe=
<dict-tag :type="DICT_TYPE.STORAGE_PALLET_STATUS" :value="row.status" />
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Pallet.planCode')" prop="planCode" min-width="150" />
<el-table-column :label="t('ErpStock.Item.warehouse')" min-width="130">
<template #default="{ row }">
{{ getWarehouseName(row.warehouseId) }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Item.area')" min-width="130">
<template #default="{ row }">
{{ getAreaName(row.areaId) }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.Pallet.productId')" prop="productId" min-width="100" />
<el-table-column :label="t('ErpStock.Item.packageCount')" prop="productCount" min-width="100" />
<el-table-column v-if="currentSelectRow?.outMode === 2" label="出库包数" min-width="130">
<el-table-column :label="t('ErpStock.Item.outCount')" min-width="120">
<template #default="{ row }">
<el-input-number
v-model="row.packageCount"
controls-position="right"
:min="0"
:precision="0"
class="!w-100%"
@change="handlePalletPackageCountChange($event, row)"
@click.stop
/>
<el-input :model-value="getPalletOutCount(row)" disabled />
</template>
</el-table-column>
<el-table-column v-if="currentSelectRow?.outMode === 2" :label="t('ErpStock.Item.outPackageCount')" min-width="130">
<template #default="{ row }">
<el-input-number v-model="row.packageCount" controls-position="right" :min="0" :precision="0" class="!w-100%"
@change="handlePalletPackageCountChange($event, row)" @click.stop />
</template>
</el-table-column>
</el-table>
<div class="product-dialog-pagination">
<Pagination
:total="palletDialogTotal"
v-model:page="palletQueryParams.pageNo"
v-model:limit="palletQueryParams.pageSize"
@pagination="getPalletDialogList"
/>
<div v-if="!disabled" class="product-dialog-pagination">
<Pagination :total="palletDialogTotal" v-model:page="palletQueryParams.pageNo"
v-model:limit="palletQueryParams.pageSize" @pagination="getPalletDialogList" />
</div>
<template #footer>
<el-button type="primary" @click="confirmPalletSelect">{{ t('common.ok') }}</el-button>
<el-button v-if="!disabled" type="primary" @click="confirmPalletSelect">{{ t('common.ok') }}</el-button>
<el-button @click="palletDialogVisible = false">{{ t('common.cancel') }}</el-button>
</template>
</Dialog>
<Dialog :title="relatedOrderDialogTitle" v-model="relatedOrderDialogVisible" width="1100px">
<el-table
v-loading="relatedOrderLoading"
:data="relatedOrderList"
:stripe="true"
:show-overflow-tooltip="true"
row-key="id"
@row-click="handleRelatedOrderRowClick"
>
<el-table v-loading="relatedOrderLoading" :data="relatedOrderList" :stripe="true" :show-overflow-tooltip="true"
row-key="id" @row-click="handleRelatedOrderRowClick">
<el-table-column width="55" align="center">
<template #default="{ row }">
<el-radio v-model="selectedRelatedOrderId" :label="row.id">&nbsp;</el-radio>
</template>
</el-table-column>
<template v-if="relatedOrderType === 'repair'">
<el-table-column :label="t('EquipmentManagement.DvRepair.repairCode')" align="center" prop="repairCode" min-width="180" />
<el-table-column :label="t('EquipmentManagement.DvRepair.repairName')" align="center" prop="repairName" min-width="160" />
<el-table-column :label="t('EquipmentManagement.DvRepair.repairCode')" align="center" prop="repairCode"
min-width="180" />
<el-table-column :label="t('EquipmentManagement.DvRepair.repairName')" align="center" prop="repairName"
min-width="160" />
<el-table-column :label="t('EquipmentManagement.DvRepair.status')" align="center" prop="status" width="110">
<template #default="scope">
<el-tag :type="getRepairStatusTagType(scope.row.status)" effect="light">
@ -419,32 +377,46 @@ v-loading="productDialogLoading" :data="productDialogList" row-key="id" :stripe=
</el-tag>
</template>
</el-table-column>
<el-table-column :label="t('EquipmentManagement.DvRepair.repairStatus')" align="center" prop="repairStatus" min-width="120">
<el-table-column :label="t('EquipmentManagement.DvRepair.repairStatus')" align="center" prop="repairStatus"
min-width="120">
<template #default="scope">
<el-tag :type="getRepairResultTagType(scope.row.repairStatus)" effect="light">
{{ getRepairResultLabel(scope.row.repairStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column :label="t('EquipmentManagement.DvRepair.machineryName')" align="center" prop="machineryName" min-width="180" />
<el-table-column :label="t('EquipmentManagement.DvRepair.machineryCode')" align="center" prop="machineryCode" min-width="180" />
<el-table-column :label="t('EquipmentManagement.DvRepair.machinerySpec')" align="center" prop="machinerySpec" min-width="120" />
<el-table-column :label="t('EquipmentManagement.DvRepair.machineryType')" align="center" prop="machineryTypeId" width="100">
<el-table-column :label="t('EquipmentManagement.DvRepair.machineryName')" align="center" prop="machineryName"
min-width="180" />
<el-table-column :label="t('EquipmentManagement.DvRepair.machineryCode')" align="center" prop="machineryCode"
min-width="180" />
<el-table-column :label="t('EquipmentManagement.DvRepair.machinerySpec')" align="center" prop="machinerySpec"
min-width="120" />
<el-table-column :label="t('EquipmentManagement.DvRepair.machineryType')" align="center" prop="machineryTypeId"
width="100">
<template #default="scope">
<dict-tag :type="DICT_TYPE.MES_MACHINE_TYPE" :value="scope.row.machineryTypeId" />
</template>
</el-table-column>
<el-table-column :label="t('EquipmentManagement.DvRepair.requireDate')" align="center" prop="requireDate" :formatter="dateFormatter2" width="110" />
<el-table-column :label="t('EquipmentManagement.DvRepair.finishDate')" align="center" prop="finishDate" :formatter="dateFormatter2" width="110" />
<el-table-column :label="t('EquipmentManagement.DvRepair.confirmDate')" align="center" prop="confirmDate" :formatter="dateFormatter2" width="110" />
<el-table-column :label="t('EquipmentManagement.DvRepair.acceptedBy')" align="center" prop="acceptedBy" min-width="150" />
<el-table-column :label="t('EquipmentManagement.DvRepair.confirmBy')" align="center" prop="confirmBy" min-width="150" />
<el-table-column :label="t('EquipmentManagement.DvRepair.createTime')" align="center" prop="createTime" :formatter="dateFormatter" width="170" />
<el-table-column :label="t('EquipmentManagement.DvRepair.requireDate')" align="center" prop="requireDate"
:formatter="dateFormatter2" width="110" />
<el-table-column :label="t('EquipmentManagement.DvRepair.finishDate')" align="center" prop="finishDate"
:formatter="dateFormatter2" width="110" />
<el-table-column :label="t('EquipmentManagement.DvRepair.confirmDate')" align="center" prop="confirmDate"
:formatter="dateFormatter2" width="110" />
<el-table-column :label="t('EquipmentManagement.DvRepair.acceptedBy')" align="center" prop="acceptedBy"
min-width="150" />
<el-table-column :label="t('EquipmentManagement.DvRepair.confirmBy')" align="center" prop="confirmBy"
min-width="150" />
<el-table-column :label="t('EquipmentManagement.DvRepair.createTime')" align="center" prop="createTime"
:formatter="dateFormatter" width="170" />
</template>
<template v-else>
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.planNo')" align="center" prop="planNo" min-width="160" />
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.deviceName')" align="center" prop="deviceName" min-width="160" />
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.planType')" align="center" prop="planType" width="90">
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.planNo')" align="center" prop="planNo"
min-width="160" />
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.deviceName')" align="center"
prop="deviceName" min-width="160" />
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.planType')" align="center" prop="planType"
width="90">
<template #default="scope">
<el-tag v-if="String(scope.row.planType) === '1'" type="primary">
{{ t('EquipmentManagement.WorkOrderManagement.planTypeInspect') }}
@ -455,16 +427,22 @@ v-loading="productDialogLoading" :data="productDialogList" row-key="id" :stripe=
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.configName')" align="center" prop="configName" min-width="160" />
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.jobStatus')" align="center" prop="jobStatus" width="120">
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.configName')" align="center"
prop="configName" min-width="160" />
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.jobStatus')" align="center" prop="jobStatus"
width="120">
<template #default="scope">
<dict-tag :type="'job_status'" :value="scope.row.jobStatus" />
</template>
</el-table-column>
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.operatorName')" align="center" prop="operatorName" width="140" />
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.taskTime')" align="center" prop="taskTime" :formatter="dateFormatter" width="180" />
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.taskEndTime')" align="center" prop="taskEndTime" :formatter="dateFormatter" width="180" />
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.jobResult')" align="center" prop="jobResult" width="90">
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.operatorName')" align="center"
prop="operatorName" width="140" />
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.taskTime')" align="center" prop="taskTime"
:formatter="dateFormatter" width="180" />
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.taskEndTime')" align="center"
prop="taskEndTime" :formatter="dateFormatter" width="180" />
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.jobResult')" align="center" prop="jobResult"
width="90">
<template #default="scope">
<el-tag v-if="scope.row.jobResult == '1'" type="success">
{{ t('EquipmentManagement.WorkOrderManagement.jobResultOk') }}
@ -475,16 +453,13 @@ v-loading="productDialogLoading" :data="productDialogList" row-key="id" :stripe=
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.createTime')" align="center" prop="createTime" :formatter="dateFormatter" width="180" />
<el-table-column :label="t('EquipmentManagement.WorkOrderManagement.createTime')" align="center"
prop="createTime" :formatter="dateFormatter" width="180" />
</template>
</el-table>
<div class="product-dialog-pagination">
<Pagination
:total="relatedOrderTotal"
v-model:page="relatedOrderQueryParams.pageNo"
v-model:limit="relatedOrderQueryParams.pageSize"
@pagination="getRelatedOrderList"
/>
<Pagination :total="relatedOrderTotal" v-model:page="relatedOrderQueryParams.pageNo"
v-model:limit="relatedOrderQueryParams.pageSize" @pagination="getRelatedOrderList" />
</div>
<template #footer>
<el-button type="primary" @click="confirmRelatedOrderSelect">{{ t('common.ok') }}</el-button>
@ -577,8 +552,12 @@ const palletQueryParams = reactive({
pageNo: 1,
pageSize: 10,
code: undefined,
status: undefined
status: undefined,
excludeStatus: 3
})
const palletStatusOptions = computed(() =>
getIntDictOptions(DICT_TYPE.STORAGE_PALLET_STATUS).filter((dict) => Number(dict.value) !== 3)
)
const RELATED_PURPOSE_REPAIR = '1'
const RELATED_PURPOSE_MAINTAIN = '2'
const relatedOrderDialogVisible = ref(false)
@ -861,7 +840,7 @@ const getDefaultSupplierName = (product: any) => {
}
const normalizeRows = (rows: any[]) => {
;(rows || []).forEach(normalizeRow)
; (rows || []).forEach(normalizeRow)
}
const normalizeRow = (row: any) => {
@ -945,10 +924,16 @@ const clearProduct = (row: any) => {
}
const handleProductClear = (row: any) => {
if (props.disabled) return
clearProduct(row)
setStockCount(row)
}
const handleProductInputClick = (row: any) => {
if (props.disabled) return
openProductSelectDialog(row)
}
const openProductSelectDialog = async (row: any) => {
if (!activeCategoryType.value) return
currentSelectRow.value = row
@ -996,16 +981,19 @@ const confirmProductSelect = async () => {
}
const handleOutModeChange = (row: any) => {
if (props.disabled) return
clearPallet(row)
}
const openPalletSelectDialog = async (row: any) => {
currentSelectRow.value = row
selectedPalletRows.value = []
selectedPalletRows.value = getInitialSelectedPalletRows(row)
await loadRowsWarehouseAreas(selectedPalletRows.value)
palletQueryParams.pageNo = 1
palletQueryParams.code = undefined
palletQueryParams.status = undefined
palletDialogVisible.value = true
if (props.disabled) return
await getPalletDialogList()
}
@ -1015,8 +1003,8 @@ const getPalletDialogList = async () => {
const data = await PalletApi.getPalletPage({
...palletQueryParams,
productId: currentSelectRow.value?.productId,
warehouseId: currentSelectRow.value?.warehouseId,
areaId: currentSelectRow.value?.areaId
warehouseId: isProductStockOut.value ? undefined : currentSelectRow.value?.warehouseId,
areaId: isProductStockOut.value ? undefined : currentSelectRow.value?.areaId
})
const selectedPackageMap = new Map((currentSelectRow.value?.pallets || []).map((item: any) => [item.palletId, item.packageCount]))
palletDialogList.value = (data?.list || []).map((pallet: any) => {
@ -1027,6 +1015,7 @@ const getPalletDialogList = async () => {
}
})
palletDialogTotal.value = data?.total || 0
await loadRowsWarehouseAreas(palletDialogList.value)
await nextTick()
syncPalletDialogSelection()
} finally {
@ -1048,12 +1037,16 @@ const handlePalletDialogSelectionChange = (rows: PalletVO[]) => {
}
const confirmPalletSelect = () => {
if (props.disabled) return
if (!currentSelectRow.value) return
const row = currentSelectRow.value
row.pallets = selectedPalletRows.value.map((pallet: any) => ({
palletId: pallet.id,
palletCode: pallet.code,
packageCount: getPalletPackageCount(row, pallet)
packageCount: getPalletPackageCount(row, pallet),
warehouseId: pallet.warehouseId,
areaId: pallet.areaId,
count: getSelectedPalletOutCountValue(pallet)
}))
row.palletCode = selectedPalletRows.value.map((pallet) => pallet.code).filter(Boolean).join(', ')
syncInputCountByPallets(row)
@ -1061,6 +1054,7 @@ const confirmPalletSelect = () => {
}
const clearPallet = (row: any) => {
if (props.disabled) return
if (!row) return
row.pallets = []
row.palletCode = undefined
@ -1071,6 +1065,26 @@ const clearPallet = (row: any) => {
row.count = isProductStockOut.value ? undefined : row.count
}
const getInitialSelectedPalletRows = (row: any) => {
const palletCodes = String(row?.palletCode || '')
.split(',')
.map((item) => item.trim())
.filter(Boolean)
const packageQuantity = Number(row?.packageQuantity)
return (row?.pallets || []).map((item: any, index: number) => ({
id: item.palletId,
code: item.palletCode || item.code || palletCodes[index] || String(item.palletId),
packageCount:
item.packageCount ??
(Number.isFinite(packageQuantity) && Number.isFinite(Number(item.count))
? Number(item.count) / packageQuantity
: undefined),
warehouseId: item.warehouseId,
areaId: item.areaId,
count: item.count
}))
}
const syncPalletDialogSelection = () => {
const row = currentSelectRow.value
if (!row || !palletTableRef.value) return
@ -1096,6 +1110,27 @@ const handlePalletPackageCountChange = (value: number | undefined, pallet: any)
message.warning(`出库包数不能大于包数,已自动调整为${availablePackageCount}`)
}
const getPalletOutCount = (pallet: any) => {
const packageQuantity = Number(currentSelectRow.value?.packageQuantity)
if (!Number.isFinite(packageQuantity)) return undefined
const packageCount = getPalletPackageCount(currentSelectRow.value, pallet)
return Number.isFinite(packageCount) ? packageQuantity * packageCount : undefined
}
const getSelectedPalletOutCountValue = (pallet: any) => {
const packageQuantity = Number(currentSelectRow.value?.packageQuantity)
const packageCount = Number(pallet?.packageCount)
if (Number.isFinite(packageQuantity) && Number.isFinite(packageCount)) {
return packageQuantity * packageCount
}
const currentCount = Number(pallet?.count)
return Number.isFinite(currentCount) ? currentCount : undefined
}
const getSelectedPalletOutCount = (pallet: any) => {
return getSelectedPalletOutCountValue(pallet) ?? '-'
}
const getPalletPackageCount = (row: any, pallet: any) => {
const availablePackageCount = getPalletAvailablePackageCount(pallet)
if (Number(row.outMode) === 1) {
@ -1157,9 +1192,21 @@ const clearRelatedOrder = (row: any) => {
}
const handleOutboundPurposeChange = (row: any) => {
if (props.disabled) return
clearRelatedOrder(row)
}
const getOutboundPurposeLabel = (value: any) => {
const currentValue = String(value ?? '')
return outboundPurposeOptions.value.find((item) => String(item.value) === currentValue)?.label ?? '-'
}
const getOutModeLabel = (value: any) => {
if (Number(value) === 1) return t('ErpStock.Item.outModeWholePallet')
if (Number(value) === 2) return t('ErpStock.Item.outModeSplitPallet')
return '-'
}
const getRelatedOrderPlaceholder = (purpose: any) => {
return String(purpose ?? '') === RELATED_PURPOSE_REPAIR
? t('ErpStock.Item.placeholderRelatedRepairOrder')
@ -1167,6 +1214,7 @@ const getRelatedOrderPlaceholder = (purpose: any) => {
}
const openRelatedOrderDialog = async (row: any) => {
if (props.disabled) return
const purpose = String(row.outUsageType ?? '')
if (!isRelatedPurpose(purpose)) return
currentRelatedRow.value = row
@ -1316,6 +1364,15 @@ const getAreaLabel = (item: WarehouseAreaVO) => {
return item.areaCode ? `${item.areaCode} - ${item.areaName}` : item.areaName
}
const getWarehouseName = (warehouseId: number | string | undefined) => {
return warehouseList.value.find((item) => String(item.id) === String(warehouseId))?.name ?? warehouseId ?? '-'
}
const getAreaName = (areaId: number | string | undefined) => {
const areaList = Object.values(warehouseAreaMap.value).flat()
return areaList.find((item) => String(item.id) === String(areaId))?.areaName ?? areaId ?? '-'
}
const fillProductNames = (rows: any[]) => {
if (!productList.value.length) return
rows.forEach((row) => {

@ -136,27 +136,18 @@
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('ErpStock.Pallet.planCode')" prop="planCode">
<el-input v-model="formData.planCode" :placeholder="t('ErpStock.Pallet.placeholderPlanCode')" />
</el-form-item>
</el-col>
<!-- <el-col :span="12">-->
<!-- <el-form-item :label="t('ErpStock.Pallet.planCode')" prop="planCode">-->
<!-- <el-input v-model="formData.planCode" :placeholder="t('ErpStock.Pallet.placeholderPlanCode')" />-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="12">
<el-form-item :label="t('ErpStock.Pallet.productId')" prop="productId">
<el-select
v-model="formData.productId"
:placeholder="t('ErpStock.Pallet.placeholderProductId')"
clearable
filterable
class="!w-1/1"
>
<el-option
v-for="item in productList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
<el-input :model-value="selectedProductText" readonly :placeholder="t('ErpStock.Pallet.placeholderProductId')" clearable @clear="clearProductSelection">
<template #append>
<el-button @click="openProductDialog">{{ t('common.select') }}</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
@ -363,6 +354,83 @@
<el-button @click="areaDialogVisible = false">{{ t('common.cancel') }}</el-button>
</template>
</Dialog>
<Dialog :title="t('ErpStock.Item.selectProduct')" v-model="productDialogVisible" width="1100px">
<el-form :model="productQueryParams" :inline="true" label-width="auto" class="-mb-15px">
<el-form-item :label="t('FactoryModeling.ProductInformation.searchCodeLabel')">
<el-input
v-model="productQueryParams.barCode"
clearable
:placeholder="t('FactoryModeling.ProductInformation.searchCodePlaceholder')"
class="!w-240px"
@keyup.enter="handleProductQuery"
/>
</el-form-item>
<el-form-item :label="t('FactoryModeling.ProductInformation.searchNameLabel')">
<el-input
v-model="productQueryParams.name"
clearable
:placeholder="t('FactoryModeling.ProductInformation.searchNamePlaceholder')"
class="!w-240px"
@keyup.enter="handleProductQuery"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleProductQuery">
<Icon icon="ep:search" class="mr-5px" />{{ t('common.query') }}
</el-button>
<el-button @click="resetProductQuery">
<Icon icon="ep:refresh" class="mr-5px" />{{ t('common.reset') }}
</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="productLoading"
:data="productTableList"
row-key="id"
highlight-current-row
:stripe="true"
:show-overflow-tooltip="true"
@row-click="handleProductRowClick"
>
<el-table-column align="center" width="55">
<template #default="scope">
<el-radio
:model-value="productSelection?.id"
:value="scope.row.id"
@change="handleProductRowClick(scope.row)"
/>
</template>
</el-table-column>
<el-table-column :label="t('FactoryModeling.ProductInformation.tableBarCodeColumn')" align="center" prop="barCode" min-width="150" sortable />
<el-table-column :label="t('FactoryModeling.ProductInformation.dialogCategoryTypeLabel')" align="center" prop="categoryType" min-width="120" sortable>
<template #default="scope">
<dict-tag :type="DICT_TYPE.MATERIAL_CLASSIFICATION_TYPE" :value="scope.row.categoryType" />
</template>
</el-table-column>
<el-table-column :label="t('FactoryModeling.ProductInformation.tableNameColumn')" align="left" prop="name" min-width="180" sortable />
<el-table-column :label="t('FactoryModeling.ProductInformation.tableStandardColumn')" align="center" prop="standard" min-width="120" sortable />
<el-table-column :label="t('FactoryModeling.ProductInformation.tableCategoryColumn')" align="center" prop="subCategoryName" min-width="120" sortable />
<el-table-column :label="t('FactoryModeling.ProductInformation.tableUnitColumn')" align="center" prop="unitName" min-width="90" sortable />
<el-table-column :label="t('FactoryModeling.ProductInformation.tableStatusColumn')" 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>
<div class="pallet-dialog-pagination">
<Pagination
:total="productTotal"
v-model:page="productQueryParams.pageNo"
v-model:limit="productQueryParams.pageSize"
@pagination="getProductTableList"
/>
</div>
<template #footer>
<el-button type="primary" @click="confirmProductSelection">{{ t('common.ok') }}</el-button>
<el-button @click="productDialogVisible = false">{{ t('common.cancel') }}</el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
@ -387,11 +455,22 @@ const formType = ref('')
const formRef = ref()
const warehouseOptions = ref<WarehouseVO[]>([])
const areaOptions = ref<WarehouseAreaVO[]>([])
const productList = ref<ProductVO[]>([])
const selectedProduct = ref<ProductVO | undefined>()
const unitList = ref<ProductUnitVO[]>([])
const selectedWarehouse = ref<WarehouseVO | undefined>()
const selectedArea = ref<WarehouseAreaVO | undefined>()
const productDialogVisible = ref(false)
const productLoading = ref(false)
const productTableList = ref<ProductVO[]>([])
const productTotal = ref(0)
const productSelection = ref<ProductVO | undefined>()
const productQueryParams = reactive({
pageNo: 1,
pageSize: 10,
barCode: undefined as string | undefined,
name: undefined as string | undefined,
categoryType: 1
})
const warehouseDialogVisible = ref(false)
const warehouseLoading = ref(false)
const warehouseTableList = ref<WarehouseVO[]>([])
@ -441,6 +520,10 @@ const specificationParts = reactive({
const selectedWarehouseText = computed(() => selectedWarehouse.value?.name ?? '')
const selectedAreaText = computed(() => selectedArea.value?.areaName ?? '')
const selectedProductText = computed(() => {
const product = selectedProduct.value
return product ? [product.barCode, product.name].filter(Boolean).join(' - ') : ''
})
const validateCode = (_rule, value, callback) => {
if (Boolean(formData.value.isCode)) {
@ -460,12 +543,19 @@ const formRules = reactive({
status: [{ required: true, message: t('ErpStock.Pallet.validatorStatusRequired'), trigger: 'change' }]
})
const open = async (type: string, row?: PalletVO) => {
const open = async (type: string, row?: PalletVO, defaults?: Partial<PalletVO>) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
await Promise.all([getWarehouseOptions(), getAreaOptions(), getProductList(), getUnitList()])
await Promise.all([getWarehouseOptions(), getAreaOptions(), getUnitList()])
if (type === 'create' && defaults) {
formData.value = {
...formData.value,
...defaults
}
await hydrateSelectedProduct()
}
if (type === 'update' && row) {
formData.value = {
...row,
@ -473,6 +563,7 @@ const open = async (type: string, row?: PalletVO) => {
}
parseSpecification(row.specification)
await hydrateSelectedWarehouseArea()
await hydrateSelectedProduct()
}
}
defineExpose({ open })
@ -511,10 +602,6 @@ const getAreaOptions = async () => {
areaOptions.value = data.list ?? []
}
const getProductList = async () => {
productList.value = await ProductApi.getProductSimpleList()
}
const getUnitList = async () => {
unitList.value = await ProductUnitApi.getProductUnitSimpleList()
}
@ -576,6 +663,57 @@ const hydrateSelectedWarehouseArea = async () => {
}
}
const hydrateSelectedProduct = async () => {
selectedProduct.value = undefined
if (!formData.value.productId) return
selectedProduct.value = await ProductApi.getProduct(Number(formData.value.productId))
}
const getProductTableList = async () => {
productLoading.value = true
try {
const data = await ProductApi.getProductPage(productQueryParams)
productTableList.value = data?.list ?? []
productTotal.value = data?.total ?? 0
} finally {
productLoading.value = false
}
}
const openProductDialog = async () => {
productDialogVisible.value = true
productSelection.value = selectedProduct.value
await getProductTableList()
}
const handleProductQuery = () => {
productQueryParams.pageNo = 1
getProductTableList()
}
const resetProductQuery = () => {
productQueryParams.pageNo = 1
productQueryParams.barCode = undefined
productQueryParams.name = undefined
getProductTableList()
}
const handleProductRowClick = (row: ProductVO) => {
productSelection.value = row
}
const confirmProductSelection = () => {
if (!productSelection.value) return
selectedProduct.value = productSelection.value
formData.value.productId = productSelection.value.id
productDialogVisible.value = false
}
const clearProductSelection = () => {
selectedProduct.value = undefined
formData.value.productId = undefined
}
const getWarehouseName = (warehouseId?: number) => {
return warehouseOptions.value.find((item) => item.id === warehouseId)?.name ?? '-'
}
@ -706,6 +844,8 @@ const resetForm = () => {
specificationParts.height = undefined
selectedWarehouse.value = undefined
selectedArea.value = undefined
selectedProduct.value = undefined
productSelection.value = undefined
formRef.value?.resetFields()
}
</script>

@ -86,7 +86,6 @@
{{ getAreaName(scope.row.areaId) }}
</template>
</el-table-column>
<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" />
@ -95,7 +94,7 @@
<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('common.operate')" align="center" width="150px">
<el-table-column :label="t('common.operate')" align="center" width="150px" fixed="right">
<template #default="scope">
<el-button link type="primary" @click="openForm('update', scope.row)" v-hasPermi="['erp:pallet:update']">
{{ t('action.edit') }}

Loading…
Cancel
Save