chat.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. <template>
  2. <view class="page page--divider">
  3. <view style="display: none;">{{$store.state.hackUpdate}}</view>
  4. <load-more status="loading" v-if="initializing" />
  5. <chat-panel :store-key="storeKey" :thistype="thistype" :atme="atme" :at_msg_id='at_msg_id' @close='atuser1'
  6. :sending="sending" :sendingdata="sendingdata" :manager="ismanage" :no_add="no_add"
  7. @click-avatar="openProfile" @setSending='setSending' :boardheight='boardheight' ref="panel"
  8. @chooseQuote="setQuote" />
  9. <view class="placeholder"></view>
  10. <v-sender ref='sender' v-if="!initializing" v-model="message" @send="sendTextMessage" :groupid="group.id"
  11. :isgroup="1" @face="sendVoice" @sendImage="sendImg" @sendVedio="sendVedio" @emoji="sendEmoji"
  12. @clearQute="clearQute" :no-speaking="no_speaking" :speaking_tips='speaking_tips'
  13. :forbid-redpack="group.forbid_redpack==1 && !group.owner && !ismanage?true:false"
  14. @handleEmotion="handleEmotion" @input="inputMessage" @keyboardheight='keyboardheight'
  15. @senderheight="set_sheight" :sendtype='type' />
  16. <GroupUser ref='groupuser' :groupid='group.id' :show='groupshow' @atuser='atuser'></GroupUser>
  17. </view>
  18. </template>
  19. <script>
  20. import GroupUser from '../../components/GroupUser.vue';
  21. import ChatPanel from '../../components/chat-panel.vue'
  22. import chat from "../../library/chat.js"
  23. import {
  24. mapState,
  25. mapGetters
  26. } from 'vuex';
  27. import api from "../../library/index.js"
  28. import config from "../../config.js"
  29. export default {
  30. components: {
  31. ChatPanel,
  32. GroupUser
  33. },
  34. data() {
  35. return {
  36. quoteItem: {}, //引用内容
  37. userid: uni.getStorageSync('access_token'),
  38. user: uni.getStorageSync('userInfo'),
  39. loaded: 'more',
  40. group: {},
  41. message: '',
  42. initializing: false,
  43. showPickMoney: '',
  44. getPick: '',
  45. pickErrorText: '',
  46. redpackInfo: {},
  47. sending: false,
  48. sendingdata: {},
  49. ismanage: false,
  50. no_speaking: false,
  51. no_add: false,
  52. sender: [],
  53. receiver: [],
  54. boardheight: 0,
  55. groupshow: 0,
  56. oldstr: '',
  57. atusers: {},
  58. type: '',
  59. speaking_tips: '',
  60. atme: 0,
  61. at_msg_id: 0,
  62. thistype: '',
  63. storeKey: '',
  64. list: [
  65. ['微笑', '撇嘴', '色', '发呆', '得意', '流泪', '害羞', '闭嘴'],
  66. ['睡', '大哭', '尴尬', '发怒', '调皮', '呲牙', '惊讶', '难过'],
  67. ['酷', '冷汗', '抓狂', '吐', '偷笑', '可爱', '白眼', '傲慢'],
  68. ['饥饿', '困', '惊恐', '流汗', '憨笑', '大兵', '奋斗', '咒骂'],
  69. ['疑问', '嘘', '晕', '折磨', '衰', '骷髅', '敲打', '再见'],
  70. ['擦汗', '抠鼻', '鼓掌', '糗大了', '坏笑', '左哼哼', '右哼哼', '哈欠'],
  71. ['鄙视', '委屈', '快哭了', '阴险', '亲亲', '吓', '可怜', '菜刀'],
  72. ['西瓜', '啤酒', '篮球', '乒乓', '咖啡', '饭', '猪头', '玫瑰', ],
  73. ['凋谢', '示爱', '爱心', '心碎', '蛋糕', '闪电', '炸弹', '刀'],
  74. ['足球', '瓢虫', '便便', '月亮', '太阳', '礼物', '拥抱', '强'],
  75. ['弱', '握手', '胜利', '抱拳', '勾引', '拳头', '差劲', '爱你'],
  76. ['NO', 'OK', '爱情', '飞吻', '跳跳', '发抖', '怄火', '转圈'],
  77. ['磕头', '回头', '跳绳', '挥手', '激动', '闭嘴', '笑哭', '吐舌'],
  78. ['耶', '跳舞', '恐惧', '失望', '脸红', '无语', '奸笑', '嘿哈'],
  79. ['鬼混', '福', '合十', '强壮', '红包', '发财', '庆祝', '礼物']
  80. ],
  81. reg: /\S{1,3}/gi,
  82. lists: [],
  83. listss: []
  84. };
  85. },
  86. onLoad(opts) {
  87. // console.log(opts);
  88. if (opts.atme > 0) this.atme = opts.atme
  89. if (opts.msg_id > 0) this.at_msg_id = opts.msg_id
  90. uni.setNavigationBarTitle({
  91. title: decodeURI(opts.nickname)
  92. })
  93. this.group = opts;
  94. this.group.id = parseInt(this.group.id);
  95. this.storeKey = 'G' + this.group.id;
  96. uni.setStorageSync('cache_key', this.storeKey);
  97. this.joingroup();
  98. // console.log(opts);
  99. this.$socket.on('group_update', (res) => {
  100. this.getInfo();
  101. this.getGroupUsers();
  102. })
  103. this.sender = uni.getStorageSync('userInfo');
  104. // #ifdef APP-PLUS
  105. let currentWebview = this.$mp.page.$getAppWebview();
  106. currentWebview.setStyle({
  107. titleNView: {
  108. titleText: ''
  109. },
  110. })
  111. // #endif
  112. },
  113. onUnload() {
  114. uni.setStorageSync('cache_key', '');
  115. },
  116. onShow() {
  117. this.getInfo();
  118. this.getGroupUsers();
  119. var value = '';
  120. this.list = this.list.map((line, index) => {
  121. this.listss = [];
  122. line = line.map((item, idx) => {
  123. value = item;
  124. item = item.replace(/\S{1,3}/gi, this.getemotion(item));
  125. this.listss.push({
  126. "name": item,
  127. "index": index,
  128. "value": value,
  129. "idx": idx
  130. })
  131. return item;
  132. })
  133. this.lists.push(this.listss);
  134. return line;
  135. })
  136. console.log(this.list, 'this.list');
  137. },
  138. methods: {
  139. getemotion(res) {
  140. let word = res.replace(/\[|\]/gi, '')
  141. const list = ['微笑', '撇嘴', '色', '发呆', '得意', '流泪', '害羞', '闭嘴', '睡', '大哭', '尴尬', '发怒', '调皮', '呲牙', '惊讶',
  142. '难过', '酷', '冷汗', '抓狂', '吐', '偷笑', '可爱', '白眼', '傲慢', '饥饿', '困', '惊恐', '流汗', '憨笑', '大兵', '奋斗',
  143. '咒骂', '疑问', '嘘', '晕', '折磨', '衰', '骷髅', '敲打', '再见', '擦汗', '抠鼻', '鼓掌', '糗大了', '坏笑', '左哼哼', '右哼哼',
  144. '哈欠', '鄙视', '委屈', '快哭了', '阴险', '亲亲', '吓', '可怜', '菜刀', '西瓜', '啤酒', '篮球', '乒乓', '咖啡', '饭', '猪头',
  145. '玫瑰', '凋谢', '示爱', '爱心', '心碎', '蛋糕', '闪电', '炸弹', '刀', '足球', '瓢虫', '便便', '月亮', '太阳', '礼物', '拥抱',
  146. '强', '弱', '握手', '胜利', '抱拳', '勾引', '拳头', '差劲', '爱你', 'NO', 'OK', '爱情', '飞吻', '跳跳', '发抖', '怄火',
  147. '转圈', '磕头', '回头', '跳绳', '挥手', '激动',
  148. '闭嘴', '笑哭', '吐舌', '耶', '跳舞', '恐惧', '失望', '脸红', '无语', '奸笑', '嘿哈', '鬼混', '福', '合十', '强壮', '红包',
  149. '发财', '庆祝', '礼物'
  150. ]
  151. let index = list.indexOf(word);
  152. var index1 = index + 100;
  153. return '^' + index1 + '^';
  154. },
  155. // 清除qute
  156. clearQute() {
  157. this.quoteItem = {}
  158. },
  159. setQuote(item) {
  160. if (item.message.type == 'text') {
  161. if (!item.message.content.type) {
  162. item.ttype = 'text'
  163. // 空格替换回车
  164. item.message.qute = item.message.content.replace(/<br>/g, " ").replace(/&nbsp;/g, ' ')
  165. } else if (item.message.content.type == "remind") {
  166. // 去除html 标签 && 去除 回车替换成空格
  167. if(item.message.content.remind && item.message.content.remind.nickname) {
  168. item.message.qute = item.message.content.content.replace(/<span.*?>.*?<\/span>/g, '@' + item.message.content.remind.nickname).replace(
  169. /<br>/g, " ").replace(/&nbsp;/g, ' ')
  170. }else {
  171. item.message.qute = item.message.content.content.replace(/<span.*?>|<\/span>/g, '@' + '').replace(
  172. /<br>/g, " ").replace(/&nbsp;/g, ' ')
  173. }
  174. item.ttype = 'remind'
  175. }
  176. }
  177. if (item.message.type == 'emotion') {
  178. item.ttype = 'emotion'
  179. console.log(item.message.content,'item.message.content');
  180. item.message.qute = item.message.content.content.replace(/<br>/g, " ")
  181. var content = item.message.qute.replace(/\[\S{1,3}\]/gi, this.getemotion).split('^');
  182. var imgs = [];
  183. for (var i = 0; i < content.length; i++) {
  184. if (content[i] >= 100 && content[i] <= 222) {
  185. imgs.push({
  186. 'type': 'img',
  187. 'content': "/static/emoji/" + content[i] + '.gif'
  188. })
  189. } else {
  190. imgs.push({
  191. 'type': 'text',
  192. 'content': content[i]
  193. })
  194. }
  195. }
  196. item.message.face = imgs;
  197. console.log('content', content);
  198. }
  199. if(item.message.type == 'image') {
  200. console.log('引用图片');
  201. item.ttype = 'image'
  202. item.message.qute = item.message.content
  203. }
  204. this.$refs.sender.setQute(item)
  205. this.quoteItem = item
  206. console.log("设置item", item);
  207. },
  208. // 检测输入值
  209. inputMessage(e) {
  210. // console.log(e);
  211. //console.log(this.oldstr,e);
  212. if (e.substr(e.length - 1, 1) == '@' && this.oldstr != e && e.length > 0 && e.length > this.oldstr
  213. .length) {
  214. this.groupshow = 1;
  215. uni.hideKeyboard();
  216. } else {
  217. this.groupshow = 0;
  218. }
  219. this.oldstr = e;
  220. this.emotion = e;
  221. },
  222. atuser(e) {
  223. this.groupshow = 0;
  224. if (e.nickname) {
  225. this.$refs.sender.setinputvalue(e.nickname);
  226. this.atusers = e;
  227. }
  228. },
  229. atuser1(e) {
  230. console.log(e);
  231. if (e.nickname) {
  232. this.$refs.sender.setinputvalue('@' + e.nickname);
  233. this.atusers = e;
  234. }
  235. },
  236. set_sheight(e) {
  237. this.$refs.panel.setAutoHeight(e);
  238. },
  239. keyboardheight(e) {
  240. this.boardheight = e;
  241. this.$refs.panel.setAutoHeight(0);
  242. },
  243. setSending(e) {
  244. this.sending = e;
  245. },
  246. group_init(id) {
  247. var group = uni.getStorageSync('group_' + id);
  248. if (group.id > 0 && group.id == id) this.group_set(group);
  249. },
  250. group_set(group) {
  251. this.group = group;
  252. if (group.deny_id == null) group.deny_id = '';
  253. if (group.manager_id == null) group.manager_id = '';
  254. if (this.user.status == 1 || (this.user.status == 2 && parseInt(this.user.lock_time) >= Date.parse(
  255. new Date()) / 1000)) {
  256. this.no_speaking = true;
  257. this.speaking_tips = '您的账号已被冻结';
  258. } else if ((group.no_speaking == 1) && !group.owner && group.manager_id.indexOf(this.userid) <= -1) {
  259. this.no_speaking = true;
  260. this.speaking_tips = '全体禁言,限群主和管理员可发消息';
  261. } else if ((group.deny_id.indexOf(this.userid) > -1) && !group.owner && group.manager_id.indexOf(this
  262. .userid) <= -1) {
  263. this.no_speaking = true;
  264. this.speaking_tips = '您已被禁言';
  265. } else {
  266. this.no_speaking = false;
  267. }
  268. if (group.manager_id.indexOf(this.userid) > -1 || group.owner) this.ismanage = true;
  269. else this.ismanage = false;
  270. if (group.is_owner == 1) var type = 'owner';
  271. else if (group.is_manager == 1) var type = 'manager';
  272. else var type = 'user';
  273. this.thistype = type;
  274. // console.log(this.group);
  275. if ((group.no_add == 1) && this.ismanage == false)
  276. this.no_add = true;
  277. else this.no_add = false;
  278. uni.setNavigationBarTitle({
  279. title: `${group.name}(${group.people_count}人)`
  280. })
  281. uni.setStorageSync('group_' + group.id, group);
  282. },
  283. getInfo() {
  284. if (this.group.id > 0) {
  285. this.group_init(this.group.id);
  286. api.getGroupInfo({
  287. group_id: this.group.id,
  288. from_id: this.userid,
  289. }).then(res => {
  290. this.group_set(res.data);
  291. })
  292. }
  293. },
  294. handleEmotion(value) {
  295. //console.log(value);
  296. this.emotion = value;
  297. this.type = 'emotion';
  298. },
  299. joingroup() {
  300. let data = {
  301. GroupId: this.group.id,
  302. type: 'joinGroup'
  303. }
  304. this.getGroupUsers()
  305. this.$socket.send(data);
  306. },
  307. getGroupUsers() {
  308. if(this.loaded == 'loading' || this.loaded == 'noMore') {
  309. return
  310. }
  311. this.loaded = 'loading'
  312. api.getGroupUsers({
  313. group_id: this.group.id,
  314. userid: this.userid,
  315. }).then(res => {
  316. this.loaded = 'noMore'
  317. uni.setStorageSync(this.group.id + '_group_members', res.data);
  318. }).catch(err => {
  319. this.loaded = 'more'
  320. })
  321. },
  322. toHtml(str) {
  323. str = str.replace(/ /g, "&nbsp;");
  324. str = str.replace(/\n/g, "<br>");
  325. return str;
  326. },
  327. sendImg(e) {
  328. this.commitMessage('image', e);
  329. },
  330. sendVedio(e) {
  331. this.commitMessage('vedio', e);
  332. },
  333. // 发送文本消息
  334. sendTextMessage() {
  335. let that = this;
  336. let addStr = '';
  337. console.log(that.quoteItem,'发送that.quoteItem');
  338. if (this.quoteItem && this.quoteItem.id) {
  339. addStr += '-qute-nickname=' + that.quoteItem.sender.nickname + 'q&qcontent=' + that.quoteItem
  340. .message
  341. .qute + 'q&qttype=' + that.quoteItem.ttype
  342. }
  343. if (this.type == "emotion") {
  344. this.emotionInfo = {
  345. "type": "emotion",
  346. "value": this.emotion + addStr,
  347. "content": this.emotion + addStr
  348. }
  349. this.commitMessage('emotion', this.emotionInfo);
  350. } else {
  351. var msg = this.toHtml(this.message) + addStr;
  352. this.commitMessage('text', msg,1);
  353. }
  354. this.quoteItem = {}
  355. this.$refs.sender.clearQute()
  356. // this.commitMessage('text', this.message);
  357. },
  358. commitMessage(type, sendData,ttype=0) {
  359. console.log('type:',type,'sendData:',sendData)
  360. this.message = '';
  361. if (type == 'image') {
  362. var mid = sendData.mid;
  363. sendData = sendData.src;
  364. } else if (type == 'vedio') {
  365. var mid = sendData.mid;
  366. // sendData=sendData.src;
  367. } else if (type == 'voice') {
  368. var mid = sendData.mid;
  369. } else {
  370. var mid = 'm' + Math.random().toString(36).substring(2);
  371. }
  372. var atuser = 0;
  373. if (type == 'text' && parseInt(this.atusers.id) > 0) {
  374. if (sendData.indexOf(this.atusers.nickname) > -1) {
  375. let arr = sendData.split('-qute-')
  376. if(arr[0].indexOf('@' + this.atusers.nickname) != -1) {
  377. var content = sendData.replace('@' + this.atusers.nickname, '@{' + this.atusers.id + '}');
  378. console.log('包含',content);
  379. // console.l
  380. }else {
  381. var content = sendData
  382. }
  383. sendData = {
  384. type: 'remind',
  385. remind: this.atusers,
  386. content: content
  387. }
  388. this.oldstr = '';
  389. this.atusers = {};
  390. }
  391. }
  392. if (type == 'text' && sendData == '') return false;
  393. let data = {
  394. userid: this.userid,
  395. group_id: this.group.id,
  396. type: 'group',
  397. msgtype: type,
  398. content: sendData,
  399. mid: mid
  400. }
  401. var sendlocal = 0;
  402. if ((type == 'image' && sendData.indexOf(config.imgUri) <= -1) || (type == 'vedio' && sendData.src
  403. .indexOf(config.imgUri) <= -1) || (type == 'voice' && sendData.url.indexOf(config.imgUri) <= -
  404. 1)) {
  405. sendlocal = 1;
  406. } else {
  407. this.$socket.send(data);
  408. }
  409. this.type = 'text';
  410. if (type !== 'image' && type !== 'voice') sendlocal = 1;
  411. var that = this;
  412. if (sendlocal == 1) {
  413. // setTimeout(function(){
  414. var arr = {};
  415. arr.id = that.group.id;
  416. arr.cache_key = 'G' + arr.id;
  417. arr['self'] = 1;
  418. arr['isloading'] = 1;
  419. arr['receiver_id'] = 0
  420. arr['sender_id'] = that.sender.id;
  421. arr['group_id'] = that.group.id;
  422. arr['timestamp'] = parseInt(new Date().getTime() / 1000);
  423. arr['time'] = '';
  424. arr['message'] = {
  425. type: type,
  426. content: sendData
  427. }
  428. arr['sender'] = that.sender;
  429. arr['receiver'] = that.group;
  430. arr['nickname'] = that.sender.nickname;
  431. arr['avatar'] = that.sender.avatar;
  432. arr['msg_id'] = '';
  433. arr['_mid'] = mid;
  434. // that.$refs.panel.sendmsg({ data:arr});
  435. that.sendingdata = arr;
  436. that.sending = true;
  437. // console.log(arr)
  438. // that.sendmsg(arr);
  439. // },20,that,mid)
  440. }
  441. },
  442. sendVoice(e) {
  443. this.commitMessage('voice', e);
  444. },
  445. sendEmoji(e) {
  446. this.commitMessage('face', e)
  447. },
  448. openProfile(e) {
  449. let params = {
  450. id: e.id,
  451. status: 'friend'
  452. };
  453. return this.$jump('friend.detail', params)
  454. }
  455. },
  456. onNavigationBarButtonTap() {
  457. this.$refs.panel.endVedio();
  458. this.$jump('group.detail', {
  459. id: this.group.id,
  460. 'from': 'chat'
  461. });
  462. }
  463. }
  464. </script>