341 lines
7.9 KiB
Vue
Raw Normal View History

2024-12-09 14:16:57 +08:00
<template>
<view class="weather-wrap" :style="[weatherBg(nowData.code)]" @click="handleLocation">
<view class="content-wrap">
<view class="temp-wrap">
<view class="img-wrap">
<u--image :showLoading="true" :src="`/static/weather/${nowData.code}.svg`" width="130rpx"
height="130rpx"></u--image>
</view>
<view class="num-wrap">
<view v-if="nowData.temperature" style="margin-left: 30rpx; font-size: 64rpx;">
{{nowData.temperature}}
</view>
<view v-else class="null-data" style="margin-left: 30rpx;"></view>
</view>
</view>
<view class="city">
<text v-if="nowData.city">{{nowData.city}}</text>
<view v-else class="null-loc-wrap">
<view>未知位置</view>
<view class="loc">点击屏幕重新定位</view>
</view>
</view>
</view>
<view class="bottom-wrap">
<view class="item-wrap" v-for="(item,index) in nextData" :key="index">
<view class="i-top-wrap">
<text>{{item.date_text}}</text>
<text style="margin-left: 30rpx;">{{item.date}}</text>
</view>
<view class="i-bot-wrap">
<image :src="'/static/weather/'+item.code_day+'.svg'" 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" style="margin-left: 30rpx;"></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: ""
},
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(235deg, #FFF1E3 0%, #F3F7FF 45%, #DDE4FB 100%)'
}
}
if (icon >= 2 && icon <= 12) {
return {
background: 'linear-gradient(235deg, #ECF4FF 0%, #E0EBFB 46%, #CBD6E5 100%)'
}
}
if (icon >= 13 && icon <= 17) {
return {
background: 'linear-gradient(229deg, rgba(225,243,251,0.99) 0%, #DCF5FE 43%, #DBF0F1 100%)'
}
}
if (icon >= 18 && icon <= 20) {
return {
background: 'linear-gradient(235deg, #D1C3B4 0%, #E1D9D3 38%, #EEEAE7 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 };
} 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);
} 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;
.num-wrap {
display: flex;
flex-direction: row;
}
.img-wrap {
display: flex;
align-items: center;
}
}
.city {
padding: 20rpx;
font-size: 36rpx;
.null-loc-wrap {
font-size: 32rpx;
text-align: center;
.loc {
margin-top: 6rpx;
font-size: 24rpx;
color: #888;
}
}
}
}
.bottom-wrap {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10rpx 20rpx 20rpx;
font-size: 28rpx;
.item-wrap {
display: flex;
flex-direction: column;
.i-top-wrap {
display: flex;
flex-direction: row;
align-items: center;
}
.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;
}
}
</style>