mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-18 01:06:39 +08:00
handle the exception for web front page
This commit is contained in:
parent
9a503ddc72
commit
8a8c43c7a5
@ -9,6 +9,10 @@ package chatimpl
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"geekai/core"
|
"geekai/core"
|
||||||
"geekai/core/types"
|
"geekai/core/types"
|
||||||
"geekai/handler"
|
"geekai/handler"
|
||||||
@ -19,10 +23,6 @@ import (
|
|||||||
"geekai/store/vo"
|
"geekai/store/vo"
|
||||||
"geekai/utils"
|
"geekai/utils"
|
||||||
"geekai/utils/resp"
|
"geekai/utils/resp"
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"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) {
|
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 the chat model bind a KEY, use it directly
|
||||||
if session.Model.KeyId > 0 {
|
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
|
// use the last unused key
|
||||||
if apiKey.Id == 0 {
|
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 {
|
if apiKey.Id == 0 {
|
||||||
return nil, errors.New("no available key, please import key")
|
return nil, errors.New("no available key, please import key")
|
||||||
|
@ -9,13 +9,13 @@ package chatimpl
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"geekai/core/types"
|
"geekai/core/types"
|
||||||
"geekai/store/model"
|
"geekai/store/model"
|
||||||
"geekai/store/vo"
|
"geekai/store/vo"
|
||||||
"geekai/utils"
|
"geekai/utils"
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
@ -75,12 +75,16 @@ func (h *ChatHandler) sendOpenAiMessage(
|
|||||||
|
|
||||||
var responseBody = types.ApiResponse{}
|
var responseBody = types.ApiResponse{}
|
||||||
err = json.Unmarshal([]byte(line[6:]), &responseBody)
|
err = json.Unmarshal([]byte(line[6:]), &responseBody)
|
||||||
if err != nil || len(responseBody.Choices) == 0 { // 数据解析出错
|
if err != nil { // 数据解析出错
|
||||||
logger.Error(err, line)
|
logger.Error(err, line)
|
||||||
utils.ReplyMessage(ws, ErrorMsg)
|
utils.ReplyMessage(ws, ErrorMsg)
|
||||||
utils.ReplyMessage(ws, ErrImg)
|
utils.ReplyMessage(ws, ErrImg)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if len(responseBody.Choices) == 0 { // Fixed: 兼容 Azure API 第一个输出空行
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if responseBody.Choices[0].FinishReason == "stop" && len(contents) == 0 {
|
if responseBody.Choices[0].FinishReason == "stop" && len(contents) == 0 {
|
||||||
utils.ReplyMessage(ws, "抱歉😔😔😔,AI助手由于未知原因已经停止输出内容。")
|
utils.ReplyMessage(ws, "抱歉😔😔😔,AI助手由于未知原因已经停止输出内容。")
|
||||||
break
|
break
|
||||||
|
@ -8,16 +8,16 @@ package chatimpl
|
|||||||
// * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"geekai/core/types"
|
|
||||||
"geekai/store/model"
|
|
||||||
"geekai/store/vo"
|
|
||||||
"geekai/utils"
|
|
||||||
"context"
|
"context"
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"geekai/core/types"
|
||||||
|
"geekai/store/model"
|
||||||
|
"geekai/store/vo"
|
||||||
|
"geekai/utils"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"html/template"
|
"html/template"
|
||||||
@ -80,11 +80,11 @@ func (h *ChatHandler) sendXunFeiMessage(
|
|||||||
var res *gorm.DB
|
var res *gorm.DB
|
||||||
// use the bind key
|
// use the bind key
|
||||||
if session.Model.KeyId > 0 {
|
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
|
// use the last unused key
|
||||||
if res.Error != nil {
|
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 {
|
if res.Error != nil {
|
||||||
utils.ReplyMessage(ws, "抱歉😔😔😔,系统已经没有可用的 API KEY,请联系管理员!")
|
utils.ReplyMessage(ws, "抱歉😔😔😔,系统已经没有可用的 API KEY,请联系管理员!")
|
||||||
|
@ -10,13 +10,13 @@ package handler
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"geekai/core"
|
"geekai/core"
|
||||||
"geekai/core/types"
|
"geekai/core/types"
|
||||||
"geekai/store/model"
|
"geekai/store/model"
|
||||||
"geekai/utils"
|
"geekai/utils"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"gorm.io/gorm"
|
"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
|
// if the chat model bind a KEY, use it directly
|
||||||
var res *gorm.DB
|
var res *gorm.DB
|
||||||
if chatModel.KeyId > 0 {
|
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
|
// use the last unused key
|
||||||
if apiKey.Id == 0 {
|
if apiKey.Id == 0 {
|
||||||
|
@ -57,6 +57,7 @@ export default defineComponent({
|
|||||||
if (!this.finalTokens) {
|
if (!this.finalTokens) {
|
||||||
httpPost("/api/chat/tokens", {text: this.content, model: this.model}).then(res => {
|
httpPost("/api/chat/tokens", {text: this.content, model: this.model}).then(res => {
|
||||||
this.finalTokens = res.data;
|
this.finalTokens = res.data;
|
||||||
|
}).catch(() => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -654,55 +654,63 @@ const connect = function (chat_id, role_id) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_socket.addEventListener('message', event => {
|
_socket.addEventListener('message', event => {
|
||||||
if (event.data instanceof Blob) {
|
try {
|
||||||
const reader = new FileReader();
|
if (event.data instanceof Blob) {
|
||||||
reader.readAsText(event.data, "UTF-8");
|
const reader = new FileReader();
|
||||||
reader.onload = () => {
|
reader.readAsText(event.data, "UTF-8");
|
||||||
const data = JSON.parse(String(reader.result));
|
reader.onload = () => {
|
||||||
if (data.type === 'start') {
|
const data = JSON.parse(String(reader.result));
|
||||||
console.log(data)
|
if (data.type === 'start') {
|
||||||
chatData.value.push({
|
chatData.value.push({
|
||||||
type: "reply",
|
type: "reply",
|
||||||
id: randString(32),
|
id: randString(32),
|
||||||
icon: _role['icon'],
|
icon: _role['icon'],
|
||||||
content: ""
|
content: ""
|
||||||
});
|
});
|
||||||
} else if (data.type === 'end') { // 消息接收完毕
|
} else if (data.type === 'end') { // 消息接收完毕
|
||||||
// 追加当前会话到会话列表
|
// 追加当前会话到会话列表
|
||||||
if (isNewChat && newChatItem.value !== null) {
|
if (isNewChat && newChatItem.value !== null) {
|
||||||
newChatItem.value['title'] = previousText.value;
|
newChatItem.value['title'] = previousText.value;
|
||||||
newChatItem.value['chat_id'] = chat_id;
|
newChatItem.value['chat_id'] = chat_id;
|
||||||
chatList.value.unshift(newChatItem.value);
|
chatList.value.unshift(newChatItem.value);
|
||||||
activeChat.value = newChatItem.value;
|
activeChat.value = newChatItem.value;
|
||||||
newChatItem.value = null; // 只追加一次
|
newChatItem.value = null; // 只追加一次
|
||||||
}
|
}
|
||||||
|
|
||||||
enableInput()
|
enableInput()
|
||||||
lineBuffer.value = ''; // 清空缓冲
|
lineBuffer.value = ''; // 清空缓冲
|
||||||
|
|
||||||
// 获取 token
|
// 获取 token
|
||||||
const reply = chatData.value[chatData.value.length - 1]
|
const reply = chatData.value[chatData.value.length - 1]
|
||||||
httpPost("/api/chat/tokens", {text: "", model: getModelValue(modelID.value), chat_id: chat_id}).then(res => {
|
httpPost("/api/chat/tokens", {
|
||||||
reply['created_at'] = new Date().getTime();
|
text: "",
|
||||||
reply['tokens'] = res.data;
|
model: getModelValue(modelID.value),
|
||||||
// 将聊天框的滚动条滑动到最底部
|
chat_id: chat_id
|
||||||
nextTick(() => {
|
}).then(res => {
|
||||||
document.getElementById('chat-box').scrollTo(0, document.getElementById('chat-box').scrollHeight)
|
reply['created_at'] = new Date().getTime();
|
||||||
|
reply['tokens'] = res.data;
|
||||||
|
// 将聊天框的滚动条滑动到最底部
|
||||||
|
nextTick(() => {
|
||||||
|
document.getElementById('chat-box').scrollTo(0, document.getElementById('chat-box').scrollHeight)
|
||||||
|
})
|
||||||
|
}).catch(() => {
|
||||||
})
|
})
|
||||||
})
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
lineBuffer.value += data.content;
|
lineBuffer.value += data.content;
|
||||||
const reply = chatData.value[chatData.value.length - 1]
|
const reply = chatData.value[chatData.value.length - 1]
|
||||||
reply['orgContent'] = lineBuffer.value;
|
reply['orgContent'] = lineBuffer.value;
|
||||||
reply['content'] = md.render(processContent(lineBuffer.value));
|
reply['content'] = md.render(processContent(lineBuffer.value));
|
||||||
}
|
}
|
||||||
// 将聊天框的滚动条滑动到最底部
|
// 将聊天框的滚动条滑动到最底部
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
document.getElementById('chat-box').scrollTo(0, document.getElementById('chat-box').scrollHeight)
|
document.getElementById('chat-box').scrollTo(0, document.getElementById('chat-box').scrollHeight)
|
||||||
localStorage.setItem("chat_id", chat_id)
|
localStorage.setItem("chat_id", chat_id)
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -99,7 +99,6 @@
|
|||||||
import LoginDialog from "@/components/LoginDialog.vue";
|
import LoginDialog from "@/components/LoginDialog.vue";
|
||||||
import {nextTick, onMounted, onUnmounted, ref} from 'vue';
|
import {nextTick, onMounted, onUnmounted, ref} from 'vue';
|
||||||
import {Markmap} from 'markmap-view';
|
import {Markmap} from 'markmap-view';
|
||||||
import {loadCSS, loadJS} from 'markmap-common';
|
|
||||||
import {Transformer} from 'markmap-lib';
|
import {Transformer} from 'markmap-lib';
|
||||||
import {checkSession} from "@/action/session";
|
import {checkSession} from "@/action/session";
|
||||||
import {httpGet} from "@/utils/http";
|
import {httpGet} from "@/utils/http";
|
||||||
@ -129,9 +128,6 @@ const showLoginDialog = ref(false)
|
|||||||
const isLogin = ref(false)
|
const isLogin = ref(false)
|
||||||
const loginUser = ref({power: 0})
|
const loginUser = ref({power: 0})
|
||||||
const transformer = new Transformer();
|
const transformer = new Transformer();
|
||||||
const {scripts, styles} = transformer.getAssets()
|
|
||||||
loadCSS(styles);
|
|
||||||
loadJS(scripts);
|
|
||||||
|
|
||||||
|
|
||||||
const svgRef = ref(null)
|
const svgRef = ref(null)
|
||||||
@ -142,8 +138,12 @@ const loading = ref(false)
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initData()
|
initData()
|
||||||
markMap.value = Markmap.create(svgRef.value)
|
try {
|
||||||
update()
|
markMap.value = Markmap.create(svgRef.value)
|
||||||
|
update()
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const initData = () => {
|
const initData = () => {
|
||||||
@ -168,9 +168,13 @@ const initData = () => {
|
|||||||
|
|
||||||
const update = () => {
|
const update = () => {
|
||||||
|
|
||||||
const {root} = transformer.transform(processContent(text.value))
|
try {
|
||||||
markMap.value.setData(root)
|
const {root} = transformer.transform(processContent(text.value))
|
||||||
markMap.value.fit()
|
markMap.value.setData(root)
|
||||||
|
markMap.value.fit()
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const processContent = (text) => {
|
const processContent = (text) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user