@hlw-uni/mp-vue 2.1.71 → 2.1.97

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