张延森 4 年 前
コミット
0af5986165

+ 36
- 0
src/components/QueryTable/index.jsx ファイルの表示

@@ -0,0 +1,36 @@
1
+import React, { useState, useRef, useImperativeHandle } from 'react'
2
+import Search from '@/components/Search'
3
+import TableList from '@/components/TableList'
4
+
5
+export default React.forwardRef((props, ref) => {
6
+  const tableRef = useRef()
7
+  const [searchData, setSearchData] = useState({})
8
+  const {api, searchFields, onPageChange, ...leftProps} = props
9
+  const handleSearch = (data) => setSearchData(data)
10
+
11
+  useImperativeHandle(ref, () => ({
12
+    reload: () => {
13
+      if (tableRef.current) {
14
+        tableRef.current.reload()
15
+      }
16
+    },
17
+  }))
18
+
19
+  return (
20
+    <>
21
+      <Search
22
+        fields={searchFields}
23
+        onSearch={handleSearch}
24
+        onReset={handleSearch}
25
+      />
26
+
27
+      <TableList
28
+        ref={tableRef}
29
+        api={api}
30
+        params={searchData}
31
+        {...leftProps}
32
+        onPageChange={onPageChange}
33
+      />
34
+    </>
35
+  )
36
+})

+ 7
- 2
src/components/Search/Field.jsx ファイルの表示

@@ -5,7 +5,12 @@ const Option = Select.Option
5 5
 const { RangePicker } = DatePicker
6 6
 
