08335 / hivui-platform-template
hivui平台项目模板
Newer
Older
hivui-platform-template / project / hivuiMain / views / design / columnsSelect.vue
caibinghong on 4 Jun 2021 add
<template>
    <Dialog ref="cmp-dd" :title="dialogTitle" :width="650" :height="465">
        <div class="pl-design-row pl-row transfer-tip">
            <div class="pl-design-col pl-col-11">                
                <div class="pl-field">
                    <div class="pl-field-lb">{{$lang("setHeight")||"设置高度"}}</div>
                    <div class="pl-field-val">
                        <input class="pl-field-text" type="text" v-model="panelHeight"
                        onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"
                        />
                    </div>
                </div>
            </div>
            <div class="pl-design-col pl-col-2"></div>
            <div class="pl-design-col pl-col-11">
                &nbsp;&nbsp;
                <i class="move iconfont icon-moveSort2"></i>{{$lang("dragOrderFlag")||"拖动排序标识"}}
                <!-- <i class="del iconfont icon-close"></i>删除标识 -->
            </div>
        </div>
        <div class="pl-design-row pl-row transfer-box">            
            <div class="pl-design-col pl-col-11">
                <v-jstree ref="cmp-tree"
                :data="columns" show-checkbox multiple allow-batch collapse
                text-field-name="name"
                @item-click="itemClick"></v-jstree>
            </div>
            <!--
            <div class="pl-design-col pl-col-11">
                <div class="transfer-item" v-for="(item,index) in columns" @click="item.checked=!item.checked">
                    <i class="iconfont" :class="item.checked?'icon-checkbox':'icon-checkbox-empty'"></i>
                    <span>{{item.title}}</span>
                </div>
            </div>
            -->
            <div class="pl-design-col pl-col-2">
                <div><i class="iconfont icon-arrow-right-circle" @click="handleMoveRight"></i></div>
                <div><i class="iconfont icon-arrow-left-circle" @click="handleMoveLeft"></i></div>
                <div><i class="iconfont icon-arrow-rightMore-circle" @click="handleMoveAllRight"></i></div>
                <div><i class="iconfont icon-arrow-leftMore-circle" @click="handleMoveAllLeft"></i></div>
            </div>
            <div class="pl-design-col pl-col-11" ref="dom-selected">
                <div class="transfer-item" v-for="(item,index) in selectList" :resId="item.resId">
                    <i class="move iconfont icon-moveSort2"></i>
                    <i class="iconfont" :class="item.selected?'icon-checkbox':'icon-checkbox-empty'"
                         @click="item.selected=!item.selected"
                    ></i>
                    <span @click="item.selected=!item.selected">{{item.name}}</span>
                    <!-- <i class="del iconfont icon-close"></i> -->
                </div>
            </div>
        </div>
        <template slot="footer">            
            <button class="pl-btn pl-btn-round" @click="handleCancel">{{$lang("cancel")||"取消"}}</button>
            <button v-if="!isEdit" class="pl-btn pl-btn-round pl-btn-primary" @click="handleOk">{{$lang("ok")||"确定"}}</button>
            <button v-if="isEdit" class="pl-btn pl-btn-round pl-btn-primary" @click="handleEdit">{{$lang("ok")||"确定"}}</button>
        </template>
    </Dialog>
</template>
<script>
import findIndex from 'lodash/findIndex';
import cloneDeep from 'lodash/cloneDeep';

import VJstree from 'vue-jstree'
import Dialog from "@main/components/dialog";
import Sortable from 'sortablejs';
import {strFormat} from '@main/utils/index';

