@hlw-uni/mp-vue 2.1.71 → 2.1.98

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 (86) hide show
  1. package/README.md +230 -386
  2. package/dist/app.d.ts +1 -1
  3. package/dist/core/index.d.ts +3 -0
  4. package/dist/core/{theme.d.ts → theme/index.d.ts} +6 -1
  5. package/dist/hlw.d.ts +1 -10
  6. package/dist/index.d.ts +2 -2
  7. package/dist/index.js +834 -804
  8. package/dist/index.mjs +836 -806
  9. package/dist/utils/ad/index.d.ts +61 -0
  10. package/dist/{composables/utils → utils/common}/index.d.ts +1 -24
  11. package/dist/{composables → utils}/device/index.d.ts +7 -8
  12. package/dist/utils/index.d.ts +5 -0
  13. package/dist/{composables → utils}/navigator/index.d.ts +14 -30
  14. package/dist/{composables → utils}/request/client.d.ts +2 -8
  15. package/dist/{composables → utils}/request/index.d.ts +1 -1
  16. package/dist/{composables → utils}/request/service.d.ts +2 -2
  17. package/package.json +1 -1
  18. package/src/app.ts +2 -2
  19. package/src/components/hlw-add-mini/README.md +56 -9
  20. package/src/components/hlw-add-mini/index.vue +12 -9
  21. package/src/components/hlw-avatar-upload/index.vue +103 -0
  22. package/src/components/hlw-back-top/index.vue +1 -1
  23. package/src/components/hlw-button/index.vue +5 -16
  24. package/src/components/hlw-canvas/index.vue +7 -7
  25. package/src/components/hlw-cell/index.vue +1 -1
  26. package/src/components/{hlw-custom/hlw-custom.vue → hlw-custom-service/hlw-custom-service.vue} +27 -15
  27. package/src/components/hlw-empty/index.vue +14 -0
  28. package/src/components/hlw-header/index.vue +1 -1
  29. package/src/components/hlw-menu/index.vue +40 -37
  30. package/src/components/hlw-nav-bar/index.vue +23 -8
  31. package/src/components/hlw-nickname/index.vue +185 -0
  32. package/src/components/hlw-notice-bar/index.vue +23 -0
  33. package/src/components/hlw-page/index.vue +27 -8
  34. package/src/components/hlw-paging/index.vue +36 -0
  35. package/src/components/hlw-popup/index.vue +23 -0
  36. package/src/components/hlw-reward-ad/index.vue +133 -0
  37. package/src/components/hlw-search/index.vue +25 -0
  38. package/src/components/hlw-sheet/index.vue +1 -1
  39. package/src/components/hlw-status-bar/index.vue +113 -0
  40. package/src/components/hlw-tag/index.vue +22 -0
  41. package/src/core/index.ts +3 -0
  42. package/src/{composables → core}/msg/index.ts +0 -1
  43. package/src/{composables → core}/refs/index.ts +0 -1
  44. package/src/core/theme/index.ts +115 -0
  45. package/src/hlw.ts +1 -21
  46. package/src/index.ts +3 -11
  47. package/src/utils/ad/README.md +114 -0
  48. package/src/utils/ad/index.ts +234 -0
  49. package/src/{composables/utils → utils/common}/index.ts +1 -27
  50. package/src/{composables → utils}/device/index.ts +13 -21
  51. package/src/utils/index.ts +5 -0
  52. package/src/{composables → utils}/navigator/index.ts +30 -31
  53. package/src/{composables → utils}/request/client.ts +3 -11
  54. package/src/{composables → utils}/request/index.ts +1 -1
  55. package/src/{composables → utils}/request/service.ts +5 -6
  56. package/src/{composables → utils}/request/types.ts +0 -1
  57. package/dist/composables/ad/index.d.ts +0 -42
  58. package/dist/composables/index.d.ts +0 -11
  59. package/src/composables/ad/README.md +0 -58
  60. package/src/composables/ad/index.ts +0 -227
  61. package/src/composables/device/README.md +0 -50
  62. package/src/composables/index.ts +0 -38
  63. package/src/composables/msg/README.md +0 -79
  64. package/src/composables/navigator/README.md +0 -71
  65. package/src/composables/refs/README.md +0 -40
  66. package/src/composables/request/README.md +0 -124
  67. package/src/composables/share/README.md +0 -53
  68. package/src/composables/utils/README.md +0 -81
  69. package/src/core/theme.ts +0 -62
  70. /package/dist/{composables → core}/msg/index.d.ts +0 -0
  71. /package/dist/{composables → core}/refs/index.d.ts +0 -0
  72. /package/dist/{composables → core}/share/index.d.ts +0 -0
  73. /package/dist/{composables → utils}/request/adapters/alist.d.ts +0 -0
  74. /package/dist/{composables → utils}/request/adapters/base.d.ts +0 -0
  75. /package/dist/{composables → utils}/request/adapters/cos.d.ts +0 -0
  76. /package/dist/{composables → utils}/request/adapters/index.d.ts +0 -0
  77. /package/dist/{composables → utils}/request/adapters/oss.d.ts +0 -0
  78. /package/dist/{composables → utils}/request/adapters/qiniu.d.ts +0 -0
  79. /package/dist/{composables → utils}/request/types.d.ts +0 -0
  80. /package/src/{composables → core}/share/index.ts +0 -0
  81. /package/src/{composables → utils}/request/adapters/alist.ts +0 -0
  82. /package/src/{composables → utils}/request/adapters/base.ts +0 -0
  83. /package/src/{composables → utils}/request/adapters/cos.ts +0 -0
  84. /package/src/{composables → utils}/request/adapters/index.ts +0 -0
  85. /package/src/{composables → utils}/request/adapters/oss.ts +0 -0
  86. /package/src/{composables → utils}/request/adapters/qiniu.ts +0 -0
package/dist/index.mjs CHANGED
@@ -4,419 +4,461 @@ var __publicField = (obj, key, value) => {
4
4
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
5
  return value;
6
6
  };
