|
|
@@ -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)
|