refactor: org pathId (#3516)

This commit is contained in:
a.e.
2025-01-03 09:53:53 +08:00
committed by archer
parent d24d29ac48
commit a401d4d612
6 changed files with 33 additions and 14 deletions

View File

@@ -1,6 +1,10 @@
import { OrgSchemaType } from './type';
export const OrgCollectionName = 'team_orgs'; export const OrgCollectionName = 'team_orgs';
export const OrgMemberCollectionName = 'team_org_members'; export const OrgMemberCollectionName = 'team_org_members';
export const getChildrenPath = (org: OrgSchemaType) => `${org.path}/${org.pathId}`;
// export enum OrgMemberRole { // export enum OrgMemberRole {
// owner = 'owner', // owner = 'owner',
// admin = 'admin', // admin = 'admin',

View File

@@ -4,6 +4,7 @@ import { ResourcePermissionType } from '../type';
type OrgSchemaType = { type OrgSchemaType = {
_id: string; _id: string;
teamId: string; teamId: string;
pathId: string;
path: string; path: string;
name: string; name: string;
avatar?: string; avatar?: string;

View File

@@ -3,6 +3,7 @@ import type { OrgSchemaType } from '@fastgpt/global/support/user/team/org/type';
import type { ClientSession } from 'mongoose'; import type { ClientSession } from 'mongoose';
import { MongoOrgModel } from './orgSchema'; import { MongoOrgModel } from './orgSchema';
import { MongoOrgMemberModel } from './orgMemberSchema'; import { MongoOrgMemberModel } from './orgMemberSchema';
import { getChildrenPath } from '@fastgpt/global/support/user/team/org/constant';
export const getOrgsByTmbId = async ({ teamId, tmbId }: { teamId: string; tmbId: string }) => export const getOrgsByTmbId = async ({ teamId, tmbId }: { teamId: string; tmbId: string }) =>
MongoOrgMemberModel.find({ teamId, tmbId }, 'orgId').lean(); MongoOrgMemberModel.find({ teamId, tmbId }, 'orgId').lean();
@@ -42,7 +43,7 @@ export const getChildrenByOrg = async ({
teamId: string; teamId: string;
session?: ClientSession; session?: ClientSession;
}) => { }) => {
return MongoOrgModel.find({ teamId, path: { $regex: `^${org.path}/${org._id}` } }, undefined, { return MongoOrgModel.find({ teamId, path: { $regex: `^${getChildrenPath(org)}` } }, undefined, {
session session
}).lean(); }).lean();
}; };

View File

@@ -2,8 +2,8 @@ import { TeamCollectionName } from '@fastgpt/global/support/user/team/constant';
import { OrgCollectionName } from '@fastgpt/global/support/user/team/org/constant'; import { OrgCollectionName } from '@fastgpt/global/support/user/team/org/constant';
import type { OrgSchemaType } from '@fastgpt/global/support/user/team/org/type'; import type { OrgSchemaType } from '@fastgpt/global/support/user/team/org/type';
import { connectionMongo, getMongoModel } from '../../../common/mongo'; import { connectionMongo, getMongoModel } from '../../../common/mongo';
import { ResourcePermissionCollectionName } from '../schema';
import { OrgMemberCollectionName } from './orgMemberSchema'; import { OrgMemberCollectionName } from './orgMemberSchema';
import { getNanoid } from '@fastgpt/global/common/string/tools';
const { Schema } = connectionMongo; const { Schema } = connectionMongo;
function requiredStringPath(this: OrgSchemaType) { function requiredStringPath(this: OrgSchemaType) {
@@ -17,6 +17,12 @@ export const OrgSchema = new Schema(
ref: TeamCollectionName, ref: TeamCollectionName,
required: true required: true
}, },
pathId: {
// path id, only used for path
type: String,
required: true,
default: () => getNanoid()
},
path: { path: {
type: String, type: String,
required: requiredStringPath // allow empty string, but not null required: requiredStringPath // allow empty string, but not null
@@ -57,6 +63,15 @@ try {
teamId: 1, teamId: 1,
path: 1 path: 1
}); });
OrgSchema.index(
{
teamId: 1,
pathId: 1
},
{
unique: true
}
);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }

View File

