@robot-admin/request-core 0.2.0 → 0.4.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.
Files changed (59) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/LICENSE +21 -0
  3. package/README.md +248 -357
  4. package/SECURITY.md +14 -0
  5. package/dist/axios.cjs +134 -809
  6. package/dist/axios.cjs.map +1 -1
  7. package/dist/axios.d.cts +55 -220
  8. package/dist/axios.d.ts +55 -220
  9. package/dist/axios.js +2 -790
  10. package/dist/axios.js.map +1 -1
  11. package/dist/chunk-2JXH7SIL.js +711 -0
  12. package/dist/chunk-2JXH7SIL.js.map +1 -0
  13. package/dist/chunk-56QOEWUS.js +8 -0
  14. package/dist/chunk-56QOEWUS.js.map +1 -0
  15. package/dist/chunk-DUP3Y4DN.js +320 -0
  16. package/dist/chunk-DUP3Y4DN.js.map +1 -0
  17. package/dist/chunk-JGFRUAZT.cjs +1007 -0
  18. package/dist/chunk-JGFRUAZT.cjs.map +1 -0
  19. package/dist/chunk-KHI6XQRN.cjs +717 -0
  20. package/dist/chunk-KHI6XQRN.cjs.map +1 -0
  21. package/dist/chunk-OAZ5BUBU.js +969 -0
  22. package/dist/chunk-OAZ5BUBU.js.map +1 -0
  23. package/dist/chunk-QSDNDTOZ.js +28 -0
  24. package/dist/chunk-QSDNDTOZ.js.map +1 -0
  25. package/dist/chunk-UHXBAFY6.cjs +323 -0
  26. package/dist/chunk-UHXBAFY6.cjs.map +1 -0
  27. package/dist/chunk-WUZ43MLM.cjs +30 -0
  28. package/dist/chunk-WUZ43MLM.cjs.map +1 -0
  29. package/dist/chunk-WXHQXPS4.cjs +10 -0
  30. package/dist/chunk-WXHQXPS4.cjs.map +1 -0
  31. package/dist/crud.cjs +12 -484
  32. package/dist/crud.cjs.map +1 -1
  33. package/dist/crud.d.cts +8 -269
  34. package/dist/crud.d.ts +8 -269
  35. package/dist/crud.js +4 -487
  36. package/dist/crud.js.map +1 -1
  37. package/dist/index.cjs +136 -1302
  38. package/dist/index.cjs.map +1 -1
  39. package/dist/index.d.cts +7 -165
  40. package/dist/index.d.ts +7 -165
  41. package/dist/index.js +5 -1283
  42. package/dist/index.js.map +1 -1
  43. package/dist/naive.cjs +14 -0
  44. package/dist/naive.cjs.map +1 -0
  45. package/dist/naive.d.cts +9 -0
  46. package/dist/naive.d.ts +9 -0
  47. package/dist/naive.js +5 -0
  48. package/dist/naive.js.map +1 -0
  49. package/dist/types-BRDRqYFs.d.cts +197 -0
  50. package/dist/types-BVJhlSuh.d.cts +310 -0
  51. package/dist/types-BVJhlSuh.d.ts +310 -0
  52. package/dist/types-CUyibJZX.d.ts +197 -0
  53. package/dist/vue.cjs +93 -0
  54. package/dist/vue.cjs.map +1 -0
  55. package/dist/vue.d.cts +38 -0
  56. package/dist/vue.d.ts +38 -0
  57. package/dist/vue.js +71 -0
  58. package/dist/vue.js.map +1 -0
  59. package/package.json +60 -16
package/dist/index.cjs CHANGED
@@ -1,1310 +1,144 @@
1
1
  'use strict';
2
2
 
3
- var axios = require('axios');
4
- var vue = require('vue');
5
- var naiveUi = require('naive-ui');
3
+ var chunkUHXBAFY6_cjs = require('./chunk-UHXBAFY6.cjs');
4
+ var chunkWXHQXPS4_cjs = require('./chunk-WXHQXPS4.cjs');
5
+ var chunkWUZ43MLM_cjs = require('./chunk-WUZ43MLM.cjs');
6
+ require('./chunk-KHI6XQRN.cjs');
7
+ var chunkJGFRUAZT_cjs = require('./chunk-JGFRUAZT.cjs');
6
8
 
7
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
9
 
9
- var axios__default = /*#__PURE__*/_interopDefault(axios);
10
10
 
