微信小程序获取当前地理信息之天气预报

项目描述

本文讲述从微信小程序代码编辑到个人开发者微信小程序发布大致过程,其中使用了微信官方接口wx.chooseLocation实现获取当前用户地理位置信息,下方小程序为实体效果,可扫描看下是否胃口,具体实现步骤请往下滑…天气预报

前期准备

项目主要功能为展现近24小时天气及展示7天天气预报信息,接口数据准备如下

1. 和风天气SDK

和风天气官网获取天气SDK,个人开发者注册后可免费使用1个SDK
和风天气控制台
因作者已创建项目,无法选择免费订阅,具体操作如下:选择免费订阅,选择Web API其他名称自行输入后创建,成功后查看KEY,这玩意等下代码内会用着
和风天气

2.微信小程序接口权限

微信小程序公众号获取地理信息接口权限
登录微信小程序公众号>>开发管理>>接口设置,如图微信小程序公众号
这里进行小程序接口权限申请,最好是申请黄色框内权限,但作者看了哈,个人开发者貌似比较麻烦更甚着无法申请,作者就未作纠结就申请了红色框内权限(申请时间大概花费两小时)
如果后来者只是想了解一下,不想将小程序提交为线上小程序情况可忽略此步骤

上代码

wxml代码

<view class="header-modular" wx:if="{{now}}">
	<image class="bg-wave" src="https://codermoyv.gitee.io/coder-moyv/assets/images/wechat/bg_wave.gif"></image>
	<view class="row">
		<view class="row location-wrap" bindtap="designatedSpot">
			<image class="icon" src="/images/icon_location.png"></image>
			<view class="title">{{City}} {{County}}</view>
		</view>

	</view>
	<view class="row">
		<view class="tmp">{{now.temp}}°</view>
		<image class="icon-weather" src="https://codermoyv.gitee.io/coder-moyv/assets/images/wechat/weather_custom/{{now.icon}}.png"></image>
	</view>
	<view class="tips-wrap">
		<view class="tips ">{{now.windDir}} {{now.windScale}}</view>
		<view class="tips ">湿度 {{now.humidity}}%</view>
		<view class="tips ">气压 {{now.pressure}}Pa</view>
	</view>
</view>

<view class="card-modular " wx:if="{{hourly}}">
	<view class="title">24小时预报</view>
	<view class="card-wrap">
		<block wx:for="{{hourly}}" wx:key="index">
			<view class="item hourly">
				<view class="text-gray">{{item.time}}</view>
				<image class="icon" src="https://codermoyv.gitee.io/coder-moyv/assets/images/wechat/weather_custom/{{item.icon}}.png"></image>
				<view class="text-primary mb-32">{{item.temp}}°</view>
				<view>{{item.windDir}}</view>
				<view class="text-gray">{{item.windScale}}</view>
			</view>
		</block>
	</view>
</view>

<view class="card-modular" wx:if="{{daily}}">
	<view class="title">7天预报</view>
	<view class="card-wrap">
		<block wx:for="{{daily}}" wx:key="index">
			<view class="item daily">
				<view>{{item.dateToString}}</view>
				<view class="text-gray">{{item.date}}</view>
				<image class="icon" src="https://codermoyv.gitee.io/coder-moyv/assets/images/wechat/weather_custom/{{item.iconDay}}.png"></image>
				<view class="text-primary ">{{item.tempMin}}°~{{item.tempMax}}°</view>
				<image class="icon" src="https://codermoyv.gitee.io/coder-moyv/assets/images/wechat/weather_custom/{{item.iconNight}}.png"></image>
				<view>{{item.windDirDay}}</view>
				<view class="text-gray">{{item.windScaleDay}}</view>
			</view>
		</block>
	</view>
</view>

js代码

需输入自己获取的KEY

