wangji-request 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Your Name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # HTTP Client
2
+
3
+ 一个轻量级的 HTTP 客户端库,基于 axios 封装,提供简洁的 API 和 TypeScript 类型支持。
4
+
5
+ ## 特性
6
+
7
+
8
+
9
+ ## 安装
10
+
11
+ ```bash
12
+ npm install git@github.com:HanWuJiJack/request.git
13
+ ```
14
+
15
+ 或者使用 yarn:
16
+
17
+ ```bash
18
+ yarn add git@github.com:HanWuJiJack/request.git
19
+ ```
20
+
21
+ ## 快速开始
22
+
23
+ ### 基础用法
24
+
25
+
26
+
27
+ ## 许可证
28
+
29
+ MIT
30
+
31
+ ## 贡献
32
+
33
+ 欢迎提交 issue 和 pull request!
34
+
35
+ ## 支持
36
+
37
+ 如有问题或建议,请提交 issue。
package/build.js ADDED
@@ -0,0 +1,16 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ // Create ES module version
5
+ const indexPath = path.join(__dirname, 'dist', 'index.js');
6
+ const indexContent = fs.readFileSync(indexPath, 'utf8');
7
+
8
+ // Transform CommonJS to ESM
9
+ const esmContent = indexContent
10
+ .replace(/^"use strict";?\n?/, '')
11
+ .replace(/Object\.defineProperty\(exports,.*?\{.*?\}\);?\n?/gs, '');
12
+
13
+ const mesmPath = path.join(__dirname, 'dist', 'index.mjs');
14
+ fs.writeFileSync(mesmPath, esmContent);
15
+
16
+ console.log('Build complete: ESM module created at dist/index.mjs');
@@ -0,0 +1,47 @@
1
+ import { AxiosRequestConfig } from 'axios';
2
+ type ErrorCodeMap = Record<string | number, string>;
3
+ interface HttpClientOptions {
4
+ Notification: any;
5
+ Message: any;
6
+ store: any;
7
+ getToken: () => string | null;
8
+ errorCode: ErrorCodeMap;
9
+ MessageDebounce: (msg: string) => void;
10
+ baseURL: string;
11
+ timeout?: number;
12
+ loadingObj?: {
13
+ open: () => void;
14
+ close: () => void;
15
+ };
16
+ }
17
+ interface RequestOptions extends AxiosRequestConfig {
18
+ load?: boolean;
19
+ delayTime?: number;
20
+ time?: number;
21
+ autoCancel?: boolean;
22
+ }
23
+ interface CancelMap {
24
+ [key: string]: (msg?: string) => void;
25
+ }
26
+ declare global {
27
+ interface Window {
28
+ cancelApiMap?: CancelMap;
29
+ }
30
+ }
31
+ export default class HttpClient {
32
+ private opts;
33
+ private requestFn;
34
+ private service;
35
+ constructor(opts: HttpClientOptions);
36
+ getRequest(): (options: {
37
+ method?: string;
38
+ url: string;
39
+ data?: any;
40
+ params?: any;
41
+ headers?: any;
42
+ config?: RequestOptions;
43
+ autoCancel?: boolean;
44
+ }) => Promise<any>;
45
+ }
46
+ export {};
47
+ //# sourceMappingURL=http-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../src/http-client.ts"],"names":[],"mappings":"AAAA,OAAc,EAEZ,kBAAkB,EAGnB,MAAM,OAAO,CAAA;AAEd,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,CAAA;AAEnD,UAAU,iBAAiB;IACzB,YAAY,EAAE,GAAG,CAAA;IACjB,OAAO,EAAE,GAAG,CAAA;IACZ,KAAK,EAAE,GAAG,CAAA;IACV,QAAQ,EAAE,MAAM,MAAM,GAAG,IAAI,CAAA;IAC7B,SAAS,EAAE,YAAY,CAAA;IACvB,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,IAAI,CAAA;QAChB,KAAK,EAAE,MAAM,IAAI,CAAA;KAClB,CAAA;CACF;AAED,UAAU,cAAe,SAAQ,kBAAkB;IACjD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,UAAU,SAAS;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CACtC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,YAAY,CAAC,EAAE,SAAS,CAAA;KACzB;CACF;AAED,MAAM,CAAC,OAAO,OAAO,UAAU;IAajB,OAAO,CAAC,IAAI;IAZxB,OAAO,CAAC,SAAS,CAQC;IAElB,OAAO,CAAC,OAAO,CAAe;gBAEV,IAAI,EAAE,iBAAiB;IAmLpC,UAAU,cA/LY;QAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,GAAG,EAAE,MAAM,CAAA;QACX,IAAI,CAAC,EAAE,GAAG,CAAA;QACV,MAAM,CAAC,EAAE,GAAG,CAAA;QACZ,OAAO,CAAC,EAAE,GAAG,CAAA;QACb,MAAM,CAAC,EAAE,cAAc,CAAA;QACvB,UAAU,CAAC,EAAE,OAAO,CAAA;KACrB,KAAK,OAAO,CAAC,GAAG,CAAC;CA0LnB"}
@@ -0,0 +1,139 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import axios from 'axios';
11
+ export default class HttpClient {
12
+ constructor(opts) {
13
+ this.opts = opts;
14
+ const { Notification, Message, store, getToken, errorCode, MessageDebounce, baseURL, timeout = 5000, loadingObj } = opts;
15
+ axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';
16
+ this.service = axios.create({
17
+ baseURL,
18
+ timeout
19
+ });
20
+ // ================= 请求拦截 =================
21
+ this.service.interceptors.request.use((config) => {
22
+ var _a;
23
+ const isToken = ((_a = config.headers) === null || _a === void 0 ? void 0 : _a.isToken) === false;
24
+ const token = getToken();
25
+ if (token && !isToken) {
26
+ config.headers = Object.assign(Object.assign({}, config.headers), { Authorization: `Bearer ${token}` });
27
+ }
28
+ // GET 参数拼接(保持你原逻辑)
29
+ if (config.method === 'get' && config.params) {
30
+ let url = config.url + '?';
31
+ for (const key of Object.keys(config.params)) {
32
+ const value = config.params[key];
33
+ const part = encodeURIComponent(key) + '=';
34
+ if (value !== null && value !== undefined) {
35
+ if (typeof value === 'object') {
36
+ for (const subKey of Object.keys(value)) {
37
+ const subVal = value[subKey];
38
+ if (subVal !== null && subVal !== undefined) {
39
+ const paramsKey = `${key}[${subKey}]`;
40
+ url +=
41
+ encodeURIComponent(paramsKey) +
42
+ '=' +
43
+ encodeURIComponent(subVal) +
44
+ '&';
45
+ }
46
+ }
47
+ }
48
+ else {
49
+ url += part + encodeURIComponent(value) + '&';
50
+ }
51
+ }
52
+ }
53
+ url = url.slice(0, -1);
54
+ config.params = undefined;
55
+ config.url = url;
56
+ }
57
+ return config;
58
+ }, (error) => Promise.reject(error));
59
+ // ================= 响应拦截 =================
60
+ this.service.interceptors.response.use((res) => {
61
+ var _a, _b, _c;
62
+ const code = (_b = (_a = res.data) === null || _a === void 0 ? void 0 : _a.code) !== null && _b !== void 0 ? _b : 200;
63
+ const message = errorCode[code] || ((_c = res.data) === null || _c === void 0 ? void 0 : _c.msg) || errorCode['default'];
64
+ if (code === 401) {
65
+ store.dispatch('LogOut').then(() => {
66
+ window.location.href = '/PI/index';
67
+ });
68
+ return Promise.reject('令牌验证失败');
69
+ }
70
+ if (code === 500) {
71
+ Message({
72
+ message,
73
+ type: 'error'
74
+ });
75
+ return Promise.reject({ message, code });
76
+ }
77
+ if (code !== 200) {
78
+ Notification.error({ title: message });
79
+ return Promise.reject({ message, code });
80
+ }
81
+ return res.data;
82
+ }, (error) => {
83
+ let message = error.message;
84
+ if (message === 'Network Error') {
85
+ message = '后端接口连接异常';
86
+ }
87
+ else if (message.includes('timeout')) {
88
+ message = '系统接口请求超时';
89
+ }
90
+ else if (message.includes('Request failed with status code')) {
91
+ message = `系统接口${message.slice(-3)}异常`;
92
+ }
93
+ MessageDebounce(message);
94
+ return Promise.reject(error);
95
+ });
96
+ // ================= request 包装 =================
97
+ this.requestFn = (_a) => __awaiter(this, [_a], void 0, function* ({ method = 'get', url, data, params, headers, config = {}, autoCancel = false }) {
98
+ const requestMethod = method.toLowerCase();
99
+ if (method === 'post' || config.load) {
100
+ loadingObj === null || loadingObj === void 0 ? void 0 : loadingObj.open();
101
+ }
102
+ // ================= 取消请求 =================
103
+ if (autoCancel) {
104
+ if (!window.cancelApiMap) {
105
+ window.cancelApiMap = {};
106
+ }
107
+ const key = url + method;
108
+ if (window.cancelApiMap[key]) {
109
+ return Promise.reject('阻止进程');
110
+ }
111
+ config.cancelToken = new axios.CancelToken((cancel) => {
112
+ window.cancelApiMap[key] = cancel;
113
+ });
114
+ }
115
+ try {
116
+ const res = yield this.service(Object.assign({ method: requestMethod, url,
117
+ data,
118
+ params,
119
+ headers }, config));
120
+ const delay = config.time || 1800;
121
+ const result = yield new Promise((resolve) => {
122
+ setTimeout(() => resolve(res), delay);
123
+ });
124
+ return result;
125
+ }
126
+ finally {
127
+ if (method === 'post' || config.load) {
128
+ setTimeout(() => {
129
+ loadingObj === null || loadingObj === void 0 ? void 0 : loadingObj.close();
130
+ }, config.delayTime || 1000);
131
+ }
132
+ }
133
+ });
134
+ }
135
+ getRequest() {
136
+ return this.requestFn;
137
+ }
138
+ }
139
+ //# sourceMappingURL=http-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-client.js","sourceRoot":"","sources":["../src/http-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import HttpClient from './http-client';
2
+ import type { RequestConfig, HttpClientConfig, RequestInterceptor, ResponseInterceptor, ErrorInterceptor } from './types';
3
+ export default HttpClient;
4
+ export { HttpClient, RequestConfig, HttpClientConfig, RequestInterceptor, ResponseInterceptor, ErrorInterceptor, };
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,eAAe,CAAC;AACvC,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAGjB,eAAe,UAAU,CAAC;AAG1B,OAAO,EACL,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,GACjB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ import HttpClient from './http-client';
2
+ // Default export
3
+ export default HttpClient;
4
+ // Named exports
5
+ export { HttpClient, };
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,eAAe,CAAC;AASvC,iBAAiB;AACjB,eAAe,UAAU,CAAC;AAE1B,gBAAgB;AAChB,OAAO,EACL,UAAU,GAMX,CAAC"}
package/dist/index.mjs ADDED
@@ -0,0 +1,6 @@
1
+ import HttpClient from './http-client';
2
+ // Default export
3
+ export default HttpClient;
4
+ // Named exports
5
+ export { HttpClient, };
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,26 @@
1
+ import { AxiosRequestConfig, AxiosResponse } from 'axios';
2
+ export interface RequestConfig extends AxiosRequestConfig {
3
+ showLoading?: boolean;
4
+ showError?: boolean;
5
+ timeout?: number;
6
+ }
7
+ export interface HttpClientConfig {
8
+ baseURL?: string;
9
+ timeout?: number;
10
+ headers?: Record<string, string>;
11
+ interceptors?: {
12
+ request?: (config: AxiosRequestConfig) => AxiosRequestConfig;
13
+ response?: (response: AxiosResponse) => AxiosResponse;
14
+ error?: (error: any) => Promise<any>;
15
+ };
16
+ }
17
+ export interface RequestInterceptor {
18
+ (config: AxiosRequestConfig): AxiosRequestConfig;
19
+ }
20
+ export interface ResponseInterceptor {
21
+ (response: AxiosResponse): AxiosResponse;
22
+ }
23
+ export interface ErrorInterceptor {
24
+ (error: any): Promise<any>;
25
+ }
26
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE1D,MAAM,WAAW,aAAc,SAAQ,kBAAkB;IACvD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE;QACb,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,kBAAkB,CAAC;QAC7D,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,aAAa,CAAC;QACtD,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;KACtC,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,CAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB,CAAC;CAClD;AAED,MAAM,WAAW,mBAAmB;IAClC,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa,CAAC;CAC1C;AAED,MAAM,WAAW,gBAAgB;IAC/B,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CAC5B"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/jest.config.js ADDED
@@ -0,0 +1,12 @@
1
+ module.exports = {
2
+ preset: 'ts-jest',
3
+ testEnvironment: 'node',
4
+ roots: ['<rootDir>/src'],
5
+ testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
6
+ collectCoverageFrom: [
7
+ 'src/**/*.ts',
8
+ '!src/**/*.d.ts',
9
+ '!src/**/index.ts',
10
+ ],
11
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
12
+ };
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "wangji-request",
3
+ "version": "1.0.0",
4
+ "description": "A lightweight HTTP client wrapper based on axios",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.mjs",
10
+ "require": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "tsc && node build.js",
16
+ "prebuild": "npm run clean",
17
+ "clean": "rm -rf dist",
18
+ "test": "jest",
19
+ "prepare": "npm run build",
20
+ "prepublishOnly": "npm run build",
21
+ "version": "npm run build"
22
+ },
23
+ "keywords": [
24
+ "http",
25
+ "axios",
26
+ "request",
27
+ "client",
28
+ "api"
29
+ ],
30
+ "author": "Your Name",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/your-username/http-client"
35
+ },
36
+ "bugs": {
37
+ "url": "https://github.com/your-username/http-client/issues"
38
+ },
39
+ "homepage": "https://github.com/your-username/http-client#readme",
40
+ "dependencies": {
41
+ "axios": "^0.21.0"
42
+ },
43
+ "devDependencies": {
44
+ "@types/jest": "^29.5.0",
45
+ "@types/node": "^20.0.0",
46
+ "jest": "^29.5.0",
47
+ "ts-jest": "^29.1.0",
48
+ "typescript": "^5.0.0"
49
+ },
50
+ "engines": {
51
+ "node": ">=14.0.0"
52
+ },
53
+ "publishConfig": {
54
+ "access": "public"
55
+ }
56
+ }
@@ -0,0 +1,72 @@
1
+ import HttpClient from '../http-client';
2
+ import axios from 'axios';
3
+
4
+ jest.mock('axios');
5
+ const mockedAxios = axios as jest.Mocked<typeof axios>;
6
+
7
+ describe('HttpClient', () => {
8
+ let client: HttpClient;
9
+
10
+ beforeEach(() => {
11
+ jest.clearAllMocks();
12
+ mockedAxios.create.mockReturnValue({
13
+ get: jest.fn(),
14
+ post: jest.fn(),
15
+ put: jest.fn(),
16
+ patch: jest.fn(),
17
+ delete: jest.fn(),
18
+ head: jest.fn(),
19
+ options: jest.fn(),
20
+ defaults: {
21
+ headers: { common: {} },
22
+ },
23
+ interceptors: {
24
+ request: { use: jest.fn() },
25
+ response: { use: jest.fn() },
26
+ },
27
+ } as any);
28
+ client = new HttpClient();
29
+ });
30
+
31
+ it('should create an instance', () => {
32
+ expect(client).toBeTruthy();
33
+ expect(mockedAxios.create).toHaveBeenCalled();
34
+ });
35
+
36
+ it('should initialize with custom config', () => {
37
+ const customConfig = {
38
+ baseURL: 'https://api.example.com',
39
+ timeout: 5000,
40
+ };
41
+ new HttpClient(customConfig);
42
+ expect(mockedAxios.create).toHaveBeenCalledWith(
43
+ expect.objectContaining({
44
+ baseURL: customConfig.baseURL,
45
+ timeout: customConfig.timeout,
46
+ }),
47
+ );
48
+ });
49
+
50
+ it('should have all HTTP methods', () => {
51
+ expect(typeof client.get).toBe('function');
52
+ expect(typeof client.post).toBe('function');
53
+ expect(typeof client.put).toBe('function');
54
+ expect(typeof client.patch).toBe('function');
55
+ expect(typeof client.delete).toBe('function');
56
+ expect(typeof client.head).toBe('function');
57
+ expect(typeof client.options).toBe('function');
58
+ });
59
+
60
+ it('should provide setToken method', () => {
61
+ expect(typeof client.setToken).toBe('function');
62
+ });
63
+
64
+ it('should provide clearToken method', () => {
65
+ expect(typeof client.clearToken).toBe('function');
66
+ });
67
+
68
+ it('should expose axios instance', () => {
69
+ const instance = client.getAxiosInstance();
70
+ expect(instance).toBeDefined();
71
+ });
72
+ });
@@ -0,0 +1,237 @@
1
+ import axios, {
2
+ AxiosInstance,
3
+ AxiosRequestConfig,
4
+ AxiosResponse,
5
+ CancelTokenSource
6
+ } from 'axios'
7
+
8
+ type ErrorCodeMap = Record<string | number, string>
9
+
10
+ interface HttpClientOptions {
11
+ Notification: any
12
+ Message: any
13
+ store: any
14
+ getToken: () => string | null
15
+ errorCode: ErrorCodeMap
16
+ MessageDebounce: (msg: string) => void
17
+ baseURL: string
18
+ timeout?: number
19
+ loadingObj?: {
20
+ open: () => void
21
+ close: () => void
22
+ }
23
+ }
24
+
25
+ interface RequestOptions extends AxiosRequestConfig {
26
+ load?: boolean
27
+ delayTime?: number
28
+ time?: number
29
+ autoCancel?: boolean
30
+ }
31
+
32
+ interface CancelMap {
33
+ [key: string]: (msg?: string) => void
34
+ }
35
+
36
+ declare global {
37
+ interface Window {
38
+ cancelApiMap?: CancelMap
39
+ }
40
+ }
41
+
42
+ export default class HttpClient {
43
+ private requestFn: (options: {
44
+ method?: string
45
+ url: string
46
+ data?: any
47
+ params?: any
48
+ headers?: any
49
+ config?: RequestOptions
50
+ autoCancel?: boolean
51
+ }) => Promise<any>
52
+
53
+ private service: AxiosInstance
54
+
55
+ constructor(private opts: HttpClientOptions) {
56
+ const {
57
+ Notification,
58
+ Message,
59
+ store,
60
+ getToken,
61
+ errorCode,
62
+ MessageDebounce,
63
+ baseURL,
64
+ timeout = 5000,
65
+ loadingObj
66
+ } = opts
67
+
68
+ axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
69
+
70
+ this.service = axios.create({
71
+ baseURL,
72
+ timeout
73
+ })
74
+
75
+ // ================= 请求拦截 =================
76
+ this.service.interceptors.request.use(
77
+ (config: AxiosRequestConfig & any) => {
78
+ const isToken = config.headers?.isToken === false
79
+
80
+ const token = getToken()
81
+ if (token && !isToken) {
82
+ config.headers = {
83
+ ...config.headers,
84
+ Authorization: `Bearer ${token}`
85
+ }
86
+ }
87
+
88
+ // GET 参数拼接(保持你原逻辑)
89
+ if (config.method === 'get' && config.params) {
90
+ let url = config.url + '?'
91
+
92
+ for (const key of Object.keys(config.params)) {
93
+ const value = config.params[key]
94
+
95
+ const part = encodeURIComponent(key) + '='
96
+
97
+ if (value !== null && value !== undefined) {
98
+ if (typeof value === 'object') {
99
+ for (const subKey of Object.keys(value)) {
100
+ const subVal = value[subKey]
101
+ if (subVal !== null && subVal !== undefined) {
102
+ const paramsKey = `${key}[${subKey}]`
103
+ url +=
104
+ encodeURIComponent(paramsKey) +
105
+ '=' +
106
+ encodeURIComponent(subVal) +
107
+ '&'
108
+ }
109
+ }
110
+ } else {
111
+ url += part + encodeURIComponent(value) + '&'
112
+ }
113
+ }
114
+ }
115
+
116
+ url = url.slice(0, -1)
117
+ config.params = undefined
118
+ config.url = url
119
+ }
120
+
121
+ return config
122
+ },
123
+ (error) => Promise.reject(error)
124
+ )
125
+
126
+ // ================= 响应拦截 =================
127
+ this.service.interceptors.response.use(
128
+ (res: AxiosResponse<any>) => {
129
+ const code = res.data?.code ?? 200
130
+ const message =
131
+ errorCode[code] || res.data?.msg || errorCode['default']
132
+
133
+ if (code === 401) {
134
+ store.dispatch('LogOut').then(() => {
135
+ window.location.href = '/PI/index'
136
+ })
137
+ return Promise.reject('令牌验证失败')
138
+ }
139
+
140
+ if (code === 500) {
141
+ Message({
142
+ message,
143
+ type: 'error'
144
+ })
145
+ return Promise.reject({ message, code })
146
+ }
147
+
148
+ if (code !== 200) {
149
+ Notification.error({ title: message })
150
+ return Promise.reject({ message, code })
151
+ }
152
+
153
+ return res.data
154
+ },
155
+ (error) => {
156
+ let message: string = error.message
157
+
158
+ if (message === 'Network Error') {
159
+ message = '后端接口连接异常'
160
+ } else if (message.includes('timeout')) {
161
+ message = '系统接口请求超时'
162
+ } else if (message.includes('Request failed with status code')) {
163
+ message = `系统接口${message.slice(-3)}异常`
164
+ }
165
+
166
+ MessageDebounce(message)
167
+ return Promise.reject(error)
168
+ }
169
+ )
170
+
171
+ // ================= request 包装 =================
172
+ this.requestFn = async ({
173
+ method = 'get',
174
+ url,
175
+ data,
176
+ params,
177
+ headers,
178
+ config = {},
179
+ autoCancel = false
180
+ }) => {
181
+ const requestMethod =
182
+ method.toLowerCase() as AxiosRequestConfig['method']
183
+
184
+
185
+
186
+ if (method === 'post' || config.load) {
187
+ loadingObj?.open()
188
+ }
189
+
190
+ // ================= 取消请求 =================
191
+ if (autoCancel) {
192
+ if (!window.cancelApiMap) {
193
+ window.cancelApiMap = {}
194
+ }
195
+
196
+ const key = url + method
197
+
198
+ if (window.cancelApiMap[key]) {
199
+ return Promise.reject('阻止进程')
200
+ }
201
+
202
+ config.cancelToken = new axios.CancelToken((cancel) => {
203
+ window.cancelApiMap![key] = cancel
204
+ })
205
+ }
206
+
207
+ try {
208
+ const res = await this.service({
209
+ method: requestMethod,
210
+ url,
211
+ data,
212
+ params,
213
+ headers,
214
+ ...config
215
+ })
216
+
217
+ const delay = config.time || 1800
218
+
219
+ const result = await new Promise((resolve) => {
220
+ setTimeout(() => resolve(res), delay)
221
+ })
222
+
223
+ return result
224
+ } finally {
225
+ if (method === 'post' || config.load) {
226
+ setTimeout(() => {
227
+ loadingObj?.close()
228
+ }, config.delayTime || 1000)
229
+ }
230
+ }
231
+ }
232
+ }
233
+
234
+ public getRequest() {
235
+ return this.requestFn
236
+ }
237
+ }
package/src/index.ts ADDED
@@ -0,0 +1,21 @@
1
+ import HttpClient from './http-client';
2
+ import type {
3
+ RequestConfig,
4
+ HttpClientConfig,
5
+ RequestInterceptor,
6
+ ResponseInterceptor,
7
+ ErrorInterceptor,
8
+ } from './types';
9
+
10
+ // Default export
11
+ export default HttpClient;
12
+
13
+ // Named exports
14
+ export {
15
+ HttpClient,
16
+ RequestConfig,
17
+ HttpClientConfig,
18
+ RequestInterceptor,
19
+ ResponseInterceptor,
20
+ ErrorInterceptor,
21
+ };
package/src/types.ts ADDED
@@ -0,0 +1,30 @@
1
+ import { AxiosRequestConfig, AxiosResponse } from 'axios';
2
+
3
+ export interface RequestConfig extends AxiosRequestConfig {
4
+ showLoading?: boolean;
5
+ showError?: boolean;
6
+ timeout?: number;
7
+ }
8
+
9
+ export interface HttpClientConfig {
10
+ baseURL?: string;
11
+ timeout?: number;
12
+ headers?: Record<string, string>;
13
+ interceptors?: {
14
+ request?: (config: AxiosRequestConfig) => AxiosRequestConfig;
15
+ response?: (response: AxiosResponse) => AxiosResponse;
16
+ error?: (error: any) => Promise<any>;
17
+ };
18
+ }
19
+
20
+ export interface RequestInterceptor {
21
+ (config: AxiosRequestConfig): AxiosRequestConfig;
22
+ }
23
+
24
+ export interface ResponseInterceptor {
25
+ (response: AxiosResponse): AxiosResponse;
26
+ }
27
+
28
+ export interface ErrorInterceptor {
29
+ (error: any): Promise<any>;
30
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2015",
4
+ "module": "ESNext",
5
+ "lib": ["ESNext", "DOM"],
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "declaration": true,
13
+ "declarationMap": true,
14
+ "sourceMap": true,
15
+ "moduleResolution": "Node",
16
+ "resolveJsonModule": true,
17
+ "allowSyntheticDefaultImports": true
18
+ },
19
+ "include": ["src"],
20
+ "exclude": ["node_modules", "dist", "**/*.test.ts"]
21
+ }