<template>
	<view class="z-table">
		<view class="z-table-main" :style="[{ 'background-color': this.tempbackgroundColor }, { color: this.temptextColor }, { height: tableHeight + 'px' }]">
			<view v-if="!tableLoaded && (!tableData || !columns)" :class="['z-loading', { ztableLoading: tableShow }]"><view class="z-loading-animate"></view></view>
			<!-- 查询过滤器 -->
			<view v-if="tbName.length > 0 || searchBox" class="pagination" :style="[{ 'border-bottom': '1rpx solid ' + templineColor }]">
				<uni-lr-row :layout="searchBoxTW" style="height: 100%;width: 100%;padding:0">
					<uni-input-row
						slot="left"
						v-if="tbName.length > 0 || searchBox"
						type="hint"
						:inputBorder="false"
						v-model="tbName"
						style="height: 100%;"
						:after="false"
						:hintIcons="false"
						inputIcon="info"
						:placeholderColor="temptitleColor"
						:alignment="titleAlignment"
						:iconColor="tempiconColor"
						:readonlyColor="tempbackgroundColor"
						:showButton="searchBox"
						buttonIcon="search"
						@buttonClick="buttonClick"
					></uni-input-row>
					<uni-lr-row v-if="searchBox" slot="right" :layout="40" style="height: 100%;width: 100%;">
						<uni-input-row
							slot="left"
							type="combox"
							rowHeight="100%"
							:after="false"
							:inputBorder="false"
							:textColor="temptextColor"
							:iconColor="tempiconColor"
							:defaultColor="tempbackgroundColor"
							:selectorColor="tempbackgroundColor"
							:verify="true"
							:clearable="true"
							v-model="searchCol"
							:range="searchColData"
							rangeKey="field"
							rangeVal="title"
							placeholder="列名"
						></uni-input-row>
						<uni-input-row
							slot="right"
							type="text"
							rowHeight="100%"
							:after="false"
							:inputBorder="false"
							:textColor="temptextColor"
							:iconColor="tempiconColor"
							:defaultColor="tempbackgroundColor"
							:buttonColor="tempbuttonColor"
							clearable
							showButton
							btConfirm
							buttonIcon="search"
							v-model="searchVal"
							@clear="onSearchClear"
							@confirm="onSearch($event)"
							placeholder="搜索内容"
						></uni-input-row>
					</uni-lr-row>
				</uni-lr-row>
			</view>

			<!-- 表格内容 -->
			<!-- "{ height:  (searchBox || tbName.length > 0 ? 0 : 10) + (pagination ? 0 : 10) + 80 + '%' }" -->
			<scroll-view scroll-y="true" scroll-x="true" :style="tbHeight">
				<view class="z-table-pack" :style="[{ 'background-color': tempbackgroundColor }, { color: temptextColor }]">
					<!-- 行头部 -->
					<view class="z-table-title" :style="[{ 'border-right': '1rpx solid ' + templineColor }, { 'border-bottom': '1rpx solid ' + templineColor }]">
						<!-- 添加行编号 -->
						<view
							v-if="rowNumbers"
							:class="['z-table-title-item', { 'z-table-stick-side': fixedSelectBox }]"
							:style="[
								{ 'border-left': '1rpx solid ' + templineColor },
								{ 'border-right': '1rpx solid ' + (showSelect ? 'rgb(0, 0, 0, 0)' : templineColor) },
								{ 'border-top': '1rpx solid ' + templineColor },
								{ width: rowNW + 'rpx' },
								{ 'background-color': tempbackgroundColor },
								{ color: temptextColor }
							]"
						>
							<view class="z-table-col-text text-center">
								<view v-if="rowCount">{{ tableData.length }}</view>
							</view>
						</view>
						<!-- 单选图片显示 -->
						<view
							v-if="showSelect && singleSelect"
							:class="['z-table-title-item', { 'z-table-stick-side': fixedSelectBox }]"
							:style="[
								{ 'border-left': '1rpx solid ' + templineColor },
								{ 'border-right': '1rpx solid ' + templineColor },
								{ 'border-top': '1rpx solid ' + templineColor },
								{ left: rowNumbers ? rowNW + 'rpx' : '0' },
								{ width: showSW + 'rpx' },
								{ 'background-color': tempbackgroundColor },
								{ color: temptextColor }
							]"
						>
							<uni-icons :color="tempiconColor" type="circle-filled" size="18"></uni-icons>
						</view>
						<!-- 多选复选框显示 -->
						<view
							v-if="showSelect && !singleSelect"
							:class="['z-table-title-item', { 'z-table-stick-side': fixedSelectBox }]"
							:style="[
								{ 'border-left': '1rpx solid ' + templineColor },
								{ 'border-right': '1rpx solid ' + templineColor },
								{ 'border-top': '1rpx solid ' + templineColor },
								{ left: rowNumbers ? rowNW + 'rpx' : '0' },
								{ width: showSW + 'rpx' },
								{ 'background-color': tempbackgroundColor },
								{ color: temptextColor }
							]"
						>
							<view class="select-box" @click="doSelect(true)"><view :class="['select-tip', { selected: selectAll }]"></view></view>
						</view>
						<!-- 列集合遍历 -->
						<view
							class="z-table-title-item"
							:class="{ 'z-table-stick-side': stickSide && index == 0 }"
							:style="[
								{ 'border-left': '1rpx solid ' + (index === 0 ? 'rgb(0, 0, 0, 0)' : templineColor) },
								{ 'border-top': '1rpx solid ' + templineColor },
								{ left: stickSide ? (rowNumbers ? rowNW : 0) + (showSelect ? showSW : 0) + 'rpx' : '0' },
								{ width: item.width ? item.width + 'rpx' : '200rpx' },
								{ 'background-color': tempbackgroundColor },
								{ color: temptextColor }
							]"
							v-for="(item, index) in columns"
							:key="index"
							v-if="!item.hidden"
							@click="sort(item.field, index)"
						>
							<view v-if="item.group" style="height: 100%;width: 100%;">
								<!-- 显示列分组标题明细 -->
								<view v-for="(gCol, gIndex) in item.columns" :key="gIndex">
									<view
										v-if="gIndex === 0 && item.gTitle && item.gTitle.length > 0"
										:class="[
											'z-table-col-text',
											{
												'text-left': item.talign === 'left' || talign === 'left',
												'text-center': item.talign === 'center' || talign === 'center',
												'text-right': item.talign === 'right' || talign === 'right'
											}
										]"
									>
										<view v-html="getTitleText(item)"></view>
									</view>
									<view
										v-if="gCol.title && gCol.title.length > 0"
										:class="[
											'z-table-col-text',
											{
												'text-left': gCol.talign === 'left' || talign === 'left',
												'text-center': gCol.talign === 'center' || talign === 'center',
												'text-right': gCol.talign === 'right' || talign === 'right'
											}
										]"
									>
										<view v-html="getTitleText(gCol)"></view>
									</view>
								</view>
							</view>
							<view
								v-else
								:class="[
									'z-table-col-text',
									{
										'text-left': item.talign === 'left' || talign === 'left',
										'text-center': item.talign === 'center' || talign === 'center',
										'text-right': item.talign === 'right' || talign === 'right'
									}
								]"
							>
								<view v-if="item.title && item.title.length > 0" v-html="getTitleText(item)"></view>
								<view v-if="item.hasOwnProperty('field') && item.hasOwnProperty('sort') && tableData.length" class="sort">
									<view
										class="up-arrow"
										:style="{ 'border-bottom': '4px solid ' + (nowSortKey == item.field && sortType == 'asc' ? temptitleColor : temptextColor) }"
									></view>
									<view
										class="down-arrow"
										:style="{ 'border-top': '4px solid ' + (nowSortKey == item.field && sortType == 'desc' ? temptitleColor : temptextColor) }"
									></view>
								</view>
							</view>
						</view>
					</view>

					<!-- 行内容 -->
					<view
						v-if="tableData.length"
						:style="[{ 'border-right': '1rpx solid ' + templineColor }]"
						:class="['table-container-box', { 'short-table': !longTable && showBottomSum }]"
					>
						<view
							v-if="row.rowSearch && (!pagination || (current * pageSize - pageSize <= iIndex && iIndex < current * pageSize))"
							class="z-table-container-row"
							:class="{ 'z-table-has-bottom': showBottomSum }"
							v-for="(row, iIndex) in tableData"
							:key="iIndex"
							:style="onRowStyle(row, iIndex)"
						>
							<!-- 添加行编号 -->
							<view
								v-if="rowNumbers"
								:class="['z-table-container-col', { 'z-table-stick-side': fixedSelectBox }]"
								:style="[
									{ 'border-left': '1rpx solid ' + templineColor },
									{ 'border-right': '1rpx solid ' + (showSelect ? 'rgb(0, 0, 0, 0)' : templineColor) },
									{ 'border-top': '1rpx solid ' + (iIndex === 0 ? 'rgb(0, 0, 0, 0)' : templineColor) },
									{ 'border-bottom': (!fillRow && iIndex == tableData.length - 1 ? '1' : '0') + 'rpx solid ' + templineColor },
									{ width: rowNW + 'rpx' },
									{ 'background-color': tempbackgroundColor }
								]"
							>
								<view class="z-table-col-text text-center">
									<view>{{ iIndex + 1 }}</view>
								</view>
							</view>
							<!-- 添加复选框 -->
							<view
								v-if="showSelect"
								:class="['z-table-container-col', { 'z-table-stick-side': fixedSelectBox }]"
								:style="[
									{ 'border-left': '1rpx solid ' + templineColor },
									{ 'border-right': '1rpx solid ' + templineColor },
									{ 'border-top': '1rpx solid ' + (iIndex === 0 ? 'rgb(0, 0, 0, 0)' : templineColor) },
									{ 'border-bottom': (!fillRow && iIndex == tableData.length - 1 ? '1' : '0') + 'rpx solid ' + templineColor },
									{ left: rowNumbers ? rowNW + 'rpx' : '0' },
									{ width: showSW + 'rpx' },
									{ 'background-color': tempbackgroundColor }
								]"
							>
								<view class="select-box" @click="doSelect(false, iIndex, row)"><view :class="['select-tip', { selected: row['rowChecked'] }]"></view></view>
							</view>
							<!-- 行数据遍历 -->
							<view
								:class="['z-table-container-col', { 'z-table-stick-side': stickSide && jIndex == 0 }]"
								:style="[
									{ 'border-left': '1rpx solid ' + (jIndex === 0 ? 'rgb(0, 0, 0, 0)' : templineColor) },
									{ 'border-top': '1rpx solid ' + (iIndex === 0 ? 'rgb(0, 0, 0, 0)' : templineColor) },
									{ 'border-bottom': (!fillRow && iIndex == tableData.length - 1 ? '1' : '0') + 'rpx solid ' + templineColor },
									{ left: stickSide ? (rowNumbers ? rowNW : 0) + (showSelect ? showSW : 0) + 'rpx' : '0' },
									{ width: col.width ? col.width + 'rpx' : '200rpx' }
								]"
								v-for="(col, jIndex) in columns"
								:key="jIndex"
								v-if="!col.hidden"
								@click="itemClick(iIndex, row, col)"
							>
								<!-- 多分组的时候，是否需要把内容填充 style="height: 100%;width: 100%;" -->
								<view v-if="col.group">
									<view v-for="(gCol, gIndex) in col['columns']" :key="gIndex">
										<view
											v-html="getRowContent(row, gCol, iIndex)"
											:class="[
												'z-table-col-text',
												{
													'text-left': col.align === 'left' || align === 'left',
													'text-center': col.align === 'center' || align === 'center',
													'text-right': col.align === 'right' || align === 'right'
												}
											]"
										></view>
									</view>
								</view>
								<view
									v-else
									v-html="getRowContent(row, col, iIndex)"
									:class="[
										'z-table-col-text',
										{
											'text-left': col.align === 'left' || align === 'left',
											'text-center': col.align === 'center' || align === 'center',
											'text-right': col.align === 'right' || align === 'right'
										}
									]"
								></view>
							</view>
						</view>

						<!-- 空白行 -->
						<view
							v-if="fillRow && tableData.length < fillCount"
							class="z-table-container-row"
							:class="{ 'z-table-has-bottom': showBottomSum }"
							v-for="(row, marginIndex) in fillCount"
						>
							<!-- 添加行编号 -->
							<view
								v-if="rowNumbers"
								:class="['z-table-container-col', { 'z-table-stick-side': fixedSelectBox }]"
								:style="[
									{ 'border-left': '1rpx solid ' + templineColor },
									{ 'border-right': '1rpx solid ' + (showSelect ? 'rgb(0, 0, 0, 0)' : templineColor) },
									{ width: rowNW + 'rpx' },
									{ 'background-color': (tableData.length + marginIndex) % 2 === 0 ? tempbackgroundColor2 : tempbackgroundColor }
								]"
							>
								<view class="z-table-col-text text-center"><view></view></view>
							</view>

							<!-- 添加复选框 -->
							<view
								v-if="showSelect"
								:class="['z-table-container-col', { 'z-table-stick-side': fixedSelectBox }]"
								:style="[
									{ 'border-left': '1rpx solid ' + templineColor },
									{ 'border-right': '1rpx solid ' + templineColor },
									{ left: rowNumbers ? rowNW + 'rpx' : '0' },
									{ width: showSW + 'rpx' },
									{ 'background-color': (tableData.length + marginIndex) % 2 === 0 ? tempbackgroundColor2 : tempbackgroundColor }
								]"
							>
								<view><view class="select-tip"></view></view>
							</view>

							<!-- 行数据遍历 -->
							<view
								:class="['z-table-container-col', { 'z-table-stick-side': stickSide && jIndex == 0 }]"
								:style="[
									{ 'border-left': '1rpx solid ' + (marginjIndex === 0 ? 'rgb(0, 0, 0, 0)' : templineColor) },
									{ left: stickSide ? (rowNumbers ? rowNW : 0) + (showSelect ? showSW : 0) + 'rpx' : '0' },
									{ width: col.width ? col.width + 'rpx' : '200rpx' },
									{ 'background-color': (tableData.length + marginIndex) % 2 === 0 ? tempbackgroundColor2 : tempbackgroundColor }
								]"
								v-for="(col, marginjIndex) in columns"
								v-if="!col.hidden"
							>
								<view class="z-table-col-text"></view>
							</view>
						</view>
					</view>
				</view>

				<!-- 页脚 -->
				<view
					:class="['z-table-bottom', { 'long-table': longTable }]"
					:style="[{ 'border-right': '1rpx solid ' + templineColor }, { 'border-bottom': '1rpx solid ' + templineColor }]"
					v-if="showBottomSum && tableData.length"
				>
					<!-- 行号和复选框站的宽度 -->
					<view
						class="z-table-bottom-col z-table-stick-side"
						:style="[
							{ 'border-left': '1rpx solid ' + templineColor },
							{ 'border-right': '1rpx solid ' + templineColor },
							{ 'border-top': '1rpx solid ' + templineColor },
							{ width: (rowNumbers ? rowNW : 0) + (showSelect ? showSW : 0) + (rowNumbers && showSelect ? -1 : 0) + 'rpx' },
							{ 'background-color': tempfooterColor },
							{ color: temptextColor }
						]"
					>
						<view class="z-table-bottom-text"><uni-icons :color="tempiconColor" type="huizong" size="20" /></view>
					</view>
					<!-- 遍历列数，分别计算合计值 -->
					<view
						class="z-table-bottom-col"
						:class="{ 'z-table-stick-side': stickSide && sumIndex == 0 }"
						:style="[
							{ 'border-left': '1rpx solid ' + (sumIndex === 0 ? 'rgb(0, 0, 0, 0)' : templineColor) },
							{ 'border-top': '1rpx solid ' + templineColor },
							{ left: stickSide ? (rowNumbers ? rowNW : 0) + (showSelect ? showSW : 0) + 'rpx' : '0' },
							{ width: sumCol.width ? sumCol.width + 'rpx' : '200rpx' },
							{ 'background-color': tempfooterColor },
							{ color: temptextColor }
						]"
						v-for="(sumCol, sumIndex) in columns"
						:key="sumIndex"
						v-if="!sumCol['hidden']"
					>
						<view
							class="z-table-bottom-text"
							:class="[
								'z-table-col-text',
								{
									'text-left': sumCol.align === 'left' || align === 'left',
									'text-center': sumCol.align === 'center' || align === 'center',
									'text-right': sumCol.align === 'right' || align === 'right'
								}
							]"
						>
							<!-- 默认总计，后面扩展平均值、最大最小值都可以 -->
							<text>{{ dosum(sumCol) }}</text>
						</view>
					</view>
				</view>
			</scroll-view>

			<!-- 分页器 -->
			<view v-if="pagination" class="pagination" :style="[{ 'border-top': '1rpx solid ' + templineColor }]">
				<uni-pagination
					style="height: 100%;"
					show-icon="true"
					:pageSize="pageSize"
					:iconColor="tempiconColor"
					:textColor1="temptitleColor"
					:textColor="temptextColor"
					:buttonColor="tempbuttonColor"
					:total="searchLen > 0 ? searchLen : tableData.length"
					:current="current"
					@change="paginationChange"
				></uni-pagination>
			</view>

			<view v-if="tableData && tableData.length == 0 && !tableLoaded" class="table-empty">
				<!-- image v-if="!showLoading" class="empty-img" src="../static/empty.png"></image -->
				<view v-html="showLoading ? '' : emptyText"></view>
			</view>
		</view>
	</view>
