08335 / hivui-platform-template
hivui平台项目模板
Newer
Older
hivui-platform-template / project / hivuiMain / views / layout / components / Header.vue
<template>
    <div class="pl-header " :data-layout="layout">  
        <ul class="ltArea">
            <li v-if="layout=='level'" class="logoStyle">
                <div class="pl-logo">
                    <div v-if="hasTitle" @click="hideTitle(false)">
                        <img :src="def_sy_logo_horizon" :width="logoWidth" v-if="!logoOpt.src">
                        <img :src="logoOpt.src" :width="logoOpt.width?(logoOpt.width+'px'):(!logoOpt.height?logoWidth:null)" :height="logoOpt.height&&(logoOpt.height+'px')" :title="logoOpt.title" v-if="logoOpt.src">
                    </div>
                    <div v-else @click="hideTitle(true)">
                        <img :src="def_sy_minLogo" v-if="!MlogoOpt.src">
                        <img :src="MlogoOpt.src" :width="MlogoOpt.width?(MlogoOpt.width+'px'):(!MlogoOpt.height?logoWidth:null)" :height="MlogoOpt.height&&(MlogoOpt.height+'px')" :title="MlogoOpt.title" v-if="MlogoOpt.src">
                    </div>
                </div>
            </li>
            <li v-else class="logoStyle">
                <div class="pl-logo">
                    <img :src="def_sy_logo"  :width="logoWidth" v-if="!logoOpt.src">
                    <img :src="logoOpt.src" :width="logoOpt.width?(logoOpt.width+'px'):(!logoOpt.height?logoWidth:null)" :height="logoOpt.height&&(logoOpt.height+'px')" :title="logoOpt.title" v-if="logoOpt.src">
                </div>
            </li>
            <li v-if="sysList.length">                
                <div class="sysTrigger" ref='dom-sysList'  
                    @mouseover="handleShowSysList"  @mouseout="handleHideSysList">
                    <span>{{$t('hivuiMain_projectManage')}}</span>
                    <i class="iconfont icon-change"></i>
                </div> 
                <ul class="pl-menus pl-menus-sub pl-menus-pop"
                @mouseenter="handleShowSysList"  @mouseleave="handleHideSysList"
                :style="sysListStyle" v-add2Body>
                    <li class="pl-menus-item" v-for="item,index in sysList" @click="handleChangeSys(item)">
                        <a class="title"><span class="txt">{{item.title}}</span></a>
                    </li>
                </ul>   
            </li>
            <li v-if="layout == 'level'" >
                <div class="sysTrigger" ref="dom-latelyUse" 
                :title='$t("hivuiMain_recentlyUsed")'
                @mouseenter="handleShowLatelyUse"  @mouseleave="handleHideLatelyUse">
                    <i class="icon iconfont icon-time"></i>
                    <span class="title">{{$t('hivuiMain_recentlyUsed')}}</span>
                    <i class="icon iconfont icon-arrow-down"></i>
                </div>
                <ul class="pl-menus pl-menus-sub pl-menus-pop"
                @mouseenter="handleShowLatelyUse"  @mouseleave="handleHideLatelyUse"
                :style="latelyUseStyle" v-add2Body>
                    <li class="pl-menus-item" v-for="item,index in navsLatelyUse" @click="handleOpenLatelyFunc(item)">
                        <a class="title"><span class="txt">{{item.name}}</span></a>
                    </li>
                    <li v-show="navsLatelyUse.length==0" class="pl-menus-tips">
                        {{$t('hivuiMain_nodata')}}
                    </li>
                </ul> 
            </li>
            <li v-if="layout == 'level'&&showAllFuncBtn" >
                <div class="sysTrigger">
                    <span ref="allFuncBtn" class="title" @mouseenter="allFuncTriggerOpen" @mouseleave="allFuncTriggerClose">{{$t('hivuiMain_allFunction')}}</span>
                    <i class="icon iconfont icon-arrow-down"></i>
                    <allFuncMenu ref="allFuncMenu" :triggerObj="allFuncBtnObj" v-add2Body></allFuncMenu>
                </div>
            </li>
        </ul>
        <ul class="rtArea">
            <li>
                <div class="pl-search" ref="dom-searchBox" >
                    <input ref="dom-seachTxt" class="pl-search-text" type="text" :placeholder="$t('hivuiMain_searchKey')" 
                    v-model.trim="searchWord" 
                    @keyup="handleSeachKeyUp"
                    />
                    <i class="iconfont icon-search"></i>                   
                </div>  
                <ul class="pl-menus pl-menus-sub pl-menus-pop" :style="searchMenusStyle" v-add2Body>
                    <li :class="['pl-menus-item',seldIndex==index?'pl-menus-itemSeld':'']" v-for="item,index in searchList" 
                    style="width:100%"
                    @click="openFunc(item)">
                        <a class="title"><span class="txt" v-html="item.html||item.name"></span></a>
                    </li>
                    <li v-show="searchList.length==0&&searchWord.length>0" class="pl-menus-tips">
                        {{$t('hivuiMain_nodata')}}
                    </li>
                </ul> 
            </li>
            <li v-if="sysProjectManage">
                <a :href="sysProjectManage.url" target='_blank' class="item" :title="sysProjectManage.name">
                    <i class="iconfont" :class="sysProjectManage.iconClass"></i>
                    <span class="title">{{sysProjectManage.name}}</span>
                </a>  
            </li>
            <template v-for="item in sysFuncMenus">
                <li v-if="item.type!='split'">
                    <template v-if="item.type=='withNumTips'">
                        <div class="item" @click.prevent="handleFuncMenus(item,$event)">
                            <div class="tip">
                                <i class="iconfont" :class="item.iconClass"></i>
                            </div>
                            <span class="title" v-html="item.html||item.name"></span>
                            <span class="pl-head-tipsNum" :hidden="!(item.tipNum&&item.tipNum!=0)">{{item.tipNum}}</span>
                        </div>
                    </template>
                    <template v-else>
                        <template v-if="item.children&&item.children.length">
                            <div class="item" @mouseenter="handleFuncMenus(item,$event)">
                                <div class="tip">
                                    <i class="iconfont" :class="item.iconClass"></i>
                                </div>
                                <span class="title" v-html="item.html||item.name"></span>
                                <i class="iconfont icon-arrow-down" v-if="item.children"></i>
                            </div>
                        </template>
                        <template v-if="!item.children||item.children&&item.children.length==0">
                            <div class="item" @click.prevent="handleFuncMenus(item,$event)">
                                <div class="tip">
                                    <i class="iconfont" :class="item.iconClass"></i>
                                </div>
                                <span class="title" v-html="item.html||item.name"></span>
                                <i class="iconfont icon-arrow-down" v-if="item.children"></i>
                            </div>
                        </template>
                    </template>
                </li>
                <li v-if="item.type=='split'"><div class="line"></div></li>                
            </template>
            <!-- <li>
                <div class="item">
                    <div class="tip">
                        <i class="iconfont icon-user"></i>
                    </div>
                    <span class="title">{{this.$store.getters.userId}}/{{this.$store.getters.userName}}</span>
                    <i class="iconfont icon-arrow-down"></i>
                </div>
            </li>
            <li><div class="line"></div></li> -->
            <!-- 语言切换 -->
            <li v-if="langList">
                <template v-if="langList.children&&langList.children.length">
                    <div class="item" @mouseenter="handleFuncMenus(langList,$event)">
                        <div class="tip">
                            <i class="iconfont" :class="langList.iconClass"></i>
                        </div>
                        <span class="title" v-html="langList.html||langList.name"></span>
                        <i class="iconfont icon-arrow-down" v-if="langList.children"></i>
                    </div>
                </template>
            </li>
            <li v-if="langList"><div class="line"></div></li>
            <!-- 用户信息 -->
            <li>
                <template v-if="sysUserInfo.children&&sysUserInfo.children.length">
                    <div class="item" @mouseenter="handleFuncMenus(sysUserInfo,$event)">
                        <div class="tip">
                            <i class="iconfont" :class="sysUserInfo.iconClass"></i>
                        </div>
                        <span class="title" v-html="sysUserInfo.html||sysUserInfo.name"></span>
                        <i class="iconfont icon-arrow-down" v-if="sysUserInfo.children"></i>
                    </div>
                </template>
            </li>
            <li><div class="line"></div></li>
            <li v-if="hasSetting">
                <div class="item" :title="$t('hivuiMain_customWorkbench')">
                    <a href="#design" target='_blank'><i class="iconfont icon-set-fill"></i></a>   
                </div>
            </li>
            <li>
                <div class="item" :title="$t('hivuiMain_logout')">
                    <a @click="handleLogout"><i class="iconfont icon-tuichu"></i></a>    
                </div>
            </li>
        </ul>
        <vueContextMenu ref="cmp-funcMenu" :menu-items="menuItems" field="name"></vueContextMenu>
        <modifyPw></modifyPw>
    </div>
