diff --git a/backend/app/services/system_permissions.py b/backend/app/services/system_permissions.py index e9df3eb..8b39b92 100644 --- a/backend/app/services/system_permissions.py +++ b/backend/app/services/system_permissions.py @@ -85,7 +85,10 @@ MENU_PERMISSION_TREE = [ ORG_ROOT_CODE = "ORG_ROOT" ORG_ROOT_NAME = "总公司" VALID_CHILD_NODE_TYPES = { - "COMPANY": {"BRANCH": "总公司下只能新增分公司"}, + "COMPANY": { + "BRANCH": "总公司下只能新增分公司或直属部门", + "DEPARTMENT": "总公司下只能新增分公司或直属部门", + }, "BRANCH": {"DEPARTMENT": "分公司下只能新增部门"}, "DEPARTMENT": {"GROUP": "部门下只能新增小组"}, "GROUP": {}, diff --git a/backend/tests/test_system_permission_management.py b/backend/tests/test_system_permission_management.py index 532d779..1da1341 100644 --- a/backend/tests/test_system_permission_management.py +++ b/backend/tests/test_system_permission_management.py @@ -398,6 +398,32 @@ class SystemPermissionManagementTest(unittest.TestCase): self.assertEqual(tree[0].children[0].parent_id, self.company.id) self.assertEqual(tree[0].children[0].node_type, "BRANCH") + def test_create_org_node_allows_company_direct_department(self) -> None: + from app.schemas.system_permissions import OrgNodeCreate + from app.services.system_permissions import create_org_node, build_org_tree + + direct_department = create_org_node( + self.db, + OrgNodeCreate( + parent_id=self.company.id, + node_type="DEPARTMENT", + node_label="总公司直属部门", + dept_code="DIRECT-DEPT", + dept_type="ADMIN", + manager_employee_id=None, + sort_no=1, + remark=None, + status="ACTIVE", + ), + ) + + tree = build_org_tree(self.db) + self.assertEqual(direct_department.parent_id, self.company.id) + self.assertEqual(direct_department.node_type, "DEPARTMENT") + self.assertTrue( + any(child.node_label == "总公司直属部门" and child.node_type == "DEPARTMENT" for child in tree[0].children) + ) + def test_create_org_node_rejects_invalid_child_level(self) -> None: from fastapi import HTTPException from app.schemas.system_permissions import OrgNodeCreate @@ -408,9 +434,9 @@ class SystemPermissionManagementTest(unittest.TestCase): self.db, OrgNodeCreate( parent_id=self.company.id, - node_type="DEPARTMENT", - node_label="错误部门", - dept_code="BAD-DEPT", + node_type="GROUP", + node_label="错误小组", + dept_code="BAD-GROUP", dept_type="ADMIN", manager_employee_id=None, sort_no=1, @@ -419,7 +445,7 @@ class SystemPermissionManagementTest(unittest.TestCase): ), ) self.assertEqual(ctx.exception.status_code, 400) - self.assertIn("总公司下只能新增分公司", str(ctx.exception.detail)) + self.assertIn("总公司下只能新增分公司或直属部门", str(ctx.exception.detail)) def test_delete_org_node_rejects_nodes_with_children_or_bound_employees(self) -> None: from fastapi import HTTPException diff --git a/docs/superpowers/plans/2026-06-15-org-tree-action-parity.md b/docs/superpowers/plans/2026-06-15-org-tree-action-parity.md new file mode 100644 index 0000000..3c05e9c --- /dev/null +++ b/docs/superpowers/plans/2026-06-15-org-tree-action-parity.md @@ -0,0 +1,493 @@ +# 组织树与脑图操作能力一致 Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 让“组织树模式”和“脑图模式”只是展示形式不同,组织节点和人员节点的操作能力完全一致。 + +**Architecture:** 保留 `SystemPermissionView.vue` 作为唯一组织动作编排层,继续复用现有 `nodeActions(node)`、`runNodeAction(actionKey, node)`、各类 drawer 打开函数和删除/授权函数。`OrgPermissionTree.vue` 只负责展示组织树、选中节点、发出节点菜单事件,不新增第二套业务动作逻辑。 + +**Tech Stack:** Vue 3 `