7 7
 export default (props) => {
8
-  const { style, type, value, options = [], placeholder, onChange } = props
8
+  const { style, type, value, options = [], placeholder, render, onChange } = props
9
+
10
+  if (typeof render === 'function') {
11
+    const Element = render()
12
+    return React.cloneElement(Element, { value, onChange })
13
+  }
9 14
 
10 15
   const handleChange = (e) => {
11 16
     const isInput = !type || type === 'text' || type === 'input'
@@ -20,7 +25,7 @@ export default (props) => {
20 25
       )
21 26
     case 'select':
22 27
       return (
23
-        <Select style={style || {width: 120}} placeholder={placeholder} value={value} onChange={handleChange}>
28
+        <Select style={style || {width: 160}} placeholder={placeholder} value={value} onChange={handleChange}>
24 29
           {
25 30
             options.map((item) => <Option key={item.value} value={item.value}>{item.label}</Option>)
26 31
           }

+ 63
- 0
src/components/SelectButton/AreaSelect.jsx ファイルの表示

@@ -0,0 +1,63 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Select } from 'antd';
3
+
4
+import request from '../../utils/request'
5
+
6
+const { Option } = Select;
7
+
8
+/**
9
+ *
10
+ *
11
+ * @param {*} props
12
+ * @returns
13
+ */
14
+const CitySelect = (props) => {
15
+  const [ data, setData ] = useState([])
16
+  const cityId = typeof props.cityId === 'function' ? props.cityId() : props.cityId
17
+
18
+  useEffect(() => {
19
+    getCityAreaList();
20
+    getValue();
21
+  },[cityId])
22
+
23
+  const getCityAreaList = (e) => {
24
+    request({
25
+        url: '/api/admin/tdCityList/tdAreaCity',
26
+        method: 'GET',
27
+        params: {leveltype: 3, cityId},
28
+        action: 'select',
29
+    }).then((data) => {
30
+        setData(data)
31
+    })
32
+  }
33
+
34
+  /**
35
+   * 因为 有个需求是,如果这个城市被删除了,那么就直接展示为空,不能展示 cityId
36
+   */
37
+  const getValue = () => {
38
+    if (props.value) {
39
+      const tempData = data.filter(f => f.id == props.value)
40
+      const va = (tempData.length > 0) ? props.value : undefined
41
+      props.onChange(va)
42
+    }
43
+  }
44
+
45
+  return (
46
+      <Select
47
+      {...props}
48
+      showSearch
49
+      value={props.value}
50
+      style={{ width: '300px' }}
51
+      placeholder="请选择区域"
52
+      onChange={props.onChange}
53
+      filterOption={(input, option) =>
54
+        option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
55
+      }
56
+      >
57
+          {data.map(city => (
58
+            <Option key={city.id} value={city.name}>{city.name}</Option>
59
+          ))}
60
+      </Select>
61
+  )
62
+}
63
+export default CitySelect

+ 65
- 0
src/components/SelectButton/BuildSelect.jsx ファイルの表示

@@ -0,0 +1,65 @@
1
+import React, { useState, useEffect, useRef } from 'react';
2
+import { Select } from 'antd';
3
+import apis from '../../services/apis';
4
+import request from '../../utils/request'
5
+
6
+const { Option } = Select;
7
+
8
+function usePrevious(props) {
9
+  const ref = useRef();
10
+  useEffect(() => {
11
+    ref.current = props;
12
+  });
13
+  return ref.current;
14
+}
15
+
16
+/**
17
+ *
18
+ *
19
+ * @param {*} props
20
+ * @returns
21
+ */
22
+const BuildingSelect = props => {
23
+  const [data, setData] = useState([])
24
+  const [value, setValue] = useState([])
25
+  useEffect(() => {
26
+    getBuildList();
27
+  }, [props.value])
28
+
29
+
30
+  const getBuildList = e => {
31
+    request({ ...apis.building.buildingSelect, params: { pageNum: 1, pageSize: 999 } }).then(data => {
32
+        setData(data)
33
+        checkValue(data)
34
+        // 默认选中第一个
35
+    })
36
+  }
37
+
38
+
39
+  const checkValue = (data) => {
40
+    if (props.value) {
41
+      const tempData = data.filter(f => f.buildingId == props.value)
42
+      const va = (tempData.length > 0) ? props.value : '项目已下线,请重新选择项目'
43
+      props.onChange(va)
44
+
45
+    }
46
+  }
47
+
48
+  return (
49
+      <Select
50
+      showSearch
51
+      value={props.value}
52
+      style={{ width: '300px' }}
53
+      placeholder="请选择项目"
54
+      onChange={props.onChange}
55
+      filterOption={(input, option) =>
56
+        option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
57
+      }>
58
+          <Option key="" value="">全部项目</Option>
59
+          {data.map(building => (
60
+            <Option key={building.buildingId} value={building.buildingId}>{building.buildingName}</Option>
61
+          ))}
62
+      </Select>
63
+  )
64
+}
65
+export default BuildingSelect

+ 77
- 0
src/components/SelectButton/BuildSelect2.jsx ファイルの表示

@@ -0,0 +1,77 @@
1
+import React, { useState, useEffect, useRef } from 'react';
2
+import { Select } from 'antd';
3
+import apis from '../../services/apis';
4
+import request from '../../utils/request'
5
+
6
+const { Option } = Select;
7
+
8
+function usePrevious(props) {
9
+  const ref = useRef();
10
+  useEffect(() => {
11
+    ref.current = props;
12
+  });
13
+  return ref.current;
14
+}
15
+
16
+/**
17
+ *
18
+ *
19
+ * @param {*} props
20
+ * @returns
21
+ */
22
+const BuildingSelect2 = props => {
23
+  const [data, setData] = useState([])
24
+  const [value, setValue] = useState([])
25
+  console.log('props', props.cityId);
26
+  useEffect(() => {
27
+    getBuildList();
28
+  }, [props.cityId])
29
+
30
+
31
+  const getBuildList = e => {
32
+    request({ ...apis.building.buildingSelect, params: { cityId: props.cityId, pageNum: 1, pageSize: 999 } }).then(data => {
33
+      setData(data)
34
+      checkValue(data)
35
+      // 默认选中第一个
36
+    })
37
+  }
38
+
39
+
40
+  const checkValue = (data) => {
41
+    if (props.value) {
42
+      const tempData = data.filter(f => f.buildingId == props.value)
43
+      const va = (tempData.length > 0) ? props.value : '项目已下线,请重新选择项目'
44
+      props.onChange(va)
45
+
46
+    }
47
+  }
48
+
49
+  const onChange = (buildingId) => {
50
+    const building = data.filter(x => buildingId === x.buildingId)[0]
51
+
52
+    props.onChange(buildingId, building)
53
+    // if (props.value) {
54
+    //   const tempData = data.filter(f => f.buildingId == props.value)
55
+    //   const va = (tempData.length > 0) ? props.value : '项目已下线,请重新选择项目'
56
+    //   props.onChange(va)
57
+
58
+    // }={props.onChange}building.buildingId
59
+  }
60
+
61
+  return (
62
+    <Select
63
+      showSearch
64
+      value={props.value}
65
+      style={{ width: '300px' }}
66
+      placeholder="请选择项目"
67
+      onChange={ onChange}
68
+      filterOption={(input, option) =>
69
+        option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
70
+      }>
71
+      {data.map(building => (
72
+        <Option key={building.buildingId} value={building.buildingId}>{building.buildingName}</Option>
73
+      ))}
74
+    </Select>
75
+  )
76
+}
77
+export default BuildingSelect2

+ 62
- 0
src/components/SelectButton/CitySelect.jsx ファイルの表示

@@ -0,0 +1,62 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Select } from 'antd';
3
+
4
+import request from '../../utils/request'
5
+
6
+const { Option } = Select;
7
+
8
+/**
9
+ *
10
+ *
11
+ * @param {*} props
12
+ * @returns
13
+ */
14
+const CitySelect = (props) => {
15
+  const [ data, setData ] = useState([])
16
+
17
+  useEffect(() => {
18
+    getCityList();
19
+    getValue();
20
+  },[props.value])
21
+
22
+  const getCityList = (e) => {
23
+    request({
24
+        url: '/api/admin/tdCityList/tdCity',
25
+        method: 'GET',
26
+        params: {leveltype: 2, pageNum: 1,pageSize: 999},
27
+        action: 'select',
28
+    }).then((data) => {
29
+        setData(data)
30
+    })
31
+  }
32
+
33
+  /**
34
+   * 因为 有个需求是,如果这个城市被删除了,那么就直接展示为空,不能展示 cityId
35
+   */
36
+  const getValue = () => {
37
+    if (props.value) {
38
+      const tempData = data.filter(f => f.id == props.value)
39
+      const va = (tempData.length > 0) ? props.value : undefined
40
+      props.onChange(va)
41
+    }
42
+  }
43
+
44
+  return (
45
+      <Select
46
+      style={{ width: '300px' }}
47
+      placeholder="请选择城市"
48
+      showSearch
49
+      {...props}
50
+      value={props.value}
51
+      onChange={props.onChange}
52
+      filterOption={(input, option) =>
53
+        option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
54
+      }
55
+      >
56
+          {data.map(city => (
57
+            <Option key={city.id} value={city.id}>{city.name}</Option>
58
+          ))}
59
+      </Select>
60
+  )
61
+}
62
+export default CitySelect

+ 63
- 0
src/components/SelectButton/CitySelect2.jsx ファイルの表示

@@ -0,0 +1,63 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Select } from 'antd';
3
+
4
+import request from '../../utils/request'
5
+
6
+const { Option } = Select;
7
+
8
+/**
9
+ *
10
+ *
11
+ * @param {*} props
12
+ * @returns
13
+ */
14
+const CitySelect = (props) => {
15
+  const [ data, setData ] = useState([])
16
+
17
+  useEffect(() => {
18
+    getCityList();
19
+  },[props.value])
20
+
21
+  const getCityList = (e) => {
22
+    request({
23
+        url: '/api/admin/tdCityList/tdCity',
24
+        method: 'GET',
25
+        params: {leveltype: 2, pageNum: 1,pageSize: 999},
26
+        action: 'select',
27
+    }).then((data) => {
28
+        setData(data)
29
+        getValue(data);
30
+        console.log('---123---')
31
+    })
32
+  }
33
+
34
+  /**
35
+   * 因为 有个需求是,如果这个城市被删除了,那么就直接展示为空,不能展示 cityId
36
+   */
37
+  const getValue = (data) => {
38
+    console.log(props.value)
39
+    if (props.value) {
40
+      const tempData = data.filter(f => f.id == props.value)
41
+      const va = (tempData.length > 0) ? props.value : undefined
42
+      props.onChange(va)
43
+    }
44
+  }
45
+
46
+  return (
47
+      <Select
48
+      showSearch
49
+      value={props.value}
50
+      style={{ width: '180px' }}
51
+      placeholder="请选择城市"
52
+      onChange={props.onChange}
53
+      filterOption={(input, option) =>
54
+        option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
55
+      }
56
+      >
57
+          {data.map(city => (
58
+            <Option key={city.id} value={city.id}>{city.name}</Option>
59
+          ))}
60
+      </Select>
61
+  )
62
+}
63
+export default CitySelect

