| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- /**
- * 新增数据源-选择数据链接
- */
- import React from 'react'
- import { Layout, Form, Row, Col, Input, Icon, Menu, Dropdown, Divider, Upload, message, Card } from 'antd'
- import { connect } from 'dva'
- import DataConnectBox from './dataConnectBox'
- import EmptyContent from '../common/emptyContent/index'
- import './dataConnectConfig.less'
- const { Content } = Layout
- const CardGrid = Card.Grid
- const UploadDragger = Upload.Dragger
- const Search = Input.Search
- class DataConnectConfig extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- filterLabel: '',
- }
- }
-
- componentDidMount() {
- const { dispatch } = this.props;
- dispatch({ type: 'dataConnect/fetchList' });
- }
- generateCard() {
- const { dataConnect, dataSourceDetail, dispatch } = this.props;
- const { filterLabel: stateFilterLabel } = this.state;
- const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
- let filterLabel = stateFilterLabel ? (stateFilterLabel + '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') : ''; // 添加转义符号
- let filterReg = new RegExp('(' + filterLabel + '){1}', 'ig');
- let cards = dataConnect.list.map(l => {
- let o = Object.assign({}, l);
- return o.code === dataSourceDetail.connectCode || ((o['name'] + '').search(filterReg) > -1) ? o : null
- }).filter(a => a!==null).map( (l, i) => (
- <CardGrid className='dataconnect-card' key={i}>
- <Card
- hoverable={true}
- title={
- <Row type='flex' justify='start'
- onClick={() => {
- // 选中项设置
- dispatch({ type: 'dataConnect/setSelected', selected: l });
- dispatch({ type: 'dataSourceDetail/setFields', fields: [
- { name: 'connectCode', value: l.code },
- { name: 'dbType', value: l.dbType },
- { name: 'address', value: l.address },
- { name: 'port', value: l.port },
- { name: 'dbName', value: l.dbName },
- { name: 'userName', value: l.userName },
- { name: 'password', value: l.password },
- { name: 'target', value: '' },
- { name: 'columns', value: [] },
- { name: 'notice', value: '' },
- ] });
- }}
- >
- <Col className='label' title={l.name}>
- { (filterLabel) ?
- ((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.name
- }
- </Col>
- <div style={{ display: (dataConnect.selected && dataConnect.selected.code === l.code) ? 'block' : 'none' }} className='selected'></div>
- </Row>
- }
- actions={[
- <div>
- {l.dbType === 'file' ? <Icon type='file' /> : <div><Icon type='database' />{l.dbType[0].toUpperCase() + l.dbType.slice(1)}</div>}
- </div>,
- <Dropdown overlay={this.generateOperationMenu(l)} trigger={['click']}>
- <Icon style={{ fontSize: '24px' }} type="ellipsis" theme="outlined" />
- </Dropdown>
- ]}
- >
- <div className='content'
- onClick={() => {
- // 选中项设置
- dispatch({ type: 'dataConnect/setSelected', selected: l });
- dispatch({ type: 'dataSourceDetail/setFields', fields: [
- { name: 'connectCode', value: l.code },
- { name: 'connectName', value: l.name },
- { name: 'dbType', value: l.dbType },
- { name: 'address', value: l.address },
- { name: 'port', value: l.port },
- { name: 'dbName', value: l.dbName },
- { name: 'userName', value: l.userName },
- { name: 'password', value: l.password },
- { name: 'target', value: '' },
- { name: 'columns', value: [] },
- { name: 'notice', value: '' },
- ] });
- }}
- >
- { /** TODO 这里只考虑了数据库的展示情况,需要兼容展示文件类型的数据链接 */ }
- <Row className='address'>{l.address}</Row>
- <Row className='username'>{l.userName}</Row>
- </div>
- </Card>
- </CardGrid>
- ))
- if(cards.length === 0) {
- return <EmptyContent />
- }
-
- return cards;
- }
- generateOperationMenu = (item) => {
- const { dataConnect, dispatch } = this.props;
- return <Menu className='menu-operation'>
- <Menu.Item onClick={() => {
- dispatch({ type: 'dataConnect/setNewModel', model: item || dataConnect.selected });
- dispatch({ type: 'dataConnect/setNewModelFields', fields: [
- { name: 'visibleBox', value: true },
- { name: 'boxOperation', value: 'view' }
- ] });
- }}>
- <Icon type='edit'/>详情
- </Menu.Item>
- </Menu>
- }
- render() {
- const { dataSourceDetail, dispatch } = this.props;
- const { filterLabel } = this.state;
- return (
- <Form className='dataconnect-config' size='small'>
- {
- dataSourceDetail.type==='file'?(
- <div>
- <Divider orientation="left">选择文件</Divider>
- <UploadDragger
- className='upload'
- name='file' // 上传到后台的文件名
- fileList={dataSourceDetail.fileList}
- accept='application/vnd.ms-excel,.csv' // 只支持excel和csv格式文件
- action='//jsonplaceholder.typicode.com/posts/'
- headers={{authorization: 'authorization-text'}}
- beforeUpload={(file, fileList) => {
- const trueType = file.type === 'application/vnd.ms-excel';
- if (!trueType) {
- message.error('选择文件格式错误!');
- }
- const trueSize = file.size / 1024 / 1024 < 30;
- if (!trueSize) {
- message.error('选择文件过大!');
- }
- return trueType && trueSize;
- }}
- onChange={(info) => {
- const file = info.file;
- let fileList = info.fileList;
- fileList = fileList.slice(-1); // 只保留最后一个
- if (info.file.status !== 'uploading') {
- const trueType = file.type === 'application/vnd.ms-excel';
- const trueSize = file.size / 1024 / 1024 < 30;
- if(!trueType || !trueSize) {
- fileList = [];
- }
- }
- if (file.status === 'done') {
- message.success(`${file.name} 文件上传成功`);
- } else if (file.status === 'error') {
- fileList = [];
- message.error(`${file.name} 文件上传失败.`);
- }
- dispatch({ type: 'dataSourceDetail/setField', name: 'fileList', value: fileList })
- }}
- >
- <p className="ant-upload-drag-icon">
- <Icon type="inbox" />
- </p>
- <p className="ant-upload-text">点击选择或拖动文件到该区域</p>
- <p className="ant-upload-hint">仅支持上传单个30MB以内EXCEL/CSV格式文件</p>
- </UploadDragger>
- </div>
- ):(
- <Layout className='dataconnect'>
- <Content>
- <Card bordered={false} title={
- <Row type='flex' justify='end'>
- <Search
- style={{ width: '200px' }}
- value={filterLabel}
- placeholder="请输入关键字"
- onChange={e => {
- this.setState({
- filterLabel: e.target.value
- })
- // dispatch({ type: 'dataConnect/setFilterLabel', label: e.target.value });
- }}
- />
- </Row>
- }>
- <div className='dataconnect-list'>
- { this.generateCard() }
- </div>
- <DataConnectBox />
- </Card>
- </Content>
- </Layout>
- )
- }
- </Form>
- );
- }
- }
- export default connect(({ present: { dataSourceDetail, dataConnect } }) => ({ dataSourceDetail, dataConnect }))(DataConnectConfig);
|