张延森 преди 5 години
родител
ревизия
417057d0f3

+ 34
- 0
src/layouts/SearchList/BodyBodyPagination.jsx Целия файл

@@ -0,0 +1,34 @@
1
+import React, { PureComponent } from 'react'
2
+import PropTypes from 'prop-types'
3
+import { Pagination } from 'antd'
4
+
5
+import Style from './style.less'
6
+
7
+export default class BodyPagination extends PureComponent {
8
+  static propTypes = {
9
+    storage: PropTypes.func,
10
+    onChange: PropTypes.func,
11
+    configs: PropTypes.object,
12
+  }
13
+
14
+  // storage = this.props.storage
15
+
16
+  handleChange = (page, pageSize) => {
17
+    if (this.props.onChange) {
18
+      this.props.onChange(page, pageSize)
19
+    }
20
+  }
21
+
22
+  render() {
23
+    return (
24
+      <div className={Style['body-paged']}>
25
+        <Pagination
26
+          showSizeChanger
27
+          onChange={this.handleChange}
28
+          onShowSizeChange={this.handleChange} 
29
+          {...(this.props.configs || {})}
30
+        />
31
+      </div>
32
+    )
33
+  }
34
+}

+ 17
- 0
src/layouts/SearchList/BodyHeader.jsx Целия файл

@@ -0,0 +1,17 @@
1
+import React, { PureComponent } from 'react'
2
+import Style from './style.less';
3
+
4
+export default class BodyHeader extends PureComponent {
5
+  render() {
6
+    return (
7
+      <div className={Style['body-header']}>
8
+        <div className={Style['body-header-title']}>
9
+          {this.props.title}
10
+        </div>
11
+        <div className={Style['body-header-action']}>
12
+          {this.props.actions}
13
+        </div>
14
+      </div>
15
+    )
16
+  }
17
+}

+ 28
- 0
src/layouts/SearchList/SearchBody.jsx Целия файл

@@ -0,0 +1,28 @@
1
+import React, { PureComponent } from 'react'
2
+import PropTypes from 'prop-types'
3
+
4
+import { Table } from 'antd'
5
+import { isFunction } from './utils'
6
+
7
+export default class SearchBody extends PureComponent {
8
+  static propTypes = {
9
+    storage: PropTypes.func,
10
+    dataSource: PropTypes.array,
11
+    configs: PropTypes.object,
12
+  }
13
+
14
+  // storage = this.props.storage
15
+
16
+  render() {
17
+    const { dataSource, configs } = this.props
18
+    const { render, ...leftProps } = configs || {}
19
+
20
+    if (isFunction(render)) {
21
+      return render(dataSource)
22
+    }
23
+
24
+    return (
25
+      <Table dataSource={dataSource} {...leftProps} />
26
+    )
27
+  }
28
+}

+ 12
- 0
src/layouts/SearchList/SearchForm.jsx Целия файл

@@ -0,0 +1,12 @@
1
+import React, { PureComponent } from 'react'
2
+
3
+export default class SearchForm extends PureComponent {
4
+  render() {
5
+    return (
6
+      <div>
7
+        
8
+      </div>
9
+    )
10
+  }
11
+}
12
+

+ 116
- 0
src/layouts/SearchList/index.jsx Целия файл