</template>

<script>
/*
 * 表格使用
 * 注意如果需要异步加载，需要把tableData初始值设为false，当没有数据的时候值为空数组
 * props: tableData [Array | Boolean] | 表格数据 如果为false则显示loading
 * 		 columns [Array | Boolean] | 数据映射表 如果为false则显示loading 每列params => title(表头文字可以是html字符串模版), width(每列宽度) [, key(对应tableData的字段名) || format(自定义内容), sort(是否要排序), isLink(是否显示为超链接Object)]
 * 										   format格式: {template: 字符串模版用#key#表示需要被替换的数据,names: 对应template属性内要被替换的内容的key}
 * 										   isLink格式: {url: 链接地址, params: 地址带的参数Array[key|value, key|value, ...]每一项都是key和value以'|'链接,如果不带'|'默认键值同名
 * 										   cellClick(是否监听点击事件Boolean)}
 * 		 stickSide Boolean | 是否固定右侧首栏 默认不显示
 * 		 showBottomSum Boolean | 是否显示底部统计 默认不显示
 * 		 showLoading Boolean | 是否首次加载首次加载不显示暂无数据内容
 * 		 emptyText String | 空数据显示的文字内容
 *		 tableHeight Number | 设置表格高度会滚动
 *		 sort Boolean | 开启排序
 * 		 showSelect Boolean | 开启选择
 *		 singleSelect Boolean | 在开启选择的状态下是否开起单选
 * 		 align String | 内容对齐方式 left center right
 * 		 talign String | 表头对齐方式 left center right
 *
 * event: onSort | 排序事件 返回{field: 被排序列的字段名, type: 正序'asc'/倒序'desc'}
 *		  onSelect | 选中时触发 返回选择的行的下标
 * 		  onClick | 单元格点击事件 返回点击单元格所属行的数据
 *
 * function: resetSort | 调用后重置排序 *注意:不会触发sort事件
 *
 * */
