Browse Source

uniapp性能优化: 1.用pinia代替vuex

master
xsx 2 years ago
parent
commit
d791ab2940
  1. 77
      im-uniapp/App.vue
  2. 3
      im-uniapp/components/chat-at-box/chat-at-box.vue
  3. 3
      im-uniapp/components/chat-group-readed/chat-group-readed.vue
  4. 3
      im-uniapp/components/group-rtc-join/group-rtc-join.vue
  5. 19
      im-uniapp/main.js
  6. 58
      im-uniapp/pages/chat/chat-box.vue
  7. 6
      im-uniapp/pages/chat/chat-group-video.vue
  8. 6
      im-uniapp/pages/chat/chat-private-video.vue
  9. 10
      im-uniapp/pages/chat/chat.vue
  10. 19
      im-uniapp/pages/common/user-info.vue
  11. 8
      im-uniapp/pages/friend/friend-add.vue
  12. 3
      im-uniapp/pages/friend/friend.vue
  13. 21
      im-uniapp/pages/group/group-edit.vue
  14. 24
      im-uniapp/pages/group/group-info.vue
  15. 7
      im-uniapp/pages/group/group-invite.vue
  16. 7
      im-uniapp/pages/group/group-member.vue
  17. 5
      im-uniapp/pages/group/group.vue
  18. 5
      im-uniapp/pages/mine/mine-edit.vue
  19. 6
      im-uniapp/pages/mine/mine.vue
  20. 262
      im-uniapp/store/chatStore.js
  21. 34
      im-uniapp/store/configStore.js
  22. 103
      im-uniapp/store/friendStore.js
  23. 58
      im-uniapp/store/groupStore.js
  24. 35
      im-uniapp/store/index.js
  25. 42
      im-uniapp/store/userStore.js

77
im-uniapp/App.vue

@ -1,14 +1,19 @@
<script> <script>
import store from './store'; import App from './App'
import http from './common/request'; import http from './common/request';
import * as msgType from './common/messageType'; import * as msgType from './common/messageType';
import * as enums from './common/enums'; import * as enums from './common/enums';
import * as wsApi from './common/wssocket'; import * as wsApi from './common/wssocket';
import UNI_APP from '@/.env.js' import UNI_APP from '@/.env.js'
export default { export default {
data() { data() {
return { return {
chatStore: this.useChatStore(),
friendStore: this.useFriendStore(),
groupStore: this.useGroupStore(),
configStore: this.useConfigStore(),
userStore: this.useUserStore(),
isExit: false, // 退 isExit: false, // 退
audioTip: null, audioTip: null,
reconnecting: false // reconnecting: false //
@ -18,7 +23,7 @@
init() { init() {
this.isExit = false; this.isExit = false;
// //
store.dispatch("load").then(() => { this.loadStore().then(() => {
// websocket // websocket
this.initWebSocket(); this.initWebSocket();
}).catch((e) => { }).catch((e) => {
@ -40,8 +45,8 @@
}) })
} }
// 线 // 线
this.pullPrivateOfflineMessage(store.state.chatStore.privateMsgMaxId); this.pullPrivateOfflineMessage(this.chatStore.privateMsgMaxId);
this.pullGroupOfflineMessage(store.state.chatStore.groupMsgMaxId); this.pullGroupOfflineMessage(this.chatStore.groupMsgMaxId);
}); });
wsApi.onMessage((cmd, msgInfo) => { wsApi.onMessage((cmd, msgInfo) => {
if (cmd == 2) { if (cmd == 2) {
@ -69,33 +74,51 @@
}) })
}, },
loadStore(){
return this.userStore.loadUser().then(() => {
const promises = [];
promises.push(this.friendStore.loadFriend());
promises.push(this.groupStore.loadGroup());
promises.push(this.chatStore.loadChat());
promises.push(this.configStore.loadConfig());
return Promise.all(promises);
})
},
unloadStore(){
this.friendStore.clear();
this.groupStore.clear();
this.chatStore.clear();
this.configStore.clear();
this.userStore.clear();
},
pullPrivateOfflineMessage(minId) { pullPrivateOfflineMessage(minId) {
store.commit("loadingPrivateMsg", true) this.chatStore.setLoadingPrivateMsg(true)
http({ http({
url: "/message/private/pullOfflineMessage?minId=" + minId, url: "/message/private/pullOfflineMessage?minId=" + minId,
method: 'GET' method: 'GET'
}).catch(() => { }).catch(() => {
store.commit("loadingPrivateMsg", false) this.chatStore.setLoadingPrivateMsg(false)
}) })
}, },
pullGroupOfflineMessage(minId) { pullGroupOfflineMessage(minId) {
store.commit("loadingGroupMsg", true) this.chatStore.setLoadingGroupMsg(true)
http({ http({
url: "/message/group/pullOfflineMessage?minId=" + minId, url: "/message/group/pullOfflineMessage?minId=" + minId,
method: 'GET' method: 'GET'
}).catch(() => { }).catch(() => {
store.commit("loadingGroupMsg", false) this.chatStore.setLoadingGroupMsg(false)
}) })
}, },
handlePrivateMessage(msg) { handlePrivateMessage(msg) {
console.log("handlePrivateMessage")
// //
if (msg.type == enums.MESSAGE_TYPE.LOADING) { if (msg.type == enums.MESSAGE_TYPE.LOADING) {
store.commit("loadingPrivateMsg", JSON.parse(msg.content)) this.chatStore.setLoadingPrivateMsg(JSON.parse(msg.content))
return; return;
} }
// //
if (msg.type == enums.MESSAGE_TYPE.READED) { if (msg.type == enums.MESSAGE_TYPE.READED) {
store.commit("resetUnreadCount", { this.chatStore.resetUnreadCount( {
type: 'PRIVATE', type: 'PRIVATE',
targetId: msg.recvId targetId: msg.recvId
}) })
@ -103,13 +126,13 @@
} }
// , // ,
if (msg.type == enums.MESSAGE_TYPE.RECEIPT) { if (msg.type == enums.MESSAGE_TYPE.RECEIPT) {
store.commit("readedMessage", { this.chatStore.readedMessage( {
friendId: msg.sendId friendId: msg.sendId
}) })
return; return;
} }
// //
msg.selfSend = msg.sendId == store.state.userStore.userInfo.id; msg.selfSend = msg.sendId == this.userStore.userInfo.id;
// id // id
let friendId = msg.selfSend ? msg.recvId : msg.sendId; let friendId = msg.selfSend ? msg.recvId : msg.sendId;
this.loadFriendInfo(friendId).then((friend) => { this.loadFriendInfo(friendId).then((friend) => {
@ -151,9 +174,9 @@
headImage: friend.headImage headImage: friend.headImage
}; };
// //
store.commit("openChat", chatInfo); this.chatStore.openChat(chatInfo);
// //
store.commit("insertMessage", msg); this.chatStore.insertMessage(msg);
// //
this.playAudioTip(); this.playAudioTip();
@ -161,7 +184,7 @@
handleGroupMessage(msg) { handleGroupMessage(msg) {
// //
if (msg.type == enums.MESSAGE_TYPE.LOADING) { if (msg.type == enums.MESSAGE_TYPE.LOADING) {
store.commit("loadingGroupMsg", JSON.parse(msg.content)) this.chatStore.setLoadingGroupMsg(JSON.parse(msg.content))
return; return;
} }
// //
@ -171,7 +194,7 @@
type: 'GROUP', type: 'GROUP',
targetId: msg.groupId targetId: msg.groupId
} }
store.commit("resetUnreadCount", chatInfo) this.chatStore.resetUnreadCount(chatInfo)
return; return;
} }
// //
@ -183,11 +206,11 @@
readedCount: msg.readedCount, readedCount: msg.readedCount,
receiptOk: msg.receiptOk receiptOk: msg.receiptOk
}; };
store.commit("updateMessage", msgInfo) this.chatStore.updateMessage(msgInfo)
return; return;
} }
// //
msg.selfSend = msg.sendId == store.state.userStore.userInfo.id; msg.selfSend = msg.sendId == this.userStore.userInfo.id;
this.loadGroupInfo(msg.groupId).then((group) => { this.loadGroupInfo(msg.groupId).then((group) => {
// //
this.insertGroupMessage(group, msg); this.insertGroupMessage(group, msg);
@ -241,15 +264,15 @@
headImage: group.headImageThumb headImage: group.headImageThumb
}; };
// //
store.commit("openChat", chatInfo); this.chatStore.openChat(chatInfo);
// //
store.commit("insertMessage", msg); this.chatStore.insertMessage( msg);
// //
this.playAudioTip(); this.playAudioTip();
}, },
loadFriendInfo(id) { loadFriendInfo(id) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let friend = store.getters.findFriend(id); let friend = this.friendStore.findFriend(id);
if (friend) { if (friend) {
resolve(friend); resolve(friend);
} else { } else {
@ -257,7 +280,7 @@
url: `/friend/find/${id}`, url: `/friend/find/${id}`,
method: 'GET' method: 'GET'
}).then((friend) => { }).then((friend) => {
store.commit("addFriend", friend); this.friendStore.addFriend(friend);
resolve(friend) resolve(friend)
}) })
} }
@ -265,7 +288,7 @@
}, },
loadGroupInfo(id) { loadGroupInfo(id) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let group = store.state.groupStore.groups.find((g) => g.id == id); let group = this.groupStore.groups.find((g) => g.id == id);
if (group) { if (group) {
resolve(group); resolve(group);
} else { } else {
@ -273,8 +296,8 @@
url: `/group/find/${id}`, url: `/group/find/${id}`,
method: 'GET' method: 'GET'
}).then((group) => { }).then((group) => {
this.groupStore.addGroup(group);
resolve(group) resolve(group)
store.commit("addGroup", group);
}) })
} }
}); });
@ -287,7 +310,7 @@
uni.reLaunch({ uni.reLaunch({
url: "/pages/login/login" url: "/pages/login/login"
}) })
store.dispatch("unload"); this.unloadStore();
}, },
playAudioTip() { playAudioTip() {
// //
@ -314,7 +337,7 @@
title: '连接已断开,尝试重新连接...', title: '连接已断开,尝试重新连接...',
icon: 'none', icon: 'none',
}) })
store.commit("setUserInfo", userInfo); this.userStore.setUserInfo(userInfo);
// //
let loginInfo = uni.getStorageSync("loginInfo") let loginInfo = uni.getStorageSync("loginInfo")
wsApi.reconnect(UNI_APP.WS_URL, loginInfo.accessToken); wsApi.reconnect(UNI_APP.WS_URL, loginInfo.accessToken);

