475 lines
13 KiB
Vue
475 lines
13 KiB
Vue
<template>
|
|
<view @click="pageClick" class="group_members_container">
|
|
<group-member-list-header
|
|
ref="navHeaderRef"
|
|
:checkVisible.sync="showCheck"
|
|
:isTransfer="isTransfer"
|
|
:isSetAdmin="isSetAdmin"
|
|
:isNomal="!isOwner && !isAdmin"
|
|
:groupID="groupID"
|
|
@removeMember="showMemberCheck"
|
|
/>
|
|
|
|
<view class="search_bar_wrap">
|
|
<u-search class="search_bar" shape="square" placeholder="搜索" :showAction="false"
|
|
v-model="keyword" />
|
|
</view>
|
|
|
|
<u-list class="member_list" @scrolltolower="loadMore" lowerThreshold="100" height="1">
|
|
<u-list-item v-for="member in filterGroupMemberList" :key="member.userID">
|
|
<user-item
|
|
@itemClick="userClick"
|
|
@updateCheck="updateCheck"
|
|
@longtapEvent="longtap"
|
|
:checked="isChecked(member.userID)"
|
|
:checkVisible="showCheck"
|
|
:disabled="!canCheck(member) && showCheck" :item="member"
|
|
/>
|
|
</u-list-item>
|
|
<view v-show="loadState.loading" class="member_loading">
|
|
<u-loading-icon></u-loading-icon>
|
|
</view>
|
|
</u-list>
|
|
|
|
<choose-index-footer
|
|
v-if="showCheck"
|
|
:comfirmLoading="comfirmLoading"
|
|
@removeItem="updateCheck"
|
|
@confirm="confirm"
|
|
:choosedData="getChoosedData"
|
|
:isRemove="isRemove"
|
|
:maxLength="groupMemberLength" />
|
|
|
|
<u-modal
|
|
:show="showConfirmModal"
|
|
asyncClose
|
|
showCancelButton
|
|
@confirm="modalConfirm"
|
|
@cancel="() => (showConfirmModal = false)" :content="isRemove? '确定移除已选群成员?': `确定要把群主转移给${choosedTransferMember.nickname}吗?`
|
|
" />
|
|
<u-toast ref="uToast"></u-toast>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
let moreActionArea;
|
|
import {mapActions,mapGetters} from "vuex";
|
|
import {GroupMemberListTypes} from "@/constant";
|
|
import IMSDK, {GroupMemberRole} from "openim-uniapp-polyfill";
|
|
import UserItem from "@/components/UserItem/index.vue";
|
|
import GroupMemberListHeader from "./components/GroupMemberListHeader.vue";
|
|
import ChooseIndexFooter from "@/components/ChooseIndexFooter/index.vue";
|
|
import util from "@/util/index.js"
|
|
export default {
|
|
components: {
|
|
GroupMemberListHeader,
|
|
ChooseIndexFooter,
|
|
UserItem,
|
|
},
|
|
data() {
|
|
return {
|
|
showCheck: false,
|
|
groupID: "",
|
|
keyword: "",
|
|
showConfirmModal: false,
|
|
comfirmLoading: false,
|
|
groupMemberList: [],
|
|
filterGroupMemberList:[],
|
|
choosedMemberIDList: [],
|
|
choosedTransferMember: {},
|
|
type: GroupMemberListTypes.Preview,
|
|
isRightKick: true,
|
|
loadState: {
|
|
hasMore: true,
|
|
loading: false,
|
|
},
|
|
adminUserIdList:[]
|
|
};
|
|
},
|
|
computed: {
|
|
...mapGetters([
|
|
'storeCurrentUserID',
|
|
'storeCurrentGroup',
|
|
"storeCurrentMemberInGroup"
|
|
]),
|
|
getChoosedData() {
|
|
const tmpList = [...this.choosedMemberIDList];
|
|
return this.groupMemberList.filter(
|
|
(member) => {
|
|
const idx = tmpList.findIndex((item) => item === member.userID);
|
|
if (idx > -1) {
|
|
tmpList.splice(idx, 1);
|
|
}
|
|
return idx > -1;
|
|
},
|
|
);
|
|
},
|
|
isRemove() {
|
|
return this.type === GroupMemberListTypes.Kickout;
|
|
},
|
|
isTransfer() {
|
|
return this.type === GroupMemberListTypes.Transfer;
|
|
},
|
|
isSetAdmin() {
|
|
return this.type === GroupMemberListTypes.setAdmin;
|
|
},
|
|
isChecked() {
|
|
return (userID) => this.choosedMemberIDList.includes(userID);
|
|
},
|
|
isOwner() {
|
|
return (
|
|
this.storeCurrentMemberInGroup.roleLevel ===
|
|
GroupMemberRole.Owner
|
|
);
|
|
},
|
|
isAdmin() {
|
|
return (
|
|
this.storeCurrentMemberInGroup.roleLevel === GroupMemberRole.Admin
|
|
);
|
|
},
|
|
canCheck() {
|
|
return ({
|
|
roleLevel,
|
|
userID
|
|
}) => {
|
|
if (this.type === GroupMemberListTypes.Kickout) {
|
|
return (
|
|
(this.isOwner || (this.isAdmin && roleLevel !== GroupMemberRole.Owner)) &&
|
|
userID !== this.$store.storeCurrentUserID
|
|
);
|
|
}
|
|
|
|
return userID !== this.$store.storeCurrentUserID;
|
|
};
|
|
},
|
|
groupMemberLength() {
|
|
return this.storeCurrentGroup?.memberCount ?? 0;
|
|
},
|
|
|
|
},
|
|
watch:{
|
|
keyword(v){
|
|
this.filterGroupMemberList = this.getFilterGroupMemberList();
|
|
},
|
|
groupMemberList(v){
|
|
this.filterGroupMemberList = this.getFilterGroupMemberList();
|
|
},
|
|
},
|
|
onLoad(options) {
|
|
const {
|
|
groupID,
|
|
type
|
|
} = options;
|
|
this.loadMemberList(groupID);
|
|
this.type = type;
|
|
this.groupID = groupID;
|
|
this.isRightKick = (type == GroupMemberListTypes.setAdmin|| type === GroupMemberListTypes.Kickout);
|
|
if (this.isRightKick) {
|
|
this.showCheck = true;
|
|
}
|
|
if(type == GroupMemberListTypes.setAdmin){
|
|
IMSDK.asyncApi('getGroupMemberOwnerAndAdmin', IMSDK.uuid(), this.groupID).then(({data}) => {
|
|
let arr = [];
|
|
data.forEach((item)=>{
|
|
if(item.roleLevel == GroupMemberRole.Admin){
|
|
arr.push(item.userID);
|
|
}
|
|
});
|
|
this.adminUserIdList = arr;
|
|
this.choosedMemberIDList = arr;
|
|
console.log(arr);
|
|
// 调用成功
|
|
})
|
|
.catch(({ errCode, errMsg }) => {
|
|
console.log(errCode, errMsg );
|
|
// 调用失败
|
|
})
|
|
}
|
|
|
|
},
|
|
methods: {
|
|
getFilterGroupMemberList(){
|
|
if(this.keyword){
|
|
return this.groupMemberList.filter((item)=>{
|
|
const kw = this.keyword.toLowerCase();
|
|
if(item.nickname && item.nickname.toLowerCase().includes(kw)){
|
|
return true;
|
|
}
|
|
if(item.showName && item.showName.toLowerCase().includes(kw)){
|
|
return true;
|
|
}
|
|
if(item.remark && item.remark.toLowerCase().includes(kw)){
|
|
return true;
|
|
}
|
|
if(item.groupName && item.groupName.toLowerCase().includes(kw)){
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
}
|
|
return this.groupMemberList;
|
|
},
|
|
async pageClick(e) {
|
|
if (!moreActionArea) {
|
|
moreActionArea = await this.getEl(".more_container");
|
|
}
|
|
if (!moreActionArea) return;
|
|
if (
|
|
e.target.y < moreActionArea.top ||
|
|
e.target.y > moreActionArea.bottom ||
|
|
e.target.x < moreActionArea.left
|
|
) {
|
|
this.$refs.navHeaderRef.checkMenu();
|
|
}
|
|
},
|
|
async confirm() {
|
|
if(this.isSetAdmin){
|
|
uni.showLoading({mask:true})
|
|
const remveUserIds = this.adminUserIdList.filter(userID=>{
|
|
return !this.choosedMemberIDList.includes(userID);
|
|
});
|
|
const addUserIds = this.choosedMemberIDList.filter(userID=>{
|
|
return !this.adminUserIdList.includes(userID);
|
|
});
|
|
remveUserIds.forEach(async (userID)=>{
|
|
await IMSDK.asyncApi(IMSDK.IMMethods.SetGroupMemberInfo,IMSDK.uuid(),{
|
|
roleLevel:GroupMemberRole.Normal,
|
|
groupID:this.groupID,
|
|
userID:userID
|
|
});
|
|
})
|
|
addUserIds.forEach(async (userID)=>{
|
|
await IMSDK.asyncApi(IMSDK.IMMethods.SetGroupMemberInfo,IMSDK.uuid(),{
|
|
roleLevel:GroupMemberRole.Admin,
|
|
groupID:this.groupID,
|
|
userID:userID
|
|
});
|
|
})
|
|
uni.hideLoading();
|
|
this.groupMemberList = [];
|
|
this.loadMemberList(this.groupID);
|
|
uni.navigateBack();
|
|
}else{
|
|
this.showConfirmModal = true;
|
|
}
|
|
},
|
|
modalConfirm() {
|
|
let func = () => {};
|
|
if (this.type === GroupMemberListTypes.Kickout) {
|
|
func = IMSDK.asyncApi(IMSDK.IMMethods.KickGroupMember, IMSDK.uuid(), {
|
|
groupID: this.getChoosedData[0].groupID,
|
|
reason: "",
|
|
userIDList: this.getChoosedData.map((member) => member.userID),
|
|
});
|
|
} else {
|
|
func = IMSDK.asyncApi(
|
|
IMSDK.IMMethods.TransferGroupOwner,
|
|
IMSDK.uuid(), {
|
|
groupID: this.choosedTransferMember.groupID,
|
|
newOwnerUserID: this.choosedTransferMember.userID,
|
|
},
|
|
);
|
|
}
|
|
func
|
|
.then(() => this.showToast("操作成功", () => uni.navigateBack()))
|
|
.catch(() => this.showToast("操作失败"))
|
|
.finally(() => (this.showConfirmModal = false));
|
|
},
|
|
updateChoosedData(userID) {
|
|
if (this.choosedMemberIDList.includes(userID)) {
|
|
const idx = this.choosedMemberIDList.findIndex(
|
|
(item) => item === userID,
|
|
);
|
|
const tmpArr = [...this.choosedMemberIDList];
|
|
tmpArr.splice(idx, 1);
|
|
this.choosedMemberIDList = tmpArr;
|
|
} else {
|
|
this.choosedMemberIDList = [...this.choosedMemberIDList, userID];
|
|
}
|
|
},
|
|
userClick(member) {
|
|
if (this.type === GroupMemberListTypes.Transfer) {
|
|
if (member.userID === this.storeCurrentUserID) return;
|
|
this.choosedTransferMember = member;
|
|
this.showConfirmModal = true;
|
|
} else {
|
|
if(member.userID == this.storeCurrentUserID){
|
|
return ;
|
|
}
|
|
if(this.storeCurrentMemberInGroup.roleLevel < 60 && this.storeCurrentGroup.lookMemberInfo!=0){
|
|
return ;
|
|
}
|
|
const s = util.aesencode(member);
|
|
uni.$u.route("/pages/common/userCard/index", {
|
|
sourceID: member.userID,
|
|
memberInfo: s,
|
|
});
|
|
}
|
|
},
|
|
updateCheck(member) {
|
|
this.updateChoosedData(member.userID);
|
|
},
|
|
showMemberCheck() {
|
|
this.type = GroupMemberListTypes.Kickout;
|
|
this.showCheck = true;
|
|
},
|
|
loadMore() {
|
|
const stateKey = "loadState";
|
|
const methodKey = "loadMemberList";
|
|
if (this[stateKey].hasMore && !this[stateKey].loading) {
|
|
this[methodKey]();
|
|
}
|
|
},
|
|
loadMemberList(groupID) {
|
|
this.loadState.loading = true;
|
|
IMSDK.asyncApi(IMSDK.IMMethods.GetGroupMemberList, IMSDK.uuid(), {
|
|
groupID: groupID ?? this.groupID,
|
|
filter: 0,
|
|
offset: this.groupMemberList.length,
|
|
count: 500,
|
|
})
|
|
.then(({
|
|
data
|
|
}) => {
|
|
this.groupMemberList = [...this.groupMemberList, ...data];
|
|
this.filterGroupMemberList = this.getFilterGroupMemberList();
|
|
this.loadState.hasMore = data.length === 500;
|
|
})
|
|
.finally(() => (this.loadState.loading = false));
|
|
},
|
|
longtap(member){
|
|
const _this = this;
|
|
if(this.isRightKick){
|
|
return ;
|
|
}
|
|
if(!this.isOwner&&!this.isAdmin){
|
|
return ;
|
|
}
|
|
if(this.storeCurrentMemberInGroup.roleLevel <= member.roleLevel ){
|
|
return ;
|
|
}
|
|
let itemList = [];
|
|
if(this.isOwner){
|
|
itemList.push(member.roleLevel == GroupMemberRole.Admin ? '取消管理员' : '设为管理员');
|
|
}
|
|
if(this.isOwner || this.isAdmin){
|
|
itemList.push(member.muteEndTime > 0 ? '取消禁言':'设置禁言');
|
|
itemList.push('踢出群聊');
|
|
}
|
|
uni.showActionSheet({
|
|
itemList:itemList,
|
|
async success({tapIndex}) {
|
|
const label = itemList[tapIndex];
|
|
if(['设为管理员','取消管理员'].includes(label)){
|
|
let roleId = label=='设为管理员' ? GroupMemberRole.Admin : GroupMemberRole.Normal;
|
|
|
|
await IMSDK.asyncApi(IMSDK.IMMethods.SetGroupMemberInfo,IMSDK.uuid(),{
|
|
roleLevel:roleId,
|
|
groupID:_this.groupID,
|
|
userID:member.userID
|
|
});
|
|
_this.groupMemberList = _this.groupMemberList.map((item)=>{
|
|
if(item.userID == member.userID){
|
|
item.roleLevel = roleId
|
|
}
|
|
return item;
|
|
});
|
|
return ;
|
|
}
|
|
if(['取消禁言','设置禁言'].includes(label)){
|
|
if(label == '取消禁言'){
|
|
_this.setMute(member.userID,0)
|
|
return ;
|
|
}
|
|
uni.showActionSheet({
|
|
itemList:['2小时','8小时','1天','3天','7天','15天','30天','1年'],
|
|
success(res){
|
|
const secs = [3600*2,3600*8,3600*24,3600*72,3600*24*7,3600*24*15,3600*24*30,3600*24*365];
|
|
_this.setMute(member.userID,secs[res.tapIndex])
|
|
}
|
|
});
|
|
return ;
|
|
}
|
|
if(label=="踢出群聊"){
|
|
await IMSDK.asyncApi(IMSDK.IMMethods.KickGroupMember,IMSDK.uuid(),{
|
|
groupID:_this.groupID,
|
|
reason:"",
|
|
userIDList:[member.userID]
|
|
});
|
|
_this.groupMemberList = _this.groupMemberList.filter((item)=>{
|
|
return item.userID != member.userID;
|
|
});
|
|
return ;
|
|
}
|
|
}
|
|
})
|
|
},
|
|
async setMute(userID,mutedSeconds){
|
|
const _this = this;
|
|
await IMSDK.asyncApi(IMSDK.IMMethods.ChangeGroupMemberMute,IMSDK.uuid(),{
|
|
mutedSeconds:mutedSeconds,
|
|
groupID:_this.groupID,
|
|
userID:userID
|
|
});
|
|
this.groupMemberList = this.groupMemberList.map((item)=>{
|
|
if(item.userID == userID){
|
|
item.muteEndTime = mutedSeconds===0 ? 0 : (new Date().getTime())+mutedSeconds*1000
|
|
}
|
|
return item;
|
|
});
|
|
},
|
|
showToast(message, complete = null) {
|
|
this.$refs.uToast.show({
|
|
message,
|
|
complete,
|
|
});
|
|
},
|
|
getEl(el) {
|
|
return new Promise((resolve) => {
|
|
const query = uni.createSelectorQuery().in(this);
|
|
query
|
|
.select(el)
|
|
.boundingClientRect((data) => {
|
|
// 存在data,且存在宽和高,视为渲染完毕
|
|
resolve(data);
|
|
})
|
|
.exec();
|
|
});
|
|
},
|
|
},
|
|
onBackPress(options) {
|
|
if (this.showCheck && this.isRightKick) {
|
|
this.showCheck = false;
|
|
this.type = GroupMemberListTypes.Preview;
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.group_members_container {
|
|
@include colBox(false);
|
|
height: 100vh;
|
|
overflow: hidden;
|
|
|
|
.search_bar_wrap {
|
|
height: 34px;
|
|
padding: 12px 22px;
|
|
}
|
|
|
|
.at_all_btn {
|
|
font-weight: 500;
|
|
padding: 24rpx 44rpx;
|
|
}
|
|
|
|
::v-deep.u-popup {
|
|
flex: none;
|
|
}
|
|
|
|
.member_list {
|
|
flex: 1;
|
|
}
|
|
}
|
|
</style> |