Эх сурвалжийг харах

筛选功能前后台对接

zhuth 7 жил өмнө
parent
commit
80cbd253b4

+ 0 - 29
jenkins/scripts/deliver.sh

@@ -1,29 +0,0 @@
-#!/usr/bin/env sh
-
-echo 'The following "npm" command builds your Node.js/React application for'
-echo 'production in the local "build" directory (i.e. within the'
-echo '"/var/jenkins_home/workspace/simple-node-js-react-app" directory),'
-echo 'correctly bundles React in production mode and optimizes the build for'
-echo 'the best performance.'
-set -x
-npm run build
-set +x
-
-echo 'The following "npm" command runs your Node.js/React application in'
-echo 'development mode and makes the application available for web browsing.'
-echo 'The "npm start" command has a trailing ampersand so that the command runs'
-echo 'as a background process (i.e. asynchronously). Otherwise, this command'
-echo 'can pause running builds of CI/CD applications indefinitely. "npm start"'
-echo 'is followed by another command that retrieves the process ID (PID) value'
-echo 'of the previously run process (i.e. "npm start") and writes this value to'
-echo 'the file ".pidfile".'
-set -x
-npm start &
-sleep 1
-echo $! > .pidfile
-set +x
-
-echo 'Now...'
-echo 'Visit http://localhost:80 to see your Node.js/React application in action.'
-echo '(This is why you specified the "args ''-p 3000:3000''" parameter when you'
-echo 'created your initial Pipeline as a Jenkinsfile.)'

+ 0 - 7
jenkins/scripts/kill.sh

@@ -1,7 +0,0 @@
-#!/usr/bin/env sh
-
-echo 'The following command terminates the "npm start" process using its PID'
-echo '(written to ".pidfile"), all of which were conducted when "deliver.sh"'
-echo 'was executed.'
-set -x
-kill $(cat .pidfile)

+ 6 - 4
src/components/chartDesigner/content.jsx

