Browse Source

列表过滤组件封装

zhuth 6 years ago
parent
commit
4b39614cbc

+ 4 - 59
src/components/chart/list.jsx

@@ -2,7 +2,7 @@
  * 图表列表
  */
 import React from 'react'
-import { Layout, Button, Icon, Input, Menu, Dropdown, Card, Col, Row, Breadcrumb, Tag, Checkbox, Select, DatePicker } from 'antd'
+import { Layout, Button, Icon, Menu, Dropdown, Card, Col, Row, Breadcrumb, Tag, Checkbox } from 'antd'
 import { connect } from 'dva'
 import ChooseDataSourceBox from './chooseDataSourceBox'
 import GroupManagementBox from '../common/groupManageMentBox/box'
@@ -16,12 +16,10 @@ import DistributeBox from './distributeBox';
 import TransferBox from '../common/selectUserBox/selectUserBox'
 import DeleteBox from '../common/deleteBox/deleteBox'
 import { arrayToTree } from '../../utils/baseUtils'
+import ListFilter from '../common/listFilter/index'
 import './list.less'
 const { Content } = Layout
-const { Search } = Input
 const CardGrid = Card.Grid
-const { Option } = Select
-const { RangePicker } = DatePicker
 
 
 class ChartList extends React.Component {
@@ -183,7 +181,7 @@ class ChartList extends React.Component {
         let { filterItem } = chart
 
         const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
-        let filterLabel = chart.filterLabel.replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
+        let filterLabel = chart.filterLabel ? (chart.filterLabel + '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') : ''; // 添加转义符号
         let filterReg = new RegExp('(' + filterLabel + '){1}', 'ig');
         
         
@@ -317,12 +315,6 @@ class ChartList extends React.Component {
         })
     }
 
-    generateFilterItems = () => {
-        const { filterItems } = this.props.chart;
-        return filterItems.map(t => <Option key={t.name}  value={t.name}>{t.label}</Option>);
-    }
-
-
     handleVisibleChange = (flag) => {
         this.setState({ visibleGroupMenu: flag });
     }
