From 0ee9737136b71eb71ad44bf27dd6bcee8bb96bd8 Mon Sep 17 00:00:00 2001 From: lorne <1991wangliang@gmail.com> Date: Wed, 14 May 2025 20:25:43 +0800 Subject: [PATCH 1/2] #3 --- package.json | 3 +- src/utils/http.ts | 192 +++++++++++++++++++++++++++++++++++++++++++++ src/utils/index.ts | 2 + src/utils/sleep.ts | 7 ++ 4 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 src/utils/http.ts create mode 100644 src/utils/sleep.ts diff --git a/package.json b/package.json index 2cb532d..6c4fb3b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@codingapi/ui-framework", - "version": "0.0.25", + "version": "0.0.26", "description": "A UI Framework built with React and Typescript", "keywords": [ "ui", @@ -27,6 +27,7 @@ ], "dependencies": { "@types/node": "^22.15.2", + "axios": "^1.9.0", "base64-js": "^1.5.1", "jszip": "^3.10.1", "lodash": "^4.17.21", diff --git a/src/utils/http.ts b/src/utils/http.ts new file mode 100644 index 0000000..2478e2b --- /dev/null +++ b/src/utils/http.ts @@ -0,0 +1,192 @@ +import axios, {AxiosInstance} from "axios"; +import {sleep} from "./sleep"; +import {Base64Utils} from "./base64"; + +export interface MessageBox { + success: (msg: string) => void; + error: (msg: string) => void; +} + +export class HttpClient { + private readonly api: AxiosInstance; + private readonly messageBox: MessageBox; + + constructor(timeout: number, messageBox: MessageBox) { + this.messageBox = messageBox; + this.api = axios.create({ + timeout: timeout, + headers: { + "Content-Type": "application/json", + }, + }); + + this.addRequestInterceptors(); + this.addResponseInterceptors(); + } + + private addRequestInterceptors() { + this.api.interceptors.request.use((config: any) => { + const token = localStorage.getItem("token"); + if (token) { + config.headers = { + Authorization: `${token}`, + } as any; + } + return config; + }, (error: any) => { + return Promise.reject(error); + }); + } + + private addResponseInterceptors() { + this.api.interceptors.response.use(async (response: any) => { + const headers = response.headers; + const token = headers['authorization']; + + const state = response.status; + if (state === 200) { + if (token) { + console.log('reset token', token); + localStorage.setItem("token", token) + } + + if (response.data) { + const success = response.data.success; + if (!success) { + const errMessage = response.data.errMessage; + const errCode = response.data.errCode; + if ("token.expire" === errCode || "token.error" === errCode) { + this.messageBox.error('登录已过期,请退出再重新打开'); + await sleep(1500); + localStorage.clear(); + window.location.href = '/#login'; + } else { + if ("login.error" === errCode) { + return response; + } + this.messageBox.error(errMessage) + } + } + } else { + this.messageBox.error('抱歉,该账户无权限访问'); + } + } + return response; + }, + (error: any) => { + const response = error.response; + const state = response.data.status; + + if (state === 403) { + this.messageBox.error('抱歉,该账户无权限访问'); + return { + data: { + success: false, + } + } + } + return Promise.reject(error); + } + ) + } + + public get = async (url: string, params?: any) => { + try { + const response = await this.api.get(url, { + params + }); + return response.data; + } catch (e) { + return { + success: false, + } + } + } + + public post = async (url: string, data: any) => { + try { + const response = await this.api.post(url, data); + return response.data; + } catch (e) { + return { + success: false, + } + } + } + + + public page = async (url: string, params: any, sort: any, filter: any, match: { + key: string, + type: string + }[]) => { + const base64Match = Base64Utils.stringToBase64(JSON.stringify(match)); + const base64Sort = Base64Utils.stringToBase64(JSON.stringify(sort)); + const base64Filter = Base64Utils.stringToBase64(JSON.stringify(filter)); + + const response = await this.get(url, { + ...params, + sort: base64Sort, + filter: base64Filter, + params: base64Match, + }); + + if (response.success) { + const list = response.data.total > 0 ? response.data.list : []; + return { + data: list, + success: response.success, + total: response.data.total + }; + } else { + return { + data: [], + success: response.success, + total: 0 + } + } + } + + + public download = async (url: string, filename?: string) => { + try { + const token = localStorage.getItem("token"); + const response = await axios.get(url, { + responseType: 'blob', + headers: { + 'Authorization': token, + } + }); + const bytes = await response.data; + const blob = new Blob([bytes]); + const downloadUrl = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = downloadUrl; + a.download = filename || 'result.csv'; + a.click(); + } catch (e) { + console.log(e); + } + } + + public postDownload = async (url: string, data: any, filename?: string) => { + try { + const token = localStorage.getItem("token"); + const response = await axios.post(url, data, { + responseType: 'blob', + headers: { + 'Authorization': token, + } + }); + const bytes = await response.data; + const blob = new Blob([bytes]); + const downloadUrl = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = downloadUrl; + a.download = filename || 'result.csv'; + a.click(); + } catch (e) { + console.log(e); + } + } + +} diff --git a/src/utils/index.ts b/src/utils/index.ts index ffb2559..4524928 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,3 +1,5 @@ export * from './base64'; export * from './dynamicComponent'; export * from './role'; +export * from './sleep'; +export * from './http'; diff --git a/src/utils/sleep.ts b/src/utils/sleep.ts new file mode 100644 index 0000000..1bde575 --- /dev/null +++ b/src/utils/sleep.ts @@ -0,0 +1,7 @@ +export const sleep = async (time: number) => { + return new Promise((resolve:any) => { + setTimeout(() => { + resolve(); + }, time); + }) +} From 07fa01b84fcf4b171a9d6dba2d7a2a0ca8ba215b Mon Sep 17 00:00:00 2001 From: lorne <1991wangliang@gmail.com> Date: Wed, 14 May 2025 20:44:19 +0800 Subject: [PATCH 2/2] fix #3 --- README.md | 56 ++++++++++++++++++++++++++ playground/src/App.tsx | 2 + playground/src/components/HttpTest.tsx | 49 ++++++++++++++++++++++ src/utils/http.ts | 42 ++++++++++++++++--- 4 files changed, 144 insertions(+), 5 deletions(-) create mode 100644 playground/src/components/HttpTest.tsx diff --git a/README.md b/README.md index 33c339e..0a08991 100644 --- a/README.md +++ b/README.md @@ -306,6 +306,61 @@ const MicroComponentTest = () => { export default MicroComponentTest; ``` + +### 网络请求 +``` +import React from "react"; +import Space from "@/components/Space"; +//@ts-ignore +import {HttpClient,Response} from "@codingapi/ui-framework"; + +const httpClient = new HttpClient(10000,{ + success:(msg:string)=>{ + console.log('success',msg); + }, + error:(msg:string)=>{ + console.log('error',msg); + }, +}); + +const HttpTest = ()=>{ + + const [url, setUrl] = React.useState('/api/products'); + + const handlerGet = ()=>{ + httpClient.get(url).then((res:Response)=>{ + const json = JSON.stringify(res); + console.log(json); + alert(json); + }) + } + + return ( + <> +