站点选择

@aligov/bops-site-select

站点选择

返回所有选择的子节点的 value。

如果一个节点下的所有子节点都已选择,那么展示父节点,返回的 value 依然是所有选择的子节点的 value。

基础功能

import SiteSelect from '@aligov/bops-site-select';

<SiteSelect />

基于基础的功能又做了下面的定制。

单选

import { SingleSiteSelect } from '@aligov/bops-site-select';

<SingleSiteSelect />

服务范围

import { ServiceRange } from '@aligov/bops-site-select';

<ServiceRange />

当前站点

import { CurSiteSelect } from '@aligov/bops-site-select';

<CurSiteSelect />

其他相关导出

API

参数名 说明 必填 类型 默认值 备注
rootId 根结点 id string
value 选择的值 array 添加该属性表示受控
queryService 数据加载服务 (rootId) => Promise<K[]> bops 默认服务 用来查询树数据
onChange 选择变更后触发的函数 (value) => void 一般搭配 value 来做受控
multiple 是否多选 boolean true
returnLeafValue 多选时是否返回叶子结点的值而非使用父节点替代 boolean true
className 扩展 treeSelect 的 className string mod-bops-site-select
popupClassName 扩展 treeSelect 下拉的 className string mod-bops-site-select-poup

queryService 需要返回一个数组,数组元素类型是 K,其至少需要包括 key, valuelabelparentId (父结点的 vlaue,无则为 null)属性。

基于 TreeSelect 组件,具体参考该组件的文档。

DEMO 列表

简单使用

mockService 只是这里 demo 用,否则除非有定制需求,不然不用传

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import BopsSiteSelect from '@aligov/bops-site-select';
import './demo.scss';

const mockData = require('./mock/all.json');

const mockService = (rootId) => {
  console.log('rootId', rootId);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(mockData);
    }, 1000);
  });
};

class App extends Component {
  render() {
    return (
      <div>
        <BopsSiteSelect rootId="330000" queryService={mockService} />
      </div>
    );
  }
}

ReactDOM.render((
  <App />
), mountNode);

单选

mockService 只是这里 demo 用,否则除非有定制需求,不然不用传

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { SingleSiteSelect } from '@aligov/bops-site-select';
import './demo.scss';

const mockData = require('./mock/all.json');

const mockService = (rootId) => {
  console.log('rootId', rootId);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(mockData);
    }, 1000);
  });
};

class App extends Component {
  state = {};

  onChange = (val) => {
    this.setState({
      value: val
    });
  };
  
  render() {
    const { value } = this.state;
    return (
      <div>
        <div style={{ display: 'flex' }}>
          <div style={{ flex: 1 }}>
            <h3>不受控</h3>
            <SingleSiteSelect queryService={mockService} />
          </div>
          <div style={{ flex: 1 }}>
            <h3>受控  value: {value}</h3>
            <SingleSiteSelect queryService={mockService} value={value} onChange={this.onChange}/>
          </div>
        </div>
      </div>
    );
  }
}

ReactDOM.render((
  <App/>
), mountNode);

受控

mockService 只是这里 demo 用,否则除非有定制需求,不然不用传

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import BopsSiteSelect from '@aligov/bops-site-select';
import './demo.scss';

const mockData = require('./mock/all.json');

const mockService = (rootId) => {
  console.log('rootId', rootId);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(mockData);
    }, 1000);
  });
};

class App extends Component {
  state = {
    value: []
  };
  
  onChange = (val) => {
    this.setState({
      value: val
    });
  };
  
  render() {
    const { value } = this.state;
    
    return (
      <div>
        <div>选择总数:{value.length}</div>
        <div>
          value: 
          <p style={{ wordBreak: 'break-all', wordWrap: 'break-word' }}>{JSON.stringify(value)}</p>
        </div>
        <BopsSiteSelect rootId="330000" value={value} queryService={mockService} onChange={this.onChange} />
      </div>
    );
  }
}

ReactDOM.render((
  <App />
), mountNode);

管理权力归属

mockService 只是这里 demo 用,否则除非有定制需求,不然不用传

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { SingleSiteSelect } from '@aligov/bops-site-select';
import './demo.scss';

const mockData = require('./mock/all.json');

const mockService = (rootId) => {
  console.log('rootId', rootId);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(mockData);
    }, 1000);
  });
};

class App extends Component {
  state = {
    value: []
  };
  
  onChange = (val) => {
    this.setState({
      value: val
    });
  };
  
  render() {
    const { value } = this.state;
    
    return (
      <div>
        <div>
          value: 
          <p style={{ wordBreak: 'break-all', wordWrap: 'break-word' }}>{JSON.stringify(value)}</p>
        </div>
        <SingleSiteSelect queryService={mockService} value={value} onChange={this.onChange} />
      </div>
    );
  }
}

ReactDOM.render((
  <App />
), mountNode);

服务范围

mockService 只是这里 demo 用,否则除非有定制需求,不然不用传

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { ServiceRange, SingleSiteSelect } from '@aligov/bops-site-select';
import './demo.scss';

const mockData = require('./mock/getAllSiteDetailByLeafId.json');

const mockService = (rootId) => {
  console.log('rootId', rootId);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(mockData);
    }, 1000);
  });
};

