Skip to content

Commit e6085a4

Browse files
style: Assistant embedded with appearance configuration
1 parent 5783f3e commit e6085a4

File tree

6 files changed

+150
-102
lines changed

6 files changed

+150
-102
lines changed

backend/apps/system/api/assistant.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ async def ui(session: SessionDep, data: str = Form(), files: List[UploadFile] =
104104
db_model.configuration = json.dumps(config_obj, ensure_ascii=False)
105105
session.add(db_model)
106106
session.commit()
107+
await clear_ui_cache(db_model.id)
108+
109+
@clear_cache(namespace=CacheNamespace.EMBEDDED_INFO, cacheName=CacheName.ASSISTANT_INFO, keyExpression="id")
110+
async def clear_ui_cache(id: int):
111+
pass
107112

108113
@router.get("", response_model=list[AssistantModel])
109114
async def query(session: SessionDep):
@@ -112,7 +117,7 @@ async def query(session: SessionDep):
112117

113118
@router.post("")
114119
async def add(request: Request, session: SessionDep, creator: AssistantBase):
115-
save(request, session, creator)
120+
await save(request, session, creator)
116121

117122

118123
@router.put("")

frontend/public/assistant.js

Lines changed: 95 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
header_font_color: 'rgb(100, 106, 115)',
99
x_type: 'right',
1010
y_type: 'bottom',
11-
x_value: '-5',
12-
y_value: '33',
11+
x_val: '30',
12+
y_val: '30',
13+
float_icon_drag: false,
1314
}
1415
const script_id_prefix = 'sqlbot-assistant-float-script-'
1516
const guideHtml = `
@@ -35,8 +36,8 @@
3536

3637
const chatButtonHtml = (data) => `
3738
<div class="sqlbot-assistant-chat-button">
38-
<img style="height:100%;width:100%;display:none;" src="${data.float_icon}">
39-
<svg style="display:none;margin-right: 20px;" data-v-39a51454="" xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="none">
39+
<img style="height:30px;width:30px;display:none;" src="${data.float_icon}">
40+
<svg style="display:none;" data-v-39a51454="" xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="none">
4041
<path fill="#149CC5" d="M28.333 13.669h-.231c.138.758.207 1.527.206 2.298.005.946-.107 1.89-.335 2.808h.65a1.05 1.05 0 0 0 1.05-1.05V15.01a1.343 1.343 0 0 0-1.34-1.341"></path>
4142
<path fill="#69CAA4" d="M1.692 15.967c0-.77.068-1.54.206-2.298h-.23a1.34 1.34 0 0 0-1.342 1.34v2.716a1.05 1.05 0 0 0 1.05 1.05h.651a11.4 11.4 0 0 1-.335-2.808"></path>
4243
<path fill="url(#a)" d="M15 3.795c-6.89 0-12.474 5.282-12.474 12.171 0 6.89 5.585 10.239 12.474 10.239s12.474-3.35 12.474-10.238c0-6.89-5.585-12.172-12.474-12.172m3.026 17.33h-6.052a6 6 0 0 1-2.484-.535c-.564-.256-2.208.282-2.663-.127-.551-.495.117-1.969-.221-2.636a6.014 6.014 0 0 1 5.368-8.73h6.052a6.014 6.014 0 0 1 0 12.029"></path>
@@ -158,16 +159,16 @@
158159
}
159160
const drag = (e) => {
160161
if (['touchmove', 'touchstart'].includes(e.type)) {
161-
chat_button.style.top = e.touches[0].clientY - chat_button_img.naturalHeight / 2 + 'px'
162-
chat_button.style.left = e.touches[0].clientX - chat_button_img.naturalWidth / 2 + 'px'
162+
chat_button.style.top = e.touches[0].clientY - chat_button_img.clientHeight / 2 + 'px'
163+
chat_button.style.left = e.touches[0].clientX - chat_button_img.clientHeight / 2 + 'px'
163164
} else {
164-
chat_button.style.top = e.y - chat_button_img.naturalHeight / 2 + 'px'
165-
chat_button.style.left = e.x - chat_button_img.naturalWidth / 2 + 'px'
165+
chat_button.style.top = e.y - chat_button_img.clientHeight / 2 + 'px'
166+
chat_button.style.left = e.x - chat_button_img.clientHeight / 2 + 'px'
166167
}
167-
chat_button.style.width = chat_button_img.naturalWidth + 'px'
168-
chat_button.style.height = chat_button_img.naturalHeight + 'px'
168+
chat_button.style.width = chat_button_img.clientHeight + 'px'
169+
chat_button.style.height = chat_button_img.clientHeight + 'px'
169170
}
170-
if (data.is_draggable) {
171+
if (data.float_icon_drag) {
171172
chat_button.addEventListener('drag', drag)
172173
chat_button.addEventListener('dragover', (e) => {
173174
e.preventDefault()
@@ -234,14 +235,14 @@
234235
height: 64px;
235236
box-shadow: 1px 1px 1px 9999px rgba(0,0,0,.6);
236237
position: absolute;
237-
${data.x_type}: ${data.x_value}px;
238-
${data.y_type}: ${data.y_value}px;
238+
${data.x_type}: ${data.x_val}px;
239+
${data.y_type}: ${data.y_val}px;
239240
z-index: 10001;
240241
}
241242
#sqlbot-assistant .sqlbot-assistant-tips {
242243
position: fixed;
243-
${data.x_type}:calc(${data.x_value}px + 75px);
244-
${data.y_type}: calc(${data.y_value}px + 0px);
244+
${data.x_type}:calc(${data.x_val}px + 75px);
245+
${data.y_type}: calc(${data.y_val}px + 0px);
245246
padding: 22px 24px 24px;
246247
border-radius: 6px;
247248
color: #ffffff;
@@ -297,76 +298,76 @@
297298
display:none;
298299
}
299300
@media only screen and (max-width: 768px) {
300-
#sqlbot-assistant-chat-container {
301-
width: 100%;
302-
height: 70%;
303-
right: 0 !important;
304-
}
305-
}
306-
307-
#sqlbot-assistant .sqlbot-assistant-chat-button{
308-
position: fixed;
309-
${data.x_type}: ${data.x_value}px;
310-
${data.y_type}: ${data.y_value}px;
311-
cursor: pointer;
312-
z-index:10000;
313-
}
314-
#sqlbot-assistant #sqlbot-assistant-chat-container{
315-
z-index:10000;position: relative;
316-
border-radius: 8px;
317-
//border: 1px solid #ffffff;
318-
background: linear-gradient(188deg, rgba(235, 241, 255, 0.20) 39.6%, rgba(231, 249, 255, 0.20) 94.3%), #EFF0F1;
319-
box-shadow: 0px 4px 8px 0px rgba(31, 35, 41, 0.10);
320-
position: fixed;bottom: 16px;right: 16px;overflow: hidden;
301+
#sqlbot-assistant-chat-container {
302+
width: 100%;
303+
height: 70%;
304+
right: 0 !important;
321305
}
306+
}
322307
323-
.ed-overlay-dialog {
324-
margin-top: 50px;
325-
}
326-
.ed-drawer {
327-
margin-top: 50px;
328-
}
308+
#sqlbot-assistant .sqlbot-assistant-chat-button{
309+
position: fixed;
310+
${data.x_type}: ${data.x_val}px;
311+
${data.y_type}: ${data.y_val}px;
312+
cursor: pointer;
313+
z-index:10000;
314+
}
315+
#sqlbot-assistant #sqlbot-assistant-chat-container{
316+
z-index:10000;position: relative;
317+
border-radius: 8px;
318+
//border: 1px solid #ffffff;
319+
background: linear-gradient(188deg, rgba(235, 241, 255, 0.20) 39.6%, rgba(231, 249, 255, 0.20) 94.3%), #EFF0F1;
320+
box-shadow: 0px 4px 8px 0px rgba(31, 35, 41, 0.10);
321+
position: fixed;bottom: 16px;right: 16px;overflow: hidden;
322+
}
329323
330-
#sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-operate{
331-
top: 18px;
332-
right: 15px;
333-
position: absolute;
334-
display: flex;
335-
align-items: center;
336-
line-height: 18px;
337-
}
338-
#sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-operate .sqlbot-assistant-chat-close{
339-
margin-left:15px;
340-
cursor: pointer;
341-
}
342-
#sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-operate .sqlbot-assistant-openviewport{
324+
.ed-overlay-dialog {
325+
margin-top: 50px;
326+
}
327+
.ed-drawer {
328+
margin-top: 50px;
329+
}
343330
344-
cursor: pointer;
345-
}
346-
#sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-operate .sqlbot-assistant-closeviewport{
331+
#sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-operate{
332+
top: 18px;
333+
right: 15px;
334+
position: absolute;
335+
display: flex;
336+
align-items: center;
337+
line-height: 18px;
338+
}
339+
#sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-operate .sqlbot-assistant-chat-close{
340+
margin-left:15px;
341+
cursor: pointer;
342+
}
343+
#sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-operate .sqlbot-assistant-openviewport{
347344
348-
cursor: pointer;
349-
}
350-
#sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-viewportnone{
351-
display:none;
345+
cursor: pointer;
346+
}
347+
#sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-operate .sqlbot-assistant-closeviewport{
348+
349+
cursor: pointer;
350+
}
351+
#sqlbot-assistant #sqlbot-assistant-chat-container .sqlbot-assistant-viewportnone{
352+
display:none;
353+
}
354+
#sqlbot-assistant #sqlbot-assistant-chat-container #sqlbot-assistant-chat-iframe-${data.id} {
355+
height:100%;
356+
width:100%;
357+
border: none;
358+
}
359+
#sqlbot-assistant #sqlbot-assistant-chat-container {
360+
animation: appear .4s ease-in-out;
361+
}
362+
@keyframes appear {
363+
from {
364+
height: 0;;
352365
}
353-
#sqlbot-assistant #sqlbot-assistant-chat-container #sqlbot-assistant-chat-iframe-${data.id}{
354-
height:100%;
355-
width:100%;
356-
border: none;
357-
}
358-
#sqlbot-assistant #sqlbot-assistant-chat-container {
359-
animation: appear .4s ease-in-out;
360-
}
361-
@keyframes appear {
362-
from {
363-
height: 0;;
364-
}
365366
366-
to {
367-
height: 600px;
368-
}
369-
}`.replaceAll('#sqlbot-assistant ', `#${sqlbot_assistantId} `)
367+
to {
368+
height: 600px;
369+
}
370+
}`.replaceAll('#sqlbot-assistant ', `#${sqlbot_assistantId} `)
370371
root.appendChild(style)
371372
}
372373
function getParam(src, key) {
@@ -460,14 +461,29 @@
460461
}
461462
const data = res.data
462463
const config_json = data.configuration
463-
let tempData = Object.assign(defaultData, { id, domain_url, name: data.name })
464+
let tempData = Object.assign(defaultData, data)
465+
if (tempData.configuration) {
466+
delete tempData.configuration
467+
}
464468
if (config_json) {
465469
const config = JSON.parse(config_json)
466470
if (config) {
467471
delete config.id
468472
tempData = Object.assign(tempData, config)
469473
}
470474
}
475+
tempData['id'] = id
476+
tempData['domain_url'] = domain_url
477+
478+
if (tempData['float_icon'] && !tempData['float_icon'].startsWith('http://')) {
479+
tempData['float_icon'] =
480+
`${domain_url}/api/v1/system/assistant/picture/${tempData['float_icon']}`
481+
482+
if (domain_url.includes('5173')) {
483+
tempData['float_icon'] = tempData['float_icon'].replace('5173', '8000')
484+
}
485+
}
486+
471487
tempData['online'] = online && online.toString().toLowerCase() == 'true'
472488
initsqlbot_assistant(tempData)
473489
if (data.type == 1) {
Lines changed: 6 additions & 0 deletions
Loading
Lines changed: 6 additions & 0 deletions
Loading

frontend/src/views/chat/index.vue

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,17 @@
105105
</template>
106106

107107
<div v-else class="assistant-desc">
108-
<img :src="logoAssistant" class="logo" width="30px" height="30px" alt="" />
108+
<img
109+
v-if="logoAssistant"
110+
:src="logoAssistant"
111+
class="logo"
112+
width="30px"
113+
height="30px"
114+
alt=""
115+
/>
116+
<el-icon v-else size="32">
117+
<logo_fold />
118+
</el-icon>
109119
<div class="i-am">{{ welcome }}</div>
110120
<div class="i-can">{{ welcomeDesc }}</div>
111121
</div>

frontend/src/views/embedded/index.vue

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div class="sqlbot-assistant-container">
3-
<div class="header">
3+
<div class="header" :style="{ color: customSet.header_font_color }">
44
<el-icon size="20" @click="openHistory">
55
<icon_sidebar_outlined></icon_sidebar_outlined>
66
</el-icon>
@@ -30,13 +30,14 @@ import { onBeforeMount, nextTick, onBeforeUnmount, ref, onMounted, reactive } fr
3030
import ChatComponent from '@/views/chat/index.vue'
3131
import { request } from '@/utils/request'
3232
import LOGO from '@/assets/embedded/LOGO.png'
33-
import icon_sidebar_outlined from '@/assets/embedded/icon_sidebar_outlined.svg'
33+
import icon_sidebar_outlined from '@/assets/embedded/icon_sidebar_outlined_nofill.svg'
3434
import icon_new_chat_outlined from '@/assets/svg/icon_new_chat_outlined.svg'
3535
import { useRoute } from 'vue-router'
3636
import { assistantApi } from '@/api/assistant'
3737
import { useAssistantStore } from '@/stores/assistant'
3838
import { setCurrentColor } from '@/utils/utils'
39-
39+
import { useI18n } from 'vue-i18n'
40+
const { t } = useI18n()
4041
const assistantStore = useAssistantStore()
4142
const route = useRoute()
4243
const chatRef = ref()
@@ -101,8 +102,8 @@ onMounted(() => {
101102
})
102103
const customSet = reactive({
103104
name: '',
104-
welcome: '',
105-
welcome_desc: '',
105+
welcome: t('embedded.i_am_sqlbot'),
106+
welcome_desc: t('embedded.data_analysis_now'),
106107
theme: '#1CBA90',
107108
header_font_color: '#1F2329',
108109
}) as { [key: string]: any }
@@ -124,23 +125,7 @@ onBeforeMount(async () => {
124125
ElMessage.error('Miss assistant id, please check assistant url')
125126
return
126127
}
127-
request.get(`/system/assistant/info/${assistantId}`).then((res) => {
128-
if (res?.configuration) {
129-
const rawData = JSON.parse(res?.configuration)
130-
logo.value = baseUrl + rawData.logo
131-
132-
for (const key in customSet) {
133-
if (Object.prototype.hasOwnProperty.call(customSet, key) && rawData[key]) {
134-
customSet[key] = rawData[key]
135-
}
136-
}
137128
138-
nextTick(() => {
139-
setPageCustomColor(customSet.theme)
140-
setPageHeaderFontColor(customSet.header_font_color)
141-
})
142-
}
143-
})
144129
const online = route.query.online
145130
setFormatOnline(online)
146131
@@ -165,6 +150,26 @@ onBeforeMount(async () => {
165150
messageId: assistantId,
166151
}
167152
window.parent.postMessage(readyData, '*')
153+
154+
request.get(`/system/assistant/${assistantId}`).then((res) => {
155+
if (res?.configuration) {
156+
const rawData = JSON.parse(res?.configuration)
157+
if (rawData.logo) {
158+
logo.value = baseUrl + rawData.logo
159+
}
160+
161+
for (const key in customSet) {
162+
if (Object.prototype.hasOwnProperty.call(customSet, key) && rawData[key]) {
163+
customSet[key] = rawData[key]
164+
}
165+
}
166+
167+
nextTick(() => {
168+
setPageCustomColor(customSet.theme)
169+
setPageHeaderFontColor(customSet.header_font_color)
170+
})
171+
}
172+
})
168173
})
169174
170175
onBeforeUnmount(() => {

0 commit comments

Comments
 (0)