| | |
| | | <script lang="tsx"> |
| | | import type { PropType, CSSProperties } from 'vue'; |
| | | import type { PropType, CSSProperties } from 'vue'; |
| | | |
| | | import { computed, defineComponent, unref, toRef } from 'vue'; |
| | | import { BasicMenu } from '/@/components/Menu'; |
| | | import { SimpleMenu } from '/@/components/SimpleMenu'; |
| | | import { AppLogo } from '/@/components/Application'; |
| | | import { computed, defineComponent, unref, toRef } from 'vue'; |
| | | import { BasicMenu } from '@/components/Menu'; |
| | | import { SimpleMenu } from '@/components/SimpleMenu'; |
| | | import { AppLogo } from '@/components/Application'; |
| | | |
| | | import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum'; |
| | | import { MenuModeEnum, MenuSplitTyeEnum } from '@/enums/menuEnum'; |
| | | |
| | | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
| | | import { ScrollContainer } from '/@/components/Container'; |
| | | import { useMenuSetting } from '@/hooks/setting/useMenuSetting'; |
| | | import { ScrollContainer } from '@/components/Container'; |
| | | |
| | | import { useGo } from '/@/hooks/web/usePage'; |
| | | import { useSplitMenu } from './useLayoutMenu'; |
| | | import { openWindow } from '/@/utils'; |
| | | import { propTypes } from '/@/utils/propTypes'; |
| | | import { isNullOrUnDef, isUrl } from '/@/utils/is'; |
| | | import { useRootSetting } from '/@/hooks/setting/useRootSetting'; |
| | | import { useAppInject } from '/@/hooks/web/useAppInject'; |
| | | import { useDesign } from '/@/hooks/web/useDesign'; |
| | | import { getEntity } from '/@/api/tigerapi/system'; |
| | | import { useGo } from '@/hooks/web/usePage'; |
| | | import { useSplitMenu } from './useLayoutMenu'; |
| | | import { openWindow } from '@/utils'; |
| | | import { propTypes } from '@/utils/propTypes'; |
| | | import { isHttpUrl, isNullOrUnDef } from '@/utils/is'; |
| | | import { useRootSetting } from '@/hooks/setting/useRootSetting'; |
| | | import { useAppInject } from '@/hooks/web/useAppInject'; |
| | | import { useDesign } from '@/hooks/web/useDesign'; |
| | | import { getEntity } from '/@/api/tigerapi/system'; |
| | | |
| | | export default defineComponent({ |
| | | name: 'LayoutMenu', |
| | | props: { |
| | | theme: propTypes.oneOf(['light', 'dark']), |
| | | export default defineComponent({ |
| | | name: 'LayoutMenu', |
| | | props: { |
| | | theme: propTypes.oneOf(['light', 'dark']), |
| | | |
| | | splitType: { |
| | | type: Number as PropType<MenuSplitTyeEnum>, |
| | | default: MenuSplitTyeEnum.NONE, |
| | | splitType: { |
| | | type: Number as PropType<MenuSplitTyeEnum>, |
| | | default: MenuSplitTyeEnum.NONE, |
| | | }, |
| | | |
| | | isHorizontal: propTypes.bool, |
| | | // menu Mode |
| | | menuMode: { |
| | | type: [String] as PropType<MenuModeEnum | null>, |
| | | default: '', |
| | | }, |
| | | }, |
| | | setup(props) { |
| | | const go = useGo(); |
| | | |
| | | isHorizontal: propTypes.bool, |
| | | // menu Mode |
| | | menuMode: { |
| | | type: [String] as PropType<MenuModeEnum | null>, |
| | | default: '', |
| | | const { |
| | | getMenuMode, |
| | | getMenuType, |
| | | getMenuTheme, |
| | | getCollapsed, |
| | | getCollapsedShowTitle, |
| | | getAccordion, |
| | | getIsHorizontal, |
| | | getIsSidebarType, |
| | | getSplit, |
| | | } = useMenuSetting(); |
| | | const { getShowLogo } = useRootSetting(); |
| | | |
| | | const { prefixCls } = useDesign('layout-menu'); |
| | | |
| | | const { menusRef } = useSplitMenu(toRef(props, 'splitType')); |
| | | |
| | | const { getIsMobile } = useAppInject(); |
| | | |
| | | const getComputedMenuMode = computed(() => |
| | | unref(getIsMobile) ? MenuModeEnum.INLINE : props.menuMode || unref(getMenuMode), |
| | | ); |
| | | |
| | | const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme)); |
| | | |
| | | const getIsShowLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType)); |
| | | |
| | | const getUseScroll = computed(() => { |
| | | return ( |
| | | !unref(getIsHorizontal) && |
| | | (unref(getIsSidebarType) || |
| | | props.splitType === MenuSplitTyeEnum.LEFT || |
| | | props.splitType === MenuSplitTyeEnum.NONE) |
| | | ); |
| | | }); |
| | | |
| | | const getWrapperStyle = computed((): CSSProperties => { |
| | | return { |
| | | height: `calc(100% - ${unref(getIsShowLogo) ? '48px' : '0px'})`, |
| | | }; |
| | | }); |
| | | |
| | | const getLogoClass = computed(() => { |
| | | return [ |
| | | `${prefixCls}-logo`, |
| | | unref(getComputedMenuTheme), |
| | | { |
| | | [`${prefixCls}--mobile`]: unref(getIsMobile), |
| | | }, |
| | | ]; |
| | | }); |
| | | |
| | | const getCommonProps = computed(() => { |
| | | const menus = unref(menusRef); |
| | | return { |
| | | menus, |
| | | beforeClickFn: beforeMenuClickFn, |
| | | items: menus, |
| | | theme: unref(getComputedMenuTheme), |
| | | accordion: unref(getAccordion), |
| | | collapse: unref(getCollapsed), |
| | | collapsedShowTitle: unref(getCollapsedShowTitle), |
| | | onMenuClick: handleMenuClick, |
| | | }; |
| | | }); |
| | | /** |
| | | * click menu |
| | | * @param menu |
| | | */ |
| | | |
| | | function handleMenuClick(path: string) { |
| | | if (path.split('/').length > 2 && path.split('/')[2] == 'LC') { |
| | | getEntity({ |
| | | sqlcmd: `CODE_NAME ='${path.split('/')[1]}'`, |
| | | entityName: 'SYS_LOW_CODE', |
| | | order: '', |
| | | }).then((data) => { |
| | | var searchForms = JSON.parse(data.Data.Items[0].SEARCH_FORM_JSON); |
| | | let colSlots = [] as string[]; |
| | | for (const i in searchForms) { |
| | | if (!isNullOrUnDef(searchForms[i]['colSlot'])) { |
| | | colSlots.push('form-' + searchForms[i]['colSlot']); |
| | | } |
| | | } |
| | | |
| | | var _cruds = JSON.parse(data.Data.Items[0].FORM_JSON); |
| | | let crudColSlots = [] as string[]; |
| | | for (const i in _cruds) { |
| | | if (!isNullOrUnDef(_cruds[i]['colSlot'])) { |
| | | crudColSlots.push(_cruds[i]['colSlot']); |
| | | } |
| | | } |
| | | const id = { ID:path.split('/')[1], EntityName: data.Data.Items[0].ASSEMBLY_NAME, colSlots: colSlots, crudColSlots: crudColSlots }; |
| | | go(`/${path.split('/')[1]}/${path.split('/')[2]}/${encodeURI(JSON.stringify(id))}`); |
| | | }); |
| | | } else if ( |
| | | (path.split('/').length > 2 && path.split('/')[2] == 'High') || |
| | | path.split('/')[2] == 'CP' |
| | | ) { |
| | | const id = { |
| | | Name: path.split('/')[1], |
| | | Title: `${path.split('/')[1]}`, |
| | | colSlots: [], |
| | | crudColSlots: [], |
| | | OtherTableName: [], |
| | | SessionName: |
| | | `${path.split('/')[1]}_update` /* session名,用来传递参数,不在浏览器地址栏显示 */, |
| | | }; |
| | | // 将对象转换为JSON字符串并保存到sessionStorage |
| | | sessionStorage.removeItem(`${id.SessionName}_params`); |
| | | sessionStorage.setItem(`${id.SessionName}_params`, encodeURI(JSON.stringify(id))); |
| | | go(`/${path.split('/')[1]}/${path.split('/')[2]}/${encodeURI(JSON.stringify({ sName: id.SessionName, Name: id.Name }))}`); |
| | | } else { |
| | | go(path); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * before click menu |
| | | * @param menu |
| | | */ |
| | | async function beforeMenuClickFn(path: string) { |
| | | if (!isHttpUrl(path)) { |
| | | return true; |
| | | } |
| | | openWindow(path); |
| | | return false; |
| | | } |
| | | |
| | | function renderHeader() { |
| | | if (!unref(getIsShowLogo) && !unref(getIsMobile)) return null; |
| | | |
| | | return ( |
| | | <AppLogo |
| | | showTitle={!unref(getCollapsed)} |
| | | class={unref(getLogoClass)} |
| | | theme={unref(getComputedMenuTheme)} |
| | | /> |
| | | ); |
| | | } |
| | | |
| | | function renderMenu() { |
| | | const { menus, ...menuProps } = unref(getCommonProps); |
| | | // console.log(menus); |
| | | if (!menus || !menus.length) return null; |
| | | return !props.isHorizontal ? ( |
| | | <SimpleMenu {...menuProps} isSplitMenu={unref(getSplit)} items={menus} /> |
| | | ) : ( |
| | | <BasicMenu |
| | | {...(menuProps as any)} |
| | | isHorizontal={props.isHorizontal} |
| | | type={unref(getMenuType)} |
| | | showLogo={unref(getIsShowLogo)} |
| | | mode={unref(getComputedMenuMode as any)} |
| | | items={menus} |
| | | /> |
| | | ); |
| | | } |
| | | |
| | | return () => { |
| | | return ( |
| | | <> |
| | | {renderHeader()} |
| | | {unref(getUseScroll) ? ( |
| | | <ScrollContainer style={unref(getWrapperStyle)}>{() => renderMenu()}</ScrollContainer> |
| | | ) : ( |
| | | renderMenu() |
| | | )} |
| | | </> |
| | | ); |
| | | }; |
| | | }, |
| | | }, |
| | | setup(props) { |
| | | const go = useGo(); |
| | | |
| | | const { |
| | | getMenuMode, |
| | | getMenuType, |
| | | getMenuTheme, |
| | | getCollapsed, |
| | | getCollapsedShowTitle, |
| | | getAccordion, |
| | | getIsHorizontal, |
| | | getIsSidebarType, |
| | | getSplit, |
| | | } = useMenuSetting(); |
| | | const { getShowLogo } = useRootSetting(); |
| | | |
| | | const { prefixCls } = useDesign('layout-menu'); |
| | | |
| | | const { menusRef } = useSplitMenu(toRef(props, 'splitType')); |
| | | |
| | | const { getIsMobile } = useAppInject(); |
| | | |
| | | const getComputedMenuMode = computed(() => |
| | | unref(getIsMobile) ? MenuModeEnum.INLINE : props.menuMode || unref(getMenuMode), |
| | | ); |
| | | |
| | | const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme)); |
| | | |
| | | const getIsShowLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType)); |
| | | |
| | | const getUseScroll = computed(() => { |
| | | return ( |
| | | !unref(getIsHorizontal) && |
| | | (unref(getIsSidebarType) || |
| | | props.splitType === MenuSplitTyeEnum.LEFT || |
| | | props.splitType === MenuSplitTyeEnum.NONE) |
| | | ); |
| | | }); |
| | | |
| | | const getWrapperStyle = computed((): CSSProperties => { |
| | | return { |
| | | height: `calc(100% - ${unref(getIsShowLogo) ? '48px' : '0px'})`, |
| | | }; |
| | | }); |
| | | |
| | | const getLogoClass = computed(() => { |
| | | return [ |
| | | `${prefixCls}-logo`, |
| | | unref(getComputedMenuTheme), |
| | | { |
| | | [`${prefixCls}--mobile`]: unref(getIsMobile), |
| | | }, |
| | | ]; |
| | | }); |
| | | |
| | | const getCommonProps = computed(() => { |
| | | const menus = unref(menusRef); |
| | | return { |
| | | menus, |
| | | beforeClickFn: beforeMenuClickFn, |
| | | items: menus, |
| | | theme: unref(getComputedMenuTheme), |
| | | accordion: unref(getAccordion), |
| | | collapse: unref(getCollapsed), |
| | | collapsedShowTitle: unref(getCollapsedShowTitle), |
| | | onMenuClick: handleMenuClick, |
| | | }; |
| | | }); |
| | | /** |
| | | * click menu |
| | | * @param menu |
| | | */ |
| | | |
| | | function handleMenuClick(path: string) { |
| | | if (path.split('/').length > 2 && path.split('/')[2] == 'LC') { |
| | | getEntity({ |
| | | sqlcmd: `ASSEMBLY_NAME ='${path.split('/')[1]}'`, |
| | | entityName: 'SYS_LOW_CODE', |
| | | }).then((data) => { |
| | | var searchForms = JSON.parse(data.Data.Items[0].SEARCH_FORM_JSON); |
| | | let colSlots = [] as string[]; |
| | | for (const i in searchForms) { |
| | | if (!isNullOrUnDef(searchForms[i]['colSlot'])) { |
| | | colSlots.push('form-' + searchForms[i]['colSlot']); |
| | | } |
| | | } |
| | | |
| | | var _cruds = JSON.parse(data.Data.Items[0].FORM_JSON); |
| | | let crudColSlots = [] as string[]; |
| | | for (const i in _cruds) { |
| | | if (!isNullOrUnDef(_cruds[i]['colSlot'])) { |
| | | crudColSlots.push(_cruds[i]['colSlot']); |
| | | } |
| | | } |
| | | const id = { ID: path.split('/')[1], colSlots: colSlots, crudColSlots: crudColSlots }; |
| | | go(`/${path.split('/')[1]}/${path.split('/')[2]}/${encodeURI(JSON.stringify(id))}`); |
| | | }); |
| | | } else if (path.split('/').length > 2 && path.split('/')[2] == 'High') { |
| | | const id = { Name: path.split('/')[1] }; |
| | | go(`/${path.split('/')[1]}/${path.split('/')[2]}/${encodeURI(JSON.stringify(id))}`); |
| | | } else { |
| | | go(path); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * before click menu |
| | | * @param menu |
| | | */ |
| | | async function beforeMenuClickFn(path: string) { |
| | | if (!isUrl(path)) { |
| | | return true; |
| | | } |
| | | openWindow(path); |
| | | return false; |
| | | } |
| | | |
| | | function renderHeader() { |
| | | if (!unref(getIsShowLogo) && !unref(getIsMobile)) return null; |
| | | |
| | | return ( |
| | | <AppLogo |
| | | showTitle={!unref(getCollapsed)} |
| | | class={unref(getLogoClass)} |
| | | theme={unref(getComputedMenuTheme)} |
| | | /> |
| | | ); |
| | | } |
| | | |
| | | function renderMenu() { |
| | | const { menus, ...menuProps } = unref(getCommonProps); |
| | | // console.log(menus); |
| | | if (!menus || !menus.length) return null; |
| | | return !props.isHorizontal ? ( |
| | | <SimpleMenu {...menuProps} isSplitMenu={unref(getSplit)} items={menus} /> |
| | | ) : ( |
| | | <BasicMenu |
| | | {...(menuProps as any)} |
| | | isHorizontal={props.isHorizontal} |
| | | type={unref(getMenuType)} |
| | | showLogo={unref(getIsShowLogo)} |
| | | mode={unref(getComputedMenuMode as any)} |
| | | items={menus} |
| | | /> |
| | | ); |
| | | } |
| | | |
| | | return () => { |
| | | return ( |
| | | <> |
| | | {renderHeader()} |
| | | {unref(getUseScroll) ? ( |
| | | <ScrollContainer style={unref(getWrapperStyle)}>{() => renderMenu()}</ScrollContainer> |
| | | ) : ( |
| | | renderMenu() |
| | | )} |
| | | </> |
| | | ); |
| | | }; |
| | | }, |
| | | }); |
| | | }); |
| | | </script> |
| | | <style lang="less"> |
| | | @prefix-cls: ~'@{namespace}-layout-menu'; |
| | | @logo-prefix-cls: ~'@{namespace}-app-logo'; |
| | | @prefix-cls: ~'@{namespace}-layout-menu'; |
| | | @logo-prefix-cls: ~'@{namespace}-app-logo'; |
| | | |
| | | .@{prefix-cls} { |
| | | &-logo { |
| | | height: @header-height; |
| | | padding: 10px 4px 10px 10px; |
| | | .@{prefix-cls} { |
| | | &-logo { |
| | | height: @header-height; |
| | | padding: 10px 4px 10px 10px; |
| | | |
| | | img { |
| | | width: 150px; //@logo-width; |
| | | height: @logo-width; |
| | | img { |
| | | width: @logo-width; |
| | | height: @logo-width; |
| | | } |
| | | } |
| | | } |
| | | |
| | | &--mobile { |
| | | .@{logo-prefix-cls} { |
| | | &__title { |
| | | opacity: 1; |
| | | &--mobile { |
| | | .@{logo-prefix-cls} { |
| | | &__title { |
| | | opacity: 1; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |