gaoluyang
2026-06-02 7c2cdcbc7f5585b96fba76a07b0e4417a09c4d7e
src/hooks/usePaginationApi.jsx
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,145 @@
import { ref, reactive, watchEffect, unref } from "vue";
import useFormData from "@/hooks/useFormData";
import { deepClone, isEqual } from "@/utils/index.js"
import { ElMessage } from 'element-plus'
/**
 * åˆ†é¡µapi
 * @param api æŽ¥å£
 * @param initalFilters åˆå§‹åŒ–筛选条件
 * @param sorters
 * @param filterTransformer
 */
export function usePaginationApi(
  api,
  initalFilters,
  columns,
  sorters,
  filterTransformer,
  cb
) {
  const dataList = ref([]);
  const { form: filters, resetForm } = useFormData(initalFilters);
  let lastFilters = deepClone(initalFilters);
  const sorter = reactive(sorters || {});
  const others = ref({});
  const loading = ref(true);
  const paginationAlign = ref("right");
  /** åˆ†é¡µé…ç½® */
  const pagination = reactive({
    pageSize: 100,
    currentPage: 1,
    pageSizes: [10, 15, 20],
    total: 0,
    align: "right",
    background: true
  });
  /** åŠ è½½åŠ¨ç”»é…ç½® */
  const loadingConfig = reactive({
    text: "正在加载第一页...",
    viewBox: "-10, -10, 50, 50",
    spinner: `
        <path class="path" d="
          M 30 15
          L 28 17
          M 25.61 25.61
          A 15 15, 0, 0, 1, 15 30
          A 15 15, 0, 1, 1, 27.99 7.5
          L 15 15
        " style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
      `
    // svg: "",
    // background: rgba()
  });
  function getFinalParams() {
    const finalFilters = {};
    const beforeParams = unref(filters);
    if (filterTransformer) {
      Object.keys(beforeParams).forEach(key => {
        if (filterTransformer[key]) {
          Object.assign(
            finalFilters,
            filterTransformer[key](beforeParams[key], beforeParams)
          );
        } else {
          finalFilters[key] = beforeParams[key];
        }
      });
    }
    return filterTransformer
      ? { ...finalFilters, ...sorter }
      : { ...beforeParams, ...sorter };
  }
  async function getTableData() {
    // å¦‚果这次和上次的filter不同,那么就重置页码
    if (!isEqual(unref(filters), lastFilters)) {
      pagination.currentPage = 1;
      lastFilters = deepClone(unref(filters));
    }
    loading.value = true;
    api({
      ...getFinalParams(),
      current: pagination.currentPage,
      size: pagination.pageSize
    }).then(({ code, data, msg, ...rest }) => {
      if (code == 200) {
        // pagination.currentPage = meta.current_page;
        // pagination.pageSize = meta.per_page;
        pagination.total = data.total;
        others.value = rest;
        dataList.value = data.records;
        cb && cb(data);
        loading.value = false;
      } else {
        loading.value = false;
        ElMessage({ message: msg, type: "error" });
      }
    });
  }
  function onSizeChange(val) {
    pagination.pageSize = val;
    pagination.currentPage = 1;
    getTableData();
  }
  function onCurrentChange(val) {
    loadingConfig.text = `正在加载第${val}页...`;
    loading.value = true;
    getTableData();
  }
  function resetFilters() {
    resetForm();
    pagination.currentPage = 1;
    getTableData();
  }
  watchEffect(() => {
    pagination.align = paginationAlign.value
  });
  // onMounted(() => {
  //   getTableData();
  // });
  return {
    loading,
    columns,
    dataList,
    pagination,
    loadingConfig,
    paginationAlign,
    filters,
    sorter,
    others,
    onSizeChange,
    onCurrentChange,
    getTableData,
    resetFilters
  };
}