index.jsx 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import React from 'react';
  2. import Taro from '@tarojs/taro';
  3. import { View, Map } from '@tarojs/components';
  4. import { Icon, Loading } from '@antmjs/vantui';
  5. import { getLocation } from '@/utils/authorize';
  6. import iconPath from '@/assets/icons/marker.png';
  7. import style from './style.module.less';
  8. /**
  9. * 这里使用2个map, 每个 map 负责不同的场景
  10. * 如果使用 1 个map, 通过属性去控制, 微信暂时有 bug 比如 showLocation 就有bug
  11. */
  12. export default (props) => {
  13. const { readOnly, location, onChange } = props;
  14. console.log('-----map---readOnly---', readOnly);
  15. const id = React.useMemo(() => `map-${Math.random().toString(36).substring(2, 10)}`, []);
  16. const idReadOnly = React.useMemo(() => `map-${Math.random().toString(36).substring(2, 10)}`, []);
  17. const mapCtxRef = React.useRef();
  18. const [
  19. markers,
  20. center,
  21. ] = React.useMemo(() => {
  22. // eslint-disable-next-line no-undef
  23. const loc = location || DEFAULT_POS;
  24. const [longitude, latitude] = loc.split(',');
  25. const mks = readOnly ? [{
  26. id: 1,
  27. longitude,
  28. latitude,
  29. iconPath,
  30. width: 17,
  31. height: 20
  32. }] : [];
  33. return [
  34. mks,
  35. { longitude, latitude }
  36. ]
  37. }, [location, readOnly]);
  38. const moveTo = (ctx, point) => {
  39. ctx.moveToLocation({
  40. ...point,
  41. fail: console.error,
  42. })
  43. }
  44. const getContext = React.useCallback(() => {
  45. const query = Taro.createSelectorQuery();
  46. query.select(`#${id}`).context(res => {
  47. mapCtxRef.current = res.context;
  48. // 修改中心图标 - 暂时不起作用, wx bug
  49. mapCtxRef.current.setLocMarkerIcon({
  50. iconPath,
  51. fail: console.error,
  52. })
  53. }).exec();
  54. }, [id]);
  55. const fixedLocation = () => {
  56. return new Promise((resolve) => {
  57. Taro.showLoading({
  58. title: '加载中',
  59. })
  60. getLocation({ type: 'gcj02' }).then((res) => {
  61. Taro.hideLoading()
  62. resolve(res);
  63. }).catch((err) => {
  64. console.error(err);
  65. Taro.hideLoading();
  66. Taro.showToast({
  67. title: '定位失败',
  68. icon: 'none',
  69. })
  70. });
  71. });
  72. }
  73. const onRefresh = () => {
  74. if (mapCtxRef.current) {
  75. fixedLocation().then((res) => {
  76. const { longitude, latitude } = res;
  77. onChange([res.longitude, res.latitude].join(','));
  78. moveTo(mapCtxRef.current, { longitude, latitude });
  79. })
  80. }
  81. }
  82. React.useEffect(() => {
  83. if (!readOnly) {
  84. getContext();
  85. // 获取定位
  86. fixedLocation().then((res) => {
  87. const { longitude, latitude } = res;
  88. onChange([longitude, latitude].join(','));
  89. })
  90. }
  91. // eslint-disable-next-line react-hooks/exhaustive-deps
  92. }, [readOnly, getContext]);
  93. return (
  94. <View className={style['map-wrapper']}>
  95. {
  96. !readOnly && (
  97. <Map
  98. id={id}
  99. showLocation
  100. longitude={center.longitude}
  101. latitude={center.latitude}
  102. >
  103. <Icon name="aim" size="24px" onClick={onRefresh} color="#1A7565" className={style['icon']} />
  104. </Map>
  105. )
  106. }
  107. {
  108. readOnly && (
  109. <Map
  110. id={idReadOnly}
  111. longitude={center.longitude}
  112. latitude={center.latitude}
  113. markers={markers}
  114. />
  115. )
  116. }
  117. </View >
  118. )
  119. }