index.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. <template>
  2. <view class="visit-map-panel">
  3. <map
  4. class="visit-map-panel__map"
  5. :latitude="mapLatitude"
  6. :longitude="mapLongitude"
  7. :circles="rangeCircles"
  8. :markers="targetMarkers"
  9. :scale="15"
  10. show-location
  11. show-compass
  12. />
  13. <view class="visit-map-panel__locate" @click="emit('refresh-location')">⌖</view>
  14. <view class="visit-map-panel__add-card">
  15. <view class="visit-map-panel__add-title">
  16. 附近没有合适的{{ targetTypeLabel }}?
  17. </view>
  18. <view class="visit-map-panel__add-action">+ 新增地点</view>
  19. </view>
  20. </view>
  21. </template>
  22. <script setup lang="ts">
  23. import { computed } from 'vue'
  24. import type { LocationResult } from '@/lib/location'
  25. import type { VisitTarget } from '../../types'
  26. const props = defineProps<{
  27. target?: VisitTarget
  28. targetTypeLabel: string
  29. currentLocation: LocationResult | null
  30. rangeRadius: number
  31. }>()
  32. const emit = defineEmits<{
  33. (event: 'refresh-location'): void
  34. }>()
  35. const rangeCircles = computed(() => {
  36. if (!props.currentLocation) return []
  37. return [
  38. {
  39. latitude: props.currentLocation.latitude,
  40. longitude: props.currentLocation.longitude,
  41. radius: props.rangeRadius,
  42. color: '#42bde9aa',
  43. fillColor: '#42bde926',
  44. strokeWidth: 2,
  45. },
  46. ]
  47. })
  48. const targetMarkers = computed(() => {
  49. if (!props.target) return []
  50. return [
  51. {
  52. id: 1,
  53. latitude: props.target.latitude,
  54. longitude: props.target.longitude,
  55. iconPath: '/static/images/common/map-marker.png',
  56. width: 30,
  57. height: 30,
  58. callout: {
  59. content: props.target.name,
  60. color: '#1f2937',
  61. fontSize: 12,
  62. borderRadius: 6,
  63. borderWidth: 1,
  64. borderColor: '#dbeafe',
  65. bgColor: '#ffffff',
  66. padding: 7,
  67. textAlign: 'center' as const,
  68. display: 'ALWAYS' as const,
  69. },
  70. },
  71. ]
  72. })
  73. const mapLatitude = computed(
  74. () => props.currentLocation?.latitude ?? props.target?.latitude ?? 22.543096
  75. )
  76. const mapLongitude = computed(
  77. () => props.currentLocation?.longitude ?? props.target?.longitude ?? 114.057865
  78. )
  79. </script>
  80. <style lang="scss" scoped>
  81. .visit-map-panel {
  82. position: relative;
  83. height: 480rpx;
  84. overflow: hidden;
  85. background: #dce8f3;
  86. }
  87. .visit-map-panel__map {
  88. width: 100%;
  89. height: 100%;
  90. }
  91. .visit-map-panel__locate {
  92. position: absolute;
  93. top: 28rpx;
  94. right: 28rpx;
  95. width: 66rpx;
  96. height: 66rpx;
  97. color: #2f8cf7;
  98. font-size: 44rpx;
  99. font-weight: 700;
  100. line-height: 66rpx;
  101. text-align: center;
  102. background: rgba(255, 255, 255, 0.96);
  103. border-radius: 20rpx;
  104. box-shadow: 0 10rpx 28rpx rgba(24, 39, 75, 0.14);
  105. }
  106. .visit-map-panel__add-card {
  107. position: absolute;
  108. right: 28rpx;
  109. bottom: 44rpx;
  110. left: 28rpx;
  111. display: flex;
  112. align-items: center;
  113. min-height: 80rpx;
  114. padding: 12rpx 14rpx 12rpx 22rpx;
  115. background: rgba(255, 255, 255, 0.97);
  116. border-radius: 20rpx;
  117. box-shadow: 0 16rpx 40rpx rgba(24, 39, 75, 0.16);
  118. box-sizing: border-box;
  119. }
  120. .visit-map-panel__add-title {
  121. flex: 1;
  122. min-width: 0;
  123. overflow: hidden;
  124. color: #1e293b;
  125. font-size: 24rpx;
  126. font-weight: 650;
  127. line-height: 34rpx;
  128. text-overflow: ellipsis;
  129. white-space: nowrap;
  130. }
  131. .visit-map-panel__add-action {
  132. flex-shrink: 0;
  133. height: 54rpx;
  134. margin-left: 14rpx;
  135. padding: 0 18rpx;
  136. color: #2f8cf7;
  137. font-size: 22rpx;
  138. font-weight: 650;
  139. line-height: 54rpx;
  140. background: #edf6ff;
  141. border-radius: 16rpx;
  142. }
  143. </style>