@@ -4,6 +4,7 @@ import Avatar from '@fastgpt/web/components/common/Avatar';
import { useToggle } from 'ahooks'; import { useToggle } from 'ahooks';
import { useMemo } from 'react'; import { useMemo } from 'react';
import IconButton from './IconButton'; import IconButton from './IconButton';
import { getChildrenPath } from '@fastgpt/global/support/user/team/org/constant';
function OrgTreeNode({ function OrgTreeNode({
org, org,
@@ -19,7 +20,7 @@ function OrgTreeNode({
index?: number; index?: number;
}) { }) {
const children = useMemo( const children = useMemo(
() => list.filter((item) => item.path === `${org.path}/${org._id}`), () => list.filter((item) => item.path === getChildrenPath(org)),
[org, list] [org, list]
); );
const [isExpanded, toggleIsExpanded] = useToggle(index === 0); const [isExpanded, toggleIsExpanded] = useToggle(index === 0);

View File

@@ -30,12 +30,13 @@ import { TeamContext } from '../context';
import { getOrgList } from '@/web/support/user/team/org/api'; import { getOrgList } from '@/web/support/user/team/org/api';
import IconButton from './IconButton'; import IconButton from './IconButton';
import type { defaultOrgForm, OrgFormType } from './OrgInfoModal'; import { defaultOrgForm, type OrgFormType } from './OrgInfoModal';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import MyBox from '@fastgpt/web/components/common/MyBox'; import MyBox from '@fastgpt/web/components/common/MyBox';
import Path from '@/components/common/folder/Path'; import Path from '@/components/common/folder/Path';
import { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type'; import { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type';
import { getChildrenPath } from '@fastgpt/global/support/user/team/org/constant';
const OrgInfoModal = dynamic(() => import('./OrgInfoModal')); const OrgInfoModal = dynamic(() => import('./OrgInfoModal'));
const OrgMemberManageModal = dynamic(() => import('./OrgMemberManageModal')); const OrgMemberManageModal = dynamic(() => import('./OrgMemberManageModal'));
@@ -88,7 +89,7 @@ function OrgTable() {
const currentOrgs = useMemo(() => { const currentOrgs = useMemo(() => {
if (orgs.length === 0) return []; if (orgs.length === 0) return [];
if (parentPath === '') { if (parentPath === '') {
setParentPath(`/${orgs[0]._id}`); setParentPath(`/${orgs[0].pathId}`);
return []; return [];
} }
return orgs return orgs
@@ -97,8 +98,7 @@ function OrgTable() {
return { return {
...item, ...item,
count: count:
item.members.length + item.members.length + orgs.filter((org) => org.path === getChildrenPath(item)).length
orgs.filter((org) => org.path === `${item.path}/${item._id}`).length
}; };
}); });
}, [orgs, parentPath]); }, [orgs, parentPath]);
@@ -107,18 +107,18 @@ function OrgTable() {
const currentOrgId = splitPath[splitPath.length - 1]; const currentOrgId = splitPath[splitPath.length - 1];
if (!currentOrgId) return; if (!currentOrgId) return;
return orgs.find((org) => org._id === currentOrgId); return orgs.find((org) => org.pathId === currentOrgId);
}, [orgs, parentPath]); }, [orgs, parentPath]);
const paths = useMemo(() => { const paths = useMemo(() => {
const splitPath = parentPath.split('/').filter(Boolean); const splitPath = parentPath.split('/').filter(Boolean);
return splitPath return splitPath
.map((id) => { .map((id) => {
const org = orgs.find((org) => org._id === id)!; const org = orgs.find((org) => org.pathId === id)!;
if (org.path === '') return; if (org.path === '') return;
return { return {
parentId: `${org.path}/${org._id}`, parentId: getChildrenPath(org),
parentName: org.name parentName: org.name
}; };
}) })
@@ -175,10 +175,7 @@ function OrgTable() {
{currentOrgs.map((org) => ( {currentOrgs.map((org) => (
<Tr key={org._id} overflow={'unset'}> <Tr key={org._id} overflow={'unset'}>
<Td> <Td>
<HStack <HStack cursor={'pointer'} onClick={() => setParentPath(getChildrenPath(org))}>
cursor={'pointer'}
onClick={() => setParentPath(`${org.path}/${org._id}`)}
>
<MemberTag name={org.name} avatar={org.avatar} /> <MemberTag name={org.name} avatar={org.avatar} />
<Tag size="sm">{org.count}</Tag> <Tag size="sm">{org.count}</Tag>
<MyIcon <MyIcon