refactor Network

This commit is contained in:
Timi
2026-07-29 15:04:47 +08:00
parent ff3297e879
commit 8b24804b22
6 changed files with 106 additions and 62 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
"module": "./dist/timi-web.mjs", "module": "./dist/timi-web.mjs",
"style": "./dist/timi-web.css", "style": "./dist/timi-web.css",
"private": false, "private": false,
"version": "0.0.21", "version": "0.0.22",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
+2 -2
View File
@@ -1,2 +1,2 @@
export * from "./device"; export * from "./deviceStore";
export * from "./user"; export * from "./userStore";
+1 -1
View File
@@ -13,7 +13,7 @@ export type Model = {
deletedAt?: number; deletedAt?: number;
} }
export type Response<T> = { export type ApiResponse<T> = {
code: number; code: number;
msg?: string; msg?: string;
data: T; data: T;
+102 -58
View File
@@ -1,75 +1,119 @@
import axios, { InternalAxiosRequestConfig } from "axios"; import axios, {type AxiosInstance, type AxiosResponse, type InternalAxiosRequestConfig} from "axios";
import Cooker from "./Cooker"; import {ApiResponse} from "../types";
import type { Response } from "../types/Model";
import Time from "./Time";
import { userStore } from "../store/user";
type ErrorCallback = (response: Response<any>) => void; export type ErrorCallback = (response: ApiResponse<any>) => void;
export type RequestInterceptor = (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;
export interface ResponseObserverPayload {
config?: InternalAxiosRequestConfig;
status?: number;
response?: AxiosResponse;
error?: any;
serverResponse?: ApiResponse<any>;
}
export type ResponseObserver = (payload: ResponseObserverPayload) => void;
let globalErrorCallback: ErrorCallback | null = null; let globalErrorCallback: ErrorCallback | null = null;
let globalRequestInterceptor: RequestInterceptor | null = null;
let globalResponseObserver: ResponseObserver | null = null;
export const setGlobalErrorCallback = (callback: ErrorCallback) => { export const setGlobalErrorCallback = (callback: ErrorCallback) => {
globalErrorCallback = callback; globalErrorCallback = callback;
}; };
const userTokenInterceptors = async (config: InternalAxiosRequestConfig<any>) => { export const setGlobalRequestInterceptor = (callback: RequestInterceptor | null) => {
let token = userStore.loginUser.token?.value; globalRequestInterceptor = callback;
const cookieToken = Cooker.get("Token");
if (token && token === cookieToken) {
config.headers.set({"Token": token});
} else {
if (cookieToken) {
token = cookieToken;
userStore.loginUser.token = {
value: token,
expireAt: Time.now() + Time.D
};
}
if (token) {
await userStore.login4Token({
value: token,
expireAt: Time.now() + Time.D
});
}
}
return config;
}; };
axios.defaults.withCredentials = true;
axios.interceptors.response.use((axiosResp: any) => { export const setGlobalResponseObserver = (callback: ResponseObserver | null) => {
if (!axiosResp.config.responseType) { globalResponseObserver = callback;
// 服务端返回 };
const serverResp = axiosResp.data as Response<any>;
if (serverResp.code < 40000) { const notifyResponseObserver = (payload: ResponseObserverPayload) => {
// 200 或 300 HTTP 状态段视为成功 if (!globalResponseObserver) {
return serverResp.data; return;
} else {
if (globalErrorCallback) {
globalErrorCallback(serverResp);
}
// 由调用方处理
return Promise.reject(serverResp.msg);
}
} }
return axiosResp.data; globalResponseObserver(payload);
}, (error: any) => { };
// 请求错误
if (error) { const applyDefaultInterceptors = (instance: AxiosInstance) => {
if (error.response && error.response.status) { instance.defaults.withCredentials = true;
throw error; instance.interceptors.request.use((config) => {
if (globalRequestInterceptor) {
return globalRequestInterceptor(config);
} }
if (error.request) { return config;
if (error.message.startsWith("timeout")) { });
throw new Error("time out"); instance.interceptors.response.use((axiosResp: any) => {
if (!axiosResp.config.responseType) {
// 服务端返回
const serverResp = axiosResp.data as ApiResponse<any>;
if (serverResp.code < 40000) {
notifyResponseObserver({
config: axiosResp?.config,
status: axiosResp?.status,
response: axiosResp,
serverResponse: serverResp
});
// 200 或 300 HTTP 状态段视为成功
return serverResp.data;
} else { } else {
throw new Error(error.message); notifyResponseObserver({
config: axiosResp?.config,
status: axiosResp?.status,
response: axiosResp,
serverResponse: serverResp,
error: serverResp.msg
});
if (globalErrorCallback) {
globalErrorCallback(serverResp);
}
// 由调用方处理
return Promise.reject(serverResp.msg);
} }
} }
} notifyResponseObserver({
throw error; config: axiosResp?.config,
}); status: axiosResp?.status,
response: axiosResp
});
return axiosResp.data;
}, (error: any) => {
notifyResponseObserver({
config: error?.config,
status: error?.response?.status,
response: error?.response,
error
});
// 请求错误
if (error) {
if (error.response && error.response.status) {
throw error;
}
if (error.request) {
if (error.message && error.message.startsWith("timeout")) {
throw new Error("time out");
} else {
throw new Error(error.message || "request error");
}
}
}
throw error;
});
};
const axiosInstance = axios.create();
applyDefaultInterceptors(axiosInstance);
export const createServiceAxios = (baseURL?: string) => {
const instance = axios.create({ baseURL });
applyDefaultInterceptors(instance);
return instance;
};
export default { export default {
axios, axios: axiosInstance,
userTokenInterceptors, setGlobalErrorCallback,
setGlobalErrorCallback setGlobalRequestInterceptor,
setGlobalResponseObserver,
createServiceAxios
}; };