<template>
	<view class="wyb-table-box">
		<!-- loading加载框 -->
		<view v-if="loading" class="wyb-table-loading-box" :style="{
			'max-width': width === 'auto' ? screenWidth : width,
			'max-height': height === 'auto' ? '300rpx' : height,
			backgroundColor: loaderBgColor,
			borderTop: '1px solid' + borderColor,
			borderBottom: '1px solid' + borderColor,
			borderLeft: showLeftAndRightBorder ? '1px solid' + borderColor : 'none',
			borderRight: showLeftAndRightBorder ? '1px solid' + borderColor : 'none'}">
			<view class="loader-one" :style="{
				 width: loaderSize + 'rpx',
				 height: loaderSize + 'rpx',
				 borderTop: '3px solid ' + loadingColor.top,
				 borderRight: '3px solid ' + loadingColor.right,
				 borderBottom: '3px solid ' + loadingColor.bottom,
				 borderLeft: '3px solid ' + loadingColor.left}" />
		</view>
		<!-- table主体 -->
		<view v-if="!loading" class="wyb-table-scroll-view" :style="{
			'max-width': width,
			'max-height': height}">
			<!-- borderTop: '1px solid' + borderColor,
			borderLeft: showLeftAndRightBorder ? '1px solid' + borderColor : 'none',
			borderRight: showLeftAndRightBorder ? '1px solid' + borderColor : 'none' -->
			<view class="wyb-table-header" :style="{borderBottom: '1px solid' + borderColor}">
				<view class="wyb-table-header-item" v-if="enableCheck" :style="{
					 minWidth: checkColWidth + 'rpx',
					 maxWidth: checkColWidth + 'rpx',
					 minHeight: minHeight[0] + 'rpx',
					 textAlign: textAlign,
					 justifyContent: textAlign === 'center' ? textAlign : (textAlign === 'left' ? 'flex-start' : 'flex-end'),
					 fontSize: fontSize[0] + 'rpx',
					 color: headerFtColor,
					 padding: padding[0] + 'rpx ' + (padding[1] || padding[0]) + 'rpx',
					 backgroundColor: headerBgColor,
					 borderRight: '1px solid' + borderColor,
					 zIndex: 30,
					 left: 0, 
					 color: headerFtColor,
					 backgroundColor: headerBgColor,
					 position: 'sticky'}">
						<view 
						 class="wyb-table-checkbox"
						 v-if="enableCheck === 'multiple'"
						 @tap.stop="onCheckAllTap"
						 :style="{
							width: checkColWidth * 0.5 + 'rpx',
							height: checkColWidth * 0.5 + 'rpx',
							backgroundColor: checkerBoxBgColor,
							border: '1px solid ' + checkerBorderColor}">
							<text 
							 class="iconfont icon-check"
							 v-show="checkAll"
							 :style="{
								color: checkerColor,
								backgroundColor: checkerBgColor,
								paddingTop: (fontSize[1] || fontSize[0]) * 0.15 + 'rpx',
								fontSize: (fontSize[1] || fontSize[0]) + 'rpx'}" />
						</view>
					 </view>
				<view ref="iosBug" class="wyb-table-header-item" v-for="(item, index) in headers" :key="item.key" @tap="onHeaderItemTap(index)"
				 :style="{
					 minWidth: (item.width || defaultColWidth) + 'rpx',
					 maxWidth: (item.width || defaultColWidth) + 'rpx',
					 minHeight: minHeight[0] + 'rpx',
					 textAlign: textAlign,
					 justifyContent: textAlign === 'center' ? textAlign : (textAlign === 'left' ? 'flex-start' : 'flex-end'),
					 fontSize: fontSize[0] + 'rpx',
					 fontWeight: headerWeight ? 'bold' : 'normal',
					 color: headerFtColor,
					 padding: padding[0] + 'rpx ' + (padding[1] || padding[0]) + 'rpx',
					 backgroundColor: headerBgColor,
					 borderRight: index === headers.length - 1 || (!showVertBorder && index !== 0) ? 'none' : '1px solid' + borderColor,
					 zIndex: index === 0 ? 20 : 0,
					 left: index === 0 && firstLineFixed ? (enableCheck ? checkColWidth + 'rpx' : 0) : 'auto', 
					 position: index === 0 ? 'sticky' : 'static'}">
					 <text :style="{marginLeft: autoSortShow(index) && textAlign !== 'left' ? fontSize[0] * 0.65 + 'rpx' : 0}">
						 {{item.label || emptyString}}
					 </text>
					 <view class="wyb-table-header-icon" v-if="autoSortShow(index)">
					 	<text class="iconfont icon-arrow-up" :style="{
							color: sortWays[sortWay] === 'asc' && sortActiveKey === item.key ? 
								headerFtColor : RGBChange(headerFtColor, 0.7, 'light'),
							fontWeight: 'normal',
							marginBottom: '-12px',
							transform: 'scale(0.4)'}" />
					 	<text class="iconfont icon-arrow-down" :style="{
							color: sortWays[sortWay] === 'inv' && sortActiveKey === item.key ? 
								headerFtColor : RGBChange(headerFtColor, 0.7, 'light'),
							fontWeight: 'normal',
							transform: 'scale(0.4)'}" />
					 </view>
				</view>
			</view>
			<view class="wyb-table-content">
				<view class="wyb-table-content-line" :class="'wyb-table-content-line-'+ cIndex"
				  v-for="(content, cIndex) in contentsSort" :key="contentLineKey(content, cIndex)"
				 :style="{borderTop: cIndex === 0 ? 'none' : '1px solid' + borderColor}">
					<view class="wyb-table-content-item" v-if="enableCheck" :style="{
						 minWidth: checkColWidth + 'rpx',
						 maxWidth: checkColWidth + 'rpx',
						 textAlign: textAlign,
						 justifyContent: textAlign === 'center' ? textAlign : (textAlign === 'left' ? 'flex-start' : 'flex-end'),
						 fontSize: (fontSize[1] || fontSize[0]) + 'rpx',
						 minHeight: (minHeight[1] || minHeight[0]) + 'rpx',
						 padding: padding[0] + 'rpx ' + (padding[1] || padding[0]) + 'rpx',
						 borderRight: '1px solid' + borderColor,
						 zIndex: 21,
						 color: contentFtColor,
						 backgroundColor: checkerCellBgColor,
						 left: 0,
						 position: 'sticky'}">
							<view 
							 class="wyb-table-checkbox" 
							 @tap.stop="onCheckItemTap(cIndex)"
							 :style="{
								width: checkColWidth * 0.5 + 'rpx',
								height: checkColWidth * 0.5 + 'rpx',
								backgroundColor: checkerBoxBgColor,
								border: '1px solid ' + checkerBorderColor}">
								<text 
								 class="iconfont icon-check" 
								 v-show="contentsSort[cIndex].checked"
								 :style="{
									color: checkerColor,
									backgroundColor: checkerBgColor,
									paddingTop: (fontSize[1] || fontSize[0]) * 0.15 + 'rpx',
									fontSize: (fontSize[1] || fontSize[0]) + 'rpx'}" />
							</view>
						 </view>
					<view
					 class="wyb-table-content-item" 
					 v-for="(header, hIndex) in headers"
					 @tap.stop="onContentItemTap(cIndex, hIndex)"
					 :key="contentItemKey(header, hIndex)" 
					 :style="{
						 minWidth: (header.width || defaultColWidth) + 'rpx',
						 maxWidth: (header.width || defaultColWidth) + 'rpx',
						 textAlign: textAlign,
						 justifyContent: textAlign === 'center' ? textAlign : (textAlign === 'left' ? 'flex-start' : 'flex-end'),
						 fontSize: (fontSize[1] || fontSize[0]) + 'rpx',
						 textDecoration: autoTextDecoration(cIndex, hIndex),
						 color: autoContentColor(cIndex, hIndex),
						 backgroundColor: content.disabled ? '#ecf0f1' : autoContentBgColor(cIndex, hIndex),
						 padding: padding[0] + 'rpx ' + (padding[1] || padding[0]) + 'rpx',
						 borderBottom: cIndex === contents.length - 1 ? '1px solid' + borderColor : 'none',
						 borderRight: hIndex === headers.length - 1 || (!showVertBorder && hIndex !== 0) ? 'none' : '1px solid' + borderColor,
						 zIndex: hIndex === 0 ? 20 : 0,
						 left: enableCheck ? checkColWidth + 'rpx' : 0,
						 position: hIndex === 0 && firstLineFixed ? 'sticky' : 'static',
						 ...content.searchStyle }">
						<input class="lf-w-100" placeholder="请输入.." 
							:disabled="content.disabled || false"
							v-if="isObject(autoContentItem(cIndex, hIndex), 'edit')" 
							:style="{minHeight: (minHeight[1] || minHeight[0]) + 'rpx'}"
							placeholder-style="font-size: 30rpx"
							:type="autoContentItem(cIndex, hIndex).type || 'number'"
							@blur="inputBlur(cIndex, hIndex, $event)" 
							:value="autoContentItem(cIndex, hIndex).value" />
						<button class="diy-btn" v-else-if="isObject(autoContentItem(cIndex, hIndex), 'button')" @click="buttonClick(cIndex, hIndex)">{{ autoContentItem(cIndex, hIndex).value }}</button>
						<view class="lf-w-100 lf-h-100 lf-row-center" v-else :style="{minHeight: (minHeight[1] || minHeight[0]) + 'rpx', 'word-break': 'break-all'}">{{ autoContentItem(cIndex, hIndex) }}</view>
					</view>
				</view>
				<view v-if="computedCol.length !== 0" class="wyb-table-content-line" :style="{
					position: bottomComputedFixed ? 'sticky' : 'static',
					bottom: 0,
					zIndex: 25,
					borderTop: '1px solid' + borderColor}">
					<view class="wyb-table-content-item" v-if="enableCheck" :style="{
						 minWidth: checkColWidth + 'rpx',
						 maxWidth: checkColWidth + 'rpx',
						 textAlign: textAlign,
						 justifyContent: textAlign === 'center' ? textAlign : (textAlign === 'left' ? 'flex-start' : 'flex-end'),
						 fontSize: (fontSize[1] || fontSize[0]) + 'rpx',
						 minHeight: (minHeight[1] || minHeight[0]) + 'rpx',
						 padding: padding[0] + 'rpx ' + (padding[1] || padding[0]) + 'rpx',
						 borderBottom: '1px solid' + borderColor,
						 borderRight: '1px solid' + borderColor,
						 zIndex: 25,
						 color: contentFtColor,
						 backgroundColor: checkerCellBgColor,
						 left: 0,
						 position: 'sticky'}"></view>
					<view class="wyb-table-content-item" v-for="(header, index) in headers" :key="index"
					:style="{
						 minWidth: (header.width || defaultColWidth) + 'rpx',
						 maxWidth: (header.width || defaultColWidth) + 'rpx',
						 textAlign: textAlign,
						 justifyContent: textAlign === 'center' ? textAlign : (textAlign === 'left' ? 'flex-start' : 'flex-end'),
						 fontSize: (fontSize[1] || fontSize[0]) + 'rpx',
						 color: contentFtColor,
						 minHeight: (minHeight[1] || minHeight[0]) + 'rpx',
						 padding: padding[0] + 'rpx ' + (padding[1] || padding[0]) + 'rpx',
						 backgroundColor: index === 0 ? firstColBgColor : contentBgColor,
						 borderBottom: '1px solid' + borderColor,
						 borderRight: index === headers.length - 1 || (!showVertBorder && index !== 0) ? 'none' : '1px solid' + borderColor,
						 zIndex: index === 0 ? 20 : 0,
						 left: enableCheck ? checkColWidth + 'rpx' : 0,
						 position: index === 0 && firstLineFixed ? 'sticky' : 'static'}">
						{{autoBottomComputedItem(index)}}
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import Pinyin from './js/characterToPinyin.js'
	import {isEqual} from './js/objEqual.js'
	let timer = null;
	export default {
		data() {
			return {
				bottomComputed: [],
				colorList: [],
				bgColorList: [],
				contentsSort: this.contents.slice(),
				oContentsSort: [],
				sortWay: 0,
				sortKeys: [],
				sortActiveKey: '',
				sortIsNumbers: [],
				checkAll: false,
				checkList: [],
				onload: true,
				event: {
					checkType: this.enableCheck,
					data: []
				},
				chars: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
			}
		},
		computed: {
			// 加载颜色
			loadingColor() {
				let color = this.loaderColor.slice()
				let rgbList = this.hexToRgb(color)
				let top = 'rgba(' + rgbList[0] + ',' + rgbList[1] + ',' + rgbList[2] + ', 0.3)'
				let bottom = 'rgba(' + rgbList[0] + ',' + rgbList[1] + ',' + rgbList[2] + ', 0.3)'
				let right = 'rgba(' + rgbList[0] + ',' + rgbList[1] + ',' + rgbList[2] + ', 0.3)'
				let left = 'rgb(' + rgbList[0] + ',' + rgbList[1] + ',' + rgbList[2] + ')'
				return {
					top,
					bottom,
					right,
					left
				}
			},
			// content每一项key值
			contentLineKey() {
				return function(content, cIndex) {
					return this.randomString(32, this.chars)
				} 
			},
			// 自动分配单元格内容key值
			contentItemKey() {
				return function(header, hIndex) {
					return this.randomString(16, this.chars);
				}
			},
			// 获取表格内容，每一个格子
			autoContentItem() {
				return function(cIndex, hIndex) {
					let content = this.contentsSort[cIndex]
					let header = this.headers[hIndex]
					let result = ''
					if (content[header.key] || content[header.key] === 0) {
						result = content[header.key]
						if (this.urlCol.length !== 0) {
							for (let i in this.urlCol) {
								let item = this.urlCol[i]
								if (header.key === item.key) {
									// 该单元格为链接
									result = content[header.key][0]
								}
							}
						}
						if (this.formatCol.length !== 0) {
							this.formatCol.forEach(item => {
								if (header.key === item.key) {
									let needRplace = new RegExp(`\#${item['key']}\#`, 'mg')
									result = item.template.replace(needRplace, result)
								}
							})
						}
						
					} else {
						result = this.emptyString
					}
					return result
				}
			},
			autoBottomComputedItem() {
				return function(index) {
					let bottomComputed = {}
					let needComputed = []
					this.computedCol.forEach(key => {
						let computedColData = []
						this.contentsSort.forEach(content => {
							computedColData.push(content[key] || '0')
						})
						needComputed.push(computedColData)
					})
					needComputed.forEach((item, index) => {
						let total = 0
						item.forEach(num => {
							total += parseFloat(num)
						})
						bottomComputed[this.computedCol[index]] = total
					})
					let header = this.headers[index]
					let result = this.computedCol.includes(header.key) ? 
						bottomComputed[header.key] : (index === 0 ? '总计' : this.emptyString)
					if (this.formatCol.length !== 0) {
						this.formatCol.forEach(item => {
							if (item.bottomComputedFormat) {
								if (header.key === item.key) {
									let needRplace = new RegExp(`\#${item['key']}\#`, 'mg')
									result = item.template.replace(needRplace, bottomComputed[item.key])
								}
							}
						})
					}
					return result
				}
			},
			// 判断单元格为链接，显示文字下划线
			autoTextDecoration() {
				return function(cIndex, hIndex) {
					let result = 'auto'
					let content = this.contentsSort[cIndex]
					let header = this.headers[hIndex]
					if (this.urlCol.length !== 0) {
						for (let i in this.urlCol) {
							let item = this.urlCol[i]
							if (header.key === item.key) {
								// 该单元格为链接
								if (content[header.key]) {
									result = 'underline'
								}
							}
						}
					}
					return result
				}
			},
			// 分配表格内容背景颜色
			autoContentBgColor() {
				return function(cIndex, hIndex) {
					let result = this.contentBgColor
					let content = this.contentsSort[cIndex]
					let header = this.headers[hIndex]
					let keys = []
					// 先判断是不是首列，设置基础样式
					if (hIndex === 0) {
						result = this.firstColBgColor
					}
					// 再判断条件格式传没传值，设置条件样式
					if (this.valueFormat.length !== 0) {
						this.valueFormat.forEach(item => {
							keys.push(item.key)
						})
						if (keys.includes(header.key)) {
							// 该列开启了条件格式
							let key = header.key
							let type = this.valueFormat[keys.indexOf(key)].type
							let style = this.valueFormat[keys.indexOf(key)].style
							let range = this.valueFormat[keys.indexOf(key)].range || ''
							switch(type) {
								case 'bigger':
									if (parseFloat(content[key]) > range) {
										if (style.bgColor) result = style.bgColor
									}
									break
								case 'smaller':
									if (parseFloat(content[key]) < range) {
										if (style.bgColor) result = style.bgColor
									}
									break
								case 'equal':
									let val
									if (typeof range === 'number') val = parseFloat(content[key])
									else val = content[key]
									if (val === range) {
										if (style.bgColor) result = style.bgColor
									}
									break
								case 'range':
									if (parseFloat(content[key]) > range[0] && parseFloat(content[key]) < range[1]){
										if (style.bgColor) result = style.bgColor
									}
									break
								case 'average-bigger':
									let average = this.getAverage(key)
									if (parseFloat(content[key]) > average) {
										if (style.bgColor) result = style.bgColor
									}
									break
								case 'average-smaller':
									average = this.getAverage(key)
									if (parseFloat(content[key]) < average) {
										if (style.bgColor) result = style.bgColor
									}
									break
								case 'average-equal':
									average = this.getAverage(key)
									if (parseFloat(content[key]) === average) {
										if (style.bgColor) result = style.bgColor
									}
									break
							}
						}
					}
					// console.log("=====", content[header.key]);
					
					// return result
					if(this.isObject(content[header.key], 'edit')){
						return this.$props.contentBgColor;
					}else{
						return '#fff';
					}
				}
			},
			// 分配表格内容字体颜色
			autoContentColor() {
				return function(cIndex, hIndex) {
					let result = this.contentFtColor
					let content = this.contentsSort[cIndex]
					let header = this.headers[hIndex]
					let keys = []
					// 先判断是不是链接，设置基础样式
					if (this.urlCol.length !== 0) {
						for (let i in this.urlCol) {
							let item = this.urlCol[i]
							if (header.key === item.key) {
								// 该单元格为链接
								if (content[header.key]) {
									result = this.linkColor
								}
							}
						}
					}
					// 再判断条件格式传没传值，设置条件样式
					if (this.valueFormat.length !== 0) {
						this.valueFormat.forEach(item => {
							keys.push(item.key)
						})
						if (keys.includes(header.key)) {
							// 该列开启了条件格式
							let key = header.key
							let type = this.valueFormat[keys.indexOf(key)].type
							let style = this.valueFormat[keys.indexOf(key)].style
							let range = this.valueFormat[keys.indexOf(key)].range || ''
							switch(type) {
								case 'bigger':
									if (parseFloat(content[key]) > range) {
										if (style.color) result = style.color
									}
									break
								case 'smaller':
									if (parseFloat(content[key]) < range) {
										if (style.color) result = style.color
									}
									break
								case 'equal':
									let val
									if (typeof range === 'number') val = parseFloat(content[key])
									else val = content[key]
									if (val === range) {
										if (style.color) result = style.color
									}
									break
								case 'range':
									if (parseFloat(content[key]) > range[0] && parseFloat(content[key]) < range[1]){
										if (style.color) result = style.color
									}
									break
								case 'average-bigger':
									let average = this.getAverage(key)
									if (parseFloat(content[key]) > average) {
										if (style.color) result = style.color
									}
									break
								case 'average-smaller':
									average = this.getAverage(key)
									if (parseFloat(content[key]) < average) {
										if (style.color) result = style.color
									}
									break
								case 'average-equal':
									average = this.getAverage(key)
									if (parseFloat(content[key]) === average) {
										if (style.color) result = style.color
									}
									break
							}
						}
					}
					return result
				}
			},
			// 显示筛选排序
			autoSortShow() {
				return function(hIndex) {
					let result = false
					let header = this.headers[hIndex]
					let keys = []
					// 判断排序是否传值
					if (this.sortCol.length !== 0 && this.sortKeys.length === 0) {
						this.sortCol.forEach(item => {
							keys.push(item.key)
						})
						this.sortKeys = keys
						if (keys.includes(header.key)) {
							result = true
						}
					} else if (this.sortCol.length !== 0) {
						if (this.sortKeys.includes(header.key)) {
							result = true
						}
					}
					return result
				}
			},
			// 获取屏幕可用宽度
			screenWidth() {
				return `${uni.getSystemInfoSync()['screenWidth']}px`
			}
		},
		props: {
			headers: {
				type: Array,
				default() {
					return [{
						key: 'name',
						label: '姓名'
					},{
						key: 'age',
						label: '年龄'
					},{
						key: 'sex',
						label: '性别'
					},{
						key: 'height',
						label: '身高'
					},{
						key: 'info',
						label: '描述'
					},{
						key: 'operation',
						label: '操作'
					}]
				}
			},
			contents: {
				type: Array,
				default() {
					return [{
						name: '张三',
						age: '18',
						sex: '男',
						height: '192cm',
						info: '无敌叫是',
						operation: {button: true, key: 'delete', value: '删除'}
					}, {
						name: '李四',
						age: '18',
						sex: '男',
						height: '192cm',
						info: '无敌叫是'
					}, {
						name: '赵五',
						age: '18',
						sex: '男',
						height: '192cm',
						info: '无敌叫是'
					}]
				}
			},
			emptyString: {
				type: String,
				default: '-'
			},
			width: {
				type: String,
				default: `${uni.getSystemInfoSync().screenWidth}px`
			},
			height: {
				type: String,
				default: 'auto'
			},
			fontSize: {
				type: Array,
				default() {
					return [30]
				}
			},
			defaultColWidth: {
				type: Number,
				default: 165
			},
			headerWeight: {
				type: Boolean,
				default: true
			},
			minHeight: {
				type: Array,
				default() {
					return [70]
				}
			},
			headerBgColor: {
				type: String,
				default: '#fff'
			},
			contentBgColor: {
				type: String,
				default: '#fff'
			},
			headerFtColor: {
				type: String,
				default: '#3e3e3e'
			},
			contentFtColor: {
				type: String,
				default: '#3e3e3e'
			},
			linkColor: {
				type: String,
				default: '#0024c8'
			},
			firstColBgColor: {
				type: String,
				default: '#f1f1f1'
			},
			firstLineFixed: {
				type: Boolean,
				default: false
			},
			textAlign: {
				type: String,
				default: 'center'
			},
			padding: {
				type: Array,
				default() {
					return [5, 10]
				}
			},
			borderColor: {
				type: String,
				default: '#e1e1e1'
			},
			urlCol: {
				type: Array,
				default() {
					return []
				}
			},
			computedCol: {
				type: Array,
				default() {
					return []
				}
			},
			bottomComputedFixed: {
				type: Boolean,
				default: true
			},
			valueFormat: {
				type: Array,
				default() {
					return []
				}
			},
			formatCol: {
				type: Array,
				default() {
					return []
				}
			},
			showLeftAndRightBorder: {
				type: Boolean,
				default: false
			},
			showVertBorder: {
				type: Boolean,
				default: true
			},
			sortCol: {
				type: Array,
				default() {
					return []
				}
			},
			sortWays: {
				type: Array,
				default() {
					return ['none', 'asc', 'inv']
				}
			},
			loading: {
				type: Boolean,
				default: false
			},
			loaderSize: {
				type: [String, Number],
				default: 50
			},
			loaderColor: {
				type: String,
				default: '#a3a3a3'
			},
			loaderBgColor: {
				type: String,
				default: '#f8f8f8'
			},
			enableCheck: {
				type: String,
				default: ''
			},
			checkColWidth: {
				type: [String, Number],
				default: '70'
			},
			checkerColor: {
				type: String,
				default: '#3e3e3e'
			},
			checkerBorderColor: {
				type: String,
				default: '#d3d3d3'
			},
			checkerBgColor: {
				type: String,
				default: 'rgba(0, 0, 0, 0)'
			},
			checkerBoxBgColor: {
				type: String,
				default: 'rgba(0, 0, 0, 0)'
			},
			checkerCellBgColor: {
				type: String,
				default: '#f1f1f1'
			},
			scrollToInput: {
				type: Boolean, // 是否自动滚动到含有input的位置
				default: false
			},
			searchKey: {
				type: String,
				default: '' // 表格搜索内容
			}
		},
		watch: {
			headers(val) {
				this.$forceUpdate()
			},
			contents(val) {
				this.contentsSort = val.slice()
				if (this.onload) {
					this.contentsSort.forEach(item => {
						this.$set(item, 'checked', false)
					})
					this.oContentsSort = this.contentsSort.slice()
					this.onload = false
				}
				this.$forceUpdate()
			},
			searchKey(val){
				console.log("搜索：", val);
				let positionIndex = null;
				// 处理被模糊匹配的item背景颜色变化
				this.contentsSort.map((c_item, c_index) => {
					this.$set(c_item, 'searchStyle', {});
					this.headers.map(h_item => {
						if(h_item.search){
							let contentLine = c_item[h_item.key];
							if(val && contentLine.indexOf(val) >= 0){
								if(positionIndex == null){
									positionIndex = c_index; // 拿到第一个被匹配的table item
								}
								this.$set(c_item, 'searchStyle', {backgroundColor: '#ffdede'});
							}
						}
					})
				})
				// 处理匹配到item时滚动至第一个item
				if(positionIndex != null){
					let tabView = document.querySelector('.wyb-table-scroll-view'); // 获取第一层大对象，table
					let tabContent = tabView.querySelector('.wyb-table-content'); // 获取第二层，table的content部分
					let contentLine = tabContent.querySelector('.wyb-table-content-line-'+ positionIndex); // 获取第三层，获取内容列
					let tabViewTop = tabView.offsetTop; // table距离页面高度
					let offsetHeight = contentLine.offsetHeight; // table行高度
					let offsetTop = contentLine.offsetTop; // table行距离页面高度
					tabView.scrollTop = offsetTop - tabViewTop - offsetHeight;
				}else if(val){
					this.$msg('该关键字没有搜索到物资哦')
				}
			}
		},
		mounted() {
			this.contentsSort.forEach(item => {
				this.$set(item, 'checked', false)
			})
			this.oContentsSort = this.contentsSort.slice()
			if (this.sortCol.length !== 0) {
				this.sortActiveKey = this.sortCol[0].key
				uni.setStorageSync('lastSortActiveKey', this.sortActiveKey)
				this.doSort(this.sortCol[0].key, this.sortWays[this.sortWay], this.sortCol[0].isNumber)
			}
			this.autoScrollView();
		},
		methods: {
			// 页面初次加载，判断是否自动滚动至input输入框所在的位置
			autoScrollView(){
				try{
					// #ifdef H5
					if(this.$props.scrollToInput){
						setTimeout(function(){
							//  完整选取dom .wyb-table-scroll-view .wyb-table-content .wyb-table-content-line .wyb-table-content-item input
							let tabView = document.querySelector('.wyb-table-scroll-view'); // 获取第一层大对象，table
							let tabContent = tabView.querySelector('.wyb-table-content'); // 获取第二层，table的content部分
							let contentLine = tabContent.querySelector('.wyb-table-content-line'); // 获取第三层，获取内容列
							let contentItem = contentLine.querySelector('.wyb-table-content-item input'); // 获取第四层，内容单元格
							let offsetWidth = contentItem.offsetParent.offsetWidth;
							let offsetLeft = contentItem.offsetParent.offsetLeft - offsetWidth - 20;
							timer = setInterval(function(){
								tabView.scrollLeft += 2;
								if(tabView.scrollLeft >= offsetLeft){
									clearInterval(timer);
								}
							}, 2);
						}, 1000)
					}
					// #endif
				}catch(e){
					console.log(e);
				}
			},
			inputBlur(cIndex, hIndex, event){
				let event_obj = {};
				let value = event.detail.value;
				let content = this.contentsSort[cIndex];
				let header = this.headers[hIndex];
				
				if(content[header.key]){
					event_obj = {
						content: content[header.key],
						contentIndex: cIndex,
						header: header.label,
						headerIndex: hIndex,
						key: header.key,
						lineData: content,
						detailValue: value
					}
					this.$emit('onInputChange', event_obj);
				}
			},
			buttonClick(cIndex, hIndex){
				let event_obj = {};
				let content = this.contentsSort[cIndex];
				let header = this.headers[hIndex];
				
				if(content[header.key]){
					event_obj = {
						content: content[header.key],
						contentIndex: cIndex,
						header: header.label,
						headerIndex: hIndex,
						key: header.key,
						lineData: content
					}
					this.$emit('onButtonClick', event_obj);
				}
			},
			isObject(val, key){
			   return this.$shared.isValueType(val) == 'object' && val[key];
			},
			doSort(key, type, isNumber) {
				let arr = this.contentsSort
				if (type === 'asc') {
					// 升序
					if (isNumber) {
						arr.sort((a, b) => {
						    return (parseFloat(a[key].toString().replace(/[^0-9]/ig, "")) || 0) - 
								(parseFloat(b[key].toString().replace(/[^0-9]/ig, "")) || 0)
						})
					} else {
						arr.sort((a, b) => {
							let A = Pinyin.getSpell(a[key].charAt(0), function(charactor, spell) {
								return spell[1]
							}).charAt(0).charCodeAt()
							let B = Pinyin.getSpell(b[key].charAt(0), function(charactor, spell) {
								return spell[1]
							}).charAt(0).charCodeAt()
							return A - B
						})
					}
					
				} else if (type === 'inv') {
					// 倒序
					if (isNumber) {
						arr.sort((a, b) => {
						    return (parseFloat(b[key].toString().replace(/[^0-9]/ig, "")) || 0) - 
								(parseFloat(a[key].toString().replace(/[^0-9]/ig, "")) || 0)
						})
					} else {
						arr.sort((a, b) => {
							let A = Pinyin.getSpell(a[key].charAt(0), function(charactor, spell) {
								return spell[1]
							}).charAt(0).charCodeAt()
							let B = Pinyin.getSpell(b[key].charAt(0), function(charactor, spell) {
								return spell[1]
							}).charAt(0).charCodeAt()
							return B - A
						})
					} 
				} else {
					this.contentsSort = this.oContentsSort.slice()
				}
				if (this.enableCheck) {
					this.event.data.forEach(item => {
						this.contentsSort.forEach((content, index) => {
							if (isEqual(item.lineData, content)) {
								item.index = index
							}
						})
					})
				}
				this.$forceUpdate()
			},
			initBottomComputed() {
				let result = {}
				let needComputed = []
				this.computedCol.forEach(key => {
					let computedColData = []
					this.contentsSort.forEach(content => {
						computedColData.push(content[key] || '0')
					})
					needComputed.push(computedColData)
				})
				needComputed.forEach((item, index) => {
					let total = 0
					item.forEach(num => {
						total += parseFloat(num)
					})
					result[this.computedCol[index]] = total
				})
				this.bottomComputed = result
			},
			onHeaderItemTap(index) {
				let header = this.headers[index]
				const lastSortActiveKey = uni.getStorageSync('lastSortActiveKey') || ''
				if (this.sortCol.length !== 0) {
					if (this.sortKeys.includes(header.key)) {
						// 当前列开启了排序
						this.sortActiveKey = header.key
						uni.setStorageSync('lastSortActiveKey', this.sortActiveKey)
						if (this.sortWay < 2 && lastSortActiveKey === this.sortActiveKey) {
							this.sortWay++
						} else if (lastSortActiveKey !== this.sortActiveKey) {
							this.sortWay = 1
						} else if (this.sortWay >= 2) {
							this.sortWay = 0
						}
						let isNumber = this.sortCol[this.sortKeys.indexOf(header.key)].isNumber
						this.doSort(header.key, this.sortWays[this.sortWay], isNumber)
					}
				}
			},
			onContentItemTap(cIndex, hIndex) {
				let event = {}
				let content = this.contentsSort[cIndex]
				let header = this.headers[hIndex]
				let keys = []
				
				if (this.urlCol.length !== 0) {
					for (let i in this.urlCol) {
						let item = this.urlCol[i]
						keys.push(item.key)
					}
				}
				
				if (content && content[header.key]) {
					if (keys.includes(header.key)) {
						// 该单元格为链接
						switch(this.urlCol[keys.indexOf(header.key)].type) {
							case 'route':
								let url = content[header.key][1]
								if (content[header.key][2]) {
									url = `${url}?`
									Object.keys(content[header.key][2]).forEach(key => {
										url += `&${key}=${content[header['key']][2][key]}`
									})
								}
								uni.navigateTo({url})
								break
							case 'http':
								this.openURL(content[header.key][1])
								break
						}
					} else {
						event = {
							content: content[header.key],
							contentIndex: cIndex,
							header: header.label,
							headerIndex: hIndex,
							key: header.key,
							lineData: content
						}
						this.$emit('onCellClick', event)
					}
					
				} else {
					event = {
						content: '',
						contentIndex: cIndex,
						header: header.label,
						headerIndex: hIndex,
						key: header.key,
						lineData: content
					}
					if (keys.includes(header.key)) {
						// 该单元格为链接
						event['isLink'] = true
					}
					this.$emit('onCellClick', event)
				}
				
			},
			onCheckAllTap() {
				if (this.enableCheck === 'multiple') {
					let checkList = []
					this.contentsSort.forEach(item => {
						checkList.push(item.checked)
					})
					this.checkList = checkList
					if (!this.checkAll) {
						this.checkAll = true
						this.contentsSort.forEach(item => {
							item.checked = true
						})
						this.event.data = []
						this.contentsSort.forEach((content, index) => {
							this.event.data.push({
								index,
								lineData: content
							})
						})
						
					} else {
						this.checkAll = false
						this.event.data = []
						this.contentsSort.forEach(item => {
							item.checked = false
						})
					}
					this.$emit('onCheck', this.event)
				}
			},
			onCheckItemTap(cIndex) {
				let content = this.contentsSort[cIndex]
				if (this.enableCheck === 'single') {
					this.contentsSort.forEach((item, index) => {
						if (cIndex === index) {
							item.checked = !item.checked
						} else {
							item.checked = false
						}
					})
				} else if (this.enableCheck === 'multiple') {
					this.contentsSort[cIndex]['checked'] = !this.contentsSort[cIndex]['checked']
				}
				if (this.contentsSort[cIndex]['checked']) {
					if (this.enableCheck === 'single') {
						this.event.data = []
					}
					this.event.data.push({
						index: cIndex,
						lineData: this.contentsSort[cIndex]
					})
				} else {
					this.event.data.forEach(item => {
						if (item.index === cIndex) this.event.data.splice(this.event.data.indexOf(item), 1)
					})
					if (this.event.data.length === 0) {
						this.checkAll = false
					}
				}
				this.$forceUpdate()
				this.$emit('onCheck', this.event)
			},
			openURL(href) {
				// #ifdef APP-PLUS
				plus.runtime.openURL(href)
				// #endif
				// #ifdef H5
				window.open(href)
				// #endif
				// #ifdef MP
				uni.setClipboardData({
					data: href,
					success() {
						uni.showToast({
							title: '网址已复制，请在手机浏览器里粘贴该网址',
							icon: 'none'
						})
					}
				})
				// #endif
			},
			getAverage(key) {
				let numList = []
				this.contentsSort.forEach(content => {
					numList.push(parseFloat(content[key]) || 0)
				})
				return numList.reduce((a, b) => a + b) / numList.length
			},
			getTotal(key) {
				let numList = []
				this.contentsSort.forEach(content => {
					numList.push(parseFloat(content[key]) || 0)
				})
				return numList.reduce((a, b) => a + b)
			},
			RGBChange(color, level, type) {
				// 判断颜色类型
				let r = 0,
					g = 0,
					b = 0,
					hasAlpha = false,
					alpha = 1
				if (color.indexOf('#') !== -1) {
					// hex转rgb
					if (color.length === 4) {
						let arr = color.split('')
						color = '#' + arr[1] + arr[1] + arr[2] + arr[2] + arr[3] + arr[3]
					}
					let color16List = [color.substring(1, 3), color.substring(3, 5), color.substring(5, 7)]
					r = parseInt(color16List[0], 16)
					g = parseInt(color16List[1], 16)
					b = parseInt(color16List[2], 16)
			
				} else {
					hasAlpha = color.indexOf('a') !== -1
					let root = color.slice()
					let idx = root.indexOf('(') + 1
					root = root.substring(idx)
					let firstDotIdx = root.indexOf(',')
					r = parseFloat(root.substring(0, firstDotIdx))
					root = root.substring(firstDotIdx + 1)
					let secondDotIdx = root.indexOf(',')
					g = parseFloat(root.substring(0, secondDotIdx))
					root = root.substring(secondDotIdx + 1)
					if (hasAlpha) {
						let thirdDotIdx = root.indexOf(',')
						b = parseFloat(root.substring(0, thirdDotIdx))
						alpha = parseFloat(root.substring(thirdDotIdx + 1))
					} else {
						b = parseFloat(root)
					}
				}
			
				let rgbc = [r, g, b]
				// 减淡或加深
				for (var i = 0; i < 3; i++)
					type === 'light' ? rgbc[i] = Math.floor((255 - rgbc[i]) * level + rgbc[i]) : rgbc[i] = Math.floor(rgbc[i] * (1 -
						level))
			
				if (hasAlpha) {
					return `rgba(${rgbc[0]}, ${rgbc[1]}, ${rgbc[2]}, ${alpha})`
				} else {
					return `rgb(${rgbc[0]}, ${rgbc[1]}, ${rgbc[2]})`
				}
			},
			hexToRgb(color) {
				if (color.length === 4) {
					let arr = color.split('')
					color = '#' + arr[1] + arr[1] + arr[2] + arr[2] + arr[3] + arr[3]
				}
				let color16List = [color.substring(1, 3), color.substring(3, 5), color.substring(5, 7)]
				let r = parseInt(color16List[0], 16)
				let g = parseInt(color16List[1], 16)
				let b = parseInt(color16List[2], 16)
				return [r, g, b]
			},
			randomString(length, chars) {
			    var result = ''
			    for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)]
			    return result
			}
		},
		destroyed(){
			if(timer){
				clearInterval(timer);
				timer = null;
			}
		}
	}
