admin-vue3/src/layout/components/ToolHeader.vue

120 lines
4.1 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.

<script lang="tsx">
import { defineComponent, computed } from 'vue'
import router from '@/router'
import { Message } from '@/layout/components/Message'
import { Collapse } from '@/layout/components/Collapse'
import { UserInfo } from '@/layout/components/UserInfo'
import { Screenfull } from '@/layout/components/Screenfull'
import { Breadcrumb } from '@/layout/components/Breadcrumb'
import { SizeDropdown } from '@/layout/components/SizeDropdown'
import { LocaleDropdown } from '@/layout/components/LocaleDropdown'
import RouterSearch from '@/components/RouterSearch/index.vue'
import TenantVisit from '@/layout/components/TenantVisit/index.vue'
import { useAppStore } from '@/store/modules/app'
import { useDesign } from '@/hooks/web/useDesign'
import { Icon } from '@/components/Icon'
import { checkPermi } from '@/utils/permission'
const { getPrefixCls, variables } = useDesign()
const prefixCls = getPrefixCls('tool-header')
const appStore = useAppStore()
// 面包屑
const breadcrumb = computed(() => appStore.getBreadcrumb)
// 折叠图标
const hamburger = computed(() => appStore.getHamburger)
// 全屏图标
const screenfull = computed(() => appStore.getScreenfull)
// 搜索图片
const search = computed(() => appStore.search)
// 尺寸图标
const size = computed(() => appStore.getSize)
// 布局
const layout = computed(() => appStore.getLayout)
// 多语言图标
const locale = computed(() => appStore.getLocale)
// 消息图标
const message = computed(() => appStore.getMessage)
// 租户切换权限
const hasTenantVisitPermission = computed(
() => import.meta.env.VITE_APP_TENANT_ENABLE === 'true' && checkPermi(['system:tenant:visit'])
)
// 顶部聊天入口:用路由 name resolve 出完整 URL在新标签页打开 IM 主页
// 场景考虑IM 是全屏沉浸式壳,如果在当前页 push 会把原来在用的后台管理界面挤掉;开新 Tab 更符合用户预期
const goToChat = () => {
// 用路由 name resolve 出完整 URL在新标签页打开 IM 主页
const { href } = router.resolve({ name: 'ImHome' })
window.open(href, '_blank')
}
export default defineComponent({
name: 'ToolHeader',
setup() {
return () => (
<div
id={`${variables.namespace}-tool-header`}
class={[
prefixCls,
'h-[var(--top-tool-height)] relative px-[var(--top-tool-p-x)] flex items-center justify-between',
'dark:bg-[var(--el-bg-color)]'
]}
>
{layout.value !== 'top' ? (
<div class="h-full flex items-center">
{hamburger.value && layout.value !== 'cutMenu' ? (
<Collapse class="custom-hover" color="var(--top-header-text-color)"></Collapse>
) : undefined}
{breadcrumb.value ? <Breadcrumb class="lt-md:hidden"></Breadcrumb> : undefined}
</div>
) : undefined}
<div class="h-full flex items-center">
{hasTenantVisitPermission.value ? <TenantVisit /> : undefined}
{screenfull.value ? (
<Screenfull class="custom-hover" color="var(--top-header-text-color)"></Screenfull>
) : undefined}
{search.value ? (
<RouterSearch isModal={false} color="var(--top-header-text-color)" />
) : undefined}
{size.value ? (
<SizeDropdown class="custom-hover" color="var(--top-header-text-color)"></SizeDropdown>
) : undefined}
{locale.value ? (
<LocaleDropdown
class="custom-hover"
color="var(--top-header-text-color)"
></LocaleDropdown>
) : undefined}
{message.value ? (
<Message class="custom-hover" color="var(--top-header-text-color)"></Message>
) : undefined}
{/* IM 聊天入口 */}
<div class="custom-hover" onClick={goToChat}>
<Icon color="var(--top-header-text-color)" size={18} icon="ep:chat-dot-round" />
</div>
<UserInfo></UserInfo>
</div>
</div>
)
}
})
</script>
<style lang="scss" scoped>
$prefix-cls: #{$namespace}-tool-header;
.#{$prefix-cls} {
transition: left var(--transition-time-02);
}
</style>