You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
437 lines
10 KiB
437 lines
10 KiB
<template> |
|
<div> |
|
<el-drawer |
|
title="群设置" |
|
:visible.sync="visible" |
|
:size="400" |
|
append-to-body |
|
direction="rtl" |
|
> |
|
<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-drawer> |
|
|
|
<!-- 添加成员弹窗 --> |
|
<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, |
|
groupInfo: Object, |
|
}, |
|
|
|
data() { |
|
return { |
|
visible: false, |
|
isSearchVisible: false, |
|
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; |
|
}, |
|
|
|
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>
|
|
|