diff --git a/src/components/GroupTreeSearchPanel.vue b/src/components/GroupTreeSearchPanel.vue index 2da0ea7..b5e6458 100644 --- a/src/components/GroupTreeSearchPanel.vue +++ b/src/components/GroupTreeSearchPanel.vue @@ -285,10 +285,13 @@ defineExpose({ .tree-body { flex: 1; min-height: 0; + display: flex; + flex-direction: column; } -.tree-body :deep(.ztree) { - height: 100%; - overflow-y: auto; +/* 滚动职责统一由 MyTree(.my-tree > .ztree) 承担:此处只负责把可用高度传给子组件 */ +.tree-body > .my-tree { + flex: 1; + min-height: 0; } diff --git a/src/components/MyTree.vue b/src/components/MyTree.vue index 5c32ab2..9ec4355 100644 --- a/src/components/MyTree.vue +++ b/src/components/MyTree.vue @@ -1,9 +1,35 @@ + + diff --git a/src/views/group-user/index.vue b/src/views/group-user/index.vue index a1bd411..ecb3f41 100644 --- a/src/views/group-user/index.vue +++ b/src/views/group-user/index.vue @@ -371,7 +371,8 @@ function onSortSaved() { left: 348px !important; } -/* 左侧树容器改为 flex 纵向布局并收起自身滚动,把滚动条收敛到树节点区域(.ztree 自带 overflow-y:auto), +/* 左侧树容器改为 flex 纵向布局并收起自身滚动,把滚动条收敛到树节点区域 + (滚动体是 MyTree 内部的 .ztree,见 components/MyTree.vue), 避免树过长时把顶部 opera-ul 操作按钮条滚出屏幕;仅作用于本页,不影响全局 .tree-container */ .tree-wrapper.group-user-page .tree-container.group-user-tree { display: flex; diff --git a/src/views/role-authz/AppModuleCheckTree.vue b/src/views/role-authz/AppModuleCheckTree.vue index c70041a..885be3b 100644 --- a/src/views/role-authz/AppModuleCheckTree.vue +++ b/src/views/role-authz/AppModuleCheckTree.vue @@ -68,6 +68,7 @@ type AuthzTreeNode = { nodeType: "app" | "module"; rawId: number; appId: number; + isParent?: boolean; children?: AuthzTreeNode[]; }; type CategoryTreeItem = { cat: CategoryItem; treeData: AuthzTreeNode[]; weight: number }; @@ -115,8 +116,10 @@ function isModuleAllChecked(node: AppModuleVo): boolean { if (!node.checked) return false; return (node.children || []).every((c) => isModuleAllChecked(c)); } +// 空 children 不挂键:zTree 只要见到 children 是数组就强制 isParent=true 而渲染 +/−(叶子也会出现展开图标) function buildModuleNode(m: AppModuleVo, appId: number): AuthzTreeNode { - return { + const kids = (m.children || []).map((c) => buildModuleNode(c, appId)); + const node: AuthzTreeNode = { id: `mod_${m.id}`, name: String(m.name || ""), open: true, @@ -124,21 +127,26 @@ function buildModuleNode(m: AppModuleVo, appId: number): AuthzTreeNode { nodeType: "module", rawId: Number(m.id), appId, - children: (m.children || []).map((c) => buildModuleNode(c, appId)), + isParent: kids.length > 0, }; + if (kids.length > 0) node.children = kids; + return node; } function buildAppNode(app: AppItem): AuthzTreeNode { const appId = Number(app.id); - return { + const kids = (app.modules || []).map((m) => buildModuleNode(m, appId)); + const node: AuthzTreeNode = { id: `app_${appId}`, name: String(app.name || ""), - open: false, // 一级默认闭合,点击才展开模块 + open: false, checked: isAppChecked(app), nodeType: "app", rawId: appId, appId, - children: (app.modules || []).map((m) => buildModuleNode(m, appId)), + isParent: kids.length > 0, }; + if (kids.length > 0) node.children = kids; + return node; } // ---------------- 数据加载 ----------------