Files
FastGPT/packages/service/support/user/team/controller.ts
Archer 3c97757e4d 4.8.19-feature (#3636)
* feat: sync org from wecom, pref: member list pagination (#3549)

* feat: sync org

* chore: fe

* chore: loading

* chore: type

* pref: team member list change to pagination. Edit a sort of list apis.

* feat: member update avatar

* chore: user avatar move to tmb

* chore: init scripts move user avatar

* chore: sourceMember

* fix: list api sourceMember

* fix: member sync

* fix: pagination

* chore: adjust code

* chore: move changeOwner to pro

* chore: init v4819 script

* chore: adjust code

* chore: UserBox

* perf: scroll page code

* perf: list data

* docs:更新用户答疑 (#3576)

* docs: add custom uid docs (#3572)

* fix: pagination bug (#3577)

* 4.8.19 test (#3584)

* faet: dataset search filter

* fix: scroll page

* fix: collection list api old version (#3591)

* fix: collection list api format

* fix: type error of addSourceMemeber

* fix: scroll fetch (#3592)

* fix: yuque dataset file folder can enter (#3593)

* perf: load members;perf: yuque load;fix: workflow llm params cannot close (#3594)

* chat openapi doc

* feat: dataset openapi doc

* perf: load members

* perf: member load code

* perf: yuque load

* fix: workflow llm params cannot close

* fix: api dataset reference tag preview (#3600)

* perf: doc

* feat: chat page config

* fix: http parse (#3634)

* update doc

* fix: http parse

* fix code run node reset template (#3633)

Co-authored-by: Archer <545436317@qq.com>

* docs:faq (#3627)

* docs:faq

* docsFix

* perf: sleep plugin

* fix: selector

---------

Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com>
Co-authored-by: Jiangween <145003935+Jiangween@users.noreply.github.com>
Co-authored-by: heheer <heheer@sealos.io>
2025-01-20 19:42:33 +08:00

246 lines
6.7 KiB
TypeScript

import { TeamSchema, TeamTmbItemType } from '@fastgpt/global/support/user/team/type';
import { ClientSession, Types } from '../../../common/mongo';
import {
TeamMemberRoleEnum,
TeamMemberStatusEnum,
notLeaveStatus
} from '@fastgpt/global/support/user/team/constant';
import { MongoTeamMember } from './teamMemberSchema';
import { MongoTeam } from './teamSchema';
import { UpdateTeamProps } from '@fastgpt/global/support/user/team/controller';
import { getResourcePermission } from '../../permission/controller';
import { PerResourceTypeEnum } from '@fastgpt/global/support/permission/constant';
import { TeamPermission } from '@fastgpt/global/support/permission/user/controller';
import { TeamDefaultPermissionVal } from '@fastgpt/global/support/permission/user/constant';
import { MongoMemberGroupModel } from '../../permission/memberGroup/memberGroupSchema';
import { mongoSessionRun } from '../../../common/mongo/sessionRun';
import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant';
import { getAIApi, openaiBaseUrl } from '../../../core/ai/config';
import { createRootOrg } from '../../permission/org/controllers';
import { refreshSourceAvatar } from '../../../common/file/image/controller';
async function getTeamMember(match: Record<string, any>): Promise<TeamTmbItemType> {
const tmb = await MongoTeamMember.findOne(match).populate<{ team: TeamSchema }>('team').lean();
if (!tmb) {
return Promise.reject('member not exist');
}
const Per = await getResourcePermission({
resourceType: PerResourceTypeEnum.team,
teamId: tmb.teamId,
tmbId: tmb._id
});
return {
userId: String(tmb.userId),
teamId: String(tmb.teamId),
teamAvatar: tmb.team.avatar,
teamName: tmb.team.name,
memberName: tmb.name,
avatar: tmb.avatar,
balance: tmb.team.balance,
tmbId: String(tmb._id),
teamDomain: tmb.team?.teamDomain,
role: tmb.role,
status: tmb.status,
defaultTeam: tmb.defaultTeam,
permission: new TeamPermission({
per: Per ?? TeamDefaultPermissionVal,
isOwner: tmb.role === TeamMemberRoleEnum.owner
}),
notificationAccount: tmb.team.notificationAccount,
lafAccount: tmb.team.lafAccount,
openaiAccount: tmb.team.openaiAccount,
externalWorkflowVariables: tmb.team.externalWorkflowVariables
};
}
export async function getTmbInfoByTmbId({ tmbId }: { tmbId: string }) {
if (!tmbId) {
return Promise.reject('tmbId or userId is required');
}
return getTeamMember({
_id: new Types.ObjectId(String(tmbId)),
status: notLeaveStatus
});
}
export async function getUserDefaultTeam({ userId }: { userId: string }) {
if (!userId) {
return Promise.reject('tmbId or userId is required');
}
return getTeamMember({
userId: new Types.ObjectId(userId),
defaultTeam: true
});
}
export async function createDefaultTeam({
userId,
teamName = 'My Team',
avatar = '/icon/logo.svg',
session
}: {
userId: string;
teamName?: string;
avatar?: string;
session: ClientSession;
}) {
// auth default team
const tmb = await MongoTeamMember.findOne({
userId: new Types.ObjectId(userId),
defaultTeam: true
});
if (!tmb) {
// create team
const [{ _id: insertedId }] = await MongoTeam.create(
[
{
ownerId: userId,
name: teamName,
avatar,
createTime: new Date()
}
],
{ session }
);
// create team member
const [tmb] = await MongoTeamMember.create(
[
{
teamId: insertedId,
userId,
name: 'Owner',
role: TeamMemberRoleEnum.owner,
status: TeamMemberStatusEnum.active,
createTime: new Date(),
defaultTeam: true
}
],
{ session }
);
// create default group
await MongoMemberGroupModel.create(
[
{
teamId: tmb.teamId,
name: DefaultGroupName,
avatar
}
],
{ session }
);
await createRootOrg({ teamId: tmb.teamId, session });
console.log('create default team, group and root org', userId);
return tmb;
} else {
console.log('default team exist', userId);
}
}
export async function updateTeam({
teamId,
name,
avatar,
teamDomain,
lafAccount,
openaiAccount,
externalWorkflowVariable
}: UpdateTeamProps & { teamId: string }) {
// auth openai key
if (openaiAccount?.key) {
console.log('auth user openai key', openaiAccount?.key);
const baseUrl = openaiAccount?.baseUrl || openaiBaseUrl;
openaiAccount.baseUrl = baseUrl;
const ai = getAIApi({
userKey: openaiAccount
});
const response = await ai.chat.completions.create({
model: 'gpt-4o-mini',
max_tokens: 1,
messages: [{ role: 'user', content: 'hi' }]
});
if (response?.choices?.[0]?.message?.content === undefined) {
return Promise.reject('Key response is empty');
}
}
return mongoSessionRun(async (session) => {
const unsetObj = (() => {
const obj: Record<string, 1> = {};
if (lafAccount?.pat === '') {
obj.lafAccount = 1;
}
if (openaiAccount?.key === '') {
obj.openaiAccount = 1;
}
if (externalWorkflowVariable) {
if (externalWorkflowVariable.value === '') {
obj[`externalWorkflowVariables.${externalWorkflowVariable.key}`] = 1;
}
}
if (Object.keys(obj).length === 0) {
return undefined;
}
return {
$unset: obj
};
})();
const setObj = (() => {
const obj: Record<string, any> = {};
if (lafAccount?.pat && lafAccount?.appid) {
obj.lafAccount = lafAccount;
}
if (openaiAccount?.key && openaiAccount?.baseUrl) {
obj.openaiAccount = openaiAccount;
}
if (externalWorkflowVariable) {
if (externalWorkflowVariable.value !== '') {
obj[`externalWorkflowVariables.${externalWorkflowVariable.key}`] =
externalWorkflowVariable.value;
}
}
if (Object.keys(obj).length === 0) {
return undefined;
}
return obj;
})();
// This is where we get the old team
const team = await MongoTeam.findByIdAndUpdate(
teamId,
{
$set: {
...(name ? { name } : {}),
...(avatar ? { avatar } : {}),
...(teamDomain ? { teamDomain } : {}),
...setObj
},
...unsetObj
},
{ session }
);
// Update member group avatar
if (avatar) {
await MongoMemberGroupModel.updateOne(
{
teamId: teamId,
name: DefaultGroupName
},
{
avatar
},
{ session }
);
await refreshSourceAvatar(avatar, team?.avatar, session);
}
});
}