app.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  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. WebIM.conn.listen({
  117. onOpened(message) {
  118. console.log('im登录成功')
  119. // WebIM.conn.setPresence();
  120. // if (getCurrentRoute() == "pages/login/login" || getCurrentRoute() == "pages/login_token/login_token") {
  121. that.onLoginSuccess(wx.getStorageSync("myUsername").toLowerCase());
  122. // }
  123. let identityToken = WebIM.conn.context.accessToken
  124. let identityName = WebIM.conn.context.jid
  125. },
  126. onReconnect() {
  127. wx.showToast({
  128. title: "重连中...",
  129. duration: 2000
  130. });
  131. },
  132. onSocketConnected() {
  133. wx.showToast({
  134. title: "socket连接成功",
  135. duration: 2000
  136. });
  137. },
  138. onClosed() {
  139. wx.showToast({
  140. title: "网络已断开",
  141. icon: 'none',
  142. duration: 2000
  143. });
  144. wx.redirectTo({
  145. url: "../login/login"
  146. });
  147. that.conn.closed = true;
  148. WebIM.conn.close();
  149. },
  150. onInviteMessage(message) {
  151. that.globalData.saveGroupInvitedList.push(message);
  152. disp.fire("em.xmpp.invite.joingroup", message);
  153. // wx.showModal({
  154. // title: message.from + " 已邀你入群 " + message.roomid,
  155. // success(){
  156. // disp.fire("em.xmpp.invite.joingroup", message);
  157. // },
  158. // error(){
  159. // disp.fire("em.xmpp.invite.joingroup", message);
  160. // }
  161. // });
  162. },
  163. onReadMessage(message) {
  164. //console.log('已读', message)
  165. },
  166. onPresence(message) {
  167. console.log("onPresence", message);
  168. switch (message.type) {
  169. case "unsubscribe":
  170. console.log('unsubscribe')
  171. // pages[0].moveFriend(message);
  172. break;
  173. // 好友邀请列表
  174. case "subscribe":
  175. if (message.status === "[resp:true]") {
  176. }
  177. else {
  178. // pages[0].handleFriendMsg(message);
  179. for (let i = 0; i < that.globalData.saveFriendList.length; i++) {
  180. if (that.globalData.saveFriendList[i].from === message.from) {
  181. that.globalData.saveFriendList[i] = message
  182. disp.fire("em.xmpp.subscribe");
  183. return;
  184. }
  185. }
  186. that.globalData.saveFriendList.push(message);
  187. disp.fire("em.xmpp.subscribe");
  188. }
  189. break;
  190. case "subscribed":
  191. wx.showToast({
  192. title: "添加成功",
  193. duration: 1000
  194. });
  195. disp.fire("em.xmpp.subscribed");
  196. break;
  197. case "unsubscribed":
  198. // 延时1.5秒, 防止刚登录时和登录的toast重合
  199. setTimeout(() => {
  200. wx.showToast({
  201. title: message.from + "已退订",
  202. duration: 2000
  203. });
  204. }, 1500)
  205. disp.fire("em.xmpp.unsubscribed");
  206. break;
  207. case "direct_joined":
  208. saveGroups();
  209. wx.showToast({
  210. title: "已进群",
  211. duration: 1000
  212. });
  213. break;
  214. case "memberJoinPublicGroupSuccess":
  215. saveGroups();
  216. wx.showToast({
  217. title: "已进群",
  218. duration: 1000
  219. });
  220. break;
  221. case 'invite':
  222. let info = message.from + '邀请你加入群组'
  223. wx.showModal({
  224. title: '提示',
  225. content: info,
  226. success(res) {
  227. if (res.confirm) {
  228. console.log('用户点击确定')
  229. WebIM.conn.agreeInviteIntoGroup({
  230. invitee: WebIM.conn.context.userId,
  231. groupId: message.gid,
  232. success: () => {
  233. saveGroups();
  234. console.log('加入成功')
  235. disp.fire("em.xmpp.group.joingroup");
  236. }
  237. })
  238. } else if (res.cancel) {
  239. console.log('用户点击取消')
  240. WebIM.conn.rejectInviteIntoGroup({
  241. invitee: WebIM.conn.context.userId,
  242. groupId: message.gid
  243. })
  244. }
  245. }
  246. })
  247. break;
  248. // 好友列表
  249. // case "subscribed":
  250. // let newFriendList = [];
  251. // for(let i = 0; i < that.globalData.saveFriendList.length; i++){
  252. // if(that.globalData.saveFriendList[i].from != message.from){
  253. // newFriendList.push(that.globalData.saveFriendList[i]);
  254. // }
  255. // }
  256. // that.globalData.saveFriendList = newFriendList;
  257. // break;
  258. // 删除好友
  259. case "unavailable":
  260. disp.fire("em.xmpp.contacts.remove");
  261. disp.fire("em.xmpp.group.leaveGroup", message);
  262. break;
  263. case 'deleteGroupChat':
  264. disp.fire("em.xmpp.invite.deleteGroup", message);
  265. break;
  266. case "leaveGroup":
  267. disp.fire("em.xmpp.group.leaveGroup", message);
  268. break;
  269. case "removedFromGroup":
  270. disp.fire("em.xmpp.group.leaveGroup", message);
  271. break;
  272. // case "joinChatRoomSuccess":
  273. // wx.showToast({
  274. // title: "JoinChatRoomSuccess",
  275. // });
  276. // break;
  277. // case "memberJoinChatRoomSuccess":
  278. // wx.showToast({
  279. // title: "memberJoinChatRoomSuccess",
  280. // });
  281. // break;
  282. // case "memberLeaveChatRoomSuccess":
  283. // wx.showToast({
  284. // title: "leaveChatRoomSuccess",
  285. // });
  286. // break;
  287. default:
  288. break;
  289. }
  290. },
  291. onRoster(message) {
  292. // let pages = getCurrentPages();
  293. // if(pages[0]){
  294. // pages[0].onShow();
  295. // }
  296. },
  297. onVideoMessage(message) {
  298. console.log("onVideoMessage: ", message);
  299. if (message) {
  300. msgStorage.saveReceiveMsg(message, msgType.VIDEO);
  301. }
  302. calcUnReadSpot(message);
  303. ack(message);
  304. },
  305. onAudioMessage(message) {
  306. console.log("onAudioMessage", message);
  307. if (message) {
  308. if (onMessageError(message)) {
  309. msgStorage.saveReceiveMsg(message, msgType.AUDIO);
  310. }
  311. calcUnReadSpot(message);
  312. ack(message);
  313. }
  314. },
  315. onCmdMessage(message) {
  316. console.log("onCmdMessage", message);
  317. if (message) {
  318. emediaState.onMessage(message)
  319. if (onMessageError(message)) {
  320. msgStorage.saveReceiveMsg(message, msgType.CMD);
  321. }
  322. calcUnReadSpot(message);
  323. ack(message);
  324. }
  325. },
  326. // onLocationMessage(message){
  327. // console.log("Location message: ", message);
  328. // if(message){
  329. // msgStorage.saveReceiveMsg(message, msgType.LOCATION);
  330. // }
  331. // },
  332. onTextMessage(message) {
  333. console.log("onTextMessage", message);
  334. if (message) {
  335. if (onMessageError(message)) {
  336. msgStorage.saveReceiveMsg(message, msgType.TEXT);
  337. }
  338. calcUnReadSpot(message);
  339. ack(message);
  340. if (message.ext.action == "invite") {
  341. emediaState.onMessage(message)
  342. }
  343. if (message.ext.msg_extension) {
  344. let msgExtension = JSON.parse(message.ext.msg_extension)
  345. let conferenceId = message.ext.conferenceId
  346. let password = message.ext.password
  347. disp.fire("em.xmpp.videoCall", {
  348. msgExtension: msgExtension,
  349. conferenceId: conferenceId,
  350. password: password
  351. });
  352. }
  353. }
  354. },
  355. onEmojiMessage(message) {
  356. console.log("onEmojiMessage", message);
  357. if (message) {
  358. if (onMessageError(message)) {
  359. msgStorage.saveReceiveMsg(message, msgType.EMOJI);
  360. }
  361. calcUnReadSpot(message);
  362. ack(message);
  363. }
  364. },
  365. onPictureMessage(message) {
  366. console.log("onPictureMessage", message);
  367. if (message) {
  368. if (onMessageError(message)) {
  369. msgStorage.saveReceiveMsg(message, msgType.IMAGE);
  370. }
  371. calcUnReadSpot(message);
  372. ack(message);
  373. }
  374. },
  375. onFileMessage(message) {
  376. console.log('onFileMessage', message);
  377. if (message) {
  378. if (onMessageError(message)) {
  379. msgStorage.saveReceiveMsg(message, msgType.FILE);
  380. }
  381. calcUnReadSpot(message);
  382. ack(message);
  383. }
  384. },
  385. // 各种异常
  386. onError(error) {
  387. console.log('error', error)
  388. if (error.type == 40) { //send msg fail
  389. disp.fire("em.xmpp.error.sendMsgErr", error.failMsgs);
  390. }
  391. // 16: server-side close the websocket connection
  392. if (error.type == WebIM.statusCode.WEBIM_CONNCTION_DISCONNECTED && !logout) {
  393. if (WebIM.conn.autoReconnectNumTotal >= WebIM.conn.autoReconnectNumMax) {
  394. wx.showToast({
  395. title: "server-side close the websocket connection",
  396. duration: 1000
  397. });
  398. WebIM.conn.close();
  399. wx.redirectTo({
  400. url: "../login/login"
  401. });
  402. logout = true
  403. }
  404. return
  405. }
  406. // 8: offline by multi login
  407. if (error.type == WebIM.statusCode.WEBIM_CONNCTION_SERVER_ERROR) {
  408. wx.showToast({
  409. title: "offline by multi login",
  410. duration: 1000
  411. });
  412. wx.redirectTo({
  413. url: "../login/login"
  414. });
  415. }
  416. if (error.type == WebIM.statusCode.WEBIM_CONNCTION_OPEN_ERROR) {
  417. wx.hideLoading()
  418. disp.fire("em.xmpp.error.passwordErr");
  419. let data = error.data.data
  420. // data && message.error(data)
  421. if (data) {
  422. if (data.error_description == "user not found") {
  423. // ("用户名不存在!")
  424. disp.fire("em.xmpp.error.passwordErr");
  425. } else if (data.error_description == "invalid password") {
  426. // ('密码无效!')
  427. disp.fire("em.xmpp.error.passwordErr");
  428. } else if (data.error_description == "user not activated") {
  429. // ("用户已被封禁!")
  430. disp.fire("em.xmpp.error.activatedErr");
  431. }
  432. }
  433. }
  434. if (error.type == WebIM.statusCode.WEBIM_CONNCTION_AUTH_ERROR) {
  435. wx.hideLoading()
  436. disp.fire("em.xmpp.error.tokenErr");
  437. }
  438. if (error.type == 16) {///sendMsgError
  439. // https://developers.weixin.qq.com/community/develop/doc/00084a400202787b54f8c9e6357800
  440. // 因为上面的原因 这里不要一直提示了
  441. return
  442. console.log('socket_errorsocket_error', error)
  443. wx.showToast({
  444. title: "网络已断开",
  445. icon: 'none',
  446. duration: 2000
  447. });
  448. disp.fire("em.xmpp.error.sendMsgErr", error);
  449. }
  450. },
  451. });
  452. this.checkIsIPhoneX();
  453. },
  454. ToastPannel,
  455. globalData: {
  456. // imgPath: 'http://192.168.0.46/image',
  457. imgPath: 'https://miniapp.cqjudong.com/image',
  458. path: 'https://miniapp.cqjudong.com/base',
  459. // path: 'http://192.168.1.218:8081',
  460. Authorization: '',
  461. userInfo: {},
  462. roleInfo: {},
  463. unReadMessageNum: 0,
  464. // userInfo: null,
  465. saveFriendList: [],
  466. saveGroupInvitedList: [],
  467. isIPX: false, //是否为iphone X
  468. channel: '',
  469. roleList: [{
  470. code: 'ADMIN',
  471. page: '../index-admin/index-admin'
  472. }, {
  473. code: 'OPERATION',
  474. page: '../index/index'
  475. }, {
  476. code: 'GUEST',
  477. page: '../index-guest/index-guest'
  478. }]
  479. },
  480. conn: {
  481. closed: false,
  482. curOpenOpt: {},
  483. open(opt) {
  484. wx.showLoading({
  485. title: '正在初始化客户端...',
  486. mask: true
  487. });
  488. this.curOpenOpt = opt;
  489. WebIM.conn.open(opt);
  490. this.closed = true;
  491. },
  492. reopen() {
  493. if (this.closed) {
  494. //this.open(this.curOpenOpt);
  495. WebIM.conn.open(this.curOpenOpt);
  496. this.closed = false;
  497. }
  498. }
  499. },
  500. onShow() {
  501. // 从搜索页面进的时候退出后再回来会回到首页,此时并没有调用退出,导致登录不上
  502. // 判断当前是登录状态直接跳转到chat页面
  503. const pages = getCurrentPages();
  504. const currentPage = pages[pages.length - 1];
  505. // 选择图片或者拍照也会触发onShow,所以忽略聊天页面
  506. if (WebIM.conn.isOpened() && currentPage.route != "pages/chatroom/chatroom" && currentPage.route != "pages/groupChatRoom/groupChatRoom") {
  507. let myName = wx.getStorageSync("myUsername");
  508. wx.redirectTo({
  509. url: "../chat/chat?myName=" + myName
  510. });
  511. }
  512. wx.hideHomeButton()
  513. },
  514. /**
  515. * 环信登录成功回调
  516. * @param {*} myName
  517. */
  518. onLoginSuccess: function (myName) {
  519. wx.hideLoading()
  520. let roleList = getApp().globalData.roleList;
  521. let roleInfo = getApp().globalData.roleInfo;
  522. for (let i in roleList) {
  523. if (roleList[i].code == roleInfo.code) {
  524. wx.redirectTo({
  525. url: roleList[i].page,
  526. });
  527. break;
  528. }
  529. }
  530. },
  531. getUserInfo(cb) {
  532. var me = this;
  533. if (this.globalData.userInfo) {
  534. typeof cb == "function" && cb(this.globalData.userInfo);
  535. }
  536. else {
  537. // 调用登录接口
  538. wx.login({
  539. success() {
  540. wx.getUserInfo({
  541. success(res) {
  542. me.globalData.userInfo = res.userInfo;
  543. typeof cb == "function" && cb(me.globalData.userInfo);
  544. }
  545. });
  546. }
  547. });
  548. }
  549. },
  550. checkIsIPhoneX: function () {
  551. const me = this
  552. wx.getSystemInfo({
  553. success: function (res) {
  554. // 根据 model 进行判断
  555. if (res.model.search('iPhone X') != -1) {
  556. me.globalData.isIPX = true
  557. }
  558. }
  559. })
  560. },
  561. })