App.vue 16 KB

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