@@ -346,7 +338,6 @@ class ChartList extends React.Component {
     render() {
         const { dispatch, chart } = this.props;
         const { visibleChooseDataSourceBox, visibleDistributeBox, visibleGroupManageMentBox, visibleTransferBox, visibleDeleteBox, selectedRecord, noGroup } = this.state;
-        const { filterItem } = chart;
         return (
             <Layout className='chart-list'>
                 <Content>
@@ -364,54 +355,8 @@ class ChartList extends React.Component {
                                 { this.generateGroupTags() }
                             </Col>
                             <Col className='search'>
-                                <Col style={{ padding: '0 1px', margin: '0 -5px' }}>
-                                    <Select 
-                                        value={filterItem.name}
-                                        style={{ width: 120 }}
-                                        onChange={value => {
-                                            let item = chart.filterItems.find(i => i.name === value);
-                                            dispatch({ type: 'chart/setFilterItem', item });
-                                        }}
-                                    >
-                                        {this.generateFilterItems()}
-                                    </Select>
-                                </Col>
                                 <Col style={{ padding: '0 5px' }}>
-                                {filterItem.type === 'date' ? 
-                                    <RangePicker  
-                                        ranges={{
-                                            '今天': [moment().startOf('day'), moment().endOf('day')], 
-                                            '昨天': [moment().startOf('day').add(-1,'days'), moment().endOf('day')],
-                                            '近七天': [moment().startOf('day'),moment().endOf('day').add(6,'days')],
-                                            '本月': [moment().startOf('month'), moment().endOf('month')],
-                                            '本年': [moment().startOf('year'), moment().endOf('year')] 
-                                        }}
-                                        showTime={{ format: 'HH:mm' }}
-                                        format="YYYY-MM-DD HH:mm:ss"
-                                        onChange={e => {
-                                            //清空时间时
-                                            if(e.length === 0){
-                                                dispatch({ type: 'chart/setFilterLabel', label: '' });
-                                            }
-                                        }}
-                                        onOk={e => {
-                                            //解析时间格式
-                                            let start = e[0]
-                                            let end = e[1]
-                                            let time = start._d.getTime() + "#" + end._d.getTime()
-                                            dispatch({ type: 'chart/setFilterLabel', label: time });
-                                        }}
-                                    >
-                                    </RangePicker> 
-                                    : 
-                                    <Search
-                                        placeholder="请输入关键字"
-                                        value={chart.filterLabel}
-                                        onChange={e => {
-                                            dispatch({ type: 'chart/setFilterLabel', label: e.target.value });
-                                        }}
-                                    />
-                                }
+                                    <ListFilter modelName='chart' model={chart} />
                                 </Col>
                                 <Col >
                                     <Button style={{ marginRight: '8px' }} onClick={() => {

+ 123 - 0
src/components/common/listFilter/index.jsx

@@ -0,0 +1,123 @@
+import React from 'react'
+import { connect } from 'dva'
+import { DatePicker, Input, Select } from 'antd'
+import moment from 'moment'
+const { Search } = Input
+const { Option } = Select
+const { RangePicker } = DatePicker
+
+class ListFilter extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            fetch: false
+        }
+    }
+
+    generateFilterItem = () => {
+        const { modelName, model, dispatch } = this.props;
+        const { filterItems, filterItem } = model;
+
+        return <Select 
+            value={filterItem.name}
+            style={{ width: 120 }}
+            onChange={value => {
+                let item = filterItems.find(i => i.name === value);
+                dispatch({ type: modelName + '/setFilterItem', item });
+            }}
+        >
+            {filterItems.map(t => <Option key={t.name}  value={t.name}>{t.label}</Option>)}
+        </Select>
+    }
+
+    generateFilterValue = () => {
+        const { modelName, model, dispatch } = this.props;
+        const { fetching } = this.state;
+        const { filterItem } = model;
+        const { type, name } = filterItem;
+        if(type === 'date') {
+            return <RangePicker  
+                ranges={{
+                    '今天': [moment().startOf('day'), moment().endOf('day')], 
+                    '昨天': [moment().startOf('day').add(-1,'days'), moment().endOf('day')],
+                    '近七天': [moment().startOf('day'),moment().endOf('day').add(6,'days')],
+                    '本月': [moment().startOf('month'), moment().endOf('month')],
+                    '本年': [moment().startOf('year'), moment().endOf('year')] 
+                }}
+                showTime={{ format: 'HH:mm' }}
+                format="YYYY-MM-DD HH:mm:ss"
+                onChange={e => {
+                    //清空时间时
+                    if(e.length === 0){
+                        dispatch({ type: modelName + '/setFilterLabel', label: '' });
+                    }
+                }}
+                onOk={e => {
+                    //解析时间格式
+                    let start = e[0]
+                    let end = e[1]
+                    let time = start._d.getTime() + "#" + end._d.getTime()
+                    dispatch({ type: modelName + '/setFilterLabel', label: time });
+                }}
+            >
+            </RangePicker> 
+        }else if(type === 'string') {
+            return <Search
+                style={{ width: 150 }}
+                placeholder="请输入关键字"
+                value={model.filterLabel}
+                onChange={e => {
+                    dispatch({ type: modelName + '/setFilterLabel', label: e.target.value });
+                }}
+            />
+        }else if(type === 'enum') {
+            return <Select
+                allowClear
+                style={{ width: 150 }}
+                value={model.filterLabel || null}
+                loading={fetching}
+                onChange={(value) => {
+                    dispatch({ type: modelName + '/setFilterLabel', label: value ? value : '' });
+                }}
+                onFocus={() => {
+                    this.fetchData(filterItem)
+                }}
+            >
+                {this.state['options-' + name] ? this.state['options-' + name].map(o => <Option key={o.name} value={o.name}>{o.label}</Option>) : null}
+            </Select>
+        }
+    }
+
+    fetchData = (filterItem) => {
+        const { name, options } = filterItem;
+        let list = this.state['options-' + name];
+        if(!list || list.length === 0) {
+            if(options instanceof Array) {
+                let obj = {};
+                obj['options-' + name] = options;
+                this.setState(obj)
+            }else if(typeof options === 'function') {
+                this.setState({
+                    fetching: true
+                }, () => {
+                    options().then(list => {
+                        let obj = {
+                            fetching: false
+                        };
+                        obj['options-' + name] = list;
+                        this.setState(obj)
+                    });
+                });
+            }
+        }
+    }
+
+    render(){
+        return <div className='list-filter'>
+            {this.generateFilterItem()}
+            {this.generateFilterValue()}
+        </div>;
+    }
+}
+
+export default connect()(ListFilter)

+ 4 - 52
src/components/dataConnect/list.jsx

@@ -1,16 +1,14 @@
 import React from 'react'
-import { Layout, Row, Col, Input, Button, Icon, Card, Tooltip, Select, DatePicker } from 'antd'
+import { Layout, Row, Col, Button, Icon, Card, Tooltip, Select } from 'antd'
 import { connect } from 'dva'
-import moment from 'moment'
 import DeleteBox from '../common/deleteBox/deleteBox'
 import EmptyContent from '../common/emptyContent/index'
 import DataConnectBox from '../dataSourceDetail/dataConnectBox'
+import ListFilter from '../common/listFilter/index'
 import './list.less'
 const CardGrid = Card.Grid
 const { Content } = Layout
-const { Search } = Input
 const { Option } = Select
-const { RangePicker } = DatePicker
 
 class DataConnect extends React.Component {
     constructor(props) {
@@ -78,7 +76,7 @@ class DataConnect extends React.Component {
     generateCard() {
         const { dataConnect, dispatch } = this.props;
         const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
-        let filterLabel = dataConnect.filterLabel.replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
+        let filterLabel = dataConnect.filterLabel ? (dataConnect.filterLabel + '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') : ''; // 添加转义符号
         let filterItem = dataConnect.filterItem
         let filterReg = new RegExp('(' + filterLabel + '){1}', 'ig');
         let cards = dataConnect.list.map(l => {
@@ -228,54 +226,8 @@ class DataConnect extends React.Component {
                             <Col style={{ display: 'flex' }}>
                             </Col>
                             <Col className='search'>
-                                <Col style={{ padding: '0 1px', margin: '0 -5px' }}>
-                                    <Select 
-                                        value={dataConnect.filterItem.name}
-                                        style={{ width: 120 }}
-                                        onChange={value => {
-                                            let item = dataConnect.filterItems.find(i => i.name === value);
-                                            dispatch({ type: 'dataConnect/setFilterItem', item });
-                                        }}
-                                    >
-                                        { this.generateFilterItems() }
-                                    </Select>
-                                </Col>
                                 <Col style={{ padding: '0 5px' }}>
-                                    {dataConnect.filterItem.type === 'date' ? 
-                                        <RangePicker  
-                                            ranges={{
-                                                '今天': [moment().startOf('day'), moment().endOf('day')], 
-                                                '昨天': [moment().startOf('day').add(-1,'days'), moment().endOf('day')],
-                                                '近七天': [moment().startOf('day'),moment().endOf('day').add(6,'days')],
-                                                '本月': [moment().startOf('month'), moment().endOf('month')],
-                                                '本年': [moment().startOf('year'), moment().endOf('year')] 
-                                            }}
-                                            showTime={{ format: 'HH:mm' }}
-                                            format="YYYY-MM-DD HH:mm:ss"
-                                            onChange={e => {
-                                                //清空时间时
-                                                if(e.length === 0){
-                                                    dispatch({ type: 'dataConnect/setFilterLabel', label: '' });
-                                                }
-                                            }}
-                                            onOk={e => {
-                                                //解析时间格式
-                                                let start = e[0]
-                                                let end = e[1]
-                                                let time = start._d.getTime() + "#" + end._d.getTime()
-                                                dispatch({ type: 'dataConnect/setFilterLabel', label: time });
-                                            }}
-                                        >
-                                        </RangePicker> 
-                                        : 
-                                        <Search
-                                            value={dataConnect.filterLabel}
-                                            placeholder="请输入关键字"
-                                            onChange={e => {
-                                                dispatch({ type: 'dataConnect/setFilterLabel', label: e.target.value });
-                                            }}
-                                        />
-                                    }
+                                    <ListFilter modelName='dataConnect' model={dataConnect} />
                                 </Col>
                                 <Col >
                                     <Button style={{ marginRight: '8px' }} onClick={() => {

+ 16 - 54
src/components/dataSource/list.jsx

@@ -1,6 +1,5 @@
 import React from 'react'
-import moment from 'moment'
-import { Layout, Row, Col, Input, Button, Table, Icon, Menu, Dropdown, Card, Breadcrumb, Tag, Checkbox, Select, DatePicker } from 'antd'
+import { Layout, Row, Col, Button, Table, Icon, Menu, Dropdown, Card, Breadcrumb, Tag, Checkbox, Select } from 'antd'
 import { connect } from 'dva'
 import { arrayToTree, dateFormat } from '../../utils/baseUtils'
 import GroupManagementBox from '../common/groupManageMentBox/box'
@@ -9,11 +8,10 @@ import TransferBox from '../common/selectUserBox/selectUserBox'
 import CopyBox from './copyBox'
 import DeleteBox from '../common/deleteBox/deleteBox'
 import DataPreview from '../common/dataPreview/dataPreview'
+import ListFilter from '../common/listFilter/index'
 import './list.less'
 const { Content } = Layout
-const { Search } = Input
 const { Option } = Select
-const { RangePicker } = DatePicker
 
 class DataSource extends React.Component {
     constructor(props) {
@@ -67,7 +65,7 @@ class DataSource extends React.Component {
     onSearch(list, dataSource) {
         const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
         let filterItem = dataSource.filterItem
-        let filterLabel = (dataSource.filterLabel || '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
+        let filterLabel = dataSource.filterLabel ? (dataSource.filterLabel + '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') : ''; // 添加转义符号
         let filterReg = new RegExp('('+ filterLabel +'){1}', 'ig');
         
         return list.map(l => {
@@ -88,7 +86,12 @@ class DataSource extends React.Component {
                     return null 
                 }
             }else {
-                return ((o[filterItem.name] + '').search(filterReg) > -1) ? o : null
+                let arr = filterItem.name.split('.');
+                let v = o;
+                for(let i = 0; i < arr.length; i++) {
+                    v = v[arr[i]]
+                }
+                return ((v + '').search(filterReg) > -1) ? o : null
             }
         }).filter(a => a!==null);
     }
@@ -202,7 +205,7 @@ class DataSource extends React.Component {
         const treeData = arrayToTree(dataSource.groupList, '-1', 'code', 'pcode', 'children');
         const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
         let filterItem = dataSource.filterItem;
-        let filterLabel = dataSource.filterLabel.replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
+        let filterLabel = dataSource.filterLabel ? (dataSource.filterLabel + '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') : ''; // 添加转义符号
 
         const moreOperatingMenu = (
             <Menu className='operationmenu' visible={true}>
@@ -282,6 +285,11 @@ class DataSource extends React.Component {
                     </div>
                 </div>
             }
+        }, {
+            title: '数据链接',
+            dataIndex: 'dbConfig.name',
+            key: 'dbConfig.name',
+            width: 100
         }, {
             title: '说明',
             dataIndex: 'description',
@@ -358,54 +366,8 @@ class DataSource extends React.Component {
                                 { this.generateGroupTags() }
                             </Col>
                             <Col className='search'>
-                                <Col style={{ padding: '0 1px', margin: '0 -5px' }}>
-                                    <Select 
-                                        value={filterItem.name}
-                                        style={{ width: 120 }}
-                                        onChange={value => {
-                                            let item = dataSource.filterItems.find(i => i.name === value);
-                                            dispatch({ type: 'dataSource/setFilterItem', item });
-                                        }}
-                                    >
-                                        { this.generateFilterItems() }
-                                    </Select>
-                                </Col>
                                 <Col style={{ padding: '0 5px' }}>
-                                    {filterItem.type === 'date' ? 
-                                        <RangePicker  
-                                            ranges={{
-                                                '今天': [moment().startOf('day'), moment().endOf('day')], 
-                                                '昨天': [moment().startOf('day').add(-1,'days'), moment().endOf('day')],
-                                                '近七天': [moment().startOf('day'),moment().endOf('day').add(6,'days')],
-                                                '本月': [moment().startOf('month'), moment().endOf('month')],
-                                                '本年': [moment().startOf('year'), moment().endOf('year')] 
-                                            }}
-                                            showTime={{ format: 'HH:mm' }}
-                                            format="YYYY-MM-DD HH:mm:ss"
-                                            onChange={e => {
-                                                //清空时间时
-                                                if(e.length === 0){
-                                                    dispatch({ type: 'dataSource/setFilterLabel', label: '' });
-                                                }
-                                            }}
-                                            onOk={e => {
-                                                //解析时间格式
-                                                let start = e[0]
-                                                let end = e[1]
-                                                let time = start._d.getTime() + "#" + end._d.getTime()
-                                                dispatch({ type: 'dataSource/setFilterLabel', label: time });
-                                            }}
-                                        >
-                                        </RangePicker> 
-                                        : 
-                                        <Search
-                                            value={dataSource.filterLabel}
-                                            placeholder="请输入关键字"
-                                            onChange={e => {
-                                                dispatch({ type: 'dataSource/setFilterLabel', label: e.target.value });
-                                            }}
-                                        />
-                                    }
+                                    <ListFilter modelName='dataSource' model={dataSource} />
                                 </Col>
                                 <Col>
                                     <Button style={{ marginRight: '8px' }} onClick={() => {

+ 21 - 0
src/models/chart.js

@@ -17,6 +17,27 @@ export default {
                 { name: 'description', label: '说明', type: 'string' },
                 { name: 'creatorName', label: '创建人', type: 'string' },
                 { name: 'createTime', label: '创建时间', type: 'date' },
+                { name: 'dataSourceCode', label: '数据源', type: 'enum', options: () => {
+                    return service.fetch({
+                        url: URLS.DATASOURCE_LIST,
+                        method: 'GET',
+                        body: {
+                            pageNum: 1,
+                            pageSize: 999
+                        }
+                    }).then(res => {
+                        if(!res.error && res.data.code > 0) {
+                            return res.data.data.list.map(l => ({
+                                name: l.dataId,
+                                label: l.dataName,
+                            }));
+                        }else {
+                            message.error('获取数据源下拉列表失败: ' + res.data.msg);
+                        }
+                    }).catch(e => {
+                        message.error('获取数据源下拉列表失败: ' + e.message);
+                    });
+                } },
             ],
             filterItem: { name: 'name', label: '图表名称', type: 'string' }, // 已选过滤字段
         },

+ 21 - 0
src/models/dataSource.js

@@ -17,6 +17,27 @@ export default {
                 { name: 'description', label: '说明', type: 'string' },
                 { name: 'creatorName', label: '创建人', type: 'string' },
                 { name: 'createTime', label: '创建时间', type: 'date' },
+                { name: 'dbConfig.code', label: '数据连接', type: 'enum', options: () => {
+                    return service.fetch({
+                        url: URLS.DATACONNECT_LIST,
+                        method: 'GET',
+                        body: {
+                            pageNum: 1,
+                            pageSize: 999
+                        }
+                    }).then(res => {
+                        if(!res.error && res.data.code > 0) {
+                            return res.data.data.list.map(l => ({
+                                name: l.id,
+                                label: l.name,
+                            }));
+                        }else {
+                            message.error('获取数据源下拉列表失败: ' + res.data.msg);
+                        }
+                    }).catch(e => {
+                        message.error('获取数据源下拉列表失败: ' + e.message);
+                    });
+                } },
             ],
             filterItem: { name: 'name', label: '名称', type: 'string' }, // 已选过滤字段
         }