mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-08-14 15:35:54 +08:00
Fix: In order to distinguish the keys of a pair of messages, add a prefix to the id when rendering the message. #4409 (#4451)
### What problem does this PR solve? Fix: In order to distinguish the keys of a pair of messages, add a prefix to the id when rendering the message. #4409 ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
parent
95261f17f6
commit
2c7ba90cb4
@ -2,7 +2,6 @@ import { useDeleteMessage, useFeedback } from '@/hooks/chat-hooks';
|
|||||||
import { useSetModalState } from '@/hooks/common-hooks';
|
import { useSetModalState } from '@/hooks/common-hooks';
|
||||||
import { IRemoveMessageById, useSpeechWithSse } from '@/hooks/logic-hooks';
|
import { IRemoveMessageById, useSpeechWithSse } from '@/hooks/logic-hooks';
|
||||||
import { IFeedbackRequestBody } from '@/interfaces/request/chat';
|
import { IFeedbackRequestBody } from '@/interfaces/request/chat';
|
||||||
import { getMessagePureId } from '@/utils/chat';
|
|
||||||
import { hexStringToUint8Array } from '@/utils/common-util';
|
import { hexStringToUint8Array } from '@/utils/common-util';
|
||||||
import { SpeechPlayer } from 'openai-speech-stream-player';
|
import { SpeechPlayer } from 'openai-speech-stream-player';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
@ -15,7 +14,7 @@ export const useSendFeedback = (messageId: string) => {
|
|||||||
async (params: IFeedbackRequestBody) => {
|
async (params: IFeedbackRequestBody) => {
|
||||||
const ret = await feedback({
|
const ret = await feedback({
|
||||||
...params,
|
...params,
|
||||||
messageId: getMessagePureId(messageId),
|
messageId: messageId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ret === 0) {
|
if (ret === 0) {
|
||||||
@ -41,9 +40,8 @@ export const useRemoveMessage = (
|
|||||||
const { deleteMessage, loading } = useDeleteMessage();
|
const { deleteMessage, loading } = useDeleteMessage();
|
||||||
|
|
||||||
const onRemoveMessage = useCallback(async () => {
|
const onRemoveMessage = useCallback(async () => {
|
||||||
const pureId = getMessagePureId(messageId);
|
if (messageId) {
|
||||||
if (pureId) {
|
const code = await deleteMessage(messageId);
|
||||||
const code = await deleteMessage(pureId);
|
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
removeMessageById?.(messageId);
|
removeMessageById?.(messageId);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
|||||||
import { IClientConversation, IMessage } from '@/pages/chat/interface';
|
import { IClientConversation, IMessage } from '@/pages/chat/interface';
|
||||||
import api from '@/utils/api';
|
import api from '@/utils/api';
|
||||||
import { getAuthorization } from '@/utils/authorization-util';
|
import { getAuthorization } from '@/utils/authorization-util';
|
||||||
import { buildMessageUuid, getMessagePureId } from '@/utils/chat';
|
import { buildMessageUuid } from '@/utils/chat';
|
||||||
import { PaginationProps, message } from 'antd';
|
import { PaginationProps, message } from 'antd';
|
||||||
import { FormInstance } from 'antd/lib';
|
import { FormInstance } from 'antd/lib';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
@ -309,7 +309,9 @@ export const useSelectDerivedMessages = () => {
|
|||||||
...pre,
|
...pre,
|
||||||
{
|
{
|
||||||
...message,
|
...message,
|
||||||
id: buildMessageUuid(message),
|
id: buildMessageUuid(message), // The message id is generated on the front end,
|
||||||
|
// and the message id returned by the back end is the same as the question id,
|
||||||
|
// so that the pair of messages can be deleted together when deleting the message
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: MessageType.Assistant,
|
role: MessageType.Assistant,
|
||||||
@ -353,10 +355,7 @@ export const useSelectDerivedMessages = () => {
|
|||||||
const removeMessageById = useCallback(
|
const removeMessageById = useCallback(
|
||||||
(messageId: string) => {
|
(messageId: string) => {
|
||||||
setDerivedMessages((pre) => {
|
setDerivedMessages((pre) => {
|
||||||
const nextMessages =
|
const nextMessages = pre?.filter((x) => x.id !== messageId) ?? [];
|
||||||
pre?.filter(
|
|
||||||
(x) => getMessagePureId(x.id) !== getMessagePureId(messageId),
|
|
||||||
) ?? [];
|
|
||||||
return nextMessages;
|
return nextMessages;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
useGetChatSearchParams,
|
useGetChatSearchParams,
|
||||||
} from '@/hooks/chat-hooks';
|
} from '@/hooks/chat-hooks';
|
||||||
import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
|
import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
|
||||||
|
import { buildMessageUuidWithRole } from '@/utils/chat';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
@ -64,7 +65,7 @@ const ChatContainer = ({ controller }: IProps) => {
|
|||||||
sendLoading &&
|
sendLoading &&
|
||||||
derivedMessages.length - 1 === i
|
derivedMessages.length - 1 === i
|
||||||
}
|
}
|
||||||
key={message.id}
|
key={buildMessageUuidWithRole(message)}
|
||||||
item={message}
|
item={message}
|
||||||
nickname={userInfo.nickname}
|
nickname={userInfo.nickname}
|
||||||
avatar={userInfo.avatar}
|
avatar={userInfo.avatar}
|
||||||
|
@ -14,6 +14,7 @@ import { buildMessageItemReference } from '../utils';
|
|||||||
import PdfDrawer from '@/components/pdf-drawer';
|
import PdfDrawer from '@/components/pdf-drawer';
|
||||||
import { useFetchNextConversationSSE } from '@/hooks/chat-hooks';
|
import { useFetchNextConversationSSE } from '@/hooks/chat-hooks';
|
||||||
import { useFetchFlowSSE } from '@/hooks/flow-hooks';
|
import { useFetchFlowSSE } from '@/hooks/flow-hooks';
|
||||||
|
import { buildMessageUuidWithRole } from '@/utils/chat';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
const ChatContainer = () => {
|
const ChatContainer = () => {
|
||||||
@ -54,7 +55,7 @@ const ChatContainer = () => {
|
|||||||
{derivedMessages?.map((message, i) => {
|
{derivedMessages?.map((message, i) => {
|
||||||
return (
|
return (
|
||||||
<MessageItem
|
<MessageItem
|
||||||
key={message.id}
|
key={buildMessageUuidWithRole(message)}
|
||||||
avatardialog={avatarData?.avatar}
|
avatardialog={avatarData?.avatar}
|
||||||
item={message}
|
item={message}
|
||||||
nickname="You"
|
nickname="You"
|
||||||
|
@ -11,6 +11,7 @@ import PdfDrawer from '@/components/pdf-drawer';
|
|||||||
import { useClickDrawer } from '@/components/pdf-drawer/hooks';
|
import { useClickDrawer } from '@/components/pdf-drawer/hooks';
|
||||||
import { useFetchFlow } from '@/hooks/flow-hooks';
|
import { useFetchFlow } from '@/hooks/flow-hooks';
|
||||||
import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
|
import { useFetchUserInfo } from '@/hooks/user-setting-hooks';
|
||||||
|
import { buildMessageUuidWithRole } from '@/utils/chat';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
const FlowChatBox = () => {
|
const FlowChatBox = () => {
|
||||||
@ -46,7 +47,7 @@ const FlowChatBox = () => {
|
|||||||
sendLoading &&
|
sendLoading &&
|
||||||
derivedMessages.length - 1 === i
|
derivedMessages.length - 1 === i
|
||||||
}
|
}
|
||||||
key={message.id}
|
key={buildMessageUuidWithRole(message)}
|
||||||
nickname={userInfo.nickname}
|
nickname={userInfo.nickname}
|
||||||
avatar={userInfo.avatar}
|
avatar={userInfo.avatar}
|
||||||
avatardialog={cavasInfo.avatar}
|
avatardialog={cavasInfo.avatar}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { EmptyConversationId, MessageType } from '@/constants/chat';
|
import { EmptyConversationId } from '@/constants/chat';
|
||||||
import { Message } from '@/interfaces/database/chat';
|
import { Message } from '@/interfaces/database/chat';
|
||||||
import { IMessage } from '@/pages/chat/interface';
|
import { IMessage } from '@/pages/chat/interface';
|
||||||
import { omit } from 'lodash';
|
import { omit } from 'lodash';
|
||||||
@ -10,21 +10,11 @@ export const isConversationIdExist = (conversationId: string) => {
|
|||||||
|
|
||||||
export const buildMessageUuid = (message: Partial<Message | IMessage>) => {
|
export const buildMessageUuid = (message: Partial<Message | IMessage>) => {
|
||||||
if ('id' in message && message.id) {
|
if ('id' in message && message.id) {
|
||||||
return message.role === MessageType.User
|
return message.id;
|
||||||
? `${MessageType.User}_${message.id}`
|
|
||||||
: `${MessageType.Assistant}_${message.id}`;
|
|
||||||
}
|
}
|
||||||
return uuid();
|
return uuid();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getMessagePureId = (id?: string) => {
|
|
||||||
const strings = id?.split('_') ?? [];
|
|
||||||
if (strings.length > 0) {
|
|
||||||
return strings.at(-1);
|
|
||||||
}
|
|
||||||
return id;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const buildMessageListWithUuid = (messages?: Message[]) => {
|
export const buildMessageListWithUuid = (messages?: Message[]) => {
|
||||||
return (
|
return (
|
||||||
messages?.map((x: Message | IMessage) => ({
|
messages?.map((x: Message | IMessage) => ({
|
||||||
@ -37,3 +27,10 @@ export const buildMessageListWithUuid = (messages?: Message[]) => {
|
|||||||
export const getConversationId = () => {
|
export const getConversationId = () => {
|
||||||
return uuid().replace(/-/g, '');
|
return uuid().replace(/-/g, '');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// When rendering each message, add a prefix to the id to ensure uniqueness.
|
||||||
|
export const buildMessageUuidWithRole = (
|
||||||
|
message: Partial<Message | IMessage>,
|
||||||
|
) => {
|
||||||
|
return `${message.role}_${message.id}`;
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user