Browse Source

bug修改

twt 1 month ago
parent
commit
8e3bcc1ed8
11 changed files with 1024 additions and 55 deletions
  1. 1 0
      main.js
  2. 11 3
      pages.json
  3. 14 14
      pages/conversations.vue
  4. 16 6
      pages/editPass.vue
  5. 26 5
      pages/inquiry.vue
  6. 6 5
      pages/mine.vue
  7. 32 5
      pages/privateChat.vue
  8. 837 0
      pages/privateChatG.vue
  9. 35 15
      pages/qunfa.vue
  10. BIN
      static/img/icon_me.png
  11. 46 2
      utils/request.js

+ 1 - 0
main.js

@@ -4,6 +4,7 @@ import GoEasy from '@/uni_modules/GOEASY-IM/js_sdk/goeasy-2.13.21.esm.min.js'
 import GRTC from './lib/goeasy-rtc-0.3.7.esm.min.js'
 import request from '@/utils/request.js'
 Vue.prototype.$http = request.http
+Vue.prototype.$http2 = request.http2
 Vue.prototype.$request =request
 GoEasy.init({
     host:"hangzhou.goeasy.io",//应用所在的区域地址: 【hangzhou.goeasy.io |singapore.goeasy.io】

+ 11 - 3
pages.json

@@ -42,19 +42,27 @@
     {
       "path": "pages/privateChat",
       "style": {
-        "navigationBarTitleText": "uni-app",
+        "navigationBarTitleText": "",
         "navigationBarBackgroundColor": "#F1F1F1",
         "enablePullDownRefresh": true
       }
     },
 	{
-	  "path": "pages/qunfa",
+	  "path": "pages/privateChatG",
 	  "style": {
-	    "navigationBarTitleText": "群发",
+	    "navigationBarTitleText": "",
 	    "navigationBarBackgroundColor": "#F1F1F1",
 	    "enablePullDownRefresh": true
 	  }
 	},
+	{
+	  "path": "pages/qunfa",
+	  "style": {
+	    "navigationBarTitleText": "群发",
+	    "navigationBarBackgroundColor": "#F1F1F1"
+	    //"enablePullDownRefresh": true
+	  }
+	},
 	{
 	  "path": "pages/inquiry",
 	  "style": {

+ 14 - 14
pages/conversations.vue

@@ -6,7 +6,7 @@
 	  		<view class="navLeft" ><!-- @click="goBack" -->
 	  			<!-- <image src="../static/img/nav_icon_back.png" mode="aspectFit" class="backImg" @click="goback"></image> -->
 	  		</view>
-	  		<view class="title">询价</view>
+	  		<view class="title">{{loginInfo.supplierName}}</view>
 	  		<view class="goVin" ></view>
 	  	</view>
 	  </view>
@@ -28,10 +28,10 @@
             <view class="item-info-bottom-item">
               <view class="item-info-top_content" v-if="!conversation.lastMessage.recalled">
                 <text class="unread-text">
-                  {{ conversation.lastMessage.read === false && conversation.lastMessage.senderId === currentUser.id ? '[未读]' : '' }}
+                  {{ conversation.lastMessage.read === false && conversation.lastMessage.senderId === currentUser.userId ? '[未读]' : '' }}
                 </text>
 
-                <text v-if="conversation.lastMessage.senderId === currentUser.id">我: </text>
+                <text v-if="conversation.lastMessage.senderId === currentUser.userId">我: </text>
                 <text v-else>{{ conversation.type === 'group' ? conversation.lastMessage.senderData.name : conversation.data.name }}: </text>
                 <text v-if="conversation.lastMessage.type === 'text'">{{ conversation.lastMessage.payload.text }}</text>
                 <text v-else-if="conversation.lastMessage.type === 'video'">[视频消息]</text>
@@ -45,7 +45,7 @@
               </view>
               <view class="item-info-top_content" v-else>
                 <text>
-                  {{conversation.lastMessage.recaller.id === currentUser.id ? '你' : conversation.lastMessage.recaller.data.name}}撤回了一条消息
+                  {{conversation.lastMessage.recaller.id === currentUser.userId ? '你' : conversation.lastMessage.recaller.data.name}}撤回了一条消息
                 </text>
               </view>
               <view class="item-info-bottom_action" @click.stop="showAction(conversation)"></view>
@@ -93,11 +93,11 @@
 	},
     onShow() {
 	  this.loginInfo=uni.getStorageSync('loginInfo');
-	  uni.setNavigationBarTitle({
+	  /* uni.setNavigationBarTitle({
 		  title:this.loginInfo.supplierName
-	  });
-      uni.$currentUser = uni.getStorageSync('currentUser');
-      this.currentUser = uni.$currentUser;
+	  }); */
+     // uni.$currentUser = uni.getStorageSync('loginInfo');
+      this.currentUser = uni.getStorageSync('loginInfo') // uni.$currentUser;
 	  console.log(this.currentUser)
       if (!this.currentUser) {
         uni.navigateTo({ url: './login' });
@@ -121,10 +121,10 @@
       connectGoEasy() {
         uni.showLoading();
         GoEasy.connect({
-          id: this.currentUser.id,
+          id: this.currentUser.userId,
           data: {
-            name: this.currentUser.name,
-            avatar: this.currentUser.avatar
+            name: this.currentUser.supplierName,
+            avatar: ''
           },
           onSuccess: () => {
             console.log('GoEasy connect successfully.')
@@ -271,7 +271,7 @@
       },
       chat(conversation) {
         let path = conversation.type === GoEasy.IM_SCENE.PRIVATE ?
-          './privateChat?to=' + conversation.userId :
+          './privateChatG?to=' + conversation.userId :
           './groupChat?to=' + conversation.groupId;
 		  var friend={
 			  id:conversation.userId,
@@ -466,13 +466,13 @@
   		border-bottom: 1px solid #eaeaea;
   	}
   .goVin{
-  	width: 200rpx;
+  	width: 2rpx;
   	color: #3F90F7;
   	text-align: right;
   	padding-right: 20rpx;
   }
   .navLeft{
-  	width: 200rpx;
+  	width: 2rpx;
   	padding-left: 20rpx;
   }
   .navBox{

+ 16 - 6
pages/editPass.vue

@@ -3,7 +3,7 @@
 		<view class="line">
 			<view class="input-label">新密码</view>
 			<view>
-				<input type="password" v-model="userPwd1" class="input-field" placeholder="请输入当前密码"/>
+				<input type="password" v-model="userPwd1" class="input-field" placeholder="请输入密码"/>
 			</view>
 		</view>
 		<view class="line">
@@ -26,7 +26,7 @@
 			}
 		},
 		onLoad() {
-          this.userId=uni.getStorageSync('users').userId
+          this.userId=uni.getStorageSync('loginInfo').userId
 		},
 		methods: {
           submitFn(){
@@ -44,13 +44,23 @@
 			    },'POST').then(res => {
 					if(res.code==0){
 						uni.showToast({
-								  icon: 'none',
-								  title: '修改成功',
-								  duration: 3000
-								});
+						  icon: 'none',
+						  title: '修改成功',
+						  duration: 3000
+						});
+						setTimeout(function() {
+							uni.navigateBack(-1)
+						}, 1000);
+					
 						/* uni.navigateTo({
 											 url: './login'
 						}) */
+					}else{
+						uni.showToast({
+						  icon: 'none',
+						  title: res.msg,
+						  duration: 3000
+						});
 					}
 					
 			    }) 

+ 26 - 5
pages/inquiry.vue

@@ -14,10 +14,15 @@
 		<view style="height: 44px;"></view>
 		<scroll-view class="conversations" scroll-y="true">
 		  <view @click="setClipboardData">token:{{token}}</view>
+		  <view>
+			<!--  <video src="https://66-goesay.oss-accelerate.aliyuncs.com/goeasy-im-dmsIMTest/3369051043664274_uni-video.mp4" id="videoPlayer"
+			         ></video> -->
+		  </view>
 		  <view v-if="conversations.length > 0">
 		    <view class="scroll-item" v-for="(conversation, key) in conversations" :key="key">
 		      <view class="item-head">
-		        <image :src="conversation.data.avatar" class="head-icon"></image>
+		       <!-- <image :src="conversation.data.avatar" class="head-icon"></image> -->
+			    <image src="/static/img/icon_me.png" class="head-icon"></image>
 		        <view class="item-head_unread" v-if="conversation.unread">{{ conversation.unread }}</view>
 		      </view>
 		      <view class="scroll-item_info" @click="chat(conversation)">
@@ -94,11 +99,13 @@
 	onLoad(opt) {
 		  this.token=opt.token
 		  uni.setStorageSync('token',  this.token);
-		this.iStatusBarHeight = uni.getSystemInfoSync().statusBarHeight;
-		 this.imLoginUrl()
+		  this.iStatusBarHeight = uni.getSystemInfoSync().statusBarHeight;
+		  this.imLoginUrl()
 	},
     onShow() {
-	
+	  if(this.token){
+		  this.imLoginUrl()
+	  }
       /* uni.$currentUser = uni.getStorageSync('currentUser');
       this.currentUser = uni.$currentUser;
 	  console.log(this.currentUser)
@@ -150,6 +157,19 @@
 		    }
 		  });
 	  },
+	  chooseImage(){
+		  uni.chooseImage({
+		  	count: 6, //默认9
+		  	sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+		  	sourceType: ['album'], //从相册选择
+		  	success: function (res) {
+		  		console.log(JSON.stringify(res.tempFilePaths));
+		  	},
+			fail(err) {
+				
+			}
+		  });
+	  },
 	  imLoginUrl(){
 	  			   this.$http('imSys/imLoginUrl', {
 	  			      token:this.token,
@@ -164,7 +184,7 @@
 	  					  this.currentUser=users
 	  					//  this.connectGoEasy()
 	  					 uni.setStorageSync('users', users);
-						
+						 uni.setStorageSync('currentUser', users);
 						 console.log(this.currentUser)
 						 if (!this.currentUser) {
 						   uni.navigateTo({ url: './login' });
@@ -326,6 +346,7 @@
         })
       },
       chat(conversation) {
+		  console.log(conversation)
         let path = conversation.type === GoEasy.IM_SCENE.PRIVATE ?
           './privateChat?to=' + conversation.userId :
           './groupChat?to=' + conversation.groupId;

+ 6 - 5
pages/mine.vue

@@ -3,7 +3,7 @@
     <view class="top">
 		<view class="topBox">
 			<image src="/static/img/pic_def_ava@2x.png" mode="" class="touxiang"></image>
-			 <view class="name">{{ currentUser.name }}</view>
+			 <view class="name">{{ currentUser.supplierName }}</view>
 		</view>
      <!-- <image :src="currentUser.avatar"></image> -->
 	 
@@ -62,11 +62,11 @@
       }
     },
     onShow() {
-      this.currentUser = uni.getStorageSync("currentUser")
+      this.currentUser = uni.getStorageSync("loginInfo")
 	  var token= uni.getStorageSync("accessToken")
 	  this.token=token
 	  if(token){
-	  	 //this.imLoginUrl()
+	  	 this.imLoginUrl()
 	  }else{
 		  uni.navigateTo({
 		    url: './login'
@@ -75,8 +75,9 @@
     },
     methods: {
 		imLoginUrl(){
-			this.$http('imSys/imLoginUrl', {
+			this.$http2('imSys/imLoginUrl', {
 			   token:this.token,
+			   type:1
 			  },'POST').then(res => {
 			 	  console.log(res)	
 				  if(res.code!=0){
@@ -105,7 +106,7 @@
 			})
 		},
       logout() {
-		  uni.removeStorageSync('currentUser');
+		  uni.clearStorageSync();
 		  uni.navigateTo({
 		    url: './login'
 		  })

+ 32 - 5
pages/privateChat.vue

@@ -183,6 +183,16 @@
         </view>
       </view>
     </view>
+	
+	<view class="videoBox" v-if="videoShow"  @click="videoShow=false">
+		
+		<view style="width: 100%;" @click.stop="">
+			<video :src="videoPlayer.url"  id="videoPlayer"
+			         ></video>
+		</view>
+		
+	</view>
+	
   </view>
 </template>
 
@@ -258,7 +268,8 @@
         messageSelector: {
           visible: false,
           messages: []
-        }
+        },
+		videoShow:false
       }
     },
     onLoad(options) {
@@ -489,6 +500,7 @@
         })
       },
       sendImageMessage() {
+		
         uni.chooseImage({
           count: 9,
           success: (res) => {
@@ -699,14 +711,15 @@
         });
       },
       playVideo(e) {
-        this.videoPlayer.visible = true;
+       // this.videoPlayer.visible = true;
+	   this.videoShow=true
         this.videoPlayer.url = e.currentTarget.dataset.url;
-        this.$nextTick(() => {
+       /* this.$nextTick(() => {
           this.videoPlayer.context.requestFullScreen({
             direction: 0
           });
           this.videoPlayer.context.play();
-        });
+        }); */
       },
       playAudio (audioMessage) {
         let playingMessage = this.audioPlayer.playingMessage;
@@ -808,6 +821,20 @@
   }
 </script>
 
-<style>
+<style scoped>
   @import url('../static/style/chatInterface.css');
+  .videoBox{
+	  position: fixed;
+	  top: 0;
+	  left: 0;
+	  background: rgba(0,0,0,0.5);
+	  width: 100%;
+	  height: 100%;
+	  display: flex;
+	  align-items: center;
+  }
+	  
+  #videoPlayer{
+	  width: 100%;
+  }
 </style>

+ 837 - 0
pages/privateChatG.vue

@@ -0,0 +1,837 @@
+<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>
+
+      <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.userId" 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.userId}">
+              <view class="avatar">
+                <!-- <image :src="message.senderId === currentUser.id? currentUser.avatar : friend.avatar"></image> -->
+                <image src="/static/img/touxiang.png"></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 v-if="message.type === 'car'" class="text-content" @click="gocar">
+						  <view class="mVin">{{message.payload.vin}}</view>
+						   <view class="mcar">{{message.payload.carModel}}</view>
+				  </view>
+                </view>
+                <view v-if="message.senderId === currentUser.userId" :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 class="videoBox" v-if="videoShow"  @click="videoShow=false">
+		
+		<view style="width: 100%;" @click.stop="">
+			<video :src="videoPlayer.url"  id="videoPlayer"
+			         ></video>
+		</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: []
+        },
+		videoShow:false
+      }
+    },
+    onLoad(options) {
+      //聊天对象
+      let id = options.to;
+	  this.friend = uni.getStorageSync("friend");
+      //this.friend = restApi.findUserById(id);
+      //this.currentUser = uni.$currentUser;
+	  this.currentUser = uni.getStorageSync("loginInfo");
+	  
+      this.to = {
+        id: this.friend.id,
+        type: GoEasy.IM_SCENE.PRIVATE,
+        data: {
+          name: this.friend.supplierName,
+          avatar: '/static/images/Avatar-1.png'
+        }
+      };
+
+      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.supplierName });
+    },
+    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: {
+      //渲染文本消息,如果包含表情,替换为图片
+      //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.userId === 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.userId === 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;
+          }
+          GoEasy.im.createAudioMessage({
+            to: this.to,
+            file: file,
+            notification: {
+              title: this.currentUser.supplierName + '发来一段语音',
+              body: '[语音消息]',		// 字段最长 50 字符
+              sound: 'message',
+              badge: '+1'
+            },
+            onProgress: function (progress) {
+              console.log(progress)
+            },
+            onSuccess: (message) => {
+              this.sendMessage(message);
+            },
+            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) {
+        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) + '...';
+          }
+          GoEasy.im.createTextMessage({
+            text: this.text,
+            to: this.to,
+            notification: {
+              title: this.currentUser.supplierName + '发来一段文字',
+              body: body,
+              sound: 'message',
+              badge: '+1'
+            },
+            onSuccess: (message) => {
+              this.sendMessage(message);
+            },
+            onFailed: (e) => {
+              console.log('error :', e);
+            }
+          });
+        }
+        this.text = '';
+      },
+      sendVideoMessage() {
+        uni.chooseVideo({
+          success: (res) => {
+            GoEasy.im.createVideoMessage({
+              to: this.to,
+              file: res,
+              notification: {
+                title: this.currentUser.supplierName + '发来一个视频',
+                body: '[视频消息]',		// 字段最长 50 字符
+                sound: 'message',
+                badge: '+1'
+              },
+              onProgress: function (progress) {
+                console.log(progress)
+              },
+              onSuccess: (message) => {
+                this.otherTypesMessagePanelVisible = false;
+                this.sendMessage(message);
+              },
+              onFailed: (e) => {
+                console.log('error :', e);
+              }
+            });
+          }
+        })
+      },
+      sendImageMessage() {
+        uni.chooseImage({
+          count: 9,
+          success: (res) => {
+            res.tempFiles.forEach(file => {
+              GoEasy.im.createImageMessage({
+                to: this.to,
+                file: file,
+                notification: {
+                  title: this.currentUser.supplierName + '发来一张图片',
+                  body: '[图片消息]',		// 字段最长 50 字符
+                  sound: 'message',
+                  badge: '+1'
+                },
+                onProgress: function (progress) {
+                  console.log(progress)
+                },
+                onSuccess: (message) => {
+                  this.otherTypesMessagePanelVisible = false;
+                  this.sendMessage(message);
+                },
+                onFailed: (e) => {
+                  console.log('error :', e);
+                }
+              });
+            })
+          }
+        });
+      },
+      sendOrderMessage(order) {
+        //GoEasyIM自定义消息,实现订单发送
+        GoEasy.im.createCustomMessage({
+          type: 'order',
+          payload: order,
+          to: this.to,
+          notification: {
+            title: this.currentUser.supplierName + '发来一个订单',
+            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.userId && 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.videoShow=true
+        /* 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');
+  .videoBox{
+  	  position: fixed;
+  	  top: 0;
+  	  left: 0;
+  	  background: rgba(0,0,0,0.5);
+  	  width: 100%;
+  	  height: 100%;
+  	  display: flex;
+  	  align-items: center;
+  }
+  	  
+  #videoPlayer{
+  	  width: 100%;
+  }
+</style>

+ 35 - 15
pages/qunfa.vue

@@ -102,9 +102,9 @@
 					   <view class="mcar">{{message.payload.carModel}}</view>
 				  </view>
                 </view>
-                <view v-if="message.senderId === currentUser.id" :class="message.read ?'message-read':'message-unread'">
+                <!-- <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>
@@ -199,6 +199,14 @@
         </view>
       </view>
     </view>
+	<view class="videoBox" v-if="videoShow"  @click="videoShow=false">
+		
+		<view style="width: 100%;" @click.stop="">
+			<video :src="videoPlayer.url"  id="videoPlayer"
+			         ></video>
+		</view>
+		
+	</view>
   </view>
 </template>
 
@@ -275,16 +283,12 @@
           visible: false,
           messages: []
         },
-		toList:[
-			"A69257B1-8603-4BCD-9D32-07C18E6E14D7",
-			"1292F5DA-793B-4549-844E-C5F606869D0C",
-			"421DB63C-B274-478C-8442-CD43AD052A7B",
-			"AB6D0669-A5F8-423F-A6FE-81AC12084AFC"
-		],
+		toList:[],
 		currentUser:'',
 		nLevelIDs:'',
 		vin:'',
 		carModelInfo:'',
+		videoShow:false
       }
     },
     onLoad(options) {
@@ -314,16 +318,17 @@
       }; */
 	   this.currentUser = uni.getStorageSync('currentUser')
 	   //this.connectGoEasy()
+	   this.toList=uni.getStorageSync('supplierlist')
 	  this.to = {
-	    id: 'A69257B1-8603-4BCD-9D32-07C18E6E14D7',
+	    id: this.toList[0].id,
 	    type: GoEasy.IM_SCENE.PRIVATE,
 	    data: {
-	      name: "群发测试",
+	      name: this.toList[0].supplierName,
 	      avatar: '/static/images/Avatar-1.png'
 	    }
 	  };
 	  
-	  this.toList=uni.getStorageSync('supplierlist')
+	  
 
       this.initGoEasyListeners();
       // 语音播放器
@@ -464,7 +469,7 @@
         });
       },
       onHistoryExpired() {
-        this.history.messages = [];
+       // this.history.messages = [];
         this.loadHistoryMessage(true);
       },
       initialAudioPlayer () {
@@ -884,14 +889,15 @@
         });
       },
       playVideo(e) {
-        this.videoPlayer.visible = true;
+        //this.videoPlayer.visible = true;
         this.videoPlayer.url = e.currentTarget.dataset.url;
-        this.$nextTick(() => {
+		 this.videoShow=true
+        /* this.$nextTick(() => {
           this.videoPlayer.context.requestFullScreen({
             direction: 0
           });
           this.videoPlayer.context.play();
-        });
+        }); */
       },
       playAudio (audioMessage) {
         let playingMessage = this.audioPlayer.playingMessage;
@@ -1030,4 +1036,18 @@
 	     background: #F6F6F6;
 		 padding: 6rpx 24rpx;
   }
+  .videoBox{
+  	  position: fixed;
+  	  top: 0;
+  	  left: 0;
+  	  background: rgba(0,0,0,0.5);
+  	  width: 100%;
+  	  height: 100%;
+  	  display: flex;
+  	  align-items: center;
+  }
+  	  
+  #videoPlayer{
+  	  width: 100%;
+  }
 </style>

BIN
static/img/icon_me.png


+ 46 - 2
utils/request.js

@@ -1,5 +1,5 @@
 //测试地址
-//const baseUrl = 'http://192.168.1.9:20187/'
+//const baseUrl = 'http://192.168.1.25:20187/'
 const baseUrl = 'http://dms.66km.com.cn/'
 //正式
 //const baseUrl = 'https://apidms.66km.com/'
@@ -60,6 +60,50 @@ const http = (url = '', date = {}, type = 'POST', header = {
         }) 
     });
 }
