diff --git a/apps/application/flow/common.py b/apps/application/flow/common.py
index 10f612300..98f706fde 100644
--- a/apps/application/flow/common.py
+++ b/apps/application/flow/common.py
@@ -175,8 +175,7 @@ class Workflow:
return Workflow(nodes, edges)
def get_start_node(self):
- start_node_list = [node for node in self.nodes if node.id == 'start-node']
- return start_node_list[0]
+ return self.get_node('start-node')
def get_search_node(self):
return [node for node in self.nodes if node.type == 'search-dataset-node']
diff --git a/ui/chat.html b/ui/chat.html
new file mode 100644
index 000000000..5ab118316
--- /dev/null
+++ b/ui/chat.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+ %VITE_APP_TITLE%
+
+
+
+
+
+
diff --git a/ui/env/.env b/ui/env/.env
index 87cd57582..3fadebde2 100644
--- a/ui/env/.env
+++ b/ui/env/.env
@@ -1,4 +1,5 @@
VITE_APP_NAME=ui
VITE_BASE_PATH=/ui/
VITE_APP_PORT=3000
-VITE_APP_TITLE = 'MaxKB'
\ No newline at end of file
+VITE_APP_TITLE = 'MaxKB'
+VITE_INPUT="index.html"
\ No newline at end of file
diff --git a/ui/env/.env.chat b/ui/env/.env.chat
new file mode 100644
index 000000000..5aef14a8b
--- /dev/null
+++ b/ui/env/.env.chat
@@ -0,0 +1,5 @@
+VITE_APP_NAME=chat
+VITE_BASE_PATH=/chat/
+VITE_APP_PORT=3000
+VITE_APP_TITLE = 'MaxKB'
+VITE_INPUT="chat.html"
\ No newline at end of file
diff --git a/ui/package.json b/ui/package.json
index 272bc79d9..465a8cf9f 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -5,9 +5,12 @@
"type": "module",
"scripts": {
"dev": "vite",
+ "chat": "vite --mode chat",
"build": "run-p type-check \"build-only {@}\" --",
+ "build-chat": "run-p type-check \"build-only-chat {@}\" --",
"preview": "vite preview",
"build-only": "vite build",
+ "build-only-chat": "vite build --mode chat",
"type-check": "vue-tsc --build",
"lint": "eslint . --fix",
"format": "prettier --write src/"
@@ -39,6 +42,7 @@
"screenfull": "^6.0.2",
"sortablejs": "^1.15.6",
"use-element-plus-theme": "^0.0.5",
+ "vite-plugin-html": "^3.2.2",
"vue": "^3.5.13",
"vue-clipboard3": "^2.0.0",
"vue-codemirror": "^6.1.1",
diff --git a/ui/src/chat.ts b/ui/src/chat.ts
new file mode 100644
index 000000000..75032559b
--- /dev/null
+++ b/ui/src/chat.ts
@@ -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 }
diff --git a/ui/src/router/chat/index.ts b/ui/src/router/chat/index.ts
new file mode 100644
index 000000000..b759efeff
--- /dev/null
+++ b/ui/src/router/chat/index.ts
@@ -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,
+ path: string,
+ name?: RouteRecordName | null | undefined,
+) => Array = (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
diff --git a/ui/src/router/chat/routes.ts b/ui/src/router/chat/routes.ts
new file mode 100644
index 000000000..744c54dac
--- /dev/null
+++ b/ui/src/router/chat/routes.ts
@@ -0,0 +1,10 @@
+import type { RouteRecordRaw } from 'vue-router'
+
+export const routes: Array = [
+ // 对话
+ {
+ path: '/chat/:accessToken',
+ name: 'Chat',
+ component: () => import('@/views/chat/index.vue'),
+ },
+]
diff --git a/ui/vite.config.ts b/ui/vite.config.ts
index cb0a3d5bf..ee3d9215c 100644
--- a/ui/vite.config.ts
+++ b/ui/vite.config.ts
@@ -4,40 +4,44 @@ import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
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'
const envDir = './env'
// https://vite.dev/config/
export default defineConfig(({ mode }) => {
+ console.log('ssss')
const ENV = loadEnv(mode, envDir)
const prefix = process.env.VITE_DYNAMIC_PREFIX || ENV.VITE_BASE_PATH
const proxyConf: Record = {}
proxyConf['/api'] = {
target: 'http://127.0.0.1:8080',
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',
changeOrigin: true,
- rewrite: (path) => path.replace(ENV.VITE_BASE_PATH, '/'),
+ rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
}
proxyConf['/doc'] = {
target: 'http://127.0.0.1:8080',
changeOrigin: true,
- rewrite: (path) => path.replace(ENV.VITE_BASE_PATH, '/'),
+ rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
}
proxyConf['/static'] = {
target: 'http://127.0.0.1:8080',
changeOrigin: true,
- rewrite: (path) => path.replace(ENV.VITE_BASE_PATH, '/'),
+ rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
}
return {
preflight: false,
lintOnSave: false,
base: prefix,
envDir: envDir,
- plugins: [vue(), vueJsx(), DefineOptions()],
+ plugins: [vue(), vueJsx(), DefineOptions(), createHtmlPlugin({ template: ENV.VITE_INPUT })],
server: {
cors: true,
host: '0.0.0.0',
@@ -46,7 +50,10 @@ export default defineConfig(({ mode }) => {
proxy: proxyConf,
},
build: {
- outDir: 'dist/ui',
+ outDir: `dist${ENV.VITE_BASE_PATH}`,
+ rollupOptions: {
+ input: path.resolve(__dirname, ENV.VITE_INPUT),
+ },
},
resolve: {
alias: {