;(function () { const defaultData = { id: '1', show_guide: false, float_icon: '', domain_url: 'http://localhost:5173', header_font_color: 'rgb(100, 106, 115)', x_type: 'right', y_type: 'bottom', x_value: '-5', y_value: '33', } const script_id_prefix = 'sqlbot-assistant-float-script-' const guideHtml = `
🌟 遇见问题,不再有障碍!

你好,我是你的智能小助手。
点我,开启高效解答模式,让问题变成过去式。

` const chatButtonHtml = (data) => `
` const getChatContainerHtml = (data) => { return `
` } /** * 初始化引导 * @param {*} root */ const initGuide = (root) => { root.insertAdjacentHTML('beforeend', guideHtml) const button = root.querySelector('.sqlbot-assistant-button') const close_icon = root.querySelector('.sqlbot-assistant-close') const close_func = () => { root.removeChild(root.querySelector('.sqlbot-assistant-tips')) root.removeChild(root.querySelector('.sqlbot-assistant-mask')) localStorage.setItem('sqlbot_assistant_mask_tip', true) } button.onclick = close_func close_icon.onclick = close_func } const initChat = (root, data) => { // 添加对话icon root.insertAdjacentHTML('beforeend', chatButtonHtml(data)) // 添加对话框 root.insertAdjacentHTML('beforeend', getChatContainerHtml(data)) // 按钮元素 const chat_button = root.querySelector('.sqlbot-assistant-chat-button') const chat_button_img = root.querySelector('.sqlbot-assistant-chat-button > img') // 对话框元素 const chat_container = root.querySelector('#sqlbot-assistant-chat-container') // 引导层 const mask_content = root.querySelector('.sqlbot-assistant-mask > .sqlbot-assistant-content') const mask_tips = root.querySelector('.sqlbot-assistant-tips') chat_button_img.onload = (event) => { if (mask_content) { mask_content.style.width = chat_button_img.width + 'px' mask_content.style.height = chat_button_img.height + 'px' if (data.x_type == 'left') { mask_tips.style.marginLeft = (chat_button_img.naturalWidth > 500 ? 500 : chat_button_img.naturalWidth) - 64 + 'px' } else { mask_tips.style.marginRight = (chat_button_img.naturalWidth > 500 ? 500 : chat_button_img.naturalWidth) - 64 + 'px' } } } const viewport = root.querySelector('.sqlbot-assistant-openviewport') const closeviewport = root.querySelector('.sqlbot-assistant-closeviewport') const close_func = () => { chat_container.style['display'] = chat_container.style['display'] == 'block' ? 'none' : 'block' chat_button.style['display'] = chat_container.style['display'] == 'block' ? 'none' : 'block' } close_icon = chat_container.querySelector('.sqlbot-assistant-chat-close') chat_button.onclick = close_func close_icon.onclick = close_func const viewport_func = () => { if (chat_container.classList.contains('sqlbot-assistant-enlarge')) { chat_container.classList.remove('sqlbot-assistant-enlarge') viewport.classList.remove('sqlbot-assistant-viewportnone') closeviewport.classList.add('sqlbot-assistant-viewportnone') } else { chat_container.classList.add('sqlbot-assistant-enlarge') viewport.classList.add('sqlbot-assistant-viewportnone') closeviewport.classList.remove('sqlbot-assistant-viewportnone') } } const drag = (e) => { if (['touchmove', 'touchstart'].includes(e.type)) { chat_button.style.top = e.touches[0].clientY - chat_button_img.naturalHeight / 2 + 'px' chat_button.style.left = e.touches[0].clientX - chat_button_img.naturalWidth / 2 + 'px' } else { chat_button.style.top = e.y - chat_button_img.naturalHeight / 2 + 'px' chat_button.style.left = e.x - chat_button_img.naturalWidth / 2 + 'px' } chat_button.style.width = chat_button_img.naturalWidth + 'px' chat_button.style.height = chat_button_img.naturalHeight + 'px' } if (data.is_draggable) { chat_button.addEventListener('drag', drag) chat_button.addEventListener('dragover', (e) => { e.preventDefault() }) chat_button.addEventListener('dragend', drag) chat_button.addEventListener('touchstart', drag) chat_button.addEventListener('touchmove', drag) } viewport.onclick = viewport_func closeviewport.onclick = viewport_func } /** * 第一次进来的引导提示 */ function initsqlbot_assistant(data) { const sqlbot_div = document.createElement('div') const root = document.createElement('div') const sqlbot_root_id = 'sqlbot-assistant-root-' + data.id root.id = sqlbot_root_id initsqlbot_assistantStyle(sqlbot_div, sqlbot_root_id, data) sqlbot_div.appendChild(root) document.body.appendChild(sqlbot_div) const sqlbot_assistant_mask_tip = localStorage.getItem('sqlbot_assistant_mask_tip') if (sqlbot_assistant_mask_tip == null && data.show_guide) { initGuide(root) } initChat(root, data) } // 初始化全局样式 function initsqlbot_assistantStyle(root, sqlbot_assistantId, data) { style = document.createElement('style') style.type = 'text/css' style.innerText = ` /* 放大 */ #sqlbot-assistant .sqlbot-assistant-enlarge { width: 50%!important; height: 100%!important; bottom: 0!important; right: 0 !important; } @media only screen and (max-width: 768px){ #sqlbot-assistant .sqlbot-assistant-enlarge { width: 100%!important; height: 100%!important; right: 0 !important; bottom: 0!important; } } /* 引导 */ #sqlbot-assistant .sqlbot-assistant-mask { position: fixed; z-index: 10001; background-color: transparent; height: 100%; width: 100%; top: 0; left: 0; } #sqlbot-assistant .sqlbot-assistant-mask .sqlbot-assistant-content { width: 64px; height: 64px; box-shadow: 1px 1px 1px 9999px rgba(0,0,0,.6); position: absolute; ${data.x_type}: ${data.x_value}px; ${data.y_type}: ${data.y_value}px; z-index: 10001; } #sqlbot-assistant .sqlbot-assistant-tips { position: fixed; ${data.x_type}:calc(${data.x_value}px + 75px); ${data.y_type}: calc(${data.y_value}px + 0px); padding: 22px 24px 24px; border-radius: 6px; color: #ffffff; font-size: 14px; background: #3370FF; z-index: 10001; } #sqlbot-assistant .sqlbot-assistant-tips .sqlbot-assistant-arrow { position: absolute; background: #3370FF; width: 10px; height: 10px; pointer-events: none; transform: rotate(45deg); box-sizing: border-box; /* left */ ${data.x_type}: -5px; ${data.y_type}: 33px; border-left-color: transparent; border-bottom-color: transparent } #sqlbot-assistant .sqlbot-assistant-tips .sqlbot-assistant-title { font-size: 20px; font-weight: 500; margin-bottom: 8px; } #sqlbot-assistant .sqlbot-assistant-tips .sqlbot-assistant-button { text-align: right; margin-top: 24px; } #sqlbot-assistant .sqlbot-assistant-tips .sqlbot-assistant-button button { border-radius: 4px; background: #FFF; padding: 3px 12px; color: #3370FF; cursor: pointer; outline: none; border: none; } #sqlbot-assistant .sqlbot-assistant-tips .sqlbot-assistant-button button::after{ border: none; } #sqlbot-assistant .sqlbot-assistant-tips .sqlbot-assistant-close { position: absolute; right: 20px; top: 20px; cursor: pointer; } #sqlbot-assistant-chat-container { width: 450px; height: 600px; display:none; } @media only screen and (max-width: 768px) { #sqlbot-assistant-chat-container { width: 100%; height: 70%; right: 0 !important; } } #sqlbot-assistant .sqlbot-assistant-chat-button{ position: fixed; ${data.x_type}: ${data.x_value}px; ${data.y_type}: ${data.y_value}px; cursor: pointer; z-index:10000; } #sqlbot-assistant #sqlbot-assistant-chat-container{ z-index:10000;position: relative; border-radius: 8px; border: 1px solid #ffffff; background: linear-gradient(188deg, rgba(235, 241, 255, 0.20) 39.6%, rgba(231, 249, 255, 0.20) 94.3%), #EFF0F1; box-shadow: 0px 4px 8px 0px rgba(31, 35, 41, 0.10); position: fixed;bottom: 16px;right: 16px;overflow: hidden; } #sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-operate{ top: 18px; right: 15px; position: absolute; display: flex; align-items: center; line-height: 18px; } #sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-operate .sqlbot-assistant-chat-close{ margin-left:15px; cursor: pointer; } #sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-operate .sqlbot-assistant-openviewport{ cursor: pointer; } #sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-operate .sqlbot-assistant-closeviewport{ cursor: pointer; } #sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-viewportnone{ display:none; } #sqlbot-assistant #sqlbot-assistant-chat-container #sqlbot-assistant-chat-iframe-${data.id}{ height:100%; width:100%; border: none; } #sqlbot-assistant #sqlbot-assistant-chat-container { animation: appear .4s ease-in-out; } @keyframes appear { from { height: 0;; } to { height: 600px; } }`.replaceAll('#sqlbot-assistant ', `#${sqlbot_assistantId} `) root.appendChild(style) } function getParam(src, key) { const url = new URL(src) return url.searchParams.get(key) } function parsrCertificate(config) { const certificateList = config.certificate if (!certificateList?.length) { return null } const list = certificateList.map((item) => formatCertificate(item)).filter((item) => !!item) return JSON.stringify(list) } function isEmpty(obj) { return obj == null || typeof obj == 'undefined' } function formatCertificate(item) { const { type, source, target, target_key, target_val } = item let source_val = null if (type.toLocaleLowerCase() == 'localstorage') { source_val = localStorage.getItem(source) } if (type.toLocaleLowerCase() == 'sessionstorage') { source_val = sessionStorage.getItem(source) } if (type.toLocaleLowerCase() == 'cookie') { source_val = getCookie(source) } if (type.toLocaleLowerCase() == 'custom') { source_val = source } if (isEmpty(source_val)) { return null } return { target, key: target_key || source, value: (target_val && eval(target_val)) || source_val, } } function getCookie(key) { if (!key || !document.cookie) { return null } const cookies = document.cookie.split(';') for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim() if (cookie.startsWith(key + '=')) { return decodeURIComponent(cookie.substring(key.length + 1)) } } return null } function registerMessageEvent(id, data) { const iframe = document.getElementById(`sqlbot-assistant-chat-iframe-${id}`) const url = iframe.src const eventName = 'sqlbot_assistant_event' window.addEventListener('message', (event) => { if (event.data?.eventName === eventName) { if (event.data?.messageId !== id) { return } if (event.data?.busi == 'ready' && event.data?.ready) { const certificate = parsrCertificate(data) console.log(certificate) params = { busi: 'certificate', certificate, eventName, messageId: id, } const contentWindow = iframe.contentWindow contentWindow.postMessage(params, url) } } }) } function loadScript(src, id) { const domain_url = getDomain(src) let url = `${domain_url}/api/v1/system/assistant/info/${id}` if (domain_url.includes('5173')) { url = url.replace('5173', '8000') } fetch(url) .then((response) => response.json()) .then((res) => { const data = res.data const config_json = data.configuration let tempData = Object.assign(defaultData, { id, domain_url }) if (config_json) { const config = JSON.parse(config_json) Object.assign(tempData, config) tempData = Object.assign(tempData, config) } initsqlbot_assistant(tempData) if (data.type == 1) { registerMessageEvent(id, tempData) // postMessage the certificate to iframe } }) } function getDomain(src) { return src.substring(0, src.indexOf('/assistant.js')) } function init() { const sqlbotScripts = document.querySelectorAll(`script[id^="${script_id_prefix}"]`) const scriptsArray = Array.from(sqlbotScripts) const src_list = scriptsArray.map((script) => script.src) src_list.forEach((src) => { const id = getParam(src, 'id') const propName = script_id_prefix + id + '-state' if (window[propName]) { return true } window[propName] = true loadScript(src, id) }) } window.addEventListener('load', init) })()