opt: close websocket connection when finish a chat call for XunFei API

This commit is contained in:
RockYang 2023-10-12 10:02:12 +08:00
parent 9cbc6c91c4
commit 8b14e141d0
5 changed files with 106 additions and 158 deletions

View File

@ -1,103 +0,0 @@
package chatimpl
import (
"chatplus/core/types"
"chatplus/store/model"
"chatplus/store/vo"
"chatplus/utils"
"chatplus/utils/resp"
"gorm.io/gorm"
"github.com/gin-gonic/gin"
)
// Update 更新会话标题
func (h *ChatHandler) Update(c *gin.Context) {
var data struct {
Id uint `json:"id"`
Title string `json:"title"`
}
if err := c.ShouldBindJSON(&data); err != nil {
resp.ERROR(c, types.InvalidArgs)
return
}
var m = model.ChatItem{}
m.Id = data.Id
res := h.db.Model(&m).UpdateColumn("title", data.Title)
if res.Error != nil {
resp.ERROR(c, "Failed to update database")
return
}
resp.SUCCESS(c, types.OkMsg)
}
// History 获取聊天历史记录
func (h *ChatHandler) History(c *gin.Context) {
chatId := c.Query("chat_id") // 会话 ID
var items []model.HistoryMessage
var messages = make([]vo.HistoryMessage, 0)
res := h.db.Where("chat_id = ?", chatId).Find(&items)
if res.Error != nil {
resp.ERROR(c, "No history message")
return
} else {
for _, item := range items {
var v vo.HistoryMessage
err := utils.CopyObject(item, &v)
v.CreatedAt = item.CreatedAt.Unix()
v.UpdatedAt = item.UpdatedAt.Unix()
if err == nil {
messages = append(messages, v)
}
}
}
resp.SUCCESS(c, messages)
}
// Clear 清空所有聊天记录
func (h *ChatHandler) Clear(c *gin.Context) {
// 获取当前登录用户所有的聊天会话
user, err := utils.GetLoginUser(c, h.db)
if err != nil {
resp.NotAuth(c)
return
}
var chats []model.ChatItem
res := h.db.Where("user_id = ?", user.Id).Find(&chats)
if res.Error != nil {
resp.ERROR(c, "No chats found")
return
}
var chatIds = make([]string, 0)
for _, chat := range chats {
chatIds = append(chatIds, chat.ChatId)
// 清空会话上下文
h.App.ChatContexts.Delete(chat.ChatId)
}
err = h.db.Transaction(func(tx *gorm.DB) error {
res := h.db.Where("user_id =?", user.Id).Delete(&model.ChatItem{})
if res.Error != nil {
return res.Error
}
res = h.db.Where("user_id = ? AND chat_id IN ?", user.Id, chatIds).Delete(&model.HistoryMessage{})
if res.Error != nil {
return res.Error
}
// TODO: 是否要删除 MidJourney 绘画记录和图片文件?
return nil
})
if err != nil {
logger.Errorf("Error with delete chats: %+v", err)
resp.ERROR(c, "Failed to remove chat from database.")
return
}
resp.SUCCESS(c, types.OkMsg)
}

View File

