【后台管理系统】—— Ant Design Pro页面相关(一)

一、List列表形式

import React, { PureComponent } from 'react';
import { findDOMNode } from 'react-dom';
import moment from 'moment';
import { connect } from 'dva';
import {
  List,
  Card,
  Radio,
  Input,
  Button,
  Icon,
  Modal,
  Form,
  Select,
  Cascader,
  TreeSelect
} from 'antd';


@connect(({ course, loading }) => ({
  course,
  loading: loading.models.fetch,
}))
@Form.create()
class CourseList extends PureComponent {

   state = {  // 省略 }

   // 页面方法

   render() {

       //页面展示数据
       const {
           course: { list, page, typeList },
           loading,
       } = this.props;

       // Form表单相关方法
       const {
          form: { getFieldDecorator, getFieldError, isFieldTouched },
       } = this.props;

       const {  // 省略  } = this.state;

       // 弹框操作方法、数据处理方法  

       // 分页组件参数
       const paginationProps =
             Object.keys(page).length ? {
                   showSizeChanger: true,
                   showQuickJumper: true,
                   current: page.currentPage,
                   pageSize: page.showCount,
                   total: page.totalResult,
                   onChange: this.handlePage,
                   onShowSizeChange: this.handlePage
             } : null;

        // 添加分类弹框 - 向子组件传递需要调用的父组件的方法
        const addTypeMethods = {
             handleAddType: this.handleAddType,
             cancelAddType: this.cancelAddType,
        };

        const updTypeMethods = {  // 省略  };

        const delTypeMethods = {   // 省略  };

        // 所有删除按钮 必须加的 确认删除弹框
        const Delete = (currentItem) => {
              Modal.confirm({
                    title: '删除教程',
                    content: `确定删除教程《${currentItem.title}》吗?`,
                    okText: '确认',
                    cancelText: '取消',
                    onOk: () => this.deleteItem(currentItem.id),
              });
       };
      
      // 卡片Card右上角内容 - 按钮、触发的弹框
      const extraContent = (
      <div className={styles.extraContent} style={{display: 'inline-block'}}>
        <Cascader fieldNames={{ label: 'name', value: 'id', children: 'kinds' }}
                  options={typeList}
                  onChange={this.handleTypeSearch}
                  className={styles.extraContentCascader}
                  expandTrigger="hover"
                  placeholder="请选择类别"
                  changeOnSelect />
        <Search className={styles.extraContentSearch}
                placeholder="请输入关键字"
                onSearch={(e) => this.handleSearch(e)} />
        <Button type="primary" onClick={this.showAddType} style={{marginRight: 16}}>添加分类</Button>
        <Button type="primary" onClick={this.showUpdType} style={{marginRight: 16}}>编辑分类</Button>
        <Button type="primary" onClick={this.showDelType}>删除分类</Button>
        <AddType {...addTypeMethods}
                 typeList={typeList}
                 formLayout={this.formLayout}
                 addTypeVisible={this.state.addTypeVisible} />
        <UpdType {...updTypeMethods}
                 typeList={typeList}
                 pTypeList={pTypeList}
                 formLayout={this.formLayout}
                 pidDisable={this.state.pidDisable}
                 updTypeVisible={this.state.updTypeVisible} />
        <DelType {...delTypeMethods}
                 typeList={typeList}
                 formLayout={this.formLayout}
                 delTypeVisible={this.state.delTypeVisible} />
      </div>
    );

       // 添加 - 编辑 共用的弹框Footer
       const modalFooter = done
              ? { footer: null, onCancel: this.handleDone }
              : { okText: '保存', onOk: this.handleSubmit, onCancel: 
       this.handleCancel };

       // 列表内容 - 样式型子组件
       const ListContent = ({ data: { optCreateUser, optCreateTime } }) => (
             <div className={styles.listContent}>
                  <div className={styles.listContentItem}>
                  <span>Owner</span>
                  <p>{optCreateUser}</p>
             </div>
             <div className={styles.listContentItem}>
                  <span>创建时间</span>
                  <p>{moment(optCreateTime).format('YYYY-MM-DD HH:mm')}</p>
             </div>
      </div>
    );

     // 添加 - 编辑 公用的教程弹框 和 方法 
     const getModalContent = () => { // 省略 };


    return (
      <PageHeaderWrapper>
        <div className={styles.standardList}>
          <Card
            className={styles.listCard}
            bordered={false}
            title="教程管理"
            style={{ marginTop: 24 }}
            bodyStyle={{ padding: '0 32px 40px 32px' }}
            extra={extraContent}
          >
            <Button
              type="dashed"
              style={{  '100%', marginBottom: 8 }}
              icon="plus"
              onClick={this.showModal}
              ref={component => {
                /* eslint-disable */
                this.addBtn = findDOMNode(component);
                /* eslint-enable */
              }}
            >
              添加
            </Button>
            <List
              size="large"
              rowKey="id"
              loading={loading}
              pagination={paginationProps}
              dataSource={list}
              renderItem={item => (
                <List.Item
                  actions={[
                    <a
                      onClick={e => {
                        e.preventDefault();
                        this.showEditModal(item);
                      }}
                    >
                      编辑
                    </a>,
                    <a
                      onClick={e => {
                        e.preventDefault();
                        Delete(item);
                      }}
                      style={{color:'red'}}
                    >
                      删除
                    </a>
                  ]}
                >
                  <List.Item.Meta
                    title={<a onClick={() => this.handleFullText(item)}>{item.title}<Icon type="eye" style={{marginLeft: 15, color: '#1890FF'}} /></a>}
                  />
                  <ListContent data={item} />
                </List.Item>
              )}
            />
          </Card>
        </div>
        <Modal
          visible={fullVisible}
          footer={null}
          title={textTitle}
          width={375}
          bodyStyle={{height: 667, overflow: 'auto'}}
          onCancel={this.handlefullCancel}
          >
            <div
                className={styles.textContent}
                dangerouslySetInnerHTML = {{__html:textContent}}>
            </div>
        </Modal>
        <Modal
          visible={previewVisible}
          footer={null}
          title="正文预览"
          width={375}
          bodyStyle={{height: 667, overflow: 'auto'}}
          onCancel={this.cancelPreview}
          >
            <div
                className={styles.textContent}
                dangerouslySetInnerHTML = {{__html:this.state.editorState.toHTML()}}>
            </div>
        </Modal>
        <Modal
          title={done ? null : `教程${current.id ? '编辑' : '添加'}`}
          className={styles.standardListForm}
          width={1200}
          style={{ top: 0 }}
          bodyStyle={done ? { padding: '56px 0' } : { padding: '28px 0 0' }}
          destroyOnClose
          visible={visible}
          keyboard={false}
          maskClosable={false}
          {...modalFooter}
        >
          {getModalContent()}
        </Modal>
      </PageHeaderWrapper>
    );
  }
} 

二、Table表格形式

无统计无多选表格

无统计有多选表格

有统计有多选表格

import React, { PureComponent, Fragment } from 'react';
import { connect } from 'dva';
import moment from 'moment';
import router from 'umi/router';
import {
  Row,
  Col,
  Card,
  Form,
  Input,
  Select,
  Icon,
  Button,
  Dropdown,
  Menu,
  Modal,
  Badge,
  Divider,
  Steps,
  Radio,
} from 'antd';
import StandardTable from '@/components/StandardTable';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import { trimStr, fenToYuan } from '@/utils/utils'

import styles from './WithDraw.less';

const FormItem = Form.Item;
const { Option } = Select;
const getValue = obj =>
  Object.keys(obj)
    .map(key => obj[key])
    .join(',');
const statusMap = ['processing', 'success', 'error'];
const status = ['审核中', '已打款', '已驳回'];

// 提现 弹框
const PayModal = props => { // 省略 }

// 驳回 弹框
const RefuseModal = props => { //省略 }


/* eslint react/no-multi-comp:0 */
@connect(({ balance, loading }) => ({
  balance,
  loading: loading.models.fetch,
}))
@Form.create()
class WithDraw extends PureComponent {

  state = {
    record: {},                 // 当前行数据对象
    selectedRows: [],           // 多选得到的多行数据对象数组
    // 其它数据 省略
  };


  // title: 表格标题 dataIndex:对应字段
  columns = [
    {
      title: '持卡人姓名',
      dataIndex: 'cardholderName'
    },
    {
      title: '用户手机号',
      dataIndex: 'phone'
    },
    {
      title: '提现人ID',
      dataIndex: 'userId'
    },
    {
      title: '提现金额(元)',
      dataIndex: 'amount',
      render: val => <span>{`${fenToYuan(val)}`}</span>
    },
    {
      title: '提现卡号',
      dataIndex: 'cardCode'
    },
    {
      title: '提现卡图片',
      dataIndex: 'bankImgURL',
      render(val) {
        return <img src={ val ? val : ''} style={{ 100}} />;
      }
    },
    {
      title: '卡号类型代码',
      dataIndex: 'bankCardCode'
    },
    {
      title: '卡号类型',
      dataIndex: 'cardType'
    },
    {
      title: '申请时间',
      dataIndex: 'optCreateTime',
      sorter: true,
      render: val => <span>{moment(val).format('YYYY-MM-DD HH:mm:ss')}</span>,
    },
    {
      title: '处理状态',
      dataIndex: 'status',
      render(val) {
        return <Badge status={statusMap[val]} text={status[val]} />;
      }
    },
    {
      title: '操作',
      render: (text, record) => (
        record.status === 0 ?
        <Fragment>
            <a onClick={() => this.handlePay(record)}>打款</a>
            <Divider type="vertical" />
            <a onClick={() => this.handleRefuse(record)} style={{color:'red'}}>驳回</a>
        </Fragment>
        :
        <Fragment>
            <a disabled>已操作</a>
        </Fragment>
      ),
    },
  ];

  componentDidMount() {
    const { dispatch } = this.props;
    dispatch({
      type: 'balance/fetch',
      payload: {
        currentPage: 1,
        e: {},
        showCount: 10
      }
    });
  }

  // 分页切换表格
  handleStandardTableChange = (pagination, filtersArg, sorter) => {
    const { dispatch } = this.props;
    const { formValues } = this.state;

    const filters = Object.keys(filtersArg).reduce((obj, key) => {
      const newObj = { ...obj };
      newObj[key] = getValue(filtersArg[key]);
      return newObj;
    }, {});

    const params = {
      currentPage: pagination.current,
      e: {},
      showCount: pagination.pageSize,
      ...formValues,
      ...filters,
    };
    if (sorter.field) {
      params.sorter = `${sorter.field}_${sorter.order}`;
    }

    dispatch({
      type: 'balance/fetch',
      payload: params,
    });
  };

  // 表格重置
  handleFormReset = () => {
    const { form, dispatch } = this.props;
    form.resetFields();
    this.setState({
      formValues: {},
    });
    dispatch({
      type: 'balance/fetch',
      payload: {
        currentPage: 1,
        e: {},
        showCount: 10
      },
    });
  };

  // 批量操作按钮
  handleMenuClick = e => {
    const { dispatch } = this.props;
    const { selectedRows } = this.state;

    if (selectedRows.length === 0) return;
    switch (e.key) {
      case 'remove':
        dispatch({
          type: 'rule/remove',
          payload: {
            key: selectedRows.map(row => row.key),
          },
          callback: () => {
            this.setState({
              selectedRows: [],
            });
          },
        });
        break;
      default:
        break;
    }
  };

  // 处理多选对象数组
  handleSelectRows = rows => {
    this.setState({
      selectedRows: rows,
    });
  };

  // 搜索
  handleSearch = e => {
    e.preventDefault();

    const { dispatch, form } = this.props;

    form.validateFields((err, fieldsValue) => {
      if (err) return;

      let values = {
        ...fieldsValue,
        updatedAt: fieldsValue.updatedAt && fieldsValue.updatedAt.valueOf(),
      };

      Object.keys(values).forEach(key => {
        if(values[key]){
          values[key] = trimStr(values[key])
        }
      });

      this.setState({
        formValues: values,
      });

      // console.log(values)

      dispatch({
        type: 'balance/fetch',
        payload: {
          currentPage: 1,
          e: {
            keyword: values.keyword
          },
          showCount: 10
        }
      });
    });
  };

  //  提现 操作方法 省略
 
  //  页面头部表单  搜索 - 重置
  renderSimpleForm() {
    const {
      form: { getFieldDecorator },
    } = this.props;
    return (
      <Form onSubmit={this.handleSearch} layout="inline">
        <Row gutter={{ md: 8, lg: 24, xl: 48 }}>
          <Col md={8} sm={24}>
            <FormItem label="提现人">
              {getFieldDecorator('keyword')(<Input placeholder="请输入关键字" />)}
            </FormItem>
          </Col>
          <Col md={8} sm={24}>
            <FormItem label="状态">
              {getFieldDecorator('paystatus')(
                <Select placeholder="请选择" style={{  '100%' }}>
                  <Option value="0">审核中</Option>
                  <Option value="1">已打款</Option>
                  <Option value="2">已驳回</Option>
                </Select>
              )}
            </FormItem>
          </Col>
          <Col md={8} sm={24}>
            <span className={styles.submitButtons}>
              <Button type="primary" htmlType="submit">
                查询
              </Button>
              <Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}>
                重置
              </Button>
              {/* <a style={{ marginLeft: 8 }} onClick={this.toggleForm}>
                展开 <Icon type="down" />
              </a> */}
            </span>
          </Col>
        </Row>
      </Form>
    );
  }

  render() {
    const {
      balance: { list, page },
      loading,
    } = this.props;

    const { selectedRows, payVisible, refuseVisible, record } = this.state;

    const menu = (
      <Menu onClick={this.handleMenuClick} selectedKeys={[]}>
        <Menu.Item key="remove">删除</Menu.Item>
        <Menu.Item key="approval">批量审批</Menu.Item>
      </Menu>
    );

    list.map((item, index) => {
      item.key = index;
    })

    // 支付驳回弹框props方法
    const payMethods = {……}
    const refuseMethods = {……}

    return (
      <PageHeaderWrapper title="提现记录">
        <Card bordered={false}>
          <div className={styles.tableList}>
            <div className={styles.tableListForm}>{this.renderSimpleForm()}</div>
            <div className={styles.tableListOperator}>
              {/* <Button icon="plus" type="primary" onClick={() => this.handleModalVisible(true)}>
                新建
              </Button> */}
              {/* {selectedRows.length > 0 && ( */}
                <span>
                  <Button>批量操作</Button>
                  <Dropdown overlay={menu}>
                    <Button>
                      更多操作 <Icon type="down" />
                    </Button>
                  </Dropdown>
                </span>
              {/* )} */}
            </div>
            <StandardTable
              selectedRows={selectedRows}     //多选的行对象数组
              loading={loading}
              dataSource={list}
              page={page}
              rowKey={record => record.key}
              columns={this.columns}
              showAlert={true}                   // 是否显示统计提示Alert
              showRowSelection={true}     // 是否显示表格checkbox
              onSelectRow={this.handleSelectRows} //操作多选对象
              onChange={this.handleStandardTableChange}
            />
          </div>
        </Card>
        <PayModal {...payMethods} payVisible={payVisible} record={record}/>
        <RefuseModal {...refuseMethods} refuseVisible={refuseVisible} record={record}/>

      </PageHeaderWrapper>
    );
  }
}

export default WithDraw;

引用的StandardTable原生组件:从props中获得page对象,修改paginationProps完善表格的分页功能,依据showAlert和showRowSelection显示与执行不同操作

 render() {
    const { selectedRowKeys, needTotalList } = this.state;
    const { page, rowKey, ...rest } = this.props;
    let { currentPage, totalResult } = page;
    const list=[];

    
    let paginationProps = page ? {
       showSizeChanger: true,
       showQuickJumper: true,
       current: currentPage,
       total: totalResult,
       // pageSize: showCount,
       onShowSizeChange: handleShowSize
    } : false;

  
    return (
      <div className={styles.standardTable}>
         { this.props.showAlert ?
            <div className={styles.tableAlert}>
              <Alert
                message={
                  <Fragment>
                    已选择 <a style={{ fontWeight: 600}}>{selectedRowKeys.length}</a> 位用户&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    {/* {needTotalList.map(item => (
                      <span style={{ marginLeft: 8 }} key={item.dataIndex}>
                        {item.title}
                        总计&nbsp;
                        <span style={{ fontWeight: 600 }}>
                          {item.render ? item.render(item.total) : item.total}
                        </span>
                      </span>
                    ))} */}
                    未付款 <a style={{ fontWeight: 600, color: 'red' }}>{noPayList.length}</a> 位&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    已付款 <a style={{ fontWeight: 600, color: 'red' }}>{payedList.length}</a> 位&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    <a onClick={() => this.handlePass(this.state.selectedRows)} style={{ marginLeft: 24 }}>通过</a>
                    <a onClick={() => this.handleRefuse(this.state.selectedRows)} style={{color:'red', marginLeft: 22}}>拒绝</a>
                  </Fragment>
                }
                type="info"
                showIcon
              />
            </div>
          : null
        }
        <Table
          rowKey={rowKey || 'key'}
          rowSelection={this.props.showRowSelection ? rowSelection : null}  
          dataSource={list}
          pagination={paginationProps}
          onChange={this.handleTableChange}
          {...rest}
        />
      </div>
    );
  }

转载请注明出处

原文地址:https://www.cnblogs.com/ljq66/p/11917893.html