聊天页面处理没有聊天内容展示
This commit is contained in:
188
components/tki-file-manager/tki-file-manager.vue
Normal file
188
components/tki-file-manager/tki-file-manager.vue
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
<template xlang="wxml" minapp="mpvue">
|
||||||
|
<view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'tki-file-manager',
|
||||||
|
props: {},
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
_openFile() {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
if (plus.os.name.toLowerCase() != "android") {
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '仅支持Android平台',
|
||||||
|
success: function(res) {}
|
||||||
|
});
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
let that = this
|
||||||
|
// java 代码来自 http://www.cnblogs.com/panhouye/archive/2017/04/23/6751710.html
|
||||||
|
let main = plus.android.runtimeMainActivity();
|
||||||
|
let Intent = plus.android.importClass("android.content.Intent");
|
||||||
|
|
||||||
|
//
|
||||||
|
let fileIntent = new Intent(Intent.ACTION_GET_CONTENT)
|
||||||
|
//fileIntent.setType(“image/*”);//选择图片
|
||||||
|
//fileIntent.setType(“audio/*”); //选择音频
|
||||||
|
//fileIntent.setType(“video/*”); //选择视频 (mp4 3gp 是android支持的视频格式)
|
||||||
|
//fileIntent.setType(“video/*;image/*”);//同时选择视频和图片
|
||||||
|
fileIntent.setType("*/*"); //无类型限制
|
||||||
|
fileIntent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
|
main.startActivityForResult(fileIntent, 1);
|
||||||
|
// 获取回调
|
||||||
|
main.onActivityResult = function(requestCode, resultCode, data) {
|
||||||
|
let Activity = plus.android.importClass("android.app.Activity");
|
||||||
|
let ContentUris = plus.android.importClass("android.content.ContentUris");
|
||||||
|
let Cursor = plus.android.importClass("android.database.Cursor");
|
||||||
|
let Uri = plus.android.importClass("android.net.Uri");
|
||||||
|
let Build = plus.android.importClass("android.os.Build");
|
||||||
|
let Environment = plus.android.importClass("android.os.Environment");
|
||||||
|
let DocumentsContract = plus.android.importClass("android.provider.DocumentsContract");
|
||||||
|
let MediaStore = plus.android.importClass("android.provider.MediaStore");
|
||||||
|
// 给系统导入 contentResolver
|
||||||
|
let contentResolver = main.getContentResolver()
|
||||||
|
plus.android.importClass(contentResolver);
|
||||||
|
// 返回路径
|
||||||
|
let path = '';
|
||||||
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
|
let uri = data.getData()
|
||||||
|
|
||||||
|
if ("file" == uri.getScheme().toLowerCase()) { //使用第三方应用打开
|
||||||
|
path = uri.getPath();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) { //4.4以后
|
||||||
|
path = getPath(this, uri);
|
||||||
|
} else { //4.4以下下系统调用方法
|
||||||
|
path = getRealPathFromURI(uri)
|
||||||
|
}
|
||||||
|
// 回调
|
||||||
|
that.$emit('result', path)
|
||||||
|
}
|
||||||
|
// 4.4 以上 从Uri 获取文件绝对路径
|
||||||
|
function getPath(context, uri) {
|
||||||
|
let isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
||||||
|
let scheme = uri.getScheme().toLowerCase()
|
||||||
|
|
||||||
|
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
|
||||||
|
// ExternalStorageProvider
|
||||||
|
if (isExternalStorageDocument(uri)) {
|
||||||
|
let docId = DocumentsContract.getDocumentId(uri);
|
||||||
|
let split = docId.split(":");
|
||||||
|
let type = split[0];
|
||||||
|
// 如果是手机内部存储
|
||||||
|
if ("primary" == type.toLowerCase()) {
|
||||||
|
return Environment.getExternalStorageDirectory() + "/" + split[1];
|
||||||
|
} else {
|
||||||
|
return '/storage/' + type + "/" + split[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// DownloadsProvider
|
||||||
|
else if (isDownloadsDocument(uri)) {
|
||||||
|
let docId = DocumentsContract.getDocumentId(uri);
|
||||||
|
let split = docId.split(":");
|
||||||
|
return split[1]
|
||||||
|
// console.log(id)
|
||||||
|
// let contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), id);
|
||||||
|
// return getDataColumn(context, contentUri, null, null);
|
||||||
|
}
|
||||||
|
// MediaProvider
|
||||||
|
else if (isMediaDocument(uri)) {
|
||||||
|
let docId = DocumentsContract.getDocumentId(uri);
|
||||||
|
let split = docId.split(":");
|
||||||
|
let type = split[0];
|
||||||
|
let contentUri = null;
|
||||||
|
if ("image" == type.toLowerCase()) {
|
||||||
|
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||||
|
} else if ("video" == type.toLowerCase()) {
|
||||||
|
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
||||||
|
} else if ("audio" == type.toLowerCase()) {
|
||||||
|
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||||
|
}
|
||||||
|
let selection = "_id=?";
|
||||||
|
let selectionArgs = [split[1]];
|
||||||
|
return getDataColumn(context, contentUri, selection, selectionArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// MediaStore (and general)
|
||||||
|
else if ("content" == scheme) {
|
||||||
|
return getDataColumn(context, uri, null, null);
|
||||||
|
}
|
||||||
|
// File
|
||||||
|
else if ("file" == scheme) {
|
||||||
|
return uri.getPath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 4.4 以下 获取 绝对路径
|
||||||
|
function getRealPathFromURI(uri) {
|
||||||
|
let res = null
|
||||||
|
let proj = [MediaStore.Images.Media.DATA]
|
||||||
|
let cursor = contentResolver.query(uri, proj, null, null, null);
|
||||||
|
if (null != cursor && cursor.moveToFirst()) {
|
||||||
|
;
|
||||||
|
let column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
||||||
|
res = cursor.getString(column_index);
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
// 通过uri 查找出绝对路径
|
||||||
|
function getDataColumn(context, uri, selection, selectionArgs) {
|
||||||
|
let cursor = null;
|
||||||
|
let column = "_data";
|
||||||
|
let projection = [column];
|
||||||
|
// let contentResolver = context.getContentResolver()
|
||||||
|
// plus.android.importClass(contentResolver);
|
||||||
|
cursor = contentResolver.query(uri, projection, selection, selectionArgs, null);
|
||||||
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
|
let column_index = cursor.getColumnIndexOrThrow(column);
|
||||||
|
return cursor.getString(column_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isExternalStorageDocument(uri) {
|
||||||
|
return "com.android.externalstorage.documents" == uri.getAuthority() ? true : false
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDownloadsDocument(uri) {
|
||||||
|
return "com.android.providers.downloads.documents" == uri.getAuthority() ? true : false
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMediaDocument(uri) {
|
||||||
|
return "com.android.providers.media.documents" == uri.getAuthority() ? true : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
// #ifndef APP-PLUS
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '仅支持Android平台',
|
||||||
|
success: function(res) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
// plus.io.resolveLocalFileSystemURL( '/storage/emulated/0', function(fs) {
|
||||||
|
// var directoryReader = fs.createReader();
|
||||||
|
// directoryReader.readEntries(function(entries) {
|
||||||
|
// var i;
|
||||||
|
// for (i = 0; i < entries.length; i++) {
|
||||||
|
// console.log(entries[i].name);
|
||||||
|
// }
|
||||||
|
// }, function(e) {
|
||||||
|
// console.log("Read entries failed: " + e.message);
|
||||||
|
// });
|
||||||
|
// }, function(e) {
|
||||||
|
// console.log("Request file system failed: " + e.message);
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
4
main.js
4
main.js
@@ -31,7 +31,7 @@ Vue.use(router)
|
|||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
Vue.prototype.$store = store
|
Vue.prototype.$store = store
|
||||||
|
|
||||||
usqlite.connect({
|
uni.$sql = usqlite.connect({
|
||||||
name: 'zh-health', // 数据库名称
|
name: 'zh-health', // 数据库名称
|
||||||
path: '_doc/health.db', // 路径
|
path: '_doc/health.db', // 路径
|
||||||
}, (err, res) => {
|
}, (err, res) => {
|
||||||
@@ -40,7 +40,7 @@ usqlite.connect({
|
|||||||
fail: () => {
|
fail: () => {
|
||||||
contactModel.create((err, res) => {
|
contactModel.create((err, res) => {
|
||||||
console.error('SQLITE 创建表格', err, res)
|
console.error('SQLITE 创建表格', err, res)
|
||||||
uni.setStorageSync('FIRST_RUN', 'X')
|
uni.setStorageSync('FIRST_RUN', true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name" : "ZH-HEALTH",
|
"name" : "ZH-HEALTH",
|
||||||
"appid" : "__UNI__C29473D",
|
"appid" : "__UNI__C29473D",
|
||||||
"description" : "ZH-HEALTH,您手上的健康管理专家",
|
"description" : "ZH-HEALTH,您手上的健康管理专家",
|
||||||
"versionName" : "1.0.20",
|
"versionName" : "1.0.22",
|
||||||
"versionCode" : 100,
|
"versionCode" : 100,
|
||||||
"transformPx" : false,
|
"transformPx" : false,
|
||||||
/* 5+App特有相关 */
|
/* 5+App特有相关 */
|
||||||
@@ -47,6 +47,7 @@
|
|||||||
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
|
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
|
||||||
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
|
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
|
||||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
|
||||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||||
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
|
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
|
||||||
|
|||||||
@@ -7,33 +7,36 @@
|
|||||||
<view class="preview" v-if="msg.objectName=='RC:TxtMsg'">
|
<view class="preview" v-if="msg.objectName=='RC:TxtMsg'">
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>{{ msg.content || '' }}
|
<text v-if="conversationType == 3">{{ user.name }}:</text>{{ msg.content || '' }}
|
||||||
</view>
|
</view>
|
||||||
<view class="preview" v-if="msg.objectName=='RC:HQVCMsg'">
|
<view class="preview" v-else-if="msg.objectName=='RC:HQVCMsg'">
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[语音]
|
<text v-if="conversationType == 3">{{ user.name }}:</text>[语音]
|
||||||
</view>
|
</view>
|
||||||
<view class="preview" v-if="msg.objectName=='RC:ImgMsg'">
|
<view class="preview" v-else-if="msg.objectName=='RC:ImgMsg'">
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[图片]
|
<text v-if="conversationType == 3">{{ user.name }}:</text>[图片]
|
||||||
</view>
|
</view>
|
||||||
<view class="preview" v-if="msg.objectName=='RC:GIFMsg'">
|
<view class="preview" v-else-if="msg.objectName=='RC:GIFMsg'">
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[表情]
|
<text v-if="conversationType == 3">{{ user.name }}:</text>[表情]
|
||||||
</view>
|
</view>
|
||||||
<view class="preview" v-if="msg.objectName=='RC:FileMsg'">
|
<view class="preview" v-else-if="msg.objectName=='RC:FileMsg'">
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[文件]
|
<text v-if="conversationType == 3">{{ user.name }}:</text>[文件]
|
||||||
</view>
|
</view>
|
||||||
<view class="preview" v-if="msg.objectName=='RC:LBSMsg'">
|
<view class="preview" v-else-if="msg.objectName=='RC:LBSMsg'">
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[位置]
|
<text v-if="conversationType == 3">{{ user.name }}:</text>[位置]
|
||||||
</view>
|
</view>
|
||||||
<view class="preview" v-if="msg.objectName=='RC:InfoNtf' && JSON.parse(msg.message).mediaType==0">
|
<view class="preview" v-else-if="msg.objectName=='RC:AudioMsg'">
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[语音通话]
|
<text v-if="conversationType == 3">{{ user.name }}:</text>[语音通话]
|
||||||
</view>
|
</view>
|
||||||
<view class="preview" v-if="msg.objectName=='RC:InfoNtf' && JSON.parse(msg.message).mediaType==1">
|
<view class="preview" v-else-if="msg.objectName=='RC:VideoMsg'">
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[视频通话]
|
<text v-if="conversationType == 3">{{ user.name }}:</text>[视频通话]
|
||||||
</view>
|
</view>
|
||||||
<view class="preview" v-if="msg.objectName=='RC:GrpNtf'">
|
<view class="preview" v-else-if="msg.objectName=='RC:GrpNtf'">
|
||||||
[{{ msg.message }}]
|
[{{ msg.message }}]
|
||||||
</view>
|
</view>
|
||||||
<view class="preview" v-if="msg.objectName=='RC:RcNtf'">
|
<view class="preview" v-else-if="msg.objectName=='RC:RcNtf'">
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text> 撤回了一条消息
|
<text v-if="conversationType == 3">{{ user.name }}:</text> 撤回了一条消息
|
||||||
</view>
|
</view>
|
||||||
|
<view class="preview" v-else>
|
||||||
|
{{ msg.objectName }}
|
||||||
|
</view>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
<view class="emoji--lay" v-show="show">
|
<view class="emoji--lay" v-show="show">
|
||||||
<scroll-view class="scroll" :scroll-y="true">
|
<scroll-view class="scroll" :scroll-y="true">
|
||||||
<view class="emoji-flex">
|
<view class="emoji-flex">
|
||||||
<view class="item" v-for="(item, index) in emojiArr" :key="index" @click="$emit('onEmoji', item)">{{item.emoji}}</view>
|
<view class="item" v-for="(item, index) in emojiArr" :key="index" @click="$emit('onEmoji', item)">
|
||||||
|
{{item.emoji}}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
<view class="tool">
|
<view class="tool">
|
||||||
@@ -14,8 +16,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import emoji from '@/static/im/emoji'
|
import emoji from '@/static/im/emoji'
|
||||||
export default{
|
export default {
|
||||||
props:{
|
props: {
|
||||||
show: {
|
show: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: () => {
|
default: () => {
|
||||||
@@ -23,7 +25,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data(){
|
data() {
|
||||||
return {
|
return {
|
||||||
emojiArr: emoji
|
emojiArr: emoji
|
||||||
}
|
}
|
||||||
@@ -32,16 +34,19 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.emoji--lay{
|
.emoji--lay {
|
||||||
height: 600rpx;
|
height: 600rpx;
|
||||||
position: relative;
|
position: relative;
|
||||||
.scroll{
|
|
||||||
|
.scroll {
|
||||||
height: 600rpx;
|
height: 600rpx;
|
||||||
.emoji-flex{
|
|
||||||
|
.emoji-flex {
|
||||||
padding: 15rpx 15rpx 120rpx;
|
padding: 15rpx 15rpx 120rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
.item{
|
|
||||||
|
.item {
|
||||||
margin: 10rpx 15rpx;
|
margin: 10rpx 15rpx;
|
||||||
font-size: 52rpx;
|
font-size: 52rpx;
|
||||||
width: calc(12.5% - 30rpx);
|
width: calc(12.5% - 30rpx);
|
||||||
@@ -49,7 +54,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.tool{
|
|
||||||
|
.tool {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
@@ -58,7 +64,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
padding: 20rpx 30rpx 30rpx;
|
padding: 20rpx 30rpx 30rpx;
|
||||||
.item{
|
|
||||||
|
.item {
|
||||||
line-height: 70rpx;
|
line-height: 70rpx;
|
||||||
border-radius: 35rpx;
|
border-radius: 35rpx;
|
||||||
width: 140rpx;
|
width: 140rpx;
|
||||||
@@ -68,7 +75,8 @@
|
|||||||
background: white;
|
background: white;
|
||||||
border: solid 1rpx #f5f5f5;
|
border: solid 1rpx #f5f5f5;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
&.sent{
|
|
||||||
|
&.sent {
|
||||||
border-color: #34CE98;
|
border-color: #34CE98;
|
||||||
background: #34CE98;
|
background: #34CE98;
|
||||||
color: white;
|
color: white;
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
<text class="text">文件</text>
|
<text class="text">文件</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<tki-file-manager ref="filemanager" @result="sendFileMessage"></tki-file-manager>
|
||||||
|
|
||||||
<u-action-sheet :actions="callActions" cancelText="取消" @close="callShow = false" @select="singleCall"
|
<u-action-sheet :actions="callActions" cancelText="取消" @close="callShow = false" @select="singleCall"
|
||||||
:show="callShow">
|
:show="callShow">
|
||||||
</u-action-sheet>
|
</u-action-sheet>
|
||||||
@@ -34,11 +36,15 @@
|
|||||||
<script>
|
<script>
|
||||||
import im from '@/utils/im/index.js'
|
import im from '@/utils/im/index.js'
|
||||||
import imBase from '../../mixins/imBase.js'
|
import imBase from '../../mixins/imBase.js'
|
||||||
|
import tkiFileManager from "@/components/tki-file-manager/tki-file-manager.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [
|
mixins: [
|
||||||
imBase
|
imBase
|
||||||
],
|
],
|
||||||
|
components: {
|
||||||
|
tkiFileManager
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
callActions: [{
|
callActions: [{
|
||||||
@@ -68,6 +74,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
sendFileMessage(path) {
|
||||||
|
if (path) {
|
||||||
|
im.sentFile(this.conversationType, this.targetId, path).then(res => {
|
||||||
|
this.success()
|
||||||
|
}).catch(err => {
|
||||||
|
uni.showToast({
|
||||||
|
icon: 'none',
|
||||||
|
title: '发送文件失败' + err
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
icon: 'none',
|
||||||
|
title: '选择文件失败'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
singleCall(e) {
|
singleCall(e) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: '/pages/im/private/call?targetId=' + this.targetId + '&mediaType=' + e.type +
|
url: '/pages/im/private/call?targetId=' + this.targetId + '&mediaType=' + e.type +
|
||||||
@@ -81,10 +104,15 @@
|
|||||||
count: 9,
|
count: 9,
|
||||||
sourceType: ['album'],
|
sourceType: ['album'],
|
||||||
success: res => {
|
success: res => {
|
||||||
im.sentImage(this.conversationType, this.targetId, res.tempFilePaths[0],
|
let funs = []
|
||||||
this.sender, (res) => {
|
res.tempFilePaths.map((item, index) => {
|
||||||
this.success()
|
funs[index] = im.sentImage(this.conversationType, this
|
||||||
})
|
.targetId, item)
|
||||||
|
})
|
||||||
|
|
||||||
|
Promise.all(funs).then(res => {
|
||||||
|
this.success()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
@@ -92,8 +120,8 @@
|
|||||||
uni.chooseImage({
|
uni.chooseImage({
|
||||||
sourceType: ['camera'],
|
sourceType: ['camera'],
|
||||||
success: res => {
|
success: res => {
|
||||||
im.sentImage(this.conversationType, this.targetId, res.tempFilePaths[0],
|
im.sentImage(this.conversationType, this.targetId, res.tempFilePaths[0])
|
||||||
this.sender, (res) => {
|
.then((res) => {
|
||||||
this.success()
|
this.success()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -104,8 +132,13 @@
|
|||||||
break;
|
break;
|
||||||
case 'location':
|
case 'location':
|
||||||
uni.chooseLocation({
|
uni.chooseLocation({
|
||||||
success: (c) => {
|
success: (location) => {
|
||||||
console.log(c);
|
const thumbnail = ''
|
||||||
|
// 通过 location 的经纬度,合成一张图片,再把图片的base64发送出去
|
||||||
|
im.sentLocation(this.conversationType, this.targetId, location, thumbnail)
|
||||||
|
.then(() => {
|
||||||
|
this.success()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
@@ -116,10 +149,7 @@
|
|||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
case 'file':
|
case 'file':
|
||||||
uni.showToast({
|
this.$refs.filemanager._openFile()
|
||||||
icon: 'none',
|
|
||||||
title: '功能正在开发中'
|
|
||||||
})
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,17 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="sent--text">
|
<view class="sent--text">
|
||||||
<input
|
<input class="input" type="text" :auto-blur="true" :focus="focusState" v-model="inputTxt" confirm-type="send"
|
||||||
class="input"
|
cursor-spacing="10" @focus="focus" @blur="blur" @confirm="sent" />
|
||||||
type="text"
|
|
||||||
:auto-blur="true"
|
|
||||||
:focus="focusState"
|
|
||||||
v-model="inputTxt"
|
|
||||||
confirm-type="send"
|
|
||||||
cursor-spacing="10"
|
|
||||||
@focus="focus"
|
|
||||||
@blur="blur"
|
|
||||||
@confirm="sent"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -56,7 +46,7 @@
|
|||||||
inputTxt: ''
|
inputTxt: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created(){
|
created() {
|
||||||
uni.$on('emojiValue', res => {
|
uni.$on('emojiValue', res => {
|
||||||
this.inputTxt = res.value
|
this.inputTxt = res.value
|
||||||
})
|
})
|
||||||
@@ -65,7 +55,7 @@
|
|||||||
methods: {
|
methods: {
|
||||||
sent() {
|
sent() {
|
||||||
if (!this.disabled) {
|
if (!this.disabled) {
|
||||||
im.sentText(this.conversationType, this.targetId, this.inputTxt, this.sender, () => {
|
im.sentText(this.conversationType, this.targetId, this.inputTxt).then(() => {
|
||||||
RongIMLib.clearTextMessageDraft(this.conversationType, this.targetId)
|
RongIMLib.clearTextMessageDraft(this.conversationType, this.targetId)
|
||||||
this.$emit('success')
|
this.$emit('success')
|
||||||
this.inputTxt = ''
|
this.inputTxt = ''
|
||||||
@@ -91,6 +81,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
background: #F3F6FB;
|
background: #F3F6FB;
|
||||||
height: 70rpx;
|
height: 70rpx;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="send--voice">
|
<view class="send--voice">
|
||||||
<view class="voice" hover-class="chat-hover" @touchstart="startRecord" @touchend="stopRecord" @touchmove="touchmove">
|
<view class="voice" hover-class="chat-hover" @touchstart="startRecord" @touchend="stopRecord"
|
||||||
|
@touchmove="touchmove">
|
||||||
<text class="button">按住 说话</text>
|
<text class="button">按住 说话</text>
|
||||||
</view>
|
</view>
|
||||||
<!-- 录音层 -->
|
<!-- 录音层 -->
|
||||||
@@ -99,19 +100,19 @@
|
|||||||
stopRecord(e) {
|
stopRecord(e) {
|
||||||
if (!this.showRecordTip) return
|
if (!this.showRecordTip) return
|
||||||
// 延迟500毫秒结束录音
|
// 延迟500毫秒结束录音
|
||||||
setTimeout(()=> {
|
setTimeout(() => {
|
||||||
this.recorderManager.stop()
|
this.recorderManager.stop()
|
||||||
clearInterval(this.interval)
|
clearInterval(this.interval)
|
||||||
// 监听录音结束
|
// 监听录音结束
|
||||||
this.recorderManager.onStop(res => {
|
this.recorderManager.onStop(res => {
|
||||||
if(this.isMoveCancel) {
|
if (this.isMoveCancel) {
|
||||||
this.isMoveCancel = false
|
this.isMoveCancel = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if((this.maxRecordTime - this.recordTime) <= 0){
|
if ((this.maxRecordTime - this.recordTime) <= 0) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '说话时间太短',
|
title: '说话时间太短',
|
||||||
icon : 'none',
|
icon: 'none',
|
||||||
})
|
})
|
||||||
this.showRecordTip = false
|
this.showRecordTip = false
|
||||||
return
|
return
|
||||||
@@ -120,19 +121,19 @@
|
|||||||
this.showRecordTip = false
|
this.showRecordTip = false
|
||||||
this.senVoice()
|
this.senVoice()
|
||||||
})
|
})
|
||||||
},500)
|
}, 500)
|
||||||
},
|
},
|
||||||
// 发送语音消息
|
// 发送语音消息
|
||||||
senVoice(){
|
senVoice() {
|
||||||
if(this.mp3AudioSrc === null) {
|
if (this.mp3AudioSrc === null) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '发送失败, 暂无音频信息',
|
title: '发送失败, 暂无音频信息',
|
||||||
icon : 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
im.sentVoice(this.conversationType, this.targetId, this.mp3AudioSrc, (this.maxRecordTime -
|
im.sentVoice(this.conversationType, this.targetId, this.mp3AudioSrc, (this.maxRecordTime -
|
||||||
this.recordTime), this.sender, () => {
|
this.recordTime)).then(() => {
|
||||||
this.recordTime = this.maxRecordTime
|
this.recordTime = this.maxRecordTime
|
||||||
this.mp3AudioSrc = null
|
this.mp3AudioSrc = null
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -142,9 +143,9 @@
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 移动按钮
|
// 移动按钮
|
||||||
touchmove(e){
|
touchmove(e) {
|
||||||
if(this.startOffsetTop - e.changedTouches[0].pageY > 100){
|
if (this.startOffsetTop - e.changedTouches[0].pageY > 100) {
|
||||||
if(this.showRecordTip){
|
if (this.showRecordTip) {
|
||||||
this.isMoveCancel = true
|
this.isMoveCancel = true
|
||||||
this.showRecordTip = false
|
this.showRecordTip = false
|
||||||
this.recorderManager.stop()
|
this.recorderManager.stop()
|
||||||
@@ -160,7 +161,7 @@
|
|||||||
let betaAudio = uni.createInnerAudioContext()
|
let betaAudio = uni.createInnerAudioContext()
|
||||||
betaAudio.src = this.mp3AudioSrc;
|
betaAudio.src = this.mp3AudioSrc;
|
||||||
// 在播放中
|
// 在播放中
|
||||||
if(this.isBetaPlay){
|
if (this.isBetaPlay) {
|
||||||
betaAudio.stop()
|
betaAudio.stop()
|
||||||
betaAudio.onStop(() => {
|
betaAudio.onStop(() => {
|
||||||
this.isBetaPlay = false;
|
this.isBetaPlay = false;
|
||||||
@@ -180,7 +181,7 @@
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 播放提示音乐
|
// 播放提示音乐
|
||||||
toastAudiMp3(){
|
toastAudiMp3() {
|
||||||
let toastAudio = uni.createInnerAudioContext()
|
let toastAudio = uni.createInnerAudioContext()
|
||||||
toastAudio.src = require('@/static/im/toast/sentVoice.mp3')
|
toastAudio.src = require('@/static/im/toast/sentVoice.mp3')
|
||||||
toastAudio.autoplay = true
|
toastAudio.autoplay = true
|
||||||
@@ -227,12 +228,14 @@
|
|||||||
margin-right: 15rpx;
|
margin-right: 15rpx;
|
||||||
padding: 0 20rpx;
|
padding: 0 20rpx;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.lay{
|
|
||||||
|
.lay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -241,11 +244,13 @@
|
|||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
.lay-header{
|
|
||||||
|
.lay-header {
|
||||||
height: calc(100vh - 140px);
|
height: calc(100vh - 140px);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.modal {
|
.modal {
|
||||||
display: flex;
|
display: flex;
|
||||||
background: rgba(0, 0, 0, .6);
|
background: rgba(0, 0, 0, .6);
|
||||||
@@ -257,6 +262,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
width: 88rpx;
|
width: 88rpx;
|
||||||
height: 88rpx;
|
height: 88rpx;
|
||||||
@@ -268,12 +274,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.lay-toast{
|
|
||||||
|
.lay-toast {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: rgba($color: #fff, $alpha: .8);
|
color: rgba($color: #fff, $alpha: .8);
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
}
|
}
|
||||||
.lay-footer{
|
|
||||||
|
.lay-footer {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
border-radius: 50% 50% 0 0;
|
border-radius: 50% 50% 0 0;
|
||||||
@@ -286,11 +294,13 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
.lay-footer-icon{
|
|
||||||
|
.lay-footer-icon {
|
||||||
width: 58rpx;
|
width: 58rpx;
|
||||||
height: 58rpx;
|
height: 58rpx;
|
||||||
}
|
}
|
||||||
.lay-footer-text{
|
|
||||||
|
.lay-footer-text {
|
||||||
line-height: 40rpx;
|
line-height: 40rpx;
|
||||||
color: gray;
|
color: gray;
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
<view class="msg--call">
|
<view class="msg--call">
|
||||||
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
|
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
|
||||||
<view class="im--text" :class="isRemote ? 'left': 'right'">
|
<view class="im--text" :class="isRemote ? 'left': 'right'">
|
||||||
<uni-icons type="videocam" size="44rpx" v-if="msg.mediaType == 1" />
|
<uni-icons type="phone" size="44rpx" />
|
||||||
<uni-icons type="phone" size="40rpx" v-else />
|
|
||||||
{{ label }}
|
{{ label }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -18,7 +17,6 @@
|
|||||||
mixins: [
|
mixins: [
|
||||||
imBase
|
imBase
|
||||||
],
|
],
|
||||||
name: 'showText',
|
|
||||||
props: {
|
props: {
|
||||||
message: {
|
message: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -31,23 +29,18 @@
|
|||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
msg() {
|
|
||||||
return JSON.parse(this.message.content.message)
|
|
||||||
},
|
|
||||||
label() {
|
label() {
|
||||||
return this.msg.connected ? '通话时长:' + duration : '未接通'
|
return this.message.content.customFields.status == 1 ? '通话时长:' + duration : '未接通'
|
||||||
},
|
},
|
||||||
isRemote() {
|
isRemote() {
|
||||||
return this.message.messageDirection == 2
|
return this.message.messageDirection == 2
|
||||||
},
|
},
|
||||||
duration() {
|
duration() {
|
||||||
if (this.message.duration > 3600) {
|
if (this.message.content.customFields.duration > 3600) {
|
||||||
return moment.utc(this.message.duration * 1000).format('HH:mm:ss')
|
return moment.utc(this.message.content.customFields.duration * 1000).format('HH:mm:ss')
|
||||||
} else {
|
} else {
|
||||||
return moment.utc(this.message.duration * 1000).format('mm:ss')
|
return moment.utc(this.message.content.customFields.duration * 1000).format('mm:ss')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
95
pages/im/components/show/showFile.vue
Normal file
95
pages/im/components/show/showFile.vue
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
<template>
|
||||||
|
<view class="msg--file">
|
||||||
|
<message-state :message="message" :isGroup="isGroup" :isRemote="isRemote" />
|
||||||
|
|
||||||
|
<view class="">
|
||||||
|
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
|
||||||
|
<view class="file" :class="isRemote ? 'left': 'right'">
|
||||||
|
<view class="img">
|
||||||
|
{{ content.fileType }}
|
||||||
|
{{ content.name }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- "content": {
|
||||||
|
"fileType": "jpg",
|
||||||
|
"remote": "https://rongcloud-spic.ronghub.com/Xl1PRVpHVldeRQAGVgEHAAcBBgYGBgcDAwMGMjA3MA%3D%3D.jpg?e=1661583313&token=livk5rb3__JZjCtEiMxXpQ8QscLxbNLehwhHySnX:t58hs4uvM1RFsBeKLTcDbVW-k5w=",
|
||||||
|
"size": 347062,
|
||||||
|
"objectName": "RC:FileMsg",
|
||||||
|
"name": "Screenshot_2022-02-25-14-44-55-886_io.zhhealth.app.jpg",
|
||||||
|
"local": "file:///storage/emulated/0/DCIM/Screenshots/Screenshot_2022-02-25-14-44-55-886_io.zhhealth.app.jpg",
|
||||||
|
"userInfo": {
|
||||||
|
"userId": "10051",
|
||||||
|
"name": "Jason.电信",
|
||||||
|
"extra": "",
|
||||||
|
"portraitUrl": "http://storage.zh.shangkelian.cn/uploads/2022/02/16/29b13f5301694721ad7acd8b8b67bbd9.jpg"
|
||||||
|
}
|
||||||
|
}, -->
|
||||||
|
<script>
|
||||||
|
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||||
|
import messageState from './messageState'
|
||||||
|
import imBase from '../../mixins/imBase.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [
|
||||||
|
imBase
|
||||||
|
],
|
||||||
|
props: {
|
||||||
|
message: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isGroup: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
messageState
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isRemote() {
|
||||||
|
return this.message.messageDirection == 2
|
||||||
|
},
|
||||||
|
content() {
|
||||||
|
return this.message.content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.msg--file {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: $text-gray-m;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file {
|
||||||
|
.img {
|
||||||
|
width: 180rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
.img {
|
||||||
|
border-radius: 0 10rpx 10rpx 10rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
.img {
|
||||||
|
border-radius: 10rpx 0 10rpx 10rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
112
pages/im/components/show/showLocation.vue
Normal file
112
pages/im/components/show/showLocation.vue
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
<template>
|
||||||
|
<view class="msg--location">
|
||||||
|
<message-state :message="message" :isGroup="isGroup" :isRemote="isRemote" />
|
||||||
|
|
||||||
|
<view class="">
|
||||||
|
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
|
||||||
|
<view class="location" :class="isRemote ? 'left': 'right'" @click="showLocation">
|
||||||
|
<view class="location--name">
|
||||||
|
{{ content.customFields.name }}
|
||||||
|
</view>
|
||||||
|
<view class="location--address">
|
||||||
|
{{ content.customFields.address }}
|
||||||
|
</view>
|
||||||
|
<image class="map" :src="require('@/static/imgs/map.jpeg')" mode="aspectFill" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||||
|
import messageState from './messageState'
|
||||||
|
import imBase from '../../mixins/imBase.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [
|
||||||
|
imBase
|
||||||
|
],
|
||||||
|
name: 'showImage',
|
||||||
|
props: {
|
||||||
|
message: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isGroup: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
messageState
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isRemote() {
|
||||||
|
return this.message.messageDirection == 2
|
||||||
|
},
|
||||||
|
content() {
|
||||||
|
return this.message.content
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showLocation() {
|
||||||
|
uni.openLocation({
|
||||||
|
latitude: Number(this.content.customFields.latitude),
|
||||||
|
longitude: Number(this.content.customFields.longitude),
|
||||||
|
fail: (err) => {
|
||||||
|
uni.showToast({
|
||||||
|
icon: 'none',
|
||||||
|
title: '打开地图失败'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.msg--location {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: $text-gray-m;
|
||||||
|
}
|
||||||
|
|
||||||
|
.location {
|
||||||
|
position: relative;
|
||||||
|
width: 400rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
padding: 10rpx;
|
||||||
|
|
||||||
|
.location--name {
|
||||||
|
font-size: 32rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.location--address {
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: $text-gray-m;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map {
|
||||||
|
width: 400rpx;
|
||||||
|
height: 200rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
border-radius: 0 10rpx 10rpx 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
border-radius: 10rpx 0 10rpx 10rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
36
pages/im/components/show/showNormal.vue
Normal file
36
pages/im/components/show/showNormal.vue
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<template>
|
||||||
|
<view class="">
|
||||||
|
<show-location v-if="message.content.objectName == 'RC:LBSMsg'" :message="message" :isGroup="isGroup" />
|
||||||
|
<show-video v-else-if="message.content.objectName == 'RC:VideoMsg'" :message="message" :isGroup="isGroup" />
|
||||||
|
<show-audio v-else-if="message.content.objectName == 'RC:AudioMsg'" :message="message" :isGroup="isGroup" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import showLocation from './showLocation'
|
||||||
|
import showAudio from './showAudio'
|
||||||
|
import showVideo from './showVideo'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
message: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isGroup: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
showLocation,
|
||||||
|
showAudio,
|
||||||
|
showVideo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
84
pages/im/components/show/showVideo.vue
Normal file
84
pages/im/components/show/showVideo.vue
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<template>
|
||||||
|
<view class="msg--call">
|
||||||
|
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
|
||||||
|
<view class="im--text" :class="isRemote ? 'left': 'right'">
|
||||||
|
<uni-icons type="videocam" size="44rpx" />
|
||||||
|
{{ label }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import utils from '@/utils/index.js'
|
||||||
|
import moment from 'moment'
|
||||||
|
import imBase from '../../mixins/imBase.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [
|
||||||
|
imBase
|
||||||
|
],
|
||||||
|
props: {
|
||||||
|
message: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isGroup: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
label() {
|
||||||
|
return this.message.content.customFields.status == 1 ? '通话时长:' + duration : '未接通'
|
||||||
|
},
|
||||||
|
isRemote() {
|
||||||
|
return this.message.messageDirection == 2
|
||||||
|
},
|
||||||
|
duration() {
|
||||||
|
if (this.message.content.customFields.duration > 3600) {
|
||||||
|
return moment.utc(this.message.content.customFields.duration * 1000).format('HH:mm:ss')
|
||||||
|
} else {
|
||||||
|
return moment.utc(this.message.content.customFields.duration * 1000).format('mm:ss')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.msg--call {
|
||||||
|
.name {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: $text-gray-m;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.im--text {
|
||||||
|
max-width: 508rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
line-height: 46rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: $text-color;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
border-radius: 0 20rpx 20rpx 20rpx;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
border-radius: 20rpx 0 20rpx 20rpx;
|
||||||
|
background: $main-color;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
.uni-icons {
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -8,6 +8,9 @@
|
|||||||
<view class="notify" v-else-if="message.objectName === 'RC:RcNtf'">
|
<view class="notify" v-else-if="message.objectName === 'RC:RcNtf'">
|
||||||
{{ contact(message.senderUserId).name }} 撤回了一条消息
|
{{ contact(message.senderUserId).name }} 撤回了一条消息
|
||||||
</view>
|
</view>
|
||||||
|
<view class="notify" v-else-if="message.objectName === 'RC:InfoNtf'">
|
||||||
|
{{ message.sentTime|timeCustomCN }}
|
||||||
|
</view>
|
||||||
<view v-else :class="['cell-item', message.messageDirection == 1 ? 'right' : 'left']">
|
<view v-else :class="['cell-item', message.messageDirection == 1 ? 'right' : 'left']">
|
||||||
<u-avatar class="avatar" @click="toUser(message)" :size="avatarSize" shape="square"
|
<u-avatar class="avatar" @click="toUser(message)" :size="avatarSize" shape="square"
|
||||||
:src="contact(message.senderUserId).portraitUrl" />
|
:src="contact(message.senderUserId).portraitUrl" />
|
||||||
@@ -15,7 +18,9 @@
|
|||||||
<show-text v-if="message.objectName === 'RC:TxtMsg'" :message="message" :isGroup="isGroup" />
|
<show-text v-if="message.objectName === 'RC:TxtMsg'" :message="message" :isGroup="isGroup" />
|
||||||
<show-voice v-else-if="message.objectName === 'RC:HQVCMsg'" :message="message" :isGroup="isGroup" />
|
<show-voice v-else-if="message.objectName === 'RC:HQVCMsg'" :message="message" :isGroup="isGroup" />
|
||||||
<show-image v-else-if="message.objectName === 'RC:ImgMsg'" :message="message" :isGroup="isGroup" />
|
<show-image v-else-if="message.objectName === 'RC:ImgMsg'" :message="message" :isGroup="isGroup" />
|
||||||
<show-call v-else-if="message.objectName === 'RC:InfoNtf'" :message="message" :isGroup="isGroup" />
|
<show-file v-else-if="message.objectName === 'RC:FileMsg'" :message="message" :isGroup="isGroup" />
|
||||||
|
<show-normal v-else-if="message.objectName === 'RC:IWNormalMsg'" :message="message" :isGroup="isGroup" />
|
||||||
|
|
||||||
<view v-else class="">
|
<view v-else class="">
|
||||||
[未处理的消息类型 {{ message.objectName }}]
|
[未处理的消息类型 {{ message.objectName }}]
|
||||||
</view>
|
</view>
|
||||||
@@ -33,7 +38,8 @@
|
|||||||
import showVoice from './show/showVoice'
|
import showVoice from './show/showVoice'
|
||||||
import showImage from './show/showImage'
|
import showImage from './show/showImage'
|
||||||
import showText from './show/showText'
|
import showText from './show/showText'
|
||||||
import showCall from './show/showCall'
|
import showFile from './show/showFile'
|
||||||
|
import showNormal from './show/showNormal'
|
||||||
import utils from '@/utils/index.js'
|
import utils from '@/utils/index.js'
|
||||||
import imBase from '../mixins/imBase.js'
|
import imBase from '../mixins/imBase.js'
|
||||||
|
|
||||||
@@ -42,10 +48,11 @@
|
|||||||
imBase
|
imBase
|
||||||
],
|
],
|
||||||
components: {
|
components: {
|
||||||
showCall,
|
|
||||||
showVoice,
|
showVoice,
|
||||||
showImage,
|
showImage,
|
||||||
showText
|
showText,
|
||||||
|
showFile,
|
||||||
|
showNormal
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
message: {
|
message: {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="chat">
|
<view class="chat">
|
||||||
<sent-message-bar :conversationType="conversationType" :targetId="targetId" @onSuccess="getNewMessage()" />
|
<sent-message-bar id="msgbar" :conversationType="conversationType" :targetId="targetId"
|
||||||
|
@onSuccess="getNewMessage()" />
|
||||||
|
|
||||||
<view class="shade" @click="hidePop" v-show="showPop">
|
<view class="shade" @click="hidePop" v-show="showPop">
|
||||||
<view class="pop" :style="popStyle" :class="{'show':showPop}">
|
<view class="pop" :style="popStyle" :class="{'show':showPop}">
|
||||||
@@ -11,7 +12,8 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="body">
|
<view class="body">
|
||||||
<view class="scroll">
|
<view class="place" :style="{ height: placeHeight + 'px' }"></view>
|
||||||
|
<view class="scroll" id="scroll">
|
||||||
<view class="cell" v-for="(message, index) in messages" :key="index">
|
<view class="cell" v-for="(message, index) in messages" :key="index">
|
||||||
<show-message-cell :message="message" isGroup @messageAction="messageAction" />
|
<show-message-cell :message="message" isGroup @messageAction="messageAction" />
|
||||||
</view>
|
</view>
|
||||||
@@ -51,7 +53,9 @@
|
|||||||
messages: [],
|
messages: [],
|
||||||
groupInfo: {
|
groupInfo: {
|
||||||
name: ''
|
name: ''
|
||||||
}
|
},
|
||||||
|
placeHeight: uni.getSystemInfoSync().windowHeight,
|
||||||
|
bottomHeihgt: 56
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -69,6 +73,20 @@
|
|||||||
this.initGroupInfo()
|
this.initGroupInfo()
|
||||||
},
|
},
|
||||||
onLoad(e) {
|
onLoad(e) {
|
||||||
|
const query = uni.createSelectorQuery().in(this);
|
||||||
|
this.$nextTick(function() {
|
||||||
|
query.select('#msgbar').boundingClientRect(bottom => {
|
||||||
|
this.bottomHeihgt = bottom.height
|
||||||
|
}).exec();
|
||||||
|
})
|
||||||
|
// 监听键盘高度变化
|
||||||
|
uni.onKeyboardHeightChange(keyboard => {
|
||||||
|
query.select('#scroll').boundingClientRect(scroll => {
|
||||||
|
const placeHeight = this.windowHeight - scroll.height - keyboard.height - this
|
||||||
|
.bottomHeihgt
|
||||||
|
this.placeHeight = placeHeight > 0 ? placeHeight : 0
|
||||||
|
}).exec();
|
||||||
|
})
|
||||||
this.targetId = e.targetId
|
this.targetId = e.targetId
|
||||||
// 获取历史消息列表
|
// 获取历史消息列表
|
||||||
this.getMessageList()
|
this.getMessageList()
|
||||||
@@ -138,14 +156,25 @@
|
|||||||
this.$refs.messageBar.onHidePopus()
|
this.$refs.messageBar.onHidePopus()
|
||||||
},
|
},
|
||||||
getNewMessage() {
|
getNewMessage() {
|
||||||
|
if (new Date().getTime() - this.latestMessage.sentTime > 18000000) {
|
||||||
|
// 在本地插入一条时间的消息
|
||||||
|
const messageContent = {
|
||||||
|
objectName: 'RC:InfoNtf',
|
||||||
|
message: 'DateInfo'
|
||||||
|
}
|
||||||
|
RongIMLib.insertOutgoingMessage(this.conversationType, this.targetId, 50, messageContent, 0)
|
||||||
|
}
|
||||||
|
|
||||||
im.getMessageList(
|
im.getMessageList(
|
||||||
this.conversationType,
|
this.conversationType,
|
||||||
this.targetId,
|
this.targetId,
|
||||||
this.latestMessage.sentTime,
|
this.latestMessage.sentTime || 0,
|
||||||
10,
|
10,
|
||||||
false,
|
false,
|
||||||
(messages) => {
|
(messages) => {
|
||||||
this.messages.unshift(...messages)
|
console.log(messages);
|
||||||
|
//
|
||||||
|
this.messages.unshift(...messages.reverse())
|
||||||
this.scrollBottom()
|
this.scrollBottom()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -158,12 +187,9 @@
|
|||||||
20,
|
20,
|
||||||
true,
|
true,
|
||||||
(messages) => {
|
(messages) => {
|
||||||
console.log('获取消息列表', messages);
|
|
||||||
const msgs = messages.filter(item => item.receivedStatus == 0)
|
const msgs = messages.filter(item => item.receivedStatus == 0)
|
||||||
console.log('未读消息', msgs);
|
|
||||||
if (msgs.length) {
|
if (msgs.length) {
|
||||||
RongIMLib.sendReadReceiptResponse(3, this.targetId, msgs, (res) => {
|
RongIMLib.sendReadReceiptResponse(3, this.targetId, msgs, (res) => {
|
||||||
console.error('发送群聊已读回执成功', res);
|
|
||||||
msgs.map(item => {
|
msgs.map(item => {
|
||||||
RongIMLib.setMessageReceivedStatus(item.messageId, 1)
|
RongIMLib.setMessageReceivedStatus(item.messageId, 1)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -20,8 +20,15 @@
|
|||||||
</view>
|
</view>
|
||||||
<!-- content -->
|
<!-- content -->
|
||||||
<view v-if="$store.state.token !== ''">
|
<view v-if="$store.state.token !== ''">
|
||||||
<connection-status :connection="connection" />
|
<block v-if="conversations.length>0">
|
||||||
<conversation-list @refresh="getConversationList()" :conversations="conversations" />
|
<connection-status :connection="connection" />
|
||||||
|
<conversation-list @refresh="getConversationList()" :conversations="conversations" />
|
||||||
|
</block>
|
||||||
|
<view class="no-lists" v-else>
|
||||||
|
<u-image class="cover" radius="4" width="500rpx" height="500rpx"
|
||||||
|
:src="require('@/static/imgs/no-new-news.png')" :lazy-load="true" />
|
||||||
|
<span> 空空如也~</span>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 未登录 -->
|
<!-- 未登录 -->
|
||||||
<view v-else class="vertical null-list">
|
<view v-else class="vertical null-list">
|
||||||
@@ -55,6 +62,11 @@
|
|||||||
connectionStatus
|
connectionStatus
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
RongIMLib.getCurrentUserId(({
|
||||||
|
userId
|
||||||
|
}) => {
|
||||||
|
console.log('getCurrentUserId', userId);
|
||||||
|
})
|
||||||
// 监听新的好友申请
|
// 监听新的好友申请
|
||||||
uni.$on('onNewContactConversation', () => {
|
uni.$on('onNewContactConversation', () => {
|
||||||
console.log('更新好友申请数量');
|
console.log('更新好友申请数量');
|
||||||
@@ -107,7 +119,7 @@
|
|||||||
conversations
|
conversations
|
||||||
}) => {
|
}) => {
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
console.log(conversations,',,,,,')
|
console.log('获取会话列表', conversations);
|
||||||
this.conversations = conversations
|
this.conversations = conversations
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -215,4 +227,21 @@
|
|||||||
.u-border-bottom {
|
.u-border-bottom {
|
||||||
border-bottom: solid 1rpx #f9f9f9 !important;
|
border-bottom: solid 1rpx #f9f9f9 !important;
|
||||||
}
|
}
|
||||||
|
.no-lists {
|
||||||
|
min-height: 80vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-size: $title-size-m;
|
||||||
|
color: $text-gray-m;
|
||||||
|
.cover{
|
||||||
|
opacity: 0.8!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
padding-top: $padding;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ export default {
|
|||||||
},
|
},
|
||||||
sender() {
|
sender() {
|
||||||
return this.$store.getters.sender
|
return this.$store.getters.sender
|
||||||
|
},
|
||||||
|
windowHeight() {
|
||||||
|
return uni.getSystemInfoSync().windowHeight
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -133,23 +133,7 @@
|
|||||||
methods: {
|
methods: {
|
||||||
afterHangup() {
|
afterHangup() {
|
||||||
clearInterval(this.interval)
|
clearInterval(this.interval)
|
||||||
const targetId = this.targetId
|
// duration: this.duration
|
||||||
const sentStatus = 30
|
|
||||||
const messageContent = {
|
|
||||||
objectName: 'RC:InfoNtf',
|
|
||||||
userInfo: this.$store.getters.sender,
|
|
||||||
message: JSON.stringify({
|
|
||||||
mediaType: this.mediaType,
|
|
||||||
connected: this.connected,
|
|
||||||
duration: this.duration
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const sentTime = 0
|
|
||||||
if (this.isCall) {
|
|
||||||
IMLib.insertOutgoingMessage(1, targetId, sentStatus, messageContent, sentTime)
|
|
||||||
} else {
|
|
||||||
IMLib.insertIncomingMessage(1, targetId, targetId, sentStatus, messageContent, sentTime)
|
|
||||||
}
|
|
||||||
uni.$emit('onReceiveMessage_' + this.targetId, {
|
uni.$emit('onReceiveMessage_' + this.targetId, {
|
||||||
targetId: this.targetId
|
targetId: this.targetId
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="chat">
|
<view class="chat">
|
||||||
<sent-message-bar :conversationType="conversationType" :targetId="targetId" @onSuccess="getNewMessage()" />
|
<sent-message-bar id="msgbar" :conversationType="conversationType" :targetId="targetId"
|
||||||
|
@onSuccess="getNewMessage()" />
|
||||||
<view class="shade" @click="hidePop" v-show="showPop">
|
<view class="shade" @click="hidePop" v-show="showPop">
|
||||||
<view class="pop" :style="popStyle" :class="{'show':showPop}">
|
<view class="pop" :style="popStyle" :class="{'show':showPop}">
|
||||||
<view v-for="(item, index) in popButton" :key="index" @click="pickerMenu(item)">
|
<view v-for="(item, index) in popButton" :key="index" @click="pickerMenu(item)">
|
||||||
@@ -10,7 +11,8 @@
|
|||||||
</view>
|
</view>
|
||||||
<!-- chat -->
|
<!-- chat -->
|
||||||
<view class="body">
|
<view class="body">
|
||||||
<view class="scroll">
|
<view class="place" :style="{ height: placeHeight + 'px' }"></view>
|
||||||
|
<view class="scroll" id="scroll">
|
||||||
<view class="cell" v-for="(message, index) in messages" :key="index">
|
<view class="cell" v-for="(message, index) in messages" :key="index">
|
||||||
<show-message-cell :message="message" @messageAction="messageAction" />
|
<show-message-cell :message="message" @messageAction="messageAction" />
|
||||||
</view>
|
</view>
|
||||||
@@ -46,7 +48,9 @@
|
|||||||
name: '',
|
name: '',
|
||||||
userId: '',
|
userId: '',
|
||||||
portraitUrl: ''
|
portraitUrl: ''
|
||||||
}
|
},
|
||||||
|
placeHeight: uni.getSystemInfoSync().windowHeight,
|
||||||
|
bottomHeihgt: 56
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -66,6 +70,20 @@
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
onLoad(e) {
|
onLoad(e) {
|
||||||
|
const query = uni.createSelectorQuery().in(this);
|
||||||
|
this.$nextTick(function() {
|
||||||
|
query.select('#msgbar').boundingClientRect(bottom => {
|
||||||
|
this.bottomHeihgt = bottom.height
|
||||||
|
}).exec();
|
||||||
|
})
|
||||||
|
// 监听键盘高度变化
|
||||||
|
uni.onKeyboardHeightChange(keyboard => {
|
||||||
|
query.select('#scroll').boundingClientRect(scroll => {
|
||||||
|
const placeHeight = this.windowHeight - scroll.height - keyboard.height - this
|
||||||
|
.bottomHeihgt
|
||||||
|
this.placeHeight = placeHeight > 0 ? placeHeight : 0
|
||||||
|
}).exec();
|
||||||
|
})
|
||||||
this.targetId = e.targetId
|
this.targetId = e.targetId
|
||||||
this.userInfo = this.$store.getters.contactInfo(this.targetId)
|
this.userInfo = this.$store.getters.contactInfo(this.targetId)
|
||||||
// 获取消息列表
|
// 获取消息列表
|
||||||
@@ -106,6 +124,9 @@
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
onUnload() {
|
onUnload() {
|
||||||
|
uni.offKeyboardHeightChange(res => {
|
||||||
|
console.log('卸载监听键盘高度变化', res);
|
||||||
|
})
|
||||||
uni.$off('onUserDelete_' + this.targetId)
|
uni.$off('onUserDelete_' + this.targetId)
|
||||||
uni.$off('onReceiveMessage_' + this.targetId)
|
uni.$off('onReceiveMessage_' + this.targetId)
|
||||||
uni.$off('onRecallMessage_' + this.targetId)
|
uni.$off('onRecallMessage_' + this.targetId)
|
||||||
@@ -114,19 +135,30 @@
|
|||||||
},
|
},
|
||||||
onNavigationBarButtonTap() {
|
onNavigationBarButtonTap() {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url:'/pages/im/friends/info?targetId='+this.targetId
|
url: '/pages/im/friends/info?targetId=' + this.targetId
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getNewMessage() {
|
getNewMessage() {
|
||||||
|
if (new Date().getTime() - this.latestMessage.sentTime > 18000000) {
|
||||||
|
// 在本地插入一条时间的消息
|
||||||
|
const messageContent = {
|
||||||
|
objectName: 'RC:InfoNtf',
|
||||||
|
message: 'DateInfo'
|
||||||
|
}
|
||||||
|
RongIMLib.insertOutgoingMessage(this.conversationType, this.targetId, 50, messageContent, 0)
|
||||||
|
}
|
||||||
|
|
||||||
im.getMessageList(
|
im.getMessageList(
|
||||||
this.conversationType,
|
this.conversationType,
|
||||||
this.targetId,
|
this.targetId,
|
||||||
this.latestMessage.sentTime || 0,
|
this.latestMessage.sentTime || 0,
|
||||||
1,
|
10,
|
||||||
false,
|
false,
|
||||||
(messages) => {
|
(messages) => {
|
||||||
this.messages.unshift(...messages)
|
console.log(messages);
|
||||||
|
//
|
||||||
|
this.messages.unshift(...messages.reverse())
|
||||||
this.scrollBottom()
|
this.scrollBottom()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -160,6 +192,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.place {}
|
||||||
|
|
||||||
/* 窗口 */
|
/* 窗口 */
|
||||||
.chat {
|
.chat {
|
||||||
background: $window-color;
|
background: $window-color;
|
||||||
|
|||||||
BIN
static/imgs/map.jpeg
Normal file
BIN
static/imgs/map.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
BIN
static/imgs/no-new-news.png
Normal file
BIN
static/imgs/no-new-news.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
@@ -41,6 +41,7 @@ export default {
|
|||||||
updateContactInfo(state, contactInfo) {
|
updateContactInfo(state, contactInfo) {
|
||||||
Vue.set(state.contacts, contactInfo.targetId, contactInfo)
|
Vue.set(state.contacts, contactInfo.targetId, contactInfo)
|
||||||
},
|
},
|
||||||
|
// 设置我的资料
|
||||||
setSenderInfo(state, contactInfo) {
|
setSenderInfo(state, contactInfo) {
|
||||||
state.myInfo = {
|
state.myInfo = {
|
||||||
userId: contactInfo.targetId,
|
userId: contactInfo.targetId,
|
||||||
@@ -69,8 +70,11 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
setSenderInfo({
|
setSenderInfo({
|
||||||
commit
|
commit,
|
||||||
|
dispatch
|
||||||
}, contactInfo) {
|
}, contactInfo) {
|
||||||
|
contactInfo.type = 0 // type 更改为0,标记是我自己
|
||||||
|
dispatch('updateContact', contactInfo)
|
||||||
commit('setSenderInfo', contactInfo)
|
commit('setSenderInfo', contactInfo)
|
||||||
},
|
},
|
||||||
// 载入好友信息
|
// 载入好友信息
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ const connect = (token, userInfo, callback) => {
|
|||||||
key: FK,
|
key: FK,
|
||||||
success: () => {
|
success: () => {
|
||||||
contactModel.find((err, results) => {
|
contactModel.find((err, results) => {
|
||||||
|
console.log('初始化联系人信息', results);
|
||||||
results.map(item => {
|
results.map(item => {
|
||||||
store.dispatch('launchContact', item)
|
store.dispatch('launchContact', item)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ const notifyMsgTypes = [
|
|||||||
IMLib.ObjectName.Location,
|
IMLib.ObjectName.Location,
|
||||||
IMLib.ObjectName.Voice,
|
IMLib.ObjectName.Voice,
|
||||||
IMLib.ObjectName.HQVoice,
|
IMLib.ObjectName.HQVoice,
|
||||||
IMLib.ObjectName.Sight
|
IMLib.ObjectName.Sight,
|
||||||
|
'RC:IWNormalMsg'
|
||||||
]
|
]
|
||||||
|
|
||||||
const imLibListeners = () => {
|
const imLibListeners = () => {
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ const getMessageList = (conversationType, targetId, timeStamp, count, isForward,
|
|||||||
'RC:CombineMsg',
|
'RC:CombineMsg',
|
||||||
'RC:GrpNtf',
|
'RC:GrpNtf',
|
||||||
'RC:InfoNtf',
|
'RC:InfoNtf',
|
||||||
'RC:RcNtf'
|
'RC:RcNtf',
|
||||||
|
'RC:IWNormalMsg'
|
||||||
]
|
]
|
||||||
|
|
||||||
RongIMLib.getHistoryMessagesByTimestamp(
|
RongIMLib.getHistoryMessagesByTimestamp(
|
||||||
@@ -80,35 +81,23 @@ const getGroupPendinglist = (targetId, callback) => {
|
|||||||
* @param {string} content 消息内容
|
* @param {string} content 消息内容
|
||||||
* @param {function} callback 回调函数
|
* @param {function} callback 回调函数
|
||||||
*/
|
*/
|
||||||
const sentText = (conversationType, targetId, content, user, callback) => {
|
const sentText = (conversationType, targetId, content) => {
|
||||||
const msg = {
|
return new Promise((resolve, reject) => {
|
||||||
conversationType: conversationType,
|
const message = {
|
||||||
targetId: String(targetId),
|
conversationType: conversationType,
|
||||||
content: {
|
targetId: String(targetId),
|
||||||
objectName: 'RC:TxtMsg',
|
content: {
|
||||||
content: content,
|
objectName: 'RC:TxtMsg',
|
||||||
userInfo: user
|
content: content,
|
||||||
}
|
userInfo: store.getters.sender
|
||||||
}
|
|
||||||
|
|
||||||
RongIMLib.sendMessage(msg, ({
|
|
||||||
code,
|
|
||||||
messageId
|
|
||||||
}) => {
|
|
||||||
if (code === 0) {
|
|
||||||
if (conversationType == 3) {
|
|
||||||
RongIMLib.sendReadReceiptRequest(messageId, (res) => {
|
|
||||||
console.log('发送回执请求', res);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
callback(messageId)
|
|
||||||
} else {
|
|
||||||
console.log('发送失败', msg);
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '发送失败' + code
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendCommonMessage(message, (messageId) => {
|
||||||
|
resolve(messageId)
|
||||||
|
}, (errCode) => {
|
||||||
|
reject(errCode)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,111 +107,199 @@ const sentText = (conversationType, targetId, content, user, callback) => {
|
|||||||
* @param {string} targetId 会话id
|
* @param {string} targetId 会话id
|
||||||
* @param {string} voiceUrl 录音的本地路径
|
* @param {string} voiceUrl 录音的本地路径
|
||||||
* @param {integer} time 录音时长
|
* @param {integer} time 录音时长
|
||||||
* @param {function} callback 录音时长
|
* @param {function} user 本人信息
|
||||||
*/
|
*/
|
||||||
const sentVoice = (conversationType, targetId, voiceUrl, time, user, callback) => {
|
const sentVoice = (conversationType, targetId, voiceUrl, time) => {
|
||||||
const msg = {
|
return new Promise((resolve, reject) => {
|
||||||
conversationType: conversationType,
|
const msg = {
|
||||||
targetId: String(targetId),
|
conversationType: conversationType,
|
||||||
content: {
|
targetId: String(targetId),
|
||||||
objectName: 'RC:HQVCMsg',
|
content: {
|
||||||
local: 'file:///' + plus.io.convertLocalFileSystemURL(voiceUrl),
|
objectName: 'RC:HQVCMsg',
|
||||||
duration: time == 0 ? 1 : time,
|
local: 'file://' + plus.io.convertLocalFileSystemURL(voiceUrl),
|
||||||
userInfo: user
|
duration: time == 0 ? 1 : time,
|
||||||
}
|
userInfo: store.getters.sender
|
||||||
}
|
}
|
||||||
RongIMLib.sendMediaMessage(msg, {
|
|
||||||
success: (messageId) => {
|
|
||||||
callback(messageId);
|
|
||||||
},
|
|
||||||
progress: (progress, messageId) => {
|
|
||||||
console.log(messageId);
|
|
||||||
},
|
|
||||||
cancel: (messageId) => {
|
|
||||||
// 发送取消回调
|
|
||||||
},
|
|
||||||
error: (errorCode, messageId) => {
|
|
||||||
console.log(errorCode, messageId);
|
|
||||||
}
|
}
|
||||||
|
RongIMLib.sendMediaMessage(msg, {
|
||||||
|
success: (messageId) => {
|
||||||
|
if (conversationType == 3) {
|
||||||
|
RongIMLib.sendReadReceiptRequest(messageId)
|
||||||
|
}
|
||||||
|
resolve(messageId)
|
||||||
|
},
|
||||||
|
progress: (progress, messageId) => {},
|
||||||
|
cancel: (messageId) => {},
|
||||||
|
error: (errorCode, messageId) => {
|
||||||
|
reject(errorCode)
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const sentImage = (conversationType, targetId, imageUrl, user, callback) => {
|
// 发送的图片,可能会涉及到一次多张,用Promise来确保前端一次性清算
|
||||||
const msg = {
|
const sentImage = (conversationType, targetId, imageUrl) => {
|
||||||
conversationType: conversationType,
|
return new Promise((resolve, reject) => {
|
||||||
targetId: String(targetId),
|
uni.getImageInfo({
|
||||||
content: {
|
src: imageUrl,
|
||||||
objectName: 'RC:ImgMsg',
|
success: (imgInfo) => {
|
||||||
local: 'file:///' + plus.io.convertLocalFileSystemURL(imageUrl),
|
const msg = {
|
||||||
userInfo: user
|
conversationType: conversationType,
|
||||||
}
|
targetId: String(targetId),
|
||||||
}
|
content: {
|
||||||
RongIMLib.sendMediaMessage(msg, {
|
objectName: 'RC:ImgMsg',
|
||||||
success: (messageId) => {
|
local: imgInfo.path,
|
||||||
callback(messageId);
|
userInfo: store.getters.sender
|
||||||
},
|
}
|
||||||
progress: (progress, messageId) => {
|
}
|
||||||
console.log(messageId);
|
RongIMLib.sendMediaMessage(msg, {
|
||||||
},
|
success: (messageId) => {
|
||||||
cancel: (messageId) => {
|
if (conversationType == 3) {
|
||||||
// 发送取消回调
|
RongIMLib.sendReadReceiptRequest(messageId)
|
||||||
},
|
}
|
||||||
error: (errorCode, messageId) => {
|
resolve(messageId)
|
||||||
console.log(errorCode, messageId);
|
},
|
||||||
}
|
progress: (progress, messageId) => {},
|
||||||
|
cancel: (messageId) => {},
|
||||||
|
error: (errorCode, messageId) => {
|
||||||
|
reject(errorCode)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const sentGif = (conversationType, targetId, gifUrl, time, user, callback) => {
|
const sentFile = (conversationType, targetId, fileUrl) => {
|
||||||
const msg = {
|
return new Promise((resolve, reject) => {
|
||||||
conversationType: conversationType,
|
const msg = {
|
||||||
targetId: String(targetId),
|
conversationType: conversationType,
|
||||||
content: {
|
targetId: String(targetId),
|
||||||
objectName: 'RC:GIFMsg',
|
content: {
|
||||||
local: 'file:///' + plus.io.convertLocalFileSystemURL(gifUrl),
|
objectName: 'RC:FileMsg',
|
||||||
duration: time,
|
local: plus.io.convertLocalFileSystemURL(fileUrl),
|
||||||
userInfo: user
|
userInfo: store.getters.sender
|
||||||
}
|
}
|
||||||
}
|
|
||||||
RongIMLib.sendMediaMessage(msg, {
|
|
||||||
success: (messageId) => {
|
|
||||||
callback(messageId);
|
|
||||||
},
|
|
||||||
progress: (progress, messageId) => {
|
|
||||||
console.log(messageId);
|
|
||||||
},
|
|
||||||
cancel: (messageId) => {
|
|
||||||
// 发送取消回调
|
|
||||||
},
|
|
||||||
error: (errorCode, messageId) => {
|
|
||||||
console.log(errorCode, messageId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RongIMLib.sendMediaMessage(msg, {
|
||||||
|
success: (messageId) => {
|
||||||
|
if (conversationType == 3) {
|
||||||
|
RongIMLib.sendReadReceiptRequest(messageId)
|
||||||
|
}
|
||||||
|
resolve(messageId)
|
||||||
|
},
|
||||||
|
progress: (progress, messageId) => {},
|
||||||
|
cancel: (messageId) => {},
|
||||||
|
error: (errorCode, messageId) => {
|
||||||
|
reject(errorCode)
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const sendFile = (conversationType, targetId, fileUrl, time, user, callback) => {
|
// 发送地理位置
|
||||||
const msg = {
|
const sentLocation = (conversationType, targetId, location, thumbnail) => {
|
||||||
conversationType: conversationType,
|
return new Promise((resolve, reject) => {
|
||||||
targetId: String(targetId),
|
const message = {
|
||||||
content: {
|
conversationType: conversationType,
|
||||||
objectName: 'RC:FileMsg',
|
targetId: String(targetId),
|
||||||
local: 'file:///' + plus.io.convertLocalFileSystemURL(fileUrl),
|
content: {
|
||||||
duration: time,
|
customType: 2,
|
||||||
userInfo: user
|
objectName: 'RC:LBSMsg',
|
||||||
|
customFields: {
|
||||||
|
name: location.name,
|
||||||
|
address: location.address,
|
||||||
|
latitude: Number(location.latitude),
|
||||||
|
longitude: Number(location.longitude),
|
||||||
|
thumbnail: thumbnail
|
||||||
|
},
|
||||||
|
userInfo: store.getters.sender,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
RongIMLib.sendMediaMessage(msg, {
|
sendCommonMessage(message, (messageId) => {
|
||||||
success: (messageId) => {
|
resolve(messageId)
|
||||||
callback(messageId);
|
}, (errCode) => {
|
||||||
},
|
reject(errCode)
|
||||||
progress: (progress, messageId) => {
|
})
|
||||||
console.log(messageId);
|
})
|
||||||
},
|
}
|
||||||
cancel: (messageId) => {
|
|
||||||
// 发送取消回调
|
/**
|
||||||
},
|
* 发送视频通话结果
|
||||||
error: (errorCode, messageId) => {
|
*/
|
||||||
console.log(errorCode, messageId);
|
const sentVideo = (conversationType, targetId, status, time) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const message = {
|
||||||
|
conversationType: conversationType,
|
||||||
|
targetId: String(targetId),
|
||||||
|
content: {
|
||||||
|
customType: 2,
|
||||||
|
objectName: 'RC:VideoMsg',
|
||||||
|
customFields: {
|
||||||
|
status: status,
|
||||||
|
duration: time
|
||||||
|
},
|
||||||
|
userInfo: store.getters.sender,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendCommonMessage(message, (messageId) => {
|
||||||
|
resolve(messageId)
|
||||||
|
}, (errCode) => {
|
||||||
|
reject(errCode)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送语音通话结果
|
||||||
|
*/
|
||||||
|
const sentAudio = (conversationType, targetId, status, time) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const message = {
|
||||||
|
conversationType: conversationType,
|
||||||
|
targetId: String(targetId),
|
||||||
|
content: {
|
||||||
|
customType: 2,
|
||||||
|
objectName: 'RC:AudioMsg',
|
||||||
|
customFields: {
|
||||||
|
status: status,
|
||||||
|
duration: time
|
||||||
|
},
|
||||||
|
userInfo: store.getters.sender,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendCommonMessage(message, (messageId) => {
|
||||||
|
resolve(messageId)
|
||||||
|
}, (errCode) => {
|
||||||
|
reject(errCode)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送普通消息
|
||||||
|
*/
|
||||||
|
const sendCommonMessage = (message, success, fail) => {
|
||||||
|
RongIMLib.sendMessage(message, ({
|
||||||
|
code,
|
||||||
|
messageId
|
||||||
|
}) => {
|
||||||
|
if (code === 0) {
|
||||||
|
if (message.conversationType == 3) {
|
||||||
|
RongIMLib.sendReadReceiptRequest(messageId)
|
||||||
|
}
|
||||||
|
|
||||||
|
success(messageId)
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
icon: 'none',
|
||||||
|
title: '发送失败' + code
|
||||||
|
})
|
||||||
|
fail(code)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -234,6 +311,8 @@ export default {
|
|||||||
sentText,
|
sentText,
|
||||||
sentVoice,
|
sentVoice,
|
||||||
sentImage,
|
sentImage,
|
||||||
sentGif,
|
sentFile,
|
||||||
sendFile
|
sentLocation,
|
||||||
|
sentVideo,
|
||||||
|
sentAudio
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user