diff --git a/src/views/secondOrder/components/outDialog.vue b/src/views/secondOrder/components/outDialog.vue index 069cf89..1a6c69d 100644 --- a/src/views/secondOrder/components/outDialog.vue +++ b/src/views/secondOrder/components/outDialog.vue @@ -140,6 +140,7 @@ style="width: 100%" border ref="groupTable" + @expand-change="handleExpandChange" > @@ -153,12 +154,26 @@ (val) => handleSelectionChange(val, props.row) " border + :row-key="getRowKeyId" + ref="nestedTable" > - + /> --> + + + @@ -513,6 +528,56 @@ export default { this.getOutGroupName(); }, methods: { + handleExpandChange(row, expandedRows) { + // 只处理展开的情况 + if (expandedRows.includes(row)) { + this.$nextTick(() => { + // 获取该分组对应的嵌套表格实例(需要给嵌套表格加 ref) + // 但动态 ref 难以获取,改用数据驱动方式:我们不在 UI 上依赖 selection,而是靠 selectedGroupMap 渲染 checkbox 状态 + // 所以更推荐:不依赖 el-table 的 selection UI,而是自己控制 checked 状态 + }); + } + }, + handleRowSelect(checked, childRow, parentRow) { + const key = + parentRow.materialId || parentRow.materialCode || parentRow.id; + let currentSelection = this.selectedGroupMap[key] || []; + + if (checked) { + // 添加(去重) + if ( + !currentSelection.some( + (item) => item.materialId === childRow.materialId + ) + ) { + currentSelection = [...currentSelection, { ...childRow }]; + } + } else { + // 移除 + currentSelection = currentSelection.filter( + (item) => item.materialId !== childRow.materialId + ); + } + + this.$set(this.selectedGroupMap, key, currentSelection); + + // 重建明细列表 + let allDetails = []; + Object.values(this.selectedGroupMap).forEach((selectedList) => { + allDetails = allDetails.concat( + selectedList.map((item) => ({ + ...item, + num: item.num || (item.type === "NY" ? 1 : 0), + })) + ); + }); + this.sizeForm.ldTwoOutStorageDetailList = allDetails; + this.getStatistics(); + }, + // 用于 el-table 的 row-key,确保每行有唯一 key + getRowKeyId(row) { + return row.materialId || row.id || row.materialCode; + }, isRowSelectable(row) { // 确保 materialName 是非空字符串,materialId 是非空值(字符串或数字) return ( @@ -560,16 +625,25 @@ export default { getGroupMaterial(this.sizeForm.ldTwoOutStorage).then((res) => { this.groupTableData = res.data.result; this.groupTableData.forEach((group) => { - // 初始化每个分组的选中项为当前已选的明细项 - if (group.twoInventoryVOList.length > 0) { - group.twoInventoryVOList.forEach((element) => { - element.applyNum = group.applyNum; - element.goodsCode = group.applyNum; - if (element.type === "NY") { - element.num = 1; + if ( + group.twoInventoryVOList && + group.twoInventoryVOList.length > 0 + ) { + group.twoInventoryVOList.forEach((item) => { + item.applyNum = group.applyNum; + item.goodsCode = group.applyNum; + if (item.type === "NY") { + item.num = 1; } else { - element.num = group.applyNum; + item.num = group.applyNum; } + // 初始化选中状态 + const key = group.materialId || group.materialCode || group.id; + const previouslySelected = this.selectedGroupMap[key] || []; + const isSelected = previouslySelected.some( + (sel) => sel.materialId === item.materialId + ); + this.$set(item, "_selected", isSelected); }); } }); @@ -779,56 +853,60 @@ export default { this.$refs.dynamicValidateForm.validate((valid) => { if (valid) { // ===== 非自由出库:校验分组物资勾选数量是否匹配申请数量 ===== - if (this.sizeForm.ldTwoOutStorage.groupName !== "自由出库") { - let hasError = false; - - for (const group of this.groupTableData) { - const key = group.materialId || group.materialCode || group.id; - if (!key) continue; - - // 获取该分组下用户勾选的子项 - const selectedItems = this.selectedGroupMap[key] || []; + if (this.sizeForm.ldTwoOutStorage.groupName !== "自由出库") { + let hasError = false; + + for (const group of this.groupTableData) { + const key = group.materialId || group.materialCode || group.id; + if (!key) continue; + + // 获取该分组下用户勾选的子项 + const selectedItems = this.selectedGroupMap[key] || []; + + // 如果没有勾选任何子项,跳过(或可视为错误,根据业务) + if (selectedItems.length === 0) { + this.$message.error( + `分组【${ + group.materialName || group.materialCode + }】未选择任何物资` + ); + hasError = true; + break; + } + + // 计算勾选项的 num 总和 + const totalSelectedNum = selectedItems.reduce((sum, item) => { + return sum + (Number(item.num) || 0); + }, 0); + + const applyNum = Number(group.applyNum) || 0; + + if (totalSelectedNum !== applyNum) { + this.$message.error( + `分组【${ + group.materialName || group.materialCode + }】:已选物资出库数量总和(${totalSelectedNum})与申请数量(${applyNum})不一致` + ); + hasError = true; + break; + } + } - // 如果没有勾选任何子项,跳过(或可视为错误,根据业务) - if (selectedItems.length === 0) { - this.$message.error(`分组【${group.materialName || group.materialCode}】未选择任何物资`); - hasError = true; - break; + if (hasError) { + return; // 阻止提交 + } } - // 计算勾选项的 num 总和 - const totalSelectedNum = selectedItems.reduce((sum, item) => { - return sum + (Number(item.num) || 0); - }, 0); - - const applyNum = Number(group.applyNum) || 0; - - if (totalSelectedNum !== applyNum) { - this.$message.error( - `分组【${group.materialName || group.materialCode}】:已选物资出库数量总和(${totalSelectedNum})与申请数量(${applyNum})不一致` - ); - hasError = true; - break; + // ===== 自由出库:校验是否有明细 ===== + if (this.sizeForm.ldTwoOutStorage.groupName === "自由出库") { + if ( + !this.sizeForm.ldTwoOutStorageDetailList || + this.sizeForm.ldTwoOutStorageDetailList.length === 0 + ) { + this.$message.error("请至少选择一项物资"); + return; + } } - } - - if (hasError) { - return; // 阻止提交 - } - } - - // ===== 自由出库:校验是否有明细 ===== - if (this.sizeForm.ldTwoOutStorage.groupName === "自由出库") { - if ( - !this.sizeForm.ldTwoOutStorageDetailList || - this.sizeForm.ldTwoOutStorageDetailList.length === 0 - ) { - this.$message.error("请至少选择一项物资"); - return; - } - } - - submit(this.sizeForm).then((res) => { this.$message({