export default {
	data() {
		return {
			version: '1.1.3',
			nowSortKey: '',
			sortType: 'desc', // asc/desc 升序/降序
			longTable: true,
			lineHeight: uni.upx2px(64),
			tableLoaded: false,
			tableShow: true,
			selectAll: false,
			selectArr: [],
			//分页器，每页数据量
			pageSize: 100,
			//分页器，当前页
			current: 1,
			//查询过滤后的数据源总数
			searchLen: 0,
			//查询列下拉框数据源
			searchColData: [],
			//查询列下拉框选中行数据
			searchCol: {},
			//查询过滤输入框输入的内容
			searchVal: '',
			//查询管理器中的宽度比例 title width
			searchBoxTW: 100,
			//按钮颜色
			tempbuttonColor: '#ffffff',
			//选择行背景颜色
			tempselectRowColor: '#ffe48d',
			//图片按钮颜色
			tempiconColor: '#000000',
			//标题类字体颜色
			temptitleColor: '#5500ff',
			//文本颜色/线颜色
			temptextColor: '#000000',
			//线颜色
			templineColor: '#d4d4d4',
			//主背景颜色
			tempbackgroundColor: '#f3f3f3',
			//次背景颜色
			tempbackgroundColor2: '#ffffff',
			//页脚背景颜色
			tempfooterColor: '#d4e6ff',
			fillCount: 15
		};
	},
	computed: {
		//表格高度样式设置，计算是否显示表头和分页器，然后计算出行内容高度
		tbHeight() {
			let h=0;
			if(this.searchBox || this.tbName.length > 0){
				h+=33;
			}
			if(this.pagination)
			{
				h+=33;
			}
			return {height:this.tableHeight-h+"px"};
		}
	},
	props: {
		tbName: {
			type: String,
			default: ''
		},
		tableData: {
			type: [Array, Boolean],
			default() {
				return false;
			}
		},
		columns: {
			/*
			 *
			 * [{title: xxx, field: 当前列展示对象名, width: 列宽, render: function}]
			 *
			 * */
			type: [Array, Boolean],
			required: true
		},
		//是否固定右侧首栏 默认不显示
		stickSide: {
			type: Boolean,
			default: false
		},
		//是否显示底部统计 默认不显示
		showBottomSum: {
			type: Boolean,
			default: false
		},
		//是否首次加载首次加载不显示暂无数据内容
		showLoading: {
			type: Boolean,
			default: true
		},
		//空数据显示的文字内容
		emptyText: {
			type: String,
			default: '暂无数据'
		},
		//设置表格高度会滚动
		tableHeight: {
			type: [Number, Boolean],
			default: 500
		},
		//开启选择
		showSelect: {
			type: Boolean,
			default: false
		},
		//在开启选择的状态下是否开起单选
		singleSelect: {
			type: Boolean,
			default: true
		},
		//内容对齐方式 left center right
		align: {
			type: String,
			default: 'left' // right|center|left
		},
		//表头对齐方式 left center right
		talign: {
			type: String,
			default: 'left' // right|center|left
		},
		//如果为true，当用户点击行的时候该复选框就会被选中或取消选中。
		//如果为false，当用户仅在点击该复选框的时候才会被选中或取消。
		checkOnSelect: {
			type: Boolean,
			default: true
		},
		//是否固定复选框
		fixedSelectBox: {
			type: Boolean,
			default: true
		},
		//是否显示总行数。
		rowCount: {
			type: Boolean,
			default: false
		},
		//如果为true，则显示一个行号列。
		rowNumbers: {
			type: Boolean,
			default: false
		},
		//表格数据查询操作
		searchBox: {
			type: Boolean,
			default: false
		},

		//表格数据分页操作
		pagination: {
			type: Boolean,
			default: false
		},
		//行序号宽度 rowNumbersWidth
		rowNW: {
			type: Number,
			default: 50
		},
		//复选框宽度 showSelectWidth
		showSW: {
			type: Number,
			default: 50
		},
		// 主题颜色,默认白色
		theme: {
			type: String,
			default: ''
		},
		//按钮背景颜色
		buttonColor: {
			type: String,
			default: '#ffffff'
		},
		//选择行背景颜色
		selectRowColor: {
			type: String,
			default: '#ffe48d'
		},
		//图片按钮颜色
		iconColor: {
			type: String,
			default: '#000000'
		},
		//标题类字体颜色
		titleColor: {
			type: String,
			default: '#5500ff'
		},
		//标题类字体对齐方式 默认左对齐
		titleAlignment: {
			type: String,
			default: 'left'
		},
		//文本颜色
		textColor: {
			type: String,
			default: '#000000'
		},
		//线条颜色
		lineColor: {
			type: String,
			default: '#d4d4d4'
		},
		//主背景颜色
		backgroundColor: {
			type: String,
			default: '#f3f3f3'
		},
		//次背景颜色
		backgroundColor2: {
			type: String,
			default: '#ffffff'
		},
		//页脚颜色
		footerColor: {
			type: String,
			default: '#d4e6ff'
		},
		//是否填充空行
		fillRow: {
			type: Boolean,
			default: false
		}
	},

	created() {},
	mounted() {
		//初始化表格数据
		this.init();

		//设置主题颜色
		if (this.theme === 'white') {
			//白色
			//按钮颜色
			this.tempbuttonColor = '#ffffff';
			//选择行背景颜色
			this.tempselectRowColor = '#ffe48d';
			//图片按钮颜色
			this.tempiconColor = '#000000';
			//标题类字体颜色
			this.temptitleColor = '#5500ff';
			//文本颜色/线颜色
			this.temptextColor = '#000000';
			//线颜色
			this.templineColor = '#d4d4d4';
			//主背景颜色
			this.tempbackgroundColor = '#f3f3f3';
			//次背景颜色
			this.tempbackgroundColor2 = '#ffffff';
			//页脚颜色
			this.tempfooterColor = '#d4e6ff';
		} else if (this.theme === 'black') {
			//黑色
			this.tempbuttonColor = '#5e6576';
			this.tempselectRowColor = '#5e6434';
			this.tempiconColor = '#bcc1d6';
			this.temptitleColor = '#2488ea';
			this.temptextColor = '#bcc1d6';
			this.templineColor = '#8e93a1';
			this.tempbackgroundColor = '#0f1628';
			this.tempbackgroundColor2 = '#1c263f';
			this.tempfooterColor = '#545834';
		} else {
			//自定义
			this.tempbuttonColor = this.buttonColor;
			this.tempselectRowColor = this.selectRowColor;
			this.tempiconColor = this.iconColor;
			this.temptitleColor = this.titleColor;
			this.temptextColor = this.textColor;
			this.templineColor = this.lineColor;
			this.tempbackgroundColor = this.backgroundColor;
			this.tempbackgroundColor2 = this.backgroundColor2;
			this.tempfooterColor = this.footerColor;
		}
	},
	watch: {
		columns(e) {
			this.init();
		},
		tableData() {
			this.init();
		},
		buttonColor(newVal, oldVal) {
			this.tempbuttonColor = newVal;
		},
		selectRowColor(newVal, oldVal) {
			this.tempselectRowColor = newVal;
		},
		iconColor(newVal, oldVal) {
			this.tempiconColor = newVal;
		},
		titleColor(newVal, oldVal) {
			this.temptitleColor = newVal;
		},
		textColor(newVal, oldVal) {
			this.temptextColor = newVal;
		},
		backgroundColor(newVal, oldVal) {
			this.tempbackgroundColor = newVal;
		},
		backgroundColor2(newVal, oldVal) {
			this.tempbackgroundColor2 = newVal;
		}
		// tableHeight(newVal,oldVal){
		// console.log(newVal+'高度改变'+oldVal);
		// if (newVal != oldVal) {
		// 	console.log('高度改变');
		// }
		// },
	},

	methods: {
		//行样式操作
		onRowStyle(row, index) {
			let backgroundColor = row['rowChecked'] ? this.tempselectRowColor : index % 2 === 0 ? this.tempbackgroundColor2 : this.tempbackgroundColor;
			let css = {
				'background-color': backgroundColor,
				color: this.temptextColor
			};
			this.$emit('onRowStyle', { index: index, row: row }, res => {
				var assignObj = Object.assign(css, res);
			});
			return css;
		},

		async init() {
			// 重置选择内容
			this.selectAll = false;
			this.selectArr = [];
			this.tableLoaded = false;
			this.tableShow = true;
			this.searchLen = 0;
			this.pageSize = 100;
			let _this = this;
			let container = await _this.getPageSize('.z-table-container'),
				pack = await _this.getPageSize('.z-table-pack');
			_this.timer && clearTimeout(_this.timer);
			if (container && pack) {
				_this.$nextTick(function() {
					if (_this.tableData && _this.tableData.length) {
						_this.tableShow = false;
						_this.timer = setTimeout(function() {
							_this.tableLoaded = true;
						}, 300);
					}
				});
				if (container.height != pack.height) {
					_this.longTable = true;
				} else {
					_this.longTable = false;
				}
			} else {
				_this.tableLoaded = false;
				_this.$nextTick(function() {
					_this.tableShow = true;
				});
			}
			if (_this.tableData && _this.tableData.length) {
				_this.tableData.forEach((item, index) => {
					this.$set(item, 'rowChecked', false);
					this.$set(item, 'rowSearch', true);
					this.$set(item, 'rowIndex', index);
				});
			}
			let tempSearchColData = [];
			if (_this.columns && _this.columns.length) {
				_this.columns.forEach((item, index) => {
					if (item['group'] && item['columns'].length > 0) {
						item['columns'].forEach((gItem, gIndex) => {
							if (gItem.field && gItem.title) {
								this.$set(gItem, 'index', index + gIndex);
								tempSearchColData.push(gItem);
							}
						});
					} else {
						if (item.field && item.title) {
							this.$set(item, 'index', index);
							tempSearchColData.push(item);
						}
					}
				});

				this.searchColData = tempSearchColData;
			}
		},
		getPageSize(selecter) {
			// 获取元素信息
			let query = uni.createSelectorQuery().in(this),
				_this = this;
			return new Promise((resolve, reject) => {
				query
					.select(selecter)
					.boundingClientRect(res => {
						resolve(res);
					})
					.exec();
			});
		},
		//页脚计算数量
		dosum({ field, noSum = false, formatNum = true }) {
			let sum = '-';
			if (noSum) return sum;
			if (this.tableData) {
				if (
					this.tableData.every(item => {
						return !Number.isNaN(item[field] - 0);
					})
				) {
					sum = 0;
					this.tableData.map((item, index) => {
						if (!field && index != 0) {
							sum = '-';
						} else {
							let val = item[field] - 0;
							if (Number.isNaN(val) || !item['rowSearch']) {
								sum += 0;
							} else {
								sum += val;
							}
						}
					});
				}
			}
			// sum = sum == 0 ? "-" : sum
			// return formatNum ? this.numTransform(sum) : sum
			return sum;
		},
		//得到单元格html内容
		getRowContent(row, col, index) {
			let tempHTML = '';
			//得到内容
			let rowKey = row[col.field];
			if ([null, ''].includes(rowKey)) {
				rowKey = '-';
			}
			let { formatNum = true } = col;

			if (rowKey || rowKey === 0) {
				tempHTML = rowKey;
				// tempHTML = isNaN(rowKey - 0) || !formatNum
				// 	? rowKey
				// 	: this.numTransform(rowKey - 0);
			}

			//设置自定义内容
			if (col.format) {
				tempHTML = col.format(rowKey, row, index);
			}

			tempHTML = "<view style='white-space:normal;word-break:break-all;word-wrap:break-word;'>" + tempHTML + '</view>';

			//设置超链接路径
			if (col.link) {
				let link = col.link(tempHTML, row, index);
				let urlParam = {};
				if (link.params && link.params.length > 0) {
					link.params.forEach(item => {
						if (~item.indexOf('|')) {
							let temp = item.split('|');
							urlParam[temp[0]] = row[temp[1]];
						} else {
							urlParam[item] = row[item];
						}
					});
				}
				let url = this.setUrlParams(link.url, urlParam); //得到超链接参数
				tempHTML = '<a style="color:' + this.temptitleColor + '" href="' + url + '">' + tempHTML + '</a>';
			}

			//设置自定义单元格样式
			if (col.styler) {
				let align = 'flex-start'; //默认 left
				if (col.align === 'center' || align === 'center') {
					align = 'center';
				}
				if (col.align === 'right' || align === 'right') {
					align = 'flex-end';
				}
				let style = ' display: flex;' + 'width: 100%;' + 'height: 100%;' + 'flex: 1;' + 'justify-content: ' + align + ';' + 'align-content:center; ';
				style += col.styler(rowKey, row, index);
				tempHTML = '<view style="' + style + '"><view>' + tempHTML + '</view></view>';
			}

			return tempHTML.toString();
		},
		// 得到超链接参数
		setUrlParams(url, params) {
			let tempUrl = url,
				keyArr = Object.keys(params);
			keyArr.forEach(item => {
				tempUrl += `&${item}=${params[item]}`;
			});
			tempUrl = tempUrl.replace(/\&/, '?');
			return tempUrl;
		},
		//排序操作
		sort(field, index) {
			if (!field || !this.columns[index].sort) {
				return;
			}
			// 排序功能: 如果点击的排序按钮是原先的 那么更改排序类型
			//			如果点击的另一个排序按钮 那么选择当前排序并且排序类型改为降序(desc)
			if (field != this.nowSortKey) {
				this.nowSortKey = field;
				this.sortType = 'desc';
			} else {
				this.toggleSort();
			}
			//优先先本地排序，如果需要重新从数据库查询可调用onSort事件
			let arr = this.tableData;
			for (let j = 0; j < arr.length - 1; j++) {
				//外层循环，控制趟数，每一次找到一个最大值
				for (let i = 0; i < arr.length - 1 - j; i++) {
					// 内层循环,控制比较的次数，并且判断两个数的大小
					if (this.sortType == 'asc') {
						if (arr[i][this.nowSortKey] > arr[i + 1][this.nowSortKey]) {
							let temp = arr[i + 1];
							arr[i + 1] = arr[i];
							arr[i] = temp;
						}
					} else if (arr[i][this.nowSortKey] < arr[i + 1][this.nowSortKey]) {
						let temp = arr[i + 1];
						arr[i + 1] = arr[i];
						arr[i] = temp;
					}
				}
			}
			this.$emit('onSort', {
				field: this.nowSortKey,
				type: this.sortType
			});
		},
		//排序结果
		toggleSort() {
			this.sortType = this.sortType == 'asc' ? 'desc' : 'asc';
		},
		// 页脚汇总
		numTransform(n) {
			if (Number.isNaN(n - 0)) {
				return n;
			}
			if (Math.abs(n) >= 100000000) {
				n = Number((n / 100000000).toFixed(1)) + '亿';
			} else if (Math.abs(n) >= 10000) {
				n = Number((n / 10000).toFixed(1)) + '万';
			}
			return n.toString();
		},
		//重置排序
		resetSort() {
			// 重置排序状态
			this.nowSortKey = '';
			this.sortType = 'desc';
		},
		// 单元格点击事件
		itemClick(index, row, col) {
			//隐藏查询工具栏
			if (this.searchBoxTW === 0) {
				this.buttonClick();
			}
			//点击就选中行
			if (this.checkOnSelect) {
				this.doSelect(false, index, row);
			}
			//监听单元格点击事件
			if (col.cellClick) {
				this.$emit('onClick', { index: index, row: row, col: col });
			}
		},
		//选中行事件 isAll:是否为全选
		doSelect(isAll = false, thisIndex, thisRow) {
			if (isAll) {
				this.selectArr = [];
				this.selectAll = !this.selectAll;
				this.tableData.forEach((item, index) => {
					if (this.selectAll) {
						if (item['rowSearch']) {
							if (!item['rowChecked']) {
								this.$set(item, 'rowChecked', true);
							}
							this.selectArr.push(index);
						}
					} else {
						if (item['rowChecked']) {
							this.$set(item, 'rowChecked', false);
						}
					}
				});
			} else {
				const thisCheck = this.tableData[thisIndex]['rowChecked'] || false;
				this.$set(this.tableData[thisIndex], 'rowChecked', !thisCheck);
				//检查是否已经为全部选中状态
				var tempSelectAll = true;
				//单选
				if (this.singleSelect) {
					//判断是不是原来选择的索引，如果就直接清空，不需要在push到选择数组中
					if (this.selectArr.length > 0 && this.selectArr[0] == thisIndex) {
						this.selectArr = [];
					} else {
						this.selectArr = [];
						this.selectArr.push(thisIndex);
					}
					tempSelectAll = false;
				}
				this.selectArr = [];
				for (let i = 0; i < this.tableData.length; i++) {
					if (this.singleSelect && thisIndex !== i) {
						//单选
						//除了当前选中的，其他全部为未选中状态
						this.$set(this.tableData[i], 'rowChecked', false);
					} else {
						//多选
						if (tempSelectAll && !this.tableData[i]['rowChecked']) {
							tempSelectAll = false;
						}
						if (this.tableData[i]['rowChecked']) {
							this.selectArr.push(i);
						}
					}
				}

				this.selectAll = tempSelectAll;
			}
			const index = this.singleSelect ? (this.selectArr.length > 0 ? this.selectArr[0] : -1) : this.selectArr;
			this.$emit('onSelect', { index: index, row: thisRow });
		},
		// 返回表头标签内容
		getTitleText(col) {
			let tempHTML = '';
			if (col.titler) {
				tempHTML = col.titler();
			} else if (col.title) {
				tempHTML = col.title;
			} else {
				tempHTML = col.gTitle;
			}
			return tempHTML.toString();
		},
		//分页器点击事件
		paginationChange(e) {
			this.current = e.current;
			// console.log(JSON.stringify(e)+this.current);
		},
		//搜索内容提交事件
		onSearch(e) {
			//搜索内容为空的时候，默认全选
			if (e === '') {
				this.tableData.forEach((item, index) => {
					this.$set(item, 'rowSearch', true);
				});
				this.searchLen = this.tableData.length;
				this.pageSize = 100;
				return;
			}
			//过滤后的数据总行数
			var len = 0;
			this.tableData.forEach((item, index) => {
				//指定列过滤
				if (this.searchCol['index'] >= 0) {
					var cellVal = item[this.searchCol['key']] + '';
					if (cellVal.length > 0 && cellVal.indexOf(e) > -1) {
						this.$set(item, 'rowSearch', true);
						len += 1;
					} else {
						this.$set(item, 'rowSearch', false);
					}
				} else {
					//全列过滤
					this.$set(item, 'rowSearch', false);
					let exist = false;
					for (var i = 0; i < this.searchColData.length; i++) {
						//列集合中不存在field
						if (!this.searchColData[i]['field']) {
							continue;
						}
						var cellVal = item[this.searchColData[i]['field']] + '';
						if (cellVal.length > 0 && cellVal.indexOf(e) > -1) {
							this.$set(item, 'rowSearch', true);
							exist = true;
						}
					}
					len += exist ? 1 : 0;
				}
			});
			this.searchLen = len;
			//查询后的数据不进行分页
			this.current = 1;
			this.pageSize = this.tableData.length;
		},
		//搜索清空按钮事件
		onSearchClear() {
			this.onSearch('');
		},
		// 展开查询框按钮事件
		buttonClick() {
			this.searchBoxTW = this.searchBoxTW === 0 ? 100 : 0;
		}
	}
};
</script>