+ 62
- 0
src/components/SelectButton/CitySelect3.jsx ファイルの表示

@@ -0,0 +1,62 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Select } from 'antd';
3
+
4
+import request from '../../utils/request'
5
+
6
+const { Option } = Select;
7
+
8
+/**
9
+ *
10
+ *
11
+ * @param {*} props
12
+ * @returns
13
+ */
14
+const CitySelect3 = (props) => {
15
+  const [ data, setData ] = useState([])
16
+  console.log('props', props.buildingId)
17
+  useEffect(() => {
18
+    getCityList();
19
+    getValue();
20
+  },[props.buildingId])
21
+
22
+  const getCityList = (e) => {
23
+    request({
24
+        url: '/api/admin/tdCityList/tdCity',
25
+        method: 'GET',
26
+        params: {leveltype: 2, pageNum: 1,pageSize: 999},
27
+        action: 'select',
28
+    }).then((data) => {
29
+        setData(data)
30
+    })
31
+  }
32
+
33
+  /**
34
+   * 因为 有个需求是,如果这个城市被删除了,那么就直接展示为空,不能展示 cityId
35
+   */
36
+  const getValue = () => {
37
+    if (props.value) {
38
+      const tempData = data.filter(f => f.id == props.value)
39
+      const va = (tempData.length > 0) ? props.value : undefined
40
+      props.onChange(va)
41
+    }
42
+  }
43
+
44
+  return (
45
+      <Select
46
+      {...props}
47
+      showSearch
48
+      value={props.value}
49
+      style={{ width: '300px' }}
50
+      placeholder="请选择城市"
51
+      onChange={props.onChange}
52
+      filterOption={(input, option) =>
53
+        option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
54
+      }
55
+      >
56
+          {data.map(city => (
57
+            <Option key={city.id} value={city.id}>{city.name}</Option>
58
+          ))}
59
+      </Select>
60
+  )
61
+}
62
+export default CitySelect3

+ 65
- 0
src/components/SelectButton/LivePlatSelect.jsx ファイルの表示

@@ -0,0 +1,65 @@
1
+import React, { useState, useEffect, useRef } from 'react';
2
+import { Select } from 'antd';
3
+import apis from '../../services/apis';
4
+import request from '../../utils/request'
5
+
6
+const { Option } = Select;
7
+
8
+function usePrevious(props) {
9
+  const ref = useRef();
10
+  useEffect(() => {
11
+    ref.current = props;
12
+  });
13
+  return ref.current;
14
+}
15
+
16
+/**
17
+ *
18
+ *
19
+ * @param {*} props
20
+ * @returns
21
+ */
22
+const LivePlatSelect = props => {
23
+  const [data, setData] = useState([])
24
+  const [value, setValue] = useState([])
25
+
26
+  useEffect(() => {
27
+    getLivePlatList();
28
+  }, [props.value])
29
+
30
+
31
+  const getLivePlatList = e => {
32
+    request({ ...apis.taliveActivity.livePlatList, params: { pageNum: 1, pageSize: 999 } }).then(data => {
33
+        setData(data)
34
+        checkValue(data)
35
+        // 默认选中第一个
36
+    })
37
+  }
38
+
39
+
40
+  const checkValue = (data) => {
41
+    if (props.value) {
42
+      const tempData = data.filter(f => f.id == props.value)
43
+      const va = (tempData.length > 0) ? props.value : '平台已下线,请重新选择'
44
+      props.onChange(va)
45
+
46
+    }
47
+  }
48
+
49
+  return (
50
+      <Select
51
+      showSearch
52
+      value={`${props.value || ''}`}
53
+      style={{ width: '300px' }}
54
+      placeholder="请选择平台"
55
+      onChange={props.onChange}
56
+      filterOption={(input, option) =>
57
+        option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
58
+      }>
59
+          {data.map(live => (
60
+            <Option key={live.id} value={`${live.id}`}>{live.livePlatName}</Option>
61
+          ))}
62
+      </Select>
63
+  )
64
+}
65
+export default LivePlatSelect

