After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 665 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,165 @@ |
|||||
|
import { Col, Row } from 'antd'; |
||||
|
import moment from 'moment'; |
||||
|
import React, { useState, useEffect, useMemo } from 'react'; |
||||
|
import { RouteRequest } from '@peace/utils'; |
||||
|
|
||||
|
const WEATHERMARGIN = 1 * 60 * 60 * 1000; |
||||
|
|
||||
|
const WEATHERArr = [ |
||||
|
{ |
||||
|
lbl: '未知', |
||||
|
key: 'weizhi', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '暴雪', |
||||
|
key: 'baoxue', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '多云', |
||||
|
key: 'duoyun', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '浮沉', |
||||
|
key: 'fucheng', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '雷阵雨', |
||||
|
key: 'leizhengyu', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '霾', |
||||
|
key: 'mai', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '强沙尘暴', |
||||
|
key: 'qiangshachengbao', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '晴', |
||||
|
key: 'qing', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '沙尘暴', |
||||
|
key: 'shachengbao', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '特大暴雨', |
||||
|
key: 'tedabaoyu', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '雾', |
||||
|
key: 'wu', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '小雪', |
||||
|
key: 'xiaoxue', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '小雨', |
||||
|
key: 'xiaoyu', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '扬沙', |
||||
|
key: 'yangsha', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '阴天', |
||||
|
key: 'yingtian', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '雨夹雪', |
||||
|
key: 'yujiaxue', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '阵雨', |
||||
|
key: 'zhenyu', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '中雪', |
||||
|
key: 'zhongxue', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '中雨', |
||||
|
key: 'zhongyu', |
||||
|
}, |
||||
|
{ |
||||
|
lbl: '大雨', |
||||
|
key: 'dayu', |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
const ICONSMAP = {}; |
||||
|
|
||||
|
WEATHERArr.forEach(({ lbl, key }) => { |
||||
|
const icon = `/assets/images/weather/${key}.png`; |
||||
|
ICONSMAP[lbl] = icon; |
||||
|
}); |
||||
|
|
||||
|
function Weather() { |
||||
|
const [time, setTime] = useState(new Date().toLocaleTimeString()); |
||||
|
const [weather, setWeather] = useState(''); |
||||
|
const [temp, setTemp] = useState(0); |
||||
|
|
||||
|
useEffect(() => { |
||||
|
const timeUpdate = setInterval(() => { |
||||
|
setTime(new Date().toLocaleTimeString()); |
||||
|
}, 1000); |
||||
|
return () => { |
||||
|
clearInterval(timeUpdate); |
||||
|
}; |
||||
|
}, []); |
||||
|
|
||||
|
const queryWeather = () => { |
||||
|
RouteRequest.get(`/query/weather?cname=南昌市`).then((doc) => { |
||||
|
console.log(doc, 'weather'); |
||||
|
const w = doc?.text || '未知'; |
||||
|
const temp = doc?.temp || 0; |
||||
|
setWeather(w); |
||||
|
setTemp(temp); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
useEffect(() => { |
||||
|
queryWeather(); |
||||
|
const timeUpdate = setInterval(() => { |
||||
|
queryWeather(); |
||||
|
}, WEATHERMARGIN); |
||||
|
return () => { |
||||
|
clearInterval(timeUpdate); |
||||
|
}; |
||||
|
}, []); |
||||
|
|
||||
|
const iconSrc = useMemo(() => { |
||||
|
const icon = ICONSMAP[weather]; |
||||
|
if (icon) return icon; |
||||
|
const rgx = new RegExp(weather); |
||||
|
for (const k in ICONSMAP) { |
||||
|
if (rgx.test(k)) { |
||||
|
return ICONSMAP[k]; |
||||
|
} |
||||
|
} |
||||
|
return ''; |
||||
|
}, [weather]); |
||||
|
|
||||
|
return ( |
||||
|
<div style={{ color: '#C3E6FF', marginLeft: '37px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> |
||||
|
<div style={{ borderRight: '0.5px solid #C3E6FF', paddingRight: 10 }}> |
||||
|
<div style={{ fontSize: 16 }}>{time}</div> |
||||
|
<div style={{ marginLeft: '5px', fontSize: 12 }}> |
||||
|
{moment().format( |
||||
|
'YYYY-MM-DD' |
||||
|
)} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style={{ paddingLeft: 10, display: 'flex' }}> |
||||
|
<img src={iconSrc} alt="icon" style={{ width: 44, height: 40, marginRight: 5 }} /> |
||||
|
<div> |
||||
|
<div>{weather}</div> |
||||
|
<div style={{ fontSize: 12 }}>{temp}℃</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
export default Weather; |
@ -0,0 +1,55 @@ |
|||||
|
const request = require('superagent'); |
||||
|
|
||||
|
let _weatherUrl = ''; |
||||
|
module.exports.entry = function (app, router, opts) { |
||||
|
const { weatherUrl } = opts; |
||||
|
console.log(weatherUrl, '天气'); |
||||
|
_weatherUrl = weatherUrl; |
||||
|
// _weatherUrl = "https://weatherssj.anxinyun.cn/weatherApp/weather/getImmeData"
|
||||
|
|
||||
|
router.get('/query/weather', weather); |
||||
|
}; |
||||
|
|
||||
|
async function weather(ctx) { |
||||
|
try { |
||||
|
const { cname } = ctx.query; |
||||
|
const reg = /.+?(省|市|自治区|自治州|县|区)/g; |
||||
|
const arr = cname.match(reg); |
||||
|
if (Array.isArray(arr)) { |
||||
|
let cityName = arr[0]; |
||||
|
if (arr[1]) { |
||||
|
cityName = arr[1]; |
||||
|
} |
||||
|
const weatherRes = await request.post(_weatherUrl).send({ cityName }); |
||||
|
const { body } = weatherRes; |
||||
|
if (body && body.data) { |
||||
|
ctx.status = 200; |
||||
|
ctx.body = { ...body.data, cname, texta: _weatherUrl }; |
||||
|
} else { |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { msg: '获取天气错误' }; |
||||
|
} |
||||
|
} else { |
||||
|
ctx.status = 400; |
||||
|
ctx.body = { msg: '地址解析错误' }; |
||||
|
} |
||||
|
} catch (error) { |
||||
|
console.log('[*err]', error); |
||||
|
ctx.status = 400; |
||||
|
ctx.body = error; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// ip地址识别库
|
||||
|
// 淘宝IP地址查询接口:http://ip.taobao.com/service/getIpInfo.php?ip=1.1.35.57
|
||||
|
// 腾讯IP地址查询接口:http://fw.qq.com/ipaddress
|
||||
|
// 新浪的IP地址查询接口:http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js
|
||||
|
// 新浪多地域测试方法:http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip=218.192.3.42
|
||||
|
// 搜狐IP地址查询接口(默认GBK):http://pv.sohu.com/cityjson
|
||||
|
// 搜狐IP地址查询接口(可设置编码):http://pv.sohu.com/cityjson?ie=utf-8
|
||||
|
// 搜狐另外的IP地址查询接口:http://txt.go.sohu.com/ip/soip
|
||||
|
// 谷歌IP地址查询接口:http://j.maxmind.com/app/geoip.js
|
||||
|
// 1616 IP地址查询接口:http://w.1616.net/chaxun/iptolocal.php
|
||||
|
// 126 http://ip.ws.126.net/ipquery hao123
|
||||
|
// http://app.hao123.com/ipquery/getcity.php?rtype=2
|
||||
|
// 太平洋电脑网 http://whois.pconline.com.cn/
|