雾霾天气查询网页

Wain ... 2022-5-12 全栈开发
  • 开发文档
  • 手机端
About 9 min

# 雾霾天气查询网页

# 问题描述

雾霾的频繁出现已严重的影响到人们的出行,对人们的健康造成了重大影响。因此,能在出行前查看雾霾的指数,并采取相应的措施来把雾霾的影响降到最小就显得尤为重要。本系统在分析多种因子的影响下,设计一个手机端天气查询网站。

包含以下功能:

a.定位功能:将定位城市保存在服务器端,并同时显示在客户端。

b.界面设计:包含显示天气和空气质量指数的动态显示。

c.天气详情和空气质量指数:定位后的城市在服务器端获取后,传给天气详情界面,通过所传城市用百度天气api获取对应的天气详情和空气质量指数,并保存在服务器端。

后续可以添加出行建议等功能。

项目地址:Devinwain-Github-天气查询 (opens new window)

# 主体设计

根据任务需求,我们计划设计一个适配手机端的天气查询网页,页面信息包含空气质量指数、温度等,并包含了未来10小时的预报。同时产品同学制作出相应的原型图交付给开发同学。开发同学根据原型图确定好技术选型,从而开始着手开发。

原型图:Figma原型图 (opens new window)

下面具体阐述系统的技术方案:

  • 数据:分为ip接口与天气接口,都来源于百度api平台。
  • 前端:前端使用vue2+vant UI完成手机端页面的编写。
  • 数据可视化:所用到的图表均用echarts进行绘制。
  • 后端:使用Springboot框架进行编写。

# 文件目录

# 前端

image-20220512004623414

目前只有一个页面,所以代码都写在index.vue中,由于用了echarts画图,所以中间的配置项特别长,其实页面可以分成几个组件,这样更方便维护。

# 后端

image-20220512004654892

config用来配置允许跨域,controller用来相应请求,且共享一个Address对象,目前只考虑了单用户的情况,多用户访问的话可能会有问题(待验证)。domain里是一个Address的POJO,包含ip、province、city还有一个画图需要的属性。utils里封装了获取ip的方法。

# 效果展示

访问页面后,自动定位到所在城市,结果如下图:

image-20220512004713995

自定义城市后,如河北省石家庄市,结果如下:

image-20220512004728193

服务端打印所有查询结果:

image-20220512004747991 image-20220512004800058

# 遇到的问题及解决方法

  • 问题1:本地的用户ip比较难获取
  • 解决办法:

通过ip判断是否为本地用户,若是则发送请求到http://pv.sohu.com/cityjson?ie=utf-8 (opens new window)可以获取外网ip及所在城市。

  • 问题2:echarts图表没有实时更新
  • 解决办法:

每次数据更新后都要重新setOption来更新。

  • 问题3:前端发送的post请求,后端无法正常解析,postman测试后端接口返回正常,估计是前端发的请求有点问题。
  • 解决办法:

暂时用一个hashmap来接收请求参数,所有参数会存在hashmap的第一个键里,取出来后转成json对象再去按键取值。后续可以看看哪里出问题了,或者转成一个get请求。

  • 问题4:天气的api次数快用完了
  • 解决方法:

到时候用别的api吧。

  • [ ] 问题5:前端得到的省份城市是带省、自治区、市等,后端要求不带这个(别人api要求的),所以这个还得解析一下,目前只处理了省、市的情景。
  • [ ] 问题6:/api/city与/api/weather有代码重复 需要优化,把所有外部api接口封装一下。
  • [ ] 问题7:前端的组件需要拆分

# 接口

# /api/location

描述:根据请求过来的ip通过百度的ip查询接口获取它的位置信息。本地用户会特殊处理,参考问题1。

请求类型:POST 请求参数:无