<style lang="scss">
.m-input-row {
	padding: 0;
}

.pagination {
	// height: 10%;
	height: 33px;
}

.navigator-hover {
	background: transparent;
	opacity: 1;
}

@mixin ellipsis($num: 1) {
	overflow: hidden;
	text-overflow: ellipsis;

	@if $num==1 {
		white-space: nowrap;
	} @else {
		display: -webkit-box;
		-webkit-line-clamp: $num;
		/* autoprefixer: off */
		-webkit-box-orient: vertical;
		/* autoprefixer: on */
	}
}

// 三角形
%triangle-basic {
	content: '';
	height: 0;
	width: 0;
	overflow: hidden;
}

@mixin triangle($direction, $size, $borderColor) {
	@extend %triangle-basic;

	@if $direction==top {
		border-bottom: $size solid $borderColor;
		border-left: $size dashed transparent;
		border-right: $size dashed transparent;
		border-top: 0;
	} @else if $direction==right {
		border-left: $size solid $borderColor;
		border-top: $size dashed transparent;
		border-bottom: $size dashed transparent;
		border-right: 0;
	} @else if $direction==bottom {
		border-top: $size solid $borderColor;
		border-left: $size dashed transparent;
		border-right: $size dashed transparent;
		border-bottom: 0;
	} @else if $direction==left {
		border-right: $size solid $borderColor;
		border-top: $size dashed transparent;
		border-bottom: $size dashed transparent;
		border-left: 0;
	}
}

