react做表格和分页功能

import React, { memo, useState, useEffect } from "react";
import { Table, Pagination } from "antd";
import { IDefaultParam } from "../topFilter/topFilter";
import BaseModal from "components/BaseModal/BaseModal";
import Message from "components/Message/Message";
import Nodata from "components/Nodata/Nodata";
import { useStore } from "store/appStore";
import { landUseAction, landUseStore } from "store/agriculturlLandStore/appStore";
import Service from "../../Service";
import mtStyle from "./mainTable.module.less";

const PAGESIZE_OPTIONS = ["20", "50", "100"];

interface IColumns {
  title: string | (() => React.ReactNode),
  dataIndex: string,
  key: string,
  className?: string,
  width?: number,
  fixed?: boolean | "left" | "right",
  render?: (text: any, record: any, index: number) => React.ReactNode
}

const MainTbale: React.FC<{ style?: any, param: IDefaultParam }> = ({ style, param }) => {

  const landstore = landUseStore();
  const monitorAction = landUseAction();

  const store = useStore();
  const rootFontSize = store.rootFontSize;
  const [loading, setLoading] = useState(false);
  const [pageNo, setpageNo] = useState(1);
  const [pageSize, setPageSize] = useState(20);
  const [totalCount, setTotalCount] = useState(0);
  const [dataSource, setDataSource] = useState<any[]>([]);
  const [isShow, setIsShow] = useState<boolean>(false);
  const [pointCode, setPointCode] = useState<string>("");
  const [authLists, setAuthLists] = useState(() => {
    return store.menuMap[window.location.pathname] || [];
  });

  useEffect(() => {
    setAuthLists(store.menuMap[window.location.pathname] || []);
  }, [JSON.stringify(store.menuMap)]);
  const formatData = (vl: string | number | null) => {
    return (vl || vl === 0) ? `${vl}` : "--";
  };

  const columns: IColumns[] = [
    {
      title: "序号",
      dataIndex: "number",
      key: "number",
      fixed: "left",
      width: rootFontSize,
      render: (text: any, record: any, index: number) => <span>{(index + 1) + (pageNo - 1) * pageSize}</span>
    },
    {
      title: "块块编码",
      dataIndex: "plotCode",
      key: "plotCode",
      className: "truncated col-plotCode",
      fixed: "left",
      width: 1.5 * rootFontSize,
      render: (text: string) => <div title={formatData(text)}>{formatData(text)}</div>
    },
    {
      title: "地块名称",
      dataIndex: "plotName",
      key: "plotName",
      className: "truncated col-plotName",
      fixed: "left",
      width: 2.2 * rootFontSize,
      render: (text: string) => <div title={formatData(text)}>{formatData(text)}</div>
    },
    {
      title: "用地类型",
      dataIndex: "landTypeName",
      key: "landTypeName",
      width: 1.5 * rootFontSize,
      render: (text: string) => <div>{formatData(text)}</div>
    },
    {
      title: "所属区域",
      dataIndex: "regionName",
      key: "regionName",
      width: 1.2 * rootFontSize,
      render: (text: string) => <div>{formatData(text)}</div>
    },
    {
      title: "调查时间",
      dataIndex: "surveyTime",
      key: "surveyTime",
      width: 1.6 * rootFontSize,
      render: (text: string) => <div>{formatData(text)}</div>
    },
    {
      title: "地块面积(m²)",
      dataIndex: "plotArea",
      key: "plotArea",
      width: 1.6 * rootFontSize,
      render: (text: string) => <div>{formatData(text)}</div>
    },
    {
      title: "地块详查结果",
      dataIndex: "surveyResultTypeName",
      key: "surveyResultTypeName",
      width: 1.8 * rootFontSize,
      render: (text: string) => <div title={formatData(text)}>{formatData(text)}</div>
    },
    {
      title: "超标污染物",
      dataIndex: "polluteNames",
      key: "polluteNames",
      width: 1.7 * rootFontSize,
      render: (text: string, record: any) => <div title={record.surveyResultType === 1 ? "无" : formatData(record.polluteNames)}>{record.surveyResultType === 1 ? "无" : formatData(record.polluteNames)}</div>
    },
    {
      title: "管理要求",
      dataIndex: "managementRequirements",
      key: "managementRequirements",
      className: "truncated",
      width: 1.8 * rootFontSize,
      render: (text: string) => <div title={formatData(text)}>{formatData(text)}</div>
    },
    {
      title: "操作",
      dataIndex: "operate",
      key: "operate",
      render: (text: any, record: any, index: number) => {
        return <div className={mtStyle.btnCon}>
          <span onClick={() => browse(record, "looking")}>查看</span>
          {authLists.some((item: any) => item.description === "edit") && <span onClick={() => setEdit(record, "edit")}>编辑</span>}
          {authLists.some((item: any) => item.description === "delete") && <span onClick={() => deleteCode(record)}>删除</span>}
        </div>;
      }
    },
  ];
  const onPageChange = (pageNumber: number) => {
    setpageNo(pageNumber);
    getData(pageNumber);
  };
  const pageSizeChange = (current: number, size: number) => {
    setPageSize(size);
  };
  const browse = (record: any, type: string) => {
    monitorAction.setMonitorPointTopicsSelectType({ type: type, isShow: true, data: record, isRefresh: false });
  };

  const setEdit = async (record: any, type: string) => {
    const res = await Service.getPlotDetail({ plotCode: record.plotCode });
    monitorAction.setMonitorPointTopicsSelectType({ type: type, isShow: true, data: (res || []), isRefresh: false });
  };

  const deleteCode = async (record: any) => {
    setIsShow(!isShow);
    setPointCode(record.plotCode);
  };

  useEffect(() => {
    setpageNo(1);
    getData(1);
  }, [param, pageSize]);

  useEffect(() => {
    if (landstore.selectObj.type === "export") {
      getExport();
    }
  }, [landstore.selectObj.type]);

  useEffect(() => {
    if (landstore.selectObj.isRefresh) {
      getData(1);
    }
  }, [landstore.selectObj.isRefresh]);

  const getData = async (pageNo?: number) => {
    if (!pageNo || !pageSize || !param.regionCode) return;
    setLoading(true);
    setDataSource([]);
    const par = {
      regionCode: param.regionCode === "440300000000" ? null : param.regionCode,
      regionTypeList: param.subCode,
      surveyResultTypeList: param.detaileCode,
      currentPage: pageNo,
      pageSize
    };
    const res = await Service.getPage(par);
    setTotalCount(res.totalCount || 0);
    setDataSource(res.data || []);
    setLoading(false);
    let IsLength = res.data && res.data.length ? true : false;
    monitorAction.setDataListLength(IsLength);
  };

  const getExport = async () => {
    if (!pageNo || !pageSize || !param.regionCode) return;
    const par = {
      regionCode: param.regionCode === "440300000000" ? null : param.regionCode,
      regionTypeList: param.subCode,
      surveyResultTypeList: param.detaileCode,
      currentPage: pageNo,
      pageSize
    };
    const res = await Service.getPageExport(par);
    if (res) {
      Message.success("导出成功", 3);
      window.open(res, "self");
    } else {
      Message.error("导出失败", 3);
    }
    monitorAction.setMonitorPointTopicsSelectType({ type: "", isShow: false });
  };

  const handCancel = () => {
    setIsShow(!isShow);
    setPointCode("");
  };

  const handConfirm = async () => {
    let param = {
      plotCode: pointCode
    };
    const res = await Service.getPlotDelete(param);
    if (res) {
      Message.success("删除成功", 3);
      getData(1);
    } else {
      Message.error("删除失败", 3);
    }
    setIsShow(!isShow);
    setPointCode("");
  };


  return (
    <div className={mtStyle.wrapper}>
      <Table
        rowKey={(record: any, i: number) => `${record.linkCode}_${i}`}
        columns={columns}
        dataSource={dataSource || []}
        pagination={false}
        className={`${mtStyle.PointCntTable} reset-table auto-scroll-y`}
        scroll={{ x: "17.68rem", y: "auto" }}
        loading={loading}
        locale={{
          emptyText: () => {
            return !loading ? <Nodata /> : null;
          }
        }}
      />
      <div className={mtStyle.pageCon}>
        <Pagination
          current={pageNo}
          pageSize={pageSize}
          total={totalCount}
          showTotal={(total: number) => `共${total}条`}
          pageSizeOptions={PAGESIZE_OPTIONS}
          showSizeChanger
          showQuickJumper
          className="reset-ant-pagination"
          onChange={onPageChange}
          onShowSizeChange={pageSizeChange}
        />
      </div>
      <BaseModal
        visible={isShow}
        onCancel={handCancel}
        footer={null}
        width="3.5rem"
        wrapClassName="pointModal"
        centered={true}
      >
        <div className={mtStyle.moadlTitle}>是否确认删除</div>
        <div className={mtStyle.btn}>
          <div className="cancel-btn" onClick={handCancel}>取消</div>
          <div className="add-btn" onClick={handConfirm}>确定</div>
        </div>
      </BaseModal>
    </div>
  );
};

