151 lines
3.7 KiB
TypeScript
151 lines
3.7 KiB
TypeScript
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<T = any> = (value: T | PromiseLike<T>) => void
|
|
type Rejecter = (reason?: any) => void
|
|
interface PendingRequest<T = any> {
|
|
resolve: Resolver<T>
|
|
reject: Rejecter
|
|
}
|
|
interface AssistantState {
|
|
id: string
|
|
token: string
|
|
assistant: boolean
|
|
flag: number
|
|
type: number
|
|
certificate: string
|
|
online: boolean
|
|
pageEmbedded?: boolean
|
|
requestPromiseMap: Map<string, PendingRequest>
|
|
}
|
|
|
|
export const AssistantStore = defineStore('assistant', {
|
|
state: (): AssistantState => {
|
|
return {
|
|
id: '',
|
|
token: '',
|
|
assistant: false,
|
|
flag: 0,
|
|
type: 0,
|
|
certificate: '',
|
|
online: false,
|
|
pageEmbedded: false,
|
|
requestPromiseMap: new Map<string, PendingRequest>(),
|
|
}
|
|
},
|
|
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<T>() {
|
|
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)
|
|
}
|