Compare commits
24 Commits
e9184b90c1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e07d40908b | ||
| e4d73085bc | |||
| ca40d790b1 | |||
|
|
aadef3c148 | ||
| 81d4b9017d | |||
| 335a3aa8d6 | |||
| 9628c8ccec | |||
| dbda19870f | |||
| 04d9d772c4 | |||
| bce7822e51 | |||
| 39b8f158c0 | |||
| bf94cca533 | |||
| e8e496cf37 | |||
| 3e1275fc74 | |||
| 033d0e6317 | |||
| fb3d8ff950 | |||
| 76064b3ea2 | |||
| cd63785274 | |||
|
|
33f1899b75 | ||
|
|
76854d3714 | ||
| 1b027783ea | |||
|
|
0b61a8c7f4 | ||
|
|
17899df882 | ||
| c69722491c |
8
App.vue
8
App.vue
@@ -1,13 +1,9 @@
|
|||||||
<script>
|
<script>
|
||||||
import {
|
import { getVersions } from './apis/interfaces/versions'
|
||||||
getVersions
|
|
||||||
} from './apis/interfaces/versions'
|
|
||||||
import im from '@/utils/im/index.js'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
onLaunch: function() {
|
onLaunch: function() {
|
||||||
im.initIm('lmxuhwaglu76d')
|
// return
|
||||||
return
|
|
||||||
//#ifdef APP-PLUS
|
//#ifdef APP-PLUS
|
||||||
// 获取系统版本号
|
// 获取系统版本号
|
||||||
getVersions({
|
getVersions({
|
||||||
|
|||||||
@@ -1,330 +0,0 @@
|
|||||||
/**
|
|
||||||
* Web唐明明
|
|
||||||
* 匆匆数载恍如梦,岁月迢迢华发增。
|
|
||||||
* 碌碌无为枉半生,一朝惊醒万事空。
|
|
||||||
* moduleName: 聊聊
|
|
||||||
*/
|
|
||||||
import store from '@/store'
|
|
||||||
import {
|
|
||||||
request
|
|
||||||
} from '../index'
|
|
||||||
|
|
||||||
// 获取好友列表
|
|
||||||
const getFriends = () => {
|
|
||||||
return request({
|
|
||||||
url: 'im/friends',
|
|
||||||
}, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取好友列表
|
|
||||||
const getFriendsLetter = () => {
|
|
||||||
return request({
|
|
||||||
url: 'im/friends/letter',
|
|
||||||
}, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取融云token
|
|
||||||
const getImToken = () => {
|
|
||||||
return request({
|
|
||||||
url: 'im/token',
|
|
||||||
}, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除好友
|
|
||||||
const deleteFriend = (targetId) => {
|
|
||||||
return request({
|
|
||||||
method: 'DELETE',
|
|
||||||
url: 'im/friends/' + targetId,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取用户信息
|
|
||||||
const getUserInfo = (targetId) => {
|
|
||||||
return request({
|
|
||||||
url: 'im/userInfo/' + targetId,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查看好友资料,附带好友关系
|
|
||||||
*/
|
|
||||||
const getFriendInfo = (userId) => {
|
|
||||||
return request({
|
|
||||||
url: 'im/friendInfo/' + userId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 获取好友申请列表
|
|
||||||
*/
|
|
||||||
const getPedings = () => {
|
|
||||||
return request({
|
|
||||||
url: 'im/friends/pending'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const resolveFriend = (targetId) => {
|
|
||||||
return request({
|
|
||||||
method: 'POST',
|
|
||||||
url: 'im/friends/accept/' + targetId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const rejectFriend = (targetId) => {
|
|
||||||
return request({
|
|
||||||
method: 'DELETE',
|
|
||||||
url: 'im/friends/accept/' + targetId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const searchFriend = (value) => {
|
|
||||||
return request({
|
|
||||||
url: 'im/search',
|
|
||||||
data: {
|
|
||||||
keyword: value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const pedingFriend = (recipient, message) => {
|
|
||||||
return request({
|
|
||||||
method: 'POST',
|
|
||||||
url: 'im/friends/' + recipient,
|
|
||||||
data: {
|
|
||||||
message
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 以下是群组相关业务的接口
|
|
||||||
const getMyGroups = () => {
|
|
||||||
return request({
|
|
||||||
url: 'im/groups'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取群信息,包含基础信息和 14 个用户
|
|
||||||
*/
|
|
||||||
const getGroupInfo = (groupId) => {
|
|
||||||
return request({
|
|
||||||
url: 'im/groups/' + groupId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 群组基础信息
|
|
||||||
*/
|
|
||||||
const getGroupBase = (groupId) => {
|
|
||||||
return request({
|
|
||||||
url: 'im/groups/' + groupId + '/base'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const getGroupUsers = (groupId, limit) => {
|
|
||||||
limit = limit || 0
|
|
||||||
return request({
|
|
||||||
url: 'im/groups/' + groupId + '/users?limit=' + limit
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 公告列表
|
|
||||||
const getGroupAnnouncements = (groupId) => {
|
|
||||||
return request({
|
|
||||||
url: 'im/groups/' + groupId + '/announcements'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 创建公告
|
|
||||||
const createGroupAnnouncement = (groupId, content) => {
|
|
||||||
return request({
|
|
||||||
method: 'POST',
|
|
||||||
url: 'im/groups/' + groupId + '/announcements',
|
|
||||||
data: {
|
|
||||||
content: content
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 查看该公告详情
|
|
||||||
const getGroupAnnouncement = (groupId, announcementId) => {
|
|
||||||
return request({
|
|
||||||
method: 'GET',
|
|
||||||
url: 'im/groups/' + groupId + '/announcements/' + announcementId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 删除该公告
|
|
||||||
const deleteGroupAnnouncement = (groupId, announcementId) => {
|
|
||||||
return request({
|
|
||||||
method: 'DELETE',
|
|
||||||
url: 'im/groups/' + groupId + '/announcements/' + announcementId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 置顶群公告
|
|
||||||
const topGroupAnnouncement = (groupId, announcementId) => {
|
|
||||||
return request({
|
|
||||||
method: 'POST',
|
|
||||||
url: 'im/groups/' + groupId + '/announcements/' + announcementId + '/top',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建群聊
|
|
||||||
*/
|
|
||||||
const createGroup = (data) => {
|
|
||||||
return request({
|
|
||||||
method: 'POST',
|
|
||||||
url: 'im/groups',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateGroup = (groupId, data) => {
|
|
||||||
return request({
|
|
||||||
method: 'PUT',
|
|
||||||
url: 'im/groups/' + groupId,
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搜索群聊
|
|
||||||
*/
|
|
||||||
const searchGroup = (name) => {
|
|
||||||
return request({
|
|
||||||
url: 'im/groups/search?name=' + name
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 加群前,获取的群信息
|
|
||||||
*/
|
|
||||||
const joinGroupPre = (groupId) => {
|
|
||||||
return request({
|
|
||||||
url: 'im/groups/' + groupId + '/join'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const joinGroup = (groupId, message) => {
|
|
||||||
return request({
|
|
||||||
method: 'POST',
|
|
||||||
url: 'im/groups/' + groupId + '/join',
|
|
||||||
data: {
|
|
||||||
message
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const quitGroup = (groupId) => {
|
|
||||||
return request({
|
|
||||||
method: 'DELETE',
|
|
||||||
url: 'im/groups/' + groupId + '/quit'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解散群聊
|
|
||||||
*/
|
|
||||||
const dismissGroup = (groupId) => {
|
|
||||||
return request({
|
|
||||||
method: 'DELETE',
|
|
||||||
url: 'im/groups/' + groupId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 移除群成员
|
|
||||||
*/
|
|
||||||
const removeGroupUser = (groupId, userId) => {
|
|
||||||
return request({
|
|
||||||
method: 'DELETE',
|
|
||||||
url: 'im/groups/' + groupId + '/users/' + userId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 邀请群成员
|
|
||||||
*/
|
|
||||||
const inviteGroupUser = (groupId, userIds, allowIds) => {
|
|
||||||
return request({
|
|
||||||
method: 'POST',
|
|
||||||
url: 'im/groups/' + groupId + '/invite',
|
|
||||||
data: {
|
|
||||||
userIds: userIds,
|
|
||||||
allowIds: allowIds
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置群管理
|
|
||||||
*/
|
|
||||||
const setGroupAdmin = (groupId, userId) => {
|
|
||||||
return request({
|
|
||||||
method: 'POST',
|
|
||||||
url: 'im/groups/' + groupId + '/admin/' + userId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 移除群管理
|
|
||||||
*/
|
|
||||||
const removeGroupAdmin = (groupId, userId) => {
|
|
||||||
return request({
|
|
||||||
method: 'DELETE',
|
|
||||||
url: 'im/groups/' + groupId + '/admin/' + userId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 转移群主
|
|
||||||
*/
|
|
||||||
const transferGroupOwner = (groupId, userId) => {
|
|
||||||
return request({
|
|
||||||
method: 'POST',
|
|
||||||
url: 'im/groups/' + groupId + '/owner/' + userId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 通过审核验证群成员
|
|
||||||
const groupMakeSure = (groupId, user) => {
|
|
||||||
return request({
|
|
||||||
url: `im/groups/${groupId}/makesure/${user}`,
|
|
||||||
method: 'POST'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export {
|
|
||||||
getImToken,
|
|
||||||
deleteFriend,
|
|
||||||
getFriends,
|
|
||||||
getFriendsLetter,
|
|
||||||
getUserInfo,
|
|
||||||
getFriendInfo,
|
|
||||||
getPedings,
|
|
||||||
resolveFriend,
|
|
||||||
rejectFriend,
|
|
||||||
searchFriend,
|
|
||||||
pedingFriend,
|
|
||||||
getMyGroups,
|
|
||||||
createGroup,
|
|
||||||
updateGroup,
|
|
||||||
getGroupInfo,
|
|
||||||
getGroupBase,
|
|
||||||
getGroupUsers,
|
|
||||||
getGroupAnnouncements,
|
|
||||||
getGroupAnnouncement,
|
|
||||||
createGroupAnnouncement,
|
|
||||||
deleteGroupAnnouncement,
|
|
||||||
topGroupAnnouncement,
|
|
||||||
searchGroup,
|
|
||||||
joinGroupPre,
|
|
||||||
joinGroup,
|
|
||||||
quitGroup,
|
|
||||||
dismissGroup,
|
|
||||||
inviteGroupUser,
|
|
||||||
removeGroupUser,
|
|
||||||
transferGroupOwner,
|
|
||||||
setGroupAdmin,
|
|
||||||
removeGroupAdmin,
|
|
||||||
groupMakeSure, // 通过审核
|
|
||||||
}
|
|
||||||
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>
|
||||||
26
main.js
26
main.js
@@ -10,20 +10,11 @@ import Vue from 'vue'
|
|||||||
import store from './store'
|
import store from './store'
|
||||||
import uView from 'uview-ui'
|
import uView from 'uview-ui'
|
||||||
import filters from './utils/filters.js'
|
import filters from './utils/filters.js'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
router,
|
router,
|
||||||
RouterMount
|
RouterMount
|
||||||
} from 'router'
|
} from 'router'
|
||||||
import {
|
|
||||||
usqlite
|
|
||||||
} from '@/uni_modules/onemue-USQLite/js_sdk/usqlite.js'
|
|
||||||
import {
|
|
||||||
contactModel
|
|
||||||
} from '@/utils/im/models.js'
|
|
||||||
|
|
||||||
Object.keys(filters).forEach(key => {
|
|
||||||
Vue.filter(key, filters[key])
|
|
||||||
})
|
|
||||||
|
|
||||||
Vue.use(uView);
|
Vue.use(uView);
|
||||||
Vue.use(router)
|
Vue.use(router)
|
||||||
@@ -31,21 +22,6 @@ Vue.use(router)
|
|||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
Vue.prototype.$store = store
|
Vue.prototype.$store = store
|
||||||
|
|
||||||
usqlite.connect({
|
|
||||||
name: 'zh-health', // 数据库名称
|
|
||||||
path: '_doc/health.db', // 路径
|
|
||||||
}, (err, res) => {
|
|
||||||
uni.getStorage({
|
|
||||||
key: 'FIRST_RUN',
|
|
||||||
fail: () => {
|
|
||||||
contactModel.create((err, res) => {
|
|
||||||
console.error('SQLITE 创建表格', err, res)
|
|
||||||
uni.setStorageSync('FIRST_RUN', 'X')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
App.mpType = 'app'
|
App.mpType = 'app'
|
||||||
const app = new Vue({
|
const app = new Vue({
|
||||||
store,
|
store,
|
||||||
|
|||||||
@@ -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\"/>",
|
||||||
@@ -112,33 +113,33 @@
|
|||||||
},
|
},
|
||||||
"icons" : {
|
"icons" : {
|
||||||
"android" : {
|
"android" : {
|
||||||
"hdpi" : "",
|
"hdpi" : "unpackage/res/icons/72x72.png",
|
||||||
"xhdpi" : "",
|
"xhdpi" : "unpackage/res/icons/96x96.png",
|
||||||
"xxhdpi" : "",
|
"xxhdpi" : "unpackage/res/icons/144x144.png",
|
||||||
"xxxhdpi" : ""
|
"xxxhdpi" : "unpackage/res/icons/192x192.png"
|
||||||
},
|
},
|
||||||
"ios" : {
|
"ios" : {
|
||||||
"appstore" : "",
|
"appstore" : "unpackage/res/icons/1024x1024.png",
|
||||||
"ipad" : {
|
"ipad" : {
|
||||||
"app" : "",
|
"app" : "unpackage/res/icons/76x76.png",
|
||||||
"app@2x" : "",
|
"app@2x" : "unpackage/res/icons/152x152.png",
|
||||||
"notification" : "",
|
"notification" : "unpackage/res/icons/20x20.png",
|
||||||
"notification@2x" : "",
|
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||||
"proapp@2x" : "",
|
"proapp@2x" : "unpackage/res/icons/167x167.png",
|
||||||
"settings" : "",
|
"settings" : "unpackage/res/icons/29x29.png",
|
||||||
"settings@2x" : "",
|
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||||
"spotlight" : "",
|
"spotlight" : "unpackage/res/icons/40x40.png",
|
||||||
"spotlight@2x" : ""
|
"spotlight@2x" : "unpackage/res/icons/80x80.png"
|
||||||
},
|
},
|
||||||
"iphone" : {
|
"iphone" : {
|
||||||
"app@2x" : "",
|
"app@2x" : "unpackage/res/icons/120x120.png",
|
||||||
"app@3x" : "",
|
"app@3x" : "unpackage/res/icons/180x180.png",
|
||||||
"notification@2x" : "",
|
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||||
"notification@3x" : "",
|
"notification@3x" : "unpackage/res/icons/60x60.png",
|
||||||
"settings@2x" : "",
|
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||||
"settings@3x" : "",
|
"settings@3x" : "unpackage/res/icons/87x87.png",
|
||||||
"spotlight@2x" : "",
|
"spotlight@2x" : "unpackage/res/icons/80x80.png",
|
||||||
"spotlight@3x" : ""
|
"spotlight@3x" : "unpackage/res/icons/120x120.png"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -146,36 +147,7 @@
|
|||||||
"androidStyle" : "common"
|
"androidStyle" : "common"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nativePlugins" : {
|
"nativePlugins" : {}
|
||||||
"RongCloud-Call" : {
|
|
||||||
"__plugin_info__" : {
|
|
||||||
"name" : "RCUniCall",
|
|
||||||
"description" : "融云实时音视频 SDK uni 原生插件",
|
|
||||||
"platforms" : "Android,iOS",
|
|
||||||
"url" : "https://ext.dcloud.net.cn/plugin?id=6372",
|
|
||||||
"android_package_name" : "io.zhhealth.app",
|
|
||||||
"ios_bundle_id" : "io.zhhealth.app",
|
|
||||||
"isCloud" : true,
|
|
||||||
"bought" : 1,
|
|
||||||
"pid" : "6372",
|
|
||||||
"parameters" : {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"RongCloud-IM" : {
|
|
||||||
"__plugin_info__" : {
|
|
||||||
"name" : "RCUniIM",
|
|
||||||
"description" : "融云即时通讯 SDK uni 原生插件",
|
|
||||||
"platforms" : "Android,iOS",
|
|
||||||
"url" : "https://ext.dcloud.net.cn/plugin?id=6120",
|
|
||||||
"android_package_name" : "io.zhhealth.app",
|
|
||||||
"ios_bundle_id" : "io.zhhealth.app",
|
|
||||||
"isCloud" : true,
|
|
||||||
"bought" : 1,
|
|
||||||
"pid" : "6120",
|
|
||||||
"parameters" : {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
/* 快应用特有相关 */
|
/* 快应用特有相关 */
|
||||||
"quickapp" : {},
|
"quickapp" : {},
|
||||||
|
|||||||
32
package-lock.json
generated
32
package-lock.json
generated
@@ -12,10 +12,8 @@
|
|||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"uni-read-pages": "^1.0.5",
|
"uni-read-pages": "^1.0.5",
|
||||||
"uni-simple-router": "^2.0.7",
|
"uni-simple-router": "^2.0.7",
|
||||||
"uview-ui": "^2.0.19",
|
"uview-ui": "^2.0.27"
|
||||||
"vuex": "^3.6.2"
|
}
|
||||||
},
|
|
||||||
"devDependencies": {}
|
|
||||||
},
|
},
|
||||||
"node_modules/moment": {
|
"node_modules/moment": {
|
||||||
"version": "2.29.1",
|
"version": "2.29.1",
|
||||||
@@ -37,20 +35,12 @@
|
|||||||
"integrity": "sha512-8FKv5dw7Eoonm0gkO8udprrxzin0fNUI0+AvIphFkFRH5ZmP5ZWJ2pvnWzb2NiiqQSECTSU5VSB7HhvOSwD5eA=="
|
"integrity": "sha512-8FKv5dw7Eoonm0gkO8udprrxzin0fNUI0+AvIphFkFRH5ZmP5ZWJ2pvnWzb2NiiqQSECTSU5VSB7HhvOSwD5eA=="
|
||||||
},
|
},
|
||||||
"node_modules/uview-ui": {
|
"node_modules/uview-ui": {
|
||||||
"version": "2.0.19",
|
"version": "2.0.29",
|
||||||
"resolved": "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.19.tgz",
|
"resolved": "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.29.tgz",
|
||||||
"integrity": "sha512-ddZiaP7R9wsUxMzAuhuXgh5OswgCm2lKuulTqjnRXFr0uUWsgL1iBifU3GbOwpwP0LtTHKJOo9rYv1LP0WXmzA==",
|
"integrity": "sha512-d5SttbPcowomrgpL7A1LMKRbemXtyyzpPCy98/+VQR3jfSyyHC9tfj/ZeAOKpqTn1rf9gOj2wc5tda/kVmYX2Q==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"HBuilderX": "^3.1.0"
|
"HBuilderX": "^3.1.0"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"node_modules/vuex": {
|
|
||||||
"version": "3.6.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz",
|
|
||||||
"integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==",
|
|
||||||
"peerDependencies": {
|
|
||||||
"vue": "^2.0.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -70,15 +60,9 @@
|
|||||||
"integrity": "sha512-8FKv5dw7Eoonm0gkO8udprrxzin0fNUI0+AvIphFkFRH5ZmP5ZWJ2pvnWzb2NiiqQSECTSU5VSB7HhvOSwD5eA=="
|
"integrity": "sha512-8FKv5dw7Eoonm0gkO8udprrxzin0fNUI0+AvIphFkFRH5ZmP5ZWJ2pvnWzb2NiiqQSECTSU5VSB7HhvOSwD5eA=="
|
||||||
},
|
},
|
||||||
"uview-ui": {
|
"uview-ui": {
|
||||||
"version": "2.0.19",
|
"version": "2.0.29",
|
||||||
"resolved": "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.19.tgz",
|
"resolved": "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.29.tgz",
|
||||||
"integrity": "sha512-ddZiaP7R9wsUxMzAuhuXgh5OswgCm2lKuulTqjnRXFr0uUWsgL1iBifU3GbOwpwP0LtTHKJOo9rYv1LP0WXmzA=="
|
"integrity": "sha512-d5SttbPcowomrgpL7A1LMKRbemXtyyzpPCy98/+VQR3jfSyyHC9tfj/ZeAOKpqTn1rf9gOj2wc5tda/kVmYX2Q=="
|
||||||
},
|
|
||||||
"vuex": {
|
|
||||||
"version": "3.6.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz",
|
|
||||||
"integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==",
|
|
||||||
"requires": {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
169
pages.json
169
pages.json
@@ -363,169 +363,6 @@
|
|||||||
"navigationBarBackgroundColor": "#FFFFFF"
|
"navigationBarBackgroundColor": "#FFFFFF"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "pages/im/index",
|
|
||||||
"name": "IM",
|
|
||||||
"style": {
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/private/chat",
|
|
||||||
"style": {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/private/call",
|
|
||||||
"name": "imPrivateCall",
|
|
||||||
"style": {
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/friends/index",
|
|
||||||
"name": "imFriends",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "通讯录",
|
|
||||||
"app-plus": {
|
|
||||||
"titleNView": {
|
|
||||||
"type": "default",
|
|
||||||
"buttons": [{
|
|
||||||
"float": "right",
|
|
||||||
"fontSrc": "/static/iconfont.ttf",
|
|
||||||
"text": "\ue603",
|
|
||||||
"fontSize": "20px"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/friends/pending",
|
|
||||||
"name": "imFriendsPending",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "新朋友"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/friends/search",
|
|
||||||
"name": "SearchFriend",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "好友搜索"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/friends/info",
|
|
||||||
"name": "imFriendsInfo",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "用户资料"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/friends/mine",
|
|
||||||
"name": "imFriendsMine",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "我的二维码",
|
|
||||||
"navigationBarBackgroundColor": "#34CE98",
|
|
||||||
"navigationBarTextStyle": "white"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/group/index",
|
|
||||||
"name": "imGroups",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "我的群聊",
|
|
||||||
"app-plus": {
|
|
||||||
"titleNView": {
|
|
||||||
"type": "default",
|
|
||||||
"buttons": [{
|
|
||||||
"float": "right",
|
|
||||||
"fontSrc": "/static/iconfont.ttf",
|
|
||||||
"text": "\ue60a",
|
|
||||||
"fontSize": "20px"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/group/chat",
|
|
||||||
"name": "imGroupChat",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "群聊",
|
|
||||||
"app-plus": {
|
|
||||||
"titleNView": {
|
|
||||||
"type": "default",
|
|
||||||
"buttons": [{
|
|
||||||
"float": "right",
|
|
||||||
"fontSrc": "/static/iconfont.ttf",
|
|
||||||
"text": "\ue607",
|
|
||||||
"fontSize": "20px"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/group/apply",
|
|
||||||
"name": "imGroupApply",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "申请加群"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/group/info",
|
|
||||||
"name": "imGroupInfo",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "群信息"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/group/invite",
|
|
||||||
"name": "imGroupInvite",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "选择联系人"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/group/reviewed",
|
|
||||||
"name": "imGroupReviewed",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "群聊邀请确认"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/group/users",
|
|
||||||
"name": "imGroupUsers",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "群成员"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/group/announcement",
|
|
||||||
"name": "imGroupAnnouncement",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "群公告",
|
|
||||||
"app-plus": {
|
|
||||||
"titleNView": {
|
|
||||||
"type": "default",
|
|
||||||
"buttons": [{
|
|
||||||
"float": "right",
|
|
||||||
"fontSrc": "/static/iconfont.ttf",
|
|
||||||
"text": "\ue60a",
|
|
||||||
"fontSize": "20px"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/im/group/announceCreate",
|
|
||||||
"name": "imGroupAnnouncementCreate",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "发布群公告"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "pages/wallet/add",
|
"path": "pages/wallet/add",
|
||||||
"name": "WalletAdd",
|
"name": "WalletAdd",
|
||||||
@@ -659,12 +496,6 @@
|
|||||||
"pagePath": "pages/service/index",
|
"pagePath": "pages/service/index",
|
||||||
"text": "生活"
|
"text": "生活"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"iconPath": "static/tabBar/tabBar_04.png",
|
|
||||||
"selectedIconPath": "static/tabBar/tabBar_show_04.png",
|
|
||||||
"pagePath": "pages/im/index",
|
|
||||||
"text": "聊聊"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"iconPath": "static/tabBar/tabBar_03.png",
|
"iconPath": "static/tabBar/tabBar_03.png",
|
||||||
"selectedIconPath": "static/tabBar/tabBar_show_03.png",
|
"selectedIconPath": "static/tabBar/tabBar_show_03.png",
|
||||||
|
|||||||
BIN
pages/.DS_Store
vendored
BIN
pages/.DS_Store
vendored
Binary file not shown.
@@ -34,15 +34,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { getSms, smsAuth } from "@/apis/interfaces/auth";
|
||||||
getSms,
|
|
||||||
smsAuth
|
|
||||||
} from "@/apis/interfaces/auth";
|
|
||||||
import userAuth from "@/public/userAuth";
|
import userAuth from "@/public/userAuth";
|
||||||
import {
|
|
||||||
getImToken
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
import im from '@/utils/im/index.js'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@@ -64,11 +57,6 @@
|
|||||||
"setToken",
|
"setToken",
|
||||||
res.token_type + " " + res.access_token
|
res.token_type + " " + res.access_token
|
||||||
);
|
);
|
||||||
// 在这里,登录成功,链接IM服务
|
|
||||||
getImToken().then(res => {
|
|
||||||
console.log('在这获取IM-TOKEN', res);
|
|
||||||
im.connect(res.token, res.userInfo, () => {})
|
|
||||||
})
|
|
||||||
this.$Router.back();
|
this.$Router.back();
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
<template>
|
|
||||||
<u-alert type="warning" v-if="connection != 0" :description="description" show-icon />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
connection: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
description() {
|
|
||||||
return this.connectionStatusMap.filter(item => item.index == this.connection)[0].text
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
connectionStatusMap: [{
|
|
||||||
index: -1,
|
|
||||||
text: '网络不可用'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: 0,
|
|
||||||
text: '连接成功'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: 1,
|
|
||||||
text: '连接中'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: 2,
|
|
||||||
text: '未连接'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: 3,
|
|
||||||
text: '用户账号在其它设备登录'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: 4,
|
|
||||||
text: 'TOKEN过期'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: 6,
|
|
||||||
text: '用户被禁用'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: 12,
|
|
||||||
text: '退出登录'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: 13,
|
|
||||||
text: '连接暂时被挂起'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: 14,
|
|
||||||
text: '连接超时'
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
</style>
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="message--cell">
|
|
||||||
<view class="avatar">
|
|
||||||
<u-badge max="99" shape="horn" absolute :offset="[-5, -8]" :value="item.unreadMessageCount" />
|
|
||||||
<u-avatar :src="contact(item.targetId).portraitUrl" shape="square" :size="avatarSize" />
|
|
||||||
</view>
|
|
||||||
<view class="content">
|
|
||||||
<view class="header">
|
|
||||||
<view class="name">
|
|
||||||
{{ contact(item.targetId).name }}
|
|
||||||
<text v-if="item.conversationType === 3" class='group'>[群]</text>
|
|
||||||
</view>
|
|
||||||
<view class="time">{{ item.sentTime|timeCustomCN }}</view>
|
|
||||||
</view>
|
|
||||||
<message-preview class="preview" :msg="item.latestMessage" :draft="item.draft"
|
|
||||||
:conversationType="item.conversationType" :user="item.latestMessage.userInfo" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import messagePreview from './messagePreview'
|
|
||||||
import utils from '@/utils/index.js'
|
|
||||||
import imBase from '../../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase
|
|
||||||
],
|
|
||||||
props: {
|
|
||||||
item: {
|
|
||||||
type: Object,
|
|
||||||
default: function() {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
messagePreview
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.message--cell {
|
|
||||||
display: flex;
|
|
||||||
padding: 20rpx 10rpx 0 30rpx;
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
position: relative;
|
|
||||||
padding-top: 5rpx;
|
|
||||||
|
|
||||||
.u-badge {
|
|
||||||
z-index: 998;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
margin-left: 30rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: relative;
|
|
||||||
flex: 1;
|
|
||||||
border-bottom-width: 0.5px !important;
|
|
||||||
border-color: #eee !important;
|
|
||||||
border-bottom-style: solid;
|
|
||||||
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font-size: $title-size + 2;
|
|
||||||
color: #454545;
|
|
||||||
|
|
||||||
.group {
|
|
||||||
color: $main-color;
|
|
||||||
font-size: $title-size-m - 4;
|
|
||||||
margin-left: 4px;
|
|
||||||
position: relative;
|
|
||||||
top: -4rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
font-size: $title-size-sm - 3;
|
|
||||||
color: $text-gray-m;
|
|
||||||
position: absolute;
|
|
||||||
right: 30rpx;
|
|
||||||
padding-top: 4rpx;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view>
|
|
||||||
<view class="preview" v-if="draft">
|
|
||||||
<text class="draft">[草稿]</text> {{ draft }}
|
|
||||||
</view>
|
|
||||||
<block v-else>
|
|
||||||
<view class="preview" v-if="msg.objectName=='RC:TxtMsg'">
|
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>{{ msg.content || '' }}
|
|
||||||
</view>
|
|
||||||
<view class="preview" v-if="msg.objectName=='RC:HQVCMsg'">
|
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[语音]
|
|
||||||
</view>
|
|
||||||
<view class="preview" v-if="msg.objectName=='RC:ImgMsg'">
|
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[图片]
|
|
||||||
</view>
|
|
||||||
<view class="preview" v-if="msg.objectName=='RC:GIFMsg'">
|
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[表情]
|
|
||||||
</view>
|
|
||||||
<view class="preview" v-if="msg.objectName=='RC:FileMsg'">
|
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[文件]
|
|
||||||
</view>
|
|
||||||
<view class="preview" v-if="msg.objectName=='RC:LBSMsg'">
|
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[位置]
|
|
||||||
</view>
|
|
||||||
<view class="preview" v-if="msg.objectName=='RC:InfoNtf' && JSON.parse(msg.message).mediaType==0">
|
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[语音通话]
|
|
||||||
</view>
|
|
||||||
<view class="preview" v-if="msg.objectName=='RC:InfoNtf' && JSON.parse(msg.message).mediaType==1">
|
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text>[视频通话]
|
|
||||||
</view>
|
|
||||||
<view class="preview" v-if="msg.objectName=='RC:GrpNtf'">
|
|
||||||
[{{ msg.message }}]
|
|
||||||
</view>
|
|
||||||
<view class="preview" v-if="msg.objectName=='RC:RcNtf'">
|
|
||||||
<text v-if="conversationType == 3">{{ user.name }}:</text> 撤回了一条消息
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
msg: {
|
|
||||||
type: Object,
|
|
||||||
default: {}
|
|
||||||
},
|
|
||||||
conversationType: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
draft: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
user: {
|
|
||||||
type: Object,
|
|
||||||
default: function() {
|
|
||||||
return {
|
|
||||||
name: ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.preview {
|
|
||||||
word-break: break-all;
|
|
||||||
color: $text-gray-m;
|
|
||||||
padding-top: 6rpx;
|
|
||||||
padding-bottom: $padding;
|
|
||||||
font-size: $title-size-m - 2;
|
|
||||||
height: 32rpx;
|
|
||||||
line-height: 32rpx;
|
|
||||||
width: 520rpx;
|
|
||||||
@extend .nowrap;
|
|
||||||
|
|
||||||
.draft {
|
|
||||||
color: $text-price;
|
|
||||||
padding-right: 10rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,181 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view>
|
|
||||||
<view class="shade" @click="hidePop" @touchmove="hidePop" v-show="showPop">
|
|
||||||
<view class="pop" :style="popStyle" :class="{'show':showPop}">
|
|
||||||
<view v-for="(item, index) in popButton" :key="index" @click="pickerMenu(index)">
|
|
||||||
{{ item }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view v-for="(item, index) in conversations" :key="index"
|
|
||||||
:class="['message', { 'is-top': item.isTop, 'is-active': pickedItem.targetId == item.targetId }]"
|
|
||||||
:data-item="item" @longpress="onLongPress" @click="toDetail(item)">
|
|
||||||
<message-cell :item="item" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import im from '@/utils/im/index.js'
|
|
||||||
import messageCell from './conversation/messageCell'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
conversations: {
|
|
||||||
type: Array,
|
|
||||||
default: function() {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
messageCell
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
/* 窗口尺寸 */
|
|
||||||
winSize: {},
|
|
||||||
/* 显示操作弹窗 */
|
|
||||||
showPop: false,
|
|
||||||
/* 弹窗按钮列表 */
|
|
||||||
popButton: ['置顶聊天', '标记已读', '删除该聊天'],
|
|
||||||
/* 弹窗定位样式 */
|
|
||||||
popStyle: "",
|
|
||||||
pickedItem: {},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
uni.getSystemInfo({
|
|
||||||
success: (e) => {
|
|
||||||
this.winSize = {
|
|
||||||
width: e.windowWidth,
|
|
||||||
height: e.windowHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 隐藏功能菜单
|
|
||||||
hidePop() {
|
|
||||||
this.showPop = false
|
|
||||||
this.pickedItem = {}
|
|
||||||
setTimeout(() => {
|
|
||||||
this.showShade = false
|
|
||||||
}, 250)
|
|
||||||
},
|
|
||||||
// 点击会话功能菜单
|
|
||||||
pickerMenu(index) {
|
|
||||||
if (index == 0) {
|
|
||||||
RongIMLib.setConversationToTop(this.pickedItem.conversationType, this.pickedItem.targetId, !this
|
|
||||||
.pickedItem.isTop)
|
|
||||||
} else if (index == 1) {
|
|
||||||
RongIMLib.clearMessagesUnreadStatus(this.pickedItem.conversationType, this.pickedItem.targetId, this
|
|
||||||
.pickedItem.sentTime)
|
|
||||||
} else {
|
|
||||||
RongIMLib.removeConversation(this.pickedItem.conversationType, this.pickedItem.targetId)
|
|
||||||
RongIMLib.deleteMessages(this.pickedItem.conversationType, this.pickedItem.targetId)
|
|
||||||
}
|
|
||||||
this.$emit('refresh')
|
|
||||||
im.setNotifyBadge()
|
|
||||||
this.hidePop()
|
|
||||||
},
|
|
||||||
// 长按会话,展示功能菜单
|
|
||||||
onLongPress(e) {
|
|
||||||
let [touches, style, item] = [e.touches[0], "", e.currentTarget.dataset.item]
|
|
||||||
|
|
||||||
if (touches.clientY > (this.winSize.height / 2)) {
|
|
||||||
style = `bottom:${this.winSize.height-touches.clientY}px;`
|
|
||||||
} else {
|
|
||||||
style = `top:${touches.clientY}px;`
|
|
||||||
}
|
|
||||||
|
|
||||||
if (touches.clientX > (this.winSize.width / 2)) {
|
|
||||||
style += `right:${this.winSize.width-touches.clientX}px`
|
|
||||||
} else {
|
|
||||||
style += `left:${touches.clientX}px`
|
|
||||||
}
|
|
||||||
|
|
||||||
this.popButton[0] = item.isTop ? '取消置顶' : '置顶聊天'
|
|
||||||
this.popStyle = style
|
|
||||||
this.pickedItem = item
|
|
||||||
this.$nextTick(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.showPop = true;
|
|
||||||
}, 10)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
toDetail(item) {
|
|
||||||
if (item.conversationType == 1) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/private/chat?targetId=' + item.targetId
|
|
||||||
})
|
|
||||||
} else if (item.conversationType == 3) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/group/chat?targetId=' + item.targetId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
this.hidePop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.message {
|
|
||||||
background: white;
|
|
||||||
|
|
||||||
&.is-top {
|
|
||||||
background: $window-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-active {
|
|
||||||
background: #F8FAFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 遮罩 */
|
|
||||||
.shade {
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 999;
|
|
||||||
|
|
||||||
.pop {
|
|
||||||
border-radius: 10rpx;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 101;
|
|
||||||
width: 200rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: 28rpx;
|
|
||||||
text-align: left;
|
|
||||||
color: #333;
|
|
||||||
background-color: #fff;
|
|
||||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
|
|
||||||
line-height: 80rpx;
|
|
||||||
transition: transform 0.15s ease-in-out 0s;
|
|
||||||
user-select: none;
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
transform: scale(0, 0);
|
|
||||||
|
|
||||||
&.show {
|
|
||||||
transform: scale(1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&>view {
|
|
||||||
padding: 0 20rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
user-select: none;
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: #f3f3f3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="apply--cell">
|
|
||||||
<view class="avatar">
|
|
||||||
<u-avatar :src="user.portraitUrl || require('@/static/user/cover.png')" shape="square" :size="avatarSize" />
|
|
||||||
</view>
|
|
||||||
<view class="info">
|
|
||||||
<view class="name"> {{ user.name }}</view>
|
|
||||||
<view class="message"> {{ message.message!=='null' ? message.message : '听说你很优秀,想认识下你~' }} </view>
|
|
||||||
</view>
|
|
||||||
<view class="action">
|
|
||||||
<u-button class="u-button" size="default" type="success" @click="resolve">通过</u-button>
|
|
||||||
<u-button class="u-button" size="default" type="warning" @click="reject">拒绝</u-button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import {
|
|
||||||
resolveFriend,
|
|
||||||
rejectFriend
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
import imBase from '../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase
|
|
||||||
],
|
|
||||||
props: {
|
|
||||||
message: {
|
|
||||||
type: Object,
|
|
||||||
default: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
user() {
|
|
||||||
return JSON.parse(this.message.extra)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
resolve() {
|
|
||||||
resolveFriend(this.message.sourceUserId).then(res => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '通过好友申请'
|
|
||||||
})
|
|
||||||
uni.navigateBack({})
|
|
||||||
}).catch(err => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: err.message
|
|
||||||
})
|
|
||||||
}).finally(() => {
|
|
||||||
this.clearMessages()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
reject() {
|
|
||||||
uni.showModal({
|
|
||||||
title: '拒绝申请',
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
rejectFriend(this.message.sourceUserId).then(res => {
|
|
||||||
this.clearMessages()
|
|
||||||
}).catch(err => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: err.message
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 不管是通过还是拒绝,都要把相关的信息清理
|
|
||||||
clearMessages() {
|
|
||||||
RongIMLib.deleteMessages(RongIMLib.ConversationType.SYSTEM, this.message.sourceUserId)
|
|
||||||
this.$emit('success')
|
|
||||||
uni.$emit('onNewContactConversation')
|
|
||||||
uni.$emit('onNewContactFriends')
|
|
||||||
uni.$emit('onNewContactPendings')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.apply--cell {
|
|
||||||
display: flex;
|
|
||||||
padding: $padding;
|
|
||||||
align-items: center;
|
|
||||||
border-bottom: solid 1rpx #f9f9f9;
|
|
||||||
|
|
||||||
.info {
|
|
||||||
flex: 1;
|
|
||||||
margin-left: $padding;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font-size: $title-size + 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message {
|
|
||||||
color: $text-gray-m;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
margin-top: 10rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.action {
|
|
||||||
justify-content: space-between;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.u-button {
|
|
||||||
padding: 10rpx 20rpx !important;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
height: 60rpx !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.u-button+.u-button {
|
|
||||||
margin-left: 10rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="friend-apply">
|
|
||||||
<block v-for="(item, index) in lists" v-if="lists.length > 0" :key="index">
|
|
||||||
<view class="lists">
|
|
||||||
<view class="" style="width: 100rpx;height: 100rpx;">
|
|
||||||
<u-avatar :src="JSON.parse(item.latestMessage.extra).portraitUrl" shape="square" :size="avatarSize" />
|
|
||||||
</view>
|
|
||||||
<view class="right">
|
|
||||||
<view class="title">
|
|
||||||
<view class="name">{{ item.name }}</view>
|
|
||||||
<view class="des">{{ item.latestMessage.message || '--' }}</view>
|
|
||||||
</view>
|
|
||||||
<view class="agress-btn">
|
|
||||||
<span v-if="isAgree" @click="action('agree', item)">通过</span>
|
|
||||||
<span v-if="isAgree" @click="action('reject', item)">拒绝</span>
|
|
||||||
<span v-if="isApply && !item.is_friend" @click="action('apply', item)">查看</span>
|
|
||||||
<span class="isFri" v-if="isApply && item.is_friend"
|
|
||||||
@click="action('isFriend', item)">已是好友</span>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import imBase from '../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins:[
|
|
||||||
imBase
|
|
||||||
],
|
|
||||||
name: 'friend-apply-reject-agree',
|
|
||||||
props: {
|
|
||||||
lists: {
|
|
||||||
type: Array,
|
|
||||||
default: []
|
|
||||||
},
|
|
||||||
isAgree: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
isReject: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
isApply: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
console.log(this.lists);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
action(type, item) {
|
|
||||||
if (type === 'isFriend') {
|
|
||||||
// ,后期可以跳转到信息介绍页面,先留在这里
|
|
||||||
return uni.showToast({
|
|
||||||
title: '已是好友,无需重复添加',
|
|
||||||
icon: 'none',
|
|
||||||
duration: 2000
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.$emit('action', {
|
|
||||||
type,
|
|
||||||
item
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.lists {
|
|
||||||
padding: 0 $padding;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-start;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: $title-size;
|
|
||||||
color: $text-gray;
|
|
||||||
|
|
||||||
.cover {
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
width: 570rpx;
|
|
||||||
margin-left: $margin - 10;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: $padding 0;
|
|
||||||
border-bottom: solid 1rpx #f9f9f9;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
width: 370rpx;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
width: 100%;
|
|
||||||
color: $text-color;
|
|
||||||
font-size: $title-size + 2;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.des {
|
|
||||||
width: 100%;
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
margin-top: $margin - 10;
|
|
||||||
color: $text-gray-m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.agress-btn {
|
|
||||||
display: flex;
|
|
||||||
color: #fff;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
|
|
||||||
span {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 6rpx 14rpx;
|
|
||||||
background-color: $text-price;
|
|
||||||
border-radius: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
span:nth-child(1) {
|
|
||||||
background-color: $main-color;
|
|
||||||
margin-right: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.isFri {
|
|
||||||
background-color: #f9f9f9 !important;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="friend-apply">
|
|
||||||
<block v-for="(item, index) in lists" v-if="lists.length > 0" :key="index">
|
|
||||||
<view class="lists">
|
|
||||||
<view class="" style="width: 100rpx;height: 100rpx;">
|
|
||||||
<u-avatar :src="item.portraitUrl || require('@/static/user/cover.png')" shape="square" :size="avatarSize" />
|
|
||||||
</view>
|
|
||||||
<view class="right">
|
|
||||||
<view class="title">
|
|
||||||
<view class="name">{{ item.name }}</view>
|
|
||||||
<view class="des">{{ item.address }}</view>
|
|
||||||
</view>
|
|
||||||
<view class="agress-btn">
|
|
||||||
<span v-if="isApply && item.friendship !=='accepted'" @click="action('apply', item)">查看</span>
|
|
||||||
<span class="isFri" v-if="isApply && item.friendship ==='accepted'" @click="action('isFriend', item)">已是好友</span>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import imBase from '../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase
|
|
||||||
],
|
|
||||||
name: 'friend-apply-reject-agree',
|
|
||||||
props: {
|
|
||||||
lists: {
|
|
||||||
type: Array,
|
|
||||||
default: []
|
|
||||||
},
|
|
||||||
isAgree: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
isReject: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
isApply: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
console.log(this.lists);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
action(type, item) {
|
|
||||||
if (type === 'isFriend') {
|
|
||||||
// ,后期可以跳转到信息介绍页面,先留在这里
|
|
||||||
// return uni.showToast({
|
|
||||||
// title: '已是好友,无需重复添加',
|
|
||||||
// icon: 'none',
|
|
||||||
// duration: 2000
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
this.$emit('action', {
|
|
||||||
type,
|
|
||||||
item
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.lists {
|
|
||||||
padding: 0 $padding;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-start;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: $title-size;
|
|
||||||
color: $text-gray;
|
|
||||||
|
|
||||||
.cover {
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
width: 570rpx;
|
|
||||||
margin-left: $margin - 10;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: $padding 0;
|
|
||||||
border-bottom: solid 1rpx #f9f9f9;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
width: 370rpx;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
width: 100%;
|
|
||||||
color: $text-color;
|
|
||||||
font-size: $title-size;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.des {
|
|
||||||
width: 100%;
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
font-size: $title-size-m - 2;
|
|
||||||
margin-top: $margin - 10;
|
|
||||||
color: $text-gray-m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.agress-btn {
|
|
||||||
display: flex;
|
|
||||||
color: #fff;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
|
|
||||||
span {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 6rpx 14rpx;
|
|
||||||
background-color: $text-price;
|
|
||||||
border-radius: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
span:nth-child(1) {
|
|
||||||
background-color: $main-color;
|
|
||||||
margin-right: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.isFri {
|
|
||||||
background-color: #f9f9f9 !important;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,335 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="member--list">
|
|
||||||
<view class="users">
|
|
||||||
<view :class="['user', {'active': item.targetId === currentUser.targetId}]" @longpress="showAction(item)"
|
|
||||||
v-for="(item, index) in users" :key="index" @click="toUser(item)">
|
|
||||||
<view class="avatar">
|
|
||||||
<u-avatar :size="avatarSize" shape="square"
|
|
||||||
:src="contact(item.targetId).portraitUrl || require('@/static/user/cover.png')" />
|
|
||||||
<view class="admin" v-if="item.is_admin === 1">管理</view>
|
|
||||||
<view class="owner" v-if="item.is_admin === 2">群主</view>
|
|
||||||
</view>
|
|
||||||
<view class="name">{{ item.name }}</view>
|
|
||||||
</view>
|
|
||||||
<view class="user" v-if="canInvite">
|
|
||||||
<u-avatar @click="inviteUser" :size="avatarSize" shape="square" icon="plus" bgColor="#f9f9f9"
|
|
||||||
color="#c7c7c7" />
|
|
||||||
<view class="name">邀请好友</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="loadmore" @click="loadMore" v-if="members > users.length">
|
|
||||||
查看更多群成员 <uni-icons size="30rpx" type="right"></uni-icons>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<u-action-sheet :actions="actionMap" :title="actionTitle" cancelText="取消" @close="hideAction"
|
|
||||||
@select="handleAction" :show="actionShow" />
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
getGroupUsers,
|
|
||||||
getGroupBase,
|
|
||||||
removeGroupUser,
|
|
||||||
setGroupAdmin,
|
|
||||||
removeGroupAdmin,
|
|
||||||
transferGroupOwner
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
import utils from '@/utils/index.js'
|
|
||||||
import imBase from '../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase
|
|
||||||
],
|
|
||||||
props: {
|
|
||||||
targetId: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
count: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
users: [],
|
|
||||||
isOwner: false,
|
|
||||||
isAdmin: false,
|
|
||||||
canInvite: false, // 是否可以开启邀请
|
|
||||||
adminUid: 0,
|
|
||||||
members: 0,
|
|
||||||
actionShow: false,
|
|
||||||
actionMap: [],
|
|
||||||
actionTitle: '',
|
|
||||||
currentUser: {},
|
|
||||||
labelSize: 14,
|
|
||||||
iconSize: 14
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.iconSize = utils.rpx2px(26)
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.initGroupInfo()
|
|
||||||
getGroupUsers(this.targetId, this.count).then(res => {
|
|
||||||
this.users = res
|
|
||||||
res.map(item => {
|
|
||||||
this.$store.dispatch('updateContact', item)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initGroupInfo() {
|
|
||||||
getGroupBase(this.targetId).then(res => {
|
|
||||||
this.isOwner = res.is_owner
|
|
||||||
this.isAdmin = res.is_admin
|
|
||||||
this.adminUid = res.user_id
|
|
||||||
this.members = res.members
|
|
||||||
this.canInvite = res.can_invite
|
|
||||||
})
|
|
||||||
},
|
|
||||||
initUsers() {
|
|
||||||
getGroupUsers(this.targetId, this.count).then(res => {
|
|
||||||
this.users = res
|
|
||||||
})
|
|
||||||
this.currentUser = {}
|
|
||||||
},
|
|
||||||
hideAction(item) {
|
|
||||||
this.actionShow = false
|
|
||||||
},
|
|
||||||
showAction(item) {
|
|
||||||
if (item.is_admin == 2) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.currentUser = item
|
|
||||||
this.actionTitle = item.name
|
|
||||||
// 只有管理员以上才会弹窗
|
|
||||||
if (this.isAdmin) {
|
|
||||||
if (this.isOwner) {
|
|
||||||
if (!item.is_admin) {
|
|
||||||
this.actionMap = [{
|
|
||||||
key: 0,
|
|
||||||
name: '移除成员',
|
|
||||||
disabled: false
|
|
||||||
}, {
|
|
||||||
key: 1,
|
|
||||||
name: '设置管理',
|
|
||||||
disabled: false
|
|
||||||
}, {
|
|
||||||
key: 2,
|
|
||||||
name: '转移群主',
|
|
||||||
disabled: false
|
|
||||||
}]
|
|
||||||
} else {
|
|
||||||
this.actionMap = [{
|
|
||||||
key: 0,
|
|
||||||
name: '移除成员',
|
|
||||||
disabled: false
|
|
||||||
}, {
|
|
||||||
key: 4,
|
|
||||||
name: '取消管理',
|
|
||||||
disabled: false
|
|
||||||
}, {
|
|
||||||
key: 2,
|
|
||||||
name: '转移群主',
|
|
||||||
disabled: false
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.actionMap = [{
|
|
||||||
key: 0,
|
|
||||||
name: '移除成员',
|
|
||||||
disabled: false
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
this.actionShow = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleAction(e) {
|
|
||||||
switch (e.key) {
|
|
||||||
case 0:
|
|
||||||
removeGroupUser(this.targetId, this.currentUser.targetId).then(res => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '成员移除成功'
|
|
||||||
})
|
|
||||||
}).catch(err => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: err.message
|
|
||||||
})
|
|
||||||
}).finally(() => {
|
|
||||||
this.initUsers()
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
setGroupAdmin(this.targetId, this.currentUser.targetId).then(res => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '设置管理成功'
|
|
||||||
})
|
|
||||||
}).catch(err => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: err.message
|
|
||||||
})
|
|
||||||
}).finally(() => {
|
|
||||||
this.initUsers()
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
removeGroupAdmin(this.targetId, this.currentUser.targetId).then(res => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '取消管理员成功'
|
|
||||||
})
|
|
||||||
}).catch(err => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: err.message
|
|
||||||
})
|
|
||||||
}).finally(() => {
|
|
||||||
this.initUsers()
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
uni.showModal({
|
|
||||||
title: '转让群主',
|
|
||||||
content: '这个操作不可逆转,确定要转让群主身份么?',
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
console.log(this.targetId, this.currentUser.targetId);
|
|
||||||
transferGroupOwner(this.targetId, this.currentUser.targetId).then(
|
|
||||||
res => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '群主转让成功'
|
|
||||||
})
|
|
||||||
}).catch(err => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: err.message
|
|
||||||
})
|
|
||||||
}).finally(() => {
|
|
||||||
this.initUsers()
|
|
||||||
this.initGroupInfo()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
inviteUser() {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/group/invite?targetId=' + this.targetId
|
|
||||||
})
|
|
||||||
},
|
|
||||||
loadMore() {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/group/users?targetId=' + this.targetId
|
|
||||||
})
|
|
||||||
},
|
|
||||||
toUser(item) {
|
|
||||||
if (item.targetId == this.$store.getters.sender.userId) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/friends/mine?targetId=' + item.targetId
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/friends/info?targetId=' + item.targetId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.users {
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
display: flex;
|
|
||||||
padding: 20rpx 0;
|
|
||||||
|
|
||||||
.user {
|
|
||||||
width: 126rpx;
|
|
||||||
margin-left: 20rpx;
|
|
||||||
margin-bottom: 20rpx;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
background-color: $window-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
border-radius: 0 8rpx 0 0;
|
|
||||||
position: relative;
|
|
||||||
width: 84rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.admin {
|
|
||||||
position: absolute;
|
|
||||||
background-color: $main-color;
|
|
||||||
transform: rotate(45deg);
|
|
||||||
color: #ffffff;
|
|
||||||
font-size: 16rpx;
|
|
||||||
width: 100rpx;
|
|
||||||
padding-top: 30rpx;
|
|
||||||
text-align: center;
|
|
||||||
right: -45rpx;
|
|
||||||
top: -20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.owner {
|
|
||||||
position: absolute;
|
|
||||||
background-color: $text-price;
|
|
||||||
transform: rotate(45deg);
|
|
||||||
color: #ffffff;
|
|
||||||
font-size: 16rpx;
|
|
||||||
width: 100rpx;
|
|
||||||
padding-top: 30rpx;
|
|
||||||
text-align: center;
|
|
||||||
right: -45rpx;
|
|
||||||
top: -20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
color: 20rpx;
|
|
||||||
width: 126rpx;
|
|
||||||
padding-top: 6rpx;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 22rpx !important;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
word-break: break-word;
|
|
||||||
color: $text-gray-m !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.loadmore {
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: $text-gray-m !important;
|
|
||||||
text-align: center;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.uni-icons {
|
|
||||||
color: $text-gray-m !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="emoji--lay" v-show="show">
|
|
||||||
<scroll-view class="scroll" :scroll-y="true">
|
|
||||||
<view class="emoji-flex">
|
|
||||||
<view class="item" v-for="(item, index) in emojiArr" :key="index" @click="$emit('onEmoji', item)">{{item.emoji}}</view>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
<view class="tool">
|
|
||||||
<!-- <view class="item" @click="$emit('delete')">删除</view> -->
|
|
||||||
<view class="item sent" @click="$emit('sent')">发送</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import emoji from '@/static/im/emoji'
|
|
||||||
export default{
|
|
||||||
props:{
|
|
||||||
show: {
|
|
||||||
type: Boolean,
|
|
||||||
default: () => {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data(){
|
|
||||||
return {
|
|
||||||
emojiArr: emoji
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.emoji--lay{
|
|
||||||
height: 600rpx;
|
|
||||||
position: relative;
|
|
||||||
.scroll{
|
|
||||||
height: 600rpx;
|
|
||||||
.emoji-flex{
|
|
||||||
padding: 15rpx 15rpx 120rpx;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
.item{
|
|
||||||
margin: 10rpx 15rpx;
|
|
||||||
font-size: 52rpx;
|
|
||||||
width: calc(12.5% - 30rpx);
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tool{
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
background-image: linear-gradient(to top, #FFF, rgba(255, 255, 255, .0));
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
padding: 20rpx 30rpx 30rpx;
|
|
||||||
.item{
|
|
||||||
line-height: 70rpx;
|
|
||||||
border-radius: 35rpx;
|
|
||||||
width: 140rpx;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 28rpx;
|
|
||||||
margin-left: 20rpx;
|
|
||||||
background: white;
|
|
||||||
border: solid 1rpx #f5f5f5;
|
|
||||||
box-sizing: border-box;
|
|
||||||
&.sent{
|
|
||||||
border-color: #34CE98;
|
|
||||||
background: #34CE98;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,163 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="sent--popups u-border-top" v-if="show">
|
|
||||||
<view class="item" @click="onPopupsItem('picture')">
|
|
||||||
<image class="icon" src="@/static/icon/popups-icon-00.png" mode="widthFix"></image>
|
|
||||||
<text class="text">相册</text>
|
|
||||||
</view>
|
|
||||||
<view class="item" @click="onPopupsItem('camera')">
|
|
||||||
<image class="icon" src="@/static/icon/popups-icon-01.png" mode="widthFix"></image>
|
|
||||||
<text class="text">拍摄</text>
|
|
||||||
</view>
|
|
||||||
<view class="item" @click="onPopupsItem('video')" v-if="conversationType == 1">
|
|
||||||
<image class="icon" src="@/static/icon/popups-icon-02.png" mode="widthFix"></image>
|
|
||||||
<text class="text">视频通话</text>
|
|
||||||
</view>
|
|
||||||
<view class="item" @click="onPopupsItem('location')">
|
|
||||||
<image class="icon" src="@/static/icon/popups-icon-03.png" mode="widthFix"></image>
|
|
||||||
<text class="text">位置</text>
|
|
||||||
</view>
|
|
||||||
<view class="item" @click="onPopupsItem('redpacket')">
|
|
||||||
<image class="icon" src="@/static/icon/popups-icon-04.png" mode="widthFix"></image>
|
|
||||||
<text class="text">红包</text>
|
|
||||||
</view>
|
|
||||||
<view class="item" @click="onPopupsItem('file')">
|
|
||||||
<image class="icon" src="@/static/icon/popups-icon-05.png" mode="widthFix"></image>
|
|
||||||
<text class="text">文件</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<u-action-sheet :actions="callActions" cancelText="取消" @close="callShow = false" @select="singleCall"
|
|
||||||
:show="callShow">
|
|
||||||
</u-action-sheet>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import im from '@/utils/im/index.js'
|
|
||||||
import imBase from '../../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase
|
|
||||||
],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
callActions: [{
|
|
||||||
type: 0,
|
|
||||||
name: '语音通话'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 1,
|
|
||||||
name: '视频通话'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
callShow: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
show: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
conversationType: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
targetId: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
singleCall(e) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/private/call?targetId=' + this.targetId + '&mediaType=' + e.type +
|
|
||||||
'&isCall=true'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onPopupsItem(type) {
|
|
||||||
switch (type) {
|
|
||||||
case 'picture':
|
|
||||||
uni.chooseImage({
|
|
||||||
count: 9,
|
|
||||||
sourceType: ['album'],
|
|
||||||
success: res => {
|
|
||||||
im.sentImage(this.conversationType, this.targetId, res.tempFilePaths[0],
|
|
||||||
this.sender, (res) => {
|
|
||||||
this.success()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
case 'camera':
|
|
||||||
uni.chooseImage({
|
|
||||||
sourceType: ['camera'],
|
|
||||||
success: res => {
|
|
||||||
im.sentImage(this.conversationType, this.targetId, res.tempFilePaths[0],
|
|
||||||
this.sender, (res) => {
|
|
||||||
this.success()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
case 'video':
|
|
||||||
this.callShow = true
|
|
||||||
break;
|
|
||||||
case 'location':
|
|
||||||
uni.chooseLocation({
|
|
||||||
success: (c) => {
|
|
||||||
console.log(c);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
case 'redpacket':
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '功能正在开发中'
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
case 'file':
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '功能正在开发中'
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 处理返回
|
|
||||||
success() {
|
|
||||||
this.$emit('success')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.sent--popups {
|
|
||||||
background: white;
|
|
||||||
padding: 30rpx 15rpx;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
flex-direction: row;
|
|
||||||
|
|
||||||
.item {
|
|
||||||
width: 150rpx;
|
|
||||||
margin: 15rpx;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: #555;
|
|
||||||
padding-top: 15rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
width: 110rpx;
|
|
||||||
height: 110rpx;
|
|
||||||
margin: 0 20rpx;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
background: #F3F6FB;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="sent--text">
|
|
||||||
<input
|
|
||||||
class="input"
|
|
||||||
type="text"
|
|
||||||
:auto-blur="true"
|
|
||||||
:focus="focusState"
|
|
||||||
v-model="inputTxt"
|
|
||||||
confirm-type="send"
|
|
||||||
cursor-spacing="10"
|
|
||||||
@focus="focus"
|
|
||||||
@blur="blur"
|
|
||||||
@confirm="sent"
|
|
||||||
/>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import im from '@/utils/im/index.js'
|
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import imBase from '../../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase
|
|
||||||
],
|
|
||||||
props: {
|
|
||||||
conversationType: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
targetId: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
disabled() {
|
|
||||||
return this.inputTxt.length === 0
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
RongIMLib.getTextMessageDraft(this.conversationType, this.targetId, ({
|
|
||||||
draft
|
|
||||||
}) => {
|
|
||||||
draft ? this.inputTxt = draft : ''
|
|
||||||
})
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
// 保存草稿
|
|
||||||
RongIMLib.saveTextMessageDraft(this.conversationType, this.targetId, this.inputTxt)
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
focusState: false,
|
|
||||||
inputTxt: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created(){
|
|
||||||
uni.$on('emojiValue', res => {
|
|
||||||
this.inputTxt = res.value
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
sent() {
|
|
||||||
if (!this.disabled) {
|
|
||||||
im.sentText(this.conversationType, this.targetId, this.inputTxt, this.sender, () => {
|
|
||||||
RongIMLib.clearTextMessageDraft(this.conversationType, this.targetId)
|
|
||||||
this.$emit('success')
|
|
||||||
this.inputTxt = ''
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
focus() {
|
|
||||||
this.$emit('focus')
|
|
||||||
},
|
|
||||||
blur(e) {
|
|
||||||
uni.hideKeyboard()
|
|
||||||
this.$emit('blur', e.detail)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
destroyed() {
|
|
||||||
uni.$off('emojiValue')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.sent--text {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
.input {
|
|
||||||
background: #F3F6FB;
|
|
||||||
height: 70rpx;
|
|
||||||
width: 400rpx;
|
|
||||||
border-radius: 10rpx;
|
|
||||||
margin-right: 15rpx;
|
|
||||||
padding: 0 20rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,301 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="send--voice">
|
|
||||||
<view class="voice" hover-class="chat-hover" @touchstart="startRecord" @touchend="stopRecord" @touchmove="touchmove">
|
|
||||||
<text class="button">按住 说话</text>
|
|
||||||
</view>
|
|
||||||
<!-- 录音层 -->
|
|
||||||
<view class="lay" v-if="showRecordTip">
|
|
||||||
<view class="lay-header">
|
|
||||||
<view class="modal">
|
|
||||||
<image class="icon" src="@/static/icon/record-icon.png" mode="widthFix"></image>
|
|
||||||
<text class="text">录音中 {{recordTime}} s</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="lay-toast">上滑取消</view>
|
|
||||||
<view class="lay-footer">
|
|
||||||
<image class="lay-footer-icon videoFlicker" src="@/static/icon/audio_green.png" mode="widthFix"></image>
|
|
||||||
<view class="lay-footer-text">松开发送</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import im from '@/utils/im/index.js'
|
|
||||||
import permision from '@/utils/permission.js'
|
|
||||||
import imBase from '../../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase
|
|
||||||
],
|
|
||||||
props: {
|
|
||||||
conversationType: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
targetId: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
showRecordTip: false,
|
|
||||||
recordTime: 60,
|
|
||||||
interval: 0,
|
|
||||||
maxRecordTime: 60,
|
|
||||||
recorderManager: null,
|
|
||||||
mp3AudioSrc: null,
|
|
||||||
isMoveCancel: false,
|
|
||||||
isBetaPlay: false, // 暂时无用
|
|
||||||
startOffsetTop: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
sender() {
|
|
||||||
return this.$store.getters.sender
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.recorderManager = uni.getRecorderManager()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 检查安卓录制权限
|
|
||||||
async getAndroidPermission() {
|
|
||||||
return await permision.requestAndroidPermission('android.permission.RECORD_AUDIO')
|
|
||||||
},
|
|
||||||
// 录制语音消息
|
|
||||||
startRecord(e) {
|
|
||||||
this.getAndroidPermission().then(code => {
|
|
||||||
switch (code) {
|
|
||||||
case 1:
|
|
||||||
this.startOffsetTop = e.target.offsetTop
|
|
||||||
this.showRecordTip = true
|
|
||||||
this.recorderManager.start()
|
|
||||||
this.interval = setInterval(() => {
|
|
||||||
this.recordTime -= 1
|
|
||||||
if (this.recordTime === 0) {
|
|
||||||
this.stopRecord()
|
|
||||||
}
|
|
||||||
}, 1000)
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
uni.showToast({
|
|
||||||
title: '暂无麦克风权限,请前往应用设置开启麦克风',
|
|
||||||
icon: 'none'
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
case -1:
|
|
||||||
uni.showToast({
|
|
||||||
title: '应用权限错误',
|
|
||||||
icon: 'none'
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 结束录音
|
|
||||||
stopRecord(e) {
|
|
||||||
if (!this.showRecordTip) return
|
|
||||||
// 延迟500毫秒结束录音
|
|
||||||
setTimeout(()=> {
|
|
||||||
this.recorderManager.stop()
|
|
||||||
clearInterval(this.interval)
|
|
||||||
// 监听录音结束
|
|
||||||
this.recorderManager.onStop(res => {
|
|
||||||
if(this.isMoveCancel) {
|
|
||||||
this.isMoveCancel = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if((this.maxRecordTime - this.recordTime) <= 0){
|
|
||||||
uni.showToast({
|
|
||||||
title: '说话时间太短',
|
|
||||||
icon : 'none',
|
|
||||||
})
|
|
||||||
this.showRecordTip = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.mp3AudioSrc = res.tempFilePath
|
|
||||||
this.showRecordTip = false
|
|
||||||
this.senVoice()
|
|
||||||
})
|
|
||||||
},500)
|
|
||||||
},
|
|
||||||
// 发送语音消息
|
|
||||||
senVoice(){
|
|
||||||
if(this.mp3AudioSrc === null) {
|
|
||||||
uni.showToast({
|
|
||||||
title: '发送失败, 暂无音频信息',
|
|
||||||
icon : 'none'
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
im.sentVoice(this.conversationType, this.targetId, this.mp3AudioSrc, (this.maxRecordTime -
|
|
||||||
this.recordTime), this.sender, () => {
|
|
||||||
this.recordTime = this.maxRecordTime
|
|
||||||
this.mp3AudioSrc = null
|
|
||||||
setTimeout(() => {
|
|
||||||
this.$emit('success')
|
|
||||||
this.toastAudiMp3()
|
|
||||||
}, 500)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 移动按钮
|
|
||||||
touchmove(e){
|
|
||||||
if(this.startOffsetTop - e.changedTouches[0].pageY > 100){
|
|
||||||
if(this.showRecordTip){
|
|
||||||
this.isMoveCancel = true
|
|
||||||
this.showRecordTip = false
|
|
||||||
this.recorderManager.stop()
|
|
||||||
clearInterval(this.interval)
|
|
||||||
this.recordTime = this.maxRecordTime
|
|
||||||
this.mp3AudioSrc = null
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 试听语音
|
|
||||||
startPlay() {
|
|
||||||
let betaAudio = uni.createInnerAudioContext()
|
|
||||||
betaAudio.src = this.mp3AudioSrc;
|
|
||||||
// 在播放中
|
|
||||||
if(this.isBetaPlay){
|
|
||||||
betaAudio.stop()
|
|
||||||
betaAudio.onStop(() => {
|
|
||||||
this.isBetaPlay = false;
|
|
||||||
betaAudio.destroy()
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 监听音频播放中
|
|
||||||
betaAudio.play()
|
|
||||||
betaAudio.onPlay(() => {
|
|
||||||
this.isBetaPlay = true;
|
|
||||||
})
|
|
||||||
// 监听音频结束
|
|
||||||
betaAudio.onEnded(() => {
|
|
||||||
this.isBetaPlay = false;
|
|
||||||
betaAudio.destroy()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 播放提示音乐
|
|
||||||
toastAudiMp3(){
|
|
||||||
let toastAudio = uni.createInnerAudioContext()
|
|
||||||
toastAudio.src = require('@/static/im/toast/sentVoice.mp3')
|
|
||||||
toastAudio.autoplay = true
|
|
||||||
toastAudio.volume = .1
|
|
||||||
toastAudio.onEnded(() => {
|
|
||||||
toastAudio.destroy()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
@keyframes playFlicker {
|
|
||||||
0% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
opacity: .5;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoFlicker {
|
|
||||||
animation: playFlicker 1s infinite;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.send--voice {
|
|
||||||
.voice {
|
|
||||||
display: flex;
|
|
||||||
background: $window-color;
|
|
||||||
height: 70rpx;
|
|
||||||
line-height: 70rpx;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 400rpx;
|
|
||||||
border-radius: 10rpx;
|
|
||||||
margin-right: 15rpx;
|
|
||||||
padding: 0 20rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
.button {
|
|
||||||
font-size: 30rpx;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.lay{
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
z-index: 9;
|
|
||||||
background: rgba($color: #000000, $alpha: .5);
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
box-sizing: border-box;
|
|
||||||
.lay-header{
|
|
||||||
height: calc(100vh - 140px);
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
.modal {
|
|
||||||
display: flex;
|
|
||||||
background: rgba(0, 0, 0, .6);
|
|
||||||
position: fixed;
|
|
||||||
height: 200rpx;
|
|
||||||
width: 300rpx;
|
|
||||||
border-radius: 10rpx;
|
|
||||||
z-index: 99;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
.icon {
|
|
||||||
width: 88rpx;
|
|
||||||
height: 88rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #FFFFFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.lay-toast{
|
|
||||||
text-align: center;
|
|
||||||
color: rgba($color: #fff, $alpha: .8);
|
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
.lay-footer{
|
|
||||||
background-color: white;
|
|
||||||
height: 100px;
|
|
||||||
border-radius: 50% 50% 0 0;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
text-align: center;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
.lay-footer-icon{
|
|
||||||
width: 58rpx;
|
|
||||||
height: 58rpx;
|
|
||||||
}
|
|
||||||
.lay-footer-text{
|
|
||||||
line-height: 40rpx;
|
|
||||||
color: gray;
|
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="messageBar">
|
|
||||||
<!-- footer -->
|
|
||||||
<view class="footer">
|
|
||||||
<view class="msg-type" @click="changeMessageType">
|
|
||||||
<image class="icon" src="@/static/icon/key-icon.png" v-if="chatType === 0" mode="widthFix" />
|
|
||||||
<image class="icon" src="@/static/icon/msg-icon.png" v-if="chatType === 1" mode="widthFix" />
|
|
||||||
</view>
|
|
||||||
<sent-voice v-if="chatType === 0" :conversationType="conversationType" :targetId="targetId" @success="onSuccess" />
|
|
||||||
<sent-text ref="textView" v-if="chatType === 1" :conversationType="conversationType" :targetId="targetId" @success="onSuccess" @blur="onBlur" />
|
|
||||||
<view class="msg-type msg-popups" @click="onShowEmoji">
|
|
||||||
<image class="icon" src="@/static/icon/emoji-icon.png" />
|
|
||||||
<!-- 考虑唤起键盘,暂时保留v-show -->
|
|
||||||
<!-- <image v-show="!showEmoji" class="icon" src="@/static/icon/emoji-icon.png" /> -->
|
|
||||||
<!-- <image v-show="showEmoji" class="icon" src="@/static/icon/key-icon.png" /> -->
|
|
||||||
</view>
|
|
||||||
<view class="msg-type msg-popups" @click="() => {showPopups = !showPopups, showEmoji = false}"> <image class="icon" src="@/static/icon/popups-icon.png" /> </view>
|
|
||||||
</view>
|
|
||||||
<!-- 弹出层 -->
|
|
||||||
<sent-popups :show="showPopups" :conversationType="conversationType" :targetId="targetId" @success="() => {showPopups = false, onSuccess()}" />
|
|
||||||
<!-- 表情包 -->
|
|
||||||
<sent-emoji :show="showEmoji" @onEmoji="onEmoji" @delete="onDelete" @sent="onSent"></sent-emoji>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import sentText from './sent/sentText'
|
|
||||||
import sentVoice from './sent/sentVoice'
|
|
||||||
import sentPopups from './sent/sentPopups'
|
|
||||||
import sentEmoji from './sent/sentEmoji'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
conversationType: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
targetId: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
sentText,
|
|
||||||
sentVoice,
|
|
||||||
sentPopups,
|
|
||||||
sentEmoji
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
chatType : 1, // 0 语音,1 文本
|
|
||||||
showPopups : false,
|
|
||||||
showEmoji : false,
|
|
||||||
chatText : {
|
|
||||||
value : "",
|
|
||||||
cursor : 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 切换聊天类型,语音/文本
|
|
||||||
changeMessageType() {
|
|
||||||
this.chatType = this.chatType === 1 ? 0 : 1
|
|
||||||
if(this.showEmoji) this.showEmoji = false
|
|
||||||
if(this.showPopups) this.showPopups = false
|
|
||||||
},
|
|
||||||
onSuccess() {
|
|
||||||
this.$emit('onSuccess')
|
|
||||||
},
|
|
||||||
// 处理弹出层
|
|
||||||
onHidePopus(){
|
|
||||||
if(this.showPopups){
|
|
||||||
this.showPopups = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 输入表情
|
|
||||||
onEmoji(e){
|
|
||||||
let atMsg = this.chatText
|
|
||||||
let newMsg = () => {
|
|
||||||
return atMsg.value.slice(0, atMsg.cursor) + e.emoji + atMsg.value.slice(atMsg.cursor)
|
|
||||||
}
|
|
||||||
atMsg.value = newMsg()
|
|
||||||
atMsg.cursor += 2
|
|
||||||
// 全局通讯
|
|
||||||
uni.$emit('emojiValue', atMsg)
|
|
||||||
},
|
|
||||||
// 删除表情
|
|
||||||
onDelete(){
|
|
||||||
console.log('删除')
|
|
||||||
},
|
|
||||||
// 发送消息
|
|
||||||
onSent(){
|
|
||||||
this.$refs.textView.sent()
|
|
||||||
this.chatText = {
|
|
||||||
value : "",
|
|
||||||
cursor : 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 获取输入框文字最新状态
|
|
||||||
onBlur(e){
|
|
||||||
this.chatText = e
|
|
||||||
},
|
|
||||||
// 显示emoji表情
|
|
||||||
onShowEmoji(){
|
|
||||||
this.showEmoji = !this.showEmoji
|
|
||||||
this.chatType = 1
|
|
||||||
if(this.showPopups) this.showPopups = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.messageBar{
|
|
||||||
border-radius: ($radius*2) ($radius*2) 0 0;
|
|
||||||
background: white;
|
|
||||||
.footer {
|
|
||||||
padding: 20rpx 30rpx;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
flex-direction: row;
|
|
||||||
.msg-type {
|
|
||||||
width: 70rpx;
|
|
||||||
height: 70rpx;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
margin: 5rpx;
|
|
||||||
width: 60rpx;
|
|
||||||
height: 60rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view v-if="!isRemote">
|
|
||||||
<view class="state" v-if="isGroup">
|
|
||||||
<!-- 已发送 -->
|
|
||||||
<uni-icons class="sent" type="checkmarkempty" size="28rpx" :color="message.sentStatus >= 30 ? '#34CE98' : '#999999'" />
|
|
||||||
<text class="readers">{{ readers }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="state" v-else>
|
|
||||||
<uni-icons class="sent" type="checkmarkempty" size="28rpx" :color="message.sentStatus >= 30 ? '#34CE98' : '#999999'" />
|
|
||||||
<uni-icons class="receive" type="checkmarkempty" size="28rpx" :color="message.sentStatus >= 50 ? '#34CE98' : '#999999'" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import utils from '@/utils/index.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'showText',
|
|
||||||
props: {
|
|
||||||
message: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isGroup: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
isRemote: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
iconSize() {
|
|
||||||
return utils.rpx2px(28)
|
|
||||||
},
|
|
||||||
readers() {
|
|
||||||
if (this.message.extra) {
|
|
||||||
return JSON.parse(this.message.extra).readers || 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.state {
|
|
||||||
padding: 10rpx;
|
|
||||||
border-radius: 30rpx;
|
|
||||||
background-color: #ddd;
|
|
||||||
display: flex;
|
|
||||||
margin-right: 10rpx;
|
|
||||||
|
|
||||||
.sent {
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.receive {
|
|
||||||
z-index: 1;
|
|
||||||
margin-left: -20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.readers {
|
|
||||||
font-size: 20rpx;
|
|
||||||
margin-left: -6rpx;
|
|
||||||
color: $text-gray-m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
<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" v-if="msg.mediaType == 1" />
|
|
||||||
<uni-icons type="phone" size="40rpx" v-else />
|
|
||||||
{{ 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
|
|
||||||
],
|
|
||||||
name: 'showText',
|
|
||||||
props: {
|
|
||||||
message: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isGroup: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
msg() {
|
|
||||||
return JSON.parse(this.message.content.message)
|
|
||||||
},
|
|
||||||
label() {
|
|
||||||
return this.msg.connected ? '通话时长:' + duration : '未接通'
|
|
||||||
},
|
|
||||||
isRemote() {
|
|
||||||
return this.message.messageDirection == 2
|
|
||||||
},
|
|
||||||
duration() {
|
|
||||||
if (this.message.duration > 3600) {
|
|
||||||
return moment.utc(this.message.duration * 1000).format('HH:mm:ss')
|
|
||||||
} else {
|
|
||||||
return moment.utc(this.message.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>
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="msg--image">
|
|
||||||
<message-state :message="message" :isGroup="isGroup" :isRemote="isRemote" />
|
|
||||||
|
|
||||||
<view class="">
|
|
||||||
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
|
|
||||||
<view class="image" :class="isRemote ? 'left': 'right'">
|
|
||||||
<image class="img" :src="content.thumbnail" @click="previewImage" mode="widthFix"></image>
|
|
||||||
</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: {
|
|
||||||
showImage(path) {
|
|
||||||
uni.previewImage({
|
|
||||||
urls: [
|
|
||||||
path
|
|
||||||
]
|
|
||||||
})
|
|
||||||
},
|
|
||||||
previewImage() {
|
|
||||||
if (this.content.local && this.content.local.indexOf('///data/user/') < 0) {
|
|
||||||
this.showImage(this.content.local)
|
|
||||||
} else {
|
|
||||||
this.showImage(this.content.remote)
|
|
||||||
RongIMLib.downloadMediaMessage(this.message.messageId, {
|
|
||||||
success: (path) => {
|
|
||||||
this.content.local = path
|
|
||||||
},
|
|
||||||
error: (errorCode, messageId) => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: errorCode
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.msg--image {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: $text-gray-m;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image {
|
|
||||||
.img {
|
|
||||||
width: 180rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.left {
|
|
||||||
.img {
|
|
||||||
border-radius: 0 10rpx 10rpx 10rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.right {
|
|
||||||
.img {
|
|
||||||
border-radius: 10rpx 0 10rpx 10rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="msg--text">
|
|
||||||
<message-state :message="message" :isGroup="isGroup" :isRemote="isRemote" />
|
|
||||||
|
|
||||||
<view class="">
|
|
||||||
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
|
|
||||||
<view :class="['text', isRemote ? 'left': 'right']">{{ content }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import messageState from './messageState'
|
|
||||||
import imBase from '../../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'showText',
|
|
||||||
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.content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.msg--text {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: $text-gray-m;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
box-sizing: border-box;
|
|
||||||
max-width: 502rpx;
|
|
||||||
padding: 20rpx 24rpx;
|
|
||||||
line-height: 46rpx;
|
|
||||||
font-size: 32rpx;
|
|
||||||
color: $text-color;
|
|
||||||
word-break: break-all;
|
|
||||||
|
|
||||||
&.left {
|
|
||||||
border-radius: 0 20rpx 20rpx 20rpx;
|
|
||||||
background: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.right {
|
|
||||||
border-radius: 20rpx 0 20rpx 20rpx;
|
|
||||||
background: $main-color;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,247 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="msg--voice">
|
|
||||||
<message-state :message="message" :isGroup="isGroup" :isRemote="isRemote" />
|
|
||||||
|
|
||||||
<view class="">
|
|
||||||
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
|
|
||||||
<view class="msg-voice">
|
|
||||||
<view :class="['voice', isRemote ? 'left': 'right', {'onPlay': onPlay}]" :style="{width: width + 'rpx'}"
|
|
||||||
@click="startPlay">
|
|
||||||
<image v-if="isRemote" class="icon"
|
|
||||||
:class="{ 'videoFlicker' : onPlay && msgId == message.messageId }"
|
|
||||||
src="@/static/icon/audio_green.png" mode="widthFix"></image>
|
|
||||||
<image v-else class="icon" :class="{ 'videoFlicker' : onPlay && msgId == message.messageId }"
|
|
||||||
src="@/static/icon/audio_white.png" mode="widthFix"></image>
|
|
||||||
<text class="duration">{{ duration }}"</text>
|
|
||||||
</view>
|
|
||||||
<u-badge isDot :show="message.content.local =='' && isRemote" />
|
|
||||||
</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
|
|
||||||
],
|
|
||||||
props: {
|
|
||||||
message: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isGroup: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
messageState
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
onPlay: false,
|
|
||||||
innerAC: null,
|
|
||||||
msgId: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
duration() {
|
|
||||||
return this.message.content.duration
|
|
||||||
},
|
|
||||||
isRemote() {
|
|
||||||
return this.message.messageDirection == 2
|
|
||||||
},
|
|
||||||
width() {
|
|
||||||
if (this.duration > 3) {
|
|
||||||
return (this.duration * 5) + 150
|
|
||||||
} else {
|
|
||||||
return 120
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
// 这样能临时解决,但是会一直监听
|
|
||||||
uni.$on('onVoiceMessagePlay', (messageId) => {
|
|
||||||
if (this.message.messageId != messageId) {
|
|
||||||
this.stopPlay()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 播放语音消息
|
|
||||||
startPlay() {
|
|
||||||
// 如果是正在播放的,停止当前播放
|
|
||||||
if (this.onPlay) {
|
|
||||||
this.stopPlay()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.onPlay = true
|
|
||||||
// 如果下载到了本地,那么直接播放,否则调用下载语音消息接口,下载后再播放
|
|
||||||
if (this.message.content.local && this.message.content.local.indexOf('///data/user/') < 0) {
|
|
||||||
this.playVoice(this.message.content.local)
|
|
||||||
} else {
|
|
||||||
RongIMLib.downloadMediaMessage(this.message.messageId, {
|
|
||||||
success: (path) => {
|
|
||||||
this.message.content.local = path
|
|
||||||
this.playVoice(path)
|
|
||||||
},
|
|
||||||
progress: (progress, messageId) => {},
|
|
||||||
cancel: (messageId) => {},
|
|
||||||
error: (errorCode, messageId) => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '语音播放失败'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
playVoice(path) {
|
|
||||||
console.log('准备播放', this.message.content);
|
|
||||||
this.innerAC = uni.createInnerAudioContext()
|
|
||||||
this.innerAC.src = path
|
|
||||||
this.innerAC.autoplay = false
|
|
||||||
this.msgId = this.message.messageId
|
|
||||||
this.innerAC.onCanplay(res => {
|
|
||||||
console.log('onCanplay')
|
|
||||||
this.innerAC.play()
|
|
||||||
})
|
|
||||||
this.innerAC.onPlay(res => {
|
|
||||||
console.log('onPlay')
|
|
||||||
uni.$emit('onVoiceMessagePlay', this.message.messageId)
|
|
||||||
})
|
|
||||||
this.innerAC.onEnded(res => {
|
|
||||||
this.innerAC.stop()
|
|
||||||
})
|
|
||||||
this.innerAC.onStop(() => {
|
|
||||||
this.onPlay = false
|
|
||||||
this.innerAC.destroy()
|
|
||||||
this.innerAC = null
|
|
||||||
this.msgId = null
|
|
||||||
uni.$emit('onVoiceMessageStop', this.message.messageId)
|
|
||||||
})
|
|
||||||
this.innerAC.onError(err => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '语音播放失败'
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
stopPlay() {
|
|
||||||
if (this.innerAC) {
|
|
||||||
this.innerAC.stop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
@keyframes playFlicker {
|
|
||||||
0% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
opacity: .5;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoFlicker {
|
|
||||||
animation: playFlicker 1s infinite;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.msg--voice {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
|
|
||||||
.state {
|
|
||||||
padding: 10rpx;
|
|
||||||
border-radius: 30rpx;
|
|
||||||
width: 40rpx;
|
|
||||||
background-color: #ddd;
|
|
||||||
display: flex;
|
|
||||||
margin-right: 10rpx;
|
|
||||||
|
|
||||||
.sent {
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.receive {
|
|
||||||
z-index: 1;
|
|
||||||
margin-left: -20rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: $text-gray-m;
|
|
||||||
}
|
|
||||||
|
|
||||||
.msg-voice {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.u-badge {
|
|
||||||
margin-left: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.voice {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
height: 84rpx;
|
|
||||||
padding: 0 30rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
width: 38rpx;
|
|
||||||
height: 38rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.left {
|
|
||||||
border-radius: 0 20rpx 20rpx 20rpx;
|
|
||||||
background: white;
|
|
||||||
|
|
||||||
&.onPlay {
|
|
||||||
background-color: #EEEEEE;
|
|
||||||
}
|
|
||||||
|
|
||||||
.duration {
|
|
||||||
color: #333;
|
|
||||||
font-size: 30rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.right {
|
|
||||||
border-radius: 20rpx 0 20rpx 20rpx;
|
|
||||||
background: $main-color;
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
|
|
||||||
&.onPlay {
|
|
||||||
background-color: darken($main-color, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
.duration {
|
|
||||||
color: white;
|
|
||||||
font-size: 30rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="">
|
|
||||||
<view class="notify" v-if="message.objectName === 'RC:GrpNtf'">
|
|
||||||
{{ message.content.message }}
|
|
||||||
<text class="link" @click="toAnnounce(message)" v-if="message.content.operation == 'ANNOUNCEMENT'">点击查看
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
<view class="notify" v-else-if="message.objectName === 'RC:RcNtf'">
|
|
||||||
{{ contact(message.senderUserId).name }} 撤回了一条消息
|
|
||||||
</view>
|
|
||||||
<view v-else :class="['cell-item', message.messageDirection == 1 ? 'right' : 'left']">
|
|
||||||
<u-avatar class="avatar" @click="toUser(message)" :size="avatarSize" shape="square"
|
|
||||||
:src="contact(message.senderUserId).portraitUrl" />
|
|
||||||
<view class="msg" @longpress="messageAction($event, message)">
|
|
||||||
<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-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" />
|
|
||||||
<view v-else class="">
|
|
||||||
[未处理的消息类型 {{ message.objectName }}]
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<!-- <view class="time">{{ item.sentTime|timeCustomCN }}</view> 时间判断,最好是隔一段时间没有消息才展示一个 -->
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
getGroupAnnouncement
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
import * as IMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import showVoice from './show/showVoice'
|
|
||||||
import showImage from './show/showImage'
|
|
||||||
import showText from './show/showText'
|
|
||||||
import showCall from './show/showCall'
|
|
||||||
import utils from '@/utils/index.js'
|
|
||||||
import imBase from '../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase
|
|
||||||
],
|
|
||||||
components: {
|
|
||||||
showCall,
|
|
||||||
showVoice,
|
|
||||||
showImage,
|
|
||||||
showText
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
message: {
|
|
||||||
type: Object,
|
|
||||||
default: function() {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isGroup: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
messageAction(event, message) {
|
|
||||||
this.$emit('messageAction', {
|
|
||||||
event,
|
|
||||||
message
|
|
||||||
})
|
|
||||||
},
|
|
||||||
toUser(item) {
|
|
||||||
if (item.messageDirection == 1) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/friends/mine?targetId=' + item.senderUserId
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/friends/info?targetId=' + item.senderUserId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 跳转群公告
|
|
||||||
toAnnounce(message) {
|
|
||||||
if (message.content.extra) {
|
|
||||||
getGroupAnnouncement(message.targetId, message.content.extra).then(res => {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/group/announceCreate?type=check&targetId=' + message
|
|
||||||
.targetId + '&aId=' + message.content.extra
|
|
||||||
})
|
|
||||||
}).catch(err => {
|
|
||||||
IMLib.deleteMessagesByIds([message.messageId], ({
|
|
||||||
code
|
|
||||||
}) => {
|
|
||||||
if (code === 0) {
|
|
||||||
uni.$emit('remove_message_' + message.targetId, message.messageId)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
uni.showToast({
|
|
||||||
title: '公告不存在或已删除',
|
|
||||||
icon: 'none',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '旧版本,无链接'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.notify {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #666;
|
|
||||||
|
|
||||||
.link {
|
|
||||||
color: $main-color;
|
|
||||||
margin-left: 10rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell-item {
|
|
||||||
display: flex;
|
|
||||||
width: 710rpx;
|
|
||||||
justify-content: flex-start;
|
|
||||||
|
|
||||||
&.left {
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.right {
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
|
|
||||||
.state {
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.msg {
|
|
||||||
margin: 0 20rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,188 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view>
|
|
||||||
<u-index-list :index-list="indexs" inactiveColor="#666" activeColor="#34CE98">
|
|
||||||
<view class="friend-flex" @click="toPending">
|
|
||||||
<u-avatar class="cover" size="40" shape="square" :src="require('@/static/im/im_01.png')" />
|
|
||||||
<u-badge max="99" absolute :offset="[23, 20]" :value="pendingCount" />
|
|
||||||
<view class="info">新的朋友</view>
|
|
||||||
</view>
|
|
||||||
<view class="friend-flex" @click="toGroup">
|
|
||||||
<u-avatar class="cover" size="40" shape="square" :src="require('@/static/im/im_00.png')" />
|
|
||||||
<view class="info">我的群聊</view>
|
|
||||||
</view>
|
|
||||||
<block v-if="friends.length > 0">
|
|
||||||
<u-index-item v-for="(item, fkey) in friends" :key="fkey">
|
|
||||||
<u-index-anchor :text="indexs[fkey]" bgColor="#f9f9f9" height="20" size="12" color="#666"
|
|
||||||
class="anchor" />
|
|
||||||
<view v-for="(friendItem, index) in item" :key="index" class="friend-flex"
|
|
||||||
@click="toFriend(friendItem.targetId)">
|
|
||||||
<u-avatar class="avatar-img" size="40" shape="square"
|
|
||||||
:src="contact(friendItem.targetId).portraitUrl" />
|
|
||||||
<view class="info">
|
|
||||||
<view class="name">{{ contact(friendItem.targetId).name }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</u-index-item>
|
|
||||||
</block>
|
|
||||||
<view class="no-lists" v-else>
|
|
||||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx"
|
|
||||||
:src=" require('@/static/imgs/no-friend.png')" :lazy-load="true" />
|
|
||||||
<span>暂无好友列表~</span>
|
|
||||||
</view>
|
|
||||||
</u-index-list>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
getFriendsLetter
|
|
||||||
} from '@/apis/interfaces/im';
|
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import im from '@/utils/im/index.js'
|
|
||||||
import imBase from '../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase
|
|
||||||
],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
indexs: [],
|
|
||||||
friends: [],
|
|
||||||
pendingCount: 0
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
contact() {
|
|
||||||
return function(targetId) {
|
|
||||||
return this.$store.getters.contactInfo(targetId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad() {
|
|
||||||
uni.$on('onNewContactFriends', this.checkNewFriendPending)
|
|
||||||
},
|
|
||||||
onShow() {
|
|
||||||
this.getFriendList()
|
|
||||||
this.checkNewFriendPending()
|
|
||||||
},
|
|
||||||
onUnload() {
|
|
||||||
uni.$off("onNewContactFriends")
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getFriendList() {
|
|
||||||
getFriendsLetter().then(res => {
|
|
||||||
this.indexs = res.indexList
|
|
||||||
this.friends = res.itemArr
|
|
||||||
})
|
|
||||||
},
|
|
||||||
checkNewFriendPending() {
|
|
||||||
im.getPendingList((pendings) => {
|
|
||||||
this.pendingCount = pendings.length
|
|
||||||
})
|
|
||||||
},
|
|
||||||
toGroup() {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/group/index'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
toFriend(targetId) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/friends/info?targetId=' + targetId
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 新朋友
|
|
||||||
toPending() {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/friends/pending'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onNavigationBarButtonTap(e) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/friends/search'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
// 页面空
|
|
||||||
.pages-null {
|
|
||||||
height: 70vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.anchor {
|
|
||||||
background-color: #f9f9f9 !important;
|
|
||||||
padding: 10rpx 30rpx;
|
|
||||||
border-bottom: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 好友列表
|
|
||||||
.friend-flex {
|
|
||||||
position: relative;
|
|
||||||
padding: 0 $padding 0 $padding;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.avatar-img {
|
|
||||||
box-shadow: 0 0 20rpx rgba($color: $main-color, $alpha: 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.info {
|
|
||||||
flex: 1;
|
|
||||||
margin-left: $padding;
|
|
||||||
border-bottom: solid 1rpx #f9f9f9;
|
|
||||||
height: 120rpx;
|
|
||||||
line-height: 120rpx;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font-size: $title-size;
|
|
||||||
color: #454545 !important;
|
|
||||||
@extend .nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.address {
|
|
||||||
color: $text-gray-m;
|
|
||||||
font-size: $title-size-m - 3;
|
|
||||||
padding-top: 10rpx;
|
|
||||||
word-break: break-word;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
width: 600rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-cell {
|
|
||||||
display: flex;
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px 24rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
color: #323233;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 24px;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-lists {
|
|
||||||
padding-top: $padding * 3;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
color: $text-gray-m;
|
|
||||||
|
|
||||||
span {
|
|
||||||
padding-top: $padding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,389 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="content">
|
|
||||||
<!-- 用户信息 -->
|
|
||||||
<view class="info-flex">
|
|
||||||
<u-avatar :src="userInfo.portraitUrl || require('@/static/user/cover.png')" shape="square"
|
|
||||||
:size="rpx2px(100)" bg-color="#fff"></u-avatar>
|
|
||||||
<view class="info-text">
|
|
||||||
<view class="nickname">{{ contact(targetId).name }} ({{ userInfo.name }})</view>
|
|
||||||
<view class="address" @longpress="copyAddress">地址:{{ userInfo.address }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<!-- 用户资料 -->
|
|
||||||
<view class="info-btns">
|
|
||||||
<view class="item">
|
|
||||||
<label>性别</label>
|
|
||||||
<view class="text" v-if="userInfo.gender === 0">保密</view>
|
|
||||||
<view class="text" v-else-if="userInfo.gender === 1">男</view>
|
|
||||||
<view class="text" v-else>女</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<!-- 如果是好友 -->
|
|
||||||
<block v-if="userInfo.friendship ==='accepted'">
|
|
||||||
<view class="info-btns">
|
|
||||||
<view class="item u-border-bottom" @click="setRemark">
|
|
||||||
<label>设置备注</label>
|
|
||||||
<uni-icons type="right" size="32rpx" />
|
|
||||||
</view>
|
|
||||||
<view class="item u-border-bottom">
|
|
||||||
<label>消息免打扰</label>
|
|
||||||
<u-switch size="22" v-model="status" activeColor="#34CE98" @change="setStatus"></u-switch>
|
|
||||||
</view>
|
|
||||||
<view class="item">
|
|
||||||
<label>聊天置顶</label>
|
|
||||||
<u-switch size="22" v-model="isTop" activeColor="#34CE98" @change="setTop"></u-switch>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="footer">
|
|
||||||
<view class="footer-item" @click="deleteFriend">
|
|
||||||
<view class="icon">
|
|
||||||
<u-icon class="icon-u" name="close-circle-fill" color="#fff" size="30" />
|
|
||||||
</view>
|
|
||||||
<view class="text">删除好友</view>
|
|
||||||
</view>
|
|
||||||
<view class="footer-item" @click="toPrivate">
|
|
||||||
<view class="icon ">
|
|
||||||
<u-icon class="icon-u" name="chat-fill" color="#fff" size="30" />
|
|
||||||
</view>
|
|
||||||
<view class="text">发送消息</view>
|
|
||||||
</view>
|
|
||||||
<view class="footer-item" @click="callShow = true">
|
|
||||||
<view class="icon">
|
|
||||||
<u-icon class="icon-u" name="camera-fill" color="#fff" size="30" />
|
|
||||||
</view>
|
|
||||||
<view class="text">音/视频通话</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
<block v-else>
|
|
||||||
<view class="footer">
|
|
||||||
<view class="footer-item" @click="toBeFriend">
|
|
||||||
<view class="icon">
|
|
||||||
<u-icon class="icon-u" name="plus-people-fill" color="#fff" size="30" />
|
|
||||||
</view>
|
|
||||||
<view class="text">申请好友</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
|
|
||||||
<u-modal negativeTop="300" :show="modalShow" title="修改备注" showCancelButton @cancel="onHideModal"
|
|
||||||
@confirm="onChangeRemark">
|
|
||||||
<view class="slot-content">
|
|
||||||
<u--input placeholder="好友备注" border="surround" focus v-model="contactRemark" maxlength="12" />
|
|
||||||
</view>
|
|
||||||
</u-modal>
|
|
||||||
|
|
||||||
<u-action-sheet :actions="callActions" cancelText="取消" @close="callShow = false" @select="singleCall"
|
|
||||||
:show="callShow">
|
|
||||||
</u-action-sheet>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
getFriendInfo,
|
|
||||||
pedingFriend,
|
|
||||||
deleteFriend
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index'
|
|
||||||
import imBase from '../mixins/imBase.js'
|
|
||||||
|
|
||||||
// friendship: '' 没有好友关系
|
|
||||||
// accepted 好友
|
|
||||||
// pending 申请中
|
|
||||||
// denied 拒绝
|
|
||||||
// blocked 黑名单
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase
|
|
||||||
],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
targetId: '',
|
|
||||||
userInfo: {},
|
|
||||||
status: false, // 0 是免打扰,1是正常通知
|
|
||||||
isTop: false,
|
|
||||||
block: false,
|
|
||||||
conversationType: 1,
|
|
||||||
callActions: [{
|
|
||||||
type: 0,
|
|
||||||
name: '语音通话'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 1,
|
|
||||||
name: '视频通话'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
callShow: false,
|
|
||||||
hasPeding: false,
|
|
||||||
modalShow: false,
|
|
||||||
contactRemark: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad(e) {
|
|
||||||
this.targetId = e.targetId
|
|
||||||
getFriendInfo(e.targetId).then(res => {
|
|
||||||
this.userInfo = res
|
|
||||||
// 获取到用户信息之后,去检查一下要不要更新
|
|
||||||
this.$store.dispatch('updateContact', res)
|
|
||||||
uni.setNavigationBarTitle({
|
|
||||||
title: res.name
|
|
||||||
})
|
|
||||||
})
|
|
||||||
RongIMLib.getConversationNotificationStatus(this.conversationType, this.targetId, ({
|
|
||||||
status
|
|
||||||
}) => {
|
|
||||||
this.status = !Boolean(status)
|
|
||||||
})
|
|
||||||
RongIMLib.getConversation(this.conversationType, this.targetId, ({
|
|
||||||
code,
|
|
||||||
conversation
|
|
||||||
}) => {
|
|
||||||
if (code == 0) {
|
|
||||||
this.isTop = conversation.isTop
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
copyAddress() {
|
|
||||||
uni.setClipboardData({
|
|
||||||
data: this.userInfo.address,
|
|
||||||
success: () => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '复制成功'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
toPrivate() {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/private/chat?targetId=' + this.targetId
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 设置好友备注操作
|
|
||||||
setRemark() {
|
|
||||||
this.modalShow = true
|
|
||||||
this.contactRemark = this.$store.getters.contactInfo(this.targetId).name
|
|
||||||
},
|
|
||||||
onHideModal() {
|
|
||||||
this.modalShow = false
|
|
||||||
},
|
|
||||||
onChangeRemark() {
|
|
||||||
this.$store.dispatch('setContactRemark', {
|
|
||||||
targetId: this.targetId,
|
|
||||||
remark: this.contactRemark
|
|
||||||
})
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '备注设置成功'
|
|
||||||
})
|
|
||||||
this.onHideModal()
|
|
||||||
},
|
|
||||||
setTag() {
|
|
||||||
uni.showToast({
|
|
||||||
title: '开发中',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
deleteFriend() {
|
|
||||||
uni.showModal({
|
|
||||||
title: '删除确认',
|
|
||||||
content: '确认删除后不可恢复',
|
|
||||||
success: e => {
|
|
||||||
if (e.confirm) {
|
|
||||||
deleteFriend(this.targetId).then(res => {
|
|
||||||
uni.$emit('onContactNotification')
|
|
||||||
// 删除聊天记录
|
|
||||||
RongIMLib.deleteMessages(1, this.targetId);
|
|
||||||
RongIMLib.removeConversation(1, this.targetId);
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '好友删除成功',
|
|
||||||
success() {
|
|
||||||
uni.switchTab({
|
|
||||||
url: '/pages/im/index'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
setStatus() {
|
|
||||||
RongIMLib.setConversationNotificationStatus(this.conversationType, this.targetId, this.status,
|
|
||||||
({
|
|
||||||
status
|
|
||||||
}) => {
|
|
||||||
this.status = !Boolean(status)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
setTop() {
|
|
||||||
RongIMLib.setConversationToTop(this.conversationType, this.targetId, this.isTop, (res) => {
|
|
||||||
RongIMLib.getConversation(this.conversationType, this.targetId, ({
|
|
||||||
conversation
|
|
||||||
}) => {
|
|
||||||
this.isTop = conversation.isTop
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 申请好友
|
|
||||||
toBeFriend() {
|
|
||||||
if (this.hasPeding) {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '请不要频繁操作'
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
pedingFriend(this.targetId, '').then(res => {
|
|
||||||
uni.showToast({
|
|
||||||
title: ` 申请成功,等待审核 `,
|
|
||||||
icon: 'none',
|
|
||||||
duration: 3000,
|
|
||||||
mask: true
|
|
||||||
});
|
|
||||||
this.hasPeding = true
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'error',
|
|
||||||
title: err.message,
|
|
||||||
duration: 2000,
|
|
||||||
mask: true
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
singleCall(e) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/private/call?targetId=' + this.targetId + '&mediaType=' + e.type +
|
|
||||||
'&isCall=true'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.content {
|
|
||||||
min-height: 100vh;
|
|
||||||
background: $window-color;
|
|
||||||
padding-top: $padding;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用户信息
|
|
||||||
.info-flex {
|
|
||||||
padding: $padding;
|
|
||||||
margin: 0 $margin;
|
|
||||||
display: flex;
|
|
||||||
background: white;
|
|
||||||
border-radius: $radius;
|
|
||||||
|
|
||||||
.info-text {
|
|
||||||
width: calc(100% - 50px);
|
|
||||||
padding-left: $padding;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.nickname {
|
|
||||||
line-height: 30px;
|
|
||||||
font-size: $title-size + 6;
|
|
||||||
color: #454545;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.address {
|
|
||||||
line-height: 20px;
|
|
||||||
font-size: $title-size-sm;
|
|
||||||
color: $text-gray;
|
|
||||||
text-align: left;
|
|
||||||
@extend .nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// footer
|
|
||||||
.footer {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: $padding*2 $padding;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
|
|
||||||
.footer-item {
|
|
||||||
margin: 0 $margin/2;
|
|
||||||
text-align: center;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
background: $main-color;
|
|
||||||
width: 88rpx;
|
|
||||||
height: 88rpx;
|
|
||||||
// line-height: 88rpx;
|
|
||||||
// display: inline-block;
|
|
||||||
border-radius: 50%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.icon-u {
|
|
||||||
// margin-top: calc((88rpx/2) - 13px);
|
|
||||||
// margin-left: calc((88rpx/2) - 13px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
color: $main-color;
|
|
||||||
font-size: $title-size-m - 2;
|
|
||||||
text-align: center;
|
|
||||||
padding-top: 16rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// btns
|
|
||||||
|
|
||||||
.info-btns {
|
|
||||||
background: white;
|
|
||||||
margin: $margin;
|
|
||||||
border-radius: $radius;
|
|
||||||
|
|
||||||
.u-border-bottom {
|
|
||||||
border-bottom: solid 1rpx #f9f9f9 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item {
|
|
||||||
line-height: 100rpx;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 10rpx $padding;
|
|
||||||
justify-content: space-between;
|
|
||||||
font-size: $title-size-lg;
|
|
||||||
|
|
||||||
label {
|
|
||||||
width: 200rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.uni-icons {
|
|
||||||
color: $text-gray-m !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
width: calc(100% - 200rpx);
|
|
||||||
color: $text-gray-m;
|
|
||||||
text-align: right;
|
|
||||||
@extend .nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="friend-ewm-content">
|
|
||||||
<view class="bg"></view>
|
|
||||||
<!-- 用户信息 -->
|
|
||||||
<view class="info-flex">
|
|
||||||
<view class="info-flex-item">
|
|
||||||
<u-avatar :src="infoObj.portraitUrl" @click='previewImg(infoObj.portraitUrl)' shape="square" size="210rpx" bg-color="#fff" class="avatar" />
|
|
||||||
<view class="nickname">{{infoObj.name}}</view>
|
|
||||||
<view class="address">{{infoObj.address}}</view>
|
|
||||||
<view class="info-code">
|
|
||||||
<uqrcode class="info-code-src" :size="160" :text="qrContent" />
|
|
||||||
<view class="info-code-text">扫描二维码加我ZH大健康好友</view>
|
|
||||||
</view>
|
|
||||||
<u-icon class="download" :name="require('@/static/imgs/copy-333.png')" size="14" :bold="true"
|
|
||||||
@click="copy" :label="'应用下载:'+ downUrl" labelPos="left" labelSize="14" space="6"
|
|
||||||
labelColor="#26a377" />
|
|
||||||
<view class="copy" @click="copy"> 复制地址 </view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
getUserInfo
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
infoObj: {
|
|
||||||
userId: '',
|
|
||||||
username: '',
|
|
||||||
name: '',
|
|
||||||
address: '',
|
|
||||||
portraitUrl: '',
|
|
||||||
gender: 0,
|
|
||||||
hash: ''
|
|
||||||
},
|
|
||||||
downUrl: 'http://www.baidu.com',
|
|
||||||
qrContent: 'ADDFRIEND|'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad(e) {
|
|
||||||
this.qrContent += e.targetId
|
|
||||||
getUserInfo(e.targetId).then(res => {
|
|
||||||
this.infoObj = res
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
previewImg(item){
|
|
||||||
console.log(item)
|
|
||||||
uni.previewImage({
|
|
||||||
urls:[item]
|
|
||||||
})
|
|
||||||
},
|
|
||||||
copy() {
|
|
||||||
uni.setClipboardData({
|
|
||||||
data: this.downUrl,
|
|
||||||
success: function() {
|
|
||||||
uni.showToast({
|
|
||||||
title: ` 下载链接已复制到剪贴板 `,
|
|
||||||
icon: 'none',
|
|
||||||
position:'bottom',
|
|
||||||
mask: true,
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.friend-ewm-content {
|
|
||||||
background: #fff;
|
|
||||||
min-height: 100vh;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.bg {
|
|
||||||
background-color: red;
|
|
||||||
width: 100%;
|
|
||||||
height: 340rpx;
|
|
||||||
background-color: $main-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用户信息
|
|
||||||
.info-flex {
|
|
||||||
padding: $padding 0;
|
|
||||||
// margin: 0 $margin;
|
|
||||||
background: white;
|
|
||||||
border-radius: 50rpx 50rpx 0 0;
|
|
||||||
position: relative;
|
|
||||||
top: -100rpx;
|
|
||||||
|
|
||||||
|
|
||||||
.info-flex-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: relative;
|
|
||||||
top: -160rpx;
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
// padding: 14rpx;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
background-color: #fff;
|
|
||||||
border: solid 14rpx rgba($color: #fff, $alpha:1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.nickname {
|
|
||||||
line-height: 80rpx;
|
|
||||||
font-size: $title-size + 5;
|
|
||||||
color: $text-color;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.address {
|
|
||||||
line-height: 60rpx;
|
|
||||||
font-size: $title-size-m + 2;
|
|
||||||
color: $text-gray;
|
|
||||||
text-align: left;
|
|
||||||
@extend .nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-code {
|
|
||||||
background: white;
|
|
||||||
margin: 0 $margin;
|
|
||||||
border-radius: $radius;
|
|
||||||
padding: $padding * 1.4 $padding $padding;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
&-src {
|
|
||||||
display: inline-block;
|
|
||||||
border-radius: 10rpx;
|
|
||||||
border: solid 20rpx rgba($color: #f9f9f9, $alpha:1);
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 14rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-text {
|
|
||||||
text-align: center;
|
|
||||||
color: $text-gray;
|
|
||||||
font-size: $title-size-m + 1;
|
|
||||||
line-height: 40rpx;
|
|
||||||
padding: 8rpx 0 $padding 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.download {
|
|
||||||
background-color: #f9f9fb;
|
|
||||||
padding: 20rpx 30rpx 10rpx 30rpx;
|
|
||||||
border-radius: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy {
|
|
||||||
font-size: $title-size + 4;
|
|
||||||
color: $main-color;
|
|
||||||
background-color: rgba($color: $main-color, $alpha: .1);
|
|
||||||
padding: 20rpx 100rpx;
|
|
||||||
border-radius: 50rpx;
|
|
||||||
margin-top: 40rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="pending">
|
|
||||||
<u-sticky>
|
|
||||||
<view class="header-search" @click="$Router.push({ name: 'SearchFriend' })">
|
|
||||||
<u-search placeholder="输入手机号码搜索" searchIcon="search" inputAlign="center" bgColor="white"
|
|
||||||
:disabled="true" :show-action="false" />
|
|
||||||
</view>
|
|
||||||
</u-sticky>
|
|
||||||
<block v-if="pendings.length > 0">
|
|
||||||
<view v-for="(item, index) in pendings" :key="index">
|
|
||||||
<apply-cell :message="item.latestMessage" @success="getPendingList" />
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
<view class="no-lists" v-else>
|
|
||||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx"
|
|
||||||
:src="require('@/static/imgs/no-friend.png')" :lazy-load="true" />
|
|
||||||
<span> 暂无好友申请 ~ </span>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import applyCell from '../components/friendApplyCell'
|
|
||||||
import im from '@/utils/im/index.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
applyCell
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
pendings: [],
|
|
||||||
bg: '#fff'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onShow() {
|
|
||||||
this.getPendingList()
|
|
||||||
uni.$on('onNewContactPendings', this.getPendingList)
|
|
||||||
},
|
|
||||||
onUnload() {
|
|
||||||
uni.$off('onNewContactPendings')
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getPendingList() {
|
|
||||||
im.getPendingList((pendings) => {
|
|
||||||
console.log(pendings, 'res......')
|
|
||||||
if (pendings.length > 0) {
|
|
||||||
this.bg = '#f9f9f9'
|
|
||||||
} else {
|
|
||||||
this.bg = '#fff'
|
|
||||||
}
|
|
||||||
this.pendings = pendings
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.header-search {
|
|
||||||
padding: $padding/2 $padding;
|
|
||||||
background: $window-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-lists {
|
|
||||||
padding-top: $padding * 5;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
color: $text-gray-m;
|
|
||||||
|
|
||||||
span {
|
|
||||||
padding-top: $padding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
<!--
|
|
||||||
* @Description:搜索新朋友页面
|
|
||||||
* @Author: Aimee·Zhang
|
|
||||||
* @Date: 2022-01-24 10:49:15
|
|
||||||
* @LastEditors: Aimee·Zhang
|
|
||||||
* @LastEditTime: 2022-01-25 10:18:26
|
|
||||||
-->
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<view class="search">
|
|
||||||
<!-- 搜索 -->
|
|
||||||
<u-sticky>
|
|
||||||
<view class="header-search">
|
|
||||||
<u-search placeholder="输入用户账号、手机号" searchIcon="search" @custom="search" v-model="searchValue"
|
|
||||||
@search="search" bgColor="#F3F6FB" :focus="focused" />
|
|
||||||
</view>
|
|
||||||
</u-sticky>
|
|
||||||
<block v-if="searchResult.length > 0">
|
|
||||||
<applyFriend :lists="searchResult" :isApply="true" @action="action" />
|
|
||||||
</block>
|
|
||||||
<view class="no-lists" v-if="searchResult.length === 0 && searchValue.length > 1">
|
|
||||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx"
|
|
||||||
:src="require('@/static/imgs/no-search.png')" :lazy-load="true" />
|
|
||||||
<span>暂无匹配内容~</span>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
searchFriend,
|
|
||||||
pedingFriend
|
|
||||||
} from '@/apis/interfaces/im.js';
|
|
||||||
import applyFriend from '../components/friendSearchList.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
applyFriend
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
searchResult: [],
|
|
||||||
searchValue: '',
|
|
||||||
focused: true
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
searchValue(value) {
|
|
||||||
console.log(value.length, 'length...')
|
|
||||||
if (value.length > 1) {
|
|
||||||
this.searchResult = []
|
|
||||||
this.search()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if(value.length === 0){
|
|
||||||
this.searchResult = []
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
search() {
|
|
||||||
// friendship: '' 没有好友关系
|
|
||||||
// accepted 好友
|
|
||||||
// pending 申请中
|
|
||||||
// denied 拒绝
|
|
||||||
// blocked 黑名单
|
|
||||||
searchFriend(this.searchValue)
|
|
||||||
.then(res => {
|
|
||||||
this.searchResult = res;
|
|
||||||
console.log(res)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
uni.showToast({
|
|
||||||
title: err.message,
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
action(e) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/friends/info?targetId=' + e.item.targetId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.header-search {
|
|
||||||
padding: $padding/2 $padding;
|
|
||||||
// background: $window-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-lists {
|
|
||||||
padding-top: $padding * 3;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
color: $text-gray-m;
|
|
||||||
|
|
||||||
span {
|
|
||||||
padding-top: $padding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="create">
|
|
||||||
<view class="create-title">公告内容</view>
|
|
||||||
|
|
||||||
<block v-if="type === 'check'">
|
|
||||||
<view class="content"> {{content}} </view>
|
|
||||||
</block>
|
|
||||||
|
|
||||||
<block v-else>
|
|
||||||
<u--textarea v-model="content" count height="240" maxlength="240" placeholder="请输入公告内容" />
|
|
||||||
<u-button type="primary" text="发布" :disabled="disabled" @click="onCreate" color="#34CE98" />
|
|
||||||
</block>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
createGroupAnnouncement,
|
|
||||||
getGroupAnnouncement
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
onGroupDismiss
|
|
||||||
],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
targetId: '',
|
|
||||||
content: '',
|
|
||||||
aId: '',
|
|
||||||
type: '' // cheack ' 查看详情'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad(e) {
|
|
||||||
this.targetId = e.targetId
|
|
||||||
if (e.aId) {
|
|
||||||
this.type = e.type
|
|
||||||
uni.setNavigationBarTitle({
|
|
||||||
title: '群公告'
|
|
||||||
})
|
|
||||||
this.aId = e.aId
|
|
||||||
getGroupAnnouncement(this.targetId, this.aId).then(res => {
|
|
||||||
this.content = res.content
|
|
||||||
}).catch(err => {
|
|
||||||
if (err.status_code == 404) {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
uni.navigateBack()
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
title: err.message,
|
|
||||||
icon: 'none',
|
|
||||||
mask: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
disabled() {
|
|
||||||
return this.content.length == 0 || this.content.length > 200
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onCreate() {
|
|
||||||
createGroupAnnouncement(this.targetId, this.content).then(res => {
|
|
||||||
uni.$emit('groupAnnouncementCreated')
|
|
||||||
uni.showToast({
|
|
||||||
title: '发布成功',
|
|
||||||
success: () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
uni.navigateBack()
|
|
||||||
}, 1000)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}).catch(err => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: err.message
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.create {
|
|
||||||
padding: $padding;
|
|
||||||
|
|
||||||
.create-title {
|
|
||||||
font-size: $title-size + 4;
|
|
||||||
padding: $padding - 10 0 $padding - 10 $padding - 10;
|
|
||||||
color: $text-color;
|
|
||||||
font-weight: 800;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
width: 10rpx;
|
|
||||||
height: 34rpx;
|
|
||||||
background-color: $main-color;
|
|
||||||
left: 0;
|
|
||||||
top: 26rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
color: $text-color;
|
|
||||||
font-size: $title-size;
|
|
||||||
line-height: 1.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.u-button {
|
|
||||||
margin-top: $padding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,224 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="announce" :style="`background-color:${bg};`">
|
|
||||||
<!-- 有列表 -->
|
|
||||||
<u-skeleton rows="2" :loading="loading" avatar :rows="5" v-if="announcements.length>0">
|
|
||||||
<view v-for="(item,index) in announcements" :key="index" class="item"
|
|
||||||
@longpress="actions(item.announcement_id)" @click="tabA(item.announcement_id)">
|
|
||||||
<view class="content-a"><span v-if="item.is_top">置顶</span>{{ item.content }}</view>
|
|
||||||
<view class="user">
|
|
||||||
<u-avatar :src="item.user.portraitUrl" size="40rpx" />
|
|
||||||
<view class="name">{{ item.user.name }}</view>
|
|
||||||
<view class="time">{{ item.created_at }}</view>
|
|
||||||
</view>
|
|
||||||
<!-- <view class="delete" v-if="isAdmin" @click="onDelete(item.announcement_id)">删除</view> -->
|
|
||||||
</view>
|
|
||||||
</u-skeleton>
|
|
||||||
|
|
||||||
<!-- 没有列表 -->
|
|
||||||
<view class="no-lists" v-else>
|
|
||||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx"
|
|
||||||
:src="require('@/static/imgs/no-level-list.png')" :lazy-load="true" />
|
|
||||||
<span>暂无公告内容~</span>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 弹出 -->
|
|
||||||
<u-action-sheet :actions="actionMap" :title="actionTitle" :show="actionShow" cancelText="取消"
|
|
||||||
@close="actionShow = false" @select="handleAction" />
|
|
||||||
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
getGroupInfo,
|
|
||||||
getGroupAnnouncements,
|
|
||||||
deleteGroupAnnouncement,
|
|
||||||
topGroupAnnouncement
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
|
||||||
import imBase from '../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase,
|
|
||||||
onGroupDismiss
|
|
||||||
],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
targetId: '',
|
|
||||||
groupAnnouncementId: '', // 选择公告 id
|
|
||||||
announcements: [], // 公告列表
|
|
||||||
loading: true,
|
|
||||||
isAdmin: false,
|
|
||||||
actionShow: false,
|
|
||||||
actionMap: [{
|
|
||||||
key: 2,
|
|
||||||
name: ' 删除该公告',
|
|
||||||
disabled: false
|
|
||||||
}, {
|
|
||||||
key: 3,
|
|
||||||
name: '置顶该公告',
|
|
||||||
disabled: false
|
|
||||||
}],
|
|
||||||
actionTitle: '请选择操作',
|
|
||||||
bg: '#fff'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad(e) {
|
|
||||||
this.targetId = e.targetId
|
|
||||||
getGroupInfo(this.targetId).then(res => {
|
|
||||||
this.isAdmin = res.group.is_admin
|
|
||||||
})
|
|
||||||
this.initData()
|
|
||||||
uni.$on('groupAnnouncementCreated', this.initData)
|
|
||||||
},
|
|
||||||
onUnload() {
|
|
||||||
uni.$off('groupAnnouncementCreated')
|
|
||||||
},
|
|
||||||
onNavigationBarButtonTap() {
|
|
||||||
if (this.isAdmin) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/group/announceCreate?targetId=' + this.targetId
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '没有权限'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 获取公告信息
|
|
||||||
initData() {
|
|
||||||
getGroupAnnouncements(this.targetId).then(res => {
|
|
||||||
if (res.length > 0) {
|
|
||||||
this.bg = '#f9f9f9'
|
|
||||||
} else {
|
|
||||||
this.bg = '#fff'
|
|
||||||
}
|
|
||||||
this.announcements = res
|
|
||||||
this.loading = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 选择公告 并显示操作弹窗
|
|
||||||
actions(id) {
|
|
||||||
if (this.isAdmin) {
|
|
||||||
this.groupAnnouncementId = id
|
|
||||||
this.actionShow = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 选择了操作出发事件
|
|
||||||
handleAction(e) {
|
|
||||||
console.log(e.key)
|
|
||||||
switch (e.key) {
|
|
||||||
case 2:
|
|
||||||
this.onDelete(this.groupAnnouncementId)
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
this.onTop(this.groupAnnouncementId)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tabA(id) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/group/announceCreate?type=check&targetId=' + this.targetId + '&aId=' + id
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onTop(aId) {
|
|
||||||
topGroupAnnouncement(this.targetId, aId).then(res => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: ' 置顶成功',
|
|
||||||
mask: true
|
|
||||||
})
|
|
||||||
uni.$emit('updateAnnouncement')
|
|
||||||
this.initData()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 删除公告
|
|
||||||
onDelete(aId) {
|
|
||||||
deleteGroupAnnouncement(this.targetId, aId).then(res => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '删除成功',
|
|
||||||
mask: true
|
|
||||||
})
|
|
||||||
uni.$emit('updateAnnouncement')
|
|
||||||
this.initData()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.announce {
|
|
||||||
min-height: 99vh;
|
|
||||||
|
|
||||||
.no-lists {
|
|
||||||
padding-top: $padding * 5;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
color: $text-gray-m;
|
|
||||||
|
|
||||||
span {
|
|
||||||
padding-top: $padding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.item {
|
|
||||||
background-color: #fff;
|
|
||||||
padding: $padding $padding + 10 10rpx $padding + 10;
|
|
||||||
border-bottom: $padding solid #f9f9f9;
|
|
||||||
|
|
||||||
|
|
||||||
.user {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
color: $text-gray-m;
|
|
||||||
padding: 20rpx 10rpx 10rpx 10rpx;
|
|
||||||
border-top: solid 1rpx #F9F9F9;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
padding-left: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
margin-left: 20rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-a {
|
|
||||||
font-size: $title-size;
|
|
||||||
color: $text-color;
|
|
||||||
max-width: 100%;
|
|
||||||
margin-bottom: 10rpx;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-line-clamp: 3;
|
|
||||||
overflow: hidden;
|
|
||||||
line-height: 1.5;
|
|
||||||
|
|
||||||
span {
|
|
||||||
color: #fff;
|
|
||||||
display: inline-block;
|
|
||||||
border-radius: 10rpx;
|
|
||||||
background-color: $main-color;
|
|
||||||
font-size: $title-size-m - 4;
|
|
||||||
padding: 4rpx 10rpx;
|
|
||||||
margin-right: 10rpx;
|
|
||||||
line-height: 1.4;
|
|
||||||
margin-bottom: 10rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="apply" v-if="loaded">
|
|
||||||
<u-avatar :src="group.cover || require('@/static/user/cover.png')" size="128" shape="square" />
|
|
||||||
<view class="name"> {{ group.name }} </view>
|
|
||||||
<u-button class="apply-btn" v-if="group.can_join" @click="modalShow = true" text="申请加群" :disabled="disabled" color="#34CE98" />
|
|
||||||
<view class="" v-else>
|
|
||||||
<view class="" v-if="group.is_full">群已满员</view>
|
|
||||||
<view class="" v-if="group.deny_apply">禁止申请</view>
|
|
||||||
<u-button class="apply-btn2" v-if="group.state === 'accepted'" color="#34CE98" text="进入群聊" @click="toGroupChat" />
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<u-modal negativeTop="300" :show="modalShow" title="申请原因" showCancelButton @cancel="onHideModal" @confirm="onJoinGroup">
|
|
||||||
<view class="slot-content"> <u--input placeholder="申请原因" border="surround" focus v-model="message" /> </view>
|
|
||||||
</u-modal>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
joinGroupPre,
|
|
||||||
joinGroup
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
|
||||||
import imBase from '../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase,
|
|
||||||
onGroupDismiss
|
|
||||||
],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
targetId: '',
|
|
||||||
group: {},
|
|
||||||
modalShow: false,
|
|
||||||
message: '',
|
|
||||||
disabled: false,
|
|
||||||
loaded: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad(e) {
|
|
||||||
this.targetId = e.targetId
|
|
||||||
joinGroupPre(this.targetId).then(res => {
|
|
||||||
console.log(res, 'res.返回群的基本信息')
|
|
||||||
this.group = res
|
|
||||||
this.loaded = true
|
|
||||||
}).catch(err => {
|
|
||||||
uni.showToast({
|
|
||||||
title: err.message,
|
|
||||||
icon: 'none',
|
|
||||||
mask: true,
|
|
||||||
duration: 3000
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
toGroupChat() {
|
|
||||||
uni.redirectTo({
|
|
||||||
url: '/pages/im/group/chat?targetId=' + this.targetId
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onHideModal() {
|
|
||||||
this.message = ''
|
|
||||||
this.modalShow = false
|
|
||||||
},
|
|
||||||
onJoinGroup() {
|
|
||||||
joinGroup(this.targetId, this.message).then(res => {
|
|
||||||
console.log('申请结果', res);
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '申请成功',
|
|
||||||
duration: 2000,
|
|
||||||
mast: true
|
|
||||||
})
|
|
||||||
setTimeout(() => {
|
|
||||||
this.$Router.back()
|
|
||||||
}, 2000)
|
|
||||||
}).catch(err => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: err.message
|
|
||||||
})
|
|
||||||
})
|
|
||||||
this.disabled = true
|
|
||||||
this.onHideModal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.apply {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
min-height: 100vh;
|
|
||||||
background-color: $window-color;
|
|
||||||
|
|
||||||
.u-avatar {
|
|
||||||
margin-top: 60rpx;
|
|
||||||
width: 180rpx;
|
|
||||||
height: 180rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
margin: 40rpx 0;
|
|
||||||
font-size: $title-size + 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.apply-btn {
|
|
||||||
width: 80%;
|
|
||||||
font-size: $title-size;
|
|
||||||
}
|
|
||||||
|
|
||||||
.apply-btn2 {
|
|
||||||
padding: 0 100rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,266 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="chat">
|
|
||||||
<sent-message-bar :conversationType="conversationType" :targetId="targetId" @onSuccess="getNewMessage()" />
|
|
||||||
|
|
||||||
<view class="shade" @click="hidePop" v-show="showPop">
|
|
||||||
<view class="pop" :style="popStyle" :class="{'show':showPop}">
|
|
||||||
<view v-for="(item, index) in popButton" :key="index" @click="pickerMenu(item)">
|
|
||||||
{{ item }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="body">
|
|
||||||
<view class="scroll">
|
|
||||||
<view class="cell" v-for="(message, index) in messages" :key="index">
|
|
||||||
<show-message-cell :message="message" isGroup @messageAction="messageAction" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
getGroupBase
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import im from '@/utils/im/index.js'
|
|
||||||
import sentMessageBar from '../components/sentMessageBar'
|
|
||||||
import showMessageCell from '../components/showMessageCell'
|
|
||||||
import utils from '@/utils/index.js'
|
|
||||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
|
||||||
import imBase from '../mixins/imBase.js'
|
|
||||||
import messageActions from '../mixins/messageActions.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase,
|
|
||||||
onGroupDismiss,
|
|
||||||
messageActions
|
|
||||||
],
|
|
||||||
components: {
|
|
||||||
sentMessageBar,
|
|
||||||
showMessageCell
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
avatarRpx: 84,
|
|
||||||
targetId: '',
|
|
||||||
conversationType: RongIMLib.ConversationType.GROUP,
|
|
||||||
messages: [],
|
|
||||||
groupInfo: {
|
|
||||||
name: ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
latestMessage() {
|
|
||||||
if (this.messages.length) {
|
|
||||||
return this.messages[0]
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
sentTime: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onShow() {
|
|
||||||
this.initGroupInfo()
|
|
||||||
},
|
|
||||||
onLoad(e) {
|
|
||||||
this.targetId = e.targetId
|
|
||||||
// 获取历史消息列表
|
|
||||||
this.getMessageList()
|
|
||||||
// 监听新消息
|
|
||||||
uni.$on('onReceiveMessage_' + this.targetId, (message) => {
|
|
||||||
this.getNewMessage()
|
|
||||||
})
|
|
||||||
uni.$on('onReceiptRequest', (msg) => {
|
|
||||||
if (msg.targetId == this.targetId) {
|
|
||||||
RongIMLib.getMessageByUId(msg.messageUId, (result) => {
|
|
||||||
RongIMLib.sendReadReceiptResponse(3, this.targetId, [result.message], (res) => {
|
|
||||||
console.error('发送群聊已读回执成功', res);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// 群已读回执
|
|
||||||
uni.$on('onReceiptResponse', (msg) => {
|
|
||||||
if (msg.targetId == this.targetId) {
|
|
||||||
this.messages = this.messages.map(item => {
|
|
||||||
if (msg.messageId == item.messageId) {
|
|
||||||
return msg
|
|
||||||
} else {
|
|
||||||
return item
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// 清理聊天记录
|
|
||||||
uni.$once('cleanGroupMessage', this.getMessageList)
|
|
||||||
uni.$on('onRecallMessage_' + this.targetId, (message) => {
|
|
||||||
this.messages = this.messages.map(item => {
|
|
||||||
if (message.messageId == item.messageId) {
|
|
||||||
return message
|
|
||||||
} else {
|
|
||||||
return item
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
uni.$on('onRemoveMessage_' + this.targetId, (messageId) => {
|
|
||||||
this.messages = this.messages.filter(item => item.messageId != messageId)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onUnload() {
|
|
||||||
uni.$off('onRemoveMessage_' + this.targetId)
|
|
||||||
uni.$off('onReceiveMessage_' + this.targetId)
|
|
||||||
uni.$off('onUpdateProfile_' + this.targetId)
|
|
||||||
uni.$off('onRecallMessage_' + this.targetId)
|
|
||||||
uni.$off('onReceiptRequest')
|
|
||||||
uni.$off('onReceiptResponse')
|
|
||||||
},
|
|
||||||
onNavigationBarButtonTap() {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/group/info?targetId=' + this.targetId
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initGroupInfo() {
|
|
||||||
// 获取群信息,成员数量,设置标题
|
|
||||||
getGroupBase(this.targetId).then(res => {
|
|
||||||
uni.setNavigationBarTitle({
|
|
||||||
title: res.name + `(${res.members})`
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onScroll(e) {
|
|
||||||
this.$refs.messageBar.onHidePopus()
|
|
||||||
},
|
|
||||||
getNewMessage() {
|
|
||||||
im.getMessageList(
|
|
||||||
this.conversationType,
|
|
||||||
this.targetId,
|
|
||||||
this.latestMessage.sentTime,
|
|
||||||
10,
|
|
||||||
false,
|
|
||||||
(messages) => {
|
|
||||||
this.messages.unshift(...messages)
|
|
||||||
this.scrollBottom()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 获取消息列表
|
|
||||||
getMessageList() {
|
|
||||||
im.getMessageList(
|
|
||||||
this.conversationType,
|
|
||||||
this.targetId,
|
|
||||||
0,
|
|
||||||
20,
|
|
||||||
true,
|
|
||||||
(messages) => {
|
|
||||||
console.log('获取消息列表', messages);
|
|
||||||
const msgs = messages.filter(item => item.receivedStatus == 0)
|
|
||||||
console.log('未读消息', msgs);
|
|
||||||
if (msgs.length) {
|
|
||||||
RongIMLib.sendReadReceiptResponse(3, this.targetId, msgs, (res) => {
|
|
||||||
console.error('发送群聊已读回执成功', res);
|
|
||||||
msgs.map(item => {
|
|
||||||
RongIMLib.setMessageReceivedStatus(item.messageId, 1)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
this.messages = messages
|
|
||||||
this.scrollBottom()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 滚动到底部
|
|
||||||
scrollBottom(type) {
|
|
||||||
if (this.latestMessage) {
|
|
||||||
// 清理当前会话,未读消息数量
|
|
||||||
RongIMLib.clearMessagesUnreadStatus(this.conversationType, this.targetId, this.latestMessage
|
|
||||||
.sentTime)
|
|
||||||
// 更新badge提醒数量
|
|
||||||
im.setNotifyBadge()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onHide() {
|
|
||||||
// console.log(JSON.stringify(this.$refs))
|
|
||||||
// this.$refs.voice.stopPlay()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
/* 窗口 */
|
|
||||||
.chat {
|
|
||||||
background: $window-color;
|
|
||||||
height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
|
|
||||||
.body {
|
|
||||||
overflow: scroll;
|
|
||||||
flex: 1;
|
|
||||||
height: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
|
|
||||||
.scroll {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
justify-content: flex-end;
|
|
||||||
|
|
||||||
.cell {
|
|
||||||
padding: 10rpx 20rpx;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 遮罩 */
|
|
||||||
.shade {
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 999;
|
|
||||||
|
|
||||||
.pop {
|
|
||||||
border-radius: 10rpx;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 101;
|
|
||||||
width: 200rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: 28rpx;
|
|
||||||
text-align: left;
|
|
||||||
color: #333;
|
|
||||||
background-color: #fff;
|
|
||||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
|
|
||||||
line-height: 80rpx;
|
|
||||||
transition: transform 0.15s ease-in-out 0s;
|
|
||||||
user-select: none;
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
transform: scale(0, 0);
|
|
||||||
|
|
||||||
&.show {
|
|
||||||
transform: scale(1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&>view {
|
|
||||||
padding: 0 20rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
user-select: none;
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: #f3f3f3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="group" :style="`background-color:${bg};`">
|
|
||||||
<block v-if="groups.length > 0">
|
|
||||||
<view class="title"> 群聊 </view>
|
|
||||||
<view v-for="(item, index) in groups" :key="index" class="friend-flex" @click="toGroup(item.targetId)">
|
|
||||||
<u-avatar size="36" shape="square" :src="contact(item.targetId).portraitUrl" />
|
|
||||||
<view class="info">
|
|
||||||
<view class="name">{{ item.name }} <span class="total">共{{ item.members }} 成员</span></view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="group-count"> {{ groups.length }}个群聊 </view>
|
|
||||||
</block>
|
|
||||||
<view class="no-lists" v-else>
|
|
||||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx" :src="require('@/static/imgs/no-friend.png')" :lazy-load="true" />
|
|
||||||
<span>空空如也~</span>
|
|
||||||
</view>
|
|
||||||
<u-modal negativeTop="300" :show="createModal" title="创建群聊" showCancelButton @cancel="onHideModal"
|
|
||||||
@confirm="onCreateGroup">
|
|
||||||
<view class="slot-content">
|
|
||||||
<u--input placeholder="群名称" border="surround" focus v-model="groupName"></u--input>
|
|
||||||
</view>
|
|
||||||
</u-modal>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
getMyGroups,
|
|
||||||
createGroup
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
groups: [],
|
|
||||||
createModal: false,
|
|
||||||
groupName: '',
|
|
||||||
bg: '#fff'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
contact() {
|
|
||||||
return function(targetId) {
|
|
||||||
return this.$store.getters.contactInfo(targetId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onNavigationBarButtonTap() {
|
|
||||||
this.createModal = true
|
|
||||||
},
|
|
||||||
onShow() {
|
|
||||||
this.initData()
|
|
||||||
uni.$on('onGroupDismiss', this.initData)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initData() {
|
|
||||||
getMyGroups().then((res) => {
|
|
||||||
console.log(res,'res...')
|
|
||||||
if (res.length > 0) {
|
|
||||||
this.bg = '#f9f9f9'
|
|
||||||
} else {
|
|
||||||
this.bg = '#fff'
|
|
||||||
}
|
|
||||||
this.groups = res
|
|
||||||
res.map(item => {
|
|
||||||
this.$store.dispatch('updateContact', item)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onHideModal() {
|
|
||||||
this.createModal = false
|
|
||||||
this.groupName = ''
|
|
||||||
},
|
|
||||||
onCreateGroup() {
|
|
||||||
createGroup({
|
|
||||||
name: this.groupName
|
|
||||||
}).then(res => {
|
|
||||||
uni.showToast({
|
|
||||||
title: '创建成功'
|
|
||||||
})
|
|
||||||
}).catch(err => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: err.message
|
|
||||||
})
|
|
||||||
}).finally(() => {
|
|
||||||
this.initData()
|
|
||||||
this.onHideModal()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
toGroup(targetId) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/group/chat?targetId=' + targetId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.group {
|
|
||||||
min-height: 100vh;
|
|
||||||
background-color: $window-color;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: $title-size-m;
|
|
||||||
color: $text-gray-m;
|
|
||||||
padding: 10rpx $padding;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-count {
|
|
||||||
text-align: center;
|
|
||||||
font-size: $title-size;
|
|
||||||
color: $text-gray;
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 10rpx $padding 20rpx $padding;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 好友列表
|
|
||||||
.friend-flex {
|
|
||||||
position: relative;
|
|
||||||
padding: 20rpx $padding;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
background-color: #fff;
|
|
||||||
|
|
||||||
|
|
||||||
.info {
|
|
||||||
flex: 1;
|
|
||||||
margin-left: $padding + 10;
|
|
||||||
border-bottom: solid 1rpx #f9f9f9;
|
|
||||||
padding-bottom: $padding;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font-size: $title-size + 1;
|
|
||||||
color: #454545 !important;
|
|
||||||
}
|
|
||||||
.total{
|
|
||||||
color: $text-gray-m;
|
|
||||||
font-size: $title-size-m - 5;
|
|
||||||
padding-left: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.address {
|
|
||||||
color: $text-gray-m;
|
|
||||||
font-size: $title-size-m - 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-lists {
|
|
||||||
padding-top: $padding * 5;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
color: $text-gray-m;
|
|
||||||
|
|
||||||
span {
|
|
||||||
padding-top: $padding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,378 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="container">
|
|
||||||
<view class="members u-border-bottom">
|
|
||||||
<group-user-list ref="userList" :targetId="targetId" :count="14" />
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<u-cell-group class="cells" :border="false">
|
|
||||||
<u-cell :border="false" class="u-border-bottom" isLink title="群公告" @click="toAnnouncement">
|
|
||||||
<view slot="label" class="announcement-label "> {{announcement}} </view>
|
|
||||||
</u-cell>
|
|
||||||
<u-cell :border="false" class="u-border-bottom" isLink title="二维码" @click="showGroupQrCode" />
|
|
||||||
<u-cell :border="false" class="u-border-bottom" v-if="group.can_makesure" isLink title="群聊邀请确认" @click="showGroupsSure" />
|
|
||||||
<u-cell :border="false" class="u-border-bottom" title="聊天置顶">
|
|
||||||
<u-switch slot="value" size="20" v-model="isTop" activeColor="#34CE98" @change="setTop" />
|
|
||||||
</u-cell>
|
|
||||||
<u-cell class="u-border-bottom" :border="false" title="消息免打扰">
|
|
||||||
<u-switch slot="value" size="20" v-model="status" activeColor="#34CE98" @change="setStatus" />
|
|
||||||
</u-cell>
|
|
||||||
</u-cell-group>
|
|
||||||
|
|
||||||
<u-cell-group class="cells" v-if="group.is_admin" :border="false">
|
|
||||||
<u-cell :border="false" class="u-border-bottom" isLink title="修改群聊名称" :value="groupName"
|
|
||||||
@click="onGroupName" />
|
|
||||||
<!-- <u-cell :border="false" class="u-border-bottom" isLink title="修改群头像" @click="onGroupAvatar">
|
|
||||||
<u-avatar slot="value" size="25" shape="square" :src="group.cover" />
|
|
||||||
</u-cell> -->
|
|
||||||
<u-cell :border="false" class="u-border-bottom" isLink v-if="group.is_owner" title="准入方式" :value="joinType" @click="onChangeJoinType" />
|
|
||||||
</u-cell-group>
|
|
||||||
|
|
||||||
<view class="cells actions" v-if="loaded">
|
|
||||||
<view class="action u-border-bottom" @click="onClean">清空聊天记录</view>
|
|
||||||
<view class="action u-border-bottom" v-if="group.is_owner" @click="onDismiss">解散群聊</view>
|
|
||||||
<view class="action u-border-bottom" v-else @click="onQuite">删除并退出</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<u-modal negativeTop="300" :show="modalShow" title="修改群名称" showCancelButton @cancel="onHideModal" @confirm="onChangeGroupName">
|
|
||||||
<view class="slot-content"> <u--input placeholder="群名称" border="surround" focus v-model="groupName" maxlength="12" /> </view>
|
|
||||||
</u-modal>
|
|
||||||
|
|
||||||
<u-modal :show="qrCodeShow" :title="group.name" @confirm="qrCodeShow = false">
|
|
||||||
<view class="slot-content"> <uqrcode class="info-code-src" :size="198" :text="qrContent" /> </view>
|
|
||||||
</u-modal>
|
|
||||||
|
|
||||||
<u-action-sheet @select="doAction" :actions="joinTypeMap" cancelText="取消" :show="showActions" @close="showActions=false" />
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
getGroupInfo,
|
|
||||||
updateGroup,
|
|
||||||
quitGroup,
|
|
||||||
dismissGroup
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
import {
|
|
||||||
uploads
|
|
||||||
} from '@/apis/interfaces/uploading'
|
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import groupUserList from '../components/groupUserList'
|
|
||||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
|
||||||
import imBase from '../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
groupUserList
|
|
||||||
},
|
|
||||||
mixins: [
|
|
||||||
imBase,
|
|
||||||
onGroupDismiss
|
|
||||||
],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
targetId: '',
|
|
||||||
group: {},
|
|
||||||
conversationType: 3,
|
|
||||||
announcement: '',
|
|
||||||
status: false,
|
|
||||||
isTop: false,
|
|
||||||
loaded: false,
|
|
||||||
modalShow: false,
|
|
||||||
groupName: '',
|
|
||||||
qrCodeShow: false,
|
|
||||||
qrContent: 'JOINGROUP|',
|
|
||||||
joinType: '',
|
|
||||||
joinTypeMap: [],
|
|
||||||
showActions: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad(e) {
|
|
||||||
this.targetId = e.targetId
|
|
||||||
this.qrContent += e.targetId
|
|
||||||
RongIMLib.getConversationNotificationStatus(this.conversationType, this.targetId, ({
|
|
||||||
status
|
|
||||||
}) => {
|
|
||||||
this.status = !Boolean(status)
|
|
||||||
})
|
|
||||||
RongIMLib.getConversation(this.conversationType, this.targetId, ({
|
|
||||||
code,
|
|
||||||
conversation
|
|
||||||
}) => {
|
|
||||||
if (code == 0) {
|
|
||||||
this.isTop = conversation.isTop
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.initData()
|
|
||||||
uni.$on('groupAnnouncementCreated', this.initData)
|
|
||||||
uni.$on('groupInvitedUser', this.updateUserList)
|
|
||||||
uni.$on('updateAnnouncement', this.initData)
|
|
||||||
},
|
|
||||||
onUnload() {
|
|
||||||
uni.$off('groupAnnouncementCreated')
|
|
||||||
uni.$off('groupInvitedUser')
|
|
||||||
uni.$off('updateAnnouncement')
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
updateUserList() {
|
|
||||||
this.$refs.userList.initUsers()
|
|
||||||
},
|
|
||||||
initData() {
|
|
||||||
getGroupInfo(this.targetId).then(res => {
|
|
||||||
this.group = res.group
|
|
||||||
this.groupName = res.group.name
|
|
||||||
this.announcement = res.announcement
|
|
||||||
this.members = res.members
|
|
||||||
this.loaded = true
|
|
||||||
this.joinTypeMap = res.join_type_map.map(item => {
|
|
||||||
item.disabled = item.key == res.join_type
|
|
||||||
return item
|
|
||||||
})
|
|
||||||
this.joinType = res.join_type_map.filter(item => {
|
|
||||||
return item.key == res.join_type
|
|
||||||
})[0].name
|
|
||||||
}).catch(err => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '群不存在'
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
setStatus() {
|
|
||||||
RongIMLib.setConversationNotificationStatus(this.conversationType, this.targetId, this.status,
|
|
||||||
({
|
|
||||||
status
|
|
||||||
}) => {
|
|
||||||
this.status = !Boolean(status)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
setTop() {
|
|
||||||
RongIMLib.setConversationToTop(this.conversationType, this.targetId, this.isTop, (res) => {
|
|
||||||
RongIMLib.getConversation(this.conversationType, this.targetId, ({
|
|
||||||
conversation
|
|
||||||
}) => {
|
|
||||||
this.isTop = conversation.isTop
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
toAnnouncement() {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/group/announcement?targetId=' + this.targetId
|
|
||||||
})
|
|
||||||
},
|
|
||||||
showGroupQrCode() {
|
|
||||||
this.qrCodeShow = true
|
|
||||||
},
|
|
||||||
// 群聊邀请待确认
|
|
||||||
showGroupsSure() {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: "/pages/im/group/reviewed?targetId=" + this.targetId
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onGroupName() {
|
|
||||||
this.modalShow = true
|
|
||||||
},
|
|
||||||
onChangeGroupName() {
|
|
||||||
if (this.groupName != this.group.name) {
|
|
||||||
updateGroup(this.targetId, {
|
|
||||||
name: this.groupName
|
|
||||||
}).then(res => {
|
|
||||||
this.modalShow = false
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '群名称修改成功'
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '无修改'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onHideModal() {
|
|
||||||
this.modalShow = false
|
|
||||||
this.groupName = this.group.name
|
|
||||||
},
|
|
||||||
// 修改群头像
|
|
||||||
onGroupAvatar() {
|
|
||||||
uni.chooseImage({
|
|
||||||
count: 1,
|
|
||||||
sourceType: ['album'],
|
|
||||||
crop: {
|
|
||||||
quality: 100,
|
|
||||||
width: 128,
|
|
||||||
height: 128,
|
|
||||||
resize: true
|
|
||||||
},
|
|
||||||
success: res => {
|
|
||||||
console.log(res);
|
|
||||||
let path = res.tempFiles.map((val, index) => {
|
|
||||||
return {
|
|
||||||
name: 'uploads' + index,
|
|
||||||
uri: val.path
|
|
||||||
}
|
|
||||||
})
|
|
||||||
uploads(path).then(path => {
|
|
||||||
updateGroup(this.targetId, {
|
|
||||||
cover: path.path[0]
|
|
||||||
}).then(res => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '群头像修改成功'
|
|
||||||
})
|
|
||||||
this.modalShow = false
|
|
||||||
this.group.cover = path.url[0]
|
|
||||||
})
|
|
||||||
}).catch(err => {
|
|
||||||
uni.showToast({
|
|
||||||
title: err.message,
|
|
||||||
icon: 'none'
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onChangeJoinType() {
|
|
||||||
this.showActions = true
|
|
||||||
},
|
|
||||||
doAction(e) {
|
|
||||||
updateGroup(this.targetId, {
|
|
||||||
join_type: e.key
|
|
||||||
}).then(res => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '修改成功'
|
|
||||||
})
|
|
||||||
this.joinTypeMap = this.joinTypeMap.map(item => {
|
|
||||||
if (item.key == e.key) {
|
|
||||||
item.disabled = true
|
|
||||||
} else {
|
|
||||||
item.disabled = false
|
|
||||||
}
|
|
||||||
return item
|
|
||||||
})
|
|
||||||
this.joinType = e.name
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.userList.initGroupInfo()
|
|
||||||
this.initData()
|
|
||||||
})
|
|
||||||
this.showActions = false
|
|
||||||
}).catch(err => {
|
|
||||||
console.log(err);
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'error',
|
|
||||||
title: err.message
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onClean() {
|
|
||||||
uni.showModal({
|
|
||||||
title: '清空聊天记录',
|
|
||||||
content: '清空聊天记录,只会清空本地的记录,其他成员不会变化',
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
RongIMLib.deleteMessages(3, this.targetId, () => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '清空成功'
|
|
||||||
})
|
|
||||||
uni.$emit('cleanGroupMessage')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onDismiss() {
|
|
||||||
uni.showModal({
|
|
||||||
title: '解散群聊',
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
dismissGroup(this.targetId).then(res => {
|
|
||||||
console.log('解散群', res);
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '解散成功'
|
|
||||||
})
|
|
||||||
uni.switchTab({
|
|
||||||
url: '/pages/im/index'
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onQuite() {
|
|
||||||
uni.showModal({
|
|
||||||
title: '退出群聊',
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
quitGroup(this.targetId).then(res => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '退出群聊成功'
|
|
||||||
})
|
|
||||||
// 移除指定的会话
|
|
||||||
RongIMLib.removeConversation(this.conversationType, this.targetId)
|
|
||||||
|
|
||||||
uni.switchTab({
|
|
||||||
url: '/pages/im/index'
|
|
||||||
})
|
|
||||||
}).catch(err => {
|
|
||||||
console.log(err);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.container {
|
|
||||||
min-height: 100vh;
|
|
||||||
background: $window-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cells {
|
|
||||||
margin-top: $padding;
|
|
||||||
background-color: white;
|
|
||||||
|
|
||||||
.announcement-label {
|
|
||||||
font-size: $title-size-m + 2;
|
|
||||||
padding-top: 10rpx;
|
|
||||||
color: $text-gray-m;
|
|
||||||
overflow: hidden;
|
|
||||||
width: 620rpx;
|
|
||||||
display: inline-block;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-line-clamp: 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.members {
|
|
||||||
background-color: white;
|
|
||||||
padding-bottom: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
margin-top: $padding;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
.action {
|
|
||||||
padding: $padding;
|
|
||||||
color: $text-price;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.u-border-bottom {
|
|
||||||
border-bottom: solid 1rpx #f9f9f9 !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,283 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="invite">
|
|
||||||
<view class="search u-border-bottom">
|
|
||||||
<u--input class="search-input" placeholder="搜索好友" border="none" prefixIcon="search" v-model="searchTxt"
|
|
||||||
disabledColor="#Fff" prefixIconStyle="font-size: 22px;color: #909399" @change="onSearch" />
|
|
||||||
</view>
|
|
||||||
<block v-if="friends.length > 0">
|
|
||||||
<u-index-list :index-list="indexs" inactiveColor="#666" activeColor="#34CE98">
|
|
||||||
<u-checkbox-group v-if="friends.length > 0" v-model="checkboxValue" placement="column">
|
|
||||||
<u-index-item v-for="(item, fkey) in friends" :key="fkey">
|
|
||||||
<u-index-anchor :text="indexs[fkey]" v-if="indexs[fkey]" bgColor="#f9f9f9f" height="20"
|
|
||||||
size="12" color="#666"
|
|
||||||
style="border:none !important;padding: 10rpx 30rpx;background-color: #f9f9f9 !important;" />
|
|
||||||
<view v-for="(friendItem, index) in item" :key="index" class="friend-flex"
|
|
||||||
@click="addContact(friendItem.targetId)">
|
|
||||||
<u-checkbox :name="friendItem.targetId" shape="circle" activeColor="#34ce98"
|
|
||||||
style="margin-right: 20rpx;" :disabled="canSelect(friendItem.targetId)"
|
|
||||||
:checked="canSelect(friendItem.targetId)" />
|
|
||||||
<u-avatar class="avatar-img" size="40" shape="square"
|
|
||||||
:src="contact(friendItem.targetId).portraitUrl" />
|
|
||||||
<view class="info">
|
|
||||||
<view class="name">{{ contact(friendItem.targetId).name }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</u-index-item>
|
|
||||||
</u-checkbox-group>
|
|
||||||
</u-index-list>
|
|
||||||
<view class="bottom">
|
|
||||||
<span class="onInvite" v-if="canInvite"> 添加中<span>{{`(${checkboxValue.length})` || ''}}</span></span>
|
|
||||||
<span class="onInvite" v-else @click="onInvite">完成<span>{{`(${checkboxValue.length})` || ''}}</span></span>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
<view class="no-lists" v-else>
|
|
||||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx"
|
|
||||||
:src="searchTxt=== '' ? require('@/static/imgs/no-friend.png') :require('@/static/imgs/no-search.png')"
|
|
||||||
:lazy-load="true" />
|
|
||||||
<span>{{searchTxt=== ''?'暂无好友列表~':'暂无搜索内容~'}}</span>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
getFriendsLetter,
|
|
||||||
inviteGroupUser,
|
|
||||||
getGroupUsers
|
|
||||||
} from '@/apis/interfaces/im';
|
|
||||||
import utils from '@/utils/index.js'
|
|
||||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import imBase from '../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase,
|
|
||||||
onGroupDismiss
|
|
||||||
],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
searchTxt: '',
|
|
||||||
targetId: '',
|
|
||||||
indexs: [],
|
|
||||||
orignalIndexs: [],
|
|
||||||
friends: [],
|
|
||||||
orignalFriends: [],
|
|
||||||
checkboxValue: [],
|
|
||||||
selectValue: [],
|
|
||||||
canInvite:false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
onLoad(e) {
|
|
||||||
this.targetId = e.targetId
|
|
||||||
this.getFriendList()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onSearch() {
|
|
||||||
if (this.searchTxt) {
|
|
||||||
this.friends = this.orignalFriends.map((list, index) => {
|
|
||||||
const resList = list.filter(item => {
|
|
||||||
return item.name.indexOf(this.searchTxt) >= 0
|
|
||||||
})
|
|
||||||
return resList
|
|
||||||
})
|
|
||||||
this.indexs = this.orignalIndexs.map((t, i) => {
|
|
||||||
if (this.friends[i].length > 0) {
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.friends = this.orignalFriends
|
|
||||||
this.indexs = this.orignalIndexs
|
|
||||||
}
|
|
||||||
},
|
|
||||||
canSelect(targetId) {
|
|
||||||
return utils.inArray(targetId, this.selectValue)
|
|
||||||
},
|
|
||||||
getFriendList() {
|
|
||||||
getFriendsLetter().then(res => {
|
|
||||||
this.indexs = res.indexList
|
|
||||||
this.friends = res.itemArr
|
|
||||||
this.orignalFriends = res.itemArr
|
|
||||||
this.orignalIndexs = res.indexList
|
|
||||||
})
|
|
||||||
getGroupUsers(this.targetId).then(res => {
|
|
||||||
res.map(res => {
|
|
||||||
console.log(res)
|
|
||||||
this.checkboxValue.push(String(res.targetId))
|
|
||||||
this.selectValue.push(String(res.targetId))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 点击名字新增或删除选中数据
|
|
||||||
addContact(targetId) {
|
|
||||||
const index = this.checkboxValue.findIndex(item => item == targetId)
|
|
||||||
if (utils.inArray(targetId, this.selectValue)) {
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (index === -1) {
|
|
||||||
this.checkboxValue.push(targetId)
|
|
||||||
} else {
|
|
||||||
this.checkboxValue.splice(index, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
onInvite() {
|
|
||||||
console.log(this.checkboxValue, 'userIds.....')
|
|
||||||
console.log(this.selectValue, 'userIds.....')
|
|
||||||
this.canInvite = true
|
|
||||||
let userIds = []
|
|
||||||
this.checkboxValue.filter(item => {
|
|
||||||
if (!utils.inArray(item, this.selectValue)) {
|
|
||||||
userIds.push(item)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// console.log(userIds)
|
|
||||||
inviteGroupUser(this.targetId, this.checkboxValue, userIds).then(res => {
|
|
||||||
uni.navigateBack({
|
|
||||||
delta: 1,
|
|
||||||
animationType: 'pop-out',
|
|
||||||
animationDuration: 200
|
|
||||||
});
|
|
||||||
this.canInvite = false
|
|
||||||
uni.$emit('groupInvitedUser')
|
|
||||||
}).catch(err => {
|
|
||||||
this.canInvite = false
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: err.message
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
// 页面空
|
|
||||||
.pages-null {
|
|
||||||
height: 70vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 好友列表
|
|
||||||
.friend-flex {
|
|
||||||
position: relative;
|
|
||||||
padding: 0 $padding 0 $padding;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.avatar-img {
|
|
||||||
box-shadow: 0 0 20rpx rgba($color: $main-color, $alpha: 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.info {
|
|
||||||
flex: 1;
|
|
||||||
margin-left: $padding;
|
|
||||||
border-bottom: solid 1rpx #f9f9f9;
|
|
||||||
height: 120rpx;
|
|
||||||
line-height: 120rpx;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font-size: $title-size;
|
|
||||||
color: #454545 !important;
|
|
||||||
@extend .nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.address {
|
|
||||||
color: $text-gray-m;
|
|
||||||
font-size: $title-size-m - 3;
|
|
||||||
padding-top: 10rpx;
|
|
||||||
word-break: break-word;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
width: 600rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-cell {
|
|
||||||
display: flex;
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px 24rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
color: #323233;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 24px;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invite {
|
|
||||||
position: relative;
|
|
||||||
padding: 100rpx 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
z-index: 0;
|
|
||||||
|
|
||||||
.bottom {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 120rpx;
|
|
||||||
background-color: $window-color;
|
|
||||||
z-index: 100;
|
|
||||||
color: #fff;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-end;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding-right: 30rpx;
|
|
||||||
padding-bottom: 10rpx;
|
|
||||||
|
|
||||||
.onInvite {
|
|
||||||
background-color: $main-color;
|
|
||||||
font-size: $title-size;
|
|
||||||
display: inline-block;
|
|
||||||
padding: 10rpx 30rpx;
|
|
||||||
border-radius: 10rpx;
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: $title-size - 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.search {
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 30rpx;
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
top: 0;
|
|
||||||
z-index: 100;
|
|
||||||
|
|
||||||
.search-input {
|
|
||||||
padding: 10rpx $padding;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchTxt {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.no-lists {
|
|
||||||
padding-top: $padding * 3;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
color: $text-gray-m;
|
|
||||||
|
|
||||||
span {
|
|
||||||
padding-top: $padding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
<!-- 群聊邀请确认列表页面 -->
|
|
||||||
<template>
|
|
||||||
<view class="reviewed">
|
|
||||||
<block v-if="pendings.length > 0">
|
|
||||||
<view class="reviewed-item" v-for="(item, index) in pendings" :key="index">
|
|
||||||
<u-avatar class="avatar"
|
|
||||||
:src="JSON.parse(item.content.extra).portraitUrl || require('@/static/user/cover.png')"
|
|
||||||
shape="square" size="46" />
|
|
||||||
<view style="flex:1;" v-if="item.content.operation == 'GroupPending'">
|
|
||||||
<view class="nickname">{{ JSON.parse(item.content.extra).name }} 申请加入群聊</view>
|
|
||||||
<view> 申请原因:{{ item.content.message }}</view>
|
|
||||||
</view>
|
|
||||||
<view style="flex:1;" v-if="item.content.operation == 'GroupInvite'">
|
|
||||||
<view class="nickname">
|
|
||||||
<text>{{ contact(item.content.sourceUserId).name }}</text>想邀请<span>{{ JSON.parse(item.content.extra).name }}</span>加入群聊
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="sure" @click="sure(item.content.targetUserId,item.messageId)"> 通过 </view>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
|
|
||||||
<view class="no-lists" v-else>
|
|
||||||
<u-image class="cover" radius="4" width="400rpx" height="400rpx"
|
|
||||||
:src="require('@/static/imgs/no-friend.png')" :lazy-load="true" />
|
|
||||||
<span>暂无群聊申请数据</span>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
getGroupMakeSure,
|
|
||||||
getGroupMakeSureAllow,
|
|
||||||
groupMakeSure
|
|
||||||
} from "@/apis/interfaces/im.js"
|
|
||||||
import im from '@/utils/im/message.js'
|
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
|
||||||
import imBase from '../mixins/imBase.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase,
|
|
||||||
onGroupDismiss
|
|
||||||
],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
targetId: '',
|
|
||||||
pendings: [],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
contact() {
|
|
||||||
return function(targetId) {
|
|
||||||
return this.$store.getters.contactInfo(targetId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad(e) {
|
|
||||||
this.targetId = e.targetId
|
|
||||||
this.getList()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
im.getGroupPendinglist(this.targetId, (result) => {
|
|
||||||
console.log(result)
|
|
||||||
this.pendings = result
|
|
||||||
})
|
|
||||||
},
|
|
||||||
sure(userId, latestMessageId) {
|
|
||||||
groupMakeSure(this.targetId, userId).then(res => {
|
|
||||||
// 清除聊天列表
|
|
||||||
RongIMLib.deleteMessagesByIds([latestMessageId], ({
|
|
||||||
code
|
|
||||||
}) => {
|
|
||||||
console.log('code', code)
|
|
||||||
if (code == 0) {
|
|
||||||
uni.showToast({
|
|
||||||
title: ` 通过 `,
|
|
||||||
icon: 'none',
|
|
||||||
mask: true,
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
this.getList()
|
|
||||||
uni.$emit('groupInvitedUser')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}).catch(err => {
|
|
||||||
// uni.showToast({
|
|
||||||
// title: err.message,
|
|
||||||
// icon: 'none',
|
|
||||||
// mask: true,
|
|
||||||
// duration: 2000
|
|
||||||
// })
|
|
||||||
RongIMLib.deleteMessagesByIds([latestMessageId], ({
|
|
||||||
code
|
|
||||||
}) => {
|
|
||||||
console.log('code', code)
|
|
||||||
if (code == 0) {
|
|
||||||
uni.showToast({
|
|
||||||
title: err.message,
|
|
||||||
icon: 'none',
|
|
||||||
mask: true,
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
this.getList()
|
|
||||||
uni.$emit('groupInvitedUser')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
// 直接调用通过或拒绝的接口
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.reviewed {
|
|
||||||
.reviewed-item {
|
|
||||||
margin: $padding - 10;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: flex-start;
|
|
||||||
box-sizing: border-box;
|
|
||||||
border-bottom: solid 1rpx #f9f9f9;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
padding-bottom: 20rpx;
|
|
||||||
color: $text-gray-m;
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
background-color: $main-color;
|
|
||||||
border-radius: 6rpx;
|
|
||||||
margin-right: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nickname {
|
|
||||||
font-size: $title-size;
|
|
||||||
color: $text-color;
|
|
||||||
padding-bottom: 6rpx;
|
|
||||||
|
|
||||||
span {
|
|
||||||
color: $text-color;
|
|
||||||
font-size: $title-size-m +1;
|
|
||||||
padding-top: 20rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sure {
|
|
||||||
background-color: $main-color;
|
|
||||||
color: #Fff;
|
|
||||||
text-align: center;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
padding: 6rpx 20rpx;
|
|
||||||
border-radius: 10rpx;
|
|
||||||
margin-left: 10rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-lists {
|
|
||||||
padding-top: $padding * 5;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
color: $text-gray-m;
|
|
||||||
|
|
||||||
span {
|
|
||||||
padding-top: $padding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
<template>
|
|
||||||
<group-user-list :targetId="targetId" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import groupUserList from '../components/groupUserList'
|
|
||||||
import onGroupDismiss from '../mixins/onGroupDismiss.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
onGroupDismiss
|
|
||||||
],
|
|
||||||
components: {
|
|
||||||
groupUserList
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
targetId: '',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad(e) {
|
|
||||||
this.targetId = e.targetId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@@ -1,218 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="contents">
|
|
||||||
<view class="ios-top"></view>
|
|
||||||
<!-- header -->
|
|
||||||
<view class="custom-header">
|
|
||||||
<view class="header-flex">
|
|
||||||
<view class="tabs">
|
|
||||||
<view class="item active">聊聊</view>
|
|
||||||
</view>
|
|
||||||
<view class="btns">
|
|
||||||
<view class="item" @click="scanQrCode">
|
|
||||||
<uni-icons color="#555" type="scan" size="22" />
|
|
||||||
</view>
|
|
||||||
<view class="item" @click="toFriendList">
|
|
||||||
<u-badge absolute max="99" :offset="[-5, -5]" :value="hasNewFriends" />
|
|
||||||
<uni-icons color="#555" custom-prefix="iconfont" type="icon-tuandui" size="22" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<!-- content -->
|
|
||||||
<view v-if="$store.state.token !== ''">
|
|
||||||
<connection-status :connection="connection" />
|
|
||||||
<conversation-list @refresh="getConversationList()" :conversations="conversations" />
|
|
||||||
</view>
|
|
||||||
<!-- 未登录 -->
|
|
||||||
<view v-else class="vertical null-list">
|
|
||||||
<u-empty icon="http://cdn.uviewui.com/uview/empty/permission.png" textColor="#999" text="登录后开启聊天吧~">
|
|
||||||
<template>
|
|
||||||
<view class="null-list-btn" @click="toLogin">去登录</view>
|
|
||||||
</template>
|
|
||||||
</u-empty>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import im from '@/utils/im/index.js'
|
|
||||||
import userAuth from '@/public/userAuth'
|
|
||||||
import conversationList from './components/conversationList'
|
|
||||||
import connectionStatus from './components/connectionStatus'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
conversations: [], // 会话列表
|
|
||||||
connection: 0,
|
|
||||||
hasNewFriends: 0,
|
|
||||||
perPage: 200
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
conversationList,
|
|
||||||
connectionStatus
|
|
||||||
},
|
|
||||||
onLoad() {
|
|
||||||
// 监听新的好友申请
|
|
||||||
uni.$on('onNewContactConversation', () => {
|
|
||||||
console.log('更新好友申请数量');
|
|
||||||
// 更新好友申请数量
|
|
||||||
this.checkNewFriendPending()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onShow() {
|
|
||||||
// 好友申请数量
|
|
||||||
this.checkNewFriendPending()
|
|
||||||
|
|
||||||
if (this.$store.state.token !== '') {
|
|
||||||
this.getConversationList()
|
|
||||||
}
|
|
||||||
// 监听新消息
|
|
||||||
uni.$on('onReceiveMessage', (msg) => {
|
|
||||||
this.getConversationList()
|
|
||||||
})
|
|
||||||
// 监听网络状态变化
|
|
||||||
uni.$on('onConnectionStatusChange', (status) => {
|
|
||||||
this.connection = status
|
|
||||||
if (status == 0) {
|
|
||||||
this.getConversationList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onHide() {
|
|
||||||
uni.$off('onReceiveMessage')
|
|
||||||
uni.$off('onConnectionStatusChange')
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
checkNewFriendPending() {
|
|
||||||
im.getPendingList((pendings) => {
|
|
||||||
this.hasNewFriends = pendings.length
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 检查登录
|
|
||||||
toLogin() {
|
|
||||||
if (this.$store.state.token === '') {
|
|
||||||
const Auth = new userAuth()
|
|
||||||
Auth.Login()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
// 获取会话列表,最新的一千条
|
|
||||||
getConversationList() {
|
|
||||||
RongIMLib.getConversationList([1, 3], this.perPage, 0, ({
|
|
||||||
code,
|
|
||||||
conversations
|
|
||||||
}) => {
|
|
||||||
if (code === 0) {
|
|
||||||
console.log(conversations,',,,,,')
|
|
||||||
this.conversations = conversations
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 调起扫码
|
|
||||||
scanQrCode() {
|
|
||||||
uni.scanCode({
|
|
||||||
success: (res) => {
|
|
||||||
if (res.scanType == 'QR_CODE') {
|
|
||||||
if (res.result.substr(0, 10) == 'ADDFRIEND|') {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/friends/info?targetId=' + res.result.substr(10)
|
|
||||||
})
|
|
||||||
} else if (res.result.substr(0, 10) == 'JOINGROUP|') {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/group/apply?targetId=' + res.result.substr(10)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
title: '暂不支持的二维码'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
toFriendList() {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/friends/index'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
// contents
|
|
||||||
.contents {
|
|
||||||
background-color: #fff;
|
|
||||||
min-height: 100vh;
|
|
||||||
padding-top: 90rpx + 6rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.custom-header {
|
|
||||||
@extend .ios-top;
|
|
||||||
background: $window-color;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 9999;
|
|
||||||
|
|
||||||
.header-flex {
|
|
||||||
padding: 20rpx $padding;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
height: 60rpx;
|
|
||||||
line-height: 60rpx;
|
|
||||||
|
|
||||||
.tabs {
|
|
||||||
|
|
||||||
.item {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
font-size: $title-size-lg;
|
|
||||||
color: $text-gray;
|
|
||||||
padding: 0 ($padding - 10);
|
|
||||||
border-radius: 30rpx;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
background: rgba($color: $main-color, $alpha: .1);
|
|
||||||
color: $main-color;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.btns {
|
|
||||||
.item {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: $margin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.null-list {
|
|
||||||
height: 100vh;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
&-btn {
|
|
||||||
margin-top: $margin * 2;
|
|
||||||
line-height: 70rpx;
|
|
||||||
color: $main-color;
|
|
||||||
border: solid 2rpx $main-color;
|
|
||||||
padding: 0 ($padding*3);
|
|
||||||
font-size: $title-size-m;
|
|
||||||
border-radius: 35rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.u-border-bottom {
|
|
||||||
border-bottom: solid 1rpx #f9f9f9 !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import utils from '@/utils/index.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
computed: {
|
|
||||||
contact() {
|
|
||||||
return function(targetId) {
|
|
||||||
return this.$store.getters.contactInfo(targetId)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
avatarSize() {
|
|
||||||
return utils.rpx2px(84)
|
|
||||||
},
|
|
||||||
sender() {
|
|
||||||
return this.$store.getters.sender
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
rpx2px(size) {
|
|
||||||
return utils.rpx2px(size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
import * as IMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
winSize: {},
|
|
||||||
showPop: false,
|
|
||||||
/* 弹窗按钮列表 */
|
|
||||||
popButton: ['复制', '删除', '撤回'],
|
|
||||||
/* 弹窗定位样式 */
|
|
||||||
popStyle: "",
|
|
||||||
pickedItem: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad() {
|
|
||||||
uni.getSystemInfo({
|
|
||||||
success: (e) => {
|
|
||||||
this.winSize = {
|
|
||||||
width: e.windowWidth,
|
|
||||||
height: e.windowHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 隐藏功能菜单
|
|
||||||
hidePop() {
|
|
||||||
this.showPop = false
|
|
||||||
this.pickedItem = {}
|
|
||||||
setTimeout(() => {
|
|
||||||
this.showShade = false
|
|
||||||
}, 250)
|
|
||||||
},
|
|
||||||
// 点击会话功能菜单
|
|
||||||
pickerMenu(e) {
|
|
||||||
const msg = this.pickedItem
|
|
||||||
console.log(msg);
|
|
||||||
switch (e) {
|
|
||||||
case '复制':
|
|
||||||
uni.setClipboardData({
|
|
||||||
data: msg.content.content
|
|
||||||
})
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '复制成功'
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
case '删除':
|
|
||||||
IMLib.deleteMessagesByIds([msg.messageId], ({
|
|
||||||
code
|
|
||||||
}) => {
|
|
||||||
if (code === 0) {
|
|
||||||
uni.$emit('onRemoveMessage_' + msg.targetId, msg.messageId)
|
|
||||||
uni.showToast({
|
|
||||||
title: '消息删除成功',
|
|
||||||
icon: 'none',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
case '撤回':
|
|
||||||
const pushContent = this.$store.getters.sender.name + '撤回了一条消息'
|
|
||||||
IMLib.recallMessage(msg.messageId, pushContent,
|
|
||||||
({
|
|
||||||
code,
|
|
||||||
message
|
|
||||||
}) => {
|
|
||||||
if (code === 0) {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '消息撤回成功'
|
|
||||||
})
|
|
||||||
msg.objectName = 'RC:RcNtf'
|
|
||||||
uni.$emit('onRecallMessage_' + msg.targetId, msg)
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '撤回失败' + code
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
this.hidePop()
|
|
||||||
},
|
|
||||||
messageAction(e) {
|
|
||||||
let [touches, style, item] = [e.event.touches[0], "", e.message]
|
|
||||||
|
|
||||||
if (touches.clientY > (this.winSize.height / 2)) {
|
|
||||||
style = `bottom:${this.winSize.height-touches.clientY}px;`
|
|
||||||
} else {
|
|
||||||
style = `top:${touches.clientY}px;`
|
|
||||||
}
|
|
||||||
|
|
||||||
if (touches.clientX > (this.winSize.width / 2)) {
|
|
||||||
style += `right:${this.winSize.width-touches.clientX}px`
|
|
||||||
} else {
|
|
||||||
style += `left:${touches.clientX}px`
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.messageDirection == 2) {
|
|
||||||
if (item.objectName == 'RC:TxtMsg') {
|
|
||||||
this.popButton = ['复制', '删除']
|
|
||||||
} else {
|
|
||||||
this.popButton = ['删除']
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((new Date()).getTime() - item.sentTime > 120 * 1000) {
|
|
||||||
if (item.objectName == 'RC:TxtMsg') {
|
|
||||||
this.popButton = ['复制', '删除']
|
|
||||||
} else {
|
|
||||||
this.popButton = ['删除']
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (item.objectName == 'RC:TxtMsg') {
|
|
||||||
this.popButton = ['复制', '撤回']
|
|
||||||
} else {
|
|
||||||
this.popButton = ['删除']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.popStyle = style
|
|
||||||
this.pickedItem = item
|
|
||||||
this.$nextTick(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.showPop = true;
|
|
||||||
}, 10)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
// 监听群解散的消息,直接跳转到会话列表页面
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
currentTargetId: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad(e) {
|
|
||||||
this.currentTargetId = e.targetId
|
|
||||||
|
|
||||||
uni.$once('onGroupDismiss_' + e.targetId, () => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '当前群已解散'
|
|
||||||
})
|
|
||||||
uni.switchTab({
|
|
||||||
url: '/pages/im/index'
|
|
||||||
})
|
|
||||||
})
|
|
||||||
uni.$once('onGroupRemoveYou_' + e.targetId, () => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '您已被移出群聊'
|
|
||||||
})
|
|
||||||
uni.switchTab({
|
|
||||||
url: '/pages/im/index'
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onUnload() {
|
|
||||||
uni.$off('onGroupDismiss_' + this.currentTargetId)
|
|
||||||
uni.$off('onGroupRemoveYou_' + this.currentTargetId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,338 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="call">
|
|
||||||
<view class="video">
|
|
||||||
<RongCloud-Call-RCUniCallView ref="bigVideoView" :style="bigVideoStyle" class="bigVideoView">
|
|
||||||
</RongCloud-Call-RCUniCallView>
|
|
||||||
|
|
||||||
<movable-area class="movableArea" :style="movableAreaStyle">
|
|
||||||
<movable-view class="movableView" direction="all" :x="50" :y="50" v-if="mediaType == 1 && connected">
|
|
||||||
<RongCloud-Call-RCUniCallView ref="smallVideoView" class="smallVideoView" @click="changeMine">
|
|
||||||
</RongCloud-Call-RCUniCallView>
|
|
||||||
</movable-view>
|
|
||||||
</movable-area>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="status" v-if="!connected">
|
|
||||||
<view class="remote">
|
|
||||||
<u-avatar :src="contact(targetId).portraitUrl" shape="square" :size="avatarSize" bgColor="#fff" />
|
|
||||||
<view><text class="nickname">{{ contact(targetId).name }}</text></view>
|
|
||||||
<view v-if="remoteRinging"><text class="mediaType">等待对方接听</text></view>
|
|
||||||
<view v-if="connected"><text class="mediaType">已接通</text></view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="buttons">
|
|
||||||
<view class="btn" v-if="connected" @click="changeMicrophone">
|
|
||||||
<view class="icon">
|
|
||||||
<u-icon name="mic-off" color="#ffffff" size="30" v-if="micOff" />
|
|
||||||
<u-icon name="mic" color="#ffffff" size="30" v-else />
|
|
||||||
</view>
|
|
||||||
<text class="text">麦克风</text>
|
|
||||||
</view>
|
|
||||||
<view class="btn" @click="hangup">
|
|
||||||
<view class="icon hangup">
|
|
||||||
<u-icon name="close" color="#ffffff" size="25" />
|
|
||||||
</view>
|
|
||||||
<text class="text">挂断</text>
|
|
||||||
</view>
|
|
||||||
<view class="btn" v-if="!connected && this.isCall == false" @click="accept">
|
|
||||||
<view class="icon">
|
|
||||||
<u-icon name="checkmark" color="#ffffff" size="30" />
|
|
||||||
</view>
|
|
||||||
<text class="text">接听</text>
|
|
||||||
</view>
|
|
||||||
<view class="btn" v-if="connected" @click="changeSpeaker">
|
|
||||||
<view class="icon">
|
|
||||||
<u-icon name="volume-off-fill" color="#ffffff" size="27" v-if="volumeOff" />
|
|
||||||
<u-icon name="volume-fill" color="#ffffff" size="27" v-else />
|
|
||||||
</view>
|
|
||||||
<text class="text">扬声器</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index'
|
|
||||||
import * as IMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import utils from '@/utils/index.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
targetId: '',
|
|
||||||
mediaType: 0, // 0 语音 1 视频
|
|
||||||
connected: false,
|
|
||||||
micStatus: false,
|
|
||||||
speStatus: false,
|
|
||||||
remoteRinging: false,
|
|
||||||
ring: null,
|
|
||||||
isCall: false,
|
|
||||||
avatarSize: 96,
|
|
||||||
bigVideoStyle: {},
|
|
||||||
movableAreaStyle: {},
|
|
||||||
// 关闭麦克风
|
|
||||||
micOff: false,
|
|
||||||
// 关闭扬声器
|
|
||||||
volumeOff: false,
|
|
||||||
// 通话时长
|
|
||||||
duration: 0,
|
|
||||||
interval: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad(e) {
|
|
||||||
this.avatarSize = utils.rpx2px(200)
|
|
||||||
this.targetId = e.targetId
|
|
||||||
this.mediaType = e.mediaType
|
|
||||||
this.isCall = Boolean(e.isCall)
|
|
||||||
// 进入页面开启外呼
|
|
||||||
if (this.isCall) {
|
|
||||||
CallLib.startSingleCall(this.targetId, this.mediaType, '');
|
|
||||||
if (this.mediaType == 1) {
|
|
||||||
const session = CallLib.getCurrentCallSession()
|
|
||||||
setTimeout(() => {
|
|
||||||
CallLib.setVideoView(session.mine.userId, this.$refs.bigVideoView.ref, 0, false)
|
|
||||||
}, 200)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 响铃
|
|
||||||
this.startRing()
|
|
||||||
// 监听通话链接状态
|
|
||||||
uni.$once('onCallConnected', this.onCallConnected)
|
|
||||||
uni.$once('onCallDisconnected', this.hangup)
|
|
||||||
uni.$once('onRemoteUserRinging', () => {
|
|
||||||
this.remoteRinging = true
|
|
||||||
})
|
|
||||||
uni.$once('onRemoteUserJoined', () => {
|
|
||||||
this.remoteRinging = false
|
|
||||||
})
|
|
||||||
this.bigVideoStyle = {
|
|
||||||
width: this.windowWidth + 'px',
|
|
||||||
height: this.windowHeight + 'px',
|
|
||||||
}
|
|
||||||
this.movableAreaStyle = {
|
|
||||||
width: this.windowWidth + 'px',
|
|
||||||
height: this.windowHeight + 'px',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
windowWidth() {
|
|
||||||
return uni.getSystemInfoSync().windowWidth
|
|
||||||
},
|
|
||||||
windowHeight() {
|
|
||||||
return uni.getSystemInfoSync().windowHeight
|
|
||||||
},
|
|
||||||
contact() {
|
|
||||||
return function(targetId) {
|
|
||||||
return this.$store.getters.contactInfo(targetId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
afterHangup() {
|
|
||||||
clearInterval(this.interval)
|
|
||||||
const targetId = this.targetId
|
|
||||||
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, {
|
|
||||||
targetId: this.targetId
|
|
||||||
})
|
|
||||||
},
|
|
||||||
changeMicrophone() {
|
|
||||||
this.micOff = !this.micOff
|
|
||||||
CallLib.enableMicrophone(this.micStatus)
|
|
||||||
this.micStatus = !this.micStatus
|
|
||||||
},
|
|
||||||
changeSpeaker() {
|
|
||||||
this.volumeOff = !this.volumeOff
|
|
||||||
CallLib.enableSpeaker(this.speStatus)
|
|
||||||
this.speStatus = !this.speStatus
|
|
||||||
},
|
|
||||||
accept() {
|
|
||||||
CallLib.accept()
|
|
||||||
},
|
|
||||||
onCallConnected() {
|
|
||||||
// 关掉铃声
|
|
||||||
this.stopRing()
|
|
||||||
// 设置链接状态
|
|
||||||
this.connected = true
|
|
||||||
// 视频通话,才开摄像头
|
|
||||||
if (this.mediaType == 1) {
|
|
||||||
const session = CallLib.getCurrentCallSession()
|
|
||||||
setTimeout(() => {
|
|
||||||
CallLib.setVideoView(session.targetId, this.$refs.bigVideoView.ref, 0, false)
|
|
||||||
CallLib.setVideoView(session.mine.userId, this.$refs.smallVideoView.ref, 0, true)
|
|
||||||
}, 200)
|
|
||||||
}
|
|
||||||
this.interval = setInterval(() => {
|
|
||||||
this.duration++
|
|
||||||
}, 1000)
|
|
||||||
},
|
|
||||||
// 切换主屏显示人
|
|
||||||
changeMine() {
|
|
||||||
// if (this.isCall) {
|
|
||||||
// const session = CallLib.getCurrentCallSession()
|
|
||||||
// setTimeout(() => {
|
|
||||||
// CallLib.setVideoView(session.targetId, this.$refs.bigVideoView.ref, 0, false)
|
|
||||||
// CallLib.setVideoView(session.mine.userId, this.$refs.smallVideoView.ref, 0, true)
|
|
||||||
// }, 200)
|
|
||||||
// } else {
|
|
||||||
// const session = CallLib.getCurrentCallSession()
|
|
||||||
// setTimeout(() => {
|
|
||||||
// CallLib.setVideoView(session.targetId, this.$refs.smallVideoView.ref, 0, true)
|
|
||||||
// CallLib.setVideoView(session.mine.userId, this.$refs.bigVideoView.ref, 0, false)
|
|
||||||
// }, 200)
|
|
||||||
// }
|
|
||||||
// this.isCall = !this.isCall
|
|
||||||
},
|
|
||||||
hangup() {
|
|
||||||
CallLib.hangup()
|
|
||||||
this.afterHangup()
|
|
||||||
this.stopRing()
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
this.downRing()
|
|
||||||
uni.navigateBack()
|
|
||||||
}, 200);
|
|
||||||
},
|
|
||||||
toHome() {
|
|
||||||
uni.switchTab({
|
|
||||||
url: '/pages/im/index'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
startRing() {
|
|
||||||
const ring = uni.createInnerAudioContext()
|
|
||||||
this.ring = ring
|
|
||||||
ring.autoplay = true
|
|
||||||
ring.loop = true
|
|
||||||
ring.src = '/static/im/sounds/call-ring.mp3'
|
|
||||||
ring.onEnded(() => {
|
|
||||||
ring.destroy()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
stopRing() {
|
|
||||||
this.ring.stop()
|
|
||||||
},
|
|
||||||
downRing() {
|
|
||||||
const ding = uni.createInnerAudioContext()
|
|
||||||
ding.autoplay = true
|
|
||||||
ding.src = '/static/im/sounds/call-down.mp3'
|
|
||||||
ding.onEnded(() => {
|
|
||||||
ding.destroy()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.call {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
flex-direction: column;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.video {
|
|
||||||
.movableArea {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
|
|
||||||
.movableView {
|
|
||||||
width: 180rpx;
|
|
||||||
height: 320rpx;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.smallVideoView {
|
|
||||||
width: 180rpx;
|
|
||||||
height: 320rpx;
|
|
||||||
background-color: #666;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bigVideoView {
|
|
||||||
background-color: #666;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.status {
|
|
||||||
flex: 1;
|
|
||||||
width: 750rpx;
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
top: 0;
|
|
||||||
|
|
||||||
.remote {
|
|
||||||
flex: 1;
|
|
||||||
width: 750rpx;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
top: 300rpx;
|
|
||||||
|
|
||||||
.mediaType {
|
|
||||||
font-size: 32rpx;
|
|
||||||
color: #aaa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nickname {
|
|
||||||
margin: 30rpx;
|
|
||||||
font-size: 44rpx;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 100rpx;
|
|
||||||
width: 750rpx;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-around;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
background: $main-color;
|
|
||||||
width: 132rpx;
|
|
||||||
height: 132rpx;
|
|
||||||
border-radius: 50%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
&.hangup {
|
|
||||||
background-color: $text-price;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
margin-top: 16rpx;
|
|
||||||
color: #FFFFFF;
|
|
||||||
font-size: 32rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,257 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="chat">
|
|
||||||
<sent-message-bar :conversationType="conversationType" :targetId="targetId" @onSuccess="getNewMessage()" />
|
|
||||||
<view class="shade" @click="hidePop" v-show="showPop">
|
|
||||||
<view class="pop" :style="popStyle" :class="{'show':showPop}">
|
|
||||||
<view v-for="(item, index) in popButton" :key="index" @click="pickerMenu(item)">
|
|
||||||
{{ item }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<!-- chat -->
|
|
||||||
<view class="body">
|
|
||||||
<view class="scroll">
|
|
||||||
<view class="cell" v-for="(message, index) in messages" :key="index">
|
|
||||||
<show-message-cell :message="message" @messageAction="messageAction" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import im from '@/utils/im/index.js'
|
|
||||||
import sentMessageBar from '../components/sentMessageBar'
|
|
||||||
import showMessageCell from '../components/showMessageCell'
|
|
||||||
import utils from '@/utils/index.js'
|
|
||||||
import imBase from '../mixins/imBase.js'
|
|
||||||
import messageActions from '../mixins/messageActions.js'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
mixins: [
|
|
||||||
imBase,
|
|
||||||
messageActions
|
|
||||||
],
|
|
||||||
components: {
|
|
||||||
sentMessageBar,
|
|
||||||
showMessageCell
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
targetId: '',
|
|
||||||
messages: [],
|
|
||||||
conversationType: 1,
|
|
||||||
userInfo: {
|
|
||||||
name: '',
|
|
||||||
userId: '',
|
|
||||||
portraitUrl: ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
latestMessage() {
|
|
||||||
if (this.messages.length) {
|
|
||||||
return this.messages[0]
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
sentTime: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoad(e) {
|
|
||||||
this.targetId = e.targetId
|
|
||||||
this.userInfo = this.$store.getters.contactInfo(this.targetId)
|
|
||||||
uni.setNavigationBarTitle({
|
|
||||||
title: this.contact(this.targetId).name
|
|
||||||
})
|
|
||||||
// 获取消息列表
|
|
||||||
this.getMessageList()
|
|
||||||
// 监听新消息
|
|
||||||
uni.$on('onReceiveMessage_' + this.targetId, (message) => {
|
|
||||||
this.getNewMessage()
|
|
||||||
})
|
|
||||||
// 监听消息已读状态
|
|
||||||
uni.$on('onReadReceiptReceived', (data) => {
|
|
||||||
if (data.targetId == this.targetId) {
|
|
||||||
this.messages = this.messages.map((item) => {
|
|
||||||
if (item.messageDirection == 1 && item.sentStatus == 30 && item.receivedTime <
|
|
||||||
data.messageTime + 1000) {
|
|
||||||
item.sentStatus = 50
|
|
||||||
}
|
|
||||||
return item
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
uni.$on('onRecallMessage_' + this.targetId, (message) => {
|
|
||||||
this.messages = this.messages.map(item => {
|
|
||||||
if (message.messageId == item.messageId) {
|
|
||||||
return message
|
|
||||||
} else {
|
|
||||||
return item
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
uni.$once('onUserDelete_' + this.targetId, () => {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: '好友关系已解除'
|
|
||||||
})
|
|
||||||
uni.switchTab({
|
|
||||||
url: '/pages/im/index'
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onUnload() {
|
|
||||||
uni.$off('onUserDelete_' + this.targetId)
|
|
||||||
uni.$off('onReceiveMessage_' + this.targetId)
|
|
||||||
uni.$off('onRecallMessage_' + this.targetId)
|
|
||||||
uni.$off('onRecallMessage')
|
|
||||||
uni.$off('onReadReceiptReceived')
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getNewMessage() {
|
|
||||||
im.getMessageList(
|
|
||||||
this.conversationType,
|
|
||||||
this.targetId,
|
|
||||||
this.latestMessage.sentTime || 0,
|
|
||||||
1,
|
|
||||||
false,
|
|
||||||
(messages) => {
|
|
||||||
this.messages.unshift(...messages)
|
|
||||||
this.scrollBottom()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 获取消息列表
|
|
||||||
getMessageList() {
|
|
||||||
im.getMessageList(
|
|
||||||
this.conversationType,
|
|
||||||
this.targetId,
|
|
||||||
0,
|
|
||||||
20,
|
|
||||||
true,
|
|
||||||
(messages) => {
|
|
||||||
this.messages = messages
|
|
||||||
this.scrollBottom()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 滚动到底部
|
|
||||||
scrollBottom(type) {
|
|
||||||
if (this.latestMessage) {
|
|
||||||
// 清理当前会话,未读消息数量
|
|
||||||
RongIMLib.clearMessagesUnreadStatus(this.conversationType, this.targetId, this.latestMessage
|
|
||||||
.sentTime)
|
|
||||||
// // 发送消息已读状态给对方
|
|
||||||
RongIMLib.sendReadReceiptMessage(this.conversationType, this.targetId, this.latestMessage.sentTime)
|
|
||||||
// 更新badge提醒数量
|
|
||||||
im.setNotifyBadge()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
/* 窗口 */
|
|
||||||
.chat {
|
|
||||||
background: $window-color;
|
|
||||||
height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
|
|
||||||
.body {
|
|
||||||
overflow: scroll;
|
|
||||||
flex: 1;
|
|
||||||
height: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
|
|
||||||
.scroll {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
justify-content: flex-end;
|
|
||||||
|
|
||||||
.cell {
|
|
||||||
padding: 10rpx 20rpx;
|
|
||||||
|
|
||||||
.time {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #666;
|
|
||||||
margin-bottom: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell-item {
|
|
||||||
display: flex;
|
|
||||||
width: 710rpx;
|
|
||||||
justify-content: flex-start;
|
|
||||||
|
|
||||||
&.left {
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.right {
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
|
|
||||||
.state {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.msg {
|
|
||||||
margin: 0 20rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell-footer {
|
|
||||||
height: 20rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 遮罩 */
|
|
||||||
.shade {
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 999;
|
|
||||||
|
|
||||||
.pop {
|
|
||||||
border-radius: 10rpx;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 101;
|
|
||||||
width: 200rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: 28rpx;
|
|
||||||
text-align: left;
|
|
||||||
color: #333;
|
|
||||||
background-color: #fff;
|
|
||||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
|
|
||||||
line-height: 80rpx;
|
|
||||||
transition: transform 0.15s ease-in-out 0s;
|
|
||||||
user-select: none;
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
transform: scale(0, 0);
|
|
||||||
|
|
||||||
&.show {
|
|
||||||
transform: scale(1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&>view {
|
|
||||||
padding: 0 20rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
user-select: none;
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: #f3f3f3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<!-- 头像 -->
|
<!-- 头像 -->
|
||||||
<view class="user" @click="$Router.back()">
|
<view class="user" @click="$Router.back()">
|
||||||
<u-icon name="arrow-left" color="#525252" size="22" class="downIcon" :bold="true" />
|
<u-icon name="arrow-left" color="#525252" size="22" class="downIcon" :bold="true" />
|
||||||
<!-- <u-image class="avatar" width="90rpx" height="90rpx" :src="user.avatar ? user.avatar : require('../../static/imgs/avatar.png')" :lazy-load="true" shape="circle" />
|
<!-- <u-image class="avatar" width="90rpx" height="90rpx" :src="user.avatar ? user.avatar : require('@/static/imgs/avatar.png')" :lazy-load="true" shape="circle" />
|
||||||
<view class="nickname">{{user.nickname}}</view> -->
|
<view class="nickname">{{user.nickname}}</view> -->
|
||||||
<!-- <u-icon name="arrow-down-fill" color="#525252" size="10" class="downIcon" :bold="true" space="1"/> -->
|
<!-- <u-icon name="arrow-down-fill" color="#525252" size="10" class="downIcon" :bold="true" space="1"/> -->
|
||||||
</view>
|
</view>
|
||||||
@@ -42,7 +42,6 @@
|
|||||||
<!-- 体重管理模块 -->
|
<!-- 体重管理模块 -->
|
||||||
<view class="weight-manage">
|
<view class="weight-manage">
|
||||||
<!-- 体重管理 -->
|
<!-- 体重管理 -->
|
||||||
<!-- @click="$Router.push({name:'EssentialInfo'})" -->
|
|
||||||
<view class="manage">体重管理</view>
|
<view class="manage">体重管理</view>
|
||||||
<!-- 单位:公斤 -->
|
<!-- 单位:公斤 -->
|
||||||
<u-icon class="eye" name="eye" color="#fff" size="14" :bold="true" label="单位 : 公斤" labelPos="left" labelSize="12" labelColor="#fff" space="6" />
|
<u-icon class="eye" name="eye" color="#fff" size="14" :bold="true" label="单位 : 公斤" labelPos="left" labelSize="12" labelColor="#fff" space="6" />
|
||||||
@@ -81,13 +80,13 @@
|
|||||||
</view>
|
</view>
|
||||||
<!-- 健康测评 -->
|
<!-- 健康测评 -->
|
||||||
<u-image
|
<u-image
|
||||||
:src="banner.cover || require('../../static/imgs/health1.png')"
|
:src="banner.cover || require('@/static/imgs/health1.png')"
|
||||||
class="eval-img"
|
class="eval-img"
|
||||||
@click="$Router.push({ name: 'EvaluationList' })"
|
@click="$Router.push({ name: 'EvaluationList' })"
|
||||||
:lazy-load="true"
|
:lazy-load="true"
|
||||||
radius="10rpx"
|
radius="10rpx"
|
||||||
mode="widthFix"
|
|
||||||
width="100%"
|
width="100%"
|
||||||
|
height="300rpx"
|
||||||
/>
|
/>
|
||||||
<!-- 健康记录 -->
|
<!-- 健康记录 -->
|
||||||
<view class="title">健康记录</view>
|
<view class="title">健康记录</view>
|
||||||
@@ -101,7 +100,7 @@
|
|||||||
千卡
|
千卡
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<u-image :src="require('../../static/imgs/eat.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="140rpx" />
|
<u-image class="h-icon" :src="require('@/static/imgs/eat.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="150rpx" height="150rpx"/>
|
||||||
</view>
|
</view>
|
||||||
<view class="health-2">
|
<view class="health-2">
|
||||||
<view class="health" @click="$Router.push({ name: 'Drink' })">
|
<view class="health" @click="$Router.push({ name: 'Drink' })">
|
||||||
@@ -115,7 +114,7 @@
|
|||||||
毫升
|
毫升
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<u-image :src="require('../../static/imgs/drink.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="110rpx" class="h-icon" />
|
<u-image :src="require('@/static/imgs/drink.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="120rpx" class="h-icon" height="120rpx" />
|
||||||
</view>
|
</view>
|
||||||
<view class="health" @click="$Router.push({ name: 'Weight' })">
|
<view class="health" @click="$Router.push({ name: 'Weight' })">
|
||||||
<view>
|
<view>
|
||||||
@@ -127,18 +126,18 @@
|
|||||||
公斤
|
公斤
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<u-image :src="require('../../static/imgs/weight.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="140rpx" class="h-icon" />
|
<u-image :src="require('@/static/imgs/weight.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="140rpx" height="140rpx" class="h-icon" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 营养管理 -->
|
<!-- 营养管理 -->
|
||||||
<view class="title">营养管理</view>
|
<view class="title">营养管理</view>
|
||||||
<view class="nutrition">
|
<view class="nutrition">
|
||||||
<view class="--item" @click="$Router.push({ name: 'VipFoods' })">
|
<view class="--item" @click="$Router.push({ name: 'VipFoods' })">
|
||||||
<u-icon :name="require('../../static/icon/vip.png')" size="20" :bold="true" label="会员专享食谱" labelPos="right" labelSize="16" labelColor="#525252" space="10" />
|
<u-icon :name="require('@/static/icon/vip.png')" size="20" :bold="true" label="会员专享食谱" labelPos="right" labelSize="16" labelColor="#525252" space="10" />
|
||||||
<u-icon name="arrow-right" color="#999" />
|
<u-icon name="arrow-right" color="#999" />
|
||||||
</view>
|
</view>
|
||||||
<view class="--item mt20" @click="$Router.push({ name: 'topicIndex' })">
|
<view class="--item mt20" @click="$Router.push({ name: 'topicIndex' })">
|
||||||
<u-icon :name="require('../../static/icon/helper.png')" size="20" :bold="true" label="营养小助手" labelPos="right" labelSize="16" labelColor="#525252" space="10" />
|
<u-icon :name="require('@/static/icon/helper.png')" size="20" :bold="true" label="营养小助手" labelPos="right" labelSize="16" labelColor="#525252" space="10" />
|
||||||
<u-icon name="arrow-right" color="#999" />
|
<u-icon name="arrow-right" color="#999" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -149,7 +148,7 @@
|
|||||||
<view class="search" >
|
<view class="search" >
|
||||||
<!-- 头像 -->
|
<!-- 头像 -->
|
||||||
<view class="user" @click="$Router.back()">
|
<view class="user" @click="$Router.back()">
|
||||||
<!-- <u-image class="avatar" width="90rpx" height="90rpx" :src="require('../../static/imgs/avatar.png')" :lazy-load="true" shape="circle" />
|
<!-- <u-image class="avatar" width="90rpx" height="90rpx" :src="require('@/static/imgs/avatar.png')" :lazy-load="true" shape="circle" />
|
||||||
<u-icon name="arrow-down-fill" color="#525252" size="10" class="downIcon" :bold="true" space="1" /> -->
|
<u-icon name="arrow-down-fill" color="#525252" size="10" class="downIcon" :bold="true" space="1" /> -->
|
||||||
<u-icon name="arrow-left" color="#525252" size="22" class="downIcon" :bold="true"/>
|
<u-icon name="arrow-left" color="#525252" size="22" class="downIcon" :bold="true"/>
|
||||||
</view>
|
</view>
|
||||||
@@ -201,7 +200,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 健康测评 -->
|
<!-- 健康测评 -->
|
||||||
<u-image :src="banner.cover || require('../../static/imgs/health1.png')" class="eval-img" @click="Login" :lazy-load="true" radius="10rpx" mode="widthFix" width="100%" />
|
<u-image :src="banner.cover || require('@/static/imgs/health1.png')" class="eval-img" @click="Login" :lazy-load="true" radius="10rpx" mode="widthFix" width="100%" />
|
||||||
<!-- 健康记录 -->
|
<!-- 健康记录 -->
|
||||||
<view class="title">健康记录</view>
|
<view class="title">健康记录</view>
|
||||||
<view class="health" @click="Login">
|
<view class="health" @click="Login">
|
||||||
@@ -210,7 +209,7 @@
|
|||||||
<!-- <view class="h-date">--</view> -->
|
<!-- <view class="h-date">--</view> -->
|
||||||
<view class="h-eat"><span>--</span></view>
|
<view class="h-eat"><span>--</span></view>
|
||||||
</view>
|
</view>
|
||||||
<u-image :src="require('../../static/imgs/eat.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="140rpx" />
|
<u-image :src="require('@/static/imgs/eat.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="140rpx" />
|
||||||
</view>
|
</view>
|
||||||
<view class="health-2">
|
<view class="health-2">
|
||||||
<view class="health" @click="Login">
|
<view class="health" @click="Login">
|
||||||
@@ -219,7 +218,7 @@
|
|||||||
<!-- <view class="h-date">--</view> -->
|
<!-- <view class="h-date">--</view> -->
|
||||||
<view class="h-eat"><span>--</span></view>
|
<view class="h-eat"><span>--</span></view>
|
||||||
</view>
|
</view>
|
||||||
<u-image :src="require('../../static/imgs/drink.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="110rpx" class="h-icon" />
|
<u-image :src="require('@/static/imgs/drink.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="110rpx" class="h-icon" />
|
||||||
</view>
|
</view>
|
||||||
<view class="health" @click="Login">
|
<view class="health" @click="Login">
|
||||||
<view>
|
<view>
|
||||||
@@ -227,18 +226,18 @@
|
|||||||
<!-- <view class="h-date">--</view> -->
|
<!-- <view class="h-date">--</view> -->
|
||||||
<view class="h-eat"><span>--</span></view>
|
<view class="h-eat"><span>--</span></view>
|
||||||
</view>
|
</view>
|
||||||
<u-image :src="require('../../static/imgs/weight.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="140rpx" class="h-icon" />
|
<u-image :src="require('@/static/imgs/weight.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="140rpx" class="h-icon" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 营养管理 -->
|
<!-- 营养管理 -->
|
||||||
<view class="title">营养管理</view>
|
<view class="title">营养管理</view>
|
||||||
<view class="nutrition">
|
<view class="nutrition">
|
||||||
<view class="--item" @click="Login">
|
<view class="--item" @click="Login">
|
||||||
<u-icon :name="require('../../static/icon/vip.png')" size="24" :bold="true" label="会员专享食谱" labelPos="right" labelSize="17" labelColor="#525252" space="10" />
|
<u-icon :name="require('@/static/icon/vip.png')" size="24" :bold="true" label="会员专享食谱" labelPos="right" labelSize="17" labelColor="#525252" space="10" />
|
||||||
<u-icon name="arrow-right" color="#999" />
|
<u-icon name="arrow-right" color="#999" />
|
||||||
</view>
|
</view>
|
||||||
<view class="--item mt20" @click="Login">
|
<view class="--item mt20" @click="Login">
|
||||||
<u-icon :name="require('../../static/icon/helper.png')" size="24" :bold="true" label="营养小助手" labelPos="right" labelSize="17" labelColor="#525252" space="10" />
|
<u-icon :name="require('@/static/icon/helper.png')" size="24" :bold="true" label="营养小助手" labelPos="right" labelSize="17" labelColor="#525252" space="10" />
|
||||||
<u-icon name="arrow-right" color="#999" />
|
<u-icon name="arrow-right" color="#999" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -249,7 +248,7 @@
|
|||||||
<view class="search" >
|
<view class="search" >
|
||||||
<!-- 头像 -->
|
<!-- 头像 -->
|
||||||
<view class="user" @click='$Router.back()'>
|
<view class="user" @click='$Router.back()'>
|
||||||
<!-- <u-image class="avatar" width="90rpx" height="90rpx" :src="require('../../static/imgs/avatar.png')" :lazy-load="true" shape="circle" />
|
<!-- <u-image class="avatar" width="90rpx" height="90rpx" :src="require('@/static/imgs/avatar.png')" :lazy-load="true" shape="circle" />
|
||||||
<u-icon name="arrow-down-fill" color="#525252" size="10" class="downIcon" :bold="true" space="1" /> -->
|
<u-icon name="arrow-down-fill" color="#525252" size="10" class="downIcon" :bold="true" space="1" /> -->
|
||||||
<u-icon name="arrow-left" color="#525252" size="22" class="downIcon" :bold="true"/>
|
<u-icon name="arrow-left" color="#525252" size="22" class="downIcon" :bold="true"/>
|
||||||
</view>
|
</view>
|
||||||
@@ -302,7 +301,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<!-- 健康测评 -->
|
<!-- 健康测评 -->
|
||||||
<u-image
|
<u-image
|
||||||
:src="banner.cover || require('../../static/imgs/health1.png')"
|
:src="banner.cover || require('@/static/imgs/health1.png')"
|
||||||
class="eval-img"
|
class="eval-img"
|
||||||
@click="toCreateInfo"
|
@click="toCreateInfo"
|
||||||
:lazy-load="true"
|
:lazy-load="true"
|
||||||
@@ -318,7 +317,7 @@
|
|||||||
<!-- <view class="h-date">--</view> -->
|
<!-- <view class="h-date">--</view> -->
|
||||||
<view class="h-eat"><span>--</span></view>
|
<view class="h-eat"><span>--</span></view>
|
||||||
</view>
|
</view>
|
||||||
<u-image :src="require('../../static/imgs/eat.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="140rpx" />
|
<u-image :src="require('@/static/imgs/eat.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="140rpx" />
|
||||||
</view>
|
</view>
|
||||||
<view class="health-2">
|
<view class="health-2">
|
||||||
<view class="health" @click="toCreateInfo">
|
<view class="health" @click="toCreateInfo">
|
||||||
@@ -327,7 +326,7 @@
|
|||||||
<!-- <view class="h-date">--</view> -->
|
<!-- <view class="h-date">--</view> -->
|
||||||
<view class="h-eat"><span>--</span></view>
|
<view class="h-eat"><span>--</span></view>
|
||||||
</view>
|
</view>
|
||||||
<u-image :src="require('../../static/imgs/drink.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="110rpx" class="h-icon" />
|
<u-image :src="require('@/static/imgs/drink.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="110rpx" class="h-icon" />
|
||||||
</view>
|
</view>
|
||||||
<view class="health" @click="toCreateInfo">
|
<view class="health" @click="toCreateInfo">
|
||||||
<view>
|
<view>
|
||||||
@@ -335,18 +334,18 @@
|
|||||||
<!-- <view class="h-date">--</view> -->
|
<!-- <view class="h-date">--</view> -->
|
||||||
<view class="h-eat"><span>--</span></view>
|
<view class="h-eat"><span>--</span></view>
|
||||||
</view>
|
</view>
|
||||||
<u-image :src="require('../../static/imgs/weight.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="140rpx" class="h-icon" />
|
<u-image :src="require('@/static/imgs/weight.png')" :lazy-load="true" radius="10rpx" mode="widthFix" width="140rpx" class="h-icon" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 营养管理 -->
|
<!-- 营养管理 -->
|
||||||
<view class="title">营养管理</view>
|
<view class="title">营养管理</view>
|
||||||
<view class="nutrition">
|
<view class="nutrition">
|
||||||
<view class="--item" @click="toCreateInfo">
|
<view class="--item" @click="toCreateInfo">
|
||||||
<u-icon :name="require('../../static/icon/vip.png')" size="24" :bold="true" label="会员专享食谱" labelPos="right" labelSize="17" labelColor="#525252" space="10" />
|
<u-icon :name="require('@/static/icon/vip.png')" size="24" :bold="true" label="会员专享食谱" labelPos="right" labelSize="17" labelColor="#525252" space="10" />
|
||||||
<u-icon name="arrow-right" color="#999" />
|
<u-icon name="arrow-right" color="#999" />
|
||||||
</view>
|
</view>
|
||||||
<view class="--item mt20" @click="toCreateInfo">
|
<view class="--item mt20" @click="toCreateInfo">
|
||||||
<u-icon :name="require('../../static/icon/helper.png')" size="24" :bold="true" label="营养小助手" labelPos="right" labelSize="17" labelColor="#525252" space="10" />
|
<u-icon :name="require('@/static/icon/helper.png')" size="24" :bold="true" label="营养小助手" labelPos="right" labelSize="17" labelColor="#525252" space="10" />
|
||||||
<u-icon name="arrow-right" color="#999" />
|
<u-icon name="arrow-right" color="#999" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -498,7 +497,7 @@ export default {
|
|||||||
// 体重管理
|
// 体重管理
|
||||||
.weight-manage {
|
.weight-manage {
|
||||||
height: 288rpx;
|
height: 288rpx;
|
||||||
background-image: url(../../static/imgs/banner-bg.png);
|
background-image: url(@/static/imgs/banner-bg.png);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
border-radius: $radius + 1;
|
border-radius: $radius + 1;
|
||||||
|
|||||||
@@ -98,11 +98,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<!-- 功能块 -->
|
<!-- 功能块 -->
|
||||||
<view class="btns-box">
|
<view class="btns-box">
|
||||||
<view class="btns-box-item" @click="onWallet">
|
<!-- 开通钱包方法 onWallet -->
|
||||||
<image class="icon" src="@/static/user/userIcon_00.png" mode="widthFix" />
|
|
||||||
ZH钱包
|
|
||||||
<uni-icons class="forward" type="forward" color="#999" />
|
|
||||||
</view>
|
|
||||||
<view class="btns-box-item" @click="onFiles">
|
<view class="btns-box-item" @click="onFiles">
|
||||||
<image class="icon" src="@/static/user/userIcon_02.png" mode="widthFix" />
|
<image class="icon" src="@/static/user/userIcon_02.png" mode="widthFix" />
|
||||||
健康档案
|
健康档案
|
||||||
@@ -133,7 +129,6 @@
|
|||||||
info
|
info
|
||||||
} from '@/apis/interfaces/user';
|
} from '@/apis/interfaces/user';
|
||||||
import userAuth from '@/public/userAuth';
|
import userAuth from '@/public/userAuth';
|
||||||
import im from '@/utils/im/index.js'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -12,10 +12,6 @@ import {
|
|||||||
keyAuth
|
keyAuth
|
||||||
} from '../apis/interfaces/auth'
|
} from '../apis/interfaces/auth'
|
||||||
import store from '../store'
|
import store from '../store'
|
||||||
import {
|
|
||||||
getImToken
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
import im from '@/utils/im/index.js'
|
|
||||||
|
|
||||||
class userAuth {
|
class userAuth {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|||||||
BIN
static/.DS_Store
vendored
BIN
static/.DS_Store
vendored
Binary file not shown.
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 |
BIN
static/imgs/tel-call.png
Normal file
BIN
static/imgs/tel-call.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
import im from './modules/im.js'
|
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|
||||||
@@ -38,8 +37,5 @@ export default new Vuex.Store({
|
|||||||
setRefresh(state, value) {
|
setRefresh(state, value) {
|
||||||
state.refresh = value
|
state.refresh = value
|
||||||
}
|
}
|
||||||
},
|
|
||||||
modules: {
|
|
||||||
im
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -41,20 +41,17 @@ 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,
|
||||||
name: contactInfo.name,
|
name: contactInfo.name,
|
||||||
portraitUrl: contactInfo.portraitUrl
|
portraitUrl: contactInfo.portraitUrl
|
||||||
}
|
}
|
||||||
<<<<<<< HEAD
|
|
||||||
}
|
|
||||||
=======
|
|
||||||
},
|
},
|
||||||
setContactRemark(state, contactInfo) {
|
setContactRemark(state, contactInfo) {
|
||||||
Vue.set(state.contacts, contactInfo.targetId, contactInfo)
|
Vue.set(state.contacts, contactInfo.targetId, contactInfo)
|
||||||
}
|
}
|
||||||
>>>>>>> 013c030963aef06a00ac33d5f767cbd97ef2ceac
|
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setContactRemark({
|
setContactRemark({
|
||||||
@@ -73,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)
|
||||||
},
|
},
|
||||||
// 载入好友信息
|
// 载入好友信息
|
||||||
|
|||||||
BIN
utils/im/.DS_Store
vendored
BIN
utils/im/.DS_Store
vendored
Binary file not shown.
@@ -1,16 +0,0 @@
|
|||||||
// 获取新好友申请数量
|
|
||||||
const getPendingCount = (callback) => {
|
|
||||||
RongIMLib.getConversationList([RongIMLib.ConversationType.SYSTEM], 100, 0, (res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
const pendingCount = res.conversations.filter((item) => {
|
|
||||||
return item.objectName == RongIMLib.ObjectName.ContactNotification
|
|
||||||
}).length
|
|
||||||
|
|
||||||
callback(pendingCount)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
getPendingCount
|
|
||||||
}
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index'
|
|
||||||
import store from '@/store/index.js'
|
|
||||||
import message from './message.js'
|
|
||||||
import listeners from './listeners.js'
|
|
||||||
import {
|
|
||||||
getFriends,
|
|
||||||
getUserInfo,
|
|
||||||
getImToken,
|
|
||||||
getMyGroups
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
import {
|
|
||||||
contactModel
|
|
||||||
} from './models.js'
|
|
||||||
|
|
||||||
const initIm = (KEY) => {
|
|
||||||
RongIMLib.init(KEY)
|
|
||||||
CallLib.init()
|
|
||||||
listeners.imLibListeners()
|
|
||||||
listeners.callLibListeners()
|
|
||||||
// 初始化的时候 自动链接
|
|
||||||
if (store.getters.getToken !== '') {
|
|
||||||
getImToken().then(res => {
|
|
||||||
connect(res.token, res.userInfo, (res) => {
|
|
||||||
console.log('IM.CONNECT', res);
|
|
||||||
// 发布全局事件,有新消息,刷新会话列表
|
|
||||||
uni.$emit('onReceiveMessage')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const setNotifyBadge = () => {
|
|
||||||
// 获取未读消息数量
|
|
||||||
RongIMLib.getTotalUnreadCount(({
|
|
||||||
code,
|
|
||||||
count
|
|
||||||
}) => {
|
|
||||||
if (code === 0) {
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
plus.runtime.setBadgeNumber(count)
|
|
||||||
// #endif
|
|
||||||
if (count > 0) {
|
|
||||||
uni.setTabBarBadge({
|
|
||||||
index: 3,
|
|
||||||
text: String(count > 99 ? '99+' : count)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
uni.removeTabBarBadge({
|
|
||||||
index: 3
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 连接IM服务
|
|
||||||
* @param {string} token token
|
|
||||||
* @param {object} userInfo {targetId: string, name: string, portraitUrl: string}
|
|
||||||
*/
|
|
||||||
const connect = (token, userInfo, callback) => {
|
|
||||||
RongIMLib.connect(token, res => {
|
|
||||||
callback(res)
|
|
||||||
// 更新个人信息
|
|
||||||
store.dispatch('setSenderInfo', userInfo)
|
|
||||||
// 设置未读消息数量
|
|
||||||
setNotifyBadge()
|
|
||||||
// 首次运行获取好友列表
|
|
||||||
const FK = 'ZH_CONTACT_' + userInfo.targetId
|
|
||||||
|
|
||||||
uni.getStorage({
|
|
||||||
key: FK,
|
|
||||||
success: () => {
|
|
||||||
contactModel.find((err, results) => {
|
|
||||||
results.map(item => {
|
|
||||||
store.dispatch('launchContact', item)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
fail: () => {
|
|
||||||
// 程序是首次运行,初始化加载好友和群组信息
|
|
||||||
Promise.all([getFriends(), getMyGroups()]).then(result => {
|
|
||||||
result.map(contacts => {
|
|
||||||
contacts.map(item => {
|
|
||||||
store.dispatch('initContact', item)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
uni.setStorageSync(FK, userInfo.targetId)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 断开链接
|
|
||||||
*/
|
|
||||||
const disconnect = () => {
|
|
||||||
RongIMLib.disconnect()
|
|
||||||
// 移除提醒数量
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
plus.runtime.setBadgeNumber(0)
|
|
||||||
// #endif
|
|
||||||
uni.removeTabBarBadge({
|
|
||||||
index: 3
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 播放状态
|
|
||||||
let tipState = false
|
|
||||||
|
|
||||||
const triTone = () => {
|
|
||||||
if (tipState == false) {
|
|
||||||
const innerAudioContext = uni.createInnerAudioContext()
|
|
||||||
innerAudioContext.autoplay = true
|
|
||||||
innerAudioContext.src = '/utils/im/sounds/new-msg.mp3'
|
|
||||||
innerAudioContext.onPlay(() => {
|
|
||||||
tipState = true
|
|
||||||
})
|
|
||||||
innerAudioContext.onEnded(() => {
|
|
||||||
tipState = false
|
|
||||||
innerAudioContext.destroy()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
initIm,
|
|
||||||
connect,
|
|
||||||
disconnect,
|
|
||||||
setNotifyBadge,
|
|
||||||
...message
|
|
||||||
}
|
|
||||||
@@ -1,217 +0,0 @@
|
|||||||
import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index'
|
|
||||||
import * as IMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
import store from '@/store/index.js'
|
|
||||||
import im from "@/utils/im/index.js"
|
|
||||||
import utils from '../index.js'
|
|
||||||
import {
|
|
||||||
getUserInfo
|
|
||||||
} from '@/apis/interfaces/im.js'
|
|
||||||
|
|
||||||
// 维护消息列表,检查是否需要通知声音,设置新消息提醒的数量
|
|
||||||
const onReceiveMessage = (message) => {
|
|
||||||
IMLib.getConversationNotificationStatus(message.conversationType, message.targetId, ({
|
|
||||||
code,
|
|
||||||
status
|
|
||||||
}) => {
|
|
||||||
if (code === 0) {
|
|
||||||
if (status) {
|
|
||||||
// triTone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
im.setNotifyBadge()
|
|
||||||
// 发布全局事件,有新消息,刷新会话列表
|
|
||||||
uni.$emit('onReceiveMessage', message)
|
|
||||||
// 这个是为了更新消息列表页的
|
|
||||||
uni.$emit('onReceiveMessage_' + message.targetId, message)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检测联系人信息,不存在的时候,从服务端获取
|
|
||||||
const checkContactExists = (message) => {
|
|
||||||
if (!store.getters.contactIsExist(message.targetId)) {
|
|
||||||
getUserInfo(message.targetId).then(res => {
|
|
||||||
console.log('targetId', res);
|
|
||||||
store.dispatch('initContact', res)
|
|
||||||
}).catch(err => {
|
|
||||||
console.error('getUserInfo ERR', err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (!store.getters.contactIsExist(message.senderUserId)) {
|
|
||||||
getUserInfo(message.senderUserId).then(res => {
|
|
||||||
console.log('senderUserId', message.senderUserId, res);
|
|
||||||
store.dispatch('initContact', res)
|
|
||||||
}).catch(err => {
|
|
||||||
console.error('getUserInfo ERR', err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 允许通知的消息类型,触发更新消息列表操作,提示音
|
|
||||||
const notifyMsgTypes = [
|
|
||||||
IMLib.ObjectName.Text,
|
|
||||||
IMLib.ObjectName.File,
|
|
||||||
IMLib.ObjectName.Image,
|
|
||||||
IMLib.ObjectName.GIF,
|
|
||||||
IMLib.ObjectName.Location,
|
|
||||||
IMLib.ObjectName.Voice,
|
|
||||||
IMLib.ObjectName.HQVoice,
|
|
||||||
IMLib.ObjectName.Sight
|
|
||||||
]
|
|
||||||
|
|
||||||
const imLibListeners = () => {
|
|
||||||
// 添加连接状态监听函数
|
|
||||||
IMLib.addConnectionStatusListener((res) => {
|
|
||||||
console.error('连接状态监听', res.data.status)
|
|
||||||
uni.$emit('onConnectionStatusChange', res.data.status)
|
|
||||||
})
|
|
||||||
// 添加消息监听函数
|
|
||||||
IMLib.addReceiveMessageListener((res) => {
|
|
||||||
const message = res.data.message
|
|
||||||
console.error('[收到消息]', message)
|
|
||||||
checkContactExists(message)
|
|
||||||
if (utils.inArray(message.objectName, notifyMsgTypes)) {
|
|
||||||
onReceiveMessage(message)
|
|
||||||
} else if (message.objectName === IMLib.ObjectName.ProfileNotification) {
|
|
||||||
uni.$emit('onUpdateProfile_' + message.targetId)
|
|
||||||
// 更新联系人信息
|
|
||||||
store.dispatch('updateContact', JSON.parse(message.content.data))
|
|
||||||
// 调用完更新之后,删除这条消息
|
|
||||||
IMLib.deleteMessagesByIds([message.messageId])
|
|
||||||
} else if (message.objectName === IMLib.ObjectName.ContactNotification) {
|
|
||||||
if (message.content.operation === 'Request') {
|
|
||||||
// 触发一个新好友的通知事件,【会话列表,通讯录,新朋友】页面
|
|
||||||
uni.$emit('onNewContactConversation', message)
|
|
||||||
uni.$emit('onNewContactFriends', message)
|
|
||||||
uni.$emit('onNewContactPendings', message)
|
|
||||||
} else if (message.content.operation === 'Delete') {
|
|
||||||
IMLib.cleanHistoryMessages(1, message.targetId, message.sentTime, false)
|
|
||||||
// 解散了就删了吧
|
|
||||||
IMLib.removeConversation(1, message.targetId)
|
|
||||||
// 刷新会话列表
|
|
||||||
uni.$emit('onUserDelete_' + message.targetId)
|
|
||||||
uni.$emit('onReceiveMessage', message)
|
|
||||||
}
|
|
||||||
} else if (message.objectName === IMLib.ObjectName.GroupNotification) {
|
|
||||||
// 这个是为了更新消息列表页的
|
|
||||||
uni.$emit('onReceiveMessage_' + message.targetId, message)
|
|
||||||
// 解散群
|
|
||||||
if (message.content.operation === 'Dismiss') {
|
|
||||||
IMLib.cleanHistoryMessages(3, message.targetId, message.sentTime,
|
|
||||||
false)
|
|
||||||
// 解散了就删了吧
|
|
||||||
IMLib.removeConversation(3, message.targetId)
|
|
||||||
// 发布群解散的消息
|
|
||||||
uni.$emit('onGroupDismiss')
|
|
||||||
uni.$emit('onGroupDismiss_' + message.targetId)
|
|
||||||
} else if (message.content.operation === 'REMOVE') {
|
|
||||||
// 要判断是否当前用户,然后把当前用户踢出到主页去, 删除聊天记录,会话列表
|
|
||||||
if (message.content.extra == store.getters.sender.userId) {
|
|
||||||
IMLib.cleanHistoryMessages(3, message.targetId, message.sentTime,
|
|
||||||
false)
|
|
||||||
// 解散了就删了吧
|
|
||||||
IMLib.removeConversation(3, message.targetId)
|
|
||||||
// 为了更新群列表
|
|
||||||
uni.$emit('onGroupDismiss')
|
|
||||||
uni.$emit('onGroupRemoveYou_' + message.targetId)
|
|
||||||
}
|
|
||||||
uni.$emit('onReceiveMessage_' + message.targetId, message)
|
|
||||||
// 这个是为了更新消息列表页的
|
|
||||||
}
|
|
||||||
// 触发刷新会话列表
|
|
||||||
uni.$emit('onReceiveMessage', message)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// 监听私聊消息已读回执
|
|
||||||
IMLib.addReadReceiptReceivedListener(({
|
|
||||||
data
|
|
||||||
}) => {
|
|
||||||
console.error("监听私聊消息已读回执: ", data);
|
|
||||||
uni.$emit('onReadReceiptReceived', data)
|
|
||||||
})
|
|
||||||
// 监听消息撤回操作
|
|
||||||
IMLib.addRecallMessageListener(({
|
|
||||||
data
|
|
||||||
}) => {
|
|
||||||
IMLib.getMessage(data.messageId, ({
|
|
||||||
message
|
|
||||||
}) => {
|
|
||||||
console.error("消息撤回: ", message);
|
|
||||||
im.setNotifyBadge()
|
|
||||||
uni.$emit('onReceiveMessage', message)
|
|
||||||
uni.$emit('onRecallMessage_' + message.targetId, message)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
// 监听需要群聊消息回执
|
|
||||||
IMLib.addReceiptRequestListener(({
|
|
||||||
data
|
|
||||||
}) => {
|
|
||||||
uni.$emit('onReceiptRequest', data)
|
|
||||||
})
|
|
||||||
// 群消息已读的回执
|
|
||||||
IMLib.addReceiptResponseListener(({
|
|
||||||
data
|
|
||||||
}) => {
|
|
||||||
// 获取本地消息
|
|
||||||
IMLib.getMessageByUId(data.messageUId, ({
|
|
||||||
message
|
|
||||||
}) => {
|
|
||||||
const readers = Object.keys(data.users).length
|
|
||||||
const extra = JSON.stringify({
|
|
||||||
readers
|
|
||||||
})
|
|
||||||
// 在消息的扩展数据中,设置已读数量
|
|
||||||
IMLib.setMessageExtra(message.messageId, extra, (result) => {
|
|
||||||
message.extra = extra
|
|
||||||
uni.$emit('onReceiptResponse', message)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const callLibListeners = () => {
|
|
||||||
// 音视频通话相关的
|
|
||||||
// 监听通话呼入
|
|
||||||
CallLib.onCallReceived(({
|
|
||||||
data
|
|
||||||
}) => {
|
|
||||||
console.error('onCallReceived');
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/im/private/call?targetId=' + data.targetId + '&mediaType=' +
|
|
||||||
data.mediaType
|
|
||||||
})
|
|
||||||
})
|
|
||||||
// 通话建立成功
|
|
||||||
CallLib.onCallConnected(() => {
|
|
||||||
uni.$emit('onCallConnected')
|
|
||||||
})
|
|
||||||
// 外呼
|
|
||||||
CallLib.onCallOutgoing((res) => {
|
|
||||||
console.error('onCallOutgoing', res);
|
|
||||||
uni.$emit('onCallOutgoing')
|
|
||||||
})
|
|
||||||
// 远端响铃
|
|
||||||
CallLib.onRemoteUserRinging((res) => {
|
|
||||||
console.error('onRemoteUserRinging', res);
|
|
||||||
uni.$emit('onRemoteUserRinging')
|
|
||||||
})
|
|
||||||
// 远端加入
|
|
||||||
CallLib.onRemoteUserJoined((res) => {
|
|
||||||
console.error('远端接听');
|
|
||||||
uni.$emit('onRemoteUserJoined')
|
|
||||||
})
|
|
||||||
// 断开链接
|
|
||||||
CallLib.onCallDisconnected((res) => {
|
|
||||||
console.error('断开链接', res)
|
|
||||||
uni.$emit('onCallDisconnected')
|
|
||||||
})
|
|
||||||
// 远端挂断
|
|
||||||
CallLib.onRemoteUserLeft((res) => {
|
|
||||||
console.error('远端离开', res)
|
|
||||||
uni.$emit('onRemoteUserLeft')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
imLibListeners,
|
|
||||||
callLibListeners
|
|
||||||
}
|
|
||||||
@@ -1,239 +0,0 @@
|
|||||||
import store from '@/store/index.js'
|
|
||||||
|
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
|
||||||
|
|
||||||
const getMessageList = (conversationType, targetId, timeStamp, count, isForward, callback) => {
|
|
||||||
// 获取消息列表 https://doc.rongcloud.cn/imserver/server/v1/message/objectname#objectName
|
|
||||||
const objectNames = [
|
|
||||||
'RC:TxtMsg',
|
|
||||||
'RC:VcMsg',
|
|
||||||
'RC:HQVCMsg',
|
|
||||||
'RC:ImgMsg',
|
|
||||||
'RC:GIFMsg',
|
|
||||||
'RC:ImgTextMsg',
|
|
||||||
'RC:FileMsg',
|
|
||||||
'RC:LBSMsg',
|
|
||||||
'RC:SightMsg',
|
|
||||||
'RC:ReferenceMsg',
|
|
||||||
'RC:CombineMsg',
|
|
||||||
'RC:GrpNtf',
|
|
||||||
'RC:InfoNtf',
|
|
||||||
'RC:RcNtf'
|
|
||||||
]
|
|
||||||
|
|
||||||
RongIMLib.getHistoryMessagesByTimestamp(
|
|
||||||
conversationType,
|
|
||||||
targetId,
|
|
||||||
objectNames,
|
|
||||||
timeStamp,
|
|
||||||
count,
|
|
||||||
isForward,
|
|
||||||
({
|
|
||||||
code,
|
|
||||||
messages
|
|
||||||
}) => {
|
|
||||||
if (code === 0) {
|
|
||||||
callback(messages)
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'error',
|
|
||||||
title: code
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取好友申请列表
|
|
||||||
const getPendingList = (callback, total) => {
|
|
||||||
total = total || 100
|
|
||||||
RongIMLib.getConversationList([RongIMLib.ConversationType.SYSTEM], total, 0, (res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
const pendings = res.conversations.filter((item) => {
|
|
||||||
return item.objectName == RongIMLib.ObjectName.ContactNotification &&
|
|
||||||
item.latestMessage.operation === 'Request'
|
|
||||||
})
|
|
||||||
|
|
||||||
callback(pendings)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 群组申请列表,邀请列表
|
|
||||||
const getGroupPendinglist = (targetId, callback) => {
|
|
||||||
const conversationType = RongIMLib.ConversationType.SYSTEM
|
|
||||||
const objectNames = ['RC:ContactNtf']
|
|
||||||
|
|
||||||
RongIMLib.getHistoryMessagesByTimestamp(conversationType, targetId, objectNames, 0, 1000, true,
|
|
||||||
({
|
|
||||||
messages
|
|
||||||
}) => {
|
|
||||||
callback(messages)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送文本消息
|
|
||||||
* @param {number} conversationType 消息类型
|
|
||||||
* @param {string} targetId 会话id
|
|
||||||
* @param {string} content 消息内容
|
|
||||||
* @param {function} callback 回调函数
|
|
||||||
*/
|
|
||||||
const sentText = (conversationType, targetId, content, user, callback) => {
|
|
||||||
const msg = {
|
|
||||||
conversationType: conversationType,
|
|
||||||
targetId: String(targetId),
|
|
||||||
content: {
|
|
||||||
objectName: 'RC:TxtMsg',
|
|
||||||
content: content,
|
|
||||||
userInfo: user
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送消息
|
|
||||||
* @param {number} conversationType 消息类型
|
|
||||||
* @param {string} targetId 会话id
|
|
||||||
* @param {string} voiceUrl 录音的本地路径
|
|
||||||
* @param {integer} time 录音时长
|
|
||||||
* @param {function} callback 录音时长
|
|
||||||
*/
|
|
||||||
const sentVoice = (conversationType, targetId, voiceUrl, time, user, callback) => {
|
|
||||||
const msg = {
|
|
||||||
conversationType: conversationType,
|
|
||||||
targetId: String(targetId),
|
|
||||||
content: {
|
|
||||||
objectName: 'RC:HQVCMsg',
|
|
||||||
local: 'file:///' + plus.io.convertLocalFileSystemURL(voiceUrl),
|
|
||||||
duration: time == 0 ? 1 : time,
|
|
||||||
userInfo: user
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RongIMLib.sendMediaMessage(msg, {
|
|
||||||
success: (messageId) => {
|
|
||||||
callback(messageId);
|
|
||||||
},
|
|
||||||
progress: (progress, messageId) => {
|
|
||||||
console.log(messageId);
|
|
||||||
},
|
|
||||||
cancel: (messageId) => {
|
|
||||||
// 发送取消回调
|
|
||||||
},
|
|
||||||
error: (errorCode, messageId) => {
|
|
||||||
console.log(errorCode, messageId);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const sentImage = (conversationType, targetId, imageUrl, user, callback) => {
|
|
||||||
const msg = {
|
|
||||||
conversationType: conversationType,
|
|
||||||
targetId: String(targetId),
|
|
||||||
content: {
|
|
||||||
objectName: 'RC:ImgMsg',
|
|
||||||
local: 'file:///' + plus.io.convertLocalFileSystemURL(imageUrl),
|
|
||||||
userInfo: user
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RongIMLib.sendMediaMessage(msg, {
|
|
||||||
success: (messageId) => {
|
|
||||||
callback(messageId);
|
|
||||||
},
|
|
||||||
progress: (progress, messageId) => {
|
|
||||||
console.log(messageId);
|
|
||||||
},
|
|
||||||
cancel: (messageId) => {
|
|
||||||
// 发送取消回调
|
|
||||||
},
|
|
||||||
error: (errorCode, messageId) => {
|
|
||||||
console.log(errorCode, messageId);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const sentGif = (conversationType, targetId, gifUrl, time, user, callback) => {
|
|
||||||
const msg = {
|
|
||||||
conversationType: conversationType,
|
|
||||||
targetId: String(targetId),
|
|
||||||
content: {
|
|
||||||
objectName: 'RC:GIFMsg',
|
|
||||||
local: 'file:///' + plus.io.convertLocalFileSystemURL(gifUrl),
|
|
||||||
duration: time,
|
|
||||||
userInfo: user
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RongIMLib.sendMediaMessage(msg, {
|
|
||||||
success: (messageId) => {
|
|
||||||
callback(messageId);
|
|
||||||
},
|
|
||||||
progress: (progress, messageId) => {
|
|
||||||
console.log(messageId);
|
|
||||||
},
|
|
||||||
cancel: (messageId) => {
|
|
||||||
// 发送取消回调
|
|
||||||
},
|
|
||||||
error: (errorCode, messageId) => {
|
|
||||||
console.log(errorCode, messageId);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const sendFile = (conversationType, targetId, fileUrl, time, user, callback) => {
|
|
||||||
const msg = {
|
|
||||||
conversationType: conversationType,
|
|
||||||
targetId: String(targetId),
|
|
||||||
content: {
|
|
||||||
objectName: 'RC:FileMsg',
|
|
||||||
local: 'file:///' + plus.io.convertLocalFileSystemURL(fileUrl),
|
|
||||||
duration: time,
|
|
||||||
userInfo: user
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RongIMLib.sendMediaMessage(msg, {
|
|
||||||
success: (messageId) => {
|
|
||||||
callback(messageId);
|
|
||||||
},
|
|
||||||
progress: (progress, messageId) => {
|
|
||||||
console.log(messageId);
|
|
||||||
},
|
|
||||||
cancel: (messageId) => {
|
|
||||||
// 发送取消回调
|
|
||||||
},
|
|
||||||
error: (errorCode, messageId) => {
|
|
||||||
console.log(errorCode, messageId);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
getMessageList,
|
|
||||||
getPendingList,
|
|
||||||
getGroupPendinglist,
|
|
||||||
sentText,
|
|
||||||
sentVoice,
|
|
||||||
sentImage,
|
|
||||||
sentGif,
|
|
||||||
sendFile
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
import {
|
|
||||||
usqlite
|
|
||||||
} from '@/uni_modules/onemue-USQLite/js_sdk/usqlite.js'
|
|
||||||
|
|
||||||
const contactModel = usqlite.model('contacts', {
|
|
||||||
targetId: {
|
|
||||||
type: String,
|
|
||||||
primaryKey: true,
|
|
||||||
unique: true
|
|
||||||
},
|
|
||||||
name: String,
|
|
||||||
remark: String,
|
|
||||||
hash: {
|
|
||||||
type: String,
|
|
||||||
unique: true
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
portraitUrl: String,
|
|
||||||
localAvatar: String
|
|
||||||
})
|
|
||||||
|
|
||||||
export {
|
|
||||||
contactModel
|
|
||||||
}
|
|
||||||
32
yarn.lock
32
yarn.lock
@@ -2,22 +2,22 @@
|
|||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
moment@^2.29.1:
|
"moment@^2.29.1":
|
||||||
version "2.29.1"
|
"integrity" "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
|
||||||
resolved "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz"
|
"resolved" "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz"
|
||||||
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
|
"version" "2.29.1"
|
||||||
|
|
||||||
uni-read-pages@^1.0.5:
|
"uni-read-pages@^1.0.5":
|
||||||
version "1.0.5"
|
"integrity" "sha512-GkrrZ0LX0vn9R5k6RKEi0Ez3Q3e2vUpjXQ8Z6/K/d28KudI9ajqgt8WEjQFlG5EPm1K6uTArN8LlqmZTEixDUA=="
|
||||||
resolved "https://registry.npmjs.org/uni-read-pages/-/uni-read-pages-1.0.5.tgz"
|
"resolved" "https://registry.npmjs.org/uni-read-pages/-/uni-read-pages-1.0.5.tgz"
|
||||||
integrity sha512-GkrrZ0LX0vn9R5k6RKEi0Ez3Q3e2vUpjXQ8Z6/K/d28KudI9ajqgt8WEjQFlG5EPm1K6uTArN8LlqmZTEixDUA==
|
"version" "1.0.5"
|
||||||
|
|
||||||
uni-simple-router@^2.0.7:
|
"uni-simple-router@^2.0.7":
|
||||||
version "2.0.7"
|
"integrity" "sha512-8FKv5dw7Eoonm0gkO8udprrxzin0fNUI0+AvIphFkFRH5ZmP5ZWJ2pvnWzb2NiiqQSECTSU5VSB7HhvOSwD5eA=="
|
||||||
resolved "https://registry.npmjs.org/uni-simple-router/-/uni-simple-router-2.0.7.tgz"
|
"resolved" "https://registry.npmjs.org/uni-simple-router/-/uni-simple-router-2.0.7.tgz"
|
||||||
integrity sha512-8FKv5dw7Eoonm0gkO8udprrxzin0fNUI0+AvIphFkFRH5ZmP5ZWJ2pvnWzb2NiiqQSECTSU5VSB7HhvOSwD5eA==
|
"version" "2.0.7"
|
||||||
|
|
||||||
uview-ui@^2.0.27:
|
"uview-ui@^2.0.27":
|
||||||
version "2.0.27"
|
"integrity" "sha512-d5SttbPcowomrgpL7A1LMKRbemXtyyzpPCy98/+VQR3jfSyyHC9tfj/ZeAOKpqTn1rf9gOj2wc5tda/kVmYX2Q=="
|
||||||
resolved "https://registry.yarnpkg.com/uview-ui/-/uview-ui-2.0.27.tgz#1a7dde9c6246e851d768f3efd44b5fb26774a2e1"
|
"resolved" "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.29.tgz"
|
||||||
integrity sha512-fl35rlguNPfXnwNoVv0w4zS1blFFxxSPuGR1+9SbpFGC33aiTBaoFWs/4Fppj0foS/kDCqSWcJiymNmQjPBD4g==
|
"version" "2.0.29"
|
||||||
|
|||||||
Reference in New Issue
Block a user