<template>
	<view class="container" style="box-sizing: border-box;">
		<view class="d-table" style="box-sizing: border-box;">
<!-- 			<view class="d-box">
				<view class="d-td" v-for="item in datatitleList">
					<span class="">{{item}}</span>
				</view>
			</view> -->
			<view class="d-tr">
				<!-- 	<view class="d-th">姓名</view>
				<view class="d-th">年龄</view>
				<view class="d-th">性别</view> -->

			</view>
			<!-- 为了提高dom渲染效率，当list产生破坏性变动时（如删除其中一项，或者排序等）必须使用唯一确定的key，而不能使用index -->
			<block v-for="(item, i) in treeList" :key="item.id">
				<view class="d-box" v-if="item.level === 0 || checkOpen(item.pids[item.pids.length - 1])">
					<view class="d-td">
						<view class="" style="display: flex;text-align: center;">
							
							
							<view class="d-td"  :style="{'margin-left':(item.level * 20)+'rpx'}">
								<text  v-if="dataShowType == 1">{{item.parentName}}</text>
								<view v-if="dataShowType == 2" style="text-align:center;">
									<text >{{item.raiseTeamLeder}}</text>
								</view>
							</view>
							<!-- 	<view class="content-box-title-a" @click="open(item, i)" :style="{'margin-left':(item.level * 20)+'rpx'}">
									<text style="color: black;">{{item.name}}</text>
							</view> -->
							<!-- 		<view @click="open(item, i)" style="flex: 1;text-align: left;" class="content-box-title-a" >
								<text >{{item.areaCenterName}}</text>
							</view>
							<view @click="open(item, i)" style="flex: 1;" class="content-box-title-b"  >
								<text>{{item.areaCenterName}}</text>
							</view>
							<view  @click="open(item, i)" style="flex: 1;" v-else>
								<text>{{item.name}}</text>
							</view> -->
						</view>
					</view>
					<view class="d-td" style="text-align: center;">
						<text v-if="dataShowType == 1">{{ item.name }}</text>
						<text  v-if="dataShowType == 2" style="margin-right: 30rpx;">{{item.raiseTime}}</text>
						<!-- 原本的写法 -->
						<!-- <text v-else></text> -->
					</view>
					<view class="d-td"  style="text-align: center;" v-if="dataShowType == 1">{{ item.levelName }}</view>
					<!-- 原本的结构现隐藏 -->
					<!-- <view class="d-td"  style="text-align: center;" v-if="dataShowType == 2">{{ item.count }}</view> -->
				</view>
			</block>
		</view>
	</view>
</template>

