<!--
使用方法：
import StudentSelector from '@/common/selector/StudentSelector.vue'
<student-selector :show="参数1" :userlist="参数2" @handleSubmit="方法" />
参数1用于控制选人控件是否显示；数据类型是布尔；例子true；
参数2用于已选学生回显；数据类型是数组；例子[{studentId:'1'},{studentId:'2'}]；
方法用于获取已选学生；数据类型是方法；例子function(val){ console.log(val) }；

另外
配置参数未暴露
节点点击事件未暴露
-->
<template>
    <div class="container" v-if="show">
        <header class="bar bar-nav">
            <h1 class="title">选择学生</h1>
            <a href="javascript:void(0)" class="pull-right icon" @click="handleSubmitClick">关闭</a>
        </header>
        <div class="search-wrapper" @click="handleShowSearchPanelClick">
            <div>搜索</div>
        </div>
        <div onselectstart="return false;" class="checkbox-wrapper">
            <span @click="handleChangeAllCheck" class="item-checkbox" :class="{'icon-uncheck':!isAllCheck,'icon-check':isAllCheck}"></span>
            <span class="item-label">全选</span>
        </div>
        <div class="content" ref="scrollWrapper" style="margin-top:10px">
            <vue-tree
             :eventBus="eventBus"
                :tree-data="treeData">
            </vue-tree>
        </div>
        <div class="selector-bottom">
            <span>已选{{ selectedStudentListArr.length }}人</span>
            <a @click="handleSubmitClick" class="submit-btn" href="javascript:void(0)">确定</a>
        </div>

        <div class="search-panel" v-show="showSearchPanel">
            <div style="width:100%;height:10px"></div>
            <form class="search-top" action="javascript:return true;">
                <input
                     v-model="searchVal"
                    @keyup.enter="handleSearchEvent"
                    @input="handleSearchEvent"
                     id="searchVal"
                     type="text"
                      placeholder="搜索" >
                <a @click="showSearchPanel = false" href="javascript:void(0);">取消</a>
            </form>
            <div class="search-list" ref="searchScroll">
                <div>
                    <div v-for="(item,index) in searchList" :key="index" class="checkbox-wrapper" @click="handleSelectedSearchClick(index)">
                        <span class="item-checkbox" :class="item.checked ? 'icon-check' : 'icon-uncheck'"></span>
                        <span class="item-label">{{item.studentName}}</span>
                    </div>
                </div>
            </div>
            <div class="selector-bottom">
                    <a @click="searchSubmit" class="submit-btn" href="javascript:void(0)">确定</a>
            </div>
        </div>
        <div v-transfer-dom>
            <loading :show="showLoad" :text="'加载中...'"></loading>
        </div>
    </div>
</template>

