perf: chat history api;perf: full text error (#4852)

* perf: chat history api

* perf: i18n

* perf: full text
This commit is contained in:
Archer
2025-05-20 22:31:32 +08:00
committed by GitHub
parent 89c9a02650
commit aa55f059d4
12 changed files with 192 additions and 124 deletions

View File

@@ -959,10 +959,16 @@ curl --location --request POST 'http://localhost:3000/api/core/chat/getHistories
{{< markdownify >}}
{{% alert icon=" " context="success" %}}
目前仅能获取到当前 API key 的创建者的对话。
- appId - 应用 Id
- offset - 偏移量,即从第几条数据开始取
- pageSize - 记录数量
- source - 对话源。source=api表示获取通过 API 创建的对话(不会获取到页面上的对话记录)
- startCreateTime - 开始创建时间(可选)
- endCreateTime - 结束创建时间(可选)
- startUpdateTime - 开始更新时间(可选)
- endUpdateTime - 结束更新时间(可选)
{{% /alert %}}
{{< /markdownify >}}

View File

@@ -26,6 +26,7 @@ export type ChatSchema = {
teamId: string;
tmbId: string;
appId: string;
createTime: Date;
updateTime: Date;
title: string;
customTitle: string;

View File

@@ -34,6 +34,10 @@ const ChatSchema = new Schema({
ref: AppCollectionName,
required: true
},
createTime: {
type: Date,
default: () => new Date()
},
updateTime: {
type: Date,
default: () => new Date()

View File

@@ -27,6 +27,7 @@ import { type ChatItemType } from '@fastgpt/global/core/chat/type';
import type { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import { datasetSearchQueryExtension } from './utils';
import type { RerankModelItemType } from '@fastgpt/global/core/ai/model.d';
import { addLog } from '../../../common/system/log';
export type SearchDatasetDataProps = {
histories: ChatItemType[];
@@ -544,6 +545,7 @@ export async function searchDatasetData(
};
}
try {
const searchResults = (await MongoDatasetDataText.aggregate(
[
{
@@ -655,6 +657,13 @@ export async function searchDatasetData(
}) as SearchDataResponseItemType[],
tokenLen: 0
};
} catch (error) {
addLog.error('multiQueryRecall error', error);
return {
fullTextRecallResults: [],
tokenLen: 0
};
}
};
const multiQueryRecall = async ({
embeddingLimit,

View File

@@ -6,10 +6,6 @@ export const getUserFingerprint = async () => {
console.log(result.visitorId);
};
export const hasHttps = () => {
return window.location.protocol === 'https:';
};
export const subRoute = process.env.NEXT_PUBLIC_BASE_URL;
export const getWebReqUrl = (url: string = '') => {

View File

@@ -1,8 +1,6 @@
import { useTranslation } from 'next-i18next';
import { useToast } from './useToast';
import { useCallback } from 'react';
import { hasHttps } from '../common/system/utils';
import { isProduction } from '@fastgpt/global/common/system/constants';
import MyModal from '../components/common/MyModal';
import React from 'react';
import { Box, ModalBody } from '@chakra-ui/react';
@@ -26,7 +24,7 @@ export const useCopyData = () => {
data = data.trim();
try {
if ((hasHttps() || !isProduction) && navigator.clipboard) {
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(data);
if (title) {
toast({
@@ -36,13 +34,35 @@ export const useCopyData = () => {
});
}
} else {
throw new Error('');
let textArea = document.createElement('textarea');
textArea.value = data;
// 使text area不在viewport同时设置不可见
textArea.style.position = 'absolute';
// @ts-ignore
textArea.style.opacity = 0;
textArea.style.left = '-999999px';
textArea.style.top = '-999999px';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
await new Promise((res, rej) => {
document.execCommand('copy') ? res('') : rej();
textArea.remove();
}).then(() => {
if (title) {
toast({
title,
status: 'success',
duration
});
}
});
}
} catch (error) {
setCopyContent(data);
}
},
[t, toast]
[setCopyContent, t, toast]
);
return {

View File

@@ -941,6 +941,7 @@
"pay_corporate_payment": "Payment to the public",
"pay_money": "Amount payable",
"pay_success": "Payment successfully",
"pay_year_tip": "Pay 10 months, enjoy 1 year!",
"permission.Collaborator": "Collaborator",
"permission.Default permission": "Default Permission",
"permission.Manage": "Manage",
@@ -1144,7 +1145,7 @@
"support.wallet.subscription.Next plan": "Future Package",
"support.wallet.subscription.Stand plan level": "Subscription Package",
"support.wallet.subscription.Sub plan": "Subscription Package",
"support.wallet.subscription.Sub plan tip": "Free to use {{title}} or upgrade to a higher package",
"support.wallet.subscription.Sub plan tip": "Free to use [{{title}}] or upgrade to a higher package",
"support.wallet.subscription.Team plan and usage": "Package and Usage",
"support.wallet.subscription.Training weight": "Training Priority: {{weight}}",
"support.wallet.subscription.Update extra ai points": "Extra AI Points",
@@ -1159,7 +1160,6 @@
"support.wallet.subscription.function.Points": "{{amount}} AI Points",
"support.wallet.subscription.mode.Month": "Month",
"support.wallet.subscription.mode.Period": "Subscription Period",
"support.wallet.subscription.mode.Ten Year": "Pay 10 months, imagine 1 year!",
"support.wallet.subscription.mode.Year": "Year",
"support.wallet.subscription.mode.Year sale": "Two Months Free",
"support.wallet.subscription.point": "Points",

View File

@@ -940,6 +940,7 @@
"pay_corporate_payment": "对公支付",
"pay_money": "应付金额",
"pay_success": "支付成功",
"pay_year_tip": "支付 10 个月,畅享 1 年!",
"permission.Collaborator": "协作者",
"permission.Default permission": "默认权限",
"permission.Manage": "管理",
@@ -1143,7 +1144,7 @@
"support.wallet.subscription.Next plan": "未来套餐",
"support.wallet.subscription.Stand plan level": "订阅套餐",
"support.wallet.subscription.Sub plan": "订阅套餐",
"support.wallet.subscription.Sub plan tip": "免费使用 {{title}} 或升级更高的套餐",
"support.wallet.subscription.Sub plan tip": "免费使用{{title}}或升级更高的套餐",
"support.wallet.subscription.Team plan and usage": "套餐与用量",
"support.wallet.subscription.Training weight": "训练优先级:{{weight}}",
"support.wallet.subscription.Update extra ai points": "额外 AI 积分",
@@ -1158,7 +1159,6 @@
"support.wallet.subscription.function.Points": "{{amount}} AI 积分",
"support.wallet.subscription.mode.Month": "按月",
"support.wallet.subscription.mode.Period": "订阅周期",
"support.wallet.subscription.mode.Ten Year": "支付10个月畅想1年",
"support.wallet.subscription.mode.Year": "按年",
"support.wallet.subscription.mode.Year sale": "赠送两个月",
"support.wallet.subscription.point": "积分",

View File

@@ -940,6 +940,7 @@
"pay_corporate_payment": "對公支付",
"pay_money": "應付金額",
"pay_success": "支付成功",
"pay_year_tip": "支付 10 個月,暢享 1 年!",
"permission.Collaborator": "協作者",
"permission.Default permission": "預設權限",
"permission.Manage": "管理",
@@ -1143,7 +1144,7 @@
"support.wallet.subscription.Next plan": "未來方案",
"support.wallet.subscription.Stand plan level": "訂閱方案",
"support.wallet.subscription.Sub plan": "訂閱方案",
"support.wallet.subscription.Sub plan tip": "免費使用 {{title}} 或升級更進階的方案",
"support.wallet.subscription.Sub plan tip": "免費使用{{title}}或升級更進階的方案",
"support.wallet.subscription.Team plan and usage": "方案與使用量",
"support.wallet.subscription.Training weight": "訓練優先權:{{weight}}",
"support.wallet.subscription.Update extra ai points": "額外 AI 點數",
@@ -1158,7 +1159,6 @@
"support.wallet.subscription.function.Points": "{{amount}} AI 點數",
"support.wallet.subscription.mode.Month": "按月",
"support.wallet.subscription.mode.Period": "訂閱週期",
"support.wallet.subscription.mode.Ten Year": "支付10個月暢想1年",
"support.wallet.subscription.mode.Year": "按年",
"support.wallet.subscription.mode.Year sale": "贈送兩個月",
"support.wallet.subscription.point": "點數",

View File

@@ -60,6 +60,11 @@ export type InitChatResponse = {
export type GetHistoriesProps = OutLinkChatAuthProps & {
appId?: string;
source?: `${ChatSourceEnum}`;
startCreateTime?: string;
endCreateTime?: string;
startUpdateTime?: string;
endUpdateTime?: string;
};
export type UpdateHistoryProps = OutLinkChatAuthProps & {

View File

@@ -89,7 +89,7 @@ const Standard = ({
mb={2}
mr={'-2'}
>
{t('common:support.wallet.subscription.mode.Ten Year')}
{t('common:pay_year_tip')}
</Box>
<RowTabs
list={[
@@ -110,7 +110,7 @@ const Standard = ({
onChange={(e) => setSelectSubMode(e as `${SubModeEnum}`)}
/>
</Box>
<MyIcon name={'price/pricearrow'} mt={'10px'} ml={'3px'} />
<MyIcon name={'price/pricearrow'} mt={'10px'} ml={'6px'} />
</Flex>
{/* card */}

View File

@@ -20,7 +20,18 @@ async function handler(
req: ApiRequestProps<getHistoriesBody, getHistoriesQuery>,
_res: ApiResponseType<any>
): Promise<PaginationResponse<getHistoriesResponse>> {
const { appId, shareId, outLinkUid, teamId, teamToken, source } = req.body;
const {
appId,
shareId,
outLinkUid,
teamId,
teamToken,
source,
startCreateTime,
endCreateTime,
startUpdateTime,
endUpdateTime
} = req.body;
const { offset, pageSize } = parsePaginationRequest(req);
const match = await (async () => {
@@ -49,7 +60,7 @@ async function handler(
return {
tmbId,
appId,
source
...(source && { source })
};
}
})();
@@ -61,13 +72,29 @@ async function handler(
};
}
const timeMatch: Record<string, any> = {};
if (startCreateTime || endCreateTime) {
timeMatch.createTime = {
...(startCreateTime && { $gte: new Date(startCreateTime) }),
...(endCreateTime && { $lte: new Date(endCreateTime) })
};
}
if (startUpdateTime || endUpdateTime) {
timeMatch.updateTime = {
...(startUpdateTime && { $gte: new Date(startUpdateTime) }),
...(endUpdateTime && { $lte: new Date(endUpdateTime) })
};
}
const mergeMatch = { ...match, ...timeMatch };
const [data, total] = await Promise.all([
await MongoChat.find(match, 'chatId title top customTitle appId updateTime')
await MongoChat.find(mergeMatch, 'chatId title top customTitle appId updateTime')
.sort({ top: -1, updateTime: -1 })
.skip(offset)
.limit(pageSize)
.lean(),
MongoChat.countDocuments(match)
MongoChat.countDocuments(mergeMatch)
]);
return {