+ 64
- 0
src/components/SelectButton/MiniappIconSelect.jsx ファイルの表示

@@ -0,0 +1,64 @@
1
+import React, { useState, useEffect, useRef } from 'react';
2
+import { Select } from 'antd';
3
+import apis from '../../services/apis';
4
+import request from '../../utils/request'
5
+
6
+const { Option } = Select;
7
+
8
+function usePrevious(props) {
9
+  const ref = useRef();
10
+  useEffect(() => {
11
+    ref.current = props;
12
+  });
13
+  return ref.current;
14
+}
15
+
16
+/**
17
+ *
18
+ *
19
+ * @param {*} props
20
+ * @returns
21
+ */
22
+const MiniappIconSelect = props => {
23
+  const [data, setData] = useState([])
24
+  const [value, setValue] = useState([])
25
+  useEffect(() => {
26
+    getMiniappIconSelect();
27
+  }, [props.value])
28
+
29
+
30
+  const getMiniappIconSelect = e => {
31
+    request({ ...apis.icon.minippIconList, params: { pageNum: 1, pageSize: 999 } }).then(data => {
32
+        setData(data)
33
+        checkValue(data)
34
+        // 默认选中第一个
35
+    })
36
+  }
37
+
38
+
39
+  const checkValue = (data) => {
40
+    if (props.value) {
41
+      const tempData = data.filter(f => f.iconCode == props.value)
42
+      const va = (tempData.length > 0) ? props.value : ''
43
+      props.onChange(va)
44
+
45
+    }
46
+  }
47
+
48
+  return (
49
+      <Select
50
+      showSearch
51
+      value={props.value}
52
+      style={{ width: '300px' }}
53
+      placeholder="请选择功能"
54
+      onChange={props.onChange}
55
+      filterOption={(input, option) =>
56
+        option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
57
+      }>
58
+          {data.map(icon => (
59
+            <Option key={icon.iconCode} value={icon.iconCode}>{icon.iconName}</Option>
60
+          ))}
61
+      </Select>
62
+  )
63
+}
64
+export default MiniappIconSelect

+ 60
- 0
src/components/SelectButton/NewTypeSelect.jsx ファイルの表示

@@ -0,0 +1,60 @@
1
+import React, { useState, useEffect, useRef } from 'react';
2
+import { Select } from 'antd';
3
+
4
+import request from '../../utils/request'
5
+
6
+const { Option } = Select;
7
+
8
+function usePrevious(props) {
9
+  const ref = useRef();
10
+  useEffect(() => {
11
+    ref.current = props;
12
+  });
13
+  return ref.current;
14
+}
15
+
16
+/**
17
+ *
18
+ *
19
+ * @param {*} props
20
+ * @returns
21
+ */
22
+const NewsTypeSelect = (props) => {
23
+  const [ data, setData ] = useState([])
24
+  const [ value, setValue ] = useState('')
25
+  const preProps = usePrevious(props)
26
+  
27
+  if ((!preProps || !preProps.value) && props.value && !value) {
28
+    setValue(props.value)
29
+  }
30
+
31
+  useEffect(() => {
32
+    getNewsTypeList();
33
+  },[props.buildingId])
34
+
35
+  const getNewsTypeList = (e) => {
36
+    request({
37
+        url: '/api/admin/taNewsType',
38
+        method: 'GET',
39
+        params: {pageNum: 1,pageSize: 999,buildingId: props.buildingId},
40
+        action: 'admin.taNewsType.get',
41
+    }).then((data) => {
42
+        setData(data.records)
43
+    })
44
+  }
45
+
46
+  const handleChange = (e) => {
47
+    setValue(e)
48
+    props.onChange(e)
49
+  }
50
+
51
+  return (
52
+      <Select value={props.value} style={{ width: '180px' }} placeholder="请选择资讯类型" onChange={handleChange}>
53
+          {data.map(type => (
54
+            <Option key={type.newsTypeId} value={type.newsTypeId}>{type.newsTypeName}</Option>
55
+          ))}
56
+      </Select>
57
+  )
58
+}
59
+export default NewsTypeSelect
60
+

+ 82
- 0
src/components/SelectButton/QrcodeType.jsx ファイルの表示

