mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-29 09:44:47 +00:00
4.6.4 (#588)
This commit is contained in:
@@ -7,7 +7,8 @@ import {
|
||||
useTheme,
|
||||
Divider,
|
||||
Select,
|
||||
Input
|
||||
Input,
|
||||
Link
|
||||
} from '@chakra-ui/react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { UserUpdateParams } from '@/types/user';
|
||||
@@ -249,32 +250,52 @@ const UserInfo = () => {
|
||||
</Flex>
|
||||
</Box>
|
||||
{feConfigs?.docUrl && (
|
||||
<>
|
||||
<Flex
|
||||
mt={4}
|
||||
w={['85%', '300px']}
|
||||
py={3}
|
||||
px={6}
|
||||
border={theme.borders.sm}
|
||||
borderWidth={'1.5px'}
|
||||
borderRadius={'md'}
|
||||
alignItems={'center'}
|
||||
cursor={'pointer'}
|
||||
userSelect={'none'}
|
||||
onClick={() => {
|
||||
window.open(getDocPath('/docs/intro'));
|
||||
}}
|
||||
>
|
||||
<MyIcon name={'common/courseLight'} w={'18px'} />
|
||||
<Box ml={2} flex={1}>
|
||||
{t('system.Help Document')}
|
||||
</Box>
|
||||
<Box w={'8px'} h={'8px'} borderRadius={'50%'} bg={'#67c13b'} />
|
||||
<Box fontSize={'md'} ml={2}>
|
||||
V{systemVersion}
|
||||
</Box>
|
||||
</Flex>
|
||||
</>
|
||||
<Link
|
||||
href={getDocPath('/docs/intro')}
|
||||
target="_blank"
|
||||
display={'flex'}
|
||||
mt={4}
|
||||
w={['85%', '300px']}
|
||||
py={3}
|
||||
px={6}
|
||||
border={theme.borders.sm}
|
||||
borderWidth={'1.5px'}
|
||||
borderRadius={'md'}
|
||||
alignItems={'center'}
|
||||
userSelect={'none'}
|
||||
textDecoration={'none !important'}
|
||||
>
|
||||
<MyIcon name={'common/courseLight'} w={'18px'} />
|
||||
<Box ml={2} flex={1}>
|
||||
{t('system.Help Document')}
|
||||
</Box>
|
||||
<Box w={'8px'} h={'8px'} borderRadius={'50%'} bg={'#67c13b'} />
|
||||
<Box fontSize={'md'} ml={2}>
|
||||
V{systemVersion}
|
||||
</Box>
|
||||
</Link>
|
||||
)}
|
||||
{feConfigs?.chatbotUrl && (
|
||||
<Link
|
||||
href={feConfigs.chatbotUrl}
|
||||
target="_blank"
|
||||
display={'flex'}
|
||||
mt={4}
|
||||
w={['85%', '300px']}
|
||||
py={3}
|
||||
px={6}
|
||||
border={theme.borders.sm}
|
||||
borderWidth={'1.5px'}
|
||||
borderRadius={'md'}
|
||||
alignItems={'center'}
|
||||
userSelect={'none'}
|
||||
textDecoration={'none !important'}
|
||||
>
|
||||
<MyIcon name={'core/app/aiLight'} w={'18px'} />
|
||||
<Box ml={2} flex={1}>
|
||||
{t('common.system.Help Chatbot')}
|
||||
</Box>
|
||||
</Link>
|
||||
)}
|
||||
{feConfigs?.show_openai_account && (
|
||||
<>
|
||||
@@ -283,7 +304,7 @@ const UserInfo = () => {
|
||||
<MyTooltip label={'点击配置账号'}>
|
||||
<Flex
|
||||
w={['85%', '300px']}
|
||||
py={3}
|
||||
py={4}
|
||||
px={6}
|
||||
border={theme.borders.sm}
|
||||
borderWidth={'1.5px'}
|
||||
|
45
projects/app/src/pages/api/admin/init464.ts
Normal file
45
projects/app/src/pages/api/admin/init464.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@fastgpt/service/common/response';
|
||||
|
||||
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
||||
import { PgClient } from '@fastgpt/service/common/pg';
|
||||
import { PgDatasetTableName } from '@fastgpt/global/core/dataset/constant';
|
||||
import { MongoChatItem } from '@fastgpt/service/core/chat/chatItemSchema';
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
try {
|
||||
const { limit = 50, maxSize = 3 } = req.body as { limit: number; maxSize: number };
|
||||
await authCert({ req, authRoot: true });
|
||||
await connectToDatabase();
|
||||
|
||||
try {
|
||||
await PgClient.query(
|
||||
`ALTER TABLE ${PgDatasetTableName} ADD COLUMN createTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP;`
|
||||
);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await MongoChatItem.updateMany(
|
||||
{ userFeedback: { $exists: true } },
|
||||
{ $rename: { userFeedback: 'userBadFeedback' } }
|
||||
);
|
||||
console.log(result);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
jsonRes(res, {
|
||||
data: {}
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
||||
jsonRes(res, {
|
||||
code: 500,
|
||||
error
|
||||
});
|
||||
}
|
||||
}
|
@@ -6,7 +6,7 @@ import {
|
||||
delFileByFileIdList,
|
||||
getGFSCollection
|
||||
} from '@fastgpt/service/common/file/gridfs/controller';
|
||||
import { addLog } from '@fastgpt/service/common/mongo/controller';
|
||||
import { addLog } from '@fastgpt/service/common/system/log';
|
||||
import { MongoDatasetCollection } from '@fastgpt/service/core/dataset/collection/schema';
|
||||
import { delay } from '@fastgpt/global/common/system/utils';
|
||||
|
||||
|
@@ -379,14 +379,14 @@ function datasetTemplate({
|
||||
},
|
||||
{
|
||||
key: 'similarity',
|
||||
value: 0.4,
|
||||
value: 0.1,
|
||||
type: FlowNodeInputTypeEnum.slider,
|
||||
label: '相关度',
|
||||
connected: true
|
||||
},
|
||||
{
|
||||
key: 'limit',
|
||||
value: 8,
|
||||
value: 2000,
|
||||
type: FlowNodeInputTypeEnum.slider,
|
||||
label: '单次搜索上限',
|
||||
connected: true
|
||||
|
@@ -60,12 +60,30 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
},
|
||||
{
|
||||
$addFields: {
|
||||
feedbackCount: {
|
||||
userGoodFeedbackCount: {
|
||||
$size: {
|
||||
$filter: {
|
||||
input: '$chatitems',
|
||||
as: 'item',
|
||||
cond: { $ifNull: ['$$item.userFeedback', false] }
|
||||
cond: { $ifNull: ['$$item.userGoodFeedback', false] }
|
||||
}
|
||||
}
|
||||
},
|
||||
userBadFeedbackCount: {
|
||||
$size: {
|
||||
$filter: {
|
||||
input: '$chatitems',
|
||||
as: 'item',
|
||||
cond: { $ifNull: ['$$item.userBadFeedback', false] }
|
||||
}
|
||||
}
|
||||
},
|
||||
robotBadFeedbackCount: {
|
||||
$size: {
|
||||
$filter: {
|
||||
input: '$chatitems',
|
||||
as: 'item',
|
||||
cond: { $ifNull: ['$$item.robotBadFeedback', false] }
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -80,7 +98,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
}
|
||||
}
|
||||
},
|
||||
{ $sort: { feedbackCount: -1, updateTime: -1 } },
|
||||
{
|
||||
$sort: {
|
||||
userBadFeedbackCount: -1,
|
||||
userGoodFeedbackCount: -1,
|
||||
robotBadFeedbackCount: -1,
|
||||
updateTime: -1
|
||||
}
|
||||
},
|
||||
{ $skip: (pageNum - 1) * pageSize },
|
||||
{ $limit: pageSize },
|
||||
{
|
||||
@@ -91,7 +116,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
source: 1,
|
||||
time: '$updateTime',
|
||||
messageCount: { $size: '$chatitems' },
|
||||
feedbackCount: 1,
|
||||
userGoodFeedbackCount: 1,
|
||||
userBadFeedbackCount: 1,
|
||||
robotBadFeedbackCount: 1,
|
||||
markCount: 1
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,52 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@fastgpt/service/common/response';
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
import { MongoChatItem } from '@fastgpt/service/core/chat/chatItemSchema';
|
||||
import { UpdateChatFeedbackProps } from '@fastgpt/global/core/chat/api';
|
||||
import { autChatCrud } from '@/service/support/permission/auth/chat';
|
||||
|
||||
/* 初始化我的聊天框,需要身份验证 */
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
const { chatId, chatItemId, shareId, outLinkUid, userBadFeedback, userGoodFeedback } =
|
||||
req.body as UpdateChatFeedbackProps;
|
||||
|
||||
try {
|
||||
await connectToDatabase();
|
||||
|
||||
await autChatCrud({
|
||||
req,
|
||||
authToken: true,
|
||||
chatId,
|
||||
shareId,
|
||||
outLinkUid,
|
||||
per: 'r'
|
||||
});
|
||||
|
||||
if (!chatItemId) {
|
||||
throw new Error('chatItemId is required');
|
||||
}
|
||||
|
||||
await MongoChatItem.findOneAndUpdate(
|
||||
{
|
||||
dataId: chatItemId
|
||||
},
|
||||
{
|
||||
$unset: {
|
||||
...(userBadFeedback === undefined && { userBadFeedback: '' }),
|
||||
...(userGoodFeedback === undefined && { userGoodFeedback: '' })
|
||||
},
|
||||
$set: {
|
||||
...(userBadFeedback !== undefined && { userBadFeedback }),
|
||||
...(userGoodFeedback !== undefined && { userGoodFeedback })
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
jsonRes(res);
|
||||
} catch (err) {
|
||||
jsonRes(res, {
|
||||
code: 500,
|
||||
error: err
|
||||
});
|
||||
}
|
||||
}
|
@@ -1,35 +0,0 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@fastgpt/service/common/response';
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
import { MongoChatItem } from '@fastgpt/service/core/chat/chatItemSchema';
|
||||
|
||||
/* 初始化我的聊天框,需要身份验证 */
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
try {
|
||||
await connectToDatabase();
|
||||
const { chatItemId, userFeedback = undefined } = req.body as {
|
||||
chatItemId: string;
|
||||
userFeedback?: string;
|
||||
};
|
||||
|
||||
if (!chatItemId) {
|
||||
throw new Error('chatItemId is required');
|
||||
}
|
||||
|
||||
await MongoChatItem.findOneAndUpdate(
|
||||
{
|
||||
dataId: chatItemId
|
||||
},
|
||||
{
|
||||
...(userFeedback ? { userFeedback } : { $unset: { userFeedback: '' } })
|
||||
}
|
||||
);
|
||||
|
||||
jsonRes(res);
|
||||
} catch (err) {
|
||||
jsonRes(res, {
|
||||
code: 500,
|
||||
error: err
|
||||
});
|
||||
}
|
||||
}
|
@@ -43,7 +43,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
const { history } = await getChatItems({
|
||||
chatId,
|
||||
limit: 30,
|
||||
field: `dataId obj value adminFeedback userFeedback ${ModuleOutputKeyEnum.responseData}`
|
||||
field: `dataId obj value adminFeedback userBadFeedback userGoodFeedback robotBadFeedback ${ModuleOutputKeyEnum.responseData}`
|
||||
});
|
||||
|
||||
jsonRes<InitChatResponse>(res, {
|
||||
|
@@ -42,7 +42,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
const { history } = await getChatItems({
|
||||
chatId,
|
||||
limit: 30,
|
||||
field: `dataId obj value userFeedback ${
|
||||
field: `dataId obj value userGoodFeedback userBadFeedback ${
|
||||
shareChat.responseDetail ? `adminFeedback ${ModuleOutputKeyEnum.responseData}` : ''
|
||||
} `
|
||||
});
|
||||
|
@@ -2,7 +2,7 @@ import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@fastgpt/service/common/response';
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
import { MongoUser } from '@fastgpt/service/support/user/schema';
|
||||
import { addLog } from '@fastgpt/service/common/mongo/controller';
|
||||
import { addLog } from '@fastgpt/service/common/system/log';
|
||||
import { authDataset } from '@fastgpt/service/support/permission/auth/dataset';
|
||||
import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
|
||||
import { findDatasetIdTreeByTopDatasetId } from '@fastgpt/service/core/dataset/controller';
|
||||
|
@@ -33,11 +33,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
||||
fileIds: collections.map((item) => item?.fileId || '').filter(Boolean)
|
||||
});
|
||||
|
||||
// delete collection
|
||||
await MongoDatasetCollection.deleteMany({
|
||||
_id: { $in: delIdList }
|
||||
});
|
||||
|
||||
jsonRes(res);
|
||||
} catch (err) {
|
||||
jsonRes(res, {
|
||||
|
@@ -68,13 +68,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
||||
});
|
||||
|
||||
// delete old collection
|
||||
await Promise.all([
|
||||
delCollectionRelevantData({
|
||||
collectionIds: [collection._id],
|
||||
fileIds: collection.fileId ? [collection.fileId] : []
|
||||
}),
|
||||
MongoDatasetCollection.findByIdAndRemove(collection._id)
|
||||
]);
|
||||
await delCollectionRelevantData({
|
||||
collectionIds: [collection._id],
|
||||
fileIds: collection.fileId ? [collection.fileId] : []
|
||||
});
|
||||
|
||||
jsonRes(res);
|
||||
} catch (err) {
|
||||
|
@@ -136,7 +136,7 @@ export async function pushDataToDatasetCollection({
|
||||
model,
|
||||
q: item.q,
|
||||
a: item.a,
|
||||
chunkIndex: i,
|
||||
chunkIndex: item.chunkIndex ?? i,
|
||||
indexes: item.indexes
|
||||
}))
|
||||
);
|
||||
|
@@ -2,7 +2,7 @@ import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes, responseWriteController } from '@fastgpt/service/common/response';
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
import { MongoUser } from '@fastgpt/service/support/user/schema';
|
||||
import { addLog } from '@fastgpt/service/common/mongo/controller';
|
||||
import { addLog } from '@fastgpt/service/common/system/log';
|
||||
import { authDataset } from '@fastgpt/service/support/permission/auth/dataset';
|
||||
import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
|
||||
import { findDatasetIdTreeByTopDatasetId } from '@fastgpt/service/core/dataset/controller';
|
||||
|
@@ -6,10 +6,8 @@ import { connectToDatabase } from '@/service/mongo';
|
||||
import { authDataset } from '@fastgpt/service/support/permission/auth/dataset';
|
||||
import { authTeamBalance } from '@/service/support/permission/auth/bill';
|
||||
import { pushGenerateVectorBill } from '@/service/support/wallet/bill/push';
|
||||
import { countModelPrice } from '@/service/support/wallet/bill/utils';
|
||||
import { searchDatasetData } from '@/service/core/dataset/data/pg';
|
||||
import { updateApiKeyUsage } from '@fastgpt/service/support/openapi/tools';
|
||||
import { ModelTypeEnum } from '@/service/core/ai/model';
|
||||
import { BillSourceEnum } from '@fastgpt/global/support/wallet/bill/constants';
|
||||
|
||||
export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
@@ -38,7 +36,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
|
||||
const { searchRes, tokenLen } = await searchDatasetData({
|
||||
text,
|
||||
model: dataset.vectorModel,
|
||||
limit: Math.min(limit, 50),
|
||||
limit: Math.min(limit * 800, 30000),
|
||||
datasetIds: [datasetId],
|
||||
searchMode
|
||||
});
|
||||
|
@@ -20,6 +20,7 @@ import {
|
||||
import { SimpleModeTemplate_FastGPT_Universal } from '@/global/core/app/constants';
|
||||
import { getSimpleTemplatesFromPlus } from '@/service/core/app/utils';
|
||||
import { PluginTypeEnum } from '@fastgpt/global/core/plugin/constants';
|
||||
import { getFastGPTFeConfig } from '@fastgpt/service/common/system/config/controller';
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
await getInitConfig();
|
||||
@@ -73,7 +74,17 @@ export async function getInitConfig() {
|
||||
process.env.NODE_ENV === 'development' ? 'data/config.local.json' : '/app/data/config.json';
|
||||
const res = JSON.parse(readFileSync(filename, 'utf-8')) as ConfigFileType;
|
||||
|
||||
setDefaultData(res);
|
||||
// get config from database
|
||||
const dbFeConfig = await getFastGPTFeConfig();
|
||||
const concatConfig: ConfigFileType = {
|
||||
...res,
|
||||
FeConfig: {
|
||||
...res.FeConfig,
|
||||
...dbFeConfig
|
||||
}
|
||||
};
|
||||
|
||||
setDefaultData(concatConfig);
|
||||
} catch (error) {
|
||||
setDefaultData();
|
||||
console.log('get init config error, set default', error);
|
||||
@@ -83,6 +94,23 @@ export async function getInitConfig() {
|
||||
getSystemVersion();
|
||||
getModelPrice();
|
||||
getSystemPlugin();
|
||||
|
||||
console.log({
|
||||
FeConfig: global.feConfigs,
|
||||
SystemParams: global.systemEnv,
|
||||
ChatModels: global.chatModels,
|
||||
QAModels: global.qaModels,
|
||||
CQModels: global.cqModels,
|
||||
ExtractModels: global.extractModels,
|
||||
QGModels: global.qgModels,
|
||||
VectorModels: global.vectorModels,
|
||||
ReRankModels: global.reRankModels,
|
||||
AudioSpeechModels: global.reRankModels,
|
||||
WhisperModel: global.whisperModel,
|
||||
price: global.priceMd,
|
||||
simpleModeTemplates: global.simpleModeTemplates,
|
||||
communityPlugins: global.communityPlugins
|
||||
});
|
||||
}
|
||||
|
||||
export function initGlobal() {
|
||||
@@ -125,8 +153,6 @@ export function setDefaultData(res?: ConfigFileType) {
|
||||
global.whisperModel = res?.WhisperModel || defaultWhisperModel;
|
||||
|
||||
global.priceMd = '';
|
||||
|
||||
console.log(res);
|
||||
}
|
||||
|
||||
export function getSystemVersion() {
|
||||
@@ -173,7 +199,6 @@ ${global.audioSpeechModels
|
||||
.join('\n')}
|
||||
${`| 语音输入-${global.whisperModel.name} | ${global.whisperModel.price}/分钟 |`}
|
||||
`;
|
||||
console.log(global.priceMd);
|
||||
}
|
||||
|
||||
async function getSimpleModeTemplates() {
|
||||
@@ -209,8 +234,6 @@ async function getSimpleModeTemplates() {
|
||||
} catch (error) {
|
||||
global.simpleModeTemplates = [SimpleModeTemplate_FastGPT_Universal];
|
||||
}
|
||||
console.log('simple mode templates: ');
|
||||
console.log(global.simpleModeTemplates);
|
||||
}
|
||||
|
||||
function getSystemPlugin() {
|
||||
@@ -236,6 +259,4 @@ function getSystemPlugin() {
|
||||
});
|
||||
|
||||
global.communityPlugins = fileTemplates;
|
||||
console.log('community plugins: ');
|
||||
console.log(fileTemplates);
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ import { createJWT, setCookie } from '@fastgpt/service/support/permission/contro
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
import { getUserDetail } from '@fastgpt/service/support/user/controller';
|
||||
import type { PostLoginProps } from '@fastgpt/global/support/user/api.d';
|
||||
import { UserStatusEnum } from '@fastgpt/global/support/user/constant';
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
try {
|
||||
@@ -16,13 +17,20 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
}
|
||||
|
||||
// 检测用户是否存在
|
||||
const authCert = await MongoUser.findOne({
|
||||
username
|
||||
});
|
||||
const authCert = await MongoUser.findOne(
|
||||
{
|
||||
username
|
||||
},
|
||||
'status'
|
||||
);
|
||||
if (!authCert) {
|
||||
throw new Error('用户未注册');
|
||||
}
|
||||
|
||||
if (authCert.status === UserStatusEnum.forbidden) {
|
||||
throw new Error('账号已停用,无法登录');
|
||||
}
|
||||
|
||||
const user = await MongoUser.findOne({
|
||||
username,
|
||||
password
|
||||
|
@@ -2,7 +2,7 @@ import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { authApp } from '@fastgpt/service/support/permission/auth/app';
|
||||
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
||||
import { sseErrRes, jsonRes } from '@fastgpt/service/common/response';
|
||||
import { addLog } from '@fastgpt/service/common/mongo/controller';
|
||||
import { addLog } from '@fastgpt/service/common/system/log';
|
||||
import { withNextCors } from '@fastgpt/service/common/middle/cors';
|
||||
import { ChatRoleEnum, ChatSourceEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import { sseResponseEventEnum } from '@fastgpt/service/common/response/constant';
|
||||
|
@@ -18,7 +18,8 @@ import { useTranslation } from 'next-i18next';
|
||||
import { usePagination } from '@/web/common/hooks/usePagination';
|
||||
import { getAppChatLogs } from '@/web/core/app/api';
|
||||
import dayjs from 'dayjs';
|
||||
import { ChatSourceMap, HUMAN_ICON } from '@fastgpt/global/core/chat/constants';
|
||||
import { ChatSourceMap } from '@fastgpt/global/core/chat/constants';
|
||||
import { HUMAN_ICON } from '@fastgpt/global/common/system/constants';
|
||||
import { AppLogsListItemType } from '@/types/app';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import ChatBox, { type ComponentRef } from '@/components/ChatBox';
|
||||
@@ -48,7 +49,8 @@ const Logs = ({ appId }: { appId: string }) => {
|
||||
data: logs,
|
||||
isLoading,
|
||||
Pagination,
|
||||
getData
|
||||
getData,
|
||||
pageNum
|
||||
} = usePagination<AppLogsListItemType>({
|
||||
api: getAppChatLogs,
|
||||
pageSize: 20,
|
||||
@@ -90,8 +92,7 @@ const Logs = ({ appId }: { appId: string }) => {
|
||||
<Table variant={'simple'} fontSize={'sm'}>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>{t('app.Logs Source')}</Th>
|
||||
<Th>{t('app.Logs Time')}</Th>
|
||||
<Th>{t('core.app.logs.Source And Time')}</Th>
|
||||
<Th>{t('app.Logs Title')}</Th>
|
||||
<Th>{t('app.Logs Message Total')}</Th>
|
||||
<Th>{t('app.Feedback Count')}</Th>
|
||||
@@ -107,35 +108,55 @@ const Logs = ({ appId }: { appId: string }) => {
|
||||
title={'点击查看对话详情'}
|
||||
onClick={() => setDetailLogsId(item.id)}
|
||||
>
|
||||
<Td>{t(ChatSourceMap[item.source]?.name || 'UnKnow')}</Td>
|
||||
<Td>{dayjs(item.time).format('YYYY/MM/DD HH:mm')}</Td>
|
||||
<Td>
|
||||
<Box>{t(ChatSourceMap[item.source]?.name || 'UnKnow')}</Box>
|
||||
<Box color={'myGray.500'}>{dayjs(item.time).format('YYYY/MM/DD HH:mm')}</Box>
|
||||
</Td>
|
||||
<Td className="textEllipsis" maxW={'250px'}>
|
||||
{item.title}
|
||||
</Td>
|
||||
<Td>{item.messageCount}</Td>
|
||||
<Td w={'100px'}>
|
||||
{!!item?.feedbackCount ? (
|
||||
<Box display={'inline-block'}>
|
||||
<Flex
|
||||
bg={'#FFF2EC'}
|
||||
{!!item?.userGoodFeedbackCount && (
|
||||
<Flex
|
||||
mb={item?.userGoodFeedbackCount ? 1 : 0}
|
||||
bg={'green.100'}
|
||||
color={'green.600'}
|
||||
px={3}
|
||||
py={1}
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
borderRadius={'lg'}
|
||||
fontWeight={'bold'}
|
||||
>
|
||||
<MyIcon
|
||||
mr={1}
|
||||
name={'core/chat/feedback/goodLight'}
|
||||
color={'green.600'}
|
||||
w={'14px'}
|
||||
/>
|
||||
{item.userGoodFeedbackCount}
|
||||
</Flex>
|
||||
)}
|
||||
{!!item?.userBadFeedbackCount && (
|
||||
<Flex
|
||||
bg={'#FFF2EC'}
|
||||
color={'#C96330'}
|
||||
px={3}
|
||||
py={1}
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
borderRadius={'lg'}
|
||||
fontWeight={'bold'}
|
||||
>
|
||||
<MyIcon
|
||||
mr={1}
|
||||
name={'core/chat/feedback/badLight'}
|
||||
color={'#C96330'}
|
||||
px={3}
|
||||
py={1}
|
||||
alignItems={'center'}
|
||||
borderRadius={'lg'}
|
||||
fontWeight={'bold'}
|
||||
>
|
||||
<MyIcon
|
||||
mr={1}
|
||||
name={'core/chat/feedback/badLight'}
|
||||
color={'#C96330'}
|
||||
w={'14px'}
|
||||
/>
|
||||
{item.feedbackCount}
|
||||
</Flex>
|
||||
</Box>
|
||||
) : (
|
||||
<>-</>
|
||||
w={'14px'}
|
||||
/>
|
||||
{item.userBadFeedbackCount}
|
||||
</Flex>
|
||||
)}
|
||||
</Td>
|
||||
<Td>{item.markCount}</Td>
|
||||
@@ -168,7 +189,10 @@ const Logs = ({ appId }: { appId: string }) => {
|
||||
<DetailLogsModal
|
||||
appId={appId}
|
||||
chatId={detailLogsId}
|
||||
onClose={() => setDetailLogsId(undefined)}
|
||||
onClose={() => {
|
||||
setDetailLogsId(undefined);
|
||||
getData(pageNum);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<MyModal
|
||||
@@ -297,6 +321,7 @@ function DetailLogsModal({
|
||||
showMarkIcon
|
||||
showVoiceIcon={false}
|
||||
userGuideModule={chat?.app?.userGuideModule}
|
||||
chatId={chatId}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
@@ -0,0 +1,9 @@
|
||||
import { OutLinkSchema } from '@fastgpt/global/support/outLink/type';
|
||||
import React from 'react';
|
||||
import MyModal from '@/components/MyModal';
|
||||
|
||||
const EmbModal = ({ share }: { share: OutLinkSchema }) => {
|
||||
return <MyModal isOpen>EmbModal</MyModal>;
|
||||
};
|
||||
|
||||
export default EmbModal;
|
@@ -91,11 +91,10 @@ const Share = ({ appId }: { appId: string }) => {
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>名称</Th>
|
||||
<Th>金额消耗(¥)</Th>
|
||||
<Th>金额消耗</Th>
|
||||
<Th>返回详情</Th>
|
||||
{feConfigs?.isPlus && (
|
||||
<>
|
||||
<Th>金额限制(¥)</Th>
|
||||
<Th>IP限流(人/分钟)</Th>
|
||||
<Th>过期时间</Th>
|
||||
<Th>身份校验</Th>
|
||||
@@ -109,13 +108,19 @@ const Share = ({ appId }: { appId: string }) => {
|
||||
{shareChatList.map((item) => (
|
||||
<Tr key={item._id}>
|
||||
<Td>{item.name}</Td>
|
||||
<Td>{formatPrice(item.total)}</Td>
|
||||
<Td>
|
||||
{formatPrice(item.total)}
|
||||
{feConfigs?.isPlus
|
||||
? `${
|
||||
item.limit && item.limit.credit > -1
|
||||
? ` / ${item.limit.credit}元`
|
||||
: ' / 无限制'
|
||||
}`
|
||||
: ''}
|
||||
</Td>
|
||||
<Td>{item.responseDetail ? '✔' : '✖'}</Td>
|
||||
{feConfigs?.isPlus && (
|
||||
<>
|
||||
<Td>
|
||||
{item.limit && item.limit.credit > -1 ? `${item.limit.credit}元` : '无限制'}
|
||||
</Td>
|
||||
<Td>{item?.limit?.QPM || '-'}</Td>
|
||||
<Td>
|
||||
{item?.limit?.expiredTime
|
||||
|
@@ -349,6 +349,7 @@ const Chat = ({ appId, chatId }: { appId: string; chatId: string }) => {
|
||||
onUpdateVariable={(e) => {}}
|
||||
onStartChat={startChat}
|
||||
onDelMessage={(e) => delOneHistoryItem({ ...e, chatId })}
|
||||
chatId={chatId}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
@@ -358,6 +358,9 @@ const OutLink = ({
|
||||
onUpdateVariable={(e) => {}}
|
||||
onStartChat={startChat}
|
||||
onDelMessage={(e) => delOneHistoryItem({ ...e, chatId, shareId, outLinkUid })}
|
||||
chatId={chatId}
|
||||
shareId={shareId}
|
||||
outLinkUid={outLinkUid}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
@@ -35,7 +35,7 @@ export type FileItemType = {
|
||||
id: string; // fileId / raw Link
|
||||
filename: string;
|
||||
chunks: PushDatasetDataChunkProps[];
|
||||
text: string; // raw text
|
||||
rawText: string; // raw text
|
||||
icon: string;
|
||||
tokens: number; // total tokens
|
||||
type: DatasetCollectionTypeEnum.file | DatasetCollectionTypeEnum.link;
|
||||
@@ -152,7 +152,7 @@ const FileSelect = ({
|
||||
filename: file.name,
|
||||
icon,
|
||||
tokens: filterData.reduce((sum, item) => sum + countPromptTokens(item.q), 0),
|
||||
text: `${header.join(',')}\n${data
|
||||
rawText: `${header.join(',')}\n${data
|
||||
.map((item) => `"${item[0]}","${item[1]}"`)
|
||||
.join('\n')}`,
|
||||
chunks: filterData,
|
||||
@@ -192,7 +192,7 @@ const FileSelect = ({
|
||||
id: nanoid(),
|
||||
filename: file.name,
|
||||
icon,
|
||||
text,
|
||||
rawText: text,
|
||||
tokens: splitRes.tokens,
|
||||
type: DatasetCollectionTypeEnum.file,
|
||||
fileId,
|
||||
@@ -228,7 +228,7 @@ const FileSelect = ({
|
||||
id: nanoid(),
|
||||
filename: url,
|
||||
icon: '/imgs/files/link.svg',
|
||||
text: content,
|
||||
rawText: content,
|
||||
tokens: splitRes.tokens,
|
||||
type: DatasetCollectionTypeEnum.link,
|
||||
rawLink: url,
|
||||
@@ -270,7 +270,7 @@ const FileSelect = ({
|
||||
id: nanoid(),
|
||||
filename,
|
||||
icon: '/imgs/files/txt.svg',
|
||||
text: content,
|
||||
rawText: content,
|
||||
tokens: splitRes.tokens,
|
||||
type: DatasetCollectionTypeEnum.file,
|
||||
fileId: fileIds[0],
|
||||
|
@@ -49,7 +49,7 @@ const ImportData = ({
|
||||
collectionTrainingType: DatasetCollectionTrainingModeEnum.chunk
|
||||
},
|
||||
[ImportTypeEnum.qa]: {
|
||||
defaultChunkLen: agentModel?.maxContext * 0.6 || 8000,
|
||||
defaultChunkLen: agentModel?.maxContext * 0.55 || 8000,
|
||||
chunkOverlapRatio: 0,
|
||||
unitPrice: agentModel?.price || 3,
|
||||
mode: TrainingModeEnum.qa,
|
||||
|
@@ -13,6 +13,7 @@ import { useRequest } from '@/web/common/hooks/useRequest';
|
||||
import { postDatasetCollection } from '@/web/core/dataset/api';
|
||||
import { formatPrice } from '@fastgpt/global/support/wallet/bill/tools';
|
||||
import { splitText2Chunks } from '@fastgpt/global/common/string/textSplitter';
|
||||
import { hashStr } from '@fastgpt/global/common/string/tools';
|
||||
import { useToast } from '@/web/common/hooks/useToast';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import {
|
||||
@@ -158,7 +159,9 @@ const Provider = ({
|
||||
fileId: file.fileId,
|
||||
rawLink: file.rawLink,
|
||||
chunkSize: chunkLen,
|
||||
trainingType: collectionTrainingType
|
||||
trainingType: collectionTrainingType,
|
||||
qaPrompt: mode === TrainingModeEnum.qa ? prompt : '',
|
||||
hashRawText: hashStr(file.rawText)
|
||||
});
|
||||
|
||||
// upload data
|
||||
@@ -193,7 +196,7 @@ const Provider = ({
|
||||
setFiles((state) =>
|
||||
state.map((file) => {
|
||||
const splitRes = splitText2Chunks({
|
||||
text: file.text,
|
||||
text: file.rawText,
|
||||
chunkLen,
|
||||
overlapRatio: chunkOverlapRatio
|
||||
});
|
||||
@@ -287,7 +290,7 @@ export const PreviewFileOrChunk = () => {
|
||||
px={[4, 8]}
|
||||
my={4}
|
||||
contentEditable
|
||||
dangerouslySetInnerHTML={{ __html: previewFile.text }}
|
||||
dangerouslySetInnerHTML={{ __html: previewFile.rawText }}
|
||||
fontSize={'sm'}
|
||||
whiteSpace={'pre-wrap'}
|
||||
wordBreak={'break-all'}
|
||||
|
@@ -1,11 +1,13 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import MyModal from '@/components/MyModal';
|
||||
import { Box, Button, Input, ModalBody, ModalFooter, Textarea } from '@chakra-ui/react';
|
||||
import { Box, Button, Input, Link, ModalBody, ModalFooter, Textarea } from '@chakra-ui/react';
|
||||
import { useRequest } from '@/web/common/hooks/useRequest';
|
||||
import { postFetchUrls } from '@/web/common/tools/api';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { UrlFetchResponse } from '@fastgpt/global/common/file/api.d';
|
||||
import { getDocPath } from '@/web/common/system/doc';
|
||||
import { feConfigs } from '@/web/common/system/staticData';
|
||||
|
||||
const UrlFetchModal = ({
|
||||
onClose,
|
||||
@@ -68,7 +70,12 @@ const UrlFetchModal = ({
|
||||
<Box mt={4}>
|
||||
<Box fontWeight={'bold'}>
|
||||
{t('core.dataset.website.Selector')}({t('common.choosable')})
|
||||
</Box>{' '}
|
||||
</Box>
|
||||
{feConfigs?.docUrl && (
|
||||
<Link href={getDocPath('/docs/course/websync/#选择器如何使用')} target="_blank">
|
||||
{t('core.dataset.website.Selector Course')}
|
||||
</Link>
|
||||
)}
|
||||
<Input {...register('selector')} placeholder="body .content #document" />
|
||||
</Box>
|
||||
</ModalBody>
|
||||
|
@@ -1,11 +1,13 @@
|
||||
import React from 'react';
|
||||
import MyModal from '@/components/MyModal';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { Box, Button, Input, ModalBody, ModalFooter } from '@chakra-ui/react';
|
||||
import { Box, Button, Input, Link, ModalBody, ModalFooter } from '@chakra-ui/react';
|
||||
import { strIsLink } from '@fastgpt/global/common/string/tools';
|
||||
import { useToast } from '@/web/common/hooks/useToast';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useConfirm } from '@/web/common/hooks/useConfirm';
|
||||
import { getDocPath } from '@/web/common/system/doc';
|
||||
import { feConfigs } from '@/web/common/system/staticData';
|
||||
|
||||
type FormType = {
|
||||
url?: string | undefined;
|
||||
@@ -49,6 +51,16 @@ const WebsiteConfigModal = ({
|
||||
<ModalBody>
|
||||
<Box fontSize={'sm'} color={'myGray.600'}>
|
||||
{t('core.dataset.website.Config Description')}
|
||||
{feConfigs?.docUrl && (
|
||||
<Link
|
||||
href={getDocPath('/docs/course/websync')}
|
||||
target="_blank"
|
||||
textDecoration={'underline'}
|
||||
fontWeight={'bold'}
|
||||
>
|
||||
{t('common.course.Read Course')}
|
||||
</Link>
|
||||
)}
|
||||
</Box>
|
||||
<Box mt={2}>
|
||||
<Box>{t('core.dataset.website.Base Url')}</Box>
|
||||
|
Reference in New Issue
Block a user