App.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. <script>
  2. let WebIM = (wx.WebIM = require("./utils/WebIM")["default"]);
  3. let msgStorage = require("./components/chat/msgstorage");
  4. let msgType = require("./components/chat/msgtype");
  5. let disp = require("./utils/broadcast");
  6. let logout = false;
  7. function ack(receiveMsg) {
  8. // 处理未读消息回执
  9. var bodyId = receiveMsg.id; // 需要发送已读回执的消息id
  10. var ackMsg = new WebIM.message("read", WebIM.conn.getUniqueId());
  11. ackMsg.set({
  12. id: bodyId,
  13. to: receiveMsg.from,
  14. });
  15. WebIM.conn.send(ackMsg.body);
  16. }
  17. function onMessageError(err) {
  18. if (err.type === "error") {
  19. uni.showToast({
  20. title: err.errorText,
  21. });
  22. return false;
  23. }
  24. return true;
  25. }
  26. function getCurrentRoute() {
  27. let pages = getCurrentPages();
  28. if (pages.length > 0) {
  29. let currentPage = pages[pages.length - 1];
  30. return currentPage.route;
  31. }
  32. return "/";
  33. }
  34. // 包含陌生人版本
  35. function calcUnReadSpot(message) {
  36. let myName = uni.getStorageSync("myUsername");
  37. uni.getStorageInfo({
  38. success: function (res) {
  39. let storageKeys = res.keys;
  40. let newChatMsgKeys = [];
  41. let historyChatMsgKeys = [];
  42. storageKeys.forEach((item) => {
  43. if (item.indexOf(myName) > -1 && item.indexOf("rendered_") == -1) {
  44. newChatMsgKeys.push(item);
  45. }
  46. });
  47. let count = newChatMsgKeys.reduce(function (result, curMember, idx) {
  48. let chatMsgs;
  49. chatMsgs = uni.getStorageSync(curMember) || [];
  50. return result + chatMsgs.length;
  51. }, 0);
  52. getApp().globalData.unReadMessageNum = count;
  53. disp.fire("em.unreadspot", message);
  54. },
  55. });
  56. }
  57. function saveGroups() {
  58. var me = this;
  59. return WebIM.conn.getGroup({
  60. limit: 50,
  61. success: function (res) {
  62. uni.setStorage({
  63. key: "listGroup",
  64. data: res.data,
  65. });
  66. },
  67. error: function (err) {
  68. console.log(err);
  69. },
  70. });
  71. }
  72. import amap from './common/amap-wx.130.js'
  73. var amapPlugin = new amap.AMapWX({
  74. key: 'bb69713f3c3d3c85e2662d313daa47b9'
  75. });
  76. import webIM from './utils/WebIM.js'
  77. var that = ''
  78. export default {
  79. globalData: {
  80. unReadMessageNum: 0,
  81. userInfo: null,
  82. saveFriendList: [],
  83. saveGroupInvitedList: [],
  84. isIPX: false, //是否为iphone X
  85. conn: {
  86. closed: false,
  87. curOpenOpt: {},
  88. open(opt) {
  89. uni.showLoading({
  90. title: "正在初始化客户端..",
  91. mask: true,
  92. });
  93. this.curOpenOpt = opt;
  94. WebIM.conn.open(opt);
  95. this.closed = false;
  96. },
  97. reopen() {
  98. if (this.closed) {
  99. //this.open(this.curOpenOpt);
  100. WebIM.conn.open(this.curOpenOpt);
  101. this.closed = false;
  102. }
  103. },
  104. },
  105. onLoginSuccess: function(myName) {
  106. uni.hideLoading();
  107. uni.redirectTo({
  108. url: "../chat/chat?myName=" + myName,
  109. });
  110. },
  111. getUserInfo(cb) {
  112. var me = this;
  113. if (this.userInfo) {
  114. typeof cb == "function" && cb(this.userInfo);
  115. } else {
  116. // 调用登录接口
  117. uni.login({
  118. success() {
  119. uni.getUserInfo({
  120. success(res) {
  121. me.userInfo = res.userInfo;
  122. typeof cb == "function" && cb(me.userInfo);
  123. },
  124. });
  125. },
  126. });
  127. }
  128. },
  129. checkIsIPhoneX: function() {
  130. const me = this;
  131. uni.getSystemInfo({
  132. success: function(res) {
  133. // 根据 model 进行判断
  134. if (res.model && res.model.search("iPhone X") != -1) {
  135. me.isIPX = true;
  136. }
  137. },
  138. });
  139. },
  140. getLoca: function() {
  141. var city = uni.getStorageSync('city')
  142. return new Promise((resolve, reject) => {
  143. if(!city) {
  144. uni.authorize({
  145. scope: 'scope.userLocation',
  146. success() {
  147. wx.getLocation({
  148. type: 'wgs84',
  149. success(res) {
  150. amapPlugin.getRegeo({
  151. success(data) {
  152. console.log('获取当前所在位置',data[0].regeocodeData.addressComponent);
  153. uni.setStorageSync("location",data[0].regeocodeData.addressComponent)
  154. resolve(data)
  155. },
  156. fail(err) {
  157. console.log('err=',err)
  158. }
  159. })
  160. },
  161. fail(err){
  162. console.log('err=',err)
  163. }
  164. })
  165. },
  166. fail(err) {
  167. closeLoading('error',err)
  168. }
  169. })
  170. }
  171. })
  172. }
  173. },
  174. onLoad() {
  175. that = this
  176. },
  177. onLaunch: function() {
  178. console.log('App Launch')
  179. this.HXlogin()
  180. var me = this;
  181. var logs = uni.getStorageSync("logs") || [];
  182. logs.unshift(Date.now());
  183. uni.setStorageSync("logs", logs); //
  184. disp.on("em.main.ready", function() {
  185. calcUnReadSpot();
  186. });
  187. disp.on("em.chatroom.leave", function() {
  188. calcUnReadSpot();
  189. });
  190. disp.on("em.chat.session.remove", function() {
  191. calcUnReadSpot();
  192. });
  193. disp.on("em.chat.audio.fileLoaded", function() {
  194. calcUnReadSpot();
  195. });
  196. disp.on("em.main.deleteFriend", function() {
  197. calcUnReadSpot();
  198. });
  199. disp.on("em.chat.audio.fileLoaded", function() {
  200. calcUnReadSpot();
  201. }); //
  202. WebIM.conn.listen({
  203. onOpened(message) {
  204. console.log('>>>>>>环信登录成功啦')
  205. },
  206. onReconnect() {
  207. uni.showToast({
  208. title: "重连中...",
  209. duration: 2000,
  210. });
  211. },
  212. onSocketConnected() {
  213. uni.showToast({
  214. title: "socket连接成功",
  215. duration: 2000,
  216. });
  217. },
  218. onClosed() {
  219. uni.showToast({
  220. title: "网络已断开",
  221. icon: "none",
  222. duration: 2000,
  223. });
  224. uni.redirectTo({
  225. url: "/pages/login/codeLogin/codeLogin",
  226. });
  227. me.globalData.conn.closed = true;
  228. WebIM.conn.close();
  229. },
  230. onInviteMessage(message) {
  231. me.globalData.saveGroupInvitedList.push(message);
  232. disp.fire("em.invite.joingroup", message); // uni.showModal({
  233. // title: message.from + " 已邀你入群 " + message.roomid,
  234. // success(){
  235. // disp.fire("em.invite.joingroup", message);
  236. // },
  237. // error(){
  238. // disp.fire("em.invite.joingroup", message);
  239. // }
  240. // });
  241. },
  242. onReadMessage(message) {
  243. //console.log('已读', message)
  244. },
  245. //onPresence为旧版 ,建议参考最新增删好友api文档 :http://docs-im.easemob.com/im/web/basics/buddy
  246. onPresence(message) {
  247. switch (message.type) {
  248. case "unsubscribe":
  249. break;
  250. // 好友邀请列表
  251. case "subscribe":
  252. for (let i = 0; i < me.globalData.saveFriendList.length; i++) {
  253. if (me.globalData.saveFriendList[i].from === message.from) {
  254. me.globalData.saveFriendList[i] = message;
  255. disp.fire("em.subscribe");
  256. return;
  257. }
  258. }
  259. msgStorage.saveReceiveMsg(message, 'INFORM'); //存添加好友消息,方便展示通知
  260. me.globalData.saveFriendList.push(message);
  261. disp.fire("em.subscribe");
  262. break;
  263. case "subscribed":
  264. uni.showToast({
  265. title: "添加成功",
  266. duration: 1000,
  267. });
  268. disp.fire("em.subscribed");
  269. break;
  270. case "unsubscribed":
  271. disp.fire("em.unsubscribed");
  272. break;
  273. case "direct_joined":
  274. saveGroups();
  275. uni.showToast({
  276. title: "已进群",
  277. duration: 1000,
  278. });
  279. break;
  280. case "memberJoinPublicGroupSuccess":
  281. saveGroups();
  282. uni.showToast({
  283. title: "已进群",
  284. duration: 1000,
  285. });
  286. break;
  287. case "invite":
  288. // 防止重复添加
  289. for (let i = 0; i < me.globalData.saveGroupInvitedList.length; i++) {
  290. if (me.globalData.saveGroupInvitedList[i].from === message.from) {
  291. me.globalData.saveGroupInvitedList[i] = message;
  292. disp.fire("em.invite.joingroup")
  293. return;
  294. }
  295. }
  296. me.globalData.saveGroupInvitedList.push(message);
  297. disp.fire("em.invite.joingroup");
  298. msgStorage.saveReceiveMsg(message, 'INFORM'); //存添加好友消息,方便展示通知
  299. break;
  300. case "unavailable":
  301. disp.fire("em.contacts.remove");
  302. disp.fire("em.group.leaveGroup", message);
  303. break;
  304. case "deleteGroupChat":
  305. disp.fire("em.invite.deleteGroup", message);
  306. break;
  307. case "leaveGroup":
  308. disp.fire("em.group.leaveGroup", message);
  309. break;
  310. case "removedFromGroup":
  311. disp.fire("em.group.leaveGroup", message);
  312. break;
  313. default:
  314. break;
  315. }
  316. },
  317. onRoster(message) {
  318. // let pages = getCurrentPages();
  319. // if(pages[0]){
  320. // pages[0].onShow();
  321. // }
  322. },
  323. onVideoMessage(message) {
  324. console.log("onVideoMessage: ", message);
  325. if (message) {
  326. msgStorage.saveReceiveMsg(message, msgType.VIDEO);
  327. }
  328. calcUnReadSpot(message);
  329. ack(message);
  330. },
  331. onAudioMessage(message) {
  332. console.log("onAudioMessage", message);
  333. if (message) {
  334. if (onMessageError(message)) {
  335. msgStorage.saveReceiveMsg(message, msgType.AUDIO);
  336. }
  337. calcUnReadSpot(message);
  338. ack(message);
  339. }
  340. },
  341. onCmdMessage(message) {
  342. console.log("onCmdMessage", message);
  343. if (message) {
  344. if (onMessageError(message)) {
  345. msgStorage.saveReceiveMsg(message, msgType.CMD);
  346. }
  347. calcUnReadSpot(message);
  348. ack(message);
  349. }
  350. },
  351. // onLocationMessage(message){
  352. // console.log("Location message: ", message);
  353. // if(message){
  354. // msgStorage.saveReceiveMsg(message, msgType.LOCATION);
  355. // }
  356. // },
  357. onTextMessage(message) {
  358. console.log("onTextMessage", message);
  359. if (message) {
  360. if (onMessageError(message)) {
  361. msgStorage.saveReceiveMsg(message, msgType.TEXT);
  362. }
  363. calcUnReadSpot(message);
  364. ack(message);
  365. }
  366. },
  367. onEmojiMessage(message) {
  368. console.log("onEmojiMessage", message);
  369. if (message) {
  370. if (onMessageError(message)) {
  371. msgStorage.saveReceiveMsg(message, msgType.EMOJI);
  372. }
  373. calcUnReadSpot(message);
  374. ack(message);
  375. }
  376. },
  377. onPictureMessage(message) {
  378. console.log("onPictureMessage", message);
  379. if (message) {
  380. if (onMessageError(message)) {
  381. msgStorage.saveReceiveMsg(message, msgType.IMAGE);
  382. }
  383. calcUnReadSpot(message);
  384. ack(message);
  385. }
  386. },
  387. onFileMessage(message) {
  388. console.log("onFileMessage", message);
  389. if (message) {
  390. if (onMessageError(message)) {
  391. msgStorage.saveReceiveMsg(message, msgType.FILE);
  392. }
  393. calcUnReadSpot(message);
  394. ack(message);
  395. }
  396. },
  397. // 各种异常
  398. onError(error) {
  399. console.log(error); // 16: server-side close the websocket connection
  400. // if (error.type == WebIM.statusCode.WEBIM_CONNCTION_DISCONNECTED) {
  401. // // if(error.type == WebIM.statusCode.WEBIM_CONNCTION_DISCONNECTED && !logout){
  402. // // if(WebIM.conn.autoReconnectNumTotal < WebIM.conn.autoReconnectNumMax){
  403. // // return;
  404. // // }
  405. // uni.showToast({
  406. // title: "websocket 断开",
  407. // duration: 1000
  408. // });
  409. // uni.redirectTo({
  410. // url: "../login/login"
  411. // });
  412. // logout = true;
  413. // return;
  414. // } // 8: offline by multi login
  415. // if (error.type == WebIM.statusCode.WEBIM_CONNCTION_SERVER_ERROR) {
  416. // uni.showToast({
  417. // title: "offline by multi login",
  418. // duration: 1000
  419. // });
  420. // uni.redirectTo({
  421. // url: "../login/login"
  422. // });
  423. // }
  424. if (error.type == WebIM.statusCode.WEBIM_CONNCTION_OPEN_ERROR) {
  425. uni.hideLoading();
  426. disp.fire("em.error.passwordErr"); // uni.showModal({
  427. // title: "用户名或密码错误",
  428. // confirmText: "OK",
  429. // showCancel: false
  430. // });
  431. }
  432. if (error.type == WebIM.statusCode.WEBIM_CONNCTION_AUTH_ERROR) {
  433. uni.hideLoading();
  434. disp.fire("em.error.tokenErr");
  435. }
  436. if (error.type == "socket_error") {
  437. ///sendMsgError
  438. console.log("socket_errorsocket_error", error);
  439. uni.showToast({
  440. title: "网络已断开",
  441. icon: "none",
  442. duration: 2000,
  443. });
  444. disp.fire("em.error.sendMsgErr", error);
  445. }
  446. },
  447. });
  448. this.globalData.checkIsIPhoneX();
  449. },
  450. onShow: function() {
  451. console.log('App Show')
  452. },
  453. onHide: function() {
  454. console.log('App Hide')
  455. },
  456. methods: {
  457. /* HXlisten(){
  458. console.log('<<<<<<环信监听',uni.WebIM)
  459. uni.WebIM.conn.listen({
  460. onOpened: function () {
  461. console.log('>>>>>>环信登录成功啦')
  462. }, //连接成功回调
  463. onClosed: function () {
  464. console.log("<<<<<连接关闭");
  465. }, //连接关闭回调
  466. onTextMessage: function ( message ) {
  467. console.log("收到文本消息",message);
  468. }, //收到文本消息
  469. onEmojiMessage: function ( message ) {
  470. console.log("收到表情消息",message);
  471. }, //收到表情消息
  472. onPictureMessage: function ( message ) {
  473. console.log("收到图片消息",message);
  474. }, //收到图片消息
  475. onCmdMessage: function ( message ) {
  476. console.log("收到命令消息",message);
  477. }, //收到命令消息
  478. onAudioMessage: function ( message ) {
  479. console.log("收到音频消息",message);
  480. }, //收到音频消息
  481. onLocationMessage: function ( message ) {
  482. console.log("收到位置消息",message);
  483. },//收到位置消息
  484. onFileMessage: function ( message ) {
  485. console.log("收到文件消息",message);
  486. }, //收到文件消息
  487. onCustomMessage: function ( message ) {
  488. console.log("收到自定义消息",message);
  489. }, //收到自定义消息
  490. onVideoMessage: function (message) {
  491. var node = document.getElementById('privateVideo');
  492. var option = {
  493. url: message.url,
  494. headers: {
  495. 'Accept': 'audio/mp4'
  496. },
  497. onFileDownloadComplete: function (response) {
  498. var objectURL = uni.WebIM.utils.parseDownloadResponse.call(conn, response);
  499. node.src = objectURL;
  500. },
  501. onFileDownloadError: function () {
  502. console.log('File down load error.')
  503. }
  504. };
  505. uni.WebIM.utils.download.call(conn, option);
  506. }, //收到视频消息
  507. onPresence: function ( message ) {
  508. console.log('处理“广播”或“发布-订阅”消息',message);
  509. }, //处理“广播”或“发布-订阅”消息,如联系人订阅请求、处理群组、聊天室被踢解散等消息
  510. onRoster: function ( message ) {
  511. console.log('处理好友申请',message);
  512. }, //处理好友申请
  513. onInviteMessage: function ( message ) {
  514. console.log('处理群组邀请',message);
  515. }, //处理群组邀请
  516. onOnline: function () {
  517. console.log('本机网络连接成功');
  518. }, //本机网络连接成功
  519. onOffline: function () {
  520. console.log("本机网络掉线",message);
  521. }, //本机网络掉线
  522. onError: function ( message ) {
  523. console.log("失败回调:",message);
  524. }, //失败回调
  525. onBlacklistUpdate: function (list) { //黑名单变动
  526. // 查询黑名单,将好友拉黑,将好友从黑名单移除都会回调这个函数,list则是黑名单现有的所有好友信息
  527. console.log(list);
  528. },
  529. onRecallMessage: function(message){
  530. console.log("收到撤回消息回调",message);
  531. }, //收到撤回消息回调
  532. onReceivedMessage: function(message){
  533. console.log("收到消息送达服务器回执",message);
  534. }, //收到消息送达服务器回执
  535. onDeliveredMessage: function(message){
  536. console.log("收到消息送达客户端回执",message);
  537. }, //收到消息送达客户端回执
  538. onReadMessage: function(message){
  539. console.log("收到消息已读回执",message);
  540. }, //收到消息已读回执
  541. onCreateGroup: function(message){
  542. console.log("创建群组成功回执",message);
  543. }, //创建群组成功回执(需调用createGroupNew)
  544. onMutedMessage: function(message){
  545. console.log("禁言",message);
  546. }, //如果用户在A群组被禁言,在A群发消息会走这个回调并且消息不会传递给群其它成员
  547. onChannelMessage: function(message){
  548. console.log("收到整个会话已读的回执",message);
  549. } //收到整个会话已读的回执,在对方发送channel ack时会在这个回调里收到消息
  550. });
  551. }, */
  552. HXlogin() {
  553. var userId = uni.getStorageSync('myUsername')
  554. var options = {
  555. user: userId,
  556. pwd : '12345678',
  557. appKey: uni.WebIM.config.appkey,
  558. success: function() {
  559. var lianjie = uni.WebIM.conn.isOpened()
  560. var my = uni.getStorageSync("myUsername");
  561. uni.setStorageSync('myUsername',my)
  562. },
  563. error: function() {
  564. }
  565. }
  566. uni.WebIM.conn.open(options);
  567. }
  568. }
  569. }
  570. </script>
  571. <style lang="scss">
  572. /*每个页面公共css */
  573. @import "uview-ui/index.scss";
  574. .content {
  575. background-color: #ffffff;
  576. width: 100%;
  577. min-height: 100vh;
  578. display: flex;
  579. flex-direction: column;
  580. font-size: 28rpx;
  581. color: #333;
  582. box-sizing: border-box;
  583. }
  584. .hflex {
  585. display: flex;
  586. flex-direction: row;
  587. flex-wrap: nowrap;
  588. }
  589. .vflex {
  590. display: flex;
  591. flex-direction: column;
  592. flex-wrap: nowrap;
  593. }
  594. .jbetween {
  595. justify-content: space-between;
  596. }
  597. .jaround {
  598. justify-content: space-around;
  599. }
  600. .jend {
  601. justify-content: flex-end;
  602. }
  603. .jcenter {
  604. justify-content: center;
  605. }
  606. .acenter {
  607. align-items: center;
  608. }
  609. .abetween {
  610. align-content: space-between;
  611. }
  612. .astart {
  613. align-items: flex-start;
  614. }
  615. .aend {
  616. align-items: flex-end;
  617. }
  618. .fwrap {
  619. flex-wrap: wrap;
  620. }
  621. .text_hide {
  622. overflow: hidden;
  623. white-space: nowrap;
  624. text-overflow: ellipsis;
  625. }
  626. </style>