index.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <template>
  2. <Header :class="getHeaderClass">
  3. <!-- left start -->
  4. <div :class="`${prefixCls}-left`">
  5. <!-- logo -->
  6. <AppLogo v-if="getShowHeaderLogo || getIsMobile" :class="`${prefixCls}-logo`" :theme="getHeaderTheme" :style="getLogoWidth" />
  7. <LayoutTrigger
  8. v-if="(getShowContent && getShowHeaderTrigger && !getSplit && !getIsMixSidebar) || getIsMobile"
  9. :theme="getHeaderTheme"
  10. :sider="false"
  11. />
  12. <LayoutBreadcrumb v-if="getShowContent && getShowBread" :theme="getHeaderTheme" />
  13. <!-- 欢迎语 -->
  14. <span
  15. v-if="getShowContent && getShowBreadTitle && !getIsMobile"
  16. :class="[prefixCls, `${prefixCls}--${getHeaderTheme}`, 'headerIntroductionClass']"
  17. >
  18. {{ t('layout.header.welcomeIn') }} {{ title }}
  19. </span>
  20. </div>
  21. <!-- left end -->
  22. <!-- menu start -->
  23. <div :class="`${prefixCls}-menu`" v-if="getShowTopMenu && !getIsMobile">
  24. <LayoutMenu :isHorizontal="true" :theme="getHeaderTheme" :splitType="getSplitType" :menuMode="getMenuMode" />
  25. </div>
  26. <!-- menu-end -->
  27. <!-- action -->
  28. <div :class="`${prefixCls}-action`">
  29. <Row>
  30. <Col :span="24">
  31. <div class="mr-3" v-if="isShowSelect">
  32. <Select :options="deptList" :fieldNames="{ label: 'departName', value: 'id' }" v-model:value="currentId"></Select> </div
  33. ></Col>
  34. </Row>
  35. <AppSearch :class="`${prefixCls}-action__item `" v-if="getShowSearch" />
  36. <ErrorAction v-if="getUseErrorHandle" :class="`${prefixCls}-action__item error-action`" />
  37. <Notify v-if="getShowNotice" :class="`${prefixCls}-action__item notify-item`" />
  38. <FullScreen v-if="getShowFullScreen" :class="`${prefixCls}-action__item fullscreen-item`" />
  39. <LockScreen v-if="getUseLockPage" />
  40. <UserDropDown :theme="getHeaderTheme" />
  41. <SettingDrawer v-if="getShowSetting" :class="`${prefixCls}-action__item`" />
  42. </div>
  43. </Header>
  44. <LoginSelect ref="loginSelectRef" @success="loginSelectOk"></LoginSelect>
  45. </template>
  46. <script lang="ts">
  47. import { defineComponent, unref, computed, ref, onMounted, toRaw } from 'vue';
  48. import { useGlobSetting } from '/@/hooks/setting';
  49. import { propTypes } from '/@/utils/propTypes';
  50. import { Layout, Select, Row, Col } from 'ant-design-vue';
  51. import { AppLogo } from '/@/components/Application';
  52. import LayoutMenu from '../menu/index.vue';
  53. import LayoutTrigger from '../trigger/index.vue';
  54. import { AppSearch } from '/@/components/Application';
  55. import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
  56. import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
  57. import { useRootSetting } from '/@/hooks/setting/useRootSetting';
  58. import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
  59. import { SettingButtonPositionEnum } from '/@/enums/appEnum';
  60. import { UserDropDown, LayoutBreadcrumb, FullScreen, Notify, ErrorAction, LockScreen } from './components';
  61. import { useAppInject } from '/@/hooks/web/useAppInject';
  62. import { useDesign } from '/@/hooks/web/useDesign';
  63. import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
  64. import { useLocale } from '/@/locales/useLocale';
  65. import LoginSelect from '/@/views/sys/login/LoginSelect.vue';
  66. import { useUserStore } from '/@/store/modules/user';
  67. import { useI18n } from '/@/hooks/web/useI18n';
  68. const { t } = useI18n();
  69. import { useShopInfoStore } from '/@/store/modules/shopInfo';
  70. import { storeToRefs } from 'pinia';
  71. export default defineComponent({
  72. name: 'LayoutHeader',
  73. components: {
  74. Header: Layout.Header,
  75. AppLogo,
  76. LayoutTrigger,
  77. LayoutBreadcrumb,
  78. LayoutMenu,
  79. UserDropDown,
  80. FullScreen,
  81. Notify,
  82. AppSearch,
  83. ErrorAction,
  84. LockScreen,
  85. LoginSelect,
  86. Select,
  87. Row,
  88. Col,
  89. SettingDrawer: createAsyncComponent(() => import('/@/layouts/default/setting/index.vue'), {
  90. loading: true,
  91. }),
  92. },
  93. props: {
  94. fixed: propTypes.bool,
  95. },
  96. setup(props) {
  97. const { prefixCls } = useDesign('layout-header');
  98. const userStore = useUserStore();
  99. const { getShowTopMenu, getShowHeaderTrigger, getSplit, getIsMixMode, getMenuWidth, getIsMixSidebar } = useMenuSetting();
  100. const { getUseErrorHandle, getShowSettingButton, getSettingButtonPosition, getAiIconShow } = useRootSetting();
  101. const { title } = useGlobSetting();
  102. const { isShowSelect, deptList, currentId } = storeToRefs(useShopInfoStore());
  103. const {
  104. getHeaderTheme,
  105. getShowFullScreen,
  106. getShowNotice,
  107. getShowContent,
  108. getShowBread,
  109. getShowHeaderLogo,
  110. getShowHeader,
  111. getShowSearch,
  112. getUseLockPage,
  113. getShowBreadTitle,
  114. } = useHeaderSetting();
  115. const { getShowLocalePicker } = useLocale();
  116. const { getIsMobile } = useAppInject();
  117. const getHeaderClass = computed(() => {
  118. const theme = unref(getHeaderTheme);
  119. return [
  120. prefixCls,
  121. {
  122. [`${prefixCls}--fixed`]: props.fixed,
  123. [`${prefixCls}--mobile`]: unref(getIsMobile),
  124. [`${prefixCls}--${theme}`]: theme,
  125. },
  126. ];
  127. });
  128. const getShowSetting = computed(() => {
  129. if (!unref(getShowSettingButton)) {
  130. return false;
  131. }
  132. const settingButtonPosition = unref(getSettingButtonPosition);
  133. if (settingButtonPosition === SettingButtonPositionEnum.AUTO) {
  134. return unref(getShowHeader);
  135. }
  136. return settingButtonPosition === SettingButtonPositionEnum.HEADER;
  137. });
  138. const getLogoWidth = computed(() => {
  139. if (!unref(getIsMixMode) || unref(getIsMobile)) {
  140. return {};
  141. }
  142. const width = unref(getMenuWidth) < 180 ? 180 : unref(getMenuWidth);
  143. return { width: `${width}px` };
  144. });
  145. const getSplitType = computed(() => {
  146. return unref(getSplit) ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE;
  147. });
  148. const getMenuMode = computed(() => {
  149. return unref(getSplit) ? MenuModeEnum.HORIZONTAL : null;
  150. });
  151. /**
  152. * 首页多租户部门弹窗逻辑
  153. */
  154. const loginSelectRef = ref();
  155. function showLoginSelect() {
  156. //update-begin---author:liusq Date:20220101 for:判断登录进来是否需要弹窗选择租户----
  157. //判断是否是登陆进来
  158. const loginInfo = toRaw(userStore.getLoginInfo) || {};
  159. if (!!loginInfo.isLogin) {
  160. loginSelectRef.value.show(loginInfo);
  161. }
  162. //update-end---author:liusq Date:20220101 for:判断登录进来是否需要弹窗选择租户----
  163. }
  164. function loginSelectOk() {
  165. console.log('成功。。。。。');
  166. }
  167. onMounted(() => {
  168. showLoginSelect();
  169. });
  170. return {
  171. prefixCls,
  172. getHeaderClass,
  173. getShowHeaderLogo,
  174. getHeaderTheme,
  175. getShowHeaderTrigger,
  176. getIsMobile,
  177. getShowBreadTitle,
  178. getShowBread,
  179. getShowContent,
  180. getSplitType,
  181. getSplit,
  182. getMenuMode,
  183. getShowTopMenu,
  184. getShowLocalePicker,
  185. getShowFullScreen,
  186. getShowNotice,
  187. getUseErrorHandle,
  188. getLogoWidth,
  189. getIsMixSidebar,
  190. getShowSettingButton,
  191. getShowSetting,
  192. getShowSearch,
  193. getUseLockPage,
  194. loginSelectOk,
  195. loginSelectRef,
  196. title,
  197. t,
  198. getAiIconShow,
  199. isShowSelect,
  200. deptList,
  201. currentId,
  202. };
  203. },
  204. });
  205. </script>
  206. <style lang="less">
  207. @import './index.less';
  208. //update-begin---author:scott ---date:2022-09-30 for:默认隐藏顶部菜单面包屑-----------
  209. //顶部欢迎语展示样式
  210. @prefix-cls: ~'@{namespace}-layout-header';
  211. .ant-layout .@{prefix-cls} {
  212. display: flex;
  213. padding: 0 8px;
  214. // update-begin--author:liaozhiyang---date:20240407---for:【QQYUN-8762】顶栏高度
  215. height: @header-height;
  216. // update-end--author:liaozhiyang---date:20240407---for:【QQYUN-8762】顶栏高度
  217. align-items: center;
  218. .headerIntroductionClass {
  219. margin-right: 4px;
  220. margin-bottom: 2px;
  221. border-bottom: 0px;
  222. border-left: 0px;
  223. }
  224. &--light {
  225. .headerIntroductionClass {
  226. color: #000;
  227. }
  228. }
  229. &--dark {
  230. .headerIntroductionClass {
  231. color: rgba(255, 255, 255, 1);
  232. }
  233. .anticon,
  234. .truncate {
  235. color: rgba(255, 255, 255, 1);
  236. }
  237. }
  238. //update-end---author:scott ---date::2022-09-30 for:默认隐藏顶部菜单面包屑--------------
  239. }
  240. </style>