张延森 3 years ago
parent
commit
a0fe56950e
29 changed files with 412 additions and 260 deletions
  1. 1
    1
      config/defaultSettings.js
  2. 1
    1
      package.json
  3. BIN
      src/assets/logo.png
  4. 1
    1
      src/assets/logo.svg
  5. 2
    1
      src/layouts/UserLayout.jsx
  6. 1
    1
      src/pages/Live/LiveActivity/Edit/components/share.jsx
  7. 1
    1
      src/pages/Live/liveActivity copy/edit/components/share.jsx
  8. 1
    1
      src/pages/activity/detailActivity.jsx
  9. 1
    1
      src/pages/activity/editActivity.jsx
  10. 1
    1
      src/pages/activity/groupActivity/detailActivity.jsx
  11. 1
    1
      src/pages/activity/groupActivity/editGroupActivity.jsx
  12. 1
    1
      src/pages/activity/helpActivity/detailActivity.jsx
  13. 1
    1
      src/pages/activity/helpActivity/edithelpActivity.jsx
  14. 1
    1
      src/pages/activity/liveActivity/edit/components/share.jsx
  15. 69
    35
      src/pages/building/Edit/Basic.jsx
  16. 0
    126
      src/pages/building/Edit/components/Amap.jsx
  17. 16
    0
      src/pages/building/Edit/components/Amap/PoiPicker.jsx
  18. 104
    0
      src/pages/building/Edit/components/Amap/index.jsx
  19. 8
    0
      src/pages/building/Edit/components/Amap/style.less
  20. 79
    0
      src/pages/building/Edit/components/Amap/utils.js
  21. 26
    0
      src/pages/building/Edit/components/EditableArround/MapPois.jsx
  22. 31
    22
      src/pages/building/Edit/components/EditableArround/index.jsx
  23. 35
    0
      src/pages/building/Edit/components/EditableArround/utils.js
  24. 0
    53
      src/pages/building/Edit/components/amap.less
  25. 1
    1
      src/pages/news/list/compents/Poster.jsx
  26. 1
    1
      src/pages/news/list/compents/Share.jsx
  27. 1
    1
      src/pages/news/list/editNewsList.jsx
  28. 8
    5
      src/utils/map/index.js
  29. 19
    3
      src/utils/map/sdk.js

+ 1
- 1
config/defaultSettings.js View File

@@ -12,7 +12,7 @@ export default {
12 12
   menu: {
13 13
     locale: false,
14 14
   },
15
-  title: 'Ant Design Pro',
15
+  title: '新 联 家',
16 16
   pwa: false,
17 17
   iconfontUrl: '',
18 18
 };

+ 1
- 1
package.json View File

@@ -44,6 +44,7 @@
44 44
     "not ie <= 10"
45 45
   ],