<script>
import Vue from 'vue'
import BScroll from 'better-scroll'
import VHeader from '@/common/header/VHeader'
import VueTree from '@/common/selector/VueTree.vue'
import { Loading, TransferDomDirective as TransferDom } from 'vux'
export default {
    name: 'StudentSelector',
    directives: {
        TransferDom
    },
    components: {
        VHeader,
        VueTree,
        Loading
    },
    props: {
        show: {
            type: Boolean,
            default: false
        },
        userlist: {
            type: Array,
            default: () => {
                return []
            }
        },
        // 是否通过角色查询
        isByPermiss: {
            type: Boolean,
            default: false
        },
        // 查询角色代码
        role: {
            type: Number,
            default: 0
        }
    },
    data () {
        return {
            eventBus: new Vue(),
            scroll: null,
            scrollSearch: null,
            treeData: [],
            // 设置项
            // options: {
            //     // String,节点显示字段
            //     label: 'name',
            //     // Boolean,是否显示选择框
            //     checkbox: true,
            //     // Boolean,选中时是否展开节点
            //     checkedOpen: true,
            //      // Boolean,目录是否加粗显示
            //     folderBold: true,
            //     // Boolean,获取复选项目是否包含目录,默认`true`,如果只获取叶子节点设置为`false`
            //     idsWithParent: false,
            //     // Number,初始化时展开层级,根节点为0,默认0
            //     depthOpen: 1
            // },
            // 是否全选
            isAllCheck: false,
            // 所有学生id
            studentIds: [],
            // 学生列表
            studentList: [],
            // 搜索列表
            searchList: [],
            searchVal: '',
            showLoad: false,
            showSearchPanel: false,
            selectedBranchListArr: [],
            selectedStudentListArr: []
        }
    },
    methods: {
        getStudentList () {
            this.$api.platBaseApi.getGradeStructureWithStudent().then(res => {
                this.renderStudentList(res.data)
            })
        },
        /**
         * 有筛选角色
         */
        getStudentListByPermission () {
            const params = {
                role: this.role
            }
            this.$api.platBaseApi.gradeStructureWithStudentByPermission(this.role)
                .then(res => {
                    this.renderStudentList(res.data)
                })
        },
        renderStudentList (item) {
            if (item.Status) {
                var list = item.Data
                for (var i in list) {
                    let obj = {}, item = list[i]
                    // this.treeData.push({
                    //  id:list[i].id,
                    //  name:list[i].fullname,
                    //  children:[]
                    // });
                    obj.id = item.id
                    obj.name = item.fullname
                    obj.checked = false
                    obj.type = 'branch'
                    obj.indeterminate = false
                    obj.children = []
                    this.treeData.push(obj)

                    // if(list[i].children.length > 0) continue;
                    for (var j in item.children) {
                        // this.treeData[i].children.push({
                        //  id:list[i].children[j].id,
                        //  name:list[i].children[j].fullname,
                        //  children:[]
                        // });
                        let obj2 = {}, item2 = item.children[j]
                        obj2.id = item2.id
                        obj2.name = item2.fullname
                        obj2.checked = false
                        obj2.type = 'branch'
                        obj2.indeterminate = false
                        obj2.children = []
                        this.treeData[i].children.push(obj2)

                        // if(list[i].children[j].children.lengrh > 0) continue;
                        for (var k in item2.children) {
                            // this.treeData[i].children[j].children.push({
                            //  id:list[i].children[j].children[k].studentId,
                            //  name:list[i].children[j].children[k].studentName
                            // });
                            let obj3 = {}, item3 = item2.children[k]
                            obj3.id = item3.studentId
                            obj3.name = item3.studentName
                            obj3.checked = false
                            obj3.type = 'user'
                            obj3.indeterminate = false
                            this.treeData[i].children[j].children.push(obj3)
                            // this.studentIds.push(list[i].children[j].children[k].studentId);
                            // this.studentList.push({
                            //  gradeId:list[i].id,
                            //  gradeName:list[i].fullname,
                            //  classId:list[i].children[j].id,
                            //  className:list[i].children[j].fullname,
                            //  studentId:list[i].children[j].children[k].studentId,
                            //  studentName:list[i].children[j].children[k].studentName
                            // });
                            this.studentList.push({
                                gradeId: item.id,
                                gradeName: item.fullname,
                                classId: item2.id,
                                className: item2.fullname,
                                checked: false,
                                studentId: item3.studentId,
                                studentName: item3.studentName
                            })
                        }
                    }
                }
            }
        },
        // 初始化数据
        handleInitTreeData (treeData, userList) {
            if (userList.length) {
                if (treeData.length) {
                    for (let i = 0; i < treeData.length; i++) {
                        let item = treeData[i]
                        if (treeData[i].type == 'user') {
                            for (let j = 0; j < userList.length; j++) {
                                let user = userList[j]
                                if (user.studentId == item.id) {
                                    item.checked = true
                                }
                            }
                        } else {
                            if (item.children && item.children.length) {
                                this.handleInitTreeData(item.children, userList)
                            }
                        }
                    }
                }
                this.handleSetIndeterminate(this.treeData)
            } else {
                this.setChildChecked(false, this.treeData)
            }
        },
        // 全选
        handleChangeAllCheck () {
            this.isAllCheck = !this.isAllCheck
            this.setChildChecked(this.isAllCheck, this.treeData)
            this.selectedStudentListArr = []
            this.getSelectedUser(this.treeData)
        },

        // 节点被点击
        /**
         * node 被点击的节点
         * checked 选中的状态
         * data 需要传递的数据，暂时为空
         */
        handleCheckChange (node, checked, data) {
            if (node.checked !== checked) {
                this.handleSetChecked(node, checked, this.treeData)
            }
            this.handleSetIndeterminate(this.treeData)
            this.selectedBranchListArr = this.getSelectedBranch(this.treeData)
            this.selectedStudentListArr = []
            this.getSelectedUser(this.treeData)
        },
        // 获取选中的第一级数据
        getSelectedBranch (treeData) {
            if (treeData.length) {
                return treeData.filter(item => item.checked)
            }
        },
        // 获取选中的用户
        getSelectedUser (treeData) {
            if (treeData.length) {
                for (let i = 0; i < treeData.length; i++) {
                    let item = treeData[i]
                    if (item.children && item.children.length) {
                        this.getSelectedUser(item.children)
                    } else {
                        if (item.checked && item.type === 'user') {
                            this.selectedStudentListArr.push({
                                studentId: item.id,
                                studentName: item.name
                            })
                        }
                    }
                }
            }
        },
        // 设置节点选中/不选中
        handleSetChecked (node, checked, children) {
            if (children && children.length) {
                for (let i = 0; i < children.length; i++) {
                    let child = children[i]
                    if (child.id == node.id) {
                        child.checked = checked
                        child.indeterminate = false
                        if (child.children && child.children.length) {
                            this.setChildChecked(checked, child.children)
                        }
                    } else {
                        this.handleSetChecked(node, checked, child.children)
                    }
                }
            }
        },
        // 设置子节点全部选中
        setChildChecked (checked, children) {
            for (let i = 0; i < children.length; i++) {
                let item = children[i]
                item.checked = checked
                item.indeterminate = false
                if (item.children && item.children.length) {
                    this.setChildChecked(checked, item.children)
                }
            }
        },
        // 设置选中/半选状态
        handleSetIndeterminate (treeData) {
            // 循环 children
            const loop = obj => {
                // 如果子元素还有有子元素就继续循环
                obj.children.map(item => item.children && item.children.length ? loop(item) : item)
                // 根据子元素的状态判断自身，如果子元素全选中则本身也选中，如果子元素有些全选或半选则本身半选，否则就是都没选
                obj.children.every(item => item.checked) ? (obj.checked = true, obj.indeterminate = false)
                    : obj.children.some(item => item.checked || item.indeterminate) ? (obj.checked = false, obj.indeterminate = true)
                        : (obj.checked = obj.indeterminate = false)
                return obj
            }
            treeData = treeData.map(item => loop(item))
        },
        handleSubmitClick () {
            this.$emit('handleSubmit', this.selectedStudentListArr)
        },
        // 显示搜索框
        handleShowSearchPanelClick () {
            this.searchList = []
            this.searchVal = ''
            this.studentList.map(item => item.checked = false)
            this.showSearchPanel = true
            setTimeout(() => {
                document.getElementById('searchVal').focus()
            }, 0)
        },
        // 搜索
        handleSearchEvent () {
            if (this.searchVal) {
                this.searchList = this.renderSearchList()
            }
        },
        renderSearchList () {
            return this.studentList.filter(item => item.studentName.indexOf(this.searchVal) !== -1)
        },
        handleSelectedSearchClick (index) {
            this.searchList[index].checked = !this.searchList[index].checked
        },
        // 确定提交搜索结果
        searchSubmit () {
            let userList = this.searchList.filter(item => item.checked)
            this.$nextTick(() => {
                this.handleInitTreeData(this.treeData, userList)
                this.getSelectedUser(this.treeData)
                this.showSearchPanel = false
            })
        }
    },
    watch: {
        selectedBranchListArr (newValue, oldValue) {
            this.isAllCheck = newValue.length > 0 && newValue.length == this.treeData.length
        },
        show (newValue, oldValue) {
            if (newValue) {
                this.handleInitTreeData(this.treeData, this.userlist)
                this.selectedStudentListArr = [], this.selectedBranchListArr = []
                this.getSelectedUser(this.treeData)
                this.selectedBranchListArr = this.getSelectedBranch(this.treeData)

                this.$nextTick(() => {
                    this.scroll = new BScroll(this.$refs.scrollWrapper, {
                        click: true
                    })
                })
                this.$nextTick(() => {
                    this.scrollSearch = new BScroll(this.$refs.searchScroll, {
                        click: true
                    })
                })
            }
        }
    },
    created: function () {
        this.eventBus.$on('checked-change', this.handleCheckChange)
        if (this.isByPermiss) {
            this.getStudentListByPermission()
        } else {
            this.getStudentList()
        }
    }
}
</script>

