【后台管理系统】—— 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={{ width: '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={{width: 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={{ width: '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> 位用户 {/* {needTotalList.map(item => ( <span style={{ marginLeft: 8 }} key={item.dataIndex}> {item.title} 总计 <span style={{ fontWeight: 600 }}> {item.render ? item.render(item.total) : item.total} </span> </span> ))} */} 未付款 <a style={{ fontWeight: 600, color: 'red' }}>{noPayList.length}</a> 位 已付款 <a style={{ fontWeight: 600, color: 'red' }}>{payedList.length}</a> 位 <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> ); }
转载请注明出处
越是迷茫、浮躁的时候,保持冷静和耐心,尤为重要