Vben
2021-04-10 215d8bab380728164d7fe2958c2d2d1151fce892
提交 | 用户 | age
a65ad9 1 <template>
V 2   <Dropdown placement="bottomLeft" :overlayClassName="`${prefixCls}-dropdown-overlay`">
a09a0e 3     <span :class="[prefixCls, `${prefixCls}--${theme}`]" class="flex">
3571eb 4       <img :class="`${prefixCls}__header`" :src="headerImg" />
a09a0e 5       <span :class="`${prefixCls}__info hidden md:block`">
V 6         <span :class="`${prefixCls}__name  `" class="truncate">
7           {{ getUserInfo.realName }}
8         </span>
a65ad9 9       </span>
V 10     </span>
11
12     <template #overlay>
13       <Menu @click="handleMenuClick">
3ad1a4 14         <MenuItem
V 15           key="doc"
16           :text="t('layout.header.dropdownItemDoc')"
b335e7 17           icon="ion:document-text-outline"
3ad1a4 18           v-if="getShowDoc"
V 19         />
f6cef1 20         <MenuDivider v-if="getShowDoc" />
a65ad9 21         <MenuItem
b335e7 22           key="lock"
V 23           :text="t('layout.header.tooltipLock')"
24           icon="ion:lock-closed-outline"
25         />
26         <MenuItem
da0491 27           key="logout"
a65ad9 28           :text="t('layout.header.dropdownItemLoginOut')"
27c6f6 29           icon="ion:power-outline"
a65ad9 30         />
V 31       </Menu>
32     </template>
33   </Dropdown>
b335e7 34   <LockAction @register="register" />
a65ad9 35 </template>
V 36 <script lang="ts">
37   // components
38   import { Dropdown, Menu } from 'ant-design-vue';
39
40   import { defineComponent, computed } from 'vue';
41
42   import { DOC_URL } from '/@/settings/siteSetting';
43
215d8b 44   import { useUserStore } from '/@/store/modules/user';
a65ad9 45   import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
V 46   import { useI18n } from '/@/hooks/web/useI18n';
47   import { useDesign } from '/@/hooks/web/useDesign';
b335e7 48   import { useModal } from '/@/components/Modal';
a65ad9 49
b335e7 50   import headerImg from '/@/assets/images/header.jpg';
V 51   import { propTypes } from '/@/utils/propTypes';
52   import { openWindow } from '/@/utils';
53
54   import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
55
da0491 56   type MenuEvent = 'logout' | 'doc' | 'lock';
a65ad9 57
V 58   export default defineComponent({
59     name: 'UserDropdown',
60     components: {
61       Dropdown,
62       Menu,
63       MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
64       MenuDivider: Menu.Divider,
b335e7 65       LockAction: createAsyncComponent(() => import('../lock/LockModal.vue')),
a65ad9 66     },
V 67     props: {
68       theme: propTypes.oneOf(['dark', 'light']),
69     },
70     setup() {
71       const { prefixCls } = useDesign('header-user-dropdown');
72       const { t } = useI18n();
73       const { getShowDoc } = useHeaderSetting();
215d8b 74       const userStore = useUserStore();
a65ad9 75
V 76       const getUserInfo = computed(() => {
215d8b 77         const { realName = '', desc } = userStore.getUserInfo || {};
a65ad9 78         return { realName, desc };
V 79       });
b335e7 80
V 81       const [register, { openModal }] = useModal();
82
83       function handleLock() {
84         openModal(true);
85       }
a65ad9 86
V 87       //  login out
88       function handleLoginOut() {
89         userStore.confirmLoginOut();
90       }
91
92       // open doc
93       function openDoc() {
94         openWindow(DOC_URL);
95       }
96
97       function handleMenuClick(e: { key: MenuEvent }) {
98         switch (e.key) {
da0491 99           case 'logout':
a65ad9 100             handleLoginOut();
V 101             break;
102           case 'doc':
103             openDoc();
104             break;
b335e7 105           case 'lock':
V 106             handleLock();
107             break;
a65ad9 108         }
V 109       }
110
111       return {
112         prefixCls,
113         t,
114         getUserInfo,
115         handleMenuClick,
116         getShowDoc,
3571eb 117         headerImg,
b335e7 118         register,
a65ad9 119       };
V 120     },
121   });
122 </script>
123 <style lang="less">
124   @prefix-cls: ~'@{namespace}-header-user-dropdown';
125
126   .@{prefix-cls} {
127     height: @header-height;
128     padding: 0 0 0 10px;
129     padding-right: 10px;
130     overflow: hidden;
131     font-size: 12px;
132     cursor: pointer;
133     align-items: center;
134
135     img {
8a1406 136       width: 24px;
V 137       height: 24px;
a65ad9 138       margin-right: 12px;
V 139     }
140
141     &__header {
142       border-radius: 50%;
143     }
144
145     &__name {
146       font-size: 14px;
147     }
148
149     &--dark {
150       &:hover {
151         background: @header-dark-bg-hover-color;
152       }
153     }
154
155     &--light {
156       .@{prefix-cls}__name {
157         color: @text-color-base;
158       }
159
160       .@{prefix-cls}__desc {
161         color: @header-light-desc-color;
162       }
163     }
164
165     &-dropdown-overlay {
166       .ant-dropdown-menu-item {
167         min-width: 160px;
168       }
169     }
170   }
171 </style>