//和天下 天气apikey
const APIKEY = "KEY";
Page({

    /**
     * 页面的初始数据
     */
    data: {

    },

    /**
     * 生命周期函数--监听页面加载
     */
    onLoad: function (options) {
        this.getLocation()
    },
    designatedSpot() {
        var that = this
        wx.chooseLocation({
            success(res) {
                that.setData({
                    location: res.longitude + "," + res.latitude
                })
                that.getWeather()
                that.getCityByLoaction()
            },
            fail() {
                wx.chooseLocation({
                    type: 'gcj02',
                    fail() {
                        wx.showModal({
                            title: '获取地图位置失败',
                            content: '为了给您提供准确的天气预报服务,请在设置中授权【位置信息】',
                            success(mRes) {
                                if (mRes.confirm) {
                                    wx.openSetting({
                                        success: function (data) {
                                            if (data.authSetting["scope.userLocation"] === true) {
                                                that.designatedSpot()
                                            } else {
                                                wx.showToast({
                                                    title: '授权失败',
                                                    icon: 'none',
                                                    duration: 1000
                                                })
                                            }
                                        },
                                        fail(err) {
                                            console.log(err)
                                            wx.showToast({
                                                title: '唤起设置页失败,请手动打开',
                                                icon: 'none',
                                                duration: 1000
                                            })
                                        }
                                    })
                                }
                            }
                        })
                    }
                })

            }
        })
    },

    getLocation() {
        var that = this
        wx.chooseLocation({
            type: 'gcj02',
            success(res) {
                that.setData({
                    location: res.longitude + "," + res.latitude
                })
                that.getWeather()
                that.getCityByLoaction()
            },
            fail(err) {
                wx.showModal({
                    title: '获取定位信息失败',
                    content: '为了给您提供准确的天气预报服务,请在设置中授权【位置信息】',
                    success(mRes) {
                        if (mRes.confirm) {
                            wx.openSetting({
                                success: function (data) {
                                    if (data.authSetting["scope.userLocation"] === true) {
                                        wx.showToast({
                                            title: '授权成功',
                                            icon: 'success',
                                            duration: 1000
                                        })
                                        that.getLocation()
                                    } else {
                                        wx.showToast({
                                            title: '授权失败',
                                            icon: 'none',
                                            duration: 1000
                                        })
                                        that.setData({
                                            location: "116.41,39.92"
                                        })
                                        that.getWeather()
                                        that.getCityByLoaction()
                                    }
                                },
                                fail(err) {
                                    console.log(err)
                                    wx.showToast({
                                        title: '唤起设置页失败,请手动打开',
                                        icon: 'none',
                                        duration: 1000
                                    })
                                    that.setData({
                                        location: "116.41,39.92"
                                    })
                                    that.getWeather()
                                    that.getCityByLoaction()
                                }
                            })
                        } else if (mRes.cancel) {
                            that.setData({
                                location: "116.41,39.92"
                            })
                            that.getWeather()
                            that.getCityByLoaction()
                        }
                    }
                })
            }
        })
    },

    getCityByLoaction() {
        var that = this
        wx.request({
            url: 'https://geoapi.qweather.com/v2/city/lookup?key=' + APIKEY + "&location=" + that.data.location,
            success(result) {
                var res = result.data
                if (res.code == "200") {
                    var data = res.location[0]
                    that.setData({
                        City: data.adm2,
                        County: data.name
                    })
                } else {
                    wx.showToast({
                        title: '获取城市信息失败',
                        icon: 'none'
                    })
                }

            }
        })
    },

    getWeather() {
        var that = this
        wx.showLoading({
            title: '加载中',
        })
        wx.request({
            url: 'https://devapi.qweather.com/v7/weather/now?key=' + APIKEY + "&location=" + that.data.location,
            success(result) {
                var res = result.data
                that.setData({
                    now: res.now
                })
            }
        })
        wx.request({
            url: 'https://devapi.qweather.com/v7/weather/24h?key=' + APIKEY + "&location=" + that.data.location,
            success(result) {
                var res = result.data
                res.hourly.forEach(function (item) {
                    item.time = that.formatTime(new Date(item.fxTime)).hourly
                })
                that.setData({
                    hourly: res.hourly
                })
            }
        })
        wx.request({
            url: 'https://devapi.qweather.com/v7/weather/7d?key=' + APIKEY + "&location=" + that.data.location,
            success(result) {
                var res = result.data
                res.daily.forEach(function (item) {
                    item.date = that.formatTime(new Date(item.fxDate)).daily
                    item.dateToString = that.formatTime(new Date(item.fxDate)).dailyToString
                })
                that.setData({
                    daily: res.daily
                })
                wx.hideLoading()
            }
        })
    },
    formatTime(date) {
        const year = date.getFullYear()
        const month = date.getMonth() + 1
        const day = date.getDate()
        const hour = date.getHours()
        const minute = date.getMinutes()
        const second = date.getSeconds()
        const weekArray = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]
        const isToday = date.setHours(0, 0, 0, 0) == new Date().setHours(0, 0, 0, 0)
        return {
            hourly: [hour, minute].map(this.formatNumber).join(":"),
            daily: [month, day].map(this.formatNumber).join("-"),
            dailyToString: isToday ? "今天" : weekArray[date.getDay()]
        }
    },
    formatNumber(n) {
        n = n.toString()
        return n[1] ? n : '0' + n
    },
    /**
     * 生命周期函数--监听页面初次渲染完成
     */
    onReady: function () {

    },

    /**
     * 生命周期函数--监听页面显示
     */
    onShow: function () {

    },

    /**
     * 生命周期函数--监听页面隐藏
     */
    onHide: function () {

    },

    /**
     * 生命周期函数--监听页面卸载
     */
    onUnload: function () {

    },

    /**
     * 页面相关事件处理函数--监听用户下拉动作
     */
    onPullDownRefresh: function () {

    },

    /**
     * 页面上拉触底事件的处理函数
     */
    onReachBottom: function () {

    },

    /**
     * 用户点击右上角分享
     */
    onShareAppMessage: function () {

    }
})

