test/1114/app/components/weather/WeatherSearchForm.tsx

105 lines
3.3 KiB
TypeScript
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.

//天气搜索表单组件
import { cn } from "@/components/lib/utils";
import React ,{useState,type FormEvent,type ChangeEvent, use} from "react";
import { Button } from "@/components/ui/button";
import { Input} from "../ui/input";
import {useWeatherStore} from "@/store/weatherStore";
import { AlertCircle, Loader2, RefreshCw, Search } from "lucide-react";
//城市输入验证搜索刷新
export function WeatherSearchForm() {
const {isLoading,currentWeather,setCurrentWeather,refreshWeather,searchWeather} = useWeatherStore();
const [city, setCity] = useState('');
const [inputError, setInputError] = useState('');
//输入框内容
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
setCity(event.target.value);
setInputError('');
};
//表单提交验证
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
const trimmed = city.trim();
//创建axios实例 统一请求头
const apiClient: AxiosInstance = axios.create({
baseURL: BASE_URL,
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
});
//请求拦截器
apiClient.interceptors.request.use(
(config) => {
// 在发送请求之前做些什么
config.params = {
...config.params,
access_key: API_KEY,
};
//打印请求信息
if (process.env.NODE_ENV === 'development') {
console.log('API Request:', config.method, config.url, config.params);
}
return config;
},
(error) => {
// 对请求错误做些什么
console.error('Request Error:', error);
return Promise.reject(error);
}
);
// 添加响应拦截器
apiClient.interceptors.response.use(
(response) => {
//状态为200时的错误
if (response.data && response.data.error ) {
const error = response.data.error;
console.error('API Error:', error);
throw new Error(error.info || '请求失败');
}//打印响应
if (process.env.NODE_ENV === 'development') {
console.log('API Response:', response.status, response.data);
}
return response;
},
(error:AxiosError) => {
//统一错误处理
console.error('Response Error:', error.message);
if (error.response) {
const status = error.response.status;
switch (status) {
case 404:
return Promise.reject(new Error('未找到该城市,请检查城市名称'));
case 401:
return Promise.reject(new Error('API认证失败请检查API密钥'));
case 403:
return Promise.reject(new Error('访问被拒绝,请稍后再试'));
case 429:
return Promise.reject(new Error('请求次数过多,请稍后再试'));
default:
return Promise.reject(new Error('服务器错误,请稍后再试'));
}
}else if(error.request){
return Promise.reject(new Error('网络连接失败,请检查网络状态'));
}else {
return Promise.reject(new Error('请求配置错误'));
}
}
);
//WeatherAPI
export class WeatherAPI {
static async getCurrentWeather(city: string): Promise<WeatherData> {
try {
const response = await apiClient.get<WeatherData>(
'/current',
{params : {query: city },
});
return response.data;
} catch (error) {
throw error;
}
}
}
export default apiClient;