@jetlinks-web/core 2.2.19 → 2.3.1

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/src/axios.ts CHANGED
@@ -1,354 +1,560 @@
1
1
  import { TOKEN_KEY, BASE_API, LOCAL_BASE_API } from '@jetlinks-web/constants'
2
- import {getToken, randomString} from '@jetlinks-web/utils'
2
+ import { getToken, randomString } from '@jetlinks-web/utils'
3
3
  import axios from 'axios'
4
+ import type { AxiosInstance } from 'axios'
5
+ import { isFunction, isObject } from 'lodash-es'
6
+
4
7
  import type {
5
- AxiosInstance,
6
- } from 'axios'
7
- import type { AxiosResponseRewrite } from '@jetlinks-web/types'
8
- import {isFunction, isObject} from 'lodash-es'
9
- import type { Options, ExpandRequestConfig, ExpandAxiosResponse, ExpandAxiosError, RequestOptions, PageResult, UpdateResult } from './type'
10
-
11
- export let instance: AxiosInstance = (window as any).JetlinksCore?.instance || null
12
-
13
- let _options: Options = {
14
- filter_url: [],
15
- code: 200,
16
- codeKey: 'status',
17
- timeout: 1000 * 15,
18
- handleRequest: undefined,
19
- handleResponse: undefined,
20
- handleError: undefined,
21
- langKey: 'lang',
22
- requestOptions: (config) => ({}),
23
- tokenExpiration: () => {},
24
- handleReconnect: () => Promise.resolve(),
25
- isCreateTokenRefresh: false
8
+ Options,
9
+ ExpandRequestConfig,
10
+ ExpandAxiosResponse,
11
+ AxiosResponseRewrite,
12
+ ExpandAxiosError,
13
+ RequestOptions,
14
+ PageResult,
15
+ UpdateResult
16
+ } from './type'
17
+
18
+ /**
19
+ * 扩展的 Options 接口,添加重复请求控制
20
+ */
21
+ export interface ExtendedOptions extends Options {
22
+ /**
23
+ * 是否取消重复请求,只保留最后一次
24
+ * @default false
25
+ */
26
+ cancelDuplicateRequests?: boolean
26
27
  }
27
28
 
