From d1448cb0ef10f358bb7bddb4e1ec268515e0b787 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 15 七月 2025 11:46:57 +0800
Subject: [PATCH] 项目初始化

---
 components/qian-tree/qian-tree.vue |  425 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 425 insertions(+), 0 deletions(-)

diff --git a/components/qian-tree/qian-tree.vue b/components/qian-tree/qian-tree.vue
new file mode 100644
index 0000000..e4deed7
--- /dev/null
+++ b/components/qian-tree/qian-tree.vue
@@ -0,0 +1,425 @@
+<template xlang="wxml">
+	<view class="tki-tree">
+		<view class="tki-tree-mask" :class="{'show':showTree}" @tap="_cancel"></view>
+		<view class="tki-tree-cnt" :class="{'show':showTree}">
+			<view class="tki-tree-bar">
+				<view class="tki-tree-bar-cancel" :style="{'color':cancelColor}" hover-class="hover-c" @tap="_cancel">鍙栨秷</view>
+				<view class="tki-tree-bar-title" :style="{'color':titleColor}">{{title}}</view>
+				<view class="tki-tree-bar-confirm" :style="{'color':confirmColor}" hover-class="hover-c" @tap="_confirm">纭畾</view>
+			</view>
+			<view class="tki-tree-view">
+				<scroll-view class="tki-tree-view-sc" :scroll-y="true">
+					<block v-for="(item, index) in treeList" :key="index">
+						<view class="tki-tree-item" :style="[{
+							paddingLeft: item.rank*15 + 'px',
+							zIndex: item.rank*-1 +50
+						}]"
+						 :class="{
+							border: border === true,
+							show: item.show,
+							last: item.lastRank,
+							showchild: item.showChild,
+							open: item.open,
+						}">
+							<view class="tki-tree-label" @tap.stop="_treeItemTap(item, index)">
+								<image class="tki-tree-icon" :src="item.lastRank ? lastIcon : item.showChild ? currentIcon : defaultIcon"></image>
+								{{item.name}}
+							</view>
+							<view class="tki-tree-check" @tap.stop="_treeItemSelect(item, index)" v-if="selectParent?true:item.lastRank">
+								<view class="tki-tree-check-yes" v-if="item.checked" :class="{'radio':!multiple}" :style="{'border-color':confirmColor}">
+									<view class="tki-tree-check-yes-b" :style="{'background-color':confirmColor}"></view>
+								</view>
+								<view class="tki-tree-check-no" v-else :class="{'radio':!multiple}" :style="{'border-color':confirmColor}"></view>
+							</view>
+						</view>
+					</block>
+				</scroll-view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "tki-tree",
+		props: {
+			lazy: {
+				type: Boolean,
+				default: false
+			},
+			range: {
+				type: Array,
+				default: function() {
+					return []
+				}
+			},
+			idKey: {
+				type: String,
+				default: 'id'
+			},
+			rangeKey: {
+				type: String,
+				default: 'label'
+			},
+			title: {
+				type: String,
+				default: ''
+			},
+			multiple: { // 鏄惁鍙互澶氶��
+				type: Boolean,
+				default: false
+				// default: true
+			},
+			selectParent: { //鏄惁鍙互閫夌埗绾�
+				type: Boolean,
+				default: false
+			},
+			foldAll: { //鎶樺彔鏃跺叧闂墍鏈夊凡缁忔墦寮�鐨勫瓙闆嗭紝鍐嶆鎵撳紑鏃堕渶瑕佷竴绾т竴绾ф墦寮�
+				type: Boolean,
+				default: false
+			},
+			confirmColor: { // 纭畾鎸夐挳棰滆壊
+				type: String,
+				default: '' // #07bb07
+			},
+			cancelColor: { // 鍙栨秷鎸夐挳棰滆壊
+				type: String,
+				default: '' // #757575
+			},
+			titleColor: { // 鏍囬棰滆壊
+				type: String,
+				default: '' // #757575
+			},
+			currentIcon: { // 灞曞紑鏃跺�欑殑ic
+				type: String,
+				default: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAABRCAYAAACqj0o2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MEQ0QTM0MzQ1Q0RBMTFFOUE0MjY4NzI1Njc1RjI1ODIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MEQ0QTM0MzU1Q0RBMTFFOUE0MjY4NzI1Njc1RjI1ODIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowRDRBMzQzMjVDREExMUU5QTQyNjg3MjU2NzVGMjU4MiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowRDRBMzQzMzVDREExMUU5QTQyNjg3MjU2NzVGMjU4MiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PidwepsAAAK0SURBVHja7JxbTsJAFIYHww7ciStgCeoGvGxAiOsgURegoL5720AXYLiIr0aJviq3Zx3PhIEnKG3ndtr+f3KixrSUj/ZjzjClIqUUiFm2gAAQAREQEUAEREAERAQQAREQAREBREAEREBEEqa67h9RFDWllDv0awWYlqlQHmu1WjMRRMoV1QFttA12y3xRtdNczq8EsE4/f8FumX2q77ROvNXk8UGMEKdUz6tYJHljaZAbuyUH+UR1to5BEohTuqwPCeS4pAA/qY6o/kyHOAMCeRK3owJnj+rH1jjxhqpVsstaebCz6TmnHWyXyY+xHjSBWBY/bvSgadtXBj9u9KCN3rnIfkzkQVsTEEX0Y2IP2oKo/HhMICcFAThUcwVZNGU6FdbX/XURzkbVF4+ybGhjPrFdgP66QdXNurGtSdk6Xdb9nAJ8oDo3OQlsQZzkdPw41ONBo6vI5scDefRjZg+6gpg3Pxp50CXEvPjR2IOuIXL3oxUPuobI3Y9WPOgDIlc/WvOgL4iL/vqFCcD7LH0xB4hj7cfQ/fWH9qCT+FhG0tN+DBk1PzjOM0SVllixcsBT1AvYc/kAPhc0hRg/3uvxoCgKRN9+dOrBUBB9+9GpB0NC9OVH5x4MDdG1H714kANEV3705kEOEBf9dcPi/lQnsuvLg1wgSu3Ha0v7Uh4MMgUXeuG71H407a+VBy9CPQkOdw+MtB+nGbd/D+FBbhBNxo9SjwcngJjNj0E9yBFiFj8G9SBXiGn8GNyDnCEm8SMLD3KHGOdHNh7kDjHOj2w8mAeIi/5arX+c6b/fxHz9oADEdGdjR/fXCw/OOB5oVfCOgnepz8IB14PMw03jCmTE+QBx5z0gAmKSqK9OUF+hcAeIhu/QYr4Qie8rjW83hhMBERARQAREQAREBBABERCLnH8BBgA+TQI7U4t53AAAAABJRU5ErkJggg=='
+			},
+			defaultIcon: { // 鎶樺彔鏃跺�欑殑ic
+				type: String,
+				default: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAABRCAYAAACqj0o2AAACE0lEQVR4Xu3c200DMRCF4XEltJAOkEugA+ggpUAHoQMqiFMCdEAJUMEiS4mEELlIO7bPOeN9i6K1rG/952myyea1WiCtXmEuYBPR4RBMxInoIOCwhOtJLKVszWyXc/5y2BvNEq6I+/3+kFK6M7OHnPM7jcLKjbZAvD/uaZtzflm5P4rbWyJWgDcze1LPuzVihfxUz7sH4ilJ2bx7Isrm3RtRMu8RiHJ5j0SUyXs0okTeCIj0eSMh0uaNhkiZNyIiXd7IiDR5oyNS5M2ACJ83EyJs3myIkHkzIsLlzYwIkzc7IkTeCojD81ZCHJa3GuKQvBURu+etjNgtb3XELnlHQGyedyTEZnlHQ2ySd0RE97wjI7rlHR3RJe+JeIrbLOecD6ePpZQ6W1kn2epo4MUrPOKyLN8ppYq1+y1VStncOjIdGnFZlo+U0uOtWOeOY2TE12Ouq//pEA7xXL7XfvcufR8K0Svfv6CREN3yDYfYIt9QiK3yjYTYLF95xB75SiP2ylcZsVu+cogj8pVCHJWvEuKwfOkREfKlRkTJlxkRJl86RMR8qRBR82VChM0XHpEhX2hElnyREWnyhUNkzBcKkTVfJETafIcjKuQ7FFEl35GIMvl2R1TMtyuiar49EWXzbY5oZpv/hibXTF2h3+s60FRKeT6+3TjMS3nrA3ZFRD8xrfY3ER1kJ+JEdBBwWGKeRAfEH1wS5WFZSDB/AAAAAElFTkSuQmCC'
+			},
+			lastIcon: { // 娌℃湁瀛愰泦鐨刬c
+				type: String,
+				default: ''
+			},
+			border: { // 鏄惁鏈夊垎鍓茬嚎
+				type: Boolean,
+				default: false
+			},
+		},
+		data() {
+			return {
+				showTree: false,
+				treeList: [],
+				selectIndex: -1,
+				returnedItem: [] ,//瀹氫箟涓�涓┖鏁扮粍
+				pids: [],
+				ancestorsIds: [],
+				childNums: [],
+			}
+		},
+		computed: {},
+		methods: {
+			_show() {
+				this.showTree = true
+			},
+			_hide() {
+				this.showTree = false
+			},
+			_cancel() {
+				this._hide()
+				this.$emit("cancel", '');
+			},
+			_confirm() {
+				// 澶勭悊鎵�閫夋暟鎹�
+				let rt = [],
+					obj = {};
+				this.treeList.forEach((v, i) => {
+					if (this.treeList[i].checked) {
+						rt.push(this.treeList[i].id)
+					}
+				})
+				this._hide()
+				this.$emit("confirm", rt);
+			},
+			//鎵佸钩鍖栨爲缁撴瀯
+			_renderTreeList(list = [], rank = 0, parentId = [], parents = []) {
+				list.forEach(item => {
+					this.treeList.push({
+						id: item[this.idKey],
+						name: item[this.rangeKey],
+						source: item,
+						parentId, // 鐖剁骇id鏁扮粍
+						parents, // 鐖剁骇id鏁扮粍
+						rank, // 灞傜骇
+						showChild: false, //瀛愮骇鏄惁鏄剧ず
+						open: false, //鏄惁鎵撳紑
+						show: rank === 0, // 鑷韩鏄惁鏄剧ず
+						hideArr: [],
+						orChecked: item.checked ? item.checked : false,
+						checked: item.checked ? item.checked : false,
+						childNum: 0
+					})
+					
+					if (Array.isArray(item.children) && item.children.length > 0) {
+						// console.log(item)
+						let parentid = [...parentId],
+							parentArr = [...parents];
+						delete parentArr.children
+						parentid.push(item[this.idKey]);
+						parentArr.push({
+							[this.idKey]: item[this.idKey],
+							[this.rangeKey]: item[this.rangeKey]
+						})
+						// lazy
+						if(!this.lazy) {
+							this._renderTreeList(item.children, rank + 1, parentid, parentArr)
+						}
+					} else {
+						this.treeList[this.treeList.length - 1].lastRank = true;
+					}
+				})
+			},
+			// 澶勭悊榛樿閫夋嫨
+			_defaultSelect() {
+				this.treeList.forEach((v, i) => {
+					if (v.checked) {
+						this.treeList.forEach((v2, i2) => {
+							if (v.parentId.toString().indexOf(v2.parentId.toString()) >= 0) {
+								v2.show = true
+								if (v.parentId.includes(v2.id)) {
+									v2.showChild = true;
+									v2.open = true;
+								}
+							}
+						})
+					}
+				})
+			},
+			getOwn(id, arr){
+			  //鍒╃敤foreach寰幆閬嶅巻
+			  arr.forEach((item) => {
+				//鍒ゆ柇閫掑綊缁撴潫鏉′欢
+				if(item[this.idKey] == id)
+				{       
+				  // 瀛樺偍鏁版嵁鍒扮┖鏁扮粍
+				  this.returnedItem = item
+				}
+				  else if(item.children != null) //鍒ゆ柇chlidren鏄惁鏈夋暟鎹�
+				{
+				  //閫掑綊璋冪敤
+				  this.getOwn(id, item.children);                 
+				}                   
+			  })
+			  return this.returnedItem
+			},
+			setShow (id, arr, isShow) {
+				arr.forEach((item, index) => {
+					if(item.parentId.includes(id)) {
+						this.treeList[index].showChild = isShow
+						this.treeList[index].show = isShow
+					} else if (item.children !== undefined) {
+						this.setShow(id, item.children, isShow)
+					}
+				})
+			},
+			// 鐐瑰嚮
+			_treeItemTap(item, index) {
+				// console.log(item)
+				if (item.lastRank === true) {
+					//鐐瑰嚮鏈�鍚庝竴绾ф椂瑙﹀彂浜嬩欢
+					this.treeList[index].checked = !this.treeList[index].checked
+					this._fixMultiple(index)
+					return;
+				}
+				let id = item.id;
+				item.showChild = !item.showChild;
+				// qingqian
+				if(item.showChild) {
+					const range = this.range
+					const parentIdArr = item.parentId
+					// 鎵惧埌褰撳墠鍏冪礌
+					const own = this.getOwn(id, range)
+					const checkedChildren = own.children
+					// 瀛愬厓绱犳彃鍏ョ殑绱㈠紩浣嶇疆
+					const nextIndex = this.treeList.findIndex(itemT => itemT.id === item.id)
+					console.log(checkedChildren);
+					if(checkedChildren === undefined || checkedChildren.length < 1) {
+						return
+					}
+					// 瀛愯妭鐐规暟閲�
+					this.treeList[index].childNum = checkedChildren.length
+					const newRank = item.rank + 1
+					checkedChildren.forEach(itemC => {
+						const childObj = {
+							id: itemC[this.idKey],
+							name: itemC[this.rangeKey],
+							source: {},
+							parentId: [item.id], // 鐖剁骇id鏁扮粍
+							parents: [item], // 鐖剁骇id鏁扮粍
+							rank: newRank, // 灞傜骇
+							showChild: false, //瀛愮骇鏄惁鏄剧ず
+							open: false, //鏄惁鎵撳紑
+							show: 1, // 鑷韩鏄惁鏄剧ず
+							hideArr: [],
+							orChecked:  this.treeList[index].checked,
+							checked:  this.treeList[index].checked,
+						}
+						if(!this.treeList.some(itemT => itemT.id === itemC[this.idKey])) {
+							this.treeList.splice(nextIndex+1,0,childObj)
+						}
+					})
+				}
+				// 灞曞紑/闅愯棌瀛愮骇/瀛欑骇
+				let list = this.treeList
+				item.open = item.showChild ? true : !item.open;
+				list.forEach((childItem, i) => {
+					if (item.showChild === false) {
+						//闅愯棌鎵�鏈夊瓙绾�
+						if (!childItem.parentId.includes(id)) {
+							return;
+						}
+						//TODO: 淇敼
+						if (!this.foldAll) {
+							if (childItem.lastRank !== true && !childItem.open) {
+								childItem.showChild = false;
+								this.setShow(childItem.id, this.treeList, false)
+							}
+							// 涓洪殣钘忕殑鍐呭娣诲姞涓�涓爣璁�
+							if (childItem.show) {
+								childItem.hideArr[item.rank] = id
+							}
+						} else {
+							if (childItem.lastRank !== true) {
+								childItem.showChild = false;
+								// 缁х画闅愯棌瀛愮骇鐨勭殑瀛愮骇
+								this.setShow(childItem.id, this.treeList, false)
+							}
+						}
+						if(childItem.children !== undefined) {
+							childItem.children.forEach((childItem1, i1) => {
+								if(!childItem1.parentId.includes(childItem.id)) {
+									return
+								}
+								childItem.children[i1].showChild = false
+								childItem.children[i1].show = false
+							})
+						}
+						childItem.show = false;
+					} else {
+						// 鎵撳紑瀛愰泦
+						if (childItem.parentId[childItem.parentId.length - 1] === id) {
+							childItem.show = true;
+						}
+						// 鎵撳紑琚殣钘忕殑瀛愰泦
+						if (childItem.parentId.includes(id) && !this.foldAll) {
+							// console.log(childItem.hideArr)
+							if (childItem.hideArr[item.rank] === id) {
+								childItem.show = true;
+								if (childItem.open && childItem.showChild) {
+									childItem.showChild = true
+								} else {
+									childItem.showChild = false
+								}
+								childItem.hideArr[item.rank] = null
+							}
+						}
+					}
+				})
+			},
+			// 閫氳繃鐖秈d澶勭悊瀛愮骇
+			syncChecked (trees, pid, checked) {
+				trees.forEach((item,index) => {
+					if(item.parentId.includes(pid)) {
+						this.treeList[index].checked = checked
+						this.syncChecked(trees, item.id, checked)
+					} else if(item.children !== undefined) {
+						this.syncChecked(item.children, pid, checked)
+					}
+				})
+			},
+			// 鑾峰彇鐖剁骇寰�涓婃墍鏈夊眰绾х殑id 骞跺悓姝ョ姸鎬�
+			setAncestors (pids, checked) {
+				this.treeList.forEach((item,index) => {
+					if(pids.includes(item.id)) {
+						if(checked && this.childNums[item.id] !== undefined && item.childNum === this.childNums[item.id]) {
+						// 瀛愮骇鍏ㄩ儴閫変腑, 鐖剁骇鎵嶉�変腑
+							this.treeList[index].checked = true
+						} else {
+							this.treeList[index].checked = false
+						}
+						this.setAncestors(item.parentId, checked)
+					} 
+				})
+			},
+			_treeItemSelect(item, index) {
+				this.treeList[index].checked = !this.treeList[index].checked
+				// 閫夌埗绾�, 瀛愮骇鑷姩鍏ㄩ��
+				this.syncChecked(this.treeList, item.id, this.treeList[index].checked)
+			
+				if(item.rank > 0) {
+					item.parentId.forEach((pid, indexP) => {
+						const parent = this.treeList.filter(i => i.id === pid)
+						const childNum = parent.length > 0 ? parent[0].childNum : 0
+						if(this.childNums[pid] === undefined) {
+							this.childNums[pid] = 1
+						} else if(this.childNums[pid] < childNum) {
+							this.childNums[pid]++
+						}
+					})
+					//瀛愮骇閫夋嫨/閫夋弧/鍙栨秷閫夋嫨, 鐖剁骇寰�涓婂悓姝ョ姸鎬�
+					this.setAncestors(item.parentId, this.treeList[index].checked)
+				}
+				this._fixMultiple(index)
+			},
+			// 澶勭悊鍗曢�夊閫�
+			_fixMultiple(index) {
+				if (!this.multiple) {
+					// 濡傛灉鏄崟閫�
+					this.treeList.forEach((v, i) => {
+						if (i != index) {
+							this.treeList[i].checked = false
+						} else {
+							this.treeList[i].checked = true
+						}
+					})
+				}
+			},
+			// 閲嶇疆鏁版嵁
+			_reTreeList() {
+				this.treeList.forEach((v, i) => {
+					this.treeList[i].checked = v.orChecked
+				})
+			},
+			_initTree(range = this.range){
+				this.treeList = [];
+				this._renderTreeList(range);
+				this.$nextTick(() => {
+					this._defaultSelect(range)
+				})
+			}
+		},
+		watch: {
+			range(list) {
+				this._initTree(list);
+			},
+			multiple() {
+				if (this.range.length) {
+					this._reTreeList();
+				}
+			},
+			selectParent() {
+				if (this.range.length) {
+					this._reTreeList();
+				}
+			},
+		},
+		mounted() {
+			this._initTree();
+		}
+	}
+</script>
+
+<style scoped>
+	@import "./style.css";
+</style>

--
Gitblit v1.9.3