<!--
*   教师选择器
*  	@data  teacherSelectorOptions：  控制组件显示隐藏
*   @data  list： 父组件传过已选择用户的值
* 	@data  tree： 班年级树
*   @data  defaultProps： 定义渲染内容
*   @data  userList：选择用户数据
*   @data  hasSelectedUserList：已选用户数据
* 	@data  isOrganize 组织架构标志 默认组织架构
*   @data  selectAll：全选标志
*   @data  definedGroup 自定义分组的分组类型
*   @funcnction 见方法备注
*
*   向父组件传值 hasSelectedUserList
*
*   组件调用
*   <teacher-selector :teacher-selector-options="teacherSelectorOptions" @closeTeacherSelector="handleCloseTeacherSelectorClick"></teacher-selector>
*   调用方法
*   handleAddClick() {
		const self = this;
		this.teacherSelectorOptions.isBlock = true;
		const timer = setTimeout(function () {
			self.teacherSelectorOptions.isShow = true;
			clearTimeout(timer);
		}, 0);
	},
*   关闭方法
	handleCloseStudentSelectorClick() {
		const self = this;
		this.teacherSelectorOptions.isShow = false;
		const timer = setTimeout(function () {
			self.teacherSelectorOptions.isBlock = false;
			clearTimeout(timer);
		}, 300);
	}
