<template>
	<div id="one-table">
		<el-card>
			<One-Form ref="oneForm" v-bind="$attrs" is-table @search="search" @refresh="refresh" />
			<div class="table_operation_or_search">
				<div class="table_operation_or_search-right">
					<el-button
						v-for="(btn, index) in tableFormBottonConfig"
						:key="index"
						:type="btn.btType"
						:size="btn.size ? btn.size : 'mini'"
						:icon="btn.icon"
						:loading="btn.loading"
						@click="btnTableClick(btn.type)"
					>
						{{ btn.text }}
					</el-button>
				</div>
				<!-- 页内搜索，正常不会用到 -->
				<!-- <div class="table_operation_or_search-left"><el-input v-model="searchAreaModel.search" @input="searchInput" size="mini" placeholder="输入关键字搜索"></el-input></div> -->
				<div class="table_operation_or_clear" style="clear: both;" />
			</div>
			<!-- 直接转发原有事件 -->
			<el-table
				ref="oneTableAuto"
				:height="height"
				:data="tableDataComputed"
				:border="border"
				:show-header="showheader"
				:row-key="tableGlobalConfig.rowKey"
				:tree-props="treePropsComputed"
				@select="(selection, row) => $emit('select', selection, row)"
				@select-all="selection => $emit('selectAll', selection)"
				@cell-click="(row, column, cell, event) => $emit('cell-click', row, column, cell, event)"
				@row-click="(row, column, event) => $emit('row-click', row, column, event)"
				@selection-change="selectionChange"
			>
				<!-- 根据配置加载选择框-->
				<el-table-column v-if="tableGlobalConfig.selectionCheck" type="selection" :reserve-selection="tableGlobalConfig.reserveSelection" width="55" />
				<!-- 根据配置加载需要列 -->
				<el-table-column
					v-if="tableGlobalConfig.needIndex"
					label="序号"
					align="center"
					width="60"
					type="index"
					:index="index => index + 1"
					:fixed="Boolean(requsetData.length)"
				/>

				<el-table-column
					v-for="(item, index) in tableConfigField"
					:key="index"
					:prop="item.id"
					:label="item.name"
					:width="item.width ? item.width : ''"
					:fixed="item.fixed ? item.fixed : null"
					:formatter="item.formatter ? tableColumnFormatter : null"
					:render-header="item.renderHeader ? item.renderHeader : null"
					:sortable="item.sortable ? item.sortable : null"
					:sort-method="item.sortMethod ? item.sortMethod : null"
					:show-overflow-tooltip="true"
				>
					<!-- 根据配置加载实际内容或者按钮 -->
					<template slot-scope="scope">
						<span v-if="!item.type || item.type == ''">
							<!-- 如果需要筛选内容 -->
							<span v-if="item.formatter">
								<span v-if="item.isHtml" v-html="tableColumnFormatter(scope.row, { property: item.id }, scope.row[item.id], scope.$index)" />
								<span v-else>{{ tableColumnFormatter(scope.row, { property: item.id }, scope.row[item.id], scope.$index) }}</span>
							</span>
							<span v-else>
								<span v-if="item.isHtml" v-html="scope.row[item.id]" />
								<span v-else>{{ scope.row[item.id] }}</span>
							</span>
						</span>
						<!-- <div v-if="item.type == 'tag'">
              <el-tag v-if="scope.row[item.id]" :type="item.config.type">{{ scope.row[item.id] }}</el-tag>
            </div> -->
						<!-- 加载图片 -->
						<div v-if="item.type == 'image'">
							<el-image
								v-if="item.formatter"
								class="table-image-column"
								:src="tableColumnFormatter(scope.row, { property: item.id }, scope.row[item.id], scope.$index)"
								:fit="item.fit || 'fill'"
								:preview-src-list="[tableColumnFormatter(scope.row, { property: item.id }, scope.row[item.id], scope.$index)]"
							/>
							<el-image
								v-else
								class="table-image-column"
								:src="tableColumnFormatter(scope.row, { property: item.id }, scope.row[item.id], scope.$index)"
								:preview-src-list="[scope.row[item.id]]"
								:fit="item.fit || 'fill'"
							/>
						</div>
						<!-- 加载按钮 -->
						<div v-if="item.type === 'option'">
							<span v-for="(btItem, btIndex) in item.data" :key="btIndex" class="table-col-options-button">
								<el-button
									v-if="btnTableColumnOption(scope.row, btItem.type)"
									:type="btItem.btType ? btItem.btType : 'primary'"
									:icon="btItem.icon"
									:size="btItem.size ? btItem.size : 'mini'"
									@click="columnClick(scope.row, btItem.type)"
								>
									{{ btItem.text }}
								</el-button>
							</span>
						</div>
					</template>
				</el-table-column>
			</el-table>
			<el-pagination
				class="pagination_init"
				:current-page="paginationConfig.currentPage"
				:page-sizes="[10, 20, 50, 100]"
				:page-size="paginationConfig.pagesize"
				:total="totalComputed"
				layout="total, sizes, prev, pager, next, jumper"
				@size-change="handleSizeChange"
				@current-change="handleCurrentChange"
			/>
		</el-card>
	</div>
