baseConfig.jsx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. import React from 'react'
  2. import { Form, Input, Select, Divider, Cascader } from 'antd'
  3. import { arrayToTree } from '../../utils/baseUtils'
  4. import { connect } from 'dva'
  5. import './baseConfig.less'
  6. const FormItem = Form.Item
  7. const SelectOption = Select.Option
  8. class DataSourceBaseConfig extends React.Component {
  9. constructor(props) {
  10. super(props);
  11. this.state = {
  12. validInfo: {
  13. name: { status: 'success', help: '' },
  14. description: { status: 'success', help: '' },
  15. }
  16. }
  17. }
  18. generateOptions () {
  19. const { dataConnect } = this.props;
  20. const { list } = dataConnect;
  21. return list.map((l) => {
  22. return <SelectOption value={l.code} key={l.code}>
  23. { l.name }
  24. </SelectOption>
  25. });
  26. }
  27. componentDidMount() {
  28. const { dispatch } = this.props;
  29. dispatch({ type: 'dataSource/remoteGroupList' });
  30. dispatch({ type: 'dataConnect/fetchList' });
  31. }
  32. generateGroupOptions = (treeData) => {
  33. return treeData.map(t => {
  34. t.children = t.children instanceof Array ? t.children : [];
  35. return {
  36. key: t.code,
  37. value: t.code,
  38. label: t.label,
  39. children: this.generateGroupOptions(t.children)
  40. }
  41. })
  42. }
  43. getParents = (group) => {
  44. const groupData = this.props.dataSource.groupList;
  45. let pgroups = [group];
  46. let fgroup = groupData.find(g => g.code === group.pcode);
  47. if(fgroup) {
  48. pgroups = this.getParents(fgroup).concat(pgroups);
  49. }
  50. return pgroups;
  51. }
  52. render() {
  53. const { dataConnect, dataSource, dataSourceDetail, dispatch } = this.props;
  54. const { validInfo } = this.state;
  55. const treeData = arrayToTree(dataSource.groupList, '-1', 'code', 'pcode', 'children');
  56. const formItemLayout = {
  57. labelCol: { span: 4 },
  58. wrapperCol: { span: 20 },
  59. };
  60. let getGroup = () => {
  61. const { group: key } = dataSourceDetail;
  62. if(key === '-1') {
  63. return ['-1'];
  64. }else {
  65. let group = dataSource.groupList.find(g => g.code === key);
  66. if(group) {
  67. let groups = this.getParents(group);
  68. let val = groups.map(g => g.code);
  69. return val;
  70. }else {
  71. return null;
  72. }
  73. }
  74. }
  75. return (
  76. <Form className='base-config' size='small'>
  77. <FormItem label='数据源名称' {...formItemLayout}
  78. validateStatus={validInfo.name.status}
  79. help={validInfo.name.help}
  80. >
  81. <Input
  82. key={dataSourceDetail.name}
  83. defaultValue={dataSourceDetail.name}
  84. onBlur={(e) => {
  85. dispatch({ type: 'dataSourceDetail/setField', name: 'name', value: e.target.value+'' });
  86. }}
  87. onChange={e => {
  88. let val = e.target.value + '';
  89. let status, help;
  90. if(val.trim().length === 0) {
  91. status = 'error';
  92. help = '数据源名称不能为空';
  93. }else if(val.trim().length > 50) {
  94. status = 'error';
  95. help = '数据源名称不能超过50个字符';
  96. }else {
  97. status = 'success';
  98. help = '';
  99. }
  100. window.clearTimeout(this.nameTimeout);
  101. this.nameTimeout = window.setTimeout(() => {
  102. this.setState({
  103. validInfo: { ...validInfo, name: { status, help } }
  104. });
  105. }, 100);
  106. }}>
  107. </Input>
  108. </FormItem>
  109. {
  110. dataSourceDetail.type==='file'?(
  111. <div>
  112. <Divider orientation="left">文件</Divider>
  113. <div>此处显示文件名</div>
  114. </div>
  115. ):(
  116. <div>
  117. <FormItem label='数据链接' {...formItemLayout}>
  118. <Select
  119. disabled
  120. value={dataSourceDetail.connectCode}
  121. onChange={(value) => {
  122. let selectedDataConnect = dataConnect.list.filter((l) => l.code === value)[0];
  123. dispatch({ type: 'dataSourceDetail/setFields', fields: [
  124. { name: 'connectCode', value: selectedDataConnect.code },
  125. { name: 'dbType', value: selectedDataConnect.dbType },
  126. { name: 'address', value: selectedDataConnect.address },
  127. { name: 'port', value: selectedDataConnect.port },
  128. { name: 'dbName', value: selectedDataConnect.dbName },
  129. { name: 'userName', value: selectedDataConnect.userName },
  130. ] } );
  131. }}
  132. >
  133. { this.generateOptions() }
  134. </Select>
  135. </FormItem>
  136. {/* <FormItem label='数据库类型' {...formItemLayout}>
  137. <Select
  138. disabled={true}
  139. value={dataSourceDetail.dbType}
  140. onChange={(value) => {
  141. dispatch({ type: 'dataSourceDetail/setField', name: 'dbType', value: value} );
  142. }}
  143. >
  144. <SelectOption value='oracle'>
  145. ORACLE
  146. </SelectOption>
  147. <SelectOption value='mysql'>
  148. MYSQL
  149. </SelectOption>
  150. <SelectOption value='sqlserver'>
  151. SQLSERVER
  152. </SelectOption>
  153. <SelectOption value='sqlite'>
  154. SQLITE
  155. </SelectOption>
  156. </Select>
  157. </FormItem>
  158. <Row>
  159. <Col span={19}>
  160. <FormItem label='数据库地址' {...{
  161. labelCol: { span: 5 },
  162. wrapperCol: { span: 19 }
  163. }}>
  164. <Input
  165. disabled={true}
  166. value={dataSourceDetail.address}
  167. onChange={(e) => {
  168. dispatch({ type: 'dataSourceDetail/setField', name: 'address', value: e.target.value });
  169. }}
  170. />
  171. </FormItem>
  172. </Col>
  173. <Col span={5}>
  174. <FormItem className='input-port' label='端口' {...{
  175. labelCol: { span: 12 },
  176. wrapperCol: { span: 12 }
  177. }}>
  178. <InputNumber
  179. disabled={true}
  180. value={dataSourceDetail.port}
  181. onChange={(value) => {
  182. dispatch({ type: 'dataSourceDetail/setField', name: 'port', value: value });
  183. }}
  184. />
  185. </FormItem>
  186. </Col>
  187. </Row>
  188. <FormItem label='数据库名' {...formItemLayout}>
  189. <Input
  190. disabled={true}
  191. value={dataSourceDetail.dbName}
  192. onChange={(e) => {
  193. dispatch({ type: 'dataSourceDetail/setField', name: 'dbName', value: e.target.value });
  194. }}
  195. />
  196. </FormItem>
  197. <Row>
  198. <Col span={12}>
  199. <FormItem label='用户名' {...{
  200. labelCol: { span: 8 },
  201. wrapperCol: { span: 16 }
  202. }}>
  203. <Input
  204. disabled={true}
  205. value={dataSourceDetail.userName}
  206. onChange={(e) => {
  207. dispatch({ type: 'dataSourceDetail/setField', name: 'userName', value: e.target.value });
  208. }}
  209. />
  210. </FormItem>
  211. </Col>
  212. <Col span={12}>
  213. <FormItem label='密码' {...{
  214. labelCol: { span: 8 },
  215. wrapperCol: { span: 16 }
  216. }}>
  217. <Input
  218. disabled={true}
  219. // value={dataSourceDetail.password}
  220. onChange={(e) => {
  221. let value = e.target.value;
  222. dispatch({ type: 'dataSourceDetail/setField', name: 'password', value: value });
  223. e.target.removeAttribute('value')
  224. }}
  225. />
  226. </FormItem>
  227. </Col>
  228. </Row> */}
  229. </div>
  230. )
  231. }
  232. <FormItem label='所属分组' {...formItemLayout}>
  233. <Cascader
  234. value={getGroup()}
  235. allowClear={true}
  236. changeOnSelect={true}
  237. expandTrigger='hover'
  238. placeholder='未分组'
  239. options={this.generateGroupOptions([{pcode: '-1', code: '-1', label: '未分组'}].concat(treeData))}
  240. onChange={(value, items) => {
  241. let v = value[value.length - 1];
  242. dispatch({ type: 'dataSourceDetail/setField', name: 'group', value: v });
  243. }}
  244. >
  245. </Cascader>
  246. </FormItem>
  247. <FormItem className='textarea-desc' label='说明' {...formItemLayout}
  248. validateStatus={validInfo.description.status}
  249. help={validInfo.description.help}
  250. >
  251. <Input.TextArea
  252. key={dataSourceDetail.description}
  253. autosize={{ minRows: 2, maxRows: 5 }}
  254. defaultValue={dataSourceDetail.description}
  255. onBlur={(e) => {
  256. dispatch({ type: 'dataSourceDetail/setField', name: 'description', value: e.target.value });
  257. }}
  258. onChange={e => {
  259. let val = e.target.value + '';
  260. let status, help;
  261. if(val.length > 150) {
  262. status = 'error';
  263. help = '说明不能超过150个字符';
  264. }else {
  265. status = 'success';
  266. help = '';
  267. }
  268. window.clearTimeout(this.descriptionTimeout);
  269. this.descriptionTimeout = window.setTimeout(() => {
  270. this.setState({
  271. validInfo: { ...validInfo, description: { status, help } }
  272. });
  273. }, 100);
  274. }}
  275. />
  276. </FormItem>
  277. </Form>
  278. );
  279. }
  280. }
  281. export default connect(({ present: { dataConnect, dataSource, dataSourceDetail } }) => ({ dataConnect, dataSource, dataSourceDetail }))(DataSourceBaseConfig);