<!--
*   学生选择器
*  	@data  studentSelectorOptions：  控制组件显示隐藏
*   @data list： 父组件传过已选择用户的值
* 	@data  tree： 班年级树
*   @data  defaultProps： 定义渲染内容
*   @data  userList：选择用户数据
*   @data  hasSelectedUserList：已选用户数据
*   @data  selectAll：全选标志
*   @funcnction 见方法备注
*
*   向父组件传值  hasSelectedUserList
*
* 	组件调用
*   <student-selector :student-selector-options="studentSelectorOptions" @closeStudentSelector="handleCloseStudentSelectorClick"></student-selector>
*   调用方法
*   handleAddClick() {
		const self = this;
		this.studentSelectorOptions.isBlock = true;
		const timer = setTimeout(function () {
			self.studentSelectorOptions.isShow = true;
			clearTimeout(timer);
		}, 0);
	},
*   关闭方法
	handleCloseStudentSelectorClick() {
		const self = this;
		this.studentSelectorOptions.isShow = false;
		const timer = setTimeout(function () {
			self.studentSelectorOptions.isBlock = false;
			clearTimeout(timer);
		}, 300);
	}
*  -->
<template>
	<div v-dom-portal class="selector" :class="studentSelectorOptions.isShow ? 'active' : ''" :style="{ display: studentSelectorOptions.isBlock ? 'block' : 'none' }">
		<div class="selector-mask"></div>
		<div class="selector-wrapper">
			<div class="selector-title">
				选择学生
				<a href="JavaScript:;" class="close-selector-btn" @click="handleCloseClick"><i class="el-icon-circle-close"></i></a>
			</div>
			<div class="selector-body">
				<div class="selector-panel">
					<!-- <div class="panel-title">选择:</div> -->
					<div class="panel-body">
						<div class="search-wrapper">
							<el-input ref="searchInput" placeholder="请输入学生姓名进行搜索" v-model="searchValue" @keyup.enter.native="handleSearchClick">
								<el-button slot="append" icon="el-icon-search" @click="handleSearchClick"></el-button>
							</el-input>
						</div>
						<div class="group-wrapper">
							<div class="group-list">
								<el-tree
									ref="tree"
									:data="tree"
									:show-checkbox="true"
									node-key="id"
									:default-expand-all="true"
									:props="defaultProps"
									:expand-on-click-node="false"
									:check-on-click-node="true"
									@check="handleTreeChange"
									style="background-color: transparent;"
								></el-tree>
							</div>
						</div>
					</div>
				</div>
				<div class="selector-panel panel-with-title">
					<div class="panel-title">
						选择用户
						<span class="tx-primary">{{ userListTotal }}</span>
						人
						<a href="javascript:;" class="select-all" v-show="userList.length">
							<el-checkbox v-model="selectAll" @change="handleCheckAllChange">{{ selectAllText }}</el-checkbox>
						</a>
					</div>
					<div class="panel-body">
						<ul class="selected-user-checkbox-list">
							<li class="item" v-for="item of userList" :key="item.id">
								<el-checkbox v-model="item.is_select" @change="handleCheckboxChange(item.id, item.is_select)">{{ item.realname }}</el-checkbox>
							</li>
						</ul>
					</div>
				</div>
				<div class="selector-panel panel-with-title">
					<div class="panel-title">
						已选用户
						<span class="tx-success">{{ hasSelectedUserTotal }}</span>
						人
						<a href="javascript:;" class="delete-user-list" v-if="hasSelectedUserList.length" @click="handleEmptyClick">
							<i class="el-icon-delete"></i>
							清空
						</a>
					</div>
					<div class="panel-body ">
						<ul class="selector-user-list" v-for="(item, index) of hasSelectedUserList" :key="`_${item.id}`">
							<li class="user-item">
								{{ item.realname }}
								<a href="javascript:;" class="delete-item" @click="handleDeleteItemCLick(item.id, index)"><i class="el-icon-circle-close"></i></a>
							</li>
						</ul>
					</div>
				</div>
			</div>
			<div class="selector-footer">
				<el-button type="primary" size="medium" @click="handleConfirmClick">确定</el-button>
				<el-button size="medium" @click="handleCloseClick">取消</el-button>
			</div>
		</div>
	</div>
