fix: dataset selector load error (#4243)
* fix: dataset selector load error * fix: path auth error * fix: plugin scroll * export chat log with contact (#4211) * export chat log with contact * fix --------- Co-authored-by: heheer <heheer@sealos.io>
This commit is contained in:
parent
70563d2bcb
commit
f9cecfd49a
@ -62,3 +62,4 @@ curl --location --request POST 'https://{{host}}/api/admin/initv491' \
|
|||||||
8. 修复 promp 模式工具调用,未判空思考链,导致 UI 错误展示。
|
8. 修复 promp 模式工具调用,未判空思考链,导致 UI 错误展示。
|
||||||
9. 编辑应用信息导致头像丢失。
|
9. 编辑应用信息导致头像丢失。
|
||||||
10. 分享链接标题会被刷新掉。
|
10. 分享链接标题会被刷新掉。
|
||||||
|
11. 计算 parentPath 时,存在鉴权失败清空。
|
||||||
|
|||||||
@ -1,3 +1,8 @@
|
|||||||
|
export type GetPathProps = {
|
||||||
|
sourceId?: ParentIdType;
|
||||||
|
type: 'current' | 'parent';
|
||||||
|
};
|
||||||
|
|
||||||
export type ParentTreePathItemType = {
|
export type ParentTreePathItemType = {
|
||||||
parentId: string;
|
parentId: string;
|
||||||
parentName: string;
|
parentName: string;
|
||||||
|
|||||||
@ -82,7 +82,7 @@
|
|||||||
"logs_chat_user": "user",
|
"logs_chat_user": "user",
|
||||||
"logs_empty": "No logs yet~",
|
"logs_empty": "No logs yet~",
|
||||||
"logs_export_confirm_tip": "There are a total of {{total}} dialogue records, confirm the export?",
|
"logs_export_confirm_tip": "There are a total of {{total}} dialogue records, confirm the export?",
|
||||||
"logs_export_title": "Time, source, user, title, total number of messages, user feedback, custom feedback, number of labeled answers, conversation details",
|
"logs_export_title": "Time, source, user, contact, title, total number of messages, user good feedback, user bad feedback, custom feedback, labeled answers, conversation details",
|
||||||
"logs_message_total": "Total Messages",
|
"logs_message_total": "Total Messages",
|
||||||
"logs_source": "source",
|
"logs_source": "source",
|
||||||
"logs_title": "Title",
|
"logs_title": "Title",
|
||||||
|
|||||||
@ -82,7 +82,7 @@
|
|||||||
"logs_chat_user": "使用者",
|
"logs_chat_user": "使用者",
|
||||||
"logs_empty": "还没有日志噢~",
|
"logs_empty": "还没有日志噢~",
|
||||||
"logs_export_confirm_tip": "当前共 {{total}} 条对话记录,确认导出?",
|
"logs_export_confirm_tip": "当前共 {{total}} 条对话记录,确认导出?",
|
||||||
"logs_export_title": "时间,来源,使用者,标题,消息总数,用户反馈,自定义反馈,标注答案数量,对话详情",
|
"logs_export_title": "时间,来源,使用者,联系方式,标题,消息总数,用户赞同反馈,用户反对反馈,自定义反馈,标注答案,对话详情",
|
||||||
"logs_message_total": "消息总数",
|
"logs_message_total": "消息总数",
|
||||||
"logs_source": "来源",
|
"logs_source": "来源",
|
||||||
"logs_title": "标题",
|
"logs_title": "标题",
|
||||||
|
|||||||
@ -82,7 +82,7 @@
|
|||||||
"logs_chat_user": "使用者",
|
"logs_chat_user": "使用者",
|
||||||
"logs_empty": "還沒有紀錄喔~",
|
"logs_empty": "還沒有紀錄喔~",
|
||||||
"logs_export_confirm_tip": "當前共 {{total}} 條對話記錄,確認導出?",
|
"logs_export_confirm_tip": "當前共 {{total}} 條對話記錄,確認導出?",
|
||||||
"logs_export_title": "時間,來源,使用者,標題,消息總數,用戶反饋,自定義反饋,標註答案數量,對話詳情",
|
"logs_export_title": "時間,來源,使用者,聯繫方式,標題,消息總數,用戶贊同反饋,用戶反對反饋,自定義反饋,標註答案,對話詳情",
|
||||||
"logs_message_total": "訊息總數",
|
"logs_message_total": "訊息總數",
|
||||||
"logs_source": "来源",
|
"logs_source": "来源",
|
||||||
"logs_title": "標題",
|
"logs_title": "標題",
|
||||||
|
|||||||
@ -40,26 +40,10 @@ export const DatasetSelectModal = ({
|
|||||||
const { paths, setParentId, datasets, isFetching } = useDatasetSelect();
|
const { paths, setParentId, datasets, isFetching } = useDatasetSelect();
|
||||||
const { Loading } = useLoading();
|
const { Loading } = useLoading();
|
||||||
|
|
||||||
const filterDatasets = useMemo(() => {
|
const unSelectedDatasets = useMemo(() => {
|
||||||
const selectedInDatasets = datasets.filter((item) =>
|
return datasets.filter(
|
||||||
selectedDatasets.some((dataset) => dataset.datasetId === item._id)
|
(item) => !selectedDatasets.some((dataset) => dataset.datasetId === item._id)
|
||||||
);
|
);
|
||||||
|
|
||||||
const selectedNotInDatasets = selectedDatasets
|
|
||||||
.filter((selected) => !datasets.some((dataset) => dataset._id === selected.datasetId))
|
|
||||||
.map((selected) => ({
|
|
||||||
_id: selected.datasetId,
|
|
||||||
avatar: selected.avatar,
|
|
||||||
name: selected.name,
|
|
||||||
vectorModel: selected.vectorModel
|
|
||||||
}));
|
|
||||||
|
|
||||||
return {
|
|
||||||
selected: [...selectedInDatasets, ...selectedNotInDatasets],
|
|
||||||
unSelected: datasets.filter(
|
|
||||||
(item) => !selectedDatasets.some((dataset) => dataset.datasetId === item._id)
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}, [datasets, selectedDatasets]);
|
}, [datasets, selectedDatasets]);
|
||||||
|
|
||||||
const activeVectorModel = selectedDatasets[0]?.vectorModel?.model;
|
const activeVectorModel = selectedDatasets[0]?.vectorModel?.model;
|
||||||
@ -82,11 +66,11 @@ export const DatasetSelectModal = ({
|
|||||||
]}
|
]}
|
||||||
gridGap={3}
|
gridGap={3}
|
||||||
>
|
>
|
||||||
{filterDatasets.selected.map((item) =>
|
{selectedDatasets.map((item) =>
|
||||||
(() => {
|
(() => {
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
key={item._id}
|
key={item.datasetId}
|
||||||
p={3}
|
p={3}
|
||||||
border={theme.borders.base}
|
border={theme.borders.base}
|
||||||
boxShadow={'sm'}
|
boxShadow={'sm'}
|
||||||
@ -104,7 +88,7 @@ export const DatasetSelectModal = ({
|
|||||||
_hover={{ color: 'red.500' }}
|
_hover={{ color: 'red.500' }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedDatasets((state) =>
|
setSelectedDatasets((state) =>
|
||||||
state.filter((dataset) => dataset.datasetId !== item._id)
|
state.filter((dataset) => dataset.datasetId !== item.datasetId)
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -115,7 +99,7 @@ export const DatasetSelectModal = ({
|
|||||||
)}
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{filterDatasets.selected.length > 0 && <Divider my={3} />}
|
{selectedDatasets.length > 0 && <Divider my={3} />}
|
||||||
|
|
||||||
<Grid
|
<Grid
|
||||||
gridTemplateColumns={[
|
gridTemplateColumns={[
|
||||||
@ -125,7 +109,7 @@ export const DatasetSelectModal = ({
|
|||||||
]}
|
]}
|
||||||
gridGap={3}
|
gridGap={3}
|
||||||
>
|
>
|
||||||
{filterDatasets.unSelected.map((item) =>
|
{unSelectedDatasets.map((item) =>
|
||||||
(() => {
|
(() => {
|
||||||
return (
|
return (
|
||||||
<MyTooltip
|
<MyTooltip
|
||||||
@ -203,9 +187,7 @@ export const DatasetSelectModal = ({
|
|||||||
})()
|
})()
|
||||||
)}
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
{filterDatasets.unSelected.length === 0 && (
|
{unSelectedDatasets.length === 0 && <EmptyTip text={t('common:common.folder.empty')} />}
|
||||||
<EmptyTip text={t('common:common.folder.empty')} />
|
|
||||||
)}
|
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import { useTranslation } from 'next-i18next';
|
|||||||
import { Box } from '@chakra-ui/react';
|
import { Box } from '@chakra-ui/react';
|
||||||
import ParentPaths from '@/components/common/ParentPaths';
|
import ParentPaths from '@/components/common/ParentPaths';
|
||||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
|
|
||||||
type PathItemType = {
|
type PathItemType = {
|
||||||
parentId: string;
|
parentId: string;
|
||||||
@ -70,8 +71,16 @@ const DatasetSelectContainer = ({
|
|||||||
export function useDatasetSelect() {
|
export function useDatasetSelect() {
|
||||||
const [parentId, setParentId] = useState<string>('');
|
const [parentId, setParentId] = useState<string>('');
|
||||||
|
|
||||||
const { data, isFetching } = useQuery(['loadDatasetData', parentId], () =>
|
const { data, loading: isFetching } = useRequest2(
|
||||||
Promise.all([getDatasets({ parentId }), getDatasetPaths(parentId)])
|
() =>
|
||||||
|
Promise.all([
|
||||||
|
getDatasets({ parentId }),
|
||||||
|
getDatasetPaths({ sourceId: parentId, type: 'current' })
|
||||||
|
]),
|
||||||
|
{
|
||||||
|
manual: false,
|
||||||
|
refreshDeps: [parentId]
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const paths = useMemo(() => [...(data?.[1] || [])], [data]);
|
const paths = useMemo(() => [...(data?.[1] || [])], [data]);
|
||||||
|
|||||||
@ -61,10 +61,13 @@ const Header = ({
|
|||||||
|
|
||||||
const { lastAppListRouteType } = useSystemStore();
|
const { lastAppListRouteType } = useSystemStore();
|
||||||
|
|
||||||
const { data: paths = [] } = useRequest2(() => getAppFolderPath(appId), {
|
const { data: paths = [] } = useRequest2(
|
||||||
manual: false,
|
() => getAppFolderPath({ sourceId: appId, type: 'parent' }),
|
||||||
refreshDeps: [appId]
|
{
|
||||||
});
|
manual: false,
|
||||||
|
refreshDeps: [appId]
|
||||||
|
}
|
||||||
|
);
|
||||||
const onClickRoute = useCallback(
|
const onClickRoute = useCallback(
|
||||||
(parentId: string) => {
|
(parentId: string) => {
|
||||||
router.push({
|
router.push({
|
||||||
|
|||||||
@ -112,8 +112,9 @@ const ToolSelectModal = ({ onClose, ...props }: Props & { onClose: () => void })
|
|||||||
|
|
||||||
const { data: paths = [] } = useRequest2(
|
const { data: paths = [] } = useRequest2(
|
||||||
() => {
|
() => {
|
||||||
if (templateType === TemplateTypeEnum.teamPlugin) return getAppFolderPath(parentId);
|
if (templateType === TemplateTypeEnum.teamPlugin)
|
||||||
return getSystemPluginPaths(parentId);
|
return getAppFolderPath({ sourceId: parentId, type: 'current' });
|
||||||
|
return getSystemPluginPaths({ sourceId: parentId, type: 'current' });
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
manual: false,
|
manual: false,
|
||||||
@ -186,7 +187,7 @@ const ToolSelectModal = ({ onClose, ...props }: Props & { onClose: () => void })
|
|||||||
{/* route components */}
|
{/* route components */}
|
||||||
{!searchKey && parentId && (
|
{!searchKey && parentId && (
|
||||||
<Flex mt={2} px={[3, 6]}>
|
<Flex mt={2} px={[3, 6]}>
|
||||||
<FolderPath paths={paths} FirstPathDom={null} onClick={() => onUpdateParentId(null)} />
|
<FolderPath paths={paths} FirstPathDom={null} onClick={onUpdateParentId} />
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
<MyBox isLoading={isLoading} mt={2} px={[3, 6]} pb={3} flex={'1 0 0'} overflowY={'auto'}>
|
<MyBox isLoading={isLoading} mt={2} px={[3, 6]} pb={3} flex={'1 0 0'} overflowY={'auto'}>
|
||||||
|
|||||||
@ -144,7 +144,7 @@ const ChatTest = ({ isOpen, nodes = [], edges = [], onClose }: Props) => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Flex flex={'1 0 0'} alignItems={'end'}>
|
<Flex flex={'1 0 0'} alignItems={'end'} h={'100%'}>
|
||||||
<Box flex={'1 0 0'} h={'100%'} overflow={'auto'}>
|
<Box flex={'1 0 0'} h={'100%'} overflow={'auto'}>
|
||||||
<ChatContainer />
|
<ChatContainer />
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -276,8 +276,9 @@ const RenderHeader = React.memo(function RenderHeader({
|
|||||||
// Get paths
|
// Get paths
|
||||||
const { data: paths = [] } = useRequest2(
|
const { data: paths = [] } = useRequest2(
|
||||||
() => {
|
() => {
|
||||||
if (templateType === TemplateTypeEnum.teamPlugin) return getAppFolderPath(parentId);
|
if (templateType === TemplateTypeEnum.teamPlugin)
|
||||||
return getSystemPluginPaths(parentId);
|
return getAppFolderPath({ sourceId: parentId, type: 'current' });
|
||||||
|
return getSystemPluginPaths({ sourceId: parentId, type: 'current' });
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
manual: false,
|
manual: false,
|
||||||
|
|||||||
@ -126,7 +126,7 @@ export const useChatTest = ({
|
|||||||
|
|
||||||
const CustomChatContainer = useMemoizedFn(() =>
|
const CustomChatContainer = useMemoizedFn(() =>
|
||||||
appDetail.type === AppTypeEnum.plugin ? (
|
appDetail.type === AppTypeEnum.plugin ? (
|
||||||
<Box p={5}>
|
<Box p={5} pb={16}>
|
||||||
<PluginRunBox
|
<PluginRunBox
|
||||||
appId={appId}
|
appId={appId}
|
||||||
chatId={chatId}
|
chatId={chatId}
|
||||||
|
|||||||
@ -90,7 +90,7 @@ const AppListContextProvider = ({ children }: { children: ReactNode }) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const { data: paths = [], runAsync: refetchPaths } = useRequest2(
|
const { data: paths = [], runAsync: refetchPaths } = useRequest2(
|
||||||
() => getAppFolderPath(parentId),
|
() => getAppFolderPath({ sourceId: parentId, type: 'current' }),
|
||||||
{
|
{
|
||||||
manual: false,
|
manual: false,
|
||||||
refreshDeps: [parentId]
|
refreshDeps: [parentId]
|
||||||
|
|||||||
@ -18,6 +18,10 @@ import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSc
|
|||||||
import { ChatItemValueTypeEnum, ChatSourceEnum } from '@fastgpt/global/core/chat/constants';
|
import { ChatItemValueTypeEnum, ChatSourceEnum } from '@fastgpt/global/core/chat/constants';
|
||||||
import { AIChatItemValueItemType } from '@fastgpt/global/core/chat/type';
|
import { AIChatItemValueItemType } from '@fastgpt/global/core/chat/type';
|
||||||
|
|
||||||
|
const formatJsonString = (data: any) => {
|
||||||
|
return JSON.stringify(data).replace(/"/g, '""').replace(/\n/g, '\\n');
|
||||||
|
};
|
||||||
|
|
||||||
export type ExportChatLogsBody = GetAppChatLogsProps & {
|
export type ExportChatLogsBody = GetAppChatLogsProps & {
|
||||||
title: string;
|
title: string;
|
||||||
sourcesMap: Record<string, { label: string }>;
|
sourcesMap: Record<string, { label: string }>;
|
||||||
@ -40,7 +44,30 @@ async function handler(req: ApiRequestProps<ExportChatLogsBody, {}>, res: NextAp
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { teamId } = await authApp({ req, authToken: true, appId, per: WritePermissionVal });
|
const { teamId } = await authApp({ req, authToken: true, appId, per: WritePermissionVal });
|
||||||
const teamMembers = await MongoTeamMember.find({ teamId });
|
|
||||||
|
const teamMemberWithContact = await MongoTeamMember.aggregate([
|
||||||
|
{ $match: { teamId: new Types.ObjectId(teamId) } },
|
||||||
|
{
|
||||||
|
$lookup: {
|
||||||
|
from: 'users',
|
||||||
|
localField: 'userId',
|
||||||
|
foreignField: '_id',
|
||||||
|
as: 'user'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$project: {
|
||||||
|
memberId: '$_id',
|
||||||
|
teamId: 1,
|
||||||
|
userId: 1,
|
||||||
|
name: 1,
|
||||||
|
role: 1,
|
||||||
|
status: 1,
|
||||||
|
contact: { $ifNull: [{ $arrayElemAt: ['$user.contact', 0] }, '-'] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
console.log(teamMemberWithContact);
|
||||||
|
|
||||||
const where = {
|
const where = {
|
||||||
teamId: new Types.ObjectId(teamId),
|
teamId: new Types.ObjectId(teamId),
|
||||||
@ -104,40 +131,32 @@ async function handler(req: ApiRequestProps<ExportChatLogsBody, {}>, res: NextAp
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
$addFields: {
|
$addFields: {
|
||||||
userGoodFeedbackCount: {
|
userGoodFeedbackItems: {
|
||||||
$size: {
|
$filter: {
|
||||||
$filter: {
|
input: '$chatitems',
|
||||||
input: '$chatitems',
|
as: 'item',
|
||||||
as: 'item',
|
cond: { $ifNull: ['$$item.userGoodFeedback', false] }
|
||||||
cond: { $ifNull: ['$$item.userGoodFeedback', false] }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
userBadFeedbackCount: {
|
userBadFeedbackItems: {
|
||||||
$size: {
|
$filter: {
|
||||||
$filter: {
|
input: '$chatitems',
|
||||||
input: '$chatitems',
|
as: 'item',
|
||||||
as: 'item',
|
cond: { $ifNull: ['$$item.userBadFeedback', false] }
|
||||||
cond: { $ifNull: ['$$item.userBadFeedback', false] }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
customFeedbacksCount: {
|
customFeedbackItems: {
|
||||||
$size: {
|
$filter: {
|
||||||
$filter: {
|
input: '$chatitems',
|
||||||
input: '$chatitems',
|
as: 'item',
|
||||||
as: 'item',
|
cond: { $gt: [{ $size: { $ifNull: ['$$item.customFeedbacks', []] } }, 0] }
|
||||||
cond: { $gt: [{ $size: { $ifNull: ['$$item.customFeedbacks', []] } }, 0] }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
markCount: {
|
markItems: {
|
||||||
$size: {
|
$filter: {
|
||||||
$filter: {
|
input: '$chatitems',
|
||||||
input: '$chatitems',
|
as: 'item',
|
||||||
as: 'item',
|
cond: { $ifNull: ['$$item.adminFeedback', false] }
|
||||||
cond: { $ifNull: ['$$item.adminFeedback', false] }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
chatDetails: {
|
chatDetails: {
|
||||||
@ -161,10 +180,10 @@ async function handler(req: ApiRequestProps<ExportChatLogsBody, {}>, res: NextAp
|
|||||||
source: 1,
|
source: 1,
|
||||||
time: '$updateTime',
|
time: '$updateTime',
|
||||||
messageCount: { $size: '$chatitems' },
|
messageCount: { $size: '$chatitems' },
|
||||||
userGoodFeedbackCount: 1,
|
userGoodFeedbackItems: 1,
|
||||||
userBadFeedbackCount: 1,
|
userBadFeedbackItems: 1,
|
||||||
customFeedbacksCount: 1,
|
customFeedbackItems: 1,
|
||||||
markCount: 1,
|
markItems: 1,
|
||||||
outLinkUid: 1,
|
outLinkUid: 1,
|
||||||
tmbId: 1,
|
tmbId: 1,
|
||||||
chatDetails: 1
|
chatDetails: 1
|
||||||
@ -187,14 +206,18 @@ async function handler(req: ApiRequestProps<ExportChatLogsBody, {}>, res: NextAp
|
|||||||
const time = dayjs(doc.time.toISOString()).format('YYYY-MM-DD HH:mm:ss');
|
const time = dayjs(doc.time.toISOString()).format('YYYY-MM-DD HH:mm:ss');
|
||||||
const source = sourcesMap[doc.source as ChatSourceEnum]?.label || doc.source;
|
const source = sourcesMap[doc.source as ChatSourceEnum]?.label || doc.source;
|
||||||
const title = doc.customTitle || doc.title;
|
const title = doc.customTitle || doc.title;
|
||||||
const tmb = doc.outLinkUid
|
const tmbName = doc.outLinkUid
|
||||||
? doc.outLinkUid
|
? doc.outLinkUid
|
||||||
: teamMembers.find((member) => String(member._id) === String(doc.tmbId))?.name;
|
: teamMemberWithContact.find((member) => String(member.memberId) === String(doc.tmbId))?.name;
|
||||||
|
const tmbContact = teamMemberWithContact.find(
|
||||||
|
(member) => String(member.memberId) === String(doc.tmbId)
|
||||||
|
)?.contact;
|
||||||
|
|
||||||
const messageCount = doc.messageCount;
|
const messageCount = doc.messageCount;
|
||||||
const userFeedbackCount = doc.userGoodFeedbackCount || doc.userBadFeedbackCount || '-';
|
const userGoodFeedbackItems = doc.userGoodFeedbackItems || [];
|
||||||
const customFeedbacksCount = doc.customFeedbacksCount || '-';
|
const userBadFeedbackItems = doc.userBadFeedbackItems || [];
|
||||||
const markCount = doc.markCount;
|
const customFeedbackItems = doc.customFeedbackItems || [];
|
||||||
|
const markItems = doc.markItems || [];
|
||||||
const chatDetails = doc.chatDetails.map(
|
const chatDetails = doc.chatDetails.map(
|
||||||
(chat: { id: string; value: AIChatItemValueItemType[] }) => {
|
(chat: { id: string; value: AIChatItemValueItemType[] }) => {
|
||||||
return chat.value.map((item) => {
|
return chat.value.map((item) => {
|
||||||
@ -228,9 +251,14 @@ async function handler(req: ApiRequestProps<ExportChatLogsBody, {}>, res: NextAp
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
let chatDetailsStr = JSON.stringify(chatDetails).replace(/"/g, '""').replace(/\n/g, '\\n');
|
|
||||||
|
|
||||||
const res = `\n"${time}","${source}","${tmb}","${title}","${messageCount}","${userFeedbackCount}","${customFeedbacksCount}","${markCount}","${chatDetailsStr}"`;
|
const userGoodFeedbackItemsStr = formatJsonString(userGoodFeedbackItems);
|
||||||
|
const userBadFeedbackItemsStr = formatJsonString(userBadFeedbackItems);
|
||||||
|
const customFeedbackItemsStr = formatJsonString(customFeedbackItems);
|
||||||
|
const markItemsStr = formatJsonString(markItems);
|
||||||
|
const chatDetailsStr = formatJsonString(chatDetails);
|
||||||
|
|
||||||
|
const res = `\n"${time}","${source}","${tmbName}","${tmbContact}","${title}","${messageCount}","${userGoodFeedbackItemsStr}","${userBadFeedbackItemsStr}","${customFeedbackItemsStr}","${markItemsStr}","${chatDetailsStr}"`;
|
||||||
|
|
||||||
write(res);
|
write(res);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import type {
|
import type {
|
||||||
|
GetPathProps,
|
||||||
ParentIdType,
|
ParentIdType,
|
||||||
ParentTreePathItemType
|
ParentTreePathItemType
|
||||||
} from '@fastgpt/global/common/parentFolder/type.d';
|
} from '@fastgpt/global/common/parentFolder/type.d';
|
||||||
@ -12,15 +13,15 @@ async function handler(
|
|||||||
req: NextApiRequest,
|
req: NextApiRequest,
|
||||||
res: NextApiResponse<any>
|
res: NextApiResponse<any>
|
||||||
): Promise<ParentTreePathItemType[]> {
|
): Promise<ParentTreePathItemType[]> {
|
||||||
const { parentId } = req.query as { parentId: string };
|
const { sourceId: appId, type } = req.query as GetPathProps;
|
||||||
|
|
||||||
if (!parentId) {
|
if (!appId) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
await authApp({ req, authToken: true, appId: parentId, per: ReadPermissionVal });
|
const { app } = await authApp({ req, authToken: true, appId, per: ReadPermissionVal });
|
||||||
|
|
||||||
return await getParents(parentId);
|
return await getParents(type === 'current' ? appId : app.parentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default NextAPI(handler);
|
export default NextAPI(handler);
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
|
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
|
||||||
import { NextAPI } from '@/service/middleware/entry';
|
import { NextAPI } from '@/service/middleware/entry';
|
||||||
import { ParentIdType, ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type';
|
import { GetPathProps, ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type';
|
||||||
import { getSystemPlugins } from '@/service/core/app/plugin';
|
import { getSystemPlugins } from '@/service/core/app/plugin';
|
||||||
|
|
||||||
export type pathQuery = {
|
export type pathQuery = GetPathProps;
|
||||||
parentId: ParentIdType;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type pathBody = {};
|
export type pathBody = {};
|
||||||
|
|
||||||
@ -15,18 +13,18 @@ async function handler(
|
|||||||
req: ApiRequestProps<pathBody, pathQuery>,
|
req: ApiRequestProps<pathBody, pathQuery>,
|
||||||
res: ApiResponseType<any>
|
res: ApiResponseType<any>
|
||||||
): Promise<pathResponse> {
|
): Promise<pathResponse> {
|
||||||
const { parentId } = req.query;
|
const { sourceId: pluginId, type } = req.query;
|
||||||
|
|
||||||
if (!parentId) return [];
|
if (!pluginId) return [];
|
||||||
|
|
||||||
const plugins = await getSystemPlugins();
|
const plugins = await getSystemPlugins();
|
||||||
const plugin = plugins.find((item) => item.id === parentId);
|
const plugin = plugins.find((item) => item.id === pluginId);
|
||||||
|
|
||||||
if (!plugin) return [];
|
if (!plugin) return [];
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
parentId: plugin.id,
|
parentId: type === 'current' ? plugin.id : plugin.parentId,
|
||||||
parentName: plugin.name
|
parentName: plugin.name
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@ -1,20 +1,28 @@
|
|||||||
import type { NextApiRequest } from 'next';
|
import type { NextApiRequest } from 'next';
|
||||||
import { MongoDataset } from '@fastgpt/service/core/dataset/schema';
|
import { MongoDataset } from '@fastgpt/service/core/dataset/schema';
|
||||||
import type { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type.d';
|
import type {
|
||||||
|
GetPathProps,
|
||||||
|
ParentTreePathItemType
|
||||||
|
} from '@fastgpt/global/common/parentFolder/type.d';
|
||||||
import { authDataset } from '@fastgpt/service/support/permission/dataset/auth';
|
import { authDataset } from '@fastgpt/service/support/permission/dataset/auth';
|
||||||
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||||
import { NextAPI } from '@/service/middleware/entry';
|
import { NextAPI } from '@/service/middleware/entry';
|
||||||
|
|
||||||
async function handler(req: NextApiRequest) {
|
async function handler(req: NextApiRequest) {
|
||||||
const { parentId } = req.query as { parentId: string };
|
const { sourceId: datasetId, type } = req.query as GetPathProps;
|
||||||
|
|
||||||
if (!parentId) {
|
if (!datasetId) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
await authDataset({ req, authToken: true, datasetId: parentId, per: ReadPermissionVal });
|
const { dataset } = await authDataset({
|
||||||
|
req,
|
||||||
|
authToken: true,
|
||||||
|
datasetId,
|
||||||
|
per: ReadPermissionVal
|
||||||
|
});
|
||||||
|
|
||||||
return await getParents(parentId);
|
return await getParents(type === 'current' ? dataset._id : dataset.parentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getParents(parentId?: string): Promise<ParentTreePathItemType[]> {
|
async function getParents(parentId?: string): Promise<ParentTreePathItemType[]> {
|
||||||
|
|||||||
@ -97,10 +97,10 @@ function DatasetContextProvider({ children }: { children: React.ReactNode }) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const { data: paths = [], runAsync: refetchPaths } = useRequest2(
|
const { data: paths = [], runAsync: refetchPaths } = useRequest2(
|
||||||
() => getDatasetPaths(parentId),
|
async () => getDatasetPaths({ sourceId: parentId, type: 'current' }),
|
||||||
{
|
{
|
||||||
manual: false,
|
manual: false,
|
||||||
refreshDeps: [parentId]
|
refreshDeps: [folderDetail]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import { DELETE, GET, POST } from '@/web/common/api/request';
|
import { DELETE, GET, POST } from '@/web/common/api/request';
|
||||||
import type { CreateAppFolderBody } from '@/pages/api/core/app/folder/create';
|
import type { CreateAppFolderBody } from '@/pages/api/core/app/folder/create';
|
||||||
import type { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type';
|
import type {
|
||||||
import type { ParentIdType } from '@fastgpt/global/common/parentFolder/type';
|
GetPathProps,
|
||||||
|
ParentTreePathItemType
|
||||||
|
} from '@fastgpt/global/common/parentFolder/type';
|
||||||
import type {
|
import type {
|
||||||
transitionWorkflowBody,
|
transitionWorkflowBody,
|
||||||
transitionWorkflowResponse
|
transitionWorkflowResponse
|
||||||
@ -12,10 +14,10 @@ import type { copyAppQuery, copyAppResponse } from '@/pages/api/core/app/copy';
|
|||||||
export const postCreateAppFolder = (data: CreateAppFolderBody) =>
|
export const postCreateAppFolder = (data: CreateAppFolderBody) =>
|
||||||
POST('/core/app/folder/create', data);
|
POST('/core/app/folder/create', data);
|
||||||
|
|
||||||
export const getAppFolderPath = (parentId: ParentIdType) => {
|
export const getAppFolderPath = (data: GetPathProps) => {
|
||||||
if (!parentId) return Promise.resolve<ParentTreePathItemType[]>([]);
|
if (!data.sourceId) return Promise.resolve<ParentTreePathItemType[]>([]);
|
||||||
|
|
||||||
return GET<ParentTreePathItemType[]>(`/core/app/folder/path`, { parentId });
|
return GET<ParentTreePathItemType[]>(`/core/app/folder/path`, data);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* detail */
|
/* detail */
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import { FlowNodeTemplateTypeEnum } from '@fastgpt/global/core/workflow/constant
|
|||||||
import type { GetPreviewNodeQuery } from '@/pages/api/core/app/plugin/getPreviewNode';
|
import type { GetPreviewNodeQuery } from '@/pages/api/core/app/plugin/getPreviewNode';
|
||||||
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
||||||
import type {
|
import type {
|
||||||
|
GetPathProps,
|
||||||
ParentIdType,
|
ParentIdType,
|
||||||
ParentTreePathItemType
|
ParentTreePathItemType
|
||||||
} from '@fastgpt/global/common/parentFolder/type';
|
} from '@fastgpt/global/common/parentFolder/type';
|
||||||
@ -53,9 +54,9 @@ export const getPluginGroups = () => {
|
|||||||
: Promise.resolve([defaultGroup]);
|
: Promise.resolve([defaultGroup]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSystemPluginPaths = (parentId: ParentIdType) => {
|
export const getSystemPluginPaths = (data: GetPathProps) => {
|
||||||
if (!parentId) return Promise.resolve<ParentTreePathItemType[]>([]);
|
if (!data.sourceId) return Promise.resolve<ParentTreePathItemType[]>([]);
|
||||||
return GET<ParentTreePathItemType[]>('/core/app/plugin/path', { parentId });
|
return GET<ParentTreePathItemType[]>('/core/app/plugin/path', data);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getPreviewPluginNode = (data: GetPreviewNodeQuery) =>
|
export const getPreviewPluginNode = (data: GetPreviewNodeQuery) =>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { GET, POST, PUT, DELETE } from '@/web/common/api/request';
|
import { GET, POST, PUT, DELETE } from '@/web/common/api/request';
|
||||||
import type {
|
import type {
|
||||||
|
GetPathProps,
|
||||||
ParentIdType,
|
ParentIdType,
|
||||||
ParentTreePathItemType
|
ParentTreePathItemType
|
||||||
} from '@fastgpt/global/common/parentFolder/type.d';
|
} from '@fastgpt/global/common/parentFolder/type.d';
|
||||||
@ -77,8 +78,10 @@ export const getDatasetsByAppIdAndDatasetIds = (data: { appId: string; datasetId
|
|||||||
* get type=dataset list
|
* get type=dataset list
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const getDatasetPaths = (parentId: ParentIdType) =>
|
export const getDatasetPaths = (data: GetPathProps) => {
|
||||||
GET<ParentTreePathItemType[]>('/core/dataset/paths', { parentId });
|
if (!data.sourceId) return Promise.resolve([]);
|
||||||
|
return GET<ParentTreePathItemType[]>('/core/dataset/paths', data);
|
||||||
|
};
|
||||||
|
|
||||||
export const getDatasetById = (id: string) => GET<DatasetItemType>(`/core/dataset/detail?id=${id}`);
|
export const getDatasetById = (id: string) => GET<DatasetItemType>(`/core/dataset/detail?id=${id}`);
|
||||||
|
|
||||||
|
|||||||
@ -250,7 +250,10 @@ export const DatasetPageContextProvider = ({
|
|||||||
|
|
||||||
const { data: paths = [], runAsync: refetchPaths } = useRequest2(
|
const { data: paths = [], runAsync: refetchPaths } = useRequest2(
|
||||||
() =>
|
() =>
|
||||||
getDatasetPaths(datasetDetail.parentId).then((res) => {
|
getDatasetPaths({
|
||||||
|
sourceId: datasetDetail?._id,
|
||||||
|
type: 'parent'
|
||||||
|
}).then((res) => {
|
||||||
res.push({
|
res.push({
|
||||||
parentId: '',
|
parentId: '',
|
||||||
parentName: datasetDetail.name
|
parentName: datasetDetail.name
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user