3 changed files with 273 additions and 0 deletions
@ -0,0 +1,70 @@ |
|||||
|
<template> |
||||
|
<div class="group-member-item" :style="{'height':height+'px'}"> |
||||
|
<div class="member-avatar"> |
||||
|
<head-image :size="headImageSize" :name="member.aliasName" |
||||
|
:url="member.headImage" :online="member.online"> </head-image> |
||||
|
</div> |
||||
|
<div class="member-name" :style="{'line-height':height+'px'}"> |
||||
|
<div>{{ member.aliasName }}</div> |
||||
|
</div> |
||||
|
<slot></slot> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import HeadImage from "../common/HeadImage.vue"; |
||||
|
export default { |
||||
|
name: "groupMember", |
||||
|
components: { HeadImage }, |
||||
|
data() { |
||||
|
return {}; |
||||
|
}, |
||||
|
props: { |
||||
|
member: { |
||||
|
type: Object, |
||||
|
required: true |
||||
|
}, |
||||
|
height:{ |
||||
|
type: Number, |
||||
|
default: 50 |
||||
|
} |
||||
|
}, |
||||
|
computed:{ |
||||
|
headImageSize(){ |
||||
|
return Math.ceil(this.height * 0.75) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.group-member-item { |
||||
|
display: flex; |
||||
|
margin-bottom: 1px; |
||||
|
position: relative; |
||||
|
padding: 0 15px; |
||||
|
align-items: center; |
||||
|
background-color: #fafafa; |
||||
|
white-space: nowrap; |
||||
|
box-sizing: border-box; |
||||
|
|
||||
|
&:hover { |
||||
|
background-color: #eeeeee; |
||||
|
} |
||||
|
|
||||
|
&.active { |
||||
|
background-color: #eeeeee; |
||||
|
} |
||||
|
|
||||
|
.member-name { |
||||
|
flex:1; |
||||
|
padding-left: 10px; |
||||
|
height: 100%; |
||||
|
text-align: left; |
||||
|
white-space: nowrap; |
||||
|
overflow: hidden; |
||||
|
font-size: 14px; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,161 @@ |
|||||
|
<template> |
||||
|
<el-dialog title="选择成员" :visible.sync="isShow" width="50%"> |
||||
|
<div class="group-member-selector"> |
||||
|
<div class="left-box"> |
||||
|
<el-input placeholder="搜索" v-model="searchText"> |
||||
|
<i class="el-icon-search el-input__icon" slot="suffix"> </i> |
||||
|
</el-input> |
||||
|
<el-scrollbar style="height:400px;"> |
||||
|
<div v-for="m in members" :key="m.userId"> |
||||
|
<group-member-item v-show="!m.quit&&m.aliasName.startsWith(searchText)" |
||||
|
:member="m" @click.native="onClickMember(m)"> |
||||
|
<el-checkbox :disabled="m.locked" v-model="m.checked" @change="onChange(m)" |
||||
|
@click.native.stop=""></el-checkbox> |
||||
|
</group-member-item> |
||||
|
</div> |
||||
|
</el-scrollbar> |
||||
|
</div> |
||||
|
<div class="arrow el-icon-d-arrow-right"></div> |
||||
|
<div class="right-box"> |
||||
|
<div class="select-tip"> 已勾选{{checkedMembers.length}}位成员</div> |
||||
|
<div class="checked-member-list"> |
||||
|
<div v-for="m in members" :key="m.userId"> |
||||
|
<group-member class="member-item" v-if="m.checked" :member="m"></group-member> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<span slot="footer" class="dialog-footer"> |
||||
|
<el-button @click="close()">取 消</el-button> |
||||
|
<el-button type="primary" @click="ok()">确 定</el-button> |
||||
|
</span> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import GroupMemberItem from './GroupMemberItem.vue'; |
||||
|
import GroupMember from './GroupMember.vue'; |
||||
|
|
||||
|
export default { |
||||
|
name: "addGroupMember", |
||||
|
components: { |
||||
|
GroupMemberItem, |
||||
|
GroupMember |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
isShow: false, |
||||
|
searchText: "", |
||||
|
maxSize: -1, |
||||
|
members: [] |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
groupId: { |
||||
|
type: Number |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
open(maxSize, checkedIds, lockedIds) { |
||||
|
this.maxSize = maxSize; |
||||
|
this.isShow = true; |
||||
|
this.loadGroupMembers(checkedIds, lockedIds); |
||||
|
}, |
||||
|
loadGroupMembers(checkedIds, lockedIds) { |
||||
|
this.$http({ |
||||
|
url: `/group/members/${this.groupId}`, |
||||
|
method: 'get' |
||||
|
}).then((members) => { |
||||
|
members.forEach((m) => { |
||||
|
// 默认选择和锁定的用户 |
||||
|
m.checked = checkedIds.indexOf(m.userId) >= 0; |
||||
|
m.locked = lockedIds.indexOf(m.userId) >= 0; |
||||
|
}); |
||||
|
this.members = members; |
||||
|
}); |
||||
|
}, |
||||
|
onClickMember(m) { |
||||
|
if (!m.locked) { |
||||
|
m.checked = !m.checked; |
||||
|
} |
||||
|
if (this.checkedMembers.length > this.maxSize) { |
||||
|
this.$message.error(`最多选择${this.maxSize}位成员`) |
||||
|
m.checked = false; |
||||
|
} |
||||
|
}, |
||||
|
onChange(m) { |
||||
|
if (this.checkedMembers.length > this.maxSize) { |
||||
|
this.$message.error(`最多选择${this.maxSize}位成员`) |
||||
|
m.checked = false; |
||||
|
} |
||||
|
}, |
||||
|
ok() { |
||||
|
this.$emit("complete", this.checkedMembers); |
||||
|
this.isShow = false; |
||||
|
}, |
||||
|
close() { |
||||
|
this.isShow = false; |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
checkedMembers() { |
||||
|
let ids = []; |
||||
|
this.members.forEach((m) => { |
||||
|
if (m.checked) { |
||||
|
ids.push(m); |
||||
|
} |
||||
|
}) |
||||
|
return ids; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.group-member-selector { |
||||
|
display: flex; |
||||
|
|
||||
|
.left-box { |
||||
|
width: 48%; |
||||
|
border: #587FF0 solid 1px; |
||||
|
border-radius: 5px; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.arrow { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
font-size: 20px; |
||||
|
padding: 10px; |
||||
|
font-weight: 600; |
||||
|
color: #687Ff0; |
||||
|
} |
||||
|
|
||||
|
.right-box { |
||||
|
|
||||
|
width: 48%; |
||||
|
border: #587FF0 solid 1px; |
||||
|
border-radius: 5px; |
||||
|
|
||||
|
.select-tip { |
||||
|
text-align: left; |
||||
|
height: 40px; |
||||
|
line-height: 40px; |
||||
|
text-indent: 5px; |
||||
|
} |
||||
|
|
||||
|
.checked-member-list { |
||||
|
padding: 10px; |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
flex-wrap: wrap; |
||||
|
|
||||
|
.member-item { |
||||
|
padding: 2px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,42 @@ |
|||||
|
<template> |
||||
|
<el-dialog v-dialogDrag top="5vh" title="语音通话" :close-on-click-modal="false" :close-on-press-escape="false" |
||||
|
:visible.sync="isShow" width="50%"> |
||||
|
<div class='rtc-group-video'> |
||||
|
<div style="padding-top:30px;font-weight: 600; text-align: center;font-size: 16px;"> |
||||
|
多人音视频通话为付费功能,有需要请联系作者... |
||||
|
</div> |
||||
|
<div style="padding-top:50px; text-align: center;font-size: 16px;"> |
||||
|
点击下方文档了解详细信息: |
||||
|
</div> |
||||
|
<div style="padding-top:10px; text-align: center;font-size: 16px;"> |
||||
|
<a href="https://www.yuque.com/u1475064/mufu2a/vi7engzluty594s2" target="_blank"> |
||||
|
付费-音视频通话源码 |
||||
|
</a> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: "rtcGroupVideo", |
||||
|
data() { |
||||
|
return { |
||||
|
isShow: false |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
open() { |
||||
|
this.isShow = true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.rtc-group-video { |
||||
|
height: 300px; |
||||
|
background-color: #E8F2FF; |
||||
|
} |
||||
|
</style> |
||||
Loading…
Reference in new issue