{
    "data": {
        "country": "中国",
        "country_id": "CN",
        "area": "西北",
        "region": "陕西",
        "region_id": "610000",
        "city": "西安",
        "city_id": "610100",
        "ip": "111.111.111.6",
        "long_ip": "1999977155",
        "isp": "联通"
    },
    "msg": "成功",
    "success": true,
    "code": 200,
    "taskNo": "54119621271131057206"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# /api/weather

描述:目前这个api会配合/api/location一起使用,从而保证ip不为空,然后通过ip查询该城市的天气信息。返回的数据是经过处理的(信息太多,方便前端处理)。后续还需要优化,与/api/location解耦。 请求类型:POST 请求参数:无

{
    "ip": "113.200.174.6",
    "city": "西安",
    "province": "陕西",
    "aqi": 53,
    "fut_10_hour": [
        "现在",
        "05/11",
        "01:00",
        "02:00",
        "03:00",
        "04:00",
        "05:00",
        "06:00",
        "07:00",
        "08:00"
    ],
    "fut_10_temp": [
        15,
        17,
        17,
        16,
        15,
        15,
        15,
        15,
        16,
        16
    ],
    "fut_10_aqi": [
        50,
        44,
        44,
        44,
        44,
        44,
        44,
        44,
        46,
        46
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
    "cityid": "101010100",
    "date": "2022-05-10",
    "week": "星期二",
    "update_time": "14:05",
    "city": "北京",
    "cityEn": "beijing",
    "country": "中国",
    "countryEn": "China",
    "wea": "霾",
    "wea_img": "wu",
    "tem": "14",
    "tem1": "14",
    "tem2": "10",
    "win": "南风",
    "win_speed": "2级",
    "win_meter": "8km/h",
    "humidity": "67%",
    "visibility": "5km",
    "pressure": "1007",
    "air": "63",
    "air_pm25": "45",
    "air_level": "良",
    "air_tips": "空气好,可以外出活动,除极少数对污染物特别敏感的人群以外,对公众没有危害!",
    "alarm": {
        "alarm_type": "",
        "alarm_level": "",
        "alarm_content": ""
    },
    "wea_day": "小雨",
    "wea_day_img": "yu",
    "wea_night": "小雨",
    "wea_night_img": "yu",
    "sunrise": "05:04",
    "sunset": "19:17",
    "hours": [
        {
            "hours": "现在",
            "wea": "多云",
            "wea_img": "yun",
            "tem": "13",
            "win": "南风",
            "win_speed": "3级",
            "aqi": "良",
            "aqinum": "72"
        },
        {
            "hours": "15:00",
            "wea": "多云",
            "wea_img": "yun",
            "tem": "13",
            "win": "南风",
            "win_speed": "3级",
            "aqi": "良",
            "aqinum": "69"
        },
        {
            "hours": "16:00",
            "wea": "多云",
            "wea_img": "yun",
            "tem": "13",
            "win": "南风",
            "win_speed": "3级",
            "aqi": "良",
            "aqinum": "69"
        },
        {
            "hours": "17:00",
            "wea": "阴转多云",
            "wea_img": "yun",
            "tem": "13",
            "win": "西南风",
            "win_speed": "2级",
            "aqi": "良",
            "aqinum": "70"
        },
        {
            "hours": "18:00",
            "wea": "小雨",
            "wea_img": "yu",
            "tem": "12",
            "win": "西南风",
            "win_speed": "2级",
            "aqi": "良",
            "aqinum": "70"
        },
        {
            "hours": "19:00",
            "wea": "小雨",
            "wea_img": "yu",
            "tem": "12",
            "win": "西北风",
            "win_speed": "1级",
            "aqi": "良",
            "aqinum": "71"
        },
        {
            "hours": "20:00",
            "wea": "小雨",
            "wea_img": "yu",
            "tem": "12",
            "win": "西北风",
            "win_speed": "2级",
            "aqi": "良",
            "aqinum": "74"
        },
        {
            "hours": "21:00",
            "wea": "小雨",
            "wea_img": "yu",
            "tem": "12",
            "win": "西北风",
            "win_speed": "2级",
            "aqi": "良",
            "aqinum": "74"
        },
        {
            "hours": "22:00",
            "wea": "小雨",
            "wea_img": "yu",
            "tem": "12",
            "win": "北风",
            "win_speed": "3级",
            "aqi": "良",
            "aqinum": "71"
        },
        {
            "hours": "23:00",
            "wea": "小雨",
            "wea_img": "yu",
            "tem": "12",
            "win": "东北风",
            "win_speed": "3级",
            "aqi": "良",
            "aqinum": "65"
        },
        {
            "hours": "05/11",
            "wea": "多云",
            "wea_img": "yun",
            "tem": "12",
            "win": "北风",
            "win_speed": "3级",
            "aqi": "优",
            "aqinum": "57"
        },
        {
            "hours": "01:00",
            "wea": "多云",
            "wea_img": "yun",
            "tem": "12",
            "win": "东北风",
            "win_speed": "3级",
            "aqi": "优",
            "aqinum": "51"
        },
        {
            "hours": "02:00",
            "wea": "多云",
            "wea_img": "yun",
            "tem": "12",
            "win": "东北风",
            "win_speed": "2级",
            "aqi": "优",
            "aqinum": "49"
        },
        {
            "hours": "03:00",
            "wea": "多云",
            "wea_img": "yun",
            "tem": "12",
            "win": "东北风",
            "win_speed": "2级",
            "aqi": "优",
            "aqinum": "49"
        },
        {
            "hours": "04:00",
            "wea": "多云",
            "wea_img": "yun",
            "tem": "12",
            "win": "东北风",
            "win_speed": "2级",
            "aqi": "优",
            "aqinum": "49"
        },
        {
            "hours": "05:00",
            "wea": "晴",
            "wea_img": "qing",
            "tem": "12",
            "win": "东北风",
            "win_speed": "2级",
            "aqi": "优",
            "aqinum": "46"
        },
        {
            "hours": "06:00",
            "wea": "多云",
            "wea_img": "yun",
            "tem": "12",
            "win": "东北风",
            "win_speed": "2级",
            "aqi": "优",
            "aqinum": "43"
        },
        {
            "hours": "07:00",
            "wea": "多云",
            "wea_img": "yun",
            "tem": "12",
            "win": "东北风",
            "win_speed": "2级",
            "aqi": "优",
            "aqinum": "40"
        },
        {
            "hours": "08:00",
            "wea": "多云",
            "wea_img": "yun",
            "tem": "12",
            "win": "北风",
            "win_speed": "2级",
            "aqi": "优",
            "aqinum": "40"
        },
        {
            "hours": "09:00",
            "wea": "多云",
            "wea_img": "yun",
            "tem": "14",
            "win": "西北风",
            "win_speed": "2级",
            "aqi": "优",
            "aqinum": "40"
        },
        {
            "hours": "10:00",
            "wea": "晴",
            "wea_img": "qing",
            "tem": "16",
            "win": "西北风",
            "win_speed": "3级",
            "aqi": "优",
            "aqinum": "40"
        },
        {
            "hours": "11:00",
            "wea": "晴",
            "wea_img": "qing",
            "tem": "19",
            "win": "西北风",
            "win_speed": "2级",
            "aqi": "优",
            "aqinum": "37"
        },
        {
            "hours": "12:00",
            "wea": "晴",
            "wea_img": "qing",
            "tem": "20",
            "win": "西北风",
            "win_speed": "2级",
            "aqi": "优",
            "aqinum": "34"
        }
    ],
    "aqi": {
        "update_time": "12:57",
        "air": "63",
        "air_level": "良",
        "air_tips": "空气好,可以外出活动,除极少数对污染物特别敏感的人群以外,对公众没有危害!",
        "pm25": "45",
        "pm25_desc": "良",
        "pm10": "64",
        "pm10_desc": "良",
        "o3": "59",
        "o3_desc": "优",
        "no2": "15",
        "no2_desc": "优",
        "so2": "3",
        "so2_desc": "优",
        "co": "-",
        "co_desc": "-",
        "kouzhao": "不用佩戴口罩",
        "yundong": "适宜运动",
        "waichu": "适宜外出",
        "kaichuang": "适宜开窗",
        "jinghuaqi": "关闭净化器"
    },
    "zhishu": {
        "chuanyi": {
            "level": "较冷",
            "tips": "建议着厚外套加毛衣等服装。"
        },
        "daisan": {
            "level": "带伞",
            "tips": "有降水,带雨伞,短期外出可收起雨伞。"
        },
        "ganmao": {
            "level": "易发",
            "tips": "大幅度降温,湿度较大,注意防护。"
        },
        "chenlian": {
            "level": "不宜",
            "tips": "有较强降水,建议在室内做适当锻炼。"
        },
        "ziwaixian": {
            "level": "最弱",
            "tips": "辐射弱,涂擦SPF8-12防晒护肤品。"
        },
        "liangshai": {
            "level": "不宜",
            "tips": "降水可能会淋湿衣物,请选择在室内晾晒。"
        },
        "kaiche": {
            "level": "",
            "tips": ""
        },
        "xiche": {
            "level": "不宜",
            "tips": "有雨,雨水和泥水会弄脏爱车。"
        },
        "lvyou": {
            "level": "适宜",
            "tips": "较弱降水和微风将伴您共赴旅程。"
        },
        "diaoyu": {
            "level": "不宜",
            "tips": "天气不好,有风,不适合垂钓。"
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333

# /api/city

描述:用户自主选择城市时,确认后会调用这个api查询该城市的天气,目前存在两个问题,见问题5。 请求类型:POST 请求参数:

{
    "province": "浙江",
    "city": "杭州"
}
1
2
3
4
{
    "ip": "113.200.174.6",
    "city": "西安",
    "province": "陕西",
    "aqi": 53,
    "fut_10_hour": [
        "现在",
        "05/11",
        "01:00",
        "02:00",
        "03:00",
        "04:00",
        "05:00",
        "06:00",
        "07:00",
        "08:00"
    ],
    "fut_10_temp": [
        15,
        17,
        17,
        16,
        15,
        15,
        15,
        15,
        16,
        16
    ],
    "fut_10_aqi": [
        50,
        44,
        44,
        44,
        44,
        44,
        44,
        44,
        46,
        46
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Last update: May 11, 2022 17:08