</template>

<script>
import { removeRepeatByKey } from '@/assets/public.js'
export default {
    name: 'StudnetSelector',
    props: {
        isShowFlag: {
            type: Boolean,
            default: false
        },
        studentSelectorOptions: {
            type: Object,
            default () {
                return {
                    isShow: false,
                    isBlock: false
                }
            }
        },
        list: {
            type: Array
        },
        isRenderSelected: {
            type: Boolean,
            default: true
        }
    },
    data () {
        return {
            tree: [],
            defaultProps: {
                children: 'children',
                label: 'fullname'
            },
            userList: [],
            hasSelectedUserList: [],
            selectAll: false,
            searchValue: ''
        }
    },
    watch: {
        isShowFlag (newValue, oldValue) {
            if (newValue) {
                if (this.isRenderSelected) {
                    this.hasSelectedUserList = this.list
                }
            }
        }
    },
    computed: {
        hasSelectedUserTotal () {
            return this.hasSelectedUserList.length
        },
        selectAllText () {
            return this.selectAll ? '反选' : '全选'
        },
        userListTotal () {
            return this.userList.length
        }
    },
    methods: {
    // 获取班年级
        getGradeClass () {
            this.$api.commonApi.getGradeClassList().then(res => {
                const data = res.data
                if (data.Status) {
                    this.tree = data.Data
                    this.$emit('hasGetGroup')
                } else {
                    this.$message({
                        message: '返回数据出错了',
                        type: 'warning'
                    })
                }
            })
        },
        // 搜索
        handleSearchClick (e) {
            if (this.searchValue.replace(/\s*/g, '') === '') {
                this.$message({
                    message: '输入内容不能为空',
                    type: 'warning'
                })
                return
            }
            this.$api.platBaseApi
                .call({
                    apiUrl: '/api/SystemAdmin/Student/ChoosStudent',
                    paramJson: {
                        grade_id: '',
                        class_id: '',
                        search_value: this.searchValue
                    }
                })
                .then(res => {
                    const data = res.data
                    if (data.Status) {
                        if (data.Data.length) {
                            this.$refs.tree.setCheckedKeys([])
                            let resultArr = data.Data
                            resultArr.forEach(itemI => {
                                itemI.is_select = false // 添加是否选中标志
                                this.hasSelectedUserList.forEach(itemJ => {
                                    if (itemI.id === itemJ.id) {
                                        itemI.is_select = true
                                    }
                                })
                            })
                            this.userList = resultArr
                            this.isSelectAll()
                        } else {
                            this.$message({
                                message: '暂无查询结果',
                                type: 'warning'
                            })
                        }
                    } else {
                        this.$message({
                            message: '返回数据出错了',
                            type: 'warning'
                        })
                    }
                })
        },
        // 选择组织架构
        /*
		 * 场景：
		 *  1、选中，并且选择用户和已选用户包含在所选部门，或者没有选择用户没有已选用户，或者有选择用户没有已选用户，或者没有选择用户没有已选用户
		 *  2、取消选中
		 *
		 * 处理方法：
		 * 1、获取部门里的用户数据，并与usetList合并、去重复，然后通过hasSelectedUserList 检测有没有已选择的用户，有将已选择的用户is_select置为真。赋值给userList
		 * 2、通过当前的部门id，删除对应选择用户的数据
		 *
		 * resultArr --》部门返回的数据与已选择的数据组合并去重
		 *  renderListArr --》已选择的人员默认被选中
		 *  */
        handleTreeChange (data, node) {
            let isClick = this.$refs.tree.getNode(data.id).checked // isClick  true 选中  false 反选
            let paramJson = data.category === 'class' ? { grade_id: '', class_id: data.id, search_value: '' } : { grade_id: data.id, class_id: '', search_value: '' }
            if (isClick) {
                this.$api.commonApi.chooseStudent(paramJson).then(res => {
                    const data = res.data
                    if (data.Status) {
                        let resultArr = removeRepeatByKey(data.Data.concat(this.userList), 'id')
                        resultArr.forEach(itemI => {
                            itemI.is_select = false // 添加是否选中标志
                            this.hasSelectedUserList.forEach(itemJ => {
                                if (itemI.id === itemJ.id) {
                                    itemI.is_select = true
                                }
                            })
                        })
                        this.userList = resultArr
                        this.isSelectAll()
                    } else {
                        this.$message({
                            message: '返回数据出错了',
                            type: 'warning'
                        })
                    }
                })
            } else {
                if (data.category === 'grade') {
                    this.userList = this.userList.filter(item => item.grade_id != data.id)
                } else if (data.category === 'class') {
                    this.userList = this.userList.filter(item => item.class_id != data.id)
                }
                this.isSelectAll()
            }
        },
        // 选择userList
        /* 场景：
		 *  1、已选用户存在，并且都包含在选择用户的列表内；
		 *  2、已选用户存在，并且有不包含在选择用户列表内；
		 *  3、已选用户不存在
		 *  处理方法：
		 *  1、如果选中，this.hasSelectedUserList与选中的所有值相连接，然后去重复
		 *  2、如果取消选中， 如果id相同，那么将this.hasSelectedUserList 对应的值删除。
		 *  */
        handleCheckboxChange (id, status) {
            if (status) {
                let selctedResultArr = this.userList.filter(item => item.is_select)
                this.hasSelectedUserList = removeRepeatByKey(this.hasSelectedUserList.concat(selctedResultArr), 'id')
            } else {
                this.hasSelectedUserList = this.hasSelectedUserList.filter(item => item.id != id)
            }
            this.isSelectAll()
        },
        // 全选/反选
        /*  场景：
		 *  1、已选用户存在，并且都包含在选择用户的列表内；
		 *  2、已选用户存在，并且有不包含在选择用户列表内；
		 *  3、已选用户不存在
		 *
		 *  处理方法
		 *  1、全选时，userlist的is_select置为真，hasSelectedUserList与其想连接并去重复
		 *  2、反选时，userlist的is_select置为假，hasSelectedUserList保留不在选择用户数据内的其他数据，删除再选择用户的数据
		 *  */
        handleCheckAllChange () {
            if (this.selectAll) {
                this.userList.forEach(item => {
                    item.is_select = true
                })
                this.hasSelectedUserList = removeRepeatByKey(this.hasSelectedUserList.concat(this.userList), 'id')
            } else {
                this.userList.forEach(item => {
                    item.is_select = false
                    this.hasSelectedUserList = this.hasSelectedUserList.filter(itemJ => item.id != itemJ.id)
                })
            }
        },
        // 是全选吗
        isSelectAll () {
            let len = 0
            this.userList.forEach(item => {
                if (item.is_select) {
                    len++
                }
            })
            this.selectAll = len === this.userList.length
        },
        // 删除已选择用户
        /*
		 * 场景：
		 * 1、有选择用户数据，并且已选用户数据，全部包含在选择用户内
		 * 2、没有选择用户数据
		 *
		 * 处理方法
		 * 1、删除hasSelectedUserList对应的数据，并遍历userList，如果id相同，则将此项的is_select置为fasle；
		 *
		 *  */
        handleDeleteItemCLick (id, idx) {
            this.hasSelectedUserList.splice(idx, 1)
            if (this.userList.length) {
                this.userList.forEach(item => {
                    if (item.id === id) {
                        item.is_select = false
                    }
                })
            }
            this.isSelectAll()
        },
        // 清空
        handleEmptyClick () {
            this.$confirm('确定清除所有已选学生？', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            })
                .then(() => {
                    this.hasSelectedUserList = []
                    if (this.userList.length) {
                        this.userList.forEach(item => {
                            item.is_select = false
                        })
                    }
                    this.isSelectAll()
                })
                .catch(() => {})
        },
        // 确定
        handleConfirmClick () {
            if (!this.hasSelectedUserList.length) {
                this.$message({
                    message: '请至少选择一个学生',
                    type: 'warning'
                })
                return
            }
            this.$emit('exportStudentSelectorUsers', this.hasSelectedUserList)
            // 初始化
            this.userList = []
            this.hasSelectedUserList = []
            this.selectAll = false
            this.searchValue = ''
            this.$refs.tree.setCheckedKeys([])
        },
        // 关闭模态框
        handleCloseClick () {
            this.$emit('closeStudentSelector')
            // 初始化
            this.userList = []
            this.hasSelectedUserList = []
            this.selectAll = false
            this.searchValue = ''
            this.$refs.tree.setCheckedKeys([])
        }
    },
    mounted () {
        this.getGradeClass()
    }
}
</script>

