| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { ImManagerGroupApi } from '#/api/im/manager/group'; |
| | | |
| | | import { computed, ref, useAttrs, watch } from 'vue'; |
| | | |
| | | import { IconifyIcon } from '#/packages/icons/src'; |
| | | |
| | | import { Input, Tooltip } from 'ant-design-vue'; |
| | | |
| | | import { getManagerGroup } from '#/api/im/manager/group'; |
| | | |
| | | import GroupSelectDialog from './select-dialog.vue'; |
| | | |
| | | defineOptions({ name: 'ImManagerGroupSelect', inheritAttrs: false }); |
| | | |
| | | const props = withDefaults( |
| | | defineProps<{ |
| | | allowClear?: boolean; |
| | | disabled?: boolean; |
| | | modelValue?: number; |
| | | placeholder?: string; |
| | | }>(), |
| | | { |
| | | allowClear: true, |
| | | disabled: false, |
| | | modelValue: undefined, |
| | | placeholder: 'è¯·éæ©ç¾¤', |
| | | }, |
| | | ); |
| | | |
| | | const emit = defineEmits<{ |
| | | change: [item: ImManagerGroupApi.Group | undefined]; |
| | | 'update:modelValue': [value: number | undefined]; |
| | | }>(); |
| | | |
| | | const attrs = useAttrs(); |
| | | const dialogRef = ref<InstanceType<typeof GroupSelectDialog>>(); // ç¾¤éæ©å¼¹çª |
| | | const hovering = ref(false); // é¼ æ æ¯å¦æ¬å |
| | | const selectedItem = ref<ImManagerGroupApi.Group>(); // å·²é群 |
| | | |
| | | /** è¾å
¥æ¡æ¾ç¤ºææ¬ */ |
| | | const displayLabel = computed(() => selectedItem.value?.name ?? ''); |
| | | |
| | | /** æ¯å¦æ¾ç¤ºæ¸
é¤å¾æ */ |
| | | const showClear = computed(() => { |
| | | return props.allowClear && !props.disabled && hovering.value && props.modelValue != null; |
| | | }); |
| | | |
| | | /** æ ¹æ®ç¼å·æ¥è¯¢ç¾¤ä¿¡æ¯ï¼ç¨äºç¼è¾åæ¾ï¼ */ |
| | | async function resolveItemById(id: number | undefined) { |
| | | if (id == null) { |
| | | selectedItem.value = undefined; |
| | | return; |
| | | } |
| | | if (selectedItem.value?.id === id) { |
| | | return; |
| | | } |
| | | selectedItem.value = await getManagerGroup(id); |
| | | } |
| | | |
| | | watch(() => props.modelValue, resolveItemById, { immediate: true }); |
| | | |
| | | /** æ¸
空已é群 */ |
| | | function clearSelected() { |
| | | selectedItem.value = undefined; |
| | | emit('update:modelValue', undefined); |
| | | emit('change', undefined); |
| | | } |
| | | |
| | | /** æå¼ç¾¤éæ©å¼¹çª */ |
| | | function handleClick(event: MouseEvent) { |
| | | if (props.disabled) { |
| | | return; |
| | | } |
| | | const target = event.target as HTMLElement; |
| | | if (showClear.value && target.closest('.ant-input-suffix')) { |
| | | event.stopPropagation(); |
| | | clearSelected(); |
| | | return; |
| | | } |
| | | dialogRef.value?.open(props.modelValue == null ? [] : [props.modelValue]); |
| | | } |
| | | |
| | | /** å¼¹çªéä¸åè° */ |
| | | function handleSelected(rows: ImManagerGroupApi.Group[]) { |
| | | const item = rows[0]; |
| | | if (!item) { |
| | | return; |
| | | } |
| | | selectedItem.value = item; |
| | | emit('update:modelValue', item.id); |
| | | emit('change', item); |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <div |
| | | v-bind="attrs" |
| | | class="w-full" |
| | | :class="disabled ? 'cursor-not-allowed' : 'cursor-pointer'" |
| | | @click="handleClick" |
| | | @mouseenter="hovering = true" |
| | | @mouseleave="hovering = false" |
| | | > |
| | | <Tooltip :mouse-enter-delay="0.5" :open="selectedItem ? undefined : false"> |
| | | <template #title> |
| | | <div v-if="selectedItem" class="leading-6"> |
| | | <div>群åç§°ï¼{{ selectedItem.name || '-' }}</div> |
| | | <div>群主ï¼{{ selectedItem.ownerNickname || '-' }}</div> |
| | | <div>æåæ°ï¼{{ selectedItem.memberCount ?? '-' }}</div> |
| | | </div> |
| | | </template> |
| | | <Input |
| | | :disabled="disabled" |
| | | :placeholder="placeholder" |
| | | :value="displayLabel" |
| | | readonly |
| | | > |
| | | <template #suffix> |
| | | <IconifyIcon |
| | | class="size-4" |
| | | :icon="showClear ? 'lucide:circle-x' : 'lucide:search'" |
| | | /> |
| | | </template> |
| | | </Input> |
| | | </Tooltip> |
| | | </div> |
| | | <GroupSelectDialog ref="dialogRef" @selected="handleSelected" /> |
| | | </template> |