export default memo(MainTbale);

topFilter

import React, { useState, useEffect, memo } from "react";
import { Popover } from "antd";
import { useStore } from "store/appStore";
import BaseSelect, { Option } from "components/BaseSelect/baseSelect";
import { getReginonList } from "../../../SoilMonitNetMana/components/mapContent/service";
import { detailedRes } from "./filter-consts";
import AntMulSelect from "components/AllAntMulSelect/AllAntMulSelect";
import LandTree from "./landTree";
import LayerTree from "./layerTree";
import SearchPoint from "./SearchPoint";
import { IClickType } from "../../AgriculturalLand.d";
import { landUseStore } from "store/agriculturlLandStore/appStore";
import tStyle from "./topFilter.module.less";

export interface IDefaultParam {
  regionCode: string
  subCode: string[]
  detaileCode: string[]
  plateCode: string
  searchValue: string
}

export let defaultParam: IDefaultParam = {
  regionCode: "",
  subCode: ["07", "05", "06"],
  detaileCode: (detailedRes.map((item: any) => item.code)),
  plateCode: "",
  searchValue: ""
};

export interface IProps {
  changeActiveTab: (active: number) => void,
  changeFilterParam: (vl: IDefaultParam) => void
  onAdd: (obj: IClickType) => void,
  onExport: (obj: IClickType) => void,
  style?: any;
}

