feat: 咨询消息轮询优化 — Web 自动刷新 + 患者端聊天详情页
Web 端: - ConsultationDetail 添加 10s 自动轮询新消息(after_id 增量拉取) - consultations API 补充 after_id 参数 小程序患者端: - 新增 consultation service 消息 API(listMessages/sendMessage/markSessionRead) - 新增聊天详情页(8s 轮询 + 发送消息 + 自动标记已读) - 咨询列表页点击跳转详情页(替换"即将上线"占位)
This commit is contained in:
@@ -86,7 +86,7 @@ export const consultationApi = {
|
||||
|
||||
listMessages: async (
|
||||
sessionId: string,
|
||||
params: { page?: number; page_size?: number },
|
||||
params: { page?: number; page_size?: number; after_id?: string },
|
||||
) => {
|
||||
const { data } = await client.get<{
|
||||
success: boolean;
|
||||
|
||||
@@ -9,6 +9,7 @@ import { useThemeMode } from '../../hooks/useThemeMode';
|
||||
import { AuthButton } from '../../components/AuthButton';
|
||||
|
||||
const PAGE_SIZE = 30;
|
||||
const POLL_INTERVAL = 10_000;
|
||||
|
||||
function formatTime(value: string): string {
|
||||
return new Date(value).toLocaleString('zh-CN', {
|
||||
@@ -54,6 +55,7 @@ export default function ConsultationDetail() {
|
||||
|
||||
const chatEndRef = useRef<HTMLDivElement>(null);
|
||||
const shouldScrollRef = useRef(true);
|
||||
const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
||||
|
||||
const isDark = useThemeMode();
|
||||
|
||||
@@ -103,6 +105,39 @@ export default function ConsultationDetail() {
|
||||
fetchMessages(1, false);
|
||||
}, [fetchSession, fetchMessages]);
|
||||
|
||||
// Poll new messages while session is active
|
||||
useEffect(() => {
|
||||
if (!session || session.status === 'closed') return;
|
||||
|
||||
const stopPolling = () => {
|
||||
if (pollRef.current) {
|
||||
clearInterval(pollRef.current);
|
||||
pollRef.current = null;
|
||||
}
|
||||
};
|
||||
|
||||
stopPolling();
|
||||
pollRef.current = setInterval(async () => {
|
||||
if (!sessionId) return;
|
||||
try {
|
||||
const lastId = messages.length > 0 ? messages[messages.length - 1].id : undefined;
|
||||
const result = await consultationApi.listMessages(sessionId, {
|
||||
page: 1,
|
||||
page_size: 50,
|
||||
after_id: lastId,
|
||||
});
|
||||
if (result.data.length > 0) {
|
||||
setMessages((prev) => [...prev, ...result.data]);
|
||||
shouldScrollRef.current = true;
|
||||
}
|
||||
} catch {
|
||||
// silent
|
||||
}
|
||||
}, POLL_INTERVAL);
|
||||
|
||||
return stopPolling;
|
||||
}, [session?.status, sessionId, messages.length]);
|
||||
|
||||
// Auto-scroll to bottom on new messages
|
||||
useEffect(() => {
|
||||
if (shouldScrollRef.current && chatEndRef.current) {
|
||||
|
||||
Reference in New Issue
Block a user