</template>
<script type="text/javascript">
import OneForm from './OneForm.vue'
import { request } from './common/request.js'
import { toRawType } from './common/common.js'
export default {
	name: 'OneTable',
	components: {
		OneForm
	},
	props: {
		/* 自设属性*/

		// 表格全局参数
		tableGlobalConfigProps: {
			type: Object,
			default: () => {
				return {}
			}
		},
		// 请求地址
		requsetUrl: {
			type: String,
			default: ''
		},
		// 附加请求参数
		requsetConfig: {
			type: Object,
			default: () => {
				return {}
			}
		},
		// 请求头参数
		headerConfig: {
			type: Object,
			default: () => {
				return {}
			}
		},
		// 表格分页方式  web:前端分页  backstage:后端 默认前端分页
		tablePaginationType: {
			type: String,
			default: 'backstage'
		},
		// 表格分页的请求参数
		tablePaginationConfigAuto: {
			type: Object,
			default: () => {
				return {
					page: 'currentPage',
					pageSize: 'pagesize'
				}
			}
		},
		// 表格数据源方式
		tableConfigField: {
			type: Array,
			default: () => {
				return []
			}
		},
		// 表格上按钮区域
		tableFormBottonConfig: {
			type: Array,
			default: () => {
				return []
			}
		},
		btnTableColumnOption: {
			type: Function,
			default: (row, type) => {
				return true
			}
		},
		// 表格筛选
		tableColumnFormatter: {
			type: Function,
			default: (row, column, cellValue, index) => {
				return cellValue
			}
		},
		height: {
			type: String,
			default: undefined
		},
		border: {
			type: Boolean,
			default: true
		},
		showheader: {
			type: Boolean,
			default: true
		}
	},
	data() {
		return {
			paginationConfig: {
				currentPage: 1, // 初始页
				pagesize: 10 // 每页的数据
			},
			requsetData: [], // 后端分页的数据
			total: 0, // 后端分页--由后端传来的数据长度
			requsetFormData: {}, // 搜索区域字段
			multipleSelection: [] // 表格选择数据
		}
	},
	computed: {
		tableDataComputed() {
			if (this.tablePaginationType === 'web') {
				return this.requsetData.slice(
					(this.paginationConfig.currentPage - 1) * this.paginationConfig.pagesize,
					this.paginationConfig.currentPage * this.paginationConfig.pagesize
				)
			}
			if (this.tablePaginationType === 'backstage') {
				return this.requsetData
			}
			this.$message.error('未指定分页方式，请传入参数tablePaginationType')
			return []
		},
		totalComputed() {
			if (this.tablePaginationType === 'web') {
				return this.requsetData.length
			}
			if (this.tablePaginationType === 'backstage') {
				return this.total
			}
			return 0
		},
		treePropsComputed() {
			if (this.tableGlobalConfig.tableType === 'tree') {
				return {
					children: this.tableGlobalConfig.treeChildren ? this.tableGlobalConfig.treeChildren : 'children',
					hasChildren: this.tableGlobalConfig.treeHasChildren ? this.tableGlobalConfig.treeHasChildren : 'hasChildren'
				}
			}
			return {}
		},
		tableGlobalConfig() {
			const param = {
				tableType: 'table', // 表格类型  table，tree
				treeChildren: 'children', // 为树形结构时children属性名
				treeHasChildren: 'hasChildren', // 为树形结构时hasChildren属性名
				rowKey: 'id', // 行key  为tree时必传
				selectionCheck: false, // 是否有选择框
				reserveSelection: false, // 选择框分页时是否记忆
				autoRequest: true, // 创建时自动请求
				handRequestSetPage: false, // 手动处理返回数据
				requsetType: 'get', // 默认get
				needIndex: false // 需要序号
			}
			Object.assign(param, this.tableGlobalConfigProps)
			return param
		}
	},
	watch: {},
	created() {
		// 创建时如果参数为自动请求
		if (this.tableGlobalConfig.autoRequest) {
			this.loadPage()
		}
	},
	mounted() {},
	methods: {
		// 加载表格数据
		loadPage() {
			if (this.requsetUrl === '') {
				this.$message.error('未设置表格请求地址')
				return
			}
			request(this.requsetUrl, this.getDataRequestConfig(), this.tableGlobalConfig.requsetType, this.headerConfig).then(res => {
				// 如果设置了手动处理数据 那么会调用方法并返回一个callback
				if (this.tableGlobalConfig.handRequestSetPage) {
					this.$emit('autoPage', res, (data, total) => {
						if (!data || toRawType(data) !== 'Array') {
							return this.$message.error('处理返回值列表类型错误')
						}
						if (this.tablePaginationType !== 'web' && total === undefined) {
							return this.$message.error('处理返回值列表总长度错误')
						}
						this.requsetData = data
						this.total = total || 0
					})
					return
				}
				// 常规处理
				this.requsetData = res.data.list.data
				this.total = res.data.list.total
			})
		},
		// 获取请求参数
		getDataRequestConfig() {
			// 前端分页
			if (this.tablePaginationType === 'web') {
				return Object.assign({}, this.requsetFormData, this.requsetConfig)
			}
			// 后端分页
			if (this.tablePaginationType === 'backstage') {
				const param = {}
				param[this.tablePaginationConfigAuto.page] = this.paginationConfig.currentPage
				param[this.tablePaginationConfigAuto.pageSize] = this.paginationConfig.pagesize
				Object.assign(param, this.requsetConfig, this.requsetFormData)
				return param
			}
		},
		// 表格行按钮点击
		columnClick(row, type) {
			this.$emit('tableColumnClick', row, type)
		},
		// 按钮区域点击
		btnTableClick(type) {
			this.$emit('btnTableClick', type)
		},
		// 表格选择点击
		selectionChange(selection) {
			this.multipleSelection = selection
			this.$emit('selection-change', selection)
		},
		// 分页---size
		handleSizeChange(val) {
			this.paginationConfig.pagesize = val
			if (this.tablePaginationType !== 'web') {
				this.loadPage()
			}
		},
		// 分页---当前页
		handleCurrentChange(val) {
			this.paginationConfig.currentPage = val
			if (this.tablePaginationType !== 'web') {
				this.loadPage()
			}
		},
		// 表单查询
		search(data) {
			this.requsetFormData = data
			this.loadPage()
		},
		// 表单重置
		refresh(data) {
			this.requsetFormData = data
			this.loadPage()
		},
		/* 供外部调用的方法 */

		// 获取已选中数据
		getMultipleSelection() {
			return this.multipleSelection
		},
		// 手动设置数据
		setPage(data) {
			this.requsetData = data
		},

		/* 转发原生事件 */
		clearSelection() {
			this.$refs.oneTableAuto.clearSelection()
		},
		toggleRowSelection(row, selected) {
			this.$refs.oneTableAuto.toggleRowSelection(row, selected)
		},
		toggleAllSelection() {
			this.$refs.oneTableAuto.toggleAllSelection()
		},
		toggleRowExpansion(row, expanded) {
			this.$refs.oneTableAuto.toggleRowExpansion(row, expanded)
		},
		setCurrentRow(row) {
			this.$refs.oneTableAuto.setCurrentRow(row)
		},
		clearSort() {
			this.$refs.oneTableAuto.clearSort()
		},
		clearFilter(columnKey) {
			this.$refs.oneTableAuto.clearFilter(columnKey)
		},
		doLayout() {
			this.$refs.oneTableAuto.doLayout()
		},
		sort(prop = '', order = '') {
			this.$refs.oneTableAuto.sort(prop, order)
		}
	}
}
</script>
<style>
/* 为什么不用sass？  就这几行样式引入个依赖划不来 */
#one-table {
	height: 100%;
	width: 100%;
	justify-content: center;
	align-items: center;
}
.pagination_init {
	margin-top: 10px;
}
/* 全局统一的搜索栏样式 */
.table_operation_or_search {
	margin-bottom: 10px;
}
.table_operation_or_search-right {
	float: left;
	margin-bottom: 10px;
}
.table_operation_or_search-left {
	float: right;
}
.table-col-options-button {
	display: inline-block;
	margin-left: 10px;
}
.table-image-column {
	width: 100px;
	height: 100px;
}
</style>
