|
|
|
|
<template>
|
|
|
|
|
<div>
|
|
|
|
|
<el-dialog
|
|
|
|
|
title="群设置"
|
|
|
|
|
:visible.sync="visible"
|
|
|
|
|
width="400px"
|
|
|
|
|
append-to-body
|
|
|
|
|
>
|
|
|
|
|
<div class="group-setting">
|
|
|
|
|
<!-- 群头像和名称 -->
|
|
|
|
|
<div class="group-info">
|
|
|
|
|
<el-avatar
|
|
|
|
|
:size="40"
|
|
|
|
|
:src="
|
|
|
|
|
$store.state.user.netConfig.MINIO_ENDPOINT_HTTPS +
|
|
|
|
|
groupInfo.avatar
|
|
|
|
|
"
|
|
|
|
|
class="group-avatar"
|
|
|
|
|
:icon="'el-icon-s-custom'"
|
|
|
|
|
>
|
|
|
|
|
<span class="avatar-text"> {{ groupInfo.name }}</span>
|
|
|
|
|
</el-avatar>
|
|
|
|
|
<div class="group-detail">
|
|
|
|
|
<div class="group-name">{{ groupInfo.name }}</div>
|
|
|
|
|
</div>
|
|
|
|
|
<el-button
|
|
|
|
|
class="edit-btn"
|
|
|
|
|
type="text"
|
|
|
|
|
icon="el-icon-edit"
|
|
|
|
|
@click="editGroupName"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="section">
|
|
|
|
|
<div class="section-title">群成员 {{ groupInfo.user_num }}人</div>
|
|
|
|
|
<div class="member-list">
|
|
|
|
|
<div class="member-item" @click="showAddMember">
|
|
|
|
|
<el-icon
|
|
|
|
|
class="el-icon-circle-plus-outline"
|
|
|
|
|
style="font-size: 40px"
|
|
|
|
|
/>
|
|
|
|
|
<span class="member-name">添加成员</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
v-for="member in groupInfo.user_list"
|
|
|
|
|
:key="member.id"
|
|
|
|
|
class="member-item"
|
|
|
|
|
@mouseenter="showDeleteBtn = member.id"
|
|
|
|
|
@mouseleave="showDeleteBtn = null"
|
|
|
|
|
>
|
|
|
|
|
<div class="avatar-wrapper">
|
|
|
|
|
<el-avatar
|
|
|
|
|
:size="40"
|
|
|
|
|
:src="
|
|
|
|
|
$store.state.user.netConfig.MINIO_ENDPOINT_HTTPS +
|
|
|
|
|
member.avatar
|
|
|
|
|
"
|
|
|
|
|
/>
|
|
|
|
|
<span
|
|
|
|
|
v-if="
|
|
|
|
|
userInfo.id === groupInfo.user_id &&
|
|
|
|
|
userInfo.id !== member.id &&
|
|
|
|
|
showDeleteBtn === member.id
|
|
|
|
|
"
|
|
|
|
|
class="delete-btn"
|
|
|
|
|
@click.stop="handleRemoveMember(member)"
|
|
|
|
|
>
|
|
|
|
|
<i class="el-icon-minus" />
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<span class="member-name">{{ member.name }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 群管理员 -->
|
|
|
|
|
<div
|
|
|
|
|
v-if="groupInfo.user_list.some((m) => m.id === groupInfo.user_id)"
|
|
|
|
|
class="section"
|
|
|
|
|
>
|
|
|
|
|
<div class="section-title">群管理员</div>
|
|
|
|
|
<div class="member-list">
|
|
|
|
|
<div
|
|
|
|
|
v-for="member in groupInfo.user_list.filter(
|
|
|
|
|
(m) => m.id === groupInfo.user_id
|
|
|
|
|
)"
|
|
|
|
|
:key="member.id"
|
|
|
|
|
class="member-item"
|
|
|
|
|
>
|
|
|
|
|
<el-avatar
|
|
|
|
|
:size="40"
|
|
|
|
|
:src="
|
|
|
|
|
$store.state.user.netConfig.MINIO_ENDPOINT_HTTPS +
|
|
|
|
|
member.avatar
|
|
|
|
|
"
|
|
|
|
|
/>
|
|
|
|
|
<span class="member-name">{{ member.name }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 操作按钮 -->
|
|
|
|
|
<div class="actions">
|
|
|
|
|
<el-button type="danger" @click="handleQuitGroup">
|
|
|
|
|
退出群组
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button
|
|
|
|
|
type="danger"
|
|
|
|
|
plain
|
|
|
|
|
@click="handleDismissGroup"
|
|
|
|
|
v-show="userInfo.id === groupInfo.user_id"
|
|
|
|
|
>
|
|
|
|
|
解散群组
|
|
|
|
|
</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
<!-- 添加成员弹窗 -->
|
|
|
|
|
<CreateGroupDialog
|
|
|
|
|
ref="addMemberDialog"
|
|
|
|
|
title="添加成员"
|
|
|
|
|
:minSelectCount="1"
|
|
|
|
|
@confirm="handleAddMembers"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import {
|
|
|
|
|
getMultiChatInfo,
|
|
|
|
|
inviteToMultiChat,
|
|
|
|
|
editMultiChatName,
|
|
|
|
|
quitMultiChat,
|
|
|
|
|
dismissMultiChat,
|
|
|
|
|
} from "@/api/multichat";
|
|
|
|
|
import CreateGroupDialog from "./CreateGroupDialog.vue";
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: "GroupSetting",
|
|
|
|
|
|
|
|
|
|
components: {
|
|
|
|
|
CreateGroupDialog,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
props: {
|
|
|
|
|
chat: Object,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
visible: false,
|
|
|
|
|
isSearchVisible: false,
|
|
|
|
|
groupInfo: {},
|
|
|
|
|
isAdmin: false,
|
|
|
|
|
showDeleteBtn: null,
|
|
|
|
|
currentUserId: this.$store.state.user.userInfo?.id,
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
userInfo() {
|
|
|
|
|
return this.$store.state.user.userInfo;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
async loadGroupInfo() {
|
|
|
|
|
this.visible = true;
|
|
|
|
|
if (this.chat) {
|
|
|
|
|
if (!this.chat?.id) return;
|
|
|
|
|
try {
|
|
|
|
|
const res = await getMultiChatInfo({ multi_chat_id: this.chat.id });
|
|
|
|
|
this.groupInfo = {
|
|
|
|
|
...res.data,
|
|
|
|
|
user_list: res.data.user_list.sort((a, b) => a.id - b.id),
|
|
|
|
|
};
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error("获取群信息失败", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
editGroupName() {
|
|
|
|
|
let multi_chat_id = this.chat.id;
|
|
|
|
|
this.$prompt("请输入新的群名称", "修改群名称", {
|
|
|
|
|
confirmButtonText: "确定",
|
|
|
|
|
cancelButtonText: "取消",
|
|
|
|
|
inputValue: this.groupInfo.name,
|
|
|
|
|
})
|
|
|
|
|
.then(({ value }) => {
|
|
|
|
|
editMultiChatName({
|
|
|
|
|
multi_chat_id: multi_chat_id,
|
|
|
|
|
name: value,
|
|
|
|
|
}).then(() => {
|
|
|
|
|
this.groupInfo.name = value;
|
|
|
|
|
this.$message.success("群名称修改成功");
|
|
|
|
|
// 触发刷新列表事件
|
|
|
|
|
this.$emit("refresh-list");
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {
|
|
|
|
|
this.$message.info("已取消修改");
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
showSearchRecord() {
|
|
|
|
|
this.isSearchVisible = true;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handleLocateMessage(result) {
|
|
|
|
|
this.$message.info(`定位到消息: ${result.text}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
showAddMember() {
|
|
|
|
|
this.$refs.addMemberDialog.show();
|
|
|
|
|
},
|
|
|
|
|
async handleAddMembers(selectedMembers) {
|
|
|
|
|
await inviteToMultiChat({
|
|
|
|
|
multi_chat_id: this.chat.id,
|
|
|
|
|
invite_users: selectedMembers.map((m) => m.id),
|
|
|
|
|
});
|
|
|
|
|
// 重新加载群信息
|
|
|
|
|
await this.loadGroupInfo();
|
|
|
|
|
// 触发刷新列表事件
|
|
|
|
|
this.$emit("refresh-list");
|
|
|
|
|
this.$message.success("添加成员成功");
|
|
|
|
|
},
|
|
|
|
|
handleRemoveMember(member) {
|
|
|
|
|
this.$confirm(`确定要将该成员踢出群聊吗?`, "提示", {
|
|
|
|
|
confirmButtonText: "确定",
|
|
|
|
|
cancelButtonText: "取消",
|
|
|
|
|
type: "warning",
|
|
|
|
|
})
|
|
|
|
|
.then(() => {
|
|
|
|
|
quitMultiChat({
|
|
|
|
|
// 固定值:移除成员
|
|
|
|
|
invite_type_detail: 9,
|
|
|
|
|
// 群聊ID
|
|
|
|
|
multi_chat_id: this.chat.id,
|
|
|
|
|
// 被移除成员ID
|
|
|
|
|
user_id: member.id,
|
|
|
|
|
}).then(() => {
|
|
|
|
|
this.$message.success("移除成功");
|
|
|
|
|
// 重新加载群信息
|
|
|
|
|
this.loadGroupInfo();
|
|
|
|
|
// 触发刷新列表事件
|
|
|
|
|
this.$emit("refresh-list");
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {
|
|
|
|
|
this.$message.info("已取消移除");
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
handleQuitGroup() {
|
|
|
|
|
this.$confirm("确定要退出该群组吗?", "提示", {
|
|
|
|
|
confirmButtonText: "确定",
|
|
|
|
|
cancelButtonText: "取消",
|
|
|
|
|
type: "warning",
|
|
|
|
|
})
|
|
|
|
|
.then(() => {
|
|
|
|
|
quitMultiChat({
|
|
|
|
|
// 固定值:退出群聊
|
|
|
|
|
invite_type_detail: 8,
|
|
|
|
|
// // 群聊ID
|
|
|
|
|
multi_chat_id: this.chat.id,
|
|
|
|
|
// 当前登录用户ID
|
|
|
|
|
user_id: this.currentUserId,
|
|
|
|
|
}).then(() => {
|
|
|
|
|
this.$message.success("退出成功");
|
|
|
|
|
// 触发刷新列表事件
|
|
|
|
|
this.visible = false;
|
|
|
|
|
this.$emit("quit-group", this.chat);
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {
|
|
|
|
|
this.$message.info("已取消退出");
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
handleDismissGroup() {
|
|
|
|
|
this.$confirm("确定要解散群组吗?", "提示", {
|
|
|
|
|
confirmButtonText: "确定",
|
|
|
|
|
cancelButtonText: "取消",
|
|
|
|
|
type: "error",
|
|
|
|
|
})
|
|
|
|
|
.then(() => {
|
|
|
|
|
dismissMultiChat({
|
|
|
|
|
// 群聊ID
|
|
|
|
|
multi_chat_id: this.chat.id,
|
|
|
|
|
}).then(() => {
|
|
|
|
|
this.$message.success("解散成功");
|
|
|
|
|
// 触发刷新列表事件
|
|
|
|
|
this.visible = false;
|
|
|
|
|
this.$emit("dismiss-group", this.chat);
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {
|
|
|
|
|
this.$message.info("已取消解散");
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.group-info {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
|
|
|
|
.group-avatar {
|
|
|
|
|
margin-right: 15px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.avatar-text {
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
color: #409eff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.group-detail {
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
|
|
|
|
.group-member-count {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #909399;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.edit-btn {
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.section {
|
|
|
|
|
.section-title {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: #303133;
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.member-list {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.member-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
width: calc(100% / 5);
|
|
|
|
|
|
|
|
|
|
.avatar-wrapper {
|
|
|
|
|
position: relative;
|
|
|
|
|
|
|
|
|
|
.delete-btn {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: -8px;
|
|
|
|
|
right: -8px;
|
|
|
|
|
width: 20px;
|
|
|
|
|
height: 20px;
|
|
|
|
|
background: #f56c6c;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
opacity: 0;
|
|
|
|
|
transition: opacity 0.2s;
|
|
|
|
|
|
|
|
|
|
i {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #fff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&:hover .delete-btn {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.member-name {
|
|
|
|
|
margin-top: 6px;
|
|
|
|
|
margin-bottom: 6px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #606266;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.admin-tag {
|
|
|
|
|
font-size: 10px;
|
|
|
|
|
color: #409eff;
|
|
|
|
|
background: #ecf5ff;
|
|
|
|
|
padding: 2px 6px;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
margin-top: 4px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.add-member-btn {
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
color: #409eff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.search-record-btn {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 15px;
|
|
|
|
|
background: #fff;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
background: #f5f7fa;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i:first-child {
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
color: #409eff;
|
|
|
|
|
margin-right: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.btn-text {
|
|
|
|
|
flex: 1;
|
|
|
|
|
font-size: 15px;
|
|
|
|
|
color: #303133;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.btn-desc {
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
color: #909399;
|
|
|
|
|
margin-right: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i:last-child {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #c0c4cc;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.actions {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
gap: 15px;
|
|
|
|
|
padding-top: 15px;
|
|
|
|
|
border-top: 1px solid #ebeef5;
|
|
|
|
|
|
|
|
|
|
.el-button {
|
|
|
|
|
width: 120px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|