| |
|
|
| import { AUTH_TOKEN_STORAGE_KEY, CURRENT_SESSION_KEY, SESSION_LIST_KEY } from './constants.js'; |
|
|
| |
| |
| |
| |
| export async function initTabbedSessionManagement(chatWindow) { |
| console.log("DEBUG: initTabbedSessionManagement 开始执行。"); |
| |
| const sessionTabBar = document.getElementById('session-tab-bar'); |
| const newSessionBtn = document.getElementById('new-session-btn'); |
| const deleteSessionBtn = document.getElementById('delete-session-btn'); |
| |
| |
| if (newSessionBtn) { |
| newSessionBtn.addEventListener('click', () => createNewSession(chatWindow)); |
| console.log("DEBUG: '新建会话' 按钮事件监听已添加。"); |
| } |
| if (deleteSessionBtn) { |
| deleteSessionBtn.addEventListener('click', () => deleteCurrentSession(chatWindow)); |
| console.log("DEBUG: '删除当前' 按钮事件监听已添加。"); |
| } |
| |
| |
| localStorage.removeItem(CURRENT_SESSION_KEY); |
| console.log("DEBUG: 强制清除 CURRENT_SESSION_KEY。"); |
|
|
| |
| console.log("DEBUG: 调用 loadSessions() 加载会话列表。"); |
| await loadSessions(); |
| |
| |
| let currentSessionId = localStorage.getItem(CURRENT_SESSION_KEY); |
| console.log(`DEBUG: 当前会话ID (localStorage): ${currentSessionId}`); |
| if (!currentSessionId) { |
| console.log("DEBUG: 未检测到当前会话,自动创建新会话..."); |
| const created = await createNewSession(chatWindow); |
| console.log(`DEBUG: createNewSession 返回: ${created}`); |
| if (created) { |
| console.log("DEBUG: 新会话创建成功,重新加载会话列表。"); |
| currentSessionId = localStorage.getItem(CURRENT_SESSION_KEY); |
| await loadSessions(); |
| |
| } else { |
| console.error("ERROR: 自动创建新会话失败。"); |
| } |
| } else { |
| console.log(`DEBUG: 检测到当前会话ID: ${currentSessionId},加载其历史消息。`); |
| |
| await loadSessionHistory(currentSessionId); |
| } |
| |
| console.log("DEBUG: initTabbedSessionManagement 执行完毕。"); |
| |
| |
| } |
|
|
| |
| |
| |
| |
| export async function createNewSession(chatWindow) { |
| const authToken = localStorage.getItem(AUTH_TOKEN_STORAGE_KEY); |
| let sessionName; |
| let threadId; |
|
|
| if (authToken) { |
| try { |
| const response = await fetch('/v1/sessions', { |
| method: 'POST', |
| headers: { 'X-Auth-Token': authToken } |
| }); |
| |
| if (response.ok) { |
| const data = await response.json(); |
| console.log('会话创建成功,响应数据:', data); |
| threadId = data.thread_id; |
| sessionName = data.name; |
| } else { |
| const errorText = await response.text(); |
| console.error(`创建会话失败: ${response.status} ${response.statusText}, 响应: ${errorText}`); |
| |
| console.log("DEBUG: 后端会话创建失败,尝试创建本地会话。"); |
| } |
| } catch (error) { |
| console.error('创建会话请求出错:', error); |
| |
| console.log("DEBUG: 创建会话请求出错,尝试创建本地会话。"); |
| } |
| } |
|
|
| |
| if (!threadId) { |
| threadId = `local-session-${Date.now()}`; |
| const now = new Date(); |
| const year = now.getFullYear(); |
| const month = (now.getMonth() + 1).toString().padStart(2, '0'); |
| const day = now.getDate().toString().padStart(2, '0'); |
| const hours = now.getHours().toString().padStart(2, '0'); |
| const minutes = now.getMinutes().toString().padStart(2, '0'); |
| sessionName = `本地会话-${year}${month}${day}-${hours}${minutes}`; |
| console.log(`DEBUG: 生成本地会话名称: ${sessionName}`); |
| } |
|
|
| localStorage.setItem(CURRENT_SESSION_KEY, threadId); |
| saveSessionToList(threadId, sessionName); |
| console.log('会话ID已保存到localStorage:', localStorage.getItem(CURRENT_SESSION_KEY)); |
| chatWindow.innerHTML = ''; |
| renderSessionTabs(); |
| return true; |
| } |
|
|
| |
| |
| |
| |
| export async function deleteCurrentSession(chatWindow) { |
| const authToken = localStorage.getItem(AUTH_TOKEN_STORAGE_KEY); |
| const sessionId = localStorage.getItem(CURRENT_SESSION_KEY); |
| if (!authToken || !sessionId) return; |
| |
| try { |
| const response = await fetch(`/v1/sessions/${sessionId}`, { |
| method: 'DELETE', |
| headers: { 'X-Auth-Token': authToken } |
| }); |
| |
| if (response.ok) { |
| removeSessionFromList(sessionId); |
| localStorage.removeItem(CURRENT_SESSION_KEY); |
| loadSessions(); |
| chatWindow.innerHTML = ''; |
| } |
| } catch (error) { |
| console.error('删除会话失败:', error); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| export function saveSessionToList(sessionId, name) { |
| const sessions = JSON.parse(localStorage.getItem(SESSION_LIST_KEY) || '{}'); |
| sessions[sessionId] = { |
| name: name, |
| created: Date.now() |
| }; |
| localStorage.setItem(SESSION_LIST_KEY, JSON.stringify(sessions)); |
| } |
|
|
| |
| |
| |
| |
| export function removeSessionFromList(sessionId) { |
| const sessions = JSON.parse(localStorage.getItem(SESSION_LIST_KEY) || '{}'); |
| delete sessions[sessionId]; |
| localStorage.setItem(SESSION_LIST_KEY, JSON.stringify(sessions)); |
| } |
|
|
| |
| |
| |
| function renderSessionTabs() { |
| const sessions = JSON.parse(localStorage.getItem(SESSION_LIST_KEY) || '{}'); |
| const tabsContainer = document.getElementById('session-tabs'); |
| tabsContainer.innerHTML = ''; |
| |
| Object.keys(sessions).forEach(sessionId => { |
| const session = sessions[sessionId]; |
| |
| |
| const hoursLeft = Math.max(0, 24 - Math.floor((Date.now() - session.created) / 3600000)); |
| const isCurrent = sessionId === localStorage.getItem(CURRENT_SESSION_KEY); |
| |
| const tab = document.createElement('button'); |
| tab.className = `session-tab ${isCurrent ? 'active' : ''}`; |
| tab.dataset.id = sessionId; |
| tab.textContent = `${session.name} (${hoursLeft}h)`; |
| |
| tab.addEventListener('click', () => { |
| switchSession(sessionId); |
| }); |
| |
| tabsContainer.appendChild(tab); |
| }); |
| |
| |
| const statusBar = document.getElementById('session-status'); |
| const sessionCount = Object.keys(sessions).length; |
| statusBar.innerHTML = `会话数: ${sessionCount}/5`; |
| |
| if (sessionCount >= 5) { |
| statusBar.innerHTML += ' (已达上限)'; |
| statusBar.style.color = 'red'; |
| } |
| } |
|
|
| |
| |
| |
| export async function loadSessions() { |
| |
| renderSessionTabs(); |
|
|
| const authToken = localStorage.getItem(AUTH_TOKEN_STORAGE_KEY); |
| if (!authToken) { |
| console.log("DEBUG: 无认证令牌,跳过从后端获取会话列表。"); |
| return; |
| } |
| |
| |
| try { |
| const response = await fetch('/v1/sessions', { |
| headers: { 'X-Auth-Token': authToken } |
| }); |
| |
| if (response.ok) { |
| const sessions = await response.json(); |
| const sessionMap = {}; |
| sessions.forEach(session => { |
| sessionMap[session.thread_id] = { |
| name: session.name, |
| created: session.created_at * 1000 |
| }; |
| }); |
| localStorage.setItem(SESSION_LIST_KEY, JSON.stringify(sessionMap)); |
| |
| |
| renderSessionTabs(); |
| } else { |
| const errorText = await response.text(); |
| console.error(`获取会话列表失败: ${response.status} ${response.statusText}, 响应: ${errorText}`); |
| } |
| } catch (error) { |
| console.error('获取会话列表请求出错:', error); |
| } |
| } |
|
|
| |
| |
| |
| |
| export function switchSession(sessionId) { |
| const chatWindow = document.getElementById('chat-window'); |
| localStorage.setItem(CURRENT_SESSION_KEY, sessionId); |
| chatWindow.innerHTML = ''; |
| loadSessions(); |
| |
| |
| loadSessionHistory(sessionId); |
| } |
|
|
| |
| |
| |
| |
| async function loadSessionHistory(sessionId) { |
| const chatWindow = document.getElementById('chat-window'); |
|
|
| |
| if (sessionId.startsWith('local-session-')) { |
| console.log(`DEBUG: 加载本地会话 ${sessionId},清空聊天窗口。`); |
| chatWindow.innerHTML = ''; |
| return; |
| } |
|
|
| const authToken = localStorage.getItem(AUTH_TOKEN_STORAGE_KEY); |
| if (!authToken) { |
| console.log("DEBUG: 无认证令牌,无法加载后端会话历史。"); |
| chatWindow.innerHTML = ''; |
| return; |
| } |
| |
| try { |
| const response = await fetch(`/v1/sessions/${sessionId}/history`, { |
| headers: { 'X-Auth-Token': authToken } |
| }); |
| |
| if (response.ok) { |
| const data = await response.json(); |
| |
| |
| for (const message of data.history) { |
| const messageElement = document.createElement('div'); |
| messageElement.className = `chat-message ${message.role === 'user' ? 'user-message' : 'ai-message'}`; |
| |
| let content = ''; |
| if (message.parts && message.parts.length > 0) { |
| |
| content = message.parts.map(part => part.text).join(''); |
| } else if (message.text) { |
| |
| content = message.text; |
| } |
| |
| messageElement.innerHTML = ` |
| <div class="message-content">${content}</div> |
| `; |
| chatWindow.appendChild(messageElement); |
| } |
| |
| |
| chatWindow.scrollTop = chatWindow.scrollHeight; |
| } else { |
| const errorText = await response.text(); |
| console.error(`加载会话历史失败: ${response.status} ${response.statusText}, 响应: ${errorText}`); |
| chatWindow.innerHTML = ''; |
| } |
| } catch (error) { |
| console.error('加载会话历史请求出错:', error); |
| chatWindow.innerHTML = ''; |
| } |
| } |
|
|