App.vue 17 KB

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