feat chat ui (#3253)
This commit is contained in:
parent
4948051f67
commit
9558e4053d
@ -175,8 +175,7 @@ class Workflow:
|
|||||||
return Workflow(nodes, edges)
|
return Workflow(nodes, edges)
|
||||||
|
|
||||||
def get_start_node(self):
|
def get_start_node(self):
|
||||||
start_node_list = [node for node in self.nodes if node.id == 'start-node']
|
return self.get_node('start-node')
|
||||||
return start_node_list[0]
|
|
||||||
|
|
||||||
def get_search_node(self):
|
def get_search_node(self):
|
||||||
return [node for node in self.nodes if node.type == 'search-dataset-node']
|
return [node for node in self.nodes if node.type == 'search-dataset-node']
|
||||||
|
|||||||
14
ui/chat.html
Normal file
14
ui/chat.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<base target="_blank" />
|
||||||
|
<title>%VITE_APP_TITLE%</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/chat.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
3
ui/env/.env
vendored
3
ui/env/.env
vendored
@ -1,4 +1,5 @@
|
|||||||
VITE_APP_NAME=ui
|
VITE_APP_NAME=ui
|
||||||
VITE_BASE_PATH=/ui/
|
VITE_BASE_PATH=/ui/
|
||||||
VITE_APP_PORT=3000
|
VITE_APP_PORT=3000
|
||||||
VITE_APP_TITLE = 'MaxKB'
|
VITE_APP_TITLE = 'MaxKB'
|
||||||
|
VITE_INPUT="index.html"
|
||||||
5
ui/env/.env.chat
vendored
Normal file
5
ui/env/.env.chat
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
VITE_APP_NAME=chat
|
||||||
|
VITE_BASE_PATH=/chat/
|
||||||
|
VITE_APP_PORT=3000
|
||||||
|
VITE_APP_TITLE = 'MaxKB'
|
||||||
|
VITE_INPUT="chat.html"
|
||||||
@ -5,9 +5,12 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
"chat": "vite --mode chat",
|
||||||
"build": "run-p type-check \"build-only {@}\" --",
|
"build": "run-p type-check \"build-only {@}\" --",
|
||||||
|
"build-chat": "run-p type-check \"build-only-chat {@}\" --",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"build-only": "vite build",
|
"build-only": "vite build",
|
||||||
|
"build-only-chat": "vite build --mode chat",
|
||||||
"type-check": "vue-tsc --build",
|
"type-check": "vue-tsc --build",
|
||||||
"lint": "eslint . --fix",
|
"lint": "eslint . --fix",
|
||||||
"format": "prettier --write src/"
|
"format": "prettier --write src/"
|
||||||
@ -39,6 +42,7 @@
|
|||||||
"screenfull": "^6.0.2",
|
"screenfull": "^6.0.2",
|
||||||
"sortablejs": "^1.15.6",
|
"sortablejs": "^1.15.6",
|
||||||
"use-element-plus-theme": "^0.0.5",
|
"use-element-plus-theme": "^0.0.5",
|
||||||
|
"vite-plugin-html": "^3.2.2",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-clipboard3": "^2.0.0",
|
"vue-clipboard3": "^2.0.0",
|
||||||
"vue-codemirror": "^6.1.1",
|
"vue-codemirror": "^6.1.1",
|
||||||
|
|||||||
65
ui/src/chat.ts
Normal file
65
ui/src/chat.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import '@/styles/index.scss'
|
||||||
|
import ElementPlus from 'element-plus'
|
||||||
|
import * as ElementPlusIcons from '@element-plus/icons-vue'
|
||||||
|
import zhCn from 'element-plus/es/locale/lang/zh-cn'
|
||||||
|
import enUs from 'element-plus/es/locale/lang/en'
|
||||||
|
import zhTW from 'element-plus/es/locale/lang/zh-tw'
|
||||||
|
import { createApp } from 'vue'
|
||||||
|
import { createPinia } from 'pinia'
|
||||||
|
import App from './App.vue'
|
||||||
|
import router from '@/router/chat'
|
||||||
|
import i18n from '@/locales'
|
||||||
|
import Components from '@/components'
|
||||||
|
import directives from '@/directives'
|
||||||
|
|
||||||
|
import { config } from 'md-editor-v3'
|
||||||
|
import screenfull from 'screenfull'
|
||||||
|
|
||||||
|
import katex from 'katex'
|
||||||
|
import 'katex/dist/katex.min.css'
|
||||||
|
|
||||||
|
import Cropper from 'cropperjs'
|
||||||
|
|
||||||
|
import mermaid from 'mermaid'
|
||||||
|
|
||||||
|
import highlight from 'highlight.js'
|
||||||
|
import 'highlight.js/styles/atom-one-dark.css'
|
||||||
|
|
||||||
|
config({
|
||||||
|
editorExtensions: {
|
||||||
|
highlight: {
|
||||||
|
instance: highlight,
|
||||||
|
},
|
||||||
|
screenfull: {
|
||||||
|
instance: screenfull,
|
||||||
|
},
|
||||||
|
katex: {
|
||||||
|
instance: katex,
|
||||||
|
},
|
||||||
|
cropper: {
|
||||||
|
instance: Cropper,
|
||||||
|
},
|
||||||
|
mermaid: {
|
||||||
|
instance: mermaid,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const app = createApp(App)
|
||||||
|
app.use(createPinia())
|
||||||
|
for (const [key, component] of Object.entries(ElementPlusIcons)) {
|
||||||
|
app.component(key, component)
|
||||||
|
}
|
||||||
|
const locale_map: any = {
|
||||||
|
'zh-CN': zhCn,
|
||||||
|
'zh-Hant': zhTW,
|
||||||
|
'en-US': enUs,
|
||||||
|
}
|
||||||
|
app.use(ElementPlus, {
|
||||||
|
locale: locale_map[localStorage.getItem('MaxKB-locale') || navigator.language || 'en-US'],
|
||||||
|
})
|
||||||
|
app.use(directives)
|
||||||
|
app.use(router)
|
||||||
|
app.use(i18n)
|
||||||
|
app.use(Components)
|
||||||
|
app.mount('#app')
|
||||||
|
export { app }
|
||||||
82
ui/src/router/chat/index.ts
Normal file
82
ui/src/router/chat/index.ts
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import { hasPermission } from '@/utils/permission/index'
|
||||||
|
import NProgress from 'nprogress'
|
||||||
|
import {
|
||||||
|
createRouter,
|
||||||
|
createWebHistory,
|
||||||
|
type NavigationGuardNext,
|
||||||
|
type RouteLocationNormalized,
|
||||||
|
type RouteRecordRaw,
|
||||||
|
type RouteRecordName,
|
||||||
|
} from 'vue-router'
|
||||||
|
import useStore from '@/stores'
|
||||||
|
import { routes } from '@/router/chat/routes'
|
||||||
|
NProgress.configure({ showSpinner: false, speed: 500, minimum: 0.3 })
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
|
routes: routes,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 路由前置拦截器
|
||||||
|
router.beforeEach(
|
||||||
|
async (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
|
||||||
|
NProgress.start()
|
||||||
|
if (to.name === '404') {
|
||||||
|
next()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { user, login } = useStore()
|
||||||
|
|
||||||
|
const notAuthRouteNameList = ['login', 'ForgotPassword', 'ResetPassword', 'Chat', 'UserLogin']
|
||||||
|
if (!notAuthRouteNameList.includes(to.name ? to.name.toString() : '')) {
|
||||||
|
if (to.query && to.query.token) {
|
||||||
|
localStorage.setItem('token', to.query.token.toString())
|
||||||
|
}
|
||||||
|
const token = login.getToken()
|
||||||
|
if (!token) {
|
||||||
|
next({
|
||||||
|
path: '/login',
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!user.userInfo) {
|
||||||
|
await user.profile()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 判断是否有菜单权限
|
||||||
|
if (to.meta.permission ? hasPermission(to.meta.permission as any, 'OR') : true) {
|
||||||
|
next()
|
||||||
|
} else {
|
||||||
|
// 如果没有权限则直接取404页面
|
||||||
|
next('404')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
router.afterEach(() => {
|
||||||
|
NProgress.done()
|
||||||
|
})
|
||||||
|
|
||||||
|
export const getChildRouteListByPathAndName = (path: any, name?: RouteRecordName | any) => {
|
||||||
|
return getChildRouteList(routes, path, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getChildRouteList: (
|
||||||
|
routeList: Array<RouteRecordRaw>,
|
||||||
|
path: string,
|
||||||
|
name?: RouteRecordName | null | undefined,
|
||||||
|
) => Array<RouteRecordRaw> = (routeList, path, name) => {
|
||||||
|
for (let index = 0; index < routeList.length; index++) {
|
||||||
|
const route = routeList[index]
|
||||||
|
if (name === route.name && path === route.path) {
|
||||||
|
return route.children || []
|
||||||
|
}
|
||||||
|
if (route.children && route.children.length > 0) {
|
||||||
|
const result = getChildRouteList(route.children, path, name)
|
||||||
|
if (result && result?.length > 0) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
export default router
|
||||||
10
ui/src/router/chat/routes.ts
Normal file
10
ui/src/router/chat/routes.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
|
|
||||||
|
export const routes: Array<RouteRecordRaw> = [
|
||||||
|
// 对话
|
||||||
|
{
|
||||||
|
path: '/chat/:accessToken',
|
||||||
|
name: 'Chat',
|
||||||
|
component: () => import('@/views/chat/index.vue'),
|
||||||
|
},
|
||||||
|
]
|
||||||
@ -4,40 +4,44 @@ import { defineConfig, loadEnv } from 'vite'
|
|||||||
import vue from '@vitejs/plugin-vue'
|
import vue from '@vitejs/plugin-vue'
|
||||||
import vueJsx from '@vitejs/plugin-vue-jsx'
|
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||||
import DefineOptions from 'unplugin-vue-define-options/vite'
|
import DefineOptions from 'unplugin-vue-define-options/vite'
|
||||||
|
import path from 'path'
|
||||||
|
import { createHtmlPlugin } from 'vite-plugin-html'
|
||||||
|
|
||||||
// import vueDevTools from 'vite-plugin-vue-devtools'
|
// import vueDevTools from 'vite-plugin-vue-devtools'
|
||||||
const envDir = './env'
|
const envDir = './env'
|
||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig(({ mode }) => {
|
export default defineConfig(({ mode }) => {
|
||||||
|
console.log('ssss')
|
||||||
const ENV = loadEnv(mode, envDir)
|
const ENV = loadEnv(mode, envDir)
|
||||||
const prefix = process.env.VITE_DYNAMIC_PREFIX || ENV.VITE_BASE_PATH
|
const prefix = process.env.VITE_DYNAMIC_PREFIX || ENV.VITE_BASE_PATH
|
||||||
const proxyConf: Record<string, string | ProxyOptions> = {}
|
const proxyConf: Record<string, string | ProxyOptions> = {}
|
||||||
proxyConf['/api'] = {
|
proxyConf['/api'] = {
|
||||||
target: 'http://127.0.0.1:8080',
|
target: 'http://127.0.0.1:8080',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path) => path.replace(ENV.VITE_BASE_PATH, '/'),
|
rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
|
||||||
}
|
}
|
||||||
proxyConf['/oss'] = {
|
proxyConf['/oss'] = {
|
||||||
target: 'http://127.0.0.1:8080',
|
target: 'http://127.0.0.1:8080',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path) => path.replace(ENV.VITE_BASE_PATH, '/'),
|
rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
|
||||||
}
|
}
|
||||||
proxyConf['/doc'] = {
|
proxyConf['/doc'] = {
|
||||||
target: 'http://127.0.0.1:8080',
|
target: 'http://127.0.0.1:8080',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path) => path.replace(ENV.VITE_BASE_PATH, '/'),
|
rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
|
||||||
}
|
}
|
||||||
proxyConf['/static'] = {
|
proxyConf['/static'] = {
|
||||||
target: 'http://127.0.0.1:8080',
|
target: 'http://127.0.0.1:8080',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path) => path.replace(ENV.VITE_BASE_PATH, '/'),
|
rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
preflight: false,
|
preflight: false,
|
||||||
lintOnSave: false,
|
lintOnSave: false,
|
||||||
base: prefix,
|
base: prefix,
|
||||||
envDir: envDir,
|
envDir: envDir,
|
||||||
plugins: [vue(), vueJsx(), DefineOptions()],
|
plugins: [vue(), vueJsx(), DefineOptions(), createHtmlPlugin({ template: ENV.VITE_INPUT })],
|
||||||
server: {
|
server: {
|
||||||
cors: true,
|
cors: true,
|
||||||
host: '0.0.0.0',
|
host: '0.0.0.0',
|
||||||
@ -46,7 +50,10 @@ export default defineConfig(({ mode }) => {
|
|||||||
proxy: proxyConf,
|
proxy: proxyConf,
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
outDir: 'dist/ui',
|
outDir: `dist${ENV.VITE_BASE_PATH}`,
|
||||||
|
rollupOptions: {
|
||||||
|
input: path.resolve(__dirname, ENV.VITE_INPUT),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user