import React, {Component} from 'react'
|
import PropTypes from 'prop-types'
|
import { is, fromJS } from 'immutable'
|
import { Table, message, Affix, Button, Typography } from 'antd'
|
import './index.scss'
|
|
const { Paragraph } = Typography
|
|
export default class MainTable extends Component {
|
static propTpyes = {
|
dict: PropTypes.object, // 字典项
|
MenuID: PropTypes.string, // 菜单Id
|
setting: PropTypes.object, // 表格全局设置:tableType(表格是否可选、单选、多选)、columnfixed(列固定)、actionfixed(按钮固定)
|
pickup: PropTypes.any, // 数据收起
|
setsingle: PropTypes.any, // 设置单选多选
|
columns: PropTypes.array, // 表格列
|
data: PropTypes.any, // 表格数据
|
total: PropTypes.number, // 总数
|
loading: PropTypes.bool, // 表格加载中
|
refreshdata: PropTypes.func, // 表格中排序列、页码的变化时刷新
|
buttonTrigger: PropTypes.func, // 表格中按钮触发操作
|
handleTableId: PropTypes.func // 数据切换
|
}
|
|
state = {
|
selectedRowKeys: [], // 表格中选中行
|
pageIndex: 1, // 初始页面索引
|
pageSize: 10, // 每页数据条数
|
columns: null, // 显示列
|
selectId: '',
|
isSingleSelect: false
|
}
|
|
UNSAFE_componentWillMount () {
|
const { columns, setting } = this.props
|
let _columns = []
|
|
columns.forEach(item => {
|
let cell = {
|
align: item.Align,
|
dataIndex: item.field || item.uuid,
|
title: item.label,
|
sorter: item.field && item.IsSort === 'true',
|
width: item.Width || 120,
|
render: (text, record) => {
|
return this.getContent(item, record)
|
}
|
}
|
_columns.push(cell)
|
})
|
|
this.setState({
|
columns: _columns,
|
isSingleSelect: setting.tableType === 'radio'
|
})
|
}
|
|
UNSAFE_componentWillReceiveProps(nextProps) {
|
if (!is(fromJS(this.props.setsingle), fromJS(nextProps.setsingle))) {
|
this.setState({
|
isSingleSelect: nextProps.setsingle,
|
selectedRowKeys: [],
|
selectId: ''
|
})
|
}
|
}
|
|
getContent = (item, record) => {
|
if (item.type === 'text') {
|
let content = ''
|
let match = false
|
if (item.field && record.hasOwnProperty(item.field)) {
|
content = `${record[item.field]}`
|
}
|
|
if (content && item.matchVal && content.indexOf(item.matchVal) > 0) {
|
match = true
|
}
|
|
content = (item.prefix || '') + content + (item.postfix || '')
|
|
return (
|
<div className={match ? item.color : ''}>
|
<div className="background"></div>
|
<div className="content" style={{ minWidth: (item.Width || 120) + 'px' }}>
|
{content}
|
</div>
|
</div>
|
)
|
} else if (item.type === 'number') {
|
let content = ''
|
let match = false
|
if (item.field && record.hasOwnProperty(item.field)) {
|
content = +record[item.field]
|
}
|
|
if (content && item.match && item.matchVal) {
|
if (item.match === '>') {
|
if (content > item.matchVal) {
|
match = true
|
}
|
} else if (item.match === '<') {
|
if (content < item.matchVal) {
|
match = true
|
}
|
} else if (item.match === '>=') {
|
if (content >= item.matchVal) {
|
match = true
|
}
|
} else if (item.match === '<=') {
|
if (content <= item.matchVal) {
|
match = true
|
}
|
}
|
}
|
|
if (content && item.format === 'thdSeparator') {
|
content = `${content}`
|
content = content.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
|
}
|
|
content = (item.prefix || '') + content + (item.postfix || '')
|
|
return (
|
<div className={match ? item.color : ''}>
|
<div className={'background'}></div>
|
<div className="content" style={{ minWidth: (item.Width || 120) + 'px' }}>
|
{content}
|
</div>
|
</div>
|
)
|
} else if (item.type === 'picture') {
|
let photos = ''
|
if (item.field && record.hasOwnProperty(item.field)) {
|
photos = record[item.field].split(',')
|
} else {
|
photos = ''
|
}
|
return (
|
<div className="picture-col" style={{ minWidth: (item.Width || 120) + 'px' }}>
|
{photos && photos.map((url, i) => {
|
return <img key={`${i}`} src={url} alt=""/>
|
})}
|
</div>
|
)
|
} else if (item.type === 'textarea') {
|
let content = ''
|
let match = false
|
if (item.field && record.hasOwnProperty(item.field)) {
|
content = `${record[item.field]}`
|
}
|
|
if (content && item.matchVal && content.indexOf(item.matchVal) > 0) {
|
match = true
|
}
|
|
content = (item.prefix || '') + content + (item.postfix || '')
|
|
return (
|
<div className={match ? item.color : ''}>
|
<div className="background"></div>
|
<div className="content" style={{ minWidth: (item.Width || 120) + 'px' }}>
|
<Paragraph copyable ellipsis={{ rows: 3, expandable: true }}>{content}</Paragraph>
|
</div>
|
</div>
|
)
|
} else if (item.type === 'action') {
|
return (
|
<div className={item.style} style={{ minWidth: (item.Width || 120) + 'px' }}>
|
{item.operations.map(btn => {
|
return <Button
|
className={'mk-btn mk-' + btn.class}
|
icon={btn.icon}
|
key={btn.uuid}
|
onClick={(e) => {this.actionTrigger(e, btn, record)}}
|
>{btn.label}</Button>
|
})}
|
</div>
|
)
|
} else if (item.type === 'colspan') {
|
let contents = ''
|
if (item.subColumn.length > 0) {
|
contents = item.subColumn.map(col => {
|
let content = ''
|
if (col.type === 'text' || col.type === 'textarea') {
|
if (col.field && record.hasOwnProperty(col.field)) {
|
content = `${record[col.field]}`
|
}
|
|
content = (col.prefix || '') + content + (col.postfix || '')
|
} else if (col.type === 'number') {
|
if (col.field && record.hasOwnProperty(col.field)) {
|
content = +record[col.field]
|
}
|
if (content && col.format === 'thdSeparator') {
|
content = `${content}`
|
content = content.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
|
}
|
content = (col.prefix || '') + content + (col.postfix || '')
|
}
|
return content
|
})
|
}
|
|
if (contents && item.order === 'vertical2') {
|
let _contents = []
|
for(let i = 0; i < contents.length; i += 2) {
|
_contents.push(contents.slice(i, i + 2).join(' '))
|
}
|
contents = _contents
|
}
|
|
return (
|
<div>
|
<div className="content" style={{ minWidth: (item.Width || 120) + 'px' }}>
|
{contents && item.order === 'vertical' && contents.map((content, index) => {
|
return (<p key={index}>{content}</p>)
|
})}
|
{contents && item.order === 'vertical2' && contents.map((content, index) => {
|
return (<p key={index}>{content}</p>)
|
})}
|
{contents && item.order === 'horizontal' && contents.map((content, index) => {
|
return (<span key={index}>{content}</span>)
|
})}
|
</div>
|
</div>
|
)
|
}
|
}
|
|
actionTrigger = (e, btn, record) => {
|
e.stopPropagation()
|
this.props.buttonTrigger(btn, record)
|
}
|
|
copycontent = (e, content) => {
|
// 表格中内容复制
|
e.stopPropagation()
|
let oInput = document.createElement('input')
|
oInput.value = content
|
document.body.appendChild(oInput)
|
oInput.select()
|
document.execCommand('Copy')
|
oInput.className = 'oInput'
|
oInput.style.display='none'
|
message.success(this.props.dict['main.copy.success'])
|
}
|
|
onSelectChange = selectedRowKeys => {
|
if (this.props.pickup) return
|
|
let index = ''
|
if (selectedRowKeys.length > 0) {
|
index = selectedRowKeys[selectedRowKeys.length - 1]
|
}
|
|
this.changedata(index)
|
|
this.setState({ selectedRowKeys })
|
}
|
|
changeRow = (record, index) => {
|
// 点击整行,触发切换,判断是否可选,单选或多选,进行对应操作
|
if (!this.props.setting.tableType || this.props.pickup) return
|
|
let newkeys = JSON.parse(JSON.stringify(this.state.selectedRowKeys))
|
let _re = newkeys.includes(index)
|
|
if (this.props.setting.tableType === 'radio' || this.state.isSingleSelect) {
|
this.changedata(index)
|
this.setState({ selectedRowKeys: [index] })
|
} else {
|
if (_re) {
|
newkeys = newkeys.filter(item => item !== index)
|
this.changedata('')
|
} else {
|
newkeys.push(index)
|
this.changedata(index)
|
}
|
|
this.setState({ selectedRowKeys: newkeys })
|
}
|
}
|
|
changeTable = (pagination, filters, sorter) => {
|
this.setState({
|
pageIndex: pagination.current,
|
pageSize: pagination.pageSize,
|
selectedRowKeys: []
|
})
|
this.props.refreshdata(pagination, filters, sorter)
|
}
|
|
changedata = (index) => {
|
const { data, setting } = this.props
|
let _id = ''
|
let _data = ''
|
|
if (data && data.length > 0 && index !== '') {
|
_id = data[index][setting.primaryKey] || ''
|
_data = data[index] || ''
|
}
|
|
this.setState({
|
selectId: _id
|
})
|
|
this.props.handleTableId('mainTable', _id, _data)
|
}
|
|
resetTable = () => {
|
this.setState({
|
pageIndex: 1,
|
selectId: '',
|
selectedRowKeys: []
|
})
|
}
|
|
render() {
|
const { setting, pickup } = this.props
|
let { selectedRowKeys, isSingleSelect, selectId } = this.state
|
|
let rowSelection = null
|
if (setting.tableType) {
|
rowSelection = {
|
selectedRowKeys,
|
type: (setting.tableType === 'radio' || isSingleSelect) ? 'radio' : 'checkbox',
|
onChange: this.onSelectChange
|
}
|
}
|
let offset = null
|
if (setting.columnfixed) {
|
// 表格头部固定于顶部时,判断距顶部高度
|
if (!setting.actionfixed) {
|
offset = 48
|
} else {
|
let box = document.getElementById(this.props.MenuID + 'mainaction')
|
if (box) {
|
offset = 48 + box.offsetHeight
|
} else {
|
offset = 105
|
}
|
}
|
}
|
|
let _data = this.props.data ? this.props.data : []
|
|
if (selectId && pickup && isSingleSelect) {
|
_data = _data.filter(item => item[setting.primaryKey] === selectId)
|
}
|
|
return (
|
<div className="main-table">
|
{setting.columnfixed && <Affix offsetTop={offset} className="fix-header">
|
<Table
|
size="middle"
|
bordered={true}
|
rowSelection={rowSelection}
|
columns={this.state.columns.map(column => {
|
return {
|
align: column.align,
|
dataIndex: column.dataIndex,
|
title: column.title,
|
width: column.width
|
}
|
})}
|
/>
|
</Affix>}
|
<Table
|
size="middle"
|
bordered={true}
|
rowSelection={rowSelection}
|
columns={this.state.columns}
|
dataSource={_data}
|
loading={this.props.loading}
|
scroll={{ x: '100%', y: false }}
|
onRow={(record, index) => {
|
return {
|
onClick: () => {this.changeRow(record, index)}
|
}
|
}}
|
onChange={this.changeTable}
|
pagination={{
|
current: this.state.pageIndex,
|
pageSize: this.state.pageSize,
|
pageSizeOptions: ['10', '25', '50', '100', '500', '1000'],
|
showSizeChanger: true,
|
total: this.props.total,
|
showTotal: (total, range) => `${range[0]}-${range[1]} ${this.props.dict['main.pagination.of']} ${total} ${this.props.dict['main.pagination.items']}`
|
}}
|
/>
|
</div>
|
)
|
}
|
}
|