7
- import { ref, onBeforeUpdate, onUnmounted, computed, createSSRApp } from "vue";
8
- import { onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
7
+ import { computed, watch, onMounted, ref, onBeforeUpdate, onUnmounted, createSSRApp } from "vue";
8
+ import { onShow, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
9
9
  import { defineStore } from "pinia";
10
- const cosAdapter = {
11
- name: "cos",
12
- /**
13
- * 生成 COS 直传所需的表单字段。
14
- */
15
- buildFormData(ctx) {
16
- const c = ctx.credentials ?? {};
17
- return {
18
- "q-ak": c["ak"] ?? "",
19
- policy: c["policy"] ?? "",
20
- "q-key-time": c["key-time"] ?? "",
21
- "q-signature": c["signature"] ?? "",
22
- "Content-Disposition": `inline;filename=${encodeURIComponent(ctx.fileName)}`,
23
- success_action_status: 200,
24
- ...ctx.extraData ?? {}
25
- };
26
- }
27
- };
28
- const ossAdapter = {
29
- name: "oss",
30
- /**
31
- * 生成 OSS 直传所需的表单字段。
32
- */
33
- buildFormData(ctx) {
34
- const c = ctx.credentials ?? {};
35
- return {
36
- key: c["key"] ?? ctx.fileName,
37
- policy: c["policy"] ?? "",
38
- signature: c["signature"] ?? "",
39
- OSSAccessKeyId: c["accessKeyId"] ?? "",
40
- success_action_status: 200,
41
- "Content-Disposition": `inline;filename=${encodeURIComponent(ctx.fileName)}`,
42
- ...ctx.extraData ?? {}
43
- };
44
- }
45
- };
46
- const qiniuAdapter = {
47
- name: "qiniu",
48
- /**
49
- * 生成七牛直传所需的表单字段。
50
- */
51
- buildFormData(ctx) {
52
- const c = ctx.credentials ?? {};
53
- return {
54
- token: c["token"] ?? "",
55
- key: c["key"] ?? ctx.fileName,
56
- ...ctx.extraData ?? {}
57
- };
58
- }
59
- };
60
- const alistAdapter = {
61
- name: "alist",
62
- /**
63
- * 生成 Alist 所需的表单字段。
64
- */
65
- buildFormData(ctx) {
66
- const c = ctx.credentials ?? {};
67
- return {
68
- "file-path": c["file-path"] ?? ctx.fileName,
69
- authorization: c["token"] ?? "",
70
- ...ctx.extraData ?? {}
71
- };
72
- }
73
- };
74
- const adapters = {
75
- cos: cosAdapter,
76
- oss: ossAdapter,
77
- qiniu: qiniuAdapter,
78
- alist: alistAdapter
79
- };
80
- function getAdapter(name) {
81
- const adapter = adapters[name];
82
- if (!adapter)
83
- throw new Error(`[hlw] Unknown upload adapter: ${name}`);
84
- return adapter;
85
- }
86
- class UniRequestClient {
87
- constructor() {
88
- __publicField(this, "reqInterceptors", []);
89
- __publicField(this, "resInterceptors", []);
90
- __publicField(this, "errInterceptors", []);
91
- __publicField(this, "baseURL", "");
92
- __publicField(this, "defaultHeaders", { "Content-Type": "application/json" });
93
- }
94
- /**
95
- * 设置全局基础请求 URL。
96
- */
97
- setBaseURL(url) {
98
- this.baseURL = url;
99
- }
100
- /**
101
- * 注册一个请求拦截器。
102
- */
103
- onRequest(fn) {
104
- this.reqInterceptors.push(fn);
105
- return () => this.remove(this.reqInterceptors, fn);
106
- }
107
- /**
108
- * 注册一个响应拦截器。
109
- */
110
- onResponse(fn) {
111
- const item = fn;
112
- this.resInterceptors.push(item);
113
- return () => this.remove(this.resInterceptors, item);
114
- }
115
- /**
116
- * 注册一个错误拦截器。
117
- */
118
- onError(fn) {
119
- this.errInterceptors.push(fn);
120
- return () => this.remove(this.errInterceptors, fn);
121
- }
122
- /**
123
- * 执行 HTTP 请求。
124
- */
125
- async request(config) {
126
- let cfg = {
127
- method: "GET",
128
- ...config,
129
- headers: { ...this.defaultHeaders, ...config.headers }
130
- };
131
- for (const fn of this.reqInterceptors) {
132
- cfg = await fn(cfg);
133
- }
134
- try {
135
- const res = await this.send(this.resolveUrl(cfg.url), cfg);
136
- for (const fn of this.resInterceptors) {
137
- const next = await fn(res);
138
- if (next !== void 0)
139
- return next;
140
- }
141
- return res;
142
- } catch (e) {
143
- const err = e;
144
- for (const fn of this.errInterceptors) {
145
- await fn(err);
146
- }
147
- throw err;
148
- }
149
- }
150
- /**
151
- * 发送 GET 请求。
152
- */
153
- get(url, data) {
154
- return this.request({ url, method: "GET", data });
155
- }
156
- /**
157
- * 发送 POST 请求。
158
- */
159
- post(url, data) {
160
- return this.request({ url, method: "POST", data });
161
- }
162
- /**
163
- * 发送 PUT 请求。
164
- */
165
- put(url, data) {
166
- return this.request({ url, method: "PUT", data });
167
- }
168
- /**
169
- * 发送 DELETE 请求。
170
- */
171
- del(url, data) {
172
- return this.request({ url, method: "DELETE", data });
173
- }
174
- /**
175
- * 上传本地文件,适配云存储(COS/OSS/七牛/Alist)或本地直传。
176
- */
177
- upload(config) {
178
- const fileName = config.fileName ?? config.filePath.split("/").pop() ?? "file";
179
- const server = config.type === "local" && config.url ? config.url : config.server;
180
- const formData = config.type === "local" ? config.credentials ?? {} : getAdapter(config.type).buildFormData({
181
- filePath: config.filePath,
182
- fileName,
183
- credentials: config.credentials
184
- });
185
- return new Promise((resolve, reject) => {
186
- uni.uploadFile({
187
- url: server,
188
- filePath: config.filePath,
189
- name: "file",
190
- formData,
191
- header: config.header,
192
- success: (res) => {
193
- if (res.statusCode < 200 || res.statusCode >= 300) {
194
- reject(new Error(`上传失败: ${res.statusCode}`));
195
- return;
196
- }
197
- try {
198
- const body = JSON.parse(res.data);
199
- resolve({
200
- code: body.code ?? 1,
201
- msg: body.msg ?? body.message ?? "上传成功",
202
- data: body.data ?? ""
203
- });
204
- } catch {
205
- resolve({ code: 1, msg: "上传成功", data: res.data });
206
- }
207
- },
208
- fail: (err) => reject(new Error(err.errMsg || "上传失败"))
209
- });
210
- });
10
+ const themePresets = [
11
+ {
12
+ id: "white-theme",
13
+ name: "白色主题",
14
+ color: "#ffffff"
15
+ },
16
+ {
17
+ id: "light-theme",
18
+ name: "简洁主题",
19
+ color: "var(--bg-page, #f8f8f8)"
20
+ },
21
+ {
22
+ id: "mono-theme",
23
+ name: "单色主题",
24
+ color: "var(--primary-color, #3b82f6)"
25
+ },
26
+ {
27
+ id: "color-theme",
28
+ name: "颜色主题",
29
+ color: "var(--primary-color, #3b82f6)"
211
30
  }
212
- /**
213
- * 解析微服务风格的命名空间 URL。
214
- */
215
- resolveServiceUrl(namespace, url, servicePrefix = "") {
216
- if (isAbsolute(url))
217
- return url;
218
- const ns = namespace.replace(/^\/+|\/+$/g, "").replace(/\//g, ".");
219
- const prefixValue = servicePrefix.replace(/^\/+|\/+$/g, "");
220
- const path = url.startsWith("/") ? url : `/${url}`;
221
- const prefix = [prefixValue, ns].filter(Boolean).join("/");
222
- return prefix ? `/${prefix}${path}` : path;
31
+ ];
32
+ const fontSizePresets = [
33
+ {
34
+ id: "small",
35
+ name: "较小",
36
+ class: "font-size-small"
37
+ },
38
+ {
39
+ id: "standard",
40
+ name: "标准",
41
+ class: "font-size-standard"
42
+ },
43
+ {
44
+ id: "large",
45
+ name: "较大",
46
+ class: "font-size-large"
47
+ },
48
+ {
49
+ id: "extra-large",
50
+ name: "超大",
51
+ class: "font-size-extra-large"
223
52
  }
224
- /**
225
- * 内部拼接基础 URL 与相对路径。
226
- */
227
- resolveUrl(url) {
228
- if (isAbsolute(url))
229
- return url;
230
- return `${this.baseURL}${url}`;
53
+ ];
54
+ const fontFamilyPresets = [
55
+ {
56
+ id: "system",
57
+ name: "系统默认",
58
+ class: "font-family-system"
59
+ },
60
+ {
61
+ id: "sans",
62
+ name: "现代黑体",
63
+ class: "font-family-sans"
64
+ },
65
+ {
66
+ id: "serif",
67
+ name: "经典宋体",
68
+ class: "font-family-serif"
69
+ },
70
+ {
71
+ id: "kaiti",
72
+ name: "优雅楷体",
73
+ class: "font-family-kaiti"
231
74
  }
232
- /**
233
- * 内部基于 uni.request 发送网络请求的方法。
234
- */
235
- send(url, cfg) {
236
- return new Promise((resolve, reject) => {
237
- uni.request({
238
- url,
239
- method: cfg.method,
240
- data: cfg.data,
241
- header: cfg.headers,
242
- timeout: cfg.timeout,
243
- success: (res) => {
244
- if (res.statusCode >= 200 && res.statusCode < 300) {
245
- resolve(res.data);
246
- return;
247
- }
248
- const body = res.data;
249
- reject(new Error(String((body == null ? void 0 : body.info) ?? (body == null ? void 0 : body.message) ?? `请求失败: ${res.statusCode}`)));
250
- },
251
- fail: (err) => reject(new Error(err.errMsg || "网络请求失败"))
252
- });
75
+ ];
76
+ const useThemeStore = defineStore("theme", {
77
+ state: () => ({
78
+ theme: "white-theme",
79
+ fontSize: "standard",
80
+ fontFamily: "system"
81
+ }),
82
+ getters: {},
83
+ actions: {
84
+ setFontSize(size) {
85
+ if (["small", "standard", "large", "extra-large"].includes(size)) {
86
+ this.fontSize = size;
87
+ }
88
+ },
89
+ setFontFamily(font) {
90
+ if (["system", "sans", "serif", "kaiti"].includes(font)) {
91
+ this.fontFamily = font;
92
+ }
93
+ }
94
+ },
95
+ unistorage: true
96
+ });
97
+ function useTheme() {
98
+ const store = useThemeStore();
99
+ const theme = computed(() => store.theme);
100
+ const updateNavbarColor = (targetTheme) => {
101
+ const isDarkTheme = ["mono-theme", "color-theme"].includes(targetTheme);
102
+ uni.setNavigationBarColor({
103
+ frontColor: isDarkTheme ? "#ffffff" : "#000000",
104
+ backgroundColor: isDarkTheme ? "#3b82f6" : "#ffffff",
105
+ fail: () => {
106
+ }
107
+ });
108
+ };
109
+ watch(
110
+ theme,
111
+ (newTheme) => {
112
+ updateNavbarColor(newTheme);
113
+ }
114
+ );
115
+ onMounted(() => {
116
+ updateNavbarColor(store.theme);
117
+ });
118
+ try {
119
+ onShow(() => {
120
+ updateNavbarColor(store.theme);
253
121
  });
122
+ } catch (e) {
254
123
  }
255
- /**
256
- * 从数组中安全移除某个拦截器实例。
257
- */
258
- remove(items, item) {
259
- const index = items.indexOf(item);
260
- if (index > -1)
261
- items.splice(index, 1);
124
+ updateNavbarColor(store.theme);
125
+ const fontSize = computed(() => store.fontSize);
126
+ const fontSizeClass = computed(() => {
127
+ const found = fontSizePresets.find((p) => p.id === store.fontSize);
128
+ return found ? found.class : "font-size-standard";
129
+ });
130
+ const fontFamily = computed(() => store.fontFamily);
131
+ const fontFamilyClass = computed(() => {
132
+ const found = fontFamilyPresets.find((p) => p.id === store.fontFamily);
133
+ return found ? found.class : "font-family-system";
134
+ });
135
+ function setFontSize(size) {
136
+ store.setFontSize(size);
262
137
  }
138
+ function setFontFamily(font) {
139
+ store.setFontFamily(font);
140
+ }
141
+ return {
142
+ theme,
143
+ fontSize,
144
+ fontSizeClass,
145
+ setFontSize,
146
+ fontFamily,
147
+ fontFamilyClass,
148
+ setFontFamily,
149
+ store
150
+ };
263
151
  }
264
- function isAbsolute(url) {
265
- return /^(https?:)?\/\//.test(url) || url.startsWith("file://");
266
- }
267
- const requestClient = new UniRequestClient();
268
- function useRequest() {
269
- return requestClient;
270
- }
271
- function useUpload() {
272
- const uploading = ref(false);
273
- async function upload(options) {
274
- uploading.value = true;
275
- try {
276
- return await requestClient.upload(options);
277
- } finally {
278
- uploading.value = false;
152
+ function initTheme(defaultTheme = "mono-theme") {
153
+ const hasCachedTheme = uni.getStorageSync("theme");
154
+ if (!hasCachedTheme) {
155
+ const store = useThemeStore();
156
+ const validThemes = themePresets.map((t) => t.id);
157
+ if (validThemes.includes(defaultTheme)) {
158
+ store.theme = defaultTheme;
279
159
  }
280
160
  }
281
- return { uploading, upload };
282
161
  }
283
- class BaseService {
284
- /**
285
- * 发送服务请求。会自动拼接前缀与命名空间。
286
- * @param options 请求配置项
287
- * @returns 响应结果 Promise
288
- */
289
- request(options) {
290
- return useRequest().request({
291
- ...options,
292
- url: useRequest().resolveServiceUrl(this.namespace ?? "", options.url, this.servicePrefix ?? "")
162
+ function useMsg() {
163
+ function toast(opts) {
164
+ const {
165
+ message,
166
+ icon = "none",
167
+ image = void 0,
168
+ duration = 2e3,
169
+ mask = false,
170
+ position = "center"
171
+ } = typeof opts === "string" ? { message: opts } : opts;
172
+ const mappedIcon = icon === "fail" || icon === "exception" ? "error" : icon;
173
+ uni.showToast({
174
+ title: message,
175
+ icon: mappedIcon,
176
+ image,
177
+ duration,
178
+ mask,
179
+ position
293
180
  });
294
181
  }
295
- /**
296
- * 快捷发送 GET 请求。
297
- * @param url 请求相对路径
298
- * @param data 请求参数
299
- */
300
- get(url, data) {
301
- return this.request({ url, method: "GET", data });
182
+ function success(message) {
183
+ uni.showToast({ title: message, icon: "success", duration: 2e3 });
302
184
  }
303
- /**
304
- * 快捷发送 POST 请求。
305
- * @param url 请求相对路径
306
- * @param data 请求携带的 body
307
- */
308
- post(url, data) {
309
- return this.request({ url, method: "POST", data });
185
+ function error(message) {
186
+ uni.showToast({ title: message, icon: "error", duration: 2e3 });
310
187
  }
311
- /**
312
- * 快捷发送 PUT 请求。
313
- * @param url 请求相对路径
314
- * @param data 请求携带的 body
315
- */
316
- put(url, data) {
317
- return this.request({ url, method: "PUT", data });
188
+ function showLoading(message = "加载中...") {
189
+ uni.showLoading({ title: message, mask: true });
318
190
  }
319
- /**
320
- * 快捷发送 DELETE 请求。
321
- * @param url 请求相对路径
322
- * @param data 请求参数
323
- */
324
- del(url, data) {
325
- return this.request({ url, method: "DELETE", data });
191
+ function hideLoading() {
192
+ uni.hideLoading();
193
+ }
194
+ function confirm(opts) {
195
+ return new Promise((resolve) => {
196
+ const {
197
+ title = "提示",
198
+ content,
199
+ confirmText = "确定",
200
+ cancelText = "取消",
201
+ confirmColor = "#3b82f6",
202
+ cancelColor = "#999999",
203
+ showCancel = true
204
+ } = opts;
205
+ uni.showModal({
206
+ title,
207
+ content,
208
+ confirmText,
209
+ cancelText,
210
+ confirmColor,
211
+ cancelColor,
212
+ showCancel,
213
+ success: (res) => resolve(res.confirm),
214
+ fail: () => resolve(false)
215
+ });
216
+ });
217
+ }
218
+ function setLoadingBar(progress) {
219
+ const clamped = Math.max(0, Math.min(100, progress));
220
+ const filled = Math.round(clamped / 2);
221
+ uni.setNavigationBarTitle({
222
+ title: `${"■".repeat(filled)}${"□".repeat(50 - filled)} ${clamped}%`
223
+ });
326
224
  }
225
+ return {
226
+ toast,
227
+ success,
228
+ error,
229
+ fail: error,
230
+ showLoading,
231
+ hideLoading,
232
+ confirm,
233
+ modal: confirm,
234
+ setLoadingBar
235
+ };
327
236
  }
328
- function ServiceNamespace(value) {
329
- return function(target) {
330
- target.prototype.namespace = typeof value === "string" ? value : value.namespace;
237
+ function useRefs() {
238
+ const refs = ref({});
239
+ onBeforeUpdate(() => {
240
+ refs.value = {};
241
+ });
242
+ onUnmounted(() => {
243
+ refs.value = {};
244
+ });
245
+ const setRefs = (key) => (el) => {
246
+ if (el)
247
+ refs.value[key] = el;
331
248
  };
249
+ return { refs, setRefs };
332
250
  }
333
- function ServicePrefix(value) {
334
- return function(target) {
335
- target.prototype.servicePrefix = typeof value === "string" ? value : value.prefix;
251
+ function resolveConfig(config) {
252
+ return typeof config === "function" ? config() : config ?? {};
253
+ }
254
+ function buildPayload(base, extra) {
255
+ const current = {
256
+ ...resolveConfig(base),
257
+ ...resolveConfig(extra)
258
+ };
259
+ const payload = {};
260
+ if (current.title)
261
+ payload.title = current.title;
262
+ if (current.path)
263
+ payload.path = current.path;
264
+ if (current.imageUrl)
265
+ payload.imageUrl = current.imageUrl;
266
+ return payload;
267
+ }
268
+ function showShareMenu() {
269
+ var _a;
270
+ const api = typeof uni !== "undefined" ? uni : void 0;
271
+ (_a = api == null ? void 0 : api.showShareMenu) == null ? void 0 : _a.call(api, {
272
+ withShareTicket: true,
273
+ menus: ["shareAppMessage", "shareTimeline"],
274
+ fail: () => void 0
275
+ });
276
+ }
277
+ function useShare(config = {}) {
278
+ let appMessageRegistered = false;
279
+ let timelineRegistered = false;
280
+ const onShareAppMessage$1 = (extra) => {
281
+ if (appMessageRegistered)
282
+ return;
283
+ appMessageRegistered = true;
284
+ showShareMenu();
285
+ onShareAppMessage(() => buildPayload(config, extra));
286
+ };
287
+ const onShareTimeline$1 = (extra) => {
288
+ if (timelineRegistered)
289
+ return;
290
+ timelineRegistered = true;
291
+ showShareMenu();
292
+ onShareTimeline(() => {
293
+ var _a;
294
+ const payload = buildPayload(config, extra);
295
+ return {
296
+ title: payload.title,
297
+ query: (_a = payload.path) == null ? void 0 : _a.split("?")[1],
298
+ imageUrl: payload.imageUrl
299
+ };
300
+ });
336
301
  };
302
+ onShareAppMessage$1();
303
+ onShareTimeline$1();
304
+ return {
305
+ onShareAppMessage: onShareAppMessage$1,
306
+ onShareTimeline: onShareTimeline$1,
307
+ showShareMenu
308
+ };
309
+ }
310
+ const adInstances = /* @__PURE__ */ new Map();
311
+ let activePopupId = "";
312
+ let activeRewardId = "";
313
+ let popupCallback;
314
+ let rewardCallback;
315
+ let rewardPromise = null;
316
+ let rewardResolve = null;
317
+ function resolveReward(res) {
318
+ rewardCallback == null ? void 0 : rewardCallback(res);
319
+ rewardResolve == null ? void 0 : rewardResolve(res);
320
+ rewardResolve = null;
321
+ rewardPromise = null;
322
+ }
323
+ function setPopupAd(adId, done) {
324
+ var _a, _b, _c;
325
+ popupCallback = done;
326
+ if (!adId || !uni.createInterstitialAd)
327
+ return false;
328
+ activePopupId = adId;
329
+ if (!adInstances.has(adId)) {
330
+ try {
331
+ const ad = uni.createInterstitialAd({ adUnitId: adId });
332
+ (_a = ad.onLoad) == null ? void 0 : _a.call(ad, () => console.log(`[Ad] Interstitial loaded: ${adId}`));
333
+ (_b = ad.onError) == null ? void 0 : _b.call(ad, (err) => {
334
+ console.error("[Ad] Interstitial load error:", err);
335
+ if (activePopupId === adId)
336
+ popupCallback == null ? void 0 : popupCallback(false);
337
+ });
338
+ (_c = ad.onClose) == null ? void 0 : _c.call(ad, () => {
339
+ if (activePopupId === adId)
340
+ popupCallback == null ? void 0 : popupCallback(true);
341
+ });
342
+ adInstances.set(adId, ad);
343
+ } catch (e) {
344
+ console.error("[Ad] Interstitial creation failed:", e);
345
+ return false;
346
+ }
347
+ }
348
+ return true;
337
349
  }
338
- function PluginService(target) {
339
- Object.defineProperty(target.prototype, "servicePrefix", {
340
- get() {
341
- return globalThis.VITE_PLUGIN_NAME || "";
342
- },
343
- enumerable: true,
344
- configurable: true
350
+ function showPopupAd(delay = 3e3) {
351
+ return new Promise((resolve) => {
352
+ const ad = adInstances.get(activePopupId);
353
+ if (!ad) {
354
+ resolve(false);
355
+ return;
356
+ }
357
+ const originalDone = popupCallback;
358
+ popupCallback = (ok) => {
359
+ originalDone == null ? void 0 : originalDone(ok);
360
+ resolve(ok);
361
+ };
362
+ setTimeout(
363
+ () => {
364
+ ad.show().catch((err) => {
365
+ console.error("[Ad] Interstitial show error:", err);
366
+ popupCallback == null ? void 0 : popupCallback(false);
367
+ });
368
+ },
369
+ Math.max(0, delay)
370
+ );
345
371
  });
346
372
  }
347
- function useMsg() {
348
- function toast(opts) {
349
- const {
350
- message,
351
- icon = "none",
352
- image = void 0,
353
- duration = 2e3,
354
- mask = false,
355
- position = "center"
356
- } = typeof opts === "string" ? { message: opts } : opts;
357
- const mappedIcon = icon === "fail" || icon === "exception" ? "error" : icon;
358
- uni.showToast({
359
- title: message,
360
- icon: mappedIcon,
361
- image,
362
- duration,
363
- mask,
364
- position
365
- });
366
- }
367
- function success(message) {
368
- uni.showToast({ title: message, icon: "success", duration: 2e3 });
369
- }
370
- function error(message) {
371
- uni.showToast({ title: message, icon: "error", duration: 2e3 });
373
+ function setRewardAd(adId, done) {
374
+ var _a, _b, _c;
375
+ rewardCallback = done;
376
+ rewardPromise = new Promise((resolve) => {
377
+ rewardResolve = resolve;
378
+ });
379
+ if (!adId || !uni.createRewardedVideoAd) {
380
+ resolveReward({ success: false, isEnded: false });
381
+ return rewardPromise;
372
382
  }
373
- function showLoading(message = "加载中...") {
374
- uni.showLoading({ title: message, mask: true });
383
+ activeRewardId = adId;
384
+ if (!adInstances.has(adId)) {
385
+ try {
386
+ const ad = uni.createRewardedVideoAd({ adUnitId: adId });
387
+ (_a = ad.onLoad) == null ? void 0 : _a.call(ad, () => console.log(`[Ad] Rewarded video loaded: ${adId}`));
388
+ (_b = ad.onError) == null ? void 0 : _b.call(ad, (err) => {
389
+ console.error("[Ad] Rewarded video load error:", err);
390
+ if (activeRewardId === adId) {
391
+ resolveReward({ success: false, isEnded: false, err });
392
+ }
393
+ });
394
+ (_c = ad.onClose) == null ? void 0 : _c.call(ad, (res) => {
395
+ if (activeRewardId === adId) {
396
+ const ended = !!(res == null ? void 0 : res.isEnded);
397
+ resolveReward({ success: ended, isEnded: ended });
398
+ ad.load().catch((err) => {
399
+ console.warn("[Ad] Silent preload after close failed:", err);
400
+ });
401
+ }
402
+ });
403
+ adInstances.set(adId, ad);
404
+ } catch (e) {
405
+ console.error("[Ad] Rewarded video creation failed:", e);
406
+ resolveReward({ success: false, isEnded: false, err: e });
407
+ }
375
408
  }
376
- function hideLoading() {
377
- uni.hideLoading();
409
+ return rewardPromise;
410
+ }
411
+ function showRewardAd(onShowSuccess) {
412
+ const ad = adInstances.get(activeRewardId);
413
+ if (!ad) {
414
+ return Promise.resolve({ success: false, isEnded: false });
378
415
  }
379
- function confirm(opts) {
380
- return new Promise((resolve) => {
381
- const {
382
- title = "提示",
383
- content,
384
- confirmText = "确定",
385
- cancelText = "取消",
386
- confirmColor = "#3b82f6",
387
- cancelColor = "#999999",
388
- showCancel = true
389
- } = opts;
390
- uni.showModal({
391
- title,
392
- content,
393
- confirmText,
394
- cancelText,
395
- confirmColor,
396
- cancelColor,
397
- showCancel,
398
- success: (res) => resolve(res.confirm),
399
- fail: () => resolve(false)
416
+ const current = rewardPromise || new Promise((resolve) => {
417
+ rewardResolve = resolve;
418
+ });
419
+ rewardPromise = current;
420
+ ad.show().then(() => {
421
+ onShowSuccess == null ? void 0 : onShowSuccess();
422
+ }).catch(() => {
423
+ ad.load().then(() => {
424
+ ad.show().then(() => {
425
+ onShowSuccess == null ? void 0 : onShowSuccess();
426
+ }).catch((err) => {
427
+ console.error("[Ad] Rewarded video show error:", err);
428
+ resolveReward({ success: false, isEnded: false, err });
400
429
  });
430
+ }).catch((err) => {
431
+ console.error("[Ad] Rewarded video load error:", err);
432
+ resolveReward({ success: false, isEnded: false, err });
401
433
  });
402
- }
403
- function setLoadingBar(progress) {
404
- const clamped = Math.max(0, Math.min(100, progress));
405
- const filled = Math.round(clamped / 2);
406
- uni.setNavigationBarTitle({
407
- title: `${"■".repeat(filled)}${"□".repeat(50 - filled)} ${clamped}%`
434
+ });
435
+ return current;
436
+ }
437
+ function confirmRewardAd() {
438
+ return new Promise((resolve) => {
439
+ uni.showModal({
440
+ title: "提示",
441
+ content: "需要看完广告才有奖励哦",
442
+ cancelText: "取消",
443
+ confirmText: "继续观看",
444
+ cancelColor: "#999999",
445
+ confirmColor: "#3b82f6",
446
+ success: (res) => {
447
+ resolve(!!res.confirm);
448
+ },
449
+ fail: () => {
450
+ resolve(false);
451
+ }
408
452
  });
409
- }
453
+ });
454
+ }
455
+ function useHlwAd() {
410
456
  return {
411
- toast,
412
- success,
413
- error,
414
- fail: error,
415
- showLoading,
416
- hideLoading,
417
- confirm,
418
- modal: confirm,
419
- setLoadingBar
457
+ setPopupAd,
458
+ showPopupAd,
459
+ setRewardAd,
460
+ showRewardAd,
461
+ confirmRewardAd
420
462
  };
421
463
  }
422
464
  function withQuery(url, qs) {
@@ -572,22 +614,79 @@ async function saveVideoUrl(url, progress) {
572
614
  return false;
573
615
  }
574
616
  }
575
- function useUtils() {
576
- return {
577
- withQuery,
578
- toQuery,
579
- signText,
580
- toNumber,
581
- toBoolean,
582
- copy,
583
- paste,
584
- saveImage,
585
- saveVideoFile,
586
- download,
587
- saveImageUrl,
588
- saveVideoUrl
617
+ function fail(message, options = {}) {
618
+ var _a;
619
+ if (!options.silent) {
620
+ uni.showToast({ title: message, icon: "none" });
621
+ }
622
+ (_a = options.onFail) == null ? void 0 : _a.call(options, message);
623
+ }
624
+ function failHandler(target, options = {}) {
625
+ return (error) => {
626
+ fail((error == null ? void 0 : error.errMsg) || `无法跳转:${target}`, options);
589
627
  };
590
628
  }
629
+ function navigate(type = "navigateTo", url = "", options = {}) {
630
+ if (type === "navigateBack") {
631
+ uni.navigateBack({ delta: options.delta || 1, fail: failHandler("返回上一页", options) });
632
+ return;
633
+ }
634
+ if (!url) {
635
+ fail("跳转目标未配置", options);
636
+ return;
637
+ }
638
+ const onFail = failHandler(url, options);
639
+ if (type === "redirectTo") {
640
+ uni.redirectTo({ url, fail: onFail });
641
+ return;
642
+ }
643
+ if (type === "switchTab") {
644
+ uni.switchTab({ url, fail: onFail });
645
+ return;
646
+ }
647
+ if (type === "reLaunch") {
648
+ uni.reLaunch({ url, fail: onFail });
649
+ return;
650
+ }
651
+ if (type === "miniprogram") {
652
+ const openMiniProgram = uni.navigateToMiniProgram;
653
+ if (!openMiniProgram) {
654
+ fail("当前平台不支持打开小程序", options);
655
+ return;
656
+ }
657
+ openMiniProgram({
658
+ appId: url,
659
+ path: options.path || "",
660
+ envVersion: options.envVersion || "release",
661
+ extraData: options.extraData,
662
+ fail: onFail
663
+ });
664
+ return;
665
+ }
666
+ if (type === "webview") {
667
+ fail(`H5:${url}`, options);
668
+ return;
669
+ }
670
+ uni.navigateTo({ url, animationType: "none", fail: onFail });
671
+ }
672
+ function navigateTo(url, options) {
673
+ return navigate("navigateTo", url, options);
674
+ }
675
+ function redirectTo(url, options) {
676
+ return navigate("redirectTo", url, options);
677
+ }
678
+ function switchTab(url, options) {
679
+ return navigate("switchTab", url, options);
680
+ }
681
+ function reLaunch(url, options) {
682
+ return navigate("reLaunch", url, options);
683
+ }
684
+ function navigateBack(delta = 1, options = {}) {
685
+ return navigate("navigateBack", "", { ...options, delta });
686
+ }
687
+ function navigateToMiniProgram(appId, options) {
688
+ return navigate("miniprogram", appId, options);
689
+ }
591
690
  let deviceCache = null;
592
691
  function readSafe(fn) {
593
692
  try {
@@ -647,10 +746,6 @@ function getAppid(device) {
647
746
  return device.appId || "";
648
747
  }
649
748
  }
650
- function getDevice() {
651
- deviceCache ?? (deviceCache = collectDevice());
652
- return deviceCache;
653
- }
654
749
  function getQueryInfo(info) {
655
750
  return {
656
751
  appid: info.appid,
@@ -666,441 +761,364 @@ function getQueryInfo(info) {
666
761
  sdk_version: info.sdk_version,
667
762
  host_name: info.host_name,
668
763
  host_version: info.host_version,
669
- host_language: info.host_language,
670
- language: info.language,
671
- app_version: info.app_version,
672
- app_version_code: info.app_version_code,
673
- screen_width: info.screen_width,
674
- screen_height: info.screen_height
675
- };
676
- }
677
- function useDevice() {
678
- const info = getDevice();
679
- return {
680
- info,
681
- query: toQuery(getQueryInfo(info))
682
- };
683
- }
684
- function clearDeviceCache() {
685
- deviceCache = null;
686
- }
687
- function useRefs() {
688
- const refs = ref({});
689
- onBeforeUpdate(() => {
690
- refs.value = {};
691
- });
692
- onUnmounted(() => {
693
- refs.value = {};
694
- });
695
- const setRefs = (key) => (el) => {
696
- if (el)
697
- refs.value[key] = el;
698
- };
699
- return { refs, setRefs };
700
- }
701
- function resolveConfig(config) {
702
- return typeof config === "function" ? config() : config ?? {};
703
- }
704
- function buildPayload(base, extra) {
705
- const current = {
706
- ...resolveConfig(base),
707
- ...resolveConfig(extra)
708
- };
709
- const payload = {};
710
- if (current.title)
711
- payload.title = current.title;
712
- if (current.path)
713
- payload.path = current.path;
714
- if (current.imageUrl)
715
- payload.imageUrl = current.imageUrl;
716
- return payload;
717
- }
718
- function showShareMenu() {
719
- var _a;
720
- const api = typeof uni !== "undefined" ? uni : void 0;
721
- (_a = api == null ? void 0 : api.showShareMenu) == null ? void 0 : _a.call(api, {
722
- withShareTicket: true,
723
- menus: ["shareAppMessage", "shareTimeline"],
724
- fail: () => void 0
725
- });
726
- }
727
- function useShare(config = {}) {
728
- let appMessageRegistered = false;
729
- let timelineRegistered = false;
730
- const onShareAppMessage$1 = (extra) => {
731
- if (appMessageRegistered)
732
- return;
733
- appMessageRegistered = true;
734
- showShareMenu();
735
- onShareAppMessage(() => buildPayload(config, extra));
736
- };
737
- const onShareTimeline$1 = (extra) => {
738
- if (timelineRegistered)
739
- return;
740
- timelineRegistered = true;
741
- showShareMenu();
742
- onShareTimeline(() => {
743
- var _a;
744
- const payload = buildPayload(config, extra);
745
- return {
746
- title: payload.title,
747
- query: (_a = payload.path) == null ? void 0 : _a.split("?")[1],
748
- imageUrl: payload.imageUrl
749
- };
750
- });
751
- };
752
- onShareAppMessage$1();
753
- onShareTimeline$1();
754
- return {
755
- onShareAppMessage: onShareAppMessage$1,
756
- onShareTimeline: onShareTimeline$1,
757
- showShareMenu
764
+ host_language: info.host_language,
765
+ language: info.language,
766
+ app_version: info.app_version,
767
+ app_version_code: info.app_version_code,
768
+ screen_width: info.screen_width,
769
+ screen_height: info.screen_height
758
770
  };
759
771
  }
760
- const popupCache = /* @__PURE__ */ new Map();
761
- const rewardCache = /* @__PURE__ */ new Map();
762
- let activePopupAdId = "";
763
- let popupDone;
764
- let activeRewardAdId = "";
765
- let rewardDone;
766
- let rewardPromise = null;
767
- let rewardResolve = null;
768
- function getAdApi() {
769
- if (typeof uni !== "undefined")
770
- return uni;
771
- if (typeof wx !== "undefined")
772
- return wx;
773
- return null;
772
+ function getDevice() {
773
+ deviceCache ?? (deviceCache = collectDevice());
774
+ return deviceCache;
774
775
  }
775
- function finish(res) {
776
- rewardDone == null ? void 0 : rewardDone(res);
777
- rewardResolve == null ? void 0 : rewardResolve(res);
778
- rewardResolve = null;
779
- rewardPromise = null;
776
+ function getDeviceQuery() {
777
+ return toQuery(getQueryInfo(getDevice()));
780
778
  }
781
- function useHlwAd() {
782
- function setAdPopup(adId, done) {
783
- var _a, _b, _c;
784
- popupDone = done;
785
- if (!adId)
786
- return false;
787
- const api = getAdApi();
788
- if (!(api == null ? void 0 : api.createInterstitialAd))
789
- return false;
790
- activePopupAdId = adId;
791
- if (!popupCache.has(adId)) {
792
- try {
793
- const ad = api.createInterstitialAd({ adUnitId: adId });
794
- (_a = ad.onLoad) == null ? void 0 : _a.call(ad, () => console.log(`[HlwAd] Interstitial loaded: ${adId}`));
795
- (_b = ad.onError) == null ? void 0 : _b.call(ad, (err) => {
796
- console.error("[HlwAd] Interstitial load error:", err);
797
- if (activePopupAdId === adId) {
798
- popupDone == null ? void 0 : popupDone(false);
799
- }
800
- });
801
- (_c = ad.onClose) == null ? void 0 : _c.call(ad, () => {
802
- if (activePopupAdId === adId) {
803
- popupDone == null ? void 0 : popupDone(true);
804
- }
805
- });
806
- popupCache.set(adId, ad);
807
- } catch (e) {
808
- console.error("[HlwAd] Interstitial creation failed:", e);
809
- return false;
779
+ function clearDeviceCache() {
780
+ deviceCache = null;
781
+ }
782
+ const cosAdapter = {
783
+ name: "cos",
784
+ /**
785
+ * 生成 COS 直传所需的表单字段。
786
+ */
787
+ buildFormData(ctx) {
788
+ const c = ctx.credentials ?? {};
789
+ return {
790
+ "q-ak": c["ak"] ?? "",
791
+ policy: c["policy"] ?? "",
792
+ "q-key-time": c["key-time"] ?? "",
793
+ "q-signature": c["signature"] ?? "",
794
+ "Content-Disposition": `inline;filename=${encodeURIComponent(ctx.fileName)}`,
795
+ success_action_status: 200,
796
+ ...ctx.extraData ?? {}
797
+ };
798
+ }
799
+ };
800
+ const ossAdapter = {
801
+ name: "oss",
802
+ /**
803
+ * 生成 OSS 直传所需的表单字段。
804
+ */
805
+ buildFormData(ctx) {
806
+ const c = ctx.credentials ?? {};
807
+ return {
808
+ key: c["key"] ?? ctx.fileName,
809
+ policy: c["policy"] ?? "",
810
+ signature: c["signature"] ?? "",
811
+ OSSAccessKeyId: c["accessKeyId"] ?? "",
812
+ success_action_status: 200,
813
+ "Content-Disposition": `inline;filename=${encodeURIComponent(ctx.fileName)}`,
814
+ ...ctx.extraData ?? {}
815
+ };
816
+ }
817
+ };
818
+ const qiniuAdapter = {
819
+ name: "qiniu",
820
+ /**
821
+ * 生成七牛直传所需的表单字段。
822
+ */
823
+ buildFormData(ctx) {
824
+ const c = ctx.credentials ?? {};
825
+ return {
826
+ token: c["token"] ?? "",
827
+ key: c["key"] ?? ctx.fileName,
828
+ ...ctx.extraData ?? {}
829
+ };
830
+ }
831
+ };
832
+ const alistAdapter = {
833
+ name: "alist",
834
+ /**
835
+ * 生成 Alist 所需的表单字段。
836
+ */
837
+ buildFormData(ctx) {
838
+ const c = ctx.credentials ?? {};
839
+ return {
840
+ "file-path": c["file-path"] ?? ctx.fileName,
841
+ authorization: c["token"] ?? "",
842
+ ...ctx.extraData ?? {}
843
+ };
844
+ }
845
+ };
846
+ const adapters = {
847
+ cos: cosAdapter,
848
+ oss: ossAdapter,
849
+ qiniu: qiniuAdapter,
850
+ alist: alistAdapter
851
+ };
852
+ function getAdapter(name) {
853
+ const adapter = adapters[name];
854
+ if (!adapter)
855
+ throw new Error(`[hlw] Unknown upload adapter: ${name}`);
856
+ return adapter;
857
+ }
858
+ class UniRequestClient {
859
+ constructor() {
860
+ __publicField(this, "reqInterceptors", []);
861
+ __publicField(this, "resInterceptors", []);
862
+ __publicField(this, "errInterceptors", []);
863
+ __publicField(this, "baseURL", "");
864
+ __publicField(this, "defaultHeaders", { "Content-Type": "application/json" });
865
+ }
866
+ /**
867
+ * 设置全局基础请求 URL。
868
+ */
869
+ setBaseURL(url) {
870
+ this.baseURL = url;
871
+ }
872
+ /**
873
+ * 注册一个请求拦截器。
874
+ */
875
+ onRequest(fn) {
876
+ this.reqInterceptors.push(fn);
877
+ return () => this.remove(this.reqInterceptors, fn);
878
+ }
879
+ /**
880
+ * 注册一个响应拦截器。
881
+ */
882
+ onResponse(fn) {
883
+ const item = fn;
884
+ this.resInterceptors.push(item);
885
+ return () => this.remove(this.resInterceptors, item);
886
+ }
887
+ /**
888
+ * 注册一个错误拦截器。
889
+ */
890
+ onError(fn) {
891
+ this.errInterceptors.push(fn);
892
+ return () => this.remove(this.errInterceptors, fn);
893
+ }
894
+ /**
895
+ * 执行 HTTP 请求。
896
+ */
897
+ async request(config) {
898
+ let cfg = {
899
+ method: "GET",
900
+ ...config,
901
+ headers: { ...this.defaultHeaders, ...config.headers }
902
+ };
903
+ for (const fn of this.reqInterceptors) {
904
+ cfg = await fn(cfg);
905
+ }
906
+ try {
907
+ const res = await this.send(this.resolveUrl(cfg.url), cfg);
908
+ for (const fn of this.resInterceptors) {
909
+ const next = await fn(res);
910
+ if (next !== void 0)
911
+ return next;
912
+ }
913
+ return res;
914
+ } catch (e) {
915
+ const err = e;
916
+ for (const fn of this.errInterceptors) {
917
+ await fn(err);
810
918
  }
919
+ throw err;
811
920
  }
812
- return true;
813
921
  }
814
- function showAdPopup(delay = 3e3) {
815
- return new Promise((resolve) => {
816
- const ad = popupCache.get(activePopupAdId);
817
- if (!ad) {
818
- resolve(false);
819
- return;
820
- }
821
- const done = popupDone;
822
- popupDone = (ok) => {
823
- done == null ? void 0 : done(ok);
824
- resolve(ok);
825
- };
826
- setTimeout(() => {
827
- ad.show().catch((err) => {
828
- console.error("[HlwAd] Interstitial show error:", err);
829
- popupDone == null ? void 0 : popupDone(false);
830
- });
831
- }, Math.max(0, delay));
832
- });
922
+ /**
923
+ * 发送 GET 请求。
924
+ */
925
+ get(url, data) {
926
+ return this.request({ url, method: "GET", data });
927
+ }
928
+ /**
929
+ * 发送 POST 请求。
930
+ */
931
+ post(url, data) {
932
+ return this.request({ url, method: "POST", data });
933
+ }
934
+ /**
935
+ * 发送 PUT 请求。
936
+ */
937
+ put(url, data) {
938
+ return this.request({ url, method: "PUT", data });
939
+ }
940
+ /**
941
+ * 发送 DELETE 请求。
942
+ */
943
+ del(url, data) {
944
+ return this.request({ url, method: "DELETE", data });
833
945
  }
834
- function setAdReward(adId, done) {
835
- var _a, _b, _c;
836
- rewardDone = done;
837
- rewardPromise = new Promise((resolve) => {
838
- rewardResolve = resolve;
946
+ /**
947
+ * 上传本地文件,适配云存储(COS/OSS/七牛/Alist)或本地直传。
948
+ */
949
+ upload(config) {
950
+ const fileName = config.fileName ?? config.filePath.split("/").pop() ?? "file";
951
+ const server = config.type === "local" && config.url ? config.url : config.server;
952
+ const formData = config.type === "local" ? config.credentials ?? {} : getAdapter(config.type).buildFormData({
953
+ filePath: config.filePath,
954
+ fileName,
955
+ credentials: config.credentials
839
956
  });
840
- if (!adId) {
841
- finish({ ok: false });
842
- return rewardPromise;
843
- }
844
- const api = getAdApi();
845
- if (!(api == null ? void 0 : api.createRewardedVideoAd)) {
846
- finish({ ok: false });
847
- return rewardPromise;
848
- }
849
- activeRewardAdId = adId;
850
- if (!rewardCache.has(adId)) {
851
- try {
852
- const ad = api.createRewardedVideoAd({ adUnitId: adId });
853
- (_a = ad.onLoad) == null ? void 0 : _a.call(ad, () => console.log(`[HlwAd] Rewarded video loaded: ${adId}`));
854
- (_b = ad.onError) == null ? void 0 : _b.call(ad, (err) => {
855
- console.error("[HlwAd] Rewarded video load error:", err);
856
- if (activeRewardAdId === adId) {
857
- finish({ ok: false, err });
957
+ return new Promise((resolve, reject) => {
958
+ uni.uploadFile({
959
+ url: server,
960
+ filePath: config.filePath,
961
+ name: "file",
962
+ formData,
963
+ header: config.header,
964
+ success: (res) => {
965
+ if (res.statusCode < 200 || res.statusCode >= 300) {
966
+ reject(new Error(`上传失败: ${res.statusCode}`));
967
+ return;
858
968
  }
859
- });
860
- (_c = ad.onClose) == null ? void 0 : _c.call(ad, (res) => {
861
- if (activeRewardAdId === adId) {
862
- const isEnded = !!(res == null ? void 0 : res.isEnded);
863
- finish({ ok: isEnded, isEnded });
969
+ try {
970
+ const body = JSON.parse(res.data);
971
+ resolve({
972
+ code: body.code ?? 1,
973
+ msg: body.msg ?? body.message ?? "上传成功",
974
+ data: body.data ?? ""
975
+ });
976
+ } catch {
977
+ resolve({ code: 1, msg: "上传成功", data: res.data });
978
+ }
979
+ },
980
+ fail: (err) => reject(new Error(err.errMsg || "上传失败"))
981
+ });
982
+ });
983
+ }
984
+ /**
985
+ * 解析微服务风格的命名空间 URL。
986
+ */
987
+ resolveServiceUrl(namespace, url, servicePrefix = "") {
988
+ if (isAbsolute(url))
989
+ return url;
990
+ const ns = namespace.replace(/^\/+|\/+$/g, "").replace(/\//g, ".");
991
+ const prefixValue = servicePrefix.replace(/^\/+|\/+$/g, "");
992
+ const path = url.startsWith("/") ? url : `/${url}`;
993
+ const prefix = [prefixValue, ns].filter(Boolean).join("/");
994
+ return prefix ? `/${prefix}${path}` : path;
995
+ }
996
+ /**
997
+ * 内部拼接基础 URL 与相对路径。
998
+ */
999
+ resolveUrl(url) {
1000
+ if (isAbsolute(url))
1001
+ return url;
1002
+ return `${this.baseURL}${url}`;
1003
+ }
1004
+ /**
1005
+ * 内部基于 uni.request 发送网络请求的方法。
1006
+ */
1007
+ send(url, cfg) {
1008
+ return new Promise((resolve, reject) => {
1009
+ uni.request({
1010
+ url,
1011
+ method: cfg.method,
1012
+ data: cfg.data,
1013
+ header: cfg.headers,
1014
+ timeout: cfg.timeout,
1015
+ success: (res) => {
1016
+ if (res.statusCode >= 200 && res.statusCode < 300) {
1017
+ resolve(res.data);
1018
+ return;
864
1019
  }
865
- });
866
- rewardCache.set(adId, ad);
867
- } catch (e) {
868
- console.error("[HlwAd] Rewarded video creation failed:", e);
869
- finish({ ok: false, err: e });
870
- }
871
- }
872
- return rewardPromise;
873
- }
874
- function showAdReward() {
875
- const ad = rewardCache.get(activeRewardAdId);
876
- if (!ad) {
877
- return Promise.resolve({ ok: false });
878
- }
879
- const current = rewardPromise || new Promise((resolve) => {
880
- rewardResolve = resolve;
881
- });
882
- rewardPromise = current;
883
- ad.show().catch(() => {
884
- ad.load().then(() => ad.show()).catch((err) => {
885
- console.error("[HlwAd] Rewarded video show error:", err);
886
- finish({ ok: false, err });
1020
+ const body = res.data;
1021
+ reject(new Error(String((body == null ? void 0 : body.info) ?? (body == null ? void 0 : body.message) ?? `请求失败: ${res.statusCode}`)));
1022
+ },
1023
+ fail: (err) => reject(new Error(err.errMsg || "网络请求失败"))
887
1024
  });
888
1025
  });
889
- return current;
890
1026
  }
891
- return {
892
- setAdPopup,
893
- showAdPopup,
894
- setAdReward,
895
- showAdReward
896
- };
897
- }
898
- function fail(message, options = {}) {
899
- var _a;
900
- if (!options.silent) {
901
- uni.showToast({ title: message, icon: "none" });
1027
+ /**
1028
+ * 从数组中安全移除某个拦截器实例。
1029
+ */
1030
+ remove(items, item) {
1031
+ const index = items.indexOf(item);
1032
+ if (index > -1)
1033
+ items.splice(index, 1);
902
1034
  }
903
- (_a = options.onFail) == null ? void 0 : _a.call(options, message);
904
1035
  }
905
- function failHandler(target, options = {}) {
906
- return (error) => {
907
- fail((error == null ? void 0 : error.errMsg) || `无法跳转:${target}`, options);
908
- };
1036
+ function isAbsolute(url) {
1037
+ return /^(https?:)?\/\//.test(url) || url.startsWith("file://");
909
1038
  }
910
- function navigate(type = "navigateTo", url = "", options = {}) {
911
- if (type === "navigateBack") {
912
- uni.navigateBack({ delta: options.delta || 1, fail: failHandler("返回上一页", options) });
913
- return;
914
- }
915
- if (!url) {
916
- fail("跳转目标未配置", options);
917
- return;
1039
+ const requestClient = new UniRequestClient();
1040
+ const request = requestClient;
1041
+ function useUpload() {
1042
+ const uploading = ref(false);
1043
+ async function upload(options) {
1044
+ uploading.value = true;
1045
+ try {
1046
+ return await requestClient.upload(options);
1047
+ } finally {
1048
+ uploading.value = false;
1049
+ }
918
1050
  }
919
- const onFail = failHandler(url, options);
920
- if (type === "redirectTo") {
921
- uni.redirectTo({ url, fail: onFail });
922
- return;
1051
+ return { uploading, upload };
1052
+ }
1053
+ class BaseService {
1054
+ /**
1055
+ * 发送服务请求。会自动拼接前缀与命名空间。
1056
+ * @param options 请求配置项
1057
+ * @returns 响应结果 Promise
1058
+ */
1059
+ request(options) {
1060
+ return request.request({
1061
+ ...options,
1062
+ url: request.resolveServiceUrl(this.namespace ?? "", options.url, this.servicePrefix ?? "")
1063
+ });
923
1064
  }
924
- if (type === "switchTab") {
925
- uni.switchTab({ url, fail: onFail });
926
- return;
1065
+ /**
1066
+ * 快捷发送 GET 请求。
1067
+ * @param url 请求相对路径
1068
+ * @param data 请求参数
1069
+ */
1070
+ get(url, data) {
1071
+ return this.request({ url, method: "GET", data });
927
1072
  }
928
- if (type === "reLaunch") {
929
- uni.reLaunch({ url, fail: onFail });
930
- return;
1073
+ /**
1074
+ * 快捷发送 POST 请求。
1075
+ * @param url 请求相对路径
1076
+ * @param data 请求携带 the body
1077
+ */
1078
+ post(url, data) {
1079
+ return this.request({ url, method: "POST", data });
931
1080
  }
932
- if (type === "miniprogram") {
933
- const openMiniProgram = uni.navigateToMiniProgram;
934
- if (!openMiniProgram) {
935
- fail("当前平台不支持打开小程序", options);
936
- return;
937
- }
938
- openMiniProgram({
939
- appId: url,
940
- path: options.path || "",
941
- envVersion: options.envVersion || "release",
942
- extraData: options.extraData,
943
- fail: onFail
944
- });
945
- return;
1081
+ /**
1082
+ * 快捷发送 PUT 请求。
1083
+ * @param url 请求相对路径
1084
+ * @param data 请求携带 the body
1085
+ */
1086
+ put(url, data) {
1087
+ return this.request({ url, method: "PUT", data });
946
1088
  }
947
- if (type === "webview") {
948
- fail(`H5:${url}`, options);
949
- return;
1089
+ /**
1090
+ * 快捷发送 DELETE 请求。
1091
+ * @param url 请求相对路径
1092
+ * @param data 请求参数
1093
+ */
1094
+ del(url, data) {
1095
+ return this.request({ url, method: "DELETE", data });
950
1096
  }
951
- uni.navigateTo({ url, fail: onFail });
952
1097
  }
953
- function useNavigate() {
954
- return {
955
- /** 核心底层路由分发函数 */
956
- navigate,
957
- /** 保留当前页面,跳转到应用内的某个页面 */
958
- to: (url, options) => navigate("navigateTo", url, options),
959
- /** 关闭当前页面,跳转到应用内的某个页面 */
960
- redirect: (url, options) => navigate("redirectTo", url, options),
961
- /** 跳转到 switchTab 页面,并关闭其他所有非 tabBar 页面 */
962
- tab: (url, options) => navigate("switchTab", url, options),
963
- /** 关闭所有页面,打开到应用内的某个页面 */
964
- reLaunch: (url, options) => navigate("reLaunch", url, options),
965
- /** 关闭当前页面,返回上一页面或多级页面 */
966
- back: (delta = 1, options = {}) => navigate("navigateBack", "", { ...options, delta }),
967
- /** 打开另一个小程序 */
968
- miniProgram: (appId, options) => navigate("miniprogram", appId, options)
1098
+ function ServiceNamespace(value) {
1099
+ return function(target) {
1100
+ target.prototype.namespace = typeof value === "string" ? value : value.namespace;
969
1101
  };
970
1102
  }
971
- const themePresets = [
972
- {
973
- id: "white-theme",
974
- name: "白色主题",
975
- color: "#ffffff"
976
- },
977
- {
978
- id: "light-theme",
979
- name: "简洁主题",
980
- color: "var(--bg-page, #f8f8f8)"
981
- },
982
- {
983
- id: "mono-theme",
984
- name: "单色主题",
985
- color: "var(--primary-color, #3b82f6)"
986
- },
987
- {
988
- id: "color-theme",
989
- name: "颜色主题",
990
- color: "var(--primary-color, #3b82f6)"
991
- }
992
- ];
993
- const fontSizePresets = [
994
- {
995
- id: "small",
996
- name: "较小",
997
- class: "font-size-small"
998
- },
999
- {
1000
- id: "standard",
1001
- name: "标准",
1002
- class: "font-size-standard"
1003
- },
1004
- {
1005
- id: "large",
1006
- name: "较大",
1007
- class: "font-size-large"
1008
- },
1009
- {
1010
- id: "extra-large",
1011
- name: "超大",
1012
- class: "font-size-extra-large"
1013
- }
1014
- ];
1015
- const fontFamilyPresets = [
1016
- {
1017
- id: "system",
1018
- name: "系统默认",
1019
- class: "font-family-system"
1020
- },
1021
- {
1022
- id: "sans",
1023
- name: "现代黑体",
1024
- class: "font-family-sans"
1025
- },
1026
- {
1027
- id: "serif",
1028
- name: "经典宋体",
1029
- class: "font-family-serif"
1030
- },
1031
- {
1032
- id: "kaiti",
1033
- name: "优雅楷体",
1034
- class: "font-family-kaiti"
1035
- }
1036
- ];
1037
- const useThemeStore = defineStore("theme", {
1038
- state: () => ({
1039
- theme: "white-theme",
1040
- fontSize: "standard",
1041
- fontFamily: "system"
1042
- }),
1043
- getters: {},
1044
- actions: {
1045
- setFontSize(size) {
1046
- if (["small", "standard", "large", "extra-large"].includes(size)) {
1047
- this.fontSize = size;
1048
- }
1103
+ function ServicePrefix(value) {
1104
+ return function(target) {
1105
+ target.prototype.servicePrefix = typeof value === "string" ? value : value.prefix;
1106
+ };
1107
+ }
1108
+ function PluginService(target) {
1109
+ Object.defineProperty(target.prototype, "servicePrefix", {
1110
+ get() {
1111
+ return globalThis.VITE_PLUGIN_NAME || "";
1049
1112
  },
1050
- setFontFamily(font) {
1051
- if (["system", "sans", "serif", "kaiti"].includes(font)) {
1052
- this.fontFamily = font;
1053
- }
1054
- }
1055
- },
1056
- unistorage: true
1057
- });
1058
- function useTheme() {
1059
- const store = useThemeStore();
1060
- const theme = computed(() => store.theme);
1061
- const fontSize = computed(() => store.fontSize);
1062
- const fontSizeClass = computed(() => {
1063
- const found = fontSizePresets.find((p) => p.id === store.fontSize);
1064
- return found ? found.class : "font-size-standard";
1065
- });
1066
- const fontFamily = computed(() => store.fontFamily);
1067
- const fontFamilyClass = computed(() => {
1068
- const found = fontFamilyPresets.find((p) => p.id === store.fontFamily);
1069
- return found ? found.class : "font-family-system";
1113
+ enumerable: true,
1114
+ configurable: true
1070
1115
  });
1071
- function setFontSize(size) {
1072
- store.setFontSize(size);
1073
- }
1074
- function setFontFamily(font) {
1075
- store.setFontFamily(font);
1076
- }
1077
- return {
1078
- theme,
1079
- fontSize,
1080
- fontSizeClass,
1081
- setFontSize,
1082
- fontFamily,
1083
- fontFamilyClass,
1084
- setFontFamily,
1085
- store
1086
- };
1087
1116
  }
1088
1117
  let _msg = null;
1089
- let _utils = null;
1090
1118
  const hlw = {
1091
1119
  /** 延迟创建消息提示实例。 */
1092
1120
  get $msg() {
1093
1121
  return _msg ?? (_msg = useMsg());
1094
- },
1095
- /** 延迟读取并缓存设备信息。 */
1096
- get $device() {
1097
- return useDevice().info;
1098
- },
1099
- /** 复用全局请求实例。 */
1100
- $request: useRequest(),
1101
- /** 延迟创建通用工具实例。 */
1102
- get $utils() {
1103
- return _utils ?? (_utils = useUtils());
1104
1122
  }
1105
1123
  };
1106
1124
  let _installed = false;
@@ -1122,7 +1140,7 @@ function useApp() {
1122
1140
  }
1123
1141
  return createApp;
1124
1142
  }
1125
- return { install, use, hlw, request: useRequest() };
1143
+ return { install, use, hlw, request };
1126
1144
  }
1127
1145
  function copyText(data) {
1128
1146
  uni.setClipboardData({
@@ -1168,36 +1186,48 @@ export {
1168
1186
  alistAdapter,
1169
1187
  auth,
1170
1188
  clearDeviceCache,
1189
+ confirmRewardAd,
1171
1190
  copy,
1172
1191
  cosAdapter,
1173
1192
  download,
1174
1193
  fontFamilyPresets,
1175
1194
  fontSizePresets,
1176
1195
  getAdapter,
1196
+ getDevice,
1197
+ getDeviceQuery,
1177
1198
  hlw,
1199
+ initTheme,
1200
+ navigate,
1201
+ navigateBack,
1202
+ navigateTo,
1203
+ navigateToMiniProgram,
1178
1204
  ossAdapter,
1179
1205
  paste,
1180
1206
  qiniuAdapter,
1207
+ reLaunch,
1208
+ redirectTo,
1209
+ request,
1181
1210
  saveImage,
1182
1211
  saveImageUrl,
1183
1212
  saveVideoFile,
1184
1213
  saveVideoUrl,
1214
+ setPopupAd,
1215
+ setRewardAd,
1216
+ showPopupAd,
1217
+ showRewardAd,
1185
1218
  signText,
1219
+ switchTab,
1186
1220
  themePresets,
1187
1221
  toBoolean,
1188
1222
  toNumber,
1189
1223
  toQuery,
1190
1224
  useApp,
1191
- useDevice,
1192
1225
  useHlwAd,
1193
1226
  useMsg,
1194
- useNavigate,
1195
1227
  useRefs,
1196
- useRequest,
1197
1228
  useShare,
1198
1229
  useTheme,
1199
1230
  useUpload,
1200
- useUtils,
1201
1231
  vCopy,
1202
1232
  withQuery
1203
1233
  };