const TopFilter: React.FC<IProps> = (props) => {
  const store = useStore();
  const IsList = landUseStore();  // IsList.dataLength判断表格是否有数据(true表示无数据)

  const [activeTab, setActiveTab] = useState(1);
  const [filtParam, setFilterParam] = useState(defaultParam);
  const [regionList, setRegionList] = useState<any[]>([]);
  const [showItem, setShowItem] = useState(true);

  const [authLists, setAuthLists] = useState(() => {
    return store.menuMap[window.location.pathname] || [];
  });

  useEffect(() => {
    setAuthLists(store.menuMap[window.location.pathname] || []);
  }, [JSON.stringify(store.menuMap)]);

  useEffect(() => {
    (async () => {
      const res = await getReginonList();
      const code = res && res[0] ? res[0].regionCode : "";
      defaultParam = {
        ...defaultParam,
        regionCode: code
      };
      setRegionList(res || []);
      setFilterParam((pra: IDefaultParam) => ({
        ...pra,
        regionCode: code
      }));
    })();
  }, []);

  useEffect(() => {
    props.changeActiveTab && props.changeActiveTab(activeTab);
  }, [activeTab]);

  useEffect(() => {
    props.changeFilterParam && props.changeFilterParam(filtParam);
  }, [JSON.stringify(filtParam)]);

  const changeTab = (n: number) => {
    if (n === activeTab) return;
    if (n === 1) {
      setShowItem(true);
    } else {
      setShowItem(false);
    }
    setActiveTab(n);
  };

  const changeParam = (val: any, type: string) => {
    setFilterParam((par: IDefaultParam) => ({
      ...par,
      [type]: val
    }));
    if (type === "searchValue") {
      setFilterParam((prev: IDefaultParam) => ({
        ...prev,
        [type]: (val.includes("_") ? val.split("_")[1] : val)
      }));
    }
  };

  const addContent = () => {
    props.onAdd && props.onAdd({ type: "add", isShow: true });
  };

  const exportContent = () => {
    if (!IsList.dataLength) return;
    props.onExport && props.onExport({ type: "export", isShow: false });
  };

  return (
    <div className={tStyle.wrapper} style={props.style}>
      <div className={tStyle.mapSwitch}>
        <Popover
          placement="bottom"
          content="地图概览"
          trigger="hover"
          overlayClassName="restet-map-over-lay"
        ><div className={activeTab ? tStyle.selected : ""} onClick={() => changeTab(1)}><i className="iconfont paicon-map" /></div></Popover>
        <Popover
          placement="bottom"
          content="地块列表"
          trigger="hover"
          overlayClassName="restet-map-over-lay"
        ><div className={!activeTab ? tStyle.selected : ""} onClick={() => changeTab(0)}><i className="iconfont paicon-table_list" /></div></Popover>
      </div>
      <div className={tStyle.filterOpts}>
        <div className={tStyle.selOpts}>
          <div style={{ flexBasis: "1.6rem" }}>
            <BaseSelect
              value={filtParam.regionCode || undefined}
              onChange={(vl: any) => changeParam(vl, "regionCode")}
            >
              {(regionList || []).map((item: any) => {
                return (
                  <Option
                    key={item.regionCode}
                    title={item.regionName}
                    value={item.regionCode}
                  >
                    {item.regionName}
                  </Option>
                );
              })}
            </BaseSelect>
          </div>
          <div style={{ flexBasis: "2.1rem" }}>
            <LandTree changeCheck={(vl: any) => changeParam(vl, "subCode")} className="filterlandTree" />
          </div>
          <div style={{ flexBasis: "2.1rem" }}>
            <AntMulSelect
              optionList={(detailedRes || [])}
              value={filtParam.detaileCode}
              onChange={(vl: any) => changeParam(vl, "detaileCode")}
              allLabel="地块详查结果(全部)"
            />
          </div>
          {
            showItem && <div style={{ flexBasis: "2.1rem" }}>
              <LayerTree onChange={(vl: any) => changeParam(vl, "plateCode")} />
            </div>
          }
        </div>
        <div className={tStyle.pointSearch}>
          {
            showItem && (
              <SearchPoint
                className={tStyle.mapFilterWrapper}
                changeName={(vl: any) => changeParam(vl, "searchValue")}
                code={filtParam.subCode}
                placeholderText="地块关键字检索"
                searchKeyWord="searchValue"
              />
            )
          }
        </div>
        <div className={tStyle.btn}>
          {!showItem && (
            <div className={tStyle.btnGroups}>
              {authLists.some((item: any) => item.description === "add") && <div onClick={addContent} className={tStyle.addBtn}>新增</div>}
              <div onClick={exportContent} className={`${tStyle.export} ${!IsList.dataLength && tStyle.noData}`}>导出</div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

export default memo(TopFilter);

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页