@hlw-uni/mp-vue 2.1.56 → 2.1.58
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/dist/app.d.ts +12 -1
- package/dist/composables/ad/index.d.ts +26 -0
- package/dist/composables/device/index.d.ts +14 -0
- package/dist/composables/index.d.ts +1 -1
- package/dist/composables/msg/index.d.ts +44 -3
- package/dist/composables/navigator/index.d.ts +37 -1
- package/dist/composables/refs/index.d.ts +15 -1
- package/dist/composables/request/client.d.ts +87 -0
- package/dist/composables/request/service.d.ts +64 -0
- package/dist/composables/request/types.d.ts +50 -13
- package/dist/composables/share/index.d.ts +38 -0
- package/dist/composables/theme/appearance.d.ts +30 -4
- package/dist/composables/theme/font.d.ts +23 -0
- package/dist/composables/theme/index.d.ts +19 -6
- package/dist/composables/theme/palette.d.ts +23 -0
- package/dist/composables/theme/typography.d.ts +9 -1
- package/dist/composables/utils/index.d.ts +120 -13
- package/dist/directives/copy.d.ts +5 -0
- package/dist/hlw.d.ts +10 -0
- package/dist/index.js +305 -199
- package/dist/index.mjs +306 -200
- package/dist/stores/theme.d.ts +3 -0
- package/package.json +1 -1
- package/src/app.ts +20 -3
- package/src/components/hlw-ad/index.vue +58 -12
- package/src/components/hlw-add-mini/README.md +10 -11
- package/src/components/hlw-add-mini/index.vue +93 -66
- package/src/components/hlw-button/index.vue +33 -18
- package/src/composables/ad/index.ts +136 -62
- package/src/composables/device/index.ts +32 -2
- package/src/composables/index.ts +18 -1
- package/src/composables/msg/index.ts +70 -16
- package/src/composables/navigator/index.ts +45 -1
- package/src/composables/refs/index.ts +27 -4
- package/src/composables/request/client.ts +149 -0
- package/src/composables/request/service.ts +64 -0
- package/src/composables/request/types.ts +53 -13
- package/src/composables/share/index.ts +48 -0
- package/src/composables/theme/appearance.ts +31 -4
- package/src/composables/theme/font.ts +23 -0
- package/src/composables/theme/index.ts +23 -7
- package/src/composables/theme/palette.ts +32 -0
- package/src/composables/theme/typography.ts +9 -1
- package/src/composables/utils/index.ts +227 -127
- package/src/directives/copy.ts +31 -19
- package/src/hlw.ts +11 -0
- package/src/stores/theme.ts +28 -5
|
@@ -1,26 +1,48 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* useRefs - 模板 Ref 批量管理
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* 主要用于在 v-for 循环场景下,动态收集一组子元素或子组件的引用实例。
|
|
5
|
+
* 规避了 Vue3 在 v-for 中绑定 ref 时需要手动处理数组收集和清理的冗余逻辑。
|
|
5
6
|
*/
|
|
6
7
|
import { ref, onBeforeUpdate, onUnmounted } from "vue";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
|
-
* 管理动态 ref
|
|
10
|
+
* 管理动态 ref 集合的 hook,尤其适合 v-for 列表场景。
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```vue
|
|
14
|
+
* <template>
|
|
15
|
+
* <view v-for="item in list" :key="item.id" :ref="setRefs(item.id)">
|
|
16
|
+
* {{ item.name }}
|
|
17
|
+
* </view>
|
|
18
|
+
* </template>
|
|
19
|
+
*
|
|
20
|
+
* <script setup>
|
|
21
|
+
* const { refs, setRefs } = useRefs();
|
|
22
|
+
* // 访问特定子项的 DOM/实例: refs.value[itemId]
|
|
23
|
+
* </script>
|
|
24
|
+
* ```
|
|
10
25
|
*/
|
|
11
26
|
export function useRefs() {
|
|
27
|
+
/** 存放动态收集到的所有组件或 DOM 实例的 Key-Value 映射对象 */
|
|
12
28
|
const refs = ref<Record<string, any>>({});
|
|
13
29
|
|
|
30
|
+
// 每次组件更新前清空缓存,以便重新收集最新存在的元素引用
|
|
14
31
|
onBeforeUpdate(() => {
|
|
15
32
|
refs.value = {};
|
|
16
33
|
});
|
|
17
34
|
|
|
35
|
+
// 组件卸载时清空所有引用,防止内存泄漏
|
|
18
36
|
onUnmounted(() => {
|
|
19
37
|
refs.value = {};
|
|
20
38
|
});
|
|
21
39
|
|
|
22
40
|
/**
|
|
23
|
-
* 按 key
|
|
41
|
+
* 按 key 生成一个 ref 绑定回调函数。
|
|
42
|
+
* Vue 模板的 `:ref` 绑定此返回值后,会自动在挂载时填入实例,卸载时清除。
|
|
43
|
+
*
|
|
44
|
+
* @param key 标识该子项的唯一 Key
|
|
45
|
+
* @returns 用于 ref 绑定的回调函数
|
|
24
46
|
*/
|
|
25
47
|
const setRefs = (key: string) => (el: any) => {
|
|
26
48
|
if (el) refs.value[key] = el;
|
|
@@ -28,3 +50,4 @@ export function useRefs() {
|
|
|
28
50
|
|
|
29
51
|
return { refs, setRefs };
|
|
30
52
|
}
|
|
53
|
+
|
|
@@ -10,20 +10,98 @@ import type {
|
|
|
10
10
|
} from "./types";
|
|
11
11
|
import { getAdapter } from "./adapters";
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* HTTP 请求客户端接口定义。
|
|
15
|
+
* 提供基础的 HTTP 请求方法、文件直传服务配置以及拦截器管理。
|
|
16
|
+
*/
|
|
13
17
|
export interface RequestClient {
|
|
18
|
+
/**
|
|
19
|
+
* 发送网络请求。
|
|
20
|
+
* @param config 请求配置项
|
|
21
|
+
* @returns 封装后的响应结果 Promise
|
|
22
|
+
*/
|
|
14
23
|
request<T = unknown>(config: RequestConfig): Promise<ApiResponse<T>>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 发送 GET 请求的快捷方法。
|
|
27
|
+
* @param url 请求的目标 URL
|
|
28
|
+
* @param data 请求携带的 query 参数
|
|
29
|
+
* @returns 封装后的响应结果 Promise
|
|
30
|
+
*/
|
|
15
31
|
get<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 发送 POST 请求的快捷方法。
|
|
35
|
+
* @param url 请求的目标 URL
|
|
36
|
+
* @param data 请求携带的 body 数据
|
|
37
|
+
* @returns 封装后的响应结果 Promise
|
|
38
|
+
*/
|
|
16
39
|
post<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 发送 PUT 请求的快捷方法。
|
|
43
|
+
* @param url 请求的目标 URL
|
|
44
|
+
* @param data 请求携带的 body 数据
|
|
45
|
+
* @returns 封装后的响应结果 Promise
|
|
46
|
+
*/
|
|
17
47
|
put<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 发送 DELETE 请求的快捷方法。
|
|
51
|
+
* @param url 请求的目标 URL
|
|
52
|
+
* @param data 请求携带的 query 或 body 数据
|
|
53
|
+
* @returns 封装后的响应结果 Promise
|
|
54
|
+
*/
|
|
18
55
|
del<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 上传本地文件到服务器或第三方云存储。
|
|
59
|
+
* @param config 文件上传配置项
|
|
60
|
+
* @returns 上传解析结果 Promise
|
|
61
|
+
*/
|
|
19
62
|
upload(config: UploadConfig): Promise<UploadResult>;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 设置基础请求域名或前缀。
|
|
66
|
+
* @param url 域名字符串(如 'https://api.example.com')
|
|
67
|
+
*/
|
|
20
68
|
setBaseURL(url: string): void;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 拼接并解析微服务模块或命名空间下的请求 URL。
|
|
72
|
+
* @param namespace 命名空间/模块名称
|
|
73
|
+
* @param url 具体的接口路径
|
|
74
|
+
* @param servicePrefix 服务的前缀,可选
|
|
75
|
+
* @returns 拼接完成的完整路径
|
|
76
|
+
*/
|
|
21
77
|
resolveServiceUrl(namespace: string, url: string, servicePrefix?: string): string;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 注册请求拦截器,在请求发出前触发。
|
|
81
|
+
* @param fn 拦截器处理函数
|
|
82
|
+
* @returns 用于注销该拦截器的注销函数
|
|
83
|
+
*/
|
|
22
84
|
onRequest(fn: RequestInterceptor): () => void;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* 注册响应拦截器,在成功接收响应后触发。
|
|
88
|
+
* @param fn 拦截器处理函数
|
|
89
|
+
* @returns 用于注销该拦截器的注销函数
|
|
90
|
+
*/
|
|
23
91
|
onResponse<T = unknown>(fn: ResponseInterceptor<T>): () => void;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* 注册错误拦截器,在请求或响应阶段发生异常时触发。
|
|
95
|
+
* @param fn 错误拦截处理器
|
|
96
|
+
* @returns 用于注销该拦截器的注销函数
|
|
97
|
+
*/
|
|
24
98
|
onError(fn: ErrorInterceptor): () => void;
|
|
25
99
|
}
|
|
26
100
|
|
|
101
|
+
/**
|
|
102
|
+
* UniApp 请求客户端的实现类。
|
|
103
|
+
* 基于 uni.request 与 uni.uploadFile 封装,内置拦截器调用链路。
|
|
104
|
+
*/
|
|
27
105
|
class UniRequestClient implements RequestClient {
|
|
28
106
|
private reqInterceptors: RequestInterceptor[] = [];
|
|
29
107
|
private resInterceptors: ResponseInterceptor[] = [];
|
|
@@ -31,26 +109,41 @@ class UniRequestClient implements RequestClient {
|
|
|
31
109
|
private baseURL = "";
|
|
32
110
|
private defaultHeaders: Record<string, string> = { "Content-Type": "application/json" };
|
|
33
111
|
|
|
112
|
+
/**
|
|
113
|
+
* 设置全局基础请求 URL。
|
|
114
|
+
*/
|
|
34
115
|
setBaseURL(url: string): void {
|
|
35
116
|
this.baseURL = url;
|
|
36
117
|
}
|
|
37
118
|
|
|
119
|
+
/**
|
|
120
|
+
* 注册一个请求拦截器。
|
|
121
|
+
*/
|
|
38
122
|
onRequest(fn: RequestInterceptor): () => void {
|
|
39
123
|
this.reqInterceptors.push(fn);
|
|
40
124
|
return () => this.remove(this.reqInterceptors, fn);
|
|
41
125
|
}
|
|
42
126
|
|
|
127
|
+
/**
|
|
128
|
+
* 注册一个响应拦截器。
|
|
129
|
+
*/
|
|
43
130
|
onResponse<T = unknown>(fn: ResponseInterceptor<T>): () => void {
|
|
44
131
|
const item = fn as ResponseInterceptor;
|
|
45
132
|
this.resInterceptors.push(item);
|
|
46
133
|
return () => this.remove(this.resInterceptors, item);
|
|
47
134
|
}
|
|
48
135
|
|
|
136
|
+
/**
|
|
137
|
+
* 注册一个错误拦截器。
|
|
138
|
+
*/
|
|
49
139
|
onError(fn: ErrorInterceptor): () => void {
|
|
50
140
|
this.errInterceptors.push(fn);
|
|
51
141
|
return () => this.remove(this.errInterceptors, fn);
|
|
52
142
|
}
|
|
53
143
|
|
|
144
|
+
/**
|
|
145
|
+
* 执行 HTTP 请求。
|
|
146
|
+
*/
|
|
54
147
|
async request<T = unknown>(config: RequestConfig): Promise<ApiResponse<T>> {
|
|
55
148
|
let cfg: RequestConfig = {
|
|
56
149
|
method: "GET",
|
|
@@ -58,12 +151,14 @@ class UniRequestClient implements RequestClient {
|
|
|
58
151
|
headers: { ...this.defaultHeaders, ...config.headers },
|
|
59
152
|
};
|
|
60
153
|
|
|
154
|
+
// 顺序执行请求拦截器
|
|
61
155
|
for (const fn of this.reqInterceptors) {
|
|
62
156
|
cfg = await fn(cfg);
|
|
63
157
|
}
|
|
64
158
|
|
|
65
159
|
try {
|
|
66
160
|
const res = await this.send<T>(this.resolveUrl(cfg.url), cfg);
|
|
161
|
+
// 顺序执行响应拦截器
|
|
67
162
|
for (const fn of this.resInterceptors) {
|
|
68
163
|
const next = await fn(res as ApiResponse<unknown>);
|
|
69
164
|
if (next !== undefined) return next as ApiResponse<T>;
|
|
@@ -71,6 +166,7 @@ class UniRequestClient implements RequestClient {
|
|
|
71
166
|
return res;
|
|
72
167
|
} catch (e) {
|
|
73
168
|
const err = e as Error;
|
|
169
|
+
// 执行错误拦截器
|
|
74
170
|
for (const fn of this.errInterceptors) {
|
|
75
171
|
await fn(err);
|
|
76
172
|
}
|
|
@@ -78,22 +174,37 @@ class UniRequestClient implements RequestClient {
|
|
|
78
174
|
}
|
|
79
175
|
}
|
|
80
176
|
|
|
177
|
+
/**
|
|
178
|
+
* 发送 GET 请求。
|
|
179
|
+
*/
|
|
81
180
|
get<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
|
|
82
181
|
return this.request<T>({ url, method: "GET", data });
|
|
83
182
|
}
|
|
84
183
|
|
|
184
|
+
/**
|
|
185
|
+
* 发送 POST 请求。
|
|
186
|
+
*/
|
|
85
187
|
post<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
|
|
86
188
|
return this.request<T>({ url, method: "POST", data });
|
|
87
189
|
}
|
|
88
190
|
|
|
191
|
+
/**
|
|
192
|
+
* 发送 PUT 请求。
|
|
193
|
+
*/
|
|
89
194
|
put<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
|
|
90
195
|
return this.request<T>({ url, method: "PUT", data });
|
|
91
196
|
}
|
|
92
197
|
|
|
198
|
+
/**
|
|
199
|
+
* 发送 DELETE 请求。
|
|
200
|
+
*/
|
|
93
201
|
del<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
|
|
94
202
|
return this.request<T>({ url, method: "DELETE", data });
|
|
95
203
|
}
|
|
96
204
|
|
|
205
|
+
/**
|
|
206
|
+
* 上传本地文件,适配云存储(COS/OSS/七牛/Alist)或本地直传。
|
|
207
|
+
*/
|
|
97
208
|
upload(config: UploadConfig): Promise<UploadResult> {
|
|
98
209
|
const fileName = config.fileName ?? config.filePath.split("/").pop() ?? "file";
|
|
99
210
|
const server = config.type === "local" && config.url ? config.url : config.server;
|
|
@@ -134,6 +245,9 @@ class UniRequestClient implements RequestClient {
|
|
|
134
245
|
});
|
|
135
246
|
}
|
|
136
247
|
|
|
248
|
+
/**
|
|
249
|
+
* 解析微服务风格的命名空间 URL。
|
|
250
|
+
*/
|
|
137
251
|
resolveServiceUrl(namespace: string, url: string, servicePrefix = ""): string {
|
|
138
252
|
if (isAbsolute(url)) return url;
|
|
139
253
|
|
|
@@ -145,11 +259,17 @@ class UniRequestClient implements RequestClient {
|
|
|
145
259
|
return prefix ? `/${prefix}${path}` : path;
|
|
146
260
|
}
|
|
147
261
|
|
|
262
|
+
/**
|
|
263
|
+
* 内部拼接基础 URL 与相对路径。
|
|
264
|
+
*/
|
|
148
265
|
private resolveUrl(url: string): string {
|
|
149
266
|
if (isAbsolute(url)) return url;
|
|
150
267
|
return `${this.baseURL}${url}`;
|
|
151
268
|
}
|
|
152
269
|
|
|
270
|
+
/**
|
|
271
|
+
* 内部基于 uni.request 发送网络请求的方法。
|
|
272
|
+
*/
|
|
153
273
|
private send<T>(url: string, cfg: RequestConfig): Promise<ApiResponse<T>> {
|
|
154
274
|
return new Promise((resolve, reject) => {
|
|
155
275
|
uni.request({
|
|
@@ -172,22 +292,51 @@ class UniRequestClient implements RequestClient {
|
|
|
172
292
|
});
|
|
173
293
|
}
|
|
174
294
|
|
|
295
|
+
/**
|
|
296
|
+
* 从数组中安全移除某个拦截器实例。
|
|
297
|
+
*/
|
|
175
298
|
private remove<T>(items: T[], item: T): void {
|
|
176
299
|
const index = items.indexOf(item);
|
|
177
300
|
if (index > -1) items.splice(index, 1);
|
|
178
301
|
}
|
|
179
302
|
}
|
|
180
303
|
|
|
304
|
+
/**
|
|
305
|
+
* 判断 URL 是否为绝对路径(支持 http://, https://, file://)。
|
|
306
|
+
*/
|
|
181
307
|
function isAbsolute(url: string): boolean {
|
|
182
308
|
return /^(https?:)?\/\//.test(url) || url.startsWith("file://");
|
|
183
309
|
}
|
|
184
310
|
|
|
185
311
|
const requestClient = new UniRequestClient();
|
|
186
312
|
|
|
313
|
+
/**
|
|
314
|
+
* 获取全局请求客户端单例。
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* ```ts
|
|
318
|
+
* const http = useRequest();
|
|
319
|
+
* http.setBaseURL('https://api.example.com');
|
|
320
|
+
* ```
|
|
321
|
+
*/
|
|
187
322
|
export function useRequest(): RequestClient {
|
|
188
323
|
return requestClient;
|
|
189
324
|
}
|
|
190
325
|
|
|
326
|
+
/**
|
|
327
|
+
* 文件上传 composable。
|
|
328
|
+
* 提供 `uploading` 状态与上传方法。
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* ```ts
|
|
332
|
+
* const { uploading, upload } = useUpload();
|
|
333
|
+
* const res = await upload({
|
|
334
|
+
* type: 'oss',
|
|
335
|
+
* filePath: 'temp-path',
|
|
336
|
+
* server: 'https://oss-endpoint.com'
|
|
337
|
+
* });
|
|
338
|
+
* ```
|
|
339
|
+
*/
|
|
191
340
|
export function useUpload() {
|
|
192
341
|
const uploading = ref(false);
|
|
193
342
|
|
|
@@ -1,22 +1,56 @@
|
|
|
1
1
|
import { useRequest } from "./client";
|
|
2
2
|
import type { ApiResponse, RequestConfig } from "./types";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* 带有具体必填 URL 的服务请求配置。
|
|
6
|
+
*/
|
|
4
7
|
export type ServiceRequestConfig = Omit<RequestConfig, "url"> & {
|
|
5
8
|
url: string;
|
|
6
9
|
};
|
|
7
10
|
|
|
11
|
+
/**
|
|
12
|
+
* 命名空间装饰器配置项。
|
|
13
|
+
*/
|
|
8
14
|
export interface ServiceNamespaceOptions {
|
|
15
|
+
/** 微服务或模块命名空间 */
|
|
9
16
|
namespace: string;
|
|
10
17
|
}
|
|
11
18
|
|
|
19
|
+
/**
|
|
20
|
+
* 服务前缀装饰器配置项。
|
|
21
|
+
*/
|
|
12
22
|
export interface ServicePrefixOptions {
|
|
23
|
+
/** 基础路径前缀 */
|
|
13
24
|
prefix: string;
|
|
14
25
|
}
|
|
15
26
|
|
|
27
|
+
/**
|
|
28
|
+
* 基础服务抽象类。
|
|
29
|
+
* 业务 Service 类继承此类后,可通过 decorators 注入前缀与命名空间,
|
|
30
|
+
* 并通过便捷方法发起网络请求。
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* @ServicePrefix('/api')
|
|
35
|
+
* @ServiceNamespace('user')
|
|
36
|
+
* class UserService extends BaseService {
|
|
37
|
+
* getUserInfo(id: string) {
|
|
38
|
+
* return this.get(`/info?id=${id}`);
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
16
43
|
export class BaseService {
|
|
44
|
+
/** 当前服务的命名空间(一般由 @ServiceNamespace 注入) */
|
|
17
45
|
declare namespace: string;
|
|
46
|
+
/** 当前服务的基础路径前缀(一般由 @ServicePrefix 注入) */
|
|
18
47
|
declare servicePrefix: string;
|
|
19
48
|
|
|
49
|
+
/**
|
|
50
|
+
* 发送服务请求。会自动拼接前缀与命名空间。
|
|
51
|
+
* @param options 请求配置项
|
|
52
|
+
* @returns 响应结果 Promise
|
|
53
|
+
*/
|
|
20
54
|
request<T = unknown>(options: ServiceRequestConfig): Promise<ApiResponse<T>> {
|
|
21
55
|
return useRequest().request<T>({
|
|
22
56
|
...options,
|
|
@@ -24,29 +58,59 @@ export class BaseService {
|
|
|
24
58
|
});
|
|
25
59
|
}
|
|
26
60
|
|
|
61
|
+
/**
|
|
62
|
+
* 快捷发送 GET 请求。
|
|
63
|
+
* @param url 请求相对路径
|
|
64
|
+
* @param data 请求参数
|
|
65
|
+
*/
|
|
27
66
|
get<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
|
|
28
67
|
return this.request<T>({ url, method: "GET", data });
|
|
29
68
|
}
|
|
30
69
|
|
|
70
|
+
/**
|
|
71
|
+
* 快捷发送 POST 请求。
|
|
72
|
+
* @param url 请求相对路径
|
|
73
|
+
* @param data 请求携带的 body
|
|
74
|
+
*/
|
|
31
75
|
post<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
|
|
32
76
|
return this.request<T>({ url, method: "POST", data });
|
|
33
77
|
}
|
|
34
78
|
|
|
79
|
+
/**
|
|
80
|
+
* 快捷发送 PUT 请求。
|
|
81
|
+
* @param url 请求相对路径
|
|
82
|
+
* @param data 请求携带的 body
|
|
83
|
+
*/
|
|
35
84
|
put<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
|
|
36
85
|
return this.request<T>({ url, method: "PUT", data });
|
|
37
86
|
}
|
|
38
87
|
|
|
88
|
+
/**
|
|
89
|
+
* 快捷发送 DELETE 请求。
|
|
90
|
+
* @param url 请求相对路径
|
|
91
|
+
* @param data 请求参数
|
|
92
|
+
*/
|
|
39
93
|
del<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
|
|
40
94
|
return this.request<T>({ url, method: "DELETE", data });
|
|
41
95
|
}
|
|
42
96
|
}
|
|
43
97
|
|
|
98
|
+
/**
|
|
99
|
+
* 服务命名空间类装饰器。
|
|
100
|
+
* 注入 `namespace` 到服务类中。
|
|
101
|
+
* @param value 命名空间名称或配置对象
|
|
102
|
+
*/
|
|
44
103
|
export function ServiceNamespace(value: string | ServiceNamespaceOptions) {
|
|
45
104
|
return function (target: { prototype: { namespace?: string } }) {
|
|
46
105
|
target.prototype.namespace = typeof value === "string" ? value : value.namespace;
|
|
47
106
|
};
|
|
48
107
|
}
|
|
49
108
|
|
|
109
|
+
/**
|
|
110
|
+
* 服务前缀类装饰器。
|
|
111
|
+
* 注入 `servicePrefix` 到服务类中。
|
|
112
|
+
* @param value 前缀值或配置对象
|
|
113
|
+
*/
|
|
50
114
|
export function ServicePrefix(value: string | ServicePrefixOptions) {
|
|
51
115
|
return function (target: { prototype: { servicePrefix?: string } }) {
|
|
52
116
|
target.prototype.servicePrefix = typeof value === "string" ? value : value.prefix;
|
|
@@ -1,53 +1,93 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* API 统一响应格式
|
|
3
|
+
* 定义服务端接口的标准数据返回格式。
|
|
4
|
+
*/
|
|
2
5
|
export interface ApiResponse<T = unknown> {
|
|
6
|
+
/** 业务状态码 (例如: 1 代表成功,非 1 代表不同类型的失败) */
|
|
3
7
|
code: number;
|
|
8
|
+
/** 响应的主体数据 */
|
|
4
9
|
data: T;
|
|
10
|
+
/** 响应的文本提示信息(如:操作成功、系统繁忙) */
|
|
5
11
|
info: string;
|
|
6
12
|
}
|
|
7
13
|
|
|
8
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* 分页请求的标准数据包装格式。
|
|
16
|
+
*/
|
|
9
17
|
export interface PageResult<T = unknown> {
|
|
18
|
+
/** 分页列表数据 */
|
|
10
19
|
list: T[];
|
|
20
|
+
/** 总记录数 */
|
|
11
21
|
total: number;
|
|
22
|
+
/** 当前页码 */
|
|
12
23
|
page: number;
|
|
24
|
+
/** 每页记录条数 */
|
|
13
25
|
pageSize: number;
|
|
14
26
|
}
|
|
15
27
|
|
|
16
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* HTTP 请求参数配置项。
|
|
30
|
+
*/
|
|
17
31
|
export interface RequestConfig {
|
|
32
|
+
/** 请求的目标 URL,支持绝对路径或相对 BaseURL 的相对路径 */
|
|
18
33
|
url: string;
|
|
34
|
+
/** 请求的 HTTP 方法,默认 "GET" */
|
|
19
35
|
method?: "GET" | "POST" | "PUT" | "DELETE";
|
|
36
|
+
/** 请求携带的数据载体,GET/DELETE 对应 Query 传参,POST/PUT 对应 Body 传参 */
|
|
20
37
|
data?: unknown;
|
|
38
|
+
/** 自定义请求头 */
|
|
21
39
|
headers?: Record<string, string>;
|
|
40
|
+
/** 请求超时时间,单位毫秒 */
|
|
22
41
|
timeout?: number;
|
|
23
42
|
}
|
|
24
43
|
|
|
25
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* 请求拦截器函数定义。
|
|
46
|
+
* 允许在请求被发出前修改请求配置,支持异步处理。
|
|
47
|
+
*/
|
|
26
48
|
export type RequestInterceptor = (config: RequestConfig) => RequestConfig | Promise<RequestConfig>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 响应拦截器函数定义。
|
|
52
|
+
* 允许在响应被接收并传递给业务逻辑前对响应数据做预处理,支持异步处理。
|
|
53
|
+
*/
|
|
27
54
|
export type ResponseInterceptor<T = unknown> = (res: ApiResponse<T>) => ApiResponse<T> | void | Promise<ApiResponse<T> | void>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 错误拦截器函数定义。
|
|
58
|
+
* 用于统一捕获和处理网络层或业务层抛出的异常。
|
|
59
|
+
*/
|
|
28
60
|
export type ErrorInterceptor = (err: Error) => void | Error | Promise<void | Error>;
|
|
29
61
|
|
|
30
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* 云存储或文件直传服务配置项。
|
|
64
|
+
*/
|
|
31
65
|
export interface UploadConfig {
|
|
32
|
-
/**
|
|
66
|
+
/** 上传的服务器网关 URL */
|
|
33
67
|
server: string;
|
|
34
|
-
/**
|
|
68
|
+
/** 本地待上传的文件路径 (tempFilePath) */
|
|
35
69
|
filePath: string;
|
|
36
|
-
/**
|
|
70
|
+
/** 直传服务器接收的文件参数名称,默认自动从 filePath 中截取 */
|
|
37
71
|
fileName?: string;
|
|
38
|
-
/**
|
|
72
|
+
/** 云直传供应商类型,支持 'cos' | 'oss' | 'qiniu' | 'alist' | 'local' */
|
|
39
73
|
type: string;
|
|
40
|
-
/**
|
|
74
|
+
/** 直传签名凭证所需的一组敏感密钥对(AK、Signature、Token 等) */
|
|
41
75
|
credentials?: Record<string, string>;
|
|
42
|
-
/**
|
|
76
|
+
/** 直传时的自定义 HTTP 请求头 */
|
|
43
77
|
header?: Record<string, string>;
|
|
44
|
-
/**
|
|
78
|
+
/** 当 type="local" 时,可以通过此属性覆盖 server 参数作为最终上传端点 */
|
|
45
79
|
url?: string;
|
|
46
80
|
}
|
|
47
81
|
|
|
48
|
-
/**
|
|
82
|
+
/**
|
|
83
|
+
* 文件上传完成后标准接口解析出的结果。
|
|
84
|
+
*/
|
|
49
85
|
export interface UploadResult {
|
|
86
|
+
/** 业务状态码 */
|
|
50
87
|
code: number;
|
|
88
|
+
/** 上传提示信息 */
|
|
51
89
|
msg: string;
|
|
90
|
+
/** 上传成功后云端资源的可访问 URL 或文件路径 */
|
|
52
91
|
data: string;
|
|
53
92
|
}
|
|
93
|
+
|
|
@@ -3,24 +3,53 @@ import {
|
|
|
3
3
|
onShareTimeline as registerShareTimeline,
|
|
4
4
|
} from "@dcloudio/uni-app";
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* 分享卡片配置项。
|
|
8
|
+
*/
|
|
6
9
|
export interface ShareConfig {
|
|
10
|
+
/** 分享的标题,默认使用小程序名称 */
|
|
7
11
|
title?: string;
|
|
12
|
+
/** 分享的页面路径,支持携带 query 参数,如 '/pages/index/index?id=123' */
|
|
8
13
|
path?: string;
|
|
14
|
+
/** 分享卡片的展示图 URL 或本地路径 */
|
|
9
15
|
imageUrl?: string;
|
|
10
16
|
}
|
|
11
17
|
|
|
18
|
+
/**
|
|
19
|
+
* 支持静态配置或动态解析器函数。
|
|
20
|
+
*/
|
|
12
21
|
export type ShareConfigResolver = ShareConfig | (() => ShareConfig);
|
|
13
22
|
|
|
23
|
+
/**
|
|
24
|
+
* 分享操作句柄接口。
|
|
25
|
+
*/
|
|
14
26
|
export interface ShareHandlers {
|
|
27
|
+
/**
|
|
28
|
+
* 手动触发分享好友设置。
|
|
29
|
+
* @param config 可选的额外覆盖分享配置
|
|
30
|
+
*/
|
|
15
31
|
onShareAppMessage: (config?: ShareConfigResolver) => void;
|
|
32
|
+
/**
|
|
33
|
+
* 手动触发分享朋友圈设置。
|
|
34
|
+
* @param config 可选的额外覆盖分享配置
|
|
35
|
+
*/
|
|
16
36
|
onShareTimeline: (config?: ShareConfigResolver) => void;
|
|
37
|
+
/**
|
|
38
|
+
* 显示分享菜单项,启用小程序右上角分享。
|
|
39
|
+
*/
|
|
17
40
|
showShareMenu: () => void;
|
|
18
41
|
}
|
|
19
42
|
|
|
43
|
+
/**
|
|
44
|
+
* 解析分享配置。
|
|
45
|
+
*/
|
|
20
46
|
function resolveConfig(config?: ShareConfigResolver): ShareConfig {
|
|
21
47
|
return typeof config === "function" ? config() : (config ?? {});
|
|
22
48
|
}
|
|
23
49
|
|
|
50
|
+
/**
|
|
51
|
+
* 合并并构建标准的分享数据载体。
|
|
52
|
+
*/
|
|
24
53
|
function buildPayload(base: ShareConfigResolver, extra?: ShareConfigResolver): ShareConfig {
|
|
25
54
|
const current = {
|
|
26
55
|
...resolveConfig(base),
|
|
@@ -33,6 +62,9 @@ function buildPayload(base: ShareConfigResolver, extra?: ShareConfigResolver): S
|
|
|
33
62
|
return payload;
|
|
34
63
|
}
|
|
35
64
|
|
|
65
|
+
/**
|
|
66
|
+
* 显示微信原生分享菜单。
|
|
67
|
+
*/
|
|
36
68
|
function showShareMenu(): void {
|
|
37
69
|
const api = typeof uni !== "undefined" ? (uni as unknown as {
|
|
38
70
|
showShareMenu?: (options: {
|
|
@@ -49,6 +81,21 @@ function showShareMenu(): void {
|
|
|
49
81
|
});
|
|
50
82
|
}
|
|
51
83
|
|
|
84
|
+
/**
|
|
85
|
+
* 小程序页面分享 Hook。
|
|
86
|
+
* 自动调用并监听当前页面的 `onShareAppMessage` 与 `onShareTimeline` 原生事件。
|
|
87
|
+
*
|
|
88
|
+
* @param config 默认的分享配置或配置函数
|
|
89
|
+
* @returns 包含手动触发或配置的方法句柄
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* useShare({
|
|
94
|
+
* title: '欢迎体验我的小程序',
|
|
95
|
+
* path: '/pages/index/index'
|
|
96
|
+
* });
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
52
99
|
export function useShare(config: ShareConfigResolver = {}): ShareHandlers {
|
|
53
100
|
let appMessageRegistered = false;
|
|
54
101
|
let timelineRegistered = false;
|
|
@@ -74,6 +121,7 @@ export function useShare(config: ShareConfigResolver = {}): ShareHandlers {
|
|
|
74
121
|
});
|
|
75
122
|
};
|
|
76
123
|
|
|
124
|
+
// 默认在 setup 阶段触发注册
|
|
77
125
|
onShareAppMessage();
|
|
78
126
|
onShareTimeline();
|
|
79
127
|
|