<style lang="less" scoped>
@import '~styles/varibles.less';
.selector {
	display: none;
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 3006;
	.selector-mask {
		position: fixed;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		z-index: 1;
		background-color: rgba(0, 0, 0, 0.5);
		opacity: 0;
		-webkit-transition: opacity 0.3s;
		transition: opacity 0.3s;
	}
	.selector-wrapper {
		position: absolute;
		top: 70px;
		left: 50%;
		width: 800px;
		height: 552px;
		margin-left: -400px;
		border-radius: 8px;
		background: rgb(255, 255, 255);
		overflow: hidden;
		z-index: 2;
		opacity: 0;
		-webkit-transition: opacity 0.3s;
		transition: opacity 0.3s;
		.selector-title {
			position: relative;
			line-height: 44px;
			background-color: #f2f2f2;
			font-size: 20px;
			text-align: center;
			.close-selector-btn {
				position: absolute;
				line-height: 44px;
				top: 0;
				right: 0;
				width: 44px;
				text-align: center;
				color: #b9b9b9;
				&:hover {
					color: #a3a3a3;
				}
			}
		}
		.selector-body {
			display: flex;
			justify-content: space-around;
			height: 438px;
			padding: 0 20px;
			.selector-panel {
				width: 32%;
				height: 100%;
				.panel-body {
					height: 418px;
					margin-top: 20px;
					padding: 10px;
					background-color: #f9f9f9;
					border: 1px solid #f2f2f2;
					border-radius: 5px;
					overflow-y: hidden;
					.group-wrapper {
						margin-top: 10px;
						height: 354px;
						/deep/ .el-tree-node__label {
							overflow: hidden;
							text-overflow: ellipsis;
							white-space: nowrap;
						}
						.group-list {
							height: 352px;
							margin-top: 10px;
							overflow-y: auto;
							.group-radio-list {
								.group-radio-item {
									position: relative;
									line-height: 28px;
									padding: 0 16px 0 6px;
									text-overflow: ellipsis;
									white-space: nowrap;
									cursor: pointer;
									color: #606266;
									&:hover {
										background: #eaeaea;
									}
								}
							}
						}
					}
					.selector-user-list {
						position: relative;
						.user-item {
							position: relative;
							line-height: 28px;
							padding: 0 16px 0 6px;
							text-overflow: ellipsis;
							white-space: nowrap;
							cursor: pointer;
							color: #606266;
							.delete-item {
								position: absolute;
								top: 0;
								right: 0;
								bottom: 0;
								line-height: 28px;
								color: #b2b2b2;
								font-size: 16px;
							}
							&:hover {
								background: #eaeaea;
							}
						}
					}
				}
				&.panel-with-title {
					margin-top: 20px;
					.panel-title {
						position: relative;
						line-height: 36px;
						.delete-user-list {
							position: absolute;
							top: 0;
							right: 0;
							line-height: 36px;
							color: #ff0000;
						}
						.select-all {
							position: absolute;
							top: 0;
							right: 0;
							line-height: 36px;
							color: @textBuleColor;
							&.is-select {
								color: #e6a23c;
							}
						}
					}
					.panel-body {
						margin-top: 0;
						height: 382px;
						overflow-y: auto;
					}
				}
			}

			.selected-user-checkbox-list {
				.item {
					position: relative;
					height: 28px;
					padding: 0 6px;
					cursor: pointer;
					&:hover {
						background: #eaeaea;
					}
					/deep/ .el-checkbox {
						display: flex;
						align-items: center;
						height: 100%;
						.el-checkbox__label {
							display: flex;
							flex: 1;
							justify-content: space-between;
						}
					}
				}
			}
		}
		.selector-footer {
			line-height: 70px;
			padding: 0 20px;
			text-align: right;
		}
	}
	&.active {
		.selector-mask,
		.selector-wrapper {
			opacity: 1;
		}
	}
}
</style>
