4.8.19-feature (#3636)

* feat: sync org from wecom, pref: member list pagination (#3549)

* feat: sync org

* chore: fe

* chore: loading

* chore: type

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

* feat: member update avatar

* chore: user avatar move to tmb

* chore: init scripts move user avatar

* chore: sourceMember

* fix: list api sourceMember

* fix: member sync

* fix: pagination

* chore: adjust code

* chore: move changeOwner to pro

* chore: init v4819 script

* chore: adjust code

* chore: UserBox

* perf: scroll page code

* perf: list data

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

* docs: add custom uid docs (#3572)

* fix: pagination bug (#3577)

* 4.8.19 test (#3584)

* faet: dataset search filter

* fix: scroll page

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

* fix: collection list api format

* fix: type error of addSourceMemeber

* fix: scroll fetch (#3592)

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

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

* chat openapi doc

* feat: dataset openapi doc

* perf: load members

* perf: member load code

* perf: yuque load

* fix: workflow llm params cannot close

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

* perf: doc

* feat: chat page config

* fix: http parse (#3634)

* update doc

* fix: http parse

* fix code run node reset template (#3633)

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

* docs:faq (#3627)

* docs:faq

* docsFix

* perf: sleep plugin

* fix: selector

---------

Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com>
Co-authored-by: Jiangween <145003935+Jiangween@users.noreply.github.com>
Co-authored-by: heheer <heheer@sealos.io>
This commit is contained in:
Archer
2025-01-20 19:42:33 +08:00
committed by GitHub
parent 9f33729ca9
commit 3c97757e4d
170 changed files with 2317 additions and 1615 deletions

View File

@@ -5,6 +5,8 @@ import { jiebaSplit } from '@fastgpt/service/common/string/jieba';
import { MongoDatasetDataText } from '@fastgpt/service/core/dataset/data/dataTextSchema';
import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { MongoUser } from '@fastgpt/service/support/user/schema';
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
import { NextApiRequest, NextApiResponse } from 'next';
/*
@@ -14,6 +16,7 @@ import { NextApiRequest, NextApiResponse } from 'next';
2. 执行升级脚本,不要删除 MongoDatasetData 里的数据。
3. 切换正式版镜像,让 MongoDatasetDataText 生效。
4. 删除 MongoDatasetData 里的索引和多余字段。4819 再删
5. 移动 User 表中的 avatar 字段到 TeamMember 表中。
*/
let success = 0;
async function handler(req: NextApiRequest, res: NextApiResponse) {
@@ -109,15 +112,26 @@ const initData = async (batchSize: number) => {
}
};
const batchUpdateFields = async (batchSize = 2000) => {
// Update in batches
await MongoDatasetData.updateMany(
{ initFullText: { $exists: true } },
{
$unset: {
initFullText: 1,
fullTextToken: 1
}
}
);
};
// const batchUpdateFields = async (batchSize = 2000) => {
// // Find documents that still have these fields
// const documents = await MongoDatasetData.find({ initFullText: { $exists: true } }, '_id')
// .limit(batchSize)
// .lean();
// if (documents.length === 0) return;
// // Update in batches
// await MongoDatasetData.updateMany(
// { _id: { $in: documents.map((doc) => doc._id) } },
// {
// $unset: {
// initFullText: 1
// // fullTextToken: 1
// }
// }
// );
// success += documents.length;
// console.log('Delete success:', success);
// await batchUpdateFields(batchSize);
// };

View File

@@ -0,0 +1,55 @@
import { NextAPI } from '@/service/middleware/entry';
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { MongoUser } from '@fastgpt/service/support/user/schema';
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
import { NextApiRequest, NextApiResponse } from 'next';
/*
简单版迁移:直接升级到最新镜像,会去除 MongoDatasetData 里的索引。直接执行这个脚本。
无缝迁移:
1. 移动 User 表中的 avatar 字段到 TeamMember 表中。
*/
async function handler(req: NextApiRequest, res: NextApiResponse) {
await authCert({ req, authRoot: true });
await moveUserAvatar();
return { success: true };
}
export default NextAPI(handler);
const moveUserAvatar = async () => {
try {
const users = await MongoUser.find({}, '_id avatar');
console.log('Total users:', users.length);
let success = 0;
for await (const user of users) {
// @ts-ignore
if (!user.avatar) continue;
try {
await mongoSessionRun(async (session) => {
await MongoTeamMember.updateOne(
{
userId: user._id
},
{
$set: {
avatar: (user as any).avatar // 删除 avatar 字段, 因为 Type 改了,所以这里不能直接写 user.avatar
}
},
{ session }
);
// @ts-ignore
user.avatar = undefined;
await user.save({ session });
});
success++;
console.log('Move avatar success:', success);
} catch (error) {
console.error(error);
}
}
} catch (error) {
console.error(error);
}
};

View File

@@ -8,7 +8,8 @@ async function handler(req: ApiRequestProps<{}, { bufferId?: string }>, res: Nex
// If bufferId is the same as the current bufferId, return directly
if (bufferId && global.systemInitBufferId && global.systemInitBufferId === bufferId) {
return {
bufferId: global.systemInitBufferId
bufferId: global.systemInitBufferId,
systemVersion: global.systemVersion || '0.0.0'
};
}

View File

@@ -1,6 +1,5 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { MongoChat } from '@fastgpt/service/core/chat/chatSchema';
import type { PagingData } from '@/types';
import { AppLogsListItemType } from '@/types/app';
import { Types } from '@fastgpt/service/common/mongo';
import { addDays } from 'date-fns';
@@ -10,19 +9,22 @@ import { ChatItemCollectionName } from '@fastgpt/service/core/chat/chatItemSchem
import { NextAPI } from '@/service/middleware/entry';
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
import { readFromSecondary } from '@fastgpt/service/common/mongo/utils';
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
import { PaginationResponse } from '@fastgpt/web/common/fetch/type';
import { addSourceMember } from '@fastgpt/service/support/user/utils';
async function handler(
req: NextApiRequest,
_res: NextApiResponse
): Promise<PagingData<AppLogsListItemType>> {
): Promise<PaginationResponse<AppLogsListItemType>> {
const {
pageNum = 1,
pageSize = 20,
appId,
dateStart = addDays(new Date(), -7),
dateEnd = new Date()
} = req.body as GetAppChatLogsParams;
const { pageSize = 20, offset } = parsePaginationRequest(req);
if (!appId) {
throw new Error('缺少参数');
}
@@ -39,7 +41,7 @@ async function handler(
}
};
const [data, total] = await Promise.all([
const [list, total] = await Promise.all([
MongoChat.aggregate(
[
{ $match: where },
@@ -51,7 +53,7 @@ async function handler(
updateTime: -1
}
},
{ $skip: (pageNum - 1) * pageSize },
{ $skip: offset },
{ $limit: pageSize },
{
$lookup: {
@@ -144,10 +146,14 @@ async function handler(
MongoChat.countDocuments(where, { ...readFromSecondary })
]);
const listWithSourceMember = await addSourceMember({
list: list
});
const listWithoutTmbId = list.filter((item) => !item.tmbId);
return {
pageNum,
pageSize,
data,
list: listWithSourceMember.concat(listWithoutTmbId),
total
};
}

View File

@@ -18,6 +18,7 @@ import { replaceRegChars } from '@fastgpt/global/common/string/tools';
import { concatPer } from '@fastgpt/service/support/permission/controller';
import { getGroupsByTmbId } from '@fastgpt/service/support/permission/memberGroup/controllers';
import { getOrgIdSetWithParentByTmbId } from '@fastgpt/service/support/permission/org/controllers';
import { addSourceMember } from '@fastgpt/service/support/user/utils';
export type ListAppBody = {
parentId?: ParentIdType;
@@ -201,19 +202,9 @@ async function handler(req: ApiRequestProps<ListAppBody>): Promise<AppListItemTy
})
.filter((app) => app.permission.hasReadPer);
return formatApps.map((app) => ({
_id: app._id,
tmbId: app.tmbId,
avatar: app.avatar,
type: app.type,
name: app.name,
intro: app.intro,
updateTime: app.updateTime,
permission: app.permission,
pluginData: app.pluginData,
inheritPermission: app.inheritPermission ?? true,
private: app.privateApp
}));
return addSourceMember({
list: formatApps
});
}
export default NextAPI(handler);

View File

@@ -6,6 +6,8 @@ import { ApiRequestProps } from '@fastgpt/service/type/next';
import { authApp } from '@fastgpt/service/support/permission/app/auth';
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
import { VersionListItemType } from '@fastgpt/global/core/app/version';
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
import { addSourceMember } from '@fastgpt/service/support/user/utils';
export type versionListBody = PaginationProps<{
appId: string;
@@ -15,41 +17,40 @@ export type versionListResponse = PaginationResponse<VersionListItemType>;
async function handler(
req: ApiRequestProps<versionListBody>,
res: NextApiResponse<any>
_res: NextApiResponse<any>
): Promise<versionListResponse> {
const { offset, pageSize, appId } = req.body;
const { appId } = req.body;
const { offset, pageSize } = parsePaginationRequest(req);
await authApp({ appId, req, per: WritePermissionVal, authToken: true });
const [result, total] = await Promise.all([
MongoAppVersion.find(
{
(async () => {
const versions = await MongoAppVersion.find({
appId
},
'_id appId versionName time isPublish tmbId'
)
.sort({
time: -1
})
.skip(offset)
.limit(pageSize),
.sort({
time: -1
})
.skip(offset)
.limit(pageSize)
.lean();
return addSourceMember({
list: versions
}).then((list) =>
list.map((item) => ({
...item,
isPublish: !!item.isPublish
}))
);
})(),
MongoAppVersion.countDocuments({ appId })
]);
const versionList = result.map((item) => {
return {
_id: item._id,
appId: item.appId,
versionName: item.versionName,
time: item.time,
isPublish: item.isPublish,
tmbId: item.tmbId
};
});
return {
total,
list: versionList
list: result
};
}

View File

@@ -12,7 +12,6 @@ describe('发布应用版本测试', () => {
nodes: [],
edges: [],
chatConfig: {},
type: AppTypeEnum.simple,
isPublish: false,
versionName: '1'
};

View File

@@ -164,6 +164,10 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
runningAppInfo: {
id: appId,
teamId: app.teamId,
tmbId: app.tmbId
},
runningUserInfo: {
teamId,
tmbId
},

View File

@@ -7,6 +7,7 @@ import { NextAPI } from '@/service/middleware/entry';
import { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
import { GetHistoriesProps } from '@/global/core/chat/api';
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
import { addMonths } from 'date-fns';
export type getHistoriesQuery = {};
@@ -17,9 +18,10 @@ export type getHistoriesResponse = {};
async function handler(
req: ApiRequestProps<getHistoriesBody, getHistoriesQuery>,
res: ApiResponseType<any>
_res: ApiResponseType<any>
): Promise<PaginationResponse<getHistoriesResponse>> {
const { appId, shareId, outLinkUid, teamId, teamToken, offset, pageSize, source } = req.body;
const { appId, shareId, outLinkUid, teamId, teamToken, source } = req.body;
const { offset, pageSize } = parsePaginationRequest(req);
const match = await (async () => {
if (shareId && outLinkUid) {

View File

@@ -13,6 +13,7 @@ import { filterPublicNodeResponseData } from '@fastgpt/global/core/chat/utils';
import { GetChatTypeEnum } from '@/global/core/chat/constants';
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
import { ChatItemType } from '@fastgpt/global/core/chat/type';
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
export type getPaginationRecordsQuery = {};
@@ -22,16 +23,11 @@ export type getPaginationRecordsResponse = PaginationResponse<ChatItemType>;
async function handler(
req: ApiRequestProps<getPaginationRecordsBody, getPaginationRecordsQuery>,
res: ApiResponseType<any>
_res: ApiResponseType<any>
): Promise<getPaginationRecordsResponse> {
const {
appId,
chatId,
offset,
pageSize = 10,
loadCustomFeedbacks,
type = GetChatTypeEnum.normal
} = req.body;
const { appId, chatId, loadCustomFeedbacks, type = GetChatTypeEnum.normal } = req.body;
const { offset, pageSize } = parsePaginationRequest(req);
if (!appId || !chatId) {
return {

View File

@@ -6,6 +6,7 @@ import { ApiRequestProps } from '@fastgpt/service/type/next';
import { ChatInputGuideSchemaType } from '@fastgpt/global/core/chat/inputGuide/type';
import { authApp } from '@fastgpt/service/support/permission/app/auth';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
export type ChatInputGuideProps = PaginationProps<{
appId: string;
@@ -17,7 +18,8 @@ async function handler(
req: ApiRequestProps<ChatInputGuideProps>,
res: NextApiResponse<any>
): Promise<ChatInputGuideResponse> {
const { appId, pageSize, offset, searchKey } = req.body;
const { appId, searchKey } = req.body;
const { offset, pageSize } = parsePaginationRequest(req);
await authApp({ req, appId, authToken: true, per: ReadPermissionVal });

View File

@@ -2,7 +2,6 @@ import type { NextApiRequest } from 'next';
import { DatasetTrainingCollectionName } from '@fastgpt/service/core/dataset/training/schema';
import { Types } from '@fastgpt/service/common/mongo';
import type { DatasetCollectionsListItemType } from '@/global/core/dataset/type.d';
import type { GetDatasetCollectionsProps } from '@/global/core/api/datasetReq';
import { MongoDatasetCollection } from '@fastgpt/service/core/dataset/collection/schema';
import { DatasetCollectionTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { authDataset } from '@fastgpt/service/support/permission/dataset/auth';
@@ -10,11 +9,10 @@ import { DatasetDataCollectionName } from '@fastgpt/service/core/dataset/data/sc
import { startTrainingQueue } from '@/service/core/dataset/training/utils';
import { NextAPI } from '@/service/middleware/entry';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { PagingData } from '@/types';
import { readFromSecondary } from '@fastgpt/service/common/mongo/utils';
import { collectionTagsToTagLabel } from '@fastgpt/service/core/dataset/collection/utils';
async function handler(req: NextApiRequest): Promise<PagingData<DatasetCollectionsListItemType>> {
async function handler(req: NextApiRequest) {
let {
pageNum = 1,
pageSize = 10,
@@ -24,7 +22,7 @@ async function handler(req: NextApiRequest): Promise<PagingData<DatasetCollectio
selectFolder = false,
filterTags = [],
simple = false
} = req.body as GetDatasetCollectionsProps;
} = req.body as any;
searchText = searchText?.replace(/'/g, '');
pageSize = Math.min(pageSize, 30);

View File

@@ -0,0 +1,192 @@
import type { NextApiRequest } from 'next';
import { DatasetTrainingCollectionName } from '@fastgpt/service/core/dataset/training/schema';
import { Types } from '@fastgpt/service/common/mongo';
import type { DatasetCollectionsListItemType } from '@/global/core/dataset/type.d';
import type { GetDatasetCollectionsProps } from '@/global/core/api/datasetReq';
import { MongoDatasetCollection } from '@fastgpt/service/core/dataset/collection/schema';
import { DatasetCollectionTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { authDataset } from '@fastgpt/service/support/permission/dataset/auth';
import { DatasetDataCollectionName } from '@fastgpt/service/core/dataset/data/schema';
import { startTrainingQueue } from '@/service/core/dataset/training/utils';
import { NextAPI } from '@/service/middleware/entry';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { readFromSecondary } from '@fastgpt/service/common/mongo/utils';
import { collectionTagsToTagLabel } from '@fastgpt/service/core/dataset/collection/utils';
import { PaginationResponse } from '@fastgpt/web/common/fetch/type';
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
async function handler(
req: NextApiRequest
): Promise<PaginationResponse<DatasetCollectionsListItemType>> {
let {
datasetId,
parentId = null,
searchText = '',
selectFolder = false,
filterTags = [],
simple = false
} = req.body as GetDatasetCollectionsProps;
let { pageSize, offset } = parsePaginationRequest(req);
pageSize = Math.min(pageSize, 30);
searchText = searchText?.replace(/'/g, '');
// auth dataset and get my role
const { teamId, permission } = await authDataset({
req,
authToken: true,
authApiKey: true,
datasetId,
per: ReadPermissionVal
});
const match = {
teamId: new Types.ObjectId(teamId),
datasetId: new Types.ObjectId(datasetId),
parentId: parentId ? new Types.ObjectId(parentId) : null,
...(selectFolder ? { type: DatasetCollectionTypeEnum.folder } : {}),
...(searchText
? {
name: new RegExp(searchText, 'i')
}
: {}),
...(filterTags.length ? { tags: { $in: filterTags } } : {})
};
const selectField = {
_id: 1,
parentId: 1,
tmbId: 1,
name: 1,
type: 1,
forbid: 1,
createTime: 1,
updateTime: 1,
trainingType: 1,
fileId: 1,
rawLink: 1,
tags: 1,
externalFileId: 1
};
// not count data amount
if (simple) {
const collections = await MongoDatasetCollection.find(match, undefined, {
...readFromSecondary
})
.select(selectField)
.sort({
updateTime: -1
})
.lean();
return {
list: await Promise.all(
collections.map(async (item) => ({
...item,
tags: await collectionTagsToTagLabel({
datasetId,
tags: item.tags
}),
dataAmount: 0,
trainingAmount: 0,
permission
}))
),
total: await MongoDatasetCollection.countDocuments(match)
};
}
const [collections, total]: [DatasetCollectionsListItemType[], number] = await Promise.all([
MongoDatasetCollection.aggregate([
{
$match: match
},
{
$sort: { updateTime: -1 }
},
{
$skip: offset
},
{
$limit: pageSize
},
// count training data
{
$lookup: {
from: DatasetTrainingCollectionName,
let: { id: '$_id', team_id: match.teamId, dataset_id: match.datasetId },
pipeline: [
{
$match: {
$expr: {
$and: [{ $eq: ['$teamId', '$$team_id'] }, { $eq: ['$collectionId', '$$id'] }]
}
}
},
{ $count: 'count' }
],
as: 'trainingCount'
}
},
// count collection total data
{
$lookup: {
from: DatasetDataCollectionName,
let: { id: '$_id', team_id: match.teamId, dataset_id: match.datasetId },
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: ['$teamId', '$$team_id'] },
{ $eq: ['$datasetId', '$$dataset_id'] },
{ $eq: ['$collectionId', '$$id'] }
]
}
}
},
{ $count: 'count' }
],
as: 'dataCount'
}
},
{
$project: {
...selectField,
dataAmount: {
$ifNull: [{ $arrayElemAt: ['$dataCount.count', 0] }, 0]
},
trainingAmount: {
$ifNull: [{ $arrayElemAt: ['$trainingCount.count', 0] }, 0]
}
}
}
]),
MongoDatasetCollection.countDocuments(match, {
...readFromSecondary
})
]);
const list = await Promise.all(
collections.map(async (item) => ({
...item,
tags: await collectionTagsToTagLabel({
datasetId,
tags: item.tags
}),
permission
}))
);
if (list.find((item) => item.trainingAmount > 0)) {
startTrainingQueue();
}
// count collections
return {
list,
total
};
}
export default NextAPI(handler);

View File

@@ -10,6 +10,7 @@ import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
import { ApiRequestProps } from '@fastgpt/service/type/next';
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
import type { DatasetCollectionsListItemType } from '@/global/core/dataset/type.d';
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
export type GetScrollCollectionsProps = PaginationProps<{
datasetId: string;
@@ -25,8 +26,6 @@ async function handler(
): Promise<PaginationResponse<DatasetCollectionsListItemType>> {
let {
datasetId,
pageSize = 10,
offset,
parentId = null,
searchText = '',
selectFolder = false,
@@ -36,6 +35,7 @@ async function handler(
if (!datasetId) {
return Promise.reject(CommonErrEnum.missingParams);
}
let { offset, pageSize } = parsePaginationRequest(req);
searchText = searchText?.replace(/'/g, '');
pageSize = Math.min(pageSize, 30);

View File

@@ -3,19 +3,21 @@ import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
import { replaceRegChars } from '@fastgpt/global/common/string/tools';
import { NextAPI } from '@/service/middleware/entry';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { PagingData, RequestPaging } from '@/types';
import { ApiRequestProps } from '@fastgpt/service/type/next';
import { DatasetDataListItemType } from '@/global/core/dataset/type';
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
import { PaginationResponse } from '@fastgpt/web/common/fetch/type';
export type GetDatasetDataListProps = RequestPaging & {
export type GetDatasetDataListProps = {
searchText?: string;
collectionId: string;
};
async function handler(
req: ApiRequestProps<GetDatasetDataListProps>
): Promise<PagingData<DatasetDataListItemType>> {
let { pageNum = 1, pageSize = 10, searchText = '', collectionId } = req.body;
): Promise<PaginationResponse<DatasetDataListItemType>> {
let { searchText = '', collectionId } = req.body;
let { offset, pageSize } = parsePaginationRequest(req);
pageSize = Math.min(pageSize, 30);
@@ -40,19 +42,17 @@ async function handler(
: {})
};
const [data, total] = await Promise.all([
const [list, total] = await Promise.all([
MongoDatasetData.find(match, '_id datasetId collectionId q a chunkIndex')
.sort({ chunkIndex: 1, updateTime: -1 })
.skip((pageNum - 1) * pageSize)
.skip(offset)
.limit(pageSize)
.lean(),
MongoDatasetData.countDocuments(match)
]);
return {
pageNum,
pageSize,
data,
list,
total
};
}

View File

@@ -6,6 +6,7 @@ import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { ApiRequestProps } from '@fastgpt/service/type/next';
import { DatasetDataListItemType } from '@/global/core/dataset/type';
import { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
import { parsePaginationRequest } from '@fastgpt/service/common/api/pagination';
export type GetDatasetDataListProps = PaginationProps & {
searchText?: string;
@@ -16,7 +17,8 @@ export type GetDatasetDataListRes = PaginationResponse<DatasetDataListItemType>;
async function handler(
req: ApiRequestProps<GetDatasetDataListProps>
): Promise<GetDatasetDataListRes> {
let { offset, pageSize = 10, searchText = '', collectionId } = req.body;
let { searchText = '', collectionId } = req.body;
let { offset, pageSize } = parsePaginationRequest(req);
pageSize = Math.min(pageSize, 30);

View File

@@ -1,8 +1,6 @@
import type { DatasetListItemType } from '@fastgpt/global/core/dataset/type.d';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { MongoDataset } from '@fastgpt/service/core/dataset/schema';
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
import { getVectorModel } from '@fastgpt/service/core/ai/model';
import { NextAPI } from '@/service/middleware/entry';
import { DatasetPermission } from '@fastgpt/global/support/permission/dataset/controller';
import {
@@ -19,6 +17,8 @@ import { replaceRegChars } from '@fastgpt/global/common/string/tools';
import { getGroupsByTmbId } from '@fastgpt/service/support/permission/memberGroup/controllers';
import { concatPer } from '@fastgpt/service/support/permission/controller';
import { getOrgIdSetWithParentByTmbId } from '@fastgpt/service/support/permission/org/controllers';
import { addSourceMember } from '@fastgpt/service/support/user/utils';
import { getVectorModel } from '@fastgpt/service/core/ai/model';
export type GetDatasetListBody = {
parentId: ParentIdType;
@@ -167,28 +167,24 @@ async function handler(req: ApiRequestProps<GetDatasetListBody>) {
})();
return {
...dataset,
_id: dataset._id,
avatar: dataset.avatar,
name: dataset.name,
intro: dataset.intro,
type: dataset.type,
vectorModel: getVectorModel(dataset.vectorModel),
inheritPermission: dataset.inheritPermission,
tmbId: dataset.tmbId,
updateTime: dataset.updateTime,
permission: Per,
privateDataset
};
})
.filter((app) => app.permission.hasReadPer);
const data = formatDatasets.map<DatasetListItemType>((item) => ({
_id: item._id,
avatar: item.avatar,
name: item.name,
intro: item.intro,
type: item.type,
permission: item.permission,
vectorModel: getVectorModel(item.vectorModel),
inheritPermission: item.inheritPermission,
tmbId: item.tmbId,
updateTime: item.updateTime,
private: item.privateDataset
}));
return data;
return addSourceMember({
list: formatDatasets
});
}
export default NextAPI(handler);

View File

@@ -45,7 +45,11 @@ async function handler(
requestOrigin: req.headers.origin,
mode: 'debug',
runningAppInfo: {
id: appId,
id: app._id,
teamId: app.teamId,
tmbId: app.tmbId
},
runningUserInfo: {
teamId,
tmbId
},

View File

@@ -1,17 +1,18 @@
import { MongoUser } from '@fastgpt/service/support/user/schema';
import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { UserUpdateParams } from '@/types/user';
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
/* update user info */
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
import { NextAPI } from '@/service/middleware/entry';
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
import { getUserDetail } from '@fastgpt/service/support/user/controller';
import { refreshSourceAvatar } from '@fastgpt/service/common/file/image/controller';
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
export type UserAccountUpdateQuery = {};
export type UserAccountUpdateBody = UserUpdateParams;
export type UserAccountUpdateResponse = {};
async function handler(
req: ApiRequestProps<UserAccountUpdateBody, UserAccountUpdateQuery>,
_res: ApiResponseType<any>
@@ -19,21 +20,33 @@ async function handler(
const { avatar, timezone } = req.body;
const { tmbId } = await authCert({ req, authToken: true });
const user = await getUserDetail({ tmbId });
// const user = await getUserDetail({ tmbId });
// 更新对应的记录
await mongoSessionRun(async (session) => {
await MongoUser.updateOne(
{
_id: user._id
},
{
...(avatar && { avatar }),
...(timezone && { timezone })
}
).session(session);
await refreshSourceAvatar(avatar, user.avatar, session);
const tmb = await MongoTeamMember.findById(tmbId).session(session);
if (timezone) {
await MongoUser.updateOne(
{
_id: tmb?.userId
},
{
timezone
}
).session(session);
}
// if avatar, update team member avatar
if (avatar) {
await MongoTeamMember.updateOne(
{
_id: tmbId
},
{
avatar
}
).session(session);
await refreshSourceAvatar(avatar, tmb?.avatar, session);
}
});
return {};

View File

@@ -280,6 +280,10 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
teamId: String(app.teamId),
tmbId: String(app.tmbId)
},
runningUserInfo: {
teamId,
tmbId
},
uid: String(outLinkUserId || tmbId),
chatId,