chat-panel.vue 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500
  1. <template>
  2. <view @tap="ontap">
  3. <scroll-view class="chat-detail" :style="{'height':chatheight+'px'}" id="chat" scroll-y="true"
  4. :scroll-into-view="scrollToView" @scroll="chatscroll">
  5. <!-- <view class="chat-detail" id="chat" auto-height="true" > -->
  6. <!-- 加载历史数据waitingUI -->
  7. <view class="nodata" v-if="showmore && system.chattime<3650"> 仅能查看最近{{system.chattime}}日的聊天记录</view>
  8. <view class="loading" v-if="showLoading">
  9. <view class="spinner">
  10. <view class="rect1"></view>
  11. <view class="rect2"></view>
  12. <view class="rect3"></view>
  13. <view class="rect4"></view>
  14. <view class="rect5"></view>
  15. </view>
  16. </view>
  17. <view v-for="(m,index) in messagelist_old" :key="'itemold_'+m.msg_id" :id="'item_'+m.msg_id"
  18. v-if="m.isloading!=3">
  19. <messageitem :item="m" :loading_id="loading_id" :userid="userid" :playVoiceId="playVoiceId"
  20. @redpack_open="redpack_open" @atusuer='atusuer' @clickAvatar='clickAvatar' @msgAction='msgAction'
  21. @play_vedio='play_vedio' @playVoice="playVoice"></messageitem>
  22. </view>
  23. <view v-for="(m,index) in messagelist" :key="'itemnew_'+m.msg_id" :id="'item_'+m.msg_id"
  24. v-if="m.isloading!=3">
  25. <view class="nodata" v-if="unreadid==m.msg_id">以下是未读消息</view>
  26. <messageitem :item="m" :ref="'messageitem_'+index" :loading_id="loading_id" :unreadid="unreadid"
  27. :userid="userid" :playVoiceId="playVoiceId" @redpack_open="redpack_open" @atusuer='atusuer'
  28. @clickAvatar='clickAvatar' @msgAction='msgAction' @play_vedio='play_vedio' @playVoice="playVoice">
  29. </messageitem>
  30. </view>
  31. <view v-if="sending">
  32. <messageitem id="self_send" :item="sendingdata" :userid="userid" :loading_id="loading_id"
  33. @clickAvatar='clickAvatar' @redpack_open="redpack_open" @msgAction='msgAction'
  34. @play_vedio='play_vedio' @playVoice="playVoice"></messageitem>
  35. </view>
  36. <view id="self_bottom1" class="self_bottom">
  37. </view>
  38. <view id="self_bottom2" class="self_bottom">
  39. </view>
  40. </scroll-view>
  41. <view class="unread" @tap="scrollto_unread" v-if="unreadnum>0">有<view class="num">{{unreadnum}}</view>条未读消息
  42. </view>
  43. <view :class="touch_class" :style="touch_style" v-if="touch_menu">
  44. <block v-for="(m1,index1) in touch_menulist" :key="'menu_'+index1">
  45. <view @tap="tap_menu(m1.type)">{{m1.text}}</view>
  46. </block>
  47. </view>
  48. <view class="vedioplay" v-if="videoshow" :style="{'display':videoshow?'inline-block':'none'}">
  49. <video id="video_play" :src="videosrc" loop="false" autoplay="true" @play="playVedio()" @ended="endVedio()"
  50. @pause="pauseVedio()" :poster="poster"></video>
  51. <view class="bottom">
  52. <uni-icons type='closeempty' class="icon1" @tap="endVedio()"></uni-icons>
  53. </view>
  54. </view>
  55. <redpick v-if="is_redpack_open" :item="redpack_info" @closePick="is_redpack_open=false;"
  56. @fresmsg="freshmsg_fromredopen"></redpick>
  57. <logoutwords v-if="showlogout" :item="logoutinfo" @sub="logout_sub" @cancle="showlogout=false;"></logoutwords>
  58. </view>
  59. </template>
  60. <script>
  61. import {
  62. mapState,
  63. mapGetters
  64. } from 'vuex';
  65. import action from '../library/action.js'
  66. import messageitem from './messageitem.vue'
  67. import http from "../library/http.js"
  68. import chat from "../library/chat.js"
  69. import uniIcons from './uni-icons/uni-icons.vue'
  70. import redpick from './get-redpick.vue'
  71. import Vue from 'vue';
  72. import logoutwords from './logout_words.vue'
  73. const innerAudioContext = uni.createInnerAudioContext();
  74. let loadStatus = false;
  75. let lastMid = '';
  76. var windowHeight = uni.getSystemInfoSync().windowHeight;
  77. var windowWidth = uni.getSystemInfoSync().windowWidth;
  78. var statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
  79. var chatheight = windowHeight - 60;
  80. var chattop = 0;
  81. // #ifndef APP-PLUS
  82. var chattop = statusBarHeight + 45;
  83. var windowWidth = uni.getSystemInfoSync().screenHeight;
  84. var chatheight = uni.getSystemInfoSync().windowHeight - chattop - 60;
  85. // #endif
  86. function timestampToTime(timestamp) {
  87. var date = new Date(timestamp * 1000); //时间戳为10位需*1000,时间戳为13位的话不需乘1000
  88. var Y = date.getFullYear();
  89. var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1);
  90. var D = date.getDate();
  91. var h = date.getHours();
  92. var m = date.getMinutes();
  93. var s = date.getSeconds();
  94. if (D < 10) D = '0' + D;
  95. if (h < 10) h = '0' + h;
  96. if (m < 10) m = '0' + m;
  97. if (s < 10) s = '0' + s;
  98. return Y + '-' + M + '-' + D + ' ' + h + ':' + m + ':' + s;
  99. }
  100. export default {
  101. components: {
  102. uniIcons,
  103. messageitem,
  104. redpick,
  105. logoutwords
  106. },
  107. props: {
  108. storeKey: {
  109. require: true
  110. },
  111. boardheight: {
  112. type: Number,
  113. default: 0
  114. },
  115. manager: {
  116. type: [Number, String, Object, Boolean],
  117. default: 0
  118. },
  119. thistype: {
  120. default: '',
  121. },
  122. sending: {
  123. type: Boolean,
  124. default: false
  125. },
  126. sendingdata: {
  127. default: {}
  128. },
  129. no_add: {
  130. type: Boolean,
  131. default: false
  132. },
  133. atme: {
  134. default: 0
  135. },
  136. at_msg_id: {
  137. default: 0
  138. }
  139. },
  140. data() {
  141. return {
  142. chatheight: chatheight,
  143. chattop: chattop,
  144. panelheight: chatheight,
  145. paddingtop: 0,
  146. scrollToView: 'self_bottom2',
  147. scrollAnimation: true,
  148. showLoading: false,
  149. playVoiceId: '',
  150. isizes: {},
  151. pageHeight: 0,
  152. contentViewHeight: 0,
  153. footViewHeight: 90,
  154. mitemHeight: 0,
  155. scrollTop: 0,
  156. letterDetails: [],
  157. senderheight: 0,
  158. hide_list: '',
  159. loading_id: 0,
  160. playVedioId: '',
  161. videoshow: false,
  162. videosrc: "",
  163. video_playing: false,
  164. video_end: false,
  165. poster: null,
  166. isbottom: false,
  167. pagemaxtop: 0,
  168. isscroll: false,
  169. pagetop: 0,
  170. storeId: 0,
  171. isgroup: 1,
  172. page: 0,
  173. pagenum: 0,
  174. userid: parseInt(uni.getStorageSync('access_token')),
  175. isfrist: 0,
  176. oldheight: 0,
  177. lastmessage: [],
  178. oldlength: 0,
  179. showmore: false,
  180. touch_menu: false,
  181. touch_style: "",
  182. touch_class: 'touch_menu',
  183. touch_menulist: [],
  184. touch_time: 0,
  185. touch_timer: null,
  186. message: [],
  187. touch_item: null,
  188. isfristload: true,
  189. maxheight: 0,
  190. msg_id1: 0,
  191. messagelist: uni.getStorageSync(uni.getStorageSync('access_token') + "_chat_" + this.storeKey),
  192. messagelist_old: [],
  193. isupdate: false,
  194. lastscroll: 0,
  195. scrollpos: 'down',
  196. unreadid: 0,
  197. unreadnum: 0,
  198. redpack_info: {},
  199. is_redpack_open: false,
  200. showlogout: false,
  201. logoutinfo: {},
  202. keyboardheight: 0,
  203. system: uni.getStorageSync('system')
  204. };
  205. },
  206. mounted() {
  207. uni.setStorageSync('storeykey', 'chat');
  208. if (this.atme == 1 && this.at_msg_id > 0) {
  209. this.scrolltoAtme();
  210. } else {
  211. this.isfristload = false;
  212. }
  213. this.scrollToBottom(0);
  214. this.storeId = this.storeKey.substr(1, this.storeKey.length - 1);
  215. if (this.storeKey.indexOf('G') > -1) {
  216. this.isgroup = 1;
  217. //群组消息
  218. this.group_read(this.storeId);
  219. } else {
  220. this.isgroup = 0;
  221. this.user_read(this.storeId);
  222. //私人消息
  223. }
  224. // console.log(this.messagelist.length)
  225. // if(this.messagelist.length>30){
  226. // for(var i=0;i<this.messagelist.length-30;i++){
  227. // this.messagelist.splice(i,1);
  228. // }
  229. // uni.setStorageSync(uni.getStorageSync('access_token')+"_chat_"+this.storeKey,this.messagelist);
  230. // }
  231. var that = this;
  232. that.messageslist(0);
  233. var that = this;
  234. this.$socket.on('chat', (res) => {
  235. this.sendmsg(res);
  236. console.log('zhe',res)
  237. })
  238. // #ifdef APP-PLUS
  239. var that = this;
  240. setTimeout(function() {
  241. var wh = uni.getSystemInfoSync().screenHeight;
  242. var ch = wh - statusBarHeight - 105;
  243. if (ch < that.chatheight) that.chatheight = ch;
  244. else {
  245. var wh = uni.getSystemInfoSync().windowHeight;
  246. var ch = wh - 60;
  247. that.chatheight = ch;
  248. }
  249. }, 1000)
  250. uni.onKeyboardHeightChange(res => {
  251. if (res.height > 0) {
  252. that.scrollToBottom();
  253. }
  254. this.chatheight = this.panelheight - res.height;
  255. this.$forceUpdate();
  256. this.keyboardheight = res.height;
  257. // console.log(this.chatheight);
  258. // console.log(this.panelheight,this.maxheight)
  259. // if(this.panelheight<=this.maxheight && this.messagelist.length<=6){
  260. // // that.paddingtop=res.height;
  261. // // that.$forceUpdate();
  262. // }
  263. })
  264. // #endif
  265. // console.log(message)
  266. },
  267. destroyed() {
  268. this.$socket.off('chat');
  269. uni.setStorageSync('storeykey', "index");
  270. if (this.isgroup == 1) {
  271. this.group_read(this.storeId);
  272. } else {
  273. this.user_read(this.storeId);
  274. }
  275. },
  276. computed: {},
  277. methods: {
  278. redpack_open(m) {
  279. this.redpack_info = m;
  280. this.is_redpack_open = true;
  281. },
  282. scrolltoAtme() {
  283. if (this.atme == 1 && this.at_msg_id > 0 && this.isfristload == true) {
  284. this.scrollToView = 'item_' + this.at_msg_id;
  285. this.isfristload = false;
  286. }
  287. },
  288. sendmsg(res) {
  289. var res = chat.push(res, 'chat');
  290. if (res != false) {
  291. // console.log(res.msglist.length)
  292. this.$store.commit('chat/update_msglist', res.msglist);
  293. }
  294. this.freshmsg()
  295. },
  296. freshmsg() {
  297. this.messagelist = uni.getStorageSync(this.userid + "_chat_" + this.storeKey);
  298. },
  299. freshmsg_fromredopen(e) {
  300. //this.messagelist='';
  301. this.freshmsg();
  302. // var index=this.messagelist.findIndex(v => v.msg_id == e.msg_id);
  303. // console.log(index)
  304. // this.$set(this.messagelist,index,e)
  305. },
  306. isindexhtml(str) {
  307. var arr = ['<br', '&nbsp;', "<div", "<span"];
  308. str = str.toString();
  309. for (var i = 0; i < arr.length; i++) {
  310. //console.log(str,arr[i])
  311. if (str.indexOf(arr[i]) > -1) return true;
  312. }
  313. return false;
  314. },
  315. getautoheight() {
  316. // console.log(this.oldheight);
  317. this.showLoading = false;
  318. var that = this;
  319. setTimeout(function() {
  320. if (this.pagenum > 0)
  321. that.scrollToView = 'item_'.that.msg_id1;
  322. }, 200)
  323. },
  324. message_format(data) {
  325. var messagedata = [];
  326. if (data.length > 0) {
  327. for (var i = 0; i < data.length; i++) {
  328. var item = data[i];
  329. try {
  330. if (item.type == 'time') {
  331. var temp = {
  332. type: 'tips',
  333. message: {
  334. content: item.content,
  335. type: 'tips'
  336. },
  337. 'msg_id': item.id,
  338. isloading: 0
  339. };
  340. temp['sender_id'] = item.userid;
  341. temp['sender'] = item.sender;
  342. temp['timestamp'] = item.addtime;
  343. messagedata.push(temp);
  344. } else if (item.addtime != undefined && item.addtime > 0) {
  345. var temp = {};
  346. temp['_mid'] = 'm' + Math.random().toString(36).substring(2);
  347. temp['cache_key'] = this.storeKey;
  348. temp['group_id'] = item.groupid;
  349. if (this.isgroup == 1) temp['id'] = item.groupid;
  350. else temp['id'] = item.userid;
  351. temp['isloading'] = 0;
  352. temp['msg_id'] = item.id;
  353. temp['self'] = item.self;
  354. temp['sender_id'] = item.userid;
  355. temp['sender'] = item.sender;
  356. temp['timestamp'] = item.addtime;
  357. temp['unread'] = 0;
  358. temp['type'] = item.type;
  359. temp['message'] = {
  360. 'type': item.type,
  361. 'content': item.content1
  362. };
  363. messagedata.push(temp);
  364. }
  365. } catch (e) {
  366. //TODO handle the exception
  367. /// console.log(e)
  368. }
  369. }
  370. }
  371. return messagedata;
  372. },
  373. //获取云端消息记录
  374. messageslist(totime) {
  375. var lists = [];
  376. var time1 = (new Date()).getTime() / 1000 - 7 * 24 * 3600;
  377. if (totime < 1) {
  378. var isfrist = true;
  379. totime = parseInt((new Date()).getTime() / 1000);
  380. } else {
  381. var isfrist = false;
  382. if (this.showLoading == true) return false;
  383. }
  384. var storekey = this.storeKey
  385. var postdata = {
  386. id: parseInt(this.storeId),
  387. userid: parseInt(this.userid),
  388. isgroup: this.isgroup,
  389. totime: totime
  390. };
  391. var that = this;
  392. http.setWait(false).get('group.php?act=messages2', postdata).then(res => {
  393. if (res.code == 200) {
  394. // console.log(res);
  395. var data = res.data;
  396. var messagedata = this.message_format(data);
  397. if (isfrist == true) {
  398. if (messagedata.length < 1) {
  399. this.messagelist = [];
  400. this.showmore = true;
  401. }
  402. uni.setStorageSync(this.userid + "_chat_" + this.storeKey, messagedata);
  403. this.freshmsg();
  404. var that = this;
  405. setTimeout(function() {
  406. if (that.atme == 1 && that.at_msg_id > 0) {
  407. that.scrolltoAtme();
  408. } else
  409. that.scrollToBottom();
  410. that.isupdate = true;
  411. }, 300)
  412. } else {
  413. this.showLoading = false;
  414. if (messagedata.length > 0) {
  415. if (this.messagelist_old.length > 0) {
  416. var scrollToView = 'item_' + this.messagelist_old[0].msg_id;
  417. this.messagelist_old.unshift(...messagedata)
  418. } else {
  419. var scrollToView = 'item_' + this.messagelist[0].msg_id;
  420. this.messagelist_old = messagedata;
  421. }
  422. this.showmore = false;
  423. var that = this;
  424. setTimeout(function() {
  425. that.scrollToView = scrollToView
  426. }, 200)
  427. } else {
  428. this.showmore = true;
  429. }
  430. }
  431. }
  432. })
  433. },
  434. update_message(data) {
  435. var isin = 0;
  436. for (var i = this.messagelist.length - 1; i >= 0; i--) {
  437. var item = this.messagelist[i];
  438. if (parseInt(item.msg_id) == parseInt(data.msg.msg_id)) {
  439. return false;
  440. }
  441. }
  442. var messageold = uni.getStorageSync(this.userid + "_chatold_" + this.storeKey);
  443. for (var i = messageold.length - 1; i >= 0; i--) {
  444. var item = messageold[i];
  445. if (parseInt(item.msg_id) == parseInt(data.msg.msg_id)) {
  446. return false;
  447. }
  448. }
  449. var message = messageold.concat(this.messagelist);
  450. },
  451. //设置群未读消息
  452. group_read(group_id) {
  453. this.$store.commit('chat/clearunread', this.storeKey);
  454. },
  455. user_read(userid) {
  456. this.$store.commit('chat/clearunread', this.storeKey);
  457. },
  458. scrollto_unread() {
  459. this.scrollToView = "item_" + this.unreadid;
  460. this.unreadid = 0;
  461. this.unreadnum = 0;
  462. },
  463. chatscroll(e) {
  464. // if(this.keyboardheight>0) uni.hideKeyboard();
  465. this.touch_menu = false;
  466. var top = e.detail.scrollTop;
  467. this.maxheight = e.detail.scrollHeight;
  468. if (top > this.maxheight) this.maxheight = top;
  469. if (top + this.panelheight >= this.maxheight - 100 && top > 0) {
  470. this.isbottom = true;
  471. this.unreadid = 0;
  472. this.unreadnum = 0;
  473. } else this.isbottom = false;
  474. if (top > this.lastscroll) this.scrollpos = 'down';
  475. else this.scrollpos = 'up';
  476. // console.log(this.scrollpos,this.isbottom);
  477. this.lastscroll = top;
  478. if (top < 50 && this.isfristload == false && this.isupdate == true) {
  479. if (this.messagelist_old.length > 0) {
  480. var msg = this.messagelist_old[0];
  481. } else {
  482. var msg = this.messagelist[0];
  483. }
  484. if (msg.timestamp == undefined) var totime = msg.msg_id;
  485. else var totime = msg.timestamp;
  486. if (totime > 0) totime = totime - 1;
  487. this.messageslist(parseInt(totime));
  488. this.showLoading = true;
  489. }
  490. },
  491. setAutoHeight(e) {
  492. //console.log(e);
  493. this.touch_menu = false;
  494. },
  495. vedio_show(m) {
  496. if (m.isloading == 1) {
  497. return m.message.content.src;
  498. } else
  499. return this.image_cache(m.message.content.src)
  500. },
  501. poster_show(m) {
  502. if (m.isloading == 1) {
  503. return false;
  504. } else {
  505. var src = m.message.content.src;
  506. try {
  507. var arr = src.split('/');
  508. var filename = arr[arr.length - 1];
  509. var arr1 = filename.split('.');
  510. var newname = arr1[0] + "_video.jpg";
  511. var poster = src.replace(filename, newname);
  512. return poster;
  513. } catch (e) {
  514. //TODO handle the exception
  515. return "/static/img/vediobanner.jpg";
  516. }
  517. }
  518. },
  519. scrollToBottom: function() {
  520. var that = this;
  521. setTimeout(function() {
  522. if (that.scrollToView == "self_bottom1")
  523. that.scrollToView = "self_bottom2";
  524. else {
  525. that.scrollToView = "self_bottom1";
  526. }
  527. that.pagenum = 0;
  528. that.isbottom = true;
  529. that.unreadnum = 0;
  530. that.unreadid = 0;
  531. }, 200)
  532. },
  533. play_vedio(m) {
  534. this.videoshow = true;
  535. this.videosrc = this.vedio_show(m);
  536. this.poster = this.poster_show(m);
  537. this.video_playing = false;
  538. var that = this;
  539. setTimeout(function() {
  540. var videoContext = uni.createVideoContext('video_play');
  541. if (that.video_playing == false) {
  542. // videoContext.requestFullScreen(0);
  543. // setTimeout(function(){videoContext.play()},100);
  544. that.playVedioId = m._mid;
  545. videoContext.play();
  546. }
  547. }, 500)
  548. },
  549. //结束播放
  550. endVedio() {
  551. this.video_end = true;
  552. var videoContext = uni.createVideoContext('video_play');
  553. // videoContext.exitFullScreen();
  554. videoContext.pause();
  555. this.playVedioId = "";
  556. this.videosrc = "";
  557. this.pauseVedio();
  558. var that = this;
  559. that.video_end = false;
  560. },
  561. playVedio() {
  562. this.video_playing = true;
  563. this.video_end = false;
  564. this.videoshow = true;
  565. },
  566. pauseVedio() {
  567. this.video_playing = false;
  568. this.videoshow = false;
  569. },
  570. screenchange() {
  571. if (this.video_playing == true) {
  572. var videoContext = uni.createVideoContext('video_play');
  573. videoContext.exitFullScreen();
  574. videoContext.pause();
  575. this.playVedioId = "";
  576. this.videosrc = "";
  577. this.pauseVedio();
  578. } else {
  579. if (this.video_end == false) {
  580. var videoContext = uni.createVideoContext('video_play');
  581. videoContext.play();
  582. }
  583. }
  584. },
  585. playVoice(message) {
  586. var that = this;
  587. var id = message._mid;
  588. if (this.playVoiceId == id) {
  589. innerAudioContext.stop();
  590. innerAudioContext.src = '';
  591. that.playVoiceId = "";
  592. that.loading_id = 0;
  593. return false;
  594. }
  595. if (this.playVoiceId !== '') {
  596. innerAudioContext.stop();
  597. innerAudioContext.src = '';
  598. that.playVoiceId = "";
  599. that.loading_id = 0;
  600. }
  601. // if (this.playVoiceId == '') {
  602. this.loading_id = id;
  603. innerAudioContext.src = this.image_cache(message.message.content.url);
  604. innerAudioContext.volume = 1;
  605. innerAudioContext.autoplay = true;
  606. innerAudioContext.onCanplay(function() {
  607. innerAudioContext.play();
  608. that.playVoiceId = id;
  609. that.loading_id = 0;
  610. })
  611. innerAudioContext.onEnded(() => {
  612. innerAudioContext.stop();
  613. innerAudioContext.src = '';
  614. that.playVoiceId = "";
  615. that.loading_id = 0;
  616. });
  617. },
  618. atusuer(msg) {
  619. if (msg.sender.id != this.userid) {
  620. let result = {
  621. id: msg.id,
  622. nickname: msg.sender.nickname
  623. }
  624. this.$emit('close', result);
  625. }
  626. // console.log(msg) ;
  627. },
  628. clickAvatar(msg) {
  629. if (msg.id > 0) {
  630. var params = {
  631. id: msg.sender.id,
  632. 'group_id': msg.group_id,
  633. thistype: this.thistype
  634. };
  635. // console.log(JSON.stringify(msg));
  636. return this.$jump('friend.detail', params)
  637. //this.$emit('click-avatar', this.messages[index]);
  638. } else {
  639. return false;
  640. }
  641. },
  642. toText(msg) {
  643. var text = msg.replace(/&nbsp;/g, ' ');
  644. text = text.replace(/<br>/g, '\n');
  645. text = text.replace(/<\/?[^>]*>/g, '');
  646. return text;
  647. },
  648. copyText(msg) {
  649. var message = msg.message;
  650. if (message.content.type == 'remind')
  651. var content = message.content.content;
  652. else if (message.type == 'url')
  653. var content = message.content.content;
  654. else var content = message.content
  655. content = this.toText(content);
  656. uni.setClipboardData({
  657. data: content,
  658. success: function() {
  659. uni.showToast({
  660. title: '复制成功',
  661. icon: 'none'
  662. })
  663. }
  664. });
  665. },
  666. ontap() {
  667. if (new Date().getTime() - this.touch_time > 1500) this.touch_menu = false;;
  668. },
  669. delete_msg(msg) {
  670. var list = this.messagelist;
  671. var isin = 0;
  672. var list11 = [];
  673. list.forEach(item => {
  674. if (parseInt(item.msg_id) == parseInt(msg.msg_id)) {
  675. // item.isloading=3;
  676. isin = 1;
  677. } else {
  678. list11.push(item);
  679. }
  680. })
  681. var that = this;
  682. if (isin == 1) {
  683. that.messagelist = list11;
  684. uni.setStorageSync(this.userid + "_chat_" + this.storeKey, list11);
  685. } else {
  686. var list = this.messagelist_old;
  687. var list11 = [];
  688. list.forEach(item => {
  689. if (parseInt(item.msg_id) == parseInt(msg.msg_id)) {
  690. } else {
  691. list11.push(item);
  692. }
  693. })
  694. that.messagelist_old = list11;
  695. }
  696. var postdata = {
  697. id: msg.msg_id,
  698. userid: this.userid
  699. };
  700. http.setWait(false).get('group.php?act=clearchatlist', postdata).then(res => {
  701. })
  702. // this.freshmsg();
  703. },
  704. logout_sub(e) {
  705. uni.showToast({
  706. icon: 'none',
  707. title: '操作成功'
  708. })
  709. },
  710. tap_menu(type) {
  711. var msg = this.touch_item;
  712. uni.showToast({
  713. title: new Date().getTime() - this.touch_time
  714. })
  715. if (new Date().getTime() - this.touch_time > 1000) {
  716. this.touch_menu = false;
  717. var that = this;
  718. if(type == 'quote') {
  719. console.log('this.touch_item:',this.touch_item);
  720. this.$emit('chooseQuote',this.touch_item)
  721. }
  722. if (type == "delete") {
  723. // this.clearchatlist(msg);
  724. this.delete_msg(msg)
  725. }
  726. if (type == 'copy') {
  727. that.copyText(msg);
  728. }
  729. if (type == 'back') {
  730. let data = {
  731. userid: that.userid,
  732. msg_id: msg.msg_id,
  733. type: 'chat_back',
  734. store: that.storeKey
  735. }
  736. that.$socket.send(data);
  737. }
  738. if (type == 'at') {
  739. that.atusuer(msg);
  740. }
  741. if (type == 'view') {
  742. that.clickAvatar(msg);
  743. }
  744. if (type == 'manage0') {
  745. var data = {
  746. type: 'groupset1',
  747. mode: 'manage',
  748. settype: 0,
  749. group_id: msg.group_id,
  750. userid: msg.sender.id,
  751. from_uid: uni.getStorageSync('access_token')
  752. };
  753. that.$socket.send(data);
  754. }
  755. if (type == 'manage1') {
  756. var data = {
  757. type: 'groupset1',
  758. mode: 'manage',
  759. settype: 1,
  760. group_id: msg.group_id,
  761. userid: msg.sender.id,
  762. from_uid: uni.getStorageSync('access_token')
  763. };
  764. that.$socket.send(data);
  765. }
  766. if (type == 'deny0') {
  767. var data = {
  768. type: 'groupset1',
  769. mode: 'deny',
  770. settype: 0,
  771. group_id: msg.group_id,
  772. userid: msg.sender.id,
  773. from_uid: uni.getStorageSync('access_token')
  774. };
  775. that.$socket.send(data);
  776. }
  777. if (type == 'deny1') {
  778. var data = {
  779. type: 'groupset1',
  780. mode: 'deny',
  781. settype: 1,
  782. group_id: msg.group_id,
  783. userid: msg.sender.id,
  784. from_uid: uni.getStorageSync('access_token')
  785. };
  786. that.$socket.send(data);
  787. }
  788. if (type == 'deleteuser') {
  789. // var data={type:'deleteGroup',group_id:msg.group_id,userid:msg.id,fromid:uni.getStorageSync('access_token')};
  790. // that.$socket.send(data);
  791. this.showlogout = true;
  792. this.logoutinfo = {
  793. group_id: msg.group_id,
  794. userid: msg.sender.id,
  795. nickname: msg.sender.nickname
  796. };
  797. }
  798. if (type == 'manage0' || type == 'manage1' || type == 'deny0' || type == 'deny1' || type ==
  799. 'deleteuser') {
  800. uni.showToast({
  801. title: '操作成功',
  802. icon: 'none'
  803. })
  804. }
  805. }
  806. },
  807. msgAction(e, msg) {
  808. this.touch_item = msg;
  809. this.touch_time = new Date().getTime();
  810. var user_id = uni.getStorageSync('access_token');
  811. var that = this;
  812. var itemList = [{
  813. type: 'delete',
  814. text: '删除'
  815. }];
  816. if ((that.manager == 1 && msg.group_id > 0) || (user_id == msg.sender.id && new Date().getTime() /
  817. 1000 - (parseInt(msg.timestamp)) <= 120)) {
  818. itemList.push({
  819. type: 'back',
  820. text: '撤回消息'
  821. });
  822. }
  823. if (msg.message.type == 'text' || msg.message.type == 'url') {
  824. itemList = itemList.concat([{
  825. type: 'copy',
  826. text: '复制'
  827. }, {
  828. type: 'quote',
  829. text: '引用'
  830. }])
  831. // itemList.push({
  832. // type: 'copy',
  833. // text: '复制'
  834. // });
  835. }
  836. if(msg.message.type == 'emotion' || msg.message.type == 'image') {
  837. itemList.push({
  838. type: 'quote',
  839. text: '引用'
  840. });
  841. }
  842. if (that.manager == 1 && msg.group_id > 0 && user_id != msg.sender.id) {
  843. var users = uni.getStorageSync(msg.group_id + '_group_members');
  844. var thistype = 'user';
  845. var usertype = "user";
  846. var is_deny = 0;
  847. var isin = 0;
  848. for (var i = 0; i < users.length; i++) {
  849. if (users[i].id == user_id) thistype = users[i].type;
  850. if (users[i].id == msg.sender.id) {
  851. usertype = users[i].type;
  852. is_deny = users[i].is_deny;
  853. isin = 1;
  854. }
  855. }
  856. }
  857. if (thistype == 'owner') {
  858. if (usertype == 'manager') itemList.push({
  859. 'type': 'manage0',
  860. 'text': '取消管理'
  861. });
  862. else itemList.push({
  863. 'type': 'manage1',
  864. 'text': '设为管理'
  865. });
  866. if (is_deny == 1) itemList.push({
  867. 'type': 'deny0',
  868. 'text': '解除禁言'
  869. });
  870. else itemList.push({
  871. 'type': 'deny1',
  872. 'text': '禁言'
  873. });
  874. if (isin == 1) itemList.push({
  875. 'type': 'deleteuser',
  876. 'text': '踢人'
  877. });
  878. }
  879. if (thistype == 'manager' && usertype == 'user') {
  880. if (is_deny == 1) itemList.push({
  881. 'type': 'deny0',
  882. 'text': '解除禁言'
  883. });
  884. else itemList.push({
  885. 'type': 'deny1',
  886. 'text': '禁言'
  887. });
  888. if (isin == 1) itemList.push({
  889. 'type': 'deleteuser',
  890. 'text': '踢人'
  891. });
  892. }
  893. // itemList.push({type:'view',text:'查看名片'});
  894. this.touch_menulist = itemList;
  895. this.touch_menu = 0;
  896. var y = e.changedTouches[0].clientY + 50;
  897. var yy = "top";
  898. var xx = "left";
  899. var top = 0;
  900. var classname = "touch_menu";
  901. var len = itemList.length;
  902. if (y < 160) {
  903. yy = 'top'
  904. top = y - 10
  905. classname += ' top';
  906. } else {
  907. top = windowHeight - y + 85;
  908. yy = 'bottom';
  909. classname += ' bottom'
  910. }
  911. if (msg.sender.id == this.userid) {
  912. var xx = "right";
  913. //var x=windowWidth-x;
  914. classname += " right";
  915. } else classname += " left";
  916. this.touch_class = classname;
  917. this.touch_style = yy + ":" + top + "px";
  918. setTimeout(function() {
  919. that.touch_menu = true;
  920. }, 100)
  921. clearTimeout(this.touch_timer);
  922. this.touch_timer = setTimeout(function() {
  923. that.touch_menu = 0;
  924. }, 5000)
  925. },
  926. },
  927. watch: {
  928. messagelist(val) {
  929. console.log('消息改变',val)
  930. if (val.length > 0) {
  931. var last = val[val.length - 1];
  932. if (last.msg_id != this.lastmessage.msg_id) {
  933. //this.pagenum=0;
  934. // console.log(last);
  935. if (last.self == 1 && this.sendingdata._mid == last._mid || last.message.type == 'tips') {
  936. this.$emit('setSending', false);
  937. this.scrollToBottom();
  938. } else {
  939. if (this.isbottom == true) {
  940. this.scrollToBottom();
  941. } else {
  942. if (last.self != 1) {
  943. this.unreadnum++;
  944. if (this.unreadid == 0) this.unreadid = last.msg_id;
  945. }
  946. }
  947. }
  948. }
  949. this.lastmessage = last;
  950. } else {
  951. this.showmore = true;
  952. }
  953. var that = this;
  954. this.$store.commit('chat/clearunread', this.storeKey);
  955. // //创建后调用回到底部方法
  956. },
  957. sending(val) {
  958. if (val != false) {
  959. this.scrollToBottom();
  960. }
  961. }
  962. }
  963. }
  964. </script>
  965. <style lang="scss" scoped>
  966. $redpackBgColor: #EF9638;
  967. $reverseTextBgColor: #3388ff;
  968. $voiceBgColor: #fafafa;
  969. $voiceColor: #000;
  970. $reverseVoiceBgColor: #3388ff;
  971. $reverseVoiceColor: #fff;
  972. .chat-detail {
  973. width: 100%;
  974. padding: 0px 0px;
  975. position: fixed;
  976. z-index: 1;
  977. left: 0px;
  978. bottom: 60px;
  979. width: 100%;
  980. }
  981. .unread {
  982. position: fixed;
  983. z-index: 999s;
  984. right: 5px;
  985. bottom: 75px;
  986. height: 25px;
  987. line-height: 25px;
  988. padding: 0px 10px;
  989. border-radius: 10px;
  990. background-color: #eee;
  991. color: #333;
  992. font-size: 14px;
  993. clear: both;
  994. }
  995. .unread .num {
  996. color: #FF0000;
  997. padding: 0px 2px;
  998. display: inline-block;
  999. font-weight: 600;
  1000. }
  1001. .self_bottom {
  1002. height: 10px;
  1003. display: block;
  1004. clear: both;
  1005. margin-top: 10px;
  1006. }
  1007. .nodata {
  1008. height: 30px;
  1009. line-height: 30px;
  1010. text-align: center;
  1011. font-size: 12px;
  1012. color: #ccc;
  1013. }
  1014. .vedioplay {
  1015. position: fixed;
  1016. z-index: 9999999999;
  1017. background-color: #000;
  1018. top: 0px;
  1019. width: 100%;
  1020. left: 0px;
  1021. height: 100vh;
  1022. line-height: calc(100vh - 45px);
  1023. vertical-align: middle;
  1024. display: table-cell;
  1025. }
  1026. .vedioplay video {
  1027. vertical-align: middle;
  1028. width: 100%;
  1029. display: inline-block;
  1030. height:90%;
  1031. z-index: 99;
  1032. }
  1033. .vedioplay .bottom {
  1034. position: absolute;
  1035. z-index: 999;
  1036. bottom: 10px;
  1037. left: 0px;
  1038. // background-color: red;
  1039. width: 100%;
  1040. height: 50px;
  1041. line-height: 50px;
  1042. color: #fff;
  1043. text-align: center;
  1044. }
  1045. .vedioplay .bottom .icon1 {
  1046. font-size: 36px !important;
  1047. color: #eee !important;
  1048. }
  1049. .vedio {
  1050. display: inline-block;
  1051. float: left;
  1052. width: calc(100% - 200upx);
  1053. border-radius: 10upx;
  1054. padding-top: 0upx;
  1055. padding-bottom: 0upx;
  1056. overflow: hidden;
  1057. position: relative;
  1058. z-index: 0;
  1059. }
  1060. .vedio .timeshow {
  1061. position: absolute;
  1062. right: 12upx;
  1063. bottom: 16upx;
  1064. font-size: 24upx;
  1065. color: #FFFFFF;
  1066. z-index: 999999999;
  1067. }
  1068. .vedio .play_btn {
  1069. position: absolute;
  1070. height: 80upx;
  1071. width: 80upx;
  1072. left: calc(50% - 40upx);
  1073. top: calc(50% - 40upx);
  1074. z-index: 999999999;
  1075. }
  1076. .vedio_src {
  1077. max-width: 100%;
  1078. border-radius: 10upx;
  1079. max-height: 70vw;
  1080. z-index: 0 !important;
  1081. }
  1082. .touch_menu {
  1083. position: fixed;
  1084. z-index: 9999;
  1085. background-color: rgba(0, 0, 0, 0.8);
  1086. border: 1px #000 solid;
  1087. border-radius: 10px;
  1088. padding: 0px 10px;
  1089. line-height: 30px;
  1090. max-width: 100%;
  1091. font-size: 14px;
  1092. min-height: 40px;
  1093. }
  1094. .touch_menu view {
  1095. height: 45px;
  1096. line-height: 45px;
  1097. color: #fff;
  1098. display: inline-block;
  1099. padding: 0px 10px;
  1100. text-align: center;
  1101. border-right: 1px #999 solid;
  1102. }
  1103. .touch_menu view:last-child {
  1104. border-width: 0px;
  1105. ;
  1106. }
  1107. .touch_menu.right view {
  1108. padding: 0px 15px;
  1109. }
  1110. .touch_menu::before {
  1111. display: block;
  1112. content: " ";
  1113. position: absolute;
  1114. width: 0;
  1115. height: 0;
  1116. border-style: solid;
  1117. }
  1118. .touch_menu.top::before {
  1119. top: -12px;
  1120. border-width: 0px 12px 12px 12px;
  1121. border-color: #000 transparent;
  1122. }
  1123. .touch_menu.bottom::before {
  1124. bottom: -24px;
  1125. border-width: 12px;
  1126. border-color: #000 transparent transparent transparent;
  1127. }
  1128. .touch_menu.left {
  1129. text-align: left;
  1130. left: 3px;
  1131. }
  1132. .touch_menu.right {
  1133. text-align: right;
  1134. right: 20px;
  1135. }
  1136. .touch_menu.left::before {
  1137. left: 70px;
  1138. }
  1139. .touch_menu.right::before {
  1140. right: 50px;
  1141. }
  1142. .first {
  1143. width: 2px;
  1144. height: 2px;
  1145. background: #fff;
  1146. top: 22px;
  1147. left: 22px;
  1148. }
  1149. .second {
  1150. width: 12px;
  1151. height: 12px;
  1152. top: 17px;
  1153. left: 17px;
  1154. }
  1155. .third {
  1156. width: 20px;
  1157. height: 20px;
  1158. top: 12px;
  1159. left: 12px;
  1160. }
  1161. @keyframes fadeInOut {
  1162. 0% {
  1163. opacity: 0;
  1164. }
  1165. 100% {
  1166. opacity: 1;
  1167. }
  1168. }
  1169. /**/
  1170. .loading {
  1171. //loading动画
  1172. display: flex;
  1173. justify-content: center;
  1174. @keyframes stretchdelay {
  1175. 0%,
  1176. 40%,
  1177. 100% {
  1178. transform: scaleY(0.6);
  1179. }
  1180. 20% {
  1181. transform: scaleY(1.0);
  1182. }
  1183. }
  1184. .spinner {
  1185. margin: 20upx 0;
  1186. width: 60upx;
  1187. height: 25px;
  1188. display: flex;
  1189. align-items: center;
  1190. justify-content: space-between;
  1191. view {
  1192. background-color: #ff9800;
  1193. height: 25px;
  1194. width: 3px;
  1195. border-radius: 3px;
  1196. animation: stretchdelay 1.2s infinite ease-in-out;
  1197. }
  1198. .rect2 {
  1199. animation-delay: -1.1s;
  1200. }
  1201. .rect3 {
  1202. animation-delay: -1.0s;
  1203. }
  1204. .rect4 {
  1205. animation-delay: -0.9s;
  1206. }
  1207. .rect5 {
  1208. animation-delay: -0.8s;
  1209. }
  1210. }
  1211. }
  1212. image {
  1213. will-change: transform;
  1214. }
  1215. .loadingbox {
  1216. height: 80upx;
  1217. width: 70upx;
  1218. justify-content: center;
  1219. line-height: 80upx;
  1220. display: inline-block;
  1221. text-align: center;
  1222. vertical-align: top;
  1223. }
  1224. .loadingbox image {
  1225. height: 36upx;
  1226. width: 36upx;
  1227. vertical-align: middle;
  1228. }
  1229. </style>