a {
	text-decoration: none;
}

.z-table {
	position: relative;
	display: inline-block;
	height: 100%;
	width: 100%;
	min-height: 130rpx;
	background: #fff;
	border: solid 2rpx #ccc;
	font-size: $uni-font-size-sm;
	box-sizing: border-box;
	transform: translateZ(0);
	.z-table-main {
		height: 100%;
		box-sizing: border-box;
	}

	.z-table-pack {
		position: relative;
		min-height: 100%;
		width: fit-content;
	}

	.z-table-title {
		position: sticky;
		width: 100% !important;
		top: 0;
		min-height: 64rpx;
		z-index: 1;

		.z-table-title-item {
			// border-bottom: solid 1rpx #dbdbdb;
			// border-right: solid 1rpx #dbdbdb;
			background: #f8f8f8;
		}

		.z-table-stick-side {
			position: sticky;
			top: 0;
			left: 0;
			// border-right: solid 1rpx #dbdbdb;
			box-sizing: border-box;
		}
	}

	.table-container-box.short-table {
		padding-bottom: 48rpx;
	}

	.z-table-title,
	.z-table-container-row {
		display: flex;
		width: fit-content;
		white-space: nowrap;
		box-sizing: border-box;

		.z-table-title-item,
		.z-table-container-col {
			@include ellipsis();
			display: inline-flex;
			// padding: 0 3rpx;
			min-height: 64rpx;
			align-items: center;
			line-height: 64rpx;
			box-sizing: border-box;
			// flex-direction:column;
			// border-right: solid 1rpx #dbdbdb;
		}
	}

	.z-table-container-row {
		z-index: 0;
		// border-bottom: solid 1rpx #f4f4f4;
		box-sizing: border-box;
	}

	.z-table-stick-side {
		position: sticky;
		left: 0;
		// background: #f7f9ff;
		// border-right: solid 1rpx #dbdbdb;
		box-sizing: border-box;
	}

	.z-table-bottom {
		position: absolute;
		bottom: 0;
		z-index: 9;
		display: flex;
		justify-items: center;
		width: fit-content;
		// background: #4298f7 !important;
		color: #fff !important;
		white-space: nowrap;
		box-sizing: border-box;

		&.long-table {
			position: sticky;
		}

		.z-table-stick-side {
			background: #4298f7; //!important;
			box-sizing: border-box;
		}

		.z-table-bottom-col {
			display: inline-flex;
			align-items: center;
			text-align: center;
			padding: 16rpx 0 16rpx 0;
			box-sizing: border-box;
		}

		.z-table-bottom-text {
			line-height: 100%;
			box-sizing: border-box;
		}
	}

	.table-empty {
		position: absolute;
		top: 64rpx;
		height: 64rpx;
		line-height: 64rpx;
		width: 100%;
		text-align: center;
	}

	.sort {
		display: flex;
		padding: 5rpx;
		flex-direction: column;
		justify-content: center;

		.up-arrow {
			@include triangle(top, 10rpx, #ccc);
			display: block;
			margin-bottom: 5rpx;

			&.action {
				@include triangle(top, 10rpx, #4298f7);
			}
		}

		.down-arrow {
			@include triangle(bottom, 10rpx, #ccc);
			display: block;

			&.action {
				@include triangle(bottom, 10rpx, #4298f7);
			}
		}
	}

	// 1.0.5
	.z-loading {
		position: absolute;
		top: 0;
		left: 0;
		z-index: 2;
		display: flex;
		align-items: center;
		justify-content: center;
		height: 100%;
		width: 100%;
		background: #fff;
		opacity: 0;
		transition: all 0.3s;

		&.ztableLoading {
			opacity: 1;
		}

		.z-loading-animate {
			position: relative;
			display: inline-block;
			width: 30rpx;
			height: 30rpx;
			margin-right: 20rpx;
			border-radius: 100%;
			border: solid 6rpx #ccc;
			vertical-align: middle;
			animation: rotate 1s ease-in-out infinite;

			&::after {
				content: '';
				display: block;
				position: absolute;
				top: -10rpx;
				z-index: 1;
				background: #fff;
				width: 20rpx;
				height: 20rpx;
				border-radius: 10rpx;
			}
		}

		@keyframes rotate {
			from {
				transform: rotate(0deg);
			}

			to {
				transform: rotate(360deg);
			}
		}
	}

	// 1.1.0 小复选框
	.select-box {
		display: inline-block;
		width: 30rpx;
		height: 30rpx;
		line-height: 14rpx;
		margin: 0 5rpx;
		border: solid 2rpx #4298f7;
		border-radius: 4rpx;
		background: #fff;
		text-align: center;
	}

	.select-tip {
		display: inline-block;
		opacity: 0;
		transform: rotate(90deg);
		transition: all 0.3s;

		&.selected {
			position: relative;
			top: 4rpx;
			left: -4rpx;
			height: 4rpx;
			background: #4298f7;
			width: 10rpx;
			opacity: 1;
			transform: rotate(45deg);

			&:before,
			&:after {
				content: '';
				position: absolute;
				display: block;
				height: 4rpx;
				background: #4298f7;
			}

			&:before {
				bottom: -2rpx;
				left: -4rpx;
				width: 8rpx;
				transform: rotate(-90deg);
			}

			&:after {
				bottom: 16rpx;
				right: -16rpx;
				width: 34rpx;
				transform: rotate(-90deg);
			}
		}
	}

	// 1.1.1
	.z-table-col-text {
		display: flex;
		width: 100%;
		height: 100%;
		flex: 1;
		justify-content: flex-start;
		align-content: center;

		&.text-center {
			justify-content: center;
		}

		&.text-right {
			justify-content: flex-end;
		}
	}
}
</style>
