@base-web-kits/base-tools-web 1.0.2 → 1.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/README.md +2 -2
- package/dist/base-tools-web.umd.global.js +1385 -1
- package/dist/base-tools-web.umd.global.js.map +1 -1
- package/dist/config/index.d.ts +55 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/index.cjs +1214 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1219 -1
- package/dist/index.js.map +1 -1
- package/dist/network/index.d.ts +3 -0
- package/dist/network/index.d.ts.map +1 -0
- package/dist/{load/index.d.ts → network/load.d.ts} +1 -1
- package/dist/network/load.d.ts.map +1 -0
- package/dist/network/request.d.ts +151 -0
- package/dist/network/request.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/web/config/index.ts +67 -0
- package/src/web/index.ts +2 -1
- package/src/web/network/index.ts +2 -0
- package/src/web/network/request.ts +491 -0
- package/dist/load/index.d.ts.map +0 -1
- /package/src/web/{load/index.ts → network/load.ts} +0 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/** 请求方法类型 */
|
|
2
|
+
export type RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'HEAD' | 'OPTIONS' | 'TRACE' | 'PATCH';
|
|
3
|
+
/**
|
|
4
|
+
* 请求参数类型
|
|
5
|
+
* 包含 fetch 原生支持的 BodyInit 类型,以及支持自动 JSON 序列化的对象和数组
|
|
6
|
+
*/
|
|
7
|
+
export type RequestData = string | ArrayBuffer | ArrayBufferView | Blob | FormData | URLSearchParams | ReadableStream<Uint8Array> | Record<string, unknown> | unknown[] | null;
|
|
8
|
+
/**
|
|
9
|
+
* 响应数据类型
|
|
10
|
+
*/
|
|
11
|
+
export type ResponseData = string | ArrayBuffer | Blob | Record<string, unknown> | unknown[] | null;
|
|
12
|
+
/**
|
|
13
|
+
* 发起请求的配置 (对外,参数可选)
|
|
14
|
+
*/
|
|
15
|
+
export type RequestConfig<D extends RequestData = RequestData> = Partial<RequestConfigBase<D>>;
|
|
16
|
+
/**
|
|
17
|
+
* 自定义请求的配置 (接口字段参数必填)
|
|
18
|
+
*/
|
|
19
|
+
export type RequestConfigBase<D extends RequestData = RequestData> = {
|
|
20
|
+
/** 接口地址 */
|
|
21
|
+
url: string;
|
|
22
|
+
/** 请求方法 */
|
|
23
|
+
method?: RequestMethod;
|
|
24
|
+
/** 请求头 */
|
|
25
|
+
header?: Record<string, string>;
|
|
26
|
+
/** 请求参数 */
|
|
27
|
+
data?: D;
|
|
28
|
+
/** 超时时间 (毫秒), 默认 60000 */
|
|
29
|
+
timeout?: number;
|
|
30
|
+
/** 接口返回响应数据的字段, 支持"a[0].b.c"的格式, 当配置false时返回完整的响应数据 */
|
|
31
|
+
resKey: string | false;
|
|
32
|
+
/** 接口返回响应消息的字段, 支持"a[0].b.c"的格式 */
|
|
33
|
+
msgKey: string;
|
|
34
|
+
/** 接口返回响应状态码的字段, 支持"a[0].b.c"的格式 */
|
|
35
|
+
codeKey: string;
|
|
36
|
+
/** 接口返回成功状态码的字段, 支持"a[0].b.c"的格式 (默认取 codeKey) */
|
|
37
|
+
successKey?: string;
|
|
38
|
+
/** 成功状态码 */
|
|
39
|
+
successCode: (number | string)[];
|
|
40
|
+
/** 登录过期状态码 */
|
|
41
|
+
reloginCode: (number | string)[];
|
|
42
|
+
/** 是否显示进度条 (默认true) */
|
|
43
|
+
showLoading?: boolean;
|
|
44
|
+
/** 是否提示接口异常 (默认true) */
|
|
45
|
+
toastError?: boolean;
|
|
46
|
+
/** 是否输出日志 (默认true) */
|
|
47
|
+
isLog?: boolean;
|
|
48
|
+
/** 额外输出的日志数据 */
|
|
49
|
+
extraLog?: Record<string, unknown>;
|
|
50
|
+
/** 响应数据的缓存时间, 单位毫秒。仅在成功时缓存;仅缓存在内存,应用退出,缓存消失。(默认0,不开启缓存) */
|
|
51
|
+
cacheTime?: number;
|
|
52
|
+
/** 是否开启流式传输 (如 SSE) */
|
|
53
|
+
enableChunked?: boolean;
|
|
54
|
+
/** 响应类型 (默认 json, enableChunked为true时忽略) */
|
|
55
|
+
responseType?: 'text' | 'arraybuffer' | 'json';
|
|
56
|
+
/** 响应拦截 */
|
|
57
|
+
responseInterceptor?: (data: ResponseData) => ResponseData;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* 请求任务对象 (用于取消请求或监听流式数据)
|
|
61
|
+
*/
|
|
62
|
+
export interface RequestTask {
|
|
63
|
+
/** 取消请求 */
|
|
64
|
+
abort: () => void;
|
|
65
|
+
/** 监听流式数据块接收事件 */
|
|
66
|
+
onChunkReceived: (callback: ChunkCallback) => void;
|
|
67
|
+
/** 取消监听流式数据块接收事件 */
|
|
68
|
+
offChunkReceived: () => void;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 流式数据块接收事件回调
|
|
72
|
+
*/
|
|
73
|
+
export type ChunkCallback = (response: {
|
|
74
|
+
data: ArrayBuffer;
|
|
75
|
+
}) => void;
|
|
76
|
+
/**
|
|
77
|
+
* 基础请求 (返回 Promise 和 Task 对象)
|
|
78
|
+
* 基于 fetch API 封装,支持流式请求
|
|
79
|
+
* @param config 请求配置
|
|
80
|
+
* @returns Promise<T> & { task?: RequestTask }
|
|
81
|
+
* @example
|
|
82
|
+
* // 在入口文件完成配置 (确保请求失败有toast提示,登录过期能够触发重新登录,log有日志输出)
|
|
83
|
+
* setBaseToolsConfig({
|
|
84
|
+
* toast: ({ msg, status }) => (status === 'fail' ? message.error(msg) : message.success(msg)),
|
|
85
|
+
* showLoading: () => message.loading('加载中...'),
|
|
86
|
+
* hideLoading: () => message.destroy(),
|
|
87
|
+
* toLogin: () => reLogin(),
|
|
88
|
+
* log(level, data) {
|
|
89
|
+
* if (data.name === 'request') {
|
|
90
|
+
* sendLog('request', data); // 请求日志
|
|
91
|
+
* } else if (level === 'error') {
|
|
92
|
+
* sendLog('error', data); // 错误日志
|
|
93
|
+
* } else {
|
|
94
|
+
* sendLog('action', data); // 操作日志
|
|
95
|
+
* }
|
|
96
|
+
* },
|
|
97
|
+
* });
|
|
98
|
+
*
|
|
99
|
+
* // 封装项目的基础请求
|
|
100
|
+
* export function requestApi<T>(config: RequestConfig) {
|
|
101
|
+
* return request<T>({
|
|
102
|
+
* header: { token: 'xx', version: 'xx', tid: 'xx' }, // 会自动过滤空值
|
|
103
|
+
* // responseInterceptor: (res) => res, // 响应拦截,可预处理响应数据,如解密 (可选)
|
|
104
|
+
* resKey: 'data',
|
|
105
|
+
* msgKey: 'message',
|
|
106
|
+
* codeKey: 'status',
|
|
107
|
+
* successCode: [1],
|
|
108
|
+
* reloginCode: [-10],
|
|
109
|
+
* ...config,
|
|
110
|
+
* });
|
|
111
|
+
* }
|
|
112
|
+
*
|
|
113
|
+
* // 1. 基于上面 requestApi 的普通接口
|
|
114
|
+
* export function apiGoodList(data: { page: number, size: number }) {
|
|
115
|
+
* return requestApi<GoodItem[]>({ url: '/goods/list', data, resKey: 'data.list' });
|
|
116
|
+
* }
|
|
117
|
+
*
|
|
118
|
+
* const goodList = await apiGoodList({ page:1, size:10 });
|
|
119
|
+
*
|
|
120
|
+
* // 2. 参数泛型的写法
|
|
121
|
+
* export function apiGoodList(config: RequestConfig<{ page: number, size: number }>) {
|
|
122
|
+
* return requestApi<GoodItem[]>({ url: '/goods/list', resKey: 'data.list', ...config });
|
|
123
|
+
* }
|
|
124
|
+
*
|
|
125
|
+
* const goodList = await apiGoodList({ data: { page:1, size:10 }, showLoading: false });
|
|
126
|
+
*
|
|
127
|
+
* // 3. 基于上面 requestApi 的流式接口
|
|
128
|
+
* export function apiChatStream(data: { question: string }) {
|
|
129
|
+
* return requestApi<T>({
|
|
130
|
+
* url: '/sse/chatStream',
|
|
131
|
+
* data,
|
|
132
|
+
* resKey: false,
|
|
133
|
+
* showLoading: false,
|
|
134
|
+
* responseType: 'arraybuffer',
|
|
135
|
+
* enableChunked: true,
|
|
136
|
+
* });
|
|
137
|
+
* }
|
|
138
|
+
*
|
|
139
|
+
* const { task } = apiChatStream({question: '你好'}); // 发起流式请求
|
|
140
|
+
*
|
|
141
|
+
* task.onChunkReceived((res) => {
|
|
142
|
+
* console.log('ArrayBuffer', res.data); // 接收流式数据
|
|
143
|
+
* });
|
|
144
|
+
*
|
|
145
|
+
* task.offChunkReceived(); // 取消监听,中断流式接收 (调用时机:流式结束,组件销毁,页面关闭)
|
|
146
|
+
* task.abort(); // 取消请求 (若流式传输中,会中断流并抛出异常)
|
|
147
|
+
*/
|
|
148
|
+
export declare function request<T, D extends RequestData = RequestData>(config: RequestConfigBase<D>): Promise<T> & {
|
|
149
|
+
task?: RequestTask;
|
|
150
|
+
};
|
|
151
|
+
//# sourceMappingURL=request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/web/network/request.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export type AppConfig = {
|
|
2
|
+
/** 全局 Toast 提示 */
|
|
3
|
+
toast?: (option: { msg: string; status: 'success' | 'fail' }) => void;
|
|
4
|
+
/** 显示全局 Loading */
|
|
5
|
+
showLoading?: () => void;
|
|
6
|
+
/** 隐藏全局 Loading */
|
|
7
|
+
hideLoading?: () => void;
|
|
8
|
+
/** 跳转登录页的方法 */
|
|
9
|
+
toLogin?: () => void;
|
|
10
|
+
/** 日志记录函数 */
|
|
11
|
+
log?: (level: 'info' | 'error' | 'warn' | 'debug', data: AppLogInfo) => void;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type AppLogInfo = {
|
|
15
|
+
/** 调用函数的名称 */
|
|
16
|
+
name: string;
|
|
17
|
+
|
|
18
|
+
/** 函数的调用状态 */
|
|
19
|
+
status?: 'success' | 'fail';
|
|
20
|
+
|
|
21
|
+
/** 函数的调用参数 */
|
|
22
|
+
option?: unknown;
|
|
23
|
+
|
|
24
|
+
/** 函数的调用结果 */
|
|
25
|
+
res?: unknown;
|
|
26
|
+
|
|
27
|
+
/** 函数的调用错误 */
|
|
28
|
+
e?: unknown;
|
|
29
|
+
|
|
30
|
+
/** 日志描述 */
|
|
31
|
+
desc?: string;
|
|
32
|
+
|
|
33
|
+
// 其他自定义属性
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const appConfig: AppConfig = {};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 获取应用配置
|
|
41
|
+
*/
|
|
42
|
+
export function getBaseToolsConfig() {
|
|
43
|
+
return appConfig;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 初始化应用配置 (在入口文件设置)
|
|
48
|
+
* @example
|
|
49
|
+
* setBaseToolsConfig({
|
|
50
|
+
* toast: ({ msg, status }) => (status === 'fail' ? message.error(msg) : message.success(msg)),
|
|
51
|
+
* showLoading: () => message.loading('加载中...'),
|
|
52
|
+
* hideLoading: () => message.destroy(),
|
|
53
|
+
* toLogin: () => reLogin(),
|
|
54
|
+
* log(level, data) {
|
|
55
|
+
* if (data.name === 'request') {
|
|
56
|
+
* sendLog('request', data); // 请求日志
|
|
57
|
+
* } else if (level === 'error') {
|
|
58
|
+
* sendLog('error', data); // 错误日志
|
|
59
|
+
* } else {
|
|
60
|
+
* sendLog('action', data); // 操作日志
|
|
61
|
+
* }
|
|
62
|
+
* },
|
|
63
|
+
* });
|
|
64
|
+
*/
|
|
65
|
+
export function setBaseToolsConfig(newConfig: AppConfig) {
|
|
66
|
+
Object.assign(appConfig, newConfig);
|
|
67
|
+
}
|
package/src/web/index.ts
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
* 内部统一导出, 外部快捷引入: import {xx} from 'base-tools/web'
|
|
3
3
|
*/
|
|
4
4
|
export * from './clipboard';
|
|
5
|
+
export * from './config';
|
|
5
6
|
export * from './cookie';
|
|
6
7
|
export * from './device';
|
|
7
8
|
export * from './dom';
|
|
8
|
-
export * from './
|
|
9
|
+
export * from './network';
|
|
9
10
|
export * from './storage';
|
|
10
11
|
export * from './url';
|