优化
This commit is contained in:
		| @ -133,7 +133,7 @@ | |||||||
|               </el-select> |               </el-select> | ||||||
|             </template> |             </template> | ||||||
|           </el-table-column> |           </el-table-column> | ||||||
|           <!-- 物资名称列 --> |           <!-- 物资名称列(核心修改:动态过滤已选选项) --> | ||||||
|           <el-table-column prop="name" align="center" label="物资名称" width="160"> |           <el-table-column prop="name" align="center" label="物资名称" width="160"> | ||||||
|             <template #default="scope"> |             <template #default="scope"> | ||||||
|               <el-input v-model="scope.row.name" v-if="scope.row.mrpBaseId" placeholder="请输入物资名称" disabled /> |               <el-input v-model="scope.row.name" v-if="scope.row.mrpBaseId" placeholder="请输入物资名称" disabled /> | ||||||
| @ -144,7 +144,13 @@ | |||||||
|                 placeholder="请选择" |                 placeholder="请选择" | ||||||
|                 @change="(val) => selectName(val, scope.row, scope.$index)" |                 @change="(val) => selectName(val, scope.row, scope.$index)" | ||||||
|               > |               > | ||||||
|                 <el-option v-for="item in nameList" :key="item.id" :label="item.name" :value="item.id" /> |                 <!-- 动态过滤:排除当前行外已选中的物资ID --> | ||||||
|  |                 <el-option  | ||||||
|  |                   v-for="item in getAvailableNameList(scope.$index)"  | ||||||
|  |                   :key="item.id"  | ||||||
|  |                   :label="item.name"  | ||||||
|  |                   :value="item.id"  | ||||||
|  |                 /> | ||||||
|               </el-select> |               </el-select> | ||||||
|             </template> |             </template> | ||||||
|           </el-table-column> |           </el-table-column> | ||||||
| @ -152,24 +158,21 @@ | |||||||
|           <el-table-column align="center" label="剩余量" width="80"> |           <el-table-column align="center" label="剩余量" width="80"> | ||||||
|             <template #default="scope"> |             <template #default="scope"> | ||||||
|               <span>{{ scope.row.Remaining }}</span> |               <span>{{ scope.row.Remaining }}</span> | ||||||
|               <!-- <el-input disabled v-model="scope.row.Remaining" placeholder="剩余量" /> --> |  | ||||||
|             </template> |             </template> | ||||||
|           </el-table-column> |           </el-table-column> | ||||||
|           <!-- 规格型号列 --> |           <!-- 规格型号列 --> | ||||||
|           <el-table-column prop="specification" align="center" label="规格型号" width="100"> |           <el-table-column prop="specification" align="center" label="规格型号" width="100"> | ||||||
|             <template #default="scope"> |             <template #default="scope"> | ||||||
|               <span>{{ scope.row.specification }}</span> |               <span>{{ scope.row.specification }}</span> | ||||||
|               <!-- <el-input v-model="scope.row.specification" placeholder="请输入规格型号" disabled /> --> |  | ||||||
|             </template> |             </template> | ||||||
|           </el-table-column> |           </el-table-column> | ||||||
|           <!-- 单位列 --> |           <!-- 单位列 --> | ||||||
|           <el-table-column prop="unit" align="center" label="单位" width="80"> |           <el-table-column prop="unit" align="center" label="单位" width="80"> | ||||||
|             <template #default="scope"> |             <template #default="scope"> | ||||||
|               <span>{{ scope.row.unit }}</span> |               <span>{{ scope.row.unit }}</span> | ||||||
|               <!-- <el-input v-model="scope.row.unit" placeholder="请输入单位" disabled /> --> |  | ||||||
|             </template> |             </template> | ||||||
|           </el-table-column> |           </el-table-column> | ||||||
|           <!-- 数量列(新增错误提示展示) --> |           <!-- 数量列 --> | ||||||
|           <el-table-column prop="demandQuantity" align="center" label="数量" width="140"> |           <el-table-column prop="demandQuantity" align="center" label="数量" width="140"> | ||||||
|             <template #default="scope"> |             <template #default="scope"> | ||||||
|               <el-input |               <el-input | ||||||
| @ -181,7 +184,7 @@ | |||||||
|                 type="number" |                 type="number" | ||||||
|                 min="0" |                 min="0" | ||||||
|               /> |               /> | ||||||
|               <!-- 数量错误提示(红色小字体) --> |               <!-- 数量错误提示 --> | ||||||
|               <div v-if="scope.row.quantityError" class="text-red-500 text-xs mt-1">{{ scope.row.quantityError }}</div> |               <div v-if="scope.row.quantityError" class="text-red-500 text-xs mt-1">{{ scope.row.quantityError }}</div> | ||||||
|             </template> |             </template> | ||||||
|           </el-table-column> |           </el-table-column> | ||||||
| @ -239,7 +242,7 @@ import { | |||||||
| } from '@/api/materials/batchPlan'; | } from '@/api/materials/batchPlan'; | ||||||
| import { CailiaoshebeiVO, CailiaoshebeiQuery, CailiaoshebeiForm } from '@/api/materials/batchPlan/types'; | import { CailiaoshebeiVO, CailiaoshebeiQuery, CailiaoshebeiForm } from '@/api/materials/batchPlan/types'; | ||||||
| import { useUserStoreHook } from '@/store/modules/user'; | import { useUserStoreHook } from '@/store/modules/user'; | ||||||
| import { getCurrentInstance, ComponentInternalInstance, watch, onMounted, onUnmounted } from 'vue'; | import { getCurrentInstance, ComponentInternalInstance, watch, onMounted, onUnmounted, computed } from 'vue'; | ||||||
| import type { ElFormInstance } from 'element-plus'; | import type { ElFormInstance } from 'element-plus'; | ||||||
|  |  | ||||||
| // 类型定义补充 | // 类型定义补充 | ||||||
| @ -302,7 +305,7 @@ const dialog = reactive<DialogOption>({ | |||||||
|   title: '' |   title: '' | ||||||
| }); | }); | ||||||
|  |  | ||||||
| // 初始化表单数据(补充版本号、重复错误提示字段) | // 初始化表单数据 | ||||||
| const initFormData: FormData = { | const initFormData: FormData = { | ||||||
|   mrpBaseBo: { |   mrpBaseBo: { | ||||||
|     id: undefined, |     id: undefined, | ||||||
| @ -323,10 +326,10 @@ const initFormData: FormData = { | |||||||
|       qs: undefined, |       qs: undefined, | ||||||
|       arrivalTime: undefined, |       arrivalTime: undefined, | ||||||
|       remark: undefined, |       remark: undefined, | ||||||
|       Remaining: 0, // 初始化剩余量 |       Remaining: 0, | ||||||
|       quantityError: '', // 初始化数量错误提示 |       quantityError: '', | ||||||
|       batchNumber: undefined, // 初始化版本号 |       batchNumber: undefined, | ||||||
|       duplicateError: '', // 初始化重复错误提示 |       duplicateError: '', | ||||||
|       mrpBaseId: undefined |       mrpBaseId: undefined | ||||||
|     } |     } | ||||||
|   ] |   ] | ||||||
| @ -390,7 +393,7 @@ const validateDemandQuantity = (row: PlanListItem, index: number) => { | |||||||
|   // 1. 清除之前的错误信息 |   // 1. 清除之前的错误信息 | ||||||
|   row.quantityError = ''; |   row.quantityError = ''; | ||||||
|  |  | ||||||
|   // 2. 处理空值(若需必填可补充:row.quantityError = '数量不能为空') |   // 2. 处理空值 | ||||||
|   if (row.demandQuantity === null || row.demandQuantity === undefined || row.demandQuantity === '') { |   if (row.demandQuantity === null || row.demandQuantity === undefined || row.demandQuantity === '') { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| @ -426,42 +429,20 @@ const getMrpBaseRemaining = async (suppliespriceId: number, row: PlanListItem) = | |||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** 校验重复数据:版本号+物资名称不能重复 */ | /** 获取可用物资列表(过滤已选选项) */ | ||||||
| const checkDuplicate = () => { | const getAvailableNameList = (currentIndex: number) => { | ||||||
|   const planList = form.value.planList; |   // 收集除当前行外已选中的物资ID | ||||||
|   let hasDuplicate = false; |   const selectedIds = form.value.planList | ||||||
|  |     .filter((_, index) => index !== currentIndex) | ||||||
|  |     .map(item => item.suppliespriceId) | ||||||
|  |     .filter(id => id !== undefined && id !== null); | ||||||
|  |  | ||||||
|   // 1. 清除所有重复错误提示 |   // 过滤掉已选中的物资 | ||||||
|   planList.forEach((item) => { |   return nameList.value.filter(item => !selectedIds.includes(item.id)); | ||||||
|     item.duplicateError = ''; |  | ||||||
|   }); |  | ||||||
|  |  | ||||||
|   // 2. 遍历校验重复(只校验版本号和物资名称都存在的行) |  | ||||||
|   for (let i = 0; i < planList.length; i++) { |  | ||||||
|     const current = planList[i]; |  | ||||||
|     // 跳过版本号或物资名称为空的行 |  | ||||||
|     if (!current.batchNumber || !current.suppliespriceId) continue; |  | ||||||
|  |  | ||||||
|     for (let j = i + 1; j < planList.length; j++) { |  | ||||||
|       const compare = planList[j]; |  | ||||||
|       if (!compare.batchNumber || !compare.suppliespriceId) continue; |  | ||||||
|  |  | ||||||
|       // 版本号和物资ID都相同则判定为重复 |  | ||||||
|       if (current.batchNumber === compare.batchNumber && current.suppliespriceId === compare.suppliespriceId) { |  | ||||||
|         current.duplicateError = `与第${j + 1}行重复(同版本+同物资)`; |  | ||||||
|         compare.duplicateError = `与第${i + 1}行重复(同版本+同物资)`; |  | ||||||
|         hasDuplicate = true; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return hasDuplicate; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** 选择物资名称触发(新增索引参数,用于触发重复校验) */ | /** 选择物资名称触发 */ | ||||||
| const selectName = (val: number, row: PlanListItem, index: number) => { | const selectName = (val: number, row: PlanListItem, index: number) => { | ||||||
|   console.log(row); |  | ||||||
|  |  | ||||||
|   // 1. 获取剩余量并更新基础信息 |   // 1. 获取剩余量并更新基础信息 | ||||||
|   getMrpBaseRemaining(val, row).then(() => { |   getMrpBaseRemaining(val, row).then(() => { | ||||||
|     const selected = nameList.value.find((item: any) => item.id === val); |     const selected = nameList.value.find((item: any) => item.id === val); | ||||||
| @ -473,9 +454,6 @@ const selectName = (val: number, row: PlanListItem, index: number) => { | |||||||
|       row.remark = selected.remark || ''; |       row.remark = selected.remark || ''; | ||||||
|       row.arrivalTime = selected.arrivalTime || ''; |       row.arrivalTime = selected.arrivalTime || ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // 2. 触发重复校验 |  | ||||||
|     checkDuplicate(); |  | ||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -514,8 +492,6 @@ const delRow = (index: number) => { | |||||||
|     return proxy?.$modal.msgWarning('请至少保留一项物资数据'); |     return proxy?.$modal.msgWarning('请至少保留一项物资数据'); | ||||||
|   } |   } | ||||||
|   form.value.planList.splice(index, 1); |   form.value.planList.splice(index, 1); | ||||||
|   // 删除后重新校验重复(避免删除重复行后错误提示残留) |  | ||||||
|   checkDuplicate(); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** 新增表格行 */ | /** 新增表格行 */ | ||||||
| @ -577,15 +553,15 @@ const handleUpdata = () => { | |||||||
|   if (!queryParams.value.mainData.mrpBaseId) { |   if (!queryParams.value.mainData.mrpBaseId) { | ||||||
|     return proxy?.$modal.msgError('请先选择批次'); |     return proxy?.$modal.msgError('请先选择批次'); | ||||||
|   } |   } | ||||||
|   // 1. 获取对应版本的物资列表 |   // 获取对应版本的物资列表 | ||||||
|   reset(); |   reset(); | ||||||
|   loading.value = true; |   loading.value = true; | ||||||
|   getCailiaoshebei(queryParams.value.mainData.mrpBaseId) |   getCailiaoshebei(queryParams.value.mainData.mrpBaseId) | ||||||
|     .then((res: any) => { |     .then((res: any) => { | ||||||
|       // 1. 更新基础信息 |       // 更新基础信息 | ||||||
|       form.value.mrpBaseBo = res.data.mrpBaseBo || initFormData.mrpBaseBo; |       form.value.mrpBaseBo = res.data.mrpBaseBo || initFormData.mrpBaseBo; | ||||||
|  |  | ||||||
|       // 2. 更新表格数据(补充缺失字段) |       // 更新表格数据(补充缺失字段) | ||||||
|       form.value.planList = (res.data.planList || []).map((item: any) => ({ |       form.value.planList = (res.data.planList || []).map((item: any) => ({ | ||||||
|         id: item.id, |         id: item.id, | ||||||
|         name: item.name, |         name: item.name, | ||||||
| @ -597,13 +573,12 @@ const handleUpdata = () => { | |||||||
|         arrivalTime: item.arrivalTime, |         arrivalTime: item.arrivalTime, | ||||||
|         remark: item.remark, |         remark: item.remark, | ||||||
|         Remaining: Number(item.remaining) || 0, |         Remaining: Number(item.remaining) || 0, | ||||||
|         // remaining: |  | ||||||
|         quantityError: '', |         quantityError: '', | ||||||
|         batchNumber: item.batchNumber, |         batchNumber: item.batchNumber, | ||||||
|         duplicateError: '', |         duplicateError: '', | ||||||
|         mrpBaseId: item.mrpBaseId |         mrpBaseId: item.mrpBaseId | ||||||
|       })); |       })); | ||||||
|       // 3. 打开对话框 |       // 打开对话框 | ||||||
|       dialog.visible = true; |       dialog.visible = true; | ||||||
|       dialog.title = '修改物资-需求'; |       dialog.title = '修改物资-需求'; | ||||||
|     }) |     }) | ||||||
| @ -617,38 +592,32 @@ const handleUpdata = () => { | |||||||
|  |  | ||||||
| /** 提交数据(整合所有校验) */ | /** 提交数据(整合所有校验) */ | ||||||
| const submitTransferForm = async () => { | const submitTransferForm = async () => { | ||||||
|   // 1. 先校验重复数据 |   // 1. 校验数量合法性(检查是否有数量错误) | ||||||
|   const hasDuplicate = checkDuplicate(); |  | ||||||
|   if (hasDuplicate) { |  | ||||||
|     return proxy?.$modal.msgError('存在重复的版本号+物资组合,请修正后提交'); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // 2. 校验数量合法性(检查是否有数量错误) |  | ||||||
|   const hasQuantityError = form.value.planList.some((row) => row.quantityError); |   const hasQuantityError = form.value.planList.some((row) => row.quantityError); | ||||||
|   if (hasQuantityError) { |   if (hasQuantityError) { | ||||||
|     return proxy?.$modal.msgError('存在非法数量,请修正后提交'); |     return proxy?.$modal.msgError('存在非法数量,请修正后提交'); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // 3. 执行表单基础验证 |   // 2. 执行表单基础验证 | ||||||
|   const result = validateAndClean(form.value.planList); |   const result = validateAndClean(form.value.planList); | ||||||
|   if (!result.valid) { |   if (!result.valid) { | ||||||
|     return proxy?.$modal.msgError(result.message); |     return proxy?.$modal.msgError(result.message); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // 4. 表单组件验证 |   // 3. 表单组件验证 | ||||||
|   cailiaoshebeiFormRef.value?.validate(async (valid: boolean) => { |   cailiaoshebeiFormRef.value?.validate(async (valid: boolean) => { | ||||||
|     if (!valid) return; |     if (!valid) return; | ||||||
|  |  | ||||||
|     buttonLoading.value = true; |     buttonLoading.value = true; | ||||||
|     try { |     try { | ||||||
|       // 5. 提交数据 |       // 4. 提交数据 | ||||||
|       await updateCailiaoshebei({ |       await updateCailiaoshebei({ | ||||||
|         ...form.value, |         ...form.value, | ||||||
|         planList: result.data // 使用清洗后的数据 |         planList: result.data // 使用清洗后的数据 | ||||||
|       }); |       }); | ||||||
|       proxy?.$modal.msgSuccess('操作成功'); |       proxy?.$modal.msgSuccess('操作成功'); | ||||||
|       dialog.visible = false; |       dialog.visible = false; | ||||||
|       // 6. 刷新列表 |       // 5. 刷新列表 | ||||||
|       await getList(); |       await getList(); | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|       proxy?.$modal.msgError('操作失败,请重试'); |       proxy?.$modal.msgError('操作失败,请重试'); | ||||||
| @ -773,7 +742,7 @@ const getVersion = () => { | |||||||
|     }); |     }); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** 选择版本号触发(新增索引参数,用于触发重复校验) */ | /** 选择版本号触发 */ | ||||||
| const selectNameVersion = (val: string, row: PlanListItem, index: number) => { | const selectNameVersion = (val: string, row: PlanListItem, index: number) => { | ||||||
|   row.batchNumber = val; |   row.batchNumber = val; | ||||||
|   row.suppliespriceId = undefined; // 切换版本号时清空物资选择 |   row.suppliespriceId = undefined; // 切换版本号时清空物资选择 | ||||||
| @ -788,11 +757,8 @@ const selectNameVersion = (val: string, row: PlanListItem, index: number) => { | |||||||
|   row.duplicateError = ''; |   row.duplicateError = ''; | ||||||
|   row.mrpBaseId = ''; |   row.mrpBaseId = ''; | ||||||
|  |  | ||||||
|   // 1. 获取对应版本的物资列表 |   // 获取对应版本的物资列表 | ||||||
|   getNameList(val); |   getNameList(val); | ||||||
|  |  | ||||||
|   // 2. 触发重复校验(清空物资后可能消除重复) |  | ||||||
|   checkDuplicate(); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** 页面挂载时初始化 */ | /** 页面挂载时初始化 */ | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ | |||||||
|       <!-- 表单区域 --> |       <!-- 表单区域 --> | ||||||
|       <el-card class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden"> |       <el-card class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden"> | ||||||
|         <div class="p-4 bg-gradient-to-r from-blue-50 to-indigo-50 border-b border-gray-100"> |         <div class="p-4 bg-gradient-to-r from-blue-50 to-indigo-50 border-b border-gray-100"> | ||||||
|           <h3 class="text-lg font-semibold text-gray-800">设计原则</h3> |           <h3 class="text-lg font-semibold text-gray-800">物质供应总计划</h3> | ||||||
|         </div> |         </div> | ||||||
|         <div class="p-6"> |         <div class="p-6"> | ||||||
|           <!-- <el-form ref="leaveFormRef" v-loading="loading" :disabled="routeParams.type === 'view' || form.status == 'waiting' || routeParams.type === 'update'" :model="form" |           <!-- <el-form ref="leaveFormRef" v-loading="loading" :disabled="routeParams.type === 'view' || form.status == 'waiting' || routeParams.type === 'update'" :model="form" | ||||||
| @ -148,7 +148,7 @@ const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>(); | |||||||
| const flowCodeOptions = [ | const flowCodeOptions = [ | ||||||
|   { |   { | ||||||
|     value: currentProject.value?.id + '_totalsupplyplan', |     value: currentProject.value?.id + '_totalsupplyplan', | ||||||
|     label: '物资总计划审核' |     label: '物质供应总计划审核' | ||||||
|   } |   } | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
| @ -214,7 +214,7 @@ const getInfo = () => { | |||||||
|     console.log('res.data', masterDataRes); |     console.log('res.data', masterDataRes); | ||||||
|     Object.assign(form.value, masterDataRes?.data[0]); |     Object.assign(form.value, masterDataRes?.data[0]); | ||||||
|     // console.log('form', form.value); |     // console.log('form', form.value); | ||||||
|     tableData.value = res.rows; |     tableData.value = res.rows.reverse();//翻转 | ||||||
|     loading.value = false; |     loading.value = false; | ||||||
|     buttonLoading.value = false; |     buttonLoading.value = false; | ||||||
|   }); |   }); | ||||||
|  | |||||||
| @ -10,9 +10,9 @@ | |||||||
|             <el-form-item label="设备统称" prop="name"> |             <el-form-item label="设备统称" prop="name"> | ||||||
|               <el-input v-model="queryParams.name" placeholder="请输入设备统称" clearable @keyup.enter="handleQuery" /> |               <el-input v-model="queryParams.name" placeholder="请输入设备统称" clearable @keyup.enter="handleQuery" /> | ||||||
|             </el-form-item> |             </el-form-item> | ||||||
|             <el-form-item label="到货日期" prop="arrivalDate"> |             <!-- <el-form-item label="到货日期" prop="arrivalDate"> | ||||||
|               <el-date-picker clearable v-model="queryParams.arrivalDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择到货日期" /> |               <el-date-picker clearable v-model="queryParams.arrivalDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择到货日期" /> | ||||||
|             </el-form-item> |             </el-form-item> --> | ||||||
|             <el-form-item> |             <el-form-item> | ||||||
|               <el-button type="primary" v-hasPermi="['cailiaoshebei:purchaseDoc:list']" icon="Search" @click="handleQuery">搜索</el-button> |               <el-button type="primary" v-hasPermi="['cailiaoshebei:purchaseDoc:list']" icon="Search" @click="handleQuery">搜索</el-button> | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user