class App extends Component {
  state = {
    value: []
  };
  
  onChange = (val) => {
    this.setState({
      value: val
    });
  };
  
  render() {
    const { value } = this.state;
    
    return (
      <div>
        <div>选择总数:{value.length}</div>
        <div>
          value: 
          <p style={{ wordBreak: 'break-all', wordWrap: 'break-word' }}>{JSON.stringify(value)}</p>
        </div>
        <ServiceRange rootId="330199" value={value} queryService={mockService} onChange={this.onChange} />
      </div>
    );
  }
}

ReactDOM.render((
  <App />
), mountNode);

权力归属及服务范围

mockService 只是这里 demo 用,否则除非有定制需求,不然不用传

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Form, Field } from '@alifd/next';
import { ServiceRange, SingleSiteSelect } from '@aligov/bops-site-select';
import './demo.scss';

const FormItem = Form.Item;
const FormItemLayout = {
  labelCol: {
    fixedSpan: 5
  }
};

const mockAuthSites = require('./mock/getSiteByUserId.json');
const mockHZSites = require('./mock/getAllSiteDetailByLeafId.json');
const mockNBSites = require('./mock/getAllSiteDetailByLeafId_nb.json');

const mockAuthService = (rootId) => {
  console.log('rootId', rootId);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(mockAuthSites);
    }, 1000);
  });
};

const mockRangeService = (rootId) => {
  console.log('rootId', rootId);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(rootId == 330199 ? mockHZSites : mockNBSites);
    }, 1000);
  });
};

class App extends Component {
  field = new Field(this, {
    onChange: (name, value) => {
      if (name === 'scope') {
        this.field.setValue('range', []);
      }
    }
  });
  
  state = {
    scope: undefined,
    range: []
  };
  
  onChange = (val) => {
    this.setState({
      value: val
    });
  };
  
  render() {
    const { value } = this.state;
    
    return (
      <div>
        <h3>管理权力归属和服务范围联动</h3>
        <Form {...FormItemLayout} field={this.field}>
          <FormItem label="管理权力归属">
            <SingleSiteSelect name="scope" queryService={mockAuthService} />
          </FormItem>
          <FormItem label="服务范围">
            <ServiceRange name="range" rootId={this.field.getValue('scope')} queryService={mockRangeService} />
          </FormItem>
        </Form>
        <div>this.field.getValues(): {JSON.stringify(this.field.getValues())}</div>
      </div>
    );
  }
}

ReactDOM.render((
  <App />
), mountNode);

当前站点

mockService 只是这里 demo 用,否则除非有定制需求,不然不用传

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Form, Field } from '@alifd/next';
import { CurSiteSelectWithCtx } from '@aligov/bops-site-select';
import './demo.scss';

const FormItem = Form.Item;
const FormItemLayout = {
  labelCol: {
    fixedSpan: 5
  }
};

const mockData = require('./mock/getSiteByUserId.json');

const mockService = (rootId) => {
  console.log('rootId', rootId);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(mockData);
    }, 1000);
  });
};

class App extends Component {
  field = new Field(this, {
    onChange: (name, value) => {
      if (name === 'scope') {
        this.field.setValue('range', []);
      }
    }
  });
  
  state = {
    scope: undefined,
    range: []
  };
  
  onChange = (val) => {
    this.setState({
      value: val
    });
  };
  
  render() {
    const { value } = this.state;
    
    return (
      <div>
        <Form {...FormItemLayout} field={this.field}>
          <FormItem label="当前站点">
            <CurSiteSelectWithCtx queryService={mockService} name="curSite" />
          </FormItem>
        </Form>
        <div>this.field.getValues(): {JSON.stringify(this.field.getValues())}</div>
      </div>
    );
  }
}

ReactDOM.render((
  <App />
), mountNode);

使用当前站点的页面

mockService 只是这里 demo 用,否则除非有定制需求,不然不用传

import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
import { Form, Field } from '@alifd/next';
import { CurSiteBox, useCurSite } from '@aligov/bops-site-select';
import './demo.scss';

const FormItem = Form.Item;
const FormItemLayout = {
  labelCol: {
    fixedSpan: 5
  }
};

const mockData = require('./mock/getSiteByUserId.json');

const mockService = (rootId) => {
  console.log('rootId', rootId);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(mockData);
    }, 1000);
  });
};

function Content(props) {
  const [reloadCount, setReloadCount] = useState(0);
  const [reloading, setReloading] = useState(false);
  const { site } = useCurSite();
  
  // 模拟站点切换后更新数据
  useEffect(() => {
    setReloading(true);
    setTimeout(() => {
      setReloadCount(reloadCount + 1);
      setReloading(false);
    }, 1000);
  }, [site]);
  
  return (
    <div style={{ marginTop: 20 }}>
      <div>props: {JSON.stringify(props)}</div>
      <div>reloading: {reloading ? 'loading' : 'loaded'}</div>
      <div>reload count: {reloadCount}</div>
      <div>cur site: {site}</div>
    </div>
  );
}


const selectProps = {
  queryService: mockService
};

function App() {
  return (
    <CurSiteBox selectProps={selectProps}>
      <Content testA={1} />
    </CurSiteBox>
  );
}


ReactDOM.render((
  <App />
), mountNode);