<template> <div class="app-app-menu"> <app-icon-menus :menus = "menus" :ctrlName = "'iconmenu'" @menuClick="select"></app-icon-menus> </div> </template> <script lang='tsx'> import { Vue, Component, Prop, Provide, Emit, Watch, Model,Inject } from 'vue-property-decorator'; import { CreateElement } from 'vue'; import { Subject, Subscription } from 'rxjs'; import { ControlInterface } from '@/interface/control'; import { UIActionTool,Util,ViewTool } from '@/utils'; import NavDataService from '@/service/app/navdata-service'; import AppCenterService from "@service/app/app-center-service"; import IconMenuService from './icon-menu-appmenu-service'; import IconMenuModel from './icon-menu-appmenu-model'; import { Environment } from '@/environments/environment'; import AuthService from '@/authservice/auth-service'; @Component({ components: { } }) export default class IconMenuBase extends Vue implements ControlInterface { /** * 名称 * * @type {string} * @memberof IconMenuBase */ @Prop() public name?: string; /** * 视图通讯对象 * * @type {Subject<ViewState>} * @memberof IconMenuBase */ @Prop() public viewState!: Subject<ViewState>; /** * 应用上下文 * * @type {*} * @memberof IconMenuBase */ @Prop() public context!: any; /** * 视图参数 * * @type {*} * @memberof IconMenuBase */ @Prop() public viewparams!: any; /** * 视图状态事件 * * @public * @type {(Subscription | undefined)} * @memberof IconMenuBase */ public viewStateEvent: Subscription | undefined; /** * 获取部件类型 * * @returns {string} * @memberof IconMenuBase */ public getControlType(): string { return 'APPMENU' } /** * 建构部件服务对象 * * @type {IconMenuService} * @memberof IconMenuBase */ public service: IconMenuService = new IconMenuService({ $store: this.$store }); /** * 关闭视图 * * @param {any} args * @memberof IconMenuBase */ public closeView(args: any): void { let _this: any = this; _this.$emit('closeview', [args]); } /** * 计数器刷新 * * @memberof IconMenuBase */ public counterRefresh(){ const _this:any =this; if(_this.counterServiceArray && _this.counterServiceArray.length >0){ _this.counterServiceArray.forEach((item:any) =>{ if(item.refreshData && item.refreshData instanceof Function){ item.refreshData(); } }) } } /** * 获取多项数据 * * @returns {any[]} * @memberof IconMenuBase */ public getDatas(): any[] { return []; } /** * 获取单项树 * * @returns {*} * @memberof IconMenuBase */ public getData(): any { return null; } /** * 导航模式(route:面包屑模式、tab:分页导航模式) * * @type {string} * @memberof IconMenuBase */ @Prop({default:'tab'}) public navModel?:string; /** * 视图标识 * * @type {string} * @memberof IconMenuBase */ @Prop() public viewtag!:string; /** * 菜单模型 * * @public * @type {IconMenuModel} * @memberof IconMenuBase */ public menuMode: IconMenuModel = new IconMenuModel(); /** * 显示处理提示 * * @type {boolean} * @memberof IconMenuBase */ @Prop({ default: true }) public showBusyIndicator?: boolean; /** * 菜单数据 * * @public * @type {any[]} * @memberof IconMenuBase */ @Provide() public menus: any[] = []; /** * 菜单收缩改变 * * @type {boolean} * @memberof IconMenuBase */ @Model() public collapsechange?: boolean; /** * 监听菜单收缩 * * @param {*} newVal * @param {*} oldVal * @memberof IconMenuBase */ @Watch('collapsechange') onCollapsechangeChange(newVal: any, oldVal: any) { if (newVal !== this.isCollapse) { this.isCollapse = !this.isCollapse; } } /** * 当前模式,菜单在顶部还是在底部 * * @type {*} * @memberof IconMenuBase */ @Prop() mode: any; /** * 应用起始页面 * * @type {boolean} * @memberof IconMenuBase */ @Prop({ default: false }) isDefaultPage?: boolean; /** * 空白视图模式 * * @type {boolean} * @memberof IconMenuBase */ @Prop({ default: false }) isBlankMode?:boolean; /** * 默认打开视图 * * @type {*} * @memberof IconMenuBase */ @Prop() defPSAppView: any; /** * 默认激活的index * * @type {*} * @memberof IconMenuBase */ @Provide() defaultActive: any = null; /** * 当前选中主题 * * @type {*} * @memberof IconMenuBase */ @Prop() selectTheme: any; /** * 默认打开的index数组 * * @type {any[]} * @memberof IconMenuBase */ @Provide() public defaultOpeneds: any[] = []; /** * 是否展开 * * @type {boolean} * @memberof IconMenuBase */ @Provide() public isCollapse: boolean = false; /** * 触发方式,默认click * * @type {string} * @memberof IconMenuBase */ @Provide() trigger: string = 'click'; /** * 计数器数据 * * @type {*} * @memberof IconMenuBase */ public counterdata: any = {}; /** * 建构权限服务对象 * * @type {AuthService} * @memberof IconMenuBase */ public authService:AuthService = new AuthService(); /** * vue 生命周期 * * @memberof IconMenuBase */ public created() { this.afterCreated(); } /** * 执行created后的逻辑 * * @memberof IconMenuBase */ public afterCreated(){ if (Object.is(this.mode, 'horizontal')) { this.trigger = 'hover'; } if (this.viewState) { this.viewStateEvent = this.viewState.subscribe(({ tag, action, data }) => { if (!Object.is(tag, this.name)) { return; } this.load(data); }); } } /** * vue 生命周期 * * @memberof IconMenuBase */ public destroyed() { this.afterDestroy(); } /** * 执行destroyed后的逻辑 * * @memberof IconMenuBase */ public afterDestroy() { if (this.viewStateEvent) { this.viewStateEvent.unsubscribe(); } } /** * 获取菜单项数据 * * @public * @param {any[]} items * @param {string} name * @returns * @memberof IconMenuBase */ public compute(items: any[], name: string) { const item: any = {}; items.some((_item: any) => { if (name && Object.is(_item.name, name)) { Object.assign(item, _item); this.setHideSideBar(_item); return true; } if (_item.items && Array.isArray(_item.items)) { const subItem = this.compute(_item.items, name); if (Object.keys(subItem).length > 0) { Object.assign(item, subItem); return true; } } return false; }); return item; } /** * 设置是否隐藏菜单栏 * * @public * @param {*} item * @memberof IconMenuBase */ public setHideSideBar(item: any): void { } /** * 菜单项选中处理 * * @param {*} index * @param {any[]} indexs * @returns * @memberof IconMenuBase */ public select(index: any, indexs: any[]) { let item = this.compute(this.menus, index); if (Object.keys(item).length === 0) { return; } this.click(item); } /** * 菜单点击 * * @public * @param {*} item 菜单数据 * @memberof IconMenuBase */ public click(item: any) { if (item) { let navDataService = NavDataService.getInstance(); if(Object.is(this.navModel,"route")){ navDataService.removeNavData(this.viewtag); } switch (item.appfunctag) { case 'AppFunc75': this.clickAppFunc75(item); return; default: console.warn('未指定应用功能'); } } } /** * 打开Vue官网 * * @param {*} [item={}] * @memberof IconMenu */ public clickAppFunc75(item: any = {}){ const localdata: any = this.$store.getters.getLocalData(); const url = `https://cn.vuejs.org/index.html`; window.open(url, '_blank'); } /** * 数据加载 * * @param {*} data * @memberof IconMenuBase */ public load(data: any) { this.handleMenusResource(this.menuMode.getAppMenuItems()); } /** * 通过统一资源标识计算菜单 * * @param {*} data * @memberof IconMenuBase */ public handleMenusResource(inputMenus:Array<any>){ if(this.$store.getters['authresource/getEnablePermissionValid']){ this.computedEffectiveMenus(inputMenus); this.computeParentMenus(inputMenus); } this.dataProcess(inputMenus); this.menus = inputMenus; } /** * 计算有效菜单项 * * @param {*} inputMenus * @memberof IconMenuBase */ public computedEffectiveMenus(inputMenus:Array<any>){ inputMenus.forEach((_item:any) =>{ if(!this.authService.getMenusPermission(_item)){ _item.hidden = true; if (_item.items && _item.items.length > 0) { this.computedEffectiveMenus(_item.items); } } }) } /** * 计算父项菜单项是否隐藏 * * @param {*} inputMenus * @memberof IconMenuBase */ public computeParentMenus(inputMenus:Array<any>){ if(inputMenus && inputMenus.length >0){ inputMenus.forEach((item:any) =>{ if(item.hidden && item.items && item.items.length >0){ item.items.map((singleItem:any) =>{ if(!singleItem.hidden){ item.hidden = false; }else{ if(singleItem.items && singleItem.items.length >0){ singleItem.items.map((grandsonItem:any) =>{ if(!grandsonItem.hidden){ item.hidden = false; } }) } } if(item.items && item.items.length >0){ this.computeParentMenus(item.items); } }) } }) } } /** * 数据处理 * * @public * @param {any[]} items * @memberof IconMenuBase */ public dataProcess(items: any[]): void { items.forEach((_item: any) => { if (_item.expanded) { this.defaultOpeneds.push(_item.name); } if (_item.items && _item.items.length > 0) { this.dataProcess(_item.items) } }); } /** * 提示框主题样式 * * @readonly * @type {string} * @memberof IconMenuBase */ get popperClass(): string { return 'app-popper-menu ' + this.selectTheme; } } </script> <style lang='less'> @import './icon-menu-appmenu.less'; </style>