admin-vue3/src/views/im/home/components/ToolBar.vue

113 lines
3.9 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>
<!--
ToolBarIM 左侧工具栏
布局顶部头像 中间三 Tab消息/好友/群聊 底部设置
-->
<div
class="flex flex-col items-center w-14 pt-4 pb-3 gap-2 flex-shrink-0 select-none bg-[#2b2b2b]"
>
<!-- 顶部用户头像点击跳个人中心 UserAvatar 统一首字 / 哈希配色规则 -->
<div class="mb-2 cursor-pointer" @click="goProfile">
<UserAvatar
:url="userStore.getUser?.avatar"
:name="userStore.getUser?.nickname"
:size="36"
:clickable="false"
/>
</div>
<!-- 中间三 Tab -->
<div class="flex flex-col items-center gap-2 flex-1 w-full">
<div
v-for="item in tabs"
:key="item.name"
class="flex items-center justify-center w-10 h-10 rounded-lg text-[#a0a0a0] cursor-pointer transition-all hover:text-white hover:bg-white/10"
:class="{ 'bg-white/15 text-white': isActive(item.name) }"
@click="goTab(item.name)"
>
<el-badge
v-if="item.name === 'ImHomeConversation' && totalUnread > 0"
:value="totalUnread"
:max="99"
class="tool-bar__badge"
>
<Icon :icon="item.icon" :size="22" />
</el-badge>
<el-badge
v-else-if="item.name === 'ImHomeContact' && unhandledRequestCount > 0"
:value="unhandledRequestCount"
:max="99"
class="tool-bar__badge"
>
<Icon :icon="item.icon" :size="22" />
</el-badge>
<Icon v-else :icon="item.icon" :size="22" />
</div>
</div>
<!-- 底部设置按钮:点击跳个人中心 -->
<div class="flex flex-col items-center gap-2 w-full">
<div
class="flex items-center justify-center w-10 h-10 rounded-lg text-[#a0a0a0] cursor-pointer transition-all hover:text-white hover:bg-white/10"
@click="goProfile"
>
<Icon icon="ant-design:setting-outlined" :size="22" />
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import Icon from '@/components/Icon/src/Icon.vue'
import { useUserStore } from '@/store/modules/user'
import { useConversationStore } from '../store/conversationStore'
import { useFriendStore } from '../store/friendStore'
import { useImUiStore } from '../store/uiStore'
import UserAvatar from './user/UserAvatar.vue'
defineOptions({ name: 'ImToolBar' })
const route = useRoute()
const router = useRouter()
const userStore = useUserStore()
const conversationStore = useConversationStore()
const friendStore = useFriendStore()
const uiStore = useImUiStore()
const totalUnread = computed(() => conversationStore.getTotalUnread) // 消息 Tab 的红点:所有非免打扰会话的未读总和
const unhandledRequestCount = computed(() => friendStore.getUnhandledRequestCount) // 通讯录 Tab 的红点:未处理好友申请数(接收方=我)
const tabs = [
{ name: 'ImHomeConversation', icon: 'ep:chat-round' },
{ name: 'ImHomeContact', icon: 'mingcute:contacts-line' }
] // 两个主 Tab用路由 name 而非 path避免前缀 / 嵌套调整后失效
/** 当前路由是否命中 Tab直接比对 route.name */
const isActive = (name: string) => route.name === name
/** 切换 Tab当前已选中时消息 Tab 触发"滚动到下一个未读"(对齐微信 PC其它 Tab 无动作 */
const goTab = (name: string) => {
if (route.name === name) {
if (name === 'ImHomeConversation') {
uiStore.requestNextUnreadJump()
}
return
}
router.push({ name })
}
/** 跳转个人中心(路由 name=Profile */
const goProfile = () => router.push({ name: 'Profile' })
</script>
<style scoped>
/* :deep 穿透 el-badge 子组件内部 .el-badge__content右上角红点位置 + 去掉描边 */
.tool-bar__badge :deep(.el-badge__content) {
top: 4px;
right: 8px;
border: none;
}
</style>