diff --git a/packages/global/support/user/team/org/constant.ts b/packages/global/support/user/team/org/constant.ts index 5b764877b225..93d3f020ad7e 100644 --- a/packages/global/support/user/team/org/constant.ts +++ b/packages/global/support/user/team/org/constant.ts @@ -1,6 +1,10 @@ +import { OrgSchemaType } from './type'; + export const OrgCollectionName = 'team_orgs'; export const OrgMemberCollectionName = 'team_org_members'; +export const getChildrenPath = (org: OrgSchemaType) => `${org.path}/${org.pathId}`; + // export enum OrgMemberRole { // owner = 'owner', // admin = 'admin', diff --git a/packages/global/support/user/team/org/type.d.ts b/packages/global/support/user/team/org/type.d.ts index d183169d64e6..ca4a73292272 100644 --- a/packages/global/support/user/team/org/type.d.ts +++ b/packages/global/support/user/team/org/type.d.ts @@ -4,6 +4,7 @@ import { ResourcePermissionType } from '../type'; type OrgSchemaType = { _id: string; teamId: string; + pathId: string; path: string; name: string; avatar?: string; diff --git a/packages/service/support/permission/org/controllers.ts b/packages/service/support/permission/org/controllers.ts index 863d0288c3d5..b58736b749b5 100644 --- a/packages/service/support/permission/org/controllers.ts +++ b/packages/service/support/permission/org/controllers.ts @@ -3,6 +3,7 @@ import type { OrgSchemaType } from '@fastgpt/global/support/user/team/org/type'; import type { ClientSession } from 'mongoose'; import { MongoOrgModel } from './orgSchema'; import { MongoOrgMemberModel } from './orgMemberSchema'; +import { getChildrenPath } from '@fastgpt/global/support/user/team/org/constant'; export const getOrgsByTmbId = async ({ teamId, tmbId }: { teamId: string; tmbId: string }) => MongoOrgMemberModel.find({ teamId, tmbId }, 'orgId').lean(); @@ -42,7 +43,7 @@ export const getChildrenByOrg = async ({ teamId: string; session?: ClientSession; }) => { - return MongoOrgModel.find({ teamId, path: { $regex: `^${org.path}/${org._id}` } }, undefined, { + return MongoOrgModel.find({ teamId, path: { $regex: `^${getChildrenPath(org)}` } }, undefined, { session }).lean(); }; diff --git a/packages/service/support/permission/org/orgSchema.ts b/packages/service/support/permission/org/orgSchema.ts index 6d6bc2bb155e..18d3e1a83787 100644 --- a/packages/service/support/permission/org/orgSchema.ts +++ b/packages/service/support/permission/org/orgSchema.ts @@ -2,8 +2,8 @@ import { TeamCollectionName } from '@fastgpt/global/support/user/team/constant'; import { OrgCollectionName } from '@fastgpt/global/support/user/team/org/constant'; import type { OrgSchemaType } from '@fastgpt/global/support/user/team/org/type'; import { connectionMongo, getMongoModel } from '../../../common/mongo'; -import { ResourcePermissionCollectionName } from '../schema'; import { OrgMemberCollectionName } from './orgMemberSchema'; +import { getNanoid } from '@fastgpt/global/common/string/tools'; const { Schema } = connectionMongo; function requiredStringPath(this: OrgSchemaType) { @@ -17,6 +17,12 @@ export const OrgSchema = new Schema( ref: TeamCollectionName, required: true }, + pathId: { + // path id, only used for path + type: String, + required: true, + default: () => getNanoid() + }, path: { type: String, required: requiredStringPath // allow empty string, but not null @@ -57,6 +63,15 @@ try { teamId: 1, path: 1 }); + OrgSchema.index( + { + teamId: 1, + pathId: 1 + }, + { + unique: true + } + ); } catch (error) { console.log(error); } diff --git a/projects/app/src/pages/account/team/components/OrgManage/OrgTree.tsx b/projects/app/src/pages/account/team/components/OrgManage/OrgTree.tsx index cda5df41ab3b..2305f6bb4578 100644 --- a/projects/app/src/pages/account/team/components/OrgManage/OrgTree.tsx +++ b/projects/app/src/pages/account/team/components/OrgManage/OrgTree.tsx @@ -4,6 +4,7 @@ import Avatar from '@fastgpt/web/components/common/Avatar'; import { useToggle } from 'ahooks'; import { useMemo } from 'react'; import IconButton from './IconButton'; +import { getChildrenPath } from '@fastgpt/global/support/user/team/org/constant'; function OrgTreeNode({ org, @@ -19,7 +20,7 @@ function OrgTreeNode({ index?: number; }) { const children = useMemo( - () => list.filter((item) => item.path === `${org.path}/${org._id}`), + () => list.filter((item) => item.path === getChildrenPath(org)), [org, list] ); const [isExpanded, toggleIsExpanded] = useToggle(index === 0); diff --git a/projects/app/src/pages/account/team/components/OrgManage/index.tsx b/projects/app/src/pages/account/team/components/OrgManage/index.tsx index 35612d8f100d..3388df44057f 100644 --- a/projects/app/src/pages/account/team/components/OrgManage/index.tsx +++ b/projects/app/src/pages/account/team/components/OrgManage/index.tsx @@ -30,12 +30,13 @@ import { TeamContext } from '../context'; import { getOrgList } from '@/web/support/user/team/org/api'; import IconButton from './IconButton'; -import type { defaultOrgForm, OrgFormType } from './OrgInfoModal'; +import { defaultOrgForm, type OrgFormType } from './OrgInfoModal'; import dynamic from 'next/dynamic'; import MyBox from '@fastgpt/web/components/common/MyBox'; import Path from '@/components/common/folder/Path'; import { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type'; +import { getChildrenPath } from '@fastgpt/global/support/user/team/org/constant'; const OrgInfoModal = dynamic(() => import('./OrgInfoModal')); const OrgMemberManageModal = dynamic(() => import('./OrgMemberManageModal')); @@ -88,7 +89,7 @@ function OrgTable() { const currentOrgs = useMemo(() => { if (orgs.length === 0) return []; if (parentPath === '') { - setParentPath(`/${orgs[0]._id}`); + setParentPath(`/${orgs[0].pathId}`); return []; } return orgs @@ -97,8 +98,7 @@ function OrgTable() { return { ...item, count: - item.members.length + - orgs.filter((org) => org.path === `${item.path}/${item._id}`).length + item.members.length + orgs.filter((org) => org.path === getChildrenPath(item)).length }; }); }, [orgs, parentPath]); @@ -107,18 +107,18 @@ function OrgTable() { const currentOrgId = splitPath[splitPath.length - 1]; if (!currentOrgId) return; - return orgs.find((org) => org._id === currentOrgId); + return orgs.find((org) => org.pathId === currentOrgId); }, [orgs, parentPath]); const paths = useMemo(() => { const splitPath = parentPath.split('/').filter(Boolean); return splitPath .map((id) => { - const org = orgs.find((org) => org._id === id)!; + const org = orgs.find((org) => org.pathId === id)!; if (org.path === '') return; return { - parentId: `${org.path}/${org._id}`, + parentId: getChildrenPath(org), parentName: org.name }; }) @@ -175,10 +175,7 @@ function OrgTable() { {currentOrgs.map((org) => ( - setParentPath(`${org.path}/${org._id}`)} - > + setParentPath(getChildrenPath(org))}> {org.count}