From e6085a4c1b49683e3142b105720d34ce7ffd796a Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Thu, 21 Aug 2025 16:52:26 +0800 Subject: [PATCH] style: Assistant embedded with appearance configuration --- backend/apps/system/api/assistant.py | 7 +- frontend/public/assistant.js | 180 ++++++++++-------- .../embedded/icon_sidebar_outlined_nofill.svg | 6 + .../svg/icon_sidebar_outlined_nofill.svg | 6 + frontend/src/views/chat/index.vue | 12 +- frontend/src/views/embedded/index.vue | 47 +++-- 6 files changed, 153 insertions(+), 105 deletions(-) create mode 100644 frontend/src/assets/embedded/icon_sidebar_outlined_nofill.svg create mode 100644 frontend/src/assets/svg/icon_sidebar_outlined_nofill.svg diff --git a/backend/apps/system/api/assistant.py b/backend/apps/system/api/assistant.py index a2b4dfc9..3b476129 100644 --- a/backend/apps/system/api/assistant.py +++ b/backend/apps/system/api/assistant.py @@ -104,6 +104,11 @@ async def ui(session: SessionDep, data: str = Form(), files: List[UploadFile] = db_model.configuration = json.dumps(config_obj, ensure_ascii=False) session.add(db_model) session.commit() + await clear_ui_cache(db_model.id) + +@clear_cache(namespace=CacheNamespace.EMBEDDED_INFO, cacheName=CacheName.ASSISTANT_INFO, keyExpression="id") +async def clear_ui_cache(id: int): + pass @router.get("", response_model=list[AssistantModel]) async def query(session: SessionDep): @@ -112,7 +117,7 @@ async def query(session: SessionDep): @router.post("") async def add(request: Request, session: SessionDep, creator: AssistantBase): - save(request, session, creator) + await save(request, session, creator) @router.put("") diff --git a/frontend/public/assistant.js b/frontend/public/assistant.js index 4b986199..794289a4 100644 --- a/frontend/public/assistant.js +++ b/frontend/public/assistant.js @@ -8,8 +8,9 @@ header_font_color: 'rgb(100, 106, 115)', x_type: 'right', y_type: 'bottom', - x_value: '-5', - y_value: '33', + x_val: '30', + y_val: '30', + float_icon_drag: false, } const script_id_prefix = 'sqlbot-assistant-float-script-' const guideHtml = ` @@ -35,8 +36,8 @@ const chatButtonHtml = (data) => `
- - + + @@ -158,16 +159,16 @@ } 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' + chat_button.style.top = e.touches[0].clientY - chat_button_img.clientHeight / 2 + 'px' + chat_button.style.left = e.touches[0].clientX - chat_button_img.clientHeight / 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.top = e.y - chat_button_img.clientHeight / 2 + 'px' + chat_button.style.left = e.x - chat_button_img.clientHeight / 2 + 'px' } - chat_button.style.width = chat_button_img.naturalWidth + 'px' - chat_button.style.height = chat_button_img.naturalHeight + 'px' + chat_button.style.width = chat_button_img.clientHeight + 'px' + chat_button.style.height = chat_button_img.clientHeight + 'px' } - if (data.is_draggable) { + if (data.float_icon_drag) { chat_button.addEventListener('drag', drag) chat_button.addEventListener('dragover', (e) => { e.preventDefault() @@ -234,14 +235,14 @@ 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; + ${data.x_type}: ${data.x_val}px; + ${data.y_type}: ${data.y_val}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); + ${data.x_type}:calc(${data.x_val}px + 75px); + ${data.y_type}: calc(${data.y_val}px + 0px); padding: 22px 24px 24px; border-radius: 6px; color: #ffffff; @@ -297,76 +298,76 @@ 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-chat-container { + width: 100%; + height: 70%; + right: 0 !important; } - #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-button{ + position: fixed; + ${data.x_type}: ${data.x_val}px; + ${data.y_type}: ${data.y_val}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; + } + + .ed-overlay-dialog { + margin-top: 50px; + } + .ed-drawer { + margin-top: 50px; + } + + #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;; } - .ed-overlay-dialog { - margin-top: 50px; - } - .ed-drawer { - margin-top: 50px; - } - - #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; + to { + height: 600px; } - #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} `) + }`.replaceAll('#sqlbot-assistant ', `#${sqlbot_assistantId} `) root.appendChild(style) } function getParam(src, key) { @@ -460,7 +461,10 @@ } const data = res.data const config_json = data.configuration - let tempData = Object.assign(defaultData, { id, domain_url, name: data.name }) + let tempData = Object.assign(defaultData, data) + if (tempData.configuration) { + delete tempData.configuration + } if (config_json) { const config = JSON.parse(config_json) if (config) { @@ -468,6 +472,18 @@ tempData = Object.assign(tempData, config) } } + tempData['id'] = id + tempData['domain_url'] = domain_url + + if (tempData['float_icon'] && !tempData['float_icon'].startsWith('http://')) { + tempData['float_icon'] = + `${domain_url}/api/v1/system/assistant/picture/${tempData['float_icon']}` + + if (domain_url.includes('5173')) { + tempData['float_icon'] = tempData['float_icon'].replace('5173', '8000') + } + } + tempData['online'] = online && online.toString().toLowerCase() == 'true' initsqlbot_assistant(tempData) if (data.type == 1) { diff --git a/frontend/src/assets/embedded/icon_sidebar_outlined_nofill.svg b/frontend/src/assets/embedded/icon_sidebar_outlined_nofill.svg new file mode 100644 index 00000000..ad723ea3 --- /dev/null +++ b/frontend/src/assets/embedded/icon_sidebar_outlined_nofill.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/src/assets/svg/icon_sidebar_outlined_nofill.svg b/frontend/src/assets/svg/icon_sidebar_outlined_nofill.svg new file mode 100644 index 00000000..ad723ea3 --- /dev/null +++ b/frontend/src/assets/svg/icon_sidebar_outlined_nofill.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/src/views/chat/index.vue b/frontend/src/views/chat/index.vue index b25f3344..5d6e4e9e 100644 --- a/frontend/src/views/chat/index.vue +++ b/frontend/src/views/chat/index.vue @@ -105,7 +105,17 @@
- + + + +
{{ welcome }}
{{ welcomeDesc }}
diff --git a/frontend/src/views/embedded/index.vue b/frontend/src/views/embedded/index.vue index 2dfb2d88..dfaed1b2 100644 --- a/frontend/src/views/embedded/index.vue +++ b/frontend/src/views/embedded/index.vue @@ -1,6 +1,6 @@