11
- // src/axios/request.ts
12
-
13
- // src/axios/plugins/request.ts
14
- var reLoginPromise = null;
15
- var reLoginResolve = null;
16
- var reLoginReject = null;
17
- function waitForReLogin() {
18
- if (!reLoginPromise) {
19
- reLoginPromise = new Promise((resolve, reject) => {
20
- reLoginResolve = resolve;
21
- reLoginReject = reject;
22
- }).finally(() => {
23
- reLoginPromise = null;
24
- reLoginResolve = null;
25
- reLoginReject = null;
26
- });
27
- }
28
- return reLoginPromise;
29
- }
30
- function getReLoginPromise() {
31
- return reLoginPromise;
32
- }
33
- function resolveReLogin() {
34
- if (reLoginResolve) {
35
- reLoginResolve();
36
- }
37
- }
38
- function rejectReLogin(reason) {
39
- if (reLoginReject) {
40
- reLoginReject(reason);
41
- }
42
- }
43
-
44
- // src/axios/utils/abort.ts
45
- function ensureSharedAbortController(config) {
46
- if (typeof AbortController === "undefined") return null;
47
- const existing = config.__abortController;
48
- if (existing) {
49
- existing._startTime ?? (existing._startTime = Date.now());
50
- config.signal = existing.signal;
51
- return existing;
52
- }
53
- const externalSignal = config.signal;
54
- const controller = new AbortController();
55
- controller._startTime = Date.now();
56
- if (externalSignal && externalSignal !== controller.signal) {
57
- config.__externalSignal = externalSignal;
58
- const forwardAbort = () => {
59
- if (!controller.signal.aborted) {
60
- controller.abort(externalSignal.reason);
61
- }
62
- };
63
- if (externalSignal.aborted) {
64
- forwardAbort();
65
- } else {
66
- externalSignal.addEventListener?.("abort", forwardAbort, { once: true });
67
- config.__abortCleanup = () => {
68
- externalSignal.removeEventListener?.("abort", forwardAbort);
69
- };
70
- }
71
- }
72
- config.__abortController = controller;
73
- config.signal = controller.signal;
74
- return controller;
75
- }
76
- function cleanupAbortContext(config) {
77
- if (!config) return;
78
- config.__abortCleanup?.();
79
- if (config.__externalSignal) {
80
- config.signal = config.__externalSignal;
81
- } else if (config.signal === config.__abortController?.signal) {
82
- delete config.signal;
83
- }
84
- delete config.__abortCleanup;
85
- delete config.__externalSignal;
86
- delete config.__abortController;
87
- }
88
-
89
- // src/axios/utils/helpers.ts
90
- var binaryObjectIds = /* @__PURE__ */ new WeakMap();
91
- var nextBinaryObjectId = 0;
92
- function getBinaryObjectId(value) {
93
- let id = binaryObjectIds.get(value);
94
- if (id === void 0) {
95
- id = ++nextBinaryObjectId;
96
- binaryObjectIds.set(value, id);
97
- }
98
- return id;
99
- }
100
- function sortedStringify(obj, seen = /* @__PURE__ */ new WeakSet()) {
101
- if (obj === null || obj === void 0) {
102
- return "";
103
- }
104
- if (typeof obj === "bigint") return `bigint:${obj.toString()}`;
105
- if (typeof obj !== "object") {
106
- return `${typeof obj}:${String(obj)}`;
107
- }
108
- if (seen.has(obj)) {
109
- throw new Error("\u68C0\u6D4B\u5230\u5FAA\u73AF\u5F15\u7528\uFF0C\u65E0\u6CD5\u751F\u6210\u7A33\u5B9A\u7684\u7F13\u5B58\u952E");
110
- }
111
- seen.add(obj);
112
- try {
113
- if (Array.isArray(obj)) {
114
- return `[${obj.map((item) => sortedStringify(item, seen)).join(",")}]`;
115
- }
116
- if (obj instanceof Date) return `date:${obj.toISOString()}`;
117
- if (typeof URLSearchParams !== "undefined" && obj instanceof URLSearchParams) {
118
- return `url-search:${JSON.stringify(Array.from(obj.entries()).sort())}`;
119
- }
120
- if (typeof FormData !== "undefined" && obj instanceof FormData) {
121
- const entries = Array.from(obj.entries()).map(([key, value]) => [
122
- key,
123
- typeof value === "string" ? `string:${value}` : `binary:${getBinaryObjectId(value)}:${value.name}:${value.size}:${value.type}`
124
- ]);
125
- return `form-data:${JSON.stringify(entries)}`;
126
- }
127
- if (typeof Blob !== "undefined" && obj instanceof Blob || obj instanceof ArrayBuffer || ArrayBuffer.isView(obj)) {
128
- return `binary:${getBinaryObjectId(obj)}`;
129
- }
130
- const source = typeof obj.toJSON === "function" && obj.constructor?.name === "AxiosHeaders" ? obj.toJSON() : obj;
131
- const sortedKeys = Object.keys(source).sort();
132
- return `{${sortedKeys.map((key) => `${JSON.stringify(key)}:${sortedStringify(source[key], seen)}`).join(",")}}`;
133
- } finally {
134
- seen.delete(obj);
135
- }
136
- }
137
- function generateRequestKey(config) {
138
- const { method = "get", url = "", params, data, headers } = config;
139
- const parts = [method.toUpperCase(), url];
140
- if (params != null) {
141
- parts.push(sortedStringify(params));
142
- }
143
- if (data != null) {
144
- parts.push(sortedStringify(data));
145
- }
146
- if (headers) {
147
- const authHeaders = {};
148
- const authKeys = ["authorization", "x-tenant-id", "x-user-id"];
149
- const lowerHeaders = {};
150
- const headerSource = typeof headers.toJSON === "function" ? headers.toJSON() : headers;
151
- for (const [k, v] of Object.entries(headerSource)) {
152
- lowerHeaders[String(k).toLowerCase()] = v;
153
- }
154
- for (const key of authKeys) {
155
- if (lowerHeaders[key] != null) {
156
- authHeaders[key] = String(lowerHeaders[key]);
157
- }
158
- }
159
- if (Object.keys(authHeaders).length > 0) {
160
- parts.push(sortedStringify(authHeaders));
161
- }
162
- }
163
- return parts.join("|");
164
- }
165
- var MemoryCache = class {
166
- constructor() {
167
- this.cache = /* @__PURE__ */ new Map();
168
- this.maxSize = 1e3;
169
- // 最大缓存数量
170
- this.accessOrder = /* @__PURE__ */ new Set();
171
- }
172
- // 记录访问顺序
173
- /**
174
- * 获取缓存
175
- */
176
- get(key) {
177
- const item = this.cache.get(key);
178
- if (!item) return null;
179
- if (Date.now() > item.expireAt) {
180
- this.cache.delete(key);
181
- this.accessOrder.delete(key);
182
- return null;
183
- }
184
- this.accessOrder.delete(key);
185
- this.accessOrder.add(key);
186
- return item.data;
187
- }
188
- /**
189
- * 设置缓存
190
- */
191
- set(key, data, ttl) {
192
- if (!Number.isFinite(ttl) || ttl < 0) {
193
- throw new RangeError("\u7F13\u5B58 TTL \u5FC5\u987B\u662F\u5927\u4E8E\u6216\u7B49\u4E8E 0 \u7684\u6709\u9650\u6570\u503C");
194
- }
195
- if (this.maxSize === 0) return;
196
- if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
197
- this.evictOldest();
198
- }
199
- const expireAt = Date.now() + ttl;
200
- this.cache.set(key, {
201
- data,
202
- expireAt
203
- });
204
- this.accessOrder.delete(key);
205
- this.accessOrder.add(key);
206
- }
207
- /**
208
- * 删除缓存
209
- */
210
- delete(key) {
211
- this.accessOrder.delete(key);
212
- return this.cache.delete(key);
213
- }
214
- /**
215
- * 清空所有缓存
216
- */
217
- clear() {
218
- this.cache.clear();
219
- this.accessOrder.clear();
220
- }
221
- /**
222
- * 清理过期缓存
223
- */
224
- cleanup() {
225
- const now = Date.now();
226
- const entries = Array.from(this.cache.entries());
227
- for (const [key, item] of entries) {
228
- if (now > item.expireAt) {
229
- this.cache.delete(key);
230
- this.accessOrder.delete(key);
231
- }
232
- }
233
- }
234
- /**
235
- * 获取缓存大小
236
- */
237
- get size() {
238
- return this.cache.size;
239
- }
240
- /**
241
- * 设置最大缓存大小
242
- */
243
- setMaxSize(size) {
244
- if (!Number.isInteger(size) || size < 0) {
245
- throw new RangeError("\u7F13\u5B58\u6700\u5927\u5BB9\u91CF\u5FC5\u987B\u662F\u5927\u4E8E\u6216\u7B49\u4E8E 0 \u7684\u6574\u6570");
246
- }
247
- this.maxSize = size;
248
- while (this.cache.size > this.maxSize) {
249
- this.evictOldest();
250
- }
251
- }
252
- /**
253
- * 清理最旧的缓存(LRU)
254
- */
255
- evictOldest() {
256
- const oldestKey = this.accessOrder.values().next().value;
257
- if (oldestKey) {
258
- this.cache.delete(oldestKey);
259
- this.accessOrder.delete(oldestKey);
260
- }
261
- }
262
- };
263
- var globalCache = new MemoryCache();
264
- function delay(ms, signal) {
265
- if (signal?.aborted) {
266
- return Promise.reject(createAbortError(signal.reason));
267
- }
268
- return new Promise((resolve, reject) => {
269
- const timer = setTimeout(() => {
270
- signal?.removeEventListener?.("abort", onAbort);
271
- resolve();
272
- }, Math.max(0, Number.isFinite(ms) ? ms : 0));
273
- const onAbort = () => {
274
- clearTimeout(timer);
275
- signal?.removeEventListener?.("abort", onAbort);
276
- reject(createAbortError(signal?.reason));
277
- };
278
- signal?.addEventListener?.("abort", onAbort, { once: true });
279
- });
280
- }
281
- function createAbortError(reason) {
282
- if (reason instanceof Error) return reason;
283
- return Object.assign(new Error("canceled"), {
284
- name: "AbortError",
285
- code: "ERR_CANCELED",
286
- reason
287
- });
288
- }
289
- function isNetworkError(error) {
290
- return !error.response && Boolean(error.code) && error.code !== "ECONNABORTED" && error.code !== "ERR_CANCELED" && error.message !== "canceled" && error.message !== "Request aborted" && error.message !== "Request cancelled";
291
- }
292
- function isTimeoutError(error) {
293
- return error?.code === "ECONNABORTED" || error?.code === "ETIMEDOUT";
294
- }
295
- function isRetryableStatus(status, retryableStatusCodes) {
296
- return retryableStatusCodes.includes(status);
297
- }
298
- function normalizeConfig(config, defaults) {
299
- if (config === true) {
300
- return { ...defaults, enabled: true };
301
- }
302
- if (config === false) {
303
- return { ...defaults, enabled: false };
304
- }
305
- if (config && typeof config === "object") {
306
- const definedEntries = Object.entries(config).filter(
307
- ([, value]) => value !== void 0
308
- );
309
- return { ...defaults, ...Object.fromEntries(definedEntries) };
310
- }
311
- return defaults;
312
- }
313
-
314
- // src/axios/plugins/dedupe.ts
315
- var DEFAULT_DEDUPE_CONFIG = {
316
- enabled: true,
317
- keyGenerator: generateRequestKey
318
- };
319
- var pendingRequests = /* @__PURE__ */ new Map();
320
- var CLEANUP_INTERVAL = 3e4;
321
- var REQUEST_TIMEOUT = 5 * 60 * 1e3;
322
- var cleanupTimer = null;
323
- function cleanupExpiredRequests() {
324
- const now = Date.now();
325
- Array.from(pendingRequests.entries()).forEach(([key, controller]) => {
326
- const startTime = controller._startTime || now;
327
- if (now - startTime > REQUEST_TIMEOUT) {
328
- try {
329
- controller.abort();
330
- } catch (error) {
331
- console.warn("Abort error:", error);
332
- }
333
- pendingRequests.delete(key);
334
- }
335
- });
336
- stopCleanupTimerIfIdle();
337
- }
338
- function startCleanupTimer() {
339
- if (cleanupTimer) return;
340
- cleanupTimer = setInterval(cleanupExpiredRequests, CLEANUP_INTERVAL);
341
- cleanupTimer.unref?.();
342
- }
343
- function stopCleanupTimerIfIdle() {
344
- if (pendingRequests.size === 0 && cleanupTimer) {
345
- clearInterval(cleanupTimer);
346
- cleanupTimer = null;
347
- }
348
- }
349
- function removePendingRequest(config) {
350
- const requestKey = config.__requestKey;
351
- const controller = config.__abortController;
352
- if (requestKey && controller && pendingRequests.get(requestKey) === controller) {
353
- pendingRequests.delete(requestKey);
354
- }
355
- stopCleanupTimerIfIdle();
356
- }
357
- function onRequest(config) {
358
- const enhancedConfig = config;
359
- const dedupeConfig = normalizeConfig(
360
- enhancedConfig.dedupe,
361
- DEFAULT_DEDUPE_CONFIG
362
- );
363
- if (!dedupeConfig.enabled) {
364
- return config;
365
- }
366
- if (config.__fromCache) {
367
- return config;
368
- }
369
- const keyGenerator = dedupeConfig.keyGenerator || DEFAULT_DEDUPE_CONFIG.keyGenerator;
370
- const requestKey = keyGenerator(config);
371
- const existing = pendingRequests.get(requestKey);
372
- if (existing) {
373
- try {
374
- existing.abort();
375
- } catch (error) {
376
- console.warn("Abort existing request error:", error);
377
- }
378
- pendingRequests.delete(requestKey);
379
- }
380
- const controller = ensureSharedAbortController(enhancedConfig);
381
- if (!controller) return config;
382
- enhancedConfig.__requestKey = requestKey;
383
- pendingRequests.set(requestKey, controller);
384
- startCleanupTimer();
385
- return config;
386
- }
387
- function onResponse(response) {
388
- const config = response.config;
389
- removePendingRequest(config);
390
- return response;
391
- }
392
- function onResponseError(error) {
393
- const config = error.config;
394
- if (config) {
395
- removePendingRequest(config);
396
- }
397
- return Promise.reject(error);
398
- }
399
- function setupDedupePlugin(instance) {
400
- instance.interceptors.request.use(onRequest);
401
- instance.interceptors.response.use(onResponse, onResponseError);
402
- }
403
- function cancelAllPendingRequests() {
404
- pendingRequests.forEach((controller) => {
405
- try {
406
- controller.abort();
407
- } catch (error) {
408
- console.warn("Error aborting pending request:", error);
409
- }
410
- });
411
- pendingRequests.clear();
412
- stopCleanupTimerIfIdle();
413
- }
414
- function getPendingRequestCount() {
415
- return pendingRequests.size;
416
- }
417
-
418
- // src/axios/plugins/cache.ts
419
- var DEFAULT_CACHE_CONFIG = {
420
- enabled: false,
421
- ttl: 5 * 60 * 1e3,
422
- // 5 分钟
423
- forceUpdate: false
424
- };
425
- function shouldUseCache(config, cacheConfig) {
426
- if (config.method?.toUpperCase() !== "GET") {
427
- return false;
428
- }
429
- if (!cacheConfig.enabled) {
430
- return false;
431
- }
432
- if (cacheConfig.forceUpdate) {
433
- return false;
434
- }
435
- return true;
436
- }
437
- function createCacheResponse(cachedData, config) {
438
- return {
439
- data: cachedData.data,
440
- status: cachedData.status,
441
- statusText: `${cachedData.statusText} (from cache)`,
442
- headers: cachedData.headers,
443
- config
444
- };
445
- }
446
- function tryGetFromCache(config, cacheConfig) {
447
- if (!shouldUseCache(config, cacheConfig)) {
448
- return null;
449
- }
450
- const requestKey = generateRequestKey(config);
451
- const cachedData = globalCache.get(requestKey);
452
- if (cachedData) {
453
- return createCacheResponse(cachedData, config);
454
- }
455
- return null;
456
- }
457
- function saveToCache(response, config, cacheConfig) {
458
- if (config.method?.toUpperCase() === "GET" && cacheConfig.enabled && response.status === 200) {
459
- const requestKey = generateRequestKey(config);
460
- const ttl = cacheConfig.ttl ?? DEFAULT_CACHE_CONFIG.ttl;
461
- const cachedResponse = {
462
- data: response.data,
463
- status: response.status,
464
- statusText: response.statusText,
465
- headers: { ...response.headers }
466
- };
467
- globalCache.set(requestKey, cachedResponse, ttl);
468
- }
469
- }
470
- function onRequest2(config) {
471
- const enhancedConfig = config;
472
- const cacheConfig = normalizeConfig(
473
- enhancedConfig.cache,
474
- DEFAULT_CACHE_CONFIG
475
- );
476
- const cachedResponse = tryGetFromCache(config, cacheConfig);
477
- if (cachedResponse) {
478
- config.__fromCache = true;
479
- return Promise.reject({
480
- __fromCache: true,
481
- __cachedResponse: cachedResponse,
482
- config
483
- });
484
- }
485
- return config;
486
- }
487
- function onResponse2(response) {
488
- const config = response.config;
489
- if (config.__fromCache) {
490
- return config.__cachedResponse;
491
- }
492
- const cacheConfig = normalizeConfig(
493
- config.cache,
494
- DEFAULT_CACHE_CONFIG
495
- );
496
- saveToCache(response, response.config, cacheConfig);
497
- return response;
498
- }
499
- function onResponseError2(error) {
500
- if (error.__fromCache) {
501
- return Promise.resolve(error.__cachedResponse);
502
- }
503
- return Promise.reject(error);
504
- }
505
- function setupCachePlugin(instance) {
506
- instance.interceptors.request.use(onRequest2);
507
- instance.interceptors.response.use(onResponse2, onResponseError2);
508
- }
509
- function clearAllCache() {
510
- globalCache.clear();
511
- }
512
- function clearCache(config) {
513
- const requestKey = generateRequestKey(config);
514
- return globalCache.delete(requestKey);
515
- }
516
- function cleanupExpiredCache() {
517
- globalCache.cleanup();
518
- }
519
- function getCacheSize() {
520
- return globalCache.size;
521
- }
522
-
523
- // src/axios/plugins/retry.ts
524
- var DEFAULT_RETRY_CONFIG = {
525
- enabled: false,
526
- count: 3,
527
- delay: 1e3,
528
- exponentialBackoff: true,
529
- jitter: true,
530
- retryableStatusCodes: [408, 429, 500, 502, 503, 504],
531
- // 默认仅重试幂等方法,避免对 POST 等非幂等请求重复执行造成副作用(重复扣款/重复创建)
532
- retryableMethods: ["GET", "HEAD", "OPTIONS", "PUT", "DELETE"]
533
- };
534
- function isCancelError(error) {
535
- return error?.name === "CanceledError" || error?.name === "AbortError" || error?.code === "ERR_CANCELED";
536
- }
537
- function shouldRetry(error, retryConfig) {
538
- if (!retryConfig.enabled) {
539
- return false;
540
- }
541
- const config = error.config;
542
- const currentRetryCount = config.__retryCount ?? 0;
543
- if (currentRetryCount >= retryConfig.count) {
544
- return false;
545
- }
546
- if (isCancelError(error)) {
547
- return false;
548
- }
549
- const method = (config.method || "get").toUpperCase();
550
- if (!retryConfig.retryableMethods.some(
551
- (retryableMethod) => retryableMethod.toUpperCase() === method
552
- )) {
553
- return false;
554
- }
555
- if (isNetworkError(error)) {
556
- return true;
557
- }
558
- if (isTimeoutError(error)) {
559
- return true;
560
- }
561
- if (error.response?.status) {
562
- return isRetryableStatus(
563
- error.response.status,
564
- retryConfig.retryableStatusCodes
565
- );
566
- }
567
- return false;
568
- }
569
- function getRetryDelay(retryCount, retryConfig) {
570
- let calculated;
571
- if (!retryConfig.exponentialBackoff) {
572
- calculated = retryConfig.delay;
573
- } else {
574
- calculated = retryConfig.delay * Math.pow(2, retryCount - 1);
575
- }
576
- if (retryConfig.jitter) {
577
- const factor = 0.75 + Math.random() * 0.5;
578
- calculated = Math.round(calculated * factor);
579
- }
580
- return Math.min(Math.max(0, calculated), 3e4);
581
- }
582
- function setupRetryPlugin(instance) {
583
- const onResponseError4 = async (error) => {
584
- const config = error.config;
585
- if (!config) {
586
- return Promise.reject(error);
587
- }
588
- const retryConfig = normalizeConfig(
589
- config.retry,
590
- DEFAULT_RETRY_CONFIG
591
- );
592
- if (!shouldRetry(error, retryConfig)) {
593
- return Promise.reject(error);
594
- }
595
- config.__retryCount = (config.__retryCount ?? 0) + 1;
596
- const retryDelay = getRetryDelay(config.__retryCount, retryConfig);
597
- try {
598
- await delay(retryDelay, config.signal);
599
- } catch (abortError) {
600
- const error_ = Object.assign(new Error("canceled"), {
601
- name: "CanceledError",
602
- code: "ERR_CANCELED",
603
- config,
604
- cause: abortError
605
- });
606
- return Promise.reject(error_);
607
- }
608
- const retryConfig_ = { ...config };
609
- delete retryConfig_.__cancelId;
610
- delete retryConfig_.__requestKey;
611
- return instance.request(retryConfig_);
612
- };
613
- instance.interceptors.response.use(void 0, onResponseError4);
614
- }
615
-
616
- // src/axios/plugins/response.ts
617
- function setupResponsePlugin(instance) {
618
- instance.interceptors.response.use(
619
- (response) => {
620
- cleanupAbortContext(response.config);
621
- return response;
622
- },
623
- (error) => {
624
- cleanupAbortContext(error?.config);
625
- return Promise.reject(error);
626
- }
627
- );
628
- }
629
-
630
- // src/axios/plugins/cancel.ts
631
- var DEFAULT_CANCEL_CONFIG = {
632
- enabled: true,
633
- whitelist: []
634
- };
635
- var cancelableRequests = /* @__PURE__ */ new Map();
636
- var requestId = 0;
637
- var CLEANUP_INTERVAL2 = 3e4;
638
- var REQUEST_TIMEOUT2 = 3e5;
639
- var cleanupTimer2 = null;
640
- function cleanupExpiredRequests2() {
641
- const now = Date.now();
642
- const expiredKeys = [];
643
- for (const [key, controller] of cancelableRequests.entries()) {
644
- const requestStartTime = controller._startTime || now;
645
- if (now - requestStartTime > REQUEST_TIMEOUT2) {
646
- expiredKeys.push(key);
647
- try {
648
- controller.abort();
649
- } catch (error) {
650
- console.warn("Error aborting expired request:", error);
651
- }
652
- }
653
- }
654
- expiredKeys.forEach((key) => cancelableRequests.delete(key));
655
- stopCleanupTimerIfIdle2();
656
- }
657
- function startCleanupTimer2() {
658
- if (cleanupTimer2) return;
659
- cleanupTimer2 = setInterval(cleanupExpiredRequests2, CLEANUP_INTERVAL2);
660
- cleanupTimer2.unref?.();
661
- }
662
- function stopCleanupTimer() {
663
- if (cleanupTimer2) {
664
- clearInterval(cleanupTimer2);
665
- cleanupTimer2 = null;
666
- }
667
- }
668
- function stopCleanupTimerIfIdle2() {
669
- if (cancelableRequests.size === 0) stopCleanupTimer();
670
- }
671
- function isInWhitelist(url, whitelist) {
672
- return whitelist.some((pattern) => pattern.test(url));
673
- }
674
- function onRequest3(config) {
675
- const enhancedConfig = config;
676
- const cancelConfig = normalizeConfig(
677
- enhancedConfig.cancel,
678
- DEFAULT_CANCEL_CONFIG
679
- );
680
- if (!cancelConfig.enabled) {
681
- return config;
682
- }
683
- if (config.__fromCache) {
684
- return config;
685
- }
686
- const url = config.url || "";
687
- if (isInWhitelist(url, cancelConfig.whitelist)) {
688
- return config;
689
- }
690
- const activeController = ensureSharedAbortController(enhancedConfig);
691
- if (!activeController) return config;
692
- const id = `request_${++requestId}`;
693
- enhancedConfig.__cancelId = id;
694
- cancelableRequests.set(id, activeController);
695
- startCleanupTimer2();
696
- return config;
697
- }
698
- function onResponse3(response) {
699
- const config = response.config;
700
- const cancelId = config.__cancelId;
701
- if (cancelId) {
702
- cancelableRequests.delete(cancelId);
703
- stopCleanupTimerIfIdle2();
704
- }
705
- return response;
706
- }
707
- function onResponseError3(error) {
708
- const config = error.config;
709
- const cancelId = config?.__cancelId;
710
- if (cancelId) {
711
- cancelableRequests.delete(cancelId);
712
- stopCleanupTimerIfIdle2();
713
- }
714
- return Promise.reject(error);
715
- }
716
- function setupCancelPlugin(instance) {
717
- instance.interceptors.request.use(onRequest3);
718
- instance.interceptors.response.use(onResponse3, onResponseError3);
719
- }
720
- function cancelAllRequests() {
721
- cancelableRequests.forEach((controller) => {
722
- try {
723
- controller.abort();
724
- } catch (error) {
725
- console.warn("Error aborting request:", error);
726
- }
727
- });
728
- cancelableRequests.clear();
729
- stopCleanupTimer();
730
- }
731
- function getCancelableRequestCount() {
732
- return cancelableRequests.size;
733
- }
734
-
735
- // src/axios/plugins/index.ts
736
- function setupPlugins(instance) {
737
- setupCachePlugin(instance);
738
- setupCancelPlugin(instance);
739
- setupDedupePlugin(instance);
740
- setupRetryPlugin(instance);
741
- setupResponsePlugin(instance);
742
- }
743
-
744
- // src/axios/service.ts
745
- var globalService = null;
746
- function setGlobalAxiosInstance(instance) {
747
- globalService = instance;
748
- }
749
- function getGlobalAxiosInstance() {
750
- if (!globalService) {
751
- throw new Error(
752
- "Axios instance not initialized. Please call createRequestCore() or setGlobalAxiosInstance() first."
753
- );
754
- }
755
- return globalService;
756
- }
757
- new Proxy({}, {
758
- get(_target, prop) {
759
- return getGlobalAxiosInstance()[prop];
760
- }
11
+ Object.defineProperty(exports, "createRequestClient", {
12
+ enumerable: true,
13
+ get: function () { return chunkUHXBAFY6_cjs.createRequestClient; }
14
+ });
15
+ Object.defineProperty(exports, "setDefaultRequestClient", {
16
+ enumerable: true,
17
+ get: function () { return chunkUHXBAFY6_cjs.setDefaultRequestClient; }
18
+ });
19
+ Object.defineProperty(exports, "useTableCrud", {
20
+ enumerable: true,
21
+ get: function () { return chunkWXHQXPS4_cjs.useTableCrud; }
22
+ });
23
+ Object.defineProperty(exports, "useNaiveTableCrud", {
24
+ enumerable: true,
25
+ get: function () { return chunkWUZ43MLM_cjs.useNaiveTableCrud; }
26
+ });
27
+ Object.defineProperty(exports, "MemoryCache", {
28
+ enumerable: true,
29
+ get: function () { return chunkJGFRUAZT_cjs.MemoryCache; }
30
+ });
31
+ Object.defineProperty(exports, "RequestError", {
32
+ enumerable: true,
33
+ get: function () { return chunkJGFRUAZT_cjs.RequestError; }
34
+ });
35
+ Object.defineProperty(exports, "cancelAllPendingRequests", {
36
+ enumerable: true,
37
+ get: function () { return chunkJGFRUAZT_cjs.cancelAllPendingRequests; }
38
+ });
39
+ Object.defineProperty(exports, "cancelAllRequests", {
40
+ enumerable: true,
41
+ get: function () { return chunkJGFRUAZT_cjs.cancelAllRequests; }
42
+ });
43
+ Object.defineProperty(exports, "cancelRequestScope", {
44
+ enumerable: true,
45
+ get: function () { return chunkJGFRUAZT_cjs.cancelRequestScope; }
46
+ });
47
+ Object.defineProperty(exports, "cleanupExpiredCache", {
48
+ enumerable: true,
49
+ get: function () { return chunkJGFRUAZT_cjs.cleanupExpiredCache; }
50
+ });
51
+ Object.defineProperty(exports, "clearAllCache", {
52
+ enumerable: true,
53
+ get: function () { return chunkJGFRUAZT_cjs.clearAllCache; }
54
+ });
55
+ Object.defineProperty(exports, "clearCache", {
56
+ enumerable: true,
57
+ get: function () { return chunkJGFRUAZT_cjs.clearCache; }
58
+ });
59
+ Object.defineProperty(exports, "clearCacheByPrefix", {
60
+ enumerable: true,
61
+ get: function () { return chunkJGFRUAZT_cjs.clearCacheByPrefix; }
62
+ });
63
+ Object.defineProperty(exports, "clearCacheByTag", {
64
+ enumerable: true,
65
+ get: function () { return chunkJGFRUAZT_cjs.clearCacheByTag; }
66
+ });
67
+ Object.defineProperty(exports, "createAxiosInstance", {
68
+ enumerable: true,
69
+ get: function () { return chunkJGFRUAZT_cjs.createAxiosInstance; }
70
+ });
71
+ Object.defineProperty(exports, "createRequestCore", {
72
+ enumerable: true,
73
+ get: function () { return chunkJGFRUAZT_cjs.createRequestCore; }
74
+ });
75
+ Object.defineProperty(exports, "deleteData", {
76
+ enumerable: true,
77
+ get: function () { return chunkJGFRUAZT_cjs.deleteData; }
78
+ });
79
+ Object.defineProperty(exports, "generateRequestKey", {
80
+ enumerable: true,
81
+ get: function () { return chunkJGFRUAZT_cjs.generateRequestKey; }
82
+ });
83
+ Object.defineProperty(exports, "getCacheSize", {
84
+ enumerable: true,
85
+ get: function () { return chunkJGFRUAZT_cjs.getCacheSize; }
86
+ });
87
+ Object.defineProperty(exports, "getCancelableRequestCount", {
88
+ enumerable: true,
89
+ get: function () { return chunkJGFRUAZT_cjs.getCancelableRequestCount; }
90
+ });
91
+ Object.defineProperty(exports, "getData", {
92
+ enumerable: true,
93
+ get: function () { return chunkJGFRUAZT_cjs.getData; }
94
+ });
95
+ Object.defineProperty(exports, "getGlobalConfig", {
96
+ enumerable: true,
97
+ get: function () { return chunkJGFRUAZT_cjs.getGlobalConfig; }
98
+ });
99
+ Object.defineProperty(exports, "getPendingRequestCount", {
100
+ enumerable: true,
101
+ get: function () { return chunkJGFRUAZT_cjs.getPendingRequestCount; }
102
+ });
103
+ Object.defineProperty(exports, "getReLoginPromise", {
104
+ enumerable: true,
105
+ get: function () { return chunkJGFRUAZT_cjs.getReLoginPromise; }
106
+ });
107
+ Object.defineProperty(exports, "isCanceledError", {
108
+ enumerable: true,
109
+ get: function () { return chunkJGFRUAZT_cjs.isCanceledError; }
110
+ });
111
+ Object.defineProperty(exports, "isRequestError", {
112
+ enumerable: true,
113
+ get: function () { return chunkJGFRUAZT_cjs.isRequestError; }
114
+ });
115
+ Object.defineProperty(exports, "normalizeRequestError", {
116
+ enumerable: true,
117
+ get: function () { return chunkJGFRUAZT_cjs.normalizeRequestError; }
118
+ });
119
+ Object.defineProperty(exports, "onReLoginCancel", {
120
+ enumerable: true,
121
+ get: function () { return chunkJGFRUAZT_cjs.onReLoginCancel; }
122
+ });
123
+ Object.defineProperty(exports, "onReLoginSuccess", {
124
+ enumerable: true,
125
+ get: function () { return chunkJGFRUAZT_cjs.onReLoginSuccess; }
126
+ });
127
+ Object.defineProperty(exports, "patchData", {
128
+ enumerable: true,
129
+ get: function () { return chunkJGFRUAZT_cjs.patchData; }
130
+ });
131
+ Object.defineProperty(exports, "postData", {
132
+ enumerable: true,
133
+ get: function () { return chunkJGFRUAZT_cjs.postData; }
134
+ });
135
+ Object.defineProperty(exports, "putData", {
136
+ enumerable: true,
137
+ get: function () { return chunkJGFRUAZT_cjs.putData; }
138
+ });
139
+ Object.defineProperty(exports, "waitForReLogin", {
140
+ enumerable: true,
141
+ get: function () { return chunkJGFRUAZT_cjs.waitForReLogin; }
761
142
  });
762
- async function getData(url, config) {
763
- const response = await getGlobalAxiosInstance().get(url, config);
764
- return response.data;
765
- }
766
- async function postData(url, data, config) {
767
- const response = await getGlobalAxiosInstance().post(url, data, config);
768
- return response.data;
769
- }
770
- async function putData(url, data, config) {
771
- const response = await getGlobalAxiosInstance().put(url, data, config);
772
- return response.data;
773
- }
774
- async function deleteData(url, config) {
775
- const response = await getGlobalAxiosInstance().delete(url, config);
776
- return response.data;
777
- }
778
-
779
- // src/axios/request.ts
780
- function createAxiosInstance(config = {}) {
781
- const instance = axios__default.default.create({
782
- timeout: 5e3,
783
- headers: {
784
- "Content-Type": "application/json"
785
- },
786
- ...config
787
- });
788
- setupPlugins(instance);
789
- return instance;
790
- }
791
- var onReLoginSuccess = () => {
792
- resolveReLogin();
793
- };
794
- var onReLoginCancel = () => {
795
- rejectReLogin(new Error("\u91CD\u65B0\u767B\u5F55\u5DF2\u53D6\u6D88"));
796
- };
797
-
798
- // src/core.ts
799
- var globalConfig = {
800
- successCodes: [200, 0, "200", "0"],
801
- fieldAliases: {
802
- data: ["data", "list", "items", "records"],
803
- list: ["list", "items", "records", "rows", "data"],
804
- total: ["total", "totalCount", "count", "totalElements"]
805
- }
806
- };
807
- function getGlobalConfig() {
808
- return globalConfig;
809
- }
810
- function createRequestCore(config = {}) {
811
- const {
812
- request = {},
813
- interceptors = {},
814
- successCodes,
815
- fieldAliases
816
- } = config;
817
- if (successCodes) {
818
- globalConfig.successCodes = successCodes;
819
- }
820
- if (fieldAliases) {
821
- globalConfig.fieldAliases = {
822
- data: fieldAliases.data || globalConfig.fieldAliases.data,
823
- list: fieldAliases.list || globalConfig.fieldAliases.list,
824
- total: fieldAliases.total || globalConfig.fieldAliases.total
825
- };
826
- }
827
- const axiosInstance = createAxiosInstance(request);
828
- setGlobalAxiosInstance(axiosInstance);
829
- if (interceptors.request) {
830
- axiosInstance.interceptors.request.use(
831
- interceptors.request,
832
- interceptors.requestError
833
- );
834
- }
835
- if (interceptors.response) {
836
- axiosInstance.interceptors.response.use(
837
- interceptors.response,
838
- interceptors.responseError
839
- );
840
- }
841
- return {
842
- install(app) {
843
- app.config.globalProperties.$axios = axiosInstance;
844
- },
845
- axiosInstance
846
- };
847
- }
848
-
849
- // src/composables/useTableCrud/constants.ts
850
- var DEFAULT_CONFIG = {
851
- /** 默认 ID 字段名 */
852
- idKey: "id",
853
- /** 默认分页大小 */
854
- pageSize: 10,
855
- /** 默认启用分页 */
856
- paginationEnabled: true,
857
- /** 默认当前页 */
858
- currentPage: 1
859
- };
860
- var DATA_FIELD_ALIASES = ["data", "list", "items", "records"];
861
- var LIST_FIELD_ALIASES = [
862
- "list",
863
- "items",
864
- "records",
865
- "rows",
866
- "data"
867
- ];
868
- var TOTAL_FIELD_ALIASES = [
869
- "total",
870
- "totalCount",
871
- "count",
872
- "totalElements"
873
- ];
874
- var SUCCESS_CODES = [200, 0, "200", "0"];
875
- var DEFAULT_MESSAGES = {
876
- createSuccess: "\u65B0\u589E\u6210\u529F",
877
- updateSuccess: "\u66F4\u65B0\u6210\u529F",
878
- deleteSuccess: "\u5220\u9664\u6210\u529F",
879
- saveError: "\u4FDD\u5B58\u5931\u8D25",
880
- deleteError: "\u5220\u9664\u5931\u8D25",
881
- loadError: "\u6570\u636E\u52A0\u8F7D\u5931\u8D25",
882
- detailError: "\u8BE6\u60C5\u83B7\u53D6\u5931\u8D25",
883
- noDeleteApi: "\u672A\u914D\u7F6E\u5220\u9664\u63A5\u53E3"
884
- };
885
-
886
- // src/composables/useTableCrud/utils.ts
887
- function getRuntimeFieldAliases() {
888
- const config = getGlobalConfig();
889
- return {
890
- data: config.fieldAliases.data || DATA_FIELD_ALIASES,
891
- list: config.fieldAliases.list || LIST_FIELD_ALIASES,
892
- total: config.fieldAliases.total || TOTAL_FIELD_ALIASES
893
- };
894
- }
895
- function getRuntimeSuccessCodes() {
896
- const config = getGlobalConfig();
897
- return config.successCodes || SUCCESS_CODES;
898
- }
899
- var FieldFinder = {
900
- /**
901
- * 查找第一个存在的字段值
902
- */
903
- findFirst(obj, aliases, defaultValue) {
904
- if (!obj || typeof obj !== "object") return defaultValue;
905
- for (const key of aliases) {
906
- if (key in obj && obj[key] !== void 0) {
907
- return obj[key];
908
- }
909
- }
910
- return defaultValue;
911
- },
912
- /**
913
- * 查找第一个存在的数字字段
914
- */
915
- findNumber(obj, aliases, defaultValue = 0) {
916
- const value = this.findFirst(obj, aliases, defaultValue);
917
- return Number(value) || defaultValue;
918
- }
919
- };
920
- var ResponseNormalizer = {
921
- /**
922
- * 判断响应是否成功
923
- */
924
- isSuccess(res) {
925
- if (typeof res.success === "boolean") return res.success;
926
- const successCodes = getRuntimeSuccessCodes();
927
- return successCodes.includes(res.code) || successCodes.includes(String(res.code));
928
- },
929
- /**
930
- * 标准化响应数据(提取 data 层)
931
- */
932
- normalize(res) {
933
- if (!res || typeof res !== "object" || !("data" in res)) {
934
- return { data: res, success: true, raw: res };
935
- }
936
- const aliases = getRuntimeFieldAliases();
937
- return {
938
- data: FieldFinder.findFirst(res, aliases.data, res),
939
- success: ResponseNormalizer.isSuccess(res),
940
- raw: res
941
- };
942
- }
943
- };
944
- var UrlUtils = {
945
- /**
946
- * 构建 URL(处理路径参数)
947
- */
948
- buildUrl(endpoint, id) {
949
- if (id !== void 0 && endpoint.includes(":id")) {
950
- return endpoint.replace(":id", String(id));
951
- }
952
- return endpoint;
953
- }
954
- };
955
- var DataExtractor = {
956
- /**
957
- * 从响应中提取列表数据(支持多种格式)
958
- *
959
- * 支持的响应结构:
960
- * 1. { code: 0, data: { list: [...], total: 10 } } // 嵌套结构(最常见)
961
- * 2. { data: { items: [...], total: 10 } } // 嵌套结构
962
- * 3. { list: [...], total: 10 } // 扁平结构
963
- * 4. { items: [...], totalCount: 10 } // 不同字段名
964
- * 5. { data: [...] } // 直接数组
965
- * 6. [...] // 纯数组
966
- */
967
- extractList(response) {
968
- const normalized = ResponseNormalizer.normalize(response);
969
- const dataLayer = normalized.data ?? response;
970
- const aliases = getRuntimeFieldAliases();
971
- const list = FieldFinder.findFirst(dataLayer, aliases.list, []);
972
- const total = FieldFinder.findNumber(dataLayer, aliases.total, 0);
973
- return {
974
- items: Array.isArray(list) ? list : [],
975
- total
976
- };
977
- },
978
- /**
979
- * 从响应中提取详情数据
980
- */
981
- extractDetail(response) {
982
- const normalized = ResponseNormalizer.normalize(response);
983
- return normalized.data;
984
- }
985
- };
986
- var RowUtils = {
987
- /**
988
- * 从数组中查找行索引
989
- */
990
- findIndex(items, idKey, id) {
991
- return items.findIndex((item) => item[idKey] === id);
992
- },
993
- /**
994
- * 从数组中移除行
995
- */
996
- remove(items, idKey, id) {
997
- const index = this.findIndex(items, idKey, id);
998
- if (index !== -1) {
999
- items.splice(index, 1);
1000
- return true;
1001
- }
1002
- return false;
1003
- },
1004
- /**
1005
- * 生成默认 ID
1006
- */
1007
- generateId() {
1008
- return Date.now() + Math.floor(Math.random() * 1e3);
1009
- }
1010
- };
1011
-
1012
- // src/composables/useTableCrud/useTableCrud.ts
1013
- function useTableCrud(config) {
1014
- const {
1015
- api,
1016
- columns,
1017
- customActions = [],
1018
- detail: detailConfig,
1019
- idKey = DEFAULT_CONFIG.idKey,
1020
- defaultPageSize = DEFAULT_CONFIG.pageSize,
1021
- defaultPaginationEnabled = DEFAULT_CONFIG.paginationEnabled,
1022
- autoLoad = true,
1023
- extractListData
1024
- } = config;
1025
- const message = naiveUi.useMessage();
1026
- const dialog = naiveUi.useDialog();
1027
- const data = vue.shallowRef([]);
1028
- const total = vue.ref(0);
1029
- const loading = vue.ref(false);
1030
- const tableRef = vue.ref();
1031
- const paginationEnabled = vue.ref(defaultPaginationEnabled);
1032
- const page = vue.reactive({
1033
- current: DEFAULT_CONFIG.currentPage,
1034
- size: defaultPageSize
1035
- });
1036
- const detailVisible = vue.ref(false);
1037
- const detailData = vue.ref(null);
1038
- const detailTitle = vue.ref("");
1039
- const detail = {
1040
- visible: detailVisible,
1041
- data: detailData,
1042
- title: detailTitle,
1043
- show: (row) => {
1044
- detailData.value = row;
1045
- detailTitle.value = `\u8BE6\u60C5 - ${row.name || row[idKey]}`;
1046
- detailVisible.value = true;
1047
- },
1048
- close: () => {
1049
- detailVisible.value = false;
1050
- detailData.value = null;
1051
- detailTitle.value = "";
1052
- }
1053
- };
1054
- const refresh = async () => {
1055
- if (!api.list) return;
1056
- loading.value = true;
1057
- try {
1058
- const queryParams = paginationEnabled.value ? { page: page.current, pageSize: page.size } : {};
1059
- const response = await getData(api.list, { params: queryParams });
1060
- const extracted = extractListData ? extractListData(response) : DataExtractor.extractList(response);
1061
- data.value = extracted.items;
1062
- total.value = extracted.total;
1063
- } catch (error) {
1064
- console.error("[useTableCrud] \u6570\u636E\u52A0\u8F7D\u5931\u8D25:", error);
1065
- message.error(DEFAULT_MESSAGES.loadError);
1066
- } finally {
1067
- loading.value = false;
1068
- }
1069
- };
1070
- const getDetail = async (row) => {
1071
- if (!api.get) {
1072
- detail.show(row);
1073
- return row;
1074
- }
1075
- loading.value = true;
1076
- try {
1077
- const url = UrlUtils.buildUrl(api.get, row[idKey]);
1078
- const response = await getData(url, {});
1079
- const detailData2 = DataExtractor.extractDetail(response);
1080
- if (detailData2) {
1081
- detail.show(detailData2);
1082
- return detailData2;
1083
- }
1084
- return null;
1085
- } catch (error) {
1086
- console.error("[useTableCrud] \u8BE6\u60C5\u83B7\u53D6\u5931\u8D25:", error);
1087
- message.error(DEFAULT_MESSAGES.detailError);
1088
- return null;
1089
- } finally {
1090
- loading.value = false;
1091
- }
1092
- };
1093
- const create = async (row) => {
1094
- if (!api.create) {
1095
- message.warning("\u672A\u914D\u7F6E\u65B0\u589E\u63A5\u53E3");
1096
- return;
1097
- }
1098
- loading.value = true;
1099
- try {
1100
- await postData(api.create, row);
1101
- message.success(DEFAULT_MESSAGES.createSuccess);
1102
- await refresh();
1103
- } catch (error) {
1104
- console.error("[useTableCrud] \u65B0\u589E\u5931\u8D25:", error);
1105
- message.error("\u65B0\u589E\u5931\u8D25");
1106
- throw error;
1107
- } finally {
1108
- loading.value = false;
1109
- }
1110
- };
1111
- const save = async (row) => {
1112
- if (!api.update) {
1113
- message.warning("\u672A\u914D\u7F6E\u66F4\u65B0\u63A5\u53E3");
1114
- return;
1115
- }
1116
- loading.value = true;
1117
- try {
1118
- const url = UrlUtils.buildUrl(api.update, row[idKey]);
1119
- await putData(url, row);
1120
- message.success(DEFAULT_MESSAGES.updateSuccess);
1121
- await refresh();
1122
- } catch (error) {
1123
- console.error("[useTableCrud] \u66F4\u65B0\u5931\u8D25:", error);
1124
- message.error(DEFAULT_MESSAGES.saveError);
1125
- throw error;
1126
- } finally {
1127
- loading.value = false;
1128
- }
1129
- };
1130
- const remove = async (row) => {
1131
- if (!api.remove) {
1132
- message.warning(DEFAULT_MESSAGES.noDeleteApi);
1133
- return;
1134
- }
1135
- loading.value = true;
1136
- try {
1137
- const url = UrlUtils.buildUrl(api.remove, row[idKey]);
1138
- await deleteData(url);
1139
- message.success(DEFAULT_MESSAGES.deleteSuccess);
1140
- RowUtils.remove(data.value, idKey, row[idKey]);
1141
- await refresh();
1142
- } catch (error) {
1143
- console.error("[useTableCrud] \u5220\u9664\u5931\u8D25:", error);
1144
- message.error(DEFAULT_MESSAGES.deleteError);
1145
- throw error;
1146
- } finally {
1147
- loading.value = false;
1148
- }
1149
- };
1150
- const batchRemove = async (rows) => {
1151
- if (!rows || rows.length === 0) {
1152
- message.warning("\u8BF7\u9009\u62E9\u8981\u5220\u9664\u7684\u6570\u636E");
1153
- return;
1154
- }
1155
- if (!api.remove && !api.batchRemove) {
1156
- message.warning(DEFAULT_MESSAGES.noDeleteApi);
1157
- return;
1158
- }
1159
- loading.value = true;
1160
- try {
1161
- if (api.batchRemove) {
1162
- const ids = rows.map((row) => row[idKey]);
1163
- await postData(api.batchRemove, { ids });
1164
- } else {
1165
- await Promise.all(
1166
- rows.map((row) => {
1167
- const url = UrlUtils.buildUrl(api.remove, row[idKey]);
1168
- return deleteData(url);
1169
- })
1170
- );
1171
- }
1172
- message.success(`\u6210\u529F\u5220\u9664 ${rows.length} \u6761\u6570\u636E`);
1173
- await refresh();
1174
- } catch (error) {
1175
- console.error("[useTableCrud] \u6279\u91CF\u5220\u9664\u5931\u8D25:", error);
1176
- message.error("\u6279\u91CF\u5220\u9664\u5931\u8D25");
1177
- throw error;
1178
- } finally {
1179
- loading.value = false;
1180
- }
1181
- };
1182
- const handleCancel = async () => {
1183
- await refresh();
1184
- };
1185
- const handlePaginationChange = (pageNum, pageSize) => {
1186
- page.current = pageNum;
1187
- page.size = pageSize;
1188
- refresh();
1189
- };
1190
- const handleRowDelete = (deletedRow) => {
1191
- RowUtils.remove(data.value, idKey, deletedRow[idKey]);
1192
- };
1193
- const pagination = vue.computed(() => {
1194
- if (!paginationEnabled.value) return false;
1195
- return {
1196
- enabled: true,
1197
- page: page.current,
1198
- pageSize: page.size
1199
- };
1200
- });
1201
- const createActionContext = (index) => ({
1202
- data: data.value,
1203
- index,
1204
- page,
1205
- paginationEnabled: paginationEnabled.value,
1206
- message,
1207
- dialog,
1208
- refresh
1209
- });
1210
- const actions = vue.computed(() => {
1211
- const result = {};
1212
- if (api.update) {
1213
- result.edit = async (row) => {
1214
- try {
1215
- await save(row);
1216
- return { data: row, error: null };
1217
- } catch (error) {
1218
- return { data: null, error };
1219
- }
1220
- };
1221
- }
1222
- if (api.remove) {
1223
- result.delete = async (row) => {
1224
- try {
1225
- await remove(row);
1226
- return { data: { success: true }, error: null };
1227
- } catch (error) {
1228
- return { data: null, error };
1229
- }
1230
- };
1231
- }
1232
- if (api.get) {
1233
- result.detail = async (row) => {
1234
- try {
1235
- const detailData2 = await getDetail(row);
1236
- return { data: detailData2, error: null };
1237
- } catch (error) {
1238
- return { data: null, error };
1239
- }
1240
- };
1241
- }
1242
- if (customActions.length > 0) {
1243
- result.custom = customActions.map((action) => ({
1244
- key: action.key,
1245
- label: action.label,
1246
- icon: action.icon,
1247
- type: action.type || "default",
1248
- onClick: (row, index) => {
1249
- const context = createActionContext(index);
1250
- return action.handler(row, context);
1251
- }
1252
- }));
1253
- }
1254
- return result;
1255
- });
1256
- if (autoLoad) {
1257
- refresh();
1258
- }
1259
- return {
1260
- // 数据状态
1261
- data,
1262
- loading,
1263
- total,
1264
- // 表格配置
1265
- columns: vue.computed(() => columns),
1266
- actions,
1267
- tableRef,
1268
- // 分页
1269
- page,
1270
- paginationEnabled,
1271
- pagination,
1272
- // 核心方法
1273
- refresh,
1274
- create,
1275
- save,
1276
- remove,
1277
- batchRemove,
1278
- getDetail,
1279
- // 事件处理
1280
- handleCancel,
1281
- handlePaginationChange,
1282
- handleRowDelete,
1283
- // 详情弹窗
1284
- detail,
1285
- detailConfig
1286
- };
1287
- }
1288
-
1289
- exports.cancelAllPendingRequests = cancelAllPendingRequests;
1290
- exports.cancelAllRequests = cancelAllRequests;
1291
- exports.cleanupExpiredCache = cleanupExpiredCache;
1292
- exports.clearAllCache = clearAllCache;
1293
- exports.clearCache = clearCache;
1294
- exports.createAxiosInstance = createAxiosInstance;
1295
- exports.createRequestCore = createRequestCore;
1296
- exports.deleteData = deleteData;
1297
- exports.getCacheSize = getCacheSize;
1298
- exports.getCancelableRequestCount = getCancelableRequestCount;
1299
- exports.getData = getData;
1300
- exports.getGlobalConfig = getGlobalConfig;
1301
- exports.getPendingRequestCount = getPendingRequestCount;
1302
- exports.getReLoginPromise = getReLoginPromise;
1303
- exports.onReLoginCancel = onReLoginCancel;
1304
- exports.onReLoginSuccess = onReLoginSuccess;
1305
- exports.postData = postData;
1306
- exports.putData = putData;
1307
- exports.useTableCrud = useTableCrud;
1308
- exports.waitForReLogin = waitForReLogin;
1309
143
  //# sourceMappingURL=index.cjs.map
1310
144
  //# sourceMappingURL=index.cjs.map