zoukankan      html  css  js  c++  java
  • 小程序通过腾讯地图选择收货地址

    小程序可通过小程序插件或基础地图来实现收货地址的选择
    <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;
        130rpx;
    }
    
    .map-page .search .city-name{
         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{
        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;
         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;
    }
    
  • 相关阅读:
    Java 重写(Override)与重载(Overload)
    Java 继承
    Java 异常处理
    Java Scanner 类
    Java 流(Stream)、文件(File)和IO
    Java 方法
    Java 正则表达式
    Beta冲刺——代码规范、冲刺任务与计划
    Beta冲刺——凡事预则立
    Beta冲刺——问题总结博客(事后诸葛亮和组员交换事宜)
  • 原文地址:https://www.cnblogs.com/Grani/p/14742003.html
Copyright © 2011-2022 走看看