cjd-parkball
Version:
> 中后台业务组件库,中后台就像公园,进入需要买门票(登录),所以以 Parkball(公园球) 命名,公园内必定捕获!作为一个组件库,提供使用方法文档,方便开发者的调用
306 lines (275 loc) • 8.74 kB
JavaScript
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import { Table } from 'antd'
import store from 'store2'
import tableDragger from 'table-dragger'
import { message } from '../..'
import ColumnTh from './column-th'
import { customStoreKey } from '../utils'
import renderMore from '../common/render-more'
import CustomColumn from './custom-column'
import DataExport from './data-export'
import moreItems from './more-item'
import getCollpaseColumns from './formatColumns'
import './index.scss'
const getColumnKey = column => column.key || column.dataIndex
/**
* localstorage 存储的数据模型 columnConfig:
* columns: [{
* dataIndex: dataIndex || key,
* show: bool,
* ...otherAttr,
* }]
*/
export default class extends Component {
/**
* 默认属性值
* @param {Array} tools 工具列表
* hint:
* @param {bool || array || object} collapseRow 合并行,默认为不合并,传入要合并的dataIndex
* @param {bool || array || object} collapseCol 合并列,默认为不合并,传入对象或数组,对象属性包括
* 行号,开始合并的dataIndex以及合并的列的数量
*/
static defaultProps = {
columns: [],
custom: false,
scope: 'parkball',
tableKey: 'pk-table-key',
// collapseRow: [],
// collapseCol: [],
dragMode: false,
dataExport: false,
resize: false,
inline: false,
}
static propTypes = {
columns: PropTypes.array,
custom: PropTypes.bool,
scope: PropTypes.string,
tableKey: PropTypes.string,
dataExport: PropTypes.bool,
resize: PropTypes.bool,
dragMode: PropTypes.oneOf(['column', 'row', 'free', false]),
inline: PropTypes.bool,
// collapseRow: PropTypes.oneOfType([
// PropTypes.bool,
// PropTypes.object,
// PropTypes.array,
// ]),
// collapseCol: PropTypes.oneOfType([
// PropTypes.bool,
// PropTypes.object,
// PropTypes.array,
// ]),
}
// 初始化拖拽实例
dragger
state = {
columnConfig: this.getColumnConfig(),
}
components = {
header: {
cell: props => <ColumnTh resize={this.props.resize} {...props} />,
},
}
// 从 localStorage 中获取 column config
getColumnConfig () {
const { custom, dragMode } = this.props
const key = customStoreKey({ ...this.props, compKey: this.props.tableKey })
const columnConfig = store.get(key)
if ((custom || dragMode) && columnConfig) {
return columnConfig
}
return this.props.columns.map((i) => {
return {
dataIndex: getColumnKey(i),
show: true,
fixed: i.fixed,
}
})
}
// merge config 后的 columns
getColumnWithConfig () {
const { custom, dragMode, columns } = this.props
const { columnConfig = [] } = this.state
if (custom || dragMode) {
const newColumns = []
const propsColumn = {}
this.props.columns.forEach((column) => {
propsColumn[getColumnKey(column)] = column
})
columnConfig.forEach((column) => {
const columnKey = getColumnKey(column)
newColumns.push({ ...propsColumn[columnKey], ...column })
delete propsColumn[columnKey]
})
// console.log(newColumns, Object.values(propsColumn))
return [...newColumns, ...Object.values(propsColumn)]
}
return columns
}
// 开启 resize 后,调整 width 的事件回调
handleResize = index => (e, { size }) => {
const newColumnConfig = [...this.state.columnConfig]
newColumnConfig[index] = {
...newColumnConfig[index],
width: size.width,
}
this.setState({ columnConfig: newColumnConfig })
}
// 自定义表格列
handleCustomColumn = (customColumn) => {
if (customColumn.length === 0) {
message.info('表格至少显示一列')
} else {
const columnConfig = this.state.columnConfig.map((col) => {
const dataIndex = getColumnKey(col)
return {
dataIndex,
show: customColumn.indexOf(dataIndex) > -1,
fixed: col.fixed,
}
})
const key = customStoreKey({ ...this.props, compKey: this.props.tableKey })
store(key, columnConfig)
this.setState({ columnConfig })
}
}
// 列数据处理
serializeColumns (columns) {
const {
operationItemLength, custom, resize, scope, tableKey,
} = this.props
const newColumns = []
const showColumns = columns.filter(c => c.show !== false)
showColumns.forEach((col, colIndex) => {
const newCol = { ...col }
if (resize && !col.fixed) {
newCol.onHeaderCell = column => ({
width: column.width,
onResize: this.handleResize(colIndex),
})
}
if (!col.fixed) {
newCol.className = 'normal-column'
}
if (custom && colIndex === showColumns.length - 1) {
newCol.title = (<CustomColumn
scope={scope}
tableKey={tableKey}
columns={columns}
{...this.state}
handleCustomColumn={this.handleCustomColumn}
col={col}
/>)
}
if (col.render && !col.tip) {
newCol.render = (text, record, index) => {
let operation = col.render(text, record, index)
return renderMore(operation, col.operationItemLength || operationItemLength)
}
}
if (col.tip) {
newCol.render = (text, record, index) => {
if (col.render) {
let items = col.render(text, record, index)
return moreItems(items, col.width)
}
return moreItems(text, col.width)
}
}
newColumns.push(newCol)
})
return newColumns
}
// 表格更新后需要重新初始化 drag
componentDidMount () {
if (this.props.dragMode) {
this.initTableDragger()
}
}
// 初始化 drag 模式
initTableDragger = () => {
const { dragMode, tableKey } = this.props
const columnConfig = this.getColumnWithConfig()
if (dragMode) {
this.dragger = tableDragger(document.querySelector(`#pk-table-${tableKey} table`), {
dragMode,
dragHandler: '.normal-column',
})
this.dragger.on('drop', (oldIndex, newIndex) => {
if (!columnConfig[oldIndex].fixed && !columnConfig[newIndex].fixed) {
const draggedColumn = columnConfig[oldIndex]
const newColumnConfig = [...columnConfig]
newColumnConfig.splice(oldIndex, 1)
newColumnConfig.splice(newIndex, 0, draggedColumn)
const key = customStoreKey({ ...this.props, compKey: this.props.tableKey })
store(key, newColumnConfig)
setTimeout(() => {
this.setState({
columnConfig: newColumnConfig,
})
}, 0)
}
})
}
}
// 获取行合并后的 column
getCollpaseColumns=(columns) => {
if (this.props.collapseCol) {
return getCollpaseColumns.call(this, columns)
}
return columns
}
// 实例数据更新后,需要重新初始化 drag
componentDidUpdate () {
if (this.props.dragMode) {
this.dragger.destroy()
this.initTableDragger()
}
}
render () {
let {
columns = [], dataExport, dragMode, resize, inline, ...restProps
} = this.props
columns = this.serializeColumns(this.getColumnWithConfig())
return (
<div id={`pk-table-${restProps.tableKey}`} className={classnames('pk-table', { 'pk-draggable-table': dragMode, 'pk-table-inline': inline })}>
<Table
bordered={resize}
components={this.components}
columns={columns}
scroll={{ x: inline }}
locale={{ // ie下面诡异的布局问题,添加1px padding解决
emptyText: <div
style={{
width: '100%', height: 160, position: 'relative', padding: 1,
}}
>
<div style={{
width: '100%', position: 'relative', top: '50%', marginTop: -46.5,
}}
>
<div style={{ position: 'relative', height: 75 }}>
<img
style={{ position: 'absolute', left: '50%', marginLeft: -37.5 }}
width="75"
height="75"
alt="暂无数据"
src="https://new-minio.ichint.com/chint/table-placeholder.png"
/>
</div>
<div>暂无数据</div>
</div>
</div>,
}}
{...restProps}
/>
{
dataExport ? <DataExport columns={columns} /> : null
}
</div>
)
}
}