<!--
 * @Descripttion: 表格选择器组件
 * @version: 1.3
 * @Author: sakuya
 * @Date: 2021年6月10日10:04:07
 * @LastEditors: sakuya
 * @LastEditTime: 2022年6月6日21:50:36
-->

<template>
	<el-select ref="select" v-model="defaultValue" :size="size" :clearable="clearable" :multiple="multiple" :collapse-tags="collapseTags" :collapse-tags-tooltip="collapseTagsTooltip" :placeholder="placeholder" :disabled="disabled" :placement="placement" @remove-tag="removeTag" @visible-change="visibleChange" @clear="clear">
		<template #empty>
			<div class="sc-table-select__table" :style="{ width: tableWidth + 'px' }" v-loading="loading">
				<div class="sc-table-select__header">
					<slot name="header" :queryForm="formData" :submit="formSubmit"></slot>
				</div>
				<el-table :class="!multiple && highlightCurrent && 'table-row-cursor'" ref="table" :data="tableData" :height="245" :highlight-current-row="!multiple && highlightCurrent" @row-click="click" @select="select" @select-all="selectAll">
					<el-table-column v-if="multiple" type="selection" width="45"></el-table-column>
					<el-table-column v-else type="index" width="60">
						<template #default="scope"><span>{{ scope.$index + (currentPage - 1) * pageSize + 1 }}</span></template>
					</el-table-column>
					<slot></slot>
				</el-table>
				<div v-if="!hidePagination" class="sc-table-select__page">
					<el-pagination small background :layout="paginationLayout" :total="total" :page-size="pageSize" :page-sizes="pageSizes" v-model:currentPage="currentPage" @current-change="getData" @update:page-size="pageSizeChange"></el-pagination>
				</div>
			</div>
		</template>
	</el-select>
</template>

