由于antd design表格提供的筛选方法只能筛选顶级父节点数据,不适用搜索子节点需求,故对筛选方法做如下调整(主要修改onFilter方法,部分引入请忽略)
import React, { Fragment } from 'react'; import { connect } from 'dva'; import { Button, Card, Col, Form, Input, Drawer, Row, Radio, Table, TreeSelect, Switch, message, Icon } from 'antd'; import { delInvalidData } from '../../utils/utils'; import PageHeaderWrapper from '../../components/PageHeaderWrapper'; import {getTreeMenu} from '../../services/vApi'; import BraftEditor from 'braft-editor'; import Editor from '../../components/Editor/Editor'; import Highlighter from 'react-highlight-words'; const FormItem = Form.Item; const SESSION_KEY = 'OperationGuideManage.params'; function initParams() { return { action: 'getTreeMenu' }; } @connect(({ user }) => ({ user })) @Form.create() class OperationGuideManage extends React.PureComponent { state = { params: {}, data:[], loading: false, plsc:false, edit: false, view: false, searchText: '', searchedColumn: '', expendKeys: [] }; getColumnSearchProps = dataIndex => ({ filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => ( <div style={{ padding: 8 }}> <Input ref={node => { this.searchInput = node; }} placeholder='节点名称' value={selectedKeys[0]} onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])} onPressEnter={() => this.handleSearch(selectedKeys, confirm, dataIndex)} style={{ width: 188, marginBottom: 8, display: 'block' }} /> <Button type="primary" onClick={() => this.handleSearch(selectedKeys, confirm, dataIndex)} icon="search" size="small" style={{ width: 90, marginRight: 8 }} > 搜索 </Button> <Button onClick={() => this.handleReset(clearFilters)} size="small" style={{ width: 90 }}> 重置 </Button> </div> ), filterIcon: filtered => ( <Icon type="search" style={{ color: filtered ? '#1890ff' : undefined }} /> ), onFilter: (value, record) =>{ let expendKeys = this.state.expendKeys; if(record[dataIndex] .toString() .toLowerCase() .includes(value.toLowerCase())){ expendKeys.push(record.key); } if(record.children){ const ch = this.getIndex(record.children, dataIndex, value); expendKeys.push(...ch) if(ch && ch.length > 0){ expendKeys.push(record.key) } } expendKeys = expendKeys.filter((item, index) => expendKeys.indexOf(item, 0) === index); return this.filterIndex(record, dataIndex, value)}, onFilterDropdownVisibleChange: visible => { if (visible) { setTimeout(() => this.searchInput.select()); } }, render: text => this.state.searchedColumn === dataIndex ? ( <Highlighter highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }} searchWords={[this.state.searchText]} autoEscape textToHighlight={text.toString()} /> ) : ( text ), }); handleSearch = (selectedKeys, confirm, dataIndex) => { confirm(); this.setState({ searchText: selectedKeys[0], searchedColumn: dataIndex, expendKeys: [] }); }; handleReset = clearFilters => { clearFilters(); this.setState({ searchText: '' }); }; filterIndex = (record, dataIndex, value) => { let res = record[dataIndex] .toString() .toLowerCase() .includes(value.toLowerCase()); if (!res && record.children){ if (record.children.some(item => item[dataIndex].toString() .toLowerCase() .includes(value.toLowerCase()))) { res = true; } else { for (let i = 0; i < record.children.length; i++) { res = this.filterIndex(record.children[i], dataIndex, value); if(res){ break; } } } } return res; } getIndex = (children, dataIndex, value) => { let indexs = []; for (let i = 0; i < children.length; i++){ if(children[i][dataIndex].toString() .toLowerCase() .includes(value.toLowerCase())){ indexs.push(children[i].key); } if (children[i].children){ const ch = this.getIndex(children[i].children, dataIndex, value); indexs.push(...ch); if(ch && ch.length > 0){ indexs.push(children[i].key) } } } return indexs; } columns = [ { title: '节点名称', dataIndex: 'title',...this.getColumnSearchProps('title'), key: 'title'}, { title: '文章关联类型', dataIndex: 'url', render: (text,record) =><span>{!record.url ? '未关联' : record.url.startsWith('http') ? '外部链接' : '内部文章'}</span> }, { title: '操作',align:'center', width:100, render: (text, record) => <Fragment> <Row> <a onClick={() => this.handleModalVisible('view', true, record)}>查看</a> </Row> <Row> <a onClick={() => this.handleModalVisible('edit', true, record)}>编辑</a> </Row> </Fragment> }, ]; componentDidMount(){ const session = sessionStorage.getItem(SESSION_KEY); let params = JSON.parse(session) || initParams(); this.query(params); } query = (params) => { this.setState({ loading: true }) sessionStorage.setItem(SESSION_KEY, JSON.stringify(params)); this.setState({ params: params }); let payload = delInvalidData(params); getTreeMenu(payload).then(res => { this.setState({ loading: false }) if(res && res.state === 'success'){ this.setState({ data: res.data }) } }) }; handleModalVisible = (modal, flag, record) => { record && (this.current = record); this.setState({ [modal]: !!flag }); }; handleSearch1 = e => { e.preventDefault(); const { form } = this.props; form.validateFields((err, fieldsValue) => { if (err) return; this.query({ ...initParams(), ...fieldsValue, time: fieldsValue.time && fieldsValue.time.length ? [fieldsValue.time[0].format('YYYY-MM-DD'), fieldsValue.time[1].format('YYYY-MM-DD')] : null }); }); }; handleFormReset = () => { const { form } = this.props; form.resetFields(); this.setState({ params: {} }); }; renderForm() { return ( <Form onSubmit={this.handleSearch1} layout="inline"> <Row gutter={{ md: 8, lg: 24, xl: 48 }}> <Col md={11} sm={24}> <span> <Button type="primary" htmlType="submit"> 刷新 </Button> <Button style={{ marginLeft: 8}} onClick={()=>this.handleModalVisible('plsc', true, null)}> 新增 </Button> </span> </Col> </Row> </Form> ); } onExpandedRowsChange = e => { this.setState({ expendKeys: e }) } render() { const { user: { currentUser } } = this.props; const {params,plsc, data, loading, edit, view, expendKeys} = this.state; const parentProps = { params: params, handleModalVisible: this.handleModalVisible, user:currentUser, query: this.query, data } return ( <PageHeaderWrapper> <Card bordered={false}> <div className="searchForm">{this.renderForm()}</div> <Table rowKey="key" loading={loading} dataSource={data} columns={this.columns} pagination={false} expandedRowKeys={expendKeys} onExpandedRowsChange={this.onExpandedRowsChange} /> </Card> {plsc && <AddNode modalVisible={plsc} {...parentProps} />} {edit && <EditNode modalVisible={edit} {...parentProps} record={this.current}/>} {view && <ViewNode modalVisible={view} {...parentProps} record={this.current}/>} </PageHeaderWrapper> ); } } export default OperationGuideManage;