From 914c8ed99fb76553fc579f8b44338492eba165c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B1=A4=E5=AD=A6=E4=BC=9A?= Date: Mon, 15 Jun 2026 01:56:59 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BB=84=E7=BB=87=E6=A0=91?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E7=BA=BF=E5=B1=82=E7=BA=A7=E5=85=B3=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/OrgPermissionTree.test.js | 4 +- frontend/src/components/OrgPermissionTree.vue | 77 +++++++++++-------- 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/frontend/src/components/OrgPermissionTree.test.js b/frontend/src/components/OrgPermissionTree.test.js index ad691db..02d4bc0 100644 --- a/frontend/src/components/OrgPermissionTree.test.js +++ b/frontend/src/components/OrgPermissionTree.test.js @@ -9,10 +9,10 @@ const source = readFileSync(join(__dirname, "OrgPermissionTree.vue"), "utf8"); describe("OrgPermissionTree hierarchy lines", () => { it("draws connector lines only between each node and its direct children", () => { + assert.match(source, /\.org-tree-children\s*>\s*\.org-tree-branch::before/); assert.match(source, /\.org-tree-children\s*>\s*\.org-tree-branch\s*>\s*\.org-tree-node::before/); - assert.match(source, /\.org-tree-children\s*>\s*\.org-tree-branch\s*>\s*\.org-tree-node::after/); assert.doesNotMatch(source, /\.org-tree-children::before/); - assert.doesNotMatch(source, /\.org-tree-branch::before/); + assert.doesNotMatch(source, /^\.org-tree-branch::before/m); assert.match(source, /--tree-connector-x/); assert.match(source, /--tree-connector-color/); assert.match(source, /--tree-connector-width:\s*2px/); diff --git a/frontend/src/components/OrgPermissionTree.vue b/frontend/src/components/OrgPermissionTree.vue index b46801d..70e2bde 100644 --- a/frontend/src/components/OrgPermissionTree.vue +++ b/frontend/src/components/OrgPermissionTree.vue @@ -577,9 +577,10 @@ function removeEmployee(employee) { } .org-tree-list { - --tree-connector-color: rgba(37, 99, 235, 0.74); + --tree-connector-color: rgba(29, 78, 216, 0.9); --tree-connector-width: 2px; - --tree-connector-arm: 14px; + --tree-connector-arm: 20px; + --tree-node-center: 20px; display: flex; flex: 1; flex-direction: column; @@ -598,6 +599,25 @@ function removeEmployee(employee) { gap: 2px; } +.org-tree-children > .org-tree-branch::before { + content: ""; + position: absolute; + top: calc(-1 * var(--tree-connector-width)); + bottom: calc(-1 * var(--tree-connector-width)); + left: var(--tree-connector-x); + width: var(--tree-connector-width); + background: var(--tree-connector-color); + border-radius: 999px; + box-shadow: 0 0 0 1px rgba(219, 234, 254, 0.85); + transform: translateX(-50%); + pointer-events: none; +} + +.org-tree-children > .org-tree-branch:last-child::before { + bottom: auto; + height: calc(var(--tree-node-center) + var(--tree-connector-width)); +} + .org-tree-node { position: relative; display: grid; @@ -618,26 +638,13 @@ function removeEmployee(employee) { .org-tree-children > .org-tree-branch > .org-tree-node::before { content: ""; position: absolute; - top: 50%; + top: var(--tree-node-center); left: calc(var(--tree-connector-x) - var(--tree-connector-width) / 2); width: var(--tree-connector-arm); height: var(--tree-connector-width); background: var(--tree-connector-color); border-radius: 999px; - transform: translateY(-50%); - pointer-events: none; -} - -.org-tree-children > .org-tree-branch > .org-tree-node::after { - content: ""; - position: absolute; - top: calc(50% - 10px); - left: var(--tree-connector-x); - width: var(--tree-connector-width); - height: 20px; - background: var(--tree-connector-color); - border-radius: 999px; - transform: translateX(-50%); + box-shadow: 0 0 0 1px rgba(219, 234, 254, 0.85); pointer-events: none; } @@ -798,6 +805,25 @@ function removeEmployee(employee) { gap: 2px; } +:deep(.org-tree-children > .org-tree-branch::before) { + content: ""; + position: absolute; + top: calc(-1 * var(--tree-connector-width)); + bottom: calc(-1 * var(--tree-connector-width)); + left: var(--tree-connector-x); + width: var(--tree-connector-width); + background: var(--tree-connector-color); + border-radius: 999px; + box-shadow: 0 0 0 1px rgba(219, 234, 254, 0.85); + transform: translateX(-50%); + pointer-events: none; +} + +:deep(.org-tree-children > .org-tree-branch:last-child::before) { + bottom: auto; + height: calc(var(--tree-node-center) + var(--tree-connector-width)); +} + :deep(.org-tree-node) { position: relative; display: grid; @@ -819,26 +845,13 @@ function removeEmployee(employee) { :deep(.org-tree-children > .org-tree-branch > .org-tree-node::before) { content: ""; position: absolute; - top: 50%; + top: var(--tree-node-center); left: calc(var(--tree-connector-x) - var(--tree-connector-width) / 2); width: var(--tree-connector-arm); height: var(--tree-connector-width); background: var(--tree-connector-color); border-radius: 999px; - transform: translateY(-50%); - pointer-events: none; -} - -:deep(.org-tree-children > .org-tree-branch > .org-tree-node::after) { - content: ""; - position: absolute; - top: calc(50% - 10px); - left: var(--tree-connector-x); - width: var(--tree-connector-width); - height: 20px; - background: var(--tree-connector-color); - border-radius: 999px; - transform: translateX(-50%); + box-shadow: 0 0 0 1px rgba(219, 234, 254, 0.85); pointer-events: none; }