gaoluyang
4 天以前 787ccc59ba89bacc075562a161ecf02bc76ebadc
src/views/im/home/components/rtc/rtc-call-member-picker-dialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,109 @@
<script lang="ts" setup>
import type { GroupMemberLite } from '../group'
import { computed, ref } from 'vue'
import { Button, Modal } from 'ant-design-vue'
import { getCurrentUserId } from '#/views/im/utils/auth'
import { useGroupStore } from '../../store/groupStore'
import { GroupMemberPickerPanel } from '../picker'
defineOptions({ name: 'ImRtcCallMemberPickerDialog' })
const emit = defineEmits<{
  /** é€‰å®Œç‚¹å®Œæˆï¼›æºå¸¦é€‰ä¸­çš„ userId åˆ—表 */
  success: [selectedIds: number[]]
}>()
type PickerMode = 'add' | 'invite'
const groupStore = useGroupStore()
const visible = ref(false) // å¼¹çª—显隐
const groupId = ref(0) // å½“前群编号;open æ—¶ç”±è°ƒç”¨æ–¹ä¼ å…¥
const mode = ref<PickerMode>('invite') // å¼¹çª—用途;invite=发起群通话选邀请人 / add=通话中追加成员
const excludeUserIds = ref<number[]>([]) // ç½®ç°çš„ userId åˆ—表;add åœºæ™¯æŠŠå·²åœ¨é€šè¯å†…的人禁用
const selectedIds = ref<number[]>([]) // å½“前选中的 userId åˆ—表;GroupMemberPickerPanel v-model ç»‘过来
/** æ ‡é¢˜ï¼›æŒ‰ç”¨é€”切换 */
const title = computed(() => (mode.value === 'add' ? '添加成员' : '选择成员'))
/** ç¾¤æˆå‘˜åˆ—表;从 groupStore çŽ°å–ï¼Œmap æˆ GroupMemberLite */
const members = computed<GroupMemberLite[]>(() => {
  const group = groupStore.getGroup(groupId.value)
  return (group?.members || []).map((member) => ({
    userId: member.userId,
    nickname: member.nickname,
    showName: member.displayUserName || member.nickname,
    avatar: member.avatar,
    status: member.status,
    role: member.role
  }))
})
/** è‡ªå·±ä¸å‡ºçŽ°åœ¨é€‰é¡¹é‡Œ */
const hideIds = computed<number[]>(() => {
  const myId = getCurrentUserId()
  return myId ? [myId] : []
})
/** å·²åœ¨é€šè¯å†…的成员置灰 */
const disabledIds = computed<number[]>(() => excludeUserIds.value)
/** æ˜¯å¦å¯æäº¤ï¼šè‡³å°‘选 1 ä¸ª */
const canSubmit = computed(() => selectedIds.value.length > 0)
/** æ‰“开弹窗;excludeUserIds ç”¨äºŽã€Œæ·»åŠ æˆå‘˜ã€æ—¶æŠŠå·²åœ¨é€šè¯å†…çš„äººç½®ç° */
function open(opts: { excludeUserIds?: number[]; groupId: number; mode?: PickerMode; }) {
  groupId.value = opts.groupId
  mode.value = opts.mode || 'invite'
  excludeUserIds.value = opts.excludeUserIds || []
  selectedIds.value = []
  visible.value = true
}
defineExpose({ open }) // æä¾› open æ–¹æ³•,用于打开弹窗
/** ç‚¹å®Œæˆï¼šemit é€‰ä¸­ ID åˆ—表给父级 + å…³é—­å¼¹çª—;提交按钮 disabled å·²ä¿è¯ selectedIds éžç©º */
function handleOk() {
  emit('success', [...selectedIds.value])
  visible.value = false
}
</script>
<template>
  <!--
    é€šè¯æˆå‘˜é€‰æ‹©å¼¹çª—:发起群通话时选邀请人 / é€šè¯ä¸­æ·»åŠ æˆå‘˜ï¼›
    é€‰æ‹© UI å§”托 GroupMemberPickerPanel;自己 hide、已在通话内的成员 disabled
  -->
  <Modal
    v-model:open="visible"
    :title="title"
    width="720px"
    :mask-closable="false"
    class="im-picker-dialog"
  >
    <div class="h-[480px]">
      <GroupMemberPickerPanel
        v-model:selected-ids="selectedIds"
        :members="members"
        :disabled-ids="disabledIds"
        :hide-ids="hideIds"
      />
    </div>
    <template #footer>
      <Button @click="visible = false">取消</Button>
      <Button type="primary" :disabled="!canSubmit" @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>