</template>
<script>
import pinyin from 'js-pinyin';//ie 下有问题 编译不过
 
import vueContextMenu from "@main/components/contextMenu";
import modifyPw from "@main/views/layout/components/modifyPw";
import allFuncMenu from './allFuncMenu'
import {changeBz} from "@main/api/user";

import { removeToken } from '@main/utils/auth'
import def_sy_loading from "@main/assets/logo_max.png"
import def_sy_minLogo from "@main/assets/logo_min.png"
import def_sy_logo from "@main/assets/logo.png"
import def_sy_logo_horizon from "@main/assets/logo_horizon.png"


export default {
    components:{
        vueContextMenu,
        modifyPw,
        allFuncMenu,
    },
    inject:['addTab','showTab','hideTab'],
    props:{
        hasTitle:{
            type: Boolean,
        },
        logoWidth:{
            type: String,
        }
    },
    data(){
        return {
            menuItems:[],
            searchWord:"",
            searchList:[],
            seldIndex:0,
            menuShow:false,
            searchMenusStyle:{
                display:'none',
                left:0,
                top:0,
                width:0,
                // maxHeight:'50%',
                // overflow:'auto'
            },
            sysListStyle:{
                display:'none',
                left:0,
                top:0,
            },
            latelyUseStyle:{
                display:'none',
                left:0,
                top:0,
                maxHeight:'50%',
                overflow:'auto'
            },
            def_sy_minLogo:def_sy_minLogo,
            def_sy_logo:def_sy_logo,
            def_sy_logo_horizon:def_sy_logo_horizon,
            numTipTimer:null,
            showAllFuncBtn:window.customSysCofig.isShowAllFunc===false?false:true,
            isShowAllFuncMenu:false,
            allFuncBtnObj:{},
        }
    },  
    computed:{
        hasSetting(){
            let cfg = this.$store.state.app.config||{};
            return cfg.sysSetTabs&&cfg.sysSetTabs.length;
        },
        sysList(){
            let cfg = this.$store.state.app.config||{};
            return cfg.sysList||[];
        },
        sysUserInfo(){
            let me=this;
            let cfg = this.$store.state.app.config||{};
            function replaceData(str){
                if(!str)return ['',false];
                var _arr=str.match(/\${(\S*?)}/g);
                var nullNum=0;

                if(_arr&&_arr.length>0){
                    for(let i of _arr){
                        var _data=me.userInfo[i.match(/\${(\S*)}/)[1]];
                        if(typeof(_data)!="undefined"){
                            str=str.replace(i,_data);
                        }else{
                            str=str.replace(i,me.$t('hivuiMain_header_null'));
                            nullNum++;
                        }
                    }
                    return [str,nullNum==_arr.length?false:true];
                }
                return [str,true];
            }
            //多岗信息文字模板format
            function orgBzTplFormat(str,item){
                let fieldArr=str.match(/(?<=\${).*?(?=})/g);
                fieldArr.forEach((_i)=>{
                    if(typeof(item[_i])!="undefined"){
                        str=str.replaceAll("${"+_i+"}",item[_i]);
                    }
                });
                return str;
            }
            let _userInfo=cfg.userInfo;
            if(_userInfo){
                _userInfo.name=replaceData(_userInfo.name)[0];
                if(_userInfo.children&&_userInfo.children.length>0){
                    _userInfo.children=_userInfo.children.filter((item)=>{
                        let _rData=replaceData(item.name);
                        item.name=_rData[0];
                        switch(item.type){
                            case "modifyUserInfo":
                                item.handler=me.modifyUserInfo;
                                break;
                            case "modifyPw":
                                item.handler=me.modifyPw;
                                break;
                            case "personalCenter":
                                item.handler=me.personalCenter;
                                break;
                            case "orgBz":
                                if(Array.isArray(me.bzList)&&me.bzList.length>1){
                                    item.children=[];
                                    for(let i of me.bzList){
                                        item.children.push({
                                            iconClass:'icon-user',
                                            name:cfg.orgBzTpl?orgBzTplFormat(cfg.orgBzTpl,i):`${i.fbzname}/${i.fbzid}`,
                                            handler:function(){
                                                me.__changeOrgBz(`${i.fbzid}`);
                                            }
                                        });
                                    }
                                }
                                break;
                        }
                        if(_rData[1]){
                            return item;
                        }
                    });
                }
            }
            return _userInfo||[];
        },
        sysProjectManage(){
            let cfg = this.$store.state.app.config||{};
            let  item = cfg.sysProjectMange||{},flag=false;
            this.$store.state.app.powerList.forEach(p=>{
                if(p.resUrl.indexOf(item.uri)>-1){
                    flag = true;
                    return true;
                }                        
            });
            if(flag){
                return cfg.sysProjectMange;
            }else{
                return null;
            }
        },
        langList(){            
            let cfg = this.$store.state.app.config||{};
            if(!cfg.showChangeLangBtn){
                return;
            }
            let menus = cfg.langList||[];
            return menus;
        },
        sysFuncMenus(){            
            let cfg = this.$store.state.app.config||{};
            let menus = cfg.sysFuncMenus||[];
            return menus;
        },
        logoOpt(){
            let cfg = this.$store.state.app.config||{};
            return (this.layout=="level"&&cfg.sysLogoHorizon?cfg.sysLogoHorizon:cfg.sysLogo)||{};
        },
        MlogoOpt(){
            let cfg = this.$store.state.app.config||{};
            return cfg.MsysLogo||{};
        },
        layout(){
            return window.localStorage.getItem('layout');
        },
        navsLatelyUse(){
            return this.$store.getters.navsLatelyUse;
        },
        token(){
            return this.$store.getters.token;
        },
        userInfo(){
            return this.$store.state.user.userInfo;
        },
        bzList(){
            debugger
            return this.$store.state.user.bzList;
        },

    },
    watch:{ 
        searchWord(newVal,oldVal){
            this.seldIndex=0;
            this.doSearch(newVal);
        }
    },
    mounted(){ 
        let me=this;
        document.addEventListener('click',me.hideSeachResult);
        me.$store.dispatch("app/getSysConfig");
        me.sysFuncMenus.filter(item=>{
            if(item.type=="withNumTips"&&item.numFunc){
                function __intervalFunc(){
                    item.numFunc().then(res=>{
                        me.$set(item,"tipNum",res.num);
                        if(res.num){
                            window.SysPage.notificationFunc(me.$t("hivuiMain_header_notification_title"),item.messageText(res),()=>{
                                me.handleFuncMenus(item);
                            });
                        }
                    }).catch(err=>{
                        clearInterval(me.numTipTimer);
                    });
                }
                clearInterval(me.numTipTimer);
                me.numTipTimer=setInterval(__intervalFunc,item.numIntervalTime||1000*30);
                __intervalFunc();
            }
        });
        me.allFuncBtnObj=(me.layout == 'level')&&me.showAllFuncBtn&&me.$refs.allFuncBtn.getBoundingClientRect();
        
    },
    beforeDestroy(){
        document.removeEventListener('click',this.hideSeachResult)
    },
    methods:{
        openDesign(){
            this.$refs['cmp-dd'].show();
        },
        doSearch(cnKey){
            if(cnKey==""){                
                this.hideSeachResult();
                return;
            }
            this.showSeachResult();
            let list = [],
                records = this.$store.getters.menusList;
             let py = pinyin.getCamelChars(cnKey).toLocaleLowerCase();
            console.log('records', records)
            //let py = Scp.String.getPinyin(cnKey).toLocaleLowerCase();

            let  re = new RegExp("^[a-zA-Z]+$");
            for(let i=0,l=records.length;i<l;i++){
                let item = records[i];
                if(list.length>10){
                    break;
                }
                if(item.name){
                    if(re.test(cnKey)){
                        let y = pinyin.getCamelChars(item.name).toLocaleLowerCase();
                        //let y = Scp.String.getPinyin(item.name).toLocaleLowerCase();
                        if(y.indexOf(py)>-1 && item.type!='dir'){
                            list.push(item);
                        }  
                    }else{
                        if(item.name.indexOf(cnKey)>-1 && item.type!='dir' ){
                            list.push(item);
                            continue;
                        }  
                    }
                }
            }
            this.$set(this,'searchList',list);
        },
        openFunc(item){
            if(item.type== "link"){
                window.open(item.resUrl,item.name);
                return;
            }
            // this.addTab(item.resUrl,item.name,item.resId)
            this.addTab(item);//inject 提供的方法只能 传一个参数
        },
        handleSearchBoxClick(){
            this.doSearch(this.searchWord);
            this.$refs['dom-seachTxt'].focus();
        },
        handleSeachKeyUp(evt){
            if(evt.keyCode==40){//ArrowDown
                if(this.seldIndex<this.searchList.length-1){
                    this.seldIndex++;
                }else{
                    this.seldIndex=0;
                }
            }
            if(evt.keyCode==38){//ArrowUp
                if(this.seldIndex==0){
                    this.seldIndex=this.searchList.length-1;
                }else{
                    this.seldIndex--;
                }
            }
            if(evt.keyCode==13){//enter
                let item = this.searchList[this.seldIndex];
                if(item.type== "link"){
                    window.open(item.resUrl,item.name);
                    return;
                }

                // this.addTab(item.resUrl,item.name,item.resId);
                this.addTab(item);//inject 提供的方法只能 传一个参数
                this.searchWord = "";
                this.seldIndex = 0;
                this.hideSeachResult();
            }
        },
        showSeachResult(){
            this.searchMenusStyle.display ='block';
            let s = this.$refs["dom-searchBox"];
            let rect = s.getBoundingClientRect();
            this.searchMenusStyle.left = rect.left+'px';
            this.searchMenusStyle.top = rect.top + rect.height + 5 +'px';
            this.searchMenusStyle.width = rect.width+'px';
            this.searchMenusStyle.opacity = '1';
        },
        hideSeachResult(){
            this.searchMenusStyle.display ='none';
        },
        handleChangeSys(item){
            if(!item.url)return;
            if(item.target=="_blank"){
                window.open(item.url)
            }else{
                window.location.href=item.url;
            }
        },
        handleShowSysList(){
            this.sysListStyle.display ='block';
            let s = this.$refs["dom-sysList"];
            let rect = s.getBoundingClientRect();
            this.sysListStyle.left = rect.left+'px';
            this.sysListStyle.top = rect.top + rect.height  +'px';
        },
        handleHideSysList(){
            this.sysListStyle.display ='none';
        },
        handleFuncMenus(item,$event){
            $event&&$event.stopPropagation();
            if(item.type== "link"){
                window.open(item.resUrl,item.name);
                return;
            }
            var _url=item.url;
            if(item.type== "widthToken"||item.type== "withToken"){
                _url=item.url+"&access_token="+this.token;
            }
            if(item.url){
                item.target=='tab'? this.addTab({
                    resUrl:_url,
                    name:item.name,
                    resId:item.id,
                    openType:item.openType,
                }) : window.open(_url);
                return
            }else{
                item.handler&&item.handler();
            }
            if(item.children&&item.children.length){
                this.menuItems = item.children;
                this.$refs['cmp-funcMenu'].open($event)
            }
        },
        async handleLogout(){
                await this.$store.dispatch("user/logout").then(()=>{
                    //removeToken();
                    if(window.HIVUI_SETTING.isSingleLogin&&window.HIVUI_SETTING.singleLogoutUrl){
                        location=window.HIVUI_SETTING.singleLogoutUrl;
                    }else{
                        location=window.HIVUI_SETTING.loginUrl;
                    }
                });
        },
        handleShowLatelyUse(){
            this.$store.dispatch('app/getLatelyUse')//最近使用 
            let s = this.$refs["dom-latelyUse"];
            let rect = s.getBoundingClientRect();
            this.latelyUseStyle.display ='block';
            this.latelyUseStyle.left = rect.left+'px';
            this.latelyUseStyle.top = rect.top + rect.height  +'px';
            this.latelyUseStyle.opacity = '1';
        },
        handleHideLatelyUse(){
            this.latelyUseStyle.display ='none';
        },
        handleOpenLatelyFunc(item){      
            if(item.type== "link"){
                window.open(item.resUrl,item.name);
                return;
            }
            this.addTab({
                resUrl:item.resUrl,
                name:item.name,
                openType:item.openType,
            });//inject 提供的方法只能 传一个参数
        },   
        hideTitle(name){
            this.$emit('hideTitle', name);
        },
        //切岗
        __changeOrgBz(bzid){
            changeBz({
                bzid:bzid
            }).then(res=>{
                window.location.reload();
            });
        },
        modifyPw(){
            this.$store.dispatch("user/showPwDialog",true);
        },
        // 个人中心
        personalCenter(){
            top.window.SysPage.newPage(this.$t("hivuiMain_app_personal_Center"), '#personalCenter');
        },
        modifyUserInfo(){
            
        },
        //全部功能弹窗
        allFuncTrigger(){
            let me=this;
            me.isShowAllFuncMenu=me.isShowAllFuncMenu?false:true;
            if(me.isShowAllFuncMenu){
                me.$refs.allFuncMenu.showBox();
            }else{
                me.$refs.allFuncMenu.hideBox();
            }
        },
        allFuncTriggerOpen(){
            let me=this;
            me.$refs.allFuncMenu.showBox();
        },
        allFuncTriggerClose(){
            let me=this;
            me.$refs.allFuncMenu.hideBox();
        },
    }
}
</script>
<style lang="less" scoped>
    .pl-header{
        z-index: 99;
    }
</style>