App.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. <script>
  2. //app.js
  3. const req = require("./utils/request.js");
  4. // // #ifndef H5
  5. // let livePlayer = requirePlugin('live-player-plugin')
  6. // // #endif
  7. import _chunkArr from './hxChatSDK/utils/chunkArr';
  8. let WebIM = (wx.WebIM = require("./hxChatSDK/utils/WebIM")["default"]);
  9. let msgStorage = require("./chat/components/chat/msgstorage");
  10. let msgType = require("./chat/components/chat/msgtype");
  11. let disp = require("./hxChatSDK/utils/broadcast");
  12. let logout = false;
  13. import {
  14. onGetSilentConfig
  15. } from './chat/components/chat/pushStorage'
  16. export default {
  17. onLaunch: function(options) {
  18. req.removeStorage('shareId')
  19. // this.globalData.appInitData();
  20. this.globalData.InitUpdateManager();
  21. this.globalData.getChatList();
  22. //
  23. uni.hideTabBar();
  24. var me = this;
  25. var logs = uni.getStorageSync("logs") || [];
  26. logs.unshift(Date.now());
  27. uni.setStorageSync("logs", logs);
  28. disp.on("em.main.ready", function() {
  29. calcUnReadSpot();
  30. });
  31. disp.on("em.chatroom.leave", function() {
  32. calcUnReadSpot();
  33. });
  34. disp.on("em.chat.session.remove", function() {
  35. calcUnReadSpot();
  36. });
  37. disp.on("em.chat.audio.fileLoaded", function() {
  38. calcUnReadSpot();
  39. });
  40. disp.on("em.main.deleteFriend", function() {
  41. calcUnReadSpot();
  42. });
  43. disp.on("em.chat.audio.fileLoaded", function() {
  44. calcUnReadSpot();
  45. }); //
  46. disp.on("em.mian.profile.update", function() {
  47. me.fetchUserInfoWithLoginId()
  48. });
  49. disp.on("em.mian.friendProfile.update", function() {
  50. me.fetchFriendInfoFromServer()
  51. });
  52. WebIM.conn.listen({
  53. onOpened(message) {
  54. console.log('监听onOpened>>>>>', message);
  55. if (
  56. getCurrentRoute() == "pages/user/user" ||
  57. getCurrentRoute() == "pages/login_token/login_token"
  58. ) {
  59. me.globalData.onLoginSuccess(
  60. uni.getStorageSync("myUsername")
  61. );
  62. }
  63. },
  64. onReconnect() {
  65. uni.showToast({
  66. title: "重连中...",
  67. duration: 2000,
  68. });
  69. },
  70. onSocketConnected() {
  71. uni.showToast({
  72. title: "socket连接成功",
  73. duration: 2000,
  74. });
  75. },
  76. onClosed() {
  77. // uni.showToast({
  78. // title: "退出登录",
  79. // icon: "none",
  80. // duration: 2000,
  81. // });
  82. console.log('>>>>>>>>>>>IM被退出登录>>>>>>>>>>>>>>>>>')
  83. // uni.redirectTo({
  84. // url: "../login/login",
  85. // });
  86. me.globalData.conn.closed = true;
  87. WebIM.conn.close();
  88. },
  89. onInviteMessage(message) {
  90. me.globalData.saveGroupInvitedList.push(message);
  91. disp.fire("em.invite.joingroup", message);
  92. },
  93. onReadMessage(message) {
  94. //console.log('已读', message)
  95. },
  96. //onPresence为旧版 ,建议参考最新增删好友api文档 :http://docs-im.easemob.com/im/web/basics/buddy
  97. onPresence(message) {
  98. switch (message.type) {
  99. case "unsubscribe":
  100. break;
  101. // 好友邀请列表
  102. case "subscribe":
  103. for (let i = 0; i < me.globalData.saveFriendList.length; i++) {
  104. if (me.globalData.saveFriendList[i].from === message.from) {
  105. me.globalData.saveFriendList[i] = message;
  106. disp.fire("em.subscribe");
  107. return;
  108. }
  109. }
  110. msgStorage.saveReceiveMsg(message, "INFORM"); //存添加好友消息,方便展示通知
  111. me.globalData.saveFriendList.push(message);
  112. disp.fire("em.subscribe");
  113. break;
  114. case "subscribed":
  115. uni.showToast({
  116. title: "添加成功",
  117. duration: 1000,
  118. });
  119. disp.fire("em.subscribed");
  120. break;
  121. case "unsubscribed":
  122. disp.fire("em.unsubscribed", message);
  123. break;
  124. case "direct_joined":
  125. saveGroups();
  126. uni.showToast({
  127. title: "已进群",
  128. duration: 1000,
  129. });
  130. break;
  131. case "memberJoinPublicGroupSuccess":
  132. saveGroups();
  133. uni.showToast({
  134. title: "已进群",
  135. duration: 1000,
  136. });
  137. break;
  138. case "invite":
  139. // 防止重复添加
  140. for (
  141. let i = 0; i < me.globalData.saveGroupInvitedList.length; i++
  142. ) {
  143. if (me.globalData.saveGroupInvitedList[i].from === message.from) {
  144. me.globalData.saveGroupInvitedList[i] = message;
  145. disp.fire("em.invite.joingroup");
  146. return;
  147. }
  148. }
  149. me.globalData.saveGroupInvitedList.push(message);
  150. msgStorage.saveReceiveMsg(message, "INFORM"); //存添加好友消息,方便展示通知
  151. disp.fire("em.invite.joingroup");
  152. break;
  153. case "unavailable":
  154. disp.fire("em.contacts.remove");
  155. disp.fire("em.group.leaveGroup", message);
  156. break;
  157. case "deleteGroupChat":
  158. disp.fire("em.invite.deleteGroup", message);
  159. break;
  160. case "leaveGroup":
  161. disp.fire("em.group.leaveGroup", message);
  162. break;
  163. case "removedFromGroup":
  164. disp.fire("em.group.leaveGroup", message);
  165. break;
  166. default:
  167. break;
  168. }
  169. },
  170. onRoster(message) {},
  171. onVideoMessage(message) {
  172. console.log("onVideoMessage: ", message);
  173. if (message) {
  174. msgStorage.saveReceiveMsg(message, msgType.VIDEO);
  175. }
  176. calcUnReadSpot(message);
  177. ack(message);
  178. onGetSilentConfig(message);
  179. },
  180. onAudioMessage(message) {
  181. console.log("onAudioMessage", message);
  182. if (message) {
  183. if (onMessageError(message)) {
  184. msgStorage.saveReceiveMsg(message, msgType.AUDIO);
  185. }
  186. calcUnReadSpot(message);
  187. ack(message);
  188. onGetSilentConfig(message);
  189. }
  190. },
  191. onCmdMessage(message) {
  192. console.log("onCmdMessage", message);
  193. if (message) {
  194. if (onMessageError(message)) {
  195. msgStorage.saveReceiveMsg(message, msgType.CMD);
  196. }
  197. calcUnReadSpot(message);
  198. ack(message);
  199. onGetSilentConfig(message);
  200. }
  201. },
  202. onTextMessage(message) {
  203. console.log("onTextMessage", message);
  204. if (message) {
  205. if (onMessageError(message)) {
  206. msgStorage.saveReceiveMsg(message, msgType.TEXT);
  207. }
  208. calcUnReadSpot(message);
  209. ack(message);
  210. onGetSilentConfig(message);
  211. }
  212. },
  213. onEmojiMessage(message) {
  214. console.log("onEmojiMessage", message);
  215. if (message) {
  216. if (onMessageError(message)) {
  217. msgStorage.saveReceiveMsg(message, msgType.EMOJI);
  218. }
  219. calcUnReadSpot(message);
  220. ack(message);
  221. onGetSilentConfig(message);
  222. }
  223. },
  224. onPictureMessage(message) {
  225. console.log("onPictureMessage", message);
  226. if (message) {
  227. if (onMessageError(message)) {
  228. msgStorage.saveReceiveMsg(message, msgType.IMAGE);
  229. }
  230. calcUnReadSpot(message);
  231. ack(message);
  232. onGetSilentConfig(message);
  233. }
  234. },
  235. onFileMessage(message) {
  236. console.log("onFileMessage", message);
  237. if (message) {
  238. if (onMessageError(message)) {
  239. msgStorage.saveReceiveMsg(message, msgType.FILE);
  240. }
  241. calcUnReadSpot(message);
  242. ack(message);
  243. onGetSilentConfig(message);
  244. }
  245. },
  246. // 各种异常
  247. onError(error) {
  248. console.log(error); // 16: server-side close the websocket connection
  249. if (error.type == WebIM.statusCode.WEBIM_CONNCTION_OPEN_ERROR) {
  250. uni.hideLoading();
  251. disp.fire("em.error.passwordErr");
  252. }
  253. if (error.type == WebIM.statusCode.WEBIM_CONNCTION_AUTH_ERROR) {
  254. uni.hideLoading();
  255. disp.fire("em.error.tokenErr");
  256. }
  257. if (error.type == "socket_error") {
  258. ///sendMsgError
  259. console.log("socket_errorsocket_error", error);
  260. uni.showToast({
  261. title: "网络已断开",
  262. icon: "none",
  263. duration: 2000,
  264. });
  265. disp.fire("em.error.sendMsgErr", error);
  266. }
  267. },
  268. });
  269. this.globalData.checkIsIPhoneX();
  270. },
  271. onShow(options) {
  272. let scene = options.scene;
  273. req.setStorage('scene', scene)
  274. this.globalData.getVideoScene();
  275. },
  276. globalData: {
  277. phoneNumber: '',
  278. unReadMessageNum: 0,
  279. userInfo: null,
  280. userInfoFromServer: null, //用户属性从环信服务器获取
  281. friendUserInfoMap: new Map(), //好友属性
  282. saveFriendList: [],
  283. saveGroupInvitedList: [],
  284. isIPX: false, //是否为iphone X
  285. conn: {
  286. closed: false,
  287. curOpenOpt: {},
  288. open(opt) {
  289. // uni.showLoading({
  290. // title: "加载中...",
  291. // mask: true,
  292. // });
  293. this.curOpenOpt = opt;
  294. WebIM.conn.open(opt).then(() => {
  295. //token获取成功,即可开始请求用户属性。
  296. disp.fire("em.mian.profile.update");
  297. disp.fire("em.mian.friendProfile.update");
  298. console.log('>>>>>token成功')
  299. }).catch((err) => {
  300. console.log('>>>>>token获取失败', err)
  301. });
  302. this.closed = false;
  303. },
  304. reopen() {
  305. if (this.closed) {
  306. //this.open(this.curOpenOpt);
  307. WebIM.conn.open(this.curOpenOpt);
  308. this.closed = false;
  309. }
  310. },
  311. },
  312. onLoginSuccess: function(myName) {
  313. // uni.hideLoading();
  314. uni.navigateTo({
  315. url: "/chat/conversation/conversation?myName=" + myName,
  316. });
  317. },
  318. getUserInfo(cb) {
  319. var me = this;
  320. if (this.userInfo) {
  321. typeof cb == "function" && cb(this.userInfo);
  322. } else {
  323. // 调用登录接口
  324. uni.login({
  325. success() {
  326. uni.getUserInfo({
  327. success(res) {
  328. me.userInfo = res.userInfo;
  329. typeof cb == "function" && cb(me.userInfo);
  330. },
  331. });
  332. },
  333. });
  334. }
  335. },
  336. checkIsIPhoneX: function() {
  337. const me = this;
  338. uni.getSystemInfo({
  339. success: function(res) {
  340. // 根据 model 进行判断
  341. if (res.model && res.model.search("iPhone X") != -1) {
  342. me.isIPX = true;
  343. }
  344. },
  345. });
  346. },
  347. //获取客服配置
  348. getChatList() {
  349. // req.getRequest('/api/customer/list', {}, res => {
  350. // req.setStorage('chatService', res);
  351. // });
  352. },
  353. appInitData() {
  354. var getSysInfo = uni.getSystemInfoSync();
  355. this.isIPhone = getSysInfo.model.indexOf("iPhone") != -1;
  356. this.isIPhoneX = getSysInfo.model.indexOf("iPhone X") != -1 || getSysInfo.model.indexOf("iPhone 11") != -
  357. 1; // 是否为全面屏
  358. this.isFullScreen = getSysInfo.screenHeight / getSysInfo.screenWidth >= 2.1; // iPhoneX底部空白高度为68,全面屏为20
  359. this.bottomBlankHeignt = this.isIPhoneX ? 68 : this.isFullScreen ? 10 : 0;
  360. this.height = getSysInfo.statusBarHeight;
  361. this.screenHeight = getSysInfo.screenHeight;
  362. },
  363. getVideoScene() {
  364. let scene = req.getStorage('scene');
  365. let arr = [1195, 1193, 1191, 1184, 1177, 1176, 1175, 1201, 1216, 10001]
  366. req.setStorage('isVideoScene', false)
  367. arr.some(it => {
  368. if (it === scene) {
  369. req.setStorage('isVideoScene', true)
  370. }
  371. })
  372. console.log('isVideoScene==', req.getStorage('isVideoScene'))
  373. },
  374. InitUpdateManager() {
  375. const updateManager = uni.getUpdateManager();
  376. let that = this;
  377. updateManager.onCheckForUpdate(function(res) {
  378. // 请求完新版本信息的回调
  379. console.log(res.hasUpdate);
  380. });
  381. updateManager.onUpdateReady(function() {
  382. uni.showModal({
  383. title: '更新提示',
  384. content: '新版本已经准备好,是否重启应用?',
  385. success: function(res) {
  386. if (res.confirm) {
  387. // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
  388. uni.clearStorage({
  389. success() {
  390. updateManager.applyUpdate();
  391. }
  392. });
  393. }
  394. }
  395. });
  396. });
  397. updateManager.onUpdateFailed(function() { // 新版本下载失败
  398. });
  399. },
  400. getCheckSessoin(success) {
  401. // var sessionKey = req.getStorage('SESSION_KEY');
  402. // let that = this;
  403. // wx.checkSession({
  404. // success() {
  405. // if (!sessionKey) {
  406. // that.getSessionKey(success);
  407. // } else {
  408. // success.call(this, sessionKey);
  409. // }
  410. // },
  411. // fail() {
  412. // that.getSessionKey(success);
  413. // }
  414. // })
  415. this.getSessionKey(success);
  416. },
  417. getSessionKey(success) {
  418. let that = this;
  419. uni.login({
  420. success(res) {
  421. req.postRequest('/api/code', {
  422. code: res.code
  423. }, data => {
  424. that.SESSION_KEY = data.session_key;
  425. req.setStorage('SESSION_KEY', data.session_key);
  426. success.call(this, data);
  427. }, true);
  428. }
  429. });
  430. },
  431. userInfo: null,
  432. height: 0,
  433. isredenvelopes: true,
  434. isLayerAd: true,
  435. /**
  436. * 打开新页面
  437. */
  438. openPage(e) {
  439. let url
  440. if (e.indexOf("plugin-private:") != -1) {
  441. url = `${e}`
  442. } else {
  443. url = `/${e}`
  444. }
  445. uni.navigateTo({
  446. // url: `/${e}`
  447. url: url
  448. });
  449. // uni.navigateTo({
  450. // url: `/${e}`
  451. // });
  452. },
  453. /**
  454. *
  455. * 关闭当前页面,跳转到应用内的某个页面。
  456. */
  457. redirectTab(path) {
  458. uni.redirectTo({
  459. url: `/${path}`
  460. });
  461. },
  462. /**
  463. *
  464. * 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
  465. */
  466. switchTab(path) {
  467. uni.switchTab({
  468. url: `/${path}`
  469. });
  470. },
  471. /**
  472. *
  473. * 关闭所有页面,打开到应用内的某个页面
  474. */
  475. reLaunchTo(path) {
  476. uni.reLaunch({
  477. url: `/${path}`
  478. });
  479. },
  480. /**
  481. *
  482. * 保留当前页面,跳转到应用内的某个页面
  483. */
  484. navigateTo(path) {
  485. uni.navigateTo({
  486. url: `/${path}`
  487. });
  488. }
  489. },
  490. methods: {
  491. async fetchUserInfoWithLoginId() {
  492. const userId = await uni.WebIM.conn.user;
  493. if (userId) {
  494. try {
  495. const {
  496. data
  497. } = await uni.WebIM.conn.fetchUserInfoById(userId)
  498. this.globalData.userInfoFromServer = Object.assign({}, data[userId]);
  499. } catch (error) {
  500. console.log(error)
  501. console.log("用户属性获取失败")
  502. // uni.showToast({
  503. // title: "用户属性获取失败",
  504. // icon: "none",
  505. // duration: 2000,
  506. // })
  507. }
  508. }
  509. },
  510. async fetchFriendInfoFromServer() {
  511. let friendList = []
  512. try {
  513. const res = await uni.WebIM.conn.getContacts()
  514. friendList = Object.assign([], res?.data)
  515. if (friendList.length && friendList.length < 99) {
  516. const {
  517. data
  518. } = await uni.WebIM.conn.fetchUserInfoById(friendList)
  519. this.setFriendUserInfotoMap(data)
  520. } else {
  521. let newArr = _chunkArr(friendList, 99)
  522. for (let i = 0; i < newArr.length; i++) {
  523. const {
  524. data
  525. } = await uni.WebIM.conn.fetchUserInfoById(newArr[i])
  526. this.setFriendUserInfotoMap(data)
  527. }
  528. }
  529. } catch (error) {
  530. console.log(error)
  531. console.log("用户属性获取失败")
  532. // uni.showToast({
  533. // title: "用户属性获取失败",
  534. // icon: "none"
  535. // })
  536. }
  537. },
  538. setFriendUserInfotoMap(data) {
  539. if (Object.keys(data).length) {
  540. for (const key in data) {
  541. if (Object.hasOwnProperty.call(data, key)) {
  542. const values = data[key];
  543. Object.values(values).length && this.globalData.friendUserInfoMap.set(key, values);
  544. }
  545. }
  546. }
  547. }
  548. }
  549. };
  550. /*--------环信SDK消息-----------------------*/
  551. function ack(receiveMsg) {
  552. // 处理未读消息回执
  553. var bodyId = receiveMsg.id; // 需要发送已读回执的消息id
  554. var ackMsg = new WebIM.message("read", WebIM.conn.getUniqueId());
  555. ackMsg.set({
  556. id: bodyId,
  557. to: receiveMsg.from,
  558. });
  559. WebIM.conn.send(ackMsg.body);
  560. }
  561. function onMessageError(err) {
  562. if (err.type === "error") {
  563. uni.showToast({
  564. title: err.errorText,
  565. });
  566. return false;
  567. }
  568. return true;
  569. }
  570. function getCurrentRoute() {
  571. let pages = getCurrentPages();
  572. if (pages.length > 0) {
  573. let currentPage = pages[pages.length - 1];
  574. return currentPage.route;
  575. }
  576. return "/";
  577. }
  578. // 包含陌生人版本
  579. //该方法用以计算本地存储消息的未读总数。
  580. function calcUnReadSpot(message) {
  581. let myName = uni.getStorageSync("myUsername");
  582. let pushObj = uni.getStorageSync("pushStorageData")
  583. let pushAry = pushObj[myName] || []
  584. uni.getStorageInfo({
  585. success: function(res) {
  586. let storageKeys = res.keys;
  587. let newChatMsgKeys = [];
  588. let historyChatMsgKeys = [];
  589. storageKeys.forEach((item) => {
  590. if (item.indexOf(myName) > -1 && item.indexOf("rendered_") == -1 && item.indexOf(
  591. "imUserInfo_") == -1) {
  592. newChatMsgKeys.push(item);
  593. }
  594. });
  595. console.log('newChatMsgKeys》》》》》', newChatMsgKeys);
  596. let count = newChatMsgKeys.reduce(function(result, curMember, idx) {
  597. let newName = curMember.split(myName)[0]
  598. let chatMsgs;
  599. chatMsgs = uni.getStorageSync(curMember) || [];
  600. console.log('chatMsgs>>>>>', chatMsgs);
  601. //过滤消息来源与当前登录ID一致的消息,不计入总数中。
  602. chatMsgs = chatMsgs.filter((msg) => msg.yourname !== myName);
  603. if (pushAry.includes(newName)) return result
  604. return result + chatMsgs.length;
  605. }, 0);
  606. getApp().globalData.unReadMessageNum = count;
  607. disp.fire("em.unreadspot", message);
  608. },
  609. });
  610. }
  611. function saveGroups() {
  612. var me = this;
  613. return WebIM.conn.getGroup({
  614. limit: 50,
  615. success: function(res) {
  616. uni.setStorage({
  617. key: "listGroup",
  618. data: res.data,
  619. });
  620. },
  621. error: function(err) {
  622. console.log(err);
  623. },
  624. });
  625. }
  626. </script>
  627. <style>
  628. @import "./app.css";
  629. </style>