Files
Situation-Awareness-Platfor…/src/components/MemberAvatarList/index.vue

169 lines
3.9 KiB
Vue
Raw Normal View History

2025-03-12 18:41:20 +08:00
<template>
<div class="g-member-avatar">
<d-row justify="between" v-if="!hideTop">
<d-col class="flex">
<slot name="title">
<Icon class="g-member-avatar-icon" :name="typeIcon"></Icon>
<div class="g-member-avatar-title ml-2 text-G900 text-sm">{{ title }}</div>
<span class="g-member-avatar-num ml-2 text-CG600 " v-if="!hideNum">{{ count }}</span>
</slot>
</d-col>
<d-col v-if="!hideRightMore && data.length" @click="emits('handleMore')">
<slot name="more">
<router-link :to="toMore">
<Icon :name="moreIcon" color="#707A8"></Icon>
</router-link>
</slot>
</d-col>
</d-row>
<div class="g-member-avatar-list">
<slot name="content">
<template v-for="(item, index) in userData.slice(0, 25)" :key="index">
<d-tooltip :content="item.name" :disabled="!showHover">
<GAvatar class="mb-2" :class="{ 'g-member-avatar-list-rounded': !isRound }"
:name="item.name" :is_round="isRound"
:src="item.avatar"></GAvatar>
</d-tooltip>
</template>
<!-- <template v-if="showBlank">
<template v-for="(item, index) in (25 - userData.slice(0, 25).length)" :key="index">
<div class="g-member-avatar-list-empty mb-2" :class="{ 'g-member-avatar-list-rounded': !isRound }"></div>
</template>
</template> -->
</slot>
</div>
<router-link :to="toMore" v-if="!hideBottomMore && data.length">
<div class="g-member-avatar-more" @click="emits('handleMore')">
<slot name="bottomMore">
查看全部{{ title }}
</slot>
</div>
</router-link>
</div>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue';
interface userAvatarListRow {
username:string;
iam_id:string;
name?: string;
avatar?:string;
avatar_url?:string;
}
const props = withDefaults(defineProps<{
data?: Array<userAvatarListRow>;
title?: string;
hideNum?: boolean;
count?: number;
hideTop?: boolean;
hideRightMore?: boolean;
hideBottomMore?: boolean;
toMore?: string
isRound?: boolean
showHover: boolean
moreIcon?: string
typeIcon?: string
showBlank?: boolean
}>(), {
data: () => [],
title: '组织成员',
toMore: '',
hideNum: false,
count: 0,
hideTop: false,
hideRightMore: false,
hideBottomMore: false,
isRound: true,
showHover: false,
moreIcon: 'gt-all',
typeIcon: 'gt-organizations-c',
showBlank: true
});
const emits = defineEmits(['handleMore']);
const userData = ref<userAvatarListRow[]>([]);
watch(() => props.data, (val) => {
init();
}, {
deep: true
});
const init = async() => {
userData.value = JSON.parse(JSON.stringify(props.data || []));
// for (let [i, len] = [0, data.length]; i < len; i++) {
// const item = data[i];
// if (!item.avatar) {
// item.noAvatar = true;
// break;
// // return false;
// }
// try {
// await fetch(item.avatar);
// } catch {
// item.noAvatar = true;
// }
// }
// userData.value = data;
};
init();
</script>
<style scoped lang="scss">
$g-member-avatar-border-color: rgba(0, 0, 0, 0.1);
.g-member-avatar {
width: 100%;
&-icon {
margin-top: 2px;
}
&-list {
display: flex;
align-items: center;
margin-top: 12px;
flex-wrap: wrap;
&-empty {
width: 32px;
height: 32px;
background: #FFFFFF;
border: 1px solid $g-member-avatar-border-color;
border-radius: 50%;
z-index: -1;
margin-right: -4px;
}
&-round {
border-radius: 50%;
}
:deep(.devui-avatar) {
margin-right: -4px;
img {
object-fit: cover;
}
}
&-rounded {
border-radius: 4px !important;
:deep(img) {
border-radius: 4px !important;
}
}
}
:deep(.devui-icon__container) {
vertical-align: middle;
}
&-more {
margin-top: 8px;
}
}
</style>