|
@@ -0,0 +1,174 @@
|
|
|
|
|
+package api
|
|
|
|
|
+
|
|
|
|
|
+import (
|
|
|
|
|
+ "context"
|
|
|
|
|
+ "errors"
|
|
|
|
|
+ "fmt"
|
|
|
|
|
+ "github.com/gogf/gf/v2/frame/g"
|
|
|
|
|
+ "strconv"
|
|
|
|
|
+ "time"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+const (
|
|
|
|
|
+ api = "https://api.seniverse.com/v3/weather/now.json?language=zh-Hans&unit=c&location="
|
|
|
|
|
+ dayApi = "https://api.seniverse.com/v3/weather/daily.json?language=zh-Hans&unit=c&start=-1&days=5&location="
|
|
|
|
|
+ airApi = "https://api.seniverse.com/v3/air/now.json?language=zh-Hans&scope=city&location="
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+// WeatherResp 天气
|
|
|
|
|
+type WeatherResp struct {
|
|
|
|
|
+ Results []struct {
|
|
|
|
|
+ Location struct {
|
|
|
|
|
+ Id string `json:"id"`
|
|
|
|
|
+ Name string `json:"name"`
|
|
|
|
|
+ Country string `json:"country"`
|
|
|
|
|
+ Path string `json:"path"`
|
|
|
|
|
+ Timezone string `json:"timezone"`
|
|
|
|
|
+ TimezoneOffset string `json:"timezone_offset"`
|
|
|
|
|
+ } `json:"location"`
|
|
|
|
|
+ Now struct {
|
|
|
|
|
+ Text string `json:"text"`
|
|
|
|
|
+ Code string `json:"code"`
|
|
|
|
|
+ Temperature string `json:"temperature"`
|
|
|
|
|
+ FeelsLike string `json:"feels_like"`
|
|
|
|
|
+ Pressure string `json:"pressure"`
|
|
|
|
|
+ Humidity string `json:"humidity"`
|
|
|
|
|
+ Visibility string `json:"visibility"`
|
|
|
|
|
+ WindDirection string `json:"wind_direction"`
|
|
|
|
|
+ WindDirectionDegree string `json:"wind_direction_degree"`
|
|
|
|
|
+ WindSpeed string `json:"wind_speed"`
|
|
|
|
|
+ WindScale string `json:"wind_scale"`
|
|
|
|
|
+ Clouds string `json:"clouds"`
|
|
|
|
|
+ DewPoint string `json:"dew_point"`
|
|
|
|
|
+ } `json:"now"`
|
|
|
|
|
+ LastUpdate time.Time `json:"last_update"`
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type XinZhiDayWeatherInfo struct {
|
|
|
|
|
+ Results []struct {
|
|
|
|
|
+ Location struct {
|
|
|
|
|
+ Id string `json:"id"`
|
|
|
|
|
+ Name string `json:"name"`
|
|
|
|
|
+ Country string `json:"country"`
|
|
|
|
|
+ Path string `json:"path"`
|
|
|
|
|
+ Timezone string `json:"timezone"`
|
|
|
|
|
+ TimezoneOffset string `json:"timezone_offset"`
|
|
|
|
|
+ } `json:"location"`
|
|
|
|
|
+ Daily []struct {
|
|
|
|
|
+ Date string `json:"date"`
|
|
|
|
|
+ TextDay string `json:"text_day"`
|
|
|
|
|
+ CodeDay string `json:"code_day"`
|
|
|
|
|
+ TextNight string `json:"text_night"`
|
|
|
|
|
+ CodeNight string `json:"code_night"`
|
|
|
|
|
+ High string `json:"high"`
|
|
|
|
|
+ Low string `json:"low"`
|
|
|
|
|
+ Rainfall string `json:"rainfall"`
|
|
|
|
|
+ Precip string `json:"precip"`
|
|
|
|
|
+ WindDirection string `json:"wind_direction"`
|
|
|
|
|
+ WindDirectionDegree string `json:"wind_direction_degree"`
|
|
|
|
|
+ WindSpeed string `json:"wind_speed"`
|
|
|
|
|
+ WindScale string `json:"wind_scale"`
|
|
|
|
|
+ Humidity string `json:"humidity"`
|
|
|
|
|
+ } `json:"daily"`
|
|
|
|
|
+ LastUpdate time.Time `json:"last_update"`
|
|
|
|
|
+ } `json:"results"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type AirInfo struct {
|
|
|
|
|
+ Results []struct {
|
|
|
|
|
+ Location struct {
|
|
|
|
|
+ Id string `json:"id"`
|
|
|
|
|
+ Name string `json:"name"`
|
|
|
|
|
+ Country string `json:"country"`
|
|
|
|
|
+ Path string `json:"path"`
|
|
|
|
|
+ Timezone string `json:"timezone"`
|
|
|
|
|
+ TimezoneOffset string `json:"timezone_offset"`
|
|
|
|
|
+ } `json:"location"`
|
|
|
|
|
+ Air struct {
|
|
|
|
|
+ City struct {
|
|
|
|
|
+ Aqi string `json:"aqi"` // 空气质量指数(AQI)是描述空气质量状况的定量指数
|
|
|
|
|
+ Pm25 string `json:"pm25"` // PM2.5颗粒物(粒径小于等于2.5μm)1小时平均值。单位:μg/m³
|
|
|
|
|
+ Pm10 string `json:"pm10"` // PM10颗粒物(粒径小于等于10μm)1小时平均值。单位:μg/m³
|
|
|
|
|
+ So2 string `json:"so2"` // 二氧化硫1小时平均值。单位:μg/m³
|
|
|
|
|
+ No2 string `json:"no2"` // 二氧化氮1小时平均值。单位:μg/m³
|
|
|
|
|
+ Co string `json:"co"` // 一氧化碳1小时平均值。单位:mg/m³
|
|
|
|
|
+ O3 string `json:"o3"` // 臭氧1小时平均值。单位:μg/m³
|
|
|
|
|
+ PrimaryPollutant string `json:"primary_pollutant"` // 首要污染物
|
|
|
|
|
+ Quality string `json:"quality"` // 空气质量类别,有“优、良、轻度污染、中度污染、重度污染、严重污染”6类
|
|
|
|
|
+ LastUpdate time.Time `json:"last_update"` // 数据发布时间
|
|
|
|
|
+ } `json:"city"`
|
|
|
|
|
+ } `json:"air"`
|
|
|
|
|
+ LastUpdate time.Time `json:"last_update"`
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type WeatherInfoResp struct {
|
|
|
|
|
+ Location string `json:"location"`
|
|
|
|
|
+ Text string `json:"text"`
|
|
|
|
|
+ Code string `json:"code"`
|
|
|
|
|
+ Temperature int `json:"temperature"`
|
|
|
|
|
+ Humidity int `json:"humidity"`
|
|
|
|
|
+ AQI int `json:"aqi"`
|
|
|
|
|
+ PM25 int `json:"pm25"`
|
|
|
|
|
+ PM10 int `json:"pm10"`
|
|
|
|
|
+ Quality string `json:"quality"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func GetWeatherInfo(location, key string) (*WeatherInfoResp, error) {
|
|
|
|
|
+ result := new(WeatherInfoResp)
|
|
|
|
|
+ info, err := GetWeatherInfoByLocation(location, key)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+ result.Location = info.Results[0].Location.Name
|
|
|
|
|
+ result.Text = info.Results[0].Now.Text
|
|
|
|
|
+ result.Code = info.Results[0].Now.Code
|
|
|
|
|
+ result.Temperature, _ = strconv.Atoi(info.Results[0].Now.Temperature)
|
|
|
|
|
+ result.Humidity, _ = strconv.Atoi(info.Results[0].Now.Humidity)
|
|
|
|
|
+ airInfo, err := GetAirInfoByLocation(location, key)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+ result.PM25, _ = strconv.Atoi(airInfo.Results[0].Air.City.Pm25)
|
|
|
|
|
+ result.AQI, _ = strconv.Atoi(airInfo.Results[0].Air.City.Aqi)
|
|
|
|
|
+ result.PM10, _ = strconv.Atoi(airInfo.Results[0].Air.City.Pm10)
|
|
|
|
|
+ result.Quality = airInfo.Results[0].Air.City.Quality
|
|
|
|
|
+ return result, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func GetWeatherInfoByLocation(location, key string) (*WeatherResp, error) {
|
|
|
|
|
+ ctx := context.Background()
|
|
|
|
|
+ url := fmt.Sprintf("%s%s&key=%s", api, location, key)
|
|
|
|
|
+ res := g.Client().GetVar(ctx, url)
|
|
|
|
|
+ var result WeatherResp
|
|
|
|
|
+ err := res.Scan(&result)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, errors.New("天气查询失败")
|
|
|
|
|
+ }
|
|
|
|
|
+ return &result, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func GetDayWeatherInfoByLocation(location, key string) (*XinZhiDayWeatherInfo, error) {
|
|
|
|
|
+ ctx := context.Background()
|
|
|
|
|
+ url := fmt.Sprintf("%s%s&key=%s", dayApi, location, key)
|
|
|
|
|
+ res := g.Client().GetVar(ctx, url)
|
|
|
|
|
+ var result XinZhiDayWeatherInfo
|
|
|
|
|
+ err := res.Scan(&result)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, errors.New("天气查询失败")
|
|
|
|
|
+ }
|
|
|
|
|
+ return &result, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func GetAirInfoByLocation(location, key string) (*AirInfo, error) {
|
|
|
|
|
+ ctx := context.Background()
|
|
|
|
|
+ url := fmt.Sprintf("%s%s&key=%s", airApi, location, key)
|
|
|
|
|
+ res := g.Client().GetVar(ctx, url)
|
|
|
|
|
+ var result AirInfo
|
|
|
|
|
+ err := res.Scan(&result)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, errors.New("天气查询失败")
|
|
|
|
|
+ }
|
|
|
|
|
+ return &result, nil
|
|
|
|
|
+}
|