*  -->
<template>
	<div class="selector" v-dom-portal :class="teacherSelectorOptions.isShow ? 'active' : ''" :style="{ display: teacherSelectorOptions.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">
							<ul class="group-tab">
								<li class="tab-item" :class="isOrganize ? 'current' : ''" @click="handleTabClick(true)"><a href="javascript:;">组织架构</a></li>
								<li class="tab-item" :class="!isOrganize ? 'current' : ''" @click="handleTabClick(false)"><a href="javascript:;">自定义分组</a></li>
							</ul>
							<div class="group-list">
								<div class="group-item" v-show="isOrganize">
									<template v-if="tree.length">
										<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>
									</template>
								</div>
								<div class="group-item" v-show="!isOrganize">
									<ul class="group-checkbox-list" v-if="customGroupList.length">
										<li
											class="group-checkbox-item"
											v-for="(item, index) of customGroupList"
											:key="item.id"
											:class="item.isActive ? 'active' : ''"
											@click="handleDefinedGroupChange(item, index)"
										>
											<span class="checkbox-inner"></span>
											{{ item.group_name }}
										</li>
									</ul>
								</div>
							</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 && this.isMultiple">
							<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 }}
									<span class="pull-right">{{ item.mobile }}</span>
								</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: 'TeacherSelector',
    props: {
        isShowFlag: {
            type: Boolean,
            default: false
        },
        teacherSelectorOptions: {
            type: Object,
            default () {
                return {
                    isShow: false,
                    isBlock: false
                }
            }
        },
        list: {
            type: Array
        },
        isRenderSelected: {
            type: Boolean,
            default: true
        },
        isMultiple: { // 是否多选，默认多选
            type: Boolean,
            default: true
        }
    },
    data () {
        return {
            tree: [],
            defaultProps: {
                children: 'children',
                label: 'fullname'
            },
            userList: [],
            hasSelectedUserList: [],
            selectAll: false,
            isOrganize: true,
            searchValue: '',
            customGroupList: [],
            isGetCustomGroup: false
        }
    },
    watch: {
        isShowFlag (newValue, oldValue) {
            if (newValue) {
                if (this.isRenderSelected) {
                    this.hasSelectedUserList = this.list
                }
            }
        },
        hasSelectedUserList (newVal, oldVal) {
            if (!this.isMultiple && newVal && newVal.length > 1) { // 当只能单选时
                this.hasSelectedUserList = oldVal
                this.userList.forEach(item => {
                    if (item.id !== oldVal[0].id) {
                        item.is_select = false
                    }
                })
                this.$message({
                    message: '只能选择一个',
                    type: 'warning'
                })
            }
        }
    },
    computed: {
        hasSelectedUserTotal () {
            return this.hasSelectedUserList.length
        },
        selectAllText () {
            return this.selectAll ? '反选' : '全选'
        },
        userListTotal () {
            return this.userList.length
        }
    },
    methods: {
    // 获取组织架构
        getGroup () {
            this.$api.platBaseApi
                .call({
                    apiUrl: '/api/SystemAdmin/Organize/OrganizeTree',
                    paramJson: {}
                })
                .then(res => {
                    const data = res.data
                    if (data.Status) {
                        let dataArr = []
                        dataArr.push(data.Data)
                        this.tree = dataArr
                        this.$emit('hasGetGroup')
                    } else {
                        this.$message({
                            message: '返回数据出错了',
                            type: 'warning'
                        })
                    }
                })
        },
        // 获取自定义分组
        getCustomGroup () {
            this.$api.platBaseApi
                .call({
                    apiUrl: '/api/SystemAdmin/CustomGroup/CustomGroupList',
                    paramJson: { user_id: '' }
                })
                .then(res => {
                    const data = res.data
                    if (data.Status) {
                        let customGroupListArr = []
                        data.Data.forEach(item => {
                            item.isActive = false
                            customGroupListArr.push(item)
                        })
                        this.customGroupList = customGroupListArr
                        this.isGetCustomGroup = true
                    } 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/User/ChooseUser',
                    paramJson: {
                        sub_company_id: '',
                        department_id: '',
                        sub_department_id: '',
                        workgroup_id: '',
                        search_value: this.searchValue
                    }
                })
                .then(res => {
                    const data = res.data
                    if (data.Status) {
                        if (data.Data.length) {
                            this.$refs.tree.setCheckedKeys([])
                            this.customGroupList.forEach(item => {
                                item.isActive = false
                            })
                            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'
                        })
                    }
                })
        },
        // 点击tab
        handleTabClick (bool) {
            if (this.isOrganize != bool) {
                this.isOrganize = bool
                // isGetCustomGroup 作为加载自定义分组的一个标志,防止重复请求
                if (!bool && !this.isGetCustomGroup) {
                    this.getCustomGroup()
                }
            }
        },
        // 选择组织架构
        /*
		 * 场景：
		 *  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 = this.chooseUserData(data.category, data.id)
            if (isClick) {
                this.$api.platBaseApi
                    .call({
                        apiUrl: '/api/SystemAdmin/User/ChooseUser',
                        paramJson: 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 === 'Company') {
                    this.userList = []
                } else if (data.category === 'SubCompany') {
                    this.userList = this.userList.filter(item => item.sub_company_id != data.id)
                } else if (data.category === 'Department') {
                    this.userList = this.userList.filter(item => item.department_id != data.id)
                } else if (data.category === 'SubDepartment') {
                    this.userList = this.userList.filter(item => item.sub_department_id != data.id)
                } else if (data.category === 'WorkGroup') {
                    this.userList = this.userList.filter(item => item.workgroup_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(() => {})
        },
        // 自定义分组
        /*
		 * 场景
		 * 1、已经选择了部门又选择自定义分组
		 * 2、没有选择部门子选择自定义分组
		 * 3、已有已选择用户
		 * 4、没有已选择用户
		 *
		 * 处理方法：
		 * 1、首先遍历userList，清除掉已选择的自定义分组的数据，然后连接新的自定义分组返回数据，
		 * 然后去重得到userList，再反查已选择的用户，如果已选择的用户有数据，则遍历，将id相同的
		 * is_select置为真
		 *
		 *  */
        handleDefinedGroupChange (data, idx) {
            if (!data.isActive) {
                console.log('选中')
                this.customGroupList[idx].isActive = true
                this.$api.platBaseApi
                    .call({
                        apiUrl: '/api/SystemAdmin/CustomGroup/CustomGroupPeople',
                        paramJson: { group_id: data.id }
                    })
                    .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 {
                console.log('反选')
                this.customGroupList[idx].isActive = false
                console.log(data.id)
                this.userList = this.userList.filter(item => item.custom_group_id != data.id)
            }
        },
        // 选择组织架构的传值
        chooseUserData (category, id) {
            let data = {
                sub_company_id: '',
                department_id: '',
                sub_department_id: '',
                workgroup_id: '',
                search_value: ''
            }
            switch (category) {
            case 'Company':
                break
            case 'SubCompany':
                data.sub_company_id = id
                break
            case 'Department':
                data.department_id = id
                break
            case 'SubDepartment':
                data.sub_department_id = id
                break
            case 'WorkGroup':
                data.workgroup_id = id
                break
            default:
                break
            }
            return data
        },
        // 确定
        handleConfirmClick () {
            if (!this.hasSelectedUserList.length) {
                this.$message({
                    message: '请至少选择一个教师',
                    type: 'warning'
                })
                return
            }
            this.$emit('exportTeacherSelectorUsers', this.hasSelectedUserList)
            // 初始化
            this.userList = []
            this.hasSelectedUserList = []
            this.selectAll = false
            this.isOrganize = true
            this.searchValue = ''
            this.$refs.tree.setCheckedKeys([])
            this.customGroupList.forEach(item => {
                item.isActive = false
            })
        },
        // 关闭模态框
        handleCloseClick () {
            this.$emit('closeTeacherSelector')
            // 初始化
            this.userList = []
            this.hasSelectedUserList = []
            this.selectAll = false
            this.isOrganize = true
            this.searchValue = ''
            this.$refs.tree.setCheckedKeys([])
            this.customGroupList.forEach(item => {
                item.isActive = false
            })
        }
    },
    mounted () {}
}
</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: 820px;
		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-tab {
							display: flex;
							border: 1px solid #409eff;
							border-radius: 3px;
							.tab-item {
								width: 50%;
								height: 30px;
								line-height: 30px;
								text-align: center;
								color: @textBuleColor;
								&.current {
									background-color: #409eff;
									color: #fff;
								}
								a {
									display: block;
									height: 100%;
									line-height: 30px;
									color: inherit;
								}
							}
						}
						.group-list {
							height: 312px;
							margin-top: 10px;
							overflow-y: auto;
							.group-checkbox-list {
								.group-checkbox-item {
									position: relative;
									line-height: 28px;
									padding: 0 6px 0 32px;
									text-overflow: ellipsis;
									white-space: nowrap;
									cursor: pointer;
									color: #606266;
									font-size: 14px;
									&:hover {
										background: #eaeaea;
									}
									.checkbox-inner {
										position: absolute;
										top: 50%;
										left: 8px;
										border: 1px solid #dcdfe6;
										border-radius: 2px;
										-webkit-box-sizing: border-box;
										box-sizing: border-box;
										width: 14px;
										height: 14px;
										background-color: #fff;
										z-index: 1;
										-webkit-transition: border-color 0.25s cubic-bezier(0.71, -0.46, 0.29, 1.46), background-color 0.25s cubic-bezier(0.71, -0.46, 0.29, 1.46);
										transition: border-color 0.25s cubic-bezier(0.71, -0.46, 0.29, 1.46), background-color 0.25s cubic-bezier(0.71, -0.46, 0.29, 1.46);
										transform: translateY(-50%);
									}
									&.active {
										.checkbox-inner {
											background-color: #409eff;
											border-color: #409eff;
											&:after {
												-webkit-box-sizing: content-box;
												box-sizing: content-box;
												content: '';
												border: 1px solid #fff;
												border-left: 0;
												border-top: 0;
												height: 7px;
												left: 4px;
												position: absolute;
												top: 1px;
												-webkit-transform: rotate(45deg) scaleY(1);
												transform: rotate(45deg) scaleY(1);
												width: 3px;
												-webkit-transition: -webkit-transform 0.15s ease-in 0.05s;
												transition: -webkit-transform 0.15s ease-in 0.05s;
												transition: transform 0.15s ease-in 0.05s;
												transition: transform 0.15s ease-in 0.05s, -webkit-transform 0.15s ease-in 0.05s;
												transition: transform 0.15s ease-in 0.05s, -webkit-transform 0.15s ease-in 0.05s;
												-webkit-transform-origin: center;
												transform-origin: center;
											}
										}
									}
								}
							}
						}
					}
					.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>