@@ -19,7 +19,7 @@ const { TabPane } = Tabs
 
 class ChartDesignerContent extends React.Component {
     render() {
-        const { chartDesigner, dispatch } = this.props;
+        const { chartDesigner, dispatch, loading } = this.props;
         const { baseConfig, autoRefresh } = chartDesigner;
         const { viewType } = baseConfig;
         const formItemLayout = {
@@ -78,12 +78,12 @@ class ChartDesignerContent extends React.Component {
                         </div>
                     </Footer> 
                 </Sider>
-                <Content>
+                <Content style={{ overflow: 'hidden' }}>
                     <Layout>
                         <Header className='content-header'>
                             <ToolBar className='header-toolbar'/>
                         </Header>
-                        <Content>
+                        <Content style={{ overflow: 'auto' }}>
                             { chartView }
                         </Content>
                     </Layout>
@@ -92,7 +92,9 @@ class ChartDesignerContent extends React.Component {
         )
     }
 }
-function mapStateToProps({ present: { chartDesigner } }) {
+function mapStateToProps(state) {
+    const chartDesigner = state.present.chartDesigner;
+
     return { chartDesigner: chartDesigner }
 }
 export default connect(mapStateToProps)(ChartDesignerContent);

+ 12 - 3
src/components/chartDesigner/layout.jsx

@@ -1,5 +1,5 @@
 import React from 'react'
-import { Layout } from 'antd'
+import { Layout, Spin, Icon } from 'antd'
 import './layout.less'
 import { connect } from 'dva'
 import ChartDesignerHeader from './header'
@@ -16,14 +16,23 @@ class ChartDesigner extends React.Component {
         }
     }
     render() {
+        const { loading } = this.props;
         return <Layout className='chartdesigner-layout'>
             <Header>
                 <ChartDesignerHeader />
             </Header>
-            <Content>
+            <Content style={{ height: 0 }}>
                 <ChartDesignerContent />
             </Content>
+            <div style={{ display: loading ? 'block' : 'none', position: 'absolute', height: '100%', width: '100%', zIndex: '4', background: 'rgba(51,51,51,.1)' }}>
+                <Spin style={{ display: 'inline-block', position: 'absolute', top: '50%', left: '50%', margin: '-10px' }} indicator={<Icon type="loading" style={{ fontSize: 24 }} spin />}/>
+            </div>
         </Layout>
     }
 }
-export default connect()(ChartDesigner);
+function mapStateToProps(state) {
+    const loading = state.present.loading.models.chartDesigner;
+
+    return { loading }
+}
+export default connect(mapStateToProps)(ChartDesigner);

+ 6 - 0
src/components/chartDesigner/sections/ScatterConfigForm.jsx

@@ -15,6 +15,8 @@ const ScatterConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
 				<Cascader
 					value={[chartDesigner.scatterConfig.xAxis.column.value, chartDesigner.scatterConfig.xAxis.granularity.value]}
 					allowClear={true}
+					showSearch
+					filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 					options={columns.filter(c =>['scale', 'ordinal'].indexOf(c.type) !== -1).map((c, i)=>{
 						return {
 							type: c.type,
@@ -58,6 +60,8 @@ const ScatterConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
 					className='gauge-item'
 					value={[chartDesigner.scatterConfig.yAxis.column.value, chartDesigner.scatterConfig.yAxis.gauge.value]}
 					allowClear={true}
+					showSearch
+					filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 					options={columns.map((c, i)=>{
 						return {
 							value: c.name,
@@ -121,6 +125,8 @@ const ScatterConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
 					maxTagCount={1}
 					labelInValue={true}
 					allowClear={true}
+					showSearch
+					filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 					placeholder='请选择...'
 					onChange={(value) => {
 						// value = value.splice(-1);

+ 5 - 2
src/components/chartDesigner/sections/aggregateTableConfigForm.jsx

@@ -21,19 +21,19 @@ class AggregateTableConfigForm extends React.Component {
 			searchKey: value
 		});
 	}
-
 	render() {
 		const props = this.props;
 		const { formItemLayout, chartDesigner, dispatch } = props;
 		const{ searchKey } = this.state;
 		const { columns, aggregateTableConfig } = chartDesigner;
-
+		
 		let options = columns.filter(c => c.label.toLowerCase().indexOf(searchKey.toLowerCase()) !== -1);
 		return (
 			<Form>
 				<FormItem label='分析目标' {...formItemLayout}>
 					<Select
 						value={aggregateTableConfig.targetColumn.name}
+						dropdownMatchSelectWidth={false}
 						showSearch
 						filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 						onChange={(value) => {
@@ -63,8 +63,11 @@ class AggregateTableConfigForm extends React.Component {
 					<Select
 						mode='multiple'
 						labelInValue={true}
+						dropdownMatchSelectWidth={false}
 						placeholder='请选择...'
 						allowClear={true}
+						showSearch
+						filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 						onChange={(value) => {
 							dispatch({ type: 'chartDesigner/changeField', name: 'aggregateTableConfig', value: { ...props.chartDesigner.aggregateTableConfig, groupBy: value } });
 						}}

+ 7 - 1
src/components/chartDesigner/sections/barConfigForm.jsx

@@ -1,7 +1,6 @@
 import React from 'react'
 import { Form, Select, Tag, Cascader, Dropdown, Menu } from 'antd'
 import { connect } from 'dva'
-import '../../../models/chartDesigner'
 import GAUGE from './gauge.json'
 import GRANULARITY from './granularity.json'
 const FormItem = Form.Item
@@ -11,6 +10,7 @@ const BarConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
 	
 	const columns = chartDesigner.columns;
 
+	console.log(chartDesigner.barConfig.groupBy);
 	return (
 		<Form hideRequiredMark={true}>
 			<FormItem label='横轴' {...formItemLayout}>
@@ -18,6 +18,8 @@ const BarConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
 					className='barconfig-yaxis'
 					value={[chartDesigner.barConfig.xAxis.column.value, chartDesigner.barConfig.xAxis.granularity.value]}
 					allowClear={true}
+					showSearch
+					filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 					options={columns.filter(c =>['ordinal', 'categorical', 'time'].indexOf(c.type) !== -1).map((c, i)=>{
 						
 						return {
@@ -61,6 +63,8 @@ const BarConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
 					className='gauge-item'
 					value={[chartDesigner.barConfig.yAxis.column.value, chartDesigner.barConfig.yAxis.gauge.value]}
 					allowClear={true}
+					showSearch
+					filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 					options={columns.map((c, i)=>{
 						return {
 							value: c.name,
@@ -123,6 +127,8 @@ const BarConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
 				<Select
 					labelInValue={true}
 					placeholder='请选择...'
+					showSearch
+					filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 					allowClear={true}
 					onChange={(value) => {
 						// value = value.splice(-1);

+ 4 - 0
src/components/chartDesigner/sections/dataViewConfigForm.jsx

@@ -16,6 +16,8 @@ class DataViewConfigForm extends React.Component {
 						mode='multiple'
 						allowClear
 						value={chartDesigner.dataViewConfig.viewColumns}
+						showSearch
+						filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 						labelInValue={true}
 						onChange={(value) => {
 							dispatch({ type: 'chartDesigner/changeField', name: 'dataViewConfig', value: { ...chartDesigner.dataViewConfig, viewColumns: value }});
@@ -31,6 +33,8 @@ class DataViewConfigForm extends React.Component {
 						allowClear
 						value={chartDesigner.dataViewConfig.sortColumn}
 						labelInValue={true}
+						showSearch
+						filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 						onChange={(value) => {
 							dispatch({ type: 'chartDesigner/changeField', name: 'dataViewConfig', value: { ...chartDesigner.dataViewConfig, sortColumn: value }});
 						}}

+ 6 - 0
src/components/chartDesigner/sections/lineConfigForm.jsx

@@ -16,6 +16,8 @@ const LineConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
 				<Cascader
 					value={[chartDesigner.lineConfig.xAxis.column.value, chartDesigner.lineConfig.xAxis.granularity.value]}
 					allowClear={true}
+					showSearch
+					filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 					options={columns.filter(c =>['time'].indexOf(c.type) !== -1).map((c, i)=>{
 						return {
 							type: c.type,
@@ -57,6 +59,8 @@ const LineConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
 					className='gauge-item'
 					value={[chartDesigner.lineConfig.yAxis.column.value, chartDesigner.lineConfig.yAxis.gauge.value]}
 					allowClear={true}
+					showSearch
+					filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 					options={columns.map((c, i)=>{
 						return {
 							value: c.name,
@@ -120,6 +124,8 @@ const LineConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
 					maxTagCount={1}
 					labelInValue={true}
 					allowClear={true}
+					showSearch
+					filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 					placeholder='请选择...'
 					onChange={(value) => {
 						// value = value.splice(-1);

+ 4 - 0
src/components/chartDesigner/sections/pieConfigForm.jsx

@@ -16,6 +16,8 @@ const PieConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
 				<Cascader
 					value={[chartDesigner.pieConfig.xAxis.column.value, chartDesigner.pieConfig.xAxis.granularity.value]}
 					allowClear={true}
+					showSearch
+					filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 					options={columns.filter(c =>['ordinal', 'categorical', 'time'].indexOf(c.type) !== -1).map((c, i)=>{
 						
 						return {
@@ -59,6 +61,8 @@ const PieConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
 					className='gauge-item'
 					value={[chartDesigner.pieConfig.yAxis.column.value, chartDesigner.pieConfig.yAxis.gauge.value]}
 					allowClear={true}
+					showSearch
+					filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
 					options={columns.map((c, i)=>{
 						return {
 							value: c.name,

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

@@ -3,7 +3,6 @@ import { Tag, Icon, Button } from 'antd'
 import FilterBox from './filterBox'
 import { connect } from 'dva'
 import { dateFormat } from '../../../utils/baseUtils'
-import '../../../models/chartDesigner'
 import './toolbar.less'
 
 class Toolbar extends React.Component {

+ 67 - 20
src/models/chartDesigner.js

@@ -2,20 +2,61 @@ import { message } from 'antd'
 import * as service from '../services/index'
 import URLS from '../constants/url'
 import STATISTICS_OPTION from '../components/chartDesigner/sections/statisticsOption.json'
+import { dateFormat } from '../utils/baseUtils'
+
+function getBodyFilters(filters) {
+    return filters.filter(f => f.using).map(f => {
+        let { name, operator, type, value1, value2 } = f;
+        let bodyFilter = {
+            columnName: name,
+            columnType: type,
+            symbol: operator,
+            value: value1
+        };
+        if(type === 'string' || type === 'index') {
+            if(operator === 'null' || operator === 'notNull') {
+            }else {
+                bodyFilter['value'] = value1;
+            }
+        }else if(type === 'scale') {
+            if(operator === 'null' || operator === 'notNull') {
+            }else if(operator === 'between') {
+                bodyFilter['value'] = value1 + ',' + value2;
+            }else {
+            }
+        }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');
+
+            if(operator === 'null' || operator === 'notNull') {
+            }else if(operator === 'between') {
+                bodyFilter['value'] = v1 + ',' + v2;
+            }else {
+                bodyFilter['value'] = v1;
+            }
+        }else if(type === 'categorical') {
+            if(operator === 'null' || operator === 'notNull') {
+            }else {
+            }
+        }else {
+        }
+        return bodyFilter;
+    }); 
+}
 
 export default {
     namespace: 'chartDesigner',
     state: {
         originData: {
             code: null,
-            header: { label: '未命名' },
+            header: { label: '标题' },
             baseConfig: { dataSource: '', viewType: '' },
             aggregateTableConfig: { targetColumn: {}, statistics: [], groupBy: [] },
             dataViewConfig: { viewColumns: [], sortColumn: {}, sortType: 'asc' },
-            barConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {} },
-            lineConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {} },
+            barConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {key:''} },
+            lineConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {key:''} },
             pieConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} } },
-            scatterConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {} },
+            scatterConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {key:''} },
             style: {},
             filters: [],
             chartOption: {},
@@ -33,10 +74,10 @@ export default {
         },
         aggregateTableConfig: { targetColumn: {}, statistics: [], groupBy: [] },
         dataViewConfig: { viewColumns: [], sortColumn: {}, sortType: 'asc' },
-        barConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {} },
-        lineConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {} },
+        barConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {key:''} },
+        lineConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {key:''} },
         pieConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} } },
-        scatterConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {} },
+        scatterConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {key:''} },
         styleConfig: { },
         otherConfig:{ },
         description: '',
@@ -314,7 +355,7 @@ export default {
         *fetchBarData(action, { select, call, put }) {
             try {
                 const chartDesigner = yield select(state => state.present.chartDesigner);
-                const { code, barConfig } = chartDesigner;
+                const { code, barConfig, filters } = chartDesigner;
                 const body = {
                     id: code,
                     groups: barConfig.groupBy && barConfig.groupBy.key ? [barConfig.groupBy.key] : [],
@@ -326,14 +367,15 @@ export default {
                     yAxis: {
                         columnRename: barConfig.yAxis.column.value,
                         showDataType: barConfig.yAxis.gauge.value
-                    }
+                    },
+                    filters: getBodyFilters(filters)
                 };
-                console.log(body);
                 
                 let res = yield call(service.fetch, {
                     url: URLS.CHART_BAR_OPTION,
                     body: body
                 });
+                console.log('请求柱状图数据', body, res);
                 if(!res.err && res.data.code > 0) {
                     let xTitle = barConfig.xAxis?`${barConfig.xAxis.column.label}${barConfig.xAxis.granularity.value?'('+barConfig.xAxis.granularity.label+')':''}`:null
                     let yTitle = barConfig.yAxis?`${barConfig.yAxis.column.label}${barConfig.yAxis.gauge.value?'('+barConfig.yAxis.gauge.label+')':''}`:null
@@ -359,7 +401,7 @@ export default {
         *fetchPieData(action, { select, call, put }) {
             try {
                 const chartDesigner = yield select(state => state.present.chartDesigner);
-                const { code, pieConfig } = chartDesigner;
+                const { code, pieConfig, filters } = chartDesigner;
                 const body = {
                     id: code,
                     legendData: {
@@ -371,13 +413,14 @@ export default {
                         columnRename: pieConfig.yAxis.column.value,
                         columnName: pieConfig.yAxis.column.label,
                         showDataType: pieConfig.yAxis.gauge.value
-                    }
+                    },
+                    filters: getBodyFilters(filters)
                 };
                 let res = yield call(service.fetch, {
                     url: URLS.CHART_PIE_OPTION,
                     body: body
                 });
-
+                console.log('请求饼图数据', body, res);
                 if(!res.err && res.data.code > 0) {
                     let columnName = pieConfig.xAxis.column.label + (pieConfig.xAxis.granularity.value ? '('+pieConfig.xAxis.granularity.label+')' : '');
                     
@@ -401,7 +444,7 @@ export default {
         *fetchLineData(action, { select, call, put }) {
             try {
                 const chartDesigner = yield select(state => state.present.chartDesigner);
-                const { code, lineConfig } = chartDesigner;
+                const { code, lineConfig, filters } = chartDesigner;
                 const body = {
                     id: code,
                     xAxis: {
@@ -413,11 +456,13 @@ export default {
                         showDataType: lineConfig.yAxis.gauge.value
                     },
                     groups: lineConfig.groupBy && lineConfig.groupBy.key ? [lineConfig.groupBy.key] : [],
+                    filters: getBodyFilters(filters)
                 };
                 let res = yield call(service.fetch, {
                     url: URLS.CHART_LINE_OPTION,
                     body: body
                 });
+                console.log('请求折线图数据', body, res);
                 if(!res.err && res.data.code > 0) {
                     let xTitle = lineConfig.xAxis?`${lineConfig.xAxis.column.label}${lineConfig.xAxis.granularity.value?'('+lineConfig.xAxis.granularity.label+')':''}`:null
                     let yTitle = lineConfig.yAxis?`${lineConfig.yAxis.column.label}${lineConfig.yAxis.gauge.value?'('+lineConfig.yAxis.gauge.label+')':''}`:null
@@ -443,7 +488,7 @@ export default {
         *fetchScatterData(action, { select, call, put }) {
             try {
                 const chartDesigner = yield select(state => state.present.chartDesigner);
-                const { code, scatterConfig } = chartDesigner;
+                const { code, scatterConfig, filters } = chartDesigner;
                 const body = {
                     id: code,
                     xAxis: {
@@ -455,13 +500,13 @@ export default {
                         showDataType: scatterConfig.yAxis.gauge.value
                     },
                     groups: scatterConfig.groupBy && scatterConfig.groupBy.key ? [scatterConfig.groupBy.key] : [],
+                    filters: getBodyFilters(filters)
                 };
-                console.log(body);
                 let res = yield call(service.fetch, {
                     url: URLS.CHART_SCATTER_OPTION,
                     body: body
                 });
-                console.log(res);
+                console.log('请求散点图数据', body, res);
                 if(!res.err && res.data.code > 0) {
                     res.viewType = 'scatter';
                     let xTitle = scatterConfig.xAxis?`${scatterConfig.xAxis.column.label}${scatterConfig.xAxis.granularity.value?'('+scatterConfig.xAxis.granularity.label+')':''}`:null
@@ -487,13 +532,14 @@ export default {
         *fetchDataViewData(action, { select, call, put }) {
             try {
                 const chartDesigner = yield select(state => state.present.chartDesigner);
-                const { code, dataViewConfig } = chartDesigner;
+                const { code, dataViewConfig, filters } = chartDesigner;
                 const body = {
                     id: code,
                     columnListName: dataViewConfig.viewColumns.map(c => c.key),
                     sortColumn: dataViewConfig.sortColumn.key,
                     sort: dataViewConfig.sortType,
-                    showLine: dataViewConfig.count
+                    showLine: dataViewConfig.count,
+                    filters: getBodyFilters(filters)
                 };
                 let res = yield call(service.fetch, {
                     url: URLS.CHART_DATAVIEW_OPTION,
@@ -534,7 +580,7 @@ export default {
         *fetchAggregateTableData(action, { select, call, put }) {
             try {
                 const chartDesigner = yield select(state => state.present.chartDesigner);
-                const { code, aggregateTableConfig } = chartDesigner;
+                const { code, aggregateTableConfig, filters } = chartDesigner;
                 const { targetColumn, statistics } = aggregateTableConfig;
 
                 const body = {
@@ -542,6 +588,7 @@ export default {
                     columnName: targetColumn.name,
                     operatorList: statistics,
                     groupByList: aggregateTableConfig.groupBy && aggregateTableConfig.groupBy.length > 0 ? aggregateTableConfig.groupBy.map(g => g.key) : [],
+                    filters: getBodyFilters(filters)
                 };
                 let res = yield call(service.fetch, {
                     url: URLS.CHART_AGGREGATETABLE_OPTION,