@@ -0,0 +1,82 @@
1
+import React, { useMemo } from 'react';
2
+import { Select } from 'antd';
3
+
4
+const { Option } = Select;
5
+
6
+
7
+const qrcodeType = props => {
8
+    //   const [data, setData] = useState([])
9
+    //   useEffect(() => {
10
+
11
+    //   }, [props.value])
12
+    // const visible2 = props.visible || true
13
+    const all = props.all || false
14
+
15
+    const visible = useMemo(() => (props.visible), [props.visible]);
16
+    
17
+    const data = [
18
+        {
19
+            name: '项目',
20
+            value: 'project',
21
+            visible,
22
+        },
23
+        {
24
+            name: '报名活动',
25
+            value: 'activity',
26
+            visible,
27
+        },
28
+        {
29
+            name: '助力活动',
30
+            value: 'help',
31
+            visible,
32
+        },
33
+        {
34
+            name: '拼团活动',
35
+            value: 'group',
36
+            visible,
37
+        },
38
+        {
39
+            name: 'H5活动',
40
+            value: 'h5',
41
+            visible: true,
42
+        },
43
+        {
44
+            name: '直播活动',
45
+            value: 'live',
46
+            visible: true,
47
+        },
48
+        {
49
+            name: '资讯',
50
+            value: 'news',
51
+            visible,
52
+        },
53
+        {
54
+            name: '在线选房',
55
+            value: 'salesBatch',
56
+            visible,
57
+        },
58
+    ]
59
+
60
+
61
+    return (
62
+        // <>234</>
63
+        <Select
64
+            showSearch
65
+            value={props.value}
66
+            style={{ width: '250px' }}
67
+            placeholder="请选择二维码内容类型"
68
+            onChange={props.onChange}
69
+            // filterOption={(input, option) =>
70
+            //     // eslint-disable-next-line max-len
71
+            //     option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
72
+            // }
73
+        >
74
+            {all && <Option key="" value="">全部类型</Option>}
75
+            {data.map(Item => (
76
+
77
+                Item.visible ? <Option key={Item.vlaue} value={Item.value}> {Item.name} </Option> : ''
78
+            ))}
79
+        </Select>
80
+    )
81
+}
82
+export default qrcodeType

+ 82
- 0
src/components/SelectButton/QrcodeType1.jsx ファイルの表示

@@ -0,0 +1,82 @@
1
+import React, { useMemo } from 'react';
2
+import { Select } from 'antd';
3
+
4
+const { Option } = Select;
5
+
6
+
7
+const qrcodeType = props => {
8
+    //   const [data, setData] = useState([])
9
+    //   useEffect(() => {
10
+
11
+    //   }, [props.value])
12
+    // const visible2 = props.visible || true
13
+    const all = props.all || false
14
+
15
+    const visible = useMemo(() => (props.visible), [props.visible]);
16
+    
17
+    const data = [
18
+        {
19
+            name: '项目',
20
+            value: 'building',
21
+            visible,
22
+        },
23
+        {
24
+            name: '报名活动',
25
+            value: 'activity',
26
+            visible,
27
+        },
28
+        {
29
+            name: '助力活动',
30
+            value: 'help',
31
+            visible,
32
+        },
33
+        {
34
+            name: '拼团活动',
35
+            value: 'group',
36
+            visible,
37
+        },
38
+        {
39
+            name: 'H5活动',
40
+            value: 'h5',
41
+            visible: true,
42
+        },
43
+        {
44
+            name: '直播活动',
45
+            value: 'live',
46
+            visible: true,
47
+        },
48
+        {
49
+            name: '资讯',
50
+            value: 'news',
51
+            visible,
52
+        },
53
+        {
54
+            name: '在线选房',
55
+            value: 'house',
56
+            visible,
57
+        },
58
+    ]
59
+
60
+
61
+    return (
62
+        // <>234</>
63
+        <Select
64
+            showSearch
65
+            value={props.value}
66
+            style={{ width: '250px' }}
67
+            placeholder="请选择二维码内容类型"
68
+            onChange={props.onChange}
69
+            // filterOption={(input, option) =>
70
+            //     // eslint-disable-next-line max-len
71
+            //     option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
72
+            // }
73
+        >
74
+            {all && <Option key="" value="">全部类型</Option>}
75
+            {data.map(Item => (
76
+
77
+                Item.visible ? <Option key={Item.vlaue} value={Item.value}> {Item.name} </Option> : ''
78
+            ))}
79
+        </Select>
80
+    )
81
+}
82
+export default qrcodeType

+ 45
- 0
src/components/SelectButton/WxDictSelect.jsx ファイルの表示

@@ -0,0 +1,45 @@
1
+import React, { useState, useEffect, useRef } from 'react';
2
+import { Select } from 'antd';
3
+import apis from '../../services/apis';
4
+import request from '../../utils/request'
5
+
6
+const { Option } = Select;
7
+
8
+/**
9
+ *
10
+ *
11
+ * @param {*} props
12
+ * @returns
13
+ */
14
+const WxDictSelect = props => {
15
+  const [data, setData] = useState([])
16
+  const [value, setValue] = useState([])
17
+  useEffect(() => {
18
+    getWxDictList();
19
+  }, [props.value])
20
+
21
+
22
+  const getWxDictList = e => {
23
+    request({ ...apis.wxDict.list, params: { pageNumber: 1, pageSize: 999 } }).then(data => {
24
+        setData(data.records)
25
+        // 默认选中第一个
26
+    })
27
+  }
28
+
29
+  return (
30
+      <Select
31
+      showSearch
32
+      value={props.value}
33
+      style={{ width: '250px' }}
34
+      placeholder="请选择用户来源"
35
+      onChange={props.onChange}
36
+      filterOption={(input, option) =>
37
+        option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
38
+      }>
39
+          {data.map(wxDict => (
40
+            <Option key={wxDict.sceneType} value={wxDict.sceneType}>{wxDict.sceneAlias}</Option>
41
+          ))}
42
+      </Select>
43
+  )
44
+}
45
+export default WxDictSelect

+ 47
- 0
src/components/SelectButton/channelSelect.jsx ファイルの表示