@@ -0,0 +1,116 @@
1
+import React from 'react'
2
+import PropTypes from 'prop-types'
3
+import classNames from 'classnames'
4
+import { notification } from 'antd'
5
+
6
+import SearchForm from './SearchForm'
7
+import SearchBody from './SearchBody'
8
+import BodyHeader from './BodyHeader'
9
+import BodyPagination from './BodyBodyPaginationation'
10
+import { getStorageBuilder } from './utils'
11
+import Style from './style.less'
12
+
13
+class SearchList extends React.PureComponent {
14
+  static propTypes = {
15
+    title: PropTypes.element,
16
+    actions: PropTypes.element,
17
+    search: PropTypes.object,
18
+    body: PropTypes.object,
19
+    pagination: PropTypes.object,
20
+  }
21
+
22
+  storage = getStorageBuilder(window.Math.random().toString(36).substr(2))
23
+
24
+  state = {
25
+    dataSource: [],
26
+    conditions: {},
27
+    pageConfig: {
28
+      current: 1,
29
+      pageSize: 10,
30
+      total: 0,
31
+    },
32
+  }
33
+
34
+  handlePageChange = (page, pageSize) => {
35
+    this.setState(
36
+      (state) => ({
37
+        ...state,
38
+        pageConfig: {
39
+          ...pageConfig,
40
+          current: page,
41
+          pageSize,
42
+        }
43
+      }),
44
+      this.queryData,
45
+    )
46
+  }
47
+
48
+  handleSearchSubmit = (conditions) => {
49
+    this.setState(
50
+      (state) => ({
51
+        ...state,
52
+        conditions,
53
+      }),
54
+      this.queryData,
55
+    )
56
+  }
57
+
58
+  queryData = () => {
59
+    if (this.props.service) {
60
+      const pageConfigProps = this.props.pagination || {}
61
+      const keyOfPageNumber = pageConfigProps.keyOfPageNumber || 'pageNumber'
62
+      const keyOfPageSize= pageConfigProps.keyOfPageSize || 'pageSize'
63
+      const keyOfTotalSize= pageConfigProps.keyOfTotalSize || 'total'
64
+
65
+      const { conditions = {}, pageConfig } = this.state
66
+
67
+      this.props.service({
68
+        ...conditions,
69
+        ...{
70
+          [`${keyOfPageNumber}`]: pageConfig.current,
71
+          [`${keyOfPageSize}`]: pageConfig.pageSize,
72
+        },
73
+      }).then((res) => {
74
+        const [dataSource, pageParams] = res || []
75
+
76
+        this.setState((state) => ({
77
+          ...state,
78
+          dataSource,
79
+          pageConfig: {
80
+            ...pageConfig,
81
+            total: pageParams[keyOfTotalSize],
82
+          },
83
+        }))
84
+      }).catch((e) => {
85
+        console.error(e)
86
+      })
87
+    }
88
+  }
89
+
90
+  render() {    
91
+    const {
92
+      keyOfPageNumber,
93
+      keyOfPageSize,
94
+      keyOfTotalSize,
95
+      ...leftPageParams,
96
+    } = this.props.pagination || {}
97
+
98
+    const pageConfig = {
99
+      ...leftPageParams,
100
+      ...this.state.pageConfig,
101
+    }
102
+
103
+    return (
104
+      <div className={Style['search-list']}>
105
+        <div className={Style['head']}>
106
+          <SearchForm storage={storage} onSubmit={this.handleSearchSubmit} configs={this.props.search} />
107
+        </div>
108
+        <div className={Style['body']}>
109
+          <BodyHeader storage={storage} title={this.props.title} actions={this.props.actions} />
110
+          <SearchBody storage={storage} dataSource={this.state.dataSource} configs={this.props.body} />
111
+          <BodyPagination storage={storage} onChange={this.handlePageChange} configs={pageConfig} />
112
+        </div>
113
+      </div>
114
+    )
115
+  }
116
+}

+ 40
- 0
src/layouts/SearchList/style.less Целия файл

@@ -0,0 +1,40 @@
1
+
2
+.search-list {
3
+  .head {
4
+    margin-bottom: 24px;
5
+    padding: 16px;
6
+    overflow: hidden;
7
+    background: #fff;
8
+  }
9
+
10
+  .body {
11
+    .body-header {
12
+      display: flex;
13
+      align-items: center;
14
+      justify-content: space-between;
15
+      height: 64px;
16
+      padding: 0 24px;
17
+      line-height: 64px;
18
+
19
+      .body-header-title {
20
+        flex: 1 1;
21
+        color: #000;
22
+        font-size: 16px;
23
+        line-height: 24px;
24
+      }
25
+
26
+      .body-header-action {
27
+        display: flex;
28
+        align-items: center;
29
+        justify-content: flex-end;
30
+      }
31
+
32
+    }
33
+
34
+    .body-paged {
35
+      padding: 0 24px;
36
+      float: right;
37
+      margin: 16px 0;
38
+    }
39
+  }
40
+}

+ 34
- 0
src/layouts/SearchList/utils.js Целия файл

@@ -0,0 +1,34 @@
1
+
2
+export function isFunction(fn) {
3
+  return typeof fn === 'function'
4
+}
5
+
6
+export function setStorage(k, v) {
7
+  if (typeof v !== 'object') return
8
+
9
+  window.localStorage.setItem(k, window.JSON.stringify(v))
10
+}
11
+
12
+export function getStorage(k) {
13
+  const str = window.localStorage.getItem(k);
14
+  if (!str) return;
15
+
16
+  return window.JSON.parse(str);
17
+}
18
+
19
+export function getStorageBuilder(key, initData = {}) {
20
+  setStorage(key, initData)  
21
+
22
+  return {
23
+    set: (k, v) => {
24
+      const data = getStorage(key) || {}
25
+
26
+      setStorage({ ...data, [`${k}`]: v })
27
+    },
28
+
29
+    get: (k) => {
30
+      const data = getStorage(key) || {}
31
+      return data[k]
32
+    }
33
+  }
34
+}