mirror of
https://github.com/labring/FastGPT.git
synced 2025-12-25 20:02:47 +00:00
fix
This commit is contained in:
parent
afd9e6c439
commit
56b0165f3d
|
|
@ -27,6 +27,8 @@ import { getS3ChatSource } from '../../common/s3/sources/chat';
|
|||
import { MongoAppChatLog } from './logs/chatLogsSchema';
|
||||
import { MongoAppRegistration } from '../../support/appRegistration/schema';
|
||||
import { MongoMcpKey } from '../../support/mcp/schema';
|
||||
import { type ClientSession } from '../../common/mongo';
|
||||
import { MongoAppRecord } from './record/schema';
|
||||
|
||||
export const beforeUpdateAppFormat = ({ nodes }: { nodes?: StoreNodeItemType[] }) => {
|
||||
if (!nodes) return;
|
||||
|
|
@ -181,6 +183,8 @@ export const deleteAppDataProcessor = async ({
|
|||
await MongoAppRegistration.deleteMany({ appId });
|
||||
// 删除应用从MCP key apps数组中移除
|
||||
await MongoMcpKey.updateMany({ teamId, 'apps.appId': appId }, { $pull: { apps: { appId } } });
|
||||
// 删除应用使用记录
|
||||
await MongoAppRecord.deleteMany({ appId });
|
||||
|
||||
// 删除应用本身
|
||||
await MongoApp.deleteOne({ _id: appId });
|
||||
|
|
@ -214,13 +218,10 @@ export async function updateParentFoldersUpdateTime({
|
|||
}): Promise<void> {
|
||||
if (!parentId) return;
|
||||
|
||||
const parentApp = await MongoApp.findById(parentId).lean();
|
||||
const parentApp = await MongoApp.findById(parentId, 'parentId');
|
||||
if (!parentApp) return;
|
||||
|
||||
// Only update if parent is a folder
|
||||
if (AppFolderTypeList.includes(parentApp.type)) {
|
||||
await MongoApp.findByIdAndUpdate(parentId, { updateTime: new Date() }, { session });
|
||||
}
|
||||
await MongoApp.findByIdAndUpdate(parentId, { updateTime: new Date() }, { session });
|
||||
|
||||
// Recursively update parent folders
|
||||
await updateParentFoldersUpdateTime({
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
import {
|
||||
TeamCollectionName,
|
||||
TeamMemberCollectionName
|
||||
} from '@fastgpt/global/support/user/team/constant';
|
||||
import { getMongoModel, Schema } from '../../../common/mongo';
|
||||
import { AppCollectionName } from '../schema';
|
||||
import type { AppRecordType } from './type';
|
||||
|
||||
export const AppRecordCollectionName = 'app_records';
|
||||
|
||||
const AppRecordSchema = new Schema(
|
||||
{
|
||||
tmbId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamMemberCollectionName,
|
||||
required: true
|
||||
},
|
||||
teamId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamCollectionName,
|
||||
required: true
|
||||
},
|
||||
appId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: AppCollectionName,
|
||||
required: true
|
||||
},
|
||||
lastUsedTime: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
}
|
||||
},
|
||||
{
|
||||
timestamps: false
|
||||
}
|
||||
);
|
||||
|
||||
AppRecordSchema.index({ tmbId: 1, lastUsedTime: -1 }); // 查询用户最近使用的应用
|
||||
AppRecordSchema.index({ tmbId: 1, appId: 1 }, { unique: true }); // 防止重复记录
|
||||
AppRecordSchema.index({ teamId: 1, appId: 1 }); // 用于清理权限失效的记录
|
||||
|
||||
export const MongoAppRecord = getMongoModel<AppRecordType>(
|
||||
AppRecordCollectionName,
|
||||
AppRecordSchema
|
||||
);
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
// Zod schemas
|
||||
export const AppRecordSchemaZod = z.object({
|
||||
_id: z.string().optional(),
|
||||
tmbId: z.string(),
|
||||
teamId: z.string(),
|
||||
appId: z.string(),
|
||||
lastUsedTime: z.date()
|
||||
});
|
||||
|
||||
// 创建应用记录时的 schema(不包含 _id)
|
||||
export const CreateAppRecordSchemaZod = AppRecordSchemaZod.omit({
|
||||
_id: true
|
||||
});
|
||||
|
||||
// 更新应用记录时的 schema(部分字段可选)
|
||||
export const UpdateAppRecordSchemaZod = AppRecordSchemaZod.partial().omit({
|
||||
_id: true,
|
||||
tmbId: true,
|
||||
teamId: true,
|
||||
appId: true
|
||||
});
|
||||
|
||||
// 查询参数的 schema
|
||||
export const AppRecordQuerySchemaZod = z.object({
|
||||
tmbId: z.string().optional(),
|
||||
teamId: z.string().optional(),
|
||||
appId: z.string().optional(),
|
||||
lastUsedTime: z
|
||||
.union([
|
||||
z.date(),
|
||||
z.object({
|
||||
gte: z.date().optional(),
|
||||
lte: z.date().optional(),
|
||||
gt: z.date().optional(),
|
||||
lt: z.date().optional()
|
||||
})
|
||||
])
|
||||
.optional()
|
||||
});
|
||||
|
||||
// TypeScript types inferred from Zod schemas
|
||||
export type AppRecordType = z.infer<typeof AppRecordSchemaZod>;
|
||||
export type CreateAppRecordType = z.infer<typeof CreateAppRecordSchemaZod>;
|
||||
export type UpdateAppRecordType = z.infer<typeof UpdateAppRecordSchemaZod>;
|
||||
export type AppRecordQueryType = z.infer<typeof AppRecordQuerySchemaZod>;
|
||||
|
||||
// 兼容旧版本的类型定义(保持向后兼容)
|
||||
export type {
|
||||
AppRecordType as AppRecordSchemaType,
|
||||
CreateAppRecordType as AppRecordCreateType,
|
||||
UpdateAppRecordType as AppRecordUpdateType
|
||||
};
|
||||
|
||||
// 应用记录统计类型
|
||||
export const AppRecordStatsSchemaZod = z.object({
|
||||
totalRecords: z.number().min(0),
|
||||
uniqueApps: z.number().min(0),
|
||||
mostUsedApp: z
|
||||
.object({
|
||||
appId: z.string(),
|
||||
usageCount: z.number().min(0)
|
||||
})
|
||||
.optional(),
|
||||
lastUsedTime: z.date().optional()
|
||||
});
|
||||
|
||||
export type AppRecordStatsType = z.infer<typeof AppRecordStatsSchemaZod>;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { mongoSessionRun } from '../../../common/mongo/sessionRun';
|
||||
import { MongoAppUsage } from './schema';
|
||||
import { MongoAppRecord } from './schema';
|
||||
|
||||
export const recordAppUsage = async ({
|
||||
appId,
|
||||
|
|
@ -11,7 +11,7 @@ export const recordAppUsage = async ({
|
|||
teamId: string;
|
||||
}) => {
|
||||
await mongoSessionRun(async (session) => {
|
||||
await MongoAppUsage.findOneAndUpdate(
|
||||
await MongoAppRecord.findOneAndUpdate(
|
||||
{ tmbId, appId },
|
||||
{
|
||||
$set: {
|
||||
|
|
@ -26,24 +26,24 @@ export const recordAppUsage = async ({
|
|||
}
|
||||
);
|
||||
|
||||
// 保留最新的50条记录,删除超出限制的旧记录
|
||||
const threshold = await MongoAppUsage.findOne(
|
||||
const records = await MongoAppRecord.find(
|
||||
{ tmbId },
|
||||
{ lastUsedTime: 1 },
|
||||
{ _id: 1 },
|
||||
{
|
||||
session,
|
||||
sort: { lastUsedTime: -1 },
|
||||
skip: 49,
|
||||
lean: true
|
||||
}
|
||||
);
|
||||
|
||||
if (threshold) {
|
||||
await MongoAppUsage.deleteMany(
|
||||
if (records.length > 50) {
|
||||
const toDeleteRecords = records.slice(50);
|
||||
const toDeleteIds = toDeleteRecords.map((record) => record._id);
|
||||
|
||||
await MongoAppRecord.deleteMany(
|
||||
{
|
||||
tmbId,
|
||||
_id: { $ne: threshold._id },
|
||||
lastUsedTime: { $lte: threshold.lastUsedTime }
|
||||
_id: { $in: toDeleteIds }
|
||||
},
|
||||
{ session }
|
||||
);
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
import {
|
||||
TeamCollectionName,
|
||||
TeamMemberCollectionName
|
||||
} from '@fastgpt/global/support/user/team/constant';
|
||||
import { getMongoModel, Schema } from '../../../common/mongo';
|
||||
|
||||
export const AppUsageCollectionName = 'app_usages';
|
||||
|
||||
const AppUsageSchema = new Schema(
|
||||
{
|
||||
tmbId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamMemberCollectionName,
|
||||
required: true
|
||||
},
|
||||
teamId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamCollectionName,
|
||||
required: true
|
||||
},
|
||||
appId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'apps',
|
||||
required: true
|
||||
},
|
||||
lastUsedTime: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
}
|
||||
},
|
||||
{
|
||||
minimize: false,
|
||||
timestamps: false
|
||||
}
|
||||
);
|
||||
|
||||
AppUsageSchema.index({ tmbId: 1, lastUsedTime: -1 }); // 查询用户最近使用的应用
|
||||
AppUsageSchema.index({ tmbId: 1, appId: 1 }, { unique: true }); // 防止重复记录
|
||||
AppUsageSchema.index({ teamId: 1, appId: 1 }); // 用于清理权限失效的记录
|
||||
|
||||
export const MongoAppUsage = getMongoModel<AppUsageType>(AppUsageCollectionName, AppUsageSchema);
|
||||
|
||||
export type AppUsageType = {
|
||||
_id?: string;
|
||||
tmbId: string;
|
||||
teamId: string;
|
||||
appId: string;
|
||||
lastUsedTime: Date;
|
||||
};
|
||||
|
|
@ -32,9 +32,10 @@ const CustomPluginRunBox = dynamic(() => import('@/pageComponents/chat/CustomPlu
|
|||
|
||||
type Props = {
|
||||
myApps: AppListItemType[];
|
||||
refreshRecentlyUsed?: () => void;
|
||||
};
|
||||
|
||||
const AppChatWindow = ({ myApps }: Props) => {
|
||||
const AppChatWindow = ({ myApps, refreshRecentlyUsed }: Props) => {
|
||||
const { userInfo } = useUserStore();
|
||||
const { chatId, appId, outLinkAuthData } = useChatStore();
|
||||
|
||||
|
|
@ -122,9 +123,19 @@ const AppChatWindow = ({ myApps }: Props) => {
|
|||
title: newTitle
|
||||
}));
|
||||
|
||||
refreshRecentlyUsed?.();
|
||||
|
||||
return { responseText, isNewChat: forbidLoadChat.current };
|
||||
},
|
||||
[appId, chatId, onUpdateHistoryTitle, setChatBoxData, forbidLoadChat, isShowCite]
|
||||
[
|
||||
appId,
|
||||
chatId,
|
||||
onUpdateHistoryTitle,
|
||||
setChatBoxData,
|
||||
forbidLoadChat,
|
||||
isShowCite,
|
||||
refreshRecentlyUsed
|
||||
]
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ import { getWebReqUrl } from '@fastgpt/web/common/system/utils';
|
|||
|
||||
type Props = {
|
||||
myApps: AppListItemType[];
|
||||
refreshRecentlyUsed?: () => void;
|
||||
};
|
||||
|
||||
const defaultFileSelectConfig: AppFileSelectConfigType = {
|
||||
|
|
@ -68,7 +69,7 @@ const defaultWhisperConfig: AppWhisperConfigType = {
|
|||
autoTTSResponse: false
|
||||
};
|
||||
|
||||
const HomeChatWindow = ({ myApps }: Props) => {
|
||||
const HomeChatWindow = ({ myApps, refreshRecentlyUsed }: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const { isPc } = useSystem();
|
||||
|
||||
|
|
@ -232,6 +233,8 @@ const HomeChatWindow = ({ myApps }: Props) => {
|
|||
title: newTitle
|
||||
}));
|
||||
|
||||
refreshRecentlyUsed?.();
|
||||
|
||||
return { responseText, isNewChat: forbidLoadChat.current };
|
||||
}
|
||||
|
||||
|
|
@ -281,6 +284,8 @@ const HomeChatWindow = ({ myApps }: Props) => {
|
|||
title: newTitle
|
||||
}));
|
||||
|
||||
refreshRecentlyUsed?.();
|
||||
|
||||
return { responseText, isNewChat: forbidLoadChat.current };
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export const useChat = (appId: string) => {
|
|||
const [isInitedUser, setIsInitedUser] = useState(false);
|
||||
|
||||
// get app list
|
||||
const { data: myApps = [] } = useRequest2(() => getRecentlyUsedApps(), {
|
||||
const { data: myApps = [], refresh } = useRequest2(() => getRecentlyUsedApps(), {
|
||||
manual: false,
|
||||
errorToast: '',
|
||||
refreshDeps: [userInfo],
|
||||
|
|
@ -43,6 +43,7 @@ export const useChat = (appId: string) => {
|
|||
return {
|
||||
isInitedUser,
|
||||
userInfo,
|
||||
myApps
|
||||
myApps,
|
||||
refreshRecentlyUsed: refresh
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
|
||||
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||
import { MongoAppUsage } from '@fastgpt/service/core/app/usage/schema';
|
||||
import { MongoAppRecord } from '@fastgpt/service/core/app/record/schema';
|
||||
import { MongoApp } from '@fastgpt/service/core/app/schema';
|
||||
import { addSourceMember } from '@fastgpt/service/support/user/utils';
|
||||
import { authApp } from '@fastgpt/service/support/permission/app/auth';
|
||||
import type { AppListItemType } from '@fastgpt/global/core/app/type';
|
||||
import { AppPermission } from '@fastgpt/global/support/permission/app/controller';
|
||||
|
||||
export type GetRecentlyUsedAppsResponse = AppListItemType[];
|
||||
|
||||
|
|
@ -13,57 +13,37 @@ async function handler(
|
|||
req: ApiRequestProps<{}, {}>,
|
||||
_res: ApiResponseType<GetRecentlyUsedAppsResponse>
|
||||
): Promise<GetRecentlyUsedAppsResponse> {
|
||||
const { tmbId, teamId } = await authUserPer({
|
||||
const { tmbId } = await authUserPer({
|
||||
req,
|
||||
authToken: true,
|
||||
authApiKey: true
|
||||
});
|
||||
|
||||
const recentUsages = await MongoAppUsage.find(
|
||||
const recentRecords = await MongoAppRecord.find(
|
||||
{ tmbId },
|
||||
{ appId: 1 },
|
||||
{ sort: { lastUsedTime: -1 }, limit: 20 }
|
||||
).lean();
|
||||
|
||||
if (!recentUsages.length) return [];
|
||||
if (!recentRecords.length) return [];
|
||||
|
||||
const appIds = recentUsages.map((usage) => usage.appId);
|
||||
const appIds = recentRecords.map((record) => record.appId);
|
||||
|
||||
// 并发检查权限
|
||||
const results = await Promise.allSettled(
|
||||
appIds.map((appId) =>
|
||||
authApp({ req, authToken: true, authApiKey: true, appId, per: ReadPermissionVal })
|
||||
.then(({ app }) => ({ appId, app }))
|
||||
.catch(() => ({ appId, app: null }))
|
||||
)
|
||||
);
|
||||
const apps = await MongoApp.find(
|
||||
{
|
||||
_id: { $in: appIds },
|
||||
deleteTime: null
|
||||
},
|
||||
'_id parentId tmbId name avatar intro type updateTime pluginData inheritPermission'
|
||||
).lean();
|
||||
|
||||
const validApps: {
|
||||
appId: string;
|
||||
app: NonNullable<Awaited<ReturnType<typeof authApp>>['app']>;
|
||||
}[] = [];
|
||||
const invalidAppIds: string[] = [];
|
||||
|
||||
for (const result of results) {
|
||||
if (result.status === 'fulfilled') {
|
||||
const { appId, app } = result.value;
|
||||
if (app) {
|
||||
validApps.push({ appId, app });
|
||||
} else {
|
||||
invalidAppIds.push(appId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 异步清理无效记录
|
||||
if (invalidAppIds.length) {
|
||||
MongoAppUsage.deleteMany({ tmbId, teamId, appId: { $in: invalidAppIds } }).catch((err) =>
|
||||
console.error('Failed to clean invalid app usage records:', err)
|
||||
);
|
||||
}
|
||||
const appMap = new Map(apps.map((app) => [String(app._id), app]));
|
||||
const sortedApps = recentRecords
|
||||
.map((record) => appMap.get(String(record.appId)))
|
||||
.filter((app) => app != null);
|
||||
|
||||
return addSourceMember({
|
||||
list: validApps.map(({ app }) => ({
|
||||
list: sortedApps.map((app) => ({
|
||||
_id: app._id,
|
||||
parentId: app.parentId,
|
||||
tmbId: app.tmbId,
|
||||
|
|
@ -73,7 +53,10 @@ async function handler(
|
|||
type: app.type,
|
||||
updateTime: app.updateTime,
|
||||
pluginData: app.pluginData,
|
||||
permission: app.permission,
|
||||
permission: new AppPermission({
|
||||
role: 0,
|
||||
isOwner: String(app.tmbId) === String(tmbId)
|
||||
}),
|
||||
inheritPermission: app.inheritPermission
|
||||
}))
|
||||
});
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ async function handler(req: ApiRequestProps<PostPublishAppProps>, res: NextApiRe
|
|||
nodes
|
||||
});
|
||||
|
||||
await updateParentFoldersUpdateTime({
|
||||
parentId: app.parentId
|
||||
});
|
||||
|
||||
if (autoSave) {
|
||||
await mongoSessionRun(async (session) => {
|
||||
await MongoAppVersion.updateOne(
|
||||
|
|
@ -62,11 +66,6 @@ async function handler(req: ApiRequestProps<PostPublishAppProps>, res: NextApiRe
|
|||
session
|
||||
}
|
||||
);
|
||||
|
||||
await updateParentFoldersUpdateTime({
|
||||
parentId: app.parentId,
|
||||
session
|
||||
});
|
||||
});
|
||||
|
||||
addAuditLog({
|
||||
|
|
@ -128,11 +127,6 @@ async function handler(req: ApiRequestProps<PostPublishAppProps>, res: NextApiRe
|
|||
session
|
||||
}
|
||||
);
|
||||
|
||||
await updateParentFoldersUpdateTime({
|
||||
parentId: app.parentId,
|
||||
session
|
||||
});
|
||||
});
|
||||
|
||||
(async () => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@fastgpt/service/common/response';
|
||||
import { authApp } from '@fastgpt/service/support/permission/app/auth';
|
||||
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
|
||||
import { getGuideModule, getAppChatConfig } from '@fastgpt/global/core/workflow/utils';
|
||||
import { getChatModelNameListByModules } from '@/service/core/app/workflow';
|
||||
import type { InitChatProps, InitChatResponse } from '@/global/core/chat/api.d';
|
||||
|
|
@ -11,6 +12,8 @@ import { NextAPI } from '@/service/middleware/entry';
|
|||
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { presignVariablesFileUrls } from '@fastgpt/service/core/chat/utils';
|
||||
import { MongoAppRecord } from '@fastgpt/service/core/app/record/schema';
|
||||
import { AppErrEnum } from '@fastgpt/global/common/error/code/app';
|
||||
|
||||
async function handler(
|
||||
req: NextApiRequest,
|
||||
|
|
@ -25,57 +28,75 @@ async function handler(
|
|||
});
|
||||
}
|
||||
|
||||
// auth app permission
|
||||
const [{ app, tmbId }, chat] = await Promise.all([
|
||||
authApp({
|
||||
req,
|
||||
authToken: true,
|
||||
authApiKey: true,
|
||||
appId,
|
||||
per: ReadPermissionVal
|
||||
}),
|
||||
chatId ? MongoChat.findOne({ appId, chatId }) : undefined
|
||||
]);
|
||||
|
||||
// auth chat permission
|
||||
if (chat && !app.permission.hasReadChatLogPer && String(tmbId) !== String(chat?.tmbId)) {
|
||||
return Promise.reject(ChatErrEnum.unAuthChat);
|
||||
}
|
||||
|
||||
// get app and history
|
||||
const { nodes, chatConfig } = await getAppLatestVersion(app._id, app);
|
||||
const pluginInputs =
|
||||
chat?.pluginInputs ??
|
||||
nodes?.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput)?.inputs ??
|
||||
[];
|
||||
|
||||
const variables = await presignVariablesFileUrls({
|
||||
variables: chat?.variables,
|
||||
variableConfig: chat?.variableList
|
||||
});
|
||||
|
||||
return {
|
||||
chatId,
|
||||
appId,
|
||||
title: chat?.title,
|
||||
userAvatar: undefined,
|
||||
variables,
|
||||
app: {
|
||||
chatConfig: getAppChatConfig({
|
||||
chatConfig,
|
||||
systemConfigNode: getGuideModule(nodes),
|
||||
storeVariables: chat?.variableList,
|
||||
storeWelcomeText: chat?.welcomeText,
|
||||
isPublicFetch: false
|
||||
try {
|
||||
// auth app permission
|
||||
const [{ app, tmbId }, chat] = await Promise.all([
|
||||
authApp({
|
||||
req,
|
||||
authToken: true,
|
||||
authApiKey: true,
|
||||
appId,
|
||||
per: ReadPermissionVal
|
||||
}),
|
||||
chatModels: getChatModelNameListByModules(nodes),
|
||||
name: app.name,
|
||||
avatar: app.avatar,
|
||||
intro: app.intro,
|
||||
type: app.type,
|
||||
pluginInputs
|
||||
chatId ? MongoChat.findOne({ appId, chatId }) : undefined
|
||||
]);
|
||||
|
||||
// auth chat permission
|
||||
if (chat && !app.permission.hasReadChatLogPer && String(tmbId) !== String(chat?.tmbId)) {
|
||||
return Promise.reject(ChatErrEnum.unAuthChat);
|
||||
}
|
||||
};
|
||||
|
||||
// get app and history
|
||||
const { nodes, chatConfig } = await getAppLatestVersion(app._id, app);
|
||||
const pluginInputs =
|
||||
chat?.pluginInputs ??
|
||||
nodes?.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput)?.inputs ??
|
||||
[];
|
||||
|
||||
const variables = await presignVariablesFileUrls({
|
||||
variables: chat?.variables,
|
||||
variableConfig: chat?.variableList
|
||||
});
|
||||
|
||||
return {
|
||||
chatId,
|
||||
appId,
|
||||
title: chat?.title,
|
||||
userAvatar: undefined,
|
||||
variables,
|
||||
app: {
|
||||
chatConfig: getAppChatConfig({
|
||||
chatConfig,
|
||||
systemConfigNode: getGuideModule(nodes),
|
||||
storeVariables: chat?.variableList,
|
||||
storeWelcomeText: chat?.welcomeText,
|
||||
isPublicFetch: false
|
||||
}),
|
||||
chatModels: getChatModelNameListByModules(nodes),
|
||||
name: app.name,
|
||||
avatar: app.avatar,
|
||||
intro: app.intro,
|
||||
type: app.type,
|
||||
pluginInputs
|
||||
}
|
||||
};
|
||||
} catch (error: any) {
|
||||
if (error === AppErrEnum.unAuthApp) {
|
||||
const { tmbId, teamId } = await authUserPer({
|
||||
req,
|
||||
authToken: true,
|
||||
authApiKey: true
|
||||
});
|
||||
|
||||
await MongoAppRecord.deleteMany({
|
||||
tmbId,
|
||||
teamId,
|
||||
appId
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
export default NextAPI(handler);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import {
|
|||
} from '@fastgpt/service/core/chat/saveChat';
|
||||
import { responseWrite } from '@fastgpt/service/common/response';
|
||||
import { authOutLinkChatStart } from '@/service/support/permission/auth/outLink';
|
||||
import { recordAppUsage } from '@fastgpt/service/core/app/usage/utils';
|
||||
import { recordAppUsage } from '@fastgpt/service/core/app/record/utils';
|
||||
import { pushResult2Remote, addOutLinkUsage } from '@fastgpt/service/support/outLink/tools';
|
||||
import { getUsageSourceByAuthType } from '@fastgpt/global/support/wallet/usage/tools';
|
||||
import { authTeamSpaceToken } from '@/service/support/permission/auth/team';
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import {
|
|||
} from '@fastgpt/service/core/chat/saveChat';
|
||||
import { responseWrite } from '@fastgpt/service/common/response';
|
||||
import { authOutLinkChatStart } from '@/service/support/permission/auth/outLink';
|
||||
import { recordAppUsage } from '@fastgpt/service/core/app/usage/utils';
|
||||
import { recordAppUsage } from '@fastgpt/service/core/app/record/utils';
|
||||
import { pushResult2Remote, addOutLinkUsage } from '@fastgpt/service/support/outLink/tools';
|
||||
import { getUsageSourceByAuthType } from '@fastgpt/global/support/wallet/usage/tools';
|
||||
import { authTeamSpaceToken } from '@/service/support/permission/auth/team';
|
||||
|
|
|
|||
|
|
@ -33,7 +33,13 @@ import { MongoOutLink } from '@fastgpt/service/support/outLink/schema';
|
|||
import { addLog } from '@fastgpt/service/common/system/log';
|
||||
import { PublishChannelEnum } from '@fastgpt/global/support/outLink/constant';
|
||||
|
||||
const Chat = ({ myApps }: { myApps: AppListItemType[] }) => {
|
||||
const Chat = ({
|
||||
myApps,
|
||||
refreshRecentlyUsed
|
||||
}: {
|
||||
myApps: AppListItemType[];
|
||||
refreshRecentlyUsed: () => void;
|
||||
}) => {
|
||||
const { isPc } = useSystem();
|
||||
|
||||
const { appId } = useChatStore();
|
||||
|
|
@ -62,7 +68,9 @@ const Chat = ({ myApps }: { myApps: AppListItemType[] }) => {
|
|||
{(!datasetCiteData || isPc) && (
|
||||
<PageContainer flex="1 0 0" w={0} position="relative">
|
||||
{/* home chat window */}
|
||||
{pane === ChatSidebarPaneEnum.HOME && <HomeChatWindow myApps={myApps} />}
|
||||
{pane === ChatSidebarPaneEnum.HOME && (
|
||||
<HomeChatWindow myApps={myApps} refreshRecentlyUsed={refreshRecentlyUsed} />
|
||||
)}
|
||||
|
||||
{/* favourite apps */}
|
||||
{pane === ChatSidebarPaneEnum.FAVORITE_APPS && <ChatFavouriteApp />}
|
||||
|
|
@ -71,7 +79,9 @@ const Chat = ({ myApps }: { myApps: AppListItemType[] }) => {
|
|||
{pane === ChatSidebarPaneEnum.TEAM_APPS && <ChatTeamApp />}
|
||||
|
||||
{/* recently used apps chat window */}
|
||||
{pane === ChatSidebarPaneEnum.RECENTLY_USED_APPS && <AppChatWindow myApps={myApps} />}
|
||||
{pane === ChatSidebarPaneEnum.RECENTLY_USED_APPS && (
|
||||
<AppChatWindow myApps={myApps} refreshRecentlyUsed={refreshRecentlyUsed} />
|
||||
)}
|
||||
|
||||
{/* setting */}
|
||||
{pane === ChatSidebarPaneEnum.SETTING && <ChatSetting />}
|
||||
|
|
@ -103,7 +113,7 @@ const Render = (props: {
|
|||
const { chatId } = useChatStore();
|
||||
const { setUserInfo } = useUserStore();
|
||||
const { feConfigs } = useSystemStore();
|
||||
const { isInitedUser, userInfo, myApps } = useChat(appId);
|
||||
const { isInitedUser, userInfo, myApps, refreshRecentlyUsed } = useChat(appId);
|
||||
|
||||
const chatHistoryProviderParams = useMemo(
|
||||
() => ({ appId, source: ChatSourceEnum.online }),
|
||||
|
|
@ -154,7 +164,7 @@ const Render = (props: {
|
|||
isShowFullText={props.showFullText}
|
||||
>
|
||||
<ChatRecordContextProvider params={chatRecordProviderParams}>
|
||||
<Chat myApps={myApps} />
|
||||
<Chat myApps={myApps} refreshRecentlyUsed={refreshRecentlyUsed} />
|
||||
</ChatRecordContextProvider>
|
||||
</ChatItemContextProvider>
|
||||
</ChatContextProvider>
|
||||
|
|
|
|||
Loading…
Reference in New Issue