@@ -0,0 +1,47 @@
1
+import React, { useState, useEffect, useMemo } from 'react';
2
+import { Select } from 'antd';
3
+import apis from '../../services/apis';
4
+import request from '../../utils/request'
5
+
6
+const { Option } = Select;
7
+
8
+/**
9
+ *
10
+ *
11
+ * @param {*} props
12
+ * @returns
13
+ */
14
+const ChannelSelect = props => {
15
+  const [data, setData] = useState([])
16
+  useEffect(() => {
17
+    getChannelSelect();
18
+  }, [props.value])
19
+
20
+  const all = props.all || false
21
+
22
+
23
+  const getChannelSelect = e => {
24
+    request({ ...apis.channelList.getList, params: { pageNumber: 1, pageSize: 999 } }).then(data => {
25
+      setData(data.channelNmae)
26
+      // 默认选中第一个
27
+    })
28
+  }
29
+
30
+  return (
31
+    <Select
32
+      showSearch
33
+      value={props.value}
34
+      style={{ width: '250px' }}
35
+      placeholder="请选择渠道"
36
+      onChange={props.onChange}
37
+      filterOption={(input, option) =>
38
+        option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
39
+      }>
40
+      {all && <Option key="" value="">全部渠道</Option>}
41
+      {data.map(Item => (
42
+        <Option key={Item.channelId} value={Item.channelId}> {Item.channelName} </Option>
43
+      ))}
44
+    </Select>
45
+  )
46
+}
47
+export default ChannelSelect

+ 40
- 20
src/components/TableList/index.jsx ファイルの表示

@@ -1,15 +1,15 @@
1
-import { useCallback, useState, useEffect } from 'react';
1
+import React, { useCallback, useState, useEffect, useImperativeHandle } from 'react';
2 2
 import { stringify } from 'querystring';
3 3
 import { notification } from 'antd';
4 4
 import request from '@/utils/request'
5 5
 import TableList from './TableList';
6 6
 import Pagination from './Pagination';
7 7
 
