✨ feat(mes): 添加盘点方案状态更新功能及参数校验
新增更新盘点方案状态的接口,确保在启用状态时,相关参数不为空。 同时,更新了相关权限控制和错误码定义,提升了系统的健壮性和用户体验。pull/871/MERGE
parent
ca2447f710
commit
9a6cd0f6cb
|
|
@ -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 })
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -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 装箱单状态
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
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>
|
||||
|
|
|
|||
|
|
@ -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 @AI:isRemoteMode 字段不需要?
|
||||
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
|
||||
}
|
||||
}
|
||||
// 库位类型:需要查询库位信息,获取所属仓库ID和库区ID
|
||||
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) => {
|
||||
Loading…
Reference in New Issue