mirror of
https://github.com/labring/FastGPT.git
synced 2025-10-17 16:45:02 +00:00
4.8.4 (#1746)
This commit is contained in:
@@ -11,7 +11,7 @@ weight: 708
|
|||||||
|
|
||||||
**开发环境下**,你需要将示例配置文件 `config.json` 复制成 `config.local.json` 文件才会生效。
|
**开发环境下**,你需要将示例配置文件 `config.json` 复制成 `config.local.json` 文件才会生效。
|
||||||
|
|
||||||
这个配置文件中包含了系统参数和各个模型配置,`使用时务必去掉注释!!!!!!!!!!!!!!`
|
这个配置文件中包含了系统参数和各个模型配置:
|
||||||
|
|
||||||
## 4.6.8+ 版本新配置文件
|
## 4.6.8+ 版本新配置文件
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ llm模型全部合并
|
|||||||
|
|
||||||
1. [部署 ReRank 模型](/docs/development/custom-models/bge-rerank/)
|
1. [部署 ReRank 模型](/docs/development/custom-models/bge-rerank/)
|
||||||
1. 找到 FastGPT 的配置文件中的 `reRankModels`, 4.6.6 以前是 `ReRankModels`。
|
1. 找到 FastGPT 的配置文件中的 `reRankModels`, 4.6.6 以前是 `ReRankModels`。
|
||||||
2. 修改对应的值:(记得去掉注释)
|
2. 修改对应的值:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
@@ -4,14 +4,26 @@ description: 'FastGPT V4.8.4 更新说明'
|
|||||||
icon: 'upgrade'
|
icon: 'upgrade'
|
||||||
draft: false
|
draft: false
|
||||||
toc: true
|
toc: true
|
||||||
weight: 821
|
weight: 820
|
||||||
---
|
---
|
||||||
|
|
||||||
<!-- ## 升级指南
|
## 升级指南
|
||||||
|
|
||||||
|
### 1. 修改镜像
|
||||||
|
|
||||||
- fastgpt 镜像 tag 修改成 v4.8.4
|
- fastgpt 镜像 tag 修改成 v4.8.4
|
||||||
- fastgpt-sandbox 镜像 tag 修改成 v4.8.4 (选择性,无变更)
|
- fastgpt-sandbox 镜像 tag 修改成 v4.8.4 (选择性,无变更)
|
||||||
- 商业版镜像 tag 修改成 v4.8.4 -->
|
- 商业版镜像 tag 修改成 v4.8.4
|
||||||
|
|
||||||
|
### 2. 商业版用户执行初始化
|
||||||
|
|
||||||
|
从任意终端,发起 1 个 HTTP 请求。其中 {{rootkey}} 替换成环境变量里的 `rootkey`;{{host}} 替换成**FastGPT 商业版的域名**。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --location --request POST 'https://{{host}}/api/admin/init/484' \
|
||||||
|
--header 'rootkey: {{rootkey}}' \
|
||||||
|
--header 'Content-Type: application/json'
|
||||||
|
```
|
||||||
|
|
||||||
## V4.8.4 更新说明
|
## V4.8.4 更新说明
|
||||||
|
|
||||||
|
@@ -154,6 +154,8 @@ services:
|
|||||||
- MILVUS_TOKEN=none
|
- MILVUS_TOKEN=none
|
||||||
# sandbox 地址
|
# sandbox 地址
|
||||||
- SANDBOX_URL=http://sandbox:3000
|
- SANDBOX_URL=http://sandbox:3000
|
||||||
|
# 日志等级: debug, info, warn, error
|
||||||
|
- LOG_LEVEL=info
|
||||||
volumes:
|
volumes:
|
||||||
- ./config.json:/app/data/config.json
|
- ./config.json:/app/data/config.json
|
||||||
|
|
||||||
|
@@ -111,6 +111,8 @@ services:
|
|||||||
- PG_URL=postgresql://username:password@pg:5432/postgres
|
- PG_URL=postgresql://username:password@pg:5432/postgres
|
||||||
# sandbox 地址
|
# sandbox 地址
|
||||||
- SANDBOX_URL=http://sandbox:3000
|
- SANDBOX_URL=http://sandbox:3000
|
||||||
|
# 日志等级: debug, info, warn, error
|
||||||
|
- LOG_LEVEL=info
|
||||||
volumes:
|
volumes:
|
||||||
- ./config.json:/app/data/config.json
|
- ./config.json:/app/data/config.json
|
||||||
|
|
||||||
|
@@ -92,6 +92,8 @@ services:
|
|||||||
- MILVUS_TOKEN=zilliz_cloud_token
|
- MILVUS_TOKEN=zilliz_cloud_token
|
||||||
# sandbox 地址
|
# sandbox 地址
|
||||||
- SANDBOX_URL=http://sandbox:3000
|
- SANDBOX_URL=http://sandbox:3000
|
||||||
|
# 日志等级: debug, info, warn, error
|
||||||
|
- LOG_LEVEL=info
|
||||||
volumes:
|
volumes:
|
||||||
- ./config.json:/app/data/config.json
|
- ./config.json:/app/data/config.json
|
||||||
|
|
||||||
|
5
packages/global/core/app/collaborator.d.ts
vendored
5
packages/global/core/app/collaborator.d.ts
vendored
@@ -1,9 +1,8 @@
|
|||||||
|
import { UpdateClbPermissionProps } from '../../support/permission/collaborator';
|
||||||
import { PermissionValueType } from '../../support/permission/type';
|
import { PermissionValueType } from '../../support/permission/type';
|
||||||
|
|
||||||
export type UpdateAppCollaboratorBody = {
|
export type UpdateAppCollaboratorBody = UpdateClbPermissionProps & {
|
||||||
appId: string;
|
appId: string;
|
||||||
tmbIds: string[];
|
|
||||||
permission: PermissionValueType;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AppCollaboratorDeleteParams = {
|
export type AppCollaboratorDeleteParams = {
|
||||||
|
@@ -20,6 +20,7 @@ import { RuntimeNodeItemType } from '../runtime/type';
|
|||||||
import { PluginTypeEnum } from '../../plugin/constants';
|
import { PluginTypeEnum } from '../../plugin/constants';
|
||||||
import { RuntimeEdgeItemType, StoreEdgeItemType } from './edge';
|
import { RuntimeEdgeItemType, StoreEdgeItemType } from './edge';
|
||||||
import { NextApiResponse } from 'next';
|
import { NextApiResponse } from 'next';
|
||||||
|
import { AppDetailType, AppSchema } from '../../app/type';
|
||||||
|
|
||||||
export type FlowNodeCommonType = {
|
export type FlowNodeCommonType = {
|
||||||
flowNodeType: FlowNodeTypeEnum; // render node card
|
flowNodeType: FlowNodeTypeEnum; // render node card
|
||||||
@@ -131,7 +132,7 @@ export type ChatDispatchProps = {
|
|||||||
teamId: string;
|
teamId: string;
|
||||||
tmbId: string;
|
tmbId: string;
|
||||||
user: UserModelSchema;
|
user: UserModelSchema;
|
||||||
appId?: string;
|
app: AppDetailType | AppSchema;
|
||||||
chatId?: string;
|
chatId?: string;
|
||||||
responseChatItemId?: string;
|
responseChatItemId?: string;
|
||||||
histories: ChatItemType[];
|
histories: ChatItemType[];
|
||||||
|
@@ -8,3 +8,8 @@ export type CollaboratorItemType = {
|
|||||||
name: string;
|
name: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type UpdateClbPermissionProps = {
|
||||||
|
tmbIds: string[];
|
||||||
|
permission: PermissionValueType;
|
||||||
|
};
|
||||||
|
@@ -11,7 +11,10 @@ export enum AuthUserTypeEnum {
|
|||||||
|
|
||||||
export enum PermissionTypeEnum {
|
export enum PermissionTypeEnum {
|
||||||
'private' = 'private',
|
'private' = 'private',
|
||||||
'public' = 'public'
|
'public' = 'public',
|
||||||
|
clbPrivate = 'clbPrivate',
|
||||||
|
publicRead = 'publicRead',
|
||||||
|
publicWrite = 'publicWrite'
|
||||||
}
|
}
|
||||||
export const PermissionTypeMap = {
|
export const PermissionTypeMap = {
|
||||||
[PermissionTypeEnum.private]: {
|
[PermissionTypeEnum.private]: {
|
||||||
@@ -21,6 +24,18 @@ export const PermissionTypeMap = {
|
|||||||
[PermissionTypeEnum.public]: {
|
[PermissionTypeEnum.public]: {
|
||||||
iconLight: 'support/permission/publicLight',
|
iconLight: 'support/permission/publicLight',
|
||||||
label: 'permission.Public'
|
label: 'permission.Public'
|
||||||
|
},
|
||||||
|
[PermissionTypeEnum.publicRead]: {
|
||||||
|
iconLight: 'support/permission/publicLight',
|
||||||
|
label: '团队可访问'
|
||||||
|
},
|
||||||
|
[PermissionTypeEnum.publicWrite]: {
|
||||||
|
iconLight: 'support/permission/publicLight',
|
||||||
|
label: '团队可编辑'
|
||||||
|
},
|
||||||
|
[PermissionTypeEnum.clbPrivate]: {
|
||||||
|
iconLight: 'support/permission/privateLight',
|
||||||
|
label: '仅协作者'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,11 +1,14 @@
|
|||||||
import { PermissionKeyEnum, PermissionList, ReadPermissionVal } from '../constant';
|
import { PermissionKeyEnum, PermissionList, ReadPermissionVal } from '../constant';
|
||||||
|
import { PermissionListType } from '../type';
|
||||||
|
|
||||||
export const TeamPermissionList = {
|
export const TeamPermissionList: PermissionListType = {
|
||||||
[PermissionKeyEnum.read]: {
|
[PermissionKeyEnum.read]: {
|
||||||
...PermissionList[PermissionKeyEnum.read]
|
...PermissionList[PermissionKeyEnum.read],
|
||||||
|
description: '成员仅可阅读相关资源,无法新建资源'
|
||||||
},
|
},
|
||||||
[PermissionKeyEnum.write]: {
|
[PermissionKeyEnum.write]: {
|
||||||
...PermissionList[PermissionKeyEnum.write]
|
...PermissionList[PermissionKeyEnum.write],
|
||||||
|
description: '除了可读资源外,还可以新建新的资源'
|
||||||
},
|
},
|
||||||
[PermissionKeyEnum.manage]: {
|
[PermissionKeyEnum.manage]: {
|
||||||
...PermissionList[PermissionKeyEnum.manage],
|
...PermissionList[PermissionKeyEnum.manage],
|
||||||
|
@@ -22,7 +22,7 @@ export type UpdateTeamProps = {
|
|||||||
|
|
||||||
/* ------------- member ----------- */
|
/* ------------- member ----------- */
|
||||||
export type DelMemberProps = {
|
export type DelMemberProps = {
|
||||||
memberId: string;
|
tmbId: string;
|
||||||
};
|
};
|
||||||
export type UpdateTeamMemberProps = {
|
export type UpdateTeamMemberProps = {
|
||||||
teamId: string;
|
teamId: string;
|
||||||
@@ -33,7 +33,7 @@ export type UpdateTeamMemberProps = {
|
|||||||
export type InviteMemberProps = {
|
export type InviteMemberProps = {
|
||||||
teamId: string;
|
teamId: string;
|
||||||
usernames: string[];
|
usernames: string[];
|
||||||
role: `${TeamMemberRoleEnum}`;
|
permission: PermissionValueType;
|
||||||
};
|
};
|
||||||
export type UpdateInviteProps = {
|
export type UpdateInviteProps = {
|
||||||
tmbId: string;
|
tmbId: string;
|
||||||
@@ -43,8 +43,3 @@ export type InviteMemberResponse = Record<
|
|||||||
'invite' | 'inValid' | 'inTeam',
|
'invite' | 'inValid' | 'inTeam',
|
||||||
{ username: string; userId: string }[]
|
{ username: string; userId: string }[]
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type UpdateTeamMemberPermissionProps = {
|
|
||||||
memberIds: string[];
|
|
||||||
permission: PermissionValueType;
|
|
||||||
};
|
|
||||||
|
@@ -70,7 +70,7 @@ export const countGptMessagesTokens = (
|
|||||||
|
|
||||||
callbackMap[id] = (data) => {
|
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());
|
// console.log(process.memoryUsage());
|
||||||
|
|
||||||
resolve(data);
|
resolve(data);
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
|
import { isProduction } from './constants';
|
||||||
|
|
||||||
enum LogLevelEnum {
|
enum LogLevelEnum {
|
||||||
debug = 'debug',
|
debug = 0,
|
||||||
info = 'info',
|
info = 1,
|
||||||
warn = 'warn',
|
warn = 2,
|
||||||
error = 'error'
|
error = 3
|
||||||
}
|
}
|
||||||
const logMap = {
|
const logMap = {
|
||||||
[LogLevelEnum.debug]: {
|
[LogLevelEnum.debug]: {
|
||||||
@@ -21,20 +22,35 @@ const logMap = {
|
|||||||
levelLog: chalk.red('[Error]')
|
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 */
|
/* add logger */
|
||||||
export const addLog = {
|
export const addLog = {
|
||||||
log(level: LogLevelEnum, msg: string, obj: Record<string, any> = {}) {
|
log(level: LogLevelEnum, msg: string, obj: Record<string, any> = {}) {
|
||||||
|
if (level < logLevel) return;
|
||||||
|
|
||||||
const stringifyObj = JSON.stringify(obj);
|
const stringifyObj = JSON.stringify(obj);
|
||||||
const isEmpty = Object.keys(obj).length === 0;
|
const isEmpty = Object.keys(obj).length === 0;
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`${logMap[level].levelLog} ${dayjs().format('YYYY-MM-DD HH:mm:ss')} ${msg} ${
|
`${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;
|
const lokiUrl = process.env.LOKI_LOG_URL as string;
|
||||||
if (!lokiUrl) return;
|
if (!lokiUrl) return;
|
||||||
|
@@ -142,17 +142,17 @@ export const delCollectionRelatedSource = async ({
|
|||||||
.map((item) => item?.metadata?.relatedImgId || '')
|
.map((item) => item?.metadata?.relatedImgId || '')
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
|
|
||||||
|
// delete files
|
||||||
|
await delFileByFileIdList({
|
||||||
|
bucketName: BucketNameEnum.dataset,
|
||||||
|
fileIdList
|
||||||
|
});
|
||||||
// delete images
|
// delete images
|
||||||
await delImgByRelatedId({
|
await delImgByRelatedId({
|
||||||
teamId,
|
teamId,
|
||||||
relateIds: relatedImageIds,
|
relateIds: relatedImageIds,
|
||||||
session
|
session
|
||||||
});
|
});
|
||||||
// delete files
|
|
||||||
await delFileByFileIdList({
|
|
||||||
bucketName: BucketNameEnum.dataset,
|
|
||||||
fileIdList
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* delete collection and it related data
|
* delete collection and it related data
|
||||||
@@ -182,14 +182,16 @@ export async function delCollectionAndRelatedSources({
|
|||||||
);
|
);
|
||||||
const collectionIds = collections.map((item) => String(item._id));
|
const collectionIds = collections.map((item) => String(item._id));
|
||||||
|
|
||||||
await delCollectionRelatedSource({ collections, session });
|
|
||||||
|
|
||||||
// delete training data
|
// delete training data
|
||||||
await MongoDatasetTraining.deleteMany({
|
await MongoDatasetTraining.deleteMany({
|
||||||
teamId,
|
teamId,
|
||||||
datasetIds: { $in: datasetIds },
|
datasetIds: { $in: datasetIds },
|
||||||
collectionId: { $in: collectionIds }
|
collectionId: { $in: collectionIds }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* file and imgs */
|
||||||
|
await delCollectionRelatedSource({ collections, session });
|
||||||
|
|
||||||
// delete dataset.datas
|
// delete dataset.datas
|
||||||
await MongoDatasetData.deleteMany(
|
await MongoDatasetData.deleteMany(
|
||||||
{ teamId, datasetIds: { $in: datasetIds }, collectionId: { $in: collectionIds } },
|
{ teamId, datasetIds: { $in: datasetIds }, collectionId: { $in: collectionIds } },
|
||||||
@@ -199,6 +201,7 @@ export async function delCollectionAndRelatedSources({
|
|||||||
// delete collections
|
// delete collections
|
||||||
await MongoDatasetCollection.deleteMany(
|
await MongoDatasetCollection.deleteMany(
|
||||||
{
|
{
|
||||||
|
teamId,
|
||||||
_id: { $in: collectionIds }
|
_id: { $in: collectionIds }
|
||||||
},
|
},
|
||||||
{ session }
|
{ session }
|
||||||
|
@@ -42,7 +42,7 @@ export async function findCollectionAndChild({
|
|||||||
return collections;
|
return collections;
|
||||||
}
|
}
|
||||||
const [collection, childCollections] = await Promise.all([
|
const [collection, childCollections] = await Promise.all([
|
||||||
MongoDatasetCollection.findById(collectionId, fields),
|
MongoDatasetCollection.findById(collectionId, fields).lean(),
|
||||||
find(collectionId)
|
find(collectionId)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@@ -82,17 +82,18 @@ export async function delDatasetRelevantData({
|
|||||||
teamId,
|
teamId,
|
||||||
datasetId: { $in: datasetIds }
|
datasetId: { $in: datasetIds }
|
||||||
},
|
},
|
||||||
'_id teamId fileId metadata'
|
'_id teamId datasetId fileId metadata'
|
||||||
).lean();
|
).lean();
|
||||||
|
|
||||||
// image and file
|
|
||||||
await delCollectionRelatedSource({ collections, session });
|
|
||||||
|
|
||||||
// delete training data
|
// delete training data
|
||||||
await MongoDatasetTraining.deleteMany({
|
await MongoDatasetTraining.deleteMany({
|
||||||
teamId,
|
teamId,
|
||||||
datasetId: { $in: datasetIds }
|
datasetId: { $in: datasetIds }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// image and file
|
||||||
|
await delCollectionRelatedSource({ collections, session });
|
||||||
|
|
||||||
// delete dataset.datas
|
// delete dataset.datas
|
||||||
await MongoDatasetData.deleteMany({ teamId, datasetId: { $in: datasetIds } }, { session });
|
await MongoDatasetData.deleteMany({ teamId, datasetId: { $in: datasetIds } }, { session });
|
||||||
|
|
||||||
|
@@ -407,13 +407,13 @@ export function responseStatus({
|
|||||||
/* get system variable */
|
/* get system variable */
|
||||||
export function getSystemVariable({
|
export function getSystemVariable({
|
||||||
user,
|
user,
|
||||||
appId,
|
app,
|
||||||
chatId,
|
chatId,
|
||||||
responseChatItemId,
|
responseChatItemId,
|
||||||
histories = []
|
histories = []
|
||||||
}: Props) {
|
}: Props) {
|
||||||
return {
|
return {
|
||||||
appId,
|
appId: String(app._id),
|
||||||
chatId,
|
chatId,
|
||||||
responseChatItemId,
|
responseChatItemId,
|
||||||
histories,
|
histories,
|
||||||
|
@@ -43,7 +43,7 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
|
|||||||
let {
|
let {
|
||||||
res,
|
res,
|
||||||
detail,
|
detail,
|
||||||
appId,
|
app: { _id: appId },
|
||||||
chatId,
|
chatId,
|
||||||
stream,
|
stream,
|
||||||
responseChatItemId,
|
responseChatItemId,
|
||||||
|
@@ -33,8 +33,7 @@ type Response = DispatchNodeResultType<{
|
|||||||
export const dispatchAppRequest = async (props: Props): Promise<Response> => {
|
export const dispatchAppRequest = async (props: Props): Promise<Response> => {
|
||||||
const {
|
const {
|
||||||
res,
|
res,
|
||||||
teamId,
|
app: workflowApp,
|
||||||
tmbId,
|
|
||||||
stream,
|
stream,
|
||||||
detail,
|
detail,
|
||||||
histories,
|
histories,
|
||||||
@@ -46,10 +45,11 @@ export const dispatchAppRequest = async (props: Props): Promise<Response> => {
|
|||||||
return Promise.reject('Input is empty');
|
return Promise.reject('Input is empty');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查该工作流的tmb是否有调用该app的权限(不是校验对话的人,是否有权限)
|
||||||
const { app: appData } = await authAppByTmbId({
|
const { app: appData } = await authAppByTmbId({
|
||||||
appId: app.id,
|
appId: app.id,
|
||||||
teamId,
|
teamId: workflowApp.teamId,
|
||||||
tmbId,
|
tmbId: workflowApp.tmbId,
|
||||||
per: ReadPermissionVal
|
per: ReadPermissionVal
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ export const dispatchAppRequest = async (props: Props): Promise<Response> => {
|
|||||||
|
|
||||||
const { flowResponses, flowUsages, assistantResponses } = await dispatchWorkFlow({
|
const { flowResponses, flowUsages, assistantResponses } = await dispatchWorkFlow({
|
||||||
...props,
|
...props,
|
||||||
appId: app.id,
|
app: appData,
|
||||||
runtimeNodes: storeNodes2RuntimeNodes(appData.modules, getDefaultEntryNodeIds(appData.modules)),
|
runtimeNodes: storeNodes2RuntimeNodes(appData.modules, getDefaultEntryNodeIds(appData.modules)),
|
||||||
runtimeEdges: initWorkflowEdgeStatus(appData.edges),
|
runtimeEdges: initWorkflowEdgeStatus(appData.edges),
|
||||||
histories: chatHistories,
|
histories: chatHistories,
|
||||||
|
@@ -21,7 +21,7 @@ const UNDEFINED_SIGN = 'UNDEFINED_SIGN';
|
|||||||
|
|
||||||
export const dispatchLafRequest = async (props: LafRequestProps): Promise<LafResponse> => {
|
export const dispatchLafRequest = async (props: LafRequestProps): Promise<LafResponse> => {
|
||||||
let {
|
let {
|
||||||
appId,
|
app: { _id: appId },
|
||||||
chatId,
|
chatId,
|
||||||
responseChatItemId,
|
responseChatItemId,
|
||||||
variables,
|
variables,
|
||||||
|
@@ -7,8 +7,6 @@ import { AuthUserTypeEnum, PerResourceTypeEnum } from '@fastgpt/global/support/p
|
|||||||
import { authOpenApiKey } from '../openapi/auth';
|
import { authOpenApiKey } from '../openapi/auth';
|
||||||
import { FileTokenQuery } from '@fastgpt/global/common/file/type';
|
import { FileTokenQuery } from '@fastgpt/global/common/file/type';
|
||||||
import { MongoResourcePermission } from './schema';
|
import { MongoResourcePermission } from './schema';
|
||||||
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
|
||||||
import { mongoSessionRun } from '../../common/mongo/sessionRun';
|
|
||||||
|
|
||||||
export const getResourcePermission = async ({
|
export const getResourcePermission = async ({
|
||||||
resourceType,
|
resourceType,
|
||||||
@@ -36,41 +34,6 @@ export const getResourcePermission = async ({
|
|||||||
export const delResourcePermissionById = (id: string) => {
|
export const delResourcePermissionById = (id: string) => {
|
||||||
return MongoResourcePermission.findByIdAndRemove(id);
|
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 */
|
/* create token */
|
||||||
|
@@ -45,6 +45,11 @@ try {
|
|||||||
unique: true
|
unique: true
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
ResourcePermissionSchema.index({
|
||||||
|
resourceType: 1,
|
||||||
|
teamId: 1,
|
||||||
|
resourceId: 1
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
|
@@ -9,10 +9,7 @@ import { MongoTeamMember } from './teamMemberSchema';
|
|||||||
import { MongoTeam } from './teamSchema';
|
import { MongoTeam } from './teamSchema';
|
||||||
import { UpdateTeamProps } from '@fastgpt/global/support/user/team/controller';
|
import { UpdateTeamProps } from '@fastgpt/global/support/user/team/controller';
|
||||||
import { getResourcePermission } from '../../permission/controller';
|
import { getResourcePermission } from '../../permission/controller';
|
||||||
import {
|
import { PerResourceTypeEnum } from '@fastgpt/global/support/permission/constant';
|
||||||
PerResourceTypeEnum,
|
|
||||||
ReadPermissionVal
|
|
||||||
} from '@fastgpt/global/support/permission/constant';
|
|
||||||
import { TeamPermission } from '@fastgpt/global/support/permission/user/controller';
|
import { TeamPermission } from '@fastgpt/global/support/permission/user/controller';
|
||||||
|
|
||||||
async function getTeamMember(match: Record<string, any>): Promise<TeamTmbItemType> {
|
async function getTeamMember(match: Record<string, any>): Promise<TeamTmbItemType> {
|
||||||
|
@@ -21,6 +21,7 @@ export type SelectProps = ButtonProps & {
|
|||||||
list: {
|
list: {
|
||||||
alias?: string;
|
alias?: string;
|
||||||
label: string | React.ReactNode;
|
label: string | React.ReactNode;
|
||||||
|
description?: string;
|
||||||
value: string | number;
|
value: string | number;
|
||||||
}[];
|
}[];
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
@@ -125,10 +126,12 @@ const MySelect = (
|
|||||||
{...menuItemStyles}
|
{...menuItemStyles}
|
||||||
{...(value === item.value
|
{...(value === item.value
|
||||||
? {
|
? {
|
||||||
color: 'primary.500',
|
color: 'primary.600',
|
||||||
bg: 'myWhite.300'
|
bg: 'myGray.100'
|
||||||
}
|
}
|
||||||
: {})}
|
: {
|
||||||
|
color: 'myGray.900'
|
||||||
|
})}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (onchange && value !== item.value) {
|
if (onchange && value !== item.value) {
|
||||||
onchange(item.value);
|
onchange(item.value);
|
||||||
@@ -136,8 +139,14 @@ const MySelect = (
|
|||||||
}}
|
}}
|
||||||
whiteSpace={'pre-wrap'}
|
whiteSpace={'pre-wrap'}
|
||||||
fontSize={'sm'}
|
fontSize={'sm'}
|
||||||
|
display={'block'}
|
||||||
>
|
>
|
||||||
{item.label}
|
<Box>{item.label}</Box>
|
||||||
|
{item.description && (
|
||||||
|
<Box color={'myGray.500'} fontSize={'xs'}>
|
||||||
|
{item.description}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
</MenuList>
|
</MenuList>
|
||||||
|
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@@ -422,6 +422,9 @@ importers:
|
|||||||
js-yaml:
|
js-yaml:
|
||||||
specifier: ^4.1.0
|
specifier: ^4.1.0
|
||||||
version: 4.1.0
|
version: 4.1.0
|
||||||
|
json5:
|
||||||
|
specifier: ^2.2.3
|
||||||
|
version: 2.2.3
|
||||||
jsonwebtoken:
|
jsonwebtoken:
|
||||||
specifier: ^9.0.2
|
specifier: ^9.0.2
|
||||||
version: 9.0.2
|
version: 9.0.2
|
||||||
|
@@ -32,5 +32,7 @@ SANDBOX_URL=http://localhost:3001
|
|||||||
PRO_URL=
|
PRO_URL=
|
||||||
# 首页路径
|
# 首页路径
|
||||||
HOME_URL=/
|
HOME_URL=/
|
||||||
|
# 日志等级: debug, info, warn, error
|
||||||
|
LOG_LEVEL=info
|
||||||
# Loki Log Path
|
# Loki Log Path
|
||||||
# LOKI_LOG_URL=
|
# LOKI_LOG_URL=
|
@@ -1,37 +1,36 @@
|
|||||||
|
// 已使用 json5 进行解析,会自动去掉注释,无需手动去除
|
||||||
{
|
{
|
||||||
"feConfigs": {
|
"feConfigs": {
|
||||||
"lafEnv": "https://laf.dev"
|
"lafEnv": "https://laf.dev" // laf环境。 https://laf.run (杭州阿里云) ,或者私有化的laf环境。如果使用 Laf openapi 功能,需要最新版的 laf 。
|
||||||
},
|
},
|
||||||
"systemEnv": {
|
"systemEnv": {
|
||||||
"openapiPrefix": "fastgpt",
|
|
||||||
"vectorMaxProcess": 15,
|
"vectorMaxProcess": 15,
|
||||||
"qaMaxProcess": 15,
|
"qaMaxProcess": 15,
|
||||||
"pgHNSWEfSearch": 100,
|
"pgHNSWEfSearch": 100 // 向量搜索参数。越大,搜索越精确,但是速度越慢。设置为100,有99%+精度。
|
||||||
"tokenWorkers": 20
|
|
||||||
},
|
},
|
||||||
"llmModels": [
|
"llmModels": [
|
||||||
{
|
{
|
||||||
"model": "gpt-3.5-turbo",
|
"model": "gpt-3.5-turbo", // 模型名(对应OneAPI中渠道的模型名)
|
||||||
"name": "gpt-3.5-turbo",
|
"name": "gpt-3.5-turbo", // 模型别名
|
||||||
"maxContext": 16000,
|
"avatar": "/imgs/model/openai.svg", // 模型的logo
|
||||||
"avatar": "/imgs/model/openai.svg",
|
"maxContext": 16000, // 最大上下文
|
||||||
"maxResponse": 4000,
|
"maxResponse": 4000, // 最大回复
|
||||||
"quoteMaxToken": 13000,
|
"quoteMaxToken": 13000, // 最大引用内容
|
||||||
"maxTemperature": 1.2,
|
"maxTemperature": 1.2, // 最大温度
|
||||||
"charsPointsPrice": 0,
|
"charsPointsPrice": 0, // n积分/1k token(商业版)
|
||||||
"censor": false,
|
"censor": false, // 是否开启敏感校验(商业版)
|
||||||
"vision": false,
|
"vision": false, // 是否支持图片输入
|
||||||
"datasetProcess": true,
|
"datasetProcess": true, // 是否设置为知识库处理模型(QA),务必保证至少有一个为true,否则知识库会报错
|
||||||
"usedInClassify": true,
|
"usedInClassify": true, // 是否用于问题分类(务必保证至少有一个为true)
|
||||||
"usedInExtractFields": true,
|
"usedInExtractFields": true, // 是否用于内容提取(务必保证至少有一个为true)
|
||||||
"usedInToolCall": true,
|
"usedInToolCall": true, // 是否用于工具调用(务必保证至少有一个为true)
|
||||||
"usedInQueryExtension": true,
|
"usedInQueryExtension": true, // 是否用于问题优化(务必保证至少有一个为true)
|
||||||
"toolChoice": true,
|
"toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。目前只有gpt支持)
|
||||||
"functionCall": true,
|
"functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice,如果为false,则使用 functionCall,如果仍为 false,则使用提示词模式)
|
||||||
"customCQPrompt": "",
|
"customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型
|
||||||
"customExtractPrompt": "",
|
"customExtractPrompt": "", // 自定义内容提取提示词
|
||||||
"defaultSystemChatPrompt": "",
|
"defaultSystemChatPrompt": "", // 对话默认携带的系统提示词
|
||||||
"defaultConfig": {}
|
"defaultConfig": {} // 请求API时,挟带一些默认配置(比如 GLM4 的 top_p)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"model": "gpt-4-0125-preview",
|
"model": "gpt-4-0125-preview",
|
||||||
@@ -82,40 +81,16 @@
|
|||||||
],
|
],
|
||||||
"vectorModels": [
|
"vectorModels": [
|
||||||
{
|
{
|
||||||
"model": "text-embedding-3-large",
|
"model": "text-embedding-ada-002", // 模型名(与OneAPI对应)
|
||||||
"name": "Embedding-3-large",
|
"name": "Embedding-2", // 模型展示名
|
||||||
"avatar": "/imgs/model/openai.svg",
|
"avatar": "/imgs/model/openai.svg", // logo
|
||||||
"charsPointsPrice": 0,
|
"charsPointsPrice": 0, // n积分/1k token
|
||||||
"defaultToken": 512,
|
"defaultToken": 700, // 默认文本分割时候的 token
|
||||||
"maxToken": 3000,
|
"maxToken": 3000, // 最大 token
|
||||||
"weight": 100,
|
"weight": 100, // 优先训练权重
|
||||||
"dbConfig": {},
|
"defaultConfig": {}, // 自定义额外参数。例如,如果希望使用 embedding3-large 的话,可以传入 dimensions:1024,来返回1024维度的向量。(目前必须小于1536维度)
|
||||||
"queryConfig": {},
|
"dbConfig": {}, // 存储时的额外参数(非对称向量模型时候需要用到)
|
||||||
"defaultConfig": {
|
"queryConfig": {} // 参训时的额外参数
|
||||||
"dimensions": 1024
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "text-embedding-3-small",
|
|
||||||
"name": "Embedding-3-small",
|
|
||||||
"avatar": "/imgs/model/openai.svg",
|
|
||||||
"charsPointsPrice": 0,
|
|
||||||
"defaultToken": 512,
|
|
||||||
"maxToken": 3000,
|
|
||||||
"weight": 100,
|
|
||||||
"dbConfig": {},
|
|
||||||
"queryConfig": {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"model": "text-embedding-ada-002",
|
|
||||||
"name": "text-embedding-ada-002",
|
|
||||||
"avatar": "/imgs/model/openai.svg",
|
|
||||||
"charsPointsPrice": 0,
|
|
||||||
"defaultToken": 512,
|
|
||||||
"maxToken": 3000,
|
|
||||||
"weight": 100,
|
|
||||||
"dbConfig": {},
|
|
||||||
"queryConfig": {}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"reRankModels": [],
|
"reRankModels": [],
|
||||||
@@ -125,36 +100,12 @@
|
|||||||
"name": "OpenAI TTS1",
|
"name": "OpenAI TTS1",
|
||||||
"charsPointsPrice": 0,
|
"charsPointsPrice": 0,
|
||||||
"voices": [
|
"voices": [
|
||||||
{
|
{ "label": "Alloy", "value": "alloy", "bufferId": "openai-Alloy" },
|
||||||
"label": "Alloy",
|
{ "label": "Echo", "value": "echo", "bufferId": "openai-Echo" },
|
||||||
"value": "alloy",
|
{ "label": "Fable", "value": "fable", "bufferId": "openai-Fable" },
|
||||||
"bufferId": "openai-Alloy"
|
{ "label": "Onyx", "value": "onyx", "bufferId": "openai-Onyx" },
|
||||||
},
|
{ "label": "Nova", "value": "nova", "bufferId": "openai-Nova" },
|
||||||
{
|
{ "label": "Shimmer", "value": "shimmer", "bufferId": "openai-Shimmer" }
|
||||||
"label": "Echo",
|
|
||||||
"value": "echo",
|
|
||||||
"bufferId": "openai-Echo"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Fable",
|
|
||||||
"value": "fable",
|
|
||||||
"bufferId": "openai-Fable"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Onyx",
|
|
||||||
"value": "onyx",
|
|
||||||
"bufferId": "openai-Onyx"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Nova",
|
|
||||||
"value": "nova",
|
|
||||||
"bufferId": "openai-Nova"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Shimmer",
|
|
||||||
"value": "shimmer",
|
|
||||||
"bufferId": "openai-Shimmer"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@@ -1223,6 +1223,7 @@
|
|||||||
"Default permission": "Default permission",
|
"Default permission": "Default permission",
|
||||||
"Manage": "Manage",
|
"Manage": "Manage",
|
||||||
"Not collaborator": "Not collaborator",
|
"Not collaborator": "Not collaborator",
|
||||||
|
"Owner": "Owner",
|
||||||
"Permission": "Permission",
|
"Permission": "Permission",
|
||||||
"Permission config": "Permission config",
|
"Permission config": "Permission config",
|
||||||
"Private": "Private",
|
"Private": "Private",
|
||||||
@@ -1571,9 +1572,6 @@
|
|||||||
"Invite Member Success Tip": "Invitation completed\nSuccess: {{success}}\nInvalid usernames: {{inValid}}\nAlready in team: {{inTeam}}",
|
"Invite Member Success Tip": "Invitation completed\nSuccess: {{success}}\nInvalid usernames: {{inValid}}\nAlready in team: {{inTeam}}",
|
||||||
"Invite Member Tips": "The invitee can access or use other resources within the team",
|
"Invite Member Tips": "The invitee can access or use other resources within the team",
|
||||||
"Invite Role Admin Alias": "Invite Admin",
|
"Invite Role Admin Alias": "Invite Admin",
|
||||||
"Invite Role Admin Tip": "Admin\nCan create, edit, and use team resources",
|
|
||||||
"Invite Role Visitor Alias": "Invite Visitor",
|
|
||||||
"Invite Role Visitor Tip": "Visitor\nCan only use resources, no creation or editing rights",
|
|
||||||
"Leave Team": "Leave Team",
|
"Leave Team": "Leave Team",
|
||||||
"Leave Team Failed": "Failed to leave team",
|
"Leave Team Failed": "Failed to leave team",
|
||||||
"Manage": "Team Management",
|
"Manage": "Team Management",
|
||||||
|
@@ -1,5 +1,21 @@
|
|||||||
{
|
{
|
||||||
|
"permission": {
|
||||||
|
"Set read permission": "Read permission",
|
||||||
|
"Set write permission": "Write permission"
|
||||||
|
},
|
||||||
"team": {
|
"team": {
|
||||||
"Add manager": "Add manager"
|
"Add manager": "Add manager"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"team": {
|
||||||
|
"permission": {
|
||||||
|
"Manage": "Admin",
|
||||||
|
"Manage tip": "Team administrator with full permissions",
|
||||||
|
"Read": "Read",
|
||||||
|
"Read desc": "Members can only read related resources and cannot create new resources",
|
||||||
|
"Write": "Write",
|
||||||
|
"Write tip": "In addition to readable resources, you can create new resources"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1231,6 +1231,7 @@
|
|||||||
"Default permission": "默认权限",
|
"Default permission": "默认权限",
|
||||||
"Manage": "管理",
|
"Manage": "管理",
|
||||||
"Not collaborator": "暂无协作者",
|
"Not collaborator": "暂无协作者",
|
||||||
|
"Owner": "创建者",
|
||||||
"Permission": "权限",
|
"Permission": "权限",
|
||||||
"Permission config": "权限配置",
|
"Permission config": "权限配置",
|
||||||
"Private": "私有",
|
"Private": "私有",
|
||||||
@@ -1579,9 +1580,6 @@
|
|||||||
"Invite Member Success Tip": "邀请成员完成\n成功: {{success}}人\n用户名无效: {{inValid}}\n已在团队中:{{inTeam}}",
|
"Invite Member Success Tip": "邀请成员完成\n成功: {{success}}人\n用户名无效: {{inValid}}\n已在团队中:{{inTeam}}",
|
||||||
"Invite Member Tips": "对方可查阅或使用团队内的其他资源",
|
"Invite Member Tips": "对方可查阅或使用团队内的其他资源",
|
||||||
"Invite Role Admin Alias": "邀请管理员加入",
|
"Invite Role Admin Alias": "邀请管理员加入",
|
||||||
"Invite Role Admin Tip": "管理员\n可创建、编辑和使用团队资源",
|
|
||||||
"Invite Role Visitor Alias": "邀请访客加入",
|
|
||||||
"Invite Role Visitor Tip": "访客\n仅可使用资源,无创建编辑权限",
|
|
||||||
"Leave Team": "离开团队",
|
"Leave Team": "离开团队",
|
||||||
"Leave Team Failed": "离开团队异常",
|
"Leave Team Failed": "离开团队异常",
|
||||||
"Manage": "团队管理",
|
"Manage": "团队管理",
|
||||||
|
@@ -1,4 +1,14 @@
|
|||||||
{
|
{
|
||||||
|
"permission": {
|
||||||
|
"Manage": "管理员",
|
||||||
|
"Manage tip": "团队管理员,拥有全部权限",
|
||||||
|
"Read": "仅读",
|
||||||
|
"Read desc": "成员仅可阅读相关资源,无法新建资源",
|
||||||
|
"Set read permission": "设为仅读",
|
||||||
|
"Set write permission": "设为可写",
|
||||||
|
"Write": "可写",
|
||||||
|
"Write tip": "除了可读资源外,还可以新建新的资源"
|
||||||
|
},
|
||||||
"team": {
|
"team": {
|
||||||
"Add manager": "添加管理员"
|
"Add manager": "添加管理员"
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "app",
|
"name": "app",
|
||||||
"version": "4.8.3",
|
"version": "4.8.4",
|
||||||
"private": false,
|
"private": false,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
"mermaid": "^10.2.3",
|
"mermaid": "^10.2.3",
|
||||||
"nanoid": "^4.0.1",
|
"nanoid": "^4.0.1",
|
||||||
"next": "14.2.3",
|
"next": "14.2.3",
|
||||||
|
"json5": "^2.2.3",
|
||||||
"next-i18next": "15.2.0",
|
"next-i18next": "15.2.0",
|
||||||
"nextjs-node-loader": "^1.1.5",
|
"nextjs-node-loader": "^1.1.5",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
|
@@ -8,13 +8,13 @@ import { useTranslation } from 'next-i18next';
|
|||||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||||
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
||||||
import DefaultPermissionList from '@/components/support/permission/DefaultPerList';
|
import DefaultPermissionList from '@/components/support/permission/DefaultPerList';
|
||||||
import {
|
import CollaboratorContextProvider, {
|
||||||
CollaboratorContextProvider,
|
|
||||||
MemberManagerInputPropsType
|
MemberManagerInputPropsType
|
||||||
} from '../../support/permission/MemberManager/context';
|
} from '../../support/permission/MemberManager/context';
|
||||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||||
|
|
||||||
const FolderSlideCard = ({
|
const FolderSlideCard = ({
|
||||||
|
refreshDeps,
|
||||||
name,
|
name,
|
||||||
intro,
|
intro,
|
||||||
onEdit,
|
onEdit,
|
||||||
@@ -25,6 +25,7 @@ const FolderSlideCard = ({
|
|||||||
defaultPer,
|
defaultPer,
|
||||||
managePer
|
managePer
|
||||||
}: {
|
}: {
|
||||||
|
refreshDeps?: any[];
|
||||||
name: string;
|
name: string;
|
||||||
intro?: string;
|
intro?: string;
|
||||||
onEdit: () => void;
|
onEdit: () => void;
|
||||||
@@ -86,22 +87,24 @@ const FolderSlideCard = ({
|
|||||||
>
|
>
|
||||||
{t('common.Move')}
|
{t('common.Move')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
{managePer.permission.isOwner && (
|
||||||
variant={'transparentDanger'}
|
<Button
|
||||||
pl={1}
|
variant={'transparentDanger'}
|
||||||
leftIcon={<MyIcon name={'delete'} w={'1rem'} />}
|
pl={1}
|
||||||
transform={'none !important'}
|
leftIcon={<MyIcon name={'delete'} w={'1rem'} />}
|
||||||
w={'100%'}
|
transform={'none !important'}
|
||||||
justifyContent={'flex-start'}
|
w={'100%'}
|
||||||
size={'sm'}
|
justifyContent={'flex-start'}
|
||||||
fontSize={'mini'}
|
size={'sm'}
|
||||||
mt={3}
|
fontSize={'mini'}
|
||||||
onClick={() => {
|
mt={3}
|
||||||
openConfirm(onDelete)();
|
onClick={() => {
|
||||||
}}
|
openConfirm(onDelete)();
|
||||||
>
|
}}
|
||||||
{t('common.Delete folder')}
|
>
|
||||||
</Button>
|
{t('common.Delete folder')}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@@ -125,7 +128,7 @@ const FolderSlideCard = ({
|
|||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
<Box mt={6}>
|
<Box mt={6}>
|
||||||
<CollaboratorContextProvider {...managePer}>
|
<CollaboratorContextProvider {...managePer} refreshDeps={refreshDeps}>
|
||||||
{({ MemberListCard, onOpenManageModal, onOpenAddMember }) => {
|
{({ MemberListCard, onOpenManageModal, onOpenAddMember }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
||||||
import { MemberManagerInputPropsType, CollaboratorContextProvider } from '../MemberManager/context';
|
import CollaboratorContextProvider, { MemberManagerInputPropsType } from '../MemberManager/context';
|
||||||
import { Box, Button, Flex, HStack, ModalBody } from '@chakra-ui/react';
|
import { Box, Button, Flex, HStack, ModalBody } from '@chakra-ui/react';
|
||||||
import Avatar from '@/components/Avatar';
|
import Avatar from '@/components/Avatar';
|
||||||
import DefaultPermissionList from '../DefaultPerList';
|
import DefaultPermissionList from '../DefaultPerList';
|
||||||
|
@@ -20,8 +20,11 @@ const PermissionIconText = ({
|
|||||||
|
|
||||||
const per = useMemo(() => {
|
const per = useMemo(() => {
|
||||||
if (permission) return permission;
|
if (permission) return permission;
|
||||||
if (defaultPermission) {
|
if (defaultPermission !== undefined) {
|
||||||
return new Permission({ per: defaultPermission }).hasReadPer ? 'public' : 'private';
|
const Per = new Permission({ per: defaultPermission });
|
||||||
|
if (Per.hasWritePer) return PermissionTypeEnum.publicWrite;
|
||||||
|
if (Per.hasReadPer) return PermissionTypeEnum.publicRead;
|
||||||
|
return PermissionTypeEnum.clbPrivate;
|
||||||
}
|
}
|
||||||
return 'private';
|
return 'private';
|
||||||
}, [defaultPermission, permission]);
|
}, [defaultPermission, permission]);
|
||||||
|
@@ -26,12 +26,14 @@ import MyBox from '@fastgpt/web/components/common/MyBox';
|
|||||||
import { ChevronDownIcon } from '@chakra-ui/icons';
|
import { ChevronDownIcon } from '@chakra-ui/icons';
|
||||||
import Avatar from '@/components/Avatar';
|
import Avatar from '@/components/Avatar';
|
||||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||||
|
import { useTranslation } from 'next-i18next';
|
||||||
|
|
||||||
export type AddModalPropsType = {
|
export type AddModalPropsType = {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
function AddMemberModal({ onClose }: AddModalPropsType) {
|
function AddMemberModal({ onClose }: AddModalPropsType) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { userInfo } = useUserStore();
|
const { userInfo } = useUserStore();
|
||||||
|
|
||||||
const { permissionList, collaboratorList, onUpdateCollaborators, getPerLabelList } =
|
const { permissionList, collaboratorList, onUpdateCollaborators, getPerLabelList } =
|
||||||
@@ -63,9 +65,12 @@ function AddMemberModal({ onClose }: AddModalPropsType) {
|
|||||||
|
|
||||||
const { mutate: onConfirm, isLoading: isUpdating } = useRequest({
|
const { mutate: onConfirm, isLoading: isUpdating } = useRequest({
|
||||||
mutationFn: () => {
|
mutationFn: () => {
|
||||||
return onUpdateCollaborators(selectedMemberIdList, selectedPermission);
|
return onUpdateCollaborators({
|
||||||
|
tmbIds: selectedMemberIdList,
|
||||||
|
permission: selectedPermission
|
||||||
|
});
|
||||||
},
|
},
|
||||||
successToast: '添加成功',
|
successToast: t('common.Add Success'),
|
||||||
errorToast: 'Error',
|
errorToast: 'Error',
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
onClose();
|
onClose();
|
||||||
|
@@ -39,7 +39,10 @@ function ManageModal({ onClose }: ManageModalProps) {
|
|||||||
|
|
||||||
const { mutate: onUpdate, isLoading: isUpdating } = useRequest({
|
const { mutate: onUpdate, isLoading: isUpdating } = useRequest({
|
||||||
mutationFn: ({ tmbId, per }: { tmbId: string; per: PermissionValueType }) => {
|
mutationFn: ({ tmbId, per }: { tmbId: string; per: PermissionValueType }) => {
|
||||||
return onUpdateCollaborators([tmbId], per);
|
return onUpdateCollaborators({
|
||||||
|
tmbIds: [tmbId],
|
||||||
|
permission: per
|
||||||
|
});
|
||||||
},
|
},
|
||||||
successToast: '更新成功',
|
successToast: '更新成功',
|
||||||
errorToast: 'Error'
|
errorToast: 'Error'
|
||||||
|
@@ -6,7 +6,8 @@ import {
|
|||||||
MenuList,
|
MenuList,
|
||||||
Box,
|
Box,
|
||||||
Radio,
|
Radio,
|
||||||
useOutsideClick
|
useOutsideClick,
|
||||||
|
HStack
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import React, { useMemo, useRef, useState } from 'react';
|
import React, { useMemo, useRef, useState } from 'react';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
@@ -142,9 +143,15 @@ function PermissionSelect({
|
|||||||
bottom={0}
|
bottom={0}
|
||||||
left={0}
|
left={0}
|
||||||
/>
|
/>
|
||||||
<Box position={'relative'} cursor={'pointer'} userSelect={'none'}>
|
<Flex
|
||||||
|
alignItems={'center'}
|
||||||
|
justifyContent={'center'}
|
||||||
|
position={'relative'}
|
||||||
|
cursor={'pointer'}
|
||||||
|
userSelect={'none'}
|
||||||
|
>
|
||||||
{Button}
|
{Button}
|
||||||
</Box>
|
</Flex>
|
||||||
</Box>
|
</Box>
|
||||||
<MenuList
|
<MenuList
|
||||||
minW={isOpen ? `${width}px !important` : 0}
|
minW={isOpen ? `${width}px !important` : 0}
|
||||||
@@ -182,7 +189,7 @@ function PermissionSelect({
|
|||||||
<Box ml={4}>
|
<Box ml={4}>
|
||||||
<Box>{item.name}</Box>
|
<Box>{item.name}</Box>
|
||||||
<Box color={'myGray.500'} fontSize={'mini'}>
|
<Box color={'myGray.500'} fontSize={'mini'}>
|
||||||
{item.description}
|
{t(item.description)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -236,7 +243,7 @@ function PermissionSelect({
|
|||||||
{onDelete && (
|
{onDelete && (
|
||||||
<>
|
<>
|
||||||
<MyDivider my={2} h={'2px'} borderColor={'myGray.200'} />
|
<MyDivider my={2} h={'2px'} borderColor={'myGray.200'} />
|
||||||
<Flex
|
<HStack
|
||||||
{...MenuStyle}
|
{...MenuStyle}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onDelete();
|
onDelete();
|
||||||
@@ -244,8 +251,8 @@ function PermissionSelect({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MyIcon name="delete" w="20px" color="red.600" />
|
<MyIcon name="delete" w="20px" color="red.600" />
|
||||||
<Box color="red.600">{t('common.Delete')}</Box>
|
<Box color="red.600">{t('common.Remove')}</Box>
|
||||||
</Flex>
|
</HStack>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</MenuList>
|
</MenuList>
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
import { BoxProps, useDisclosure } from '@chakra-ui/react';
|
import { BoxProps, useDisclosure } from '@chakra-ui/react';
|
||||||
import { CollaboratorItemType } from '@fastgpt/global/support/permission/collaborator';
|
import {
|
||||||
|
CollaboratorItemType,
|
||||||
|
UpdateClbPermissionProps
|
||||||
|
} from '@fastgpt/global/support/permission/collaborator';
|
||||||
import { PermissionList } from '@fastgpt/global/support/permission/constant';
|
import { PermissionList } from '@fastgpt/global/support/permission/constant';
|
||||||
import { Permission } from '@fastgpt/global/support/permission/controller';
|
import { Permission } from '@fastgpt/global/support/permission/controller';
|
||||||
import { PermissionListType, PermissionValueType } from '@fastgpt/global/support/permission/type';
|
import { PermissionListType, PermissionValueType } from '@fastgpt/global/support/permission/type';
|
||||||
@@ -9,6 +12,7 @@ import { createContext } from 'use-context-selector';
|
|||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
|
|
||||||
import MemberListCard, { MemberListCardProps } from './MemberListCard';
|
import MemberListCard, { MemberListCardProps } from './MemberListCard';
|
||||||
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
const AddMemberModal = dynamic(() => import('./AddMemberModal'));
|
const AddMemberModal = dynamic(() => import('./AddMemberModal'));
|
||||||
const ManageModal = dynamic(() => import('./ManageModal'));
|
const ManageModal = dynamic(() => import('./ManageModal'));
|
||||||
|
|
||||||
@@ -16,8 +20,9 @@ export type MemberManagerInputPropsType = {
|
|||||||
permission: Permission;
|
permission: Permission;
|
||||||
onGetCollaboratorList: () => Promise<CollaboratorItemType[]>;
|
onGetCollaboratorList: () => Promise<CollaboratorItemType[]>;
|
||||||
permissionList: PermissionListType;
|
permissionList: PermissionListType;
|
||||||
onUpdateCollaborators: (tmbIds: string[], permission: PermissionValueType) => any;
|
onUpdateCollaborators: (props: UpdateClbPermissionProps) => any;
|
||||||
onDelOneCollaborator: (tmbId: string) => any;
|
onDelOneCollaborator: (tmbId: string) => any;
|
||||||
|
refreshDeps?: any[];
|
||||||
};
|
};
|
||||||
export type MemberManagerPropsType = MemberManagerInputPropsType & {
|
export type MemberManagerPropsType = MemberManagerInputPropsType & {
|
||||||
collaboratorList: CollaboratorItemType[];
|
collaboratorList: CollaboratorItemType[];
|
||||||
@@ -55,24 +60,28 @@ export const CollaboratorContext = createContext<CollaboratorContextType>({
|
|||||||
permission: new Permission()
|
permission: new Permission()
|
||||||
});
|
});
|
||||||
|
|
||||||
export const CollaboratorContextProvider = ({
|
const CollaboratorContextProvider = ({
|
||||||
permission,
|
permission,
|
||||||
onGetCollaboratorList,
|
onGetCollaboratorList,
|
||||||
permissionList,
|
permissionList,
|
||||||
onUpdateCollaborators,
|
onUpdateCollaborators,
|
||||||
onDelOneCollaborator,
|
onDelOneCollaborator,
|
||||||
|
refreshDeps = [],
|
||||||
children
|
children
|
||||||
}: MemberManagerInputPropsType & {
|
}: MemberManagerInputPropsType & {
|
||||||
children: (props: ChildrenProps) => ReactNode;
|
children: (props: ChildrenProps) => ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
data: collaboratorList = [],
|
data: collaboratorList = [],
|
||||||
refetch: refetchCollaboratorList,
|
runAsync: refetchCollaboratorList,
|
||||||
isLoading: isFetchingCollaborator
|
loading: isFetchingCollaborator
|
||||||
} = useQuery(['collaboratorList'], onGetCollaboratorList);
|
} = useRequest2(onGetCollaboratorList, {
|
||||||
|
manual: false,
|
||||||
|
refreshDeps
|
||||||
|
});
|
||||||
|
|
||||||
const onUpdateCollaboratorsThen = async (tmbIds: string[], permission: PermissionValueType) => {
|
const onUpdateCollaboratorsThen = async (props: UpdateClbPermissionProps) => {
|
||||||
await onUpdateCollaborators(tmbIds, permission);
|
await onUpdateCollaborators(props);
|
||||||
refetchCollaboratorList();
|
refetchCollaboratorList();
|
||||||
};
|
};
|
||||||
const onDelOneCollaboratorThen = async (tmbId: string) => {
|
const onDelOneCollaboratorThen = async (tmbId: string) => {
|
||||||
@@ -136,3 +145,5 @@ export const CollaboratorContextProvider = ({
|
|||||||
</CollaboratorContext.Provider>
|
</CollaboratorContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default CollaboratorContextProvider;
|
||||||
|
@@ -0,0 +1,66 @@
|
|||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import { Permission } from '@fastgpt/global/support/permission/controller';
|
||||||
|
import { PermissionListType } from '@fastgpt/global/support/permission/type';
|
||||||
|
import { PermissionList } from '@fastgpt/global/support/permission/constant';
|
||||||
|
import MyTag from '@fastgpt/web/components/common/Tag/index';
|
||||||
|
import { HStack } from '@chakra-ui/react';
|
||||||
|
import { useTranslation } from 'next-i18next';
|
||||||
|
|
||||||
|
const PermissionTag = ({
|
||||||
|
permission,
|
||||||
|
permissionList
|
||||||
|
}: {
|
||||||
|
permission: Permission;
|
||||||
|
permissionList: PermissionListType;
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { commonLabel, otherLabels } = useMemo(() => {
|
||||||
|
const Per = new Permission({ per: permission.value });
|
||||||
|
|
||||||
|
const commonLabel = (() => {
|
||||||
|
if (permission.isOwner) return t('permission.Owner');
|
||||||
|
if (permission.hasManagePer) return PermissionList['manage'].name;
|
||||||
|
if (permission.hasWritePer) return PermissionList['write'].name;
|
||||||
|
if (permission.hasReadPer) return PermissionList['read'].name;
|
||||||
|
|
||||||
|
return;
|
||||||
|
})();
|
||||||
|
|
||||||
|
const otherLabels: string[] = [];
|
||||||
|
Object.values(permissionList).forEach((item) => {
|
||||||
|
if (item.checkBoxType === 'multiple') {
|
||||||
|
if (Per.checkPer(item.value)) {
|
||||||
|
otherLabels.push(item.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
commonLabel,
|
||||||
|
otherLabels
|
||||||
|
};
|
||||||
|
}, [
|
||||||
|
permission.hasManagePer,
|
||||||
|
permission.hasReadPer,
|
||||||
|
permission.hasWritePer,
|
||||||
|
permission.value,
|
||||||
|
permissionList
|
||||||
|
]);
|
||||||
|
return (
|
||||||
|
<HStack>
|
||||||
|
{commonLabel && (
|
||||||
|
<MyTag type="fill" colorSchema="blue">
|
||||||
|
{commonLabel}
|
||||||
|
</MyTag>
|
||||||
|
)}
|
||||||
|
{otherLabels.map((tag, i) => (
|
||||||
|
<MyTag key={i} type="fill" colorSchema="purple">
|
||||||
|
{tag}
|
||||||
|
</MyTag>
|
||||||
|
))}
|
||||||
|
</HStack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PermissionTag;
|
@@ -3,12 +3,18 @@ import MyModal from '@fastgpt/web/components/common/MyModal';
|
|||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { ModalCloseButton, ModalBody, Box, ModalFooter, Button } from '@chakra-ui/react';
|
import { ModalCloseButton, ModalBody, Box, ModalFooter, Button } from '@chakra-ui/react';
|
||||||
import TagTextarea from '@/components/common/Textarea/TagTextarea';
|
import TagTextarea from '@/components/common/Textarea/TagTextarea';
|
||||||
import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant';
|
|
||||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
||||||
import { postInviteTeamMember } from '@/web/support/user/team/api';
|
import { postInviteTeamMember } from '@/web/support/user/team/api';
|
||||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||||
import type { InviteMemberResponse } from '@fastgpt/global/support/user/team/controller.d';
|
import type { InviteMemberResponse } from '@fastgpt/global/support/user/team/controller.d';
|
||||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||||
|
import {
|
||||||
|
ManagePermissionVal,
|
||||||
|
ReadPermissionVal,
|
||||||
|
WritePermissionVal
|
||||||
|
} from '@fastgpt/global/support/permission/constant';
|
||||||
|
import { useI18n } from '@/web/context/I18n';
|
||||||
|
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||||
|
|
||||||
const InviteModal = ({
|
const InviteModal = ({
|
||||||
teamId,
|
teamId,
|
||||||
@@ -20,25 +26,37 @@ const InviteModal = ({
|
|||||||
onSuccess: () => void;
|
onSuccess: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const { userT } = useI18n();
|
||||||
const { ConfirmModal, openConfirm } = useConfirm({
|
const { ConfirmModal, openConfirm } = useConfirm({
|
||||||
title: t('user.team.Invite Member Result Tip'),
|
title: t('user.team.Invite Member Result Tip'),
|
||||||
showCancel: false
|
showCancel: false
|
||||||
});
|
});
|
||||||
|
const { userInfo } = useUserStore();
|
||||||
|
|
||||||
const [inviteUsernames, setInviteUsernames] = useState<string[]>([]);
|
const [inviteUsernames, setInviteUsernames] = useState<string[]>([]);
|
||||||
const inviteTypes = useMemo(
|
const inviteTypes = useMemo(
|
||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
alias: t('user.team.Invite Role Visitor Alias'),
|
label: userT('permission.Read'),
|
||||||
label: t('user.team.Invite Role Visitor Tip'),
|
description: userT('permission.Read desc'),
|
||||||
value: TeamMemberRoleEnum.visitor
|
value: ReadPermissionVal
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
alias: t('user.team.Invite Role Admin Alias'),
|
label: userT('permission.Write'),
|
||||||
label: t('user.team.Invite Role Admin Tip'),
|
description: userT('permission.Write tip'),
|
||||||
value: TeamMemberRoleEnum.admin
|
value: WritePermissionVal
|
||||||
}
|
},
|
||||||
|
...(userInfo?.team?.permission.isOwner
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
label: userT('permission.Manage'),
|
||||||
|
description: userT('permission.Manage tip'),
|
||||||
|
value: ManagePermissionVal
|
||||||
|
}
|
||||||
|
]
|
||||||
|
: [])
|
||||||
],
|
],
|
||||||
[t]
|
[userInfo?.team?.permission.isOwner, userT]
|
||||||
);
|
);
|
||||||
const [selectedInviteType, setSelectInviteType] = useState(inviteTypes[0].value);
|
const [selectedInviteType, setSelectInviteType] = useState(inviteTypes[0].value);
|
||||||
|
|
||||||
@@ -47,7 +65,7 @@ const InviteModal = ({
|
|||||||
return postInviteTeamMember({
|
return postInviteTeamMember({
|
||||||
teamId,
|
teamId,
|
||||||
usernames: inviteUsernames,
|
usernames: inviteUsernames,
|
||||||
role: selectedInviteType
|
permission: selectedInviteType
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onSuccess(res: InviteMemberResponse) {
|
onSuccess(res: InviteMemberResponse) {
|
||||||
|
@@ -1,47 +1,51 @@
|
|||||||
import Avatar from '@/components/Avatar';
|
import Avatar from '@/components/Avatar';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
import { Box, MenuButton, Table, TableContainer, Tbody, Td, Th, Thead, Tr } from '@chakra-ui/react';
|
import {
|
||||||
|
Box,
|
||||||
|
HStack,
|
||||||
|
MenuButton,
|
||||||
|
Table,
|
||||||
|
TableContainer,
|
||||||
|
Tbody,
|
||||||
|
Td,
|
||||||
|
Th,
|
||||||
|
Thead,
|
||||||
|
Tr
|
||||||
|
} from '@chakra-ui/react';
|
||||||
import {
|
import {
|
||||||
TeamMemberRoleEnum,
|
TeamMemberRoleEnum,
|
||||||
TeamMemberRoleMap,
|
|
||||||
TeamMemberStatusMap
|
TeamMemberStatusMap
|
||||||
} from '@fastgpt/global/support/user/team/constant';
|
} from '@fastgpt/global/support/user/team/constant';
|
||||||
import MyMenu from '@fastgpt/web/components/common/MyMenu';
|
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useContextSelector } from 'use-context-selector';
|
import { useContextSelector } from 'use-context-selector';
|
||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||||
import { TeamModalContext } from '../context';
|
import { TeamModalContext } from '../context';
|
||||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
|
||||||
import { delRemoveMember } from '@/web/support/user/team/api';
|
|
||||||
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
|
||||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
|
import PermissionTags from '@/components/support/permission/PermissionTags';
|
||||||
|
import { TeamPermissionList } from '@fastgpt/global/support/permission/user/constant';
|
||||||
|
import PermissionSelect from '@/components/support/permission/MemberManager/PermissionSelect';
|
||||||
|
import { CollaboratorContext } from '@/components/support/permission/MemberManager/context';
|
||||||
|
import { delRemoveMember } from '@/web/support/user/team/api';
|
||||||
|
|
||||||
function MemberTable() {
|
function MemberTable() {
|
||||||
const { userInfo } = useUserStore();
|
const { userInfo } = useUserStore();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { members, refetchMembers } = useContextSelector(TeamModalContext, (v) => v);
|
const { members, refetchMembers } = useContextSelector(TeamModalContext, (v) => v);
|
||||||
|
const { onUpdateCollaborators } = useContextSelector(CollaboratorContext, (v) => v);
|
||||||
|
|
||||||
const { ConfirmModal: ConfirmRemoveMemberModal, openConfirm: openRemoveMember } = useConfirm({
|
const { ConfirmModal: ConfirmRemoveMemberModal, openConfirm: openRemoveMember } = useConfirm({
|
||||||
type: 'delete'
|
type: 'delete'
|
||||||
});
|
});
|
||||||
|
|
||||||
const { mutate: onRemoveMember, isLoading: isRemovingMember } = useRequest({
|
|
||||||
mutationFn: delRemoveMember,
|
|
||||||
onSuccess() {
|
|
||||||
refetchMembers();
|
|
||||||
},
|
|
||||||
successToast: t('user.team.Remove Member Success'),
|
|
||||||
errorToast: t('user.team.Remove Member Failed')
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyBox isLoading={isRemovingMember}>
|
<MyBox>
|
||||||
<TableContainer overflow={'unset'} fontSize={'sm'}>
|
<TableContainer overflow={'unset'} fontSize={'sm'}>
|
||||||
<Table overflow={'unset'}>
|
<Table overflow={'unset'}>
|
||||||
<Thead bg={'myWhite.400'}>
|
<Thead bg={'myWhite.400'}>
|
||||||
<Tr>
|
<Tr>
|
||||||
<Th borderRadius={'none !important'}>{t('common.Username')}</Th>
|
<Th borderRadius={'none !important'}>{t('common.Username')}</Th>
|
||||||
<Th>{t('user.team.Role')}</Th>
|
<Th>{t('common.Permission')}</Th>
|
||||||
<Th>{t('common.Status')}</Th>
|
<Th>{t('common.Status')}</Th>
|
||||||
<Th borderRadius={'none !important'}>{t('common.Action')}</Th>
|
<Th borderRadius={'none !important'}>{t('common.Action')}</Th>
|
||||||
</Tr>
|
</Tr>
|
||||||
@@ -49,13 +53,20 @@ function MemberTable() {
|
|||||||
<Tbody>
|
<Tbody>
|
||||||
{members.map((item) => (
|
{members.map((item) => (
|
||||||
<Tr key={item.userId} overflow={'unset'}>
|
<Tr key={item.userId} overflow={'unset'}>
|
||||||
<Td display={'flex'} alignItems={'center'}>
|
<Td>
|
||||||
<Avatar src={item.avatar} w={['18px', '22px']} />
|
<HStack>
|
||||||
<Box flex={'1 0 0'} w={0} ml={1} className={'textEllipsis'}>
|
<Avatar src={item.avatar} w={['18px', '22px']} />
|
||||||
{item.memberName}
|
<Box maxW={'150px'} className={'textEllipsis'}>
|
||||||
</Box>
|
{item.memberName}
|
||||||
|
</Box>
|
||||||
|
</HStack>
|
||||||
|
</Td>
|
||||||
|
<Td>
|
||||||
|
<PermissionTags
|
||||||
|
permission={item.permission}
|
||||||
|
permissionList={TeamPermissionList}
|
||||||
|
/>
|
||||||
</Td>
|
</Td>
|
||||||
<Td>{t(TeamMemberRoleMap[item.role]?.label || '')}</Td>
|
|
||||||
<Td color={TeamMemberStatusMap[item.status].color}>
|
<Td color={TeamMemberStatusMap[item.status].color}>
|
||||||
{t(TeamMemberStatusMap[item.status]?.label || '')}
|
{t(TeamMemberStatusMap[item.status]?.label || '')}
|
||||||
</Td>
|
</Td>
|
||||||
@@ -63,9 +74,8 @@ function MemberTable() {
|
|||||||
{userInfo?.team.permission.hasManagePer &&
|
{userInfo?.team.permission.hasManagePer &&
|
||||||
item.role !== TeamMemberRoleEnum.owner &&
|
item.role !== TeamMemberRoleEnum.owner &&
|
||||||
item.tmbId !== userInfo?.team.tmbId && (
|
item.tmbId !== userInfo?.team.tmbId && (
|
||||||
<MyMenu
|
<PermissionSelect
|
||||||
width={20}
|
value={item.permission.value}
|
||||||
trigger="hover"
|
|
||||||
Button={
|
Button={
|
||||||
<MenuButton
|
<MenuButton
|
||||||
_hover={{
|
_hover={{
|
||||||
@@ -79,27 +89,21 @@ function MemberTable() {
|
|||||||
<MyIcon name={'edit'} cursor={'pointer'} w="1rem" />
|
<MyIcon name={'edit'} cursor={'pointer'} w="1rem" />
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
}
|
}
|
||||||
menuList={[
|
onChange={(permission) => {
|
||||||
{
|
onUpdateCollaborators({
|
||||||
children: [
|
tmbIds: [item.tmbId],
|
||||||
{
|
permission
|
||||||
label: t('user.team.Remove Member Tip'),
|
});
|
||||||
onClick: () =>
|
}}
|
||||||
openRemoveMember(
|
onDelete={() => {
|
||||||
() =>
|
openRemoveMember(
|
||||||
onRemoveMember({
|
() => delRemoveMember(item.tmbId).then(refetchMembers),
|
||||||
teamId: item.teamId,
|
undefined,
|
||||||
memberId: item.tmbId
|
t('user.team.Remove Member Confirm Tip', {
|
||||||
}),
|
username: item.memberName
|
||||||
undefined,
|
})
|
||||||
t('user.team.Remove Member Confirm Tip', {
|
)();
|
||||||
username: item.memberName
|
}}
|
||||||
})
|
|
||||||
)()
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Td>
|
</Td>
|
||||||
|
@@ -38,7 +38,7 @@ function AddManagerModal({ onClose, onSuccess }: { onClose: () => void; onSucces
|
|||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
return updateMemberPermission({
|
return updateMemberPermission({
|
||||||
permission: ManagePermissionVal,
|
permission: ManagePermissionVal,
|
||||||
memberIds: selected.map((item) => {
|
tmbIds: selected.map((item) => {
|
||||||
return item.tmbId;
|
return item.tmbId;
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@@ -1,14 +1,26 @@
|
|||||||
import React, { ReactNode, useState } from 'react';
|
import React, { ReactNode, useCallback, useState } from 'react';
|
||||||
import { createContext } from 'use-context-selector';
|
import { createContext } from 'use-context-selector';
|
||||||
import type { EditTeamFormDataType } from './components/EditInfoModal';
|
import type { EditTeamFormDataType } from './components/EditInfoModal';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { getTeamList, getTeamMembers, putSwitchTeam } from '@/web/support/user/team/api';
|
import {
|
||||||
|
delMemberPermission,
|
||||||
|
getTeamList,
|
||||||
|
getTeamMembers,
|
||||||
|
putSwitchTeam,
|
||||||
|
updateMemberPermission
|
||||||
|
} from '@/web/support/user/team/api';
|
||||||
import { TeamMemberStatusEnum } from '@fastgpt/global/support/user/team/constant';
|
import { TeamMemberStatusEnum } from '@fastgpt/global/support/user/team/constant';
|
||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||||
import type { TeamTmbItemType, TeamMemberItemType } from '@fastgpt/global/support/user/team/type';
|
import type { TeamTmbItemType, TeamMemberItemType } from '@fastgpt/global/support/user/team/type';
|
||||||
import { useRequest } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
|
import CollaboratorContextProvider from '@/components/support/permission/MemberManager/context';
|
||||||
|
import { TeamPermissionList } from '@fastgpt/global/support/permission/user/constant';
|
||||||
|
import {
|
||||||
|
CollaboratorItemType,
|
||||||
|
UpdateClbPermissionProps
|
||||||
|
} from '@fastgpt/global/support/permission/collaborator';
|
||||||
|
|
||||||
const EditInfoModal = dynamic(() => import('./components/EditInfoModal'));
|
const EditInfoModal = dynamic(() => import('./components/EditInfoModal'));
|
||||||
|
|
||||||
@@ -55,12 +67,35 @@ export const TeamModalContextProvider = ({ children }: { children: ReactNode })
|
|||||||
// member action
|
// member action
|
||||||
const {
|
const {
|
||||||
data: members = [],
|
data: members = [],
|
||||||
refetch: refetchMembers,
|
runAsync: refetchMembers,
|
||||||
isLoading: loadingMembers
|
loading: loadingMembers
|
||||||
} = useQuery(['getMembers', userInfo?.team?.teamId], () => {
|
} = useRequest2(
|
||||||
if (!userInfo?.team?.teamId) return [];
|
() => {
|
||||||
return getTeamMembers();
|
if (!userInfo?.team?.teamId) return Promise.resolve([]);
|
||||||
});
|
return getTeamMembers();
|
||||||
|
},
|
||||||
|
{
|
||||||
|
manual: false,
|
||||||
|
refreshDeps: [userInfo?.team?.teamId]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const onGetClbList = useCallback(() => {
|
||||||
|
return refetchMembers().then((res) =>
|
||||||
|
res.map<CollaboratorItemType>((member) => ({
|
||||||
|
teamId: member.teamId,
|
||||||
|
tmbId: member.tmbId,
|
||||||
|
permission: member.permission,
|
||||||
|
name: member.memberName,
|
||||||
|
avatar: member.avatar
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}, [refetchMembers]);
|
||||||
|
const { runAsync: onUpdatePer, loading: isUpdatingPer } = useRequest2(
|
||||||
|
(props: UpdateClbPermissionProps) => {
|
||||||
|
return updateMemberPermission(props);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const { mutate: onSwitchTeam, isLoading: isSwitchingTeam } = useRequest({
|
const { mutate: onSwitchTeam, isLoading: isSwitchingTeam } = useRequest({
|
||||||
mutationFn: async (teamId: string) => {
|
mutationFn: async (teamId: string) => {
|
||||||
@@ -70,7 +105,7 @@ export const TeamModalContextProvider = ({ children }: { children: ReactNode })
|
|||||||
errorToast: t('user.team.Switch Team Failed')
|
errorToast: t('user.team.Switch Team Failed')
|
||||||
});
|
});
|
||||||
|
|
||||||
const isLoading = isLoadingTeams || isSwitchingTeam || loadingMembers;
|
const isLoading = isLoadingTeams || isSwitchingTeam || loadingMembers || isUpdatingPer;
|
||||||
|
|
||||||
const contextValue = {
|
const contextValue = {
|
||||||
myTeams,
|
myTeams,
|
||||||
@@ -86,16 +121,30 @@ export const TeamModalContextProvider = ({ children }: { children: ReactNode })
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<TeamModalContext.Provider value={contextValue}>
|
<TeamModalContext.Provider value={contextValue}>
|
||||||
{children}
|
{userInfo?.team?.permission && (
|
||||||
{!!editTeamData && (
|
<CollaboratorContextProvider
|
||||||
<EditInfoModal
|
permission={userInfo?.team?.permission}
|
||||||
defaultData={editTeamData}
|
permissionList={TeamPermissionList}
|
||||||
onClose={() => setEditTeamData(undefined)}
|
onGetCollaboratorList={onGetClbList}
|
||||||
onSuccess={() => {
|
onUpdateCollaborators={onUpdatePer}
|
||||||
refetchTeams();
|
onDelOneCollaborator={delMemberPermission}
|
||||||
initUserInfo();
|
>
|
||||||
}}
|
{() => (
|
||||||
/>
|
<>
|
||||||
|
{children}
|
||||||
|
{!!editTeamData && (
|
||||||
|
<EditInfoModal
|
||||||
|
defaultData={editTeamData}
|
||||||
|
onClose={() => setEditTeamData(undefined)}
|
||||||
|
onSuccess={() => {
|
||||||
|
refetchTeams();
|
||||||
|
initUserInfo();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</CollaboratorContextProvider>
|
||||||
)}
|
)}
|
||||||
</TeamModalContext.Provider>
|
</TeamModalContext.Provider>
|
||||||
);
|
);
|
||||||
|
@@ -12,6 +12,7 @@ import { readConfigData } from '@/service/common/system';
|
|||||||
import { exit } from 'process';
|
import { exit } from 'process';
|
||||||
import { FastGPTProUrl } from '@fastgpt/service/common/system/constants';
|
import { FastGPTProUrl } from '@fastgpt/service/common/system/constants';
|
||||||
import { initFastGPTConfig } from '@fastgpt/service/common/system/tools';
|
import { initFastGPTConfig } from '@fastgpt/service/common/system/tools';
|
||||||
|
import json5 from 'json5';
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
await getInitConfig();
|
await getInitConfig();
|
||||||
@@ -88,7 +89,7 @@ export async function initSystemConfig() {
|
|||||||
getFastGPTConfigFromDB(),
|
getFastGPTConfigFromDB(),
|
||||||
readConfigData('config.json')
|
readConfigData('config.json')
|
||||||
]);
|
]);
|
||||||
const fileRes = JSON.parse(fileConfig) as FastGPTConfigFileType;
|
const fileRes = json5.parse(fileConfig) as FastGPTConfigFileType;
|
||||||
|
|
||||||
// get config from database
|
// get config from database
|
||||||
const config: FastGPTConfigFileType = {
|
const config: FastGPTConfigFileType = {
|
||||||
@@ -131,7 +132,7 @@ export function getSystemVersion() {
|
|||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
global.systemVersion = process.env.npm_package_version || '0.0.0';
|
global.systemVersion = process.env.npm_package_version || '0.0.0';
|
||||||
} else {
|
} else {
|
||||||
const packageJson = JSON.parse(readFileSync('/app/package.json', 'utf-8'));
|
const packageJson = json5.parse(readFileSync('/app/package.json', 'utf-8'));
|
||||||
|
|
||||||
global.systemVersion = packageJson?.version;
|
global.systemVersion = packageJson?.version;
|
||||||
}
|
}
|
||||||
@@ -157,7 +158,7 @@ function getSystemPlugin() {
|
|||||||
const fileTemplates: (PluginTemplateType & { weight: number })[] = filterFiles.map((filename) => {
|
const fileTemplates: (PluginTemplateType & { weight: number })[] = filterFiles.map((filename) => {
|
||||||
const content = readFileSync(`${basePath}/${filename}`, 'utf-8');
|
const content = readFileSync(`${basePath}/${filename}`, 'utf-8');
|
||||||
return {
|
return {
|
||||||
...JSON.parse(content),
|
...json5.parse(content),
|
||||||
id: `${PluginSourceEnum.community}-${filename.replace('.json', '')}`,
|
id: `${PluginSourceEnum.community}-${filename.replace('.json', '')}`,
|
||||||
source: PluginSourceEnum.community
|
source: PluginSourceEnum.community
|
||||||
};
|
};
|
||||||
|
@@ -8,8 +8,12 @@ import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
|||||||
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';
|
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';
|
||||||
import { NextAPI } from '@/service/middleware/entry';
|
import { NextAPI } from '@/service/middleware/entry';
|
||||||
import { MongoChatInputGuide } from '@fastgpt/service/core/chat/inputGuide/schema';
|
import { MongoChatInputGuide } from '@fastgpt/service/core/chat/inputGuide/schema';
|
||||||
import { OwnerPermissionVal } from '@fastgpt/global/support/permission/constant';
|
import {
|
||||||
|
OwnerPermissionVal,
|
||||||
|
PerResourceTypeEnum
|
||||||
|
} from '@fastgpt/global/support/permission/constant';
|
||||||
import { findAppAndAllChildren } from '@fastgpt/service/core/app/controller';
|
import { findAppAndAllChildren } from '@fastgpt/service/core/app/controller';
|
||||||
|
import { MongoResourcePermission } from '@fastgpt/service/support/permission/schema';
|
||||||
|
|
||||||
async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||||
const { appId } = req.query as { appId: string };
|
const { appId } = req.query as { appId: string };
|
||||||
@@ -27,8 +31,6 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
|||||||
fields: '_id'
|
fields: '_id'
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(apps);
|
|
||||||
|
|
||||||
await mongoSessionRun(async (session) => {
|
await mongoSessionRun(async (session) => {
|
||||||
for await (const app of apps) {
|
for await (const app of apps) {
|
||||||
const appId = app._id;
|
const appId = app._id;
|
||||||
@@ -65,6 +67,14 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
|||||||
},
|
},
|
||||||
{ session }
|
{ session }
|
||||||
);
|
);
|
||||||
|
await MongoResourcePermission.deleteMany(
|
||||||
|
{
|
||||||
|
resourceType: PerResourceTypeEnum.app,
|
||||||
|
teamId,
|
||||||
|
resourceId: appId
|
||||||
|
},
|
||||||
|
{ session }
|
||||||
|
);
|
||||||
// delete app
|
// delete app
|
||||||
await MongoApp.deleteOne(
|
await MongoApp.deleteOne(
|
||||||
{
|
{
|
||||||
|
@@ -14,7 +14,6 @@ import { authApp } from '@fastgpt/service/support/permission/app/auth';
|
|||||||
import { dispatchWorkFlow } from '@fastgpt/service/core/workflow/dispatch';
|
import { dispatchWorkFlow } from '@fastgpt/service/core/workflow/dispatch';
|
||||||
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
||||||
import { getUserChatInfoAndAuthTeamPoints } from '@/service/support/permission/auth/team';
|
import { getUserChatInfoAndAuthTeamPoints } from '@/service/support/permission/auth/team';
|
||||||
import { chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt';
|
|
||||||
import { RuntimeEdgeItemType } from '@fastgpt/global/core/workflow/type/edge';
|
import { RuntimeEdgeItemType } from '@fastgpt/global/core/workflow/type/edge';
|
||||||
import { RuntimeNodeItemType } from '@fastgpt/global/core/workflow/runtime/type';
|
import { RuntimeNodeItemType } from '@fastgpt/global/core/workflow/runtime/type';
|
||||||
import { removeEmptyUserInput } from '@fastgpt/global/core/chat/utils';
|
import { removeEmptyUserInput } from '@fastgpt/global/core/chat/utils';
|
||||||
@@ -61,7 +60,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* user auth */
|
/* user auth */
|
||||||
const [_, { teamId, tmbId }] = await Promise.all([
|
const [{ app }, { teamId, tmbId }] = await Promise.all([
|
||||||
authApp({ req, authToken: true, appId, per: ReadPermissionVal }),
|
authApp({ req, authToken: true, appId, per: ReadPermissionVal }),
|
||||||
authCert({
|
authCert({
|
||||||
req,
|
req,
|
||||||
@@ -79,7 +78,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
teamId,
|
teamId,
|
||||||
tmbId,
|
tmbId,
|
||||||
user,
|
user,
|
||||||
appId,
|
app,
|
||||||
runtimeNodes: nodes,
|
runtimeNodes: nodes,
|
||||||
runtimeEdges: edges,
|
runtimeEdges: edges,
|
||||||
variables,
|
variables,
|
||||||
|
@@ -9,6 +9,7 @@ import { PostWorkflowDebugProps, PostWorkflowDebugResponse } from '@/global/core
|
|||||||
import { authPluginCrud } from '@fastgpt/service/support/permission/auth/plugin';
|
import { authPluginCrud } from '@fastgpt/service/support/permission/auth/plugin';
|
||||||
import { NextAPI } from '@/service/middleware/entry';
|
import { NextAPI } from '@/service/middleware/entry';
|
||||||
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||||
|
import { defaultApp } from '@/web/core/app/constants';
|
||||||
|
|
||||||
async function handler(
|
async function handler(
|
||||||
req: NextApiRequest,
|
req: NextApiRequest,
|
||||||
@@ -45,6 +46,12 @@ async function handler(
|
|||||||
// auth balance
|
// auth balance
|
||||||
const { user } = await getUserChatInfoAndAuthTeamPoints(tmbId);
|
const { user } = await getUserChatInfoAndAuthTeamPoints(tmbId);
|
||||||
|
|
||||||
|
const app = {
|
||||||
|
...defaultApp,
|
||||||
|
teamId,
|
||||||
|
tmbId
|
||||||
|
};
|
||||||
|
|
||||||
/* start process */
|
/* start process */
|
||||||
const { flowUsages, flowResponses, debugResponse } = await dispatchWorkFlow({
|
const { flowUsages, flowResponses, debugResponse } = await dispatchWorkFlow({
|
||||||
res,
|
res,
|
||||||
@@ -52,7 +59,7 @@ async function handler(
|
|||||||
teamId,
|
teamId,
|
||||||
tmbId,
|
tmbId,
|
||||||
user,
|
user,
|
||||||
appId,
|
app,
|
||||||
runtimeNodes: nodes,
|
runtimeNodes: nodes,
|
||||||
runtimeEdges: edges,
|
runtimeEdges: edges,
|
||||||
variables,
|
variables,
|
||||||
|
@@ -13,6 +13,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
if (!requestPath) {
|
if (!requestPath) {
|
||||||
throw new Error('url is empty');
|
throw new Error('url is empty');
|
||||||
}
|
}
|
||||||
|
if (!FastGPTProUrl) {
|
||||||
|
throw new Error('未配置商业版链接');
|
||||||
|
}
|
||||||
|
|
||||||
const parsedUrl = new URL(FastGPTProUrl);
|
const parsedUrl = new URL(FastGPTProUrl);
|
||||||
delete req.headers?.rootkey;
|
delete req.headers?.rootkey;
|
||||||
|
@@ -191,7 +191,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
user,
|
user,
|
||||||
teamId: String(teamId),
|
teamId: String(teamId),
|
||||||
tmbId: String(tmbId),
|
tmbId: String(tmbId),
|
||||||
appId: String(app._id),
|
app,
|
||||||
chatId,
|
chatId,
|
||||||
responseChatItemId,
|
responseChatItemId,
|
||||||
runtimeNodes: storeNodes2RuntimeNodes(nodes, getDefaultEntryNodeIds(nodes)),
|
runtimeNodes: storeNodes2RuntimeNodes(nodes, getDefaultEntryNodeIds(nodes)),
|
||||||
|
@@ -20,7 +20,7 @@ import Avatar from '@/components/Avatar';
|
|||||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants';
|
import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants';
|
||||||
import { CollaboratorContextProvider } from '@/components/support/permission/MemberManager/context';
|
import CollaboratorContextProvider from '@/components/support/permission/MemberManager/context';
|
||||||
import {
|
import {
|
||||||
postUpdateAppCollaborators,
|
postUpdateAppCollaborators,
|
||||||
deleteAppCollaborators,
|
deleteAppCollaborators,
|
||||||
@@ -35,6 +35,7 @@ import {
|
|||||||
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
||||||
import DefaultPermissionList from '@/components/support/permission/DefaultPerList';
|
import DefaultPermissionList from '@/components/support/permission/DefaultPerList';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
|
import { UpdateClbPermissionProps } from '@fastgpt/global/support/permission/collaborator';
|
||||||
|
|
||||||
const InfoModal = ({ onClose }: { onClose: () => void }) => {
|
const InfoModal = ({ onClose }: { onClose: () => void }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -123,7 +124,7 @@ const InfoModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
[setValue, t, toast]
|
[setValue, t, toast]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onUpdateCollaborators = async (tmbIds: string[], permission: PermissionValueType) => {
|
const onUpdateCollaborators = async ({ tmbIds, permission }: UpdateClbPermissionProps) => {
|
||||||
await postUpdateAppCollaborators({
|
await postUpdateAppCollaborators({
|
||||||
tmbIds,
|
tmbIds,
|
||||||
permission,
|
permission,
|
||||||
|
@@ -108,7 +108,7 @@ const Logs = ({ appId }: { appId: string }) => {
|
|||||||
<Th>{appT('Mark Count')}</Th>
|
<Th>{appT('Mark Count')}</Th>
|
||||||
</Tr>
|
</Tr>
|
||||||
</Thead>
|
</Thead>
|
||||||
<Tbody>
|
<Tbody fontSize={'xs'}>
|
||||||
{logs.map((item) => (
|
{logs.map((item) => (
|
||||||
<Tr
|
<Tr
|
||||||
key={item._id}
|
key={item._id}
|
||||||
|
@@ -89,10 +89,23 @@ const EditForm = ({
|
|||||||
|
|
||||||
const { setValue, getValues, handleSubmit, control, watch } = editForm;
|
const { setValue, getValues, handleSubmit, control, watch } = editForm;
|
||||||
|
|
||||||
const { fields: datasets, replace: replaceKbList } = useFieldArray({
|
const { fields: datasets, replace: replaceDatasetList } = useFieldArray({
|
||||||
control,
|
control,
|
||||||
name: 'dataset.datasets'
|
name: 'dataset.datasets'
|
||||||
});
|
});
|
||||||
|
const selectDatasets = useMemo(
|
||||||
|
() => allDatasets.filter((item) => datasets.find((dataset) => dataset.datasetId === item._id)),
|
||||||
|
[allDatasets, datasets]
|
||||||
|
);
|
||||||
|
useEffect(() => {
|
||||||
|
if (selectDatasets.length !== datasets.length) {
|
||||||
|
replaceDatasetList(
|
||||||
|
selectDatasets.map((item) => ({
|
||||||
|
datasetId: item._id
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, [datasets, replaceDatasetList, selectDatasets]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isOpen: isOpenDatasetSelect,
|
isOpen: isOpenDatasetSelect,
|
||||||
@@ -131,11 +144,6 @@ const EditForm = ({
|
|||||||
const scheduledTriggerConfig = watch('chatConfig.scheduledTriggerConfig');
|
const scheduledTriggerConfig = watch('chatConfig.scheduledTriggerConfig');
|
||||||
const searchMode = watch('dataset.searchMode');
|
const searchMode = watch('dataset.searchMode');
|
||||||
|
|
||||||
const selectDatasets = useMemo(
|
|
||||||
() => allDatasets.filter((item) => datasets.find((dataset) => dataset.datasetId === item._id)),
|
|
||||||
[allDatasets, datasets]
|
|
||||||
);
|
|
||||||
|
|
||||||
const tokenLimit = useMemo(() => {
|
const tokenLimit = useMemo(() => {
|
||||||
return llmModelList.find((item) => item.model === selectLLMModel)?.quoteMaxToken || 3000;
|
return llmModelList.find((item) => item.model === selectLLMModel)?.quoteMaxToken || 3000;
|
||||||
}, [selectLLMModel, llmModelList]);
|
}, [selectLLMModel, llmModelList]);
|
||||||
@@ -475,7 +483,7 @@ const EditForm = ({
|
|||||||
vectorModel: item.vectorModel
|
vectorModel: item.vectorModel
|
||||||
}))}
|
}))}
|
||||||
onClose={onCloseKbSelect}
|
onClose={onCloseKbSelect}
|
||||||
onChange={replaceKbList}
|
onChange={replaceDatasetList}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{isOpenDatasetParams && (
|
{isOpenDatasetParams && (
|
||||||
|
@@ -271,7 +271,13 @@ const ListItem = () => {
|
|||||||
permission: editPerApp.permission,
|
permission: editPerApp.permission,
|
||||||
onGetCollaboratorList: () => getCollaboratorList(editPerApp._id),
|
onGetCollaboratorList: () => getCollaboratorList(editPerApp._id),
|
||||||
permissionList: AppPermissionList,
|
permissionList: AppPermissionList,
|
||||||
onUpdateCollaborators: (tmbIds: string[], permission: number) => {
|
onUpdateCollaborators: ({
|
||||||
|
tmbIds,
|
||||||
|
permission
|
||||||
|
}: {
|
||||||
|
tmbIds: string[];
|
||||||
|
permission: number;
|
||||||
|
}) => {
|
||||||
return postUpdateAppCollaborators({
|
return postUpdateAppCollaborators({
|
||||||
tmbIds,
|
tmbIds,
|
||||||
permission,
|
permission,
|
||||||
|
@@ -140,6 +140,7 @@ const MyApps = () => {
|
|||||||
{!!folderDetail && isPc && (
|
{!!folderDetail && isPc && (
|
||||||
<Box pt={[4, 6]}>
|
<Box pt={[4, 6]}>
|
||||||
<FolderSlideCard
|
<FolderSlideCard
|
||||||
|
refreshDeps={[folderDetail._id]}
|
||||||
name={folderDetail.name}
|
name={folderDetail.name}
|
||||||
intro={folderDetail.intro}
|
intro={folderDetail.intro}
|
||||||
onEdit={() => {
|
onEdit={() => {
|
||||||
@@ -163,7 +164,13 @@ const MyApps = () => {
|
|||||||
permission: folderDetail.permission,
|
permission: folderDetail.permission,
|
||||||
onGetCollaboratorList: () => getCollaboratorList(folderDetail._id),
|
onGetCollaboratorList: () => getCollaboratorList(folderDetail._id),
|
||||||
permissionList: AppPermissionList,
|
permissionList: AppPermissionList,
|
||||||
onUpdateCollaborators: (tmbIds: string[], permission: number) => {
|
onUpdateCollaborators: ({
|
||||||
|
tmbIds,
|
||||||
|
permission
|
||||||
|
}: {
|
||||||
|
tmbIds: string[];
|
||||||
|
permission: number;
|
||||||
|
}) => {
|
||||||
return postUpdateAppCollaborators({
|
return postUpdateAppCollaborators({
|
||||||
tmbIds,
|
tmbIds,
|
||||||
permission,
|
permission,
|
||||||
|
@@ -374,7 +374,6 @@ const DataCard = () => {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
openConfirm(async () => {
|
openConfirm(async () => {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
|
||||||
await delOneDatasetDataById(item._id);
|
await delOneDatasetDataById(item._id);
|
||||||
getData(pageNum);
|
getData(pageNum);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -383,7 +382,6 @@ const DataCard = () => {
|
|||||||
status: 'error'
|
status: 'error'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setIsLoading(false);
|
|
||||||
})();
|
})();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -411,14 +409,8 @@ const DataCard = () => {
|
|||||||
</DrawerHeader>
|
</DrawerHeader>
|
||||||
|
|
||||||
<DrawerBody>
|
<DrawerBody>
|
||||||
{metadataList.map((item) => (
|
{metadataList.map((item, i) => (
|
||||||
<Flex
|
<Flex key={i} alignItems={'center'} mb={5} wordBreak={'break-all'} fontSize={'sm'}>
|
||||||
key={item.label}
|
|
||||||
alignItems={'center'}
|
|
||||||
mb={5}
|
|
||||||
wordBreak={'break-all'}
|
|
||||||
fontSize={'sm'}
|
|
||||||
>
|
|
||||||
<Box color={'myGray.500'} flex={'0 0 100px'}>
|
<Box color={'myGray.500'} flex={'0 0 100px'}>
|
||||||
{item.label}
|
{item.label}
|
||||||
</Box>
|
</Box>
|
||||||
|
@@ -41,7 +41,7 @@ const Slider = ({ currentTab }: { currentTab: TabEnum }) => {
|
|||||||
icon: 'common/overviewLight'
|
icon: 'common/overviewLight'
|
||||||
},
|
},
|
||||||
{ label: t('core.dataset.test.Search Test'), id: TabEnum.test, icon: 'kbTest' },
|
{ label: t('core.dataset.test.Search Test'), id: TabEnum.test, icon: 'kbTest' },
|
||||||
...(userInfo?.team.permission.hasWritePer && datasetDetail.isOwner
|
...(userInfo?.team.permission.hasManagePer || datasetDetail.isOwner
|
||||||
? [{ label: t('common.Config'), id: TabEnum.info, icon: 'common/settingLight' }]
|
? [{ label: t('common.Config'), id: TabEnum.info, icon: 'common/settingLight' }]
|
||||||
: [])
|
: [])
|
||||||
];
|
];
|
||||||
|
@@ -34,7 +34,7 @@ export const getScheduleTriggerApp = async () => {
|
|||||||
mode: 'chat',
|
mode: 'chat',
|
||||||
teamId: String(app.teamId),
|
teamId: String(app.teamId),
|
||||||
tmbId: String(app.tmbId),
|
tmbId: String(app.tmbId),
|
||||||
appId: String(app._id),
|
app,
|
||||||
runtimeNodes: storeNodes2RuntimeNodes(app.modules, getDefaultEntryNodeIds(app.modules)),
|
runtimeNodes: storeNodes2RuntimeNodes(app.modules, getDefaultEntryNodeIds(app.modules)),
|
||||||
runtimeEdges: initWorkflowEdgeStatus(app.edges),
|
runtimeEdges: initWorkflowEdgeStatus(app.edges),
|
||||||
variables: {},
|
variables: {},
|
||||||
|
@@ -1,12 +1,10 @@
|
|||||||
import { GET, POST, PUT, DELETE } from '@/web/common/api/request';
|
import { GET, POST, PUT, DELETE } from '@/web/common/api/request';
|
||||||
|
import { UpdateClbPermissionProps } from '@fastgpt/global/support/permission/collaborator';
|
||||||
import {
|
import {
|
||||||
CreateTeamProps,
|
CreateTeamProps,
|
||||||
DelMemberProps,
|
|
||||||
InviteMemberProps,
|
InviteMemberProps,
|
||||||
InviteMemberResponse,
|
InviteMemberResponse,
|
||||||
UpdateInviteProps,
|
UpdateInviteProps,
|
||||||
UpdateTeamMemberPermissionProps,
|
|
||||||
UpdateTeamMemberProps,
|
|
||||||
UpdateTeamProps
|
UpdateTeamProps
|
||||||
} from '@fastgpt/global/support/user/team/controller.d';
|
} from '@fastgpt/global/support/user/team/controller.d';
|
||||||
import type { TeamTagItemType, TeamTagSchema } from '@fastgpt/global/support/user/team/type';
|
import type { TeamTagItemType, TeamTagSchema } from '@fastgpt/global/support/user/team/type';
|
||||||
@@ -33,15 +31,15 @@ export const postInviteTeamMember = (data: InviteMemberProps) =>
|
|||||||
POST<InviteMemberResponse>(`/proApi/support/user/team/member/invite`, data);
|
POST<InviteMemberResponse>(`/proApi/support/user/team/member/invite`, data);
|
||||||
export const putUpdateMemberName = (name: string) =>
|
export const putUpdateMemberName = (name: string) =>
|
||||||
PUT(`/proApi/support/user/team/member/updateName`, { name });
|
PUT(`/proApi/support/user/team/member/updateName`, { name });
|
||||||
export const delRemoveMember = (props: DelMemberProps) =>
|
export const delRemoveMember = (tmbId: string) =>
|
||||||
DELETE(`/proApi/support/user/team/member/delete`, props);
|
DELETE(`/proApi/support/user/team/member/delete`, { tmbId });
|
||||||
export const updateInviteResult = (data: UpdateInviteProps) =>
|
export const updateInviteResult = (data: UpdateInviteProps) =>
|
||||||
PUT('/proApi/support/user/team/member/updateInvite', data);
|
PUT('/proApi/support/user/team/member/updateInvite', data);
|
||||||
export const delLeaveTeam = (teamId: string) =>
|
export const delLeaveTeam = (teamId: string) =>
|
||||||
DELETE('/proApi/support/user/team/member/leave', { teamId });
|
DELETE('/proApi/support/user/team/member/leave', { teamId });
|
||||||
|
|
||||||
/* -------------- team collaborator -------------------- */
|
/* -------------- team collaborator -------------------- */
|
||||||
export const updateMemberPermission = (data: UpdateTeamMemberPermissionProps) =>
|
export const updateMemberPermission = (data: UpdateClbPermissionProps) =>
|
||||||
PUT('/proApi/support/user/team/collaborator/update', data);
|
PUT('/proApi/support/user/team/collaborator/update', data);
|
||||||
export const delMemberPermission = (tmbId: string) =>
|
export const delMemberPermission = (tmbId: string) =>
|
||||||
DELETE('/proApi/support/user/team/collaborator/delete', { tmbId });
|
DELETE('/proApi/support/user/team/collaborator/delete', { tmbId });
|
||||||
|
Reference in New Issue
Block a user