290 lines
7.5 KiB
JavaScript
290 lines
7.5 KiB
JavaScript
import React, { Component } from 'react'
|
|
import { Form, Button, Table, Tooltip } from 'antd'
|
|
import { AntIcon } from 'components'
|
|
|
|
const clearChildren = (data) => {
|
|
data.forEach(p => {
|
|
if (p.children) {
|
|
if (p.children.length) {
|
|
p.children = clearChildren(p.children)
|
|
} else {
|
|
delete p.children
|
|
}
|
|
}
|
|
})
|
|
return data
|
|
}
|
|
|
|
/**
|
|
* 渲染查询栏
|
|
* @returns
|
|
*/
|
|
function renderQueryBar() {
|
|
|
|
const { query, moreQuery, onQueryChange } = this.props
|
|
|
|
return (
|
|
<div className="yo-query-bar">
|
|
<Form
|
|
layout="inline"
|
|
ref={this.form}
|
|
onFinish={(value) => this.onQuery(value)}
|
|
initialValues={this.props.queryInitialValues}
|
|
onValuesChange={(changedValues, allValues) => onQueryChange && onQueryChange(changedValues, allValues)}
|
|
>
|
|
{query}
|
|
<Form.Item>
|
|
<Button.Group className="mr-xs">
|
|
<Button htmlType="submit" type="primary" icon={<AntIcon type="search" />}>查询</Button>
|
|
<Tooltip placement="bottom" title="重置查询">
|
|
<Button onClick={() => this.onResetQuery()} icon={<AntIcon type="undo" />} />
|
|
</Tooltip>
|
|
</Button.Group>
|
|
{
|
|
moreQuery && <Button>更多查询条件</Button>
|
|
}
|
|
</Form.Item>
|
|
</Form>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function renderTable(props, on) {
|
|
return <Table className="yo-table" {...props} {...on} />
|
|
}
|
|
|
|
export default class QueryTable extends Component {
|
|
|
|
state = {
|
|
// 加载状态
|
|
loading: false,
|
|
// 表格类型
|
|
type: '',
|
|
// 数据
|
|
dataSource: []
|
|
}
|
|
|
|
// 查询表单实例
|
|
form = React.createRef()
|
|
|
|
// 查询值
|
|
query = {}
|
|
|
|
// 分页器配置
|
|
pagination = {
|
|
current: 1,
|
|
pageSize: 10,
|
|
total: 0,
|
|
size: 'small',
|
|
showSizeChanger: true,
|
|
showQuickJumper: true,
|
|
showTotal: (total) => `总共${total}条数据`,
|
|
position: ['bottomLeft']
|
|
}
|
|
|
|
// 默认选中页码
|
|
pageIndex = 1
|
|
// 默认页面尺寸
|
|
pageSize = 10
|
|
|
|
// 排序字段
|
|
sorter = {
|
|
sortField: '',
|
|
sortOrder: '',
|
|
}
|
|
|
|
constructor(props) {
|
|
super(props)
|
|
|
|
this.autoLoad = typeof this.props.autoLoad === 'boolean' ? this.props.autoLoad : true
|
|
this.loadData = typeof this.props.loadData === 'function' ? this.props.loadData : async () => { }
|
|
|
|
if (this.props.pageIndex) {
|
|
this.pageIndex = this.props.pageIndex
|
|
this.pagination.current = this.pageIndex
|
|
}
|
|
if (this.props.pageSize) {
|
|
this.pageSize = this.props.pageSize
|
|
this.pagination.pageSize = this.pageSize
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 自动加载数据
|
|
*/
|
|
componentDidMount() {
|
|
if (this.autoLoad) {
|
|
this.onLoadData()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 加载数据
|
|
* 调用外部传入的loadData函数,可在loadData中自行改变参数
|
|
*/
|
|
onLoadData = async () => {
|
|
this.onLoading()
|
|
|
|
const res = await this.loadData({
|
|
pageIndex: this.pagination.current,
|
|
pageSize: this.pagination.pageSize,
|
|
...this.sorter
|
|
}, this.query)
|
|
if (res.rows || res.data || res.items) {
|
|
this.setState({
|
|
type: 'table',
|
|
dataSource: res.rows || res.data || res.items
|
|
})
|
|
|
|
this.pagination.total = res.totalCount
|
|
} else if (res) {
|
|
this.setState({
|
|
type: 'tree',
|
|
dataSource: clearChildren(res)
|
|
})
|
|
|
|
this.pagination = false
|
|
}
|
|
|
|
this.onLoaded()
|
|
}
|
|
|
|
/**
|
|
* 数据开始加载
|
|
*/
|
|
onLoading = () => {
|
|
this.setState({
|
|
loading: {
|
|
indicator: <AntIcon type="loading" />
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 数据加载完成
|
|
*/
|
|
onLoaded = () => {
|
|
this.setState({ loading: false })
|
|
}
|
|
|
|
/**
|
|
* 进行查询
|
|
* 返回表单字段值,加载数据,并且返回到第一页
|
|
* @param {*} values
|
|
*/
|
|
onQuery = (values) => {
|
|
this.query = values
|
|
this.onReloadData(true)
|
|
}
|
|
|
|
/**
|
|
* 重置查询
|
|
* 初始化表单字段值,加载数据,并返回到第一页
|
|
*/
|
|
onResetQuery = () => {
|
|
|
|
const { queryInitialValues, onQueryChange } = this.props
|
|
|
|
this.form.current.resetFields()
|
|
this.query = {
|
|
...queryInitialValues
|
|
}
|
|
const values = this.form.current.getFieldsValue()
|
|
onQueryChange && onQueryChange(values, values)
|
|
this.onReloadData(true)
|
|
}
|
|
|
|
/**
|
|
* 重新加载表格数据
|
|
* @param {Boolean} resetPage 是否重置页码
|
|
*/
|
|
onReloadData = (resetPage = false) => {
|
|
if (resetPage) {
|
|
this.pagination = {
|
|
...this.pagination,
|
|
current: this.pageIndex
|
|
}
|
|
}
|
|
this.onLoadData()
|
|
}
|
|
|
|
/**
|
|
* 表格分页/筛选/排序
|
|
* @param {*} pagination
|
|
* @param {*} filters
|
|
* @param {*} sorter
|
|
*/
|
|
onTableChange = (pagination, filters, sorter) => {
|
|
this.pagination = {
|
|
...pagination,
|
|
showTotal: (total) => `总共${total}条数据`
|
|
}
|
|
this.sorter = {
|
|
sortField: sorter.field,
|
|
sortOrder: sorter.order,
|
|
}
|
|
this.onLoadData()
|
|
}
|
|
|
|
onAddRow = (record = {}) => {
|
|
let { dataSource } = this.state
|
|
if (!dataSource.find(item => !item.id)) {
|
|
dataSource = [...dataSource, record]
|
|
this.setState({
|
|
dataSource
|
|
})
|
|
return dataSource.length - 1
|
|
}
|
|
return false
|
|
}
|
|
|
|
render() {
|
|
|
|
const { loading, dataSource } = this.state
|
|
|
|
const { query, operator, columns } = this.props
|
|
|
|
const props = {
|
|
loading,
|
|
pagination: this.pagination,
|
|
dataSource,
|
|
columns: (columns || []).filter(p => !p.hidden),
|
|
bordered: true,
|
|
size: 'middle',
|
|
rowKey: record => record.id || Math.random().toString(16).slice(2),
|
|
sticky: true,
|
|
...this.props
|
|
}
|
|
|
|
const on = {
|
|
onChange: (...args) => this.onTableChange.apply(this, args)
|
|
}
|
|
|
|
return (
|
|
<section>
|
|
{query && renderQueryBar.call(this)}
|
|
<div className="yo-action-bar">
|
|
<div className="yo-action-bar--actions">
|
|
{operator}
|
|
</div>
|
|
<div className="yo-action-bar--actions">
|
|
<Button.Group>
|
|
<Tooltip placement="bottom" title="刷新">
|
|
<Button onClick={() => this.onReloadData()} type="text" icon={<AntIcon type="reload" />} />
|
|
</Tooltip>
|
|
</Button.Group>
|
|
</div>
|
|
</div>
|
|
{
|
|
this.props.editable ?
|
|
<Form ref={this.props.form}>
|
|
{renderTable.call(this, props, on)}
|
|
</Form>
|
|
:
|
|
renderTable.call(this, props, on)
|
|
}
|
|
</section>
|
|
)
|
|
}
|
|
}
|