小程序通過騰訊地圖選擇收貨地址


小程序可通過小程序插件或基礎地圖來實現收貨地址的選擇
<a href=” https://lbs.qq.com/miniProgram/plugin/pluginGuide/locationPicker” target=”_blank”>騰訊位置服務-地圖選點插件
插件開箱即用方便快捷,但好像商用要付費

看了下百果園和每日優鮮的地圖,樣子並不像使用插件,猜測是使用基礎地圖+騰訊地圖API實現的選點,於是自己動手試了下


圖一分搜索、基礎地圖、周邊推薦列表三部分,用到
騰訊位置服務關鍵詞輸入提示、逆地址解析和地點搜索-周邊推薦三個接口
<a href=” https://lbs.qq.com/service/webService/webServiceGuide/webServiceSuggestion” target=”_blank”>騰訊位置服務- WebService API

首次進入頁面通過wx.getLocation獲取手機當前地理位置通過逆地址解析得到當前所在省,地圖視野變化會觸發regionchange,在切換城市或regionchange時請求周邊推薦得到地圖下方的地點列表
<a href=” https://developers.weixin.qq.com/miniprogram/dev/component/map.html” target=”_blank”>微信官方文檔小程序-組件-地圖

城市選擇需要用到城市選擇器插件
<a href=” https://lbs.qq.com/miniProgram/plugin/pluginGuide/citySelector” target=”_blank”>騰訊位置服務- 城市選擇器插件

改善:
地點搜索加了防抖,原本是小程序直接請求的騰訊地圖接口,但發現要配域名白名單或授權IP,所以改為后台請求接口再將數據返回

JS

// pages/address-map/address-map.js
import {tencentMapKey} from '../../utils/config'
import {mapGeoCoder, mapSuggestion, mapExplore} from '../../utils/api'

const citySelector = requirePlugin('citySelector')

Page({

    /**
     * 頁面的初始數據
     */
    data: {
        cityName: '',
        longitude: '',
        latitude: '',
        city: '',           // 頂部搜索欄左邊的城市
        searchText: '',     // 搜索欄內容
        searchValid: true,  // 搜索欄節流
        searchDelay: 800,
        selectLocation: '',  // 選擇的地址
        mapCtx: '',
        mapSetting: {
            skew: 0,
            rotate: 0,
            showLocation: true,
            showScale: false,  // 比例尺
            subKey: '',
            layerStyle: 1,
            enableZoom: true,
            enableScroll: true,
            enableRotate: false,
            showCompass: true, // 指南針
            enable3D: false,
            enableOverlooking: false,
            enableSatellite: false,
            enableTraffic: false,
        },
        searchResult: [],  // 搜索結果
        exploreList: []   // 周邊熱點地址
    },

    removeSearch() {
        this.setData({
            searchText: '',
            searchResult: []
        })
    },

    searchInput(e) {
        this.setData({
            searchText: e.detail.value
        })

        if (!this.data.searchValid) return

        this.setData({searchValid: false})
        setTimeout(() => {
            this.mapSuggestion()
            this.setData({searchValid: true})
        }, this.data.searchDelay)
    },

    mapRegionChange(e) {

        if (e.type !== 'end') return

        this.data.mapCtx.getCenterLocation({
            success: res => {
                this.mapSearchExplore(res.longitude, res.latitude, 1000)
            }
        })
    },

    selectCity() {
        const referer = '湘土優選'  // 調用插件的app的名稱
        const hotCitys = ''        // 用戶自定義的的熱門城市

        wx.navigateTo({
            url: `plugin://citySelector/index?key=${tencentMapKey}&referer=${referer}&hotCitys=${hotCitys}`,
        })
    },

    clickAddress(e) {
        let address = e.currentTarget.dataset.address
        let param = {
            province: address.province,
            city: address.city,
            district: address.district,
            address: address.title,
        }
        wx.setStorageSync('mapAddress', param)
        wx.navigateBack({
            delta: 1
        })
    },

    // 騰訊地圖-周邊搜索
    mapSearchExplore(longitude, latitude, radius) {
        let param = {
            longitude,
            latitude,
            radius,
        }

        mapExplore(param).then(res => {
            this.setData({
                exploreList: res.data || []
            })
        })
    },

    // 搜索關鍵詞提示
    mapSuggestion() {
        let param = {
            keyword: this.data.searchText,
            region: this.data.cityName
        }

        mapSuggestion(param).then(res => {
            this.setData({
                searchResult: res.data || []
            })
        })
    },

    // 根據坐標獲取地名
    mapGeoCoder(latitude, longitude) {
        let param = {
            longitude: longitude,
            latitude: latitude
        }

        mapGeoCoder(param).then(res => {
            this.setData({
                cityName: res.data.city
            })
        })
    },

    /**
     * 生命周期函數--監聽頁面加載
     */
    onLoad: function (options) {
    },

    /**
     * 生命周期函數--監聽頁面初次渲染完成
     */
    onReady: function () {
        this.setData({
            mapCtx: wx.createMapContext('curMap')
        })
    },

    /**
     * 生命周期函數--監聽頁面顯示
     */
    onShow: function () {

        // 從城市選擇器插件返回后,在頁面的onShow生命周期函數中能夠調用插件接口,獲取cityInfo結果對象
        // 結果為null表示不是從選擇器插件返回,所以直接獲取當前地理位置來顯示城市名
        const selectedCity = citySelector.getCity()

        if (selectedCity) {
            let location = selectedCity.location

            this.mapSearchExplore(location.longitude, location.latitude, 1000)
            this.setData({
                cityName: selectedCity.fullname,
                longitude: location.longitude,
                latitude: location.latitude,
            })
        } else {
            wx.getLocation({
                type: 'gcj02',
                altitude: true,
                success: res => {
                    this.setData({
                        longitude: res.longitude,
                        latitude: res.latitude,
                    })
                    this.mapSearchExplore(res.longitude, res.latitude, 1000)
                    this.mapGeoCoder(res.latitude, res.longitude)
                },
                fail: function () {
                    wx.hideLoading()
                    console.log("getLocationFail")
                },
                complete: function () {
                    wx.hideLoading() // 隱藏定位中信息進度
                }
            })
        }
    },

    /**
     * 生命周期函數--監聽頁面隱藏
     */
    onHide: function () {

    },

    /**
     * 生命周期函數--監聽頁面卸載
     */
    onUnload: function () {

        // 頁面卸載時清空插件數據,防止再次進入頁面,getCity返回的是上次的結果
        citySelector.clearCity()
    },

    /**
     * 頁面相關事件處理函數--監聽用戶下拉動作
     */
    onPullDownRefresh: function () {

    },

    /**
     * 頁面上拉觸底事件的處理函數
     */
    onReachBottom: function () {

    },

    /**
     * 用戶點擊右上角分享
     */
    onShareAppMessage: function () {

    }
})

