feat(mes): 添加盘点方案状态更新功能及参数校验

新增更新盘点方案状态的接口,确保在启用状态时,相关参数不为空。
同时,更新了相关权限控制和错误码定义,提升了系统的健壮性和用户体验。
pull/871/MERGE
YunaiV 2026-03-09 22:29:49 +08:00
parent ca2447f710
commit 9a6cd0f6cb
5 changed files with 307 additions and 219 deletions

View File

@ -10,18 +10,12 @@ export interface StockTakingPlanParamVO {
remark?: string
}
export interface StockTakingPlanParamPageReqVO {
pageNo: number
pageSize: number
planId: number
}
export const StockTakingPlanParamApi = {
getStockTakingPlanParam: async (id: number) => {
return await request.get({ url: '/mes/wm/stocktaking-plan-param/get?id=' + id })
},
getStockTakingPlanParamPage: async (params: StockTakingPlanParamPageReqVO) => {
getStockTakingPlanParamPage: async (params: any) => {
return await request.get({ url: '/mes/wm/stocktaking-plan-param/page', params })
},

View File

@ -297,10 +297,9 @@ export enum DICT_TYPE {
MES_WM_TRANSFER_STATUS = 'mes_wm_transfer_status', // MES 转移单状态
MES_WM_TRANSFER_TYPE = 'mes_wm_transfer_type', // MES 转移单类型
MES_WM_STOCK_TAKING_TYPE = 'mes_wm_stock_taking_type', // MES 盘点类型
MES_WM_STOCK_TAKING_PLAN_STATUS = 'mes_wm_stock_taking_plan_status', // MES 盘点方案状态
MES_WM_STOCK_TAKING_TASK_STATUS = 'mes_wm_stock_taking_task_status', // MES 盘点任务状态
MES_WM_STOCK_TAKING_LINE_STATUS = 'mes_wm_stock_taking_task_line_status', // MES 盘点任务行状态
MES_WM_STOCK_TAKING_PARAM_TYPE = 'mes_wm_stock_taking_param_type', // MES 盘点方案参数类型
MES_WM_STOCK_TAKING_PLAN_PARAM_TYPE = 'mes_wm_stock_taking_plan_param_type', // MES 盘点方案参数类型
MES_WM_OUTSOURCE_RECPT_STATUS = 'mes_wm_outsource_recpt_status', // MES 外协入库单状态
MES_WM_PRODUCTION_ISSUE_STATUS = 'mes_wm_production_issue_status', // MES 领料出库单状态
MES_PRODUCT_PRODUCE_STATUS = 'mes_product_produce_status', // MES 生产入库单状态
@ -321,5 +320,5 @@ export enum DICT_TYPE {
MES_MD_AUTO_CODE_CYCLE_METHOD = 'mes_md_auto_code_cycle_method', // MES 编码规则循环方式
MES_WM_BARCODE_FORMAT = 'mes_wm_barcode_format', // MES 条码格式
MES_WM_BARCODE_BIZ_TYPE = 'mes_wm_barcode_biz_type', // MES 条码业务类型
MES_WM_PACKAGE_STATUS = 'mes_wm_package_status', // MES 装箱单状态
MES_WM_PACKAGE_STATUS = 'mes_wm_package_status' // MES 装箱单状态
}

View File

@ -168,8 +168,8 @@ const submitForm = async () => {
await WmSalesNoticeApi.updateSalesNotice(data)
message.success(t('common.updateSuccess'))
dialogVisible.value = false
emit('success')
}
emit('success')
} finally {
formLoading.value = false
}

View File

@ -11,7 +11,7 @@
<el-row>
<el-col :span="8">
<el-form-item label="方案编码" prop="code">
<el-input v-model="formData.code" placeholder="请输入方案编码" :disabled="isReadonly">
<el-input v-model="formData.code" placeholder="请输入方案编码" :disabled="isDetail">
<template #append>
<el-button @click="generateCode" :disabled="formType !== 'create'">生成</el-button>
</template>
@ -20,7 +20,7 @@
</el-col>
<el-col :span="8">
<el-form-item label="方案名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入方案名称" :disabled="isReadonly" />
<el-input v-model="formData.name" placeholder="请输入方案名称" :disabled="isDetail" />
</el-form-item>
</el-col>
<el-col :span="8">
@ -29,7 +29,7 @@
v-model="formData.type"
placeholder="请选择盘点类型"
class="!w-full"
:disabled="isReadonly"
:disabled="isDetail"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.MES_WM_STOCK_TAKING_TYPE)"
@ -40,7 +40,7 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="12" v-if="formData.type === MesWmStockTakingTypeEnum.DYNAMIC">
<el-form-item label="开始时间" prop="startTime">
<el-date-picker
v-model="formData.startTime"
@ -48,11 +48,11 @@
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择开始时间"
class="!w-full"
:disabled="isReadonly"
:disabled="isDetail"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="12" v-if="formData.type === MesWmStockTakingTypeEnum.DYNAMIC">
<el-form-item label="结束时间" prop="endTime">
<el-date-picker
v-model="formData.endTime"
@ -60,18 +60,18 @@
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择结束时间"
class="!w-full"
:disabled="isReadonly"
:disabled="isDetail"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="是否盲盘" prop="blindFlag">
<el-switch v-model="formData.blindFlag" :disabled="isReadonly" />
<el-switch v-model="formData.blindFlag" :disabled="isDetail" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="冻结库存" prop="frozenFlag">
<el-switch v-model="formData.frozenFlag" :disabled="isReadonly" />
<el-switch v-model="formData.frozenFlag" :disabled="isDetail" />
</el-form-item>
</el-col>
<el-col :span="24">
@ -80,7 +80,7 @@
v-model="formData.remark"
type="textarea"
placeholder="请输入备注"
:disabled="isReadonly"
:disabled="isDetail"
/>
</el-form-item>
</el-col>
@ -90,11 +90,11 @@
<!-- 编辑时展示盘点参数 -->
<template v-if="formType === 'update' && formData.id">
<el-divider content-position="center">盘点参数</el-divider>
<StockTakingParamTable :plan-id="formData.id" />
<StockTakingPlanParamList :plan-id="formData.id" />
</template>
<template #footer>
<el-button v-if="!isReadonly" @click="submitForm" type="primary" :disabled="formLoading">
<el-button v-if="!isDetail" @click="submitForm" type="primary" :disabled="formLoading">
</el-button>
<el-button @click="dialogVisible = false"> </el-button>
@ -104,25 +104,30 @@
<script setup lang="ts">
import { generateRandomStr } from '@/utils'
import { CommonStatusEnum } from '@/utils/constants'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { StockTakingPlanApi, type StockTakingPlanVO } from '@/api/mes/wm/stocktaking/plan/index'
import {
StockTakingPlanParamApi,
type StockTakingPlanParamVO
} from '@/api/mes/wm/stocktaking/plan/param/index'
import StockTakingParamTable from './components/StockTakingParamTable.vue'
import StockTakingPlanParamList from './StockTakingPlanParamList.vue'
import { MesWmStockTakingTypeEnum } from '@/views/mes/utils/constants'
defineOptions({ name: 'StockTakingPlanForm' })
const emit = defineEmits(['success']) // success
const message = useMessage() //
const { t } = useI18n() //
const dialogVisible = ref(false) //
const dialogTitle = computed(() => {
const titles = {
create: '新增盘点方案',
update: '编辑盘点方案',
detail: '盘点方案详情'
}
return titles[formType.value] || formType.value
}) //
const formLoading = ref(false) // 12
const formType = ref('create') // create - update - detail -
const isDetail = computed(() => formType.value === 'detail') //
const formRef = ref() // Ref
const paramList = ref<StockTakingPlanParamVO[]>([]) //
const formData = ref<StockTakingPlanVO>({
id: undefined,
code: undefined,
@ -140,60 +145,11 @@ const formRules = reactive({
type: [{ required: true, message: '盘点类型不能为空', trigger: 'change' }]
})
const isReadonly = computed(() => formType.value === 'detail') //
const dialogTitle = computed(() => {
const titles = {
create: '新增盘点方案',
update: '编辑盘点方案',
detail: '盘点方案详情'
}
return titles[formType.value] || formType.value
})
/** 生成方案编码 */
const generateCode = () => {
formData.value.code = 'STP' + generateRandomStr(10)
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
code: undefined,
name: undefined,
type: undefined,
startTime: undefined,
endTime: undefined,
blindFlag: false,
frozenFlag: false,
remark: undefined
}
paramList.value = []
formRef.value?.resetFields()
}
const buildValidParams = () => {
return paramList.value.filter(
(item) => item.type && item.valueId !== undefined && item.valueId !== ''
)
}
const syncPlanParams = async (planId: number) => {
const currentParams = buildValidParams()
if (currentParams.length === 0) {
return
}
await Promise.all(
currentParams.map((item) =>
StockTakingPlanParamApi.createStockTakingPlanParam({
...item,
planId,
valueId: Number(item.valueId)
})
)
)
}
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
@ -215,23 +171,36 @@ const submitForm = async () => {
await formRef.value.validate()
formLoading.value = true
try {
let planId = formData.value.id
const data = formData.value as unknown as StockTakingPlanVO
if (formType.value === 'create') {
planId = await StockTakingPlanApi.createStockTakingPlan(formData.value)
message.success('新增成功')
const res = await StockTakingPlanApi.createStockTakingPlan(data)
message.success(t('common.createSuccess'))
formData.value.id = res
formType.value = 'update'
} else {
await StockTakingPlanApi.updateStockTakingPlan(formData.value)
planId = formData.value.id
message.success('修改成功')
await StockTakingPlanApi.updateStockTakingPlan(data)
message.success(t('common.updateSuccess'))
dialogVisible.value = false
}
if (formType.value === 'create') {
formData.value.id = planId
await syncPlanParams(planId!)
}
dialogVisible.value = false
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
code: undefined,
name: undefined,
type: undefined,
startTime: undefined,
endTime: undefined,
blindFlag: false,
frozenFlag: false,
remark: undefined
}
formRef.value?.resetFields()
}
</script>

View File

@ -1,31 +1,36 @@
<!-- TODO @芋艿这里需要在 review -->
<!-- MES 盘点方案条件列表子组件 -->
<template>
<div>
<div class="mb-12px flex items-center justify-between">
<span class="text-14px font-500">盘点范围参数</span>
<el-button type="primary" plain @click="openForm('create')" :disabled="disabled || (isRemoteMode && !planId)">
<Icon icon="ep:plus" class="mr-5px" /> 添加参数
</el-button>
</div>
<el-table v-loading="loading" :data="displayList" border :show-overflow-tooltip="true" empty-text="暂无参数">
<el-table-column label="参数类型" min-width="160">
<el-button
type="primary"
plain
@click="openForm('create')"
:disabled="disabled || (isRemoteMode && !planId)"
class="mb-10px"
>
<Icon icon="ep:plus" class="mr-5px" /> 添加条件
</el-button>
<el-table
v-loading="loading"
:data="displayList"
:stripe="true"
:show-overflow-tooltip="true"
border
>
<el-table-column label="条件类型" align="center" min-width="120">
<template #default="scope">
{{ getTypeLabel(scope.row.type) }}
<dict-tag :type="DICT_TYPE.MES_WM_STOCK_TAKING_PLAN_PARAM_TYPE" :value="scope.row.type" />
</template>
</el-table-column>
<el-table-column label="参数值 ID" min-width="120" prop="valueId" />
<el-table-column label="参数值编码" min-width="160" prop="valueCode" />
<el-table-column label="参数值名称" min-width="180" prop="valueName" />
<el-table-column label="备注" min-width="180" prop="remark" />
<el-table-column v-if="!disabled" label="操作" align="center" width="120" fixed="right">
<el-table-column label="条件值编码" align="center" prop="valueCode" min-width="140" />
<el-table-column label="条件值名称" align="center" prop="valueName" min-width="160" />
<el-table-column v-if="!disabled" label="操作" align="center" width="120">
<template #default="scope">
<el-button link type="primary" @click="openForm('update', scope.row)">编辑</el-button>
<el-button link type="primary" @click="openForm('update', scope.row.id)">编辑</el-button>
<el-button link type="danger" @click="handleDelete(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<Pagination
v-if="isRemoteMode"
:total="total"
@ -35,6 +40,7 @@
/>
</div>
<!-- 添加/编辑条件弹窗 -->
<Dialog :title="dialogTitle" v-model="dialogVisible" width="900px">
<el-form
ref="formRef"
@ -45,15 +51,15 @@
>
<el-row>
<el-col :span="12">
<el-form-item label="参数类型" prop="type">
<el-form-item label="条件类型" prop="type">
<el-select
v-model="formData.type"
placeholder="请选择参数类型"
placeholder="请选择条件类型"
class="!w-full"
@change="handleTypeChange"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.MES_WM_STOCK_TAKING_PARAM_TYPE)"
v-for="dict in getIntDictOptions(DICT_TYPE.MES_WM_STOCK_TAKING_PLAN_PARAM_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
@ -62,28 +68,60 @@
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="参数值" prop="valueId">
<template v-if="formData.type === MesWmStockTakingParamTypeEnum.WAREHOUSE">
<el-form-item label="条件值" prop="valueId">
<template v-if="formData.type === BarcodeBizTypeEnum.WAREHOUSE">
<WmWarehouseSelect
v-model="formData.valueId"
@change="(item) => handleSelectorChange(item)"
/>
</template>
<template v-else-if="formData.type === MesWmStockTakingParamTypeEnum.LOCATION">
<WmWarehouseLocationSelect
<template v-else-if="formData.type === BarcodeBizTypeEnum.LOCATION">
<div class="space-y-2">
<WmWarehouseSelect
v-model="locationWarehouseId"
@change="handleLocationWarehouseChange"
class="!w-1/1"
placeholder="请选择仓库"
/>
<WmWarehouseLocationSelect
v-model="formData.valueId"
:warehouse-id="locationWarehouseId"
@change="(item) => handleSelectorChange(item)"
class="!w-1/1"
placeholder="请选择库区"
/>
</div>
</template>
<template v-else-if="formData.type === BarcodeBizTypeEnum.AREA">
<div class="space-y-2">
<WmWarehouseSelect
v-model="areaWarehouseId"
@change="handleAreaWarehouseChange"
class="!w-1/1"
placeholder="请选择仓库"
/>
<WmWarehouseLocationSelect
v-model="areaLocationId"
:warehouse-id="areaWarehouseId"
@change="handleAreaLocationChange"
class="!w-1/1"
placeholder="请选择库区"
/>
<WmWarehouseAreaSelect
v-model="formData.valueId"
:warehouse-id="areaWarehouseId"
@change="(item) => handleSelectorChange(item)"
class="!w-1/1"
placeholder="请选择库位"
/>
</div>
</template>
<template v-else-if="formData.type === BarcodeBizTypeEnum.ITEM">
<MdItemSelect
v-model="formData.valueId"
@change="(item) => handleSelectorChange(item)"
/>
</template>
<template v-else-if="formData.type === MesWmStockTakingParamTypeEnum.AREA">
<WmWarehouseAreaSelect
v-model="formData.valueId"
@change="(item) => handleSelectorChange(item)"
/>
</template>
<template v-else-if="formData.type === MesWmStockTakingParamTypeEnum.ITEM">
<MdItemSelect v-model="formData.valueId" @change="(item) => handleSelectorChange(item)" />
</template>
<template v-else>
<el-row :gutter="8" class="w-full">
<el-col :span="8">
@ -127,11 +165,15 @@ import {
StockTakingPlanParamApi,
type StockTakingPlanParamVO
} from '@/api/mes/wm/stocktaking/plan/param/index'
import { MesWmStockTakingParamTypeEnum } from '@/views/mes/utils/constants'
import { BarcodeBizTypeEnum } from '@/views/mes/utils/constants'
import WmWarehouseSelect from '@/views/mes/wm/warehouse/components/WmWarehouseSelect.vue'
import WmWarehouseLocationSelect from '@/views/mes/wm/warehouse/components/WmWarehouseLocationSelect.vue'
import WmWarehouseAreaSelect from '@/views/mes/wm/warehouse/components/WmWarehouseAreaSelect.vue'
import MdItemSelect from '@/views/mes/md/item/components/MdItemSelect.vue'
import { WmWarehouseLocationApi } from '@/api/mes/wm/warehouse/location'
import { WmWarehouseAreaApi } from '@/api/mes/wm/warehouse/area'
defineOptions({ name: 'StockTakingPlanParamList' })
interface ParamRow extends StockTakingPlanParamVO {
valueId?: number | string
@ -157,15 +199,8 @@ const emit = defineEmits<{
const { t } = useI18n()
const message = useMessage()
const isRemoteMode = computed(() => !!props.planId)
const typeOptions = computed(() => getIntDictOptions(DICT_TYPE.MES_WM_STOCK_TAKING_PARAM_TYPE))
const localRows = computed({
get: () => props.modelValue || [],
set: (value) => emit('update:modelValue', value)
})
// ==================== ====================
const loading = ref(false)
const formLoading = ref(false)
const list = ref<ParamRow[]>([])
const total = ref(0)
const queryParams = reactive({
@ -174,45 +209,15 @@ const queryParams = reactive({
planId: undefined as number | undefined
})
// TODO @AIisRemoteMode
const isRemoteMode = computed(() => !!props.planId)
const localRows = computed({
get: () => props.modelValue || [],
set: (value) => emit('update:modelValue', value)
})
const displayList = computed(() => (isRemoteMode.value ? list.value : localRows.value))
const dialogVisible = ref(false)
const dialogTitle = ref('')
const dialogType = ref<'create' | 'update'>('create')
const formRef = ref()
const formData = ref<ParamRow>({
id: undefined,
planId: undefined,
type: MesWmStockTakingParamTypeEnum.WAREHOUSE,
valueId: undefined,
valueCode: '',
valueName: '',
remark: ''
})
const editingIndex = ref<number>(-1)
const formRules = reactive({
type: [{ required: true, message: '请选择参数类型', trigger: 'change' }],
valueId: [{ required: true, message: '参数值不能为空', trigger: 'change' }]
})
const getTypeLabel = (type?: number) => {
return typeOptions.value.find((item) => item.value === type)?.label || ''
}
const resetForm = () => {
formData.value = {
id: undefined,
planId: props.planId,
type: MesWmStockTakingParamTypeEnum.WAREHOUSE,
valueId: undefined,
valueCode: '',
valueName: '',
remark: ''
}
editingIndex.value = -1
formRef.value?.resetFields()
}
/** 查询条件列表 */
const getList = async () => {
if (!isRemoteMode.value || !props.planId) {
list.value = []
@ -230,45 +235,81 @@ const getList = async () => {
}
}
const openForm = async (type: 'create' | 'update', row?: ParamRow) => {
dialogVisible.value = true
dialogType.value = type
dialogTitle.value = type === 'create' ? '添加参数' : '编辑参数'
resetForm()
if (type === 'update' && row) {
/** 删除 */
const handleDelete = async (row: ParamRow) => {
try {
await message.delConfirm()
if (isRemoteMode.value && row.id) {
formLoading.value = true
try {
formData.value = (await StockTakingPlanParamApi.getStockTakingPlanParam(row.id)) as ParamRow
} finally {
formLoading.value = false
await StockTakingPlanParamApi.deleteStockTakingPlanParam(row.id)
message.success(t('common.delSuccess'))
// TODO @AI
// 1
if (list.value.length === 1 && queryParams.pageNo > 1) {
queryParams.pageNo -= 1
}
} else {
await getList()
return
}
localRows.value = localRows.value.filter((item) => item !== row)
message.success(t('common.delSuccess'))
} catch {}
}
// ==================== / ====================
const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false)
const formType = ref('')
const formData = ref<ParamRow>({
id: undefined,
planId: undefined,
type: BarcodeBizTypeEnum.WAREHOUSE,
valueId: undefined,
valueCode: '',
valueName: '',
remark: ''
})
const formRules = reactive({
type: [{ required: true, message: '请选择条件类型', trigger: 'change' }],
valueId: [{ required: true, message: '条件值不能为空', trigger: 'change' }]
})
const formRef = ref()
const editingIndex = ref<number>(-1)
const locationWarehouseId = ref<number>() //
const areaWarehouseId = ref<number>() //
const areaLocationId = ref<number>() //
const isLoadingData = ref(false) // watch
/** 打开表单弹窗 */
const openForm = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
if (id) {
formLoading.value = true
isLoadingData.value = true
try {
formData.value = (await StockTakingPlanParamApi.getStockTakingPlanParam(id)) as ParamRow
//
await loadCascadeData()
} finally {
formLoading.value = false
isLoadingData.value = false
}
} else if (type === 'update') {
//
const row = localRows.value.find((item) => item === id)
if (row) {
formData.value = { ...row }
editingIndex.value = localRows.value.findIndex((item) => item === row)
}
}
}
const handleTypeChange = () => {
formData.value.valueId = undefined
formData.value.valueCode = ''
formData.value.valueName = ''
}
const handleSelectorChange = (item?: any) => {
formData.value.valueId = item?.id
formData.value.valueCode = item?.code || ''
formData.value.valueName = item?.name || item?.nickname || ''
}
const handleManualChange = () => {
if (formData.value.valueId !== undefined && formData.value.valueId !== null && formData.value.valueId !== '') {
const num = Number(formData.value.valueId)
formData.value.valueId = Number.isNaN(num) ? formData.value.valueId : num
}
}
/** 提交表单 */
const submitForm = async () => {
await formRef.value.validate()
formLoading.value = true
@ -278,8 +319,9 @@ const submitForm = async () => {
planId: props.planId,
valueId: Number(formData.value.valueId)
} as StockTakingPlanParamVO
if (isRemoteMode.value && props.planId) {
if (dialogType.value === 'create') {
if (formType.value === 'create') {
await StockTakingPlanParamApi.createStockTakingPlanParam(data)
message.success(t('common.createSuccess'))
} else {
@ -291,8 +333,9 @@ const submitForm = async () => {
return
}
//
const nextRows = [...localRows.value]
if (dialogType.value === 'create') {
if (formType.value === 'create') {
nextRows.push({ ...data, planId: undefined })
message.success(t('common.createSuccess'))
} else if (editingIndex.value > -1) {
@ -306,24 +349,107 @@ const submitForm = async () => {
}
}
const handleDelete = async (row: ParamRow) => {
try {
await message.delConfirm()
if (isRemoteMode.value && row.id) {
await StockTakingPlanParamApi.deleteStockTakingPlanParam(row.id)
message.success(t('common.delSuccess'))
if (list.value.length === 1 && queryParams.pageNo > 1) {
queryParams.pageNo -= 1
}
await getList()
return
}
localRows.value = localRows.value.filter((item) => item !== row)
message.success(t('common.delSuccess'))
} catch {}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
planId: props.planId,
type: BarcodeBizTypeEnum.WAREHOUSE,
valueId: undefined,
valueCode: '',
valueName: '',
remark: ''
}
editingIndex.value = -1
formRef.value?.resetFields()
}
/** 条件类型变化 */
const handleTypeChange = () => {
//
if (isLoadingData.value) {
return
}
formData.value.valueId = undefined
formData.value.valueCode = ''
formData.value.valueName = ''
//
locationWarehouseId.value = undefined
areaWarehouseId.value = undefined
areaLocationId.value = undefined
}
/** 选择器变化 */
const handleSelectorChange = (item?: any) => {
formData.value.valueId = item?.id
formData.value.valueCode = item?.code || ''
formData.value.valueName = item?.name || item?.nickname || ''
}
/** 手动输入变化 */
const handleManualChange = () => {
if (
formData.value.valueId !== undefined &&
formData.value.valueId !== null &&
formData.value.valueId !== ''
) {
const num = Number(formData.value.valueId)
formData.value.valueId = Number.isNaN(num) ? formData.value.valueId : num
}
}
/** 库区仓库选择回调:清空库区 */
const handleLocationWarehouseChange = () => {
formData.value.valueId = undefined
formData.value.valueCode = ''
formData.value.valueName = ''
}
/** 库位仓库选择回调:清空库区和库位 */
const handleAreaWarehouseChange = () => {
areaLocationId.value = undefined
formData.value.valueId = undefined
formData.value.valueCode = ''
formData.value.valueName = ''
}
/** 库位库区选择回调:清空库位 */
const handleAreaLocationChange = () => {
formData.value.valueId = undefined
formData.value.valueCode = ''
formData.value.valueName = ''
}
/** 加载级联选择器的数据(编辑时回填上级数据) */
const loadCascadeData = async () => {
if (!formData.value.type || !formData.value.valueId) {
return
}
try {
// ID
if (formData.value.type === BarcodeBizTypeEnum.LOCATION) {
const location = await WmWarehouseLocationApi.getWarehouseLocation(formData.value.valueId)
if (location?.warehouseId) {
locationWarehouseId.value = location.warehouseId
}
}
// IDID
else if (formData.value.type === BarcodeBizTypeEnum.AREA) {
const area = await WmWarehouseAreaApi.getWarehouseArea(formData.value.valueId)
if (area?.warehouseId) {
areaWarehouseId.value = area.warehouseId
}
if (area?.locationId) {
areaLocationId.value = area.locationId
}
}
} catch (error) {
console.error('加载级联数据失败:', error)
}
}
/** 监听 planId 变化 */
watch(
() => props.planId,
async (value) => {