This commit is contained in:
Archer
2024-06-12 15:17:21 +08:00
committed by GitHub
parent bc6864c3dc
commit d0085a23e6
61 changed files with 558 additions and 348 deletions

View File

@@ -1,9 +1,8 @@
import { UpdateClbPermissionProps } from '../../support/permission/collaborator';
import { PermissionValueType } from '../../support/permission/type';
export type UpdateAppCollaboratorBody = {
export type UpdateAppCollaboratorBody = UpdateClbPermissionProps & {
appId: string;
tmbIds: string[];
permission: PermissionValueType;
};
export type AppCollaboratorDeleteParams = {

View File

@@ -20,6 +20,7 @@ import { RuntimeNodeItemType } from '../runtime/type';
import { PluginTypeEnum } from '../../plugin/constants';
import { RuntimeEdgeItemType, StoreEdgeItemType } from './edge';
import { NextApiResponse } from 'next';
import { AppDetailType, AppSchema } from '../../app/type';
export type FlowNodeCommonType = {
flowNodeType: FlowNodeTypeEnum; // render node card
@@ -131,7 +132,7 @@ export type ChatDispatchProps = {
teamId: string;
tmbId: string;
user: UserModelSchema;
appId?: string;
app: AppDetailType | AppSchema;
chatId?: string;
responseChatItemId?: string;
histories: ChatItemType[];

View File

@@ -8,3 +8,8 @@ export type CollaboratorItemType = {
name: string;
avatar: string;
};
export type UpdateClbPermissionProps = {
tmbIds: string[];
permission: PermissionValueType;
};

View File

@@ -11,7 +11,10 @@ export enum AuthUserTypeEnum {
export enum PermissionTypeEnum {
'private' = 'private',
'public' = 'public'
'public' = 'public',
clbPrivate = 'clbPrivate',
publicRead = 'publicRead',
publicWrite = 'publicWrite'
}
export const PermissionTypeMap = {
[PermissionTypeEnum.private]: {
@@ -21,6 +24,18 @@ export const PermissionTypeMap = {
[PermissionTypeEnum.public]: {
iconLight: 'support/permission/publicLight',
label: 'permission.Public'
},
[PermissionTypeEnum.publicRead]: {
iconLight: 'support/permission/publicLight',
label: '团队可访问'
},
[PermissionTypeEnum.publicWrite]: {
iconLight: 'support/permission/publicLight',
label: '团队可编辑'
},
[PermissionTypeEnum.clbPrivate]: {
iconLight: 'support/permission/privateLight',
label: '仅协作者'
}
};

View File

@@ -1,11 +1,14 @@
import { PermissionKeyEnum, PermissionList, ReadPermissionVal } from '../constant';
import { PermissionListType } from '../type';
export const TeamPermissionList = {
export const TeamPermissionList: PermissionListType = {
[PermissionKeyEnum.read]: {
...PermissionList[PermissionKeyEnum.read]
...PermissionList[PermissionKeyEnum.read],
description: '成员仅可阅读相关资源,无法新建资源'
},
[PermissionKeyEnum.write]: {
...PermissionList[PermissionKeyEnum.write]
...PermissionList[PermissionKeyEnum.write],
description: '除了可读资源外,还可以新建新的资源'
},
[PermissionKeyEnum.manage]: {
...PermissionList[PermissionKeyEnum.manage],

View File

@@ -22,7 +22,7 @@ export type UpdateTeamProps = {
/* ------------- member ----------- */
export type DelMemberProps = {
memberId: string;
tmbId: string;
};
export type UpdateTeamMemberProps = {
teamId: string;
@@ -33,7 +33,7 @@ export type UpdateTeamMemberProps = {
export type InviteMemberProps = {
teamId: string;
usernames: string[];
role: `${TeamMemberRoleEnum}`;
permission: PermissionValueType;
};
export type UpdateInviteProps = {
tmbId: string;
@@ -43,8 +43,3 @@ export type InviteMemberResponse = Record<
'invite' | 'inValid' | 'inTeam',
{ username: string; userId: string }[]
>;
export type UpdateTeamMemberPermissionProps = {
memberIds: string[];
permission: PermissionValueType;
};

View File

@@ -70,7 +70,7 @@ export const countGptMessagesTokens = (
callbackMap[id] = (data) => {
// 检测是否有内存泄漏
addLog.info(`Count token time: ${Date.now() - start}, token: ${data}`);
addLog.debug(`Count token time: ${Date.now() - start}, token: ${data}`);
// console.log(process.memoryUsage());
resolve(data);

View File

@@ -1,11 +1,12 @@
import dayjs from 'dayjs';
import chalk from 'chalk';
import { isProduction } from './constants';
enum LogLevelEnum {
debug = 'debug',
info = 'info',
warn = 'warn',
error = 'error'
debug = 0,
info = 1,
warn = 2,
error = 3
}
const logMap = {
[LogLevelEnum.debug]: {
@@ -21,20 +22,35 @@ const logMap = {
levelLog: chalk.red('[Error]')
}
};
const envLogLevelMap: Record<string, number> = {
debug: 0,
info: 1,
warn: 2,
error: 3
};
const logLevel = (() => {
if (!isProduction) return LogLevelEnum.debug;
const envLogLevel = (process.env.LOG_LEVEL || 'info').toLocaleLowerCase();
if (!envLogLevel || envLogLevelMap[envLogLevel] === undefined) return LogLevelEnum.info;
return envLogLevelMap[envLogLevel];
})();
/* add logger */
export const addLog = {
log(level: LogLevelEnum, msg: string, obj: Record<string, any> = {}) {
if (level < logLevel) return;
const stringifyObj = JSON.stringify(obj);
const isEmpty = Object.keys(obj).length === 0;
console.log(
`${logMap[level].levelLog} ${dayjs().format('YYYY-MM-DD HH:mm:ss')} ${msg} ${
level !== 'error' && !isEmpty ? stringifyObj : ''
level !== LogLevelEnum.error && !isEmpty ? stringifyObj : ''
}`
);
level === 'error' && console.error(obj);
level === LogLevelEnum.error && console.error(obj);
const lokiUrl = process.env.LOKI_LOG_URL as string;
if (!lokiUrl) return;

View File

@@ -142,17 +142,17 @@ export const delCollectionRelatedSource = async ({
.map((item) => item?.metadata?.relatedImgId || '')
.filter(Boolean);
// delete files
await delFileByFileIdList({
bucketName: BucketNameEnum.dataset,
fileIdList
});
// delete images
await delImgByRelatedId({
teamId,
relateIds: relatedImageIds,
session
});
// delete files
await delFileByFileIdList({
bucketName: BucketNameEnum.dataset,
fileIdList
});
};
/**
* delete collection and it related data
@@ -182,14 +182,16 @@ export async function delCollectionAndRelatedSources({
);
const collectionIds = collections.map((item) => String(item._id));
await delCollectionRelatedSource({ collections, session });
// delete training data
await MongoDatasetTraining.deleteMany({
teamId,
datasetIds: { $in: datasetIds },
collectionId: { $in: collectionIds }
});
/* file and imgs */
await delCollectionRelatedSource({ collections, session });
// delete dataset.datas
await MongoDatasetData.deleteMany(
{ teamId, datasetIds: { $in: datasetIds }, collectionId: { $in: collectionIds } },
@@ -199,6 +201,7 @@ export async function delCollectionAndRelatedSources({
// delete collections
await MongoDatasetCollection.deleteMany(
{
teamId,
_id: { $in: collectionIds }
},
{ session }

View File

@@ -42,7 +42,7 @@ export async function findCollectionAndChild({
return collections;
}
const [collection, childCollections] = await Promise.all([
MongoDatasetCollection.findById(collectionId, fields),
MongoDatasetCollection.findById(collectionId, fields).lean(),
find(collectionId)
]);

View File

@@ -82,17 +82,18 @@ export async function delDatasetRelevantData({
teamId,
datasetId: { $in: datasetIds }
},
'_id teamId fileId metadata'
'_id teamId datasetId fileId metadata'
).lean();
// image and file
await delCollectionRelatedSource({ collections, session });
// delete training data
await MongoDatasetTraining.deleteMany({
teamId,
datasetId: { $in: datasetIds }
});
// image and file
await delCollectionRelatedSource({ collections, session });
// delete dataset.datas
await MongoDatasetData.deleteMany({ teamId, datasetId: { $in: datasetIds } }, { session });

View File

@@ -407,13 +407,13 @@ export function responseStatus({
/* get system variable */
export function getSystemVariable({
user,
appId,
app,
chatId,
responseChatItemId,
histories = []
}: Props) {
return {
appId,
appId: String(app._id),
chatId,
responseChatItemId,
histories,

View File

@@ -43,7 +43,7 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
let {
res,
detail,
appId,
app: { _id: appId },
chatId,
stream,
responseChatItemId,

View File

@@ -33,8 +33,7 @@ type Response = DispatchNodeResultType<{
export const dispatchAppRequest = async (props: Props): Promise<Response> => {
const {
res,
teamId,
tmbId,
app: workflowApp,
stream,
detail,
histories,
@@ -46,10 +45,11 @@ export const dispatchAppRequest = async (props: Props): Promise<Response> => {
return Promise.reject('Input is empty');
}
// 检查该工作流的tmb是否有调用该app的权限不是校验对话的人是否有权限
const { app: appData } = await authAppByTmbId({
appId: app.id,
teamId,
tmbId,
teamId: workflowApp.teamId,
tmbId: workflowApp.tmbId,
per: ReadPermissionVal
});
@@ -68,7 +68,7 @@ export const dispatchAppRequest = async (props: Props): Promise<Response> => {
const { flowResponses, flowUsages, assistantResponses } = await dispatchWorkFlow({
...props,
appId: app.id,
app: appData,
runtimeNodes: storeNodes2RuntimeNodes(appData.modules, getDefaultEntryNodeIds(appData.modules)),
runtimeEdges: initWorkflowEdgeStatus(appData.edges),
histories: chatHistories,

View File

@@ -21,7 +21,7 @@ const UNDEFINED_SIGN = 'UNDEFINED_SIGN';
export const dispatchLafRequest = async (props: LafRequestProps): Promise<LafResponse> => {
let {
appId,
app: { _id: appId },
chatId,
responseChatItemId,
variables,

View File

@@ -198,4 +198,4 @@ export async function authDatasetFile({
} catch (error) {
return Promise.reject(DatasetErrEnum.unAuthDatasetFile);
}
}
}

View File

@@ -7,8 +7,6 @@ import { AuthUserTypeEnum, PerResourceTypeEnum } from '@fastgpt/global/support/p
import { authOpenApiKey } from '../openapi/auth';
import { FileTokenQuery } from '@fastgpt/global/common/file/type';
import { MongoResourcePermission } from './schema';
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
import { mongoSessionRun } from '../../common/mongo/sessionRun';
export const getResourcePermission = async ({
resourceType,
@@ -36,41 +34,6 @@ export const getResourcePermission = async ({
export const delResourcePermissionById = (id: string) => {
return MongoResourcePermission.findByIdAndRemove(id);
};
export const updateResourcePermission = async ({
resourceId,
resourceType,
teamId,
tmbIdList,
permission
}: {
resourceId?: string;
resourceType: PerResourceTypeEnum;
teamId: string;
tmbIdList: string[];
permission: PermissionValueType;
}) => {
await mongoSessionRun((session) => {
return Promise.all(
tmbIdList.map((tmbId) =>
MongoResourcePermission.findOneAndUpdate(
{
resourceType,
teamId,
tmbId,
resourceId
},
{
permission
},
{
session,
upsert: true
}
)
)
);
});
};
/* 下面代码等迁移 */
/* create token */

View File

@@ -45,6 +45,11 @@ try {
unique: true
}
);
ResourcePermissionSchema.index({
resourceType: 1,
teamId: 1,
resourceId: 1
});
} catch (error) {
console.log(error);
}

View File

@@ -9,10 +9,7 @@ import { MongoTeamMember } from './teamMemberSchema';
import { MongoTeam } from './teamSchema';
import { UpdateTeamProps } from '@fastgpt/global/support/user/team/controller';
import { getResourcePermission } from '../../permission/controller';
import {
PerResourceTypeEnum,
ReadPermissionVal
} from '@fastgpt/global/support/permission/constant';
import { PerResourceTypeEnum } from '@fastgpt/global/support/permission/constant';
import { TeamPermission } from '@fastgpt/global/support/permission/user/controller';
async function getTeamMember(match: Record<string, any>): Promise<TeamTmbItemType> {

View File

@@ -21,6 +21,7 @@ export type SelectProps = ButtonProps & {
list: {
alias?: string;
label: string | React.ReactNode;
description?: string;
value: string | number;
}[];
isLoading?: boolean;
@@ -125,10 +126,12 @@ const MySelect = (
{...menuItemStyles}
{...(value === item.value
? {
color: 'primary.500',
bg: 'myWhite.300'
color: 'primary.600',
bg: 'myGray.100'
}
: {})}
: {
color: 'myGray.900'
})}
onClick={() => {
if (onchange && value !== item.value) {
onchange(item.value);
@@ -136,8 +139,14 @@ const MySelect = (
}}
whiteSpace={'pre-wrap'}
fontSize={'sm'}
display={'block'}
>
{item.label}
<Box>{item.label}</Box>
{item.description && (
<Box color={'myGray.500'} fontSize={'xs'}>
{item.description}
</Box>
)}
</MenuItem>
))}
</MenuList>