11 changed files with 543 additions and 85 deletions
@ -0,0 +1,205 @@ |
|||||
|
<template> |
||||
|
<div class="chat-group-side"> |
||||
|
<div class="group-side-search"> |
||||
|
<el-input placeholder="搜索群成员" v-model="searchText"> |
||||
|
<el-button slot="append" icon="el-icon-search"></el-button> |
||||
|
</el-input> |
||||
|
</div> |
||||
|
<el-scrollbar class="group-side-scrollbar"> |
||||
|
<div class="group-side-member-list"> |
||||
|
<div class="group-side-invite"> |
||||
|
<div class="invite-member-btn" title="邀请好友进群聊" @click="showAddGroupMember=true"> |
||||
|
<i class="el-icon-plus"></i> |
||||
|
</div> |
||||
|
<div class="invite-member-text">邀请</div> |
||||
|
<add-group-member :visible="showAddGroupMember" :groupId="group.id" :members="groupMembers" @reload="$emit('reload')" |
||||
|
@close="showAddGroupMember=false"></add-group-member> |
||||
|
</div> |
||||
|
<div v-for="(member) in groupMembers" :key="member.id"> |
||||
|
<group-member class="group-side-member" v-show="!member.quit && member.aliasName.startsWith(searchText)" :member="member" |
||||
|
:showDel="false"></group-member> |
||||
|
</div> |
||||
|
</div> |
||||
|
<el-divider content-position="center"></el-divider> |
||||
|
<el-form labelPosition="top" class="group-side-form" :model="group"> |
||||
|
<el-form-item label="群聊名称"> |
||||
|
<el-input v-model="group.name" disabled maxlength="20"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="群主"> |
||||
|
<el-input :value="ownerName" disabled></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="群公告"> |
||||
|
<el-input v-model="group.notice" disabled type="textarea" maxlength="1024" placeholder="群主未设置"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="备注"> |
||||
|
<el-input v-model="group.remark" :disabled="!editing" placeholder="群聊的备注仅自己可见" maxlength="20"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="我在本群的昵称"> |
||||
|
<el-input v-model="group.aliasName" :disabled="!editing" placeholder="xx" maxlength="20"></el-input> |
||||
|
</el-form-item> |
||||
|
|
||||
|
<div class="btn-group"> |
||||
|
<el-button v-show="editing" type="success" @click="handleSaveGroup()">提交</el-button> |
||||
|
<el-button v-show="!editing" type="primary" @click="editing=!editing">编辑</el-button> |
||||
|
<el-button type="danger" v-show="!isOwner" @click="handleQuit()">退出群聊</el-button> |
||||
|
</div> |
||||
|
</el-form> |
||||
|
</el-scrollbar> |
||||
|
|
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import AddGroupMember from '../group/AddGroupMember.vue'; |
||||
|
import GroupMember from '../group/GroupMember.vue'; |
||||
|
|
||||
|
export default { |
||||
|
name: "chatGroupSide", |
||||
|
components: { |
||||
|
AddGroupMember, |
||||
|
GroupMember |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
searchText: "", |
||||
|
editing: false, |
||||
|
showAddGroupMember: false |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
group: { |
||||
|
type: Object |
||||
|
}, |
||||
|
groupMembers: { |
||||
|
type: Array |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
handleClose() { |
||||
|
this.$emit('close'); |
||||
|
}, |
||||
|
loadGroupMembers() { |
||||
|
this.$http({ |
||||
|
url: `/api/group/members/${this.group.id}`, |
||||
|
method: "get" |
||||
|
}).then((members) => { |
||||
|
this.groupMembers = members; |
||||
|
}) |
||||
|
}, |
||||
|
handleSaveGroup() { |
||||
|
let vo = this.group; |
||||
|
this.$http({ |
||||
|
url: "/api/group/modify", |
||||
|
method: "put", |
||||
|
data: vo |
||||
|
}).then((group) => { |
||||
|
this.$store.commit("updateGroup", group); |
||||
|
this.$emit('reload'); |
||||
|
this.$message.success("修改成功"); |
||||
|
}) |
||||
|
}, |
||||
|
handleQuit() { |
||||
|
this.$confirm('退出群聊后将不再接受群里的消息,确认退出吗?', '确认退出?', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning' |
||||
|
}).then(() => { |
||||
|
this.$http({ |
||||
|
url: `/api/group/quit/${this.group.id}`, |
||||
|
method: 'delete' |
||||
|
}).then(() => { |
||||
|
this.$store.commit("removeGroup", this.group.id); |
||||
|
this.$store.commit("activeGroup", -1); |
||||
|
this.$store.commit("removeGroupChat", this.group.id); |
||||
|
}); |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
}, |
||||
|
computed: { |
||||
|
ownerName() { |
||||
|
let member = this.groupMembers.find((m) => m.userId == this.group.ownerId); |
||||
|
return member && member.aliasName; |
||||
|
}, |
||||
|
isOwner() { |
||||
|
return this.group.ownerId == this.$store.state.userStore.userInfo.id; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.chat-group-side { |
||||
|
position: relative; |
||||
|
|
||||
|
.group-side-member-list { |
||||
|
padding: 10px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
flex-wrap: wrap; |
||||
|
font-size: 16px; |
||||
|
text-align: center; |
||||
|
|
||||
|
.group-side-member { |
||||
|
margin-left: 15px; |
||||
|
} |
||||
|
|
||||
|
.group-side-invite { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
width: 50px; |
||||
|
margin-left: 15px; |
||||
|
|
||||
|
.invite-member-btn { |
||||
|
width: 100%; |
||||
|
height: 50px; |
||||
|
line-height: 50px; |
||||
|
border: #cccccc solid 1px; |
||||
|
font-size: 25px; |
||||
|
cursor: pointer; |
||||
|
box-sizing: border-box; |
||||
|
|
||||
|
&:hover { |
||||
|
border: #aaaaaa solid 1px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.invite-member-text { |
||||
|
font-size: 16px; |
||||
|
text-align: center; |
||||
|
width: 100%; |
||||
|
height: 30px; |
||||
|
line-height: 30px; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
overflow: hidden |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.group-side-form { |
||||
|
text-align: left; |
||||
|
padding: 10px; |
||||
|
height: 30%; |
||||
|
|
||||
|
.el-form-item { |
||||
|
margin-bottom: 12px; |
||||
|
|
||||
|
.el-form-item__label { |
||||
|
padding: 0; |
||||
|
line-height: 30px; |
||||
|
} |
||||
|
|
||||
|
.el-textarea__inner { |
||||
|
min-height: 100px !important; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.btn-group { |
||||
|
text-align: center; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,35 @@ |
|||||
|
<template> |
||||
|
<el-dialog width="30%" :visible.sync="visible" :before-close="handleClose"> |
||||
|
<img class="full-img" :src="url" /> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: "fullImage", |
||||
|
data() { |
||||
|
return { |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
handleClose() { |
||||
|
this.$emit("close"); |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
visible: { |
||||
|
type: Boolean |
||||
|
}, |
||||
|
url: { |
||||
|
type: String |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.full-img { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,139 @@ |
|||||
|
<template> |
||||
|
<div class="user-info-mask" @click="$emit('close')"> |
||||
|
<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 :url="user.headImageThumb" :size="60" @click.native="showFullImage()"> </head-image> |
||||
|
</div> |
||||
|
<div> |
||||
|
<el-descriptions :column="1" :title="user.userName" class="user-info-items"> |
||||
|
<el-descriptions-item label="昵称">{{ user.nickName }} |
||||
|
</el-descriptions-item> |
||||
|
<el-descriptions-item label="签名">{{ user.signature }} |
||||
|
</el-descriptions-item> |
||||
|
</el-descriptions> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
<el-divider content-position="center"></el-divider> |
||||
|
<div class="user-btn-group"> |
||||
|
<el-button v-show="isFriend" type="primary" @click="handleSendMessage()">发消息</el-button> |
||||
|
<el-button v-show="!isFriend" type="primary" @click="handleAddFriend()">加为好友</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import HeadImage from './HeadImage.vue' |
||||
|
|
||||
|
export default { |
||||
|
name: "userInfo", |
||||
|
components: { |
||||
|
HeadImage |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
user: { |
||||
|
type: Object |
||||
|
}, |
||||
|
pos: { |
||||
|
type: Object |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
handleSendMessage() { |
||||
|
let user = this.user; |
||||
|
let chat = { |
||||
|
type: 'PRIVATE', |
||||
|
targetId: user.id, |
||||
|
showName: user.nickName, |
||||
|
headImage: user.headImage, |
||||
|
}; |
||||
|
this.$store.commit("openChat", chat); |
||||
|
this.$store.commit("activeChat", 0); |
||||
|
if (this.$route.path != "/home/chat") { |
||||
|
this.$router.push("/home/chat"); |
||||
|
} |
||||
|
this.$emit("close"); |
||||
|
}, |
||||
|
handleAddFriend() { |
||||
|
this.$http({ |
||||
|
url: "/api/friend/add", |
||||
|
method: "post", |
||||
|
params: { |
||||
|
friendId: this.user.id |
||||
|
} |
||||
|
}).then((data) => { |
||||
|
this.$message.success("添加成功,对方已成为您的好友"); |
||||
|
let friend = { |
||||
|
id: this.user.id, |
||||
|
nickName: this.user.nickName, |
||||
|
headImage: this.user.headImageThumb, |
||||
|
online: this.user.online |
||||
|
} |
||||
|
this.$store.commit("addFriend", friend); |
||||
|
}) |
||||
|
}, |
||||
|
showFullImage(){ |
||||
|
if(this.user.headImage){ |
||||
|
this.$store.commit("showFullImageBox",this.user.headImage); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
isFriend() { |
||||
|
let friends = this.$store.state.friendStore.friends; |
||||
|
let friend = friends.find((f) => f.id == this.user.id); |
||||
|
return friend != undefined; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.user-info-mask { |
||||
|
background-color: rgba($color: #000000, $alpha: 0); |
||||
|
position: absolute; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.user-info { |
||||
|
position: absolute; |
||||
|
width: 300px; |
||||
|
background-color: white; |
||||
|
border: #dddddd solid 1px; |
||||
|
border-radius: 5px; |
||||
|
padding: 15px; |
||||
|
|
||||
|
.user-info-box { |
||||
|
display: flex; |
||||
|
|
||||
|
.user-info-items { |
||||
|
margin-left: 10px; |
||||
|
white-space: nowrap; |
||||
|
overflow: hidden; |
||||
|
.el-descriptions__header { |
||||
|
margin-bottom: 5px; |
||||
|
} |
||||
|
|
||||
|
.el-descriptions__title { |
||||
|
font-size: 20px; |
||||
|
} |
||||
|
|
||||
|
.el-descriptions-item__cell { |
||||
|
padding-bottom: 1px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.user-btn-group { |
||||
|
text-align: center; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,39 @@ |
|||||
|
export default { |
||||
|
state: { |
||||
|
userInfo: { // 用户信息窗口
|
||||
|
show: false, |
||||
|
user: {}, |
||||
|
pos:{ |
||||
|
x:0, |
||||
|
y:0 |
||||
|
} |
||||
|
}, |
||||
|
fullImage: { // 全屏大图
|
||||
|
show: false, |
||||
|
url: "" |
||||
|
} |
||||
|
}, |
||||
|
mutations: { |
||||
|
showUserInfoBox(state,user){ |
||||
|
state.userInfo.show = true; |
||||
|
state.userInfo.user = user; |
||||
|
|
||||
|
}, |
||||
|
setUserInfoBoxPos(state,pos){ |
||||
|
let w = document.documentElement.clientWidth; |
||||
|
let h = document.documentElement.clientHeight; |
||||
|
state.userInfo.pos.x = Math.min(pos.x,w-350); |
||||
|
state.userInfo.pos.y = Math.min(pos.y,h-200); |
||||
|
}, |
||||
|
closeUserInfoBox(state){ |
||||
|
state.userInfo.show = false; |
||||
|
}, |
||||
|
showFullImageBox(state,url){ |
||||
|
state.fullImage.show = true; |
||||
|
state.fullImage.url = url; |
||||
|
}, |
||||
|
closeFullImageBox(state){ |
||||
|
state.fullImage.show = false; |
||||
|
} |
||||
|
}, |
||||
|
} |
||||
Loading…
Reference in new issue