From 493cb195d2c29c9efae32b58090dea8d80db7e09 Mon Sep 17 00:00:00 2001 From: inter Date: Mon, 8 Sep 2025 16:36:32 +0800 Subject: [PATCH] Add File --- frontend/src/stores/assistant.ts | 150 +++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 frontend/src/stores/assistant.ts diff --git a/frontend/src/stores/assistant.ts b/frontend/src/stores/assistant.ts new file mode 100644 index 0000000..d6eeb2f --- /dev/null +++ b/frontend/src/stores/assistant.ts @@ -0,0 +1,150 @@ +import { defineStore } from 'pinia' +import { store } from './index' +import { chatApi, ChatInfo } from '@/api/chat' +import { useCache } from '@/utils/useCache' + +const { wsCache } = useCache() +const flagKey = 'sqlbit-assistant-flag' +type Resolver = (value: T | PromiseLike) => void +type Rejecter = (reason?: any) => void +interface PendingRequest { + resolve: Resolver + reject: Rejecter +} +interface AssistantState { + id: string + token: string + assistant: boolean + flag: number + type: number + certificate: string + online: boolean + pageEmbedded?: boolean + requestPromiseMap: Map +} + +export const AssistantStore = defineStore('assistant', { + state: (): AssistantState => { + return { + id: '', + token: '', + assistant: false, + flag: 0, + type: 0, + certificate: '', + online: false, + pageEmbedded: false, + requestPromiseMap: new Map(), + } + }, + getters: { + getCertificate(): string { + return this.certificate + }, + getId(): string { + return this.id + }, + getToken(): string { + return this.token + }, + getAssistant(): boolean { + return this.assistant + }, + getFlag(): number { + return this.flag + }, + getType(): number { + return this.type + }, + getOnline(): boolean { + return this.online + }, + getPageEmbedded(): boolean { + return this.pageEmbedded || false + }, + getEmbedded(): boolean { + return this.assistant && this.type === 4 + }, + }, + actions: { + refreshCertificate() { + const timeout = 30000 + return new Promise((resolve, reject) => { + const timeoutId = setTimeout(() => { + this.requestPromiseMap.delete(this.id) + reject(new Error(`Request ${this.id} timed out after ${timeout}ms`)) + }, timeout) + this.requestPromiseMap.set(this.id, { + resolve: (value: T) => { + clearTimeout(timeoutId) + this.requestPromiseMap.delete(this.id) + resolve(value) + }, + reject: (reason) => { + clearTimeout(timeoutId) + this.requestPromiseMap.delete(this.id) + reject(reason) + }, + }) + const readyData = { + eventName: this.pageEmbedded ? 'sqlbot_embedded_event' : 'sqlbot_assistant_event', + busi: 'ready', + ready: true, + messageId: this.id, + } + window.parent.postMessage(readyData, '*') + }) + }, + resolveCertificate(data?: any) { + const peddingRequest = this.requestPromiseMap.get(this.id) + if (peddingRequest) { + peddingRequest.resolve(data) + } + }, + setId(id: string) { + this.id = id + }, + setCertificate(certificate: string) { + this.certificate = certificate + }, + setType(type: number) { + this.type = type + }, + setToken(token: string) { + this.token = token + }, + setAssistant(assistant: boolean) { + this.assistant = assistant + }, + setFlag(flag: number) { + if (wsCache.get(flagKey)) { + this.flag = wsCache.get(flagKey) + } else { + this.flag = flag + wsCache.set(flagKey, flag) + } + }, + setPageEmbedded(embedded?: boolean) { + this.pageEmbedded = !!embedded + }, + setOnline(online: boolean) { + this.online = !!online + }, + async setChat() { + if (!this.assistant) { + return null + } + const res = await chatApi.startAssistantChat() + const chat: ChatInfo | undefined = chatApi.toChatInfo(res) + return chat + }, + clear() { + wsCache.delete(flagKey) + this.$reset() + }, + }, +}) + +export const useAssistantStore = () => { + return AssistantStore(store) +}