From 7789aeaad9032763805da324d743bc664bddd2e8 Mon Sep 17 00:00:00 2001 From: xiangpei <xiangpei@timesnew.cn> Date: 星期五, 18 四月 2025 17:17:26 +0800 Subject: [PATCH] 改为对接java而不是直接调langchain --- src/api/session.js | 39 ++++++ src/api/request.js | 9 src/api/chat.js | 2 vue.config.js | 2 src/components/SessionConfig.vue | 62 ++++++--- src/views/Index.vue | 194 ++++++++++++++++--------------- src/components/AiChat.vue | 16 +- 7 files changed, 195 insertions(+), 129 deletions(-) diff --git a/src/api/chat.js b/src/api/chat.js index 70d5c51..3968614 100644 --- a/src/api/chat.js +++ b/src/api/chat.js @@ -3,7 +3,7 @@ // 鍙戦�佺煡璇嗗簱闂 export const sendKbMsg = (data) => { return axios({ - url: "chat/kb_chat", + url: "chat/send/msg", method: "POST", data: data }) diff --git a/src/api/request.js b/src/api/request.js index b6b202c..c1411d0 100644 --- a/src/api/request.js +++ b/src/api/request.js @@ -28,14 +28,13 @@ instance.interceptors.response.use(function (response) { console.log("姝e父鍝嶅簲缁撴灉",response) // 澶勭悊鑷畾涔夌姸鎬佺爜 - if(response.status === 200) { + if(response.data.code === 200) { return response; - // 楠岃瘉鐮侀敊璇斁琛岋紝浠ヤ究鍒锋柊楠岃瘉鐮� - } else if(response.status === 404) { - Message.error(response.statusText); - } else { + } else if (response.data.code === 500) { Message.error(response.statusText); return Promise.reject(response.statusText); + } else { + return response; } }, function (error) { console.log("閿欒鍝嶅簲缁撴灉",error) diff --git a/src/api/session.js b/src/api/session.js new file mode 100644 index 0000000..2b7341e --- /dev/null +++ b/src/api/session.js @@ -0,0 +1,39 @@ +import axios from "./request"; + +// 鑾峰彇宸︿晶浼氳瘽鍒楄〃 +export const sessionList = (params) => { + return axios({ + url: "/session/client/list", + method: "GET", + params: params + }) +} + + +// 鏂板浼氳瘽 +export const addSession = (data) => { + return axios({ + url: "/session/", + method: "POST", + data: data + }) +} + + +// 缂栬緫浼氳瘽 +export const editSession = (data) => { + return axios({ + url: "/session/", + method: "PUT", + data: data + }) +} + + +// id鏌ユ壘浼氳瘽 +export const getSessionDetail = (id) => { + return axios({ + url: "/session/" + id, + method: "GET" + }) +} diff --git a/src/components/AiChat.vue b/src/components/AiChat.vue index 547eda8..486e8cf 100644 --- a/src/components/AiChat.vue +++ b/src/components/AiChat.vue @@ -77,7 +77,6 @@ <script> import ClipboardJS from 'clipboard'; -// import {sendKbMsg} from "@/api/chat"; import {Message} from "element-ui"; const markdownIt = require('markdown-it')(); @@ -85,24 +84,25 @@ name: 'AiChat', data() { return { + chatId: null, messages: [], // 鐢ㄤ簬椤甸潰灞曠ず鐨勫璇濆垪琛� netSearchEnable: false, inputMessage: '', sendMsgForm: { query: "", mode: "local_kb", - kb_name: "SouthWest_Neclear_Develepment_KB", - top_k: 3, - score_threshold: 2, + kbName: "SouthWest_Neclear_Develepment_KB", + topK: 3, + scoreThreshold: 2, history: [ ], stream: true, model: "Qwen25-32B-Instruct", temperature: 1.15, - max_tokens: 512, - prompt_name: "default", - return_direct: false + maxTokens: 512, + promptName: "default", + returnDirect: false }, msgIndex: null, msgRole: null, @@ -179,7 +179,7 @@ this.inputMessage = ''; const assistantIndex = this.messages.length - 1; try { - const response = await fetch('/api/chat/kb_chat', { + const response = await fetch('/api/chat/send/msg', { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/src/components/SessionConfig.vue b/src/components/SessionConfig.vue index fa265c9..006514e 100644 --- a/src/components/SessionConfig.vue +++ b/src/components/SessionConfig.vue @@ -1,7 +1,7 @@ <template> <div> <el-dialog - :title="sessionName + '鈥斺�斿璇濊缃�'" + :title="form.sessionName + '鈥斺�斿璇濊缃�'" :visible.sync="show" :close-on-click-modal="false" :destroy-on-close="true" @@ -10,7 +10,7 @@ <div class="config-item"> <div class="title">璇烽�夋嫨瀵硅瘽妯″紡锛�</div> <div> - <el-select v-model="config.chatType" @change="saveConfig" size="small"> + <el-select v-model="form.mode" size="small" disabled> <el-option label="鐭ヨ瘑搴撻棶绛�" value="kb"/> </el-select> </div> @@ -18,28 +18,28 @@ <div class="config-item"> <div class="title">璇烽�夋嫨鐭ヨ瘑搴擄細</div> <div> - <el-select v-model="config.kb" @change="saveConfig" size="small"> - <el-option label="鐭ヨ瘑搴揂" value="kb1"/> + <el-select v-model="form.kbName" size="small"> + <el-option label="SouthWest_Neclear_Develepment_KB" value="SouthWest_Neclear_Develepment_KB"/> </el-select> </div> </div> <div class="config-item"> <div class="title">鍘嗗彶瀵硅瘽杞暟锛�</div> <div> - <el-input v-model="config.hisChatNum" @input="saveConfig" type="number" size="small"/> + <el-input v-model="form.topK" type="number" size="small"/> </div> </div> <div class="config-item"> <div class="title">鍖归厤鐭ヨ瘑鏉℃暟锛�</div> <div> - <el-input v-model="config.matchKbNum" @input="saveConfig" type="number" size="small"/> + <el-input v-model="form.scoreThreshold" type="number" size="small"/> </div> </div> <div class="config-item"> <div class="title">鍖归厤鐭ヨ瘑鍒嗘暟闃堝�硷細</div> <div> <el-slider - v-model="config.matchKbScore" + v-model="form.temperature" @change="saveConfig" :min="0.00" :max="2.00" @@ -48,46 +48,66 @@ </div> </div> <div> - <el-checkbox v-model="config.returnMatchResult" @change="saveConfig">浠呰繑鍥炴绱㈢粨鏋�</el-checkbox> + <el-checkbox v-model="form.returnDirect">浠呰繑鍥炴绱㈢粨鏋�</el-checkbox> </div> <span slot="footer" class="dialog-footer"> <el-button @click="close" size="small">鍙� 娑�</el-button> + <el-button @click="saveConfig" type="primary" size="small">淇� 瀛�</el-button> </span> </el-dialog> </div> </template> <script> +import {editSession, getSessionDetail} from "@/api/session"; + export default { name: "SessionConfig", props: { - sessionName: { + id: { type: String + } + }, + watch: { + id: { + handler(newV) { + if (newV) { + getSessionDetail(newV).then(res => { + this.form = res.data.data + }) + } + } } }, data() { return { show: false, - config: { - chatType: 'kb', - kb: 'kb1', - hisChatNum: 3, - matchKbNum: 3, - matchKbScore: 1, - returnMatchResult: false + form: { + id: '', + sessionName: '', + mode: "", + kbName: "", + topK: null, + scoreThreshold: null, + stream: true, + model: "", + temperature: 0, + maxTokens: 0, + promptName: "", + returnDirect: false } }; }, methods: { saveConfig() { - console.log("瑙﹀彂淇濆瓨浜�") - this.$emit('saveConfig', this.config) + editSession(this.form).then(res => { + if (res.data.code == 200) { + this.$message.success("淇濆瓨鎴愬姛") + } + }) }, setShow(value) { this.show = value - }, - setConfig(config) { - this.config = config }, close() { this.show = false diff --git a/src/views/Index.vue b/src/views/Index.vue index 670d93d..b2ab8ff 100644 --- a/src/views/Index.vue +++ b/src/views/Index.vue @@ -15,7 +15,7 @@ <img style="width: 60px;height: 60px" src="@/assets/img/logo.png"/> </div> <div class="menu"> - <div class="add-chat"> + <div class="add-chat" @click="addSession"> <i class="el-icon-plus"/>鏂板缓瀵硅瘽 </div> <div :class="{tab: true, activeTab: this.$router.currentRoute.path == '/knowledge'}" style="margin-top: 2px" @click="changeTab()"> @@ -27,78 +27,77 @@ </div> </div> <div class="session-list"> - <div :class="{session: true, 'active-session': currentSession == index}" v-for="(session, index) in sessionList" :key="'session' + index"> - <div style="width: 100%" @mouseenter="activeSession = index" @mouseleave="activeSession = null"> - <div @click="sessionChange(session, index)">{{session.name}}</div> - <div v-show="activeSession != null && activeSession == index" class="session-more"> - <el-dropdown @command="(command) => handleCommand(session, command)" trigger="click"> + <div class="session-block"> + <div class="time">浠婂ぉ</div> + <div :class="{session: true, 'active-session': currentSession == session.id}" v-for="(session) in sessionList.today" :key="'todaysession' + session.id"> + <div style="width: 100%" @mouseenter="activeSession = session.id" @mouseleave="activeSession = null"> + <div @click="sessionChange(session, session.id)">{{session.sessionName}}</div> + <div v-show="activeSession != null && activeSession == session.id" class="session-more"> + <el-dropdown @command="(command) => handleCommand(session, command)" trigger="click"> <span class="el-dropdown-link"> <svg t="1743058876802" class="icon more" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2795" width="12" height="12"> <path fill="gray" d="M480 320C533.184 320 576 277.184 576 224S533.184 128 480 128 384 170.816 384 224 426.816 320 480 320zM480 448C426.816 448 384 490.816 384 544S426.816 640 480 640 576 597.184 576 544 533.184 448 480 448zM480 768c-53.184 0-96 42.816-96 96S426.816 960 480 960 576 917.184 576 864c0-52.672-42.816-96-96-96z" p-id="2796"></path></svg> </span> - <el-dropdown-menu slot="dropdown"> - <el-dropdown-item command="config">浼氳瘽璁剧疆</el-dropdown-item> - <el-dropdown-item command="rename">閲嶅懡鍚�</el-dropdown-item> - <el-dropdown-item command="del">鍒犻櫎</el-dropdown-item> - </el-dropdown-menu> - </el-dropdown> + <el-dropdown-menu slot="dropdown"> + <el-dropdown-item command="config">浼氳瘽璁剧疆</el-dropdown-item> + <el-dropdown-item command="rename">閲嶅懡鍚�</el-dropdown-item> + <el-dropdown-item command="del">鍒犻櫎</el-dropdown-item> + </el-dropdown-menu> + </el-dropdown> + </div> </div> </div> </div> + <div class="session-block" v-show="sessionList.yesterday && sessionList.yesterday.length > 0"> + <div class="time">鏄ㄥぉ</div> + <div :class="{session: true, 'active-session': currentSession == session.id}" v-for="(session) in sessionList.yesterday" :key="'yesterdaysession' + session.id"> + <div style="width: 100%" @mouseenter="activeSession = session.id" @mouseleave="activeSession = null"> + <div @click="sessionChange(session, session.id)">{{session.sessionName}}</div> + <div v-show="activeSession != null && activeSession == session.id" class="session-more"> + <el-dropdown @command="(command) => handleCommand(session, command)" trigger="click"> + <span class="el-dropdown-link"> + <svg t="1743058876802" class="icon more" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2795" width="12" height="12"> + <path fill="gray" d="M480 320C533.184 320 576 277.184 576 224S533.184 128 480 128 384 170.816 384 224 426.816 320 480 320zM480 448C426.816 448 384 490.816 384 544S426.816 640 480 640 576 597.184 576 544 533.184 448 480 448zM480 768c-53.184 0-96 42.816-96 96S426.816 960 480 960 576 917.184 576 864c0-52.672-42.816-96-96-96z" p-id="2796"></path></svg> + </span> + <el-dropdown-menu slot="dropdown"> + <el-dropdown-item command="config">浼氳瘽璁剧疆</el-dropdown-item> + <el-dropdown-item command="rename">閲嶅懡鍚�</el-dropdown-item> + <el-dropdown-item command="del">鍒犻櫎</el-dropdown-item> + </el-dropdown-menu> + </el-dropdown> + </div> + </div> + </div> + </div> + <div class="session-block" v-show="sessionList.old && sessionList.old.length > 0"> + <div class="time">鏇存棭</div> + <div :class="{session: true, 'active-session': currentSession == session.id}" v-for="(session) in sessionList.old" :key="'oldsession' + session.id"> + <div style="width: 100%" @mouseenter="activeSession = session.id" @mouseleave="activeSession = null"> + <div @click="sessionChange(session, session.id)">{{session.sessionName}}</div> + <div v-show="activeSession != null && activeSession == session.id" class="session-more"> + <el-dropdown @command="(command) => handleCommand(session, command)" trigger="click"> + <span class="el-dropdown-link"> + <svg t="1743058876802" class="icon more" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2795" width="12" height="12"> + <path fill="gray" d="M480 320C533.184 320 576 277.184 576 224S533.184 128 480 128 384 170.816 384 224 426.816 320 480 320zM480 448C426.816 448 384 490.816 384 544S426.816 640 480 640 576 597.184 576 544 533.184 448 480 448zM480 768c-53.184 0-96 42.816-96 96S426.816 960 480 960 576 917.184 576 864c0-52.672-42.816-96-96-96z" p-id="2796"></path></svg> + </span> + <el-dropdown-menu slot="dropdown"> + <el-dropdown-item command="config">浼氳瘽璁剧疆</el-dropdown-item> + <el-dropdown-item command="rename">閲嶅懡鍚�</el-dropdown-item> + <el-dropdown-item command="del">鍒犻櫎</el-dropdown-item> + </el-dropdown-menu> + </el-dropdown> + </div> + </div> + </div> + </div> + </div> -<!-- <div class="setting">--> -<!-- <el-tabs v-model="activeSetting" @tab-click="tabSelect">--> -<!-- <el-tab-pane label="宸ュ叿璁剧疆" name="util">--> -<!-- <div style="display: flex; align-items: center">--> -<!-- <el-checkbox v-model="enableAgent">鍚敤Agent</el-checkbox>--> -<!-- <el-tooltip style="margin-left: 10px" content="Top center" placement="right" effect="light">--> -<!-- <svg t="1742971974478" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2969" width="16" height="16"><path d="M464 784.352c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48-48 21.49-48 48z" p-id="2970" fill="#515151"></path><path d="M512 960C264.96 960 64 759.04 64 512S264.96 64 512 64s448 200.96 448 448-200.96 448-448 448z m0-831.713c-211.584 0-383.713 172.129-383.713 383.713 0 211.552 172.129 383.713 383.713 383.713 211.552 0 383.713-172.16 383.713-383.713 0-211.584-172.161-383.713-383.713-383.713z" p-id="2971" fill="#515151"></path><path d="M512 673.695c-17.665 0-32-14.336-32-31.999v-54.112c0-52.353 39.999-92.352 75.327-127.648 25.887-25.92 52.672-52.672 52.672-74.016 0-53.344-43.072-96.736-95.999-96.736-53.823 0-96 41.536-96 94.56 0 17.664-14.335 31.999-32 31.999s-32-14.336-32-32c0-87.423 71.774-158.559 160-158.559S672 297.28 672 385.92c0 47.904-36.32 84.191-71.424 119.296-27.84 27.776-56.575 56.512-56.575 82.335v54.112c0 17.665-14.336 32.032-32.001 32.032z" p-id="2972" fill="#515151"></path></svg>--> -<!-- </el-tooltip>--> -<!-- </div>--> -<!-- <div style="margin-top: 15px">--> -<!-- <div class="normal-text">閫夋嫨宸ュ叿</div>--> -<!-- <div style="margin-top: 5px">--> -<!-- <el-select v-model="selectUtil" size="mini" placeholder="鏈�夋嫨" style="width: 100%">--> -<!-- <el-option--> -<!-- v-for="item in options"--> -<!-- :key="item.value"--> -<!-- :label="item.label"--> -<!-- :value="item.value">--> -<!-- </el-option>--> -<!-- </el-select>--> -<!-- </div>--> -<!-- </div>--> -<!-- <div style="margin-top: 15px">--> -<!-- <div class="normal-text" style="display: flex;align-items: center">--> -<!-- <div>涓婁紶闄勪欢</div>--> -<!-- <el-tooltip style="margin-left: 10px" content="鍗曚釜鏂囦欢涓嶈秴杩�200M" placement="right" effect="light">--> -<!-- <svg t="1742971974478" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2969" width="16" height="16"><path d="M464 784.352c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48-48 21.49-48 48z" p-id="2970" fill="#515151"></path><path d="M512 960C264.96 960 64 759.04 64 512S264.96 64 512 64s448 200.96 448 448-200.96 448-448 448z m0-831.713c-211.584 0-383.713 172.129-383.713 383.713 0 211.552 172.129 383.713 383.713 383.713 211.552 0 383.713-172.16 383.713-383.713 0-211.584-172.161-383.713-383.713-383.713z" p-id="2971" fill="#515151"></path><path d="M512 673.695c-17.665 0-32-14.336-32-31.999v-54.112c0-52.353 39.999-92.352 75.327-127.648 25.887-25.92 52.672-52.672 52.672-74.016 0-53.344-43.072-96.736-95.999-96.736-53.823 0-96 41.536-96 94.56 0 17.664-14.335 31.999-32 31.999s-32-14.336-32-32c0-87.423 71.774-158.559 160-158.559S672 297.28 672 385.92c0 47.904-36.32 84.191-71.424 119.296-27.84 27.776-56.575 56.512-56.575 82.335v54.112c0 17.665-14.336 32.032-32.001 32.032z" p-id="2972" fill="#515151"></path></svg>--> -<!-- </el-tooltip>--> -<!-- </div>--> -<!-- <div style="margin-top: 5px">--> -<!-- <el-upload--> -<!-- class="upload"--> -<!-- drag--> -<!-- :on-change="handleChange"--> -<!-- :before-upload="handleUpload"--> -<!-- :file-list="fileList"--> -<!-- multiple>--> -<!-- <i class="el-icon-upload"></i>--> -<!-- <div class="el-upload__text">--> -<!-- <div>灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>--> -<!-- </div>--> -<!-- </el-upload>--> -<!-- </div>--> -<!-- </div>--> -<!-- </el-tab-pane>--> -<!-- <el-tab-pane label="浼氳瘽璁剧疆" name="session"></el-tab-pane>--> -<!-- </el-tabs>--> -<!-- </div>--> </div> <div class="right"> - <router-view></router-view> + <ai-chat v-if="showWhich == 'chat'"/> + <knowledge-base v-else-if="showWhich == 'kb'"/> </div> - <session-config :session-name="sessionName" @saveConfig="saveConfig" ref="sessionConfig" /> + <session-config :id="editSessionId" ref="sessionConfig" /> <el-dialog :title="'閲嶅懡鍚嶅璇�'" @@ -118,18 +117,23 @@ <script> import SessionConfig from "@/components/SessionConfig"; +import AiChat from "@/components/AiChat"; +import KnowledgeBase from "@/components/KnowledgeBase"; import Login from "@/components/Login"; +import {sessionList} from "@/api/session"; export default { name: "IndexView", components: { - SessionConfig, Login + SessionConfig, Login, AiChat, KnowledgeBase }, data() { return { + editSessionId: '', + showWhich: '', renameShow: false, rename: '', - sessionName: '', + editSession: '', config: { chatType: 'kb', kb: 'kb1', @@ -138,17 +142,11 @@ matchKbScore: 1, returnMatchResult: false }, - sessionList: [ - { - name: '浼氳瘽1' - }, - { - name: '浼氳瘽2' - }, - { - name: '浼氳瘽3' - }, - ], + sessionList: { + today: [], + yesterday: [], + old: [] + }, fileList: [], activeSession: null, currentSession: null, @@ -174,14 +172,22 @@ } }, mounted() { - + this.getSessionList() }, methods: { - sessionChange(session, index) { - this.currentSession = index - if (this.$router.currentRoute.path !== "/chat") { - this.$router.push("/chat") - } + addSession() { + this.currentSession = null + this.showWhich = 'chat' + }, + // 鑾峰彇浼氳瘽鍒楄〃 + getSessionList() { + sessionList().then(res => { + this.sessionList = res.data.data + }) + }, + sessionChange(session, id) { + this.currentSession = id + this.showWhich = 'chat' }, renameSubmit() { // TODO 淇濆瓨鍒板璇濅腑 @@ -191,15 +197,10 @@ message: '瀵硅瘽鍚嶇О宸蹭慨鏀�' }); }, - saveConfig(config) { - // TODO 淇濆瓨鍒板璇濅腑 - console.log(config, "鐖剁粍浠惰幏鍙栧埌閰嶇疆浜�") - }, handleCommand(session, command) { console.log(session, command) if (command === 'config') { - this.sessionName = session.name - this.$refs.sessionConfig.setConfig(this.config) + this.editSessionId = session.id this.$refs.sessionConfig.setShow(true) } else if (command === 'rename') { this.rename = session.name @@ -233,13 +234,8 @@ handleChange(file, fileList) { this.fileList = fileList; }, - tabSelect(tab, event) { - console.log(tab, event) - }, changeTab() { - if (this.$router.currentRoute.path !== "/knowledge") { - this.$router.push("/knowledge") - } + this.showWhich = 'kb' }, } } @@ -373,4 +369,16 @@ ::v-deep(.el-dialog) { border-radius: 16px!important; } + +.session-block { + width: 100%; + margin-bottom: 20px; +} + +.time { + padding-left: 10px; + margin-bottom: 10px; + font-style: italic; + font-weight: bold; +} </style> diff --git a/vue.config.js b/vue.config.js index 852debf..e53df27 100644 --- a/vue.config.js +++ b/vue.config.js @@ -5,7 +5,7 @@ compress: false, proxy: { "/api": { - target: 'http://i-1.gpushare.com:52574/',//浠g悊鍦板潃 鍑℃槸浣跨敤/api + target: 'http://127.0.0.1:9897/',//浠g悊鍦板潃 鍑℃槸浣跨敤/api changeOrigin: true,//鍏佽璺ㄥ煙璇锋眰 secure: false, pathRewrite: { //閲嶅啓璺緞 鏇挎崲璇锋眰鍦板潃涓殑鎸囧畾璺緞 -- Gitblit v1.8.0