mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 01:06:59 +08:00
feat: Assistant embedded
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite-sqlbot.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>SQLBot</title>
|
||||
</head>
|
||||
<body style="height: 100vh">
|
||||
<div id="sqlbot_embedded_app"></div>
|
||||
<script type="module" src="/src/main_assistant.ts"></script>
|
||||
</body>
|
||||
<style>
|
||||
#sqlbot_embedded_app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1752032446737" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4503" width="256" height="256" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M974.754909 315.345455c108.613818 232.913455 7.842909 509.789091-225.093818 618.402909A465.454545 465.454545 0 0 1 230.4 847.546182a46.545455 46.545455 0 0 1 64.488727-67.118546 372.363636 372.363636 0 0 0 415.418182 68.957091c186.344727-86.877091 266.961455-308.363636 180.084364-494.708363C803.490909 168.331636 582.004364 87.738182 395.636364 174.615273a371.805091 371.805091 0 0 0-188.462546 199.377454l63.069091 5.306182a23.272727 23.272727 0 0 1 17.198546 36.468364l-123.857455 178.269091a46.312727 46.312727 0 0 1-41.588364 19.781818 41.634909 41.634909 0 0 1-35.770181-26.926546L12.893091 391.051636a23.272727 23.272727 0 0 1 23.738182-31.371636l74.472727 6.260364A464.896 464.896 0 0 1 356.305455 90.251636C589.265455-18.385455 866.141091 82.385455 974.754909 315.322182zM529.733818 232.727273a46.545455 46.545455 0 0 1 46.405818 43.054545l0.139637 3.490909v228.887273l139.473454 79.802182a46.545455 46.545455 0 0 1 18.967273 60.276363l-1.675636 3.258182a46.545455 46.545455 0 0 1-60.276364 18.944l-3.258182-1.675636-151.179636-86.481455a69.818182 69.818182 0 0 1-35.002182-55.924363l-0.139636-4.677818V279.272727a46.545455 46.545455 0 0 1 46.545454-46.545454z" fill="" p-id="4504"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,11 @@
|
||||
import { createApp } from 'vue'
|
||||
import './style.less'
|
||||
import App from './App.vue'
|
||||
import router from './router/assistant'
|
||||
import { i18n } from './i18n'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(router)
|
||||
app.use(i18n)
|
||||
app.mount('#sqlbot_embedded_app')
|
||||
@@ -0,0 +1,21 @@
|
||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||
|
||||
import assistant from '@/views/embedded/assistant.vue'
|
||||
import { watchRouter } from './watch_assistant'
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'index',
|
||||
component: assistant,
|
||||
},
|
||||
{
|
||||
path: '/assistant',
|
||||
name: 'assistant',
|
||||
component: assistant,
|
||||
},
|
||||
],
|
||||
})
|
||||
watchRouter(router)
|
||||
export default router
|
||||
@@ -0,0 +1,32 @@
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
|
||||
import { request } from '@/utils/request'
|
||||
|
||||
export const watchRouter = (router: any) => {
|
||||
router.beforeEach(async (to: any, from: any, next: any) => {
|
||||
console.log(to, from)
|
||||
await loadXpackStatic()
|
||||
next()
|
||||
})
|
||||
}
|
||||
const loadXpackStatic = () => {
|
||||
if (document.getElementById('sqlbot_xpack_static')) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
const url = '/xpack_static/license-generator.umd.js'
|
||||
return new Promise((resolve, reject) => {
|
||||
request
|
||||
.loadRemoteScript(url, 'sqlbot_xpack_static', () => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
LicenseGenerator?.init(import.meta.env.VITE_API_BASE_URL).then(() => {
|
||||
resolve(true)
|
||||
})
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to load xpack_static script:', error)
|
||||
ElMessage.error('Failed to load license generator script')
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -645,6 +645,20 @@ const handleCtrlEnter = (e: KeyboardEvent) => {
|
||||
textarea.selectionStart = textarea.selectionEnd = start + 1
|
||||
})
|
||||
}
|
||||
|
||||
const getHistoryList = () => {
|
||||
return chatList.value
|
||||
}
|
||||
const getCurrentChatId = () => {
|
||||
return currentChatId.value
|
||||
}
|
||||
defineExpose({
|
||||
getHistoryList,
|
||||
onClickHistory,
|
||||
onChatDeleted,
|
||||
onChatRenamed,
|
||||
getCurrentChatId,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<div class="sqlbot-assistant-container">
|
||||
<div class="head">
|
||||
<div class="flex align-center">
|
||||
<div class="head-img-div">
|
||||
<img :src="AssistantGif" />
|
||||
</div>
|
||||
<h4>SQLBot 小助手</h4>
|
||||
</div>
|
||||
</div>
|
||||
<chat-component ref="chatRef" class="sqlbot-chat-container" />
|
||||
</div>
|
||||
<div class="sqlbot-top-btn">
|
||||
<el-icon style="cursor: pointer" @click="openHistory">
|
||||
<history></history>
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="sqlbot-history-container">
|
||||
<el-drawer
|
||||
v-model="drawer"
|
||||
:append-to-body="false"
|
||||
class="sqlbot-history-drawer"
|
||||
modal-class="sqlbot-history-modal"
|
||||
title=""
|
||||
direction="ttb"
|
||||
:with-header="false"
|
||||
>
|
||||
<div class="sqlbot-history-title">
|
||||
<span>历史记录</span>
|
||||
</div>
|
||||
<div class="sqlbot-history-content">
|
||||
<div v-if="!chatList.length" class="history-empty">
|
||||
<span>暂无历史记录</span>
|
||||
</div>
|
||||
<div v-else class="sqlbot-chat-list-inner">
|
||||
<el-scrollbar max-height="350px" class="sqlbot-chat-scroller">
|
||||
<template v-for="chat in chatList" :key="chat.id">
|
||||
<div
|
||||
class="chat-list-item"
|
||||
:class="{ 'is-active-chat': currentId === chat.id }"
|
||||
@click="onClickHistory(chat)"
|
||||
>
|
||||
<span class="title">{{ chat.brief ?? 'Untitled' }}</span>
|
||||
<div class="history-operate">
|
||||
<el-icon @click="EditPen(chat)"><IconOpeEdit /></el-icon>
|
||||
<el-icon @click="Delete(chat)"><IconOpeDelete /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import ChatComponent from '@/views/chat/index.vue'
|
||||
import AssistantGif from '@/assets/img/assistant.gif'
|
||||
import history from '@/assets/svg/chart/history.svg'
|
||||
import IconOpeEdit from '@/assets/svg/operate/ope-edit.svg'
|
||||
import IconOpeDelete from '@/assets/svg/operate/ope-delete.svg'
|
||||
|
||||
const chatRef = ref()
|
||||
const chatList = ref<Array<any>>([])
|
||||
const drawer = ref(false)
|
||||
const currentId = ref()
|
||||
|
||||
const openHistory = () => {
|
||||
chatList.value = chatRef.value?.getHistoryList()
|
||||
currentId.value = chatRef.value?.getCurrentChatId()
|
||||
drawer.value = true
|
||||
}
|
||||
const onClickHistory = (chat: any) => {
|
||||
chatRef.value?.onClickHistory(chat)
|
||||
}
|
||||
|
||||
const EditPen = (chat: any) => {
|
||||
chatRef.value?.onChatRenamed(chat)
|
||||
}
|
||||
const Delete = (chat: any) => {
|
||||
chatRef.value?.onChatDeleted(chat.id)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sqlbot-assistant-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
color: rgb(31, 35, 41);
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
.head {
|
||||
background: linear-gradient(90deg, #ebf1ff 24.34%, #e5fbf8 56.18%, #f2ebfe 90.18%);
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
height: 56px;
|
||||
line-height: 56px;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1px solid #dee0e3;
|
||||
.align-center {
|
||||
align-items: center;
|
||||
.head-img-div {
|
||||
display: flex;
|
||||
margin-left: 24px;
|
||||
img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.sqlbot-chat-container {
|
||||
padding-top: 56px;
|
||||
:deep(.ed-aside) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.sqlbot-top-btn {
|
||||
right: 85px;
|
||||
z-index: 2009;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
// right: 16px;
|
||||
font-size: 22px;
|
||||
}
|
||||
.sqlbot-history-container {
|
||||
width: 100%;
|
||||
:deep(.sqlbot-history-modal) {
|
||||
top: 56px !important;
|
||||
}
|
||||
:deep(.sqlbot-history-title) {
|
||||
border-bottom: 1px solid #dee0e3;
|
||||
padding: 16px 24px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #1f2329;
|
||||
}
|
||||
:deep(.ed-drawer__body) {
|
||||
padding: 0 !important;
|
||||
}
|
||||
:deep(.sqlbot-history-drawer) {
|
||||
height: fit-content !important;
|
||||
.sqlbot-history-content {
|
||||
padding: 16px;
|
||||
.history-empty {
|
||||
height: 60px;
|
||||
color: #8f959e !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
.is-active-chat {
|
||||
background-color: #ebf1ff;
|
||||
color: #3370ff;
|
||||
font-weight: 500;
|
||||
}
|
||||
.chat-list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 8px;
|
||||
font-size: 14px;
|
||||
color: #1f2329;
|
||||
justify-content: space-between;
|
||||
.history-operate {
|
||||
display: none;
|
||||
}
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
background: rgba(31, 35, 41, 0.1);
|
||||
.history-operate {
|
||||
padding-right: 16px;
|
||||
display: flex;
|
||||
column-gap: 16px;
|
||||
align-items: center;
|
||||
font-size: 18px;
|
||||
i {
|
||||
color: #8f959e;
|
||||
&:hover {
|
||||
color: #8f959e99;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
+4
-10
@@ -39,6 +39,10 @@ export default defineConfig(({ mode }) => {
|
||||
build: {
|
||||
chunkSizeWarningLimit: 2000,
|
||||
rollupOptions: {
|
||||
input: {
|
||||
main: path.resolve(__dirname, 'index.html'),
|
||||
assistant: path.resolve(__dirname, 'assistant.html'),
|
||||
},
|
||||
output: {
|
||||
manualChunks: {
|
||||
'element-plus-secondary': ['element-plus-secondary'],
|
||||
@@ -46,16 +50,6 @@ export default defineConfig(({ mode }) => {
|
||||
},
|
||||
},
|
||||
},
|
||||
// server: {
|
||||
// proxy: {
|
||||
// '/api': {
|
||||
// target: 'https://sqlbot.fit2cloud.cn',
|
||||
// changeOrigin: true,
|
||||
// rewrite: path => path.replace(/^\/api/, 'api')
|
||||
// }
|
||||
// },
|
||||
// port: 8080
|
||||
// },
|
||||
esbuild: {
|
||||
jsxFactory: 'h',
|
||||
jsxFragment: 'Fragment',
|
||||
|
||||
Reference in New Issue
Block a user