<style lang="less" scoped>
.container{
    position: fixed;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 1000;
    background: #efeff4
}
.selector-bottom{
    border-top: 1px solid #ccc;
    height: 50px;
    line-height: 50px;
    padding: 0 15px;
}
.submit-btn{
    float: right;
    margin-top:6px;
    width: 72px;
    height: 36px;
    line-height: 36px;
    text-align: center;
    background: #1296db;
    color: #fff;
    border-radius: 5px;
}
.checkbox-wrapper{
    background: #fff;
    padding: 10px 27px;
    span{
        display: inline-block;
        vertical-align: middle;
    }
}
.search-wrapper{
    width: 100%;
    background: #efeff4;
    div{
        background: #fff;
        margin: 10px;
        height: 32px;
        line-height: 32px;
        border-radius: 5px;
        color: #ccc;
        text-indent: 12px;
        font: 14px;
    }
}
.search-panel{
    width: 100%;
    position: fixed;
    top:0;left: 0;
    height: 100%;
    background: #efeff4;
    z-index: 10;
    display: flex;
    flex-direction:column;
    .search-top{
        display: flex;
        margin: 0 10px 10px;
        input{
            flex:1;
            background: #fff;
            height: 32px !important;
            line-height: 32px !important;
            border-radius: 5px;
            text-indent: 12px;
            font: 14px;
            border: 0px;
        }
        a{
            height: 32px;
            line-height: 32px;
            padding: 0 5px 0 10px;
            color: #1296db
        }
    }
    .search-list{
        flex:1;
        overflow: hidden;
    }
}
</style>
