前言
本次主要开发了前端界面的对话管理(包括新建对话、删除对话、对话标题自动生成、修改对话标题、保存会话、选择会话等)功能,效果如下:
对话管理功能具体实现
对话标题自动生成
对话标题自动生成可以划分为以下几个步骤实现:
- 通过EventSource监听服务器发送的标题生成事件。
- 创建一个新的EventSource实例,监听/api/chat/title/${this.cid}接口的事件。
- 设置会话标题为一个空字符串。
- 当接收到消息时,将数据追加到会话标题中。
- 当接收到[DONE]事件时,关闭EventSource连接,选择并保存会话。
- 如果出现错误,关闭EventSource连接。
generateConvTitle(conv,chatMsg=null) {
var that = this;
conv.title=chatMsg||"New Chat";
that.selectConversation(conv, false);
that.saveConversations()
that.tsource = undefined;},
## 修改对话标题
修改对话标题可以分为以下几个步骤实现:
**1. 编辑对话标题**:
- 当用户点击编辑按钮时,调用editTitle方法。
- 将会话的标题存储到临时变量convTitletmp中。
- 设置会话的editable属性为true,允许编辑。
- 使用$set方法更新会话列表。
- 延迟执行,使输入框聚焦以便用户可以直接编辑。
```javascript
2.确认修改对话标题:
- 当用户确认修改标题时,调用changeConvTitle方法。
- 将临时变量convTitletmp的值赋给会话的标题。
- 调用saveConversations方法保存更新后的会话列表。
- 调用cancelChangeConvTitle方法取消编辑状态。
editTitle(idx, conv) { //编辑会话标题,参数为会话id和会话
this.convTitletmp = conv.title; // 存储会话标题的临时副本
conv.editable = true; // 设置会话的 editable 属性为 true,允许编辑
this.$set(this.conversations, idx, conv); // 使用 Vue 的$set 方法更新会话列表
setTimeout(() => { // 延迟执行,确保会话列表更新完毕
document.getElementById("titleInput").focus(); // 聚焦到输入框
}, 150);
},
```
3.取消修改对话标题:
- 当用户取消修改标题时,调用cancelChangeConvTitle方法
- 将会话的editable属性设置为false,禁止编辑。
- 使用$set方法更新会话列表。
cancelChangeConvTitle(idx, conv) {
conv.editable = false;
this.$set(this.conversations, idx, conv);
},
新建对话
新建对话可以分为以下几个步骤实现:
1.触发新建对话:
- 当用户点击“新对话”按钮时,调用newChat方法。
- 方法首先检查当前会话内容是否为空,如果为空则直接返回。
- 重置聊天标题为“New chat”,并更新网页标题。
- 遍历会话列表,删除每个会话的editable、selected、delete属性。
- 调用loadId方法生成新的会话ID。
newChat() {
console.log("正尝试创建新的对话喵");
if (this.conversation.length == 0) {
return;
}
console.log("测试一下是否返回了");
this.chatTitle = "New chat";
document.title = "New chat";
var conversations = this.conversations;
for (let idx in conversations) {
var conv = conversations[idx];
delete conv.editable;
delete conv.selected;
delete conv.delete;
}
this.loadId();
},
2.生成新的对话id:
- 通过axios.post请求生成新的会话ID。
- 成功后,将响应数据中的新会话ID赋给cid,并清空当前会话内容。
loadId() { // 加载会话 ID
// this.cid = Date.now().toString(36); ; // 用时间戳来设置会话 ID
// this.conversation = []; // 清空当前会话内容
// this.conversation.id=this.cid;
var that = this; // 声明一个变量来引用当前的 Vue 实例
this.axios.post(`http://localhost:5000/generate/id`, {}) // 使用 axios 发起 POST 请求来生成会话 ID
.then((result) => { // 请求成功的回调函数
console.log(result); // 打印结果
var resp = result.data; // 获取响应数据即请求的会话id
that.cid = resp.data; // 设置会话 ID
this.conversation = []; // 清空当前会话内容
})
.catch((err) => { // 请求失败的回调函数:补充!!
console.log("无法加载会话ID",err)
});
},
删除对话
删除对话可以分为以下几个步骤来实现:
1.触发删除对话:
- 当用户确认删除对话时,调用delConv方法。
- 使用splice方法从conversations数组中删除指定索引cidx的会话。
- 调用saveConversations方法保存更新后的会话列表。
delConv(cidx) {
this.conversations.splice(cidx, 1);
this.saveConversations();
},
2.取消删除对话:
- 当用户取消删除对话时,调用cancelDelConv方法。
- 将会话的delete属性设置为false。
- 使用$set方法更新会话列表,使会话状态恢复。
cancelDelConv(idx, conv) {
conv.delete = false;
this.$set(this.conversations, idx, conv);
},
保存会话列表
- saveConversations方法用于将会话列表保存到浏览器的localStorage中。
- 深度复制会话列表,删除所有会话的editable、selected、delete属性。
- 将会话列表转换为JSON字符串,并存储到localStorage中。
saveConversations() {
var conversations = JSON.parse(JSON.stringify(this.conversations));
for (let idx in conversations) {
var conv = conversations[idx];
delete conv.editable;
delete conv.selected;
delete conv.delete;
}
let convs = JSON.stringify(conversations);
localStorage.setItem("conversations", convs);
},
选择对话
- selectConversation方法用于选择一个会话。
- 取消旧会话的选中状态,将新会话设为选中状态。
- 更新网页标题和聊天标题。
- 如果loadConv为true,通过axios.get请求加载指定会话的内容。
- 成功加载后,初始化会话内容,并检查是否滚动到底部。
selectConversation(conv, loadConv) { //点击选择会话以显示会话的聊天记录
var that = this; // 声明一个变量来引用当前的 Vue 实例
if (this.oldConv) { // 如果旧的会话存在
this.oldConv.selected = false; // 设置旧的会话的 selected 属性为 false
}
conv.selected = true; // 设置新选择的会话的 selected 属性为 true
this.oldConv = conv; // 将新选择的会话设置为旧的会话
//document.title = conv.title || "chatai"; // 设置网页标题为新选择的会话的标题
this.chatTitle = conv.title || "chatai"; // 设置聊天标题为新选择的会话的标题
if (!loadConv) { // 如果不需要加载会话内容
return; // 停止操作
}
this.axios.get(`http://localhost:5000//conv/${conv.id}`) // 使用 axios 发起 GET 请求来加载会话内容
.then((result) => { // 请求成功的回调函数
console.log("会话选择成功",result); // 打印结果
var resp = result.data; // 获取响应数据
var content = resp.data; // 获取会话内容
this.convLoading=false; //直接设置会话加载为false
that.cid = conv.id; // 设置当前会话 ID,关键
that.conversation = that.initConvs(content.convs); // 初始化会话列表
that.file_list={};
that.now_file_num=0;
// 滚动到最下面,应该指的是聊天框
that.handleScrollBottom();
setTimeout(() => { // 延迟执行,确保会话内容加载完毕
that.isScrollAndNotBottom(); // 检查是否滚动到底部
}, 300);
})
.catch((err) => { // 请求失败的回调函数
console.error("会话内容加载失败",err)
});
},
总结
通过API请求与后台进行交互,使用EventSource实现实时更新会话内容,并使用Vue.js的特性如data属性、methods方法、watch监听和computed计算属性等来实现新建对话、删除对话、自动生成对话标题和修改对话标题等功能。这些功能的实现,使得聊天应用更加灵活和用户友好。