feat: 拆分左侧栏、中间聊天区、右侧栏组件, Hooks 提取
This commit is contained in:
189
src/views/AgentChat/hooks/useAgentSessions.ts
Normal file
189
src/views/AgentChat/hooks/useAgentSessions.ts
Normal file
@@ -0,0 +1,189 @@
|
||||
// src/views/AgentChat/hooks/useAgentSessions.ts
|
||||
// 会话管理 Hook - 加载、切换、创建会话
|
||||
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import type { Dispatch, SetStateAction } from 'react';
|
||||
import axios from 'axios';
|
||||
import { logger } from '@utils/logger';
|
||||
import { MessageTypes, type Message } from '../constants/messageTypes';
|
||||
|
||||
/**
|
||||
* 会话数据结构
|
||||
*/
|
||||
export interface Session {
|
||||
session_id: string;
|
||||
title?: string;
|
||||
created_at?: string;
|
||||
timestamp?: string;
|
||||
message_count?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户信息(从 AuthContext 传入)
|
||||
*/
|
||||
export interface User {
|
||||
id: string;
|
||||
nickname?: string;
|
||||
avatar?: string;
|
||||
subscription_type?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* useAgentSessions Hook 参数
|
||||
*/
|
||||
export interface UseAgentSessionsParams {
|
||||
/** 当前用户信息 */
|
||||
user: User | null;
|
||||
/** 消息列表 setter(用于创建新会话时设置欢迎消息) */
|
||||
setMessages: Dispatch<SetStateAction<Message[]>>;
|
||||
}
|
||||
|
||||
/**
|
||||
* useAgentSessions Hook 返回值
|
||||
*/
|
||||
export interface UseAgentSessionsReturn {
|
||||
/** 会话列表 */
|
||||
sessions: Session[];
|
||||
/** 当前选中的会话 ID */
|
||||
currentSessionId: string | null;
|
||||
/** 设置当前会话 ID */
|
||||
setCurrentSessionId: Dispatch<SetStateAction<string | null>>;
|
||||
/** 是否正在加载会话列表 */
|
||||
isLoadingSessions: boolean;
|
||||
/** 加载会话列表 */
|
||||
loadSessions: () => Promise<void>;
|
||||
/** 切换到指定会话 */
|
||||
switchSession: (sessionId: string) => void;
|
||||
/** 创建新会话(显示欢迎消息) */
|
||||
createNewSession: () => void;
|
||||
/** 加载指定会话的历史消息 */
|
||||
loadSessionHistory: (sessionId: string) => Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* useAgentSessions Hook
|
||||
*
|
||||
* 管理会话列表、会话切换、新建会话逻辑
|
||||
*
|
||||
* @param params - UseAgentSessionsParams
|
||||
* @returns UseAgentSessionsReturn
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const {
|
||||
* sessions,
|
||||
* currentSessionId,
|
||||
* isLoadingSessions,
|
||||
* switchSession,
|
||||
* createNewSession,
|
||||
* } = useAgentSessions({ user, setMessages });
|
||||
* ```
|
||||
*/
|
||||
export const useAgentSessions = ({
|
||||
user,
|
||||
setMessages,
|
||||
}: UseAgentSessionsParams): UseAgentSessionsReturn => {
|
||||
const [sessions, setSessions] = useState<Session[]>([]);
|
||||
const [currentSessionId, setCurrentSessionId] = useState<string | null>(null);
|
||||
const [isLoadingSessions, setIsLoadingSessions] = useState(false);
|
||||
|
||||
/**
|
||||
* 加载用户的会话列表
|
||||
*/
|
||||
const loadSessions = useCallback(async () => {
|
||||
if (!user?.id) return;
|
||||
|
||||
setIsLoadingSessions(true);
|
||||
try {
|
||||
const response = await axios.get('/mcp/agent/sessions', {
|
||||
params: { user_id: user.id, limit: 50 },
|
||||
});
|
||||
|
||||
if (response.data.success) {
|
||||
setSessions(response.data.data);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('加载会话列表失败', error);
|
||||
} finally {
|
||||
setIsLoadingSessions(false);
|
||||
}
|
||||
}, [user?.id]);
|
||||
|
||||
/**
|
||||
* 加载指定会话的历史消息
|
||||
*/
|
||||
const loadSessionHistory = useCallback(
|
||||
async (sessionId: string) => {
|
||||
if (!sessionId) return;
|
||||
|
||||
try {
|
||||
const response = await axios.get(`/mcp/agent/history/${sessionId}`, {
|
||||
params: { limit: 100 },
|
||||
});
|
||||
|
||||
if (response.data.success) {
|
||||
const history = response.data.data;
|
||||
const formattedMessages: Message[] = history.map((msg: any, idx: number) => ({
|
||||
id: `${sessionId}-${idx}`,
|
||||
type: msg.message_type === 'user' ? MessageTypes.USER : MessageTypes.AGENT_RESPONSE,
|
||||
content: msg.message,
|
||||
plan: msg.plan ? JSON.parse(msg.plan) : null,
|
||||
stepResults: msg.steps ? JSON.parse(msg.steps) : null,
|
||||
timestamp: msg.timestamp,
|
||||
}));
|
||||
|
||||
setMessages(formattedMessages);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('加载会话历史失败', error);
|
||||
}
|
||||
},
|
||||
[setMessages]
|
||||
);
|
||||
|
||||
/**
|
||||
* 切换到指定会话
|
||||
*/
|
||||
const switchSession = useCallback(
|
||||
(sessionId: string) => {
|
||||
setCurrentSessionId(sessionId);
|
||||
loadSessionHistory(sessionId);
|
||||
},
|
||||
[loadSessionHistory]
|
||||
);
|
||||
|
||||
/**
|
||||
* 创建新会话(清空消息,显示欢迎消息)
|
||||
*/
|
||||
const createNewSession = useCallback(() => {
|
||||
setCurrentSessionId(null);
|
||||
setMessages([
|
||||
{
|
||||
id: Date.now(),
|
||||
type: MessageTypes.AGENT_RESPONSE,
|
||||
content: `你好${user?.nickname || ''}!👋\n\n我是**价小前**,你的 AI 投研助手。\n\n**我能做什么?**\n• 📊 全面分析股票基本面和技术面\n• 🔥 追踪市场热点和涨停板块\n• 📈 研究行业趋势和投资机会\n• 📰 汇总最新财经新闻和研报\n\n直接输入你的问题开始探索!`,
|
||||
timestamp: new Date().toISOString(),
|
||||
},
|
||||
]);
|
||||
}, [user?.nickname, setMessages]);
|
||||
|
||||
/**
|
||||
* 组件挂载时加载会话列表并创建新会话
|
||||
*/
|
||||
useEffect(() => {
|
||||
loadSessions();
|
||||
createNewSession();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [user]);
|
||||
|
||||
return {
|
||||
sessions,
|
||||
currentSessionId,
|
||||
setCurrentSessionId,
|
||||
isLoadingSessions,
|
||||
loadSessions,
|
||||
switchSession,
|
||||
createNewSession,
|
||||
loadSessionHistory,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user