2025-05-22 16:24:05 +08:00

341 lines
7.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>