Browse Source

数据源/图表策略过滤条件列数据查询接口调整

zhuth 7 years ago
parent
commit
5f1bf9389b

+ 3 - 29
src/components/chart/distributeBox.jsx

@@ -23,22 +23,6 @@ class DistributeBox extends React.Component {
         }
     }
 
-    componentDidMount() {
-        // const { selectedRecord, dispatch } = this.props;
-        // const chartCode = selectedRecord ? selectedRecord.code : '';
-        // dispatch({ type: 'dataSourcePolicy/fetchList', chartCode: chartCode });
-    }
-
-    hideDistributeObjectBox= () => {
-        this.setState(
-            {visibleDistributeObjectBox:false})
-    }
-
-    hideDistributePolicyRuleBox= () => {
-        this.setState(
-            {visibleDistributePolicyRuleBox:false})
-    }
-
     showAccessObjectBox = () => {
         this.setState({ visibleAccessObjectBox:true })
     }
@@ -135,17 +119,7 @@ class DistributeBox extends React.Component {
         const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
         let filterLabel = (this.state.filterLabel || '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
         
-        // const columnData = dataSource.newOne.columns ? dataSource.newOne.columns.map(c => ({
-        //     key: c.key,
-        //     label: c.alias,
-        //     name: c.name,
-        //     selection: [],
-        //     type: c.columnType,
-        //     groupable: c.groupable,
-        //     // filterable: c.filterable,
-        //     filterable: true,
-        //     bucketizable: c.bucketizable
-        // })) : [];
+        const { columnData } = chartPolicy;
         
         const columns = [{
             title:'启用',
@@ -254,7 +228,7 @@ class DistributeBox extends React.Component {
                 className='distribute-box'
                 title='图表分发策略'
                 visible={visibleDistributeBox}
-                onOk={this.okHandler}
+                onOk={hideBox}
                 onCancel={hideBox}
                 maskClosable={false}
                 destroyOnClose={true}
@@ -298,7 +272,7 @@ class DistributeBox extends React.Component {
                                 }}
                             />
                         </Card>
-                        <FilterBox key={Math.random()} columns={[]} filterData={currentPolicy ? currentPolicy.filters : []} visibleFilterBox={visiblePolicyRuleBox} hideFilterBox={this.hidePolicyRuleBox} createFilters={this.createFilters} />
+                        <FilterBox key={Math.random()} type='chart' code={chartCode} columns={columnData} filterData={currentPolicy ? currentPolicy.filters : []} visibleFilterBox={visiblePolicyRuleBox} hideFilterBox={this.hidePolicyRuleBox} createFilters={this.createFilters} />
                         <AccessObjectBox key={Math.random()} visibleBox={visibleAccessObjectBox} hideBox={this.hideAccessObjectBox} okHandler={this.setAccessObject} group={group} geren={geren} />
                     </Content>
                 </Layout>

+ 1 - 1
src/components/chart/list.jsx

@@ -74,6 +74,7 @@ class ChartList extends React.Component {
                     // const selectedChartDataSourceCode = selectedRecord ? selectedRecord.code : '';
                     const selectedChartCode = selectedRecord ? selectedRecord.code : '';
                     dispatch({ type: 'chartPolicy/fetchList', chartCode: selectedChartCode });
+                    dispatch({ type: 'chartPolicy/remoteColumnData', chartCode: selectedChartCode });
                     // dispatch({ type: 'chartDesigner/remoteDataColumn', code:  });
                     this.setState({visibleDistributeBox: true})
                 }}> 
@@ -463,7 +464,6 @@ class ChartList extends React.Component {
                     selectedRecord={selectedRecord}
                     onOk={() => {
                         dispatch({ type: 'chart/remoteDelete', code: this.state.selectedRecord.code })
-                        this.setState({ visibleDeleteBox: false })
                     }} />
             </Layout>
         )

+ 4 - 4
src/components/chartDesigner/sections/filterBox.jsx

@@ -171,18 +171,19 @@ class FilterBox extends React.Component {
     }
 
     fetchColumnData = (column) => {
-        const { chartCode } = this.props;
+        const { type, code } = this.props;
         const { columnData } = this.state;
         if(!columnData || columnData.length === 0) {
             this.setState({ columnData: [], fetching: true }, () => {
                 const body = {
-                    id: chartCode,
+                    id: code,
                     columnName: column.name
                 };
                 service.fetch({
-                    url: URLS.CHART_QUERY_COLUMNDATA,
+                    url: type === 'chart' ? URLS.CHART_QUERY_COLUMNDATA : URLS.DATASOURCE_QUERY_COLUMNDATA,
                     body: body,
                 }).then(r => {
+                    console.log('获得下拉数据', body, r);
                     if(!r.err && r.data.code > 0) {
                         return r;
                     }else {
@@ -190,7 +191,6 @@ class FilterBox extends React.Component {
                         throw obj;
                     }
                 }).then(r => {
-                    console.log('获得下拉数据', body, r);
                     const resData = r.data.data || [];
                     this.setState({
                         columnData: resData.map(d => d || 'null'),

+ 1 - 1
src/components/chartDesigner/sections/toolbar.jsx

@@ -129,7 +129,7 @@ class Toolbar extends React.Component {
                         })
                     }}>查看列</Button>
                 </div>
-                <FilterBox key={Math.random()} chartCode={code} columns={columns} filterData={filters} visibleFilterBox={visibleFilterBox} showFilterBox={this.showFilterBox} hideFilterBox={this.hideFilterBox} createFilters={this.createFilters} />  
+                <FilterBox key={Math.random()} type='chart' code={code} columns={columns} filterData={filters} visibleFilterBox={visibleFilterBox} showFilterBox={this.showFilterBox} hideFilterBox={this.hideFilterBox} createFilters={this.createFilters} />  
             </div>
         );
     }

+ 2 - 4
src/components/common/deleteBox.jsx

@@ -8,10 +8,8 @@ import { Modal } from 'antd'
  * visibleDeleteBox用于关联其父级容器中管理显示与否的state
  * hideBox方法用于隐藏对话框
  * selectedRecord用于传入被选中的条目
- * onOk方法用于执行删除操作并且需要传入隐藏对话框的方法
+ * onOk方法用于执行删除操作
  * 
- * TODO: 此处hideBox实际上传了两遍,不是很优雅
- *
  * @class DeleteBox
  * @extends {React.Component}
  * 
@@ -29,7 +27,7 @@ class DeleteBox extends React.Component {
             <Modal 
                 visible={visibleDeleteBox}
                 onCancel={hideBox}
-                onOk={onOk}
+                onOk={() => {onOk();hideBox();}}
                 destroyOnClose={true}
             >
                 <span>确定要删除{typeMapper[type]}:{selectedRecord ? selectedRecord.name : ''} 吗?</span>

+ 0 - 100
src/components/dashboard/dashboard.jsx

@@ -1,100 +0,0 @@
-import React from 'react'
-import { Tabs, Button, Icon, Input, Menu, Dropdown, Card, Avatar } from 'antd'
-import { connect } from 'dva'
-import './dashboard.less'
-const { Search } = Input
-const { TabPane } = Tabs
-const { Meta } = Card;
-
-
-class Dashboard extends React.Component {
-    constructor(props) {
-        super(props);
-        this.state = {
-        }
-    }
-
-    generateCard(listType) { 
-        let listTypeMapper = {
-            "Dynamic": this.props.dashboard.dashboardList,
-            "Static": this.props.dashboard.dashboardList, 
-        }
-        const list = listTypeMapper[listType];
-        return list.map(i => {
-            return (
-                <Card key={i.dashboardID}
-                    className='dashboard-card'
-                    cover={<img alt={i.coverAlt} src={i.coverImg} />}
-                    actions={[<Icon type="setting" />, <Icon type="edit" />, <Icon type="ellipsis" />]}
-                >
-                    <Meta
-                        avatar={<Avatar src={i.avatar} />}
-                        title={i.title}
-                        description={i.description}
-                    />
-                </Card>
-            )
-        })
-    }
-
-    render() {
-        const { dispatch } = this.props;
-        return (
-            <Tabs
-                className='dashboard-tabs'
-                type="card"
-                defaultActiveKey="1"
-                tabBarExtraContent={
-                    <div className='dashboard-tabs-tools'>
-                        <Search
-                            placeholder="请输入关键字"
-                            onSearch={value => console.log(value)}
-                        />
-                        <Dropdown overlay={(
-                            <Menu onClick={(item, key, keyPath) => {
-                                const type = item.key;
-                                dispatch({ type: 'dashboard/resetNewModel' });
-                                dispatch({ type: 'dashboard/setNewModelField', name: 'type', value: type });
-                                dispatch({ type: 'main/redirect', path: { pathname: '/dashboard/' + type + '/create' } });
-                            }}>
-                                <Menu.Item key='static'>报告</Menu.Item>
-                                <Menu.Item key='dynamic'>看板</Menu.Item>
-                            </Menu>
-                        )} trigger={['click']}>
-                            <Button style={{ display: 'inline-block' }}>
-                                <Icon type="plus" />创建
-                            </Button>
-                        </Dropdown>
-                    </div>
-                }
-                onChange={(key) => {
-                    this.setState({
-                        activeTab: key === '1' ? 'static' : 'dynamic'
-                    });
-                }}
-
-            >
-                <TabPane tab="我的看板" key="1" >
-                    <div style={{ display: 'flex', justifyContent: 'space-around', background: '#ECECEC', padding: '30px', flexWrap: 'wrap' }}>
-                        {this.generateCard("Dynamic")}
-                    </div>
-
-
-                </TabPane>
-                <TabPane tab="我的报告" key="2" >
-                    {/* 我的报表报告 */}
-                </TabPane>
-
-            </Tabs>
-        )
-
-
-    }
-}
-
-
-function mapStateToProps({present: {dashboard}}) {
-    return { dashboard }
-}
-
-export default connect(mapStateToProps)(Dashboard)

+ 0 - 18
src/components/dashboard/dashboard.less

@@ -1,18 +0,0 @@
-.dashboard-tabs {
-    .ant-tabs-bar {
-        margin-bottom: 0;
-        .ant-tabs-extra-content {
-            height: 100%;
-            .dashboard-tabs-tools {
-                .ant-input-search {
-                    width: 200px;
-                    margin-right: 5px;
-                }
-            }
-        }
-    }
-}
-
-.dashboard-card {
-    width: 300px 
-}

+ 265 - 84
src/components/dashboard/distributeBox.jsx

@@ -1,12 +1,14 @@
 import React from 'react'
-import { Modal, Table, Col, Row, Button, Input, Icon, Switch, Tag} from 'antd'
+import { Modal, Layout, Card, Table, Col, Row, Button, Input, Icon, Tag, Checkbox } from 'antd'
 import { connect } from 'dva'
-import DistributeObjectBox from './distributeObjectBox';
-import DistributePolicyRuleBox from './distributePolicyRuleBox';
+import FilterBox from '../chartDesigner/sections/filterBox'
+import AccessObjectBox from '../datasource/accessObjectBox'
+import * as moment from 'moment'
+import './distributeBox.less'
+const { Content } = Layout
 
 const Search = Input.Search;
 
-
 class DistributeBox extends React.Component {
     constructor(props){
         super(props);
@@ -14,8 +16,17 @@ class DistributeBox extends React.Component {
             filterLabel: '',
             visibleDistributeObjectBox: false,
             visibleDistributePolicyRuleBox: false,
+            currentPolicy: null,
+            visiblePolicyRuleBox: false,
+            visibleAccessObjectBox: false
         }
-    } 
+    }
+
+    componentDidMount() {
+        // const { selectedRecord, dispatch } = this.props;
+        // const chartCode = selectedRecord ? selectedRecord.code : '';
+        // dispatch({ type: 'dataSourcePolicy/fetchList', chartCode: chartCode });
+    }
 
     hideDistributeObjectBox= () => {
         this.setState(
@@ -26,100 +37,270 @@ class DistributeBox extends React.Component {
         this.setState(
             {visibleDistributePolicyRuleBox:false})
     }
+
+    showAccessObjectBox = () => {
+        this.setState({ visibleAccessObjectBox:true })
+    }
+
+    hideAccessObjectBox = () => {
+        this.setState({ visibleAccessObjectBox:false })
+    }
+
+    showPolicyRuleBox= () => {
+        this.setState({ visiblePolicyRuleBox: true })
+    }
+
+    hidePolicyRuleBox= () => {
+        this.setState({ visiblePolicyRuleBox: false })
+    }
+
+    setAccessObject = (group, geren) => {
+        const { dispatch } = this.props;
+        const { currentPolicy } = this.state;
+        let targets = group.map(g => ({
+            code: g.code,
+            name: g.name,
+            isGroup: true
+        })).concat(geren.map(g => ({
+            code: g.code,
+            name: g.name,
+            isGroup: false
+        })))
+        dispatch({ type: 'dashboardPolicy/remoteSetTarget', policy: currentPolicy, targets });
+    }
+
+    createFilters = (filters) => {
+        const { selectedRecord, dispatch } = this.props;
+        let { currentPolicy } = this.state;
+        const chartCode = selectedRecord ? selectedRecord.code : '';
+
+        currentPolicy.filters = filters;
+        dispatch({ type: 'dashboardPolicy/remoteModify', policy: currentPolicy, chartCode });
+    }
+
+    /**
+     * 生成过滤规则文本
+     */
+    createFilterLabel = (filter) => {
+        let { label, operator, operatorLabel, type, value1, value2 } = filter;
+        let filterLabel;
+
+        if(type === 'string' || type === 'index') {
+            if(operator === 'null' || operator === 'notNull') {
+                filterLabel = `${label} ${operatorLabel}`;
+            }else {
+                filterLabel = `${label} ${operatorLabel} ${value1}`;
+            }
+        }else if(type === 'scale') {
+            if(operator === 'null' || operator === 'notNull') {
+                filterLabel = `${label} ${operatorLabel}`;
+            }else if(operator === 'between') {
+                filterLabel = `${label} ${operatorLabel} ${value1} ~ ${value2}`; 
+            }else {
+                filterLabel = `${label} ${operatorLabel} ${value1}`; 
+            }
+        }else if(type === 'time') {
+            value1 = moment(value1).format('yyyy/MM/dd');
+            value2 = moment(value2).format('yyyy/MM/dd');
+            if(operator === 'null' || operator === 'notNull') {
+                filterLabel = `${label} ${operatorLabel}`;
+            }else if(operator === 'between') {
+                filterLabel = `${label} ${operatorLabel} ${value1} ~ ${value2}`;
+            }else {
+                filterLabel = `${label} ${operatorLabel} ${value1}`;
+            }
+        }else if(type === 'categorical') {
+            if(operator === 'null' || operator === 'notNull') {
+                filterLabel = `${label} ${operatorLabel}`;
+            }else {
+                filterLabel = `${label} ${operatorLabel} ${value1}`;
+            }
+        }else {
+            filterLabel = '错误条件';
+        }
+        return filterLabel;
+    }
+
     render() {
-        const { visibleDistributeObjectBox, visibleDistributePolicyRuleBox } = this.state;
-        const { visibleDistributeBox, hideBox } = this.props
-
-        const columns = [
-            {
-                title: '启用',
-                dataIndex:'enabled',
-                render: enabled => <Switch defaultChecked={enabled} />
-            },
-            {
+        const { selectedRecord, dashboardPolicy, visibleDistributeBox, hideBox, dispatch } = this.props;
+        const { visiblePolicyRuleBox, visibleAccessObjectBox } = this.state;
+        const polices = dashboardPolicy.list;
+        const chartCode = selectedRecord ? selectedRecord.code : '';
+
+        const { currentPolicy } = this.state;
+        const group = currentPolicy ? (currentPolicy.targets ? currentPolicy.targets.filter(t => t.isGroup) : []) : [];
+        const geren = currentPolicy ? (currentPolicy.targets ? currentPolicy.targets.filter(t => !t.isGroup) : []) : [];
+        
+        const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
+        let filterLabel = (this.state.filterLabel || '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
+        
+        // const columnData = dataSource.newOne.columns ? dataSource.newOne.columns.map(c => ({
+        //     key: c.key,
+        //     label: c.alias,
+        //     name: c.name,
+        //     selection: [],
+        //     type: c.columnType,
+        //     groupable: c.groupable,
+        //     // filterable: c.filterable,
+        //     filterable: true,
+        //     bucketizable: c.bucketizable
+        // })) : [];
+        
+        const columns = [{
+            title:'启用',
+            dataIndex:'enabled',
+            render: (v, r) => <Checkbox
+                checked={v}
+                onChange={(e) => {
+                    let policy = {
+                        ...r,
+                        enabled: e.target.checked
+                    }
+                    dispatch({ type: 'dashboardPolicy/remoteModify', policy, chartCode  });
+                }}
+            />,
+            width: 50
+        },{
             title: '策略名',
-            dataIndex: 'policyName',
-            render: policyName => <span>{policyName}<Icon type='copy'/></span>
-        }, {
-            title: '分发对象',
-            dataIndex: 'targets',
-            render: targets => {return (
-                <div>
-                    {targets.map((item, index) => {return <Tag key={index}>{item.isGroup ? <Icon type='tags'/>:<Icon type='user'/>}{item.value}</Tag>})}
-                    <Tag onClick={() => {this.setState({visibleDistributeObjectBox:true})}}><Icon type='plus'/></Tag>
-                </div>
-            )}
+            dataIndex: 'name',
+            render: (value, record, index) => <div key={index}>
+                {
+                    this.state.inputRow === index ? <Input value={value} suffix={<Icon style={{ cursor: 'pointer', color: '#52C41A' }} type="check-circle" onClick={() => {
+                        this.setState({
+                            inputRow: -1
+                        });
+                        dispatch({ type: 'dashboardPolicy/remoteModify', policy: record, chartCode });
+                    }}/>} onChange={(e) => {
+                        dispatch({ type: 'dashboardPolicy/modify', policy: { ...record, name: e.target.value } });
+                    }} onBlur={() => {
+                        this.setState({
+                            inputRow: -1
+                        });
+                        dispatch({ type: 'dashboardPolicy/remoteModify', policy: record, chartCode });
+                    }} onPressEnter={() => {
+                        this.setState({
+                            inputRow: -1
+                        });
+                        dispatch({ type: 'dashboardPolicy/remoteModify', policy: record, chartCode });
+                    }}/> : <span onClick={() => {
+                        this.setState({
+                            inputRow: index
+                        });
+                    }}>
+                        { filterLabel ?
+                            ((value || '').split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
+                                return (
+                                    fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === filterLabel.toLowerCase() ?
+                                    <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
+                                    fragment
+                                )
+                            }
+                            )) : value
+                        }
+                    </span>
+                }
+                {
+                    this.state.inputRow !== index && <Icon style={{ cursor: 'pointer' }} type='edit' onClick={() => {
+                        this.setState({
+                            inputRow: index
+                        });
+                    }} />
+                }
+            </div>,
+            width: 150
         }, {
             title: '行开放策略',
-            dataIndex: 'rowFilters',
-            render: rowFilters => {return (
-                <div>
-                    {rowFilters.map((filter, index) => {return <p key={index}>{filter.value}</p>})}
-                    <Tag onClick={() => {this.setState({visibleDistributePolicyRuleBox:true})}}><Icon type='plus'/></Tag>
-                </div>
-            )}
+            dataIndex: 'filters',
+            render: filter => <div>
+                {filter.length > 0 ? filter.map((f) =>
+                    <Tag
+                        className='filter-tag'
+                        key={f.code}
+                        closable={false}
+                    >
+                        {this.createFilterLabel(f)}
+                    </Tag>
+                ) : <Tag className='filter-tag' closable={false}>所有数据</Tag>}
+                <Tag
+                    onClick={this.showPolicyRuleBox}
+                    className={`filter-tag filter-tag-add`}
+                >
+                    <Icon type="filter" />
+                </Tag>
+            </div>,
+            width: 500
+        }, {
+            title: '开放对象',
+            dataIndex: 'targets',
+            render: targets => <div>
+                {
+                    targets.map((item, index) => <Tag key={index}>{item.isGroup ? <Icon type='group' /> : <Icon type='geren' />}{item.name}</Tag>)
+                }
+                <Tag onClick={this.showAccessObjectBox}><Icon type="plus" /></Tag>
+            </div>,
+            width: 300
         }, {
             title: '操作',
-            dataIndex: 'operation',
-            render: () => { return <span>删除</span>}
-        }]
-        
-        const data = [{
-            key: '1',
-            enabled: true,
-            policyName: '分发策略1',
-            targets: [{isGroup: true, value:'销售'}, {isGroup: false, value:'贺骎伟'}],
-            rowFilters: [{value:'部门字段包含售后,销售'}, {value:'公司名包含公司A'}],
-            columns: [{name:'department', alias:'部门', enabled: true}, {name:'company', alias:'公司', enabled: false}]
+            render: (v,r) => <div><span style={{ cursor: 'pointer' }} onClick={() => {
+                dispatch({ type: 'dashboardPolicy/remoteDelete', code: r.code });
+            }}>删除</span></div>,
+            width: 120
         }];
-
+        
         return (
             <Modal
                 width={1200}
                 className='distribute-box'
-                title={
-                    <Row>看板分发策略
-                    </Row>
-                }
+                title='图表分发策略'
                 visible={visibleDistributeBox}
                 onOk={this.okHandler}
                 onCancel={hideBox}
                 maskClosable={false}
                 destroyOnClose={true}
             >
-                <div>
-                    <Table
-                        columns={columns}
-                        dataSource={data}
-                        bordered
-                        title={() => {
-                            return (
-                                <div style={{ display: "flex", justifyContent: "space-between" }}>
-                                    <Col>
-                                        <Search
-                                            style={{ display: "inline" }}
-                                            placeholder="input search text"
-                                            onSearch={value => console.log(value)}
-                                            enterButton
-                                        />
-                                    </Col>
-                                    <Col>
-                                        <Button>新增策略</Button>
-                                    </Col>
-                                </div>
-                            )
-                        }}
-                    />
-                    <DistributeObjectBox 
-                        visibleDistributeObjectBox={visibleDistributeObjectBox}
-                        onCancel={this.hideDistributeObjectBox}
-                    />
-                    <DistributePolicyRuleBox
-                        visibleDistributePolicyRuleBox={visibleDistributePolicyRuleBox}
-                        onCancel={this.hideDistributePolicyRuleBox}
-                    />
-                </div>
-            
+                <Layout className='chart-policy'>
+                    <Content>
+                        <Card className='policy-body' title={
+                            <Row className='policy-tools' type='flex' justify='end'>
+                                <Col className='search'>
+                                    <Search
+                                        placeholder="请输入关键字"
+                                        onChange={e => {
+                                        }}
+                                    />
+                                    <Button className='add-btn' onClick={() => {
+                                        dispatch({ type: 'dashboardPolicy/remoteAdd', policy: {
+                                            code: Math.random(),
+                                            anabled: false,
+                                            name: '新策略',
+                                            targets: [],
+                                            filters: []
+                                        }, chartCode });
+                                    }}>
+                                        添加策略
+                                    </Button>
+                                </Col>
+                            </Row>
+                        }>
+                            <Table
+                                className='policy-table'
+                                columns={columns}
+                                dataSource={polices ? polices.filter(l => {
+                                    let reg = new RegExp('(' + filterLabel + '){1}', 'ig');
+                                    return (l.name || '').search(reg) !== -1;
+                                }).map((p, i) => ({ ...p, key: i })) : []}
+                                size='small'
+                                onRow={(record) => {
+                                    return {
+                                        onClick: () => {this.setState({ currentPolicy:  record})}
+                                    }
+                                }}
+                            />
+                        </Card>
+                        <FilterBox key={Math.random()} columns={[]} filterData={currentPolicy ? currentPolicy.filters : []} visibleFilterBox={visiblePolicyRuleBox} hideFilterBox={this.hidePolicyRuleBox} createFilters={this.createFilters} />
+                        <AccessObjectBox key={Math.random()} visibleBox={visibleAccessObjectBox} hideBox={this.hideAccessObjectBox} okHandler={this.setAccessObject} group={group} geren={geren} />
+                    </Content>
+                </Layout>
             </Modal>
         )
 
@@ -127,8 +308,8 @@ class DistributeBox extends React.Component {
     
 }
 
-function mapStateToProps({ present: { dataSource } }) {
-    return { dataSource: dataSource };
+function mapStateToProps({ present: { dashboardPolicy } }) {
+    return { dashboardPolicy };
 }
 
 export default connect(mapStateToProps)(DistributeBox)

+ 23 - 0
src/components/dashboard/distributeBox.less

@@ -0,0 +1,23 @@
+.distribute-box {
+    .ant-modal-body {
+        padding: 0;
+        .ant-card-head {
+            .ant-card-head-title {
+                padding: 8px 0;
+                .policy-tools {
+                    .search {
+                        .ant-input-search {
+                            width: auto;
+                        }
+                        .add-btn {
+                            margin-left: 5px;
+                        }
+                    }
+                }
+            }
+        }
+        .ant-card-body {
+            padding: 0;
+        }
+    }
+}

+ 0 - 19
src/components/dashboard/distributeObjectBox.jsx

@@ -1,19 +0,0 @@
-import React from 'react'
-import { Modal } from 'antd'
-
-
-class DistributeObjectBox extends React.Component {
-    render() {
-        const { visibleDistributeObjectBox, onCancel} = this.props
-        return (
-            <Modal
-                visible={visibleDistributeObjectBox}
-                onCancel={onCancel}
-            >
-                <span>Test</span>
-            </Modal>
-        )
-    }
-}
-
-export default DistributeObjectBox

+ 0 - 19
src/components/dashboard/distributePolicyRuleBox.jsx

@@ -1,19 +0,0 @@
-import React from 'react'
-import { Modal } from 'antd'
-
-
-class DistributePolicyRuleBox extends React.Component {
-    render() {
-        const { visibleDistributePolicyRuleBox, onCancel } = this.props
-        return (
-            <Modal 
-                visible={visibleDistributePolicyRuleBox}
-                onCancel={onCancel}
-            >
-                <span>Test</span>
-            </Modal>
-        )
-    }
-}
-
-export default DistributePolicyRuleBox

+ 3 - 4
src/components/dashboard/list.jsx

@@ -86,7 +86,7 @@ class DashboardList extends React.Component {
 
         let cards = list.filter(l => {
             let reg = new RegExp('(' + filterLabel + '){1}', 'ig');
-            return (l.title || '').search(reg) !== -1 || (l.description || '').search(reg) !== -1;
+            return (l.name || '').search(reg) !== -1 || (l.description || '').search(reg) !== -1;
         }).sort((a, b) => {
             return new Date(b.createTime) - new Date(a.createTime)
         }).map( (l, i) => (
@@ -98,14 +98,14 @@ class DashboardList extends React.Component {
                         <Row type='flex' justify='space-between'>
                             <Col span={21} style={{ overflow: 'hidden', textOverflow: 'ellipsis' }} >
                                 { filterLabel ?
-                                    ((l.title || '').split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
+                                    ((l.name || '').split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
                                         return (
                                             fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === filterLabel.toLowerCase() ?
                                             <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
                                             fragment
                                         )
                                     }
-                                    )) : l.title
+                                    )) : l.name
                                 }
                             </Col>
                             <Col style={{ textAlign: 'right' }} span={3} >
@@ -230,7 +230,6 @@ class DashboardList extends React.Component {
                     selectedRecord={selectedRecord}
                     onOk={() => {
                         dispatch({ type: 'dashboard/remoteDelete', code: this.state.selectedRecord.code })
-                        this.setState({ visibleDeleteBox: false })
                     }} />
             </Layout>
         )

+ 1 - 1
src/components/datasource/accessConfig.jsx

@@ -285,7 +285,7 @@ class DataSourceAccessConfig extends React.Component{
                             }}
                         />
                     </Card>
-                    <FilterBox key={Math.random()} columns={columnData} filterData={currentPolicy.filters} visibleFilterBox={visiblePolicyRuleBox} hideFilterBox={this.hidePolicyRuleBox} createFilters={this.createFilters} />
+                    <FilterBox key={Math.random()} type='dataSource' code={dataSource.newOne.code} columns={columnData} filterData={currentPolicy.filters} visibleFilterBox={visiblePolicyRuleBox} hideFilterBox={this.hidePolicyRuleBox} createFilters={this.createFilters} />
                     <AccessObjectBox key={Math.random()} visibleBox={visibleAccessObjectBox} hideBox={this.hideAccessObjectBox} okHandler={this.setAccessObject} group={group} geren={geren} />
                 </Content>
             </Layout>

+ 0 - 1
src/components/datasource/dataSource.jsx

@@ -480,7 +480,6 @@ class DataSource extends React.Component {
                             selectedRecord={selectedRecord}
                             onOk={() =>{
                                 dispatch({ type: 'dataSource/remoteDelete', code: selectedRecord.code })
-                                this.setState({visibleDeleteBox: false})
                             }} />
                     </Card>
                 </Content>

+ 6 - 2
src/constants/url.js

@@ -48,6 +48,8 @@ const URLS = {
     
     DATASOURCE_QUERY_DATACOLUMNS: BASE_URL + '/getColumnData', // 获得数据源下的列
 
+    DATASOURCE_QUERY_COLUMNDATA: BASE_URL + '/getScreenByBaseId', // 数据源获得列去重之后的数据
+
     DATASOURCE_POLICY_LIST: BASE_URL + '/getDbStrategys', // 获得数据源的策略
 
     DATASOURCE_POLICY_ADD: BASE_URL + '/addStrategys', // 添加策略
@@ -80,7 +82,7 @@ const URLS = {
 
     CHART_LIST: BASE_URL + '/getListCharts', // 获得图表列表
 
-    CHART_QUERY_COLUMNDATA: BASE_URL + '/showScreenData', // 获得列去重之后的数据
+    CHART_QUERY_COLUMNDATA: BASE_URL + '/showScreenData', // 图表获得列去重之后的数据
 
     CHART_DETAIL: BASE_URL + '/getChartsConfig', // 获得单个图表详细数据
 
@@ -96,13 +98,15 @@ const URLS = {
 
     CHART_AGGREGATETABLE_OPTION: BASE_URL + '/showPopulation', // 请求总体统计数据
 
+    CHART_QUERY_DATACOLUMNS: BASE_URL + '/getColumnByChartId', // 通过图表id获得列数据
+
     CHART_POLICY_LIST: BASE_URL + '/getChartStrategys', // 获得图表的策略
 
     CHART_POLICY_ADD: BASE_URL + '/addStrategys', // 添加策略
 
     CHART_POLICY_UPDATE: BASE_URL + '/updateStrategys', // 修改策略
 
-    CHART_POLICY_DELETE: BASE_URL + '/delDbStrategys', // 删除策略
+    CHART_POLICY_DELETE: BASE_URL + '/delChartStrategys', // 删除策略
 
     CHART_POLICY_TARGET_UPDATE: BASE_URL + '/addObject', // 设置策略对象
 

+ 2 - 0
src/index.js

@@ -12,6 +12,7 @@ import userGroup from './models/userGroup'
 import user from './models/user'
 import chartPolicy from './models/chartPolicy'
 import dataSourcePolicy from './models/dataSourcePolicy'
+import dashboardPolicy from './models/dashboardPolicy'
 import './utils/baseUtils'
 import './index.less'
 import createLoading from 'dva-loading';
@@ -42,6 +43,7 @@ app.model(userGroup); // 用户组
 app.model(user); // 用户
 app.model(chartPolicy); // 图表策略
 app.model(dataSourcePolicy); // 数据源策略
+app.model(dashboardPolicy); // 看板策略
 
 // 4. Router
 app.router(indexRouter);

+ 30 - 0
src/models/chartPolicy.js

@@ -87,6 +87,10 @@ export default {
                 }
             }
             return { ...state, list };
+        },
+        setColumnData(state, action) {
+            const { columnData } = action;
+            return { ...state, columnData }
         }
     },
     effects: {
@@ -239,6 +243,32 @@ export default {
                 console.log(body, e);
                 message.error('设置对象失败');
             }
+        },
+        /**
+         * 获得列数据
+         */
+        *remoteColumnData(action, { put, call, select }) {
+            const body = action.chartCode;
+            try {
+                const res = yield call(service.fetch, {
+                    url: URLS.CHART_QUERY_DATACOLUMNS,
+                    body
+                });
+                console.log('获得图表列数据', body, res);
+                if(!res.err && res.data.code > 0) {
+                    let columnData = res.data.data.map(d => ({
+                        name: d.columnName,
+                        label: d.columnRaname,
+                        type: d.columnType,
+                    }));
+                    yield put({ type: 'setColumnData', columnData });
+                }else {
+                    message.error('获得图表列数据失败:'+res.err||res.data.msg);
+                }
+            }catch(e) {
+                console.log(body, e);
+                message.error('获得图表列数据失败');
+            }
         }
     },
     subscriptions: {

+ 8 - 8
src/models/dashboard.js

@@ -41,7 +41,7 @@ export default {
                         let items = d.bdConfiguration ? JSON.parse(d.bdConfiguration) : [];
                         return {
                             code:  d.id+'',
-                            title: d.bdName,
+                            name: d.bdName,
                             items: items,
                             description: d.bdNote || '',
                             thumbnail: d.thumbnail,
@@ -74,7 +74,7 @@ export default {
 
                     let data = {
                         code:  resData.id+'',
-                        title: resData.bdName,
+                        name: resData.bdName,
                         items: items,
                         description: resData.bdNote || '',
                         thumbnail: resData.thumbnail,
@@ -101,9 +101,9 @@ export default {
         *remoteAdd(action, { select, call, put }) {
             try {
                 const dashboardDesigner = yield select(state => state.present.dashboardDesigner);
-                const { title, items } = dashboardDesigner;
+                const { name, items } = dashboardDesigner;
                 let body = {
-                    bdName: title,
+                    bdName: name,
                     bdNote: '',
                     bdConfiguration: JSON.stringify(items),
                     thumbnail: '',
@@ -129,9 +129,9 @@ export default {
         *remoteQucikAdd(action, { select, call, put }) {
             try {
                 const dashboardDesigner = yield select(state => state.present.dashboardDesigner);
-                const { title, items } = dashboardDesigner;
+                const { name, items } = dashboardDesigner;
                 let body = {
-                    bdName: title,
+                    bdName: name,
                     bdNote: '',
                     bdConfiguration: JSON.stringify(items),
                     thumbnail: '',
@@ -157,10 +157,10 @@ export default {
         *remoteModify(action, { select, call, put }) {
             try {
                 const dashboardDesigner = yield select(state => state.present.dashboardDesigner);
-                const { code, title, items } = dashboardDesigner;
+                const { code, name, items } = dashboardDesigner;
                 let body = {
                     id: code,
-                    bdName: title,
+                    bdName: name,
                     bdNote: '',
                     bdConfiguration: JSON.stringify(items),
                     thumbnail: '',

+ 5 - 5
src/models/dashboardDesigner.js

@@ -3,16 +3,16 @@ export default {
     state: {
         originData: {
             code: null,
-            title: '标题',
+            name: '标题',
             items: [],
             description: '',
             thumbnail: '',
             groupCode: '',
             dirty: false
         },
-        title: '标题',
+        name: '标题',
         basicConfig: {
-            title:'可爱的标题!',  
+            name:'可爱的标题!',  
             description:'',
             type:'',   //分为Dynamic和Static
             refreshTimer: 0, //自动刷新时间,如果是Static时应当无效或为0
@@ -70,7 +70,7 @@ export default {
             items = items.concat(charts.map(c => ({
                 code: c.code,
                 viewType: 'chart',
-                title: c.name,
+                name: c.name,
                 layout: { x: 0, y: 50, w: 12, h: 6},
                 chartCode: c.code
             })));
@@ -88,7 +88,7 @@ export default {
             items.push({
                 code: Math.random(),
                 viewType: 'richText',
-                title: '',
+                name: '',
                 layout: { x: 0, y: 50, w: 12, h: 6}
             });
             return Object.assign({}, state, {items, dirty: true});

+ 255 - 0
src/models/dashboardPolicy.js

@@ -0,0 +1,255 @@
+import { message } from 'antd'
+import * as service from '../services/index'
+import URLS from '../constants/url'
+import * as moment from 'moment'
+
+function getBodyFilter(modelFilter) {
+    let { name, label, operator, operatorLabel, type, value1, value2 } = modelFilter;
+    let bodyFilter = {
+        columnName: name,
+        columnLabel: label,
+        columnType: type,
+        symbol: operator,
+        symbolLabel: operatorLabel,
+        value: value1
+    };
+    if(type === 'scale' && operator === 'between') {
+        bodyFilter['value'] = value1 + ',' + value2;
+    }else if(type === 'time') {
+        // let v1 = dateFormat(new Date(value1),'yyyy-MM-dd hh:mm:ss');
+        // let v2 = dateFormat(new Date(value2),'yyyy-MM-dd hh:mm:ss');
+
+        let v1 = moment(value1).format('YYYY-MM-DD HH:mm:ss');
+        let v2 = moment(value2).format('YYYY-MM-DD HH:mm:ss');
+
+        if(operator === 'between') {
+            bodyFilter['value'] = v1 + ',' + v2;
+        }else {
+            bodyFilter['value'] = v1;
+        }
+    }
+    return bodyFilter;
+}
+function getModelFilter(resFilter) {
+    let { columnName, columnLabel, columnType, symbol, symbolLabel, value } = resFilter;
+    let modelFilter = {
+        name: columnName,
+        label: columnLabel,
+        type: columnType,
+        operator: symbol,
+        operatorLabel: symbolLabel,
+        value1: value
+    };
+    if(columnType === 'scale' && symbol === 'between') {
+        modelFilter['value1'] = value.split(',')[0];
+        modelFilter['value2'] = value.split(',')[1];
+    }else if(columnType === 'time') {
+        let value1 = value.split(',')[0];
+        let value2 = value.split(',')[1];
+        let v1 = moment(value1);
+        let v2 = moment(value2);
+
+        if(symbol === 'between') {
+            modelFilter['value1'] = v1;
+            modelFilter['value2'] = v2;
+        }else {
+            modelFilter['value'] = v1;
+        }
+    }
+    return modelFilter;
+}
+
+export default {
+    namespace: 'dashboardPolicy',
+    state: {
+        chartCode: null,
+        columnData: [],
+        list: [{
+            code: '1',
+                    enabled: true,
+                    name: '开放策略1',
+                    targets: [],
+                    filters: []
+        }]
+    },
+    reducers: {
+        list(state, action) {
+            const { list } = action;
+            return { ...state, list };
+        },
+        modify(state, action) {
+            const { policy } = action;
+            let { list } = state;
+            for(let i = 0; i < list.length; i++) {
+                if(list[i].code === policy.code) {
+                    list[i] = policy;
+                    break;
+                }
+            }
+            return { ...state, list };
+        }
+    },
+    effects: {
+        *fetchList(action, { select, call, put }) {
+            const body = action.chartCode;
+            return;
+            try {
+                const res = yield call(service.fetch, {
+                    url: URLS.CHART_POLICY_LIST,
+                    body
+                });
+                console.log('请求图表策略列表', body, res);
+                if(!res.err && res.data.code > 0) {
+                    let list = (res.data.data && res.data.data.length > 0) ? res.data.data.sort((a, b) => new Date(a.createDate) - new Date(b.createDate)).map(d => ({
+                        code: d.strategies.id,
+                        enabled: d.strategies.isOpen+'' === '1',
+                        name: d.strategies.name,
+                        targets: d.userGroupName.map(g => ({
+                            code: g.ID+'',
+                            isGroup: true,
+                            name: g.NAME
+                        })).concat(d.userName.map(u => ({
+                            code: u.ID+'',
+                            isGroup: false,
+                            name: u.NAME
+                        }))),
+                        filters: d.strategies.ruleStr ? JSON.parse(d.strategies.ruleStr).map(f => getModelFilter(f)) : [],
+                    })) : [];
+                    yield put({ type: 'list', list });
+                }else {
+                    message.error('请求图表策略列表失败');
+                }
+            }catch(e) {
+                console.log(body, e);
+                message.error('读取图表策略列表错误');
+            }
+        },
+        *remoteAdd(action, { put, call, select }) {
+            const chartPolicy = yield select(state => state.present.chartPolicy);
+            const { chartCode } = action;
+            const { policy } = action;
+            const body = {
+                type: 'chart',
+                tarId: chartCode,
+                name: policy.name,
+                rule: policy.filters.map(f => getBodyFilter(f)),
+                isOpen: policy.enabled ? '1' : '0',
+                createBy: 'zhuth'
+            };
+            return;
+            try {
+                const res = yield call(service.fetch, {
+                    url: URLS.CHART_POLICY_ADD,
+                    body,
+                });
+                console.log('添加策略', body, res);
+                if(!res.err && res.data.code > 0) {
+                    let { list } = chartPolicy;
+                    list.push({
+                        code: res.data.data,
+                        ...policy
+                    });
+                    yield put({ type: 'list', list });
+                }else {
+                    message.error('添加失败');
+                }
+            }catch(e) {
+                console.log(body, e);
+                message.error('添加失败');
+            }
+        },
+        *remoteModify(action, { put, call, select }) {
+            const { policy, chartCode } = action;
+            console.log(chartCode);
+            const body = {
+                id: policy.code,
+                type: 'chart',
+                tarId: chartCode,
+                name: policy.name,
+                rule: policy.filters.map(f => getBodyFilter(f)),
+                isOpen: policy.enabled ? '1' : '0',
+                createBy: 'zhuth'
+            };
+            return;
+            try {
+                const res = yield call(service.fetch, {
+                    url: URLS.CHART_POLICY_UPDATE,
+                    body
+                });
+                console.log('修改图表策略', body, res);
+                if(!res.err && res.data.code > 0) {
+                    yield put({ type: 'modify', policy });
+                }else {
+                    message.error('修改失败');
+                }
+            }catch(e) {
+                console.log(body, e);
+                message.error('修改失败');
+            }
+        },
+        *remoteDelete(action, { put, call, select }) {
+            const chartPolicy = yield select(state => state.present.chartPolicy);
+            const { code } = action;
+            const body = [code];
+            return;
+            try {
+                const res = yield call(service.fetch, {
+                    url: URLS.CHART_POLICY_DELETE,
+                    body
+                });
+                console.log('删除策略', body, res);
+                if(!res.err && res.data.code > 0) {
+                    let { list } = chartPolicy;
+                    for(let i = 0; i < list.length; i++) {
+                        if(list[i].code === code) {
+                            list.splice(i, 1);
+                            break;
+                        }
+                    }
+                    yield put({ type: 'list', list });
+                }else {
+                    message.error('删除失败');
+                }
+            }catch(e) {
+                console.log(body, e);
+                message.error('删除失败');
+            }
+        },
+        *remoteSetTarget(action, { put, call, select }) {
+            const { policy, targets } = action;
+            const body = {
+                stId: policy.code+'',
+                type: 'chart',
+                obj: targets.map(t => ({
+                    obId: t.code,
+                    objectType: t.isGroup ? '0' : '1'
+                }))
+            };
+            return;
+            try {
+                const res = yield call(service.fetch, {
+                    url: URLS.CHART_POLICY_TARGET_UPDATE,
+                    body
+                });
+                console.log('设置策略对象', body, res);
+                if(!res.err && res.data.code > 0) {
+                    yield put({ type: 'modify', policy: {
+                        ...policy,
+                        targets
+                    } });
+                }else {
+                    message.error('设置对象失败');
+                }
+            }catch(e) {
+                console.log(body, e);
+                message.error('设置对象失败');
+            }
+        }
+    },
+    subscriptions: {
+        setup({ dispatch, history }) {
+            return history.listen(({ pathname, query }) => {
+            })
+        }
+    }
+};