Browse Source

报表筛选自定义字段可以修改名称了

zhuth 6 years ago
parent
commit
89b74fee5f

+ 9 - 9
src/components/common/filterBox/filter2.jsx

@@ -190,6 +190,7 @@ class Filter extends React.Component {
         const { changeFilterValue: propsChangeFilterValue } = this.props;
         filter['value' + index] = value;
         if(propsChangeFilterValue && typeof propsChangeFilterValue === 'function') {
+            console.log('ok');
             propsChangeFilterValue({ ...filter });
         }
     }
@@ -197,19 +198,18 @@ class Filter extends React.Component {
     fetchColumnData = (filter, options) => {
         const { columnData } = this.state;
         const { keyword, mandatory } = options || {};
-        const { dataSource, value1 } = filter;
-        const isCusMode = dataSource.name === 'cus';
-        let column;
+        const { combined : isCusMode, dataSource, value1 } = filter;
+        let columns;
         if(isCusMode) {
-            column = dataSource.columns.find(c => c.name === filter.name)
+            columns = dataSource.map(d => ({
+                id: d.dataSource.code,
+                columnName: d.column.name,
+                keyword,
+            }))
         }
         if(!columnData || columnData.length === 0 || mandatory) {
             this.setState({ columnData: [], fetching: true }, () => {
-                const body = isCusMode ? column.relations.map(r => ({
-                    id: r.dataSource.code,
-                    columnName: r.column.name,
-                    keyword,
-                })) : {
+                const body = isCusMode ? columns : {
                     id: dataSource.name,
                     columnName: filter.name,
                     keyword, 

+ 8 - 8
src/components/common/filterBox/filterBox2.jsx

@@ -106,7 +106,7 @@ class FilterBox extends React.Component {
         const filters = form.getFieldValue('filters');
 
         let obj = {};
-        obj['columnData-' + value[0].name + '-' + value[1].name] = [];
+        obj['columnData-' + value[1].name] = [];
         this.setState(obj);
         form.setFieldsValue({
             filters: filters.map((f) => {
@@ -114,7 +114,7 @@ class FilterBox extends React.Component {
                     f.key = uuid++; // 每次重设key值以保证界面重现渲染,解决Select数据残留的问题
                     f.name = value[1].name;
                     f.combined = value[0].name === 'cus';
-                    f.dataSource = value[0];
+                    f.dataSource = value[1].relations ? value[1].relations : { code: value[0].name, label: value[0].label };
                     f.label = value[1].label;
                     f.type = value[1].type;
                     f.operator = OPERATORS[f.type][0].value;
@@ -188,10 +188,10 @@ class FilterBox extends React.Component {
         if(isCusMode) {
             column = dataSource.columns.find(c => c.name === filter.name)
         }
-        let columnData = this.state['columnData-' + filter.dataSource.name + '-' + filter.name]
+        let columnData = this.state['columnData-' + filter.name]
         if(!columnData || columnData.length === 0 || mandatory) {
             let obj = {fetching: true};
-            obj['columnData-' + filter.dataSource.name + '-' + filter.name] = []
+            obj['columnData-' + filter.name] = []
             this.setState(obj, () => {
                 const body = isCusMode ? column.relations.map(r => ({
                     id: r.dataSource.code,
@@ -216,11 +216,11 @@ class FilterBox extends React.Component {
                 }).then(r => {
                     const resData = r.data.data || [];
                     let obj = {fetching: false};
-                    obj['columnData-' + filter.dataSource.name + '-' + filter.name] = resData.filter(d => d.isFilter === '1').map(d => d || 'null')
+                    obj['columnData-' + filter.name] = resData.filter(d => d.isFilter === '1').map(d => d || 'null')
                     this.setState(obj);
                 }).catch(ex => {
                     let obj = {fetching: false};
-                    obj['columnData-' + filter.dataSource.name + '-' + filter.name] = [];
+                    obj['columnData-' + filter.name] = [];
                     this.setState(obj);
                     console.error('fetch error', ex);
                 });
@@ -284,7 +284,7 @@ class FilterBox extends React.Component {
                         <Col span={7}>
                             <FormItem key={key}>
                                 {getFieldDecorator(`filterName${key}`, {
-                                    initialValue: dataSource ? [dataSource.name, name] : undefined,
+                                    initialValue: dataSource ? (dataSource instanceof Array ? ['cus', name] : [dataSource.code, name]) : undefined,
                                     rules: [{ required: true, message: '列名不能为空' }]
                                 })(
                                     this.generateFieldItem(f)
@@ -380,7 +380,7 @@ class FilterBox extends React.Component {
     generateValueItem = (filter, index) => {
         const { fetching } = this.state;
         // const dropdownOpen = filter.key ? (this.state['dropdownOpen-' + filter.key] || false) : false;
-        const columnData = filter.name ? (this.state['columnData-' + filter.dataSource.name + '-' + filter.name] || []) : [];
+        const columnData = filter.name ? (this.state['columnData-' + filter.name] || []) : [];
         let field;
         const { type, operator } = filter;
 

+ 48 - 14
src/components/dashboardDesigner/cusFilterBox.jsx

@@ -1,6 +1,6 @@
 import React from 'react'
 import { connect } from 'dva'
-import { Modal, Input, Form, Button, Icon, Collapse, Spin } from 'antd'
+import { Modal, Input, Form, Button, Icon, Collapse, Spin, message } from 'antd'
 import './cusFilterBox.less'
 
 class CusFilterBox extends React.Component {
@@ -8,24 +8,36 @@ class CusFilterBox extends React.Component {
     constructor(props) {
         super(props);
         this.state = {
+            relationColumns: props.dashboardDesigner.relationColumns || []
         };
     }
 
     addRelationColumn = () => {
-        const { dispatch } = this.props;
-        dispatch({ type: 'dashboardDesigner/addRelationColumn' });
+        const { relationColumns } = this.state;
+        relationColumns.push({
+            code: Math.random()+'',
+            name: '新字段',
+            relations: []
+        });
+        this.setState({
+            relationColumns,
+        });
     }
 
     deleteRelationColumn = (e) => {
-        const { dispatch } = this.props;
         const code = e.target.dataset.code;
-        dispatch({ type: 'dashboardDesigner/deleteRelationColumn', code });
+        const { relationColumns } = this.state;
+        let index = relationColumns.findIndex(r => r.code === code);
+        relationColumns.splice(index, 1);
+        this.setState({
+            relationColumns,
+        });
     }
 
     generateRelations = () => {
         const { dashboardDesigner, dispatch } = this.props;
-        const { editing, selectedDataSource } = this.state;
-        const { relationColumns, dataSources, columnFetching } = dashboardDesigner;
+        const { relationColumns, editing, selectedDataSource } = this.state;
+        const { dataSources, columnFetching } = dashboardDesigner;
 
         return relationColumns.map((r, ri) => (
             <Collapse.Panel
@@ -34,7 +46,12 @@ class CusFilterBox extends React.Component {
                 header={<Form.Item className='filtercolumn-name' label='名称' labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
                     <Input size='small' value={r.name}
                     onChange={(e) => {
-                        dispatch({ type: 'dashboardDesigner/setRelationColumn', code: r.code, relationColumn: { ...r, name: e.target.value } });
+                        const { relationColumns } = this.state;
+                        let index = relationColumns.findIndex(a => a.code === r.code);
+                        relationColumns[index] = { ...r, name: e.target.value };
+                        this.setState({
+                            relationColumns
+                        });
                     }} onFocus={() => {
                         this.setState({
                             editing: true,
@@ -126,9 +143,7 @@ class CusFilterBox extends React.Component {
     }
 
     relationColumnClick = (c, r) => {
-        const { dashboardDesigner, dispatch } = this.props;
-        const { selectedDataSource } = this.state;
-        const { relationColumns } = dashboardDesigner;
+        const { relationColumns, selectedDataSource } = this.state;
         let setFlag, cusName;
 
         this.setState({
@@ -198,12 +213,14 @@ class CusFilterBox extends React.Component {
             }else {
                 relationColumns[index] = { ...r, relations }; 
             }
-            dispatch({ type: 'dashboardDesigner/setField', name: 'relationColumns', value: relationColumns });
+            this.setState({
+                relationColumns
+            });
         });
     }
 
     render() {
-        const { visibleBox, hideBox } = this.props;
+        const { visibleBox, hideBox, dispatch } = this.props;
         const { activeKey } = this.state;
 
         return <Modal
@@ -212,7 +229,24 @@ class CusFilterBox extends React.Component {
             height='80%'
             title='自定义过滤条件'
             visible={visibleBox}
-            footer={null}
+            footer={<Button className='okbtn' onClick={() => {
+                let relationColumns = this.state.relationColumns;
+                let flag = true;
+                for(let i = 0; i < relationColumns.length; i++) {
+                    let rc = relationColumns[i];
+                    if(rc.relations.length === 0) {
+                        message.error('第' + (i + 1) + '个条件[' + rc.name + ']未设置关联数据源列字段');
+                        flag = false;
+                        break;
+                    }
+                }
+                if(flag) {
+                    dispatch({ type: 'dashboardDesigner/setRelationColumns', relationColumns });
+                    hideBox();
+                }
+            }}>
+                确定
+            </Button>}
             onCancel={hideBox}
             maskClosable={false}
             destroyOnClose={true}

+ 70 - 21
src/models/dashboardDesigner.js

@@ -22,24 +22,21 @@ function getTrueFilters(item, filters) {
         )) {
             if(f.operator === 'betweent' ? ( !!f.value1 && (f.value1.length ? f.value1.length > 0 : true) && !!f.value2 && (f.value2.length ? f.value2.length > 0 : true)) : (!!f.value1 && (f.value1.length ? f.value1.length > 0 : true))) {
                 if(f.combined) {
-                    let column = f.dataSource.columns.find(c => c.name === f.name);
-                    column.relations.forEach(re => {
-                        if(re.dataSource.code === item.dataSourceCode) {
-                            trueFilters.push({
-                                dataSourceCode: re.dataSource.code,
-                                name: re.column.name,
-                                operator: f.operator,
-                                type: f.type,
-                                value1: f.value1,
-                                value2: f.value2,
-                                using: f.using
-                            });
-                        }
+                    f.dataSource.forEach(d => {
+                        trueFilters.push({
+                            dataSourceCode: d.dataSource.code,
+                            name: d.column.name,
+                            operator: f.operator,
+                            type: f.type,
+                            value1: f.value1,
+                            value2: f.value2,
+                            using: f.using
+                        });
                     });
                 }else {
-                    if(f.dataSource.name === item.dataSourceCode) {
+                    if(f.dataSource.code === item.dataSourceCode) {
                         trueFilters.push({
-                            dataSourceCode: f.dataSource.name,
+                            dataSourceCode: f.dataSource.code,
                             name: f.name,
                             operator: f.operator,
                             type: f.type,
@@ -277,7 +274,6 @@ export default {
             const { relationColumns } = state;
             let index = relationColumns.findIndex(r => r.code === code);
             relationColumns.splice(index, 1);
-            console.log(relationColumns);
             return { ...state, relationColumns, dirty: true };
         },
         setRelationColumn(state, action) {
@@ -406,11 +402,10 @@ export default {
             filters = filters.map(f => {
                 if(f.key === filter.key) {
                     if(f.combined) {
-                        let column = f.dataSource.columns.find(c => c.name === f.name);
-                        targetDataSourceCodes = targetDataSourceCodes.concat(column.relations.map(r => r.dataSource.code));
+                        targetDataSourceCodes = targetDataSourceCodes.concat(f.dataSource.map(d => d.dataSource.code));
                     }else {
-                        if(targetDataSourceCodes.indexOf(f.dataSource.name) === -1) {
-                            targetDataSourceCodes.push(f.dataSource.name);
+                        if(targetDataSourceCodes.indexOf(f.dataSource.code) === -1) {
+                            targetDataSourceCodes.push(f.dataSource.code);
                         }
                     }
                     return Object.assign({}, f, filter);
@@ -518,7 +513,61 @@ export default {
             }else {
                 return false;
             }
-        }
+        },
+        *setRelationColumns(action, { put, call, select }) {
+            const { relationColumns } = action;
+            let targetDataSourceCodes = []; // 记录有改动的数据源code
+            const dashboardDesigner = yield select(state => state.present.dashboardDesigner);
+            let { filters, items } = dashboardDesigner;
+            for(let i = filters.length - 1; i >= 0; i--) {
+                let f = filters[i];
+                let idx = relationColumns.findIndex(rc => rc.code === f.name);
+                if(idx > -1) {
+                    // 如果改变的自定义条件已经添加到了筛选条件区域
+                    let nrc = relationColumns[idx];
+                    let willRemove = false;
+                    if(f.type !== nrc.relations[0].column.type) { // 如果改变了所选的列
+                        willRemove = true;
+                    }
+                    let oldDataSourceCodes = f.dataSource.map(d => d.dataSource.code);
+                    let oldColumns = f.dataSource.map(d => d.column.name);
+                    let newDataSourceCodes = nrc.relations.map(r => r.dataSource.code);
+                    let newColumns = nrc.relations.map(r => r.column.name);
+
+                    if(!oldDataSourceCodes.equals(newDataSourceCodes) || !oldColumns.equals(newColumns)) { // 如果改变了数据源或者数据列
+                        willRemove = true;
+                    }
+                   
+                    if(willRemove) {
+                        f.dataSource.forEach(d => {
+                            targetDataSourceCodes.push(d.dataSource.code);
+                        });
+                        filters.splice(i, 1); // 将该过滤字段移除
+                    }else { // 只剩下label会改变了
+                        filters[i] = { ...filters[i], label: nrc.name }
+                    }
+                }else if(f.combined) { // 自定义字段已被删除
+                    f.dataSource.forEach(d => {
+                        targetDataSourceCodes.push(d.dataSource.code);
+                    });
+                    
+                    filters.splice(i, 1)
+                }
+            }
+            yield put({ type: 'setFields', fields: [
+                { name: 'relationColumns', value: relationColumns },
+                { name: 'filters', value: filters },
+                { name: 'dirty', value: true },
+            ] });
+            // 找到filters有影响的item
+            let targetItems = items.filter(item => targetDataSourceCodes.indexOf(item.dataSourceCode) !== -1);
+
+            yield put({ type: 'silentSetField', name: 'filters', value: filters });
+
+            for(let i = 0; i < targetItems.length; i++) {
+                yield put({ type:'fetchChartData', item: targetItems[i], mandatory: true });
+            }
+        },
     },
     subscriptions: {
         setup({ dispatch, history}) {

+ 31 - 1
src/utils/baseUtils.js

@@ -171,4 +171,34 @@ function arrayToTree(data, parent, $id, $pid, $sub) {
     return tree;
 }
 
-export { remove, isEqual, getUrlParam, hashcode, delay, dateFormat, arrayToTree };
+export { remove, isEqual, getUrlParam, hashcode, delay, dateFormat, arrayToTree };
+
+// Warn if overriding existing method
+if(Array.prototype.equals)
+    console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");
+// attach the .equals method to Array's prototype to call it on any array
+Array.prototype.equals = function (array) {
+    // if the other array is a falsy value, return
+    if (!array)
+        return false;
+
+    // compare lengths - can save a lot of time 
+    if (this.length !== array.length)
+        return false;
+
+    for (var i = 0, l = this.length; i < l; i++) {
+        // Check if we have nested arrays
+        if (this[i] instanceof Array && array[i] instanceof Array) {
+            // recurse into the nested arrays
+            if (!this[i].equals(array[i]))
+                return false;       
+        }           
+        else if (this[i] !== array[i]) { 
+            // Warning - two different object instances will never be equal: {x:20} != {x:20}
+            return false;   
+        }           
+    }       
+    return true;
+}
+// Hide method from for-in loops
+Object.defineProperty(Array.prototype, "equals", {enumerable: false});