index.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <template>
  2. <view class="content">
  3. <map style="width: 100%; height: 400px;"
  4. id="wash_map"
  5. :latitude="state.latitude"
  6. :longitude="state.longitude"
  7. :markers="state.covers"
  8. min-scale="1"
  9. :scale="12"
  10. :show-compass="false"
  11. @regionchange="handleMapRegionChange"
  12. @updated="handleMapUpdated"
  13. @labeltap="handleMapTapMarker"
  14. @markertap="handleMapTapMarker">
  15. <view class="content_reset-btn" @click="resetLocation">
  16. <uv-icon name="empty-address" size="28" color="#000" icon="/static/map-re-location.png"></uv-icon>
  17. </view>
  18. </map>
  19. <view class="w100 content_search mt10">
  20. <uv-search :showAction="true" actionText="搜索" placeholder="请输入站点名称搜索" :animation="true" @search="handleSearchStation"></uv-search>
  21. </view>
  22. <!-- 站点清单 start-->
  23. <view class="w100 content_station">
  24. <view class="station_item" v-for="item in state.stationList" :key="item.id">
  25. <view class="station_item-title">
  26. <text class="font13">{{ item.name }}</text>
  27. </view>
  28. <view class="station_item-status">
  29. <text class="station_item-status-text">营业中</text>
  30. </view>
  31. <view class="station_item-content">
  32. <view class="station_item-content-left">
  33. <view class="station_item-content-left-label">
  34. <view class="font12 station_item-content-left-label-left">
  35. <text class="station_item-content-left-label-left_idle">空闲</text>
  36. <text class="station_item-content-left-label-left_count">{{ item.idle }}/{{ item.total }}</text>
  37. </view>
  38. <!-- <uv-tags size="small" class="station_item-content-left-label_tag" text="洗车机" plain shape="circle"></uv-tags>-->
  39. <view class="station_item-content-left-label_func">{{ item.funs?.join(" | ") }}</view>
  40. </view>
  41. <view class="station_item-content-left-position">
  42. <uv-icon name="empty-address" size="20" color="#aaa"></uv-icon>
  43. <text>{{ item.address }}</text>
  44. </view>
  45. </view>
  46. <view class="station_item-content-right">
  47. <uv-button circle type="primary" size="mini" plain @click="handleNavStation(item)">去洗车</uv-button>
  48. </view>
  49. </view>
  50. <view class="station_item-distance">
  51. <uv-text type="primary" :text="item.tips" size="12"></uv-text>
  52. </view>
  53. </view>
  54. </view>
  55. <!-- 站点清单 end-->
  56. </view>
  57. </template>
  58. <script setup lang="ts">
  59. import {reactive, ref} from 'vue'
  60. import {onHide, onShow} from "@dcloudio/uni-app";
  61. const mapCtx = ref(); // 地图上下文
  62. const initState = () => ({
  63. latitude: 23.098994,
  64. longitude: 113.32252,
  65. covers: [] as any[],
  66. markers: [] as any[],
  67. isIgnoreChangeLocation: false,
  68. loading: false,
  69. stationList: [
  70. {
  71. id: 1,
  72. name: '河源路洗车场',
  73. status: 1,
  74. total: 7,
  75. idle: 2,
  76. funs: ['清洁', '泡沫', '吸尘', '消毒', '充电'],
  77. address: '深圳市宝安区河源路12345号',
  78. tips: '半小时内免停车费,超时领取停车券免费',
  79. },
  80. {
  81. id: 1,
  82. name: '河源路洗车场2222',
  83. status: 1,
  84. total: 17,
  85. idle: 2,
  86. funs: ['清洁', '泡沫', '吸尘', '消毒', '充电'],
  87. address: '深圳市宝安区河源路12345号',
  88. tips: '半小时内免停车费,超时领取停车券免费',
  89. }
  90. ] as any[]
  91. })
  92. const state = reactive(initState())
  93. onShow(() => {
  94. let gd = getApp<any>().globalData;
  95. if (!gd.token) {
  96. console.error(gd)
  97. return;
  98. }
  99. mapCtx.value = uni.createMapContext("wash_map");
  100. // refreshCouponList();
  101. });
  102. onHide(() => {
  103. Object.assign(state, initState());
  104. })
  105. const handleMapRegionChange = (e: any) => {
  106. if (state.isIgnoreChangeLocation) {
  107. return;
  108. }
  109. if (e.type === "end" && state.markers.length) {
  110. // console.log("map change end", {
  111. // ...e.detail.centerLocation,
  112. // });
  113. const current = e.target.centerLocation;
  114. const {latitude, longitude} = current;
  115. relocation(longitude, latitude);
  116. // stationPage.value.page = 1;
  117. // refreshStation({
  118. // latitude,
  119. // longitude,
  120. // });
  121. }
  122. }
  123. const relocation = (longitude: number, latitude: number) => {
  124. mapCtx.value?.moveToLocation({
  125. latitude,
  126. longitude,
  127. });
  128. }
  129. //重置地图定位
  130. const resetLocation = () => {
  131. // if (state.loading) {
  132. // return;
  133. // }
  134. console.log("reset location")
  135. uni.getLocation({
  136. type: 'gcj02', //返回可以用于uni.openLocation的经纬度
  137. success: res=>{
  138. const latitude = res.latitude;
  139. const longitude = res.longitude;
  140. console.log("reset location",res)
  141. uni.openLocation({
  142. latitude: latitude,
  143. longitude: longitude,
  144. success: function () {
  145. console.log('success');
  146. }
  147. });
  148. }
  149. });
  150. // eslint-disable-next-line promise/catch-or-return
  151. // fetchLocation().then((res: any) => {
  152. // const { latitude, longitude } = res;
  153. // mapCtx.value?.moveToLocation({
  154. // latitude,
  155. // longitude,
  156. // });
  157. // });
  158. };
  159. const handleMapUpdated = (e: any) => {
  160. setTimeout(() => {
  161. state.isIgnoreChangeLocation = false;
  162. }, 500);
  163. }
  164. const handleMapTapMarker = (e: any) => {
  165. if (e.detail.markerId === -1) {
  166. return;
  167. }
  168. let chooseMarker = state.stationList.find((k: any) => k.id == e.detail.markerId);
  169. if (chooseMarker) {
  170. // _changeMarker(findIndex);
  171. }
  172. }
  173. const handleSearchStation = (e: any) => {
  174. console.log("search>>>", e)
  175. // const { value } = e.detail;
  176. // if (!value) {
  177. // return;
  178. // }
  179. }
  180. const handleNavStation = (station: any) => {
  181. }
  182. </script>
  183. <style lang="scss" scoped>
  184. .content {
  185. width: 100%;
  186. //background: #efeffe;
  187. &_reset-btn {
  188. position: absolute;
  189. right: 10rpx;
  190. bottom: 10rpx;
  191. }
  192. &_search {
  193. }
  194. &_station {
  195. height: calc(100vh - 480px);
  196. }
  197. }
  198. .station_item {
  199. display: flex;
  200. flex-direction: column;
  201. border-radius: 10rpx;
  202. margin-top: 20rpx;
  203. padding: 15rpx;
  204. background: #fafafa;
  205. position: relative;
  206. &-title {
  207. display: inline-flex;
  208. padding-left: 5px;
  209. }
  210. &-status {
  211. position: absolute;
  212. right: 0;
  213. top: 0;
  214. &-text {
  215. background: $uni-color-primary;
  216. padding: 6rpx;
  217. color: white;
  218. font-size: 12px;
  219. }
  220. }
  221. &-content {
  222. display: flex;
  223. justify-content: space-between;
  224. width: 100%;
  225. &-left {
  226. flex: 1;
  227. display: flex;
  228. flex-direction: column;
  229. padding: 5rpx;
  230. &-label {
  231. padding: 4rpx 8rpx;
  232. display: inline-flex;
  233. margin-top: 8rpx;
  234. //justify-content: space-between;
  235. &-left {
  236. //border: 1px solid $uni-color-primary;
  237. border-radius: 4rpx;
  238. &_idle {
  239. background: $uni-color-primary;
  240. padding: 6rpx;
  241. color: white;
  242. border-radius: 4rpx;
  243. }
  244. &_count {
  245. //border-radius: 4rpx;
  246. margin-left: 10px;
  247. color: $uni-color-primary;
  248. font-size: 13px;
  249. }
  250. &_tag {
  251. width: 30rpx;
  252. }
  253. }
  254. &_func {
  255. padding-left: 50rpx;
  256. font-size: 24rpx;
  257. color: #aaa;
  258. }
  259. }
  260. &-position {
  261. display: inline-flex;
  262. font-size: 24rpx;
  263. margin-top: 8rpx;
  264. }
  265. }
  266. &-right {
  267. width: 120rpx;
  268. display: flex;
  269. flex-direction: column;
  270. justify-content: center;
  271. align-content: center;
  272. }
  273. }
  274. &-distance {
  275. font-size: 24rpx;
  276. padding-left: 5px;
  277. margin-top: 8rpx;
  278. }
  279. }
  280. </style>