diff --git a/api/handler/chatimpl/chat_handler.go b/api/handler/chatimpl/chat_handler.go index 8f420ee7..e6ec7b81 100644 --- a/api/handler/chatimpl/chat_handler.go +++ b/api/handler/chatimpl/chat_handler.go @@ -9,6 +9,10 @@ package chatimpl import ( "bytes" + "context" + "encoding/json" + "errors" + "fmt" "geekai/core" "geekai/core/types" "geekai/handler" @@ -19,10 +23,6 @@ import ( "geekai/store/vo" "geekai/utils" "geekai/utils/resp" - "context" - "encoding/json" - "errors" - "fmt" "net/http" "net/url" "regexp" @@ -481,11 +481,11 @@ func (h *ChatHandler) StopGenerate(c *gin.Context) { func (h *ChatHandler) doRequest(ctx context.Context, req types.ApiRequest, session *types.ChatSession, apiKey *model.ApiKey) (*http.Response, error) { // if the chat model bind a KEY, use it directly if session.Model.KeyId > 0 { - h.DB.Debug().Where("id", session.Model.KeyId).Find(apiKey) + h.DB.Debug().Where("id", session.Model.KeyId).Where("enabled", true).Find(apiKey) } // use the last unused key if apiKey.Id == 0 { - h.DB.Debug().Where("platform = ?", session.Model.Platform).Where("type = ?", "chat").Where("enabled = ?", true).Order("last_used_at ASC").First(apiKey) + h.DB.Debug().Where("platform", session.Model.Platform).Where("type", "chat").Where("enabled", true).Order("last_used_at ASC").First(apiKey) } if apiKey.Id == 0 { return nil, errors.New("no available key, please import key") diff --git a/api/handler/chatimpl/openai_handler.go b/api/handler/chatimpl/openai_handler.go index cf41ab1e..8a7a2891 100644 --- a/api/handler/chatimpl/openai_handler.go +++ b/api/handler/chatimpl/openai_handler.go @@ -9,13 +9,13 @@ package chatimpl import ( "bufio" + "context" + "encoding/json" + "fmt" "geekai/core/types" "geekai/store/model" "geekai/store/vo" "geekai/utils" - "context" - "encoding/json" - "fmt" "html/template" "io" "strings" @@ -75,12 +75,16 @@ func (h *ChatHandler) sendOpenAiMessage( var responseBody = types.ApiResponse{} err = json.Unmarshal([]byte(line[6:]), &responseBody) - if err != nil || len(responseBody.Choices) == 0 { // 数据解析出错 + if err != nil { // 数据解析出错 logger.Error(err, line) utils.ReplyMessage(ws, ErrorMsg) utils.ReplyMessage(ws, ErrImg) break } + if len(responseBody.Choices) == 0 { // Fixed: 兼容 Azure API 第一个输出空行 + continue + } + if responseBody.Choices[0].FinishReason == "stop" && len(contents) == 0 { utils.ReplyMessage(ws, "抱歉😔😔😔,AI助手由于未知原因已经停止输出内容。") break diff --git a/api/handler/chatimpl/xunfei_handler.go b/api/handler/chatimpl/xunfei_handler.go index 00bbc35b..ee0c7829 100644 --- a/api/handler/chatimpl/xunfei_handler.go +++ b/api/handler/chatimpl/xunfei_handler.go @@ -8,16 +8,16 @@ package chatimpl // * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ import ( - "geekai/core/types" - "geekai/store/model" - "geekai/store/vo" - "geekai/utils" "context" "crypto/hmac" "crypto/sha256" "encoding/base64" "encoding/json" "fmt" + "geekai/core/types" + "geekai/store/model" + "geekai/store/vo" + "geekai/utils" "github.com/gorilla/websocket" "gorm.io/gorm" "html/template" @@ -80,11 +80,11 @@ func (h *ChatHandler) sendXunFeiMessage( var res *gorm.DB // use the bind key if session.Model.KeyId > 0 { - res = h.DB.Where("id", session.Model.KeyId).Find(&apiKey) + res = h.DB.Where("id", session.Model.KeyId).Where("enabled", true).Find(&apiKey) } // use the last unused key if res.Error != nil { - res = h.DB.Where("platform = ?", session.Model.Platform).Where("type = ?", "chat").Where("enabled = ?", true).Order("last_used_at ASC").First(&apiKey) + res = h.DB.Where("platform", session.Model.Platform).Where("type", "chat").Where("enabled", true).Order("last_used_at ASC").First(&apiKey) } if res.Error != nil { utils.ReplyMessage(ws, "抱歉😔😔😔,系统已经没有可用的 API KEY,请联系管理员!") diff --git a/api/handler/markmap_handler.go b/api/handler/markmap_handler.go index f5034758..248e5802 100644 --- a/api/handler/markmap_handler.go +++ b/api/handler/markmap_handler.go @@ -10,13 +10,13 @@ package handler import ( "bufio" "bytes" + "encoding/json" + "errors" + "fmt" "geekai/core" "geekai/core/types" "geekai/store/model" "geekai/utils" - "encoding/json" - "errors" - "fmt" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" "gorm.io/gorm" @@ -213,7 +213,7 @@ func (h *MarkMapHandler) doRequest(req types.ApiRequest, chatModel model.ChatMod // if the chat model bind a KEY, use it directly var res *gorm.DB if chatModel.KeyId > 0 { - res = h.DB.Where("id", chatModel.KeyId).Find(apiKey) + res = h.DB.Where("id", chatModel.KeyId).Where("enabled", true).Find(apiKey) } // use the last unused key if apiKey.Id == 0 { diff --git a/web/src/components/ChatPrompt.vue b/web/src/components/ChatPrompt.vue index a6e9d42a..9c8b545b 100644 --- a/web/src/components/ChatPrompt.vue +++ b/web/src/components/ChatPrompt.vue @@ -57,6 +57,7 @@ export default defineComponent({ if (!this.finalTokens) { httpPost("/api/chat/tokens", {text: this.content, model: this.model}).then(res => { this.finalTokens = res.data; + }).catch(() => { }) } } diff --git a/web/src/views/ChatPlus.vue b/web/src/views/ChatPlus.vue index 49f31f0d..c62f42ea 100644 --- a/web/src/views/ChatPlus.vue +++ b/web/src/views/ChatPlus.vue @@ -654,55 +654,63 @@ const connect = function (chat_id, role_id) { }); _socket.addEventListener('message', event => { - if (event.data instanceof Blob) { - const reader = new FileReader(); - reader.readAsText(event.data, "UTF-8"); - reader.onload = () => { - const data = JSON.parse(String(reader.result)); - if (data.type === 'start') { - console.log(data) - chatData.value.push({ - type: "reply", - id: randString(32), - icon: _role['icon'], - content: "" - }); - } else if (data.type === 'end') { // 消息接收完毕 - // 追加当前会话到会话列表 - if (isNewChat && newChatItem.value !== null) { - newChatItem.value['title'] = previousText.value; - newChatItem.value['chat_id'] = chat_id; - chatList.value.unshift(newChatItem.value); - activeChat.value = newChatItem.value; - newChatItem.value = null; // 只追加一次 - } + try { + if (event.data instanceof Blob) { + const reader = new FileReader(); + reader.readAsText(event.data, "UTF-8"); + reader.onload = () => { + const data = JSON.parse(String(reader.result)); + if (data.type === 'start') { + chatData.value.push({ + type: "reply", + id: randString(32), + icon: _role['icon'], + content: "" + }); + } else if (data.type === 'end') { // 消息接收完毕 + // 追加当前会话到会话列表 + if (isNewChat && newChatItem.value !== null) { + newChatItem.value['title'] = previousText.value; + newChatItem.value['chat_id'] = chat_id; + chatList.value.unshift(newChatItem.value); + activeChat.value = newChatItem.value; + newChatItem.value = null; // 只追加一次 + } - enableInput() - lineBuffer.value = ''; // 清空缓冲 + enableInput() + lineBuffer.value = ''; // 清空缓冲 - // 获取 token - const reply = chatData.value[chatData.value.length - 1] - httpPost("/api/chat/tokens", {text: "", model: getModelValue(modelID.value), chat_id: chat_id}).then(res => { - reply['created_at'] = new Date().getTime(); - reply['tokens'] = res.data; - // 将聊天框的滚动条滑动到最底部 - nextTick(() => { - document.getElementById('chat-box').scrollTo(0, document.getElementById('chat-box').scrollHeight) + // 获取 token + const reply = chatData.value[chatData.value.length - 1] + httpPost("/api/chat/tokens", { + text: "", + model: getModelValue(modelID.value), + chat_id: chat_id + }).then(res => { + reply['created_at'] = new Date().getTime(); + reply['tokens'] = res.data; + // 将聊天框的滚动条滑动到最底部 + nextTick(() => { + document.getElementById('chat-box').scrollTo(0, document.getElementById('chat-box').scrollHeight) + }) + }).catch(() => { }) - }) - } else { - lineBuffer.value += data.content; - const reply = chatData.value[chatData.value.length - 1] - reply['orgContent'] = lineBuffer.value; - reply['content'] = md.render(processContent(lineBuffer.value)); - } - // 将聊天框的滚动条滑动到最底部 - nextTick(() => { - document.getElementById('chat-box').scrollTo(0, document.getElementById('chat-box').scrollHeight) - localStorage.setItem("chat_id", chat_id) - }) - }; + } else { + lineBuffer.value += data.content; + const reply = chatData.value[chatData.value.length - 1] + reply['orgContent'] = lineBuffer.value; + reply['content'] = md.render(processContent(lineBuffer.value)); + } + // 将聊天框的滚动条滑动到最底部 + nextTick(() => { + document.getElementById('chat-box').scrollTo(0, document.getElementById('chat-box').scrollHeight) + localStorage.setItem("chat_id", chat_id) + }) + }; + } + } catch (e) { + console.error(e) } }); diff --git a/web/src/views/MarkMap.vue b/web/src/views/MarkMap.vue index 8f1d0f87..63a74267 100644 --- a/web/src/views/MarkMap.vue +++ b/web/src/views/MarkMap.vue @@ -99,7 +99,6 @@ import LoginDialog from "@/components/LoginDialog.vue"; import {nextTick, onMounted, onUnmounted, ref} from 'vue'; import {Markmap} from 'markmap-view'; -import {loadCSS, loadJS} from 'markmap-common'; import {Transformer} from 'markmap-lib'; import {checkSession} from "@/action/session"; import {httpGet} from "@/utils/http"; @@ -129,9 +128,6 @@ const showLoginDialog = ref(false) const isLogin = ref(false) const loginUser = ref({power: 0}) const transformer = new Transformer(); -const {scripts, styles} = transformer.getAssets() -loadCSS(styles); -loadJS(scripts); const svgRef = ref(null) @@ -142,8 +138,12 @@ const loading = ref(false) onMounted(() => { initData() - markMap.value = Markmap.create(svgRef.value) - update() + try { + markMap.value = Markmap.create(svgRef.value) + update() + } catch (e) { + console.error(e) + } }); const initData = () => { @@ -168,9 +168,13 @@ const initData = () => { const update = () => { - const {root} = transformer.transform(processContent(text.value)) - markMap.value.setData(root) - markMap.value.fit() + try { + const {root} = transformer.transform(processContent(text.value)) + markMap.value.setData(root) + markMap.value.fit() + } catch (e) { + console.error(e) + } } const processContent = (text) => {