feat:库区信息/库位信息-新增页面

ck
黄伟杰 2 weeks ago
parent 4e134b787a
commit efaf527d80

@ -0,0 +1,34 @@
import request from '@/config/axios'
export interface WarehouseAreaVO {
id: number
warehouseId: number
areaCode: string
areaName: string
areaSize: number
description: string
status: number
createTime: string
}
export const WarehouseAreaApi = {
getWarehouseAreaPage: async (params: any) => {
return await request.get({ url: `/erp/warehouse-area/page`, params })
},
getWarehouseArea: async (id: number) => {
return await request.get({ url: `/erp/warehouse-area/get?id=` + id })
},
createWarehouseArea: async (data: WarehouseAreaVO) => {
return await request.post({ url: `/erp/warehouse-area/create`, data })
},
updateWarehouseArea: async (data: WarehouseAreaVO) => {
return await request.put({ url: `/erp/warehouse-area/update`, data })
},
deleteWarehouseArea: async (id: number) => {
return await request.delete({ url: `/erp/warehouse-area/delete?id=` + id })
}
}

@ -0,0 +1,40 @@
import request from '@/config/axios'
export interface WarehouseLocationVO {
id: number
warehouseId: number
areaId: number
code: string
name: string
areaSize: number
maxLoadWeight: number
positionX: number
positionY: number
positionZ: number
allowProductMix: boolean
allowBatchMix: boolean
status: number
createTime: string
}
export const WarehouseLocationApi = {
getWarehouseLocationPage: async (params: any) => {
return await request.get({ url: `/erp/warehouse-location/page`, params })
},
getWarehouseLocation: async (id: number) => {
return await request.get({ url: `/erp/warehouse-location/get?id=` + id })
},
createWarehouseLocation: async (data: WarehouseLocationVO) => {
return await request.post({ url: `/erp/warehouse-location/create`, data })
},
updateWarehouseLocation: async (data: WarehouseLocationVO) => {
return await request.put({ url: `/erp/warehouse-location/update`, data })
},
deleteWarehouseLocation: async (id: number) => {
return await request.delete({ url: `/erp/warehouse-location/delete?id=` + id })
}
}