wxss代码

page {
	background-color: linear-gradient(to bottom, #ffffff, #ffffff, #F6F6F6);
	padding-bottom: 60rpx;
}

.row {
	display: flex;
	align-items: center;
}

.mb-32 {
	margin-bottom: 32rpx;
}

.header-modular {
	height: 400rpx;
	background-color: #64C8FA;
	background: linear-gradient(to bottom, #56CCF2, #2F80ED);
	position: relative;
	padding: 30rpx;
}

.header-modular .bg-wave {
	width: 100vw;
	position: absolute;
	bottom: -2px;
	left: 0;
	right: 0;
	height: 120rpx;
	mix-blend-mode: screen;
}

.header-modular .location-wrap {
	color: #ffffff;
	font-weight: bold;
	font-size: 36rpx;
}

.header-modular .location-wrap .icon {
	width: 40rpx;
	height: 40rpx;
	margin-right: 8rpx;
}

.header-modular .tmp {
	font-size: 200rpx;
	color: #ffffff;
	margin-right: auto;
}

.header-modular .icon-weather {
	width: 200rpx;
	height: 200rpx;
}

.header-modular .tips-wrap {
	display: flex;
	justify-content: space-between;
}

.header-modular .tips {
	font-size: 28rpx;
	opacity: 0.8;
	color: #ffffff;
	flex: 1;
}

.header-modular .tips:nth-child(3) {
	text-align: right;
}

.header-modular .tips:nth-child(2) {
	text-align: center;
}

.card-modular {
	padding: 0 30rpx;
	margin-top: 30rpx;
}

.card-modular>.title {
	font-size: 40rpx;
	font-weight: bold;
	position: relative;
	margin-left: 14rpx;
	margin-bottom: 16rpx;
}

.card-modular>.title::before {
	content: "";
	position: absolute;
	left: -14rpx;
	top: 10rpx;
	bottom: 10rpx;
	width: 8rpx;
	border-radius: 10rpx;
	background-color: #2F80ED;
}

.card-modular .card-wrap {
	width: 690rpx;
	border-radius: 18rpx;
	background-color: #ffffff;
	box-shadow: 0 0 20rpx 0 rgba(0, 0, 0, 0.2);
	overflow-x: auto;
	white-space: nowrap;
}

.card-modular .card-wrap .item {
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	font-size: 28rpx;
	padding: 18rpx 0;
}

.card-modular .card-wrap .item.hourly {
	width: 138rpx;
}

.card-modular .card-wrap .item.daily {
	width: 172.5rpx;
}

.card-modular .card-wrap .item .icon {
	width: 60rpx;
	height: 60rpx;
	margin: 64rpx 0;
}

.card-modular .card-wrap .item .text-gray {
	color: gray;
}

.card-modular .card-wrap .item .text-primary {
	color: #2F80ED;
}

app.json代码

小程序之前进行了更新,使用定位需在app.json文件内添加如下代码,如小程序不需要上线可忽略

{
	"permission": {
	        "scope.userLocation": {
	            "desc": "小程序需要使用您的位置信息 已确认您的采样地址"
	        }
	    },
	    "requiredPrivateInfos": [
	        "chooseLocation"
	    ]
}

如小程序不需要显示底部导航栏,则在app.json内删除键值对“tabBar”信息即可

小程序上线

代码提交审核

首先进入微信小程序公众号>>版本管理,此时在开发者工具内上次的版本会出现在开发版本内,此时点击提交审核进入审核步骤,如存在微信小程序接口权限未申请、app.json对应接口信息未添加情况将直接申请不通过。

等待代码审核通过(作者忘记了具体时间,只记得下午16点左右提交了审核,23点突然想起,进入发现已审核过)
微信小程序发布

小程序发布

代码审核后可直接提交为线上版本(此过程大概20分钟),但因上线问题需要填写小程序一些用途、协议等,如实填写即可

结尾

溜了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值