mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-18 01:06:39 +08:00
1. 发起 socket 连接时候传入 chatId 来区分会话。
2. Chat-Plus 界面新增复制回复内容按钮。 3. 优化 ChatFree 聊天会话切换和管理逻辑。
This commit is contained in:
parent
00db78b446
commit
d8bc0fe125
@ -29,7 +29,9 @@ func (s *Server) ChatHandle(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
sessionId := c.Query("sessionId")
|
sessionId := c.Query("sessionId")
|
||||||
roleKey := c.Query("role")
|
roleKey := c.Query("role")
|
||||||
|
chatId := c.Query("chatId")
|
||||||
session, ok := s.ChatSession[sessionId]
|
session, ok := s.ChatSession[sessionId]
|
||||||
|
session.ChatId = chatId
|
||||||
if !ok { // 用户未登录
|
if !ok { // 用户未登录
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
@ -61,18 +63,18 @@ func (s *Server) ChatHandle(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.Info("Receive a message: ", string(message))
|
logger.Info("Receive a message: ", string(message))
|
||||||
//replyMessage(client, "当前 TOKEN 无效,请使用合法的 TOKEN 登录!", false)
|
replyMessage(client, "当前 TOKEN 无效,请使用合法的 TOKEN 登录!", false)
|
||||||
//replyMessage(client, "", true)
|
replyMessage(client, "", false)
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
//ctx, cancel := context.WithCancel(context.Background())
|
||||||
s.ReqCancelFunc[sessionId] = cancel
|
//s.ReqCancelFunc[sessionId] = cancel
|
||||||
// 回复消息
|
//// 回复消息
|
||||||
err = s.sendMessage(ctx, session, chatRole, string(message), client, false)
|
//err = s.sendMessage(ctx, session, chatRole, string(message), client, false)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
logger.Error(err)
|
// logger.Error(err)
|
||||||
} else {
|
//} else {
|
||||||
replyChunkMessage(client, types.WsMessage{Type: types.WsEnd, IsHelloMsg: false})
|
// replyChunkMessage(client, types.WsMessage{Type: types.WsEnd, IsHelloMsg: false})
|
||||||
logger.Info("回答完毕: " + string(message))
|
// logger.Info("回答完毕: " + string(message))
|
||||||
}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -94,20 +96,20 @@ func (s *Server) sendMessage(ctx context.Context, session types.ChatSession, rol
|
|||||||
|
|
||||||
if user.Status == false {
|
if user.Status == false {
|
||||||
replyMessage(ws, "当前 TOKEN 已经被禁用,如果疑问,请联系管理员!", false)
|
replyMessage(ws, "当前 TOKEN 已经被禁用,如果疑问,请联系管理员!", false)
|
||||||
replyMessage(ws, "", true)
|
replyMessage(ws, "", false)
|
||||||
return errors.New("当前 TOKEN " + user.Name + "已经被禁用")
|
return errors.New("当前 TOKEN " + user.Name + "已经被禁用")
|
||||||
}
|
}
|
||||||
|
|
||||||
if time.Now().Unix() > user.ExpiredTime {
|
if time.Now().Unix() > user.ExpiredTime {
|
||||||
exTime := time.Unix(user.ExpiredTime, 0).Format("2006-01-02 15:04:05")
|
exTime := time.Unix(user.ExpiredTime, 0).Format("2006-01-02 15:04:05")
|
||||||
replyMessage(ws, "当前 TOKEN 已过期,过期时间为:"+exTime+",如果疑问,请联系管理员!", false)
|
replyMessage(ws, "当前 TOKEN 已过期,过期时间为:"+exTime+",如果疑问,请联系管理员!", false)
|
||||||
replyMessage(ws, "", true)
|
replyMessage(ws, "", false)
|
||||||
return errors.New("当前 TOKEN " + user.Name + "已过期")
|
return errors.New("当前 TOKEN " + user.Name + "已过期")
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.MaxCalls > 0 && user.RemainingCalls <= 0 {
|
if user.MaxCalls > 0 && user.RemainingCalls <= 0 {
|
||||||
replyMessage(ws, "当前 TOKEN 点数已经用尽,加入我们的知识星球可以免费领取点卡!", false)
|
replyMessage(ws, "当前 TOKEN 点数已经用尽,加入我们的知识星球可以免费领取点卡!", false)
|
||||||
replyMessage(ws, "", true)
|
replyMessage(ws, "", false)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var req = types.ApiRequest{
|
var req = types.ApiRequest{
|
||||||
@ -117,7 +119,7 @@ func (s *Server) sendMessage(ctx context.Context, session types.ChatSession, rol
|
|||||||
Stream: true,
|
Stream: true,
|
||||||
}
|
}
|
||||||
var chatCtx []types.Message
|
var chatCtx []types.Message
|
||||||
var ctxKey = fmt.Sprintf("%s-%s", session.SessionId, role.Key)
|
var ctxKey = fmt.Sprintf("%s-%s-%s", session.SessionId, role.Key, session.ChatId)
|
||||||
if v, ok := s.ChatContexts[ctxKey]; ok && s.Config.Chat.EnableContext {
|
if v, ok := s.ChatContexts[ctxKey]; ok && s.Config.Chat.EnableContext {
|
||||||
chatCtx = v.Messages
|
chatCtx = v.Messages
|
||||||
} else {
|
} else {
|
||||||
@ -190,7 +192,7 @@ func (s *Server) sendMessage(ctx context.Context, session types.ChatSession, rol
|
|||||||
// 如果三次请求都失败的话,则返回对应的错误信息
|
// 如果三次请求都失败的话,则返回对应的错误信息
|
||||||
if err != nil {
|
if err != nil {
|
||||||
replyMessage(ws, ErrorMsg, false)
|
replyMessage(ws, ErrorMsg, false)
|
||||||
replyMessage(ws, "", true)
|
replyMessage(ws, "", false)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +239,7 @@ func (s *Server) sendMessage(ctx context.Context, session types.ChatSession, rol
|
|||||||
if err != nil { // 数据解析出错
|
if err != nil { // 数据解析出错
|
||||||
logger.Error(err, line)
|
logger.Error(err, line)
|
||||||
replyMessage(ws, ErrorMsg, false)
|
replyMessage(ws, ErrorMsg, false)
|
||||||
replyMessage(ws, "", true)
|
replyMessage(ws, "", false)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,3 +475,18 @@ func (s *Server) StopGenerateHandle(c *gin.Context) {
|
|||||||
delete(s.ReqCancelFunc, sessionId)
|
delete(s.ReqCancelFunc, sessionId)
|
||||||
c.JSON(http.StatusOK, types.BizVo{Code: types.Success})
|
c.JSON(http.StatusOK, types.BizVo{Code: types.Success})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetHelloMsgHandle 获取角色的打招呼信息
|
||||||
|
func (s *Server) GetHelloMsgHandle(c *gin.Context) {
|
||||||
|
role := strings.TrimSpace(c.Query("role"))
|
||||||
|
if role == "" {
|
||||||
|
c.JSON(http.StatusOK, types.BizVo{Code: types.InvalidParams, Message: "Invalid args"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
chatRole, err := GetChatRole(role)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, types.BizVo{Code: types.Failed, Message: "Role not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, types.BizVo{Code: types.Success, Data: chatRole.HelloMsg})
|
||||||
|
}
|
||||||
|
@ -94,6 +94,7 @@ func (s *Server) Run(webRoot embed.FS, path string, debug bool) {
|
|||||||
engine.POST("api/chat/stop", s.StopGenerateHandle)
|
engine.POST("api/chat/stop", s.StopGenerateHandle)
|
||||||
engine.POST("api/chat/history", s.GetChatHistoryHandle)
|
engine.POST("api/chat/history", s.GetChatHistoryHandle)
|
||||||
engine.POST("api/chat/history/clear", s.ClearHistoryHandle)
|
engine.POST("api/chat/history/clear", s.ClearHistoryHandle)
|
||||||
|
engine.GET("api/role/hello", s.GetHelloMsgHandle)
|
||||||
|
|
||||||
engine.POST("api/config/set", s.ConfigSetHandle)
|
engine.POST("api/config/set", s.ConfigSetHandle)
|
||||||
engine.GET("api/config/chat-roles/get", s.GetChatRoleListHandle)
|
engine.GET("api/config/chat-roles/get", s.GetChatRoleListHandle)
|
||||||
|
@ -46,6 +46,7 @@ type ChatSession struct {
|
|||||||
SessionId string `json:"session_id"`
|
SessionId string `json:"session_id"`
|
||||||
ClientIP string `json:"client_ip"` // 客户端 IP
|
ClientIP string `json:"client_ip"` // 客户端 IP
|
||||||
Username string `json:"user"` // 当前登录的 user
|
Username string `json:"user"` // 当前登录的 user
|
||||||
|
ChatId string `json:"chat_id"` // 客户端聊天会话 ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChatContext 聊天上下文
|
// ChatContext 聊天上下文
|
||||||
|
@ -6,16 +6,34 @@
|
|||||||
|
|
||||||
<div class="chat-item">
|
<div class="chat-item">
|
||||||
<div class="triangle"></div>
|
<div class="triangle"></div>
|
||||||
<div class="content reply-content" :data-clipboard-text="orgContent" v-html="content"></div>
|
<div class="content-box">
|
||||||
|
<div class="content" v-html="content"></div>
|
||||||
|
<div class="tool-box">
|
||||||
|
<el-tooltip
|
||||||
|
class="box-item"
|
||||||
|
effect="light"
|
||||||
|
content="复制回答"
|
||||||
|
placement="bottom"
|
||||||
|
>
|
||||||
|
<el-button type="info" class="copy-reply" :data-clipboard-text="orgContent">
|
||||||
|
<el-icon>
|
||||||
|
<DocumentCopy/>
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {defineComponent} from "vue"
|
import {defineComponent} from "vue"
|
||||||
|
import {DocumentCopy} from "@element-plus/icons-vue";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'ChatReply',
|
name: 'ChatReply',
|
||||||
|
components: {DocumentCopy},
|
||||||
props: {
|
props: {
|
||||||
content: {
|
content: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -66,6 +84,11 @@ export default defineComponent({
|
|||||||
top: 13px;
|
top: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content-box {
|
||||||
|
|
||||||
|
display flex
|
||||||
|
flex-direction row
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
min-height 20px;
|
min-height 20px;
|
||||||
word-break break-word;
|
word-break break-word;
|
||||||
@ -93,7 +116,17 @@ export default defineComponent({
|
|||||||
p:first-child {
|
p:first-child {
|
||||||
margin-top 0
|
margin-top 0
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-box {
|
||||||
|
padding-left 10px;
|
||||||
|
font-size 16px;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
height 20px
|
||||||
|
padding 5px 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import Chat from "@/views/Chat.vue";
|
|||||||
import NotFound from './views/404.vue'
|
import NotFound from './views/404.vue'
|
||||||
import TestPage from './views/Test.vue'
|
import TestPage from './views/Test.vue'
|
||||||
import Home from "@/views/Home.vue";
|
import Home from "@/views/Home.vue";
|
||||||
import './utils/prototype'
|
|
||||||
import ChatFree from "@/views/ChatFree.vue";
|
import ChatFree from "@/views/ChatFree.vue";
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
|
@ -72,3 +72,17 @@ export function dateFormat(timestamp, format) {
|
|||||||
}
|
}
|
||||||
return timeDate;
|
return timeDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function arrayContains(array, value, compare) {
|
||||||
|
if (typeof compare !== 'function') {
|
||||||
|
compare = function (v1, v2) {
|
||||||
|
return v1 === v2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 0; i < array.length; i++) {
|
||||||
|
if (compare(array[i], value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
8
web/src/utils/prototype.js
vendored
8
web/src/utils/prototype.js
vendored
@ -1,8 +0,0 @@
|
|||||||
// add prototype method for array to insert item
|
|
||||||
Array.prototype.insert = function (index, item) {
|
|
||||||
this.splice(index, 0, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
Array.prototype.remove = function (index) {
|
|
||||||
this.splice(index, 1)
|
|
||||||
}
|
|
@ -21,12 +21,12 @@
|
|||||||
<span class="text" v-else>{{ chat.title }}</span>
|
<span class="text" v-else>{{ 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">
|
||||||
<el-icon @click="confirm(chat)"><Check/></el-icon>
|
<el-icon @click="confirm($event, chat)"><Check/></el-icon>
|
||||||
<el-icon @click="cancel(chat)"><Close/></el-icon>
|
<el-icon @click="cancel($event, chat)"><Close/></el-icon>
|
||||||
</span>
|
</span>
|
||||||
<span class="btn" v-else>
|
<span class="btn" v-else>
|
||||||
<el-icon title="编辑" @click="editChatTitle(chat)"><Edit/></el-icon>
|
<el-icon title="编辑" @click="editChatTitle($event, chat)"><Edit/></el-icon>
|
||||||
<el-icon title="删除会话" @click="removeChat(chat)"><Delete/></el-icon>
|
<el-icon title="删除会话" @click="removeChat($event, chat)"><Delete/></el-icon>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</a></li>
|
</a></li>
|
||||||
@ -183,7 +183,7 @@ import {
|
|||||||
setLoginUser, removeChat, clearChatHistory
|
setLoginUser, removeChat, clearChatHistory
|
||||||
} from "@/utils/storage";
|
} from "@/utils/storage";
|
||||||
import {ElMessage, ElMessageBox} from "element-plus";
|
import {ElMessage, ElMessageBox} from "element-plus";
|
||||||
import {isMobile, randString} from "@/utils/libs";
|
import {arrayContains, isMobile, randString} from "@/utils/libs";
|
||||||
import Clipboard from "clipboard";
|
import Clipboard from "clipboard";
|
||||||
|
|
||||||
// 免费版 ChatGPT
|
// 免费版 ChatGPT
|
||||||
@ -215,6 +215,7 @@ export default defineComponent({
|
|||||||
showLoginDialog: false,
|
showLoginDialog: false,
|
||||||
role: 'gpt',
|
role: 'gpt',
|
||||||
replyIcon: 'images/avatar/yi_yan.png', // 回复信息的头像
|
replyIcon: 'images/avatar/yi_yan.png', // 回复信息的头像
|
||||||
|
helloMsg: '', // 打招呼信息
|
||||||
|
|
||||||
chatList: [], // 会话列表
|
chatList: [], // 会话列表
|
||||||
tmpChatTitle: '',
|
tmpChatTitle: '',
|
||||||
@ -264,9 +265,23 @@ export default defineComponent({
|
|||||||
this.inputBoxWidth = window.innerWidth - document.getElementById('sidebar').offsetWidth - 20;
|
this.inputBoxWidth = window.innerWidth - document.getElementById('sidebar').offsetWidth - 20;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// 初始化打招呼信息
|
||||||
|
httpGet("api/role/hello?role=" + this.role).then((res) => {
|
||||||
|
this.helloMsg = {
|
||||||
|
type: "reply",
|
||||||
|
id: randString(32),
|
||||||
|
icon: this.replyIcon,
|
||||||
|
content: res.data,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
// 加载聊天列表
|
||||||
|
const chatList = getChatList();
|
||||||
|
if (chatList) {
|
||||||
|
this.chatList = chatList;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新会话
|
||||||
this.newChat();
|
this.newChat();
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@ -284,7 +299,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
// 初始化 WebSocket 对象
|
// 初始化 WebSocket 对象
|
||||||
const sessionId = getSessionId();
|
const sessionId = getSessionId();
|
||||||
const socket = new WebSocket(process.env.VUE_APP_WS_HOST + `/api/chat?sessionId=${sessionId}&role=${this.role}`);
|
const socket = new WebSocket(process.env.VUE_APP_WS_HOST + `/api/chat?sessionId=${sessionId}&role=${this.role}&chatId=${this.curChat.id}`);
|
||||||
socket.addEventListener('open', () => {
|
socket.addEventListener('open', () => {
|
||||||
this.sending = false; // 允许用户发送消息
|
this.sending = false; // 允许用户发送消息
|
||||||
this.loading = false; // 隐藏加载层
|
this.loading = false; // 隐藏加载层
|
||||||
@ -292,11 +307,10 @@ export default defineComponent({
|
|||||||
this.errorMessage.close(); // 关闭错误提示信息
|
this.errorMessage.close(); // 关闭错误提示信息
|
||||||
}
|
}
|
||||||
this.activelyClose = false;
|
this.activelyClose = false;
|
||||||
// 加载聊天列表
|
|
||||||
const chatList = getChatList();
|
// 显示打招呼信息
|
||||||
if (chatList) {
|
this.chatData.push(this.helloMsg);
|
||||||
this.chatList = chatList;
|
this.fetchChatHistory(this.curChat.id);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.addEventListener('message', event => {
|
socket.addEventListener('message', event => {
|
||||||
@ -305,11 +319,6 @@ export default defineComponent({
|
|||||||
reader.readAsText(event.data, "UTF-8");
|
reader.readAsText(event.data, "UTF-8");
|
||||||
reader.onload = () => {
|
reader.onload = () => {
|
||||||
const data = JSON.parse(String(reader.result));
|
const data = JSON.parse(String(reader.result));
|
||||||
// 有聊天记录就不输出打招呼消息
|
|
||||||
if (data['is_hello_msg'] && this.chatData.length > 1) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.type === 'start') {
|
if (data.type === 'start') {
|
||||||
this.chatData.push({
|
this.chatData.push({
|
||||||
type: "reply",
|
type: "reply",
|
||||||
@ -334,9 +343,14 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.showStopGenerate = false;
|
this.showStopGenerate = false;
|
||||||
|
|
||||||
this.lineBuffer = ''; // 清空缓冲
|
this.lineBuffer = ''; // 清空缓冲
|
||||||
|
|
||||||
|
// 追加会话
|
||||||
|
if (this.curChat.title === '') {
|
||||||
|
this.curChat.title = this.previousText;
|
||||||
|
setChat(this.curChat);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.lineBuffer += data.content;
|
this.lineBuffer += data.content;
|
||||||
this.chatData[this.chatData.length - 1]['orgContent'] = this.lineBuffer;
|
this.chatData[this.chatData.length - 1]['orgContent'] = this.lineBuffer;
|
||||||
@ -400,12 +414,11 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 从后端获取聊天历史记录
|
// 加载聊天历史记录
|
||||||
fetchChatHistory: function (chatId) {
|
fetchChatHistory: function (chatId) {
|
||||||
const list = getChatHistory(chatId);
|
const list = getChatHistory(chatId);
|
||||||
if (list) {
|
if (list) {
|
||||||
const md = require('markdown-it')();
|
const md = require('markdown-it')();
|
||||||
console.log(list)
|
|
||||||
for (let i = 0; i < list.length; i++) {
|
for (let i = 0; i < list.length; i++) {
|
||||||
if (list[i].type === "prompt") {
|
if (list[i].type === "prompt") {
|
||||||
this.chatData.push(list[i]);
|
this.chatData.push(list[i]);
|
||||||
@ -562,16 +575,14 @@ export default defineComponent({
|
|||||||
if (chatHistory === null) {
|
if (chatHistory === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.curChat.title = chatHistory[0].content;
|
|
||||||
// 追加会话
|
|
||||||
setChat(this.curChat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.appendChat();
|
||||||
this.curChat = {
|
this.curChat = {
|
||||||
id: randString(32),
|
id: randString(32),
|
||||||
edit: false, // 是否处于编辑模式
|
edit: false, // 是否处于编辑模式
|
||||||
removing: false, // 是否处于删除模式
|
removing: false, // 是否处于删除模式
|
||||||
title: '新会话 - 0'
|
title: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
this.chatData = [];
|
this.chatData = [];
|
||||||
@ -582,23 +593,39 @@ export default defineComponent({
|
|||||||
this.connect();
|
this.connect();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 追加当前会话到列表
|
||||||
|
appendChat: function () {
|
||||||
|
if (this.curChat !== null && this.curChat.title !== '') {
|
||||||
|
const compare = function (v1, v2) {
|
||||||
|
return v1.id === v2.id;
|
||||||
|
}
|
||||||
|
if (!arrayContains(this.chatList, this.curChat, compare)) {
|
||||||
|
this.chatList[this.curChat.id] = this.curChat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// 编辑会话标题
|
// 编辑会话标题
|
||||||
editChatTitle: function (chat) {
|
editChatTitle: function (event, chat) {
|
||||||
|
event.stopPropagation();
|
||||||
chat.edit = true;
|
chat.edit = true;
|
||||||
this.curOpt = 'edit';
|
this.curOpt = 'edit';
|
||||||
this.tmpChatTitle = chat.title;
|
this.tmpChatTitle = chat.title;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 确认修改
|
// 确认修改
|
||||||
confirm: function (chat) {
|
confirm: function (event, chat) {
|
||||||
|
event.stopPropagation();
|
||||||
if (this.curOpt === 'edit') {
|
if (this.curOpt === 'edit') {
|
||||||
chat.title = this.tmpChatTitle;
|
chat.title = this.tmpChatTitle;
|
||||||
chat.edit = false;
|
chat.edit = false;
|
||||||
setChat(chat)
|
setChat(chat)
|
||||||
} else if (this.curOpt === 'remove') {
|
} else if (this.curOpt === 'remove') {
|
||||||
delete this.chatList[chat.id];
|
delete this.chatList[chat.id];
|
||||||
|
// 删除的会话是当前的聊天会话,则新建会话
|
||||||
if (this.curChat.id === chat.id) {
|
if (this.curChat.id === chat.id) {
|
||||||
this.chatData = [];
|
this.curChat = null;
|
||||||
|
this.newChat();
|
||||||
}
|
}
|
||||||
removeChat(chat.id);
|
removeChat(chat.id);
|
||||||
chat.removing = false;
|
chat.removing = false;
|
||||||
@ -606,13 +633,15 @@ export default defineComponent({
|
|||||||
|
|
||||||
},
|
},
|
||||||
// 取消修改
|
// 取消修改
|
||||||
cancel: function (chat) {
|
cancel: function (event, chat) {
|
||||||
|
event.stopPropagation();
|
||||||
chat.edit = false;
|
chat.edit = false;
|
||||||
chat.removing = false;
|
chat.removing = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 删除会话
|
// 删除会话
|
||||||
removeChat: function (chat) {
|
removeChat: function (event, chat) {
|
||||||
|
event.stopPropagation();
|
||||||
chat.removing = true;
|
chat.removing = true;
|
||||||
this.curOpt = 'remove';
|
this.curOpt = 'remove';
|
||||||
},
|
},
|
||||||
@ -623,8 +652,10 @@ export default defineComponent({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.appendChat();
|
||||||
|
this.chatData = [];
|
||||||
this.curChat = chat;
|
this.curChat = chat;
|
||||||
this.fetchChatHistory(chat.id);
|
this.connect();
|
||||||
},
|
},
|
||||||
|
|
||||||
// 退出登录
|
// 退出登录
|
||||||
|
@ -253,7 +253,7 @@ export default defineComponent({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const clipboard = new Clipboard('.reply-content');
|
const clipboard = new Clipboard('.copy-reply');
|
||||||
clipboard.on('success', () => {
|
clipboard.on('success', () => {
|
||||||
ElMessage.success('复制成功!');
|
ElMessage.success('复制成功!');
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user