From 86faa3be9bc56eff45099aa74abb7c3461c14a7d Mon Sep 17 00:00:00 2001 From: lion <120344285@qq.com> Date: Tue, 6 Jan 2026 14:14:26 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A2=84=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/budget/budgetList.vue | 105 ++++++++++---- src/views/budget/seeBudget.vue | 67 ++++++--- .../statisticalReport/budgetProgress.vue | 130 ++++++++++++++---- 3 files changed, 234 insertions(+), 68 deletions(-) diff --git a/src/views/budget/budgetList.vue b/src/views/budget/budgetList.vue index bf99566..547a774 100644 --- a/src/views/budget/budgetList.vue +++ b/src/views/budget/budgetList.vue @@ -28,6 +28,7 @@ clearable placeholder="选择预算类型" style="width: 130px" + popper-class="budget-type-tree-select" @change="changeType" > @@ -36,7 +37,7 @@ style="width:300px" default-expand-all :default-checked-keys="checkArr" - :check-strictly="true" + :check-strictly="false" :data="types" show-checkbox node-key="id" @@ -921,29 +922,85 @@ export default { if (!e) { this.select.type = '' this.select.typeName = '' + this.checkArr = [] + if (this.$refs.tree1) { + this.$refs.tree1.setCheckedKeys([]) + } } }, - getSelectedNodes(data, node, ref) { - const ref_data = ref || 'tree' - this.$refs[ref_data].setCheckedKeys([]) - this.checkArr = [] - if (data.children && data.children.length > 0) { - this.$Message.warning('当前节点不可选择') - this.form.type = '' - this.select.type = '' - this.editorForm.type = '' - this.$refs[ref_data].setCheckedKeys([]) - return + // 递归获取所有子节点的 id(不包含节点本身) + getAllChildrenIds(node) { + let ids = [] + if (node.children && node.children.length > 0) { + node.children.forEach(child => { + ids.push(child.id) // 添加直接子节点 id + ids = ids.concat(this.getAllChildrenIds(child)) // 递归获取子节点的子节点 + }) } - this.$refs[ref_data].setCheckedKeys([]) // 删除所有选中节点 - this.$refs[ref_data].setCheckedNodes([data]) // 选中已选中节点 - if (this.isShowAdd) { - this.form.type = data.id - } else if (this.isShowEditor) { - this.editorForm.type = data.id + return ids + }, + getSelectedNodes(data, node, ref) { + const ref_data = ref || 'tree1' + + // 如果是列表筛选模式(tree1),使用多选逻辑 + if (ref_data === 'tree1') { + // 获取所有选中的节点(当 check-strictly="false" 时,选择父级会自动选中所有子级) + const checkedNodes = this.$refs[ref_data].getCheckedNodes() + + // 收集所有选中的 id + // 规则:如果直接选择了父级,则收集父级id + 所有子级id + // 如果只选择了子级,则只收集子级id,不包含父级id + let allSelectedIds = [] + + // 遍历所有选中的节点 + checkedNodes.forEach(checkedNode => { + // 如果节点有子节点(是父级),说明用户直接选择了父级 + if (checkedNode.children && checkedNode.children.length > 0) { + // 选择父级时:添加父级id + 所有子级id + allSelectedIds.push(checkedNode.id) // 添加父级 id + // 递归获取所有子节点的 id + const childrenIds = this.getAllChildrenIds(checkedNode) + allSelectedIds = allSelectedIds.concat(childrenIds) + } else { + // 叶子节点(子级),只添加该子级id,不包含父级 + allSelectedIds.push(checkedNode.id) + } + }) + + // 去重 + allSelectedIds = [...new Set(allSelectedIds)] + + // 更新选中状态 + this.checkArr = allSelectedIds + + // 将选中的 id 以逗号分隔赋值给 this.select.type + this.select.type = allSelectedIds.join(',') + + // 更新显示的名称(只显示直接选中的节点名称,不包括自动选中的子级) + const selectedNames = checkedNodes.map(n => n.name).filter((name, index, self) => self.indexOf(name) === index) + this.select.typeName = selectedNames.join(', ') } else { - this.select.type = data.id - this.select.typeName = data.name + // 新增和编辑模式保持单选逻辑 + this.$refs[ref_data].setCheckedKeys([]) + this.checkArr = [] + if (data.children && data.children.length > 0) { + this.$Message.warning('当前节点不可选择') + this.form.type = '' + this.select.type = '' + this.editorForm.type = '' + this.$refs[ref_data].setCheckedKeys([]) + return + } + this.$refs[ref_data].setCheckedKeys([]) // 删除所有选中节点 + this.$refs[ref_data].setCheckedNodes([data]) // 选中已选中节点 + if (this.isShowAdd) { + this.form.type = data.id + } else if (this.isShowEditor) { + this.editorForm.type = data.id + } else { + this.select.type = data.id + this.select.typeName = data.name + } } console.log('checkarr', this.select.typeName, this.$refs[ref_data].getCheckedNodes()) this.$forceUpdate() @@ -1196,7 +1253,9 @@ export default { } } - + diff --git a/src/views/budget/seeBudget.vue b/src/views/budget/seeBudget.vue index 8d4c441..aaa7e4d 100644 --- a/src/views/budget/seeBudget.vue +++ b/src/views/budget/seeBudget.vue @@ -34,7 +34,7 @@ style="width:300px" default-expand-all :default-checked-keys="checkArr" - :check-strictly="true" + :check-strictly="false" :data="types" show-checkbox node-key="id" @@ -287,23 +287,56 @@ export default { } } }, + // 递归获取所有子节点的 id(不包含节点本身) + getAllChildrenIds(node) { + let ids = [] + if (node.children && node.children.length > 0) { + node.children.forEach(child => { + ids.push(child.id) // 添加直接子节点 id + ids = ids.concat(this.getAllChildrenIds(child)) // 递归获取子节点的子节点 + }) + } + return ids + }, // 树形节点选择 getSelectedNodes(data, node, ref) { const ref_data = ref || 'tree1' - this.$refs[ref_data].setCheckedKeys([]) - this.checkArr = [] - if (data.children && data.children.length > 0) { - this.$Message.warning('当前节点不可选择') - this.select.type = '' - this.select.typeName = '' - this.$refs[ref_data].setCheckedKeys([]) - return - } - this.$refs[ref_data].setCheckedKeys([]) // 删除所有选中节点 - this.$refs[ref_data].setCheckedNodes([data]) // 选中已选中节点 - this.select.type = data.id - this.select.typeName = data.name - this.checkArr = [data.id] + // 获取所有选中的节点(当 check-strictly="false" 时,选择父级会自动选中所有子级) + const checkedNodes = this.$refs[ref_data].getCheckedNodes() + + // 收集所有选中的 id + // 规则:如果直接选择了父级,则收集父级id + 所有子级id + // 如果只选择了子级,则只收集子级id,不包含父级id + let allSelectedIds = [] + + // 遍历所有选中的节点 + checkedNodes.forEach(checkedNode => { + // 如果节点有子节点(是父级),说明用户直接选择了父级 + if (checkedNode.children && checkedNode.children.length > 0) { + // 选择父级时:添加父级id + 所有子级id + allSelectedIds.push(checkedNode.id) // 添加父级 id + // 递归获取所有子节点的 id + const childrenIds = this.getAllChildrenIds(checkedNode) + allSelectedIds = allSelectedIds.concat(childrenIds) + } else { + // 叶子节点(子级),只添加该子级id,不包含父级 + allSelectedIds.push(checkedNode.id) + } + }) + + // 去重 + allSelectedIds = [...new Set(allSelectedIds)] + + // 更新选中状态 + this.checkArr = allSelectedIds + + // 将选中的 id 以逗号分隔赋值给 this.select.type + this.select.type = allSelectedIds.join(',') + + // 更新显示的名称(只显示直接选中的节点名称,不包括自动选中的子级) + const selectedNames = checkedNodes.map(n => n.name).filter((name, index, self) => self.indexOf(name) === index) + this.select.typeName = selectedNames.join(', ') + this.$forceUpdate() }, // 获取预算类型 @@ -464,9 +497,7 @@ export default { } } - ::v-deep .el-checkbox__input .el-checkbox__inner { - border-radius: 50%; - } +