@ -133,7 +133,7 @@
< / el-select >
< / template >
< / el-table-column >
<!-- 物资名称列 -- >
<!-- 物资名称列 ( 核心修改 : 动态过滤已选选项 ) -- >
< el-table-column prop = "name" align = "center" label = "物资名称" width = "160" >
< template # default = "scope" >
< el-input v-model = "scope.row.name" v-if="scope.row.mrpBaseId" placeholder="请输入物资名称" disabled / >
@ -144,7 +144,13 @@
placeholder = "请选择"
@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 >
< / template >
< / el-table-column >
@ -152,24 +158,21 @@
< el-table-column align = "center" label = "剩余量" width = "80" >
< template # default = "scope" >
< span > { { scope . row . Remaining } } < / span >
<!-- < el-input disabled v-model = "scope.row.Remaining" placeholder="剩余量" / > -- >
< / template >
< / el-table-column >
<!-- 规格型号列 -- >
< el-table-column prop = "specification" align = "center" label = "规格型号" width = "100" >
< template # default = "scope" >
< span > { { scope . row . specification } } < / span >
<!-- < el-input v-model = "scope.row.specification" placeholder="请输入规格型号" disabled / > -- >
< / template >
< / el-table-column >
<!-- 单位列 -- >
< el-table-column prop = "unit" align = "center" label = "单位" width = "80" >
< template # default = "scope" >
< span > { { scope . row . unit } } < / span >
<!-- < el-input v-model = "scope.row.unit" placeholder="请输入单位" disabled / > -- >
< / template >
< / el-table-column >
<!-- 数量列 ( 新增错误提示展示 ) -- >
<!-- 数量列 -- >
< el-table-column prop = "demandQuantity" align = "center" label = "数量" width = "140" >
< template # default = "scope" >
< el-input
@ -181,7 +184,7 @@
type = "number"
min = "0"
/ >
<!-- 数量错误提示 ( 红色小字体 ) -- >
<!-- 数量错误提示 -- >
< div v-if = "scope.row.quantityError" class="text-red-500 text-xs mt-1" > {{ scope.row.quantityError }} < / div >
< / template >
< / el -table -column >
@ -239,7 +242,7 @@ import {
} from '@/api/materials/batchPlan' ;
import { CailiaoshebeiVO , CailiaoshebeiQuery , CailiaoshebeiForm } from '@/api/materials/batchPlan/types' ;
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' ;
// 类型定义补充
@ -302,7 +305,7 @@ const dialog = reactive<DialogOption>({
title : ''
} ) ;
// 初始化表单数据(补充版本号、重复错误提示字段)
// 初始化表单数据
const initFormData : FormData = {
mrpBaseBo : {
id : undefined ,
@ -323,10 +326,10 @@ const initFormData: FormData = {
qs : undefined ,
arrivalTime : undefined ,
remark : undefined ,
Remaining : 0 , // 初始化剩余量
quantityError : '' , // 初始化数量错误提示
batchNumber : undefined , // 初始化版本号
duplicateError : '' , // 初始化重复错误提示
Remaining : 0 ,
quantityError : '' ,
batchNumber : undefined ,
duplicateError : '' ,
mrpBaseId : undefined
}
]
@ -390,7 +393,7 @@ const validateDemandQuantity = (row: PlanListItem, index: number) => {
// 1. 清除之前的错误信息
row . quantityError = '' ;
// 2. 处理空值( 若需必填可补充: row.quantityError = '数量不能为空')
// 2. 处理空值
if ( row . demandQuantity === null || row . demandQuantity === undefined || row . demandQuantity === '' ) {
return ;
}
@ -426,42 +429,20 @@ const getMrpBaseRemaining = async (suppliespriceId: number, row: PlanListItem) =
}
} ;
/** 校验重复数据:版本号+物资名称不能重复 */
const checkDuplicate = ( ) => {
const planList = form . value . planList ;
let hasDuplicate = f als e ;
/** 获取可用物资列表(过滤已选选项) */
const getAvailableNameList = ( currentIndex : number ) => {
// 收集除当前行外已选中的物资ID
const selectedIds = form . v alu e. planList
. filter ( ( _ , index ) => index !== currentIndex )
. map ( item => item . suppliespriceId )
. filter ( id => id !== undefined && id !== null ) ;
// 1. 清除所有重复错误提示
planList . forEach ( ( item ) => {
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 ;
// 过滤掉已选中的物资
return nameList . value . filter ( item => ! selectedIds . includes ( item . id ) ) ;
} ;
/** 选择物资名称触发(新增索引参数,用于触发重复校验) */
/** 选择物资名称触发 */
const selectName = ( val : number , row : PlanListItem , index : number ) => {
console . log ( row ) ;
// 1. 获取剩余量并更新基础信息
getMrpBaseRemaining ( val , row ) . then ( ( ) => {
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 . arrivalTime = selected . arrivalTime || '' ;
}
// 2. 触发重复校验
checkDuplicate ( ) ;
} ) ;
} ;
@ -514,8 +492,6 @@ const delRow = (index: number) => {
return proxy ? . $modal . msgWarning ( '请至少保留一项物资数据' ) ;
}
form . value . planList . splice ( index , 1 ) ;
// 删除后重新校验重复(避免删除重复行后错误提示残留)
checkDuplicate ( ) ;
} ;
/** 新增表格行 */
@ -577,15 +553,15 @@ const handleUpdata = () => {
if ( ! queryParams . value . mainData . mrpBaseId ) {
return proxy ? . $modal . msgError ( '请先选择批次' ) ;
}
// 1. 获取对应版本的物资列表
// 获取对应版本的物资列表
reset ( ) ;
loading . value = true ;
getCailiaoshebei ( queryParams . value . mainData . mrpBaseId )
. then ( ( res : any ) => {
// 1. 更新基础信息
// 更新基础信息
form . value . mrpBaseBo = res . data . mrpBaseBo || initFormData . mrpBaseBo ;
// 2. 更新表格数据(补充缺失字段)
// 更新表格数据(补充缺失字段)
form . value . planList = ( res . data . planList || [ ] ) . map ( ( item : any ) => ( {
id : item . id ,
name : item . name ,
@ -597,13 +573,12 @@ const handleUpdata = () => {
arrivalTime : item . arrivalTime ,
remark : item . remark ,
Remaining : Number ( item . remaining ) || 0 ,
// remaining:
quantityError : '' ,
batchNumber : item . batchNumber ,
duplicateError : '' ,
mrpBaseId : item . mrpBaseId
} ) ) ;
// 3. 打开对话框
// 打开对话框
dialog . visible = true ;
dialog . title = '修改物资-需求' ;
} )
@ -617,38 +592,32 @@ const handleUpdata = () => {
/** 提交数据(整合所有校验) */
const submitTransferForm = async ( ) => {
// 1. 先 校验重复数据
const hasDuplicate = checkDuplicate ( ) ;
if ( hasDuplicate ) {
return proxy ? . $modal . msgError ( '存在重复的版本号+物资组合,请修正后提交' ) ;
}
// 2. 校验数量合法性(检查是否有数量错误)
// 1. 校验数量合法性(检查是否有数量错误)
const hasQuantityError = form . value . planList . some ( ( row ) => row . quantityError ) ;
if ( hasQuantityError ) {
return proxy ? . $modal . msgError ( '存在非法数量,请修正后提交' ) ;
}
// 3 . 执行表单基础验证
// 2 . 执行表单基础验证
const result = validateAndClean ( form . value . planList ) ;
if ( ! result . valid ) {
return proxy ? . $modal . msgError ( result . message ) ;
}
// 4 . 表单组件验证
// 3 . 表单组件验证
cailiaoshebeiFormRef . value ? . validate ( async ( valid : boolean ) => {
if ( ! valid ) return ;
buttonLoading . value = true ;
try {
// 5 . 提交数据
// 4 . 提交数据
await updateCailiaoshebei ( {
... form . value ,
planList : result . data // 使用清洗后的数据
} ) ;
proxy ? . $modal . msgSuccess ( '操作成功' ) ;
dialog . visible = false ;
// 6 . 刷新列表
// 5 . 刷新列表
await getList ( ) ;
} catch ( error ) {
proxy ? . $modal . msgError ( '操作失败,请重试' ) ;
@ -773,7 +742,7 @@ const getVersion = () => {
} ) ;
} ;
/** 选择版本号触发(新增索引参数,用于触发重复校验) */
/** 选择版本号触发 */
const selectNameVersion = ( val : string , row : PlanListItem , index : number ) => {
row . batchNumber = val ;
row . suppliespriceId = undefined ; // 切换版本号时清空物资选择
@ -788,11 +757,8 @@ const selectNameVersion = (val: string, row: PlanListItem, index: number) => {
row . duplicateError = '' ;
row . mrpBaseId = '' ;
// 1. 获取对应版本的物资列表
// 获取对应版本的物资列表
getNameList ( val ) ;
// 2. 触发重复校验(清空物资后可能消除重复)
checkDuplicate ( ) ;
} ;
/** 页面挂载时初始化 */