export default {
    props:['portalPanel'],
    components:{
        Dialog,VJstree
    },
    data(){
        return {
            columns:[],
            defHeight:300,
            panelHeight:300,//面板高度
            selectList:[],//存放选中的栏目列表
            Sortable:null,//拖拽对象
            /**
             * 提取字段
             */
            fields:['resId','resKey','resUrl','parentId','type','isShow','name','selected']
        }
    },
    computed:{
        // columns(){
        //     let data = cloneDeep(this.$store.getters.portalColumns);
        //     return data;
        // },
        isEdit(){
            return !!this.portalPanel;
        },
        dialogTitle(){
            let title='';
            if(this.portalPanel){
                let paths =  this.portalPanel.paths;
                title = strFormat(this.$lang("editSerialRowLayout"),paths[0]+1,paths[1]+1,paths[2]+1);
            }else{                
                title = this.$lang("addColunms")||"添加门户栏目"
            }
            debugger
            return title;
        }
    },
    mounted(){
        let me=this;
        me.Sortable&&me.Sortable.destroy();
        me.$nextTick(r=>{
            me.Sortable = new Sortable(me.$refs['dom-selected'], {
                group: "transfer-item",
                handle: '.move', // handle's class
                animation: 150,
                onEnd(evt){
                    // let itemEl = evt.item,
                    //     list = [...me.selectList];
                    // list[evt.oldIndex] = list.splice(evt.newIndex, 1, list[evt.oldIndex])[0];
                    // me.$set(me,'selectList',list);
                    // console.log(me.selectList);
                }
            })
        });
        if(me.$store.getters.portalColumns.length==0){
            me.$store.dispatch('portal/loadColumns').then((res)=>{
                me.columns = cloneDeep(me.$store.getters.portalColumns);
            });
        }else{
            me.columns = cloneDeep(me.$store.getters.portalColumns);
        }
    },
    beforeDestroy(){
        this.Sortable&&this.Sortable.destroy();
    },
    methods:{ 
        resetForm(){
            let me=this;
            me.panelHeight = me.defHeight;
            me.Sortable=null;
            me.$set(me,'selectList',[]);
        },
        setForm(data){
            console.log("portal->columnsSelect.vue :" ,data);
            let me=this,columns = [];
            data.columns.map(item=>{
                let tplObj={};
                me.fields.map(key=>{
                    tplObj[key] = item[key];
                });
                tplObj.selected=false;
                columns.push(tplObj);
            });
            me.panelHeight = data.height||me.defHeight;
            me.$set(me,'selectList',columns);
            
        },
        show(){
            this.$refs['cmp-dd'].show();
            this.$nextTick(()=>{
                this.resetTreeSeleted();
            })
        },
        hide(){
            this.$refs['cmp-dd'].hide();
        }, 
        /**
         * 因为拖动后排序,所以要重新获取
         */
        getSelectList(){
            let me=this,arr=[];
            let els = me.$refs['dom-selected'].children;
            for(let i=0,l=els.length;i<l;i++){
                let resId = els[i].getAttribute('resId');
                for(let n=0,k=me.selectList.length;n<k;n++){
                    if(me.selectList[n].resId==resId){
                        arr[i] = me.selectList.splice(n,1)[0];
                        break;
                    }
                }
            }
            return arr;
        },
        handleCancel(){
            let me=this;
            me.$set(me,'selectList',[]);
            me.hide()
        },
        handleOk(){
            let me=this,data=[]; 
            let list = me.getSelectList();
            list.map(item=>{
                let tplObj={};
                me.fields.map(key=>{
                    tplObj[key] = item[key];
                });
                data.push(tplObj);
            });
            let h =  parseFloat(me.panelHeight);
            h = isNaN(h)?me.defHeight:h;
            me.$emit('onOk',data,h);
            me.resetForm();
            me.hide();
        },
        handleEdit(){
            let me=this,columns=[],newData={...this.portalPanel};
            let list = me.getSelectList();
            list.map(item=>{
                let tplObj={};
                me.fields.map(key=>{
                    tplObj[key] = item[key];
                });
                columns.push(tplObj);
            });

            let h =  parseFloat(me.panelHeight);
            h = isNaN(h)?me.defHeight:h;
            Object.assign(newData,{columns,height:h});
            console.log("portal->columnsSelect.vue -> onUpdate:" ,newData);
            me.$emit('onUpdate',newData); 
            me.resetForm();           
            me.hide();
        },
        resetTreeSeleted(){
            let me=this,$tree = me.$refs['cmp-tree'],data=$tree.data;
            me.setNodesChecks(data,false);
        },
        setNodesChecks(nodes,checked){
            let dd = (nodes)=>{
                nodes.map(item=>{
                    item.selected=checked;
                    item.children&&dd(item.children);
                });
            }
            dd(nodes);
        },
        getTreeLeafs(){
            let data=[];
            let $tree = this.$refs['cmp-tree'],nodes=$tree.data;
            let dd = (nodes)=>{
                nodes.map(item=>{
                    if(item.children.length==0){
                        item.selectList=false;
                        data.push(item);
                    }
                    item.children&&dd(item.children);
                });
            }
            dd(nodes);
            return data;
        },
        getTreeChecked(){
            let data=[];
            let $tree = this.$refs['cmp-tree'],nodes=$tree.data;
            let dd = (nodes)=>{
                nodes.map(item=>{
                    if(item.selected&&(!item.children||item.children.length==0)){
                        data.push(item);
                    }
                    item.children&&dd(item.children);
                });
            }
            dd(nodes);
            return data;
        },
        handleMoveLeft(){
            let me = this,chks=[],unChks = [];
            me.selectList.map((item,index)=>{
                if(item.selected){
                    chks.push(item);
                }else{
                    unChks.push(item)
                }
            });           
            me.$set(me,'selectList',unChks);
            me.resetTreeSeleted();
        },
        handleMoveAllLeft(){
            let me=this;
            me.$set(me,'selectList',[]);
            me.resetTreeSeleted();
        },
        handleMoveRight(){ 
            let me=this,
                chks = me.getTreeChecked(),
                oldSelds = me.selectList,
                newSelds = [];
            chks.map(item=>{
                let tplObj = {},hasItem = findIndex(oldSelds,o=>{
                    return o.resId == item.resId;
                });
                if(hasItem==-1){
                    me.fields.map(key=>{
                        tplObj[key] = item[key];
                    });
                    tplObj.selected = false;
                    newSelds.push(tplObj);
                }
            });
            chks.length&&me.$set(me,'selectList',[...newSelds,...oldSelds]);
            me.resetTreeSeleted();
        },
        handleMoveAllRight(){ 
            let me = this;
            me.$set(me,'selectList',me.getTreeLeafs());
            me.resetTreeSeleted();
        },
        itemClick (node, item, e) {             
            return;
            let index = findIndex(this.selectList,o =>o.id == node.id);
            if(index==-1){
                if(node.model.selected){
                this.selectList.push({
                    id:node.model.id,
                    pid:node.model.pid,
                    title:node.model.title,
                    href:node.model.resUrl,
                    loadType:node.model.loadType||'iframe'
                });
                }else{
                this.selectList.splice(index,1);
                }
            }else{
                this.selectList.splice(index,node.model.selected?0:1);
            }
        }
    }
}
</script>
<style lang="less" scoped>
    .transfer-tip{
        padding-bottom:5px;
        color:#999;
    }
    .transfer-box {
        >.pl-col-11{
            border: 1px #ddd solid;
            height: 300px;
            padding:5px;
            overflow: auto;
            box-shadow: inset 0px 0px 20px 1px rgba(0,0,0,0.05);
        }
        >.pl-col-2{
            text-align: center;
            padding-top: 70px;
            .iconfont{
                display: block;
                font-size:24px;
                color:#999;
                cursor: pointer;
                margin-bottom: 15px;
                &:hover{
                color:#0066cc;
                }
            }
        } 
        .transfer-item{
            padding:5px;
            &:hover{
                color:#0066cc;
                background: #efefef;
            }
            >.iconfont{
                margin-right:5px;
            }
            >.move{
                cursor: move;
            }
            >.del{
                float:right;
                cursor: pointer;
            }
        }       
    }
</style>