<script>
	import config from "@/config/tableSelect";

	export default {
		props: {
			modelValue: null,
			apiObj: { type: Object, default: () => {} },
			apiKey: { type: String, default: "get" },
			params: { type: Object, default: () => {} },
			filters: { type: Object, default: () => {} },
			placeholder: { type: String, default: "请选择" },
			size: { type: String, default: "default" },
			clearable: { type: Boolean, default: false },
			multiple: { type: Boolean, default: false },
			collapseTags: { type: Boolean, default: false },
			collapseTagsTooltip: { type: Boolean, default: false },
			disabled: { type: Boolean, default: false },
			placement: { type: String, default: "bottom-start" },
			tableWidth: { type: Number, default: 400},
			props: { type: Object, default: () => {} },
			highlightCurrent: { type: Boolean, default: true },
			hidePagination: { type: Boolean, default: false },
			pageSizes: { type: Array, default: () => config.pageSizes },
			paginationLayout: { type: String, default: config.paginationLayout },
            applySql: { type: Boolean, default: false }
		},
		data() {
			return {
				loading: false,
				defaultValue: [],
				tableData: [],
				allTableData: [],
				pageSize: config.pageSize,
				total: 0,
				currentPage: 1,
				defaultProps: {
					label: config.props.label,
					value: config.props.value,
					page: config.request.page,
					pageSize: config.request.pageSize
				},
				formData: {}
			}
		},

		watch: {
			modelValue: {
				deep: true,
				handler() {
					this.defaultValue = this.modelValue
					this.autoCurrentLabel()
				}
			},

			apiKey() {
				this.getData()
			}
		},

		mounted() {
			this.defaultProps = Object.assign(this.defaultProps, this.props);
			this.defaultValue = this.modelValue;
			this.autoCurrentLabel();
		},

		methods: {
			//表格显示隐藏回调
			visibleChange(visible) {
				if (visible) {
					this.currentPage = 1
					this.formData = {}
					this.getData()
				} else {
					this.autoCurrentLabel()
					this.$emit("resetFilter");
				}
			},

			//获取表格数据
			async getData() {
				try {
					this.loading = true;
					const reqData = {
						[this.defaultProps.page]: this.defaultProps.page == "page" ? this.currentPage - 1 : this.currentPage,
						[this.defaultProps.pageSize]: this.pageSize
					}
					if (this.hidePagination) {
						delete reqData[this.defaultProps.page]
						delete reqData[this.defaultProps.pageSize]
					}
                    if (this.applySql && this.$TOOL.data.get("APPLY_SQL")) reqData["applySql"] = this.$TOOL.data.get("APPLY_SQL");
	
					Object.assign(reqData, this.params, this.formData)
					const res = await this.apiObj[this.apiKey](reqData);
					const parseData = config.parseData(res);
					this.tableData = parseData.data || [];
					if (this.hidePagination) {
						this.allTableData = parseData.data || [];
						this.formFilter();
					}
					this.total = parseInt(parseData.total) || 0;
					this.loading = false;
	
					//表格默认赋值
					if (this.defaultValue) {
						this.$nextTick(() => {
							if (this.multiple) {
								this.defaultValue.forEach(row => {
									var setrow = this.tableData.filter(item => item[this.defaultProps.value] === row[this.defaultProps.value] )
									if (setrow.length > 0) {
										this.$refs.table.toggleRowSelection(setrow[0], true);
									}
								})
							} else {
								var setrow = this.tableData.filter(item => item[this.defaultProps.value] === this.defaultValue[this.defaultProps.value] )
								this.$refs.table.setCurrentRow(setrow[0]);
							}
							this.$refs.table.setScrollTop(0)
						})
					}
				} catch (error) {
					this.loading = false;
				}
			},
			//插糟表单提交
			formSubmit() {
				this.currentPage = 1
				this.getData()
			},
			//插糟表单筛选
			formFilter() {
				let array = this.allTableData.slice();
				for (const key in this.filters) {
					if (this.filters[key]) array = array.filter(a => a[key] && a[key].includes(this.filters[key]));
				}
				this.tableData = array.slice();
			},
			//条数变化
			pageSizeChange(size) {
				this.pageSize = size
				this.getData()
			},
			autoCurrentLabel() {
				this.$nextTick(() => {
					if (this.multiple) {
						this.$refs.select.states.selected.forEach(item => item.currentLabel = item.value[this.defaultProps.label])
					} else {
						if (this.defaultValue) this.$refs.select.states.selectedLabel = this.defaultValue[this.defaultProps.label]
					}
				})
			},
			//表格勾选事件
			select(rows, row) {
				var isSelect = rows.length && rows.indexOf(row) !== -1
				if (isSelect) {
					this.defaultValue.push(row)
				} else {
					this.defaultValue.splice(this.defaultValue.findIndex(item => item[this.defaultProps.value] == row[this.defaultProps.value]), 1)
				}
				this.autoCurrentLabel()
				this.$emit("update:modelValue", this.defaultValue);
				this.$emit("change", this.defaultValue);
			},
			//表格全选事件
			selectAll(rows) {
				var isAllSelect = rows.length > 0
				if (isAllSelect) {
					rows.forEach(row => {
						var isHas = this.defaultValue.find(item => item[this.defaultProps.value] == row[this.defaultProps.value])
						if(!isHas){
							this.defaultValue.push(row)
						}
					})
				} else {
					this.tableData.forEach(row => {
						var isHas = this.defaultValue.find(item => item[this.defaultProps.value] == row[this.defaultProps.value])
						if(isHas){
							this.defaultValue.splice(this.defaultValue.findIndex(item => item[this.defaultProps.value] == row[this.defaultProps.value]), 1)
						}
					})
				}
				this.autoCurrentLabel()
				this.$emit("update:modelValue", this.defaultValue);
				this.$emit("change", this.defaultValue);
			},
			click(row) {
				if (this.highlightCurrent) {
					if (this.multiple) {
						//处理多选点击行
					} else{ 
						this.defaultValue = row;
						this.$refs.select.blur();
						this.autoCurrentLabel();
						this.$emit("update:modelValue", this.defaultValue);
						this.$emit("change", this.defaultValue);
					}
				}
			},
			//tags删除后回调
			removeTag(tag){
				var row = this.findRowByKey(tag[this.defaultProps.value])
				this.$refs.table.toggleRowSelection(row, false);
				this.$emit("update:modelValue", this.defaultValue);
			},
			//清空后的回调
			clear(){
				this.$emit("update:modelValue", this.defaultValue);
			},
			// 关键值查询表格数据行
			findRowByKey (value) {
				return this.tableData.find(item => item[this.defaultProps.value] === value)
			},
			// 触发select隐藏
			blur(){
				this.$refs.select.blur();
			},
			// 触发select显示
			focus(){
				this.$refs.select.focus();
			}
		}
	}
</script>

<style scoped>
.sc-table-select__table {
  min-width: 100%;
  padding: 5px 12px;
}
.sc-table-select__page {
  padding-top: 12px;
}

.sc-table-select__header :deep(.el-form) .el-form-item {
  margin-right: 20px;
}

.table-row-cursor :deep(.el-table__row) {
  cursor: pointer;
}
</style>