App.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <script>
  2. import store from './store';
  3. import http from './common/request';
  4. import * as enums from './common/enums';
  5. import * as wsApi from './common/wssocket';
  6. export default {
  7. data() {
  8. return {
  9. audioTip: null
  10. }
  11. },
  12. methods: {
  13. init() {
  14. // 加载数据
  15. store.dispatch("load").then(() => {
  16. // 审核
  17. this.initAudit();
  18. // 初始化websocket
  19. this.initWebSocket();
  20. // 加载离线消息
  21. this.loadPrivateMessage(store.state.chatStore.privateMsgMaxId);
  22. this.loadGroupMessage(store.state.chatStore.groupMsgMaxId);
  23. }).catch((e) => {
  24. console.log(e);
  25. this.exit();
  26. })
  27. },
  28. initWebSocket() {
  29. let loginInfo = uni.getStorageSync("loginInfo")
  30. wsApi.init();
  31. wsApi.connect(process.env.WS_URL, loginInfo.accessToken);
  32. wsApi.onMessage((cmd, msgInfo) => {
  33. if (cmd == 2) {
  34. // 异地登录,强制下线
  35. uni.showModal({
  36. content: '您已在其他地方登陆,将被强制下线',
  37. showCancel: false,
  38. })
  39. this.exit();
  40. } else if (cmd == 3) {
  41. // 私聊消息
  42. this.handlePrivateMessage(msgInfo);
  43. } else if (cmd == 4) {
  44. // 群聊消息
  45. this.handleGroupMessage(msgInfo);
  46. }
  47. });
  48. wsApi.onClose((res) => {
  49. // 3000是客户端主动关闭
  50. if (res.code != 3000) {
  51. // 重新连接
  52. uni.showToast({
  53. title: '连接已断开,尝试重新连接...',
  54. icon: 'none',
  55. })
  56. let loginInfo = uni.getStorageSync("loginInfo")
  57. wsApi.reconnect(process.env.WS_URL, loginInfo.accessToken);
  58. }
  59. })
  60. },
  61. loadPrivateMessage(minId) {
  62. store.commit("loadingPrivateMsg", true)
  63. http({
  64. url: "/message/private/loadMessage?minId=" + minId,
  65. method: 'GET'
  66. }).then((msgInfos) => {
  67. msgInfos.forEach((msgInfo) => {
  68. msgInfo.selfSend = msgInfo.sendId == store.state.userStore.userInfo.id;
  69. let friendId = msgInfo.selfSend ? msgInfo.recvId : msgInfo.sendId;
  70. let friend = store.state.friendStore.friends.find((f) => f.id == friendId);
  71. if(friend){
  72. this.insertPrivateMessage(friend,msgInfo);
  73. }
  74. })
  75. if (msgInfos.length == 100) {
  76. // 继续拉取
  77. this.loadPrivateMessage(msgInfos[99].id);
  78. } else {
  79. store.commit("loadingPrivateMsg", false)
  80. }
  81. })
  82. },
  83. loadGroupMessage(minId) {
  84. store.commit("loadingGroupMsg", true)
  85. http({
  86. url: "/message/group/loadMessage?minId=" + minId,
  87. method: 'GET'
  88. }).then((msgInfos) => {
  89. msgInfos.forEach((msgInfo) => {
  90. msgInfo.selfSend = msgInfo.sendId == store.state.userStore.userInfo.id;
  91. let groupId = msgInfo.groupId;
  92. let group = store.state.groupStore.groups.find((g) => g.id == groupId);
  93. if(group){
  94. this.insertGroupMessage(group,msgInfo);
  95. }
  96. })
  97. if (msgInfos.length == 100) {
  98. // 继续拉取
  99. this.loadGroupMessage(msgInfos[99].id);
  100. } else {
  101. store.commit("loadingGroupMsg", false)
  102. }
  103. })
  104. },
  105. handlePrivateMessage(msg) {
  106. // 标记这条消息是不是自己发的
  107. msg.selfSend = msg.sendId == store.state.userStore.userInfo.id;
  108. // 好友id
  109. let friendId = msg.selfSend ? msg.recvId : msg.sendId;
  110. // 消息已读处理
  111. if (msg.type == enums.MESSAGE_TYPE.READED) {
  112. if (msg.selfSend) {
  113. // 我已读对方的消息,清空已读数量
  114. let chatInfo = {
  115. type: 'PRIVATE',
  116. targetId: friendId
  117. }
  118. store.commit("resetUnreadCount", chatInfo)
  119. } else {
  120. // 对方已读我的消息,修改消息状态为已读
  121. store.commit("readedMessage", {friendId:friendId})
  122. }
  123. return;
  124. }
  125. this.loadFriendInfo(friendId).then((friend) => {
  126. this.insertPrivateMessage(friend, msg);
  127. })
  128. },
  129. insertPrivateMessage(friend, msg) {
  130. // webrtc 信令
  131. if (msg.type >= enums.MESSAGE_TYPE.RTC_CALL &&
  132. msg.type <= enums.MESSAGE_TYPE.RTC_CANDIDATE) {}
  133. let chatInfo = {
  134. type: 'PRIVATE',
  135. targetId: friend.id,
  136. showName: friend.nickName,
  137. headImage: friend.headImage
  138. };
  139. // 打开会话
  140. store.commit("openChat", chatInfo);
  141. // 插入消息
  142. store.commit("insertMessage", msg);
  143. // 播放提示音
  144. !msg.selfSend && this.playAudioTip();
  145. },
  146. handleGroupMessage(msg) {
  147. // 标记这条消息是不是自己发的
  148. msg.selfSend = msg.sendId == store.state.userStore.userInfo.id;
  149. let groupId = msg.groupId;
  150. // 消息已读处理
  151. if (msg.type == enums.MESSAGE_TYPE.READED) {
  152. // 我已读对方的消息,清空已读数量
  153. let chatInfo = {
  154. type: 'GROUP',
  155. targetId: groupId
  156. }
  157. store.commit("resetUnreadCount", chatInfo)
  158. return;
  159. }
  160. this.loadGroupInfo(groupId).then((group) => {
  161. // 插入群聊消息
  162. this.insertGroupMessage(group, msg);
  163. })
  164. },
  165. insertGroupMessage(group, msg) {
  166. let chatInfo = {
  167. type: 'GROUP',
  168. targetId: group.id,
  169. showName: group.remark,
  170. headImage: group.headImageThumb
  171. };
  172. // 打开会话
  173. store.commit("openChat", chatInfo);
  174. // 插入消息
  175. store.commit("insertMessage", msg);
  176. // 播放提示音
  177. !msg.selfSend && this.playAudioTip();
  178. },
  179. loadFriendInfo(id) {
  180. return new Promise((resolve, reject) => {
  181. let friend = store.state.friendStore.friends.find((f) => f.id == id);
  182. if (friend) {
  183. resolve(friend);
  184. } else {
  185. http({
  186. url: `/friend/find/${id}`,
  187. method: 'get'
  188. }).then((friend) => {
  189. store.commit("addFriend", friend);
  190. resolve(friend)
  191. })
  192. }
  193. });
  194. },
  195. loadGroupInfo(id) {
  196. return new Promise((resolve, reject) => {
  197. let group = store.state.groupStore.groups.find((g) => g.id == id);
  198. if (group) {
  199. resolve(group);
  200. } else {
  201. http({
  202. url: `/group/find/${id}`,
  203. method: 'get'
  204. }).then((group) => {
  205. resolve(group)
  206. store.commit("addGroup", group);
  207. })
  208. }
  209. });
  210. },
  211. exit() {
  212. console.log("exit");
  213. wsApi.close();
  214. uni.removeStorageSync("loginInfo");
  215. uni.reLaunch({
  216. url: "/pages/login/login"
  217. })
  218. store.dispatch("unload");
  219. },
  220. playAudioTip() {
  221. // 音频播放无法成功
  222. // this.audioTip = uni.createInnerAudioContext();
  223. // this.audioTip.src = "/static/audio/tip.wav";
  224. // this.audioTip.play();
  225. },
  226. initAudit() {
  227. console.log("initAudit")
  228. if (store.state.userStore.userInfo.type == 1) {
  229. // 显示群组功能
  230. uni.setTabBarItem({
  231. index: 2,
  232. text: "群聊"
  233. })
  234. } else {
  235. // 隐藏群组功能
  236. uni.setTabBarItem({
  237. index: 2,
  238. text: "搜索"
  239. })
  240. }
  241. }
  242. },
  243. onLaunch() {
  244. // 登录状态校验
  245. if (uni.getStorageSync("loginInfo")) {
  246. // 初始化
  247. this.init()
  248. } else {
  249. // 跳转到登录页
  250. uni.navigateTo({
  251. url: "/pages/login/login"
  252. })
  253. }
  254. }
  255. }
  256. </script>
  257. <style lang="scss">
  258. @import url('./static/icon/iconfont.css');
  259. .tab-page {
  260. // #ifdef H5
  261. height: calc(100vh - 46px - 50px); // h5平台100vh是包含了顶部和底部,需要减去
  262. // #endif
  263. // #ifndef H5
  264. height: calc(100vh);
  265. // #endif
  266. background-color: #f8f8f8;
  267. }
  268. .page {
  269. // #ifdef H5
  270. height: calc(100vh - 45px); // h5平台100vh是包含了顶部,需要减去
  271. // #endif
  272. // #ifndef H5
  273. height: calc(100vh);
  274. // #endif
  275. background-color: #f8f8f8;
  276. }
  277. </style>