415 lines
9.6 KiB
Vue
415 lines
9.6 KiB
Vue
|
<template>
|
|||
|
<view class="weather-wrap" :style="[weatherBg(nowData.code)]" @click="handleLocation">
|
|||
|
<view class="content-wrap">
|
|||
|
<view style="display: inline-block;">
|
|||
|
<view class="temp-wrap">
|
|||
|
<view class="num-wrap">
|
|||
|
<view v-if="nowData.temperature" class="temperature">
|
|||
|
{{nowData.temperature}}℃
|
|||
|
</view>
|
|||
|
<view v-if="nowData.temperature" class="text">
|
|||
|
/ {{nowData.text}}
|
|||
|
</view>
|
|||
|
<view v-else class="null-data"></view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="city-wrap">
|
|||
|
<view class="city" style="display: flex;margin-left: 0.5rem">
|
|||
|
<u-icon name="map" color="#606266" size="16"></u-icon>
|
|||
|
<text class="city-name" v-if="nowData.city">
|
|||
|
{{nowData.city}} {{$u.timeFormat(nowData.time, 'mm-dd hh:MM')}}</text>
|
|||
|
<view v-else class="null-loc-wrap">
|
|||
|
<view>{{$tt('home.location')}}</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="img-wrap">
|
|||
|
<image :src="`/static/weather/${nowData.code}@1x.png`" style="width: 176rpx; height: 176rpx;"
|
|||
|
mode="aspectFit"></image>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view style="border: 1px solid rgba(0,0,0,0.05);"></view>
|
|||
|
<view class="bottom-wrap">
|
|||
|
<view class="item-wrap" v-for="(item,index) in nextData" :key="index">
|
|||
|
<view class="i-top-wrap">
|
|||
|
<view v-if="index===0" class="point">
|
|||
|
</view>
|
|||
|
<text>{{item.date_text}}</text>
|
|||
|
<text style="margin-left: 10rpx;">{{item.date}}</text>
|
|||
|
</view>
|
|||
|
<view class="i-bot-wrap">
|
|||
|
<image :src="'/static/weather/'+item.code_day+'@1x.png'" style="width: 50rpx; height: 50rpx;"
|
|||
|
mode="aspectFit"></image>
|
|||
|
<text v-if="item.high && item.low" style="margin-left: 30rpx;">{{item.high}}°/{{item.low}}°</text>
|
|||
|
<text v-else class="null-data"></text>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
|
|||
|
<script>
|
|||
|
Date.prototype.formatCode = function(formatStr = "yyyy-MM-DD HH:mm:ss") {
|
|||
|
const paddingZero = num => num >= 10 ? num : '0' + num;
|
|||
|
let str = formatStr;
|
|||
|
str = str.replace(/yyyy|YYYY/, this.getFullYear());
|
|||
|
str = str.replace(/MM/, paddingZero(this.getMonth() + 1));
|
|||
|
str = str.replace(/dd|DD/, paddingZero(this.getDate()));
|
|||
|
str = str.replace(/hh|HH/, paddingZero(this.getHours()));
|
|||
|
str = str.replace(/mm/, paddingZero(this.getMinutes()));
|
|||
|
str = str.replace(/ss/, paddingZero(this.getSeconds()));
|
|||
|
str = str.replace(/SS/, paddingZero(this.getMilliseconds()));
|
|||
|
return str;
|
|||
|
};
|
|||
|
|
|||
|
import projectConfig from '@/env.config.js';
|
|||
|
import QQMapWX from "@/common/qqmap-wx-jssdk.min.js";
|
|||
|
|
|||
|
export default {
|
|||
|
name: 'weather',
|
|||
|
data() {
|
|||
|
return {
|
|||
|
// 天气数据
|
|||
|
nowData: {
|
|||
|
code: "10",
|
|||
|
temperature: "",
|
|||
|
text: "阵雨",
|
|||
|
city: "",
|
|||
|
time: ""
|
|||
|
},
|
|||
|
nextData: [{
|
|||
|
date_text: '今天',
|
|||
|
code_day: "10",
|
|||
|
date: "08/14",
|
|||
|
high: "",
|
|||
|
low: "",
|
|||
|
}, {
|
|||
|
date_text: '明天',
|
|||
|
code_day: "4",
|
|||
|
date: "08/15",
|
|||
|
high: "",
|
|||
|
low: "",
|
|||
|
}, {
|
|||
|
date_text: '后天',
|
|||
|
code_day: "4",
|
|||
|
date: "08/16",
|
|||
|
high: "",
|
|||
|
low: "",
|
|||
|
}]
|
|||
|
}
|
|||
|
},
|
|||
|
created() {
|
|||
|
// 由于权限问题,app 平台除外,其他平台自动定位
|
|||
|
// #ifndef APP-PLUS
|
|||
|
this.initData();
|
|||
|
// #endif
|
|||
|
|
|||
|
// #ifdef APP-PLUS
|
|||
|
const location = uni.getStorageSync('location');
|
|||
|
if (location) {
|
|||
|
this.initData();
|
|||
|
}
|
|||
|
// #endif
|
|||
|
},
|
|||
|
computed: {
|
|||
|
weatherBg() {
|
|||
|
return icon => {
|
|||
|
if (icon >= '0' && icon <= '1') {
|
|||
|
return {
|
|||
|
background: 'linear-gradient( 50deg, #F8F9F3 0%, #FDD563 100%)'
|
|||
|
}
|
|||
|
}
|
|||
|
if (icon >= '2' && icon <= '12') {
|
|||
|
return {
|
|||
|
background: 'linear-gradient( 50deg, #E5F5FF 0%, #B1CEFE 100%)'
|
|||
|
}
|
|||
|
}
|
|||
|
if (icon >= '13' && icon <= '17') {
|
|||
|
return {
|
|||
|
background: 'linear-gradient( 50deg, #F1E7FD 0%, #9EABFF 100%)'
|
|||
|
}
|
|||
|
}
|
|||
|
if (icon >= '18' && icon <= '20') {
|
|||
|
return {
|
|||
|
background: 'linear-gradient( 50deg, #EEF0F2 0%, #E9EBF2 100%)'
|
|||
|
}
|
|||
|
}
|
|||
|
if (icon >= '21' && icon <= '30') {
|
|||
|
return {
|
|||
|
background: 'linear-gradient( 50deg, #E9EBF2 0%, #BCC4E0 100%)'
|
|||
|
}
|
|||
|
}
|
|||
|
if (icon >= '32' && icon <= '34') {
|
|||
|
return {
|
|||
|
background: 'linear-gradient( 50deg, #F8EEE4 0%, #F1D4B0 100%)'
|
|||
|
}
|
|||
|
}
|
|||
|
return {
|
|||
|
background: 'linear-gradient(235deg, #EEF5FF 0%, #D6DDEE 100%)'
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
},
|
|||
|
methods: {
|
|||
|
initData() {
|
|||
|
this.getLocation();
|
|||
|
},
|
|||
|
format(index) {
|
|||
|
var b = "";
|
|||
|
switch (index) {
|
|||
|
case 0:
|
|||
|
b = "星期日";
|
|||
|
break;
|
|||
|
case 1:
|
|||
|
b = "星期一";
|
|||
|
break;
|
|||
|
case 2:
|
|||
|
b = "星期二";
|
|||
|
break;
|
|||
|
case 3:
|
|||
|
b = "星期三";
|
|||
|
break;
|
|||
|
case 4:
|
|||
|
b = "星期四";
|
|||
|
break;
|
|||
|
case 5:
|
|||
|
b = "星期五";
|
|||
|
break;
|
|||
|
default:
|
|||
|
b = "星期六";
|
|||
|
}
|
|||
|
return b;
|
|||
|
},
|
|||
|
// 获取定位查询天气
|
|||
|
getLocation() {
|
|||
|
console.log('获取定位');
|
|||
|
let _this = this;
|
|||
|
uni.getLocation({
|
|||
|
type: 'wgs84',
|
|||
|
success(res) {
|
|||
|
_this.getCurrWeather(res);
|
|||
|
_this.getNextWeather(res);
|
|||
|
},
|
|||
|
fail(e) {
|
|||
|
console.log(e);
|
|||
|
uni.showToast({
|
|||
|
title: '无法获取定位',
|
|||
|
icon: 'none'
|
|||
|
});
|
|||
|
}
|
|||
|
});
|
|||
|
},
|
|||
|
// 获取天气信息
|
|||
|
getCurrWeather(ad) {
|
|||
|
let _this = this;
|
|||
|
uni.request({
|
|||
|
url: 'https://api.seniverse.com/v3/weather/now.json',
|
|||
|
data: {
|
|||
|
key: projectConfig.xinzhiKey,
|
|||
|
location: `${ad.latitude}:${ad.longitude}`,
|
|||
|
},
|
|||
|
success(res) {
|
|||
|
const { statusCode, data } = res;
|
|||
|
uni.showToast({
|
|||
|
image: '/static/right.png',
|
|||
|
title: data.results[0].now,
|
|||
|
})
|
|||
|
if (statusCode === 200) {
|
|||
|
_this.nowData = {
|
|||
|
...data.results[0].now,
|
|||
|
city: data.results[0].location.name,
|
|||
|
time: data.results[0].last_update
|
|||
|
};
|
|||
|
console.log(data, _this.nowData, '_this.nowData');
|
|||
|
} else {
|
|||
|
console.log('获取当前天气信息失败!');
|
|||
|
}
|
|||
|
},
|
|||
|
fail(err) {
|
|||
|
console.log('获取当前天气信息失败!', err);
|
|||
|
}
|
|||
|
});
|
|||
|
},
|
|||
|
getNextWeather(ad) {
|
|||
|
let _this = this;
|
|||
|
uni.request({
|
|||
|
url: 'https://api.seniverse.com/v3/weather/daily.json',
|
|||
|
data: {
|
|||
|
key: projectConfig.xinzhiKey,
|
|||
|
location: `${ad.latitude}:${ad.longitude}`,
|
|||
|
},
|
|||
|
success(res) {
|
|||
|
const { statusCode, data } = res;
|
|||
|
if (statusCode === 200) {
|
|||
|
_this.nextData = _this.formNextData(data.results[0].daily);
|
|||
|
console.log(_this.nextData, '_this.nextData');
|
|||
|
} else {
|
|||
|
console.log('获取未来3天天气信息失败!');
|
|||
|
}
|
|||
|
},
|
|||
|
fail(err) {
|
|||
|
console.log('获取未来3天天气信息失败!', err);
|
|||
|
}
|
|||
|
});
|
|||
|
},
|
|||
|
formNextData(list) {
|
|||
|
return list.map((item, index) => ({
|
|||
|
...item,
|
|||
|
date: `${item.date.split('-')[1]}/${item.date.split('-')[2]}`,
|
|||
|
date_text: index === 0 ? '今天' : index === 1 ? '明天' : '后天',
|
|||
|
}))
|
|||
|
},
|
|||
|
// 点击界面获取定位
|
|||
|
async handleLocation() {
|
|||
|
// 权限问题,app 平台需要判断
|
|||
|
// #ifdef APP-PLUS
|
|||
|
const location = uni.getStorageSync('location');
|
|||
|
if (!location) {
|
|||
|
let result = await this.$store.dispatch("permission/requestPermissions", 'ACCESS_FINE_LOCATION');
|
|||
|
if (result !== 1) return;
|
|||
|
uni.setStorageSync('location', true);
|
|||
|
}
|
|||
|
// #endif
|
|||
|
// 其他平台直接获取定位
|
|||
|
this.getLocation();
|
|||
|
},
|
|||
|
}
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
<style lang="scss" scoped>
|
|||
|
.weather-wrap {
|
|||
|
position: relative;
|
|||
|
display: flex;
|
|||
|
flex-direction: column;
|
|||
|
justify-content: center;
|
|||
|
border-radius: 36rpx;
|
|||
|
padding: 20rpx;
|
|||
|
height: 100%;
|
|||
|
box-sizing: border-box;
|
|||
|
|
|||
|
.content-wrap {
|
|||
|
display: flex;
|
|||
|
flex-direction: row;
|
|||
|
align-items: center;
|
|||
|
justify-content: space-between;
|
|||
|
padding: 20rpx 20rpx 10rpx;
|
|||
|
|
|||
|
.temp-wrap {
|
|||
|
display: flex;
|
|||
|
flex-direction: row;
|
|||
|
align-items: center;
|
|||
|
justify-content: flex-start;
|
|||
|
padding: 10rpx 0;
|
|||
|
|
|||
|
.num-wrap {
|
|||
|
display: flex;
|
|||
|
flex-direction: row;
|
|||
|
height: 100rpx;
|
|||
|
|
|||
|
.temperature {
|
|||
|
margin: 0.56rem 0.5rem 0;
|
|||
|
font-size: 76rpx;
|
|||
|
}
|
|||
|
|
|||
|
.text {
|
|||
|
margin: 1.8rem 0.1rem 0;
|
|||
|
font-size: 34rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.img-wrap {
|
|||
|
display: flex;
|
|||
|
align-items: center;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
.city-wrap {
|
|||
|
display: flex;
|
|||
|
flex-direction: row;
|
|||
|
align-items: center;
|
|||
|
justify-content: space-between;
|
|||
|
padding: 20rpx 0rpx;
|
|||
|
|
|||
|
.city {
|
|||
|
font-size: 36rpx;
|
|||
|
|
|||
|
.city-name {
|
|||
|
margin-left: 0.3rem;
|
|||
|
font-weight: 400;
|
|||
|
font-size: 26rpx;
|
|||
|
color: #7E7F79;
|
|||
|
line-height: 28rpx;
|
|||
|
text-align: left;
|
|||
|
font-style: normal;
|
|||
|
text-transform: none;
|
|||
|
}
|
|||
|
|
|||
|
.null-loc-wrap {
|
|||
|
font-size: 28rpx;
|
|||
|
text-align: center;
|
|||
|
margin-left: 10rpx;
|
|||
|
|
|||
|
.loc {
|
|||
|
margin-top: 6rpx;
|
|||
|
font-size: 22rpx;
|
|||
|
color: #888;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.bottom-wrap {
|
|||
|
display: flex;
|
|||
|
justify-content: space-between;
|
|||
|
align-items: center;
|
|||
|
padding: 20rpx;
|
|||
|
font-size: 28rpx;
|
|||
|
|
|||
|
.item-wrap {
|
|||
|
display: flex;
|
|||
|
flex-direction: column;
|
|||
|
margin-top: 10rpx;
|
|||
|
background: rgba(255, 255, 255, 0.22);
|
|||
|
border: 1px solid rgba(255, 255, 255, 0.41);
|
|||
|
border-radius: 20rpx;
|
|||
|
padding: 10rpx;
|
|||
|
width: 28%;
|
|||
|
|
|||
|
.i-top-wrap {
|
|||
|
display: flex;
|
|||
|
flex-direction: row;
|
|||
|
align-items: center;
|
|||
|
|
|||
|
.point {
|
|||
|
width: 8rpx;
|
|||
|
height: 8rpx;
|
|||
|
background: #005EFF;
|
|||
|
margin-right: 10rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.i-bot-wrap {
|
|||
|
display: flex;
|
|||
|
flex-direction: row;
|
|||
|
align-items: center;
|
|||
|
margin-top: 10rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.null-data {
|
|||
|
border-bottom: 10rpx solid #000000;
|
|||
|
width: 60rpx;
|
|||
|
transform: scaleY(0.5);
|
|||
|
border-top-color: #000000;
|
|||
|
border-right-color: #000000;
|
|||
|
border-left-color: #000000;
|
|||
|
margin-left: 30rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
</style>
|