✨ feat(mes): 添加盘点方案状态更新功能及参数校验
新增更新盘点方案状态的接口,确保在启用状态时,相关参数不为空。 同时,更新了相关权限控制和错误码定义,提升了系统的健壮性和用户体验。pull/871/MERGE
parent
ca2447f710
commit
9a6cd0f6cb
|
|
@ -10,18 +10,12 @@ export interface StockTakingPlanParamVO {
|
||||||
remark?: string
|
remark?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StockTakingPlanParamPageReqVO {
|
|
||||||
pageNo: number
|
|
||||||
pageSize: number
|
|
||||||
planId: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export const StockTakingPlanParamApi = {
|
export const StockTakingPlanParamApi = {
|
||||||
getStockTakingPlanParam: async (id: number) => {
|
getStockTakingPlanParam: async (id: number) => {
|
||||||
return await request.get({ url: '/mes/wm/stocktaking-plan-param/get?id=' + id })
|
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 })
|
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_STATUS = 'mes_wm_transfer_status', // MES 转移单状态
|
||||||
MES_WM_TRANSFER_TYPE = 'mes_wm_transfer_type', // 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_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_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_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_OUTSOURCE_RECPT_STATUS = 'mes_wm_outsource_recpt_status', // MES 外协入库单状态
|
||||||
MES_WM_PRODUCTION_ISSUE_STATUS = 'mes_wm_production_issue_status', // MES 领料出库单状态
|
MES_WM_PRODUCTION_ISSUE_STATUS = 'mes_wm_production_issue_status', // MES 领料出库单状态
|
||||||
MES_PRODUCT_PRODUCE_STATUS = 'mes_product_produce_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_MD_AUTO_CODE_CYCLE_METHOD = 'mes_md_auto_code_cycle_method', // MES 编码规则循环方式
|
||||||
MES_WM_BARCODE_FORMAT = 'mes_wm_barcode_format', // MES 条码格式
|
MES_WM_BARCODE_FORMAT = 'mes_wm_barcode_format', // MES 条码格式
|
||||||
MES_WM_BARCODE_BIZ_TYPE = 'mes_wm_barcode_biz_type', // 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)
|
await WmSalesNoticeApi.updateSalesNotice(data)
|
||||||
message.success(t('common.updateSuccess'))
|
message.success(t('common.updateSuccess'))
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
emit('success')
|
|
||||||
}
|
}
|
||||||
|
emit('success')
|
||||||
} finally {
|
} finally {
|
||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="方案编码" prop="code">
|
<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>
|
<template #append>
|
||||||
<el-button @click="generateCode" :disabled="formType !== 'create'">生成</el-button>
|
<el-button @click="generateCode" :disabled="formType !== 'create'">生成</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="方案名称" prop="name">
|
<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-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
v-model="formData.type"
|
v-model="formData.type"
|
||||||
placeholder="请选择盘点类型"
|
placeholder="请选择盘点类型"
|
||||||
class="!w-full"
|
class="!w-full"
|
||||||
:disabled="isReadonly"
|
:disabled="isDetail"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.MES_WM_STOCK_TAKING_TYPE)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.MES_WM_STOCK_TAKING_TYPE)"
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12" v-if="formData.type === MesWmStockTakingTypeEnum.DYNAMIC">
|
||||||
<el-form-item label="开始时间" prop="startTime">
|
<el-form-item label="开始时间" prop="startTime">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="formData.startTime"
|
v-model="formData.startTime"
|
||||||
|
|
@ -48,11 +48,11 @@
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
placeholder="请选择开始时间"
|
placeholder="请选择开始时间"
|
||||||
class="!w-full"
|
class="!w-full"
|
||||||
:disabled="isReadonly"
|
:disabled="isDetail"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12" v-if="formData.type === MesWmStockTakingTypeEnum.DYNAMIC">
|
||||||
<el-form-item label="结束时间" prop="endTime">
|
<el-form-item label="结束时间" prop="endTime">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="formData.endTime"
|
v-model="formData.endTime"
|
||||||
|
|
@ -60,18 +60,18 @@
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
placeholder="请选择结束时间"
|
placeholder="请选择结束时间"
|
||||||
class="!w-full"
|
class="!w-full"
|
||||||
:disabled="isReadonly"
|
:disabled="isDetail"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="是否盲盘" prop="blindFlag">
|
<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-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="冻结库存" prop="frozenFlag">
|
<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-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
|
|
@ -80,7 +80,7 @@
|
||||||
v-model="formData.remark"
|
v-model="formData.remark"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
placeholder="请输入备注"
|
placeholder="请输入备注"
|
||||||
:disabled="isReadonly"
|
:disabled="isDetail"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
@ -90,11 +90,11 @@
|
||||||
<!-- 编辑时展示盘点参数 -->
|
<!-- 编辑时展示盘点参数 -->
|
||||||
<template v-if="formType === 'update' && formData.id">
|
<template v-if="formType === 'update' && formData.id">
|
||||||
<el-divider content-position="center">盘点参数</el-divider>
|
<el-divider content-position="center">盘点参数</el-divider>
|
||||||
<StockTakingParamTable :plan-id="formData.id" />
|
<StockTakingPlanParamList :plan-id="formData.id" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #footer>
|
<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>
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
|
@ -104,25 +104,30 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { generateRandomStr } from '@/utils'
|
import { generateRandomStr } from '@/utils'
|
||||||
import { CommonStatusEnum } from '@/utils/constants'
|
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import { StockTakingPlanApi, type StockTakingPlanVO } from '@/api/mes/wm/stocktaking/plan/index'
|
import { StockTakingPlanApi, type StockTakingPlanVO } from '@/api/mes/wm/stocktaking/plan/index'
|
||||||
import {
|
import StockTakingPlanParamList from './StockTakingPlanParamList.vue'
|
||||||
StockTakingPlanParamApi,
|
import { MesWmStockTakingTypeEnum } from '@/views/mes/utils/constants'
|
||||||
type StockTakingPlanParamVO
|
|
||||||
} from '@/api/mes/wm/stocktaking/plan/param/index'
|
|
||||||
import StockTakingParamTable from './components/StockTakingParamTable.vue'
|
|
||||||
|
|
||||||
defineOptions({ name: 'StockTakingPlanForm' })
|
defineOptions({ name: 'StockTakingPlanForm' })
|
||||||
|
|
||||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
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 formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
const formType = ref('create') // 表单的类型:create - 新增;update - 修改;detail - 详情
|
const formType = ref('create') // 表单的类型:create - 新增;update - 修改;detail - 详情
|
||||||
|
const isDetail = computed(() => formType.value === 'detail') // 是否只读
|
||||||
const formRef = ref() // 表单 Ref
|
const formRef = ref() // 表单 Ref
|
||||||
const paramList = ref<StockTakingPlanParamVO[]>([]) // 新建方案时的本地参数列表
|
|
||||||
const formData = ref<StockTakingPlanVO>({
|
const formData = ref<StockTakingPlanVO>({
|
||||||
id: undefined,
|
id: undefined,
|
||||||
code: undefined,
|
code: undefined,
|
||||||
|
|
@ -140,60 +145,11 @@ const formRules = reactive({
|
||||||
type: [{ required: true, message: '盘点类型不能为空', trigger: 'change' }]
|
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 = () => {
|
const generateCode = () => {
|
||||||
formData.value.code = 'STP' + generateRandomStr(10)
|
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) => {
|
const open = async (type: string, id?: number) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
|
|
@ -215,23 +171,36 @@ const submitForm = async () => {
|
||||||
await formRef.value.validate()
|
await formRef.value.validate()
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
let planId = formData.value.id
|
const data = formData.value as unknown as StockTakingPlanVO
|
||||||
if (formType.value === 'create') {
|
if (formType.value === 'create') {
|
||||||
planId = await StockTakingPlanApi.createStockTakingPlan(formData.value)
|
const res = await StockTakingPlanApi.createStockTakingPlan(data)
|
||||||
message.success('新增成功')
|
message.success(t('common.createSuccess'))
|
||||||
|
formData.value.id = res
|
||||||
|
formType.value = 'update'
|
||||||
} else {
|
} else {
|
||||||
await StockTakingPlanApi.updateStockTakingPlan(formData.value)
|
await StockTakingPlanApi.updateStockTakingPlan(data)
|
||||||
planId = formData.value.id
|
message.success(t('common.updateSuccess'))
|
||||||
message.success('修改成功')
|
dialogVisible.value = false
|
||||||
}
|
}
|
||||||
if (formType.value === 'create') {
|
|
||||||
formData.value.id = planId
|
|
||||||
await syncPlanParams(planId!)
|
|
||||||
}
|
|
||||||
dialogVisible.value = false
|
|
||||||
emit('success')
|
emit('success')
|
||||||
} finally {
|
} finally {
|
||||||
formLoading.value = false
|
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>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,36 @@
|
||||||
<!-- TODO @芋艿:这里需要在 review 下; -->
|
<!-- MES 盘点方案条件列表子组件 -->
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-12px flex items-center justify-between">
|
<el-button
|
||||||
<span class="text-14px font-500">盘点范围参数</span>
|
type="primary"
|
||||||
<el-button type="primary" plain @click="openForm('create')" :disabled="disabled || (isRemoteMode && !planId)">
|
plain
|
||||||
<Icon icon="ep:plus" class="mr-5px" /> 添加参数
|
@click="openForm('create')"
|
||||||
</el-button>
|
:disabled="disabled || (isRemoteMode && !planId)"
|
||||||
</div>
|
class="mb-10px"
|
||||||
|
>
|
||||||
<el-table v-loading="loading" :data="displayList" border :show-overflow-tooltip="true" empty-text="暂无参数">
|
<Icon icon="ep:plus" class="mr-5px" /> 添加条件
|
||||||
<el-table-column label="参数类型" min-width="160">
|
</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">
|
<template #default="scope">
|
||||||
{{ getTypeLabel(scope.row.type) }}
|
<dict-tag :type="DICT_TYPE.MES_WM_STOCK_TAKING_PLAN_PARAM_TYPE" :value="scope.row.type" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="参数值 ID" min-width="120" prop="valueId" />
|
<el-table-column label="条件值编码" align="center" prop="valueCode" min-width="140" />
|
||||||
<el-table-column label="参数值编码" min-width="160" prop="valueCode" />
|
<el-table-column label="条件值名称" align="center" prop="valueName" min-width="160" />
|
||||||
<el-table-column label="参数值名称" min-width="180" prop="valueName" />
|
<el-table-column v-if="!disabled" label="操作" align="center" width="120">
|
||||||
<el-table-column label="备注" min-width="180" prop="remark" />
|
|
||||||
<el-table-column v-if="!disabled" label="操作" align="center" width="120" fixed="right">
|
|
||||||
<template #default="scope">
|
<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>
|
<el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<Pagination
|
<Pagination
|
||||||
v-if="isRemoteMode"
|
v-if="isRemoteMode"
|
||||||
:total="total"
|
:total="total"
|
||||||
|
|
@ -35,6 +40,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 添加/编辑条件弹窗 -->
|
||||||
<Dialog :title="dialogTitle" v-model="dialogVisible" width="900px">
|
<Dialog :title="dialogTitle" v-model="dialogVisible" width="900px">
|
||||||
<el-form
|
<el-form
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
|
|
@ -45,15 +51,15 @@
|
||||||
>
|
>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="参数类型" prop="type">
|
<el-form-item label="条件类型" prop="type">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formData.type"
|
v-model="formData.type"
|
||||||
placeholder="请选择参数类型"
|
placeholder="请选择条件类型"
|
||||||
class="!w-full"
|
class="!w-full"
|
||||||
@change="handleTypeChange"
|
@change="handleTypeChange"
|
||||||
>
|
>
|
||||||
<el-option
|
<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"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
|
|
@ -62,28 +68,60 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="参数值" prop="valueId">
|
<el-form-item label="条件值" prop="valueId">
|
||||||
<template v-if="formData.type === MesWmStockTakingParamTypeEnum.WAREHOUSE">
|
<template v-if="formData.type === BarcodeBizTypeEnum.WAREHOUSE">
|
||||||
<WmWarehouseSelect
|
<WmWarehouseSelect
|
||||||
v-model="formData.valueId"
|
v-model="formData.valueId"
|
||||||
@change="(item) => handleSelectorChange(item)"
|
@change="(item) => handleSelectorChange(item)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="formData.type === MesWmStockTakingParamTypeEnum.LOCATION">
|
<template v-else-if="formData.type === BarcodeBizTypeEnum.LOCATION">
|
||||||
<WmWarehouseLocationSelect
|
<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"
|
v-model="formData.valueId"
|
||||||
@change="(item) => handleSelectorChange(item)"
|
@change="(item) => handleSelectorChange(item)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</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>
|
<template v-else>
|
||||||
<el-row :gutter="8" class="w-full">
|
<el-row :gutter="8" class="w-full">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
|
|
@ -127,11 +165,15 @@ import {
|
||||||
StockTakingPlanParamApi,
|
StockTakingPlanParamApi,
|
||||||
type StockTakingPlanParamVO
|
type StockTakingPlanParamVO
|
||||||
} from '@/api/mes/wm/stocktaking/plan/param/index'
|
} 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 WmWarehouseSelect from '@/views/mes/wm/warehouse/components/WmWarehouseSelect.vue'
|
||||||
import WmWarehouseLocationSelect from '@/views/mes/wm/warehouse/components/WmWarehouseLocationSelect.vue'
|
import WmWarehouseLocationSelect from '@/views/mes/wm/warehouse/components/WmWarehouseLocationSelect.vue'
|
||||||
import WmWarehouseAreaSelect from '@/views/mes/wm/warehouse/components/WmWarehouseAreaSelect.vue'
|
import WmWarehouseAreaSelect from '@/views/mes/wm/warehouse/components/WmWarehouseAreaSelect.vue'
|
||||||
import MdItemSelect from '@/views/mes/md/item/components/MdItemSelect.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 {
|
interface ParamRow extends StockTakingPlanParamVO {
|
||||||
valueId?: number | string
|
valueId?: number | string
|
||||||
|
|
@ -157,15 +199,8 @@ const emit = defineEmits<{
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const message = useMessage()
|
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 loading = ref(false)
|
||||||
const formLoading = ref(false)
|
|
||||||
const list = ref<ParamRow[]>([])
|
const list = ref<ParamRow[]>([])
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
|
|
@ -174,45 +209,15 @@ const queryParams = reactive({
|
||||||
planId: undefined as number | undefined
|
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 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 () => {
|
const getList = async () => {
|
||||||
if (!isRemoteMode.value || !props.planId) {
|
if (!isRemoteMode.value || !props.planId) {
|
||||||
list.value = []
|
list.value = []
|
||||||
|
|
@ -230,45 +235,81 @@ const getList = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const openForm = async (type: 'create' | 'update', row?: ParamRow) => {
|
/** 删除 */
|
||||||
dialogVisible.value = true
|
const handleDelete = async (row: ParamRow) => {
|
||||||
dialogType.value = type
|
try {
|
||||||
dialogTitle.value = type === 'create' ? '添加参数' : '编辑参数'
|
await message.delConfirm()
|
||||||
resetForm()
|
|
||||||
if (type === 'update' && row) {
|
|
||||||
if (isRemoteMode.value && row.id) {
|
if (isRemoteMode.value && row.id) {
|
||||||
formLoading.value = true
|
await StockTakingPlanParamApi.deleteStockTakingPlanParam(row.id)
|
||||||
try {
|
message.success(t('common.delSuccess'))
|
||||||
formData.value = (await StockTakingPlanParamApi.getStockTakingPlanParam(row.id)) as ParamRow
|
// TODO @AI:不用这个;
|
||||||
} finally {
|
// 如果是最后一条且不是第一页,页码减1
|
||||||
formLoading.value = false
|
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 }
|
formData.value = { ...row }
|
||||||
editingIndex.value = localRows.value.findIndex((item) => item === 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 () => {
|
const submitForm = async () => {
|
||||||
await formRef.value.validate()
|
await formRef.value.validate()
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
|
|
@ -278,8 +319,9 @@ const submitForm = async () => {
|
||||||
planId: props.planId,
|
planId: props.planId,
|
||||||
valueId: Number(formData.value.valueId)
|
valueId: Number(formData.value.valueId)
|
||||||
} as StockTakingPlanParamVO
|
} as StockTakingPlanParamVO
|
||||||
|
|
||||||
if (isRemoteMode.value && props.planId) {
|
if (isRemoteMode.value && props.planId) {
|
||||||
if (dialogType.value === 'create') {
|
if (formType.value === 'create') {
|
||||||
await StockTakingPlanParamApi.createStockTakingPlanParam(data)
|
await StockTakingPlanParamApi.createStockTakingPlanParam(data)
|
||||||
message.success(t('common.createSuccess'))
|
message.success(t('common.createSuccess'))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -291,8 +333,9 @@ const submitForm = async () => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 本地模式
|
||||||
const nextRows = [...localRows.value]
|
const nextRows = [...localRows.value]
|
||||||
if (dialogType.value === 'create') {
|
if (formType.value === 'create') {
|
||||||
nextRows.push({ ...data, planId: undefined })
|
nextRows.push({ ...data, planId: undefined })
|
||||||
message.success(t('common.createSuccess'))
|
message.success(t('common.createSuccess'))
|
||||||
} else if (editingIndex.value > -1) {
|
} else if (editingIndex.value > -1) {
|
||||||
|
|
@ -306,24 +349,107 @@ const submitForm = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDelete = async (row: ParamRow) => {
|
/** 重置表单 */
|
||||||
try {
|
const resetForm = () => {
|
||||||
await message.delConfirm()
|
formData.value = {
|
||||||
if (isRemoteMode.value && row.id) {
|
id: undefined,
|
||||||
await StockTakingPlanParamApi.deleteStockTakingPlanParam(row.id)
|
planId: props.planId,
|
||||||
message.success(t('common.delSuccess'))
|
type: BarcodeBizTypeEnum.WAREHOUSE,
|
||||||
if (list.value.length === 1 && queryParams.pageNo > 1) {
|
valueId: undefined,
|
||||||
queryParams.pageNo -= 1
|
valueCode: '',
|
||||||
}
|
valueName: '',
|
||||||
await getList()
|
remark: ''
|
||||||
return
|
}
|
||||||
}
|
editingIndex.value = -1
|
||||||
|
formRef.value?.resetFields()
|
||||||
localRows.value = localRows.value.filter((item) => item !== row)
|
|
||||||
message.success(t('common.delSuccess'))
|
|
||||||
} catch {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 条件类型变化 */
|
||||||
|
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(
|
watch(
|
||||||
() => props.planId,
|
() => props.planId,
|
||||||
async (value) => {
|
async (value) => {
|
||||||
Loading…
Reference in New Issue