import { Cascader, message } from 'ant-design-vue' import { computed, defineComponent, onMounted, ref, type HTMLAttributes, type VNodeRef } from 'vue' import useWeatherStore from './useWeatherStore' import type { DefaultOptionType } from 'ant-design-vue/es/select' import { addIcons, OhVueIcon } from 'oh-vue-icons' import clsx from 'clsx' import { FaMinus, HiSolidLocationMarker } from 'oh-vue-icons/icons' import WeatherIcon from './weatherIcon' import dayjs from 'dayjs' addIcons(FaMinus, HiSolidLocationMarker) export default defineComponent(() => { const store = useWeatherStore() const hourRef = ref(null) const cascaderTriiger = ref(true) const searchValue = ref('') const filter = (inputValue: string, path: DefaultOptionType[]) => path.some( (option) => (option.label as string).toLowerCase().indexOf(inputValue.toLowerCase()) > -1 ) onMounted(() => { store.queryAll() }) const nowWeather = computed(() => { if (store.state.selectedCityCode === -1) return store.weatherData const idx = store.state.weatherList.findIndex((val) => val.id === store.state.selectedCityCode) if (idx !== -1) { return store.state.weatherList[idx].data } else { return store.weatherData } }) function getPracticeIndex(val: string) { const numVal = parseFloat(val) || 0 if (numVal < 115) { return '适宜晨练' } else { return '不宜晨练' } } function pollution(val: string) { const numVal = parseFloat(val) || 0 if (numVal < 35) { return '优' } else if (numVal < 75) { return '良' } else if (numVal < 115) { return '轻度污染' } else if (numVal < 150) { return '中度污染' } else if (numVal < 250) { return '重度污染' } else if (numVal >= 250) { return '严重污染' } else { return '未知' } } function shirtIndex(val: string) { const numVal = parseFloat(val) || 0 if (numVal < 6) { return '寒冷' } else if (numVal < 10.9) { return '冷' } else if (numVal < 14.9) { return '凉' } else if (numVal < 17.9) { return '温凉' } else if (numVal < 20.9) { return '凉舒适' } else if (numVal < 23.9) { return '舒适' } else if (numVal < 27.9) { return '热舒适' } else if (numVal >= 28) { return '炎热' } else { return '温凉' } } function coldIndex(val: string) { const numVal = parseFloat(val) || 0 if (numVal < 6) { return '易发感冒' } else if (numVal < 10.9) { return '较易发感冒' } else { return '不易发感冒' } } return () => (
{cascaderTriiger.value && ( { cascaderTriiger.value = false setTimeout(() => { cascaderTriiger.value = true }, 0) if (store.state.weatherList.findIndex((val) => val.id === option[2].value) !== -1) { message.info('该地区已添加') return } if (store.state.weatherList.length >= 5) { message.info('最多只能添加5个地区') return } store.state.weatherList.push({ id: option[2].value as number, name: option[2].label, data: await store.query(option[2].value as number) }) store.state.selectedCityCode = option[2].value as number }} notFoundContent="没有找到该地区" onClick={() => { if (store.state.cityOptions.length === 0) store.queryCity() }} searchValue={searchValue.value} placeholder="搜索其他地区天气" showSearch={{ filter }} onSearch={(value) => { searchValue.value = value }} /> )}
{ store.state.selectedCityCode = -1 }} class={clsx( 'flex flex-col justify-between gap-x-4 w-full h-[60px] relative py-2 px-3 rounded-lg cursor-pointer hover:bg-gradient-to-b from-[#d6ecff] to-[#dce3ff]', store.state.selectedCityCode === -1 ? 'bg-gradient-to-b from-[#d6ecff] to-[#dce3ff]' : 'bg-black/[0.05]' )} >
{store.weatherData?.city.name}
{store.weatherData?.base.stemp}°
{store.weatherData?.base.weather}
{store.weatherData?.base.ltemp}°/{store.weatherData?.base.htemp}°
{store.state.weatherList.map((item) => (
{ store.state.selectedCityCode = item.id }} class={clsx( 'flex flex-col group justify-between gap-x-4 w-full h-[65px] group relative py-2 px-3 rounded-lg cursor-pointer hover:bg-gradient-to-b from-[#d6ecff] to-[#dce3ff]', store.state.selectedCityCode === item.id ? 'bg-gradient-to-b from-[#d6ecff] to-[#dce3ff]' : 'bg-black/[0.05]' )} key={item.id} >
{item.data?.city.name}
{item.data?.base.stemp}°
{item.data?.base.weather}
{item.data?.base.ltemp}°/{item.data?.base.htemp}°
))}
{store.weatherData?.city.name} {nowWeather.value?.base.stemp}° {nowWeather.value?.base.weather} {nowWeather.value?.base.ltemp}°/{nowWeather.value?.base.htemp}° {nowWeather.value?.base.WD} {nowWeather.value?.base.WS}
晨练指数: {getPracticeIndex(nowWeather.value?.base.aqi || '0')}
空气质量: {pollution(nowWeather.value?.base.pm25 || '0')}
穿衣指数: {shirtIndex(nowWeather.value?.base.stemp || '0')}
雨伞指数: {nowWeather.value?.hour24.some((val) => val.weather.includes('雨')) ? '需带伞' : '无需带伞'}
感冒指数: {coldIndex(nowWeather.value?.base.stemp || '0')}
{' '}
紫外线指数: 紫外线{nowWeather.value?.base.ultraviolet}
24小时预报
{ e.preventDefault() if (!hourRef.value) return hourRef.value.scrollLeft += e.deltaY }} > {nowWeather.value?.hour24.map((item, idx) => (
{item.stemp}° {idx === 0 ? '现在' : item.hour + '时'}
))}
7日天气预报
{nowWeather.value?.weathers7.map((item, idx) => { return (
{item.ltemp + '°/' + item.htemp + '°'}
{item.weather}
{dayjs(item.date, 'MM月DD日').format('MM/DD')} {idx === 0 ? '今天' : idx === 1 ? '明天' : dayjs(item.date, 'MM月DD日').format('ddd')}
) })}
) })