WXML

<!--pages/address-map/address-map.wxml-->
<view class="map-page">
    <view class="top-container">
        <view class="search">
            <view class="city" bindtap="selectCity">
                <view class="city-name ellipsis">{{ cityName }}</view>
                <icon class="iconfont icon-xiajiantoushixinxiao"></icon>
            </view>
            <view class="text">
                <input type="text" value="{{searchText}}" bindinput="searchInput" placeholder="請輸入您的收貨地址"/>
                <icon class="iconfont icon-guanbi close-btn" bindtap="removeSearch"></icon>
            </view>
        </view>
        <view class="explore-container {{ searchResult.length > 0 ? 'search-result' :'' }}">
            <view class="item" wx:for="{{ searchResult }}" data-address="{{item}}" bindtap="clickAddress">
                <view class="name">{{ item.title }}</view>
                <view class="address">{{ item.address }}</view>
            </view>
        </view>
    </view>

    <view class="map-container">
        <map id="curMap"
             longitude="{{longitude}}"
             latitude="{{latitude}}"
             setting="{{ mapSetting }}"
             bindregionchange="mapRegionChange"></map>
    </view>
    <view class="explore-container">
        <view class="item" wx:for="{{ exploreList }}" data-address="{{item}}" bindtap="clickAddress">
            <view class="name">{{ item.title }}</view>
            <view class="address">{{ item.address }}</view>
        </view>
    </view>
</view>

WXSS

/* pages/address-map/address-map.wxss */
.map-page{
    padding:90rpx 0 0;
}

.map-page .search {
    border: 1px solid #d0d4ce;
    background-color: #d3fcbb;
    border-radius: 50rpx;
    padding: 8rpx 20rpx 8rpx 165rpx;
    margin: 10rpx 15rpx 10rpx;
    position:relative;
}

.map-page .top-container{
    background-color:#fff;
    position: fixed;
    top:0;
    left:0;
    right:0;
    z-index:100;
}

.map-page .search .city{
    position: absolute;
    top:8rpx;
    left:22rpx;
    width:130rpx;
}

.map-page .search .city-name{
    width: 120rpx;
    padding-right: 15rpx;
    box-sizing: border-box;
    border-right: 1px solid #ccc;
}

.map-page .search .city icon{
    position: absolute;
    right:12rpx;
    top:-12rpx;
}

.map-page .search .text{
    padding-right:40rpx;
}

.map-page .search .text icon{
    position: absolute;
    right: 20rpx;
    top: -5rpx;
    font-size: 28rpx;
}

.map-page .map-container {
    height: 520rpx;
}

.map-page .map-container map{
    width:100%;
    height:100%;
}

.explore-container .item{
    position: relative;
    padding: 25rpx 30rpx 25rpx 80rpx;
    border-bottom: 1px solid #eee;
}

.explore-container .item::before{
    content: "";
    position: absolute;
    top: 38rpx;
    left: 30rpx;
    width: 10rpx;
    height: 10rpx;
    border-radius: 100%;
    border: 8rpx solid #d3fcbb;
}

.explore-container .item .name{
    font-size:30rpx;
    font-weight: 700;
}

.explore-container .item .address{
    font-size:26rpx;
}

.map-page .search-result{
    position: fixed;
    top: 75rpx;
    left: 0;
    right: 0;
    bottom: 0;
    overflow-y: auto;
    background-color: #fff;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM