From 115016c2629f2d2df540caa4506674f83a8a8965 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Sun, 27 Jul 2025 00:56:07 +0800 Subject: [PATCH] perf: Assistant switch online --- backend/apps/system/crud/assistant.py | 7 ++- backend/common/core/deps.py | 3 + frontend/public/assistant.js | 84 ++++++++++++++++++++++++++- frontend/src/stores/assistant.ts | 8 +++ frontend/src/utils/request.ts | 6 ++ frontend/src/views/embedded/index.vue | 21 ++++++- 6 files changed, 122 insertions(+), 7 deletions(-) diff --git a/backend/apps/system/crud/assistant.py b/backend/apps/system/crud/assistant.py index 74d08d61..7c33cd33 100644 --- a/backend/apps/system/crud/assistant.py +++ b/backend/apps/system/crud/assistant.py @@ -35,9 +35,10 @@ def get_assistant_ds(llm_service) -> list[dict]: config: dict[any] = json.loads(configuration) oid: str = config['oid'] stmt = select(CoreDatasource.id, CoreDatasource.name, CoreDatasource.description).where(CoreDatasource.oid == oid) - private_list:list[int] = config.get('private_list') or None - if private_list: - stmt.where(~CoreDatasource.id.in_(private_list)) + if not assistant.online: + private_list:list[int] = config.get('private_list') or None + if private_list: + stmt = stmt.where(~CoreDatasource.id.in_(private_list)) db_ds_list = session.exec(stmt) result_list = [ diff --git a/backend/common/core/deps.py b/backend/common/core/deps.py index afc2dc36..0dcef442 100644 --- a/backend/common/core/deps.py +++ b/backend/common/core/deps.py @@ -25,6 +25,9 @@ async def get_current_assistant(request: Request) -> AssistantHeader | None: if request.headers.get("X-SQLBOT-ASSISTANT-CERTIFICATE"): entry_certificate = request.headers['X-SQLBOT-ASSISTANT-CERTIFICATE'] base_assistant.certificate = unquote(base64.b64decode(entry_certificate).decode('utf-8')) + if request.headers.get("X-SQLBOT-ASSISTANT-ONLINE"): + entry_online = request.headers['X-SQLBOT-ASSISTANT-ONLINE'] + base_assistant.online = str(entry_online).lower() == 'true' if entry_online else False return base_assistant CurrentAssistant = Annotated[AssistantHeader, Depends(get_current_assistant)] diff --git a/frontend/public/assistant.js b/frontend/public/assistant.js index 96c0cd21..043fd455 100644 --- a/frontend/public/assistant.js +++ b/frontend/public/assistant.js @@ -1,4 +1,5 @@ ;(function () { + window.sqlbot_assistant_handler = window.sqlbot_assistant_handler || {} const defaultData = { id: '1', show_guide: false, @@ -67,7 +68,7 @@ const getChatContainerHtml = (data) => { return `
- +
@@ -440,6 +441,7 @@ } function loadScript(src, id) { const domain_url = getDomain(src) + const online = getParam(src, 'online') let url = `${domain_url}/api/v1/system/assistant/info/${id}` if (domain_url.includes('5173')) { url = url.replace('5173', '8000') @@ -455,6 +457,7 @@ Object.assign(tempData, config) tempData = Object.assign(tempData, config) } + tempData['online'] = online && online.toString().toLowerCase() == 'true' initsqlbot_assistant(tempData) if (data.type == 1) { registerMessageEvent(id, tempData) @@ -471,13 +474,90 @@ const src_list = scriptsArray.map((script) => script.src) src_list.forEach((src) => { const id = getParam(src, 'id') + window.sqlbot_assistant_handler[id] = window.sqlbot_assistant_handler[id] || {} + window.sqlbot_assistant_handler[id]['id'] = id const propName = script_id_prefix + id + '-state' if (window[propName]) { return true } window[propName] = true loadScript(src, id) + expposeGlobalMethods(id) }) } - window.addEventListener('load', init) + function updateOnlineParam(target_url, newValue) { + try { + const url = new URL(target_url) + const [hashPath, hashQuery] = url.hash.split('?') + let searchParams + if (hashQuery) { + searchParams = new URLSearchParams(hashQuery) + } else { + searchParams = url.searchParams + } + searchParams.set('online', newValue) + if (hashQuery) { + url.hash = `${hashPath}?${searchParams.toString()}` + } else { + url.search = searchParams.toString() + } + return url.toString() + } catch (e) { + console.error('Invalid URL:', target_url) + return target_url + } + } + function expposeGlobalMethods(id) { + window.sqlbot_assistant_handler[id]['setOnline'] = (online) => { + if (online != null && typeof online != 'boolean') { + throw new Error('The parameter can only be of type boolean') + } + const iframe = document.getElementById(`sqlbot-assistant-chat-iframe-${id}`) + if (iframe) { + const url = iframe.src + const eventName = 'sqlbot_assistant_event' + const params = { + busi: 'setOnline', + online, + eventName, + messageId: id, + } + const contentWindow = iframe.contentWindow + contentWindow.postMessage(params, url) + } + } + window.sqlbot_assistant_handler[id]['refresh'] = (online) => { + if (online != null && typeof online != 'boolean') { + throw new Error('The parameter can only be of type boolean') + } + const iframe = document.getElementById(`sqlbot-assistant-chat-iframe-${id}`) + if (iframe) { + const url = iframe.src + let new_url = `${url}&t=${Date.now()}` + if (online != null) { + new_url = updateOnlineParam(new_url, online) + } + iframe.src = new_url + } + } + } + // window.addEventListener('load', init) + const executeWhenReady = (fn) => { + if ( + document.readyState === 'complete' || + (document.readyState !== 'loading' && !document.documentElement.doScroll) + ) { + setTimeout(fn, 0) + } else { + const onReady = () => { + document.removeEventListener('DOMContentLoaded', onReady) + window.removeEventListener('load', onReady) + fn() + } + document.addEventListener('DOMContentLoaded', onReady) + window.addEventListener('load', onReady) + } + } + + executeWhenReady(init) })() diff --git a/frontend/src/stores/assistant.ts b/frontend/src/stores/assistant.ts index ebfe0ffa..f40f8a72 100644 --- a/frontend/src/stores/assistant.ts +++ b/frontend/src/stores/assistant.ts @@ -11,6 +11,7 @@ interface AssistantState { flag: number type: number certificate: string + online: boolean } export const AssistantStore = defineStore('assistant', { @@ -21,6 +22,7 @@ export const AssistantStore = defineStore('assistant', { flag: 0, type: 0, certificate: '', + online: false, } }, getters: { @@ -39,6 +41,9 @@ export const AssistantStore = defineStore('assistant', { getType(): number { return this.type }, + getOnline(): boolean { + return this.online + }, }, actions: { setCertificate(certificate: string) { @@ -61,6 +66,9 @@ export const AssistantStore = defineStore('assistant', { wsCache.set(flagKey, flag) } }, + setOnline(online: boolean) { + this.online = !!online + }, async setChat() { if (!this.assistant) { return null diff --git a/frontend/src/utils/request.ts b/frontend/src/utils/request.ts index 2851979c..588b9d09 100644 --- a/frontend/src/utils/request.ts +++ b/frontend/src/utils/request.ts @@ -80,6 +80,9 @@ class HttpService { encodeURIComponent(assistantStore.getCertificate) ) } + if (!assistantStore.getType) { + config.headers['X-SQLBOT-ASSISTANT-ONLINE'] = assistantStore.getOnline + } } const locale = getLocale() if (locale) { @@ -261,6 +264,9 @@ class HttpService { encodeURIComponent(assistantStore.getCertificate) ) } + if (!assistantStore.getType) { + heads['X-SQLBOT-ASSISTANT-ONLINE'] = assistantStore.getOnline + } } // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore diff --git a/frontend/src/views/embedded/index.vue b/frontend/src/views/embedded/index.vue index 4a7b4e97..997565ca 100644 --- a/frontend/src/views/embedded/index.vue +++ b/frontend/src/views/embedded/index.vue @@ -58,14 +58,31 @@ const communicationCb = async (event: any) => { const certificate = event.data['certificate'] assistantStore.setType(1) assistantStore.setCertificate(certificate) - // store certificate to pinia + } + if (event.data?.busi == 'setOnline') { + setFormatOnline(event.data.online) } } } +const setFormatOnline = (text?: any) => { + if (text === null || typeof text === 'undefined') { + assistantStore.setOnline(false) + return + } + if (typeof text === 'boolean') { + assistantStore.setOnline(text) + return + } + if (typeof text === 'string') { + assistantStore.setOnline(text.toLowerCase() === 'true') + return + } + assistantStore.setOnline(false) +} onBeforeMount(async () => { const assistantId = route.query.id const online = route.query.online - console.log(online) + setFormatOnline(online) const now = Date.now() assistantStore.setFlag(now) const param = {