<template>
	<view class="yTable" :style="{ height: props.height }">
		<wd-toast />
		<kevyloading v-if="loading" type="bsm-loader" color="#618af8" transparent></kevyloading>
		<scroll-view scroll-y="true" class="scroll-Y" :style="{ height: props.height }" @scrolltolower="lower">
			<slot :list="list"></slot>

			<view v-show="firstLoading" v-if="list.length == 0">
				<wd-status-tip image="search" tip="暂无数据 ~" />
			</view>
		</scroll-view>
	</view>
</template>

<script setup>
import { ref } from 'vue';
import kevyloading from "@/components/kevy-loading/kevy-loading";
import { useToast } from '@/uni_modules/wot-design-uni';
const toast = useToast()

/**
 * @typedef {Object} ApiObjResponse
 * @property {Object} data - 响应数据对象。
 * @property {Array} data.rows - 数据行。
 * @property {number} data.pageSize - 每页条目数。
 * @property {number} data.total - 总条目数。
 */

/**
 * @typedef {Object} Props
 * @property {Function} apiObj - 用于获取数据的 API 函数。
 * @property {Object} params - API 调用的附加参数。
 * @property {String} height - 组件的高度。
 */

/**
 * @typedef {Object} Query
 * @property {number} page - 当前页数。
 * @property {number} pageSize - 每页条目数。
 */

/**
 * 主要组件逻辑。
 * 
 * @param {Props} props - 组件属性。
 */
const props = defineProps({
	apiObj: {
		type: Function,
		default: () => (() => { })
	},
	params: {
		type: Object,
		default: () => ({})
	},
	height: {
		type: String,
		default: "100vh"
	}
});

/** @type {Query} */
const query = ref({
	page: 1,
	pageSize: 20
});

/** @type {Ref<boolean>} */
const loading = ref(false);

/** @type {Ref<boolean>} */
const firstLoading = ref(false);

const total = ref(0)
const list = ref([])

/**
 * 获取数据的函数。
 * 
 * @returns {Promise<void>} - 异步函数。
 */
const getData = async () => {
	loading.value = true;
	const res = await props.apiObj({
		...query.value,
		...props.params
	});

	if (res.data.rows.length) {
		query.value.pageSize = res.data.pageSize;
		total.value = res.data.total;
		list.value = [...list.value, ...res.data.rows];
	} else {
		toast.success('全部加载完了');
	}

	loading.value = false;
	firstLoading.value = true;
};

getData();

/**
 * 更新数据的函数。
 * 
 * @param {Object} upParams - 更新参数。
 * @returns {Promise<void>} - 异步函数。
 */
const upData = async (upParams = {}) => {
	loading.value = true;
	query.value.page = 1;
	query.value.pageSize = 20;

	const res = await props.apiObj({
		...query.value,
		...props.params,
		...upParams
	});

	query.value.pageSize = res.data.pageSize;
	total.value = res.data.total;
	list.value = res.data.rows;

	loading.value = false;
};

/**
 * 下拉刷新时触发的函数。
 * 
 * @param {Event} e - 下拉事件对象。
 */
const lower = e => {
	query.value.page++;
	getData();
};

/**
 * 暴露组件的函数。
 */
defineExpose({
	upData
});

</script>

<style lang="scss">
.yTable {
	display: flex;
	overflow: hidden;
}

.scroll-Y {
	height: 100%;
}
</style>