<script>
	/**
	 * @vdata list 原始数据列表
	 * @vdata openList 被展开数据的id列表
	 * @vdata treeList 重组后用于展示的树形结构列表
	 * @vdata lazyList 懒加载列表，表示正在懒加载的列
	 * @vdata historyList 记录懒加载过的数据的id列表
	 * @vmethod treeToArray 将树形数据转换为一维数组，通过pids进行关联
	 * @vmethod setTree以及setLevel 给list每个下标及其chilren的每个下标添加level（level越大，表示越接近leaf，leaf代表最下层或者代表树形数据的叶子）
	 * @vmethod setLazy 设置懒加载列表
	 * @vmethod checkLazy、checkOpen 检测是否正在懒加载、是否为打开状态
	 * @vmethod syncOpen 用于同步关闭和打开状态
	 * @vmethod setTreeNode 给list添加懒加载的数据
	 */
	import api from "../../api/api";
	export default {
		props: {
			dataList: {
				type: Array,
				default: null
			},
			datatitleList: {
				type: Array,
				default: null
			},
			type: {
				type: String,
			},
			dataShowType: {
				dataShowType: String,
			}
		},
		name: 'lazy-tree',
		mounted() {
			
			this.list = this.dataList
			this.setTree();
			console.log('datatitleList',this.datatitleList);
			console.log('dataList',this.dataList);
		},
		computed: {},
		data() {
			return {
				pleft: '60rpx',
				list: [],
				openList: [], // 被展开数组
				lazyList: [], // 加载数组
				treeList: [], // 树形数组
				historyList: [] //历史数组
			};
		},
		methods: {
			pdleft(level) {
				return (
					"padding-left:" + level * 5 + 10
				);
			},
			treeToArray(nodes, ids = [0]) {
				let arr = [];
				if (this.isArray(nodes)) {
					for (let i = 0, l = nodes.length; i < l; i++) {
						const node = nodes[i];
						node.pids = ids;
						node.level = ids.length - 1;
						arr.push(node); // 取每项数据放入一个新数组
						if (this.isArray(node['children']) && node['children'].length > 0)
							// 若存在children则递归调用，把数据拼接到新数组中，并且删除该children
							arr = arr.concat(this.treeToArray(node['children'], node.pids.concat([node.id])));
						delete node['children'];
					}
				}
				return arr;
			},
			setTree() {
				// let list = this.setLevel(this.deepClone(this.list));
				// this.openIndexList.forEach((o, i) => {
				// 	const children = this.openList[i].children;
				// 	children.forEach((o1, i1) => {
				// 		list.splice(o + i1 + 1, 0, o1);
				// 	});
				// });
				const list = this.deepClone(this.list);
				this.treeList = this.treeToArray(list);
				console.log('this.treeList',this.treeList);

			},
			async lazyLoad(name) {
				return new Promise((res, rej) => {
					try {
						setTimeout(() => {
							name += '-' + 1;
							const list = [{
								name,
								age: 17,
								sex: 0,
								id: this.guid(),
								children: [],
								hasChildren: true
							}];
							res(list);
						}, 500);
					} catch (e) {
						rej(e);
					}
				});
			},
			setLazy(id) {
				const i = this.lazyList.findIndex(o => o === id);
				if (!~i) {
					this.lazyList.push(id);
				} else {
					this.lazyList.splice(i, 1);
				}
			},
			checkLazy(id) {
				return ~this.lazyList.findIndex(o => o === id);
			},
			checkOpen(id) {
				return ~this.openList.findIndex(o => o === id);

			},
			syncOpen(ids) {
				const list = [];
				ids.forEach(o => {
					this.openList.forEach(o1 => {
						o1 === o && list.push(o1);
					});
				});
				this.openList = list;
			},
			async open(item, index) {
				if (item.itemType == '2') {
					return false
				}
				try {
					if (this.checkLazy(item.id)) return;
					if (!this.checkOpen(item.id)) {
						if (!~this.historyList.findIndex(o => item.id === o)) {
							this.setLazy(item.id);
							let CffpOrgInfoReqVO = {
								id: item.id
							}
							api.queryTeamDetail(CffpOrgInfoReqVO).then(res => {
								if (res['success']) {
									if (res.data.list.length === 0) {
										uni.showToast({
											title: '职级下无数据',
											duration: 1000,
											icon: 'none'
										});
									}
									res.data.list.forEach((x) => {
										this.$set(x, 'hasChildren', true)
										this.$set(x, 'children', [])
									})
									var list = this.deepClone(res.data.list);
									this.historyList.push(item.id);
									this.setTreeNode(this.list, item.id, list);
									this.setLazy(item.id);
									this.setTree();
								}
							})
							// const list = this.deepClone(await this.lazyLoad(item.levelName));

						}
						this.openList.push(item.id);
					} else {
						this.syncOpen(item.pids);
					}
				} catch (e) {
					//TODO handle the exception
				}
			},
			setTreeNode(list = [], id, children = []) {
				const o = list.find(o => {
					if (o.id === id) {
						o.children = children;
						return true;
					} else if (this.isArray(o.children) && o.children.length) {
						return this.setTreeNode(o.children, id, children);
					} else {
						return false;
					}
				});
			},
			setLevel(list = [], index = -1) {
				index++;
				list.forEach(o => {
					o.level = index;
					if (this.isArray(o.children)) {
						this.setLevel(o.children, index);
					}
				});
				return list;
			},
			// 深度克隆
			deepClone(obj) {
				// 对常见的“非”值，直接返回原来值
				if ([null, undefined, NaN, false].includes(obj)) return obj;
				if (typeof obj !== 'object' && typeof obj !== 'function') {
					//原始类型直接返回
					return obj;
				}
				var o = this.isArray(obj) ? [] : {};
				for (let i in obj) {
					if (obj.hasOwnProperty(i)) {
						o[i] = typeof obj[i] === 'object' ? this.deepClone(obj[i]) : obj[i];
					}
				}
				return o;
			},
			// 判断arr是否为一个数组，返回一个bool值
			isArray(arr) {
				return Object.prototype.toString.call(arr) === '[object Array]';
			},
			/**
			 * 本算法来源于简书开源代码，详见：https://www.jianshu.com/p/fdbf293d0a85
			 * 全局唯一标识符（uuid，Globally Unique Identifier）,也称作 uuid(Universally Unique IDentifier)
			 * 一般用于多个组件之间,给它一个唯一的标识符,或者v-for循环的时候,如果使用数组的index可能会导致更新列表出现问题
			 * 最可能的情况是左滑删除item或者对某条信息流"不喜欢"并去掉它的时候,会导致组件内的数据可能出现错乱
			 * v-for的时候,推荐使用后端返回的id而不是循环的index
			 * @param {Number} len uuid的长度
			 * @param {Boolean} firstU 将返回的首字母置为"u"
			 * @param {Nubmer} radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制
			 */
			guid(len = 32, firstU = true, radix = null) {
				let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
				let uuid = [];
				radix = radix || chars.length;

				if (len) {
					// 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位
					for (let i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
				} else {
					let r;
					// rfc4122标准要求返回的uuid中,某些位为固定的字符
					uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
					uuid[14] = '4';

					for (let i = 0; i < 36; i++) {
						if (!uuid[i]) {
							r = 0 | (Math.random() * 16);
							uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
						}
					}
				}
				// 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class
				if (firstU) {
					uuid.shift();
					return 'u' + uuid.join('');
				} else {
					return uuid.join('');
				}
			}
		}
	};
</script>

<style lang="scss" scoped> 
	.content-box {
		background-color: #fff;
		display: flex;
		font-weight: 600;
		align-items: center;
		// padding: 0 20rpx;
		justify-content: space-between;
		box-sizing: border-box;
		// width: 100%;
	}

	.content-box-title {
		// padding: 5px 0;
		flex: 1;
		// justify-content: space-between;
		align-items: center;
		text-align: left;
		padding: 0 20rpx;
	}

	.d-box {
		background-color: #fff;
		display: flex;
		justify-content: space-between;
		padding: 20rpx 0;
		font-size: 26rpx;
		box-sizing: border-box;
		border-bottom: 1px solid #F2F2F2;
		.d-td {
			flex: 1;
			align-items: center;
			color: #333;
			// padding: 5rpx 10rpx;
		}
	}
	.d-box:last-child{
		border: none;
	}
	.content-box-title-a {
		// flex: 1;
		// padding: 0 20rpx;
		font-size: 26rpx;
		max-width: 246rpx;
		min-height: 60rpx;
		margin-top: 5rpx;
		line-height: 50rpx;
	}

	.test {
		position: relative;
		width: 160rpx;
		height: 52rpx;
		background-color: #20269B;
		display: flex;
		justify-content: center;
		align-items: center;
		color: #fff;
		margin-left: 50rpx;

		&:before {
			position: absolute;
			left: -52rpx;
			top: 0;
			content: '';
			width: 0;
			height: 0;
			border: 26rpx solid #20269B;
			border-top-color: transparent;
			border-left-color: transparent;
			border-right-color: #20269B;
			border-bottom-color: transparent;
		}

		&:after {
			position: absolute;
			left: 100%;
			top: 0;
			content: '';
			width: 0;
			height: 0;
			border: 26rpx solid #20269B;
			border-top-color: transparent;
			border-left-color: #20269B;
			border-right-color: transparent;
			border-bottom-color: transparent;
		}
	}


	.d-tr {
		display: flex;
		width: 100%;
		justify-content: space-between;
		box-sizing: border-box;
		.d-th {
			justify-content: center;
			flex: 1
		}
	}
</style>
