import React, { Component } from 'react'
|
import PropTypes from 'prop-types'
|
import { Table, Form, Select, Cascader } from 'antd'
|
import { EditOutlined } from '@ant-design/icons'
|
|
import './index.scss'
|
|
const EditableContext = React.createContext()
|
const shortkeycode = {
|
65: 'A', 66: 'B', 67: 'C', 68: 'D', 69: 'E', 70: 'F', 71: 'G', 72: 'H', 73: 'I', 74: 'J', 75: 'K', 76: 'L', 77: 'M',
|
78: 'N', 79: 'O', 80: 'P', 81: 'Q', 82: 'R', 83: 'S', 84: 'T', 85: 'U', 86: 'V', 87: 'W', 88: 'X', 89: 'Y', 90: 'Z'
|
}
|
|
class CustomEditableCell extends Component {
|
getInput = () => {
|
const { inputType, options, record } = this.props
|
|
if (inputType === 'select') {
|
let _options = []
|
if (record.$port) {
|
_options = window.GLOB.UserCacheMap.get(record.$port) || []
|
}
|
return (
|
<Select allowClear>
|
{_options.map((item, i) => (<Select.Option key={i} title={item.value} value={item.value}> {item.text} </Select.Option>))}
|
</Select>
|
)
|
} else if (inputType === 'cascader') {
|
return (
|
<Cascader allowClear options={options} placeholder=""/>
|
)
|
}
|
}
|
|
renderCell = (form) => {
|
const { getFieldDecorator } = form
|
const { editing, editable, dataIndex, record, children, className } = this.props
|
|
return (
|
<td className={className}>
|
{editing && editable ? (
|
<Form.Item style={{ margin: 0 }}>
|
{getFieldDecorator(dataIndex, {
|
initialValue: record[dataIndex] || '',
|
})(this.getInput())}
|
</Form.Item>
|
) : (
|
children
|
)}
|
</td>
|
)
|
}
|
|
render() {
|
return <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
|
}
|
}
|
|
class CustomEditTable extends Component {
|
static propTpyes = {
|
data: PropTypes.any, // 数据列表
|
onChange: PropTypes.func // 数据变化
|
}
|
|
state = {
|
data: [],
|
editingKey: '',
|
visible: false,
|
columns: [{
|
title: window.GLOB.dict['name'] || '名称',
|
dataIndex: 'label',
|
width: '25%'
|
}, {
|
title: window.GLOB.dict['shortcut'] || '快捷键',
|
dataIndex: 'shortcut',
|
inputType: 'cascader',
|
editable: true,
|
options: [],
|
width: '25%',
|
render: (text) => {
|
if (!text) return ''
|
return text[0] + '+' + shortkeycode[text[1]]
|
}
|
}, {
|
title: window.GLOB.dict['printer'] || '打印机',
|
dataIndex: 'printer',
|
inputType: 'select',
|
editable: true,
|
options: [],
|
width: '25%'
|
}, {
|
title: window.GLOB.dict['operation'] || '操作',
|
dataIndex: 'operation',
|
width: '140px',
|
render: (_, record) => {
|
const { editingKey } = this.state
|
const editable = this.isEditing(record)
|
return editable ? (
|
<div style={{textAlign: 'center', minWidth: '110px'}}>
|
<EditableContext.Consumer>
|
{form => (
|
<span onClick={() => this.save(form, record.uuid)} style={{ marginRight: 8 , color: '#1890ff', cursor: 'pointer'}}>
|
{window.GLOB.dict['save'] || '保存'}
|
</span>
|
)}
|
</EditableContext.Consumer>
|
<span style={{ color: '#1890ff', cursor: 'pointer'}} onClick={() => this.cancel(record.uuid)}>{window.GLOB.dict['cancel'] || '取消'}</span>
|
</div>
|
) : (
|
<div className={'edit-operation-btn' + (editingKey !== '' ? ' disabled' : '')} style={{minWidth: '110px'}}>
|
<span className="primary" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><EditOutlined /></span>
|
</div>
|
)
|
}
|
}],
|
printTypeColumns: [
|
{
|
title: window.GLOB.dict['print_type'] || '打印类型',
|
dataIndex: 'Text',
|
width: '26.1%'
|
},
|
{
|
title: window.GLOB.dict['printer'] || '打印机',
|
dataIndex: 'printer',
|
inputType: 'select',
|
editable: true,
|
options: [],
|
},
|
{
|
title: window.GLOB.dict['operation'] || '操作',
|
dataIndex: 'operation',
|
width: '153px',
|
render: (_, record) => {
|
const { editingKey } = this.state
|
const editable = this.isEditing(record)
|
return editable ? (
|
<div style={{textAlign: 'center', minWidth: '110px'}}>
|
<EditableContext.Consumer>
|
{form => (
|
<span onClick={() => this.save(form, record.uuid, record.parentId)} style={{ marginRight: 8 , color: '#1890ff', cursor: 'pointer'}}>
|
{window.GLOB.dict['save'] || '保存'}
|
</span>
|
)}
|
</EditableContext.Consumer>
|
<span style={{ color: '#1890ff', cursor: 'pointer'}} onClick={() => this.cancel(record.uuid)}>{window.GLOB.dict['cancel'] || '取消'}</span>
|
</div>
|
) : (
|
<div className={'edit-operation-btn' + (editingKey !== '' ? ' disabled' : '')} style={{minWidth: '110px'}}>
|
<span className="primary" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><EditOutlined /></span>
|
</div>
|
)
|
}
|
}
|
]
|
}
|
|
UNSAFE_componentWillMount () {
|
const { data } = this.props
|
|
let keys = ['shift', 'ctrl', 'alt']
|
let _options = []
|
|
keys.forEach(item => {
|
let _op = {
|
value: item,
|
label: item,
|
children: []
|
}
|
Object.keys(shortkeycode).forEach(key => {
|
if (item === 'ctrl' && ['65', '67', '68', '69', '70', '71', '72', '74', '75', '76', '78', '79', '80', '82', '83', '84', '85', '86', '87', '88', '90'].includes(key)) return
|
if (item === 'alt' && ['65', '68', '69', '70'].includes(key)) return
|
|
_op.children.push({
|
value: +key,
|
label: shortkeycode[key]
|
})
|
})
|
|
_options.push(_op)
|
})
|
|
this.setState({
|
data: data,
|
columns: this.state.columns.map(item => {
|
if (item.dataIndex === 'shortcut') {
|
item.options = _options
|
}
|
return item
|
})
|
})
|
}
|
|
isEditing = record => record.uuid === this.state.editingKey
|
|
cancel = () => {
|
this.setState({ editingKey: '' })
|
}
|
|
handleDelete = (uuid) => {
|
const { data } = this.state
|
let _data = data.filter(item => uuid !== item.uuid)
|
|
this.setState({
|
data: _data
|
}, () => {
|
this.props.onChange(_data)
|
})
|
}
|
|
save(form, uuid, parentId) {
|
form.validateFields((error, row) => {
|
if (error) {
|
return;
|
}
|
|
let newData = null
|
|
if (parentId) {
|
newData = this.state.data.map(item => {
|
if (parentId === item.uuid) {
|
item.verify.printerTypeList = item.verify.printerTypeList.map(cell => {
|
if (uuid === cell.uuid) {
|
cell = {...cell, ...row}
|
}
|
return cell
|
})
|
}
|
return item
|
})
|
} else {
|
newData = this.state.data.map(item => {
|
if (uuid === item.uuid) {
|
item = {...item, ...row}
|
}
|
return item
|
})
|
}
|
|
this.setState({ data: newData, editingKey: '' }, () => {
|
this.props.onChange(newData)
|
})
|
})
|
}
|
|
edit(uuid) {
|
this.setState({ editingKey: uuid })
|
}
|
|
render() {
|
let components = {
|
body: {
|
cell: CustomEditableCell
|
}
|
}
|
|
const columns = this.state.columns.map(col => {
|
if (!col.editable) return col
|
return {
|
...col,
|
onCell: record => ({
|
record,
|
inputType: col.inputType,
|
dataIndex: col.dataIndex,
|
options: col.options || [],
|
title: col.title,
|
editable: col.dataIndex === 'shortcut' || record.funcType === 'print',
|
editing: this.isEditing(record),
|
}),
|
}
|
})
|
|
const printTypeColumns = this.state.printTypeColumns.map(col => {
|
if (!col.editable) return col
|
return {
|
...col,
|
onCell: record => ({
|
record,
|
inputType: col.inputType,
|
dataIndex: col.dataIndex,
|
options: [],
|
title: col.title,
|
editable: true,
|
editing: this.isEditing(record),
|
}),
|
}
|
})
|
|
return (
|
<EditableContext.Provider value={this.props.form}>
|
<div className="modal-custom-edit-table">
|
<Table
|
bordered
|
rowKey="uuid"
|
components={components}
|
dataSource={this.state.data}
|
columns={columns}
|
rowClassName={(record) => 'editable-row' + (record.$expanded ? ' print' : '')}
|
pagination={false}
|
expandedRowRender={record => (
|
record.$expanded ?
|
<Table
|
bordered
|
rowKey="key"
|
size="small"
|
components={components}
|
rowClassName="editable-row"
|
dataSource={record.verify.printerTypeList}
|
columns={printTypeColumns}
|
pagination={false}
|
/> : null
|
)}
|
/>
|
</div>
|
</EditableContext.Provider>
|
)
|
}
|
}
|
|
export default Form.create()(CustomEditTable)
|