From f125d8d1bfebde03fd09f7d5adb3a3db1c61855d Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Mon, 20 Jul 2026 15:52:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=90=8E=E5=8F=B0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=85=B3=E7=B3=BB=E7=BB=91=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 6 +- pnpm-lock.yaml | 176 ++++ src/api/admin/sysUserRelation.ts | 97 ++ src/api/admin/sysUserRelationType.ts | 40 + src/components/Select/SelectUser.vue | 35 +- src/router/route.ts | 9 + src/views/admin/system/relation-type/form.vue | 179 ++++ .../admin/system/relation-type/index.vue | 119 +++ .../system/user/components/user-info-form.ts | 70 ++ .../system/user/components/user-info-form.vue | 312 ++++++ src/views/admin/system/user/form.vue | 318 +----- src/views/admin/system/user/index.vue | 32 +- .../system/user/relation-create-user.vue | 361 +++++++ src/views/admin/system/user/relation-tree.vue | 935 ++++++++++++++++++ 14 files changed, 2394 insertions(+), 295 deletions(-) create mode 100755 src/api/admin/sysUserRelation.ts create mode 100755 src/api/admin/sysUserRelationType.ts create mode 100644 src/views/admin/system/relation-type/form.vue create mode 100644 src/views/admin/system/relation-type/index.vue create mode 100644 src/views/admin/system/user/components/user-info-form.ts create mode 100644 src/views/admin/system/user/components/user-info-form.vue create mode 100644 src/views/admin/system/user/relation-create-user.vue create mode 100644 src/views/admin/system/user/relation-tree.vue diff --git a/package.json b/package.json index b39c562b..3f17e2d5 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,10 @@ "@element-plus/icons-vue": "^2.0.10", "@map-component/vue-tmap": "^1.0.1", "@popperjs/core": "2.11.8", + "@vue-flow/background": "^1.3.2", + "@vue-flow/controls": "^1.1.3", + "@vue-flow/core": "^1.48.2", + "@vue-flow/minimap": "^1.5.4", "@vueuse/core": "^10.4.1", "@vxe-ui/plugin-render-element": "^4.0.10", "@wangeditor/editor": "5.1.23", @@ -121,4 +125,4 @@ "type": "git", "url": "https://gitee.com/log4j/pig" } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e2d76c38..697f20e7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,6 +22,18 @@ importers: "@popperjs/core": specifier: 2.11.8 version: 2.11.8 + "@vue-flow/background": + specifier: ^1.3.2 + version: 1.3.2(@vue-flow/core@1.48.2(vue@3.4.15(typescript@4.9.5)))(vue@3.4.15(typescript@4.9.5)) + "@vue-flow/controls": + specifier: ^1.1.3 + version: 1.1.3(@vue-flow/core@1.48.2(vue@3.4.15(typescript@4.9.5)))(vue@3.4.15(typescript@4.9.5)) + "@vue-flow/core": + specifier: ^1.48.2 + version: 1.48.2(vue@3.4.15(typescript@4.9.5)) + "@vue-flow/minimap": + specifier: ^1.5.4 + version: 1.5.4(@vue-flow/core@1.48.2(vue@3.4.15(typescript@4.9.5)))(vue@3.4.15(typescript@4.9.5)) "@vueuse/core": specifier: ^10.4.1 version: 10.11.1(vue@3.4.15(typescript@4.9.5)) @@ -1326,6 +1338,41 @@ packages: vite: ^4.0.0 || ^5.0.0 vue: ^3.2.25 + "@vue-flow/background@1.3.2": + resolution: + { + integrity: sha512-eJPhDcLj1wEo45bBoqTXw1uhl0yK2RaQGnEINqvvBsAFKh/camHJd5NPmOdS1w+M9lggc9igUewxaEd3iCQX2w==, + } + peerDependencies: + "@vue-flow/core": ^1.23.0 + vue: ^3.3.0 + + "@vue-flow/controls@1.1.3": + resolution: + { + integrity: sha512-XCf+G+jCvaWURdFlZmOjifZGw3XMhN5hHlfMGkWh9xot+9nH9gdTZtn+ldIJKtarg3B21iyHU8JjKDhYcB6JMw==, + } + peerDependencies: + "@vue-flow/core": ^1.23.0 + vue: ^3.3.0 + + "@vue-flow/core@1.48.2": + resolution: + { + integrity: sha512-raxhgKWE+G/mcEvXJjGFUDYW9rAI3GOtiHR3ZkNpwBWuIaCC1EYiBmKGwJOoNzVFgwO7COgErnK7i08i287AFA==, + } + peerDependencies: + vue: ^3.3.0 + + "@vue-flow/minimap@1.5.4": + resolution: + { + integrity: sha512-l4C+XTAXnRxsRpUdN7cAVFBennC1sVRzq4bDSpVK+ag7tdMczAnhFYGgbLkUw3v3sY6gokyWwMl8CDonp8eB2g==, + } + peerDependencies: + "@vue-flow/core": ^1.23.0 + vue: ^3.3.0 + "@vue/compiler-core@3.4.15": resolution: { @@ -2076,6 +2123,71 @@ packages: } engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + d3-color@3.1.0: + resolution: + { + integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==, + } + engines: { node: ">=12" } + + d3-dispatch@3.0.1: + resolution: + { + integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==, + } + engines: { node: ">=12" } + + d3-drag@3.0.0: + resolution: + { + integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==, + } + engines: { node: ">=12" } + + d3-ease@3.0.1: + resolution: + { + integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==, + } + engines: { node: ">=12" } + + d3-interpolate@3.0.1: + resolution: + { + integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==, + } + engines: { node: ">=12" } + + d3-selection@3.0.0: + resolution: + { + integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==, + } + engines: { node: ">=12" } + + d3-timer@3.0.1: + resolution: + { + integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==, + } + engines: { node: ">=12" } + + d3-transition@3.0.1: + resolution: + { + integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==, + } + engines: { node: ">=12" } + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: + { + integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==, + } + engines: { node: ">=12" } + d@1.0.2: resolution: { @@ -5487,6 +5599,34 @@ snapshots: vite: 4.5.14(@types/node@18.19.130)(sass@1.58.3)(terser@5.44.0) vue: 3.4.15(typescript@4.9.5) + "@vue-flow/background@1.3.2(@vue-flow/core@1.48.2(vue@3.4.15(typescript@4.9.5)))(vue@3.4.15(typescript@4.9.5))": + dependencies: + "@vue-flow/core": 1.48.2(vue@3.4.15(typescript@4.9.5)) + vue: 3.4.15(typescript@4.9.5) + + "@vue-flow/controls@1.1.3(@vue-flow/core@1.48.2(vue@3.4.15(typescript@4.9.5)))(vue@3.4.15(typescript@4.9.5))": + dependencies: + "@vue-flow/core": 1.48.2(vue@3.4.15(typescript@4.9.5)) + vue: 3.4.15(typescript@4.9.5) + + "@vue-flow/core@1.48.2(vue@3.4.15(typescript@4.9.5))": + dependencies: + "@vueuse/core": 10.11.1(vue@3.4.15(typescript@4.9.5)) + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-zoom: 3.0.0 + vue: 3.4.15(typescript@4.9.5) + transitivePeerDependencies: + - "@vue/composition-api" + + "@vue-flow/minimap@1.5.4(@vue-flow/core@1.48.2(vue@3.4.15(typescript@4.9.5)))(vue@3.4.15(typescript@4.9.5))": + dependencies: + "@vue-flow/core": 1.48.2(vue@3.4.15(typescript@4.9.5)) + d3-selection: 3.0.0 + d3-zoom: 3.0.0 + vue: 3.4.15(typescript@4.9.5) + "@vue/compiler-core@3.4.15": dependencies: "@babel/parser": 7.28.4 @@ -5961,6 +6101,42 @@ snapshots: culori@3.3.0: {} + d3-color@3.1.0: {} + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-ease@3.0.1: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-selection@3.0.0: {} + + d3-timer@3.0.1: {} + + "d3-transition@3.0.1(d3-selection@3.0.0)": + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + d@1.0.2: dependencies: es5-ext: 0.10.64 diff --git a/src/api/admin/sysUserRelation.ts b/src/api/admin/sysUserRelation.ts new file mode 100755 index 00000000..9eb2ef22 --- /dev/null +++ b/src/api/admin/sysUserRelation.ts @@ -0,0 +1,97 @@ +import request from "/@/utils/request" + +export interface RelationGraphNode { + nodeId: string + parentNodeId?: string + root: boolean + repeated: boolean + userId: string + username?: string + name?: string + nickname?: string + displayName: string + avatar?: string + gender?: number + userCount?: number + relationCount?: number + relationId?: string + subjectUserId?: string + objectUserId?: string + relationTypeId?: string + relationCode?: string + relationName?: string + category?: string + directedFlag?: string + relationDirection?: "subject-to-object" | "object-to-subject" + userRoleName?: string + parentRoleName?: string + relationDescription?: string + effectiveTime?: string + expireTime?: string + remark?: string + children?: RelationGraphNode[] +} + +export interface RelationCreateUserForm { + subjectUserId?: string + objectUserId?: string + relationTypeId: string + effectiveTime?: string + expireTime?: string + remark?: string + username: string + password: string + phone?: string + name: string + nickname?: string + email?: string + avatar?: string + deptId?: string + role?: string[] + post?: string[] + gender?: number + staffingType?: string + lockFlag?: string + identityTypes: string[] + studentInfo?: { + studentNo: string + schoolName: string + className: string + extJson: string + } +} + +export interface RelationCreateForm { + subjectUserId: string + objectUserId: string + relationTypeId: string + effectiveTime?: string + expireTime?: string + remark?: string +} + +// 关系图谱 +export function getRelationGraph(userId?: string) { + return request({ + url: "/admin/sysUserRelation/graph/" + userId, + method: "get", + }) +} + +// 创建用户并建立关系 +export function createRelationUser(data: RelationCreateUserForm) { + return request({ + url: "/admin/sysUserRelation/create-user", + method: "post", + data, + }) +} + +// 为两个已有用户建立关系 +export function createRelation(data: RelationCreateForm) { + return request({ + url: "/admin/sysUserRelation/create", + method: "post", + data, + }) +} diff --git a/src/api/admin/sysUserRelationType.ts b/src/api/admin/sysUserRelationType.ts new file mode 100755 index 00000000..3147da96 --- /dev/null +++ b/src/api/admin/sysUserRelationType.ts @@ -0,0 +1,40 @@ +import request from "/@/utils/request" + +export function fetchList(query?: Object) { + return request({ + url: "/admin/sysUserRelationType/page", + method: "get", + params: query, + }) +} + +export function addObj(obj?: Object) { + return request({ + url: "/admin/sysUserRelationType", + method: "post", + data: obj, + }) +} + +export function getObj(id?: string) { + return request({ + url: "/admin/sysUserRelationType/" + id, + method: "get", + }) +} + +export function delObjs(ids?: Object) { + return request({ + url: "/admin/sysUserRelationType", + method: "delete", + data: ids, + }) +} + +export function putObj(obj?: Object) { + return request({ + url: "/admin/sysUserRelationType", + method: "put", + data: obj, + }) +} diff --git a/src/components/Select/SelectUser.vue b/src/components/Select/SelectUser.vue index 15d4013a..d9a05ed7 100644 --- a/src/components/Select/SelectUser.vue +++ b/src/components/Select/SelectUser.vue @@ -1,8 +1,24 @@