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:
@@ -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);
|
||||
// };
|
||||
|
||||
55
projects/app/src/pages/api/admin/initv4819.ts
Normal file
55
projects/app/src/pages/api/admin/initv4819.ts
Normal 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);
|
||||
}
|
||||
};
|
||||
@@ -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'
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ describe('发布应用版本测试', () => {
|
||||
nodes: [],
|
||||
edges: [],
|
||||
chatConfig: {},
|
||||
type: AppTypeEnum.simple,
|
||||
isPublish: false,
|
||||
versionName: '1'
|
||||
};
|
||||
|
||||
@@ -164,6 +164,10 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
|
||||
runningAppInfo: {
|
||||
id: appId,
|
||||
teamId: app.teamId,
|
||||
tmbId: app.tmbId
|
||||
},
|
||||
runningUserInfo: {
|
||||
teamId,
|
||||
tmbId
|
||||
},
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 });
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
192
projects/app/src/pages/api/core/dataset/collection/listV2.ts
Normal file
192
projects/app/src/pages/api/core/dataset/collection/listV2.ts
Normal 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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
},
|
||||
|
||||
@@ -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 {};
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user