3
im-uniapp/components/chat-at-box/chat-at-box.vue

@ -49,6 +49,7 @@
}, },
data() { data() {
return { return {
userStore: this.useUserStore(),
searchText: "", searchText: "",
showMembers:[] showMembers:[]
}; };
@ -56,7 +57,7 @@
methods: { methods: {
init(atUserIds) { init(atUserIds) {
this.showMembers = []; this.showMembers = [];
let userId = this.$store.state.userStore.userInfo.id; let userId = this.userStore.userInfo.id;
if(this.ownerId == userId){ if(this.ownerId == userId){
this.showMembers.push({ this.showMembers.push({
userId:-1, userId:-1,

3
im-uniapp/components/chat-group-readed/chat-group-readed.vue

@ -37,6 +37,7 @@
name: "chat-group-readed", name: "chat-group-readed",
data() { data() {
return { return {
chatStore: this.useChatStore(),
items: ['已读', '未读'], items: ['已读', '未读'],
current: 0, current: 0,
readedMembers: [], readedMembers: [],
@ -79,7 +80,7 @@
this.items[0] = `已读(${this.readedMembers.length})`; this.items[0] = `已读(${this.readedMembers.length})`;
this.items[1] = `未读(${this.unreadMembers.length})`; this.items[1] = `未读(${this.unreadMembers.length})`;
// //
this.$store.commit("updateMessage", { this.chatStore.updateMessage({
id: this.msgInfo.id, id: this.msgInfo.id,
groupId: this.msgInfo.groupId, groupId: this.msgInfo.groupId,
readedCount: this.readedMembers.length readedCount: this.readedMembers.length

3
im-uniapp/components/group-rtc-join/group-rtc-join.vue

@ -26,6 +26,7 @@
export default { export default {
data() { data() {
return { return {
userStore: this.useUserStore(),
rtcInfo: {} rtcInfo: {}
} }
}, },
@ -41,7 +42,7 @@
}, },
onOk() { onOk() {
let users = this.rtcInfo.userInfos; let users = this.rtcInfo.userInfos;
let mine = this.$store.state.userStore.userInfo; let mine = this.userStore.userInfo;
// //
if(!users.find((user)=>user.id==mine.id)){ if(!users.find((user)=>user.id==mine.id)){
users.push({ users.push({

19
im-uniapp/main.js

@ -5,9 +5,15 @@ import * as enums from './common/enums.js';
import * as date from './common/date'; import * as date from './common/date';
import * as socketApi from './common/wssocket'; import * as socketApi from './common/wssocket';
import * as messageType from './common/messageType'; import * as messageType from './common/messageType';
import store from './store';
import { createSSRApp } from 'vue' import { createSSRApp } from 'vue'
import uviewPlus from '@/uni_modules/uview-plus' import uviewPlus from '@/uni_modules/uview-plus'
import * as pinia from 'pinia';
import useChatStore from '@/store/chatStore.js'
import useFriendStore from '@/store/friendStore.js'
import useGroupStore from '@/store/groupStore.js'
import useConfigStore from '@/store/configStore.js'
import useUserStore from '@/store/userStore.js'
// #ifdef H5 // #ifdef H5
import * as recorder from './common/recorder-h5'; import * as recorder from './common/recorder-h5';
// #endif // #endif
@ -18,8 +24,8 @@ import * as recorder from './common/recorder-app';
export function createApp() { export function createApp() {
const app = createSSRApp(App) const app = createSSRApp(App)
app.use(store);
app.use(uviewPlus); app.use(uviewPlus);
app.use(pinia.createPinia());
app.config.globalProperties.$http = request; app.config.globalProperties.$http = request;
app.config.globalProperties.$wsApi = socketApi; app.config.globalProperties.$wsApi = socketApi;
app.config.globalProperties.$msgType = messageType; app.config.globalProperties.$msgType = messageType;
@ -27,7 +33,14 @@ export function createApp() {
app.config.globalProperties.$enums = enums; app.config.globalProperties.$enums = enums;
app.config.globalProperties.$date = date; app.config.globalProperties.$date = date;
app.config.globalProperties.$rc = recorder; app.config.globalProperties.$rc = recorder;
app.config.globalProperties.useChatStore = useChatStore;
app.config.globalProperties.useFriendStore = useFriendStore;
app.config.globalProperties.useGroupStore = useGroupStore;
app.config.globalProperties.useConfigStore = useConfigStore;
app.config.globalProperties.useUserStore = useUserStore;
return { return {
app app,
pinia
} }
} }

58
im-uniapp/pages/chat/chat-box.vue

@ -108,18 +108,27 @@
<chat-at-box ref="atBox" :ownerId="group.ownerId" :members="groupMembers" <chat-at-box ref="atBox" :ownerId="group.ownerId" :members="groupMembers"
@complete="onAtComplete"></chat-at-box> @complete="onAtComplete"></chat-at-box>
<!-- 群语音通话时选择成员 --> <!-- 群语音通话时选择成员 -->
<!-- #ifndef MP-WEIXIN -->
<group-member-selector ref="selBox" :members="groupMembers" <group-member-selector ref="selBox" :members="groupMembers"
:maxSize="$store.state.configStore.webrtc.maxChannel" :maxSize="configStore.webrtc.maxChannel"
@complete="onInviteOk"></group-member-selector> @complete="onInviteOk"></group-member-selector>
<group-rtc-join ref="rtcJoin" :groupId="group.id"></group-rtc-join> <group-rtc-join ref="rtcJoin" :groupId="group.id"></group-rtc-join>
<!-- #endif -->
</view> </view>
</template> </template>
<script> <script>
import UNI_APP from '@/.env.js'; import UNI_APP from '@/.env.js';
import useChatStore from '@/store/chatStore.js'
export default { export default {
data() { data() {
return { return {
chatStore: useChatStore(),
friendStore: this.useFriendStore(),
groupStore: this.useGroupStore(),
configStore: this.useConfigStore(),
userStore: this.useUserStore(),
chat: {}, chat: {},
friend: {}, friend: {},
group: {}, group: {},
@ -157,7 +166,7 @@
this.fillTargetId(msgInfo, this.chat.targetId); this.fillTargetId(msgInfo, this.chat.targetId);
this.sendMessageRequest(msgInfo).then((m) => { this.sendMessageRequest(msgInfo).then((m) => {
m.selfSend = true; m.selfSend = true;
this.$store.commit("insertMessage", m); this.chatStore.insertMessage(m);
// //
this.moveChatToTop(); this.moveChatToTop();
// //
@ -226,8 +235,8 @@
}) })
}, },
moveChatToTop() { moveChatToTop() {
let chatIdx = this.$store.getters.findChatIdx(this.chat); let chatIdx = this.chatStore.findChatIdx(this.chat);
this.$store.commit("moveTop", chatIdx); this.chatStore.moveTop(chatIdx);
}, },
switchReceipt() { switchReceipt() {
this.isReceipt = !this.isReceipt; this.isReceipt = !this.isReceipt;
@ -261,6 +270,7 @@
} }
}, },
sendTextMessage() { sendTextMessage() {
const timeStamp = new Date().getTime();
if (!this.sendText.trim() && this.atUserIds.length == 0) { if (!this.sendText.trim() && this.atUserIds.length == 0) {
return uni.showToast({ return uni.showToast({
title: "不能发送空白信息", title: "不能发送空白信息",
@ -279,8 +289,10 @@
// id // id
this.fillTargetId(msgInfo, this.chat.targetId); this.fillTargetId(msgInfo, this.chat.targetId);
this.sendMessageRequest(msgInfo).then((m) => { this.sendMessageRequest(msgInfo).then((m) => {
console.log("请求耗时:",new Date().getTime()-timeStamp)
m.selfSend = true; m.selfSend = true;
this.$store.commit("insertMessage", m); this.chatStore.insertMessage(m);
console.log("insertMessage耗时:",new Date().getTime()-timeStamp)
// //
this.moveChatToTop(); this.moveChatToTop();
}).finally(() => { }).finally(() => {
@ -387,7 +399,7 @@
// id // id
this.fillTargetId(msgInfo, this.chat.targetId); this.fillTargetId(msgInfo, this.chat.targetId);
// //
this.$store.commit("insertMessage", msgInfo); this.chatStore.insertMessage(msgInfo);
// //
this.moveChatToTop(); this.moveChatToTop();
// file // file
@ -404,13 +416,13 @@
msgInfo.loadStatus = 'ok'; msgInfo.loadStatus = 'ok';
msgInfo.id = m.id; msgInfo.id = m.id;
this.isReceipt = false; this.isReceipt = false;
this.$store.commit("insertMessage", msgInfo); this.chatStore.insertMessage(msgInfo);
}) })
}, },
onUploadImageFail(file, err) { onUploadImageFail(file, err) {
let msgInfo = JSON.parse(JSON.stringify(file.msgInfo)); let msgInfo = JSON.parse(JSON.stringify(file.msgInfo));
msgInfo.loadStatus = 'fail'; msgInfo.loadStatus = 'fail';
this.$store.commit("insertMessage", msgInfo); this.chatStore.insertMessage(msgInfo);
}, },
onUploadFileBefore(file) { onUploadFileBefore(file) {
let data = { let data = {
@ -433,7 +445,7 @@
// id // id
this.fillTargetId(msgInfo, this.chat.targetId); this.fillTargetId(msgInfo, this.chat.targetId);
// //
this.$store.commit("insertMessage", msgInfo); this.chatStore.insertMessage(msgInfo);
// //
this.moveChatToTop(); this.moveChatToTop();
// file // file
@ -455,13 +467,13 @@
msgInfo.loadStatus = 'ok'; msgInfo.loadStatus = 'ok';
msgInfo.id = m.id; msgInfo.id = m.id;
this.isReceipt = false; this.isReceipt = false;
this.$store.commit("insertMessage", msgInfo); this.chatStore.insertMessage(msgInfo);
}) })
}, },
onUploadFileFail(file, res) { onUploadFileFail(file, res) {
let msgInfo = JSON.parse(JSON.stringify(file.msgInfo)); let msgInfo = JSON.parse(JSON.stringify(file.msgInfo));
msgInfo.loadStatus = 'fail'; msgInfo.loadStatus = 'fail';
this.$store.commit("insertMessage", msgInfo); this.chatStore.insertMessage(msgInfo);
}, },
onDeleteMessage(msgInfo) { onDeleteMessage(msgInfo) {
uni.showModal({ uni.showModal({
@ -469,7 +481,7 @@
content: '确认删除消息?', content: '确认删除消息?',
success: (res) => { success: (res) => {
if (!res.cancel) { if (!res.cancel) {
this.$store.commit("deleteMessage", msgInfo); this.chatStore.deleteMessage(msgInfo);
uni.showToast({ uni.showToast({
title: "删除成功", title: "删除成功",
icon: "none" icon: "none"
@ -493,7 +505,7 @@
msgInfo.type = this.$enums.MESSAGE_TYPE.RECALL; msgInfo.type = this.$enums.MESSAGE_TYPE.RECALL;
msgInfo.content = '你撤回了一条消息'; msgInfo.content = '你撤回了一条消息';
msgInfo.status = this.$enums.MESSAGE_STATUS.RECALL; msgInfo.status = this.$enums.MESSAGE_STATUS.RECALL;
this.$store.commit("insertMessage", msgInfo); this.chatStore.insertMessage(msgInfo);
}) })
} }
} }
@ -558,7 +570,7 @@
url: `/message/private/maxReadedId?friendId=${fId}`, url: `/message/private/maxReadedId?friendId=${fId}`,
method: 'get' method: 'get'
}).then((id) => { }).then((id) => {
this.$store.commit("readedMessage", { this.chatStore.readedMessage({
friendId: fId, friendId: fId,
maxId: id maxId: id
}); });
@ -578,7 +590,7 @@
url: url, url: url,
method: 'PUT' method: 'PUT'
}).then(() => { }).then(() => {
this.$store.commit("resetUnreadCount", this.chat) this.chatStore.resetUnreadCount(this.chat)
this.scrollToBottom(); this.scrollToBottom();
}) })
}, },
@ -588,8 +600,8 @@
method: 'GET' method: 'GET'
}).then((group) => { }).then((group) => {
this.group = group; this.group = group;
this.$store.commit("updateChatFromGroup", group); this.chatStore.updateChatFromGroup(group);
this.$store.commit("updateGroup", group); this.groupStore.updateGroup(group);
}); });
this.$http({ this.$http({
@ -606,8 +618,8 @@
method: 'GET' method: 'GET'
}).then((friend) => { }).then((friend) => {
this.friend = friend; this.friend = friend;
this.$store.commit("updateChatFromFriend", friend); this.chatStore.updateChatFromFriend(friend);
this.$store.commit("updateFriend", friend); this.friendStore.updateFriend(friend);
}) })
}, },
rpxTopx(rpx) { rpxTopx(rpx) {
@ -649,7 +661,7 @@
}, },
computed: { computed: {
mine() { mine() {
return this.$store.state.userStore.userInfo; return this.userStore.userInfo;
}, },
title() { title() {
if (!this.chat) { if (!this.chat) {
@ -719,7 +731,7 @@
}, },
onLoad(options) { onLoad(options) {
// //
this.chat = this.$store.state.chatStore.chats[options.chatIdx]; this.chat = this.chatStore.chats[options.chatIdx];
// 20 // 20
let size = this.messageSize; let size = this.messageSize;
this.showMinIdx = size > 20 ? size - 20 : 0; this.showMinIdx = size > 20 ? size - 20 : 0;
@ -733,12 +745,12 @@
this.loadReaded(this.chat.targetId) this.loadReaded(this.chat.targetId)
} }
// //
this.$store.commit("activeChat", options.chatIdx); this.chatStore.activeChat(options.chatIdx);
// //
this.isReceipt = false; this.isReceipt = false;
}, },
onUnload() { onUnload() {
this.$store.commit("activeChat", -1); this.chatStore.activeChat(-1);
}, },
onShow(){ onShow(){
if(this.needScrollToBottom){ if(this.needScrollToBottom){

6
im-uniapp/pages/chat/chat-group-video.vue

@ -7,6 +7,8 @@
export default { export default {
data() { data() {
return { return {
configStore: this.useConfigStore(),
userStore: this.useUserStore(),
url: "", url: "",
wv: '', wv: '',
isHost: false, isHost: false,
@ -67,12 +69,12 @@
this.url = "/hybrid/html/rtc-group/index.html?"; this.url = "/hybrid/html/rtc-group/index.html?";
this.url += "baseUrl=" + UNI_APP.BASE_URL; this.url += "baseUrl=" + UNI_APP.BASE_URL;
this.url += "&groupId=" + this.groupId; this.url += "&groupId=" + this.groupId;
this.url += "&userId=" + this.$store.state.userStore.userInfo.id; this.url += "&userId=" + this.userStore.userInfo.id;
this.url += "&inviterId=" + this.inviterId; this.url += "&inviterId=" + this.inviterId;
this.url += "&isHost=" + this.isHost; this.url += "&isHost=" + this.isHost;
this.url += "&loginInfo=" + JSON.stringify(uni.getStorageSync("loginInfo")); this.url += "&loginInfo=" + JSON.stringify(uni.getStorageSync("loginInfo"));
this.url += "&userInfos=" + JSON.stringify(this.userInfos); this.url += "&userInfos=" + JSON.stringify(this.userInfos);
this.url += "&config=" + JSON.stringify(this.$store.state.configStore.webrtc); this.url += "&config=" + JSON.stringify(this.configStore.webrtc);
}, },
}, },
onBackPress() { onBackPress() {

6
im-uniapp/pages/chat/chat-private-video.vue

@ -7,6 +7,8 @@
export default { export default {
data() { data() {
return { return {
configStore: this.useConfigStore(),
userStore: this.useUserStore(),
url: "", url: "",
wv: '', wv: '',
mode: "video", mode: "video",
@ -62,9 +64,9 @@
this.url += "&isHost="+this.isHost; this.url += "&isHost="+this.isHost;
this.url += "&baseUrl="+UNI_APP.BASE_URL; this.url += "&baseUrl="+UNI_APP.BASE_URL;
this.url += "&loginInfo="+JSON.stringify(uni.getStorageSync("loginInfo")); this.url += "&loginInfo="+JSON.stringify(uni.getStorageSync("loginInfo"));
this.url += "&userInfo="+JSON.stringify(this.$store.state.userStore.userInfo); this.url += "&userInfo="+JSON.stringify(this.userStore.userInfo);
this.url += "&friend="+JSON.stringify(this.friend); this.url += "&friend="+JSON.stringify(this.friend);
this.url += "&config=" + JSON.stringify(this.$store.state.configStore.webrtc); this.url += "&config=" + JSON.stringify(this.configStore.webrtc);
}, },
}, },
onBackPress() { onBackPress() {

10
im-uniapp/pages/chat/chat.vue

@ -26,9 +26,12 @@
</template> </template>
<script> <script>
import useChatStore from '@/store/chatStore.js'
export default { export default {
data() { data() {
return { return {
chatStore: useChatStore(),
searchText: "", searchText: "",
menu: { menu: {
show: false, show: false,
@ -65,10 +68,10 @@
this.menu.show = false; this.menu.show = false;
}, },
removeChat(chatIdx) { removeChat(chatIdx) {
this.$store.commit("removeChat", chatIdx); this.chatStore.removeChat(chatIdx);
}, },
moveToTop(chatIdx) { moveToTop(chatIdx) {
this.$store.commit("moveTop", chatIdx); this.chatStore.moveTop(chatIdx);
}, },
isShowChat(chat){ isShowChat(chat){
if(chat.delete){ if(chat.delete){
@ -107,9 +110,6 @@
}); });
return chatsPos; return chatsPos;
}, },
chatStore() {
return this.$store.state.chatStore;
},
unreadCount() { unreadCount() {
let count = 0; let count = 0;
this.chatStore.chats.forEach(chat => { this.chatStore.chats.forEach(chat => {

19
im-uniapp/pages/common/user-info.vue

@ -35,6 +35,9 @@
export default { export default {
data() { data() {
return { return {
userStore: this.useUserStore(),
chatStore: this.useChatStore(),
friendStore: this.useFriendStore(),
userInfo: {} userInfo: {}
} }
}, },
@ -54,8 +57,8 @@
showName: this.userInfo.nickName, showName: this.userInfo.nickName,
headImage: this.userInfo.headImage, headImage: this.userInfo.headImage,
}; };
this.$store.commit("openChat", chat); this.chatStore.openChat(chat);
let chatIdx = this.$store.getters.findChatIdx(chat); let chatIdx = this.chatStore.findChatIdx(chat);
uni.navigateTo({ uni.navigateTo({
url:"/pages/chat/chat-box?chatIdx=" + chatIdx url:"/pages/chat/chat-box?chatIdx=" + chatIdx
}) })
@ -71,7 +74,7 @@
headImage: this.userInfo.headImageThumb, headImage: this.userInfo.headImageThumb,
online: this.userInfo.online online: this.userInfo.online
} }
this.$store.commit("addFriend", friend); this.friendStore.addFriend(friend);
uni.showToast({ uni.showToast({
title: '对方已成为您的好友', title: '对方已成为您的好友',
icon: 'none' icon: 'none'
@ -89,8 +92,8 @@
url: `/friend/delete/${this.userInfo.id}`, url: `/friend/delete/${this.userInfo.id}`,
method: 'delete' method: 'delete'
}).then((data) => { }).then((data) => {
this.$store.commit("removeFriend", this.userInfo.id); this.friendStore.removeFriend(this.userInfo.id);
this.$store.commit("removePrivateChat", this.userInfo.id); this.chatStore.removePrivateChat(this.userInfo.id);
uni.showToast({ uni.showToast({
title: `与 '${this.userInfo.nickName}'的好友关系已解除`, title: `与 '${this.userInfo.nickName}'的好友关系已解除`,
icon: 'none' icon: 'none'
@ -110,9 +113,9 @@
data: friend data: friend
}).then(() => { }).then(() => {
// //
this.$store.commit("updateFriend", friend); this.friendStore.updateFriend(friend);
// //
this.$store.commit("updateChatFromFriend", this.userInfo); this.chatStore.updateChatFromFriend(this.userInfo);
}) })
}, },
loadUserInfo(id){ loadUserInfo(id){
@ -134,7 +137,7 @@
return this.friendInfo&&!this.friendInfo.delete; return this.friendInfo&&!this.friendInfo.delete;
}, },
friendInfo(){ friendInfo(){
let friends = this.$store.state.friendStore.friends; let friends = this.friendStore.friends;
let friend = friends.find((f) => f.id == this.userInfo.id); let friend = friends.find((f) => f.id == this.userInfo.id);
return friend; return friend;
} }

8
im-uniapp/pages/friend/friend-add.vue

@ -6,7 +6,7 @@
</view> </view>
<view class="user-items"> <view class="user-items">
<scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true"> <scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true">
<view v-for="(user) in users" :key="user.id" v-show="user.id != $store.state.userStore.userInfo.id"> <view v-for="(user) in users" :key="user.id" v-show="user.id != userStore.userInfo.id">
<view class="user-item"> <view class="user-item">
<head-image :id="user.id" :name="user.nickName" <head-image :id="user.id" :name="user.nickName"
:online="user.online" :url="user.headImage" :online="user.online" :url="user.headImage"
@ -28,6 +28,8 @@
export default { export default {
data() { data() {
return { return {
friendStore: this.useFriendStore(),
userStore: this.useUserStore(),
searchText: "", searchText: "",
users: [] users: []
} }
@ -55,7 +57,7 @@
headImage: user.headImage, headImage: user.headImage,
online: user.online online: user.online
} }
this.$store.commit("addFriend", friend); this.friendStore.addFriend(friend);
uni.showToast({ uni.showToast({
title: "添加成功,对方已成为您的好友", title: "添加成功,对方已成为您的好友",
icon: "none" icon: "none"
@ -68,7 +70,7 @@
}) })
}, },
isFriend(userId) { isFriend(userId) {
let friends = this.$store.state.friendStore.friends; let friends = this.friendStore.friends;
let friend = friends.find((f) => f.id == userId); let friend = friends.find((f) => f.id == userId);
return friend&&!friend.delete; return friend&&!friend.delete;
} }

3
im-uniapp/pages/friend/friend.vue

@ -34,6 +34,7 @@
export default { export default {
data() { data() {
return { return {
friendStore: this.useFriendStore(),
searchText: '' searchText: ''
} }
}, },
@ -58,7 +59,7 @@
}, },
computed: { computed: {
friends() { friends() {
return this.$store.state.friendStore.friends; return this.friendStore.friends;
}, },
friendGroupMap(){ friendGroupMap(){
// //

21
im-uniapp/pages/group/group-edit.vue

@ -1,5 +1,5 @@
<template> <template>
<view v-if="$store.state.userStore.userInfo.type == 1" class="page group-edit"> <view v-if="userStore.userInfo.type == 1" class="page group-edit">
<uni-forms ref="form" :modelValue="group" :rules="rules" validate-trigger="bind" label-position="top" <uni-forms ref="form" :modelValue="group" :rules="rules" validate-trigger="bind" label-position="top"
label-width="100%"> label-width="100%">
<uni-forms-item label="群聊头像:" name="headImage"> <uni-forms-item label="群聊头像:" name="headImage">
@ -16,7 +16,7 @@
<uni-easyinput v-model="group.remarkGroupName" type="text" :placeholder="group.name" /> <uni-easyinput v-model="group.remarkGroupName" type="text" :placeholder="group.name" />
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="我在本群的昵称:" name="remarkNickName"> <uni-forms-item label="我在本群的昵称:" name="remarkNickName">
<uni-easyinput v-model="group.remarkNickName" type="text" :placeholder="$store.state.userStore.userInfo.nickName" /> <uni-easyinput v-model="group.remarkNickName" type="text" :placeholder="userStore.userInfo.nickName" />
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="群公告:" name="notice"> <uni-forms-item label="群公告:" name="notice">
<uni-easyinput type="textarea" v-model="group.notice" :disabled="!isOwner" placeholder="请输入群公告" /> <uni-easyinput type="textarea" v-model="group.notice" :disabled="!isOwner" placeholder="请输入群公告" />
@ -30,6 +30,9 @@
export default { export default {
data() { data() {
return { return {
chatStore: this.useChatStore(),
groupStore: this.useGroupStore(),
userStore: this.useUserStore(),
group: {}, group: {},
rules: { rules: {
name: { name: {
@ -61,7 +64,7 @@
method: "PUT", method: "PUT",
data: this.group data: this.group
}).then((group) => { }).then((group) => {
this.$store.commit("updateGroup", group); this.groupStore.updateGroup(group);
uni.showToast({ uni.showToast({
title: "修改群聊信息成功", title: "修改群聊信息成功",
icon: 'none' icon: 'none'
@ -81,7 +84,7 @@
method: 'POST', method: 'POST',
data: this.group data: this.group
}).then((group) => { }).then((group) => {
this.$store.commit("addGroup", group); this.groupStore.addGroup(group);
uni.showToast({ uni.showToast({
title: `群聊创建成功,快邀请小伙伴进群吧`, title: `群聊创建成功,快邀请小伙伴进群吧`,
icon: 'none', icon: 'none',
@ -102,25 +105,25 @@
}).then((group) => { }).then((group) => {
this.group = group; this.group = group;
// //
this.$store.commit("updateChatFromGroup", group); this.chatStore.updateChatFromGroup(group);
// //
this.$store.commit("updateGroup", group); this.groupStore.updateGroup(group);
}); });
}, },
initNewGroup() { initNewGroup() {
let userInfo = this.$store.state.userStore.userInfo; let userInfo = this.userStore.userInfo;
this.group = { this.group = {
name: `${userInfo.userName}创建的群聊`, name: `${userInfo.userName}创建的群聊`,
headImage: userInfo.headImage, headImage: userInfo.headImage,
headImageThumb: userInfo.headImageThumb, headImageThumb: userInfo.headImageThumb,
ownerId: this.$store.state.userStore.userInfo.id ownerId: this.userStore.userInfo.id
} }
} }
}, },
computed: { computed: {
isOwner() { isOwner() {
return this.$store.state.userStore.userInfo.id == this.group.ownerId return this.userStore.userInfo.id == this.group.ownerId
} }
}, },
onLoad(options) { onLoad(options) {

24
im-uniapp/pages/group/group-info.vue

@ -1,5 +1,5 @@
<template> <template>
<view v-if="$store.state.userStore.userInfo.type == 1" class="page group-info"> <view v-if="userStore.userInfo.type == 1" class="page group-info">
<view v-if="!group.quit" class="group-members"> <view v-if="!group.quit" class="group-members">
<view class="member-items"> <view class="member-items">
<view v-for="(member,idx) in groupMembers" :key="idx"> <view v-for="(member,idx) in groupMembers" :key="idx">
@ -56,6 +56,9 @@
export default { export default {
data() { data() {
return { return {
chatStore: this.useChatStore(),
groupStore: this.useGroupStore(),
userStore: this.useUserStore(),
groupId: null, groupId: null,
group:{}, group:{},
groupMembers: [] groupMembers: []
@ -85,8 +88,8 @@
showName: this.group.showGroupName, showName: this.group.showGroupName,
headImage: this.group.headImage, headImage: this.group.headImage,
}; };
this.$store.commit("openChat", chat); this.chatStore.openChat(chat);
let chatIdx = this.$store.getters.findChatIdx(chat); let chatIdx = this.chatStore.findChatIdx(chat);
uni.navigateTo({ uni.navigateTo({
url: "/pages/chat/chat-box?chatIdx=" + chatIdx url: "/pages/chat/chat-box?chatIdx=" + chatIdx
}) })
@ -111,8 +114,8 @@
uni.switchTab({ uni.switchTab({
url:"/pages/group/group" url:"/pages/group/group"
}); });
this.$store.commit("removeGroup", this.groupId); this.groupStore.removeGroup(this.groupId);
this.$store.commit("removeGroupChat",this.groupId); this.chatStore.removeGroupChat(this.groupId);
},100) },100)
} }
}) })
@ -121,7 +124,6 @@
}); });
}, },
onDissolveGroup() { onDissolveGroup() {
console.log(this.group.name)
uni.showModal({ uni.showModal({
title: '确认解散?', title: '确认解散?',
content: `确认要解散群聊'${this.group.name}'吗?`, content: `确认要解散群聊'${this.group.name}'吗?`,
@ -141,8 +143,8 @@
uni.switchTab({ uni.switchTab({
url:"/pages/group/group" url:"/pages/group/group"
}); });
this.$store.commit("removeGroup", this.groupId); this.groupStore.removeGroup(this.groupId);
this.$store.commit("removeGroupChat",this.groupId); this.chatStore.removeGroupChat(this.groupId);
},100) },100)
} }
}) })
@ -158,9 +160,9 @@
}).then((group) => { }).then((group) => {
this.group = group; this.group = group;
// //
this.$store.commit("updateChatFromGroup", group); this.chatStore.updateChatFromGroup(group);
// //
this.$store.commit("updateGroup", group); this.groupStore.updateGroup(group);
}); });
}, },
@ -180,7 +182,7 @@
return member && member.showNickName; return member && member.showNickName;
}, },
isOwner() { isOwner() {
return this.group.ownerId == this.$store.state.userStore.userInfo.id; return this.group.ownerId == this.userStore.userInfo.id;
} }
}, },
onLoad(options) { onLoad(options) {

7
im-uniapp/pages/group/group-invite.vue

@ -1,5 +1,5 @@
<template> <template>
<view v-if="$store.state.userStore.userInfo.type == 1" class="page group-invite"> <view class="page group-invite">
<view class="search-bar"> <view class="search-bar">
<uni-search-bar v-model="searchText" radius="100" cancelButton="none" placeholder="输入好友昵称搜索"></uni-search-bar> <uni-search-bar v-model="searchText" radius="100" cancelButton="none" placeholder="输入好友昵称搜索"></uni-search-bar>
</view> </view>
@ -17,7 +17,6 @@
<radio :checked="friend.checked" :disabled="friend.disabled" @click.stop="onSwitchChecked(friend)"/> <radio :checked="friend.checked" :disabled="friend.disabled" @click.stop="onSwitchChecked(friend)"/>
</view> </view>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
@ -31,6 +30,7 @@
export default { export default {
data() { data() {
return { return {
friendStore: this.useFriendStore(),
groupId: null, groupId: null,
searchText: "", searchText: "",
groupMembers: [], groupMembers: [],
@ -78,11 +78,10 @@
if (!friend.disabled) { if (!friend.disabled) {
friend.checked = !friend.checked; friend.checked = !friend.checked;
} }
console.log(this.inviteSize)
}, },
initFriendItems() { initFriendItems() {
this.friendItems = []; this.friendItems = [];
let friends = this.$store.state.friendStore.friends; let friends = this.friendStore.friends;
friends.forEach((f => { friends.forEach((f => {
if(f.delete){ if(f.delete){
return return

7
im-uniapp/pages/group/group-member.vue

@ -1,5 +1,5 @@
<template> <template>
<view v-if="$store.state.userStore.userInfo.type == 1" class="page group-member"> <view class="page group-member">
<view class="search-bar"> <view class="search-bar">
<uni-search-bar v-model="searchText" radius="100" cancelButton="none" placeholder="输入成员昵称搜索"></uni-search-bar> <uni-search-bar v-model="searchText" radius="100" cancelButton="none" placeholder="输入成员昵称搜索"></uni-search-bar>
</view> </view>
@ -29,6 +29,7 @@
export default { export default {
data() { data() {
return { return {
userStore: this.useUserStore(),
isModify: false, isModify: false,
searchText: "", searchText: "",
group: {}, group: {},
@ -79,12 +80,12 @@
}) })
}, },
isSelf(userId) { isSelf(userId) {
return this.$store.state.userStore.userInfo.id == userId return this.userStore.userInfo.id == userId
} }
}, },
computed: { computed: {
isOwner() { isOwner() {
return this.$store.state.userStore.userInfo.id == this.group.ownerId; return this.userStore.userInfo.id == this.group.ownerId;
} }
}, },
onLoad(options) { onLoad(options) {

5
im-uniapp/pages/group/group.vue

@ -9,12 +9,12 @@
<uni-icons type="personadd" size="35"></uni-icons> <uni-icons type="personadd" size="35"></uni-icons>
</view> </view>
</view> </view>
<view class="group-tip" v-if="$store.state.groupStore.groups.length==0"> <view class="group-tip" v-if="groupStore.groups.length==0">
温馨提示您现在还没有加入任何群聊点击右上方'+'按钮可以创建群聊哦~ 温馨提示您现在还没有加入任何群聊点击右上方'+'按钮可以创建群聊哦~
</view> </view>
<view class="group-items" v-else> <view class="group-items" v-else>
<scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true"> <scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true">
<view v-for="group in $store.state.groupStore.groups" :key="group.id"> <view v-for="group in groupStore.groups" :key="group.id">
<group-item v-if="!group.quit&&group.showGroupName.includes(searchText)" <group-item v-if="!group.quit&&group.showGroupName.includes(searchText)"
:group="group"></group-item> :group="group"></group-item>
</view> </view>
@ -27,6 +27,7 @@
export default { export default {
data() { data() {
return { return {
groupStore: this.useGroupStore(),
searchText: "" searchText: ""
} }
}, },

5
im-uniapp/pages/mine/mine-edit.vue

@ -31,6 +31,7 @@
export default { export default {
data() { data() {
return { return {
userStore: this.useUserStore(),
userInfo: {} userInfo: {}
} }
}, },
@ -48,7 +49,7 @@
method: "PUT", method: "PUT",
data: this.userInfo data: this.userInfo
}).then(()=>{ }).then(()=>{
this.$store.commit("setUserInfo",this.userInfo); this.userStore.setUserInfo(this.userInfo);
uni.showToast({ uni.showToast({
title:"修改成功", title:"修改成功",
icon: 'none' icon: 'none'
@ -61,7 +62,7 @@
}, },
onLoad() { onLoad() {
// //
let mine = this.$store.state.userStore.userInfo; let mine = this.userStore.userInfo;
this.userInfo = JSON.parse(JSON.stringify(mine)); this.userInfo = JSON.parse(JSON.stringify(mine));
} }
} }

6
im-uniapp/pages/mine/mine.vue

@ -34,7 +34,9 @@
<script> <script>
export default { export default {
data() { data() {
return {} return {
userStore: this.useUserStore()
}
}, },
methods: { methods: {
onModifyInfo() { onModifyInfo() {
@ -60,7 +62,7 @@
}, },
computed: { computed: {
userInfo() { userInfo() {
return this.$store.state.userStore.userInfo; return this.userStore.userInfo;
} }
} }

262
im-uniapp/store/chatStore.js

@ -1,33 +1,22 @@
import { import { defineStore } from 'pinia';
MESSAGE_TYPE, import { MESSAGE_TYPE, MESSAGE_STATUS } from '@/common/enums.js';
MESSAGE_STATUS import useUserStore from './userStore';
} from '@/common/enums.js';
import userStore from './userStore';
/*
uniapp性能优化
1.由于uniapp渲染消息性能非常拉胯,所以先把离线消息存储到cacheChats,
待所有离线消息拉取完成后再统一进行渲染
2.在vuex中对数组进行unshift,splice特别卡所以删除会话会话置顶
除消息等操作进行优化不通过unshift,splice实现改造方案如下
删除会话 通过delete标志判断是否删除
删除消息通过delete标志判断是否删除
会话置顶通过lastSendTime排序确定会话顺序
*/
let cacheChats = []; let cacheChats = [];
export default { export default defineStore('chatStore', {
state: { state: () => {
chats: [], return {
privateMsgMaxId: 0, chats: [],
groupMsgMaxId: 0, privateMsgMaxId: 0,
loadingPrivateMsg: false, groupMsgMaxId: 0,
loadingGroupMsg: false, loadingPrivateMsg: false,
loadingGroupMsg: false
}
}, },
actions: {
mutations: { initChats(chatsData) {
initChats(state, chatsData) {
cacheChats = []; cacheChats = [];
state.chats = []; this.chats = [];
for (let chat of chatsData.chats) { for (let chat of chatsData.chats) {
// 已删除的会话直接丢弃 // 已删除的会话直接丢弃
if (chat.delete) { if (chat.delete) {
@ -36,13 +25,13 @@ export default {
// 暂存至缓冲区 // 暂存至缓冲区
cacheChats.push(JSON.parse(JSON.stringify(chat))); cacheChats.push(JSON.parse(JSON.stringify(chat)));
// 加载期间显示只前15个会话做做样子,一切都为了加快初始化时间 // 加载期间显示只前15个会话做做样子,一切都为了加快初始化时间
if (state.chats.length < 15) { if (this.chats.length < 15) {
chat.messages = []; chat.messages = [];
state.chats.push(chat); this.chats.push(chat);
} }
} }
state.privateMsgMaxId = chatsData.privateMsgMaxId || 0; this.privateMsgMaxId = chatsData.privateMsgMaxId || 0;
state.groupMsgMaxId = chatsData.groupMsgMaxId || 0; this.groupMsgMaxId = chatsData.groupMsgMaxId || 0;
// 防止图片一直处在加载中状态 // 防止图片一直处在加载中状态
cacheChats.forEach((chat) => { cacheChats.forEach((chat) => {
chat.messages.forEach((msg) => { chat.messages.forEach((msg) => {
@ -52,8 +41,8 @@ export default {
}) })
}) })
}, },
openChat(state, chatInfo) { openChat(chatInfo) {
let chats = this.getters.findChats(); let chats = this.curChats;
let chat = null; let chat = null;
for (let idx in chats) { for (let idx in chats) {
if (chats[idx].type == chatInfo.type && if (chats[idx].type == chatInfo.type &&
@ -61,7 +50,7 @@ export default {
chat = chats[idx]; chat = chats[idx];
chat.delete = false; chat.delete = false;
// 放置头部 // 放置头部
this.commit("moveTop", idx) this.moveTop(idx)
break; break;
} }
} }
@ -81,17 +70,18 @@ export default {
delete: false delete: false
}; };
chats.push(chat); chats.push(chat);
this.commit("moveTop", chats.length - 1) this.moveTop(chats.length - 1)
} }
}, },
activeChat(state, idx) { activeChat(idx) {
let chats = this.getters.findChats(); let chats = this.curChats;
if (idx >= 0) { if (idx >= 0) {
chats[idx].unreadCount = 0; chats[idx].unreadCount = 0;
} }
}, },
resetUnreadCount(state, chatInfo) { resetUnreadCount(chatInfo) {
let chats = this.getters.findChats(); console.log("resetUnreadCount")
let chats = this.curChats;
for (let idx in chats) { for (let idx in chats) {
if (chats[idx].type == chatInfo.type && if (chats[idx].type == chatInfo.type &&
chats[idx].targetId == chatInfo.targetId) { chats[idx].targetId == chatInfo.targetId) {
@ -100,10 +90,10 @@ export default {
chats[idx].atAll = false; chats[idx].atAll = false;
} }
} }
this.commit("saveToStorage"); this.saveToStorage();
}, },
readedMessage(state, pos) { readedMessage(pos) {
let chats = this.getters.findChats(); let chats = this.curChats;
for (let idx in chats) { for (let idx in chats) {
if (chats[idx].type == 'PRIVATE' && if (chats[idx].type == 'PRIVATE' &&
chats[idx].targetId == pos.friendId) { chats[idx].targetId == pos.friendId) {
@ -117,58 +107,59 @@ export default {
}) })
} }
} }
this.commit("saveToStorage"); this.saveToStorage();
}, },
removeChat(state, idx) { removeChat(idx) {
let chats = this.getters.findChats(); let chats = this.curChats;
chats[idx].delete = true; chats[idx].delete = true;
this.commit("saveToStorage"); this.saveToStorage();
}, },
removePrivateChat(state, userId) { removePrivateChat(userId) {
let chats = this.getters.findChats(); let chats = this.curChats;
for (let idx in chats) { for (let idx in chats) {
if (chats[idx].type == 'PRIVATE' && if (chats[idx].type == 'PRIVATE' &&
chats[idx].targetId == userId) { chats[idx].targetId == userId) {
this.commit("removeChat", idx); this.removeChat(idx);
} }
} }
}, },
removeGroupChat(state, groupId) { removeGroupChat(groupId) {
let chats = this.getters.findChats(); let chats = this.curChats;
for (let idx in chats) { for (let idx in chats) {
if (chats[idx].type == 'GROUP' && if (chats[idx].type == 'GROUP' &&
chats[idx].targetId == groupId) { chats[idx].targetId == groupId) {
this.commit("removeChat", idx); this.removeChat(idx);
} }
} }
}, },
moveTop(state, idx) { moveTop(idx) {
let chats = this.getters.findChats(); console.log("moveTop")
let chats = this.curChats;
let chat = chats[idx]; let chat = chats[idx];
// 最新的时间会显示在顶部 // 最新的时间会显示在顶部
chat.lastSendTime = new Date().getTime(); chat.lastSendTime = new Date().getTime();
this.commit("saveToStorage"); this.saveToStorage();
}, },
insertMessage(state, msgInfo) { insertMessage(msgInfo) {
// 获取对方id或群id // 获取对方id或群id
let type = msgInfo.groupId ? 'GROUP' : 'PRIVATE'; let type = msgInfo.groupId ? 'GROUP' : 'PRIVATE';
// 记录消息的最大id // 记录消息的最大id
if (msgInfo.id && type == "PRIVATE" && msgInfo.id > state.privateMsgMaxId) { if (msgInfo.id && type == "PRIVATE" && msgInfo.id > this.privateMsgMaxId) {
state.privateMsgMaxId = msgInfo.id; this.privateMsgMaxId = msgInfo.id;
} }
if (msgInfo.id && type == "GROUP" && msgInfo.id > state.groupMsgMaxId) { if (msgInfo.id && type == "GROUP" && msgInfo.id > this.groupMsgMaxId) {
state.groupMsgMaxId = msgInfo.id; this.groupMsgMaxId = msgInfo.id;
} }
// 如果是已存在消息,则覆盖旧的消息数据 // 如果是已存在消息,则覆盖旧的消息数据
let chat = this.getters.findChat(msgInfo); let chat = this.findChat(msgInfo);
let message = this.getters.findMessage(chat, msgInfo); let message = this.findMessage(chat, msgInfo);
if (message) { if (message) {
Object.assign(message, msgInfo); Object.assign(message, msgInfo);
// 撤回消息需要显示 // 撤回消息需要显示
if (msgInfo.type == MESSAGE_TYPE.RECALL) { if (msgInfo.type == MESSAGE_TYPE.RECALL) {
chat.lastContent = msgInfo.content; chat.lastContent = msgInfo.content;
} }
this.commit("saveToStorage"); this.saveToStorage();
return; return;
} }
// 会话列表内容 // 会话列表内容
@ -187,7 +178,6 @@ export default {
} }
chat.lastSendTime = msgInfo.sendTime; chat.lastSendTime = msgInfo.sendTime;
chat.sendNickName = msgInfo.sendNickName; chat.sendNickName = msgInfo.sendNickName;
// 未读加1 // 未读加1
if (!msgInfo.selfSend && msgInfo.status != MESSAGE_STATUS.READED && if (!msgInfo.selfSend && msgInfo.status != MESSAGE_STATUS.READED &&
msgInfo.type != MESSAGE_TYPE.TIP_TEXT) { msgInfo.type != MESSAGE_TYPE.TIP_TEXT) {
@ -196,7 +186,8 @@ export default {
// 是否有人@我 // 是否有人@我
if (!msgInfo.selfSend && chat.type == "GROUP" && msgInfo.atUserIds && if (!msgInfo.selfSend && chat.type == "GROUP" && msgInfo.atUserIds &&
msgInfo.status != MESSAGE_STATUS.READED) { msgInfo.status != MESSAGE_STATUS.READED) {
let userId = userStore.state.userInfo.id; const userStore = useUserStore();
let userId = userStore.userInfo.id;
if (msgInfo.atUserIds.indexOf(userId) >= 0) { if (msgInfo.atUserIds.indexOf(userId) >= 0) {
chat.atMe = true; chat.atMe = true;
} }
@ -230,21 +221,21 @@ export default {
} else { } else {
chat.messages.splice(insertPos, 0, msgInfo); chat.messages.splice(insertPos, 0, msgInfo);
} }
this.commit("saveToStorage"); this.saveToStorage();
}, },
updateMessage(state, msgInfo) { updateMessage(msgInfo) {
// 获取对方id或群id // 获取对方id或群id
let chat = this.getters.findChat(msgInfo); let chat = this.findChat(msgInfo);
let message = this.getters.findMessage(chat, msgInfo); let message = this.findMessage(chat, msgInfo);
if (message) { if (message) {
// 属性拷贝 // 属性拷贝
Object.assign(message, msgInfo); Object.assign(message, msgInfo);
this.commit("saveToStorage"); this.saveToStorage();
} }
}, },
deleteMessage(state, msgInfo) { deleteMessage(msgInfo) {
// 获取对方id或群id // 获取对方id或群id
let chat = this.getters.findChat(msgInfo); let chat = this.findChat(msgInfo);
for (let idx in chat.messages) { for (let idx in chat.messages) {
// 已经发送成功的,根据id删除 // 已经发送成功的,根据id删除
if (chat.messages[idx].id && chat.messages[idx].id == msgInfo.id) { if (chat.messages[idx].id && chat.messages[idx].id == msgInfo.id) {
@ -258,92 +249,89 @@ export default {
break; break;
} }
} }
this.commit("saveToStorage"); this.saveToStorage();
}, },
updateChatFromFriend(state, friend) { updateChatFromFriend(friend) {
let chats = this.getters.findChats(); let chat = this.findChatByFriend(friend.id)
for (let i in chats) { if (chat.headImage != friend.headImageThumb ||
let chat = chats[i]; chat.showName != friend.nickName) {
if (chat.type == 'PRIVATE' && chat.targetId == friend.id) { // 更新会话中的群名和头像
chat.headImage = friend.headImageThumb; chat.headImage = friend.headImageThumb;
chat.showName = friend.nickName; chat.showName = friend.nickName;
break; this.saveToStorage();
}
} }
this.commit("saveToStorage");
}, },
updateChatFromGroup(state, group) { updateChatFromGroup(group) {
let chats = this.getters.findChats(); let chat = this.findChatByGroup(group.id);
for (let i in chats) { if (chat.headImage != group.headImageThumb ||
let chat = chats[i]; chat.showName != group.showGroupName) {
if (chat.type == 'GROUP' && chat.targetId == group.id) { // 更新会话中的群名称和头像
chat.headImage = group.headImageThumb; chat.headImage = group.headImageThumb;
chat.showName = group.showGroupName; chat.showName = group.showGroupName;
break; this.saveToStorage();
}
} }
this.commit("saveToStorage");
}, },
loadingPrivateMsg(state, loading) { setLoadingPrivateMsg(loading) {
state.loadingPrivateMsg = loading; this.loadingPrivateMsg = loading;
if (!this.getters.isLoading()) { if (!this.isLoading()) {
this.commit("refreshChats") this.refreshChats()
} }
}, },
loadingGroupMsg(state, loading) { setLoadingGroupMsg(loading) {
state.loadingGroupMsg = loading; this.loadingGroupMsg = loading;
if (!this.getters.isLoading()) { if (!this.isLoading()) {
this.commit("refreshChats") this.refreshChats()
} }
}, },
refreshChats(state) { refreshChats(state) {
console.log("refreshChats")
// 排序 // 排序
cacheChats.sort((chat1, chat2) => { cacheChats.sort((chat1, chat2) => {
return chat2.lastSendTime - chat1.lastSendTime; return chat2.lastSendTime - chat1.lastSendTime;
}); });
// 将消息一次性装载回来 // 将消息一次性装载回来
state.chats = cacheChats; this.chats = cacheChats;
// 断线重连后不能使用缓存模式,否则会导致聊天窗口的消息不刷新 // 断线重连后不能使用缓存模式,否则会导致聊天窗口的消息不刷新
cacheChats = state.chats; cacheChats = this.chats;
this.commit("saveToStorage"); this.saveToStorage();
}, },
saveToStorage(state) { saveToStorage(state) {
console.log("saveToStorage")
// 加载中不保存,防止卡顿 // 加载中不保存,防止卡顿
if (this.getters.isLoading()) { if (this.isLoading()) {
return; return;
} }
let userId = userStore.state.userInfo.id; const timeStamp = new Date().getTime();
const userStore = useUserStore();
let userId = userStore.userInfo.id;
let key = "chats-app-" + userId; let key = "chats-app-" + userId;
let chatsData = { let chatsData = {
privateMsgMaxId: state.privateMsgMaxId, privateMsgMaxId: this.privateMsgMaxId,
groupMsgMaxId: state.groupMsgMaxId, groupMsgMaxId: this.groupMsgMaxId,
chats: state.chats chats: this.chats
} }
uni.setStorage({ uni.setStorageSync(key, chatsData)
key: key, console.log("耗时:", new Date().getTime() - timeStamp);
data: chatsData ,
})
}, },
clear(state) { clear(state) {
cacheChats = []; cacheChats = [];
state.chats = []; this.chats = [];
state.privateMsgMaxId = 0; this.privateMsgMaxId = 0;
state.groupMsgMaxId = 0; this.groupMsgMaxId = 0;
state.loadingPrivateMsg = false; this.loadingPrivateMsg = false;
state.loadingGroupMsg = false; this.loadingGroupMsg = false;
} },
},
actions: {
loadChat(context) { loadChat(context) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let userId = userStore.state.userInfo.id; const userStore = useUserStore();
let userId = userStore.userInfo.id;
uni.getStorage({ uni.getStorage({
key: "chats-app-" + userId, key: "chats-app-" + userId,
success(res) { success: (res) => {
context.commit("initChats", res.data); this.initChats(res.data);
resolve() resolve()
}, },
fail(e) { fail: (e) => {
resolve() resolve()
} }
}); });
@ -354,11 +342,11 @@ export default {
isLoading: (state) => () => { isLoading: (state) => () => {
return state.loadingPrivateMsg || state.loadingGroupMsg return state.loadingPrivateMsg || state.loadingGroupMsg
}, },
findChats: (state, getters) => () => { curChats: (state) => {
return getters.isLoading() ? cacheChats : state.chats; return state.isLoading() ? cacheChats : state.chats;
}, },
findChatIdx: (state, getters) => (chat) => { findChatIdx: (state) => (chat) => {
let chats = getters.findChats(); let chats = state.curChats;
for (let idx in chats) { for (let idx in chats) {
if (chats[idx].type == chat.type && if (chats[idx].type == chat.type &&
chats[idx].targetId === chat.targetId) { chats[idx].targetId === chat.targetId) {
@ -367,11 +355,12 @@ export default {
} }
} }
}, },
findChat: (state, getters) => (msgInfo) => { findChat: (state) => (msgInfo) => {
let chats = getters.findChats(); let chats = state.curChats;
// 获取对方id或群id // 获取对方id或群id
let type = msgInfo.groupId ? 'GROUP' : 'PRIVATE'; let type = msgInfo.groupId ? 'GROUP' : 'PRIVATE';
let targetId = msgInfo.groupId ? msgInfo.groupId : msgInfo.selfSend ? msgInfo.recvId : msgInfo.sendId; let targetId = msgInfo.groupId ? msgInfo.groupId : msgInfo.selfSend ? msgInfo.recvId : msgInfo
.sendId;
let chat = null; let chat = null;
for (let idx in chats) { for (let idx in chats) {
if (chats[idx].type == type && if (chats[idx].type == type &&
@ -382,6 +371,14 @@ export default {
} }
return chat; return chat;
}, },
findChatByFriend: (state) => (fid) => {
return state.curChats.find(chat => chat.type == 'PRIVATE' &&
chat.targetId == fid)
},
findChatByGroup: (state) => (gid) => {
return state.curChats.find(chat => chat.type == 'GROUP' &&
chat.targetId == gid)
},
findMessage: (state) => (chat, msgInfo) => { findMessage: (state) => (chat, msgInfo) => {
if (!chat) { if (!chat) {
return null; return null;
@ -394,10 +391,9 @@ export default {
// 正在发送中的消息可能没有id,只有tmpId // 正在发送中的消息可能没有id,只有tmpId
if (msgInfo.tmpId && chat.messages[idx].tmpId && if (msgInfo.tmpId && chat.messages[idx].tmpId &&
chat.messages[idx].tmpId == msgInfo.tmpId) { chat.messages[idx].tmpId == msgInfo.tmpId) {
console.log("chat.messages[idx].tmpId == msgInfo.tmpId")
return chat.messages[idx]; return chat.messages[idx];
} }
} }
} }
} }
} });

34
im-uniapp/store/configStore.js

@ -1,32 +1,32 @@
import { defineStore } from 'pinia';
import http from '../common/request' import http from '../common/request'
export default { export default defineStore('configStore', {
state: { state: () => {
webrtc: {} return {
}, webrtc: {}
mutations: {
setConfig(state, config) {
state.webrtc = config.webrtc;
},
clear(state){
state.webrtc = {};
} }
}, },
actions:{ actions: {
loadConfig(context){ setConfig(config) {
this.webrtc = config.webrtc;
},
clear() {
this.webrtc = {};
},
loadConfig() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
http({ http({
url: '/system/config', url: '/system/config',
method: 'GET' method: 'GET'
}).then((config) => { }).then((config) => {
console.log("系统配置",config) console.log("系统配置", config)
context.commit("setConfig",config); this.setConfig(config);
resolve(); resolve();
}).catch((res)=>{ }).catch((res) => {
reject(res); reject(res);
}); });
}) })
} }
} }
})
}

103
im-uniapp/store/friendStore.js

@ -1,95 +1,92 @@
import { defineStore } from 'pinia';
import http from '../common/request' import http from '../common/request'
import {TERMINAL_TYPE} from '../common/enums.js' import { TERMINAL_TYPE } from '../common/enums.js'
export default { export default defineStore('friendStore', {
state: () => {
state: { return {
friends: [], friends: [],
timer: null timer: null
}
}, },
mutations: { actions: {
setFriends(state, friends) { setFriends(friends) {
friends.forEach((f)=>{ friends.forEach((f) => {
f.online = false; f.online = false;
f.onlineWeb = false; f.onlineWeb = false;
f.onlineApp = false; f.onlineApp = false;
}) })
state.friends = friends; this.friends = friends;
}, },
updateFriend(state, friend) { updateFriend(friend) {
state.friends.forEach((f, index) => { this.friends.forEach((f, index) => {
if (!f.delete && f.id == friend.id) { if (!f.delete && f.id == friend.id) {
// 拷贝属性 // 拷贝属性
let online = state.friends[index].online; let online = this.friends[index].online;
Object.assign(state.friends[index], friend); Object.assign(this.friends[index], friend);
state.friends[index].online = online; this.friends[index].online = online;
} }
}) })
}, },
removeFriend(state, id) { removeFriend(id) {
let friend = this.getters.findFriend(id); let friend = this.findFriend(id);
if(friend){ if (friend) {
friend.delete = true; friend.delete = true;
} }
}, },
addFriend(state, friend) { addFriend(friend) {
let f = this.getters.findFriend(friend.id); let f = this.findFriend(friend.id);
if(f){ if (f) {
Object.assign(f, friend); Object.assign(f, friend);
f.delete = false; f.delete = false;
}else{ } else {
state.friends.push(friend); this.friends.push(friend);
} }
}, },
setOnlineStatus(state, onlineTerminals) { setOnlineStatus(onlineTerminals) {
state.friends.forEach((f)=>{ this.friends.forEach((f) => {
let userTerminal = onlineTerminals.find((o)=> f.id==o.userId); let userTerminal = onlineTerminals.find((o) => f.id == o.userId);
if(userTerminal){ if (userTerminal) {
f.online = true; f.online = true;
f.onlineWeb = userTerminal.terminals.indexOf(TERMINAL_TYPE.WEB)>=0 f.onlineWeb = userTerminal.terminals.indexOf(TERMINAL_TYPE.WEB) >= 0
f.onlineApp = userTerminal.terminals.indexOf(TERMINAL_TYPE.APP)>=0 f.onlineApp = userTerminal.terminals.indexOf(TERMINAL_TYPE.APP) >= 0
}else{ } else {
f.online = false; f.online = false;
f.onlineWeb = false; f.onlineWeb = false;
f.onlineApp = false; f.onlineApp = false;
} }
}); });
}, },
refreshOnlineStatus(state) { refreshOnlineStatus() {
if (state.friends.length > 0) { if (this.friends.length > 0) {
let userIds = []; let userIds = [];
state.friends.forEach((f) => { this.friends.forEach(f => userIds.push(f.id));
userIds.push(f.id)
});
http({ http({
url: '/user/terminal/online?userIds=' + userIds.join(','), url: '/user/terminal/online?userIds=' + userIds.join(','),
method: 'GET' method: 'GET'
}).then((onlineTerminals) => { }).then((onlineTerminals) => {
this.commit("setOnlineStatus", onlineTerminals); this.setOnlineStatus(onlineTerminals);
}) })
} }
// 30s后重新拉取 // 30s后重新拉取
clearTimeout(state.timer); clearTimeout(this.timer);
state.timer = setTimeout(() => { this.timer = setTimeout(() => {
this.commit("refreshOnlineStatus"); this.refreshOnlineStatus();
}, 30000) }, 30000)
}, },
clear(state) { clear() {
clearTimeout(state.timer); clearTimeout(this.timer);
state.friends = []; this.friends = [];
state.timer = null; this.timer = null;
} },
}, loadFriend() {
actions: {
loadFriend(context) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
http({ http({
url: '/friend/list', url: '/friend/list',
method: 'GET' method: 'GET'
}).then((friends) => { }).then((friends) => {
context.commit("setFriends", friends); this.setFriends(friends);
context.commit("refreshOnlineStatus"); this.refreshOnlineStatus();
resolve() resolve()
}).catch((res) => { }).catch((res) => {
reject(); reject();
@ -97,9 +94,9 @@ export default {
}); });
} }
}, },
getters:{ getters: {
findFriend: (state) => (id) => { findFriend: (state) => (id) => {
return state.friends.find((f)=>f.id==id); return state.friends.find((f) => f.id == id);
} }
} }
} })

58
im-uniapp/store/groupStore.js

@ -1,52 +1,52 @@
import { defineStore } from 'pinia';
import http from '@/common/request'; import http from '@/common/request';
export default { export default defineStore('groupStore', {
state: { state: () => {
groups: [], return {
activeIndex: -1, groups: [],
activeIndex: -1
}
}, },
mutations: { actions: {
setGroups(state, groups) { setGroups(groups) {
state.groups = groups; this.groups = groups;
}, },
activeGroup(state, index) { activeGroup(index) {
state.activeIndex = index; this.activeIndex = index;
}, },
addGroup(state, group) { addGroup(group) {
state.groups.unshift(group); this.groups.unshift(group);
}, },
removeGroup(state, groupId) { removeGroup(groupId) {
state.groups.forEach((g, index) => { this.groups.forEach((g, index) => {
if (g.id == groupId) { if (g.id == groupId) {
state.groups.splice(index, 1); this.groups.splice(index, 1);
if (state.activeIndex >= state.groups.length) { if (this.activeIndex >= this.groups.length) {
state.activeIndex = state.groups.length - 1; this.activeIndex = this.groups.length - 1;
} }
} }
}) })
}, },
updateGroup(state, group) { updateGroup(group) {
state.groups.forEach((g, idx) => { this.groups.forEach((g, idx) => {
if (g.id == group.id) { if (g.id == group.id) {
// 拷贝属性 // 拷贝属性
Object.assign(state.groups[idx], group); Object.assign(this.groups[idx], group);
} }
}) })
}, },
clear(state){ clear() {
state.groups = []; this.groups = [];
state.activeGroup = -1; this.activeGroup = -1;
} },
}, loadGroup() {
actions: {
loadGroup(context) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
http({ http({
url: '/group/list', url: '/group/list',
method: 'GET' method: 'GET'
}).then((groups) => { }).then((groups) => {
context.commit("setGroups", groups); this.setGroups(groups);
resolve(); resolve();
}).catch((res) => { }).catch((res) => {
reject(res); reject(res);
@ -54,4 +54,4 @@ export default {
}); });
} }
} }
} })

35
im-uniapp/store/index.js

@ -1,35 +0,0 @@
import chatStore from './chatStore.js';
import friendStore from './friendStore.js';
import userStore from './userStore.js';
import groupStore from './groupStore.js';
import configStore from './configStore.js';
import { createStore } from 'vuex';
const store = createStore({
modules: {
chatStore,
friendStore,
userStore,
groupStore,
configStore
},
state: {},
actions: {
load(context) {
return this.dispatch("loadUser").then(() => {
const promises = [];
promises.push(this.dispatch("loadFriend"));
promises.push(this.dispatch("loadGroup"));
promises.push(this.dispatch("loadChat"));
promises.push(this.dispatch("loadConfig"));
return Promise.all(promises);
})
},
unload(context){
context.commit("clear");
}
},
strict: true
})
export default store;

42
im-uniapp/store/userStore.js

@ -1,44 +1,32 @@
import {USER_STATE} from "../common/enums" import { defineStore } from 'pinia';
import http from '../common/request' import http from '../common/request'
export default defineStore('userStore', {
export default { state: () => {
state: { return {
userInfo: {}, userInfo: {}
config:{ }
webrtc:{}
},
state: USER_STATE.FREE
}, },
actions: {
mutations: { setUserInfo(userInfo) {
setUserInfo(state, userInfo) { this.userInfo = userInfo;
// 使用深拷贝方式,否则小程序页面不刷新
Object.assign(state.userInfo, userInfo);
}, },
setUserState(state, userState) { clear() {
state.state = userState; this.userInfo = {};
}, },
clear(state){ loadUser(context) {
state.userInfo = {};
state.state = USER_STATE.FREE;
}
},
actions:{
loadUser(context){
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
http({ http({
url: '/user/self', url: '/user/self',
method: 'GET' method: 'GET'
}).then((userInfo) => { }).then((userInfo) => {
console.log(userInfo) console.log(userInfo)
context.commit("setUserInfo",userInfo); this.setUserInfo(userInfo);
resolve(); resolve();
}).catch((res)=>{ }).catch((res) => {
reject(res); reject(res);
}); });
}) })
} }
} }
})
}
Loading…
Cancel
Save