admin-vue3/src/views/im/home/components/group/GroupAdminSetDialog.vue

122 lines
3.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<!--
设置群管理员一个弹窗合并增 / 提交时跟当前管理员列表 diff
- dialog 壳本组件持有选择 UI 委托 GroupMemberPickerPanelgrid 形态对齐当前视觉
- 群主从候选里隐藏不能设为管理员
- 对外接口ref + open({ groupId, members, currentAdminIds, hideIds, maxSize }) + emit reload()
-->
<el-dialog
v-model="visible"
title="设置群管理员"
width="700px"
:close-on-click-modal="false"
class="im-picker-dialog"
>
<div class="h-[480px]">
<GroupMemberPickerPanel
v-model:selected-ids="selectedIds"
:members="members"
:hide-ids="hideIds"
:max-size="maxSize"
selected-display="grid"
/>
</div>
<template #footer>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" :loading="submitting" @click="handleOk">确定</el-button>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { useMessage } from '@/hooks/web/useMessage'
import { addGroupAdmin, removeGroupAdmin } from '@/api/im/group'
import { GROUP_ADMIN_MAX_COUNT } from '@/views/im/utils/config'
import GroupMemberPickerPanel from '../picker/GroupMemberPickerPanel.vue'
import type { GroupMemberLite } from './GroupMember.vue'
defineOptions({ name: 'ImGroupAdminSetDialog' })
const emit = defineEmits<{
/** 管理员变更成功;父侧通常用来 reload 群数据 */
reload: []
}>()
const message = useMessage()
const visible = ref(false)
const submitting = ref(false)
const groupId = ref(0)
const members = ref<GroupMemberLite[]>([])
/** 当前管理员 userId 列表:默认勾选 + 提交时 diff */
const currentAdminIds = ref<number[]>([])
const hideIds = ref<number[]>([])
const maxSize = ref(GROUP_ADMIN_MAX_COUNT)
const selectedIds = ref<number[]>([])
defineExpose({
/** 打开设置管理员弹窗reset → 灌参 → visible=true */
open(opts: {
groupId: number
members: GroupMemberLite[]
/** 当前管理员 userId 列表(默认勾选) */
currentAdminIds: number[]
/** 隐藏 userId群主 */
hideIds?: number[]
/** 已选数上限;不传走 GROUP_ADMIN_MAX_COUNT */
maxSize?: number
}) {
groupId.value = opts.groupId
members.value = opts.members
currentAdminIds.value = [...opts.currentAdminIds]
hideIds.value = opts.hideIds ? [...opts.hideIds] : []
maxSize.value = opts.maxSize ?? GROUP_ADMIN_MAX_COUNT
selectedIds.value = [...opts.currentAdminIds]
submitting.value = false
visible.value = true
}
})
/** 跟当前管理员列表做差集,分别拿到要新增 / 撤销的 userId */
async function handleOk() {
if (!groupId.value) {
return
}
const previousIds = currentAdminIds.value
const previousIdSet = new Set(previousIds)
const nextIds = selectedIds.value
const nextIdSet = new Set(nextIds)
const addedIds = nextIds.filter((id) => !previousIdSet.has(id))
const removedIds = previousIds.filter((id) => !nextIdSet.has(id))
if (addedIds.length === 0 && removedIds.length === 0) {
visible.value = false
return
}
submitting.value = true
try {
if (addedIds.length > 0) {
await addGroupAdmin({ groupId: groupId.value, userIds: addedIds })
}
if (removedIds.length > 0) {
await removeGroupAdmin({ groupId: groupId.value, userIds: removedIds })
}
message.success(`已更新群管理员(新增 ${addedIds.length} 位,撤销 ${removedIds.length} 位)`)
emit('reload')
visible.value = false
} finally {
submitting.value = false
}
}
</script>
<style scoped lang="scss">
@use '../picker/picker-dialog' as picker;
.im-picker-dialog {
@include picker.styles;
}
</style>