blue
1 year ago
committed by
Gitee
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
15 changed files with
115 additions and
89 deletions
-
im-uniapp/.env.js
-
im-uniapp/components/chat-item/chat-item.vue
-
im-uniapp/components/head-image/head-image.vue
-
im-uniapp/components/pop-menu/pop-menu.vue
-
im-uniapp/pages/chat/chat-box.vue
-
im-uniapp/pages/group/group-info.vue
-
im-uniapp/pages/group/group-member.vue
-
im-web/src/components/chat/ChatBox.vue
-
im-web/src/components/chat/ChatInput.vue
-
im-web/src/components/chat/ChatItem.vue
-
im-web/src/components/common/HeadImage.vue
-
im-web/src/components/common/UserInfo.vue
-
im-web/src/view/Friend.vue
-
im-web/src/view/Group.vue
-
im-web/src/view/Home.vue
|
|
|
@ -2,8 +2,8 @@ |
|
|
|
const ENV = "DEV"; |
|
|
|
const UNI_APP = {} |
|
|
|
if(ENV=="DEV"){ |
|
|
|
UNI_APP.BASE_URL = "http://192.168.43.199:8888"; |
|
|
|
UNI_APP.WS_URL = "ws://192.168.43.199:8878/im"; |
|
|
|
UNI_APP.BASE_URL = "http://127.0.0.1:8888"; |
|
|
|
UNI_APP.WS_URL = "ws://127.0.0.1:8878/im"; |
|
|
|
// H5 走本地代理解决跨域问题
|
|
|
|
// #ifdef H5
|
|
|
|
UNI_APP.BASE_URL = "/api"; |
|
|
|
|
|
|
|
@ -7,11 +7,9 @@ |
|
|
|
</view> |
|
|
|
<view class="chat-right"> |
|
|
|
<view class="chat-name"> |
|
|
|
<view class="chat-tag" v-if="chat.type=='GROUP'"> |
|
|
|
<uni-tag disabled text="群" size="mini" type="primary"></uni-tag> |
|
|
|
</view> |
|
|
|
<view class="chat-name-text"> |
|
|
|
{{chat.showName}} |
|
|
|
<view>{{chat.showName}}</view> |
|
|
|
<uni-tag v-if="chat.type=='GROUP'" circle text="群" size="small"></uni-tag> |
|
|
|
</view> |
|
|
|
<view class="chat-time">{{$date.toTimeText(chat.lastSendTime,true)}}</view> |
|
|
|
</view> |
|
|
|
@ -44,7 +42,7 @@ |
|
|
|
} |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
|
|
|
|
|
|
|
|
showChatBox() { |
|
|
|
uni.navigateTo({ |
|
|
|
url: "/pages/chat/chat-box?chatIdx=" + this.index |
|
|
|
@ -127,18 +125,26 @@ |
|
|
|
line-height: 44rpx; |
|
|
|
height: 44rpx; |
|
|
|
|
|
|
|
.chat-tag { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
margin-right: 5rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.chat-name-text { |
|
|
|
flex: 1; |
|
|
|
font-size: 30rpx; |
|
|
|
font-weight: 600; |
|
|
|
white-space: nowrap; |
|
|
|
overflow: hidden; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
|
|
|
|
.uni-tag { |
|
|
|
text-align: center; |
|
|
|
margin-left: 5rpx; |
|
|
|
border: 0; |
|
|
|
height: 30rpx; |
|
|
|
line-height: 30rpx; |
|
|
|
font-size: 20rpx; |
|
|
|
padding: 1px 5px; |
|
|
|
background-color: #de1c1c; |
|
|
|
opacity: 0.8; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.chat-time { |
|
|
|
|
|
|
|
@ -15,9 +15,8 @@ |
|
|
|
name: "head-image", |
|
|
|
data() { |
|
|
|
return { |
|
|
|
colors: ["#7dd24b", "#c7515a", "#db68ef", "#15d29b", "#85029b", |
|
|
|
"#c9b455", "#fb2609", "#bda818", "#af0831", "#326eb6" |
|
|
|
] |
|
|
|
colors: ["#5daa31", "#c7515a", "#e03697", "#85029b", |
|
|
|
"#c9b455", "#326eb6"] |
|
|
|
} |
|
|
|
}, |
|
|
|
props: { |
|
|
|
@ -50,15 +49,17 @@ |
|
|
|
} |
|
|
|
}, |
|
|
|
computed: { |
|
|
|
avatarImageStyle() { |
|
|
|
return `width:${this.size}rpx; height:${this.size}rpx;` |
|
|
|
}, |
|
|
|
avatarTextStyle() { |
|
|
|
return `width: ${this.size}rpx;height:${this.size}rpx; |
|
|
|
color:${this.textColor};font-size:${this.size*0.5}rpx; |
|
|
|
border: 2px solid ${this.textColor}; |
|
|
|
box-shadow: 0px 0px 5rpx ${this.textColor}` |
|
|
|
}, |
|
|
|
avatarImageStyle() { |
|
|
|
return `width:${this.size}rpx; |
|
|
|
height:${this.size}rpx;` |
|
|
|
}, |
|
|
|
avatarTextStyle() { |
|
|
|
return `width: ${this.size}rpx; |
|
|
|
height:${this.size}rpx; |
|
|
|
background-color:${this.textColor}; |
|
|
|
font-size:${this.size*0.5}rpx; |
|
|
|
` |
|
|
|
}, |
|
|
|
textColor() { |
|
|
|
let hash = 0; |
|
|
|
for (var i = 0; i < this.name.length; i++) { |
|
|
|
@ -79,13 +80,11 @@ |
|
|
|
position: relative; |
|
|
|
overflow: hidden; |
|
|
|
border-radius: 50%; |
|
|
|
border: 2px solid #6664eb; |
|
|
|
vertical-align: bottom; |
|
|
|
box-shadow: 0px 0px 10rpx #6664eb; |
|
|
|
} |
|
|
|
|
|
|
|
.avatar-text { |
|
|
|
background-color: #f2f2f2; |
|
|
|
color: white; |
|
|
|
border-radius: 50%; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
|
|
|
|
@ -1,10 +1,9 @@ |
|
|
|
<template> |
|
|
|
<view> |
|
|
|
<view @longpress.stop="onLongPress($event)" @touchmove="onTouchMove" @touchend="onTouchEnd"> |
|
|
|
<view @longpress.stop="onLongPress($event)" @touchmove="onTouchMove"> |
|
|
|
<slot></slot> |
|
|
|
</view> |
|
|
|
|
|
|
|
<view v-if="isShowMenu" class="pop-menu" @tap="onClose()" @contextmenu.prevent=""></view> |
|
|
|
<view v-if="isShowMenu" class="pop-menu" @touchstart="onClose()" @contextmenu.prevent=""></view> |
|
|
|
<view v-if="isShowMenu" class="menu" :style="menuStyle"> |
|
|
|
<view class="menu-item" v-for="(item) in items" :key="item.key" @click.prevent="onSelectMenu(item)"> |
|
|
|
<uni-icons class="menu-icon" :type="item.icon" :style="itemStyle(item)" size="22"></uni-icons> |
|
|
|
@ -30,9 +29,6 @@ |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
onLongPress(e){ |
|
|
|
if(this.isTouchMove){ |
|
|
|
return; |
|
|
|
} |
|
|
|
uni.getSystemInfo({ |
|
|
|
success: (res) => { |
|
|
|
let touches = e.touches[0]; |
|
|
|
@ -57,10 +53,7 @@ |
|
|
|
}) |
|
|
|
}, |
|
|
|
onTouchMove(){ |
|
|
|
this.isTouchMove = true; |
|
|
|
}, |
|
|
|
onTouchEnd(){ |
|
|
|
this.isTouchMove = false; |
|
|
|
this.onClose() |
|
|
|
}, |
|
|
|
onSelectMenu(item) { |
|
|
|
this.$emit("select", item); |
|
|
|
@ -89,9 +82,8 @@ |
|
|
|
width: 100%; |
|
|
|
height: 100%; |
|
|
|
background-color: #333; |
|
|
|
z-index: 99; |
|
|
|
z-index: 999; |
|
|
|
opacity: 0.5; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
.menu { |
|
|
|
@ -100,7 +92,7 @@ |
|
|
|
border-radius: 7px; |
|
|
|
overflow: hidden; |
|
|
|
background-color: #f5f6ff; |
|
|
|
z-index: 100; |
|
|
|
z-index: 1000; |
|
|
|
.menu-item { |
|
|
|
height: 25px; |
|
|
|
min-width: 150rpx; |
|
|
|
|
|
|
|
@ -780,8 +780,7 @@ |
|
|
|
padding: 5px; |
|
|
|
background-color: #f8f8f8; |
|
|
|
line-height: 50px; |
|
|
|
font-size: 40rpx; |
|
|
|
font-weight: 600; |
|
|
|
font-size: 36rpx; |
|
|
|
border: #dddddd solid 1px; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -15,7 +15,7 @@ |
|
|
|
<uni-icons type="plusempty" size="28" color="#888888"></uni-icons> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
<view class="member-more" @click="onShowMoreMmeber()">查看更多群成员 ></view> |
|
|
|
<view class="member-more" @click="onShowMoreMmeber()">{{`查看全部群成员${groupMembers.length}人`}}></view> |
|
|
|
</view> |
|
|
|
<view class="group-detail"> |
|
|
|
<uni-section title="群聊名称:" titleFontSize="14px"> |
|
|
|
@ -39,7 +39,7 @@ |
|
|
|
<text class="detail-text"> {{group.showNickName}}</text> |
|
|
|
</template> |
|
|
|
</uni-section> |
|
|
|
<uni-section title="群公告:" titleFontSize="14px"> |
|
|
|
<uni-section v-if="group.notice" title="群公告:" titleFontSize="14px"> |
|
|
|
<uni-notice-bar :text="group.notice" /> |
|
|
|
</uni-section> |
|
|
|
<view v-if="!group.quit" class="group-edit" @click="onEditGroup()">修改群聊资料 > </view> |
|
|
|
@ -198,7 +198,7 @@ |
|
|
|
.group-members { |
|
|
|
padding: 30rpx; |
|
|
|
background: white; |
|
|
|
|
|
|
|
|
|
|
|
.member-items { |
|
|
|
display: flex; |
|
|
|
flex-wrap: wrap; |
|
|
|
@ -237,9 +237,10 @@ |
|
|
|
} |
|
|
|
|
|
|
|
.member-more { |
|
|
|
padding: 20rpx; |
|
|
|
padding-top: 30rpx; |
|
|
|
text-align: center; |
|
|
|
font-size: 16px; |
|
|
|
font-size: 32rpx; |
|
|
|
color: #333; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -248,15 +249,17 @@ |
|
|
|
margin-top: 30rpx; |
|
|
|
padding: 30rpx; |
|
|
|
background: white; |
|
|
|
|
|
|
|
|
|
|
|
.detail-text{ |
|
|
|
font-size: 28rpx; |
|
|
|
font-weight: 600; |
|
|
|
} |
|
|
|
|
|
|
|
.group-edit { |
|
|
|
padding: 20rpx; |
|
|
|
padding-top: 30rpx; |
|
|
|
text-align: center; |
|
|
|
font-size: 30rpx; |
|
|
|
font-size: 32rpx; |
|
|
|
color: #333; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -1,7 +1,7 @@ |
|
|
|
<template> |
|
|
|
<view class="page group-member"> |
|
|
|
<view class="search-bar"> |
|
|
|
<uni-search-bar v-model="searchText" radius="100" cancelButton="none" placeholder="输入成员昵称搜索"></uni-search-bar> |
|
|
|
<uni-search-bar v-model="searchText" radius="100" cancelButton="none" placeholder="输入昵称搜索"></uni-search-bar> |
|
|
|
</view> |
|
|
|
<view class="member-items"> |
|
|
|
<scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true"> |
|
|
|
@ -11,8 +11,15 @@ |
|
|
|
<head-image :name="member.showNickName" |
|
|
|
:online="member.online" :url="member.headImage" |
|
|
|
:size="100"></head-image> |
|
|
|
|
|
|
|
<view class="member-name">{{ member.showNickName}}</view> |
|
|
|
<view class="member-name">{{ member.showNickName}} |
|
|
|
<uni-tag v-if="member.userId==group.ownerId" |
|
|
|
text="群主" size="small" circle |
|
|
|
custom-style="background-color: #e30a0a;"> |
|
|
|
</uni-tag> |
|
|
|
<uni-tag v-if="member.userId==userStore.userInfo.id" |
|
|
|
text="我" size="small" circle></uni-tag> |
|
|
|
|
|
|
|
</view> |
|
|
|
|
|
|
|
<view class="member-kick"> |
|
|
|
<button type="warn" plain v-show="isOwner && !isSelf(member.userId)" size="mini" |
|
|
|
@ -125,6 +132,8 @@ |
|
|
|
white-space: nowrap; |
|
|
|
|
|
|
|
.member-name { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
flex:1; |
|
|
|
padding-left: 20rpx; |
|
|
|
font-size: 30rpx; |
|
|
|
@ -132,6 +141,16 @@ |
|
|
|
line-height: 60rpx; |
|
|
|
white-space: nowrap; |
|
|
|
overflow: hidden; |
|
|
|
|
|
|
|
.uni-tag { |
|
|
|
margin-left: 5rpx; |
|
|
|
width: 40rpx; |
|
|
|
border: 0; |
|
|
|
height: 30rpx; |
|
|
|
line-height: 30rpx; |
|
|
|
font-size: 20rpx; |
|
|
|
text-align: center; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -689,7 +689,7 @@ |
|
|
|
|
|
|
|
.im-chat-main { |
|
|
|
padding: 0; |
|
|
|
background-color: #f8f8f8; |
|
|
|
background-color: white; |
|
|
|
|
|
|
|
.im-chat-box { |
|
|
|
>ul { |
|
|
|
@ -716,7 +716,7 @@ |
|
|
|
box-sizing: border-box; |
|
|
|
border-top: #ccc solid 1px; |
|
|
|
padding: 2px; |
|
|
|
background-color: #e8f2ff; |
|
|
|
background-color: #f8faff; |
|
|
|
|
|
|
|
>div { |
|
|
|
font-size: 22px; |
|
|
|
@ -727,22 +727,20 @@ |
|
|
|
height: 30px; |
|
|
|
text-align: center; |
|
|
|
border-radius: 3px; |
|
|
|
margin: 3px; |
|
|
|
|
|
|
|
margin: 3px 5px; |
|
|
|
color: #0f46ae; |
|
|
|
&:hover { |
|
|
|
color: black; |
|
|
|
font-weight: 600; |
|
|
|
color: #042259; |
|
|
|
} |
|
|
|
|
|
|
|
&.chat-tool-active { |
|
|
|
font-weight: 600; |
|
|
|
color: #195ee2; |
|
|
|
background-color: #ddd; |
|
|
|
color: white; |
|
|
|
background-color: #195ee2; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
>div:hover { |
|
|
|
color: #949494; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
.send-content-area { |
|
|
|
|
|
|
|
@ -480,7 +480,6 @@ |
|
|
|
left: 0; |
|
|
|
right: 0; |
|
|
|
bottom: 0; |
|
|
|
border: 1px solid #c3c3c3; |
|
|
|
outline: none; |
|
|
|
padding: 5px; |
|
|
|
line-height: 30px; |
|
|
|
|
|
|
|
@ -7,11 +7,13 @@ |
|
|
|
</div> |
|
|
|
<div class="chat-right"> |
|
|
|
<div class="chat-name"> |
|
|
|
<div class="chat-tag" v-if="chat.type=='GROUP'"> |
|
|
|
<el-tag size="mini" >群</el-tag> |
|
|
|
<div class="chat-name-text"> |
|
|
|
<div>{{chat.showName}}</div> |
|
|
|
<el-tag v-if="chat.type=='GROUP'" size="mini" effect="dark">群</el-tag> |
|
|
|
</div> |
|
|
|
<div class="chat-name-text">{{chat.showName}}</div> |
|
|
|
|
|
|
|
<div class="chat-time-text">{{showTime}}</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
<div class="chat-content"> |
|
|
|
<div class="chat-at-text">{{atText}}</div> |
|
|
|
@ -162,19 +164,26 @@ |
|
|
|
line-height: 25px; |
|
|
|
height: 25px; |
|
|
|
|
|
|
|
.chat-tag { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
margin-right: 1px; |
|
|
|
} |
|
|
|
|
|
|
|
.chat-name-text { |
|
|
|
flex: 1; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
font-size: 15px; |
|
|
|
font-weight: 600; |
|
|
|
white-space: nowrap; |
|
|
|
overflow: hidden; |
|
|
|
|
|
|
|
.el-tag { |
|
|
|
background-color: #2830d3; |
|
|
|
border-radius: 10px; |
|
|
|
border: 0; |
|
|
|
height: 16px; |
|
|
|
line-height: 16px; |
|
|
|
font-size: 10px; |
|
|
|
margin-left: 2px; |
|
|
|
opacity: 0.8; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -3,7 +3,7 @@ |
|
|
|
<img class="avatar-image" v-show="url" :src="url" |
|
|
|
:style="avatarImageStyle" loading="lazy" /> |
|
|
|
<div class="avatar-text" v-show="!url" :style="avatarTextStyle"> |
|
|
|
{{name.substring(0,1).toUpperCase()}}</div> |
|
|
|
{{name.substring(0,2).toUpperCase()}}</div> |
|
|
|
<div v-show="online" class="online" title="用户当前在线"></div> |
|
|
|
<slot></slot> |
|
|
|
</div> |
|
|
|
@ -15,8 +15,8 @@ |
|
|
|
name: "headImage", |
|
|
|
data() { |
|
|
|
return { |
|
|
|
colors:["#7dd24b","#c7515a","#db68ef","#15d29b","#85029b", |
|
|
|
"#c9b455","#fb2609","#bda818","#af0831","#326eb6"] |
|
|
|
colors: ["#5daa31", "#c7515a", "#e03697", "#85029b", |
|
|
|
"#c9b455", "#326eb6"] |
|
|
|
|
|
|
|
} |
|
|
|
}, |
|
|
|
@ -36,7 +36,7 @@ |
|
|
|
}, |
|
|
|
radius:{ |
|
|
|
type: String, |
|
|
|
default: "10%" |
|
|
|
default: "50%" |
|
|
|
}, |
|
|
|
url: { |
|
|
|
type: String |
|
|
|
@ -74,7 +74,8 @@ |
|
|
|
let w = this.width ? this.width : this.size; |
|
|
|
let h = this.height ? this.height : this.size; |
|
|
|
return `width: ${w}px;height:${h}px; |
|
|
|
color:${this.textColor};font-size:${w*0.6}px; |
|
|
|
background-color:${this.textColor}; |
|
|
|
font-size:${w*0.35}px; |
|
|
|
border-radius: ${this.radius};` |
|
|
|
}, |
|
|
|
textColor(){ |
|
|
|
@ -99,8 +100,7 @@ |
|
|
|
} |
|
|
|
|
|
|
|
.avatar-text{ |
|
|
|
background-color: #f2f2f2; /* 默认背景色 */ |
|
|
|
border-radius: 15%; /* 圆角效果 */ |
|
|
|
color: white; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
|
|
|
|
@ -3,7 +3,8 @@ |
|
|
|
<div class="user-info" :style="{left: pos.x+'px',top: pos.y+'px'}" @click.stop> |
|
|
|
<div class="user-info-box"> |
|
|
|
<div class="avatar"> |
|
|
|
<head-image :name="user.nickName" :url="user.headImageThumb" :size="60" :online="user.online" |
|
|
|
<head-image :name="user.nickName" :url="user.headImageThumb" :size="70" |
|
|
|
:online="user.online" radius="10%" |
|
|
|
@click.native="showFullImage()"> </head-image> |
|
|
|
</div> |
|
|
|
<div> |
|
|
|
@ -114,7 +115,8 @@ |
|
|
|
|
|
|
|
.user-info-box { |
|
|
|
display: flex; |
|
|
|
|
|
|
|
align-items: center; |
|
|
|
|
|
|
|
.user-info-items { |
|
|
|
margin-left: 10px; |
|
|
|
white-space: nowrap; |
|
|
|
@ -125,7 +127,7 @@ |
|
|
|
} |
|
|
|
|
|
|
|
.el-descriptions__title { |
|
|
|
font-size: 20px; |
|
|
|
font-size: 18px; |
|
|
|
} |
|
|
|
|
|
|
|
.el-descriptions-item__cell { |
|
|
|
|
|
|
|
@ -25,7 +25,7 @@ |
|
|
|
<div v-show="userInfo.id"> |
|
|
|
<div class="friend-detail"> |
|
|
|
<head-image :size="200" :name="userInfo.nickName" :url="userInfo.headImage" |
|
|
|
@click.native="showFullImage()"></head-image> |
|
|
|
@click.native="showFullImage()" radius="10%"></head-image> |
|
|
|
<div> |
|
|
|
<div class="info-item"> |
|
|
|
<el-descriptions title="好友信息" class="description" :column="1"> |
|
|
|
|
|
|
|
@ -30,7 +30,7 @@ |
|
|
|
<i v-else class="el-icon-plus avatar-uploader-icon"></i> |
|
|
|
</file-upload> |
|
|
|
<head-image v-show="!isOwner" class="avatar" :size="200" :url="activeGroup.headImage" |
|
|
|
:name="activeGroup.showGroupName"> |
|
|
|
radius="10%" :name="activeGroup.showGroupName"> |
|
|
|
</head-image> |
|
|
|
<el-button class="send-btn" icon="el-icon-position" type="primary" |
|
|
|
@click="onSendMessage()">发消息</el-button> |
|
|
|
|
|
|
|
@ -385,7 +385,7 @@ |
|
|
|
|
|
|
|
.icon { |
|
|
|
font-size: 26px; |
|
|
|
color: #888; |
|
|
|
color: #666; |
|
|
|
} |
|
|
|
|
|
|
|
.unread-text { |
|
|
|
|