diff --git a/shared/cache/cache.ts b/shared/cache/cache.ts index edd0381b..d01e14fb 100644 --- a/shared/cache/cache.ts +++ b/shared/cache/cache.ts @@ -1,3 +1,4 @@ +import { ChatConverseInfo, fetchConverseInfo } from '../model/converse'; import { fetchUserInfo, UserBaseInfo } from '../model/user'; import { queryClient } from './index'; @@ -18,3 +19,8 @@ export const getCachedUserInfo = buildCacheFactory( 'user', fetchUserInfo ); + +export const getCachedConverseInfo = buildCacheFactory( + 'converse', + fetchConverseInfo +); diff --git a/shared/index.tsx b/shared/index.tsx index 9fa1a23b..48ac81fa 100644 --- a/shared/index.tsx +++ b/shared/index.tsx @@ -60,6 +60,7 @@ export { // redux export { useAppSelector, useAppDispatch } from './redux/hooks/useAppSelector'; +export { useConverseMessage } from './redux/hooks/useConverseMessage'; export { userActions } from './redux/slices'; export { setupRedux } from './redux/setup'; export { createStore } from './redux/store'; diff --git a/shared/model/converse.ts b/shared/model/converse.ts index ae78c525..f6784211 100644 --- a/shared/model/converse.ts +++ b/shared/model/converse.ts @@ -20,3 +20,19 @@ export async function createDMConverse( return data; } + +/** + * 获取会话信息 + * @param converseId 会话ID + */ +export async function fetchConverseInfo( + converseId: string +): Promise { + const { data } = await request.get('/api/chat/converse/findConverseInfo', { + params: { + converseId, + }, + }); + + return data; +} diff --git a/shared/model/message.ts b/shared/model/message.ts new file mode 100644 index 00000000..cdbf91f9 --- /dev/null +++ b/shared/model/message.ts @@ -0,0 +1,36 @@ +import { request } from '../api/request'; + +export interface ChatMessage { + _id: string; + + content: string; + + author?: string; + + groupId?: string; + + converseId: string; + + createdAt?: string; + + updatedAt?: string; +} + +/** + * 获取会话消息 + * @param converseId 会话ID + * @param startId 开始ID + */ +export async function fetchConverseMessage( + converseId: string, + startId?: string +): Promise { + const { data } = await request.get('/api/chat/message/fetchConverseMessage', { + params: { + converseId, + startId, + }, + }); + + return data; +} diff --git a/shared/redux/hooks/useConverseMessage.ts b/shared/redux/hooks/useConverseMessage.ts new file mode 100644 index 00000000..8eb54c26 --- /dev/null +++ b/shared/redux/hooks/useConverseMessage.ts @@ -0,0 +1,31 @@ +import { getCachedConverseInfo } from '../../cache/cache'; +import { useAsync } from '../../hooks/useAsync'; +import { fetchConverseMessage } from '../../model/message'; +import { chatActions } from '../slices'; +import { useAppDispatch, useAppSelector } from './useAppSelector'; + +/** + * 会话消息管理 + */ +export function useConverseMessage(converseId: string) { + const converse = useAppSelector((state) => state.chat.converses[converseId]); + const dispatch = useAppDispatch(); + const messages = converse?.messages ?? []; + + const { loading, error } = useAsync(async () => { + if (!converse) { + const converse = await getCachedConverseInfo(converseId); + dispatch(chatActions.setConverseInfo(converse)); + + const messages = await fetchConverseMessage(converseId); + dispatch( + chatActions.appendConverseMessage({ + converseId, + messages, + }) + ); + } + }, [converse, converseId]); + + return { messages, loading, error }; +} diff --git a/web/src/components/AlertErrorView.tsx b/web/src/components/AlertErrorView.tsx new file mode 100644 index 00000000..06184ac1 --- /dev/null +++ b/web/src/components/AlertErrorView.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { Alert } from 'antd'; + +/** + * 用于接口错误显示的组件 + */ +export const AlertErrorView: React.FC<{ + error: Error; +}> = React.memo((props) => { + return ( + + ); +}); +AlertErrorView.displayName = 'AlertErrorView'; diff --git a/web/src/components/ChatBox/index.tsx b/web/src/components/ChatBox/index.tsx index 9bf2ed28..49a1f4ae 100644 --- a/web/src/components/ChatBox/index.tsx +++ b/web/src/components/ChatBox/index.tsx @@ -1,5 +1,7 @@ import { Skeleton } from 'antd'; import React from 'react'; +import { useConverseMessage } from 'pawchat-shared'; +import { AlertErrorView } from '../AlertErrorView'; const ChatBoxPlaceholder: React.FC = React.memo(() => { return ( @@ -19,11 +21,19 @@ const ChatBoxPlaceholder: React.FC = React.memo(() => { }); ChatBoxPlaceholder.displayName = 'ChatBoxPlaceholder'; -export const ChatBox: React.FC = React.memo(() => { - return ( - <> - - - ); +export const ChatBox: React.FC<{ + converseId: string; +}> = React.memo((props) => { + const { messages, loading, error } = useConverseMessage(props.converseId); + + if (loading) { + return ; + } + + if (error) { + return ; + } + + return
消息数据: {JSON.stringify(messages)}
; }); ChatBox.displayName = 'ChatBox'; diff --git a/web/src/routes/Main/Content/Personal/Converse/index.tsx b/web/src/routes/Main/Content/Personal/Converse/index.tsx index b875333b..4fc97ebe 100644 --- a/web/src/routes/Main/Content/Personal/Converse/index.tsx +++ b/web/src/routes/Main/Content/Personal/Converse/index.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { useParams } from 'react-router'; interface UserConversePanelParams { - converseUUID: string; + converseId: string; } export const ConversePanel: React.FC = React.memo(() => { @@ -11,8 +11,7 @@ export const ConversePanel: React.FC = React.memo(() => { return (
-
{params.converseUUID}
- +
); }); diff --git a/web/src/routes/Main/Content/Personal/index.tsx b/web/src/routes/Main/Content/Personal/index.tsx index 86b02b99..3e2e65bc 100644 --- a/web/src/routes/Main/Content/Personal/index.tsx +++ b/web/src/routes/Main/Content/Personal/index.tsx @@ -15,7 +15,7 @@ export const Personal: React.FC = React.memo(() => {