zoukankan      html  css  js  c++  java
  • 【后台管理系统】—— 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>
        );
      }

    转载请注明出处

  • 相关阅读:
    elk 搭建
    Web 开发规范 — WSGI
    Web 开发规范 — WSGI
    fastjson生成和解析json数据,序列化和反序列化数据
    第四章 字典
    Struts2 无后缀action请求
    字典和列表访问方式:
    第3章 使用字符串
    Struts2中的ModelDriven机制及其运用
    Struts2 的Action中取得请求参数值的几种方法
  • 原文地址:https://www.cnblogs.com/ljq66/p/11917893.html
Copyright © 2011-2022 走看看