index.jsx 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. import { useState, useEffect, useRef } from 'react'
  2. import Taro from '@tarojs/taro'
  3. import withLayout from '@/layout'
  4. import { ScrollView, Map } from '@tarojs/components'
  5. import { fetch } from '@/utils/request'
  6. import { API_ITEMS_DETAIL } from '@/constants/api'
  7. import '@/assets/css/iconfont.css'
  8. import './index.scss'
  9. export default withLayout((props) => {
  10. const { router, city } = props
  11. const { id } = router.params
  12. const [DetailInfo, setDetailInfo] = useState({})
  13. const [loc, setLoc] = useState([])
  14. const [NavList, setNavList] = useState([])
  15. const [CurrentNavId, setCurrentNavId] = useState(1)
  16. const [List, setList] = useState([])
  17. const [OtherList, setOtherList] = useState([])
  18. const [markers, setMarkers] = useState([])
  19. const mapCtx = useRef()
  20. const CutNav = (id) => {
  21. return () => {
  22. setCurrentNavId(id)
  23. }
  24. }
  25. const locationTo = () => {
  26. if (loc.length) {
  27. Taro.openLocation({
  28. longitude: loc[0],
  29. latitude: loc[1],
  30. name: DetailInfo.buildingName,
  31. address: DetailInfo.address,
  32. })
  33. }
  34. }
  35. const handlePoi = (poi) => {
  36. const [longitude, latitude] = poi.location.split(',').map(x => x ? x - 0 : undefined)
  37. const marker = {
  38. id: 1,
  39. longitude,
  40. latitude,
  41. // iconPath: '',
  42. width: 18,
  43. height: 27,
  44. callout: {
  45. content: poi.name,
  46. color: '#333333',
  47. padding: 6,
  48. display: 'ALWAYS',
  49. }
  50. }
  51. const center = markers[0]
  52. setMarkers([center, marker])
  53. if (mapCtx.current) {
  54. // 缩放地图,显示所有 marker
  55. const points = [
  56. { longitude: center.longitude, latitude: center.latitude },
  57. { longitude: marker.longitude, latitude: marker.latitude }
  58. ]
  59. mapCtx.current.includePoints({ points, padding: [32] })
  60. }
  61. }
  62. // 获取地图 Context
  63. useEffect(() => {
  64. Taro.nextTick(() => {
  65. mapCtx.current = Taro.createMapContext('around-map')
  66. })
  67. }, [])
  68. useEffect(() => {
  69. // 获取楼盘信息
  70. fetch({ url: `${API_ITEMS_DETAIL}/${id}`, spin: true }).then((res) => {
  71. if (res?.coordinate) {
  72. // 地图中心
  73. const [longitude, latitude] = res.coordinate.split(',')
  74. setLoc([longitude - 0, latitude - 0])
  75. // 中心点标记
  76. setMarkers([{
  77. id: -1,
  78. longitude,
  79. latitude,
  80. width: 18,
  81. height: 27,
  82. callout: {
  83. content: res.buildingName,
  84. color: '#333333',
  85. padding: 6,
  86. display: 'ALWAYS',
  87. }
  88. }])
  89. setDetailInfo(res || {})
  90. if (res.mapJson) {
  91. const pois = JSON.parse(res.mapJson).map(poi => ({ ...poi, data: JSON.parse(poi.data) }))
  92. setNavList(pois)
  93. setCurrentNavId(pois[0].key)
  94. setList(pois[0].data)
  95. }
  96. } else {
  97. Taro.showToast({
  98. title: '当前楼盘未设置位置信息',
  99. icon: 'none',
  100. })
  101. }
  102. }).catch((err) => {
  103. console.error(err)
  104. })
  105. }, [id])
  106. const TypeCalc = (key) => {
  107. switch (key) {
  108. case 'Transport':
  109. return '交通'
  110. case 'Mall':
  111. return '商业'
  112. case 'Edu':
  113. return '学校'
  114. case 'Hospital':
  115. return '医院'
  116. case 'Bank':
  117. return '银行'
  118. case 'Restaurant':
  119. return '餐饮'
  120. default:
  121. return ''
  122. }
  123. }
  124. return (
  125. <view className='Page buildingAround'>
  126. <view className='MapContainer'>
  127. <view>
  128. <Map
  129. id='around-map'
  130. showLocation
  131. longitude={loc[0]}
  132. latitude={loc[1]}
  133. markers={markers}
  134. />
  135. </view>
  136. </view>
  137. <view className='TabContainer'>
  138. <view>
  139. <view className='Title flex-h'>
  140. <view className='flex-item'>
  141. <text>{DetailInfo.buildingName}</text>
  142. </view>
  143. <view className='Go' onClick={locationTo}>
  144. <text>前往</text>
  145. <text className='iconfont icon-qianwang'></text>
  146. </view>
  147. </view>
  148. <view className='Address flex-h'>
  149. <text className='iconfont icon-dingwei'></text>
  150. <view className='flex-item'>
  151. <text>{DetailInfo.address}</text>
  152. </view>
  153. </view>
  154. <view className='Nav flex-h'>
  155. {
  156. NavList.map((item) => (
  157. <view className={item.key === CurrentNavId ? 'flex-item active' : 'flex-item'} key={item.key}>
  158. <text onClick={CutNav(item.key)}>{`${TypeCalc(item.key)}(${item.data.length})`}</text>
  159. </view>
  160. ))
  161. }
  162. </view>
  163. <view className='CutLine'></view>
  164. <view className='ListContainer'>
  165. <ScrollView scroll-y>
  166. <view className='ScrollContent'>
  167. <view className='List'>
  168. {
  169. List.map((item, index) => (
  170. <view className='flex-h' key={`ListItem-${index}`} onClick={() => handlePoi(item)}>
  171. <text>{index + 1}、</text>
  172. <view className='flex-item'>
  173. <text>{item.name}</text>
  174. </view>
  175. <text className='iconfont icon-dingwei'></text>
  176. <text className='distance'>{`${item.distance || '-'}m`}</text>
  177. </view>
  178. ))
  179. }
  180. </view>
  181. {
  182. OtherList.length > 0 &&
  183. <text>其他</text>
  184. }
  185. <view className='List'>
  186. {
  187. OtherList.map((item, index) => (
  188. <view className='flex-h' key={`ListItem-${index}`}>
  189. <view className='flex-item'>
  190. <text>{index + 1}、南京地铁1号线</text>
  191. </view>
  192. </view>
  193. ))
  194. }
  195. </view>
  196. </view>
  197. </ScrollView>
  198. </view>
  199. </view>
  200. </view>
  201. </view>
  202. )
  203. })