@ -59,6 +59,8 @@ export default {
copy: 'Copy',
copySuccess: 'Copy Success',
copyError: 'Copy Error',
yes: 'Yes',
no: 'No',
code:'Auto-generate on Save'
},
ReportDashboard: {
@ -287,6 +289,58 @@ export default {
cancel: 'cancel',
exportName: 'Warehouse.xls'
},
WarehouseArea: {
warehouseId: 'Warehouse',
areaCode: 'Area Code',
areaName: 'Area Name',
areaSize: 'Area Size (㎡)',
description: 'Description',
status: 'Status',
createTime: 'Create Time',
placeholderWarehouseId: 'Please select warehouse',
placeholderAreaCode: 'Please enter area code',
placeholderAreaName: 'Please enter area name',
placeholderAreaSize: 'Please enter area size',
placeholderDescription: 'Please enter description',
placeholderStatus: 'Please select status',
validatorWarehouseIdRequired: 'Warehouse is required',
validatorAreaCodeRequired: 'Area code is required',
validatorAreaNameRequired: 'Area name is required',
validatorStatusRequired: 'Status is required'
},
WarehouseLocation: {
warehouseId: 'Warehouse',
areaId: 'Area',
code: 'Location Code',
name: 'Location Name',
areaSize: 'Area Size (㎡)',
maxLoadWeight: 'Max Load Weight',
position: 'Position (X,Y,Z)',
positionX: 'Position X',
positionY: 'Position Y',
positionZ: 'Position Z',
allowProductMix: 'Allow Product Mix',
allowBatchMix: 'Allow Batch Mix',
status: 'Status',
createTime: 'Create Time',
placeholderWarehouseId: 'Please select warehouse',
placeholderAreaId: 'Please select area',
placeholderCode: 'Please enter location code',
placeholderName: 'Please enter location name',
placeholderAreaSize: 'Please enter area size',
placeholderMaxLoadWeight: 'Please enter max load weight',
placeholderPositionX: 'Please enter position X',
placeholderPositionY: 'Please enter position Y',
placeholderPositionZ: 'Please enter position Z',
placeholderStatus: 'Please select status',
validatorWarehouseIdRequired: 'Warehouse is required',
validatorAreaIdRequired: 'Area is required',
validatorCodeRequired: 'Location code is required',
validatorNameRequired: 'Location name is required',
validatorAllowProductMixRequired: 'Allow product mix is required',
validatorAllowBatchMixRequired: 'Allow batch mix is required',
validatorStatusRequired: 'Status is required'
},
Stock: {
product: 'Product',
warehouse: 'Warehouse',

@ -59,6 +59,8 @@ export default {
copy: '复制',
copySuccess: '复制成功',
copyError: '复制失败',
yes: '是',
no: '否',
code: '编码保存后自动生成'
},
ReportDashboard: {
@ -287,6 +289,58 @@ export default {
cancel: '取消',
exportName: '仓库.xls'
},
WarehouseArea: {
warehouseId: '所属仓库',
areaCode: '库区编码',
areaName: '库区名称',
areaSize: '面积(㎡)',
description: '库区描述',
status: '开启状态',
createTime: '创建时间',
placeholderWarehouseId: '请选择所属仓库',
placeholderAreaCode: '请输入库区编码',
placeholderAreaName: '请输入库区名称',
placeholderAreaSize: '请输入面积',
placeholderDescription: '请输入库区描述',
placeholderStatus: '请选择开启状态',
validatorWarehouseIdRequired: '所属仓库不能为空',
validatorAreaCodeRequired: '库区编码不能为空',
validatorAreaNameRequired: '库区名称不能为空',
validatorStatusRequired: '开启状态不能为空'
},
WarehouseLocation: {
warehouseId: '所属仓库',
areaId: '所属库区',
code: '库位编码',
name: '库位名称',
areaSize: '面积(㎡)',
maxLoadWeight: '最大载重量',
position: '库位位置(X,Y,Z)',
positionX: '位置X',
positionY: '位置Y',
positionZ: '位置Z',
allowProductMix: '允许产品混放',
allowBatchMix: '允许批次混放',
status: '开启状态',
createTime: '创建时间',
placeholderWarehouseId: '请选择所属仓库',
placeholderAreaId: '请选择所属库区',
placeholderCode: '请输入库位编码',
placeholderName: '请输入库位名称',
placeholderAreaSize: '请输入面积',
placeholderMaxLoadWeight: '请输入最大载重量',
placeholderPositionX: '请输入位置X',
placeholderPositionY: '请输入位置Y',
placeholderPositionZ: '请输入位置Z',
placeholderStatus: '请选择开启状态',
validatorWarehouseIdRequired: '所属仓库不能为空',
validatorAreaIdRequired: '所属库区不能为空',
validatorCodeRequired: '库位编码不能为空',
validatorNameRequired: '库位名称不能为空',
validatorAllowProductMixRequired: '是否允许产品混放不能为空',
validatorAllowBatchMixRequired: '是否允许批次混放不能为空',
validatorStatusRequired: '开启状态不能为空'
},
Stock: {
product: '产品',
warehouse: '仓库',

@ -0,0 +1,148 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-form-item :label="t('ErpStock.WarehouseArea.warehouseId')" prop="warehouseId">
<el-select
v-model="formData.warehouseId"
:placeholder="t('ErpStock.WarehouseArea.placeholderWarehouseId')"
class="!w-1/1"
>
<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.WarehouseArea.areaCode')" prop="areaCode">
<el-row :gutter="10" class="!w-full">
<el-col :xs="24" :sm="18" :md="16" :lg="14" :xl="12">
<el-input v-model="formData.areaCode" :placeholder="t('ErpStock.WarehouseArea.placeholderAreaCode')" :disabled="formData.isCode == true || formType === 'update'" />
</el-col>
<el-col :xs="24" :sm="6" :md="4" :lg="3" :xl="2">
<div>
<el-switch v-model="formData.isCode" :disabled="formType === 'update'" />
</div>
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseArea.areaName')" prop="areaName">
<el-input v-model="formData.areaName" :placeholder="t('ErpStock.WarehouseArea.placeholderAreaName')" />
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseArea.areaSize')" prop="areaSize">
<el-input-number
v-model="formData.areaSize"
:placeholder="t('ErpStock.WarehouseArea.placeholderAreaSize')"
:min="0"
:precision="2"
class="!w-1/1"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseArea.description')" prop="description">
<el-input type="textarea" v-model="formData.description" :placeholder="t('ErpStock.WarehouseArea.placeholderDescription')" />
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseArea.status')" prop="status">
<el-switch v-model="formData.status" :active-value="CommonStatusEnum.ENABLE" :inactive-value="CommonStatusEnum.DISABLE" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('common.ok') }}</el-button>
<el-button @click="dialogVisible = false">{{ t('common.cancel') }}</el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { WarehouseAreaApi, WarehouseAreaVO } from '@/api/erp/stock/warehousearea'
import { WarehouseApi } from '@/api/erp/stock/warehouse'
import { CommonStatusEnum } from '@/utils/constants'
defineOptions({ name: 'WarehouseAreaForm' })
const { t } = useI18n()
const message = useMessage()
const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false)
const formType = ref('')
const formData = ref({
id: undefined,
warehouseId: undefined,
areaCode: undefined,
areaName: undefined,
areaSize: undefined,
description: undefined,
status: undefined,
isCode: true
})
const formRules = reactive({
warehouseId: [{ required: true, message: t('ErpStock.WarehouseArea.validatorWarehouseIdRequired'), trigger: 'blur' }],
areaName: [{ required: true, message: t('ErpStock.WarehouseArea.validatorAreaNameRequired'), trigger: 'blur' }],
status: [{ required: true, message: t('ErpStock.WarehouseArea.validatorStatusRequired'), trigger: 'blur' }]
})
const formRef = ref()
const warehouseList = ref<any[]>([])
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
if (id) {
formLoading.value = true
try {
formData.value = await WarehouseAreaApi.getWarehouseArea(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open })
const emit = defineEmits(['success'])
const submitForm = async () => {
await formRef.value.validate()
formLoading.value = true
try {
const data = { ...formData.value } as unknown as WarehouseAreaVO
if (data.isCode) {
data.areaCode = undefined
}
if (formType.value === 'create') {
await WarehouseAreaApi.createWarehouseArea(data)
message.success(t('common.createSuccess'))
} else {
await WarehouseAreaApi.updateWarehouseArea(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
emit('success')
} finally {
formLoading.value = false
}
}
const resetForm = () => {
formData.value = {
id: undefined,
warehouseId: undefined,
areaCode: undefined,
areaName: undefined,
areaSize: undefined,
description: undefined,
status: CommonStatusEnum.ENABLE,
isCode: true
}
formRef.value?.resetFields()
}
</script>

@ -0,0 +1,201 @@
<template>
<ContentWrap>
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="auto"
>
<el-form-item :label="t('ErpStock.WarehouseArea.warehouseId')" prop="warehouseId">
<el-select
v-model="queryParams.warehouseId"
:placeholder="t('ErpStock.WarehouseArea.placeholderWarehouseId')"
clearable
class="!w-240px"
>
<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.WarehouseArea.areaCode')" prop="areaCode">
<el-input
v-model="queryParams.areaCode"
:placeholder="t('ErpStock.WarehouseArea.placeholderAreaCode')"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseArea.areaName')" prop="areaName">
<el-input
v-model="queryParams.areaName"
:placeholder="t('ErpStock.WarehouseArea.placeholderAreaName')"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseArea.status')" prop="status">
<el-select
v-model="queryParams.status"
:placeholder="t('ErpStock.WarehouseArea.placeholderStatus')"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</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:warehouse-area:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> {{ t('action.add') }}
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<ContentWrap>
<el-table
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
row-key="id"
>
<el-table-column :label="t('ErpStock.WarehouseArea.warehouseId')" align="center" prop="warehouseId" sortable>
<template #default="scope">
{{ getWarehouseName(scope.row.warehouseId) }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.WarehouseArea.areaCode')" align="center" prop="areaCode" sortable />
<el-table-column :label="t('ErpStock.WarehouseArea.areaName')" align="center" prop="areaName" sortable />
<el-table-column :label="t('ErpStock.WarehouseArea.areaSize')" align="center" prop="areaSize" />
<el-table-column :label="t('ErpStock.WarehouseArea.description')" align="center" prop="description" />
<el-table-column :label="t('ErpStock.WarehouseArea.status')" align="center" prop="status" 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" width="180px" sortable />
<el-table-column :label="t('common.operate')" align="center">
<template #default="scope">
<el-button
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['erp:warehouse-area:update']"
>
{{ t('action.edit') }}
</el-button>
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['erp:warehouse-area: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"
/>
</ContentWrap>
<WarehouseAreaForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import { WarehouseAreaApi, WarehouseAreaVO } from '@/api/erp/stock/warehousearea'
import { WarehouseApi } from '@/api/erp/stock/warehouse'
import WarehouseAreaForm from './WarehouseAreaForm.vue'
defineOptions({ name: 'ErpWarehouseArea' })
const message = useMessage()
const { t } = useI18n()
const loading = ref(true)
const list = ref<WarehouseAreaVO[]>([])
const total = ref(0)
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
warehouseId: undefined,
areaCode: undefined,
areaName: undefined,
status: undefined
})
const queryFormRef = ref()
const warehouseList = ref<any[]>([])
const getWarehouseName = (warehouseId: number) => {
return warehouseList.value.find((w) => w.id === warehouseId)?.name ?? '-'
}
const getList = async () => {
loading.value = true
try {
const data = await WarehouseAreaApi.getWarehouseAreaPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
const getWarehouseList = async () => {
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
}
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
const handleDelete = async (id: number) => {
try {
await message.delConfirm()
await WarehouseAreaApi.deleteWarehouseArea(id)
message.success(t('common.delSuccess'))
await getList()
} catch {}
}
onMounted(() => {
getWarehouseList()
getList()
})
</script>

@ -0,0 +1,227 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="120px"
v-loading="formLoading"
>
<el-form-item :label="t('ErpStock.WarehouseLocation.warehouseId')" prop="warehouseId">
<el-select
v-model="formData.warehouseId"
:placeholder="t('ErpStock.WarehouseLocation.placeholderWarehouseId')"
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-form-item>
<el-form-item :label="t('ErpStock.WarehouseLocation.areaId')" prop="areaId">
<el-select
v-model="formData.areaId"
:placeholder="t('ErpStock.WarehouseLocation.placeholderAreaId')"
class="!w-1/1"
>
<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.WarehouseLocation.code')" prop="code">
<el-row :gutter="10" class="!w-full">
<el-col :xs="24" :sm="18" :md="16" :lg="14" :xl="12">
<el-input v-model="formData.code" :placeholder="t('ErpStock.WarehouseLocation.placeholderCode')" :disabled="formData.isCode == true || formType === 'update'" />
</el-col>
<el-col :xs="24" :sm="6" :md="4" :lg="3" :xl="2">
<div>
<el-switch v-model="formData.isCode" :disabled="formType === 'update'" />
</div>
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseLocation.name')" prop="name">
<el-input v-model="formData.name" :placeholder="t('ErpStock.WarehouseLocation.placeholderName')" />
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseLocation.areaSize')" prop="areaSize">
<el-input-number
v-model="formData.areaSize"
:placeholder="t('ErpStock.WarehouseLocation.placeholderAreaSize')"
:min="0"
:precision="2"
class="!w-1/1"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseLocation.maxLoadWeight')" prop="maxLoadWeight">
<el-input-number
v-model="formData.maxLoadWeight"
:placeholder="t('ErpStock.WarehouseLocation.placeholderMaxLoadWeight')"
:min="0"
:precision="2"
class="!w-1/1"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseLocation.positionX')" prop="positionX">
<el-input-number
v-model="formData.positionX"
:placeholder="t('ErpStock.WarehouseLocation.placeholderPositionX')"
:precision="0"
class="!w-1/1"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseLocation.positionY')" prop="positionY">
<el-input-number
v-model="formData.positionY"
:placeholder="t('ErpStock.WarehouseLocation.placeholderPositionY')"
:precision="0"
class="!w-1/1"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseLocation.positionZ')" prop="positionZ">
<el-input-number
v-model="formData.positionZ"
:placeholder="t('ErpStock.WarehouseLocation.placeholderPositionZ')"
:precision="0"
class="!w-1/1"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseLocation.allowProductMix')" prop="allowProductMix">
<el-switch v-model="formData.allowProductMix" />
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseLocation.allowBatchMix')" prop="allowBatchMix">
<el-switch v-model="formData.allowBatchMix" />
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseLocation.status')" prop="status">
<el-switch v-model="formData.status" :active-value="CommonStatusEnum.ENABLE" :inactive-value="CommonStatusEnum.DISABLE" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading">{{ t('common.ok') }}</el-button>
<el-button @click="dialogVisible = false">{{ t('common.cancel') }}</el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { WarehouseLocationApi, WarehouseLocationVO } from '@/api/erp/stock/warehouselocation'
import { WarehouseApi } from '@/api/erp/stock/warehouse'
import { WarehouseAreaApi } from '@/api/erp/stock/warehousearea'
import { CommonStatusEnum } from '@/utils/constants'
defineOptions({ name: 'WarehouseLocationForm' })
const { t } = useI18n()
const message = useMessage()
const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false)
const formType = ref('')
const formData = ref({
id: undefined,
warehouseId: undefined,
areaId: undefined,
code: undefined,
name: undefined,
areaSize: undefined,
maxLoadWeight: undefined,
positionX: undefined,
positionY: undefined,
positionZ: undefined,
allowProductMix: false,
allowBatchMix: false,
status: undefined,
isCode: true
})
const formRules = reactive({
warehouseId: [{ required: true, message: t('ErpStock.WarehouseLocation.validatorWarehouseIdRequired'), trigger: 'blur' }],
areaId: [{ required: true, message: t('ErpStock.WarehouseLocation.validatorAreaIdRequired'), trigger: 'blur' }],
name: [{ required: true, message: t('ErpStock.WarehouseLocation.validatorNameRequired'), trigger: 'blur' }],
allowProductMix: [{ required: true, message: t('ErpStock.WarehouseLocation.validatorAllowProductMixRequired'), trigger: 'blur' }],
allowBatchMix: [{ required: true, message: t('ErpStock.WarehouseLocation.validatorAllowBatchMixRequired'), trigger: 'blur' }],
status: [{ required: true, message: t('ErpStock.WarehouseLocation.validatorStatusRequired'), trigger: 'blur' }]
})
const formRef = ref()
const warehouseList = ref<any[]>([])
const areaList = ref<any[]>([])
const filteredAreaList = computed(() => {
if (!formData.value.warehouseId) return areaList.value
return areaList.value.filter((item) => item.warehouseId === formData.value.warehouseId)
})
const handleWarehouseChange = () => {
formData.value.areaId = undefined
}
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
const areaData = await WarehouseAreaApi.getWarehouseAreaPage({ pageNo: 1, pageSize: 100 })
areaList.value = areaData.list ?? []
if (id) {
formLoading.value = true
try {
formData.value = await WarehouseLocationApi.getWarehouseLocation(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open })
const emit = defineEmits(['success'])
const submitForm = async () => {
await formRef.value.validate()
formLoading.value = true
try {
const data = { ...formData.value } as unknown as WarehouseLocationVO
if (data.isCode) {
data.code = undefined
}
if (formType.value === 'create') {
await WarehouseLocationApi.createWarehouseLocation(data)
message.success(t('common.createSuccess'))
} else {
await WarehouseLocationApi.updateWarehouseLocation(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
emit('success')
} finally {
formLoading.value = false
}
}
const resetForm = () => {
formData.value = {
id: undefined,
warehouseId: undefined,
areaId: undefined,
code: undefined,
name: undefined,
areaSize: undefined,
maxLoadWeight: undefined,
positionX: undefined,
positionY: undefined,
positionZ: undefined,
allowProductMix: false,
allowBatchMix: false,
status: CommonStatusEnum.ENABLE,
isCode: true
}
formRef.value?.resetFields()
}
</script>

@ -0,0 +1,263 @@
<template>
<ContentWrap>
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="auto"
>
<el-form-item :label="t('ErpStock.WarehouseLocation.warehouseId')" prop="warehouseId">
<el-select
v-model="queryParams.warehouseId"
:placeholder="t('ErpStock.WarehouseLocation.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.WarehouseLocation.areaId')" prop="areaId">
<el-select
v-model="queryParams.areaId"
:placeholder="t('ErpStock.WarehouseLocation.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.WarehouseLocation.code')" prop="code">
<el-input
v-model="queryParams.code"
:placeholder="t('ErpStock.WarehouseLocation.placeholderCode')"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseLocation.name')" prop="name">
<el-input
v-model="queryParams.name"
:placeholder="t('ErpStock.WarehouseLocation.placeholderName')"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item :label="t('ErpStock.WarehouseLocation.status')" prop="status">
<el-select
v-model="queryParams.status"
:placeholder="t('ErpStock.WarehouseLocation.placeholderStatus')"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</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:warehouse-location:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> {{ t('action.add') }}
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<ContentWrap>
<el-table
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
row-key="id"
>
<el-table-column :label="t('ErpStock.WarehouseLocation.warehouseId')" align="center" prop="warehouseId" sortable>
<template #default="scope">
{{ getWarehouseName(scope.row.warehouseId) }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.WarehouseLocation.areaId')" align="center" prop="areaId" sortable>
<template #default="scope">
{{ getAreaName(scope.row.areaId) }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.WarehouseLocation.code')" align="center" prop="code" sortable />
<el-table-column :label="t('ErpStock.WarehouseLocation.name')" align="center" prop="name" sortable />
<el-table-column :label="t('ErpStock.WarehouseLocation.areaSize')" align="center" prop="areaSize" />
<el-table-column :label="t('ErpStock.WarehouseLocation.maxLoadWeight')" align="center" prop="maxLoadWeight" />
<el-table-column :label="t('ErpStock.WarehouseLocation.position')" align="center">
<template #default="scope">
{{ scope.row.positionX ?? '-' }}, {{ scope.row.positionY ?? '-' }}, {{ scope.row.positionZ ?? '-' }}
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.WarehouseLocation.allowProductMix')" align="center" prop="allowProductMix">
<template #default="scope">
<el-tag :type="scope.row.allowProductMix ? 'success' : 'danger'" size="small">
{{ scope.row.allowProductMix ? t('common.yes') : t('common.no') }}
</el-tag>
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.WarehouseLocation.allowBatchMix')" align="center" prop="allowBatchMix">
<template #default="scope">
<el-tag :type="scope.row.allowBatchMix ? 'success' : 'danger'" size="small">
{{ scope.row.allowBatchMix ? t('common.yes') : t('common.no') }}
</el-tag>
</template>
</el-table-column>
<el-table-column :label="t('ErpStock.WarehouseLocation.status')" align="center" prop="status" 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.WarehouseLocation.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.id)"
v-hasPermi="['erp:warehouse-location:update']"
>
{{ t('action.edit') }}
</el-button>
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['erp:warehouse-location: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"
/>
</ContentWrap>
<WarehouseLocationForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import { WarehouseLocationApi, WarehouseLocationVO } from '@/api/erp/stock/warehouselocation'
import { WarehouseApi } from '@/api/erp/stock/warehouse'
import { WarehouseAreaApi } from '@/api/erp/stock/warehousearea'
import WarehouseLocationForm from './WarehouseLocationForm.vue'
defineOptions({ name: 'ErpWarehouseLocation' })
const message = useMessage()
const { t } = useI18n()
const loading = ref(true)
const list = ref<WarehouseLocationVO[]>([])
const total = ref(0)
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
warehouseId: undefined,
areaId: undefined,
code: undefined,
name: undefined,
status: undefined
})
const queryFormRef = ref()
const warehouseList = ref<any[]>([])
const areaList = ref<any[]>([])
const filteredAreaList = computed(() => {
if (!queryParams.warehouseId) return areaList.value
return areaList.value.filter((item) => item.warehouseId === queryParams.warehouseId)
})
const getWarehouseName = (warehouseId: number) => {
return warehouseList.value.find((w) => w.id === warehouseId)?.name ?? '-'
}
const getAreaName = (areaId: number) => {
return areaList.value.find((a) => a.id === areaId)?.areaName ?? '-'
}
const getList = async () => {
loading.value = true
try {
const data = await WarehouseLocationApi.getWarehouseLocationPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
const getWarehouseList = async () => {
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
}
const getAreaList = async () => {
const data = await WarehouseAreaApi.getWarehouseAreaPage({ pageNo: 1, pageSize: 100 })
areaList.value = data.list ?? []
}
const handleWarehouseChange = () => {
queryParams.areaId = undefined
}
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
const handleDelete = async (id: number) => {
try {
await message.delConfirm()
await WarehouseLocationApi.deleteWarehouseLocation(id)
message.success(t('common.delSuccess'))
await getList()
} catch {}
}
onMounted(() => {
getWarehouseList()
getAreaList()
getList()
})
</script>
Loading…
Cancel
Save