Files
lingji-work-fe/src/layouts/components/navbar/components/right-side/index.vue
rd 2d489673f6 style(layout): 优化导航栏右侧菜单项样式
- 移除菜单项的底部边距
- 为非最后一个菜单项添加底部边距,保持间距一致性
2025-09-18 10:09:35 +08:00

332 lines
11 KiB
Vue

<template>
<div class="right-wrap">
<!-- 任务中心 -->
<div
class="relative p-6px rounded-30px flex items-center justify-center task-icon"
@click="setUnread"
v-if="hasOpenEnterprise"
>
<SvgIcon name="svg-taskCenter" size="20" class="color-#737478" @click="openDownloadCenter" />
<div class="w-6px h-6px rounded-50% bg-#F64B31 absolute top-6px right-6px" v-if="hasUnreadInfo"></div>
</div>
<!-- 灵机空间入口 -->
<div
class="agent-entry mx-16px"
:class="isAgentRoute ? 'agent' : ''"
@click="handleAgentClick"
v-if="hasOpenEnterprise"
></div>
<!-- 头像设置 -->
<Dropdown trigger="click" overlayClassName="layout-avatar-dropdown">
<div class="cursor-pointer">
<Avatar :src="userInfo.head_image" :size="32" v-if="userInfo.head_image" />
<div v-else class="w-32px h-32px rounded-50% bg-#6D4CFE flex items-center justify-center">
<span class="color-#FFF text-14px font-400 lh-22px">{{ userInfo.mobile?.slice(-3) }}</span>
</div>
</div>
<template #overlay>
<Menu>
<MenuItem>
<div class="h-full flex justify-between items-center w-100%" @click="setServerMenu">
<div class="flex items-center">
<img :src="icon1" class="w-16px h-16px mr-8px" />
<span>管理中心</span>
</div>
<icon-right size="12" />
</div>
</MenuItem>
<MenuItem v-if="enterprises.length > 0">
<SubMenu value="option-1" position="lt" trigger="hover" popupClassName="enterprises-dsubmenu">
<template #title>
<div class="flex justify-between w-100% h-full items-center">
<div class="flex items-center">
<img :src="icon3" class="w-16px h-16px mr-8px" />
<span>切换企业账号</span>
</div>
<icon-right size="12" />
</div>
</template>
<div v-for="(item, index) in enterprises" :key="index">
<MenuItem
class="rounded-8px hover:bg-#F2F3F5"
@click="onEnterpriseItemClick(item)"
v-if="!primary_enterprise || item.id !== primary_enterprise.id"
>
<div
class="flex items-center w-100% justify-between"
:class="enterpriseInfo?.id === item.id ? '!color-#6D4CFE' : ''"
>
<span>{{ item.name }}</span>
<icon-check v-if="enterpriseInfo?.id === item.id" size="16" />
</div>
</MenuItem>
<template v-else>
<template v-if="item.audit_status === 1">
<div v-if="enterprises.length > 1" class="w-full h-1px bg-#E6E6E8 mb-8px"></div>
<MenuItem class="rounded-8px hover:bg-#F2F3F5 h-36px !mb-0" @click="onCreate(item)">
<div class="flex items-center">
<SvgIcon size="16.5" name="svg-organization" class="color-#737478 mr-8px" />
<span class="color-#211F24 mr-4px">创建企业账号</span>
<div class="px-8px h-20px rounded-2px bg-#FFF7E5 flex items-center">
<span class="color-#FFAE00 !text-12px !lh-20px font-400">申请中</span>
</div>
</div>
</MenuItem>
</template>
<div v-else>
<MenuItem class="rounded-8px hover:bg-#F2F3F5" @click="handleSubAccountClick(item)">
<div class="flex justify-between items-center overflow-hidden">
<div
class="flex items-center w-100% flex-1 overflow-hidden"
:class="enterpriseInfo?.id === item.id ? '!color-#6D4CFE' : ''"
>
<TextoverTips :context="item.name" />
<img :src="icon4" width="12" height="12" class="ml-4px" />
</div>
<div
class="px-8px h-20px rounded-2px flex items-center flex-shrink-0 ml-4px"
:class="_map.get(item.subscribe_status)?.bg"
v-if="[2, 3].includes(item.subscribe_status)"
>
<span class="!text-12px !lh-20px font-400" :class="_map.get(item.subscribe_status)?.color">{{
_map.get(item.subscribe_status)?.label
}}</span>
</div>
</div>
</MenuItem>
</div>
</template>
</div>
<template v-if="!primary_enterprise">
<div class="w-full h-1px bg-#E6E6E8 mb-8px" v-if="enterprises?.length > 0"></div>
<MenuItem class="rounded-8px hover:bg-#F2F3F5 h-36px !mb-0" @click="onCreate(null)">
<div class="flex items-center">
<SvgIcon size="16.5" name="svg-organization" class="color-#737478 mr-8px" />
<span class="color-#211F24 mr-4px">创建企业账号</span>
</div>
</MenuItem>
</template>
</SubMenu>
</MenuItem>
<MenuItem>
<div class="flex justify-between w-100% h-full items-center" @click="clickExit">
<div class="flex items-center">
<img :src="icon2" class="w-16px h-16px mr-8px" />
<span>退出登录</span>
</div>
<icon-right size="12" />
</div>
</MenuItem>
</Menu>
</template>
</Dropdown>
<ExitAccountModal ref="exitAccountModalRef" />
<DownloadCenterModal ref="downloadCenterModalRef" />
</div>
</template>
<script setup>
import { Dropdown, Menu, MenuItem, SubMenu, Avatar } from 'ant-design-vue';
import { useRouter } from 'vue-router'; // import router from '@/router';
import { useEnterpriseStore } from '@/stores/modules/enterprise';
import { useSidebarStore } from '@/stores/modules/side-bar';
import { useUserStore } from '@/stores';
import { handleUserHome } from '@/utils/user';
import ExitAccountModal from '../exit-account-modal';
import DownloadCenterModal from '../task-center-modal';
import icon1 from '@/assets/option.svg';
import icon2 from '@/assets/exit.svg';
import icon3 from '@/assets/change.svg';
import icon4 from './img/admin.png';
import TextoverTips from '@/components/text-over-tips/index.vue';
const props = defineProps({
isAgentRoute: {
type: Boolean,
default: false,
},
});
const _map = new Map([
[2, { label: '试用中', bg: 'bg-#F0EDFF', color: 'color-#6D4CFE' }],
[3, { label: '已到期', bg: 'bg-#F2F3F5', color: 'color-#55585F' }],
]);
const enterpriseStore = useEnterpriseStore();
const userStore = useUserStore();
const sideBarStore = useSidebarStore();
const route = useRoute();
const router = useRouter();
const exitAccountModalRef = ref(null);
const downloadCenterModalRef = ref(null);
const hasUnreadInfo = computed(() => sideBarStore.unreadInfo.length);
const hasOpenEnterprise = computed(() => enterpriseStore.isOpenEnterprise);
const primary_enterprise = computed(() => userStore.userInfo?.primary_enterprise);
const enterprises = computed(() => {
return userStore.userInfo?.enterprises ?? [];
});
const userInfo = computed(() => userStore.userInfo);
const enterpriseInfo = computed(() => {
return enterpriseStore?.enterpriseInfo ?? {};
});
const openDownloadCenter = () => {
downloadCenterModalRef.value.open();
};
const onEnterpriseItemClick = async (item) => {
enterpriseStore.setEnterpriseInfo(item);
window.location.reload();
};
const clickExit = async () => {
exitAccountModalRef.value?.open();
};
const setServerMenu = () => {
router.push('/management/person');
};
const setUnread = () => {
if (sideBarStore.unreadInfo.length) {
sideBarStore.removeTaskUnreadInfo();
}
};
const handleAgentClick = () => {
props.isAgentRoute ? handleUserHome() : router.push({ name: 'AgentIndex' });
};
const onCreate = (item) => {
if (item && item.id === primary_enterprise.value.id) {
enterpriseStore.setEnterpriseInfo(item);
}
router.push({ name: 'Trial' });
};
const handleSubAccountClick = (item) => {
enterpriseStore.setEnterpriseInfo(item);
if (item.subscribe_status === 3) {
router.push({ name: 'Trial' });
return;
}
window.location.reload();
};
</script>
<style scoped lang="scss">
@import './style.scss';
</style>
<style lang="scss">
.layout-avatar-dropdown,
.enterprises-dsubmenu {
.ant-dropdown-menu {
border-radius: 8px;
border: 1px solid var(--BG-300, #e6e6e8);
background: var(--BG-white, #fff);
padding: 12px 0px;
.ant-dropdown-menu-item {
padding: 0 12px;
font-family: $font-family-regular;
color: var(--Text-1, #211f24);
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 22px;
&:not(:last-child) {
margin-bottom: 8px;
}
.ant-dropdown-menu-title-content {
display: flex;
height: 32px;
width: 100%;
padding: 10px 24px;
align-items: center;
.ant-dropdown-menu-submenu {
width: 100%;
.ant-dropdown-menu-submenu-title {
padding: 0;
&:hover {
background: none;
}
.ant-dropdown-menu-title-content {
padding: 0 !important;
}
}
.ant-dropdown-menu-submenu-arrow {
display: none;
}
}
}
.menu-item-text {
color: var(--Text-2, #3c4043);
font-family: $font-family-regular;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: 22px;
}
.ant-dropdown-menu-title-content {
border-radius: 8px !important;
}
&:not(.ant-dropdown-menu-item):hover {
background-color: transparent;
.ant-dropdown-menu-title-content {
background: var(--BG-200, #f2f3f5);
}
}
}
}
}
.layout-avatar-dropdown,
.enterprises-dsubmenu {
width: 200px;
.ant-dropdown-menu {
padding: 8px 4px;
margin: 0;
.ant-dropdown-menu-item {
padding: 0 !important;
.ant-dropdown-menu-title-content {
padding: 0 12px !important;
}
}
}
.ant-dropdown-option-suffix {
display: none;
}
// .enterprises-doption {
// .ant-dropdown-menu-title-content {
// padding: 0 !important;
// border-radius: 8px;
// }
// &:not(.ant-dropdown-option-disabled):hover {
// background-color: transparent;
// .ant-dropdown-menu-title-content {
// background: var(--BG-200, #f2f3f5);
// }
// }
// }
}
</style>