import React, { PureComponent } from "react"; import { PullToRefresh, ListView } from "antd-mobile"; import LoadingFooter from "./LoadingFooter"; import ProCard from "@ant-design/pro-card"; import { postFetch } from "@/utils/doFetch"; import { Row, Col, Tabs, Drawer, Empty } from "antd"; import { SearchOutlined } from "@ant-design/icons"; import InitForm from "../InitForm"; const { TabPane } = Tabs; class Mcard extends PureComponent { constructor(props) { super(props); const dataSource = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2, }); this.state = { visible: false, dataSource, isLoading: true, scrolltop: 0, refreshing: false, fields: {}, searchlist: [], dataArr: props.dataSource || [], isEmpty: false, params: { pageIndex: 1, ...props.extraparams, }, }; } //获取一段分页数据 getsectiondata(np) { let { path, dataSource } = this.props || np; if (!path) { this.setState({ dataSource: dataSource ? this.state.dataSource.cloneWithRows(dataSource) : this.state.dataSource, isLoading: false, refreshing: false, isEmpty: this.state.dataArr.length == 0, }); return; } else { let postparams = this.state.params; if (this.props.pagination == "false" || this.props.pagination === false) { delete postparams.pageIndex; delete postparams.pageSize; } postFetch({ url: path, params: postparams }).then((res) => { if (!res.data) { return; } let list = res.data?.page?.list || res.data.dataList; list = list ? list : []; let dataArr = this.state.dataArr.concat(list); this.setState({ dataSource: this.state.dataSource.cloneWithRows(dataArr), isLoading: false, refreshing: false, hasMore: res?.data?.page?.hasnextpage, dataArr, isEmpty: this.state.params.pageIndex == 1 && list.length == 0, }); }); } } getfields() { let fields = {}, { columns } = this.props, searchlist = columns.filter( (it) => it.search !== false && it.option != "option" && it.key ); searchlist.map((it) => { let key = ""; if (it?.formItemProps?.name) { key = it.formItemProps.name; } else { key = it.key; } let valuetype = it.valueType ? it.valueType : "input", picker = "", format = "YYYY-MM-DD"; if (valuetype == "dateMonth") { valuetype = "datepicker"; picker = "month"; format = "YYYY-MM"; } fields[key] = { value: it.initialValue || this.state.params[key], type: valuetype, title: it?.title, name: [key], col: { span: 24 }, //栅格布局 默认 12 linked: it.linked, belinked: it.belinked, options: it.options, picker: picker, format: format, }; }); this.setState({ fields, searchlist, }); } componentDidMount() { this.getsectiondata(); this.getfields(); this.props.onRef && this.props.onRef(this); } componentWillReceiveProps(np) { np.onRef && np.onRef(this); if ( this.props.path != np.path || JSON.stringify(this.props.extraparams) != JSON.stringify(np.extraparams) || JSON.stringify(this.props.dataSource) != JSON.stringify(np.dataSource) ) { this.lv.scrollTo(0); this.setState( { hasMore: true, dataArr: np.dataSource || [], params: { pageIndex: 1, ...np.extraparams, }, }, () => { this.onRefresh(np); } ); } if (this.props.vs != np.vs) { this.onRefresh(np); } if (this.props.columns != np.columns) { this.getfields(); } } onRefresh = (np, searchdata) => { let extraparams = np ? np.extraparams : this.props.extraparams; searchdata = searchdata || {}; this.setState( { refreshing: true, isLoading: true, hasMore: true, dataArr: [], params: { pageIndex: 1, ...extraparams, ...searchdata, }, }, () => { this.getsectiondata(np); } ); }; onEndReached = (event) => { if (this.state.isLoading || !this.state.hasMore) { return; } let pageIndex = this.state.params.pageIndex + 1; this.setState( { isLoading: true, params: { pageIndex, }, }, () => { this.getsectiondata(); } ); }; render() { let { scrolltop, dataSource, isLoading, refreshing, hasMore, isEmpty, visible, fields, searchlist, } = this.state, { columns, cardtitle, cardavatar, pagetitle, pageextra, onSearchChange, tabBarExtraContent, onTabChange, tabList, } = this.props; return ( <div style={{ height: "100%" }}> <div className="fixedsearch"> {searchlist.length > 0 && ( <div className="action" onClick={() => { this.setState({ visible: true, }); }} > <SearchOutlined style={{ color: "#fff" }} /> </div> )} {pageextra && pageextra.length > 0 && pageextra.map((it) => { return <div>{it}</div>; })} </div> <Drawer visible={visible} title={"输入您的查询条件"} onClose={() => { this.setState({ visible: false, }); }} closable={true} > <InitForm fields={fields} onChange={() => {}} reset={true} submitData={(values) => { this.onRefresh(this.props, values); this.setState({ visible: false, }); onSearchChange(values); }} ></InitForm> </Drawer> <ListView ref={(el) => (this.lv = el)} dataSource={dataSource} renderHeader={() => { return pagetitle ? ( <div className="pagetitle"> <p style={{ marginBottom: 12 }} className="spacebt"> {pagetitle} {!tabList && tabBarExtraContent} </p> <Tabs style={{ width: "100%" }} onChange={onTabChange} tabBarExtraContent={tabBarExtraContent} > {tabList && tabList.map((it) => { return <TabPane tab={it.tab} key={it.key}></TabPane>; })} </Tabs> </div> ) : null; }} renderFooter={() => ( <LoadingFooter isLoading={isLoading && hasMore} isEmpty={isEmpty} ></LoadingFooter> )} renderRow={(rowData = {}) => { let extrarow = columns.filter( (it) => it.key != cardtitle && it.key != cardavatar && it.option != "option" && it.key ); return ( <ProCard headerBordered style={{ borderRadius: 4, overflow: "hidden" }} title={ <div style={{ display: "flex", justifyContent: "flex-end", alignItems: "center", }} > {cardavatar && columns .filter((it) => it.key == cardavatar)[0] ?.render(null, rowData)} <span className="oneline" style={{ marginLeft: cardavatar ? 12 : 0, color: "#1890ff", maxWidth: 300, }} > {rowData[cardtitle ? cardtitle : columns[0].key]} </span> </div> } actions={ columns.filter((it) => it.valueType == "option").length == 0 ? null : columns .filter((it) => it.valueType == "option")[0] ?.render(null, rowData, null, { type: "text" }) } > <Row> {extrarow.map((it) => { return ( <Col span={24} key={it.key} style={{ display: "flex", justifyContent: "space-between", margin: "6px 0", }} > <div style={{ display: "inline-block", flexShrink: 0 }}> {it?.title} </div> <div style={{ color: "#999", flex: 1, overflow: "hidden", textAlign: "right", wordBreak: "break-all", }} > {it.render ? it.render(null, rowData) : rowData[it.key]} </div> </Col> ); })} </Row> </ProCard> ); }} renderSeparator={(sectionID, rowID) => ( <div key={`${sectionID}-${rowID}`} style={{ backgroundColor: "transparent", height: 12, }} /> )} style={{ overflow: "auto", height: "100%", minHeight: "70vh", }} className={scrolltop > 0 ? "notrans" : "trans"} pageSize={10} onScroll={(e) => { this.setState({ scrolltop: e.target.scrollTop, }); if (e.target.scrollTop > 400) { } else { } }} scrollRenderAheadDistance={800} distanceToRefresh={window.devicePixelRatio * 25} onEndReached={this.onEndReached} onEndReachedThreshold={10} pullToRefresh={ <PullToRefresh refreshing={refreshing} onRefresh={this.onRefresh} /> } /> </div> ); } } export default Mcard;