</script>

<style>
	@import './css/iconfont.css';
	@import './css/loader.css';
	.ios-header-bug {
		height: 0;
		width: 1px;
		opacity: 0;
	}
	
	.wyb-table-scroll-view {
		overflow: scroll;
		-webkit-overflow-scrolling: touch;
		border: 2rpx solid #e5e5e5;
	}
	
	.wyb-table-scroll-view::-webkit-scrollbar {
		display: none;
		/* #ifdef MP-WEIXIN */
		width: 0;
		height: 0;
		/* #endif */
	}
	
	.wyb-table-loading-box {
		display: flex;
		align-items: center;
		justify-content: center;
		z-index: 500;
	}
	
	.wyb-table-header {
		position: sticky;
		top: 0;
		display: grid;
		grid-auto-flow: column;
		width: max-content;
		z-index: 25;
	}
	
	.wyb-table-header-item {
		flex: 1;
		display: flex;
		align-items: center;
		box-sizing: border-box;
		position: relative;
	}
	
	.wyb-table-header-icon {
		display: flex;
		flex-direction: column;
	}
	
	.wyb-table-content-line {
		display: grid;
		grid-auto-flow: column;
		width: max-content;
		position: relative;
	}
	
	.wyb-table-content-item {
		display: flex;
		flex-direction: row;
		align-items: center;
		box-sizing: border-box;
	}
	
	.wyb-table-checkbox {
		border-radius: 3px;
		display: flex;
		align-items: center;
		justify-content: center;
		position: relative;
	}
	
	.icon-check {
		width: 100%;
		height: 100%;
		position: absolute;
		border-radius: 0;
		border-radius: 3px;
		font-weight: bold;
		box-sizing: border-box;
		transform: scale(1.1);
	}
	
	.diy-btn{
		background-color: transparent;
		color: #FF3838;
		height: max-content;
		line-height: initial;
		font-size: 28rpx;
	}
</style>
