123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943 |
- <template>
- <view class="chatInterface" @contextmenu.prevent="">
- <view class="scroll-view">
- <!-- <image v-if="history.loading" class="history-loaded" src="/static/images/loading.svg"/>
- <view v-else :class="history.allLoaded ? 'history-loaded':'load'" @click="loadHistoryMessage(false)">
- <view>{{ history.allLoaded ? '已经没有更多的历史消息' : '点击获取历史消息' }}</view>
- </view> -->
- <!-- -->
- <view class="tbox">
- <view class="gongyingshangBox">
- 正在与
- <span v-for="(item,index) in 4">供应商{{index}}</span>
- 对话
- </view>
- <!-- <view class="messageLine">
- <view class="messageTxt">大众 速腾 2006款 1.6L自动时尚型LFV456HH85777845</view>
- <view class="messageTxt">我想要机油</view>
- <view class="messageImgBox">
- <image class="messageImg" src="/static/images/uniapp.png" mode="widthFix"></image>
- </view>
- </view> -->
- </view>
-
- <checkbox-group @change="selectMessages">
- <!--消息记录-->
- <view v-for="(message,index) in history.messages" :key="message.messageId">
- <!--时间显示,类似于微信,隔5分钟不发言,才显示时间-->
- <view class="time-lag">
- {{ renderMessageDate(message, index) }}
- </view>
- <view class="message-recalled" v-if="message.recalled">
- <view v-if="message.recaller.id === currentUser.id" class="message-recalled-self">
- <view>你撤回了一条消息</view>
- <span v-if="message.type === 'text' && Date.now()-message.timestamp< 60 * 1000 "
- @click="editRecalledMessage(message.payload.text)">重新编辑</span>
- </view>
- <view v-else>{{ message.recaller.data.name }}撤回了一条消息</view>
- </view>
- <view class="message-item" v-else>
- <view class="message-item-checkbox">
- <checkbox v-show="messageSelector.visible && message.status !== 'sending'" :value="message.messageId"
- :checked="messageSelector.messages.includes(message)"/>
- </view>
- <view class="message-item-content" :class="{'self' : message.senderId === currentUser.id}">
- <view class="avatar">
- <image :src="message.senderId === currentUser.id? currentUser.avatar : friend.avatar"></image>
- </view>
- <view class="content" @click.right="showActionPopup(message)" @longpress="showActionPopup(message)">
- <view class="message-payload">
- <b class="pending" v-if="message.status === 'sending'"></b>
- <b class="send-fail" v-if="message.status === 'fail'"></b>
- <view v-if="message.type === 'text'" class="text-content" v-html="renderTextMessage(message)"></view>
- <image v-if="message.type === 'image'"
- :data-url="message.payload.url"
- :src="message.payload.thumbnail"
- class="image-content"
- mode="heightFix"
- @click="showImageFullScreen"
- ></image>
- <view class="video-snapshot" v-if="message.type === 'video'" :data-url="message.payload.video.url"
- @click="playVideo">
- <image
- :src="message.payload.thumbnail.url"
- :style="{height: getImageHeight(message.payload.thumbnail.width,message.payload.thumbnail.height)+'rpx' }"
- mode="heightFix"
- ></image>
- <view class="video-play-icon"></view>
- </view>
- <view class="file-content" v-if="message.type === 'file'">
- <view class="file-info">
- <span class="file-name">{{ message.payload.name }}</span>
- <span class="file-size">{{ (message.payload.size / 1024).toFixed(2) }}KB</span>
- </view>
- <image class="file-img" src="/static/images/file-icon.png"></image>
- </view>
- <view v-if="message.type ==='audio'" class="audio-content" @click="playAudio(message)">
- <view class="audio-facade" :style="{width:Math.ceil(message.payload.duration)*7 + 50 + 'px'}">
- <view
- class="audio-facade-bg"
- :class="{'play-icon':audioPlayer.playingMessage && audioPlayer.playingMessage.messageId === message.messageId}"
- ></view>
- <view>{{Math.ceil(message.payload.duration) || 1}}<span>"</span></view>
- </view>
- </view>
- <view v-if="message.type === 'order'" class="order-content">
- <view class="order-id">订单号:{{ message.payload.id }}</view>
- <view class="order-body">
- <image :src="message.payload.url" class="order-img"></image>
- <view>
- <view class="order-name">{{ message.payload.name }}</view>
- <view class="order-info">
- <view class="order-price">{{ message.payload.price }}</view>
- <view class="order-count">共{{ message.payload.count }}件</view>
- </view>
- </view>
- </view>
- </view>
- </view>
- <view v-if="message.senderId === currentUser.id" :class="message.read ?'message-read':'message-unread'">
- <view v-if="message.status === 'success'">{{ message.read ? '已读' : '未读' }}</view>
- </view>
- </view>
- </view>
- </view>
- </view>
- </checkbox-group>
- </view>
- <view class="action-box" v-if="!videoPlayer.visible && !messageSelector.visible">
- <view class="action-top">
- <view @click="switchAudioKeyboard">
- <image class="more" v-if="audio.visible" src="/static/images/jianpan.png"></image>
- <image class="more" v-else src="/static/images/audio.png"></image>
- </view>
- <view v-if="audio.visible" class="record-input" @touchend.stop="onRecordEnd" @touchstart.stop="onRecordStart">
- {{ recorderManager.recording ? '松开发送' : '按住录音' }}
- </view>
- <!-- GoEasyIM最大支持3k的文本消息,如需发送长文本,需调整输入框maxlength值 -->
- <input v-else v-model="text" @confirm="sendTextMessage" class="consult-input" maxlength="700" placeholder="发送消息" type="text" />
- <view @click="switchEmojiKeyboard">
- <image class="more" v-if="emoji.visible" src="/static/images/jianpan.png"></image>
- <image class="more" v-else src="/static/images/emoji.png"></image>
- </view>
- <view>
- <image @click="showOtherTypesMessagePanel()" class="more" src="/static/images/more.png"/>
- </view>
- <view v-if="text" class="send-btn-box">
- <text class="btn" @click="sendTextMessage()">发送</text>
- </view>
- </view>
- <!--展示表情列表-->
- <view class="action-bottom action-bottom-emoji" v-if="emoji.visible">
- <image class="emoji-item" v-for="(emojiItem, emojiKey, index) in emoji.map" :key="index"
- :src="emoji.url + emojiItem" @click="chooseEmoji(emojiKey)"></image>
- </view>
- <!--其他类型消息面板-->
- <view v-if="otherTypesMessagePanelVisible" class="action-bottom">
- <view class="more-icon">
- <image @click="sendImageMessage()" class="operation-icon" src="/static/images/picture.png"></image>
- <view class="operation-title">图片</view>
- </view>
- <view class="more-icon">
- <image @click="sendVideoMessage()" class="operation-icon" src="/static/images/video.png"></image>
- <view class="operation-title">视频</view>
- </view>
- <view class="more-icon">
- <image @click="showOrderMessageList()" class="operation-icon" src="/static/images/order.png"></image>
- <view class="operation-title">订单</view>
- </view>
- <view class="more-icon">
- <image @click="privateCall()" class="operation-icon" src="/static/images/rtc.png"></image>
- <view class="operation-title">视频通话</view>
- </view>
- </view>
- </view>
- <view class="action-popup" @touchmove.stop.prevent v-if="actionPopup.visible">
- <view class="layer"></view>
- <view class="action-list">
- <view class="action-item" @click="deleteSingleMessage">删除</view>
- <view class="action-item" v-if="actionPopup.recallable" @click="recallMessage">撤回</view>
- <view class="action-item" @click="showCheckBox">多选</view>
- <view class="action-item" @click="hideActionPopup">取消</view>
- </view>
- </view>
- <view class="messageSelector-box" v-if="messageSelector.visible">
- <image class="messageSelector-btn" @click="deleteMultipleMessages" src="/static/images/delete.png"></image>
- </view>
- <view class="record-loading" v-if="recorderManager.recording"></view>
- <video v-if="videoPlayer.visible" :src="videoPlayer.url" id="videoPlayer"
- @fullscreenchange="onVideoFullScreenChange"></video>
- <view v-if="orderList.visible" class="order-list">
- <view class="orders-content">
- <view class="title">
- <view>请选择一个订单</view>
- <view class="close" @click="hideOrderMessageList">×</view>
- </view>
- <view class="orders">
- <view
- v-for="(order, index) in orderList.orders"
- :key="index" class="order-item"
- @click="sendOrderMessage(order)"
- >
- <view class="order-id">订单号:{{ order.id }}</view>
- <view class="order-body">
- <image :src="order.url" class="order-img"></image>
- <view class="order-name">{{ order.name }}</view>
- <view class="order-right">
- <view class="order-price">{{ order.price }}</view>
- <view class="order-count">共{{ order.count }}件</view>
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import EmojiDecoder from '../lib/EmojiDecoder';
- import restApi from '../lib/restapi';
- import {formatDate} from '../lib/utils';
- import RecorderManager from '../lib/RecorderManager';
- const IMAGE_MAX_WIDTH = 200;
- const IMAGE_MAX_HEIGHT = 150;
- const recorderManager = new RecorderManager();
- const GoEasy = uni.$GoEasy;
- const GRTC = uni.$GRTC;
- export default {
- name: 'privateChat',
- data() {
- const emojiUrl = 'https://imgcache.qq.com/open/qcloud/tim/assets/emoji/';
- const emojiMap = {
- '[么么哒]': 'emoji_3@2x.png',
- '[乒乓]': 'emoji_4@2x.png',
- '[便便]': 'emoji_5@2x.png',
- '[信封]': 'emoji_6@2x.png',
- '[偷笑]': 'emoji_7@2x.png',
- '[傲慢]': 'emoji_8@2x.png'
- };
- return {
- //聊天文本框
- text: '',
- friend: null,
- to: {},// 作为createMessage的参数
- currentUser: null,
- //定义表情列表
- emoji: {
- url: emojiUrl,
- map: emojiMap,
- visible: false,
- decoder: new EmojiDecoder(emojiUrl, emojiMap),
- },
- //是否展示‘其他消息类型面板’
- otherTypesMessagePanelVisible: false,
- orderList: {
- orders: [],
- visible: false
- },
- history: {
- messages: [],
- allLoaded: false,
- loading: false
- },
- recorderManager: recorderManager,
- audio: {
- //录音按钮展示
- visible: false
- },
- audioPlayer: {
- innerAudioContext: null,
- playingMessage: null,
- },
- videoPlayer: {
- visible: false,
- url: '',
- context: null
- },
- // 展示消息删除弹出框
- actionPopup: {
- visible: false,
- message: null,
- recallable: false,
- },
- // 消息选择
- messageSelector: {
- visible: false,
- messages: []
- },
- toList:[
- "A69257B1-8603-4BCD-9D32-07C18E6E14D7",
- "1292F5DA-793B-4549-844E-C5F606869D0C",
- "421DB63C-B274-478C-8442-CD43AD052A7B",
- "AB6D0669-A5F8-423F-A6FE-81AC12084AFC"
- ],
- currentUser:'',
- }
- },
- onLoad(options) {
- //聊天对象
- //let id = options.to;
- this.friend = uni.getStorageSync("friend");
- //this.friend = restApi.findUserById(id);
- this.currentUser = uni.$currentUser;
- this.currentUser={
- avatar: "/static/images/Avatar-1.png",
- email: "Mattie@goeasy.io",
- id: "08c0a6ec-a42b-47b2-bb1e-15e0f5f9a19a",
- name: "测试群发",
- password: "123",
- phone: "138xxxxxxxx",
- }
- /* this.to = {
- id: this.friend.ID,
- type: GoEasy.IM_SCENE.PRIVATE,
- data: {
- name: this.friend.Name,
- avatar: '/static/images/Avatar-1.png'
- }
- }; */
- this.currentUser = uni.getStorageSync('currentUser')
- //this.connectGoEasy()
- this.to = {
- id: 'A69257B1-8603-4BCD-9D32-07C18E6E14D7',
- type: GoEasy.IM_SCENE.PRIVATE,
- data: {
- name: "群发测试",
- avatar: '/static/images/Avatar-1.png'
- }
- };
-
- this.toList=uni.getStorageSync('supplierlist')
- this.initGoEasyListeners();
- // 语音播放器
- this.initialAudioPlayer();
- // 录音监听器
- this.initRecorderListeners();
- },
- onShow() {
- this.otherTypesMessagePanelVisible = false;
- this.emoji.visible = false;
- },
- onReady() {
- this.loadHistoryMessage(true);
- this.videoPlayer.context = uni.createVideoContext('videoPlayer', this);
- // https://uniapp.dcloud.io/api/ui/navigationbar?id=setnavigationbartitle
- uni.setNavigationBarTitle({ title: this.friend.Name });
- },
- onPullDownRefresh(e) {
- this.loadHistoryMessage(false);
- },
- onUnload() {
- //退出聊天页面之前,清空监听器
- GoEasy.im.off(GoEasy.IM_EVENT.PRIVATE_MESSAGE_RECEIVED, this.onMessageReceived);
- GoEasy.im.off(GoEasy.IM_EVENT.MESSAGE_DELETED, this.onMessageDeleted);
- GoEasy.im.off(GoEasy.IM_EVENT.HISTORY_EXPIRED, this.onHistoryExpired);
- },
- methods: {
- connectGoEasy() {
- console.log(this.currentUser)
-
- GoEasy.connect({
- id: this.currentUser.id,
- data: {
- name: this.currentUser.name,
- avatar: this.currentUser.avatar
- },
- onSuccess: () => {
- console.log('GoEasy connect successfully.')
- },
- onFailed: (error) => {
- console.log('Failed to connect GoEasy, code:' + error.code + ',error:' + error.content);
- },
- onProgress: (attempts) => {
- console.log('GoEasy is connecting', attempts);
- }
- });
- },
- //渲染文本消息,如果包含表情,替换为图片
- //todo:本不需要该方法,可以在标签里完成,但小程序有兼容性问题,被迫这样实现
- renderTextMessage(message) {
- return '<span>' + this.emoji.decoder.decode(message.payload.text) + '</span>'
- },
- //像微信那样显示时间,如果有几分钟没发消息了,才显示时间
- //todo:本不需要该方法,可以在标签里完成,但小程序有兼容性问题,被迫这样实现
- renderMessageDate(message, index) {
- if (index === 0) {
- return formatDate(message.timestamp)
- } else {
- if (message.timestamp - this.history.messages[index - 1].timestamp > 5 * 60 * 1000) {
- return formatDate(message.timestamp)
- }
- }
- return '';
- },
- initGoEasyListeners() {
- // 监听私聊消息
- GoEasy.im.on(GoEasy.IM_EVENT.PRIVATE_MESSAGE_RECEIVED, this.onMessageReceived);
- //监听消息删除
- GoEasy.im.on(GoEasy.IM_EVENT.MESSAGE_DELETED, this.onMessageDeleted);
- // 监听断网重连
- GoEasy.im.on(GoEasy.IM_EVENT.HISTORY_EXPIRED, this.onHistoryExpired);
- },
- onMessageReceived (message) {
- let senderId = message.senderId;
- let receiverId = message.receiverId;
- let friendId = this.currentUser.id === senderId ? receiverId : senderId;
- if (friendId === this.friend.ID) {
- this.history.messages.push(message);
- //聊天时,收到消息标记为已读
- this.markPrivateMessageAsRead();
- //收到新消息,是滚动到最底部
- this.scrollToBottom();
- }
- },
- onMessageDeleted (deletedMessages) {
- deletedMessages.forEach(message => {
- let senderId = message.senderId;
- let receiverId = message.receiverId;
- let friendId = this.currentUser.id === senderId ? receiverId : senderId;
- if (friendId === this.friend.ID) {
- let index = this.history.messages.indexOf(message);
- if (index > -1) {
- this.history.messages.splice(index, 1);
- }
- }
- });
- },
- onHistoryExpired() {
- this.history.messages = [];
- this.loadHistoryMessage(true);
- },
- initialAudioPlayer () {
- this.audioPlayer.innerAudioContext = uni.createInnerAudioContext();
- this.audioPlayer.innerAudioContext.onEnded(() => {
- this.audioPlayer.playingMessage = null;
- });
- this.audioPlayer.innerAudioContext.onStop(() => {
- this.audioPlayer.playingMessage = null;
- });
- },
- initRecorderListeners() {
- recorderManager.onRecordComplete((file, duration) => {
- if (duration < 1000) {
- uni.showToast({
- icon: 'none',
- title: '录音时间太短',
- duration: 500
- });
- return;
- }
- this.toList.forEach((item,index)=>{
- this.to.id=item.id
- this.to.data.name=item.supplierName
- var num=0
- if(index == this.toList.length-1){
- num=1
- }
- GoEasy.im.createAudioMessage({
- to: this.to,
- file: file,
- notification: {
- title: this.currentUser.name + '发来一段语音',
- body: '[语音消息]', // 字段最长 50 字符
- sound: 'message',
- badge: '+1'
- },
- onProgress: function (progress) {
- console.log(progress)
- },
- onSuccess: (message) => {
- this.sendMessage(message,num);
- },
- onFailed: (e) => {
- console.log('error :', e);
- }
- });
- })
-
- });
- },
- /**
- * 核心就是设置高度,产生明确占位
- *
- * 小 (宽度和高度都小于预设尺寸)
- * 设高=原始高度
- * 宽 (宽度>高度)
- * 高度= 根据宽度等比缩放
- * 窄 (宽度<高度)或方(宽度=高度)
- * 设高=MAX height
- *
- * @param width,height
- * @returns number
- */
- getImageHeight(width, height) {
- if (width < IMAGE_MAX_WIDTH && height < IMAGE_MAX_HEIGHT) {
- return height * 2;
- } else if (width > height) {
- return (IMAGE_MAX_WIDTH / width * height) * 2;
- } else if (width === height || width < height) {
- return IMAGE_MAX_HEIGHT * 2;
- }
- },
- sendMessage(message,num) {
- if(num==1){
- this.history.messages.push(message);
- }
-
- this.scrollToBottom();
- GoEasy.im.sendMessage({
- message: message,
- onSuccess: function () {
- console.log('发送成功.', message);
- },
- onFailed: function (error) {
- if (error.code === 507) {
- console.log('发送语音/图片/视频/文件失败,没有配置OSS存储,详情参考:https://docs.goeasy.io/2.x/im/message/media/alioss');
- } else {
- console.log('发送失败:', error);
- }
- }
- });
- },
- sendTextMessage() {
- if (this.text.trim() !== '') {
- let body = this.text;
- if (this.text.length >= 50) {
- body = this.text.substring(0, 30) + '...';
- }
-
- this.toList.forEach((item,index)=>{
- this.to.id=item.id
- this.to.data.name=item.supplierName
- var num=0
- if(index == this.toList.length-1){
- num=1
- }
- GoEasy.im.createTextMessage({
- text: this.text,
- to: this.to,
- notification: {
- title: this.currentUser.name + '发来一段文字',
- body: body,
- sound: 'message',
- badge: '+1'
- },
- onSuccess: (message) => {
- this.sendMessage(message,num);
- },
- onFailed: (e) => {
- console.log('error :', e);
- }
- });
- })
-
-
- }
- this.text = '';
- },
- sendVideoMessage() {
- uni.chooseVideo({
- success: (res) => {
- this.toList.forEach((item,index)=>{
- this.to.id=item.id
- this.to.data.name=item.supplierName
- var num=0
- if(index == this.toList.length-1){
- num=1
- }
- GoEasy.im.createVideoMessage({
- to: this.to,
- file: res,
- notification: {
- title: this.currentUser.name + '发来一个视频',
- body: '[视频消息]', // 字段最长 50 字符
- sound: 'message',
- badge: '+1'
- },
- onProgress: function (progress) {
- console.log(progress)
- },
- onSuccess: (message) => {
- this.otherTypesMessagePanelVisible = false;
- this.sendMessage(message,num);
- },
- onFailed: (e) => {
- console.log('error :', e);
- }
- });
-
- })
-
- }
- })
- },
- sendImageMessage() {
- uni.chooseImage({
- count: 9,
- success: (res) => {
- res.tempFiles.forEach(file => {
- this.toList.forEach((item,index)=>{
- this.to.id=item.id
- this.to.data.name=item.supplierName
- var num=0
- if(index == this.toList.length-1){
- num=1
- }
- GoEasy.im.createImageMessage({
- to: this.to,
- file: file,
- notification: {
- title: this.currentUser.name + '发来一张图片',
- body: '[图片消息]', // 字段最长 50 字符
- sound: 'message',
- badge: '+1'
- },
- onProgress: function (progress) {
- console.log(progress)
- },
- onSuccess: (message) => {
- this.otherTypesMessagePanelVisible = false;
- this.sendMessage(message,num);
- },
- onFailed: (e) => {
- console.log('error :', e);
- }
- });
-
- })
-
- })
- }
- });
- },
- sendOrderMessage(order) {
- //GoEasyIM自定义消息,实现订单发送
- GoEasy.im.createCustomMessage({
- type: 'order',
- payload: order,
- to: this.to,
- notification: {
- title: this.currentUser.name + '发来一个订单',
- body: '[订单消息]',
- sound: 'message',
- badge: '+1'
- },
- onSuccess: (message) => {
- this.otherTypesMessagePanelVisible = false;
- this.sendMessage(message);
- },
- onFailed: (e) => {
- console.log('error :', e);
- }
- });
- this.orderList.visible = false;
- },
- showActionPopup(message) {
- const MAX_RECALLABLE_TIME = 3 * 60 * 1000; //3分钟以内的消息才可以撤回
- this.messageSelector.messages = [message];
- if ((Date.now() - message.timestamp) < MAX_RECALLABLE_TIME && message.senderId === this.currentUser.id && message.status === 'success') {
- this.actionPopup.recallable = true;
- } else {
- this.actionPopup.recallable = false;
- }
- this.actionPopup.visible = true;
- },
- hideActionPopup () {
- this.actionPopup.visible = false;
- this.actionPopup.message = null;
- },
- deleteSingleMessage() {
- uni.showModal({
- content: '确认删除?',
- success: (res) => {
- this.actionPopup.visible = false;
- if (res.confirm) {
- this.deleteMessage();
- }
- },
- })
- },
- deleteMultipleMessages() {
- if (this.messageSelector.messages.length > 0) {
- uni.showModal({
- content: '确认删除?',
- success: (res) => {
- this.messageSelector.visible = false;
- if (res.confirm) {
- this.deleteMessage();
- }
- },
- })
- }
- },
- deleteMessage() {
- GoEasy.im.deleteMessage({
- messages: this.messageSelector.messages,
- onSuccess: (result) => {
- this.messageSelector.messages.forEach(message => {
- let index = this.history.messages.indexOf(message);
- if (index > -1) {
- this.history.messages.splice(index, 1);
- }
- });
- this.messageSelector.messages = [];
- },
- onFailed: (error) => {
- console.log('error:', error);
- }
- });
- },
- recallMessage() {
- this.actionPopup.visible = false;
- GoEasy.im.recallMessage({
- messages: this.messageSelector.messages,
- onSuccess: () => {
- console.log('撤回成功');
- },
- onFailed: (error) => {
- console.log('撤回失败,error:', error);
- }
- });
- },
- editRecalledMessage(text) {
- if (this.audio.visible) {
- this.audio.visible = false;
- }
- this.text = text;
- },
- showCheckBox() {
- this.messageSelector.messages = [];
- this.messageSelector.visible = true;
- this.actionPopup.visible = false;
- },
- selectMessages(e) {
- const selectedMessageIds = e.detail.value;
- let selectedMessages = [];
- this.history.messages.forEach(message => {
- if (selectedMessageIds.includes(message.messageId)) {
- selectedMessages.push(message);
- }
- })
- this.messageSelector.messages = selectedMessages;
- },
- loadHistoryMessage(scrollToBottom) {//历史消息
- this.history.loading = true;
- let lastMessageTimeStamp = null;
- let lastMessage = this.history.messages[0];
- if (lastMessage) {
- lastMessageTimeStamp = lastMessage.timestamp;
- }
- GoEasy.im.history({
- id: this.friend.ID,
- type: GoEasy.IM_SCENE.PRIVATE,
- lastTimestamp: lastMessageTimeStamp,
- limit: 10,
- onSuccess: (result) => {
- uni.stopPullDownRefresh();
- this.history.loading = false;
- let messages = result.content;
- if (messages.length === 0) {
- this.history.allLoaded = true;
- } else {
- if (lastMessageTimeStamp) {
- this.history.messages = messages.concat(this.history.messages);
- } else {
- this.history.messages = messages;
- }
- if (messages.length < 10) {
- this.history.allLoaded = true;
- }
- if (scrollToBottom) {
- this.scrollToBottom();
- //收到的消息设置为已读
- this.markPrivateMessageAsRead();
- }
- }
- },
- onFailed: (error) => {
- //获取失败
- console.log('获取历史消息失败:', error);
- uni.stopPullDownRefresh();
- this.history.loading = false;
- }
- });
- },
- //语音录制按钮和键盘输入的切换
- switchAudioKeyboard() {
- if (!this.audio.visible) {
- recorderManager.authorize().then(() => {
- console.log('录音权限获取成功');
- this.audio.visible = true;
- }).catch((err) => {
- console.log('err:', err)
- uni.showModal({
- title: '获取录音权限失败',
- content: '请先打开麦克风权限'
- });
- });
- } else {
- this.audio.visible = false;
- }
- },
- onRecordStart() {
- recorderManager.start();
- },
- onRecordEnd() {
- recorderManager.stop();
- },
- showImageFullScreen(e) {
- let imagesUrl = [e.currentTarget.dataset.url];
- uni.previewImage({
- urls: imagesUrl
- });
- },
- playVideo(e) {
- this.videoPlayer.visible = true;
- this.videoPlayer.url = e.currentTarget.dataset.url;
- this.$nextTick(() => {
- this.videoPlayer.context.requestFullScreen({
- direction: 0
- });
- this.videoPlayer.context.play();
- });
- },
- playAudio (audioMessage) {
- let playingMessage = this.audioPlayer.playingMessage;
- if (playingMessage) {
- this.audioPlayer.innerAudioContext.stop();
- // 如果点击的消息正在播放,就认为是停止播放操作
- if (playingMessage === audioMessage) {
- return;
- }
- }
- this.audioPlayer.playingMessage = audioMessage;
- this.audioPlayer.innerAudioContext.src = audioMessage.payload.url;
- this.audioPlayer.innerAudioContext.play();
- },
- onVideoFullScreenChange(e) {
- //当退出全屏播放时,隐藏播放器
- if (this.videoPlayer.visible && !e.detail.fullScreen) {
- this.videoPlayer.visible = false;
- this.videoPlayer.context.stop();
- }
- },
- messageInputFocusin() {
- this.otherTypesMessagePanelVisible = false;
- this.emoji.visible = false;
- },
- switchEmojiKeyboard() {
- this.emoji.visible = !this.emoji.visible;
- this.otherTypesMessagePanelVisible = false;
- },
- showOtherTypesMessagePanel() {
- this.otherTypesMessagePanelVisible = !this.otherTypesMessagePanelVisible;
- this.emoji.visible = false;
- },
- chooseEmoji(emojiKey) {
- this.text += emojiKey;
- },
- showOrderMessageList() {
- this.orderList.orders = restApi.getOrderList();
- this.orderList.visible = true;
- },
- hideOrderMessageList() {
- this.orderList.visible = false;
- },
- privateCall() {
- uni.showActionSheet({
- itemList: ['视频通话', '音频通话'],
- success: (res) => {
- const mediaType = res.tapIndex === 0 ? 1 : 0;
- const notificationBody = res.tapIndex === 0 ? '邀请你视频通话' : '邀请你语音通话';
- GRTC.call({
- calleeId: this.friend.ID,
- mediaType: mediaType,
- notification: {
- title: this.currentUser.name,
- body: notificationBody,
- sound: 'ring',
- badge: '+1'
- },
- }).then(() => {
- uni.navigateTo({
- url: `./rtc/private/dial`,
- })
- }).catch((error)=>{
- console.log("呼叫失败:", error);
- uni.showToast({
- icon: "error",
- title: "呼叫失败:" + error,
- duration: 2000
- })
- })
- },
- fail: (res) => {
- console.log(res.errMsg);
- }
- });
- },
- scrollToBottom() {
- this.$nextTick(() => {
- uni.pageScrollTo({
- scrollTop: 2000000,
- duration: 0
- });
- });
- },
- markPrivateMessageAsRead() {
- GoEasy.im.markMessageAsRead({
- id: this.to.id,
- type: this.to.type,
- onSuccess: function () {
- console.log('标记私聊已读成功');
- },
- onFailed: function (error) {
- console.log("标记私聊已读失败", error);
- }
- });
- }
- }
- }
- </script>
- <style scoped>
- @import url('../static/style/chatInterface.css');
- .gongyingshangBox{
- background: #ffffff;
-
- padding: 24rpx;
- color: #333;
- }
- .tbox{
- padding-top: 30rpx;
- }
- .messageTxt{
- max-width: 500rpx;
- padding: 24rpx;
- background: #ffffff;
- border-radius: 10rpx;
- margin-top: 24rpx;
- text-align: right;
-
- }
- .messageImgBox{
- width: 500rpx;
- margin-top: 24rpx;
- background: #ffffff;
- border-radius: 10rpx;
- overflow: hidden;
- }
- .messageImg{
- width: 500rpx;
- }
- .messageLine{
- padding-left: 200rpx;
- }
- </style>
|