chatStore.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. import { MESSAGE_TYPE, MESSAGE_STATUS } from '@/common/enums.js';
  2. import userStore from './userStore';
  3. export default {
  4. state: {
  5. activeIndex: -1,
  6. chats: [],
  7. privateMsgMaxId: 0,
  8. groupMsgMaxId: 0,
  9. loadingPrivateMsg: false,
  10. loadingGroupMsg: false,
  11. },
  12. mutations: {
  13. initChats(state, chatsData) {
  14. state.chats = chatsData.chats ||[];
  15. state.privateMsgMaxId = chatsData.privateMsgMaxId||0;
  16. state.groupMsgMaxId = chatsData.groupMsgMaxId||0;
  17. // 防止图片一直处在加载中状态
  18. state.chats.forEach((chat) => {
  19. chat.messages.forEach((msg) => {
  20. if (msg.loadStatus == "loading") {
  21. msg.loadStatus = "fail"
  22. }
  23. })
  24. })
  25. },
  26. openChat(state, chatInfo) {
  27. let chat = null;
  28. for (let idx in state.chats) {
  29. if (state.chats[idx].type == chatInfo.type &&
  30. state.chats[idx].targetId === chatInfo.targetId) {
  31. chat = state.chats[idx];
  32. // 放置头部
  33. this.commit("moveTop",idx)
  34. break;
  35. }
  36. }
  37. // 创建会话
  38. if (chat == null) {
  39. chat = {
  40. targetId: chatInfo.targetId,
  41. type: chatInfo.type,
  42. showName: chatInfo.showName,
  43. headImage: chatInfo.headImage,
  44. lastContent: "",
  45. lastSendTime: new Date().getTime(),
  46. unreadCount: 0,
  47. messages: [],
  48. atMe: false,
  49. atAll: false
  50. };
  51. state.chats.unshift(chat);
  52. }
  53. this.commit("saveToStorage");
  54. },
  55. activeChat(state, idx) {
  56. state.activeIndex = idx;
  57. if (idx >= 0) {
  58. state.chats[idx].unreadCount = 0;
  59. }
  60. },
  61. resetUnreadCount(state, chatInfo) {
  62. for (let idx in state.chats) {
  63. if (state.chats[idx].type == chatInfo.type &&
  64. state.chats[idx].targetId == chatInfo.targetId) {
  65. state.chats[idx].unreadCount = 0;
  66. state.chats[idx].atMe = false;
  67. state.chats[idx].atAll = false;
  68. }
  69. }
  70. this.commit("saveToStorage");
  71. },
  72. readedMessage(state, pos) {
  73. for (let idx in state.chats) {
  74. if (state.chats[idx].type == 'PRIVATE' &&
  75. state.chats[idx].targetId == pos.friendId) {
  76. state.chats[idx].messages.forEach((m) => {
  77. if (m.selfSend && m.status != MESSAGE_STATUS.RECALL) {
  78. // pos.maxId为空表示整个会话已读
  79. if(!pos.maxId || m.id <= pos.maxId){
  80. m.status = MESSAGE_STATUS.READED
  81. }
  82. }
  83. })
  84. }
  85. }
  86. this.commit("saveToStorage");
  87. },
  88. removeChat(state, idx) {
  89. state.chats.splice(idx, 1);
  90. this.commit("saveToStorage");
  91. },
  92. removePrivateChat(state, userId) {
  93. for (let idx in state.chats) {
  94. if (state.chats[idx].type == 'PRIVATE' &&
  95. state.chats[idx].targetId == userId) {
  96. this.commit("removeChat", idx);
  97. }
  98. }
  99. },
  100. moveTop(state, idx) {
  101. // 加载中不移动,很耗性能
  102. if(state.loadingPrivateMsg || state.loadingGroupMsg){
  103. return ;
  104. }
  105. if (idx > 0) {
  106. let chat = state.chats[idx];
  107. state.chats.splice(idx, 1);
  108. state.chats.unshift(chat);
  109. this.commit("saveToStorage");
  110. }
  111. },
  112. insertMessage(state, msgInfo) {
  113. // 获取对方id或群id
  114. let type = msgInfo.groupId ? 'GROUP' : 'PRIVATE';
  115. // 记录消息的最大id
  116. if (msgInfo.id && type == "PRIVATE" && msgInfo.id > state.privateMsgMaxId) {
  117. state.privateMsgMaxId = msgInfo.id;
  118. }
  119. if (msgInfo.id && type == "GROUP" && msgInfo.id > state.groupMsgMaxId) {
  120. state.groupMsgMaxId = msgInfo.id;
  121. }
  122. // 如果是已存在消息,则覆盖旧的消息数据
  123. let chat = this.getters.findChat(msgInfo);
  124. let message = this.getters.findMessage(chat, msgInfo);
  125. if(message){
  126. Object.assign(message, msgInfo);
  127. // 撤回消息需要显示
  128. if(msgInfo.type == MESSAGE_TYPE.RECALL){
  129. chat.lastContent = msgInfo.content;
  130. }
  131. this.commit("saveToStorage");
  132. return;
  133. }
  134. // 会话列表内容
  135. if(!state.loadingPrivateMsg && !state.loadingGroupMsg){
  136. if (msgInfo.type == MESSAGE_TYPE.IMAGE) {
  137. chat.lastContent = "[图片]";
  138. } else if (msgInfo.type == MESSAGE_TYPE.FILE) {
  139. chat.lastContent = "[文件]";
  140. } else if (msgInfo.type == MESSAGE_TYPE.AUDIO) {
  141. chat.lastContent = "[语音]";
  142. } else if (msgInfo.type == MESSAGE_TYPE.TEXT || msgInfo.type == MESSAGE_TYPE.RECALL) {
  143. chat.lastContent = msgInfo.content;
  144. } else if (msgInfo.type == MESSAGE_TYPE.RT_VOICE) {
  145. chat.lastContent = "[语音通话]";
  146. } else if (msgInfo.type == MESSAGE_TYPE.RT_VIDEO) {
  147. chat.lastContent = "[视频通话]";
  148. }
  149. chat.lastSendTime = msgInfo.sendTime;
  150. chat.sendNickName = msgInfo.sendNickName;
  151. }
  152. // 未读加1
  153. if (!msgInfo.selfSend && msgInfo.status != MESSAGE_STATUS.READED
  154. && msgInfo.type != MESSAGE_TYPE.TIP_TEXT) {
  155. chat.unreadCount++;
  156. }
  157. // 是否有人@我
  158. if(!msgInfo.selfSend && chat.type=="GROUP" && msgInfo.atUserIds
  159. && msgInfo.status != MESSAGE_STATUS.READED){
  160. let userId = userStore.state.userInfo.id;
  161. if(msgInfo.atUserIds.indexOf(userId)>=0){
  162. chat.atMe = true;
  163. }
  164. if(msgInfo.atUserIds.indexOf(-1)>=0){
  165. chat.atAll = true;
  166. }
  167. }
  168. // 间隔大于10分钟插入时间显示
  169. if (!chat.lastTimeTip || (chat.lastTimeTip < msgInfo.sendTime - 600 * 1000)) {
  170. chat.messages.push({
  171. sendTime: msgInfo.sendTime,
  172. type: MESSAGE_TYPE.TIP_TIME,
  173. });
  174. chat.lastTimeTip = msgInfo.sendTime;
  175. }
  176. // 根据id顺序插入,防止消息乱序
  177. let insertPos = chat.messages.length;
  178. for (let idx in chat.messages) {
  179. if (chat.messages[idx].id && msgInfo.id < chat.messages[idx].id) {
  180. insertPos = idx;
  181. console.log(`消息出现乱序,位置:${chat.messages.length},修正至:${insertPos}`);
  182. break;
  183. }
  184. }
  185. chat.messages.splice(insertPos, 0, msgInfo);
  186. this.commit("saveToStorage");
  187. },
  188. updateMessage(state, msgInfo) {
  189. // 获取对方id或群id
  190. let chat = this.getters.findChat(msgInfo);
  191. let message = this.getters.findMessage(chat, msgInfo);
  192. if(message){
  193. // 属性拷贝
  194. Object.assign(message, msgInfo);
  195. this.commit("saveToStorage");
  196. }
  197. },
  198. deleteMessage(state, msgInfo) {
  199. // 获取对方id或群id
  200. let chat = this.getters.findChat(msgInfo);
  201. for (let idx in chat.messages) {
  202. // 已经发送成功的,根据id删除
  203. if (chat.messages[idx].id && chat.messages[idx].id == msgInfo.id) {
  204. chat.messages.splice(idx, 1);
  205. break;
  206. }
  207. // 正在发送中的消息可能没有id,根据发送时间删除
  208. if (msgInfo.selfSend && chat.messages[idx].selfSend &&
  209. chat.messages[idx].sendTime == msgInfo.sendTime) {
  210. chat.messages.splice(idx, 1);
  211. break;
  212. }
  213. }
  214. this.commit("saveToStorage");
  215. },
  216. updateChatFromFriend(state, friend) {
  217. for (let i in state.chats) {
  218. let chat = state.chats[i];
  219. if (chat.type == 'PRIVATE' && chat.targetId == friend.id) {
  220. chat.headImage = friend.headImageThumb;
  221. chat.showName = friend.nickName;
  222. break;
  223. }
  224. }
  225. this.commit("saveToStorage");
  226. },
  227. updateChatFromGroup(state, group) {
  228. for (let i in state.chats) {
  229. let chat = state.chats[i];
  230. if (chat.type == 'GROUP' && chat.targetId == group.id) {
  231. chat.headImage = group.headImageThumb;
  232. chat.showName = group.remark;
  233. break;
  234. }
  235. }
  236. this.commit("saveToStorage");
  237. },
  238. loadingPrivateMsg(state, loadding) {
  239. state.loadingPrivateMsg = loadding;
  240. if(!state.loadingPrivateMsg && !state.loadingGroupMsg){
  241. this.commit("refreshChats")
  242. }
  243. },
  244. loadingGroupMsg(state, loadding) {
  245. state.loadingGroupMsg = loadding;
  246. if(!state.loadingPrivateMsg && !state.loadingGroupMsg){
  247. this.commit("refreshChats")
  248. }
  249. },
  250. refreshChats(state){
  251. state.chats.forEach((chat)=>{
  252. if(chat.messages.length>0){
  253. let msgInfo = chat.messages[chat.messages.length-1];
  254. if (msgInfo.type == MESSAGE_TYPE.IMAGE) {
  255. chat.lastContent = "[图片]";
  256. } else if (msgInfo.type == MESSAGE_TYPE.FILE) {
  257. chat.lastContent = "[文件]";
  258. } else if (msgInfo.type == MESSAGE_TYPE.AUDIO) {
  259. chat.lastContent = "[语音]";
  260. } else if (msgInfo.type == MESSAGE_TYPE.TEXT || msgInfo.type == MESSAGE_TYPE.RECALL) {
  261. chat.lastContent = msgInfo.content;
  262. }
  263. chat.lastSendTime = msgInfo.sendTime;
  264. }else{
  265. chat.lastContent = "";
  266. chat.lastSendTime = new Date().getTime()
  267. }
  268. })
  269. state.chats.sort((chat1, chat2) => {
  270. return chat2.lastSendTime-chat1.lastSendTime;
  271. });
  272. },
  273. saveToStorage(state) {
  274. let userId = userStore.state.userInfo.id;
  275. let key = "chats-" + userId;
  276. let chatsData = {
  277. privateMsgMaxId: state.privateMsgMaxId,
  278. groupMsgMaxId: state.groupMsgMaxId,
  279. chats: state.chats
  280. }
  281. uni.setStorage({
  282. key: key,
  283. data: chatsData
  284. })
  285. },
  286. clear(state) {
  287. state.chats = [];
  288. state.activeIndex = -1;
  289. state.privateMsgMaxId = 0;
  290. state.groupMsgMaxId = 0;
  291. state.loadingPrivateMsg = false;
  292. state.loadingGroupMsg = false;
  293. }
  294. },
  295. actions: {
  296. loadChat(context) {
  297. return new Promise((resolve, reject) => {
  298. let userId = userStore.state.userInfo.id;
  299. uni.getStorage({
  300. key: "chats-" + userId,
  301. success(res) {
  302. context.commit("initChats", res.data);
  303. resolve()
  304. },
  305. fail(e) {
  306. resolve()
  307. }
  308. });
  309. })
  310. }
  311. },
  312. getters: {
  313. findChatIdx: (state) => (chat) => {
  314. for (let idx in state.chats) {
  315. if (state.chats[idx].type == chat.type &&
  316. state.chats[idx].targetId === chat.targetId) {
  317. chat = state.chats[idx];
  318. return idx;
  319. }
  320. }
  321. },
  322. findChat: (state) => (msgInfo) => {
  323. // 获取对方id或群id
  324. let type = msgInfo.groupId ? 'GROUP' : 'PRIVATE';
  325. let targetId = msgInfo.groupId ? msgInfo.groupId : msgInfo.selfSend ? msgInfo.recvId : msgInfo.sendId;
  326. let chat = null;
  327. for (let idx in state.chats) {
  328. if (state.chats[idx].type == type &&
  329. state.chats[idx].targetId === targetId) {
  330. chat = state.chats[idx];
  331. break;
  332. }
  333. }
  334. return chat;
  335. },
  336. findMessage: (state) => (chat, msgInfo) => {
  337. if (!chat) {
  338. return null;
  339. }
  340. for (let idx in chat.messages) {
  341. // 通过id判断
  342. if (msgInfo.id && chat.messages[idx].id == msgInfo.id) {
  343. return chat.messages[idx];
  344. }
  345. // 正在发送中的消息可能没有id,通过发送时间判断
  346. if (msgInfo.selfSend && chat.messages[idx].selfSend &&
  347. chat.messages[idx].sendTime == msgInfo.sendTime) {
  348. return chat.messages[idx];
  349. }
  350. }
  351. }
  352. }
  353. }