123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500 |
- <template>
- <header class="z-40" :class="{ dark: store.state.semidark && store.state.menu === 'horizontal' }">
- <div class="shadow-sm">
- <div class="relative bg-white flex w-full items-center px-5 py-2.5 dark:bg-[#0e1726]">
- <div class="horizontal-logo flex lg:hidden justify-between items-center ltr:mr-2 rtl:ml-2">
- <router-link to="/dashboard" class="main-logo flex items-center shrink-0">
- <img class="w-full h-12 ltr:-ml-1 rtl:-mr-1 inline" src="https://www.raycos.com.cn/theme/m049/images/logo.png" alt="" />
- <!-- <span class="text-2xl ltr:ml-1.5 rtl:mr-1.5 font-semibold align-middle hidden md:inline dark:text-white-light transition-all duration-300"
- >V3studio App</span
- > -->
- </router-link>
- <!-- 原导航 -->
- <a
- href="javascript:;"
- class="collapse-icon flex-none dark:text-[#d0d2d6] hover:text-primary dark:hover:text-primary flex lg:hidden ltr:ml-2 rtl:mr-2 p-2 rounded-full bg-white-light/40 dark:bg-dark/40 hover:bg-white-light/90 dark:hover:bg-dark/60"
- @click="toggleSidebars"
- >
- <icon-menu class="w-5 h-5" />
- </a>
- </div>
- <!-- 头部中间功能--待开发 -->
- <div class="ltr:mr-2 rtl:ml-2 hidden sm:block">
- <ul class="flex items-center space-x-2 rtl:space-x-reverse dark:text-[#d0d2d6]">
- <li>
- <!-- to="/apps/calendar" -->
- <router-link
- to=""
- class="block p-2 rounded-full bg-white-light/40 dark:bg-dark/40 hover:text-primary hover:bg-white-light/90 dark:hover:bg-dark/60"
- >
- <icon-calendar />
- </router-link>
- </li>
- <li>
- <router-link
- to=""
- class="block p-2 rounded-full bg-white-light/40 dark:bg-dark/40 hover:text-primary hover:bg-white-light/90 dark:hover:bg-dark/60"
- >
- <icon-edit />
- </router-link>
- </li>
- <li>
- <router-link
- to=""
- class="block p-2 rounded-full bg-white-light/40 dark:bg-dark/40 hover:text-primary hover:bg-white-light/90 dark:hover:bg-dark/60"
- >
- <icon-chat-notification />
- </router-link>
- </li>
- </ul>
- </div>
- <div
- class="sm:flex-1 ltr:sm:ml-0 ltr:ml-auto sm:rtl:mr-0 rtl:mr-auto flex items-center space-x-1.5 lg:space-x-2 rtl:space-x-reverse dark:text-[#d0d2d6]"
- >
- <div class="sm:ltr:mr-auto sm:rtl:ml-auto">
- <form
- class="sm:relative absolute inset-x-0 sm:top-0 top-1/2 sm:translate-y-0 -translate-y-1/2 sm:mx-0 mx-4 z-10 sm:block hidden"
- :class="{ '!block': search }"
- @submit.prevent="search = false"
- ></form>
- <button
- type="button"
- class="search_btn sm:hidden p-2 rounded-full bg-white-light/40 dark:bg-dark/40 hover:bg-white-light/90 dark:hover:bg-dark/60"
- @click="search = !search"
- >
- <icon-search class="w-4.5 h-4.5 mx-auto dark:text-[#d0d2d6]" />
- </button>
- </div>
- <a href="javascript:;" v-if="superMenu == 'compan' && founder == '1'" @click="getBranch('super')"> 返回</a>
- <div>
- <a
- href="javascript:;"
- v-show="store.state.theme === 'light'"
- class="flex items-center p-2 rounded-full bg-white-light/40 dark:bg-dark/40 hover:text-primary hover:bg-white-light/90 dark:hover:bg-dark/60"
- @click="toggleTheme('dark')"
- >
- <icon-sun />
- </a>
- <a
- href="javascript:;"
- v-show="store.state.theme === 'dark'"
- class="flex items-center p-2 rounded-full bg-white-light/40 dark:bg-dark/40 hover:text-primary hover:bg-white-light/90 dark:hover:bg-dark/60"
- @click="toggleTheme('system')"
- >
- <icon-moon />
- </a>
- <a
- href="javascript:;"
- v-show="store.state.theme === 'system'"
- class="flex items-center p-2 rounded-full bg-white-light/40 dark:bg-dark/40 hover:text-primary hover:bg-white-light/90 dark:hover:bg-dark/60"
- @click="toggleTheme('dark')"
- >
- <!-- <icon-laptop /> -->
- <icon-sun />
- </a>
- </div>
- <div class="dropdown shrink-0 mr-2">
- <Popper :placement="store.state.rtlClass === 'rtl' ? 'bottom-start' : 'bottom-end'" offsetDistance="0">
- <el-badge :value="countNot" :hidden="countNot == 0" class="item">
- <button
- type="button"
- class="pt-2 block p-2 rounded-full bg-white-light/40 dark:bg-dark/40 hover:text-primary hover:bg-white-light/90 dark:hover:bg-dark/60"
- @click="goNotify"
- >
- <icon-mail-dot />
- </button>
- </el-badge>
- <!-- <template #content="{ close }">
- <ul class="top-11 !py-0 text-dark dark:text-white-dark w-[300px] sm:w-[375px] text-xs">
- <li class="mb-5">
- <div class="overflow-hidden relative rounded-t-md !p-5 text-white">
- <div class="absolute h-full w-full bg-[url('/assets/images/menu-heade.jpg')] bg-no-repeat bg-center bg-cover inset-0"></div>
- <h4 class="font-semibold relative z-10 text-lg">Messages</h4>
- </div>
- </li>
- <template v-for="msg in messages" :key="msg.id">
- <li>
- <div class="flex items-center py-3 px-5">
- <div v-html="msg.image"></div>
- <span class="px-3 dark:text-gray-500">
- <div class="font-semibold text-sm dark:text-white-light/90" v-text="msg.title"></div>
- <div v-text="msg.message"></div>
- </span>
- <span
- class="font-semibold bg-white-dark/20 rounded text-dark/60 px-1 ltr:ml-auto rtl:mr-auto whitespace-pre dark:text-white-dark ltr:mr-2 rtl:ml-2"
- v-text="msg.time"
- ></span>
- <button type="button" class="text-neutral-300 hover:text-danger" @click="removeMessage(msg.id)">
- <icon-x-circle />
- </button>
- </div>
- </li>
- </template>
- <template v-if="messages.length">
- <li class="border-t border-white-light text-center dark:border-white/10 mt-5">
- <div
- class="flex items-center py-4 px-5 text-primary font-semibold group dark:text-gray-400 justify-center cursor-pointer"
- @click="close()"
- >
- <span class="group-hover:underline ltr:mr-1 rtl:ml-1">VIEW ALL ACTIVITIES</span>
- <icon-arrow-left class="group-hover:translate-x-1 transition duration-300 ltr:ml-1 rtl:mr-1" />
- </div>
- </li>
- </template>
- <template v-if="!messages.length">
- <li class="mb-5">
- <div class="!grid place-content-center hover:!bg-transparent text-lg min-h-[200px]">
- <div class="mx-auto ring-4 ring-primary/30 rounded-full mb-4 text-primary">
- <icon-info-circle :fill="true" class="w-10 h-10" />
- </div>
- No data available.
- </div>
- </li>
- </template>
- </ul>
- </template> -->
- </Popper>
- </div>
- <!-- <div class="dropdown shrink-0">
- <Popper :placement="store.state.rtlClass === 'rtl' ? 'bottom-end' : 'bottom-start'"
- offsetDistance="8">
- <button type="button"
- class="relative block p-2 rounded-full bg-white-light/40 dark:bg-dark/40 hover:text-primary hover:bg-white-light/90 dark:hover:bg-dark/60">
- <icon-bell-bing />
- <span class="flex absolute w-3 h-3 ltr:right-0 rtl:left-0 top-0">
- <span
- class="animate-ping absolute ltr:-left-[3px] rtl:-right-[3px] -top-[3px] inline-flex h-full w-full rounded-full bg-success/50 opacity-75"></span>
- <span class="relative inline-flex rounded-full w-[6px] h-[6px] bg-success"></span>
- </span>
- </button>
- <template #content="{ close }">
- <ul
- class="!py-0 text-dark dark:text-white-dark w-[300px] sm:w-[350px] divide-y dark:divide-white/10">
- <li>
- <div class="flex items-center px-4 py-2 justify-between font-semibold">
- <h4 class="text-lg">Notification</h4>
- <template v-if="notifications.length">
- <span class="badge bg-primary/80"
- v-text="notifications.length + 'New'"></span>
- </template>
- </div>
- </li>
- <template v-for="notification in notifications" :key="notification.id">
- <li class="dark:text-white-light/90">
- <div class="group flex items-center px-4 py-2">
- <div class="grid place-content-center rounded">
- <div class="w-12 h-12 relative">
- <img class="w-12 h-12 rounded-full object-cover"
- :src="`/assets/images/${notification.profile}`" alt="" />
- <span
- class="bg-success w-2 h-2 rounded-full block absolute right-[6px] bottom-0"></span>
- </div>
- </div>
- <div class="ltr:pl-3 rtl:pr-3 flex flex-auto">
- <div class="ltr:pr-3 rtl:pl-3">
- <h6 v-html="notification.message"></h6>
- <span class="text-xs block font-normal dark:text-gray-500"
- v-text="notification.time"></span>
- </div>
- <button type="button"
- class="ltr:ml-auto rtl:mr-auto text-neutral-300 hover:text-danger opacity-0 group-hover:opacity-100"
- @click="removeNotification(notification.id)">
- <icon-x-circle />
- </button>
- </div>
- </div>
- </li>
- </template>
- <template v-if="notifications.length">
- <li>
- <div class="p-4">
- <button class="btn btn-primary block w-full btn-small"
- @click="close()">Read All Notifications</button>
- </div>
- </li>
- </template>
- <template v-if="!notifications.length">
- <li>
- <div
- class="!grid place-content-center hover:!bg-transparent text-lg min-h-[200px]">
- <div
- class="mx-auto ring-4 ring-primary/30 rounded-full mb-4 text-primary">
- <icon-info-circle :fill="true" class="w-10 h-10" />
- </div>
- No data available.
- </div>
- </li>
- </template>
- </ul>
- </template>
- </Popper>
- </div> -->
- <div class="dropdown shrink-0">
- <Popper :placement="store.state.rtlClass === 'rtl' ? 'bottom-end' : 'bottom-start'" offsetDistance="8" class="!block">
- <button type="button" class="relative group block">
- <img
- class="w-9 h-9 rounded-full object-cover saturate-50 group-hover:saturate-100"
- v-if="store.state.user.user.face !== undefined"
- :src="store.state.user.user.face"
- alt=""
- />
- <img class="w-9 h-9 rounded-full object-cover saturate-50 group-hover:saturate-100" v-else src="../../assets/images/logos.png" alt="" />
- </button>
- <template #content="{ close }">
- <ul class="text-dark dark:text-white-dark !py-0 w-[230px] font-semibold dark:text-white-light/90">
- <li>
- <div class="flex items-center px-4 py-4">
- <div class="flex-none">
- <img
- class="rounded-md w-10 h-10 object-cover"
- v-if="store.state.user.user.face !== undefined"
- :src="store.state.user.user.face"
- alt=""
- />
- <img class="rounded-md w-10 h-10 object-cover" v-else src="../../assets/images/logos.png" alt="" />
- </div>
- <div class="ltr:pl-4 rtl:pr-4 truncate">
- <h4 class="text-base">
- {{ store.state.user.user.username }}<span class="text-xs bg-success-light rounded text-success px-1 ltr:ml-2 rtl:ml-2">Pro</span>
- </h4>
- <!-- <a class="text-black/60 hover:text-primary dark:text-dark-light/60 dark:hover:text-white" href="javascript:;">johndoe@gmail.com</a> -->
- </div>
- </div>
- </li>
- <li>
- <a href="javascript:;" class="dark:hover:text-white" @click="goInfo">
- <icon-user class="w-4.5 h-4.5 ltr:mr-2 rtl:ml-2 shrink-0" />
- 个人信息
- </a>
- </li>
- <li>
- <a href="javascript:;" class="dark:hover:text-white" @click="editPassword">
- <icon-lock-dots class="w-4.5 h-4.5 ltr:mr-2 rtl:ml-2 shrink-0" />
- 修改密码
- </a>
- </li>
- <li class="border-t border-white-light dark:border-white-light/10">
- <a class="text-danger !py-3 dark:hover:text-white" @click="handleLogoutClick">
- <icon-logout class="w-4.5 h-4.5 ltr:mr-2 rtl:ml-2 rotate-90 shrink-0" />
- 退出
- </a>
- </li>
- </ul>
- </template>
- </Popper>
- </div>
- </div>
- </div>
- </div>
- </header>
- </template>
- <script lang="ts" setup>
- import { ref, onMounted, computed, reactive, watch } from 'vue';
- import { useI18n } from 'vue-i18n';
- import appSetting from '@/app-setting';
- import { useRouter, useRoute } from 'vue-router';
- import { useStore } from 'vuex';
- import IconMenu from '@/components/icon/icon-menu.vue';
- import IconCalendar from '@/components/icon/icon-calendar.vue';
- import IconEdit from '@/components/icon/icon-edit.vue';
- import IconChatNotification from '@/components/icon/icon-chat-notification.vue';
- import IconSearch from '@/components/icon/icon-search.vue';
- import IconXCircle from '@/components/icon/icon-x-circle.vue';
- import IconSun from '@/components/icon/icon-sun.vue';
- import IconMoon from '@/components/icon/icon-moon.vue';
- import IconLaptop from '@/components/icon/icon-laptop.vue';
- import IconMailDot from '@/components/icon/icon-mail-dot.vue';
- import IconArrowLeft from '@/components/icon/icon-arrow-left.vue';
- /* import IconInfoCircle from '@/components/icon/icon-info-circle.vue';
- import IconBellBing from '@/components/icon/icon-bell-bing.vue';
- import IconUser from '@/components/icon/icon-user.vue';
- import IconMail from '@/components/icon/icon-mail.vue';
- import IconLockDots from '@/components/icon/icon-lock-dots.vue';
- import IconLogout from '@/components/icon/icon-logout.vue'; */
- import IconMenuDashboard from '@/components/icon/menu/icon-menu-dashboard.vue';
- import IconCaretDown from '@/components/icon/icon-caret-down.vue';
- import IconMenuApps from '@/components/icon/menu/icon-menu-apps.vue';
- import IconMenuComponents from '@/components/icon/menu/icon-menu-components.vue';
- import IconMenuElements from '@/components/icon/menu/icon-menu-elements.vue';
- import IconMenuDatatables from '@/components/icon/menu/icon-menu-datatables.vue';
- import IconMenuForms from '@/components/icon/menu/icon-menu-forms.vue';
- import IconMenuPages from '@/components/icon/menu/icon-menu-pages.vue';
- import IconMenuMore from '@/components/icon/menu/icon-menu-more.vue';
- import { ElMessageBox } from 'element-plus';
- import * as API_Company from '@/api/company';
- //ElMessageBox
- const store = useStore();
- const route = useRoute();
- const router = useRouter();
- const search = ref(false);
- // multi language
- const i18n = reactive(useI18n());
- const changeLanguage = (item: any) => {
- i18n.locale = item.code;
- appSetting.toggleLanguage(item);
- };
- const superMenu = computed(() => store.state.superMenu);
- const founder = computed(() => store.state.user.user.founder);
- const currentFlag = computed(() => {
- return `/assets/images/flags/${i18n.locale.toUpperCase()}.svg`;
- });
- const countNot = ref(0);
- /* 获取账号未读消息 */
- const GET_countNot = () => {
- API_Company.countNotReadSys().then((res) => {
- countNot.value = res;
- });
- };
- const notifications = ref([
- {
- id: 1,
- profile: 'user-profile.jpeg',
- message: '<strong class="text-sm mr-1">John Doe</strong>invite you to <strong>Prototyping</strong>',
- time: '45 min ago',
- },
- {
- id: 2,
- profile: 'profile-34.jpeg',
- message: '<strong class="text-sm mr-1">Adam Nolan</strong>mentioned you to <strong>UX Basics</strong>',
- time: '9h Ago',
- },
- {
- id: 3,
- profile: 'profile-16.jpeg',
- message: '<strong class="text-sm mr-1">Anna Morgan</strong>Upload a file',
- time: '9h Ago',
- },
- ]);
- const messages = ref([
- {
- id: 1,
- image:
- '<span class="grid place-content-center w-9 h-9 rounded-full bg-success-light dark:bg-success text-success dark:text-success-light"><svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg></span>',
- title: 'Congratulations!',
- message: 'Your OS has been updated.',
- time: '1hr',
- },
- {
- id: 2,
- image:
- '<span class="grid place-content-center w-9 h-9 rounded-full bg-info-light dark:bg-info text-info dark:text-info-light"><svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg></span>',
- title: 'Did you know?',
- message: 'You can switch between artboards.',
- time: '2hr',
- },
- {
- id: 3,
- image:
- '<span class="grid place-content-center w-9 h-9 rounded-full bg-danger-light dark:bg-danger text-danger dark:text-danger-light"> <svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></span>',
- title: 'Something went wrong!',
- message: 'Send Reposrt',
- time: '2days',
- },
- {
- id: 4,
- image:
- '<span class="grid place-content-center w-9 h-9 rounded-full bg-warning-light dark:bg-warning text-warning dark:text-warning-light"><svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"></circle> <line x1="12" y1="8" x2="12" y2="12"></line> <line x1="12" y1="16" x2="12.01" y2="16"></line></svg></span>',
- title: 'Warning',
- message: 'Your password strength is low.',
- time: '5days',
- },
- ]);
- onMounted(() => {
- setActiveDropdown();
- GET_countNot();
- });
- watch(route, (to, from) => {
- setActiveDropdown();
- });
- const setActiveDropdown = () => {
- const selector = document.querySelector('ul.horizontal-menu a[href="' + window.location.pathname + '"]');
- if (selector) {
- selector.classList.add('active');
- const all: any = document.querySelectorAll('ul.horizontal-menu .nav-link.active');
- for (let i = 0; i < all.length; i++) {
- all[0]?.classList.remove('active');
- }
- const ul: any = selector.closest('ul.sub-menu');
- if (ul) {
- let ele: any = ul.closest('li.menu').querySelectorAll('.nav-link');
- if (ele) {
- ele = ele[0];
- setTimeout(() => {
- ele?.classList.add('active');
- });
- }
- }
- }
- };
- /* 前往消息页面 */
- const goNotify = () => {
- router.push({
- name: 'Notify',
- });
- };
- /* 修改密码 */
- const editPassword = () => {
- router.push({
- path: '/lockscreen',
- });
- };
- /* 前往个人信息页面 */
- const goInfo = () => {
- router.push({
- name: 'companyInfo',
- });
- };
- const removeNotification = (value: number) => {
- notifications.value = notifications.value.filter((d) => d.id !== value);
- };
- const removeMessage = (value: number) => {
- messages.value = messages.value.filter((d) => d.id !== value);
- };
- const toggleSidebars = () => {
- store.dispatch('toggleSidebar');
- };
- const toggleTheme = (theme) => {
- store.dispatch('toggleTheme', theme);
- };
- const closes = () => {
- console.log('001');
- };
- const handleLogoutClick = () => {
- ElMessageBox.confirm('确定退出吗?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- })
- .then(() => {
- store.dispatch('logoutAction').then(() => {
- const route = router.resolve('/login');
- location.replace(route.href); // 为了重新实例化vue-router对象 避免bug
- });
- })
- .catch(() => {
- /* Handle cancel action if needed */
- });
- };
- const getBranch = (value) => {
- store.dispatch('toggleSuperMenu', value);
- router.push({
- name: 'dashboard',
- });
- };
- </script>
|