@ -7,6 +7,7 @@ import (
"chatplus/utils" "chatplus/utils"
"chatplus/utils/resp" "chatplus/utils/resp"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gorm.io/gorm"
) )
// List 获取会话列表 // List 获取会话列表
@ -47,6 +48,95 @@ func (h *ChatHandler) List(c *gin.Context) {
resp.SUCCESS(c, items) resp.SUCCESS(c, items)
} }
// Update 更新会话标题
func (h *ChatHandler) Update(c *gin.Context) {
var data struct {
ChatId string `json:"chat_id"`
Title string `json:"title"`
}
if err := c.ShouldBindJSON(&data); err != nil {
resp.ERROR(c, types.InvalidArgs)
return
}
res := h.db.Model(&model.ChatItem{}).Where("chat_id = ?", data.ChatId).UpdateColumn("title", data.Title)
if res.Error != nil {
resp.ERROR(c, "Failed to update database")
return
}
resp.SUCCESS(c, types.OkMsg)
}
// Clear 清空所有聊天记录
func (h *ChatHandler) Clear(c *gin.Context) {
// 获取当前登录用户所有的聊天会话
user, err := utils.GetLoginUser(c, h.db)
if err != nil {
resp.NotAuth(c)
return
}
var chats []model.ChatItem
res := h.db.Where("user_id = ?", user.Id).Find(&chats)
if res.Error != nil {
resp.ERROR(c, "No chats found")
return
}
var chatIds = make([]string, 0)
for _, chat := range chats {
chatIds = append(chatIds, chat.ChatId)
// 清空会话上下文
h.App.ChatContexts.Delete(chat.ChatId)
}
err = h.db.Transaction(func(tx *gorm.DB) error {
res := h.db.Where("user_id =?", user.Id).Delete(&model.ChatItem{})
if res.Error != nil {
return res.Error
}
res = h.db.Where("user_id = ? AND chat_id IN ?", user.Id, chatIds).Delete(&model.HistoryMessage{})
if res.Error != nil {
return res.Error
}
// TODO: 是否要删除 MidJourney 绘画记录和图片文件?
return nil
})
if err != nil {
logger.Errorf("Error with delete chats: %+v", err)
resp.ERROR(c, "Failed to remove chat from database.")
return
}
resp.SUCCESS(c, types.OkMsg)
}
// History 获取聊天历史记录
func (h *ChatHandler) History(c *gin.Context) {
chatId := c.Query("chat_id") // 会话 ID
var items []model.HistoryMessage
var messages = make([]vo.HistoryMessage, 0)
res := h.db.Where("chat_id = ?", chatId).Find(&items)
if res.Error != nil {
resp.ERROR(c, "No history message")
return
} else {
for _, item := range items {
var v vo.HistoryMessage
err := utils.CopyObject(item, &v)
v.CreatedAt = item.CreatedAt.Unix()
v.UpdatedAt = item.UpdatedAt.Unix()
if err == nil {
messages = append(messages, v)
}
}
}
resp.SUCCESS(c, messages)
}
// Remove 删除会话 // Remove 删除会话
func (h *ChatHandler) Remove(c *gin.Context) { func (h *ChatHandler) Remove(c *gin.Context) {
chatId := h.GetTrim(c, "chat_id") chatId := h.GetTrim(c, "chat_id")
@ -80,6 +170,7 @@ func (h *ChatHandler) Remove(c *gin.Context) {
resp.SUCCESS(c, types.OkMsg) resp.SUCCESS(c, types.OkMsg)
} }
// Detail 对话详情,用户导出对话
func (h *ChatHandler) Detail(c *gin.Context) { func (h *ChatHandler) Detail(c *gin.Context) {
chatId := h.GetTrim(c, "chat_id") chatId := h.GetTrim(c, "chat_id")
if utils.IsEmptyValue(chatId) { if utils.IsEmptyValue(chatId) {

View File

@ -150,6 +150,7 @@ func (h *ChatHandler) sendXunFeiMessage(
}) })
if result.Payload.Choices.Status == 2 { // 最终结果 if result.Payload.Choices.Status == 2 { // 最终结果
_ = conn.Close() // 关闭连接
break break
} }

View File

@ -1,55 +1,5 @@
package main package main
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
)
func main() { func main() {
apiKey := "qjvqGdqpTY7qQaGBMenM7XgQ"
apiSecret := "3G1RzBGXywZv4VbYRTyAfNns1vIOAG8t"
token, err := getBaiduToken(apiKey, apiSecret)
if err != nil {
log.Fatal(err)
}
fmt.Println(token)
} }
func getBaiduToken(apiKey string, apiSecret string) (string, error) {
url := fmt.Sprintf("https://aip.baidubce.com/oauth/2.0/token?client_id=%s&client_secret=%s&grant_type=client_credentials", apiKey, apiSecret)
client := &http.Client{}
req, err := http.NewRequest("POST", url, nil)
if err != nil {
return "", err
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Accept", "application/json")
res, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("error with send request: %w", err)
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
return "", fmt.Errorf("error with read response: %w", err)
}
var r map[string]interface{}
err = json.Unmarshal(body, &r)
if err != nil {
return "", fmt.Errorf("error with parse response: %w", err)
}
if r["error"] != nil {
return "", fmt.Errorf("error with api response: %s", r["error_description"])
}
return fmt.Sprintf("%s", r["access_token"]), nil
}

View File

@ -22,7 +22,8 @@
@click="changeChat(chat)"> @click="changeChat(chat)">
<el-image :src="chat.icon" class="avatar"/> <el-image :src="chat.icon" class="avatar"/>
<span class="chat-title-input" v-if="chat.edit"> <span class="chat-title-input" v-if="chat.edit">
<el-input v-model="tmpChatTitle" size="small" placeholder="请输入会话标题"/> <el-input v-model="tmpChatTitle" size="small" @keydown="titleKeydown($event, chat)"
placeholder="请输入会话标题"/>
</span> </span>
<span v-else class="chat-title">{{ chat.title }}</span> <span v-else class="chat-title">{{ chat.title }}</span>
<span class="btn btn-check" v-if="chat.edit || chat.removing"> <span class="btn btn-check" v-if="chat.edit || chat.removing">
@ -451,16 +452,24 @@ const editChatTitle = function (event, chat) {
tmpChatTitle.value = chat.title; tmpChatTitle.value = chat.title;
}; };
const titleKeydown = (e, chat) => {
if (e.keyCode === 13) {
e.stopPropagation();
confirm(e, chat)
}
}
// //
const confirm = function (event, chat) { const confirm = function (event, chat) {
event.stopPropagation(); event.stopPropagation();
if (curOpt.value === 'edit') { if (curOpt.value === 'edit') {
if (tmpChatTitle.value === '') { if (tmpChatTitle.value === '') {
ElMessage.error("请输入会话标题!"); return ElMessage.error("请输入会话标题!");
return;
} }
if (!chat.chat_id) {
httpPost('/api/chat/update', {id: chat.id, title: tmpChatTitle.value}).then(() => { return ElMessage.error("对话 ID 为空,请刷新页面再试!");
}
httpPost('/api/chat/update', {chat_id: chat.chat_id, title: tmpChatTitle.value}).then(() => {
chat.title = tmpChatTitle.value; chat.title = tmpChatTitle.value;
chat.edit = false; chat.edit = false;
}).catch(e => { }).catch(e => {