import React from 'react';import { Table, Input, InputNumber, Form, Select } from 'antd';import { OPTION_TYPE } from '../../constants/typeConstant';import event, { EVENT_TYPE } from '../../utils/event';import Common from '../../utils/common';// 支持按行编辑的table// 必传参数:columns、onSave、newRowKey、updateList// column以editable标识是否可编辑, inputType标识编辑时为input还是select等, optionList标识为select时的可选值const EditableContext = React.createContext();class EditableCell extends React.Component { getInput = () => { const {inputType, mode, optionList} = this.props; switch(inputType){ case 'input': return <Input style={{width: '100%'}}/>; case 'number': return <InputNumber style={{width: '100%'}}/>; case 'select': return <Select style={{width: '100%'}} showSearch allowClear mode={mode || 'multiple'} optionFilterProp="children" > {optionList?.map((item) => ( <Select.Option value={item.value} key={item.value}> {item.label} </Select.Option> )) } </Select> } return <Input/>; }; renderCell = ({ getFieldDecorator }) => { debugger const { editing, dataIndex, title, inputType, required, record, index, children, ...restProps } = this.props; return ( <td {...restProps}> {editing ? ( <Form.Item style={{ margin: 0 }}> {getFieldDecorator(dataIndex, { rules: [ { required: required == true || false, message: required == true ? `请输入 ${title}!`: '' } ], initialValue: (record[dataIndex] && Array.isArray(record[dataIndex])) ? record[dataIndex]?.map(item => Common.types(item).isObject ? item.value : item) : (Common.types(record[dataIndex]).isObject ? record[dataIndex].value : record[dataIndex]) })(this.getInput())} </Form.Item> ) : ( children )} </td> ); }; render() { return <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>; }}class EditableTable extends React.Component { constructor(props) { super(props); this.state = { editingKey: '' }; } componentDidMount(){ event.addListener(EVENT_TYPE.ADD_ROW_IN_EDITABLE_TABLE, this.editNewRow); } componentWillUnmount(){ event.removeListener(EVENT_TYPE.ADD_ROW_IN_EDITABLE_TABLE, this.editNewRow); } isEditing = record => record.key === this.state.editingKey; // 取消 cancel = (key) => { const {updateList} = this.props; updateList && updateList(); this.setState({ editingKey: '' }); }; //保存 save(form, key, onSave) { const { updateList} = this.props; form.validateFields((error, row) => { if (error) { return; } //调用自定义保存方法 onSave(row); updateList && updateList(); this.setState({ editingKey: '' }); }); } // 切换为编辑状态 edit(key) { this.setState({ editingKey: key }); } // 新增行切换为编辑状态 editNewRow = () =>{ const {newRowKey} = this.props; this.setState({ editingKey: newRowKey || 'new_row' }); } formatColumns = () => { const {columns, handleView, handleDelete} = this.props; const newColumns = [...columns]; return newColumns?.map(column => { if(column?.dataIndex == 'operation'){ const viewOption = column.options?.find(option => option.type === OPTION_TYPE.VIEW); const editOption = column.options?.find(option => option.type === OPTION_TYPE.EDIT); const deleteOption = column.options?.find(option => option.type === OPTION_TYPE.DELETE); column.render = (text, record) => { const { editingKey } = this.state; const editable = this.isEditing(record); return <> { viewOption && !editable && viewOption?.render(record) } {editOption &&( editable ? ( <span> <EditableContext.Consumer> {form => ( <a onClick={() => this.save(form, record.key, editOption.onSave)} style={{ marginRight: 10 }} > 保存 </a> )} </EditableContext.Consumer> <a onClick={() => this.cancel(record.key)} > 取消 </a> </span> ) : ( <a disabled={editingKey !== ''} onClick={() => this.edit(record.key)} style={{ marginRight: 10 }} > 编辑 </a> ) )} { deleteOption && !editable && deleteOption?.render(record) } </> } } if(!column.editable) { return column; } return { ...column, onCell: record => ({ record, inputType: column.inputType, dataIndex: column.dataIndex, title: column.title, required: column.required, mode: column.mode, optionList: column.optionList, editing: this.isEditing(record) }) }; }); } render() { const {columns, ...restProps} = this.props; const components = { body: { cell: EditableCell } }; return ( <EditableContext.Provider value={this.props.form}> <Table components={components} columns={this.formatColumns()} {...restProps} /> </EditableContext.Provider> ); }}export default Form.create()(EditableTable);