app.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. // app.js
  2. let WebIM = wx.WebIM = require("./utils/WebIM")["default"];
  3. let msgStorage = require("./utils/msgstorage");
  4. let msgType = require("./utils/msgtype");
  5. let ToastPannel = require("./comps/toast/toast");
  6. let disp = require("./utils/broadcast");
  7. let logout = false;
  8. const AgoraMiniappSDK = require('./emedia/Agora_Miniapp_SDK_for_WeChat');
  9. // const AgoraMiniappSDK = require('./emedia/Agora');
  10. wx.AgoraMiniappSDK = AgoraMiniappSDK
  11. console.log('WebIM', WebIM)
  12. console.log('wx.AgoraMiniappSDK', wx.AgoraMiniappSDK)
  13. let emediaState = require('./utils/emediaState');
  14. function ack(receiveMsg) {
  15. // 处理未读消息回执
  16. var bodyId = receiveMsg.id; // 需要发送已读回执的消息id
  17. var ackMsg = new WebIM.message("read", WebIM.conn.getUniqueId());
  18. ackMsg.set({
  19. id: bodyId,
  20. to: receiveMsg.from
  21. });
  22. WebIM.conn.send(ackMsg.body);
  23. }
  24. function onMessageError(err) {
  25. if (err.type === "error") {
  26. wx.showToast({
  27. title: err.errorText
  28. });
  29. return false;
  30. }
  31. return true;
  32. }
  33. function getCurrentRoute() {
  34. let pages = getCurrentPages();
  35. if (pages.length > 0) {
  36. let currentPage = pages[pages.length - 1];
  37. return currentPage.route;
  38. }
  39. return '/'
  40. }
  41. // 包含陌生人版本
  42. function calcUnReadSpot(message) {
  43. let myName = wx.getStorageSync("myUsername");
  44. wx.getStorageInfo({
  45. success: function (res) {
  46. let storageKeys = res.keys;
  47. let newChatMsgKeys = [];
  48. let historyChatMsgKeys = [];
  49. storageKeys.forEach((item) => {
  50. if (item.indexOf(myName) > -1 && item.indexOf('rendered_') == -1) {
  51. newChatMsgKeys.push(item)
  52. }
  53. });
  54. let count = newChatMsgKeys.reduce(function (result, curMember, idx) {
  55. let chatMsgs;
  56. chatMsgs = wx.getStorageSync(curMember) || [];
  57. return result + chatMsgs.length;
  58. }, 0);
  59. getApp().globalData.unReadMessageNum = count;
  60. disp.fire("em.xmpp.unreadspot", message);
  61. }
  62. })
  63. }
  64. function saveGroups() {
  65. var me = this;
  66. return WebIM.conn.getGroup({
  67. limit: 50,
  68. success: function (res) {
  69. wx.setStorage({
  70. key: "listGroup",
  71. data: res.data
  72. });
  73. },
  74. error: function (err) {
  75. console.log(err)
  76. }
  77. });
  78. }
  79. App({
  80. onLaunch() {
  81. // 调用 API 从本地缓存中获取数据
  82. wx.setInnerAudioOption({ obeyMuteSwitch: false })
  83. var that = this;
  84. // 展示本地存储能力
  85. const logs = wx.getStorageSync('logs') || []
  86. logs.unshift(Date.now())
  87. wx.setStorageSync('logs', logs)
  88. // 登录
  89. wx.login({
  90. success: res => {
  91. // 发送 res.code 到后台换取 openId, sessionKey, unionId
  92. }
  93. });
  94. //
  95. disp.on("em.main.ready", function () {
  96. calcUnReadSpot();
  97. });
  98. disp.on("em.chatroom.leave", function () {
  99. calcUnReadSpot();
  100. });
  101. disp.on("em.chat.session.remove", function () {
  102. calcUnReadSpot();
  103. });
  104. disp.on('em.chat.audio.fileLoaded', function () {
  105. calcUnReadSpot()
  106. });
  107. disp.on('em.main.deleteFriend', function () {
  108. calcUnReadSpot()
  109. });
  110. disp.on('em.chat.audio.fileLoaded', function () {
  111. calcUnReadSpot()
  112. });
  113. // 音视频邀请
  114. disp.on('emedia.confirmRing', function () {
  115. });
  116. /**
  117. * 环信监听事件
  118. */
  119. WebIM.conn.listen({
  120. //连接成功回调
  121. onOpened(message) {
  122. console.log('im登录成功');
  123. // WebIM.conn.setPresence();
  124. // if (getCurrentRoute() == "pages/login/login" || getCurrentRoute() == "pages/login_token/login_token") {
  125. that.onLoginSuccess(wx.getStorageSync("myUsername").toLowerCase());
  126. // }
  127. let identityToken = WebIM.conn.context.accessToken
  128. let identityName = WebIM.conn.context.jid
  129. },
  130. onReconnect() {
  131. wx.showToast({
  132. title: "重连中...",
  133. duration: 2000
  134. });
  135. },
  136. onSocketConnected() {
  137. wx.showToast({
  138. title: "socket连接成功",
  139. duration: 2000
  140. });
  141. },
  142. onClosed() {
  143. wx.showToast({
  144. title: "已退出登录",
  145. icon: 'none',
  146. duration: 2000
  147. });
  148. wx.redirectTo({
  149. url: "../login/login"
  150. });
  151. that.conn.closed = true;
  152. WebIM.conn.close();
  153. },
  154. onInviteMessage(message) {
  155. that.globalData.saveGroupInvitedList.push(message);
  156. disp.fire("em.xmpp.invite.joingroup", message);
  157. // wx.showModal({
  158. // title: message.from + " 已邀你入群 " + message.roomid,
  159. // success(){
  160. // disp.fire("em.xmpp.invite.joingroup", message);
  161. // },
  162. // error(){
  163. // disp.fire("em.xmpp.invite.joingroup", message);
  164. // }
  165. // });
  166. },
  167. onReadMessage(message) {
  168. //console.log('已读', message)
  169. },
  170. onPresence(message) {
  171. console.log("onPresence", message);
  172. switch (message.type) {
  173. case "unsubscribe":
  174. console.log('unsubscribe')
  175. // pages[0].moveFriend(message);
  176. break;
  177. // 好友邀请列表
  178. case "subscribe":
  179. if (message.status === "[resp:true]") {
  180. }
  181. else {
  182. // pages[0].handleFriendMsg(message);
  183. for (let i = 0; i < that.globalData.saveFriendList.length; i++) {
  184. if (that.globalData.saveFriendList[i].from === message.from) {
  185. that.globalData.saveFriendList[i] = message
  186. disp.fire("em.xmpp.subscribe");
  187. return;
  188. }
  189. }
  190. that.globalData.saveFriendList.push(message);
  191. disp.fire("em.xmpp.subscribe");
  192. }
  193. break;
  194. case "subscribed":
  195. wx.showToast({
  196. title: "添加成功",
  197. duration: 1000
  198. });
  199. disp.fire("em.xmpp.subscribed");
  200. break;
  201. case "unsubscribed":
  202. // 延时1.5秒, 防止刚登录时和登录的toast重合
  203. setTimeout(() => {
  204. wx.showToast({
  205. title: message.from + "已退订",
  206. duration: 2000
  207. });
  208. }, 1500)
  209. disp.fire("em.xmpp.unsubscribed");
  210. break;
  211. case "direct_joined":
  212. saveGroups();
  213. // wx.showToast({
  214. // title: "已进群",
  215. // duration: 1000
  216. // });
  217. break;
  218. case "memberJoinPublicGroupSuccess":
  219. saveGroups();
  220. // wx.showToast({
  221. // title: "已进群",
  222. // duration: 1000
  223. // });
  224. break;
  225. case 'invite':
  226. let info = message.from + '邀请你加入群组'
  227. wx.showModal({
  228. title: '提示',
  229. content: info,
  230. success(res) {
  231. if (res.confirm) {
  232. console.log('用户点击确定')
  233. WebIM.conn.agreeInviteIntoGroup({
  234. invitee: WebIM.conn.context.userId,
  235. groupId: message.gid,
  236. success: () => {
  237. saveGroups();
  238. console.log('加入成功')
  239. disp.fire("em.xmpp.group.joingroup");
  240. }
  241. })
  242. } else if (res.cancel) {
  243. console.log('用户点击取消')
  244. WebIM.conn.rejectInviteIntoGroup({
  245. invitee: WebIM.conn.context.userId,
  246. groupId: message.gid
  247. })
  248. }
  249. }
  250. })
  251. break;
  252. // 好友列表
  253. // case "subscribed":
  254. // let newFriendList = [];
  255. // for(let i = 0; i < that.globalData.saveFriendList.length; i++){
  256. // if(that.globalData.saveFriendList[i].from != message.from){
  257. // newFriendList.push(that.globalData.saveFriendList[i]);
  258. // }
  259. // }
  260. // that.globalData.saveFriendList = newFriendList;
  261. // break;
  262. // 删除好友
  263. case "unavailable":
  264. disp.fire("em.xmpp.contacts.remove");
  265. disp.fire("em.xmpp.group.leaveGroup", message);
  266. break;
  267. case 'deleteGroupChat':
  268. disp.fire("em.xmpp.invite.deleteGroup", message);
  269. break;
  270. case "leaveGroup":
  271. disp.fire("em.xmpp.group.leaveGroup", message);
  272. break;
  273. case "removedFromGroup":
  274. disp.fire("em.xmpp.group.leaveGroup", message);
  275. break;
  276. // case "joinChatRoomSuccess":
  277. // wx.showToast({
  278. // title: "JoinChatRoomSuccess",
  279. // });
  280. // break;
  281. // case "memberJoinChatRoomSuccess":
  282. // wx.showToast({
  283. // title: "memberJoinChatRoomSuccess",
  284. // });
  285. // break;
  286. // case "memberLeaveChatRoomSuccess":
  287. // wx.showToast({
  288. // title: "leaveChatRoomSuccess",
  289. // });
  290. // break;
  291. default:
  292. break;
  293. }
  294. },
  295. onRoster(message) {
  296. // let pages = getCurrentPages();
  297. // if(pages[0]){
  298. // pages[0].onShow();
  299. // }
  300. },
  301. onVideoMessage(message) {
  302. console.log("onVideoMessage: ", message);
  303. if (message) {
  304. msgStorage.saveReceiveMsg(message, msgType.VIDEO);
  305. }
  306. calcUnReadSpot(message);
  307. ack(message);
  308. },
  309. onAudioMessage(message) {
  310. console.log("onAudioMessage", message);
  311. if (message) {
  312. if (onMessageError(message)) {
  313. msgStorage.saveReceiveMsg(message, msgType.AUDIO);
  314. }
  315. calcUnReadSpot(message);
  316. ack(message);
  317. }
  318. },
  319. onCmdMessage(message) {
  320. console.log("onCmdMessage", message);
  321. if (message) {
  322. emediaState.onMessage(message)
  323. if (onMessageError(message)) {
  324. msgStorage.saveReceiveMsg(message, msgType.CMD);
  325. }
  326. calcUnReadSpot(message);
  327. ack(message);
  328. }
  329. },
  330. // onLocationMessage(message){
  331. // console.log("Location message: ", message);
  332. // if(message){
  333. // msgStorage.saveReceiveMsg(message, msgType.LOCATION);
  334. // }
  335. // },
  336. onTextMessage(message) {
  337. console.log("onTextMessage", message);
  338. if (message) {
  339. if (onMessageError(message)) {
  340. msgStorage.saveReceiveMsg(message, msgType.TEXT);
  341. }
  342. calcUnReadSpot(message);
  343. ack(message);
  344. if (message.ext.action == "invite") {
  345. emediaState.onMessage(message)
  346. }
  347. if (message.ext.msg_extension) {
  348. let msgExtension = JSON.parse(message.ext.msg_extension)
  349. let conferenceId = message.ext.conferenceId
  350. let password = message.ext.password
  351. disp.fire("em.xmpp.videoCall", {
  352. msgExtension: msgExtension,
  353. conferenceId: conferenceId,
  354. password: password
  355. });
  356. }
  357. }
  358. },
  359. onEmojiMessage(message) {
  360. console.log("onEmojiMessage", message);
  361. if (message) {
  362. if (onMessageError(message)) {
  363. msgStorage.saveReceiveMsg(message, msgType.EMOJI);
  364. }
  365. calcUnReadSpot(message);
  366. ack(message);
  367. }
  368. },
  369. onPictureMessage(message) {
  370. console.log("onPictureMessage", message);
  371. if (message) {
  372. if (onMessageError(message)) {
  373. msgStorage.saveReceiveMsg(message, msgType.IMAGE);
  374. }
  375. calcUnReadSpot(message);
  376. ack(message);
  377. }
  378. },
  379. onFileMessage(message) {
  380. console.log('onFileMessage', message);
  381. if (message) {
  382. if (onMessageError(message)) {
  383. msgStorage.saveReceiveMsg(message, msgType.FILE);
  384. }
  385. calcUnReadSpot(message);
  386. ack(message);
  387. }
  388. },
  389. // 各种异常
  390. onError(error) {
  391. console.log('error', error)
  392. if (error.type == 40) { //send msg fail
  393. disp.fire("em.xmpp.error.sendMsgErr", error.failMsgs);
  394. }
  395. // 16: server-side close the websocket connection
  396. if (error.type == WebIM.statusCode.WEBIM_CONNCTION_DISCONNECTED && !logout) {
  397. if (WebIM.conn.autoReconnectNumTotal >= WebIM.conn.autoReconnectNumMax) {
  398. wx.showToast({
  399. title: "server-side close the websocket connection",
  400. duration: 1000
  401. });
  402. WebIM.conn.close();
  403. wx.redirectTo({
  404. url: "./pages/login/login"
  405. });
  406. logout = true
  407. }
  408. return
  409. }
  410. // 8: offline by multi login
  411. if (error.type == WebIM.statusCode.WEBIM_CONNCTION_SERVER_ERROR) {
  412. wx.showToast({
  413. title: "offline by multi login",
  414. duration: 1000
  415. });
  416. wx.redirectTo({
  417. url: "./pages/login/login"
  418. });
  419. }
  420. if (error.type == WebIM.statusCode.WEBIM_CONNCTION_OPEN_ERROR) {
  421. wx.hideLoading()
  422. disp.fire("em.xmpp.error.passwordErr");
  423. let data = error.data.data
  424. // data && message.error(data)
  425. if (data) {
  426. if (data.error_description == "user not found") {
  427. // ("用户名不存在!")
  428. disp.fire("em.xmpp.error.passwordErr");
  429. } else if (data.error_description == "invalid password") {
  430. // ('密码无效!')
  431. disp.fire("em.xmpp.error.passwordErr");
  432. } else if (data.error_description == "user not activated") {
  433. // ("用户已被封禁!")
  434. disp.fire("em.xmpp.error.activatedErr");
  435. }
  436. }
  437. }
  438. if (error.type == WebIM.statusCode.WEBIM_CONNCTION_AUTH_ERROR) {
  439. wx.hideLoading()
  440. disp.fire("em.xmpp.error.tokenErr");
  441. }
  442. if (error.type == 16) {///sendMsgError
  443. // https://developers.weixin.qq.com/community/develop/doc/00084a400202787b54f8c9e6357800
  444. // 因为上面的原因 这里不要一直提示了
  445. return
  446. // console.log('socket_errorsocket_error', error)
  447. // wx.showToast({
  448. // title: "网络已断开",
  449. // icon: 'none',
  450. // duration: 2000
  451. // });
  452. // disp.fire("em.xmpp.error.sendMsgErr", error);
  453. }
  454. },
  455. });
  456. this.checkIsIPhoneX();
  457. },
  458. ToastPannel,
  459. globalData: {
  460. // imgPath: 'http://192.168.0.46/image',
  461. imgPath: 'https://miniapp.cqjudong.com/image',
  462. path: 'https://miniapp.cqjudong.com/base',
  463. // path: 'http://192.168.1.218:8081',
  464. Authorization: '',
  465. userInfo: {},
  466. roleInfo: {},
  467. unReadMessageNum: 0,
  468. // userInfo: null,
  469. saveFriendList: [],
  470. saveGroupInvitedList: [],
  471. isIPX: false, //是否为iphone X
  472. channel: '',
  473. roleList: [{
  474. code: 'ADMIN',
  475. page: '../index-admin/index-admin'
  476. }, {
  477. code: 'OPERATION',
  478. page: '../index-work/index-work'
  479. }, {
  480. code: 'GUEST',
  481. page: '../index-guest/index-guest'
  482. }]
  483. },
  484. conn: {
  485. closed: false,
  486. curOpenOpt: {},
  487. open(opt) {
  488. wx.showLoading({
  489. title: '正在初始化客户端...',
  490. mask: true
  491. });
  492. this.curOpenOpt = opt;
  493. WebIM.conn.open(opt);
  494. this.closed = true;
  495. },
  496. reopen() {
  497. if (this.closed) {
  498. //this.open(this.curOpenOpt);
  499. WebIM.conn.open(this.curOpenOpt);
  500. this.closed = false;
  501. }
  502. }
  503. },
  504. onShow() {
  505. // 从搜索页面进的时候退出后再回来会回到首页,此时并没有调用退出,导致登录不上
  506. // 判断当前是登录状态直接跳转到chat页面
  507. const pages = getCurrentPages();
  508. const currentPage = pages[pages.length - 1];
  509. // 选择图片或者拍照也会触发onShow,所以忽略聊天页面
  510. if (WebIM.conn.isOpened() && currentPage.route != "pages/chatroom/chatroom" && currentPage.route != "pages/groupChatRoom/groupChatRoom") {
  511. let myName = wx.getStorageSync("myUsername");
  512. wx.redirectTo({
  513. url: "../chat/chat?myName=" + myName
  514. });
  515. }
  516. wx.hideHomeButton()
  517. },
  518. /**
  519. * 环信登录成功回调
  520. * @param {*} myName
  521. */
  522. onLoginSuccess: function (myName) {
  523. wx.hideLoading();
  524. wx.switchTab({
  525. url: '../index/index',
  526. })
  527. },
  528. getUserInfo(cb) {
  529. var me = this;
  530. if (this.globalData.userInfo) {
  531. typeof cb == "function" && cb(this.globalData.userInfo);
  532. }
  533. else {
  534. // 调用登录接口
  535. wx.login({
  536. success() {
  537. wx.getUserInfo({
  538. success(res) {
  539. me.globalData.userInfo = res.userInfo;
  540. typeof cb == "function" && cb(me.globalData.userInfo);
  541. }
  542. });
  543. }
  544. });
  545. }
  546. },
  547. checkIsIPhoneX: function () {
  548. const me = this
  549. wx.getSystemInfo({
  550. success: function (res) {
  551. // 根据 model 进行判断
  552. if (res.model.search('iPhone X') != -1) {
  553. me.globalData.isIPX = true
  554. }
  555. }
  556. })
  557. },
  558. })