group mangage

This commit is contained in:
cansnow
2026-01-10 15:40:38 +08:00
parent 825ac3457d
commit 941464c330
12 changed files with 392 additions and 181 deletions
+10 -4
View File
@@ -1,5 +1,5 @@
<template> <template>
<view @click="clickItem" class="user_item"> <view @longtap.stop.prevent="longtap" @tap="clickItem" class="user_item">
<view v-if="checkVisible" class="check_wrap" <view v-if="checkVisible" class="check_wrap"
:class="{ check_wrap_active: checked, check_wrap_disabled: disabled }"> :class="{ check_wrap_active: checked, check_wrap_disabled: disabled }">
<u-icon v-show="checked" name="checkbox-mark" size="12" color="#fff" /> <u-icon v-show="checked" name="checkbox-mark" size="12" color="#fff" />
@@ -8,9 +8,10 @@
<my-avatar :src="item.faceURL" :desc="item.remark || item.nickname || item.showName" <my-avatar :src="item.faceURL" :desc="item.remark || item.nickname || item.showName"
:isGroup="item.groupName !== undefined || isGroupConversation" size="42" /> :isGroup="item.groupName !== undefined || isGroupConversation" size="42" />
<view class="user_item_details"> <view class="user_item_details">
<text class="user_name">{{item.remark || item.nickname || item.groupName || item.showName}}</text> <view class="user_name">{{item.remark || item.nickname || item.groupName || item.showName}}</view>
<text v-if="item.roleLevel === 100" class="user_role">群主</text> <view v-if="item.roleLevel === 100" class="user_role">群主</view>
<text v-if="item.roleLevel === 60" class="user_role admin_role">管理员</text> <view v-else-if="item.roleLevel === 60" class="user_role admin_role">管理员<u-icon v-if="item.muteEndTime>0" size="24" name="volume-off"></u-icon></view>
<view v-else class="user_role"><u-icon v-if="item.muteEndTime>0" size="24" name="volume-off"></u-icon></view>
<!-- <view class="bottom_line" /> --> <!-- <view class="bottom_line" /> -->
</view> </view>
@@ -55,6 +56,9 @@
this.$emit(this.checkVisible ? "updateCheck" : "itemClick", this.item); this.$emit(this.checkVisible ? "updateCheck" : "itemClick", this.item);
} }
}, },
longtap(){
this.$emit("longtapEvent", this.item);
}
}, },
}; };
</script> </script>
@@ -119,6 +123,8 @@
padding: 8rpx 24rpx; padding: 8rpx 24rpx;
border-radius: 24rpx; border-radius: 24rpx;
margin-left: 24rpx; margin-left: 24rpx;
display: flex;
align-items: center;
color: $u-tips-color; color: $u-tips-color;
} }
+2
View File
@@ -19,6 +19,8 @@ export const GroupMemberListTypes = {
Preview: "Preview", Preview: "Preview",
Transfer: "Transfer", Transfer: "Transfer",
Kickout: "Kickout", Kickout: "Kickout",
setAdmin: "setAdmin",
Mute: "Mute",
}; };
export const ContactChooseTypes = { export const ContactChooseTypes = {
@@ -1,5 +1,5 @@
<template> <template>
<view> <view v-if="storeCurrentMemberInGroup.muteEndTime===0">
<view class="chat_footer"> <view class="chat_footer">
<!-- 语音信息 --> <!-- 语音信息 -->
<image class="action_btn" v-show="inputType == 'keyboard'" @click.prevent="swtichInputType('record')" mode="heightFix" src="@/static/images/chating_footer_audio.png" alt="" srcset="" /> <image class="action_btn" v-show="inputType == 'keyboard'" @click.prevent="swtichInputType('record')" mode="heightFix" src="@/static/images/chating_footer_audio.png" alt="" srcset="" />
@@ -43,12 +43,17 @@
</view> </view>
<!-- #endif --> <!-- #endif -->
</view> </view>
<view v-else>
<view class="forbidden_footer">
<view class="mute_tip">您被禁言至{{date(storeCurrentMemberInGroup.muteEndTime)}}</view>
</view>
</view>
</template> </template>
<script> <script>
import {mapGetters,mapActions} from "vuex"; import {mapGetters,mapActions} from "vuex";
import {getPurePath,html2Text,getVideoCover,getVideoInfo} from "@/util/common"; import {getPurePath,html2Text,getVideoCover,getVideoInfo} from "@/util/common";
import {offlinePushInfo} from "@/util/imCommon"; import {offlinePushInfo,date} from "@/util/imCommon";
import {ChatingFooterActionTypes,UpdateMessageTypes,} from "@/constant"; import {ChatingFooterActionTypes,UpdateMessageTypes,} from "@/constant";
import IMSDK, {IMMethods,MessageStatus,MessageType,} from "openim-uniapp-polyfill"; import IMSDK, {IMMethods,MessageStatus,MessageType,} from "openim-uniapp-polyfill";
import CustomEditor from "./CustomEditor"; import CustomEditor from "./CustomEditor";
@@ -101,7 +106,8 @@
"storeCurrentConversation", "storeCurrentConversation",
"storeCurrentGroup", "storeCurrentGroup",
"storeBlackList", "storeBlackList",
"storeCurrentUserID" "storeCurrentUserID",
"storeCurrentMemberInGroup"
]), ]),
hasContent() { hasContent() {
return html2Text(this.inputHtml) !== ""; return html2Text(this.inputHtml) !== "";
@@ -113,6 +119,8 @@
}, },
}, },
mounted() { mounted() {
console.log(this.storeCurrentGroup)
console.log(this.storeCurrentMemberInGroup)
this.setKeyboardListener(); this.setKeyboardListener();
}, },
beforeDestroy() { beforeDestroy() {
@@ -120,6 +128,7 @@
}, },
methods: { methods: {
...mapActions("message", ["pushNewMessage", "updateOneMessage"]), ...mapActions("message", ["pushNewMessage", "updateOneMessage"]),
date,
async createTextMessage() { async createTextMessage() {
let message = ""; let message = "";
const text = html2Text(this.inputHtml); const text = html2Text(this.inputHtml);
@@ -510,6 +519,9 @@
max-height: 120px; max-height: 120px;
padding: 10rpx 20rpx; padding: 10rpx 20rpx;
gap: 20rpx; gap: 20rpx;
.mute_tip{
}
.input_content { .input_content {
flex: 1; flex: 1;
@@ -1,6 +1,6 @@
<template> <template>
<view class="text_message_container bg_container"> <view class="text_message_container bg_container">
<u-parse :content="getContent" :previewImg="false" :showImgMenu="false" selectable></u-parse> <u-parse :content="getContent" :previewImg="false" :showImgMenu="false"></u-parse>
</view> </view>
</template> </template>
+27 -15
View File
@@ -26,7 +26,7 @@
import SelectHeader from "./components/SelectHeader"; import SelectHeader from "./components/SelectHeader";
import SelectFooter from "./components/SelectFooter"; import SelectFooter from "./components/SelectFooter";
import {markConversationAsRead} from "@/util/imCommon"; import {markConversationAsRead} from "@/util/imCommon";
import IMSDK, {MessageType} from "openim-uniapp-polyfill"; import IMSDK, {MessageType,GroupMemberRole} from "openim-uniapp-polyfill";
export default { export default {
components: { components: {
ChatingHeader, ChatingHeader,
@@ -52,8 +52,18 @@
...mapGetters([ ...mapGetters([
"storeHistoryMessageList", "storeHistoryMessageList",
"storeCurrentUserID", "storeCurrentUserID",
"storeCurrentConversation","storeCurrentMsg",'storeCurrentMsgID' "storeCurrentConversation",
"storeCurrentMsg",
'storeCurrentMsgID',
"storeCurrentGroup",
"storeCurrentMemberInGroup"
]), ]),
isOwner() {
return this.storeCurrentMemberInGroup.roleLevel === GroupMemberRole.Owner;
},
isAdmin() {
return this.storeCurrentMemberInGroup.roleLevel === GroupMemberRole.Admin;
},
}, },
created() { created() {
this.Audio = uni.createInnerAudioContext(); //音频 this.Audio = uni.createInnerAudioContext(); //音频
@@ -174,7 +184,7 @@
this.onUserMessageEvent({type: 'cancelSelect'}); this.onUserMessageEvent({type: 'cancelSelect'});
}, },
async doForwarMsg(userList, groupList, msgiem) async doForwarMsg(userList, groupList, msgiem)
{ {b
//console.log(userList,groupList); //console.log(userList,groupList);
const _this = this; const _this = this;
for (var i = 0; i < userList.length; i++) { for (var i = 0; i < userList.length; i++) {
@@ -234,7 +244,11 @@
} }
return; return;
} }
if (e.type == 'deleteMsg') { if (e.type == 'deleteMsg' || e.type == 'deleteServerMsg') {
let method = IMSDK.IMMethods.DeleteMessageFromLocalStorage;
if(e.type == 'deleteServerMsg'){
method = IMSDK.IMMethods.DeleteMessage
}
let deleteMsgs = []; let deleteMsgs = [];
if (!data) { if (!data) {
deleteMsgs = [...this.selectItems]; deleteMsgs = [...this.selectItems];
@@ -243,19 +257,11 @@
} }
for (let i = 0; i < deleteMsgs.length; i++) { for (let i = 0; i < deleteMsgs.length; i++) {
let element = deleteMsgs[i]; let element = deleteMsgs[i];
IMSDK.asyncApi(IMSDK.IMMethods.DeleteMessageFromLocalStorage, IMSDK.uuid(), { IMSDK.asyncApi(method, IMSDK.uuid(), {
//IMSDK.asyncApi(IMSDK.IMMethods.DeleteMessage, IMSDK.uuid(), {
conversationID: _this.storeCurrentConversation.conversationID, conversationID: _this.storeCurrentConversation.conversationID,
clientMsgID: element.clientMsgID clientMsgID: element.clientMsgID
}).then(res => { });
}).catch(res => {
console.log('catch',res);
}).finally(() => {
console.log('finally',arguments);
})
} }
this.selectItems = []; this.selectItems = [];
this.$refs.chatingListRef.loadMessageList(); this.$refs.chatingListRef.loadMessageList();
return; return;
@@ -316,7 +322,7 @@
}) })
return; return;
} }
if(e.type == 'audio_msg_click'){ if (e.type == 'audio_msg_click'){
if(_this.storeCurrentMsgID){ if(_this.storeCurrentMsgID){
_this.updateCurrentMsg({clientMsgID:""}); _this.updateCurrentMsg({clientMsgID:""});
}else{ }else{
@@ -338,6 +344,9 @@
if (_this.storeCurrentUserID == data.sendID && diff < 120000) { if (_this.storeCurrentUserID == data.sendID && diff < 120000) {
menu.push('撤回') menu.push('撤回')
} }
if(_this.isAdmin | _this.isOwner){
menu.push('删除(管理员功能)')
}
uni.showActionSheet({ uni.showActionSheet({
itemList: menu, itemList: menu,
success({tapIndex}) { success({tapIndex}) {
@@ -377,6 +386,9 @@
case "删除": case "删除":
_this.onUserMessageEvent({type: 'deleteMsg'}, data); _this.onUserMessageEvent({type: 'deleteMsg'}, data);
break; break;
case "删除(管理员功能)":
_this.onUserMessageEvent({type: 'deleteServerMsg'}, data);
break;
default: default:
break; break;
} }
+32 -1
View File
@@ -3,10 +3,12 @@
<u-navbar :autoBack="true" bgColor="#ECECEC" title="群管理" safeAreaInsetTop placeholder fixed></u-navbar> <u-navbar :autoBack="true" bgColor="#ECECEC" title="群管理" safeAreaInsetTop placeholder fixed></u-navbar>
<uni-list> <uni-list>
<uni-list-item title="群主管理权转让" @click="toTransfer" showArrow clickable></uni-list-item> <uni-list-item title="群主管理权转让" @click="toTransfer" showArrow clickable></uni-list-item>
<uni-list-item title="设置管理员" @click="setAdmin" showArrow clickable></uni-list-item>
<uni-list-item title="进群验证" @switchChange="updateGroupInfo('needVerification',storeCurrentGroup.needVerification==1 ? 2: 1)" showSwitch :switchChecked="!(storeCurrentGroup.needVerification != 1)"></uni-list-item> <uni-list-item title="进群验证" @switchChange="updateGroupInfo('needVerification',storeCurrentGroup.needVerification==1 ? 2: 1)" showSwitch :switchChecked="!(storeCurrentGroup.needVerification != 1)"></uni-list-item>
<!-- <uni-list-item title="进群验证" :rightText="verifyTypeText" @click="changeVerify" clickable></uni-list-item> -->
<uni-list-item title="允许查看成员资料" @switchChange="updateGroupInfo('lookMemberInfo',storeCurrentGroup.applyMemberFriend == 1 ? 0 : 1)" showSwitch :switchChecked="storeCurrentGroup.applyMemberFriend==0"></uni-list-item> <uni-list-item title="允许查看成员资料" @switchChange="updateGroupInfo('lookMemberInfo',storeCurrentGroup.applyMemberFriend == 1 ? 0 : 1)" showSwitch :switchChecked="storeCurrentGroup.applyMemberFriend==0"></uni-list-item>
<uni-list-item title="允许群内添加好友" @switchChange="updateGroupInfo('applyMemberFriend',storeCurrentGroup.applyMemberFriend == 1 ? 0 : 1)" showSwitch :switchChecked="storeCurrentGroup.applyMemberFriend==0"></uni-list-item> <uni-list-item title="允许群内添加好友" @switchChange="updateGroupInfo('applyMemberFriend',storeCurrentGroup.applyMemberFriend == 1 ? 0 : 1)" showSwitch :switchChecked="storeCurrentGroup.applyMemberFriend==0"></uni-list-item>
<uni-list-item :title="isMute ? '解除禁言':'全员禁言'" @switchChange="updateMute" showSwitch :switchChecked="isMute"></uni-list-item> <uni-list-item title="全员禁言" @switchChange="updateMute" showSwitch :switchChecked="isMute"></uni-list-item>
</uni-list> </uni-list>
</view> </view>
@@ -28,8 +30,19 @@
"storeCurrentMemberInGroup", "storeCurrentMemberInGroup",
"storeCurrentGroup", "storeCurrentGroup",
]), ]),
verifyTypeText(){
if(this.storeCurrentGroup.needVerification === 0){
return '0'
}
if(this.storeCurrentGroup.needVerification === 1){
return '1'
}
return '2';
}
}, },
onLoad() { onLoad() {
this.isMute = this.storeCurrentGroup.status == 3;
//console.log(this.storeCurrentGroup);
// IMSDK.asyncApi('getSpecifiedGroupsInfo', IMSDK.uuid(), [this.storeCurrentGroup.groupID]).then(res=>{ // IMSDK.asyncApi('getSpecifiedGroupsInfo', IMSDK.uuid(), [this.storeCurrentGroup.groupID]).then(res=>{
// console.log(res); // console.log(res);
// }).catch(e=>{ // }).catch(e=>{
@@ -42,7 +55,13 @@
url: `/pages/conversation/groupMemberList/index?type=${GroupMemberListTypes.Transfer}&groupID=${this.storeCurrentGroup.groupID}`, url: `/pages/conversation/groupMemberList/index?type=${GroupMemberListTypes.Transfer}&groupID=${this.storeCurrentGroup.groupID}`,
}); });
}, },
setAdmin(){
uni.navigateTo({
url: `/pages/conversation/groupMemberList/index?type=${GroupMemberListTypes.setAdmin}&groupID=${this.storeCurrentGroup.groupID}`,
});
},
updateMute(){ updateMute(){
this.isMute = !this.isMute;
IMSDK.asyncApi('changeGroupMute', IMSDK.uuid(), { IMSDK.asyncApi('changeGroupMute', IMSDK.uuid(), {
groupID: this.storeCurrentGroup.groupID, groupID: this.storeCurrentGroup.groupID,
isMute: this.isMute isMute: this.isMute
@@ -61,6 +80,18 @@
console.log(e); console.log(e);
}) })
}, },
changeVerify(){
uni.showActionSheet({
itemList:[
'申请进群需要群主或管理员同意;群成员邀请可以直接进群',
'申请进群需要群主或管理员同意;群主和管理员邀请可以直接进群;普通成员邀请进群需群主或管理员同意',
'直接进群'
],
success(res){
console.log(res);
}
})
}
}, },
}; };
</script> </script>
@@ -1,126 +1,128 @@
<template> <template>
<custom-nav-bar @leftClick="leftClick" :title="getTitle"> <custom-nav-bar @leftClick="leftClick" :title="getTitle">
</custom-nav-bar> </custom-nav-bar>
</template> </template>
<script> <script>
import CustomNavBar from "@/components/CustomNavBar/index.vue"; import CustomNavBar from "@/components/CustomNavBar/index.vue";
import { ContactChooseTypes } from "@/constant"; import {
export default { ContactChooseTypes
name: "", } from "@/constant";
components: { export default {
CustomNavBar, name: "",
}, components: {
props: { CustomNavBar,
checkVisible: { },
type: Boolean, props: {
default: false, checkVisible: {
}, type: Boolean,
isNomal: { default: false,
type: Boolean, },
default: false, isNomal: {
}, type: Boolean,
isTransfer: { default: false,
type: Boolean, },
default: false, isTransfer: {
}, type: Boolean,
isAt: { default: false,
type: Boolean, },
default: false, isAt: {
}, type: Boolean,
isSetAdmin: { default: false,
type: Boolean, },
default: false, isSetAdmin: {
}, type: Boolean,
isMute: { default: false,
type: Boolean, },
default: false, isMute: {
}, type: Boolean,
isCall: { default: false,
type: Boolean, },
default: false, isCall: {
}, type: Boolean,
groupID: String, default: false,
}, },
data() { groupID: String,
return { },
moreMenuVisible: false, data() {
}; return {
}, moreMenuVisible: false,
computed: { };
getTitle() { },
if (this.isCall) { computed: {
return "邀请成员"; getTitle() {
} if (this.isCall) {
if (this.isAt) { return "邀请成员";
return "选择提醒的人"; }
} if (this.isAt) {
if (this.isSetAdmin) { return "选择提醒的人";
return "设置管理员"; }
} if (this.isSetAdmin) {
if (this.isMute) { return "设置管理员";
return "禁言成员"; }
} if (this.isMute) {
if (this.checkVisible) { return "禁言成员";
return "移除群成员"; }
} if (this.checkVisible) {
return "群成员"; return "移除群成员";
}, }
}, return "群成员";
methods: { },
leftClick() { },
if (this.checkVisible) { methods: {
this.$emit("update:checkVisible", false); leftClick() {
} if (this.checkVisible) {
}, this.$emit("update:checkVisible", false);
rightClick() { }
this.moreMenuVisible = true; },
}, rightClick() {
checkMenu() { this.moreMenuVisible = true;
if (this.moreMenuVisible) { },
this.moreMenuVisible = false; checkMenu() {
} if (this.moreMenuVisible) {
}, this.moreMenuVisible = false;
inviteMember() { }
uni.navigateTo({ },
url: `/pages/common/contactChoose/index?type=${ContactChooseTypes.Invite}&groupID=${this.groupID}`, inviteMember() {
}); uni.navigateTo({
}, url: `/pages/common/contactChoose/index?type=${ContactChooseTypes.Invite}&groupID=${this.groupID}`,
removeMember() { });
this.$emit("removeMember"); },
}, removeMember() {
}, this.$emit("removeMember");
}; },
},
};
</script> </script>
<style lang="scss"> <style lang="scss">
.more_container { .more_container {
position: relative; position: relative;
.more_dot { .more_dot {
padding: 24rpx; padding: 24rpx;
margin-right: 20rpx; margin-right: 20rpx;
} }
.more_menu { .more_menu {
position: absolute; position: absolute;
bottom: 0; bottom: 0;
left: 50%; left: 50%;
transform: translate(-100%, 100%); transform: translate(-100%, 100%);
box-shadow: 0px 0px 6px 2px rgba(0, 0, 0, 0.16); box-shadow: 0px 0px 6px 2px rgba(0, 0, 0, 0.16);
width: max-content; width: max-content;
border-radius: 8rpx; border-radius: 8rpx;
background-color: #fff; background-color: #fff;
.menu_item { .menu_item {
padding: 20rpx 48rpx; padding: 20rpx 48rpx;
font-size: 28rpx; font-size: 28rpx;
color: $uni-text-color; color: $uni-text-color;
// &:nth-child(1) { // &:nth-child(1) {
// border-bottom: 1px solid #F0F0F0; // border-bottom: 1px solid #F0F0F0;
// } // }
} }
} }
} }
</style> </style>
+167 -20
View File
@@ -1,7 +1,14 @@
<template> <template>
<view @click="pageClick" class="group_members_container"> <view @click="pageClick" class="group_members_container">
<group-member-list-header ref="navHeaderRef" :checkVisible.sync="showCheck" :isTransfer="isTransfer" <group-member-list-header
:isNomal="!isOwner && !isAdmin" :groupID="groupID" @removeMember="showMemberCheck" /> ref="navHeaderRef"
:checkVisible.sync="showCheck"
:isTransfer="isTransfer"
:isSetAdmin="isSetAdmin"
:isNomal="!isOwner && !isAdmin"
:groupID="groupID"
@removeMember="showMemberCheck"
/>
<view class="search_bar_wrap"> <view class="search_bar_wrap">
<u-search disabled class="search_bar" shape="square" placeholder="搜索" :showAction="false" <u-search disabled class="search_bar" shape="square" placeholder="搜索" :showAction="false"
@@ -10,22 +17,35 @@
<u-list class="member_list" @scrolltolower="loadMore" lowerThreshold="100" height="1"> <u-list class="member_list" @scrolltolower="loadMore" lowerThreshold="100" height="1">
<u-list-item v-for="member in groupMemberList" :key="member.userID"> <u-list-item v-for="member in groupMemberList" :key="member.userID">
<user-item @itemClick="userClick" @updateCheck="updateCheck" :checked="isChecked(member.userID)" <user-item
:checkVisible="showCheck" :disabled="!canCheck(member) && showCheck" :item="member" /> @itemClick="userClick"
@updateCheck="updateCheck"
@longtapEvent="longtap"
:checked="isChecked(member.userID)"
:checkVisible="showCheck"
:disabled="!canCheck(member) && showCheck" :item="member"
/>
</u-list-item> </u-list-item>
<view v-show="loadState.loading" class="member_loading"> <view v-show="loadState.loading" class="member_loading">
<u-loading-icon></u-loading-icon> <u-loading-icon></u-loading-icon>
</view> </view>
</u-list> </u-list>
<choose-index-footer v-if="showCheck" :comfirmLoading="comfirmLoading" @removeItem="updateCheck" <choose-index-footer
@confirm="confirm" :choosedData="getChoosedData" :isRemove="isRemove" :maxLength="groupMemberLength" /> v-if="showCheck"
:comfirmLoading="comfirmLoading"
@removeItem="updateCheck"
@confirm="confirm"
:choosedData="getChoosedData"
:isRemove="isRemove"
:maxLength="groupMemberLength" />
<u-modal :show="showConfirmModal" asyncClose showCancelButton @confirm="modalConfirm" <u-modal
@cancel="() => (showConfirmModal = false)" :content=" :show="showConfirmModal"
isRemove asyncClose
? '确定移除已选群成员?' showCancelButton
: `确定要把群主转移给${choosedTransferMember.nickname}吗?` @confirm="modalConfirm"
@cancel="() => (showConfirmModal = false)" :content="isRemove? '确定移除已选群成员?': `确定要把群主转移给${choosedTransferMember.nickname}吗?`
" /> " />
<u-toast ref="uToast"></u-toast> <u-toast ref="uToast"></u-toast>
</view> </view>
@@ -61,6 +81,7 @@
hasMore: true, hasMore: true,
loading: false, loading: false,
}, },
adminUserIdList:[]
}; };
}, },
computed: { computed: {
@@ -82,6 +103,9 @@
isTransfer() { isTransfer() {
return this.type === GroupMemberListTypes.Transfer; return this.type === GroupMemberListTypes.Transfer;
}, },
isSetAdmin() {
return this.type === GroupMemberListTypes.setAdmin;
},
isChecked() { isChecked() {
return (userID) => this.choosedMemberIDList.includes(userID); return (userID) => this.choosedMemberIDList.includes(userID);
}, },
@@ -93,8 +117,7 @@
}, },
isAdmin() { isAdmin() {
return ( return (
this.$store.getters.storeCurrentMemberInGroup.roleLevel === this.$store.getters.storeCurrentMemberInGroup.roleLevel === GroupMemberRole.Admin
GroupMemberRole.Admin
); );
}, },
canCheck() { canCheck() {
@@ -125,12 +148,29 @@
this.loadMemberList(groupID); this.loadMemberList(groupID);
this.type = type; this.type = type;
this.groupID = groupID; this.groupID = groupID;
this.isRightKick = type === GroupMemberListTypes.Kickout; this.isRightKick = (type == GroupMemberListTypes.setAdmin|| type === GroupMemberListTypes.Kickout);
if ( if (this.isRightKick) {
this.isRightKick
) {
this.showCheck = true; 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: { methods: {
async pageClick(e) { async pageClick(e) {
@@ -146,8 +186,36 @@
this.$refs.navHeaderRef.checkMenu(); this.$refs.navHeaderRef.checkMenu();
} }
}, },
confirm() { async confirm() {
this.showConfirmModal = true; 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() { modalConfirm() {
let func = () => {}; let func = () => {};
@@ -182,7 +250,6 @@
} else { } else {
this.choosedMemberIDList = [...this.choosedMemberIDList, userID]; this.choosedMemberIDList = [...this.choosedMemberIDList, userID];
} }
console.log(this.choosedMemberIDList);
}, },
userClick(member) { userClick(member) {
if (this.type === GroupMemberListTypes.Transfer) { if (this.type === GroupMemberListTypes.Transfer) {
@@ -227,6 +294,86 @@
}) })
.finally(() => (this.loadState.loading = false)); .finally(() => (this.loadState.loading = false));
}, },
longtap(member){
const _this = this;
if(this.isRightKick){
return ;
}
if(!this.isOwner&&!this.isAdmin){
return ;
}
if(this.$store.getters.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}) {
if(tapIndex == 0){
let roleId = itemList[tapIndex]=='设为管理员' ? 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(tapIndex == 1){
if(itemList[tapIndex]=='取消禁言'){
_this.setMute(member.userID,0)
return ;
}
uni.showActionSheet({
itemList:['2小时','8小时','1天','3天','7天','15天','30天','1年'],
async 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(tapIndex == 2){
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) { showToast(message, complete = null) {
this.$refs.uToast.show({ this.$refs.uToast.show({
message, message,
@@ -11,6 +11,7 @@
<view class="member_item" v-for="(member, index) in groupMemberList" :key="member.userID"> <view class="member_item" v-for="(member, index) in groupMemberList" :key="member.userID">
<my-avatar :src="member.faceURL" :desc="member.nickname" :key="member.userID" size="48" /> <my-avatar :src="member.faceURL" :desc="member.nickname" :key="member.userID" size="48" />
<view class="ower" v-if="member.roleLevel === 100">群主</view> <view class="ower" v-if="member.roleLevel === 100">群主</view>
<view class="ower" v-if="member.roleLevel === 60">管理员</view>
<text class="member_item_name">{{ member.nickname }}</text> <text class="member_item_name">{{ member.nickname }}</text>
</view> </view>
<view class="member_item"> <view class="member_item">
+6 -16
View File
@@ -3,26 +3,16 @@
<u-navbar :autoBack="true" bgColor="#ECECEC" :title="'群聊设置('+storeCurrentGroup.memberCount+')'" safeAreaInsetTop placeholder fixed></u-navbar> <u-navbar :autoBack="true" bgColor="#ECECEC" :title="'群聊设置('+storeCurrentGroup.memberCount+')'" safeAreaInsetTop placeholder fixed></u-navbar>
<view class="group_settings_content"> <view class="group_settings_content">
<view class="setting_row info_row">
<view class="group_avatar" @click="updateGroupAvatar">
<my-avatar :src="storeCurrentConversation.faceURL" :isGroup="true" size="46" />
<image v-if="isOwner" class="edit_icon" src="@/static/images/group_setting_edit.png" alt="" />
</view>
<view class="group_info">
<view class="group_info_name">
<text class="group_name">{{ storeCurrentConversation.showName }}({{storeCurrentGroup.memberCount}})</text>
<image v-if="isOwner || isAdmin" @click="toUpdateGroupName" style="width: 24rpx; height: 24rpx" src="@/static/images/group_edit.png" alt="" />
</view>
<text @click="copyGroupID" class="sub_title">{{storeCurrentConversation.groupID}}</text>
</view>
</view>
<group-member-row v-if="isJoinGroup" :isNomal="!isAdmin && !isOwner" <group-member-row v-if="isJoinGroup" :isNomal="!isAdmin && !isOwner"
:groupID="storeCurrentConversation.groupID" :memberCount="storeCurrentGroup.memberCount" :groupID="storeCurrentConversation.groupID" :memberCount="storeCurrentGroup.memberCount"
:groupMemberList="groupMemberList" /> :groupMemberList="groupMemberList" />
<uni-list> <uni-list>
<uni-list-item title="群图标" @click="updateGroupAvatar" clickable showArrow>
<template v-slot:footer>
<my-avatar :src="storeCurrentConversation.faceURL" :isGroup="true" size="46" />
</template>
</uni-list-item>
<uni-list-item title="群聊名称" :rightText="storeCurrentConversation.showName" @click="editGroupName" :clickable="isOwner || isAdmin" :showArrow="isOwner || isAdmin"></uni-list-item> <uni-list-item title="群聊名称" :rightText="storeCurrentConversation.showName" @click="editGroupName" :clickable="isOwner || isAdmin" :showArrow="isOwner || isAdmin"></uni-list-item>
<uni-list-item title="群公告" to="/pages/conversation/groupSettings/announcement" clickable showArrow></uni-list-item> <uni-list-item title="群公告" to="/pages/conversation/groupSettings/announcement" clickable showArrow></uni-list-item>
<uni-list-item title="群二维码" :to="getGroupQrcdeUrl" clickable showArrow></uni-list-item> <uni-list-item title="群二维码" :to="getGroupQrcdeUrl" clickable showArrow></uni-list-item>
@@ -95,7 +85,7 @@
}; };
}, },
onShow() { onShow() {
console.log(this.storeCurrentConversation); //console.log(this.storeCurrentConversation);
/* /*
this.$store.commit("conversation/SET_CURRENT_CONVERSATION", { this.$store.commit("conversation/SET_CURRENT_CONVERSATION", {
"conversationID": "sg_1793688611", "conversationID": "sg_1793688611",
+1 -1
View File
@@ -104,7 +104,7 @@ const actions = {
); );
}, },
updateCurrentMemberInGroup({commit,state}, memberInfo) { updateCurrentMemberInGroup({commit,state}, memberInfo) {
console.log(memberInfo); //console.log(memberInfo);
if ( if (
memberInfo.groupID === state.currentMemberInGroup.groupID && memberInfo.groupID === state.currentMemberInGroup.groupID &&
memberInfo.userID === state.currentMemberInGroup.userID memberInfo.userID === state.currentMemberInGroup.userID
+13 -5
View File
@@ -30,6 +30,10 @@ dayjs.updateLocale("zh-cn", {
}, },
}); });
export const date = (timestemp, fmt = 'YYYY-MM-DD HH:mm:ss') => {
if (!timestemp) return "";
return dayjs(timestemp).format(fmt)
};
export const formatMessageTime = (timestemp, keepSameYear = false) => { export const formatMessageTime = (timestemp, keepSameYear = false) => {
if (!timestemp) return ""; if (!timestemp) return "";
const isRecent = dayjs().diff(timestemp, "day") < 7; const isRecent = dayjs().diff(timestemp, "day") < 7;
@@ -175,16 +179,20 @@ export const parseMessageByType = (pmsg) => {
return `${getName(kickOpUser)}踢出了${kickStr}${kickdUserList.length > 3 ? "..." : ""}`; return `${getName(kickOpUser)}踢出了${kickStr}${kickdUserList.length > 3 ? "..." : ""}`;
case MessageType.GroupMemberMuted: case MessageType.GroupMemberMuted:
//群成员禁言通知 //群成员禁言通知
return `[GroupMemberMuted]`; const groupMemberMutedDetail = JSON.parse(pmsg.notificationElem.detail);
return `${getName(groupMemberMutedDetail.opUser)}取消了${getName(groupMemberMutedDetail.mutedUser)}的禁言`;
case MessageType.GroupMemberCancelMuted: case MessageType.GroupMemberCancelMuted:
//取消群成员禁言通知 //取消群成员禁言通知
return `[GroupMemberCancelMuted]`; const groupMemberCancelMutedDetail = JSON.parse(pmsg.notificationElem.detail);
return `${getName(groupMemberCancelMutedDetail.opUser)}禁言了${getName(groupMemberCancelMutedDetail.mutedUser)}`;
case MessageType.GroupMuted: case MessageType.GroupMuted:
//群禁言通知 //群禁言通知
return `[GroupMuted]`; const groupGroupMutedDetail = JSON.parse(pmsg.notificationElem.detail);
return `${getName(groupGroupMutedDetail.opUser)}设置了全员禁言`;
case MessageType.GroupCancelMuted: case MessageType.GroupCancelMuted:
//取消群禁言通知 //取消群禁言通知
return `[GroupCancelMuted]`; const groupGroupCancelMutedDetail = JSON.parse(pmsg.notificationElem.detail);
return `${getName(groupGroupCancelMutedDetail.opUser)}取消了全员禁言`;
case MessageType.MemberQuit: case MessageType.MemberQuit:
const quitDetails = JSON.parse(pmsg.notificationElem.detail); const quitDetails = JSON.parse(pmsg.notificationElem.detail);
const quitUser = quitDetails.quitUser; const quitUser = quitDetails.quitUser;
@@ -210,9 +218,9 @@ export const parseMessageByType = (pmsg) => {
//群公告更新 //群公告更新
const groupAnnouncementUpdatedDetail = JSON.parse(pmsg.notificationElem.detail); const groupAnnouncementUpdatedDetail = JSON.parse(pmsg.notificationElem.detail);
return `${getName(groupAnnouncementUpdatedDetail.opUser)}更新了群公告`; return `${getName(groupAnnouncementUpdatedDetail.opUser)}更新了群公告`;
return `[GroupAnnouncementUpdated]`;
case MessageType.BurnMessageChange: case MessageType.BurnMessageChange:
//阅后即焚开启或关闭通知 //阅后即焚开启或关闭通知
//console.log(pmsg);
return `[BurnMessageChange]`; return `[BurnMessageChange]`;
case MessageType.RevokeMessage: case MessageType.RevokeMessage:
let notificationElem = JSON.parse(pmsg.notificationElem.detail); let notificationElem = JSON.parse(pmsg.notificationElem.detail);