gaoluyang
2026-06-29 27cd042df9aca0383a49f3514bc21958dd890912
src/views/im/home/components/group/group-owner-transfer-dialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,126 @@
<script lang="ts" setup>
import type { GroupMemberLite } from './group-member.vue'
import { computed, ref } from 'vue'
import { confirm } from '#/packages/effects/common-ui/src'
import { Button, message, Modal } from 'ant-design-vue'
import { transferGroupOwner } from '#/api/im/group'
import { GroupMemberPickerPanel } from '../picker'
defineOptions({ name: 'ImGroupOwnerTransferDialog' })
const emit = defineEmits<{
  /** è½¬è®©æˆåŠŸï¼›çˆ¶ä¾§é€šå¸¸ç”¨æ¥ reload ç¾¤æ•°æ® */
  reload: []
}>()
const visible = ref(false)
const submitting = ref(false)
const groupId = ref(0)
const members = ref<GroupMemberLite[]>([])
const hideIds = ref<number[]>([])
const selectedIds = ref<number[]>([])
defineExpose({
  /** æ‰“开转让群主弹窗:reset â†’ çŒå‚ â†’ visible=true */
  open(opts: {
    groupId: number
    /** éšè— userId:当前用户(不能转给自己) */
    hideIds?: number[]
    members: GroupMemberLite[]
  }) {
    groupId.value = opts.groupId
    members.value = opts.members
    hideIds.value = opts.hideIds ? [...opts.hideIds] : []
    selectedIds.value = []
    submitting.value = false
    visible.value = true
  }
})
/** é€‰ä¸­çš„æ–°ç¾¤ä¸»å¯¹è±¡ï¼ˆå–数组首项) */
const newOwner = computed<GroupMemberLite | undefined>(() => {
  if (selectedIds.value.length === 0) {
    return undefined
  }
  return members.value.find((member) => member.userId === selectedIds.value[0])
})
/** äºŒæ¬¡ç¡®è®¤è½¬è®©ï¼šè½¬è®©åŽæ—§ç¾¤ä¸»é™ä¸ºæ™®é€šæˆå‘˜ï¼Œæ— æ³•撤销 */
async function handleOk() {
  if (!groupId.value || !newOwner.value) {
    return
  }
  try {
    await confirm(
      `确定将群主转让给 ${newOwner.value.showName}?转让后你将变为普通成员,无法撤销。`,
      '确认转让群主'
    )
  } catch {
    return
  }
  submitting.value = true
  try {
    await transferGroupOwner({
      id: groupId.value,
      newOwnerUserId: newOwner.value.userId
    })
    message.success('群主转让成功')
    emit('reload')
    visible.value = false
  } finally {
    submitting.value = false
  }
}
</script>
<template>
  <!--
    è½¬è®©ç¾¤ä¸»ï¼šé€‰ 1 ä½æ–°ç¾¤ä¸» â†’ äºŒæ¬¡ç¡®è®¤ â†’ transferGroupOwner
    - dialog å£³æœ¬ç»„件持有;选择 UI å§”托 GroupMemberPickerPanel
    - å½“前用户从候选里隐藏(不能转给自己)
    - maxSize=1 é™å®šå•选
    - å¯¹å¤–接口:ref + open({ groupId, members, hideIds }) + emit reload()
  -->
  <Modal
    v-model:open="visible"
    title="选择新群主"
    width="700px"
    :mask-closable="false"
    class="im-picker-dialog"
  >
    <div class="h-[480px]">
      <GroupMemberPickerPanel
        v-model:selected-ids="selectedIds"
        :members="members"
        :hide-ids="hideIds"
        :max-size="1"
      />
    </div>
    <template #footer>
      <Button @click="visible = false">取消</Button>
      <Button
        type="primary"
        :loading="submitting"
        :disabled="selectedIds.length === 0"
        @click="handleOk"
      >
        ç¡®å®š
      </Button>
    </template>
  </Modal>
</template>
<style scoped lang="scss">
@use '../picker/picker-dialog' as picker;
/* :deep ç©¿é€ el-dialog å†…部类;复用 picker å…¬å…± mixin */
.im-picker-dialog {
  @include picker.styles;
}
</style>