28
- let failedQueue = [];
29
- let isRefreshing = false;
29
+ /**
30
+ * AxiosService 类 - 封装所有 axios 相关功能
31
+ */
32
+ export class AxiosService {
33
+ private instance: AxiosInstance | null = null
34
+ private options: ExtendedOptions
35
+ private failedQueue: Array<{ resolve: (token: string) => void; reject: (error: any) => void }> = []
36
+ private isRefreshing = false
37
+ private pendingRequests = new Map<string, AbortController>()
38
+ private isApp = (window as any).__MICRO_APP_ENVIRONMENT__
39
+
40
+ constructor(options?: Partial<ExtendedOptions>) {
41
+ this.options = {
42
+ filter_url: [],
43
+ code: 200,
44
+ codeKey: 'status',
45
+ timeout: 1000 * 15,
46
+ handleRequest: undefined,
47
+ handleResponse: undefined,
48
+ handleError: undefined,
49
+ langKey: 'lang',
50
+ requestOptions: (config) => ({}),
51
+ tokenExpiration: () => {},
52
+ handleReconnect: () => Promise.resolve(),
53
+ isCreateTokenRefresh: false,
54
+ cancelDuplicateRequests: false, // 默认关闭
55
+ ...options
56
+ }
30
57
 
31
- const isApp = (window as any).__MICRO_APP_ENVIRONMENT__
58
+ // 如果已经存在全局实例,使用它
59
+ if ((window as any).JetlinksCore?.instance) {
60
+ this.instance = (window as any).JetlinksCore.instance
61
+ }
62
+ }
32
63
 
33
- const pendingRequests = new Map<string, AbortController>();
34
- const requestRecords = (config: ExpandRequestConfig) => {
35
- const key = randomString(32)
64
+ /**
65
+ * 初始化 axios 实例
66
+ */
67
+ initialize(options?: Partial<ExtendedOptions>): void {
68
+ if (options) {
69
+ this.options = { ...this.options, ...options }
70
+ }
36
71
 
37
- // 取消重复请求
38
- if (pendingRequests.has(key)) {
39
- pendingRequests.get(key)?.abort()
72
+ this.instance = axios.create({
73
+ withCredentials: false,
74
+ timeout: this.options.timeout,
75
+ baseURL: BASE_API
76
+ })
77
+
78
+ this.instance.interceptors.request.use(
79
+ (config) => this.handleRequest(config as ExpandRequestConfig),
80
+ (error) => this.errorHandler(error)
81
+ )
82
+
83
+ this.instance.interceptors.response.use(
84
+ (response) => this.handleResponse(response as unknown as ExpandAxiosResponse),
85
+ (error) => this.errorHandler(error as ExpandAxiosError<any>)
86
+ )
40
87
  }
41
88
 
42
- const controller = new AbortController()
43
- config.signal = controller.signal;
44
- config.__requestKey = key;
45
-
46
- pendingRequests.set(key, controller)
47
- }
89
+ /**
90
+ * 获取 axios 实例
91
+ */
92
+ getInstance(): AxiosInstance {
93
+ if (!this.instance) {
94
+ this.initialize()
95
+ }
96
+ return this.instance!
97
+ }
48
98
 
49
- const handleRequest = (config: ExpandRequestConfig) => {
50
- requestRecords(config)
51
- const token = getToken();
52
- const lang = localStorage.getItem(_options.langKey)
53
- const localBaseApi = localStorage.getItem(LOCAL_BASE_API)
99
+ /**
100
+ * 生成请求的唯一标识
101
+ * 如果启用了 cancelDuplicateRequests,则基于 method + url + params/data
102
+ * 否则使用随机字符串
103
+ */
104
+ private generateRequestKey(config: ExpandRequestConfig): string {
105
+
106
+ // 统一接口请求的唯一标识
107
+ const method = config.method?.toUpperCase() || 'GET'
108
+ const url = config.url || ''
109
+
110
+ // 序列化参数,用于判断是否为同一请求
111
+ const params = config.params || {}
112
+ const data = config.data || {}
113
+ const payload = method === 'GET' ? params : data
114
+
115
+ // 生成稳定的请求标识
116
+ let payloadStr = ''
117
+ try {
118
+ payloadStr = JSON.stringify(payload, Object.keys(payload).sort())
119
+ } catch {
120
+ payloadStr = randomString(16) // 降级为随机标识
121
+ }
54
122
 
55
- if (lang) {
56
- config.headers[_options.langKey] = lang
123
+ return `${method}:${url}:${payloadStr}`
57
124
  }
58
125
 
59
- if (localBaseApi && !config.baseURL) {
60
- const _url = config.url.startsWith('/') ? config.url : `/${config.url}`
61
- config.url = localBaseApi + _url
62
- }
126
+ /**
127
+ * 记录请求 - 支持 AbortController
128
+ */
129
+ private requestRecords(config: ExpandRequestConfig): void {
130
+ if (!this.options.cancelDuplicateRequests) {
131
+ return
132
+ }
63
133
 
64
- // 没有token,并且该接口需要token校验
65
- if (!token && !_options.filter_url?.some((url) => config.url?.includes(url))) {
66
- // 跳转登录页
67
- _options.tokenExpiration?.()
68
- return config
69
- }
134
+ const key = this.generateRequestKey(config)
135
+
136
+ // 如果启用了取消重复请求,且存在相同的请求,则取消前一个
137
+ if (this.pendingRequests.has(key)) {
138
+ this.pendingRequests.get(key)?.abort()
139
+ this.pendingRequests.delete(key)
140
+ }
70
141
 
71
- if (!config.headers[TOKEN_KEY]) {
72
- config.headers[TOKEN_KEY] = token
142
+ const controller = new AbortController()
143
+ config.signal = controller.signal
144
+ config.__requestKey = key
145
+
146
+ this.pendingRequests.set(key, controller)
73
147
  }
74
148
 
75
- if (_options.requestOptions && isFunction(_options.requestOptions)) {
76
- const extraOptions = _options.requestOptions(config)
77
- if (extraOptions && isObject(extraOptions)) {
78
- for (const key in extraOptions) {
79
- config[key] = extraOptions[key]
149
+ /**
150
+ * 请求拦截器处理
151
+ */
152
+ private handleRequest(config: ExpandRequestConfig): ExpandRequestConfig {
153
+ this.requestRecords(config)
154
+ const token = getToken()
155
+ const lang = localStorage.getItem(this.options.langKey!)
156
+ const localBaseApi = localStorage.getItem(LOCAL_BASE_API)
157
+
158
+ if (lang) {
159
+ config.headers[this.options.langKey!] = lang
160
+ }
161
+
162
+ if (localBaseApi && !config.baseURL) {
163
+ const _url = config.url!.startsWith('/') ? config.url : `/${config.url}`
164
+ config.url = localBaseApi + _url
165
+ }
166
+
167
+ // 没有token,并且该接口需要token校验
168
+ if (!token && !this.options.filter_url?.some((url) => config.url?.includes(url))) {
169
+ this.options.tokenExpiration?.()
170
+ return config
171
+ }
172
+
173
+ if (!config.headers[TOKEN_KEY]) {
174
+ config.headers[TOKEN_KEY] = token
175
+ }
176
+
177
+ if (this.options.requestOptions && isFunction(this.options.requestOptions)) {
178
+ const extraOptions = this.options.requestOptions(config)
179
+ if (extraOptions && isObject(extraOptions)) {
180
+ for (const key in extraOptions) {
181
+ config[key] = extraOptions[key]
182
+ }
80
183
  }
81
184
  }
185
+
186
+ return config
82
187
  }
83
188
 
84
- return config
85
- }
189
+ /**
190
+ * 响应拦截器处理
191
+ */
192
+ private handleResponse(response: ExpandAxiosResponse): any {
193
+ const __key = response.config?.__requestKey
194
+ if (__key) {
195
+ this.pendingRequests.delete(__key)
196
+ }
86
197
 
87
- const handleResponse = (response: ExpandAxiosResponse) => {
88
- if (_options.handleResponse && isFunction(_options.handleResponse)) {
89
- return _options.handleResponse(response)
90
- }
198
+ if (this.options.handleResponse && isFunction(this.options.handleResponse)) {
199
+ return this.options.handleResponse(response)
200
+ }
91
201
 
92
- const __key = response.config?.__requestKey
93
- if(__key){
94
- pendingRequests.delete(__key)
95
- }
202
+ if (response.data instanceof ArrayBuffer) {
203
+ return response
204
+ }
96
205
 
97
- if (response.data instanceof ArrayBuffer) {
98
- return response
99
- }
206
+ const status = response.data[this.options.codeKey || 'status']
100
207
 
101
- const status = response.data[_options.codeKey || 'status']
208
+ // 增加业务接口处理成功判断方式,只需要判断返回参数包含:success为true
209
+ if (
210
+ typeof response.data === 'object' &&
211
+ typeof response.data.success === 'undefined'
212
+ ) {
213
+ response.data.success = status === this.options.code
214
+ }
102
215
 
103
- // 增加业务接口处理成功判断方式,只需要判断返回参数包含:success为true
104
- if (
105
- typeof response.data === 'object' &&
106
- typeof response.data.success === 'undefined'
107
- ) {
108
- response.data.success = status === _options.code
216
+ return response.data
109
217
  }
110
218
 
111
- return response.data
112
- }
219
+ /**
220
+ * Token 刷新处理
221
+ */
222
+ private async createTokenRefreshHandler(err: ExpandAxiosError<any>): Promise<any> {
223
+ const originalRequest = err.config!
224
+
225
+ if (this.isRefreshing) {
226
+ // 记录之后失败的请求
227
+ return new Promise((resolve, reject) => {
228
+ this.failedQueue.push({ resolve, reject })
229
+ })
230
+ .then((_token) => {
231
+ if (originalRequest.signal?.aborted) {
232
+ return Promise.reject(new axios.Cancel('Request aborted'))
233
+ }
234
+
235
+ originalRequest.headers[TOKEN_KEY] = _token
236
+ return this.instance!(originalRequest)
237
+ })
238
+ .catch((err) => Promise.reject(err))
239
+ }
240
+
241
+ originalRequest._retry = true
242
+ this.isRefreshing = true
113
243
 
114
- const createTokenRefreshHandler = async (err) => {
115
- const originalRequest = err.config;
116
- if (isRefreshing) { // 记录之后失败的请求
117
- return new Promise((resolve, reject) => {
118
- failedQueue.push({ resolve, reject });
119
- }).then((_token) => {
120
- originalRequest.headers[TOKEN_KEY] = _token;
121
- return instance(originalRequest)
122
- }).catch(err => Promise.reject(err))
123
- }
124
- originalRequest._retry = true;
125
- isRefreshing = true;
126
- try {
127
- const loginResult = await _options.handleReconnect?.()
128
- if(loginResult){
129
- const token = getToken() // 更新请求头, 修改全部的token
130
- originalRequest.headers[TOKEN_KEY] = token;
131
- failedQueue.forEach(a => a.resolve(token));
132
- return instance(originalRequest);
244
+ try {
245
+ const loginResult = await this.options.handleReconnect?.()
246
+ if (loginResult) {
247
+ const token = getToken() // 更新请求头, 修改全部的token
248
+ originalRequest.headers[TOKEN_KEY] = token
249
+ this.failedQueue.forEach((a) => a.resolve(token))
250
+ return this.instance!(originalRequest)
251
+ }
252
+ } catch (err) {
253
+ this.failedQueue.forEach((cb) => cb.reject(err))
254
+ throw err
255
+ } finally {
256
+ this.failedQueue = []
257
+ this.isRefreshing = false
133
258
  }
134
- } catch (err) {
135
- failedQueue.forEach(cb => cb.reject(err));
136
- throw err;
137
- } finally {
138
- failedQueue = [];
139
- isRefreshing = false;
140
259
  }
141
- }
142
- const errorHandler = async (err: ExpandAxiosError<any>) => {
143
- let description = err.response?.message || 'Error'
144
- let _status: string | number = 0
145
- if (err.response) {
146
- const {data, status} = err.response
147
- _status = status
148
- switch (status) {
149
- case 400:
150
- case 403:
151
- case 500:
152
- description = (`${data?.message}`).substring(0, 90)
153
- break;
154
- case 401:
155
- description = err.response.data.result?.text || '用户未登录';
156
- _options.tokenExpiration?.(err)
157
- if(_options.isCreateTokenRefresh){
158
- return createTokenRefreshHandler(err)
159
- }
160
- break;
161
- case 404:
162
- description = err?.response?.data?.message || `${data?.error} ${data?.path}`
163
- break;
164
- default:
165
- break;
260
+
261
+ /**
262
+ * 错误处理
263
+ */
264
+ private async errorHandler(err: ExpandAxiosError<any>): Promise<any> {
265
+ // 清理请求记录
266
+ const __key = err.config?.__requestKey
267
+ if (__key) {
268
+ this.pendingRequests.delete(__key)
166
269
  }
167
- } else if (err.response === undefined) {
168
- description = err.message.includes('timeout') ? '接口响应超时' : err.message
169
- _status = 'timeout'
170
- }
171
270
 
172
- if (_options.handleError && isFunction(_options.handleError)) {
173
- _options.handleError(description, _status, err)
174
- }
271
+ // 如果是用户主动取消的请求,不做错误处理
272
+ if (axios.isCancel(err as any)) {
273
+ return Promise.reject(err)
274
+ }
175
275
 
176
- return Promise.reject(err)
177
- }
276
+ let description = err.response?.message || 'Error'
277
+ let _status: string | number = 0
278
+
279
+ const response = err.response
280
+ if (response) {
281
+ const { data, status } = response
282
+ _status = status
283
+
284
+ switch (status) {
285
+ case 400:
286
+ case 403:
287
+ case 500:
288
+ description = `${data?.message}`.substring(0, 90)
289
+ break
290
+ case 401:
291
+ description = (data as any)?.result?.text || '用户未登录'
292
+ this.options.tokenExpiration?.(err as any)
293
+ if (this.options.isCreateTokenRefresh) {
294
+ return this.createTokenRefreshHandler(err)
295
+ }
296
+ break
297
+ case 404:
298
+ description = data?.message || `${(data as any)?.error} ${(data as any)?.path}`
299
+ break
300
+ default:
301
+ break
302
+ }
303
+ } else {
304
+ const errAny = err as any
305
+ if (errAny.message) {
306
+ description = errAny.message.includes('timeout') ? '接口响应超时' : errAny.message
307
+ _status = 'timeout'
308
+ }
309
+ }
178
310
 
179
- export const abortAllRequests = () => {
180
- pendingRequests.forEach(controller => controller.abort())
181
- pendingRequests.clear()
182
- }
311
+ if (this.options.handleError && isFunction(this.options.handleError)) {
312
+ const result = this.options.handleError(description, _status, err as any)
313
+ // 如果 handleError 返回了 Promise,则返回它以替换原始错误
314
+ if (result && typeof result.then === 'function') {
315
+ return result
316
+ }
317
+ }
183
318
 
184
- export const crateAxios = (options: Options) => {
185
- if (options) {
186
- _options = Object.assign(_options, options)
319
+ return Promise.reject(err)
187
320
  }
188
321
 
189
- instance = axios.create({
190
- withCredentials: false,
191
- timeout: _options.timeout,
192
- baseURL: BASE_API
193
- })
322
+ /**
323
+ * 取消所有进行中的请求
324
+ */
325
+ abortAllRequests(): void {
326
+ this.pendingRequests.forEach((controller) => controller.abort())
327
+ this.pendingRequests.clear()
328
+ }
194
329
 
195
- instance.interceptors.request.use(
196
- handleRequest,
197
- errorHandler
198
- )
330
+ /**
331
+ * 取消特定请求
332
+ */
333
+ abortRequest(requestKey: string): void {
334
+ const controller = this.pendingRequests.get(requestKey)
335
+ if (controller) {
336
+ controller.abort()
337
+ this.pendingRequests.delete(requestKey)
338
+ }
339
+ }
199
340
 
200
- instance.interceptors.response.use(
201
- handleResponse,
202
- errorHandler
203
- )
204
- }
341
+ /**
342
+ * 获取当前进行中的请求数量
343
+ */
344
+ getPendingRequestsCount(): number {
345
+ return this.pendingRequests.size
346
+ }
205
347
 
206
- export const post = <T = any>(url: string, data: any = {}, ext?: any) => {
207
- return (instance<any, AxiosResponseRewrite<T>>({
208
- method: 'POST',
209
- url,
210
- data,
211
- ...ext,
212
- }))
213
- }
348
+ /**
349
+ * HTTP 方法封装 - POST
350
+ */
351
+ post<T = any>(url: string, data: any = {}, ext?: any): Promise<AxiosResponseRewrite<T>> {
352
+ return this.getInstance()<any, AxiosResponseRewrite<T>>({
353
+ method: 'POST',
354
+ url,
355
+ data,
356
+ ...ext
357
+ })
358
+ }
214
359
 
215
- export const get = <T = any>(url: string, params: any = undefined, ext?: any) => {
216
- return instance<any, AxiosResponseRewrite<T>>({
217
- method: 'GET',
218
- url,
219
- params,
220
- ...ext,
221
- })
222
- }
360
+ /**
361
+ * HTTP 方法封装 - GET
362
+ */
363
+ get<T = any>(url: string, params: any = undefined, ext?: any): Promise<AxiosResponseRewrite<T>> {
364
+ return this.getInstance()<any, AxiosResponseRewrite<T>>({
365
+ method: 'GET',
366
+ url,
367
+ params,
368
+ ...ext
369
+ })
370
+ }
223
371
 
224
- export const put = <T = any>(url: string, data: any = {}, ext?: any) => {
225
- return instance<any, AxiosResponseRewrite<T>>({
226
- method: 'PUT',
227
- url,
228
- data,
229
- ...ext,
230
- })
231
- }
372
+ /**
373
+ * HTTP 方法封装 - PUT
374
+ */
375
+ put<T = any>(url: string, data: any = {}, ext?: any): Promise<AxiosResponseRewrite<T>> {
376
+ return this.getInstance()<any, AxiosResponseRewrite<T>>({
377
+ method: 'PUT',
378
+ url,
379
+ data,
380
+ ...ext
381
+ })
382
+ }
232
383
 
233
- export const patch = <T = any>(url: string, data: any = {}, ext?: any) => {
234
- return instance<any, AxiosResponseRewrite<T>>({
235
- method: 'patch',
236
- url,
237
- data,
238
- ...ext,
239
- })
240
- }
384
+ /**
385
+ * HTTP 方法封装 - PATCH
386
+ */
387
+ patch<T = any>(url: string, data: any = {}, ext?: any): Promise<AxiosResponseRewrite<T>> {
388
+ return this.getInstance()<any, AxiosResponseRewrite<T>>({
389
+ method: 'PATCH',
390
+ url,
391
+ data,
392
+ ...ext
393
+ })
394
+ }
241
395
 
242
- export const remove = <T = any>(url: string, params: any = undefined, ext?: any) => {
243
- return instance<any, AxiosResponseRewrite<T>>({
244
- method: 'DELETE',
245
- url,
246
- params,
247
- ...ext,
248
- })
249
- }
396
+ /**
397
+ * HTTP 方法封装 - DELETE
398
+ */
399
+ remove<T = any>(url: string, params: any = undefined, ext?: any): Promise<AxiosResponseRewrite<T>> {
400
+ return this.getInstance()<any, AxiosResponseRewrite<T>>({
401
+ method: 'DELETE',
402
+ url,
403
+ params,
404
+ ...ext
405
+ })
406
+ }
250
407
 
251
- export const getStream = (url: string, params?: any, ext?: any) => {
252
- return get(url, params, { responseType: 'arraybuffer', ...ext })
253
- }
408
+ /**
409
+ * 获取流数据 - GET
410
+ */
411
+ getStream(url: string, params?: any, ext?: any): Promise<any> {
412
+ return this.get(url, params, { responseType: 'arraybuffer', ...ext })
413
+ }
254
414
 
255
- export const postStream = (url: string, data: any, ext?: any) => {
256
- return post(url, data, { responseType: 'arraybuffer', ...ext })
415
+ /**
416
+ * 获取流数据 - POST
417
+ */
418
+ postStream(url: string, data: any, ext?: any): Promise<any> {
419
+ return this.post(url, data, { responseType: 'arraybuffer', ...ext })
420
+ }
257
421
  }
258
422
 
259
- export const request = {
260
- post, get, put, patch, remove, getStream, postStream
423
+ // 创建默认的 AxiosService 实例
424
+ const defaultAxiosService = new AxiosService()
425
+
426
+ // 导出默认实例和工厂函数
427
+ export const createAxiosService = (options?: Partial<ExtendedOptions>): AxiosService => {
428
+ const service = new AxiosService(options)
429
+ service.initialize()
430
+ return service
261
431
  }
262
432
 
433
+
434
+ /**
435
+ * Request 类 - 业务请求封装
436
+ * 默认使用全局共享的 axios 实例,特殊情况可传入自定义实例
437
+ */
263
438
  export class Request {
439
+ private _instance?: AxiosInstance
264
440
 
265
- constructor(public basePath: string) {
441
+ constructor(public basePath: string, instance?: AxiosInstance) {
266
442
  this.basePath = basePath.startsWith('/') ? basePath : `/${basePath}`
443
+ this._instance = instance
444
+ }
445
+
446
+ /**
447
+ * 获取 axios 实例
448
+ * 延迟获取以确保全局实例已初始化
449
+ */
450
+ private get instance(): AxiosInstance {
451
+ return this._instance || defaultAxiosService.getInstance()
267
452
  }
268
453
 
269
454
  private requestWrapper<T = any>(
270
455
  defaultUrl: string,
271
- defaultMethod: 'post'| 'get'| 'put'| 'patch'| 'remove'| 'getStream'| 'postStream',
456
+ defaultMethod: 'post' | 'get' | 'put' | 'patch' | 'remove' | 'getStream' | 'postStream',
272
457
  dataOrParams: any = {},
273
458
  options: RequestOptions = {}
274
459
  ): Promise<AxiosResponseRewrite<T>> {
275
460
  const { url = defaultUrl, method = defaultMethod, ...rest } = options
276
- return request[method]<T>(`${this.basePath}${url}`, dataOrParams, rest)
461
+ const fn = this[method] as (url: string, dataOrParams: any, options?: any) => Promise<AxiosResponseRewrite<T>>
462
+ return fn.call(this, url, dataOrParams, rest)
277
463
  }
278
464
 
279
465
  /**
280
466
  * 分页查询
281
- * @param {object} data 查询参数
282
- * @param {object} options 请求配置
467
+ * @param data 查询参数
468
+ * @param options 请求配置
283
469
  */
284
- page<T = any>(data: any={}, options: RequestOptions= {
285
- url: undefined,
286
- method: undefined,
287
- }) {
470
+ page<T = any>(
471
+ data: any = {},
472
+ options: RequestOptions = {
473
+ url: undefined,
474
+ method: undefined
475
+ }
476
+ ): Promise<AxiosResponseRewrite<PageResult<T>>> {
288
477
  return this.requestWrapper<PageResult<T>>('/_query', 'post', data, options)
289
478
  }
290
479
 
291
480
  /**
292
481
  * 不分页查询
293
- * @param {object} data 查询参数
294
- * @param {object} options 请求配置
482
+ * @param data 查询参数
483
+ * @param options 请求配置
295
484
  */
296
- noPage<T = any>(data: any={}, options: RequestOptions = {
297
- url: undefined,
298
- method: undefined,
299
- }) {
485
+ noPage<T = any>(
486
+ data: any = {},
487
+ options: RequestOptions = {
488
+ url: undefined,
489
+ method: undefined
490
+ }
491
+ ): Promise<AxiosResponseRewrite<T[]>> {
300
492
  return this.requestWrapper<T[]>('/_query/no-paging', 'post', { paging: false, ...data }, options)
301
493
  }
302
494
 
303
495
  /**
304
496
  * 详情查询
305
- * @param {string} id 详情ID
306
- * @param {object} params 查询参数
307
- * @param {object} options 请求配置
497
+ * @param id 详情ID
498
+ * @param params 查询参数
499
+ * @param options 请求配置
308
500
  */
309
- detail<T = any>(id: string, params?: any, options: RequestOptions= {
310
- url: undefined,
311
- method: undefined,
312
- }) {
501
+ detail<T = any>(
502
+ id: string,
503
+ params?: any,
504
+ options: RequestOptions = {
505
+ url: undefined,
506
+ method: undefined
507
+ }
508
+ ): Promise<AxiosResponseRewrite<T>> {
313
509
  return this.requestWrapper<T>(`/${id}/detail`, 'get', params, options)
314
510
  }
315
511
 
316
512
  /**
317
513
  * 保存
318
- * @param {object} data 保存参数
319
- * @param {object} options 请求配置
514
+ * @param data 保存参数
515
+ * @param options 请求配置
320
516
  */
321
- save<T = any>(data: any={}, options: RequestOptions = {
322
- url: undefined,
323
- method: undefined,
324
- }) {
517
+ save<T = any>(
518
+ data: any = {},
519
+ options: RequestOptions = {
520
+ url: undefined,
521
+ method: undefined
522
+ }
523
+ ): Promise<AxiosResponseRewrite<T>> {
325
524
  return this.requestWrapper<T>('', 'post', data, options)
326
525
  }
327
526
 
328
527
  /**
329
528
  * 更新
330
- * @param {object} data 更新参数
331
- * @param {object} options 请求配置
529
+ * @param data 更新参数
530
+ * @param options 请求配置
332
531
  */
333
- update<T extends UpdateResult>(data: any={}, options: RequestOptions = {
334
- url: undefined,
335
- method: undefined,
336
- }) {
532
+ update<T extends UpdateResult>(
533
+ data: any = {},
534
+ options: RequestOptions = {
535
+ url: undefined,
536
+ method: undefined
537
+ }
538
+ ): Promise<AxiosResponseRewrite<T>> {
337
539
  return this.requestWrapper<T>('', 'patch', data, options)
338
540
  }
339
541
 
340
542
  /**
341
543
  * 删除
342
- * @param {string} id 删除ID
343
- * @param {object} params 请求参数
344
- * @param {object} options 请求配置
544
+ * @param id 删除ID
545
+ * @param params 请求参数
546
+ * @param options 请求配置
345
547
  * @example ${basePath}/${id}
346
548
  */
347
- delete<T = any>(id: string, params?: any, options: RequestOptions = {
348
- url: undefined,
349
- method: undefined,
350
- }) {
351
- return this.requestWrapper<T>(`/${id}`, 'post', params, options)
549
+ delete<T = any>(
550
+ id: string,
551
+ params?: any,
552
+ options: RequestOptions = {
553
+ url: undefined,
554
+ method: undefined
555
+ }
556
+ ): Promise<AxiosResponseRewrite<T>> {
557
+ return this.requestWrapper<T>(`/${id}`, 'remove', params, options)
352
558
  }
353
559
 
354
560
  /**
@@ -357,39 +563,98 @@ export class Request {
357
563
  * @param type
358
564
  * @param options
359
565
  */
360
- batch<T = any>(data = {}, type?: string, options?: RequestOptions) {
566
+ batch<T = any>(data = {}, type?: string, options?: RequestOptions): Promise<AxiosResponseRewrite<T>> {
361
567
  const url = `/_batch${type ? '/' + type : ''}`
362
568
  return this.requestWrapper<T>(url, 'post', data, options)
363
569
  }
364
570
 
365
- post<T = any>(url: string, data?: any, options?: any) {
366
- return post<T>(`${this.basePath}${url}`, data, options)
571
+ post<T = any>(url: string, data?: any, options?: any): Promise<AxiosResponseRewrite<T>> {
572
+ return this.instance<any, AxiosResponseRewrite<T>>({
573
+ method: 'POST',
574
+ url: `${this.basePath}${url}`,
575
+ data,
576
+ ...options
577
+ })
367
578
  }
368
579
 
369
- get<T = any>(url: string, params?: any, options?: any) {
370
- return get<T>(`${this.basePath}${url}`, params, options)
580
+ get<T = any>(url: string, params?: any, options?: any): Promise<AxiosResponseRewrite<T>> {
581
+ return this.instance<any, AxiosResponseRewrite<T>>({
582
+ method: 'GET',
583
+ url: `${this.basePath}${url}`,
584
+ params,
585
+ ...options
586
+ })
371
587
  }
372
588
 
373
- put<T = any>(url: string, data?: any, options?: any) {
374
- return put<T>(`${this.basePath}${url}`, data, options)
589
+ put<T = any>(url: string, data?: any, options?: any): Promise<AxiosResponseRewrite<T>> {
590
+ return this.instance<any, AxiosResponseRewrite<T>>({
591
+ method: 'PUT',
592
+ url: `${this.basePath}${url}`,
593
+ data,
594
+ ...options
595
+ })
375
596
  }
376
597
 
377
- patch<T = any>(url: string, data?: any, options?: any) {
378
- return patch<T>(`${this.basePath}${url}`, data, options)
598
+ patch<T = any>(url: string, data?: any, options?: any): Promise<AxiosResponseRewrite<T>> {
599
+ return this.instance<any, AxiosResponseRewrite<T>>({
600
+ method: 'PATCH',
601
+ url: `${this.basePath}${url}`,
602
+ data,
603
+ ...options
604
+ })
379
605
  }
380
606
 
381
- remove<T = any>(url: string, params?: any, options?: any) {
382
- return remove<T>(`${this.basePath}${url}`, params, options)
607
+ remove<T = any>(url: string, params?: any, options?: any): Promise<AxiosResponseRewrite<T>> {
608
+ return this.instance<any, AxiosResponseRewrite<T>>({
609
+ method: 'DELETE',
610
+ url: `${this.basePath}${url}`,
611
+ params,
612
+ ...options
613
+ })
383
614
  }
384
615
 
385
- getStream(url: string, params?: any, options?: any) {
386
- return get(`${this.basePath}${url}`, params, { responseType: 'arraybuffer', ...options })
616
+ getStream(url: string, params?: any, options?: any): Promise<any> {
617
+ return this.get(`${url}`, params, { responseType: 'arraybuffer', ...options })
387
618
  }
388
619
 
389
- postStream(url: string, data?: any, options?: any) {
390
- return post(`${this.basePath}${url}`, data, { responseType: 'arraybuffer', ...options })
620
+ postStream(url: string, data?: any, options?: any): Promise<any> {
621
+ return this.post(`${url}`, data, { responseType: 'arraybuffer', ...options })
391
622
  }
392
623
  }
393
624
 
625
+ // 导出默认 request 对象(保持向后兼容)
626
+ export const request = {
627
+ post: defaultAxiosService.post.bind(defaultAxiosService),
628
+ get: defaultAxiosService.get.bind(defaultAxiosService),
629
+ put: defaultAxiosService.put.bind(defaultAxiosService),
630
+ patch: defaultAxiosService.patch.bind(defaultAxiosService),
631
+ remove: defaultAxiosService.remove.bind(defaultAxiosService),
632
+ getStream: defaultAxiosService.getStream.bind(defaultAxiosService),
633
+ postStream: defaultAxiosService.postStream.bind(defaultAxiosService)
634
+ }
635
+
636
+ // 导出便捷函数(保持向后兼容)
637
+ export const post = defaultAxiosService.post.bind(defaultAxiosService)
638
+ export const get = defaultAxiosService.get.bind(defaultAxiosService)
639
+ export const put = defaultAxiosService.put.bind(defaultAxiosService)
640
+ export const patch = defaultAxiosService.patch.bind(defaultAxiosService)
641
+ export const remove = defaultAxiosService.remove.bind(defaultAxiosService)
642
+ export const getStream = defaultAxiosService.getStream.bind(defaultAxiosService)
643
+ export const postStream = defaultAxiosService.postStream.bind(defaultAxiosService)
394
644
 
645
+ // 导出工具函数
646
+ export const abortAllRequests = () => defaultAxiosService.abortAllRequests()
647
+
648
+ export const getInstance = () => defaultAxiosService.getInstance()
649
+
650
+ // 导出 axios 实例(兼容旧代码)
651
+ export let instance: AxiosInstance
652
+
653
+ // 导出初始化函数(兼容旧代码)
654
+ export const crateAxios = (options: ExtendedOptions) => {
655
+ defaultAxiosService.initialize(options)
656
+ instance = defaultAxiosService.getInstance()
657
+ }
395
658
 
659
+ // 导出默认服务实例
660
+ export default defaultAxiosService