+
+const http2 = (url = '', date = {}, type = 'POST', header = {
+}) => {
+    return new Promise((resolve, reject) => {
+		header={};
+		var imAccessToken= uni.getStorageSync("accessToken")
+		var token= uni.getStorageSync("token")
+		//token='431A242A-0694-4D6F-9657-C31AD25E7D15'
+		if(token){
+			header['token']=imAccessToken;
+			//header['uid']=wxOpenData.loginInfo.uid; 
+		} 
+ 
+		header['Content-Type']='application/x-www-form-urlencoded';
+		//console.log(header)
+        uni.request({
+            method: type,
+            url: baseUrl + url,
+            data: date,
+            header: header,
+            dataType: 'json',         
+        }).then((response) => {
+          
+            let [error, res] = response;
+		 
+			if(res.data.code==401||res.data.code==403){
+				
+			}else if(res.data.code==409){
+				
+			}
+			if(res.data.code==1){
+				  uni.showToast({
+				      title: res.data.msg,
+				  	 icon:'none',
+				      duration: 4000,
+				  });
+			}
+            resolve(res.data);
+        }).catch(error => {
+            let [err, res] = error;
+            reject(err)
+        }) 
+    });
+}
 // 请求图片流
 const httpBinary = (url = '', date = {}, type = 'POST', header = {
 }) => {
@@ -144,5 +188,5 @@ function refresh(url,date,type,header){
 }
 
 export default {
-	http,baseUrl,httpBinary
+	http,baseUrl,httpBinary,http2
 }