diff --git a/im-uniapp/App.vue b/im-uniapp/App.vue
index a30cd85..c103597 100644
--- a/im-uniapp/App.vue
+++ b/im-uniapp/App.vue
@@ -356,6 +356,10 @@
url: "/pages/chat/chat"
})
} else {
+ uni.showToast({
+ title: '您的登陆信息已失效,请重新登陆',
+ icon: 'none'
+ })
// 跳转到登录页
// #ifdef H5
uni.navigateTo({
diff --git a/im-uniapp/components/chat-item/chat-item.vue b/im-uniapp/components/chat-item/chat-item.vue
index db6f955..21b3e06 100644
--- a/im-uniapp/components/chat-item/chat-item.vue
+++ b/im-uniapp/components/chat-item/chat-item.vue
@@ -17,7 +17,7 @@
{{atText}}
- {{chat.sendNickName+': '}}
+ {{chat.sendNickName+': '}}
@@ -44,6 +44,7 @@
}
},
methods: {
+
showChatBox() {
uni.navigateTo({
url: "/pages/chat/chat-box?chatIdx=" + this.index
@@ -51,6 +52,18 @@
}
},
computed: {
+ isShowSendName() {
+ if (!this.chat.sendNickName) {
+ return false;
+ }
+ let size = this.chat.messages.length;
+ if (size == 0) {
+ return false;
+ }
+ // 只有群聊的普通消息需要显示名称
+ let lastMsg = this.chat.messages[size - 1];
+ return this.$msgType.isNormal(lastMsg.type)
+ },
atText() {
if (this.chat.atMe) {
return "[有人@我]"
diff --git a/im-uniapp/pages/common/user-info.vue b/im-uniapp/pages/common/user-info.vue
index 366a034..4c6c25c 100644
--- a/im-uniapp/pages/common/user-info.vue
+++ b/im-uniapp/pages/common/user-info.vue
@@ -81,7 +81,7 @@
onDelFriend(){
uni.showModal({
title: "确认删除",
- content: `确认要删除与 '${this.userInfo.nickName}'的好友关系吗?`,
+ content: `确认删除 '${this.userInfo.nickName}',并删除聊天记录吗?`,
success: (res)=> {
if(res.cancel)
return;
diff --git a/im-uniapp/store/chatStore.js b/im-uniapp/store/chatStore.js
index 7a4faa0..6ae6eef 100644
--- a/im-uniapp/store/chatStore.js
+++ b/im-uniapp/store/chatStore.js
@@ -92,11 +92,11 @@ export default defineStore('chatStore', {
readedMessage(pos) {
let chat = this.findChatByFriend(pos.friendId);
chat.messages.forEach((m) => {
- if (m.selfSend && m.status < MESSAGE_STATUS.RECALL) {
+ if (m.id && m.selfSend && m.status < MESSAGE_STATUS.RECALL) {
// pos.maxId为空表示整个会话已读
if (!pos.maxId || m.id <= pos.maxId) {
m.status = MESSAGE_STATUS.READED
- chats.stored = false;
+ chat.stored = false;
}
}
})
@@ -137,9 +137,10 @@ export default defineStore('chatStore', {
let chat = chats[idx];
chats.splice(idx, 1);
chats.unshift(chat);
+ chat.lastSendTime = new Date().getTime();
+ chat.stored = false;
this.saveToStorage();
}
-
},
insertMessage(msgInfo) {
// 获取对方id或群id
@@ -171,12 +172,14 @@ export default defineStore('chatStore', {
chat.lastContent = "[文件]";
} else if (msgInfo.type == MESSAGE_TYPE.AUDIO) {
chat.lastContent = "[语音]";
- } else if (msgInfo.type == MESSAGE_TYPE.TEXT || msgInfo.type == MESSAGE_TYPE.RECALL) {
- chat.lastContent = msgInfo.content;
} else if (msgInfo.type == MESSAGE_TYPE.ACT_RT_VOICE) {
chat.lastContent = "[语音通话]";
} else if (msgInfo.type == MESSAGE_TYPE.ACT_RT_VIDEO) {
chat.lastContent = "[视频通话]";
+ } else if (msgInfo.type == MESSAGE_TYPE.TEXT ||
+ msgInfo.type == MESSAGE_TYPE.RECALL ||
+ msgInfo.type == MESSAGE_TYPE.TIP_TEXT) {
+ chat.lastContent = msgInfo.content;
}
chat.lastSendTime = msgInfo.sendTime;
chat.sendNickName = msgInfo.sendNickName;
@@ -313,22 +316,23 @@ export default defineStore('chatStore', {
// 按会话为单位存储,只存储有改动的会话
this.chats.forEach((chat)=>{
let chatKey = `${key}-${chat.type}-${chat.targetId}`
- if(chat.delete){
- uni.removeStorageSync(chatKey);
- return;
- }
if(!chat.stored){
- uni.setStorageSync(chatKey,chat);
+ if(chat.delete){
+ uni.removeStorageSync(chatKey);
+ }else{
+ uni.setStorageSync(chatKey,chat);
+ }
+ chat.stored = true;
+ }
+ if(!chat.delete){
+ chatKeys.push(chatKey);
}
- chat.stored = true;
- chatKeys.push(chatKey);
})
// 会话核心信息
let chatsData = {
privateMsgMaxId: this.privateMsgMaxId,
groupMsgMaxId: this.groupMsgMaxId,
chatKeys: chatKeys
- //chats: this.chats
}
uni.setStorageSync(key, chatsData)
},
diff --git a/im-web/src/store/chatStore.js b/im-web/src/store/chatStore.js
index 826c2db..f9ff092 100644
--- a/im-web/src/store/chatStore.js
+++ b/im-web/src/store/chatStore.js
@@ -21,7 +21,7 @@ export default {
state.chats = [];
state.privateMsgMaxId = chatsData.privateMsgMaxId || 0;
state.groupMsgMaxId = chatsData.groupMsgMaxId || 0;
- cacheChats = chatsData.chats||[];
+ cacheChats = chatsData.chats || [];
// 防止图片一直处在加载中状态
cacheChats.forEach((chat) => {
chat.messages.forEach((msg) => {
@@ -55,7 +55,9 @@ export default {
unreadCount: 0,
messages: [],
atMe: false,
- atAll: false
+ atAll: false,
+ stored: false,
+ delete: false
};
chats.unshift(chat);
}
@@ -72,26 +74,23 @@ export default {
chats[idx].unreadCount = 0;
chats[idx].atMe = false;
chats[idx].atAll = false;
+ chats[idx].stored = false;
+ this.commit("saveToStorage");
+ break;
}
}
- this.commit("saveToStorage");
},
readedMessage(state, pos) {
- let chats = this.getters.findChats();
- for (let idx in chats) {
- if (chats[idx].type == 'PRIVATE' &&
- chats[idx].targetId == pos.friendId) {
- chats[idx].messages.forEach((m) => {
- if (m.selfSend && m.status != MESSAGE_STATUS.RECALL) {
- // pos.maxId为空表示整个会话已读
- if (!pos.maxId || m.id <= pos.maxId) {
- m.status = MESSAGE_STATUS.READED
- }
-
- }
- })
+ let chat = this.getters.findChatByFriend(pos.friendId);
+ chat.messages.forEach((m) => {
+ if (m.id && m.selfSend && m.status != MESSAGE_STATUS.RECALL) {
+ // pos.maxId为空表示整个会话已读
+ if (!pos.maxId || m.id <= pos.maxId) {
+ m.status = MESSAGE_STATUS.READED
+ chat.stored = false;
+ }
}
- }
+ })
this.commit("saveToStorage");
},
removeChat(state, idx) {
@@ -99,9 +98,30 @@ export default {
if (chats[idx] == state.activeChat) {
state.activeChat = null;
}
- chats.splice(idx, 1);
+ chats[idx].delete = true;
+ chats[idx].stored = false;
this.commit("saveToStorage");
},
+ removePrivateChat(state,friendId){
+ let chats = this.getters.findChats();
+ for (let idx in chats) {
+ if (chats[idx].type == 'PRIVATE' &&
+ chats[idx].targetId === friendId) {
+ this.commit("removeChat",idx)
+ break;
+ }
+ }
+ },
+ removeGroupChat(state,groupId){
+ let chats = this.getters.findChats();
+ for (let idx in chats) {
+ if (chats[idx].type == 'GROUP' &&
+ chats[idx].targetId === groupId) {
+ this.commit("removeChat",idx)
+ break;
+ }
+ }
+ },
moveTop(state, idx) {
// 加载中不移动,很耗性能
if (this.getters.isLoading()) {
@@ -112,18 +132,11 @@ export default {
let chat = chats[idx];
chats.splice(idx, 1);
chats.unshift(chat);
+ chat.lastSendTime = new Date().getTime();
+ chat.stored = false;
this.commit("saveToStorage");
}
},
- removePrivateChat(state, friendId) {
- let chats = this.getters.findChats();
- for (let idx in chats) {
- if (chats[idx].type == 'PRIVATE' &&
- chats[idx].targetId == friendId) {
- this.commit("removeChat", idx);
- }
- }
- },
insertMessage(state, msgInfo) {
let type = msgInfo.groupId ? 'GROUP' : 'PRIVATE';
// 记录消息的最大id
@@ -142,6 +155,7 @@ export default {
if (msgInfo.type == MESSAGE_TYPE.RECALL) {
chat.lastContent = msgInfo.content;
}
+ chat.stored = false;
this.commit("saveToStorage");
return;
}
@@ -152,14 +166,14 @@ export default {
chat.lastContent = "[文件]";
} else if (msgInfo.type == MESSAGE_TYPE.AUDIO) {
chat.lastContent = "[语音]";
- } else if (msgInfo.type == MESSAGE_TYPE.TEXT ||
- msgInfo.type == MESSAGE_TYPE.RECALL ||
- msgInfo.type == MESSAGE_TYPE.TIP_TEXT) {
- chat.lastContent = msgInfo.content;
} else if (msgInfo.type == MESSAGE_TYPE.ACT_RT_VOICE) {
chat.lastContent = "[语音通话]";
} else if (msgInfo.type == MESSAGE_TYPE.ACT_RT_VIDEO) {
chat.lastContent = "[视频通话]";
+ } else if (msgInfo.type == MESSAGE_TYPE.TEXT ||
+ msgInfo.type == MESSAGE_TYPE.RECALL ||
+ msgInfo.type == MESSAGE_TYPE.TIP_TEXT) {
+ chat.lastContent = msgInfo.content;
}
chat.lastSendTime = msgInfo.sendTime;
chat.sendNickName = msgInfo.sendNickName;
@@ -199,6 +213,7 @@ export default {
}
}
chat.messages.splice(insertPos, 0, msgInfo);
+ chat.stored = false;
this.commit("saveToStorage");
},
updateMessage(state, msgInfo) {
@@ -208,6 +223,7 @@ export default {
if (message) {
// 属性拷贝
Object.assign(message, msgInfo);
+ chat.stored = false;
this.commit("saveToStorage");
}
},
@@ -226,31 +242,30 @@ export default {
break;
}
}
+ chat.stored = false;
this.commit("saveToStorage");
},
updateChatFromFriend(state, friend) {
- let chats = this.getters.findChats();
- for (let i in chats) {
- let chat = chats[i];
- if (chat.type == 'PRIVATE' && chat.targetId == friend.id) {
- chat.headImage = friend.headImageThumb;
- chat.showName = friend.nickName;
- break;
- }
+ let chat = this.getters.findChatByFriend(friend.id);
+ // 更新会话中的群名和头像
+ if (chat && (chat.headImage != friend.headImageThumb ||
+ chat.showName != friend.nickName)) {
+ chat.headImage = friend.headImageThumb;
+ chat.showName = friend.nickName;
+ chat.stored = false;
+ this.commit("saveToStorage")
}
- this.commit("saveToStorage");
},
updateChatFromGroup(state, group) {
- let chats = this.getters.findChats();
- for (let i in chats) {
- let chat = chats[i];
- if (chat.type == 'GROUP' && chat.targetId == group.id) {
- chat.headImage = group.headImageThumb;
- chat.showName = group.showGroupName;
- break;
- }
+ let chat = this.getters.findChatByGroup(group.id);
+ if (chat && (chat.headImage != group.headImageThumb ||
+ chat.showName != group.showGroupName)) {
+ // 更新会话中的群名称和头像
+ chat.headImage = group.headImageThumb;
+ chat.showName = group.showGroupName;
+ chat.stored = false;
+ this.commit("saveToStorage")
}
- this.commit("saveToStorage");
},
loadingPrivateMsg(state, loading) {
state.loadingPrivateMsg = loading;
@@ -282,10 +297,28 @@ export default {
}
let userId = userStore.state.userInfo.id;
let key = "chats-" + userId;
+ let chatKeys = [];
+ // 按会话为单位存储,
+ state.chats.forEach((chat) => {
+ // 只存储有改动的会话
+ let chatKey = `${key}-${chat.type}-${chat.targetId}`
+ if (!chat.stored) {
+ if (chat.delete) {
+ localForage.removeItem(chatKey);
+ } else {
+ localForage.setItem(chatKey, chat);
+ }
+ chat.stored = true;
+ }
+ if (!chat.delete) {
+ chatKeys.push(chatKey);
+ }
+ })
+ // 会话核心信息
let chatsData = {
privateMsgMaxId: state.privateMsgMaxId,
groupMsgMaxId: state.groupMsgMaxId,
- chats: state.chats
+ chatKeys: chatKeys
}
localForage.setItem(key, chatsData)
},
@@ -293,7 +326,6 @@ export default {
cacheChats = []
state.chats = [];
state.activeChat = null;
-
}
},
actions: {
@@ -301,17 +333,27 @@ export default {
return new Promise((resolve, reject) => {
let userId = userStore.state.userInfo.id;
let key = "chats-" + userId;
- localForage.getItem(key).then((item)=>{
- let chatsData = item;
- // 兼容历史数据,以后要删除
- if(!chatsData){
- chatsData = JSON.parse(localStorage.getItem(key));
+ localForage.getItem(key).then((chatsData) => {
+ if (!chatsData) {
+ resolve();
}
- if (chatsData) {
+ else if(chatsData.chats){
+ // 兼容旧版本
context.commit("initChats", chatsData);
+ resolve();
+ }else if (chatsData.chatKeys) {
+ const promises = [];
+ chatsData.chatKeys.forEach(key => {
+ promises.push(localForage.getItem(key))
+ })
+ Promise.all(promises).then(chats => {
+ chatsData.chats = chats.filter(o => o);
+ context.commit("initChats", chatsData);
+ resolve();
+ })
}
- resolve();
- }).catch(()=>{
+ }).catch((e) => {
+ console.log("加载消息失败")
reject();
})
})
@@ -349,6 +391,16 @@ export default {
}
return chat;
},
+ findChatByFriend: (state, getters) => (fid) => {
+ let chats = getters.findChats();
+ return chats.find(chat => chat.type == 'PRIVATE' &&
+ chat.targetId == fid)
+ },
+ findChatByGroup: (state, getters) => (gid) => {
+ let chats = getters.findChats();
+ return chats.find(chat => chat.type == 'GROUP' &&
+ chat.targetId == gid)
+ },
findMessage: (state) => (chat, msgInfo) => {
if (!chat) {
return null;
diff --git a/im-web/src/view/Chat.vue b/im-web/src/view/Chat.vue
index bb107aa..be1be02 100644
--- a/im-web/src/view/Chat.vue
+++ b/im-web/src/view/Chat.vue
@@ -12,7 +12,7 @@
-
diff --git a/im-web/src/view/Friend.vue b/im-web/src/view/Friend.vue
index 24f29df..c904fd3 100644
--- a/im-web/src/view/Friend.vue
+++ b/im-web/src/view/Friend.vue
@@ -89,7 +89,7 @@
this.loadUserInfo(friend, idx);
},
onDelItem(friend, idx) {
- this.$confirm(`确认要解除与 '${friend.nickName}'的好友关系吗?`, '确认解除?', {
+ this.$confirm(`确认删除'${friend.nickName}',并清空聊天记录吗?`, '确认解除?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
diff --git a/im-web/src/view/Group.vue b/im-web/src/view/Group.vue
index cde4c0e..77dd34e 100644
--- a/im-web/src/view/Group.vue
+++ b/im-web/src/view/Group.vue
@@ -172,7 +172,7 @@
});
},
onDissolve() {
- this.$confirm('确认要解散群聊吗?', '确认解散?', {
+ this.$confirm(`确认要解散'${this.activeGroup.name}'吗?`, '确认解散?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
@@ -183,6 +183,7 @@
}).then(() => {
this.$message.success(`群聊'${this.activeGroup.name}'已解散`);
this.$store.commit("removeGroup", this.activeGroup.id);
+ this.$store.commit("removeGroupChat", this.activeGroup.id);
this.reset();
});
})
@@ -208,7 +209,7 @@
},
onQuit() {
- this.$confirm('退出群聊后将不再接受群里的消息,确认退出吗?', '确认退出?', {
+ this.$confirm(`确认退出'${this.activeGroup.showGroupName}',并清空聊天记录吗?`, '确认退出?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
@@ -217,6 +218,7 @@
url: `/group/quit/${this.activeGroup.id}`,
method: 'delete'
}).then(() => {
+ this.$message.success(`您已退出'${this.activeGroup.name}'`);
this.$store.commit("removeGroup", this.activeGroup.id);
this.$store.commit("removeGroupChat", this.activeGroup.id);
this.reset();