46 46
   "dependencies": {
47
+    "@amap/amap-jsapi-loader": "^1.0.1",
47 48
     "@ant-design/pro-layout": "^4.10.13",
48 49
     "@antv/data-set": "^0.11.0",
49 50
     "@zjxpcyc/xrc-form2": "2.2.2",
@@ -58,7 +59,6 @@
58 59
     "path-to-regexp": "2.4.0",
59 60
     "qs": "^6.9.0",
60 61
     "react": "^16.8.6",
61
-    "react-amap": "^1.2.8",
62 62
     "react-copy-to-clipboard": "^5.0.1",
63 63
     "react-dom": "^16.8.6",
64 64
     "react-helmet": "^5.2.1",

BIN
src/assets/logo.png View File


+ 1
- 1
src/assets/logo.svg
File diff suppressed because it is too large
View File


+ 2
- 1
src/layouts/UserLayout.jsx View File

@@ -7,6 +7,7 @@ import { formatMessage } from 'umi-plugin-react/locale';
7 7
 // import SelectLang from '@/components/SelectLang';
8 8
 import logo from '../assets/logo.svg';
9 9
 import styles from './UserLayout.less';
10
+import setting from '../../config/defaultSettings'
10 11
 
11 12
 const UserLayout = (props) => {
12 13
   const {
@@ -44,7 +45,7 @@ const UserLayout = (props) => {
44 45
             <div className={styles.header}>
45 46
               <Link to="/">
46 47
                 <img alt="logo" className={styles.logo} src={logo} />
47
-                <span className={styles.title}>新联康</span>
48
+                <span className={styles.title}>{setting.title}</span>
48 49
               </Link>
49 50
             </div>
50 51
             <div className={styles.desc}>Ant Design 是西湖区最具影响力的 Web 设计规范</div>

+ 1
- 1
src/pages/Live/LiveActivity/Edit/components/share.jsx View File

@@ -9,7 +9,7 @@ import Wangedit from '../../../../../components/Wangedit/Wangedit'
9 9
 import request from '../../../../../utils/request'
10 10
 import yinhao from '../../../../../assets/yinhao.png'
11 11
 import ImageUploader from '../../../../../components/XForm/ImageUpload';
12
-import logo from '../../../../../assets/logo.png';
12
+import logo from '../../../../../assets/logo.svg';
13 13
 import touxiang from '../../../../../assets/touxiang.jpg';
14 14
 import poster1 from '../../../../../assets/poster1.png';
15 15
 import poster2 from '../../../../../assets/poster2.png';

+ 1
- 1
src/pages/Live/liveActivity copy/edit/components/share.jsx View File

@@ -9,7 +9,7 @@ import Wangedit from '../../../../../components/Wangedit/Wangedit'
9 9
 import request from '../../../../../utils/request'
10 10
 import yinhao from '../../../../../assets/yinhao.png'
11 11
 import ImageUploader from '../../../../../components/XForm/ImageUpload';
12
-import logo from '../../../../../assets/logo.png';
12
+import logo from '../../../../../assets/logo.svg';
13 13
 import touxiang from '../../../../../assets/touxiang.jpg';
14 14
 import poster1 from '../../../../../assets/poster1.png';
15 15
 import poster2 from '../../../../../assets/poster2.png';

+ 1
- 1
src/pages/activity/detailActivity.jsx View File

@@ -11,7 +11,7 @@ import Wangedit from '../../components/Wangedit/Wangedit'
11 11
 import request from '../../utils/request'
12 12
 import yinhao from '../../assets/yinhao.png'
13 13
 import ImageUploader from '../../components/XForm/ImageUpload';
14
-import logo from '../../assets/logo.png';
14
+import logo from '../../assets/logo.svg';
15 15
 import touxiang from '../../assets/touxiang.jpg';
16 16
 import poster1 from '../../assets/poster1.png';
17 17
 import poster2 from '../../assets/poster2.png';

+ 1
- 1
src/pages/activity/editActivity.jsx View File

@@ -12,7 +12,7 @@ import Wangedit from '../../components/Wangedit/Wangedit'
12 12
 import request from '../../utils/request'
13 13
 import yinhao from '../../assets/yinhao.png'
14 14
 import ImageUploader from '../../components/XForm/ImageUpload';
15
-import logo from '../../assets/logo.png';
15
+import logo from '../../assets/logo.svg';
16 16
 import touxiang from '../../assets/touxiang.jpg';
17 17
 import poster1 from '../../assets/poster1.png';
18 18
 import poster2 from '../../assets/poster2.png';

+ 1
- 1
src/pages/activity/groupActivity/detailActivity.jsx View File

@@ -11,7 +11,7 @@ import Wangedit from '../../../components/Wangedit/Wangedit'
11 11
 import request from '../../../utils/request'
12 12
 import yinhao from '../../../assets/yinhao.png'
13 13
 import ImageUploader from '../../../components/XForm/ImageUpload';
14
-import logo from '../../../assets/logo.png';
14
+import logo from '../../../assets/logo.svg';
15 15
 import touxiang from '../../../assets/touxiang.jpg';
16 16
 import poster1 from '../../../assets/poster1.png';
17 17
 import poster2 from '../../../assets/poster2.png';

+ 1
- 1
src/pages/activity/groupActivity/editGroupActivity.jsx View File

@@ -11,7 +11,7 @@ import Wangedit from '../../../components/Wangedit/Wangedit'
11 11
 import request from '../../../utils/request'
12 12
 import yinhao from '../../../assets/yinhao.png'
13 13
 import ImageUploader from '../../../components/XForm/ImageUpload';
14
-import logo from '../../../assets/logo.png';
14
+import logo from '../../../assets/logo.svg';
15 15
 import touxiang from '../../../assets/touxiang.jpg';
16 16
 import poster1 from '../../../assets/poster1.png';
17 17
 import poster2 from '../../../assets/poster2.png';

+ 1
- 1
src/pages/activity/helpActivity/detailActivity.jsx View File

@@ -11,7 +11,7 @@ import Wangedit from '../../../components/Wangedit/Wangedit'
11 11
 import request from '../../../utils/request'
12 12
 import yinhao from '../../../assets/yinhao.png'
13 13
 import ImageUploader from '../../../components/XForm/ImageUpload';
14
-import logo from '../../../assets/logo.png';
14
+import logo from '../../../assets/logo.svg';
15 15
 import touxiang from '../../../assets/touxiang.jpg';
16 16
 import poster1 from '../../../assets/poster1.png';
17 17
 import poster2 from '../../../assets/poster2.png';

+ 1
- 1
src/pages/activity/helpActivity/edithelpActivity.jsx View File

@@ -11,7 +11,7 @@ import Wangedit from '../../../components/Wangedit/Wangedit'
11 11
 import request from '../../../utils/request'
12 12
 import yinhao from '../../../assets/yinhao.png'
13 13
 import ImageUploader from '../../../components/XForm/ImageUpload';
14
-import logo from '../../../assets/logo.png';
14
+import logo from '../../../assets/logo.svg';
15 15
 import touxiang from '../../../assets/touxiang.jpg';
16 16
 import poster1 from '../../../assets/poster1.png';
17 17
 import poster2 from '../../../assets/poster2.png';

+ 1
- 1
src/pages/activity/liveActivity/edit/components/share.jsx View File

@@ -9,7 +9,7 @@ import Wangedit from '../../../../../components/Wangedit/Wangedit'
9 9
 import request from '../../../../../utils/request'
10 10
 import yinhao from '../../../../../assets/yinhao.png'
11 11
 import ImageUploader from '../../../../../components/XForm/ImageUpload';
12
-import logo from '../../../../../assets/logo.png';
12
+import logo from '../../../../../assets/logo.svg';
13 13
 import touxiang from '../../../../../assets/touxiang.jpg';
14 14
 import poster1 from '../../../../../assets/poster1.png';
15 15
 import poster2 from '../../../../../assets/poster2.png';

+ 69
- 35
src/pages/building/Edit/Basic.jsx View File

@@ -1,13 +1,15 @@
1
-import React from 'react'
1
+import React, { useState } from 'react'
2 2
 import { Row, Col, Form, Input, InputNumber, Radio, notification, Select } from 'antd'
3
-import FileUpload from '@/components/XForm/FileUpload';
4
-import ImageUpload from '@/components/XForm/ImageUpload';
5
-import ImageListUpload from '@/components/XForm/ImageListUpload';
3
+import FileUpload from '@/components/XForm/FileUpload'
4
+import ImageUpload from '@/components/XForm/ImageUpload'
5
+import ImageListUpload from '@/components/XForm/ImageListUpload'
6 6
 import SelectCity from '@/components/SelectButton/CitySelect'
7 7
 import AreaSelect from '@/components/SelectButton/AreaSelect'
8
+import { POI_TYPES_KETY, POI_TYPES, getPoiData } from '@/utils/map'
8 9
 import BuildingType from './components/BuildingTypeSelect'
9 10
 import OpenTimePicker from './components/OpenTimePicker'
10 11
 import Amap from './components/Amap'
12
+import EditableArround from './components/EditableArround'
11 13
 import { formItemLayout, groupItemLayout } from './utils'
12 14
 
13 15
 const fullWidth= { width: '100%' }
@@ -21,7 +23,10 @@ const GroupItem = ({children}) => (
21 23
   </Row>
22 24
 )
23 25
 
24
-const BuildingBasic = (props) => {
26
+const initPoiData = POI_TYPES.map((poi) => poi.key).reduce((acc, key) => ({ ...acc, [key]: undefined }), {})
27
+
28
+const BuildingBasic = React.forwardRef((props, ref) => {
29
+  const [pois, setPois] = useState(initPoiData)
25 30
   const { form } = props;
26 31
   const { getFieldDecorator, getFieldValue, setFieldsValue } = form;
27 32
 
@@ -40,7 +45,7 @@ const BuildingBasic = (props) => {
40 45
   }
41 46
 
42 47
   // 周边设施 回调
43
-  function handleMapScope(e) {
48
+  function handleMapScopeChange(e) {
44 49
     const coordinateValue = getFieldValue('coordinate')
45 50
     if (!coordinateValue) {
46 51
       notification.error({ message: '请先选择项目坐标位置' })
@@ -48,11 +53,15 @@ const BuildingBasic = (props) => {
48 53
     }
49 54
 
50 55
     const lngLat = getFieldValue('coordinate').split(',')
51
-    const poiData = [].concat(POI_TYPES)
52
-    poiData.map(item => {
53
-      getAroundData({ types: item.key, location: lngLat, radius: e }).then(res => {
54
-        const { pois } = res
55
-        setFormMapScopeValue(item.key, pois)
56
+
57
+    // 把支持的周边分类都去检索一遍
58
+    POI_TYPES.forEach(({ key }) => {
59
+      getPoiData({ type: key, location: lngLat, radius: e }).then(res => {
60
+        const poiStr = (res.pois || []).map((p) => p.name).join(',')
61
+        setPois({
62
+          ...pois,
63
+          [key]: poiStr
64
+        })
56 65
       }).catch(err => {
57 66
         console.error(err)
58 67
         notification.error({ message: '周边数据获取失败' })
@@ -65,11 +74,11 @@ const BuildingBasic = (props) => {
65 74
       <Item label="项目Id" style={{ display: 'none' }}>
66 75
         {getFieldDecorator('buildingId')(<Input disabled />)}
67 76
       </Item>
68
-      {/* <Item label="楼盘编号" >
77
+      <Item label="楼盘编号" >
69 78
         {getFieldDecorator('code', {
70 79
           rules: [{ required: true, message: '请输入楼盘编号' }],
71 80
         })(<Input />)}
72
-      </Item> */}
81
+      </Item>
73 82
       <Item label="楼盘名称" >
74 83
         {getFieldDecorator('buildingName', {
75 84
           rules: [{ required: true, message: '请输入楼盘名' }],
@@ -184,31 +193,56 @@ const BuildingBasic = (props) => {
184 193
           rules: [{ required: true, message: '请输入项目地址' }],
185 194
         })(<Input />)}
186 195
       </Form.Item>
187
-      <Form.Item label="地图位置" >
188
-        {getFieldDecorator('mapCoordinate')(<Amap onChange={e => setFieldsValue({ coordinate: e })}/>)}
196
+      <Form.Item label="项目坐标" >
197
+        {getFieldDecorator('coordinate', {
198
+          rules: [{ required: true, message: '请输入项目坐标' }],
199
+        })(<Amap onChange={e => setFieldsValue({ coordinate: e })} />)}
200
+      </Form.Item>
201
+      <Form.Item label="周边范围" >
202
+        {getFieldDecorator('mapScope', {
203
+          rules: [{ required: true, message: '请选择周边设施搜索范围' }],
204
+        })(
205
+          <Select placeholder="周边设施搜索范围" style={fullWidth} onChange={handleMapScopeChange}>
206
+            <Select.Option value={1000}>1公里</Select.Option>
207
+            <Select.Option value={3000}>3公里</Select.Option>
208
+            <Select.Option value={5000}>5公里</Select.Option>
209
+            <Select.Option value={10000}>10公里</Select.Option>
210
+          </Select>,
211
+        )}
212
+      </Form.Item>
213
+      <Form.Item label="周边交通" >
214
+        {getFieldDecorator('buildingTransport')(
215
+          <EditableArround pois={pois[POI_TYPES_KETY.Transport]} />,
216
+        )}
217
+      </Form.Item>
218
+      <Form.Item label="周边商业" >
219
+        {getFieldDecorator('buildingMall')(
220
+          <EditableArround pois={pois[POI_TYPES_KETY.Mall]} />,
221
+        )}
222
+      </Form.Item>
223
+      <Form.Item label="周边学校" >
224
+        {getFieldDecorator('buildingEdu')(
225
+          <EditableArround pois={pois[POI_TYPES_KETY.Edu]} />,
226
+        )}
227
+      </Form.Item>
228
+      <Form.Item label="周边医院" >
229
+        {getFieldDecorator('buildingHospital')(
230
+          <EditableArround pois={pois[POI_TYPES_KETY.Hospital]} />,
231
+        )}
232
+      </Form.Item>
233
+      <Form.Item label="周边银行" >
234
+        {getFieldDecorator('buildingBank')(
235
+          <EditableArround pois={pois[POI_TYPES_KETY.Bank]} />,
236
+        )}
237
+      </Form.Item>
238
+      <Form.Item label="周边餐饮" >
239
+        {getFieldDecorator('buildingRestaurant')(
240
+          <EditableArround pois={pois[POI_TYPES_KETY.Restaurant]} />,
241
+        )}
189 242
       </Form.Item>
190
-      <GroupItem>
191
-        <Form.Item label="项目坐标" {...groupItemLayout.a } >
192
-          {getFieldDecorator('coordinate', {
193
-            rules: [{ required: true, message: '请输入项目坐标' }],
194
-          })(<Input disabled />)}
195
-        </Form.Item>
196
-        <Form.Item label="周边范围" {...groupItemLayout.b } >
197
-          {getFieldDecorator('mapScope', {
198
-            rules: [{ required: true, message: '请选择周边设施搜索范围' }],
199
-          })(
200
-            <Select placeholder="周边设施搜索范围" style={fullWidth} onChange={e => getMapScope(e)}>
201
-              <Option value={1000}>1公里</Option>
202
-              <Option value={3000}>3公里</Option>
203
-              <Option value={5000}>5公里</Option>
204
-              <Option value={10000}>10公里</Option>
205
-            </Select>,
206
-          )}
207
-        </Form.Item>
208
-      </GroupItem>
209 243
 
210 244
     </Form>
211 245
   )
212
-}
246
+})
213 247
 
214 248
 export default Form.create({ onValuesChange: console.log })(BuildingBasic)

+ 0
- 126
src/pages/building/Edit/components/Amap.jsx View File

@@ -1,126 +0,0 @@
1
-import React from 'react';
2
-import ReactDOM from 'react-dom';
3
-import { Map, Marker } from 'react-amap';
4
-import styles from './amap.less'
5
-
6
-class Amap extends React.Component {
7
-
8
-  constructor(props) {
9
-    super(props);
10
-    this.state = {
11
-      markerPosition: { longitude: 120, latitude: 35 },
12
-    }
13
-    // 高德地图 Marker 实例
14
-    this.markerInstance = undefined
15
-    // 高德地图 Map 实例
16
-    this.mapInstance = undefined
17
-
18
-    this.amapEvents = {
19
-      created: mapInstance => {
20
-        console.log('高德地图 Map 实例创建成功;如果你要亲自对实例进行操作,可以从这里开始。比如:');
21
-        console.log('缩放级别:', mapInstance.getZoom());
22
-        this.mapInstance = mapInstance
23
-        
24
-
25
-        AMap.plugin(['AMap.Autocomplete', 'AMap.PlaceSearch', 'AMap.CitySearch'], () => {
26
-          // 实例化Autocomplete
27
-          const autoOptions = {
28
-            // city 限定城市,默认全国
29
-            // city: '025',
30
-            // input 为绑定输入提示功能的input的DOM ID
31
-            input: 'amapInput',
32
-          }
33
-          const autoComplete = new AMap.Autocomplete(autoOptions);
34
-          // 无需再手动执行search方法,autoComplete会根据传入input对应的DOM动态触发search
35
-
36
-          const placeSearch = new AMap.PlaceSearch({
37
-            // city: '南京',
38
-            map: mapInstance,
39
-          })
40
-
41
-          // 监听下拉框选中事件
42
-          AMap.event.addListener(autoComplete, 'select', e => {
43
-            // TODO 针对选中的poi实现自己的功能
44
-            placeSearch.setCity(e.poi.adcode)
45
-            placeSearch.search(e.poi.name)
46
-          })
47
-
48
-
49
-          const citySearch = new AMap.CitySearch()
50
-          citySearch.getLocalCity((status, result) => {
51
-            if (status === 'complete' && result.info === 'OK') {
52
-              // 查询成功,result即为当前所在城市信息
53
-              console.log('当前所在城市:', result)
54
-              if (result && result.city && result.bounds) {
55
-                // 当前城市名称
56
-                // const cityinfo = result.city;
57
-
58
-                // 当前城市位置信息
59
-                const citybounds = result.bounds;
60
-                // document.getElementById('info').innerHTML = '您当前所在城市:'+cityinfo;
61
-                // 地图显示当前城市
62
-                mapInstance.setBounds(citybounds);
63
-                // 需要在设置坐标成功后,重新设置 缩放级别
64
-                // mapInstance.setZoom(15)
65
-              }
66
-            }
67
-          })
68
-        })
69
-
70
-        // 实例点击事件
71
-        mapInstance.on('click', e => {
72
-          const lngLat = `${e.lnglat.getLng()},${e.lnglat.getLat()}`
73
-          console.log('坐标位置:', lngLat)
74
-          this.props.onChange(lngLat)
75
-        });
76
-      },
77
-    };
78
-    this.markerEvents = {
79
-      created: markerInstance => {
80
-        console.log('高德地图 Marker 实例创建成功;如果你要亲自对实例进行操作,可以从这里开始。比如:');
81
-        console.log(markerInstance.getPosition());
82
-
83
-        this.markerInstance = markerInstance
84
-      },
85
-    }
86
-    // this.markerPosition = { longitude: 120, latitude: 30 };
87
-  }
88
-
89
-  componentDidUpdate(prevProps) {
90
-    const { value } = this.props
91
-    if (this.props.value !== prevProps.value) {
92
-      if (value) {
93
-        const temp = value.split(',')
94
-        this.setState({ markerPosition: { longitude: temp[1], latitude: temp[0] } }, () => {
95
-          if (this.mapInstance) {
96
-            // 需要在设置坐标成功后,重新设置 缩放级别
97
-            this.mapInstance.setZoom(15)
98
-          }
99
-        })
100
-      }
101
-    }
102
-  }
103
-
104
-  render() {
105
-    return (
106
-      <>
107
-        <div style={{ width: '100%', height: '400px', position: 'relative' }}>
108
-          {/* zoom={15} 设置后,无效,不知道什么原因,必须手动设置 */}
109
-          <Map plugins={['ToolBar']} events={this.amapEvents} amapkey="f0d1d4f82432504003ebf46e5e36ff03" center={this.state.markerPosition}>
110
-            <Marker position={this.state.markerPosition} events={this.markerEvents} />
111
-          </Map>
112
-          {
113
-          <div className={styles.infoBox}>
114
-            <span className={styles.inputText}>请输入关键字</span>
115
-            <input id="amapInput" className={styles.input} type="text" />
116
-          </div>
117
-          }
118
-        </div>
119
-      </>
120
-    )
121
-  }
122
-}
123
-
124
-// f0d1d4f82432504003ebf46e5e36ff03
125
-
126
-export default Amap

+ 16
- 0
src/pages/building/Edit/components/Amap/PoiPicker.jsx View File

@@ -0,0 +1,16 @@
1
+import React, { useEffect } from 'react'
2
+
3
+export default (props) => {
4
+  
5
+  useEffect(() => {
6
+    window.AMapUI.loadUI(['misc/PoiPicker'], function(PoiPicker) {
7
+      const poiPicker = new PoiPicker({
8
+          input: props.input.current
9
+      });
10
+
11
+      poiPicker.on('poiPicked', props.onPick)
12
+    });
13
+  }, [])
14
+
15
+  return null
16
+}

+ 104
- 0
src/pages/building/Edit/components/Amap/index.jsx View File

@@ -0,0 +1,104 @@
1
+import React, { useEffect, useRef, useState } from 'react';
2
+import { sdk } from '@/utils/map'
3
+import { newMarker, autoPos, autoPoi } from './utils'
4
+import './style.less'
5
+
6
+const plugins = ['AMap.Scale', 'AMap.ToolBar', 'AMap.Geolocation', 'AMap.Autocomplete', 'AMap.PlaceSearch']
7
+
8
+export default (props) => {
9
+  const map = useRef()
10
+  const container = useRef()
11
+  const inputRef = useRef()
12
+  const posMarker = useRef()
13
+  const [currentPos, setCurrentPos] = useState([]);
14
+
15
+  const handleClick = (e) => {
16
+    const { lnglat } = e
17
+    const pos = [lnglat.getLng(), lnglat.getLat()]
18
+    setCurrentPos(pos)
19
+    props.onChange(pos.join(','))
20
+  }
21
+
22
+  useEffect(() => {
23
+    // 只加载一次 amap 相关 js
24
+    sdk.loadMapModule({
25
+      plugins,
26
+    }).then((AMap) => {
27
+      const instance = new AMap.Map(container.current, { zoom: 12 })
28
+      instance.addControl(new AMap.Scale())
29
+      instance.addControl(new AMap.ToolBar())
30
+      
31
+      // 尝试自动定位到当前位置
32
+      if (!props.value) {
33
+        instance.addControl(autoPos(AMap))
34
+      }
35
+
36
+      // 当前选中点 - 初始的时候没有定位
37
+      posMarker.current = newMarker(AMap, {
38
+        active: true,
39
+        map: instance,
40
+        position: props.value ? props.value.split(',') : undefined,
41
+      })
42
+
43
+      // POI 搜索
44
+      autoPoi(instance, AMap, inputRef, { click: handleClick })
45
+
46
+      instance.on('click', handleClick);
47
+      map.current = instance
48
+    })
49
+  }, [])
50
+
51
+  useEffect(() => {
52
+    if (props.value) {
53
+      setCurrentPos(props.value.split(','))
54
+    }
55
+  }, [props.value])
56
+
57
+  useEffect(() => {
58
+    if (currentPos.length) {
59
+      posMarker.current.setPosition(currentPos)
60
+    }
61
+  }, [currentPos])
62
+
63
+  const boxStyle = {
64
+    width: '100%',
65
+    height: '400px',
66
+    position: 'relative',
67
+    ...(props.style || {}),
68
+  }
69
+
70
+  const mapStyle = {
71
+    height: '100%',
72
+    width: '100%',
73
+    margin: 0,
74
+  }
75
+
76
+  const inputStyle = {
77
+    width: '200px',
78
+    padding: '5px',
79
+    position: 'absolute',
80
+    zIndex: 9999,
81
+    right: '30px',
82
+    lineHeight: '1em',
83
+  }
84
+
85
+  const inputSty1 = {
86
+    ...inputStyle,
87
+    top: '50px',
88
+  }
89
+
90
+  const inputSty2 = {
91
+    ...inputStyle,
92
+    top: '10px',
93
+    background: 'rgba(255, 255, 255, .9)',
94
+    border: '1px solid',
95
+  }
96
+
97
+  return (
98
+    <div className={props.className} style={boxStyle}>
99
+      <div ref={container} style={mapStyle} id="poi-map-wrapper"></div>
100
+      <input placeholder="请输入搜索关键字" ref={inputRef} style={inputSty1} />
101
+      <input value={`坐标: ${currentPos.join(',')}`} style={inputSty2} disabled />
102
+    </div>
103
+  )
104
+}

+ 8
- 0
src/pages/building/Edit/components/Amap/style.less View File

@@ -0,0 +1,8 @@
1
+:global{
2
+  #poi-map-wrapper {
3
+    .amap-marker-label{
4
+      border: 0;
5
+      background-color: transparent;
6
+    }
7
+  }
8
+}

+ 79
- 0
src/pages/building/Edit/components/Amap/utils.js View File

@@ -0,0 +1,79 @@
1
+
2
+const iconNoraml = '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png';
3
+const iconActive = '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png';
4
+
5
+export function newMarker(AMap, options = {}) {
6
+  const { active = false, ...params } = options;
7
+  const icon = new AMap.Icon({
8
+    size: new AMap.Size(25, 34),
9
+    image: active ? iconActive : iconNoraml,
10
+    imageSize: new AMap.Size(25, 34),
11
+  })
12
+  const offset = new AMap.Pixel(-13, -30)
13
+
14
+  return new AMap.Marker({ icon, offset, ...params });
15
+}
16
+
17
+export function autoPos(AMap, options = {}) {
18
+  return new AMap.Geolocation({
19
+    enableHighAccuracy: true,//是否使用高精度定位,默认:true
20
+    timeout: 10000,          //超过10秒后停止定位,默认:5s
21
+    buttonPosition:'RB',    //定位按钮的停靠位置
22
+    buttonOffset: new AMap.Pixel(10, 20),//定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
23
+    zoomToAccuracy: true,   //定位成功后是否自动调整地图视野到定位点
24
+    ...options,
25
+  });
26
+}
27
+
28
+const labelStyle = `
29
+  padding: .5em .8em;
30
+  border-radius: .25rem;
31
+  background-color: white;
32
+  box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2);
33
+`
34
+
35
+export function autoPoi(map, AMap, inputRef, evt) {
36
+  const markers = [];
37
+  const input = inputRef.current
38
+
39
+  const destroy = () => {
40
+    if (markers.length) {
41
+      markers.forEach((m) => map.remove(m))
42
+      markers.splice(0, markers.length)
43
+    }
44
+  }
45
+
46
+  const handleSearchResult = (status, result) => {
47
+    // 先清空
48
+    destroy();
49
+
50
+    const { pois } = result.poiList;
51
+    (pois || []).forEach((poi) => {
52
+      const { location, name } = poi;
53
+      const marker = newMarker(AMap, {
54
+        map,
55
+        position: location,
56
+        label: {
57
+          content: `<div style="${labelStyle}">${name}</div>`,
58
+          direction: 'top',
59
+        },
60
+      })
61
+      marker.on('click', evt.click)
62
+      markers.push(marker)
63
+    })
64
+    map.setFitView();
65
+  }
66
+  
67
+  const placeSearch = new AMap.PlaceSearch({ pageSize: 20 });
68
+  const autoComplete = new AMap.Autocomplete({ input });
69
+
70
+  // 选择自动填充
71
+  autoComplete.on('select', e => {
72
+    placeSearch.setCity(e.poi.adcode)
73
+    placeSearch.search(e.poi.name, handleSearchResult)
74
+  })
75
+
76
+  autoComplete.on('error', (err) => console.error(err))
77
+
78
+  return autoComplete;
79
+}

+ 26
- 0
src/pages/building/Edit/components/EditableArround/MapPois.jsx View File

@@ -0,0 +1,26 @@
1
+import React, { useRef, useEffect, forwardRef } from 'react'
2
+
3
+export default forwardRef((props, ref) => {
4
+  const tags = useRef((props.pois || '').split(','))
5
+
6
+  // 用来记录上一次传值
7
+  const previous = useRef()
8
+
9
+  // 监控 props.pois 的变化, 触发 onChange
10
+  // 实际场景中 props.pois 只会由地图引起变化
11
+  useEffect(() => {
12
+    const changed = previous.current !== props.pois
13
+    if (changed) {
14
+      tags.current = (props.pois || '').split(',')
15
+      previous.current = props.pois
16
+
17
+      if (props.onChange) {
18
+        props.onChange(tags.current)
19
+      }
20
+    }
21
+  }, [props.pois, props.onChange])
22
+
23
+  return (
24
+    <></>
25
+  )
26
+})

src/pages/building/Edit/components/EditableArround.jsx → src/pages/building/Edit/components/EditableArround/index.jsx View File

@@ -1,18 +1,40 @@
1 1
 import React, { useEffect, useRef, useState } from 'react'
2
-import { Typography, Tag, Input } from 'antd'
2
+import { Typography, Tag, Input, Icon } from 'antd'
3
+import MapPois from './MapPois'
4
+import { arrRemove, arrAdd } from './utils'
5
+
6
+/**
7
+ * 因为周边TAG, 包含了2个部分的维护,一个是自定义周边,一个是地图周边,所以,需要单独写2个标签的处理
8
+ */
3 9
 
4 10
 export default React.forwardRef((props, ref) => {
5 11
   const inputRef = useRef()
6
-  const valRef = useRef()
12
+  const poiRef = useRef()
7 13
   const [inputValue, setInputValue] = useState()
8 14
   const [inputVisible, setInputVisible] = useState(false)
9 15
   const [tags, setTags] = useState([])
10
-  // 地图周边 tag
11 16
   const [mapTags, setMapTags] = useState([])
12 17
 
18
+  const handlePoiChange = (e) => {
19
+    setMapTags(e)
20
+
21
+    // 先清理原来的
22
+    const tagArr = arrRemove(tags, mapTags)
23
+    // 再加入新的
24
+    const nwTags = arrAdd(tagArr, e)
25
+
26
+    if (nwTags !== tags) {
27
+      setTags(nwTags)
28
+  
29
+      if (props.onChange) {
30
+        props.onChange(nwTags.join(','))
31
+      }
32
+    }
33
+  }
34
+
13 35
   const handleClose = (tag) => {
14 36
     if (mapTags.indexOf(tag) > -1) {
15
-      setMapTags(mapTags.filter((t) => t !== tag))
37
+      setMapTags(mapTags.filter((it) => it !== tag))
16 38
     }
17 39
 
18 40
     if (props.onChange) {
@@ -30,26 +52,13 @@ export default React.forwardRef((props, ref) => {
30 52
   }
31 53
 
32 54
   useEffect(() => {
33
-    setMapTags(props.mapPois || [])
34
-  }, [props.mapPois])
35
-
36
-  useEffect(() => {
37
-    const vals = (props.value||'').split(',')
38
-    const arr = vals.concat(mapTags)
39
-
40
-    // 去重
41
-    const nwTags = []
42
-    arr.forEach((it) => {
43
-      if (nwTags.indexOf(it) === -1) {
44
-        nwTags.push(it)
45
-      }
46
-    })
47
-
48
-    setTags(nwTags)
49
-  }, [props.value, mapTags])
55
+    const arr = props.value ? props.value.split(',') : []
56
+    setTags(arr)
57
+  }, [props.value])
50 58
 
51 59
   return (
52 60
     <div>
61
+      <MapPois ref={poiRef} pois={props.pois} onChange={handlePoiChange} />
53 62
       {
54 63
         tags.map((tag) => (
55 64
           <Tag key={tag} closable onClose={() => handleClose(tag)}>
@@ -63,7 +72,7 @@ export default React.forwardRef((props, ref) => {
63 72
             ref={inputRef}
64 73
             type="text"
65 74
             size="small"
66
-            style={{ width: 80, display: inputVisible ? 'block' : 'none' }}
75
+            style={{ width: 80, display: inputVisible ? 'inline-block' : 'none' }}
67 76
             value={inputValue}
68 77
             onChange={e => setInputValue(e.target.value)}
69 78
             onBlur={handleInputConfirm}

+ 35
- 0
src/pages/building/Edit/components/EditableArround/utils.js View File

@@ -0,0 +1,35 @@
1
+
2
+export function arrRemove(src, target) {
3
+  if (!target || target.length < 1) {
4
+    return src;
5
+  }
6
+
7
+  if (!src || src.length < 1) {
8
+    return src;
9
+  }
10
+
11
+  const arr = src.filter((it) => target.indexOf(it) === -1)
12
+  if (arr.length === src.length) return src;
13
+
14
+  return arr;
15
+}
16
+
17
+export function arrAdd(src, add) {
18
+  if (!add || add.length < 1) {
19
+    return src;
20
+  }
21
+
22
+  if (!src || add.length < 1) {
23
+    return [...add]
24
+  }
25
+
26
+  
27
+  const nwTags = src.slice()
28
+  add.forEach((it) => {
29
+    if (nwTags.indexOf(it) === -1) {
30
+      nwTags.push(it)
31
+    }
32
+  })
33
+
34
+  return src;
35
+}

+ 0
- 53
src/pages/building/Edit/components/amap.less View File

@@ -1,53 +0,0 @@
1
-
2
-.infoBox {
3
-  padding: 10px;
4
-  position: absolute;
5
-  top: 20px;
6
-  left: 20px;
7
-  background-color: white;
8
-  width: 290px;
9
-  box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);
10
-  z-index: 100;
11
-  .inputText{
12
-    margin-right: 10px;
13
-  }
14
-  .input{
15
-    width: 150px;
16
-    height: 32px;
17
-    font-size: 16px;
18
-  }
19
- 
20
-}
21
-
22
-
23
-/* types */
24
-
25
-.native-toast-error {
26
-  background-color: #d92727;
27
-  color: white;
28
-}
29
-
30
-.native-toast-success {
31
-  background-color: #62a465;
32
-  color: white;
33
-}
34
-
35
-.native-toast-warning {
36
-  background-color: #fdaf17;
37
-  color: white;
38
-}
39
-
40
-.native-toast-info {
41
-  background-color: #5060ba;
42
-  color: white;
43
-}
44
-
45
-[class^="native-toast-icon-"] {
46
-  vertical-align: middle;
47
-  margin-right: 8px
48
-}
49
-
50
-[class^="native-toast-icon-"] svg {
51
-  width: 16px;
52
-  height: 16px;
53
-}

+ 1
- 1
src/pages/news/list/compents/Poster.jsx View File

@@ -5,7 +5,7 @@ import apis from '@/services/apis';
5 5
 import router from 'umi/router';
6 6
 import request from '@/utils/request';
7 7
 import ImageUploader from '@/components/XForm/ImageUpload';
8
-import logo from '../../../../assets/logo.png';
8
+import logo from '../../../../assets/logo.svg';
9 9
 import yinhao from '../../../../assets/yinhao.png';
10 10
 import touxiang from '../../../../assets/touxiang.jpg';
11 11
 import poster1 from '../../../../assets/poster1.png';

+ 1
- 1
src/pages/news/list/compents/Share.jsx View File

@@ -5,7 +5,7 @@ import apis from '@/services/apis';
5 5
 import router from 'umi/router';
6 6
 import request from '@/utils/request';
7 7
 import ImageUploader from '@/components/XForm/ImageUpload';
8
-import logo from '../../../../assets/logo.png';
8
+import logo from '../../../../assets/logo.svg';
9 9
 import poster2 from '../../../../assets/poster2.png';
10 10
 
11 11
 

+ 1
- 1
src/pages/news/list/editNewsList.jsx View File

@@ -8,7 +8,7 @@ import  { FieldTypes, createForm } from '../../../components/XForm';
8 8
 import Wangedit from '../../../components/Wangedit/Wangedit'
9 9
 import request from '../../../utils/request'
10 10
 import ImageUploader from '../../../components/XForm/ImageUpload';
11
-import logo from '../../../assets/logo.png';
11
+import logo from '../../../assets/logo.svg';
12 12
 import yinhao from '../../../assets/yinhao.png'
13 13
 import touxiang from '../../../assets/touxiang.jpg';
14 14
 import poster1 from '../../../assets/poster1.png';

+ 8
- 5
src/utils/map/index.js View File

@@ -1,8 +1,11 @@
1 1
 import amapSDK from './sdk';
2 2
 
3
-const AMAP_KEY = '14f05ce59c26364fd0674014dc0d8b1b'
3
+export const AMAP_KEY = {
4
+  service: '3be0a9567a794d2690d378476f057a6f',
5
+  web: '29259f677b42900507074fd92ecb628a',
6
+}
4 7
 
5
-const sdk = amapSDK(AMAP_KEY)
8
+export const sdk = amapSDK(AMAP_KEY)
6 9
 
7 10
 export const POI_TYPES_KETY = {
8 11
   Transport: 'Transport',
@@ -61,7 +64,7 @@ export const POI_TYPES = [
61 64
  * 获取周边数据
62 65
  * @param {查询参数} params 
63 66
  */
64
-export function getAroundData (params) {
67
+export function getPoiData (params) {
65 68
   return new Promise((resolve, reject) => {
66 69
       const { type, location } = params
67 70
       if (!type) {
@@ -81,9 +84,9 @@ export function getAroundData (params) {
81 84
         return
82 85
       }
83 86
 
84
-      sdk({
85
-        types: poiType.types.join('|'),
87
+      sdk.getPlaceAround({
86 88
         ...params,
89
+        types: poiType.types.join('|'),
87 90
       }).then(resolve)
88 91
       .catch(reject);
89 92
   })

+ 19
- 3
src/utils/map/sdk.js View File

@@ -1,3 +1,4 @@
1
+import AMapLoader from '@amap/amap-jsapi-loader'
1 2
 
2 3
 // 简易请求
3 4
 function request(url, params, options = {}) {
@@ -16,7 +17,7 @@ function request(url, params, options = {}) {
16 17
     }).then(response => response.json())
17 18
     .then((data) => {
18 19
       const { status, info } = data
19
-      if (status === 1) {
20
+      if (status === '1') {
20 21
         resolve(data)
21 22
       } else {
22 23
         console.error(data)
@@ -27,15 +28,30 @@ function request(url, params, options = {}) {
27 28
   })
28 29
 }
29 30
 
30
-export function amapSDK(key) {
31
+export default function amapSDK(key) {
31 32
   const prefix = 'https://restapi.amap.com'
32 33
 
34
+  function loadMapModule(options = {}) {
35
+    // AMapLoader 可以多次加载
36
+    return new Promise((resolve, reject) => {
37
+      AMapLoader.load({
38
+        ...options,
39
+        key: key.web,
40
+      }).then((AMap) => {
41
+        resolve(AMap)
42
+      }).catch((e) => {
43
+        reject(e)
44
+      })
45
+    })
46
+  }
47
+
33 48
   function getPlaceAround(params = {}) {
34 49
     const url = `${prefix}/v5/place/around`
35
-    return request(url, { key, ...params } )
50
+    return request(url, { key: key.service, ...params } )
36 51
   }
37 52
 
38 53
   return {
54
+    loadMapModule,
39 55
     getPlaceAround,
40 56
   }
41 57
 }