@hzab/data-model 2.0.3-alpha.0 → 2.1.0-alpha.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/CHANGELOG.md +9 -145
- package/LICENSE +21 -0
- package/README.md +50 -270
- package/dist/index.cjs +6010 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1305 -0
- package/dist/index.d.ts +1305 -0
- package/dist/index.js +5956 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -50
- package/src/hooks.ts +42 -38
- package/src/index.ts +14 -11
- package/src/ArrayUtils.ts +0 -712
- package/src/RequestCache.ts +0 -202
- package/src/array-data-model.ts +0 -479
- package/src/axios.ts +0 -245
- package/src/data-model.ts +0 -850
- package/src/public-utils.ts +0 -26
- package/src/type.ts +0 -109
- package/src/utils.ts +0 -98
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1305 @@
|
|
|
1
|
+
import * as _axios from 'axios';
|
|
2
|
+
import { AxiosRequestConfig, InternalAxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 接口缓存
|
|
6
|
+
*
|
|
7
|
+
* 在本地模型上,将 axios 请求配置中的 `cache` 字段设置为 `CacheItem`,
|
|
8
|
+
* 即可在请求拦截器中自动缓存请求结果。
|
|
9
|
+
*
|
|
10
|
+
* 在响应拦截器中,如果请求命中缓存,则直接返回缓存结果,
|
|
11
|
+
* 否则继续执行请求,并将结果缓存。
|
|
12
|
+
*
|
|
13
|
+
* 缓存结果的过期时间由 `cacheTTL` 配置,默认 3000 毫秒。
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 缓存配置
|
|
18
|
+
*/
|
|
19
|
+
interface CacheOpt {
|
|
20
|
+
/** 缓存时间 毫秒 */
|
|
21
|
+
cacheTTL?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 缓存方法入参配置
|
|
25
|
+
*/
|
|
26
|
+
interface RequestCacheParams {
|
|
27
|
+
options?: CacheOpt;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 接口入参(用于生成缓存 key)
|
|
31
|
+
*/
|
|
32
|
+
interface Req {
|
|
33
|
+
method?: string;
|
|
34
|
+
baseURL?: string;
|
|
35
|
+
url?: string;
|
|
36
|
+
params?: unknown;
|
|
37
|
+
data?: unknown;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 缓存对象
|
|
41
|
+
*/
|
|
42
|
+
interface CacheItem {
|
|
43
|
+
key: string;
|
|
44
|
+
/** 过期时间戳 */
|
|
45
|
+
expires: number;
|
|
46
|
+
/** 缓存的 promise(进行中或已 settled) */
|
|
47
|
+
promise: Promise<unknown>;
|
|
48
|
+
/** 缓存的 axios config 配置 */
|
|
49
|
+
config?: InternalAxiosRequestConfig;
|
|
50
|
+
resolve: (d: unknown) => void;
|
|
51
|
+
reject: (err: unknown) => void;
|
|
52
|
+
/** 首个请求是否已结束 */
|
|
53
|
+
settled?: boolean;
|
|
54
|
+
/** 是否已成功写入结果(仅成功响应进入结果缓存) */
|
|
55
|
+
hasResult?: boolean;
|
|
56
|
+
/** 从所属 RequestCache 中移除本条目 */
|
|
57
|
+
clear?: () => void;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 命中缓存时 reject 的错误对象(供响应拦截器识别)
|
|
61
|
+
*/
|
|
62
|
+
interface CacheHitError {
|
|
63
|
+
from: "cache";
|
|
64
|
+
code: 200;
|
|
65
|
+
key: string;
|
|
66
|
+
config: InternalAxiosRequestConfig;
|
|
67
|
+
cache: CacheItem;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 是否为缓存命中错误
|
|
71
|
+
*/
|
|
72
|
+
declare function isCacheHitError(error: unknown): error is CacheHitError;
|
|
73
|
+
/**
|
|
74
|
+
* 接口缓存类
|
|
75
|
+
* - 进行中:相同 key 复用同一个 promise(请求去重)
|
|
76
|
+
* - 成功后:在 TTL 内复用结果;失败不保留结果缓存
|
|
77
|
+
*/
|
|
78
|
+
declare class RequestCache {
|
|
79
|
+
options: CacheOpt;
|
|
80
|
+
cacheTTL: number;
|
|
81
|
+
_cacheMap: Map<string, CacheItem>;
|
|
82
|
+
constructor(params?: RequestCacheParams);
|
|
83
|
+
/**
|
|
84
|
+
* 处理 axios request 拦截逻辑
|
|
85
|
+
*/
|
|
86
|
+
handleAxRequest(config: InternalAxiosRequestConfig & {
|
|
87
|
+
cache?: CacheItem;
|
|
88
|
+
}): (InternalAxiosRequestConfig<any, any> & {
|
|
89
|
+
cache?: CacheItem;
|
|
90
|
+
}) | Promise<never>;
|
|
91
|
+
/**
|
|
92
|
+
* 缓存是否仍有效(未过期)
|
|
93
|
+
*/
|
|
94
|
+
isFresh(cache?: CacheItem | null): cache is CacheItem;
|
|
95
|
+
/**
|
|
96
|
+
* 判断是否存在可复用缓存(进行中,或 TTL 内的成功结果)
|
|
97
|
+
*/
|
|
98
|
+
hasCache(axConf: Req): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* 获取缓存
|
|
101
|
+
*/
|
|
102
|
+
getCache(axConf: Req): CacheItem | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* 按 key 获取未过期缓存
|
|
105
|
+
*/
|
|
106
|
+
getCacheByKey(key: string): CacheItem | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* 添加缓存
|
|
109
|
+
*/
|
|
110
|
+
addCache(data: CacheItem, opt?: CacheOpt): CacheItem;
|
|
111
|
+
rmCache(config: Req): void;
|
|
112
|
+
/**
|
|
113
|
+
* 获取缓存的 key
|
|
114
|
+
*/
|
|
115
|
+
getCacheKey(config?: Req): string;
|
|
116
|
+
/**
|
|
117
|
+
* 序列化对象,保证属性顺序一致
|
|
118
|
+
*/
|
|
119
|
+
private stableStringify;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
declare const TOKEN = "token";
|
|
123
|
+
interface AxiosRequestConfigWithCache extends InternalAxiosRequestConfig {
|
|
124
|
+
cache?: CacheItem;
|
|
125
|
+
}
|
|
126
|
+
type AxiosResponseCus = AxiosResponse & {
|
|
127
|
+
config: AxiosRequestConfigWithCache;
|
|
128
|
+
};
|
|
129
|
+
declare const axios: AxiosInstance;
|
|
130
|
+
/**
|
|
131
|
+
* 创建带共享拦截器(RequestCache)的 axios 实例。
|
|
132
|
+
* 不替换默认 `axios`;多 baseURL / 单测注入优先用本工厂 + `DataModel({ axios })`。
|
|
133
|
+
* 若需被后续 `setAx*` 批量作用,再 `registerAxios([client])`。
|
|
134
|
+
*/
|
|
135
|
+
declare function createAxiosClient(config?: AxiosRequestConfig): AxiosInstance;
|
|
136
|
+
/**
|
|
137
|
+
* 处理错误回调函数的选项接口
|
|
138
|
+
*/
|
|
139
|
+
interface HandleErrCbOptions {
|
|
140
|
+
/** 直接替换回调函数 */
|
|
141
|
+
replaceErrCb?: boolean;
|
|
142
|
+
/** 日志前缀 */
|
|
143
|
+
logPrefix?: string;
|
|
144
|
+
/**
|
|
145
|
+
* 稳定 id:同实例同 id 再次挂载时先 eject 旧拦截器(幂等)。
|
|
146
|
+
* 不传则每次追加一层(多次调用会重复触发)。
|
|
147
|
+
*/
|
|
148
|
+
id?: string;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* setToken 选项接口
|
|
152
|
+
*/
|
|
153
|
+
interface SetTokenOptions {
|
|
154
|
+
/** 是否同时设置 cookie */
|
|
155
|
+
hasCookie?: boolean;
|
|
156
|
+
/** cookie 属性配置 */
|
|
157
|
+
cookieAttrs?: Record<string, unknown>;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* getToken 选项接口
|
|
161
|
+
*/
|
|
162
|
+
interface GetTokenOptions {
|
|
163
|
+
/** 是否从 cookie 获取 */
|
|
164
|
+
hasCookie?: boolean;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* 设置 token(localStorage 便捷封装,并同步 Authorization)
|
|
168
|
+
* @param token token 值
|
|
169
|
+
* @param opt 选项(`hasCookie` 需要已安装 optional peer `js-cookie`,否则仅写 localStorage)
|
|
170
|
+
*/
|
|
171
|
+
declare function setToken(token?: string, opt?: SetTokenOptions): void;
|
|
172
|
+
/**
|
|
173
|
+
* 获取 token(localStorage 优先;`hasCookie` 时尽力读 cookie,未加载则回退 localStorage)
|
|
174
|
+
* @param opt 选项
|
|
175
|
+
* @returns token 值
|
|
176
|
+
*/
|
|
177
|
+
declare function getToken(opt?: GetTokenOptions): string;
|
|
178
|
+
declare const temp: {
|
|
179
|
+
axiosList: AxiosInstance[];
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* 将 axios 实例登记进列表,供后续 `setAx*` 批量作用(按引用去重)。
|
|
183
|
+
* 只作用于调用当时已在列表中的实例;后登记的实例不会自动补上已挂过的拦截器。
|
|
184
|
+
* @param axiosList axios 实例列表
|
|
185
|
+
* @returns 更新后的 axios 实例列表
|
|
186
|
+
*/
|
|
187
|
+
declare function registerAxios(axiosList: AxiosInstance[]): AxiosInstance[];
|
|
188
|
+
/**
|
|
189
|
+
* @deprecated 旧写法别名;等价 `registerAxios`。
|
|
190
|
+
*/
|
|
191
|
+
declare const setAxios: typeof registerAxios;
|
|
192
|
+
/**
|
|
193
|
+
* @deprecated 旧写法;设置默认 axios 实例,供未显式传 `axios` 的 DataModel 兜底。
|
|
194
|
+
*/
|
|
195
|
+
declare function setDefaultAxios(ax?: AxiosInstance): void;
|
|
196
|
+
/** 读取默认 axios 实例(供 DataModel 构造兜底) */
|
|
197
|
+
declare function getDefaultAxios(): AxiosInstance | undefined;
|
|
198
|
+
/**
|
|
199
|
+
* 为当前 `axiosList` 中的实例挂请求拦截器。
|
|
200
|
+
* 仅作用于调用当时已登记的实例;后 `registerAxios` 的实例不会自动继承。
|
|
201
|
+
* 传入 `opt.id` 时可幂等替换同 id 拦截器;不传 id 则每次追加。
|
|
202
|
+
*/
|
|
203
|
+
declare function setAxRequest(cb: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig>, errCb?: (error: any) => Promise<any>, opt?: HandleErrCbOptions): void;
|
|
204
|
+
/**
|
|
205
|
+
* 为当前 `axiosList` 中的实例挂响应拦截器。
|
|
206
|
+
* 语义同 `setAxRequest`(当时列表 / 可选 `opt.id` 幂等)。
|
|
207
|
+
*/
|
|
208
|
+
declare function setAxResponse(cb: (response: AxiosResponse) => AxiosResponse | Promise<AxiosResponse>, errCb?: (error: unknown) => Promise<unknown>, opt?: HandleErrCbOptions): void;
|
|
209
|
+
/**
|
|
210
|
+
* 处理错误回调函数
|
|
211
|
+
* @param errCb 错误回调
|
|
212
|
+
* @param opt 选项
|
|
213
|
+
* @returns 处理后的错误回调
|
|
214
|
+
*/
|
|
215
|
+
declare function handleErrCb(errCb?: (error: any) => Promise<any>, opt?: HandleErrCbOptions): (error: any) => Promise<any>;
|
|
216
|
+
/**
|
|
217
|
+
* 设置 axios.defaults
|
|
218
|
+
* @param key 配置键
|
|
219
|
+
* @param val 配置值
|
|
220
|
+
*/
|
|
221
|
+
declare function setAxDefaults(key: string, val: any): void;
|
|
222
|
+
/**
|
|
223
|
+
* 设置 headers
|
|
224
|
+
* @param key header 键
|
|
225
|
+
* @param val header 值
|
|
226
|
+
*/
|
|
227
|
+
declare function setAxHeaders(key: string, val: any): void;
|
|
228
|
+
/**
|
|
229
|
+
* 设置 timeout
|
|
230
|
+
* @param timeout 超时时间
|
|
231
|
+
*/
|
|
232
|
+
declare function setAxTimeout(timeout?: number): void;
|
|
233
|
+
/**
|
|
234
|
+
* 设置 Authorization token
|
|
235
|
+
* @param token token 值
|
|
236
|
+
*/
|
|
237
|
+
declare function setAxAuthorization(token: string): void;
|
|
238
|
+
/**
|
|
239
|
+
* 设置 baseUrl
|
|
240
|
+
* @param url 基础 URL
|
|
241
|
+
*/
|
|
242
|
+
declare function setAxBaseUrl(url: string): void;
|
|
243
|
+
/**
|
|
244
|
+
* 获取 AbortController,用于取消请求(推荐,配合 axios config.signal)
|
|
245
|
+
* @returns AbortController
|
|
246
|
+
*/
|
|
247
|
+
declare function createAbortController(): AbortController;
|
|
248
|
+
/**
|
|
249
|
+
* @deprecated 旧写法;获取 axios.CancelToken.source,用于取消请求。
|
|
250
|
+
* 新页面推荐 `createAbortController` + `signal`。
|
|
251
|
+
* @returns CancelToken source
|
|
252
|
+
*/
|
|
253
|
+
declare function getCancelTokenSource(): _axios.CancelTokenSource;
|
|
254
|
+
/**
|
|
255
|
+
* 检查是否是 cancel / abort 的结果
|
|
256
|
+
*/
|
|
257
|
+
declare function isCancel(res: unknown): boolean;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* 通用 JSON 对象类型
|
|
261
|
+
*/
|
|
262
|
+
type JSONObject = Record<string, any>;
|
|
263
|
+
/**
|
|
264
|
+
* 查询参数类型
|
|
265
|
+
*/
|
|
266
|
+
type QueryParams = JSONObject;
|
|
267
|
+
/**
|
|
268
|
+
* 请求数据类型
|
|
269
|
+
*/
|
|
270
|
+
type RequestData = JSONObject;
|
|
271
|
+
/**
|
|
272
|
+
* 响应数据类型
|
|
273
|
+
*/
|
|
274
|
+
interface ResponseData<T = Record<string, any>> extends AxiosResponse {
|
|
275
|
+
data: ResData<T>;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* 接口返回数据格式
|
|
279
|
+
*/
|
|
280
|
+
interface ResData<T = Record<string, any>> {
|
|
281
|
+
code: number;
|
|
282
|
+
data: T;
|
|
283
|
+
msg: string;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Axios 配置类型
|
|
287
|
+
*/
|
|
288
|
+
type AxiosConfig = AxiosRequestConfig;
|
|
289
|
+
/**
|
|
290
|
+
* 数据映射函数类型(入参 / 出参同为 `T`,与实体泛型贯通)
|
|
291
|
+
* @template T - 映射数据类型
|
|
292
|
+
*/
|
|
293
|
+
type MapFunction<T = any> = (data: T) => T;
|
|
294
|
+
/**
|
|
295
|
+
* 带原始参数的映射函数类型(用于请求前处理,支持同步 / 异步)
|
|
296
|
+
* @template T - 处理后的参数类型
|
|
297
|
+
* @template P - 原始参数类型
|
|
298
|
+
*/
|
|
299
|
+
type RequestMapFunction<T = RequestData, P = unknown> = (params: T, originalParams?: P) => T | Promise<T>;
|
|
300
|
+
/**
|
|
301
|
+
* 列表请求返回结果接口
|
|
302
|
+
* @template T - 列表项数据类型
|
|
303
|
+
*/
|
|
304
|
+
interface GetListResult<T = Record<string, any>> {
|
|
305
|
+
/** 列表数据 */
|
|
306
|
+
list: T[];
|
|
307
|
+
/** 分页信息 */
|
|
308
|
+
pagination: {
|
|
309
|
+
current?: number;
|
|
310
|
+
total: number;
|
|
311
|
+
pageSize?: number;
|
|
312
|
+
};
|
|
313
|
+
/** 其他扩展字段 */
|
|
314
|
+
[key: string]: any;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* 自定义列表请求函数类型
|
|
318
|
+
* @template T - 列表项数据类型
|
|
319
|
+
*/
|
|
320
|
+
type GetListFunc<T = Record<string, any>> = (query: QueryParams) => Promise<GetListResult<T>>;
|
|
321
|
+
/**
|
|
322
|
+
* @deprecated 旧写法响应处理函数;2.1 兼容层。设置后 `handleRes` 走旧分支,否则走 `responseAdapter`。
|
|
323
|
+
*/
|
|
324
|
+
type HandleResponseFunc = (response: AxiosResponse) => ResponseData;
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* 三端 CRUD 正式契约。本地模型可对 `ctx` / `axiosConf` 忽略(签名对齐)。
|
|
328
|
+
* List 页消费子集类型由 `@hzab/data-display` 的 `ListRenderModel` 定义,本包不耦合 UI。
|
|
329
|
+
*/
|
|
330
|
+
interface ICrudModel<T = Record<string, any>> {
|
|
331
|
+
query: QueryParams;
|
|
332
|
+
ctx?: Record<string, any>;
|
|
333
|
+
get(q?: QueryParams, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T | null>;
|
|
334
|
+
getList(q?: QueryParams, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<GetListResult<T>>;
|
|
335
|
+
create(data: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T>;
|
|
336
|
+
update(data: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T>;
|
|
337
|
+
patch(data: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T>;
|
|
338
|
+
delete(config: ModelDeleteConfig, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<unknown>;
|
|
339
|
+
multipleDelete(config: ModelDeleteConfig, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<MultipleDeleteResult>;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* 删除请求配置(对齐 axios.delete:params / data)
|
|
344
|
+
*/
|
|
345
|
+
interface ModelDeleteConfig {
|
|
346
|
+
params?: Record<string, any>;
|
|
347
|
+
data?: Record<string, any>;
|
|
348
|
+
[key: string]: any;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* 批量删除结果
|
|
352
|
+
*/
|
|
353
|
+
interface MultipleDeleteResult {
|
|
354
|
+
sucList: any[];
|
|
355
|
+
failList: any[];
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* 三端 DataModel 共用的 CRUD / maps 构造参数。
|
|
359
|
+
* `*Api` 在本地模型上可为形态对齐占位;`*Map` 与实体泛型 `T` 贯通。
|
|
360
|
+
*/
|
|
361
|
+
interface CrudModelOptions<T = Record<string, any>> {
|
|
362
|
+
/**
|
|
363
|
+
* 非空则按 key 复用实例(各端 registry 带前缀,互不冲突)。
|
|
364
|
+
* 首次创建写入 registry;再次 `new` / `getInstance` 同 key 返回已有实例。
|
|
365
|
+
* 默认不传 = 每次 new 新实例(测试 / 临时模型)。
|
|
366
|
+
*/
|
|
367
|
+
singletonKey?: string;
|
|
368
|
+
/** 请求 url 替换的额外参数 */
|
|
369
|
+
ctx?: JSONObject;
|
|
370
|
+
/** GET 请求的参数 */
|
|
371
|
+
query?: QueryParams;
|
|
372
|
+
/** POST 接口地址 */
|
|
373
|
+
createApi?: string;
|
|
374
|
+
/** GET 详情 接口地址 */
|
|
375
|
+
getApi?: string;
|
|
376
|
+
/** GET 列表 接口地址 */
|
|
377
|
+
getListApi?: string;
|
|
378
|
+
/** GET 列表 接口回调,用于自定义列表请求接口 */
|
|
379
|
+
getListFunc?: GetListFunc<T>;
|
|
380
|
+
/** PUT 接口地址 */
|
|
381
|
+
updateApi?: string;
|
|
382
|
+
/** PATCH 接口地址 */
|
|
383
|
+
patchApi?: string;
|
|
384
|
+
/** DELETE 接口地址 */
|
|
385
|
+
deleteApi?: string;
|
|
386
|
+
/** DELETE 批量删除 接口地址 */
|
|
387
|
+
multipleDeleteApi?: string;
|
|
388
|
+
/** GET 列表 接口请求前数据处理回调 */
|
|
389
|
+
getListReqMap?: RequestMapFunction<QueryParams>;
|
|
390
|
+
/** GET 列表 接口请求结果数据处理回调 */
|
|
391
|
+
getListResMap?: MapFunction<GetListResult<T>>;
|
|
392
|
+
/** GET 详情 接口请求前数据处理回调 */
|
|
393
|
+
getReqMap?: RequestMapFunction<QueryParams>;
|
|
394
|
+
/** GET 详情 接口请求结果数据处理回调 */
|
|
395
|
+
getResMap?: MapFunction<T>;
|
|
396
|
+
/** POST 接口请求前数据处理回调 */
|
|
397
|
+
createReqMap?: RequestMapFunction<RequestData>;
|
|
398
|
+
/** POST 接口请求结果数据处理回调 */
|
|
399
|
+
createResMap?: MapFunction<T>;
|
|
400
|
+
/** PUT 接口请求前数据处理回调 */
|
|
401
|
+
updateReqMap?: RequestMapFunction<RequestData>;
|
|
402
|
+
/** PUT 接口请求结果数据处理回调 */
|
|
403
|
+
updateResMap?: MapFunction<T>;
|
|
404
|
+
/** PATCH 接口请求前数据处理回调 */
|
|
405
|
+
patchReqMap?: RequestMapFunction<RequestData>;
|
|
406
|
+
/** PATCH 接口请求结果数据处理回调 */
|
|
407
|
+
patchResMap?: MapFunction<T>;
|
|
408
|
+
/** DELETE 接口请求前数据处理回调 */
|
|
409
|
+
deleteReqMap?: RequestMapFunction<JSONObject>;
|
|
410
|
+
/** DELETE 接口请求结果数据处理回调 */
|
|
411
|
+
deleteResMap?: MapFunction;
|
|
412
|
+
/** DELETE 批量删除 接口请求前数据处理回调 */
|
|
413
|
+
multipleDeleteReqMap?: RequestMapFunction<JSONObject>;
|
|
414
|
+
/** DELETE 批量删除 接口请求结果数据处理回调 */
|
|
415
|
+
multipleDeleteResMap?: MapFunction<MultipleDeleteResult>;
|
|
416
|
+
/**
|
|
417
|
+
* @deprecated 旧写法字段;2.1 仅保留供旧 list-render 提交前直接调用。
|
|
418
|
+
* `create()` 内部只跑 `createReqMap`,不会二次调用本字段。
|
|
419
|
+
*/
|
|
420
|
+
createMap?: MapFunction<RequestData>;
|
|
421
|
+
/**
|
|
422
|
+
* @deprecated 旧写法字段;仅保留供旧 list-render 提交前直接调用。
|
|
423
|
+
* `update()` 内部只跑 `updateReqMap`,不会二次调用本字段。
|
|
424
|
+
*/
|
|
425
|
+
updateMap?: MapFunction<RequestData>;
|
|
426
|
+
/**
|
|
427
|
+
* @deprecated 旧写法字段;仅保留供旧 list-render 提交前直接调用。
|
|
428
|
+
* `patch()` 内部只跑 `patchReqMap`,不会二次调用本字段。
|
|
429
|
+
*/
|
|
430
|
+
patchMap?: MapFunction<RequestData>;
|
|
431
|
+
/**
|
|
432
|
+
* @deprecated 旧写法字段;`get()` 内先跑本字段再跑 `getResMap`(先旧后新)。
|
|
433
|
+
*/
|
|
434
|
+
getMap?: MapFunction<T>;
|
|
435
|
+
/**
|
|
436
|
+
* @deprecated 旧写法字段;`getList()` 内逐条 map `list[]`(不是 `getListResMap` 的 1:1)。
|
|
437
|
+
*/
|
|
438
|
+
getListMap?: MapFunction<T>;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* DataModel / ArrayDataModel / IndexedDbDataModel 的共性基类:
|
|
442
|
+
* CRUD 模板(ReqMap → do* → ResMap)、query 合并、本地入参处理、删除 id 解析、configure。
|
|
443
|
+
* 子类只实现 `doGet` / `doGetList` / `doCreate` / …
|
|
444
|
+
*/
|
|
445
|
+
declare abstract class BaseDataModel<T = Record<string, any>> implements ICrudModel<T> {
|
|
446
|
+
/** 注册用 key(不含端前缀);无单例时为 undefined */
|
|
447
|
+
readonly singletonKey?: string;
|
|
448
|
+
ctx: Record<string, any>;
|
|
449
|
+
query: QueryParams;
|
|
450
|
+
createApi?: string;
|
|
451
|
+
getApi?: string;
|
|
452
|
+
getListApi?: string;
|
|
453
|
+
getListFunc?: GetListFunc<T>;
|
|
454
|
+
updateApi?: string;
|
|
455
|
+
patchApi?: string;
|
|
456
|
+
deleteApi?: string;
|
|
457
|
+
multipleDeleteApi?: string;
|
|
458
|
+
getListReqMap?: RequestMapFunction<QueryParams>;
|
|
459
|
+
getListResMap?: MapFunction<GetListResult<T>>;
|
|
460
|
+
getReqMap?: RequestMapFunction<QueryParams>;
|
|
461
|
+
getResMap?: MapFunction<T>;
|
|
462
|
+
createReqMap?: RequestMapFunction<RequestData>;
|
|
463
|
+
createResMap?: MapFunction<T>;
|
|
464
|
+
updateReqMap?: RequestMapFunction<RequestData>;
|
|
465
|
+
updateResMap?: MapFunction<T>;
|
|
466
|
+
patchReqMap?: RequestMapFunction<RequestData>;
|
|
467
|
+
patchResMap?: MapFunction<T>;
|
|
468
|
+
deleteReqMap?: RequestMapFunction<JSONObject>;
|
|
469
|
+
deleteResMap?: MapFunction;
|
|
470
|
+
multipleDeleteReqMap?: RequestMapFunction<JSONObject>;
|
|
471
|
+
multipleDeleteResMap?: MapFunction<MultipleDeleteResult>;
|
|
472
|
+
/**
|
|
473
|
+
* @deprecated 旧写法字段;仅保留供旧 list-render 提交前直接调用。
|
|
474
|
+
* `create()` 等模板不调用本字段(见 `createReqMap`)。
|
|
475
|
+
*/
|
|
476
|
+
createMap?: MapFunction<RequestData>;
|
|
477
|
+
/**
|
|
478
|
+
* @deprecated 旧写法字段;仅保留供旧 list-render 提交前直接调用。
|
|
479
|
+
*/
|
|
480
|
+
updateMap?: MapFunction<RequestData>;
|
|
481
|
+
/**
|
|
482
|
+
* @deprecated 旧写法字段;仅保留供旧 list-render 提交前直接调用。
|
|
483
|
+
*/
|
|
484
|
+
patchMap?: MapFunction<RequestData>;
|
|
485
|
+
/**
|
|
486
|
+
* @deprecated 旧写法字段;`get()` 内先跑本字段再跑 `getResMap`(先旧后新)。
|
|
487
|
+
*/
|
|
488
|
+
getMap?: MapFunction<T>;
|
|
489
|
+
/**
|
|
490
|
+
* @deprecated 旧写法字段;`getList()` 内逐条 map `list[]`(不是 `getListResMap` 的 1:1)。
|
|
491
|
+
*/
|
|
492
|
+
getListMap?: MapFunction<T>;
|
|
493
|
+
constructor(params?: CrudModelOptions<T>);
|
|
494
|
+
/**
|
|
495
|
+
* 显式更新配置。二次 `getInstance` **不会**合并 options,改 api / maps 等必须走本方法。
|
|
496
|
+
* - 浅层赋值 api / maps 等
|
|
497
|
+
* - `query` / `ctx`:merge 出新对象
|
|
498
|
+
* - 忽略 `singletonKey`(不可通过 configure 改 key)
|
|
499
|
+
*/
|
|
500
|
+
configure(partial: Partial<CrudModelOptions<T>>): this;
|
|
501
|
+
/**
|
|
502
|
+
* 合并实例 query 与调用参数,并去掉空值
|
|
503
|
+
*/
|
|
504
|
+
protected mergeQuery(q?: QueryParams): QueryParams;
|
|
505
|
+
/**
|
|
506
|
+
* 应用可选 ResMap
|
|
507
|
+
*/
|
|
508
|
+
protected applyResMap<U>(data: U, resMap?: MapFunction<U>): U;
|
|
509
|
+
/**
|
|
510
|
+
* FormData → 对象 → reqMap(本地模型用;保留 File/Blob 引用,不转回 FormData)
|
|
511
|
+
*/
|
|
512
|
+
handleInputParams(params: RequestData | FormData, reqMapFn?: RequestMapFunction<RequestData>): Promise<Record<string, any>>;
|
|
513
|
+
/**
|
|
514
|
+
* 从 delete config 解析主键:`config[idKey]` → `params` → `data` → `ctx`
|
|
515
|
+
*/
|
|
516
|
+
protected resolveDeleteId(config: ModelDeleteConfig, idKey: string, ctx?: Record<string, any>): any;
|
|
517
|
+
get(q?: QueryParams, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T | null>;
|
|
518
|
+
getList(q?: QueryParams, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<GetListResult<T>>;
|
|
519
|
+
create(data: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T>;
|
|
520
|
+
update(data: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T>;
|
|
521
|
+
patch(data: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T>;
|
|
522
|
+
delete(config?: ModelDeleteConfig, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<unknown>;
|
|
523
|
+
multipleDelete(config?: ModelDeleteConfig, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<MultipleDeleteResult>;
|
|
524
|
+
protected abstract doGet(query: QueryParams, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T | null>;
|
|
525
|
+
protected abstract doGetList(query: QueryParams, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<GetListResult<T>>;
|
|
526
|
+
protected abstract doCreate(data: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T>;
|
|
527
|
+
protected abstract doUpdate(data: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T>;
|
|
528
|
+
protected abstract doPatch(data: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T>;
|
|
529
|
+
protected abstract doDelete(config: ModelDeleteConfig, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<unknown>;
|
|
530
|
+
protected abstract doMultipleDelete(config: ModelDeleteConfig, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<MultipleDeleteResult>;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* 三端统一业务错误(HTTP / Array / IndexedDB)。
|
|
535
|
+
* 用户可见文案只走 `_msg`。
|
|
536
|
+
*/
|
|
537
|
+
declare class ModelError extends Error {
|
|
538
|
+
code?: number | string;
|
|
539
|
+
/** 唯一用户可见文案字段 */
|
|
540
|
+
_msg?: string;
|
|
541
|
+
cause?: unknown;
|
|
542
|
+
response?: unknown;
|
|
543
|
+
data?: unknown;
|
|
544
|
+
constructor(message: string, init?: Partial<ModelError>);
|
|
545
|
+
}
|
|
546
|
+
/** 是否为 ModelError */
|
|
547
|
+
declare function isModelError(err: unknown): err is ModelError;
|
|
548
|
+
/**
|
|
549
|
+
* @deprecated 兼容旧 API:`ApiError` 已统一为 `ModelError`。
|
|
550
|
+
* 注意 `_message`(deprecated)仅在旧写法解析路径动态写入,不属正式契约。
|
|
551
|
+
*/
|
|
552
|
+
type ApiError = ModelError;
|
|
553
|
+
|
|
554
|
+
/** DataModel 全局默认错误文案 */
|
|
555
|
+
interface DataModelMessages {
|
|
556
|
+
defaultErrMsg: string;
|
|
557
|
+
networkErrMsg: string;
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* 批量设置 DataModel 默认错误文案
|
|
561
|
+
* @param partial 要覆盖的错误文案
|
|
562
|
+
*/
|
|
563
|
+
declare function setDataModelMessages(partial: Partial<DataModelMessages>): void;
|
|
564
|
+
/**
|
|
565
|
+
* @deprecated 旧写法;等价 `setDataModelMessages({ defaultErrMsg })`。
|
|
566
|
+
*/
|
|
567
|
+
declare function setDefaultErrMsg(msg: string): void;
|
|
568
|
+
/**
|
|
569
|
+
* @deprecated 旧写法;等价 `setDataModelMessages({ networkErrMsg })`。
|
|
570
|
+
*/
|
|
571
|
+
declare function setNetworkErrMsg(msg: string): void;
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* HTTP 响应协议适配器:替代硬编码 `code == 200` / Spring 分页字段。
|
|
575
|
+
* 传入 Partial 时与 `defaultResponseAdapter` 浅合并(见 `resolveResponseAdapter`)。
|
|
576
|
+
*/
|
|
577
|
+
|
|
578
|
+
interface ResponseAdapter {
|
|
579
|
+
isSuccess(body: unknown, raw: AxiosResponse): boolean;
|
|
580
|
+
getData<T = unknown>(body: unknown, raw: AxiosResponse): T;
|
|
581
|
+
getMessage(body: unknown, raw: AxiosResponse): string;
|
|
582
|
+
normalizeList?<T = unknown>(data: unknown): GetListResult<T> | unknown;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* 默认协议:`{ code, data, msg }`;Spring `content` + `pageNumber` 归一为 `{ list, pagination }`。
|
|
586
|
+
*/
|
|
587
|
+
declare const defaultResponseAdapter: ResponseAdapter;
|
|
588
|
+
/** 将用户传入的 Partial 与默认适配器浅合并。 */
|
|
589
|
+
declare function resolveResponseAdapter(partial?: Partial<ResponseAdapter>): ResponseAdapter;
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* DataModel 构造函数参数接口
|
|
593
|
+
*/
|
|
594
|
+
interface DataModelOptions<T = Record<string, any>> extends CrudModelOptions<T> {
|
|
595
|
+
/**
|
|
596
|
+
* 响应协议适配器;可只传要覆盖的方法,其余合并自 `defaultResponseAdapter`。
|
|
597
|
+
*/
|
|
598
|
+
responseAdapter?: Partial<ResponseAdapter>;
|
|
599
|
+
/** 请求的 axios 实例 */
|
|
600
|
+
axios?: typeof axios;
|
|
601
|
+
/** axios 配置 */
|
|
602
|
+
axiosConf?: AxiosConfig;
|
|
603
|
+
/** GET 列表接口 axios 配置 */
|
|
604
|
+
getListAxiosConf?: AxiosConfig;
|
|
605
|
+
/** GET 详情接口 axios 配置 */
|
|
606
|
+
getAxiosConf?: AxiosConfig;
|
|
607
|
+
/** POST 接口 axios 配置 */
|
|
608
|
+
createAxiosConf?: AxiosConfig;
|
|
609
|
+
/** PUT 接口 axios 配置 */
|
|
610
|
+
updateAxiosConf?: AxiosConfig;
|
|
611
|
+
/** PATCH 接口 axios 配置 */
|
|
612
|
+
patchAxiosConf?: AxiosConfig;
|
|
613
|
+
/** DELETE 接口 axios 配置 */
|
|
614
|
+
deleteAxiosConf?: AxiosConfig;
|
|
615
|
+
/** DELETE 批量删除接口 axios 配置 */
|
|
616
|
+
multipleDeleteAxiosConf?: AxiosConfig;
|
|
617
|
+
/**
|
|
618
|
+
* @deprecated 旧写法字段;设置后 `handleRes` 走旧分支,否则走 `responseAdapter`。
|
|
619
|
+
*/
|
|
620
|
+
handleResponse?: HandleResponseFunc;
|
|
621
|
+
/**
|
|
622
|
+
* @deprecated 旧写法字段;为 true 时 `get`/`create` 等直接 resolve 原始 response。
|
|
623
|
+
*/
|
|
624
|
+
isResponse?: boolean;
|
|
625
|
+
/**
|
|
626
|
+
* @deprecated 旧写法字段;为 true 时直接 resolve `response.data`(或 response)。
|
|
627
|
+
*/
|
|
628
|
+
isResponseData?: boolean;
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* 获取 API 地址的选项接口
|
|
632
|
+
*/
|
|
633
|
+
interface GetApiUrlOptions {
|
|
634
|
+
/** 请求来源标识 */
|
|
635
|
+
from?: string;
|
|
636
|
+
[key: string]: any;
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* 错误处理选项接口
|
|
640
|
+
*/
|
|
641
|
+
interface HandleMsgOptions {
|
|
642
|
+
/** 是否使用 response.statusText 作为兜底 msg */
|
|
643
|
+
useStatusText?: boolean;
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* DataModel 类
|
|
647
|
+
* 用于封装常用的 CRUD 请求方法
|
|
648
|
+
*/
|
|
649
|
+
declare class DataModel<T = Record<string, any>> extends BaseDataModel<T> implements ICrudModel<T> {
|
|
650
|
+
/** 响应协议适配器(完整,已与 default 合并) */
|
|
651
|
+
responseAdapter: ResponseAdapter;
|
|
652
|
+
/** 请求的 axios 实例 */
|
|
653
|
+
axios: typeof axios;
|
|
654
|
+
/** axios 配置 */
|
|
655
|
+
axiosConf: AxiosConfig;
|
|
656
|
+
getListAxiosConf?: AxiosConfig;
|
|
657
|
+
getAxiosConf?: AxiosConfig;
|
|
658
|
+
createAxiosConf?: AxiosConfig;
|
|
659
|
+
updateAxiosConf?: AxiosConfig;
|
|
660
|
+
patchAxiosConf?: AxiosConfig;
|
|
661
|
+
deleteAxiosConf?: AxiosConfig;
|
|
662
|
+
multipleDeleteAxiosConf?: AxiosConfig;
|
|
663
|
+
/**
|
|
664
|
+
* @deprecated 旧写法字段;设置后 `handleRes` 走旧分支,否则走 `responseAdapter`。
|
|
665
|
+
*/
|
|
666
|
+
handleResponse?: HandleResponseFunc;
|
|
667
|
+
/**
|
|
668
|
+
* @deprecated 旧写法字段;为 true 时直接 resolve 原始 response。
|
|
669
|
+
*/
|
|
670
|
+
isResponse: boolean;
|
|
671
|
+
/**
|
|
672
|
+
* @deprecated 旧写法字段;为 true 时直接 resolve `response.data`(或 response)。
|
|
673
|
+
*/
|
|
674
|
+
isResponseData: boolean;
|
|
675
|
+
/**
|
|
676
|
+
* 按 key 复用实例。二次调用忽略 options;改配置请用 `configure`。
|
|
677
|
+
*/
|
|
678
|
+
static getInstance<T = Record<string, any>>(key: string, options?: DataModelOptions<T>): DataModel<T>;
|
|
679
|
+
static clearInstance(key: string): boolean;
|
|
680
|
+
static clearAllInstances(): void;
|
|
681
|
+
constructor(params?: DataModelOptions<T>);
|
|
682
|
+
configure(partial: Partial<DataModelOptions<T>>): this;
|
|
683
|
+
/**
|
|
684
|
+
* 获取请求 url 地址
|
|
685
|
+
*/
|
|
686
|
+
getApiUrl(api: string | undefined, record?: JSONObject, ctx?: JSONObject, opt?: GetApiUrlOptions): string;
|
|
687
|
+
protected doGet(query: QueryParams, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T | null>;
|
|
688
|
+
protected doGetList(query: QueryParams, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<GetListResult<T>>;
|
|
689
|
+
protected doCreate(params?: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T>;
|
|
690
|
+
protected doUpdate(params?: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T>;
|
|
691
|
+
protected doPatch(params?: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<T>;
|
|
692
|
+
protected doDelete(_config: ModelDeleteConfig, ctx?: JSONObject, _axiosConf?: AxiosConfig): Promise<unknown>;
|
|
693
|
+
protected doMultipleDelete(_config: ModelDeleteConfig, ctx?: JSONObject, _axiosConf?: AxiosConfig): Promise<MultipleDeleteResult>;
|
|
694
|
+
private settleRes;
|
|
695
|
+
private settleErr;
|
|
696
|
+
/**
|
|
697
|
+
* 处理响应结果(走 responseAdapter)
|
|
698
|
+
*/
|
|
699
|
+
handleRes(response: ResponseData, resolve: (res: any) => void, reject: (err: ModelError) => void, opt?: {
|
|
700
|
+
fallbackData?: JSONObject;
|
|
701
|
+
}): void;
|
|
702
|
+
errorHandler(err: any | undefined, reject: (err: ModelError) => void): void;
|
|
703
|
+
handleMsg(response: any, opt?: HandleMsgOptions): string;
|
|
704
|
+
getNetworkErrMsg(errOrCode?: string | {
|
|
705
|
+
code?: string;
|
|
706
|
+
}): string;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* getPublicUrl 选项接口
|
|
711
|
+
*/
|
|
712
|
+
interface GetPublicUrlOptions {
|
|
713
|
+
/** 是否返回完整路径 */
|
|
714
|
+
isFullPath?: boolean;
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* 获取 public 文件路径(自动拼接 hash 数据)
|
|
718
|
+
*
|
|
719
|
+
* 兼容旧写法;本仓 webpack-config 尚无 `public-utils`,先留在 core 兼容层。
|
|
720
|
+
* @param url 文件路径
|
|
721
|
+
* @param opt 选项
|
|
722
|
+
* @returns 完整的 public 文件路径
|
|
723
|
+
*/
|
|
724
|
+
declare function getPublicUrl(url: string | any, opt?: GetPublicUrlOptions): string | any;
|
|
725
|
+
|
|
726
|
+
/**
|
|
727
|
+
* 共享查询协议类型(Array / IndexedDB / QueryEngine)。
|
|
728
|
+
* 与 pageNum / pageSize / sortKey / range / IN 约定一致。
|
|
729
|
+
*/
|
|
730
|
+
/**
|
|
731
|
+
* 分页信息
|
|
732
|
+
*/
|
|
733
|
+
interface Pagination {
|
|
734
|
+
/** 当前页码 */
|
|
735
|
+
current?: number;
|
|
736
|
+
/** 总条数 */
|
|
737
|
+
total: number;
|
|
738
|
+
/** 每页条数 */
|
|
739
|
+
pageSize?: number;
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* 列表查询结果
|
|
743
|
+
*/
|
|
744
|
+
interface FindListResult<T = Record<string, any>> {
|
|
745
|
+
/** 列表数据 */
|
|
746
|
+
list: T[];
|
|
747
|
+
/** 分页信息 */
|
|
748
|
+
pagination: Pagination;
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* 排序路径配置
|
|
752
|
+
*/
|
|
753
|
+
interface SortPathConfig {
|
|
754
|
+
/** 字段路径 */
|
|
755
|
+
path: string;
|
|
756
|
+
/** 字段类型 */
|
|
757
|
+
type?: string;
|
|
758
|
+
/** 自定义比较函数 */
|
|
759
|
+
customCompare?: (a: any, b: any, opt: any) => number;
|
|
760
|
+
/** 自定义值格式化函数 */
|
|
761
|
+
customFormat?: (val: any, data: any) => any;
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* 查询参数(分页 / 排序 + 任意过滤字段)
|
|
765
|
+
*/
|
|
766
|
+
interface ItemQuery {
|
|
767
|
+
/** 页码 */
|
|
768
|
+
pageNum?: number;
|
|
769
|
+
/** 每页条数 */
|
|
770
|
+
pageSize?: number;
|
|
771
|
+
/** 排序字段 */
|
|
772
|
+
sortKey?: string | string[] | SortPathConfig[];
|
|
773
|
+
/** 排序方式 */
|
|
774
|
+
sortType?: "asc" | "desc" | Record<string, "asc" | "desc">;
|
|
775
|
+
/**
|
|
776
|
+
* @deprecated 旧写法排序字段;QueryEngine 内部归一到 `sortKey`。
|
|
777
|
+
*/
|
|
778
|
+
orderByColumn?: string | string[] | SortPathConfig[];
|
|
779
|
+
/**
|
|
780
|
+
* @deprecated 旧写法排序方式;QueryEngine 内部归一到 `sortType`(boolean:true=asc, false=desc)。
|
|
781
|
+
*/
|
|
782
|
+
isAsc?: "asc" | "desc" | boolean;
|
|
783
|
+
/** 其他筛选条件 */
|
|
784
|
+
[key: string]: any;
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* 可替换的列表匹配函数(默认 includes / IN / 范围)
|
|
788
|
+
*/
|
|
789
|
+
type QueryMatcher = (item: Record<string, any>, query: Record<string, any>, options: QueryOptions) => boolean;
|
|
790
|
+
/**
|
|
791
|
+
* 查询选项
|
|
792
|
+
*/
|
|
793
|
+
interface QueryOptions {
|
|
794
|
+
/** 字符串字段是否开启模糊匹配 */
|
|
795
|
+
fuzzy?: boolean;
|
|
796
|
+
/** 模糊匹配时是否忽略大小写 */
|
|
797
|
+
ignoreCase?: boolean;
|
|
798
|
+
/** 限制参与模糊匹配的字段;未设则对 query 中的字符串键生效 */
|
|
799
|
+
searchFields?: string[];
|
|
800
|
+
/** 自定义 matcher,传入则替换默认匹配逻辑 */
|
|
801
|
+
matcher?: QueryMatcher;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* 默认 matcher:字段匹配(includes / IN / 范围);支持 searchFields 限定模糊字段
|
|
806
|
+
*/
|
|
807
|
+
declare const defaultQueryMatcher: QueryMatcher;
|
|
808
|
+
interface QueryEngine {
|
|
809
|
+
/** filter → sort → paginate */
|
|
810
|
+
run<T extends Record<string, any>>(source: T[], query?: ItemQuery, options?: QueryOptions): FindListResult<T>;
|
|
811
|
+
match(item: Record<string, any>, query: Record<string, any>, options?: QueryOptions): boolean;
|
|
812
|
+
filter<T extends Record<string, any>>(source: T[], query: Record<string, any>, options?: QueryOptions): T[];
|
|
813
|
+
sort<T extends Record<string, any>>(list: T[], sortKey?: string | string[] | SortPathConfig[], sortType?: "asc" | "desc" | Record<string, "asc" | "desc">): T[];
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* 创建共享查询引擎(Array 全量 / IDB 索引预筛后的 candidates 共用)
|
|
817
|
+
*/
|
|
818
|
+
declare function createQueryEngine(defaults?: QueryOptions): QueryEngine;
|
|
819
|
+
/** 默认引擎(fuzzy 由调用方按场景传入) */
|
|
820
|
+
declare const defaultQueryEngine: QueryEngine;
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* 状态码枚举
|
|
824
|
+
*/
|
|
825
|
+
declare const STATE_CODE: {
|
|
826
|
+
/** 成功 */
|
|
827
|
+
readonly SUC: 200;
|
|
828
|
+
/** 未找到 */
|
|
829
|
+
readonly NOT_FOUND: 404;
|
|
830
|
+
/**
|
|
831
|
+
* @deprecated 旧写法拼写错误;等价 `NOT_FOUND`。
|
|
832
|
+
*/
|
|
833
|
+
readonly NOT_FOUNT: 404;
|
|
834
|
+
/** 错误 */
|
|
835
|
+
readonly ERR: 500;
|
|
836
|
+
/** 缺少 ID 错误 */
|
|
837
|
+
readonly ERR_INPUT_ID: 501;
|
|
838
|
+
};
|
|
839
|
+
/**
|
|
840
|
+
* 状态码类型
|
|
841
|
+
*/
|
|
842
|
+
type StateCode = (typeof STATE_CODE)[keyof typeof STATE_CODE];
|
|
843
|
+
/**
|
|
844
|
+
* ArrayUtils 构造函数参数接口
|
|
845
|
+
*/
|
|
846
|
+
interface ArrayUtilsOptions<T = Record<string, any>> {
|
|
847
|
+
/** 子项唯一标志字段 */
|
|
848
|
+
idKey?: string;
|
|
849
|
+
/** 列表数据 */
|
|
850
|
+
list?: T[];
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* 数组模拟数据库存储
|
|
854
|
+
* @template T - 列表项数据类型
|
|
855
|
+
*/
|
|
856
|
+
declare class ArrayUtils<T extends Record<string, any> = Record<string, any>> {
|
|
857
|
+
/** 子项唯一标志字段 */
|
|
858
|
+
protected _idKey: string;
|
|
859
|
+
/** 列表数据 */
|
|
860
|
+
protected _list: T[];
|
|
861
|
+
constructor(params?: ArrayUtilsOptions<T>);
|
|
862
|
+
/** 主键字段名(供组合方读取) */
|
|
863
|
+
get idKey(): string;
|
|
864
|
+
/**
|
|
865
|
+
* 通过 id 获取子项
|
|
866
|
+
* @param id 目标 ID
|
|
867
|
+
* @returns 匹配的子项或 null
|
|
868
|
+
*/
|
|
869
|
+
findItemById(id: string | number): T | null;
|
|
870
|
+
/**
|
|
871
|
+
* 通过 query 获取子项
|
|
872
|
+
* @param query 查询条件
|
|
873
|
+
* @param options 查询选项
|
|
874
|
+
* @returns 匹配的子项或 null
|
|
875
|
+
*/
|
|
876
|
+
findItem(query?: Record<string, any>, options?: QueryOptions): T | null;
|
|
877
|
+
/**
|
|
878
|
+
* 通过 query 筛选列表(支持多条件筛选、分页、排序)
|
|
879
|
+
* 委托共享 QueryEngine:filter → sort → paginate
|
|
880
|
+
*/
|
|
881
|
+
findListByQuery(query?: ItemQuery, options?: QueryOptions): Promise<FindListResult<T>>;
|
|
882
|
+
/**
|
|
883
|
+
* 对目标数据进行多维度排序
|
|
884
|
+
*/
|
|
885
|
+
getSortList(sortKey?: string | string[] | SortPathConfig[], sortType?: "asc" | "desc" | Record<string, "asc" | "desc">, customList?: T[]): T[];
|
|
886
|
+
/**
|
|
887
|
+
* 比较两个数据对象的排序顺序(支持多字段优先级排序)
|
|
888
|
+
*/
|
|
889
|
+
compareData(dataA: T, dataB: T, opt: {
|
|
890
|
+
paths: (string | SortPathConfig)[];
|
|
891
|
+
pathIdx?: number;
|
|
892
|
+
sortType?: "asc" | "desc" | Record<string, "asc" | "desc">;
|
|
893
|
+
}): number;
|
|
894
|
+
/**
|
|
895
|
+
* 根据路径获取并处理字段值
|
|
896
|
+
*/
|
|
897
|
+
handleValByKey(data: T, pathConfig: string | SortPathConfig | null | undefined): any;
|
|
898
|
+
/**
|
|
899
|
+
* 获取完整列表
|
|
900
|
+
*/
|
|
901
|
+
findAllList(): T[];
|
|
902
|
+
/**
|
|
903
|
+
* 获取总数
|
|
904
|
+
*/
|
|
905
|
+
getCount(): number;
|
|
906
|
+
/**
|
|
907
|
+
* push 数据
|
|
908
|
+
*/
|
|
909
|
+
pushItem(data: Partial<T>): T;
|
|
910
|
+
pushItem(data: Partial<T>[]): T[];
|
|
911
|
+
/**
|
|
912
|
+
* unshift 数据
|
|
913
|
+
*/
|
|
914
|
+
unshiftItem(data: Partial<T>): T;
|
|
915
|
+
/**
|
|
916
|
+
* 根据 id 更新子项——直接替换
|
|
917
|
+
*/
|
|
918
|
+
replaceItem(data: T): T | StateCode;
|
|
919
|
+
/**
|
|
920
|
+
* 根据 id 更新子项——仅修改传入的数据
|
|
921
|
+
*/
|
|
922
|
+
updateItemValue(data: Partial<T> & {
|
|
923
|
+
[key: string]: any;
|
|
924
|
+
}): T | StateCode;
|
|
925
|
+
/**
|
|
926
|
+
* 删除子项
|
|
927
|
+
*/
|
|
928
|
+
delItem(id: any): StateCode;
|
|
929
|
+
/**
|
|
930
|
+
* 清空所有数据
|
|
931
|
+
*/
|
|
932
|
+
clearAll(): StateCode;
|
|
933
|
+
/**
|
|
934
|
+
* 批量删除
|
|
935
|
+
*/
|
|
936
|
+
deleteItems(ids: any[]): number;
|
|
937
|
+
/**
|
|
938
|
+
* 判断列表是否为空
|
|
939
|
+
*/
|
|
940
|
+
isEmpty(): boolean;
|
|
941
|
+
/**
|
|
942
|
+
* 获取指定范围的列表
|
|
943
|
+
*/
|
|
944
|
+
slice(start?: number, end?: number): T[];
|
|
945
|
+
/**
|
|
946
|
+
* 检查单个 item 是否匹配所有 query 条件
|
|
947
|
+
*/
|
|
948
|
+
protected _isItemMatchQuery(item: T, query: Record<string, any>, options?: QueryOptions): boolean;
|
|
949
|
+
/**
|
|
950
|
+
* 过滤空查询条件
|
|
951
|
+
*/
|
|
952
|
+
protected _filterEmptyQuery(query: Record<string, any>): Record<string, any>;
|
|
953
|
+
/**
|
|
954
|
+
* 检查 ID 是否无效
|
|
955
|
+
*/
|
|
956
|
+
protected _isInvalidId(id: any): boolean;
|
|
957
|
+
/**
|
|
958
|
+
* 子项没有 id 的时候自动添加
|
|
959
|
+
*/
|
|
960
|
+
protected _setId(item: T): T;
|
|
961
|
+
/**
|
|
962
|
+
* 设置创建时间
|
|
963
|
+
*/
|
|
964
|
+
protected _setCreateTime(item: T): void;
|
|
965
|
+
/**
|
|
966
|
+
* 设置更新时间
|
|
967
|
+
*/
|
|
968
|
+
protected _setUpdateTime(item: T): void;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
/**
|
|
972
|
+
* ArrayDataModel 构造函数参数接口
|
|
973
|
+
*/
|
|
974
|
+
interface ArrayDataModelOptions<T extends Record<string, any> = Record<string, any>> extends CrudModelOptions<T>, ArrayUtilsOptions<T> {
|
|
975
|
+
/** 查询选项 */
|
|
976
|
+
arrOptions?: ArrOptions;
|
|
977
|
+
/**
|
|
978
|
+
* 写操作模拟网络延迟(ms)。默认 `0`;demo 可设 `300` 等。
|
|
979
|
+
*/
|
|
980
|
+
delayMs?: number;
|
|
981
|
+
}
|
|
982
|
+
/**
|
|
983
|
+
* 查询选项
|
|
984
|
+
*/
|
|
985
|
+
interface ArrOptions {
|
|
986
|
+
/** 字符串字段是否开启模糊匹配 */
|
|
987
|
+
fuzzy?: boolean;
|
|
988
|
+
/** 模糊匹配时是否忽略大小写 */
|
|
989
|
+
ignoreCase?: boolean;
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
* handleRes 选项
|
|
993
|
+
*/
|
|
994
|
+
interface HandleResOptions {
|
|
995
|
+
/** 成功结果映射 */
|
|
996
|
+
resMap?: MapFunction<Record<string, any>>;
|
|
997
|
+
/** 成功时 resolve 的资源快照(create/update/patch) */
|
|
998
|
+
payload?: Record<string, any>;
|
|
999
|
+
}
|
|
1000
|
+
/**
|
|
1001
|
+
* ArrayDataModel 本地数据 DataModel(内存列表模拟 CRUD)。
|
|
1002
|
+
*
|
|
1003
|
+
* FormData:create/update/patch 入参若为 FormData,会先 `formDataToObj` 成普通对象再入库;
|
|
1004
|
+
* 不转回 FormData(无 multipart)。其中的 File/Blob 仅保留内存引用,不落盘、不持久化。
|
|
1005
|
+
* @template T - 数据类型
|
|
1006
|
+
*/
|
|
1007
|
+
declare class ArrayDataModel<T extends Record<string, any> = Record<string, any>> extends BaseDataModel<T> implements ICrudModel<T> {
|
|
1008
|
+
/** 内存列表存储 */
|
|
1009
|
+
private store;
|
|
1010
|
+
/** 查询选项 */
|
|
1011
|
+
private _arrOptions?;
|
|
1012
|
+
/** 写操作延迟(ms) */
|
|
1013
|
+
private delayMs;
|
|
1014
|
+
static getInstance<T extends Record<string, any> = Record<string, any>>(key: string, options?: ArrayDataModelOptions<T>): ArrayDataModel<T>;
|
|
1015
|
+
static clearInstance(key: string): boolean;
|
|
1016
|
+
static clearAllInstances(): void;
|
|
1017
|
+
constructor(params?: ArrayDataModelOptions<T>);
|
|
1018
|
+
/**
|
|
1019
|
+
* 更新配置。不允许通过 configure 替换整个 `list` 存储(易丢数据);要重置用 `clearInstance`。
|
|
1020
|
+
*/
|
|
1021
|
+
configure(partial: Partial<ArrayDataModelOptions<T>>): this;
|
|
1022
|
+
private delay;
|
|
1023
|
+
private rejectCode;
|
|
1024
|
+
protected doGet(query: QueryParams, _ctx?: JSONObject, _axiosConf?: AxiosConfig): Promise<T | null>;
|
|
1025
|
+
protected doGetList(query: QueryParams, _ctx?: JSONObject, _axiosConf?: AxiosConfig): Promise<FindListResult<T>>;
|
|
1026
|
+
protected doCreate(params: RequestData | FormData, _ctx?: JSONObject, _axiosConf?: AxiosConfig): Promise<T>;
|
|
1027
|
+
protected doUpdate(params: RequestData | FormData, _ctx?: JSONObject, _axiosConf?: AxiosConfig): Promise<T>;
|
|
1028
|
+
protected doPatch(params: RequestData | FormData, _ctx?: JSONObject, _axiosConf?: AxiosConfig): Promise<T>;
|
|
1029
|
+
protected doDelete(_config: ModelDeleteConfig, ctx?: Record<string, any>, _axiosConf?: AxiosConfig): Promise<Record<string, any>>;
|
|
1030
|
+
protected doMultipleDelete(_config: ModelDeleteConfig, ctx?: Record<string, any>, _axiosConf?: AxiosConfig): Promise<MultipleDeleteResult>;
|
|
1031
|
+
/**
|
|
1032
|
+
* 处理响应结果(delete 等仍用状态码)
|
|
1033
|
+
*/
|
|
1034
|
+
handleRes(res: number, resolve: (res: Record<string, any>) => void, reject: (err: ModelError) => void, opt?: HandleResOptions): void;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
/**
|
|
1038
|
+
* IndexedDB DataModel 业务状态码(含与 Array 对齐的码 + 冲突)
|
|
1039
|
+
*/
|
|
1040
|
+
declare const IDB_STATE_CODE: {
|
|
1041
|
+
/** 主键 / 唯一约束冲突 */
|
|
1042
|
+
readonly CONFLICT: 409;
|
|
1043
|
+
readonly SUC: 200;
|
|
1044
|
+
readonly NOT_FOUND: 404;
|
|
1045
|
+
readonly NOT_FOUNT: 404;
|
|
1046
|
+
readonly ERR: 500;
|
|
1047
|
+
readonly ERR_INPUT_ID: 501;
|
|
1048
|
+
};
|
|
1049
|
+
type IdbStateCode = (typeof IDB_STATE_CODE)[keyof typeof IDB_STATE_CODE];
|
|
1050
|
+
/**
|
|
1051
|
+
* IndexedDB 业务错误(`ModelError` 子类,文案仅 `_msg`)
|
|
1052
|
+
*/
|
|
1053
|
+
declare class IdbModelError extends ModelError {
|
|
1054
|
+
code: number | string;
|
|
1055
|
+
_msg: string;
|
|
1056
|
+
constructor(code: number | string, message?: string, data?: unknown);
|
|
1057
|
+
}
|
|
1058
|
+
/** 是否为 IdbModelError */
|
|
1059
|
+
declare function isIdbModelError(err: unknown): err is IdbModelError;
|
|
1060
|
+
/** 是否为 IndexedDB 主键 / 唯一约束冲突 */
|
|
1061
|
+
declare function isIdbConstraintError(err: unknown): boolean;
|
|
1062
|
+
|
|
1063
|
+
/**
|
|
1064
|
+
* 跨 tab 同步变更动作
|
|
1065
|
+
*/
|
|
1066
|
+
type IdbSyncAction = "create" | "update" | "patch" | "delete" | "multipleDelete" | "gc";
|
|
1067
|
+
/**
|
|
1068
|
+
* 跨 tab 同步消息(只广播变更通知,不推全量记录)
|
|
1069
|
+
*/
|
|
1070
|
+
interface IdbSyncMessage {
|
|
1071
|
+
v: 1;
|
|
1072
|
+
dbName: string;
|
|
1073
|
+
storeName: string;
|
|
1074
|
+
action: IdbSyncAction;
|
|
1075
|
+
/** 受影响的主键列表(可知时带上) */
|
|
1076
|
+
ids?: any[];
|
|
1077
|
+
/** 发送方实例 id,用于忽略自发消息 */
|
|
1078
|
+
tabId: string;
|
|
1079
|
+
ts: number;
|
|
1080
|
+
}
|
|
1081
|
+
type IdbSyncListener = (message: IdbSyncMessage) => void;
|
|
1082
|
+
/**
|
|
1083
|
+
* 跨 tab 同步选项
|
|
1084
|
+
*/
|
|
1085
|
+
interface IdbSyncOptions {
|
|
1086
|
+
/** 是否启用,默认 true */
|
|
1087
|
+
enabled?: boolean;
|
|
1088
|
+
/**
|
|
1089
|
+
* 通道名;默认 `data-model:idb:${dbName}`
|
|
1090
|
+
* 同库多 store 共用 channel,接收方按 `storeName` 过滤
|
|
1091
|
+
*/
|
|
1092
|
+
channelName?: string;
|
|
1093
|
+
/** 无 BroadcastChannel 时是否用 localStorage 事件兜底,默认 true */
|
|
1094
|
+
storageFallback?: boolean;
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
/**
|
|
1098
|
+
* IndexedDB 业务 store 索引配置(在 `onupgradeneeded` 中创建)
|
|
1099
|
+
*/
|
|
1100
|
+
interface IdbIndexConfig {
|
|
1101
|
+
/** 索引名 */
|
|
1102
|
+
name: string;
|
|
1103
|
+
/** 索引字段路径 */
|
|
1104
|
+
keyPath: string | string[];
|
|
1105
|
+
/** 是否唯一索引 */
|
|
1106
|
+
unique?: boolean;
|
|
1107
|
+
}
|
|
1108
|
+
/**
|
|
1109
|
+
* 业务记录中的文件引用(Blob 存在独立 files objectStore)
|
|
1110
|
+
*/
|
|
1111
|
+
interface FileRef {
|
|
1112
|
+
/** files store 主键 */
|
|
1113
|
+
fileId: string;
|
|
1114
|
+
/** 原始文件名 */
|
|
1115
|
+
name: string;
|
|
1116
|
+
/** MIME type */
|
|
1117
|
+
type: string;
|
|
1118
|
+
/** 字节大小 */
|
|
1119
|
+
size: number;
|
|
1120
|
+
}
|
|
1121
|
+
/**
|
|
1122
|
+
* 对外文件记录(`getFile` 返回;始终带可消费的 `Blob`)
|
|
1123
|
+
*/
|
|
1124
|
+
interface FileRecord {
|
|
1125
|
+
id: string;
|
|
1126
|
+
blob: Blob;
|
|
1127
|
+
name: string;
|
|
1128
|
+
type: string;
|
|
1129
|
+
size: number;
|
|
1130
|
+
createdAt: number;
|
|
1131
|
+
/** 来源业务 store,便于排查 / 清理 */
|
|
1132
|
+
storeName?: string;
|
|
1133
|
+
}
|
|
1134
|
+
/**
|
|
1135
|
+
* IndexedDbDataModel 构造参数。
|
|
1136
|
+
* CRUD / maps 字段与 DataModel、ArrayDataModel 对齐;`*Api` 可不填(无 HTTP)。
|
|
1137
|
+
*/
|
|
1138
|
+
interface IndexedDbDataModelOptions<T extends Record<string, any> = Record<string, any>> extends CrudModelOptions<T> {
|
|
1139
|
+
/** IndexedDB 数据库名 */
|
|
1140
|
+
dbName: string;
|
|
1141
|
+
/** 业务 objectStore 名 */
|
|
1142
|
+
storeName: string;
|
|
1143
|
+
/** 主键字段,默认 `id` */
|
|
1144
|
+
idKey?: string;
|
|
1145
|
+
/** 最低版本(可选,默认 1);缺表/缺索引时会自动升 version,同库多 store 无需手工对齐 */
|
|
1146
|
+
version?: number;
|
|
1147
|
+
/** 业务 store 可选索引 */
|
|
1148
|
+
indexes?: IdbIndexConfig[];
|
|
1149
|
+
/** 文件 store 名,默认 `__files`(同库共享) */
|
|
1150
|
+
filesStoreName?: string;
|
|
1151
|
+
/**
|
|
1152
|
+
* 跨 tab 同步:默认启用。
|
|
1153
|
+
* - `false` 关闭
|
|
1154
|
+
* - 对象可配 `channelName` / `storageFallback`
|
|
1155
|
+
*/
|
|
1156
|
+
sync?: boolean | IdbSyncOptions;
|
|
1157
|
+
/** 查询选项(模糊匹配、自定义 matcher 等) */
|
|
1158
|
+
idbOptions?: QueryOptions;
|
|
1159
|
+
}
|
|
1160
|
+
/**
|
|
1161
|
+
* 判断值是否为 `FileRef`(业务记录中的文件引用)
|
|
1162
|
+
*/
|
|
1163
|
+
declare function isFileRef(value: unknown): value is FileRef;
|
|
1164
|
+
|
|
1165
|
+
/**
|
|
1166
|
+
* IndexedDB 版 DataModel。
|
|
1167
|
+
*
|
|
1168
|
+
* 业务用法对齐 `DataModel` / `ArrayDataModel`:`get` / `getList` / `create` / `update` /
|
|
1169
|
+
* `patch` / `delete` / `multipleDelete`,以及 `*ReqMap` / `*ResMap` 等(模板在 `BaseDataModel`)。
|
|
1170
|
+
*
|
|
1171
|
+
* - 数据持久化到 IndexedDB 业务 store
|
|
1172
|
+
* - `File` / `Blob` 写入独立 files store,记录只保留 `FileRef`
|
|
1173
|
+
* - 模糊搜索默认 includes,可通过 `idbOptions.matcher` 替换
|
|
1174
|
+
*
|
|
1175
|
+
* @template T - 业务记录类型
|
|
1176
|
+
*/
|
|
1177
|
+
declare class IndexedDbDataModel<T extends Record<string, any> = Record<string, any>> extends BaseDataModel<T> implements ICrudModel<T> {
|
|
1178
|
+
/** IndexedDB 数据库名 */
|
|
1179
|
+
dbName: string;
|
|
1180
|
+
/** 业务 objectStore 名 */
|
|
1181
|
+
storeName: string;
|
|
1182
|
+
/** 文件 objectStore 名 */
|
|
1183
|
+
filesStoreName: string;
|
|
1184
|
+
/** 数据库版本 */
|
|
1185
|
+
version: number;
|
|
1186
|
+
/** 主键字段名 */
|
|
1187
|
+
idKey: string;
|
|
1188
|
+
/** 业务 store 索引配置 */
|
|
1189
|
+
indexes?: IndexedDbDataModelOptions<T>["indexes"];
|
|
1190
|
+
/** 模糊匹配等查询选项 */
|
|
1191
|
+
idbOptions: QueryOptions;
|
|
1192
|
+
/** 由本实例 `getFileUrl` 创建的 object URL,close / revokeAll 时统一释放 */
|
|
1193
|
+
private objectUrls;
|
|
1194
|
+
/** 跨 tab 同步总线(sync: false 时为 null) */
|
|
1195
|
+
private syncBus;
|
|
1196
|
+
/** 远程变更监听(含本页其它实例) */
|
|
1197
|
+
private remoteListeners;
|
|
1198
|
+
static getInstance<T extends Record<string, any> = Record<string, any>>(key: string, options: IndexedDbDataModelOptions<T>): IndexedDbDataModel<T>;
|
|
1199
|
+
static clearInstance(key: string): boolean;
|
|
1200
|
+
static clearAllInstances(): void;
|
|
1201
|
+
constructor(params: IndexedDbDataModelOptions<T>);
|
|
1202
|
+
/**
|
|
1203
|
+
* 更新配置。不允许改 `dbName` / `storeName` / `indexes` / `version` / `filesStoreName`(已 open 的库);
|
|
1204
|
+
* 要换库用 `clearInstance` + 新 key。
|
|
1205
|
+
*/
|
|
1206
|
+
configure(partial: Partial<IndexedDbDataModelOptions<T>>): this;
|
|
1207
|
+
/** 广播本 store 变更(供其它 tab / 实例刷新) */
|
|
1208
|
+
private publishSync;
|
|
1209
|
+
/**
|
|
1210
|
+
* 订阅其它 tab(或同页其它实例)对本 store 的写变更。
|
|
1211
|
+
* 收到后通常重新 `getList` / `get`;不自动改本地内存。
|
|
1212
|
+
* @returns 取消订阅函数
|
|
1213
|
+
*/
|
|
1214
|
+
subscribe(listener: IdbSyncListener): () => void;
|
|
1215
|
+
/** 供 db 层使用的打开配置 */
|
|
1216
|
+
private get dbOpt();
|
|
1217
|
+
/** 抛出 `IdbModelError`(带 code / _msg,且为 Error 子类) */
|
|
1218
|
+
private rejectCode;
|
|
1219
|
+
/**
|
|
1220
|
+
* 预打开数据库连接(可选;CRUD 内部会自动 open)
|
|
1221
|
+
*/
|
|
1222
|
+
ready(): Promise<IDBDatabase>;
|
|
1223
|
+
/**
|
|
1224
|
+
* 释放 object URL、断开同步总线,并关闭本库缓存连接
|
|
1225
|
+
*/
|
|
1226
|
+
close(): Promise<void>;
|
|
1227
|
+
/**
|
|
1228
|
+
* 查询详情。有主键走 `store.get`;否则 getAll + 精确匹配取首条。找不到返回 `null`。
|
|
1229
|
+
* ReqMap / ResMap 由模板处理;此处接收已 merge + ReqMap 的 query。
|
|
1230
|
+
*/
|
|
1231
|
+
protected doGet(query: QueryParams, _ctx?: JSONObject, _axiosConf?: AxiosConfig): Promise<T | null>;
|
|
1232
|
+
/**
|
|
1233
|
+
* 列表查询:索引预筛 + 内存过滤 / 模糊 / 排序 / 分页。
|
|
1234
|
+
* getListFunc / ResMap 由模板处理。
|
|
1235
|
+
*/
|
|
1236
|
+
protected doGetList(query: QueryParams, _ctx?: JSONObject, _axiosConf?: AxiosConfig): Promise<FindListResult<T>>;
|
|
1237
|
+
/**
|
|
1238
|
+
* 创建记录。缺主键时自动 `nanoid()`;`File`/`Blob` 写入 files store。
|
|
1239
|
+
* ResMap 由模板处理。
|
|
1240
|
+
*/
|
|
1241
|
+
protected doCreate(params: RequestData | FormData, _ctx?: JSONObject, _axiosConf?: AxiosConfig): Promise<T>;
|
|
1242
|
+
/**
|
|
1243
|
+
* 整单替换更新(需带主键)。替换文件时删除旧 blob。ResMap 由模板处理。
|
|
1244
|
+
*/
|
|
1245
|
+
protected doUpdate(params: RequestData | FormData, _ctx?: JSONObject, _axiosConf?: AxiosConfig): Promise<T>;
|
|
1246
|
+
/**
|
|
1247
|
+
* 局部更新:先读后 merge 再 put。替换文件时删除旧 blob。ResMap 由模板处理。
|
|
1248
|
+
*/
|
|
1249
|
+
protected doPatch(params: RequestData | FormData, _ctx?: JSONObject, _axiosConf?: AxiosConfig): Promise<T>;
|
|
1250
|
+
/**
|
|
1251
|
+
* 删除单条,并级联删除记录上的 FileRef 对应文件。
|
|
1252
|
+
* deleteReqMap / deleteResMap 由模板处理。
|
|
1253
|
+
*/
|
|
1254
|
+
protected doDelete(config: ModelDeleteConfig, ctx?: Record<string, any>, _axiosConf?: AxiosConfig): Promise<Record<string, any>>;
|
|
1255
|
+
/**
|
|
1256
|
+
* 批量删除。ids 可为数组或逗号分隔字符串;返回 `{ sucList, failList }`。
|
|
1257
|
+
* ReqMap / ResMap 由模板处理;逐条走 `this.delete`。
|
|
1258
|
+
*/
|
|
1259
|
+
protected doMultipleDelete(config: ModelDeleteConfig, ctx?: Record<string, any>, _axiosConf?: AxiosConfig): Promise<MultipleDeleteResult>;
|
|
1260
|
+
/**
|
|
1261
|
+
* 按 fileId 读取文件内容(含 Blob)
|
|
1262
|
+
*/
|
|
1263
|
+
getFile(fileId: string): Promise<FileRecord | null>;
|
|
1264
|
+
/**
|
|
1265
|
+
* 按 fileId 生成 `blob:` URL,并由本实例托管;可用 `revokeFileUrl` / `close` 释放
|
|
1266
|
+
*/
|
|
1267
|
+
getFileUrl(fileId: string): Promise<string | null>;
|
|
1268
|
+
/**
|
|
1269
|
+
* 释放单个由 `getFileUrl` 创建的 object URL
|
|
1270
|
+
*/
|
|
1271
|
+
revokeFileUrl(url: string): void;
|
|
1272
|
+
/**
|
|
1273
|
+
* 释放本实例托管的全部 object URL
|
|
1274
|
+
*/
|
|
1275
|
+
revokeAllFileUrls(): void;
|
|
1276
|
+
/**
|
|
1277
|
+
* 扫描本 store 记录,删除 files store 中未被引用且归属本 store 的孤儿文件。
|
|
1278
|
+
* @returns 删除的文件数量
|
|
1279
|
+
*/
|
|
1280
|
+
gcOrphanFiles(): Promise<number>;
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
/**
|
|
1284
|
+
* useDataModel 选项接口
|
|
1285
|
+
*/
|
|
1286
|
+
interface UseDataModelOptions<T = any> {
|
|
1287
|
+
/** 动态数据监听的目标 */
|
|
1288
|
+
effectTargets?: any[];
|
|
1289
|
+
/** 动态的 params 数据,包含了 query */
|
|
1290
|
+
effectParams?: Partial<DataModelOptions<T>>;
|
|
1291
|
+
/** 动态的 query 数据 */
|
|
1292
|
+
effectQuery?: DataModelOptions<T>["query"];
|
|
1293
|
+
}
|
|
1294
|
+
/**
|
|
1295
|
+
* 解决 hooks 重复实例化导致 query 丢失的问题
|
|
1296
|
+
* @param {Object} initParams 初始参数
|
|
1297
|
+
* @param {Object} opt
|
|
1298
|
+
* @param {Object} opt.effectTargets 动态数据监听的目标
|
|
1299
|
+
* @param {Object} opt.effectParams 动态的 params 数据,包含了 query
|
|
1300
|
+
* @param {Object} opt.effectQuery 动态的 query 数据
|
|
1301
|
+
* @returns DataModel 实例
|
|
1302
|
+
*/
|
|
1303
|
+
declare const useDataModel: <T = any>(initParams?: DataModelOptions<T>, opt?: UseDataModelOptions<T>) => DataModel<T>;
|
|
1304
|
+
|
|
1305
|
+
export { type ApiError, type ArrOptions, ArrayDataModel, type ArrayDataModelOptions, ArrayUtils, type ArrayUtilsOptions, type AxiosConfig, type AxiosRequestConfigWithCache, type AxiosResponseCus, BaseDataModel, type CacheHitError, type CacheItem, type CacheOpt, type CrudModelOptions, DataModel, type DataModelMessages, type DataModelOptions, type FileRecord, type FileRef, type FindListResult, type GetApiUrlOptions, type GetListFunc, type GetListResult, type GetPublicUrlOptions, type GetTokenOptions, type HandleErrCbOptions, type HandleMsgOptions, type HandleResOptions, type HandleResponseFunc, type ICrudModel, IDB_STATE_CODE, type IdbIndexConfig, IdbModelError, type IdbStateCode, IndexedDbDataModel, type IndexedDbDataModelOptions, type ItemQuery, type JSONObject, type MapFunction, type ModelDeleteConfig, ModelError, type MultipleDeleteResult, type QueryEngine, type QueryMatcher, type QueryOptions, type QueryParams, type Req, RequestCache, type RequestCacheParams, type RequestData, type RequestMapFunction, type ResData, type ResponseAdapter, type ResponseData, STATE_CODE, type SetTokenOptions, type StateCode, TOKEN, type UseDataModelOptions, axios, createAbortController, createAxiosClient, createQueryEngine, DataModel as default, defaultQueryEngine, defaultQueryMatcher, defaultResponseAdapter, getCancelTokenSource, getDefaultAxios, getPublicUrl, getToken, handleErrCb, isCacheHitError, isCancel, isFileRef, isIdbConstraintError, isIdbModelError, isModelError, registerAxios, resolveResponseAdapter, setAxAuthorization, setAxBaseUrl, setAxDefaults, setAxHeaders, setAxRequest, setAxResponse, setAxTimeout, setAxios, setDataModelMessages, setDefaultAxios, setDefaultErrMsg, setNetworkErrMsg, setToken, temp, useDataModel };
|