| | import { defineStore } from 'pinia'; |
| | import { ref, computed } from 'vue'; |
| |
|
| | |
| | export interface SessionNode { |
| | id: string; |
| | text: string; |
| | translatedText?: string; |
| | timestamp: number; |
| | |
| | } |
| |
|
| | |
| | export interface SessionSummary { |
| | startTime: number; |
| | title: string; |
| | outline: string[]; |
| | nodeCount: number; |
| | } |
| |
|
| | const LOCAL_STORAGE_SESSION_PREFIX = 'rt_session_'; |
| |
|
| | export const useSessionStore = defineStore('session', () => { |
| | |
| |
|
| | |
| | const sessionSummaries = ref<SessionSummary[]>([]); |
| |
|
| | |
| | const currentSessionNodes = ref<SessionNode[]>([]); |
| | |
| | const currentSessionStartTime = ref<number | null>(null); |
| | |
| | const isSessionActive = ref(false); |
| |
|
| | |
| |
|
| | |
| | const sortedSessionSummaries = computed(() => { |
| | |
| | return [...sessionSummaries.value].sort((a, b) => b.startTime - a.startTime); |
| | }); |
| |
|
| | |
| |
|
| | |
| | |
| | |
| | function startSession() { |
| | if (isSessionActive.value) { |
| | console.warn("尝试在已有活动会话时开始新会话。"); |
| | |
| | |
| | return; |
| | } |
| | currentSessionStartTime.value = Date.now(); |
| | currentSessionNodes.value = []; |
| | isSessionActive.value = true; |
| | console.log(`新会话开始于: ${new Date(currentSessionStartTime.value).toLocaleString()}`); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | function addNode(node: SessionNode) { |
| | if (!isSessionActive.value || !currentSessionStartTime.value) { |
| | console.warn("没有活动的会话来添加节点。"); |
| | return; |
| | } |
| | currentSessionNodes.value.push(node); |
| | |
| | |
| | } |
| |
|
| | |
| | |
| | |
| | function endSession() { |
| | if (!isSessionActive.value || !currentSessionStartTime.value) { |
| | console.log("没有活动的会话可以结束。"); |
| | |
| | isSessionActive.value = false; |
| | currentSessionStartTime.value = null; |
| | currentSessionNodes.value = []; |
| | return; |
| | } |
| |
|
| | const startTime = currentSessionStartTime.value; |
| | const nodes = [...currentSessionNodes.value]; |
| |
|
| | |
| | isSessionActive.value = false; |
| | currentSessionStartTime.value = null; |
| | currentSessionNodes.value = []; |
| |
|
| | if (nodes.length === 0) { |
| | console.log("会话结束,但没有节点需要保存。"); |
| | return; |
| | } |
| |
|
| | |
| | const title = nodes[0]?.text.substring(0, 10) || '无标题会话'; |
| | const n1 = nodes[0]; |
| | const outline = [ |
| | `${n1?.text.substring(0, 56)}...\n`, |
| | `${n1?.translatedText?.substring(0, 56)}...\n`, |
| | ] |
| | |
| | const summary: SessionSummary = { |
| | startTime, |
| | title, |
| | outline, |
| | nodeCount: nodes.length, |
| | }; |
| |
|
| | |
| | try { |
| | const storageKey = `${LOCAL_STORAGE_SESSION_PREFIX}${startTime}`; |
| | localStorage.setItem(storageKey, JSON.stringify(nodes)); |
| | console.log(`完整会话 ${startTime} 已保存到 localStorage.`); |
| |
|
| | |
| | |
| | const existingIndex = sessionSummaries.value.findIndex(s => s.startTime === startTime); |
| | if (existingIndex === -1) { |
| | sessionSummaries.value.push(summary); |
| | } else { |
| | console.warn(`会话摘要 ${startTime} 已存在,将进行覆盖。`); |
| | sessionSummaries.value[existingIndex] = summary; |
| | } |
| | |
| |
|
| | console.log(`会话 ${startTime} 结束并已处理。`); |
| |
|
| | } catch (error) { |
| | console.error("保存会话到 localStorage 时出错:", error); |
| | |
| | |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | function loadSessionContent(startTime: number): SessionNode[] | null { |
| | try { |
| | const storageKey = `${LOCAL_STORAGE_SESSION_PREFIX}${startTime}`; |
| | const storedData = localStorage.getItem(storageKey); |
| | if (storedData) { |
| | const nodes = JSON.parse(storedData) as SessionNode[]; |
| | console.log(`从 localStorage 加载了会话 ${startTime} 的内容 (${nodes.length} 个节点)`); |
| | return nodes; |
| | } |
| | console.warn(`在 localStorage 中未找到键为 ${storageKey} 的会话数据。`); |
| | return null; |
| | } catch (error) { |
| | console.error(`从 localStorage 加载会话 ${startTime} 时出错:`, error); |
| | return null; |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | function deleteSession(startTime: number) { |
| | try { |
| | |
| | const index = sessionSummaries.value.findIndex(s => s.startTime === startTime); |
| | if (index > -1) { |
| | sessionSummaries.value.splice(index, 1); |
| | console.log(`会话摘要 ${startTime} 已从 Pinia store 中移除。`); |
| | |
| | } else { |
| | console.warn(`尝试删除一个不存在的会话摘要: ${startTime}`); |
| | } |
| |
|
| | |
| | const storageKey = `${LOCAL_STORAGE_SESSION_PREFIX}${startTime}`; |
| | localStorage.removeItem(storageKey); |
| | console.log(`会话 ${startTime} 的完整内容已从 localStorage 中移除。`); |
| |
|
| | } catch (error) { |
| | console.error(`删除会话 ${startTime} 时出错:`, error); |
| | } |
| | } |
| |
|
| | |
| | return { |
| | |
| | sessionSummaries, |
| | currentSessionNodes, |
| | currentSessionStartTime, |
| | isSessionActive, |
| |
|
| | |
| | sortedSessionSummaries, |
| |
|
| | |
| | startSession, |
| | addNode, |
| | endSession, |
| | loadSessionContent, |
| | deleteSession, |
| | }; |
| | }, { |
| | |
| | persist: { |
| | |
| | paths: ['sessionSummaries'], |
| | |
| | |
| | }, |
| | }); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | export function downloadSessionData(startTime: number, nodes: SessionNode[], format: 'json' | 'txt' = 'json') { |
| | if (!nodes || nodes.length === 0) { |
| | console.error("没有数据可供下载:", startTime); |
| | alert("没有内容可以下载。"); |
| | return; |
| | } |
| | try { |
| | const dateStr = new Date(startTime).toISOString().split('T')[0]; |
| | let dataStr: string; |
| | let mimeType: string; |
| | let fileExtension: string; |
| |
|
| | if (format === 'txt') { |
| | dataStr = nodes.map(n => `${new Date(n.timestamp).toLocaleTimeString()} - ${n.text}`).join('\n'); |
| | mimeType = 'text/plain;charset=utf-8;'; |
| | fileExtension = 'txt'; |
| | } else { |
| | dataStr = JSON.stringify(nodes, null, 2); |
| | mimeType = 'application/json;charset=utf-8;'; |
| | fileExtension = 'json'; |
| | } |
| |
|
| | const filename = `session_${dateStr}_${startTime}.${fileExtension}`; |
| | const blob = new Blob([dataStr], { type: mimeType }); |
| | const link = document.createElement("a"); |
| |
|
| | |
| | const url = URL.createObjectURL(blob); |
| | link.setAttribute("href", url); |
| | link.setAttribute("download", filename); |
| | link.style.visibility = 'hidden'; |
| | document.body.appendChild(link); |
| | link.click(); |
| |
|
| | |
| | document.body.removeChild(link); |
| | URL.revokeObjectURL(url); |
| |
|
| | console.log(`已触发下载会话 ${startTime} 为 ${filename}`); |
| |
|
| | } catch (error) { |
| | console.error(`下载会话 ${startTime} 时出错:`, error); |
| | alert("下载文件时发生错误。"); |
| | } |
| | } |
| |
|