8
-export default (props) => {
8
+export default React.forwardRef((props, ref) => {
9 9
   const [loading, setLoading] = useState(false)
10 10
   const [pageConfig, setPageConfig] = useState({ current: 1, pageSize: 10, total: 0 })
11 11
   const [list, setList] = useState()
12
-  const { api, params = {}, ...tableProps } = props
12
+  const { api, params = {}, onPageChange, ...tableProps } = props
13 13
   const paramsStr = stringify({
14 14
     ...params,
15 15
     pageNum: pageConfig.current,
@@ -17,10 +17,16 @@ export default (props) => {
17 17
   })
18 18
 
19 19
   const updatePageConfig = useCallback((config) => {
20
-    setPageConfig({
20
+    const newPage = {
21 21
       ...pageConfig,
22
-      ...config
23
-    })
22
+      ...config,
23
+    }
24
+
25
+    setPageConfig(newPage)
26
+
27
+    if (onPageChange) {
28
+      onPageChange(newPage)
29
+    }
24 30
   }, [pageConfig])
25 31
 
26 32
   const handlePageChange = (current, pageSize) => {
@@ -28,20 +34,34 @@ export default (props) => {
28 34
     updatePageConfig(config)
29 35
   }
30 36
 
37
+  // 获取远程数据
38
+  const fetchData = useCallback(
39
+    () => {
40
+      const url = `${api.url}?${paramsStr}`
41
+      setLoading(true)
42
+      request({...api, url}).then((res) => {
43
+        const {current, total, records = []} = res
44
+        setLoading(false)
45
+        setList(records)
46
+        updatePageConfig({current, total})
47
+      }).catch((err) => {
48
+        console.error(err)
49
+        setLoading(false)
50
+        notification.warn({ message: err.message })
51
+      })
52
+    },
53
+    [paramsStr, api],
54
+  )
55
+
56
+  // 监控查询参数的修改
31 57
   useEffect(() => {
32
-    const url = `${api.url}?${paramsStr}`
33
-    setLoading(true)
34
-    request({...api, url}).then((res) => {
35
-      const {current, total, records = []} = res
36
-      setLoading(false)
37
-      setList(records)
38
-      updatePageConfig({current, total})
39
-    }).catch((err) => {
40
-      console.error(err)
41
-      setLoading(false)
42
-      notification.warn({ message: err.message })
43
-    })
44
-  }, [paramsStr, api])
58
+    fetchData()
59
+  }, [paramsStr])
60
+
61
+  // 透传给父组件部分方法
62
+  useImperativeHandle(ref, () => ({
63
+    reload: fetchData
64
+  }))
45 65
 
46 66
   return (
47 67
     <>
@@ -49,4 +69,4 @@ export default (props) => {
49 69
       <Pagination {...pageConfig} onChange={handlePageChange} />
50 70
     </>
51 71
   )
52
-};
72
+});

+ 0
- 48
src/pages/building/List/components/Search.jsx ファイルの表示

@@ -1,48 +0,0 @@
1
-import React from 'react'
2
-import Search from '@/components/Search'
3
-
4
-export default (props) => {
5
-  const searchFields = [
6
-    {
7
-      name: 'name',
8
-      label: '楼盘名称',
9
-      placeholder: '请输入楼盘名称',
10
-    },
11
-    {
12
-      name: 'buildingStatus',
13
-      label: '楼盘状态',
14
-      placeholder: '请选择楼盘状态',
15
-      type: 'select',
16
-      options: [
17
-        {label: '已发布', value: 1},
18
-        {label: '未发布', value: 2}
19
-      ]
20
-    },
21
-    {
22
-      name: 'buildingStatus',
23
-      label: '销售状态',
24
-      placeholder: '请选择销售状态',
25
-      type: 'select',
26
-      options: [
27
-        {label: '待售', value: '待售'},
28
-        {label: '在售', value: '在售'},
29
-        {label: '售罄', value: '售罄'},
30
-        {label: '在租', value: '在租'},
31
-      ]
32
-    },
33
-    {
34
-      name: 'isMain',
35
-      label: '首页推荐',
36
-      placeholder: '请选择首页推荐',
37
-      type: 'select',
38
-      options: [
39
-        {label: '推荐', value: 1},
40
-        {label: '未推荐', value: 2},
41
-      ]
42
-    },
43
-  ]
44
-
45
-  return (
46
-    <Search fields={searchFields} onSearch={props.onSearch} onReset={props.onSearch} />
47
-  )
48
-}

+ 0
- 100
src/pages/building/List/components/Table.jsx ファイルの表示

@@ -1,100 +0,0 @@
1
-import React, { useState } from 'react'
2
-import { router } from 'umi'
3
-import { Button, Badge } from 'antd'
4
-import moment from 'moment'
5
-import TableList from '@/components/TableList'
6
-import OperButton from '@/components/OperButton'
7
-import AuthButton from '@/components/AuthButton'
8
-import withActions from '@/components/ActionList'
9
-
10
-export default (props) => {
11
-  const [page, setPage] = useState({current: 1, pageSize: 10})
12
-  const { api, params, onDelete, onPublish } = props
13
-
14
-  const columns = [
15
-    {
16
-      title: '编号',
17
-      key: '#',
18
-      align: 'center',
19
-      render: (t, r, index) => (page.current - 1) * page.pageSize + index + 1,
20
-    },
21
-    {
22
-      title: '封面',
23
-      dataIndex: 'buildingListImg',
24
-      key: 'buildingListImg',
25
-      align: 'center',
26
-      render: (_, row) => {
27
-        if (row.buildingListImg && row.buildingListImg[0]) {
28
-          return <img src={row.buildingListImg[0].url} width={128} height={72} style={{borderRadius: '4px'}} alt="" />
29
-        }
30
-        return null
31
-      }
32
-    },
33
-    {
34
-      title: '楼盘名称',
35
-      dataIndex: 'buildingName',
36
-      key: 'buildingName',
37
-      align: 'center',
38
-      render: (t, row) => (
39
-        <AuthButton name="admin.building.update" noRight={t}>
40
-          <Button
41
-            type="link"
42
-            onClick={() => router.push({
43
-              pathname: '/building/list/add',
44
-              query: {
45
-                id: row.buildingId,
46
-              },
47
-            })}
48
-          >{t}</Button>
49
-        </AuthButton>
50
-      )
51
-    },
52
-    {
53
-      title: '销售状态',
54
-      dataIndex: 'marketStatus',
55
-      key: 'marketStatus',
56
-      align: 'center',
57
-    },
58
-    {
59
-      title: '录入时间',
60
-      dataIndex: 'createDate',
61
-      key: 'createDate',
62
-      align: 'center',
63
-      render: (t) => moment(t).format('YYYY-MM-DD HH:mm')
64
-    },
65
-    {
66
-      title: '状态',
67
-      dataIndex: 'status',
68
-      key: 'status',
69
-      align: 'center',
70
-      render: (t) => t === 1 ? <Badge status="success" text="已发布" /> : <Badge status="processing" text="未发布" />
71
-    },
72
-    {
73
-      title: '操作',
74
-      key: 'options',
75
-      align: 'center',
76
-      render: withActions((_, row) => [
77
-        <AuthButton name="admin.building.public" noRight={null}>
78
-          <OperButton onClick={() => onPublish(row)}>{row.status === 1 ? '取消发布' : '发布'}</OperButton>
79
-        </AuthButton>,
80
-        <AuthButton name="admin.building.delete" noRight={null}>
81
-          <OperButton.Confirm
82
-            title="确认删除?"
83
-            content="删除之后不可恢复"
84
-            onClick={() => onDelete(row)}
85
-          >删除</OperButton.Confirm>
86
-        </AuthButton>
87
-      ], {noMargin: true})
88
-    },
89
-  ]
90
-
91
-  return (
92
-    <TableList
93
-      api={api}
94
-      params={params}
95
-      rowKey="buildingId"
96
-      columns={columns}
97
-      onPageChange={(pg) => setPage(pg)}
98
-    />
99
-  )
100
-}

+ 27
- 18
src/pages/building/List/index.jsx ファイルの表示

@@ -1,28 +1,37 @@
1
-import React, { useState } from 'react'
1
+import React, { useMemo, useRef, useCallback, useState } from 'react'
2 2
 import apis from '@/services/apis'
3
-import Search from './components/Search'
4
-import Table from './components/Table'
3
+import QueryTable from '@/components/QueryTable'
4
+import getSearchFields from './searchFields'
5
+import getTableColumns from './tableColumns'
5 6
 
6 7
 export default (props) => {
7
-  const [searchData, setSearchData] = useState({})
8
-
9
-  const handleDelete = (row) => {
8
+  const ref = useRef()
9
+  const [page, setPage] = useState({current: 1, pageSize: 10})
10
+  const onPublish = useCallback((row) => {
10 11
     //
11
-  }
12
+  }, [])
13
+
14
+  const onDelete = useCallback((row) => {
12 15
 
13
-  const handlePublish = (row) => {
16
+  }, [])
14 17
 
15
-  }
18
+  const searchFields = useMemo(getSearchFields, [])
19
+  const tableColumns = useMemo(() => {
20
+    return getTableColumns({
21
+      page,
22
+      onPublish,
23
+      onDelete,
24
+    })
25
+  }, [page])
16 26
 
17 27
   return (
18
-    <div>
19
-      <Search onSearch={(data) => setSearchData(data)} />
20
-      <Table
21
-        api={apis.building.getList}
22
-        params={searchData}
23
-        onDelete={handleDelete}
24
-        onPublish={handlePublish}
25
-      />
26
-    </div>
28
+    <QueryTable
29
+      ref={ref}
30
+      rowKey="buildingId"
31
+      api={apis.building.getList}
32
+      searchFields={searchFields}
33
+      columns={tableColumns}
34
+      onPageChange={(pg) => setPage(pg)}
35
+    />
27 36
   )
28 37
 }

+ 47
- 0
src/pages/building/List/searchFields.js ファイルの表示

@@ -0,0 +1,47 @@
1
+import SelectCity from '@/components/SelectButton/CitySelect'
2
+
3
+export default () => [
4
+  {
5
+    name: 'cityId',
6
+    label: '城市',
7
+    placeholder: '请选择城市',
8
+    render: () => <SelectCity style={{width: 160}} />
9
+  },
10
+  {
11
+    name: 'name',
12
+    label: '楼盘名称',
13
+    placeholder: '请输入楼盘名称',
14
+  },
15
+  {
16
+    name: 'buildingStatus',
17
+    label: '楼盘状态',
18
+    placeholder: '请选择楼盘状态',
19
+    type: 'select',
20
+    options: [
21
+      {label: '已发布', value: 1},
22
+      {label: '未发布', value: 2}
23
+    ]
24
+  },
25
+  {
26
+    name: 'marketStatus',
27
+    label: '销售状态',
28
+    placeholder: '请选择销售状态',
29
+    type: 'select',
30
+    options: [
31
+      {label: '待售', value: '待售'},
32
+      {label: '在售', value: '在售'},
33
+      {label: '售罄', value: '售罄'},
34
+      {label: '在租', value: '在租'},
35
+    ]
36
+  },
37
+  {
38
+    name: 'isMain',
39
+    label: '首页推荐',
40
+    placeholder: '请选择首页推荐',
41
+    type: 'select',
42
+    options: [
43
+      {label: '推荐', value: 1},
44
+      {label: '未推荐', value: 2},
45
+    ]
46
+  },
47
+]

+ 83
- 0
src/pages/building/List/tableColumns.js ファイルの表示

@@ -0,0 +1,83 @@
1
+import { router } from 'umi'
2
+import { Button, Badge } from 'antd'
3
+import moment from 'moment'
4
+import OperButton from '@/components/OperButton'
5
+import AuthButton from '@/components/AuthButton'
6
+import withActions from '@/components/ActionList'
7
+
8
+export default ({page, onPublish, onDelete}) => [
9
+  {
10
+    title: '编号',
11
+    key: '#',
12
+    align: 'center',
13
+    render: (t, r, index) => (page.current - 1) * page.pageSize + index + 1,
14
+  },
15
+  {
16
+    title: '封面',
17
+    dataIndex: 'buildingListImg',
18
+    key: 'buildingListImg',
19
+    align: 'center',
20
+    render: (_, row) => {
21
+      if (row.buildingListImg && row.buildingListImg[0]) {
22
+        return <img src={row.buildingListImg[0].url} width={128} height={72} style={{borderRadius: '4px'}} alt="" />
23
+      }
24
+      return null
25
+    }
26
+  },
27
+  {
28
+    title: '楼盘名称',
29
+    dataIndex: 'buildingName',
30
+    key: 'buildingName',
31
+    align: 'center',
32
+    render: (t, row) => (
33
+      <AuthButton name="admin.building.update" noRight={t}>
34
+        <Button
35
+          type="link"
36
+          onClick={() => router.push({
37
+            pathname: '/building/list/add',
38
+            query: {
39
+              id: row.buildingId,
40
+            },
41
+          })}
42
+        >{t}</Button>
43
+      </AuthButton>
44
+    )
45
+  },
46
+  {
47
+    title: '销售状态',
48
+    dataIndex: 'marketStatus',
49
+    key: 'marketStatus',
50
+    align: 'center',
51
+  },
52
+  {
53
+    title: '录入时间',
54
+    dataIndex: 'createDate',
55
+    key: 'createDate',
56
+    align: 'center',
57
+    render: (t) => moment(t).format('YYYY-MM-DD HH:mm')
58
+  },
59
+  {
60
+    title: '状态',
61
+    dataIndex: 'status',
62
+    key: 'status',
63
+    align: 'center',
64
+    render: (t) => t === 1 ? <Badge status="success" text="已发布" /> : <Badge status="processing" text="未发布" />
65
+  },
66
+  {
67
+    title: '操作',
68
+    key: 'options',
69
+    align: 'center',
70
+    render: withActions((_, row) => [
71
+      <AuthButton name="admin.building.public" noRight={null}>
72
+        <OperButton onClick={() => onPublish(row)}>{row.status === 1 ? '取消发布' : '发布'}</OperButton>
73
+      </AuthButton>,
74
+      <AuthButton name="admin.building.delete" noRight={null}>
75
+        <OperButton.Confirm
76
+          title="确认删除?"
77
+          content="删除之后不可恢复"
78
+          onClick={() => onDelete(row)}
79
+        >删除</OperButton.Confirm>
80
+      </AuthButton>
81
+    ], {noMargin: true})
82
+  },
83
+]