@lambo-design-mobile/lambo-js-bridge 1.0.0-beta.38 → 1.0.0-beta.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.versionrc +23 -23
- package/CHANGELOG.md +395 -388
- package/README.md +523 -523
- package/demo/index.vue +517 -517
- package/index.js +3 -3
- package/package.json +1 -1
- package/src/sdk/BrowserAdapter.js +63 -63
- package/src/sdk/CcworkAdapter.js +80 -80
- package/src/sdk/CordovaAdapter.js +20 -20
- package/src/sdk/DingTalkAdapter.js +20 -20
- package/src/sdk/LPAPI.js +1119 -1119
- package/src/sdk/LamboJsBridge.js +117 -117
- package/src/sdk/MobileIMAdapter.js +127 -127
- package/src/sdk/WeComAdapter.js +648 -576
- package/src/sdk/WechatAdapter.js +430 -342
- package/src/sdk/YunTuAdapter.js +316 -316
- package/src/sdk/yuntu.js +55 -55
package/src/sdk/WeComAdapter.js
CHANGED
|
@@ -1,576 +1,648 @@
|
|
|
1
|
-
/* eslint-disable no-undef */
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
3
|
-
// import * as ww from '@wecom/jssdk'
|
|
4
|
-
import ajax from '@lambo-design-mobile/shared/utils/ajax';
|
|
5
|
-
import config from '@lambo-design-mobile/shared/config/config';
|
|
6
|
-
|
|
7
|
-
class WeComAdapter {
|
|
8
|
-
constructor(_options) {
|
|
9
|
-
this.corpId = _options.weComId; // 保存 appId 以便在 getInitInfo 中使用
|
|
10
|
-
this.agentId = _options.agentId;
|
|
11
|
-
this.isRecording = false;
|
|
12
|
-
// if(!window.wx){
|
|
13
|
-
// // const script = document.createElement('script')
|
|
14
|
-
// // script.src = "//wwcdn.weixin.qq.com/node/open/js/wecom-jssdk-1.3.1.js"
|
|
15
|
-
// // document.head.appendChild(script)
|
|
16
|
-
// const script = document.createElement('script');
|
|
17
|
-
// script.src = "//res.wx.qq.com/open/js/jweixin-1.2.0.js";
|
|
18
|
-
// document.head.appendChild(script);
|
|
19
|
-
// const script1 = document.createElement('script');
|
|
20
|
-
// script1.src = "https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js";
|
|
21
|
-
// document.head.appendChild(script1);
|
|
22
|
-
// }
|
|
23
|
-
// this.init( _options)
|
|
24
|
-
function loadScript(src) {
|
|
25
|
-
return new Promise((resolve, reject) => {
|
|
26
|
-
const script = document.createElement('script');
|
|
27
|
-
script.src = src;
|
|
28
|
-
script.onload = () => resolve(script);
|
|
29
|
-
script.onerror = () => reject(new Error('Failed to load script'));
|
|
30
|
-
document.head.appendChild(script);
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let self = this
|
|
35
|
-
function initJsSdk() {
|
|
36
|
-
loadScript('//res.wx.qq.com/open/js/jweixin-1.2.0.js')
|
|
37
|
-
.then((script) => {
|
|
38
|
-
console.log('Script loaded');
|
|
39
|
-
self.init(_options);
|
|
40
|
-
})
|
|
41
|
-
.catch((err) => console.error(err));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const ua = navigator.userAgent;
|
|
45
|
-
const isiOS = /iPhone|iPad|iPod/i.test(ua);
|
|
46
|
-
const isMiniProgramUA = /miniProgram/i.test(ua);
|
|
47
|
-
const isiOSMiniProgramUA = isiOS && isMiniProgramUA;
|
|
48
|
-
|
|
49
|
-
// iOS 使用的是 WKWebview,其 JavaScript 注入时机与 UIWebview 不同,存在更严格的同步性要求。
|
|
50
|
-
// 如果在你调用 wx.config 时,微信的 JS 桥还没有完全注入到当前 Webview 中,初始化就会失败。
|
|
51
|
-
if (isiOSMiniProgramUA) {
|
|
52
|
-
setTimeout(() => {
|
|
53
|
-
initJsSdk();
|
|
54
|
-
}, 1000);
|
|
55
|
-
} else {
|
|
56
|
-
initJsSdk();
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async init(options) {
|
|
61
|
-
// 在iOS小程序的webview中,currentUrl不能使用动态的,要使用小程序首次打开webview的URL,通过参数传进来
|
|
62
|
-
const currentUrl = encodeURIComponent(window.location.href.split('#')[0]);
|
|
63
|
-
ajax
|
|
64
|
-
.request({
|
|
65
|
-
url:
|
|
66
|
-
config.upmsServerContext +
|
|
67
|
-
'/manage/ibpWxCpBaseinfo/gtJsTicket?corpId=' +
|
|
68
|
-
options.weComId +
|
|
69
|
-
'&agentId=' +
|
|
70
|
-
options.agentId +
|
|
71
|
-
'&url=' +
|
|
72
|
-
(options.currentUrl || currentUrl),
|
|
73
|
-
method: 'get',
|
|
74
|
-
})
|
|
75
|
-
.then((resp) => {
|
|
76
|
-
if (resp.data.code === 1) {
|
|
77
|
-
const { data } = resp.data;
|
|
78
|
-
wx.config({
|
|
79
|
-
beta: true,
|
|
80
|
-
// debug: true,
|
|
81
|
-
appId: data.corpId, // 必填,企业微信的corpid,必须与当前登录的企业一致
|
|
82
|
-
// agentid: '1000065', // 必填,企业微信的应用id (e.g. 1000247)
|
|
83
|
-
timestamp: data.timestamp, // 必填,生成签名的时间戳
|
|
84
|
-
nonceStr: data.noncestr, // 必填,生成签名的随机串
|
|
85
|
-
signature: data.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
|
|
86
|
-
jsApiList: [
|
|
87
|
-
'getLocation',
|
|
88
|
-
'scanQRCode',
|
|
89
|
-
'chooseImage',
|
|
90
|
-
'openLocation',
|
|
91
|
-
'getLocalImgData',
|
|
92
|
-
'startRecord',
|
|
93
|
-
'stopRecord',
|
|
94
|
-
'onVoiceRecordEnd',
|
|
95
|
-
'uploadVoice'
|
|
96
|
-
], // 必填,传入需要使用的接口名称
|
|
97
|
-
success(res) {
|
|
98
|
-
console.log('ready...');
|
|
99
|
-
},
|
|
100
|
-
fail(res) {
|
|
101
|
-
if (res.errMsg.indexOf('function not exist') > -1) {
|
|
102
|
-
alert('版本过低请升级');
|
|
103
|
-
}
|
|
104
|
-
},
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
wx.error(function (res) {
|
|
108
|
-
console.error(res);
|
|
109
|
-
});
|
|
110
|
-
wx.ready(function () {
|
|
111
|
-
console.log('ready.....');
|
|
112
|
-
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
|
|
113
|
-
});
|
|
114
|
-
wx.checkJsApi({
|
|
115
|
-
jsApiList: [
|
|
116
|
-
'getLocation',
|
|
117
|
-
'scanQRCode',
|
|
118
|
-
'chooseImage',
|
|
119
|
-
'openLocation',
|
|
120
|
-
'getLocalImgData',
|
|
121
|
-
'startRecord',
|
|
122
|
-
'stopRecord',
|
|
123
|
-
'onVoiceRecordEnd',
|
|
124
|
-
'uploadVoice',
|
|
125
|
-
], // 需要检测的JS接口列表
|
|
126
|
-
success(res) {
|
|
127
|
-
// 以键值对的形式返回,可用的api值true,不可用为false
|
|
128
|
-
// 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
|
|
129
|
-
},
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
})
|
|
133
|
-
.catch((err) => {
|
|
134
|
-
console.error(err);
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
async startWeComRecording(options = {}) {
|
|
139
|
-
if (this.isRecording) {
|
|
140
|
-
throw new Error('录音已在进行中');
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return new Promise((resolve, reject) => {
|
|
144
|
-
wx.ready(() => {
|
|
145
|
-
wx.onVoiceRecordEnd({
|
|
146
|
-
complete: (res) => {
|
|
147
|
-
if (!this.isRecording) return;
|
|
148
|
-
this.isRecording = false;
|
|
149
|
-
console.log('录音满1分钟自动停止,开始处理...');
|
|
150
|
-
this._uploadAndSave(res.localId)
|
|
151
|
-
.then(fileInfo => {
|
|
152
|
-
if (
|
|
153
|
-
options.onAutoStopSuccess
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
if (
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
|
|
1
|
+
/* eslint-disable no-undef */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
3
|
+
// import * as ww from '@wecom/jssdk'
|
|
4
|
+
import ajax from '@lambo-design-mobile/shared/utils/ajax';
|
|
5
|
+
import config from '@lambo-design-mobile/shared/config/config';
|
|
6
|
+
|
|
7
|
+
class WeComAdapter {
|
|
8
|
+
constructor(_options) {
|
|
9
|
+
this.corpId = _options.weComId; // 保存 appId 以便在 getInitInfo 中使用
|
|
10
|
+
this.agentId = _options.agentId;
|
|
11
|
+
this.isRecording = false;
|
|
12
|
+
// if(!window.wx){
|
|
13
|
+
// // const script = document.createElement('script')
|
|
14
|
+
// // script.src = "//wwcdn.weixin.qq.com/node/open/js/wecom-jssdk-1.3.1.js"
|
|
15
|
+
// // document.head.appendChild(script)
|
|
16
|
+
// const script = document.createElement('script');
|
|
17
|
+
// script.src = "//res.wx.qq.com/open/js/jweixin-1.2.0.js";
|
|
18
|
+
// document.head.appendChild(script);
|
|
19
|
+
// const script1 = document.createElement('script');
|
|
20
|
+
// script1.src = "https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js";
|
|
21
|
+
// document.head.appendChild(script1);
|
|
22
|
+
// }
|
|
23
|
+
// this.init( _options)
|
|
24
|
+
function loadScript(src) {
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const script = document.createElement('script');
|
|
27
|
+
script.src = src;
|
|
28
|
+
script.onload = () => resolve(script);
|
|
29
|
+
script.onerror = () => reject(new Error('Failed to load script'));
|
|
30
|
+
document.head.appendChild(script);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let self = this;
|
|
35
|
+
function initJsSdk() {
|
|
36
|
+
loadScript('//res.wx.qq.com/open/js/jweixin-1.2.0.js')
|
|
37
|
+
.then((script) => {
|
|
38
|
+
console.log('Script loaded');
|
|
39
|
+
self.init(_options);
|
|
40
|
+
})
|
|
41
|
+
.catch((err) => console.error(err));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const ua = navigator.userAgent;
|
|
45
|
+
const isiOS = /iPhone|iPad|iPod/i.test(ua);
|
|
46
|
+
const isMiniProgramUA = /miniProgram/i.test(ua);
|
|
47
|
+
const isiOSMiniProgramUA = isiOS && isMiniProgramUA;
|
|
48
|
+
|
|
49
|
+
// iOS 使用的是 WKWebview,其 JavaScript 注入时机与 UIWebview 不同,存在更严格的同步性要求。
|
|
50
|
+
// 如果在你调用 wx.config 时,微信的 JS 桥还没有完全注入到当前 Webview 中,初始化就会失败。
|
|
51
|
+
if (isiOSMiniProgramUA) {
|
|
52
|
+
setTimeout(() => {
|
|
53
|
+
initJsSdk();
|
|
54
|
+
}, 1000);
|
|
55
|
+
} else {
|
|
56
|
+
initJsSdk();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async init(options) {
|
|
61
|
+
// 在iOS小程序的webview中,currentUrl不能使用动态的,要使用小程序首次打开webview的URL,通过参数传进来
|
|
62
|
+
const currentUrl = encodeURIComponent(window.location.href.split('#')[0]);
|
|
63
|
+
ajax
|
|
64
|
+
.request({
|
|
65
|
+
url:
|
|
66
|
+
config.upmsServerContext +
|
|
67
|
+
'/manage/ibpWxCpBaseinfo/gtJsTicket?corpId=' +
|
|
68
|
+
options.weComId +
|
|
69
|
+
'&agentId=' +
|
|
70
|
+
options.agentId +
|
|
71
|
+
'&url=' +
|
|
72
|
+
(options.currentUrl || currentUrl),
|
|
73
|
+
method: 'get',
|
|
74
|
+
})
|
|
75
|
+
.then((resp) => {
|
|
76
|
+
if (resp.data.code === 1) {
|
|
77
|
+
const { data } = resp.data;
|
|
78
|
+
wx.config({
|
|
79
|
+
beta: true,
|
|
80
|
+
// debug: true,
|
|
81
|
+
appId: data.corpId, // 必填,企业微信的corpid,必须与当前登录的企业一致
|
|
82
|
+
// agentid: '1000065', // 必填,企业微信的应用id (e.g. 1000247)
|
|
83
|
+
timestamp: data.timestamp, // 必填,生成签名的时间戳
|
|
84
|
+
nonceStr: data.noncestr, // 必填,生成签名的随机串
|
|
85
|
+
signature: data.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
|
|
86
|
+
jsApiList: [
|
|
87
|
+
'getLocation',
|
|
88
|
+
'scanQRCode',
|
|
89
|
+
'chooseImage',
|
|
90
|
+
'openLocation',
|
|
91
|
+
'getLocalImgData',
|
|
92
|
+
'startRecord',
|
|
93
|
+
'stopRecord',
|
|
94
|
+
'onVoiceRecordEnd',
|
|
95
|
+
'uploadVoice',
|
|
96
|
+
], // 必填,传入需要使用的接口名称
|
|
97
|
+
success(res) {
|
|
98
|
+
console.log('ready...');
|
|
99
|
+
},
|
|
100
|
+
fail(res) {
|
|
101
|
+
if (res.errMsg.indexOf('function not exist') > -1) {
|
|
102
|
+
alert('版本过低请升级');
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
wx.error(function (res) {
|
|
108
|
+
console.error(res);
|
|
109
|
+
});
|
|
110
|
+
wx.ready(function () {
|
|
111
|
+
console.log('ready.....');
|
|
112
|
+
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
|
|
113
|
+
});
|
|
114
|
+
wx.checkJsApi({
|
|
115
|
+
jsApiList: [
|
|
116
|
+
'getLocation',
|
|
117
|
+
'scanQRCode',
|
|
118
|
+
'chooseImage',
|
|
119
|
+
'openLocation',
|
|
120
|
+
'getLocalImgData',
|
|
121
|
+
'startRecord',
|
|
122
|
+
'stopRecord',
|
|
123
|
+
'onVoiceRecordEnd',
|
|
124
|
+
'uploadVoice',
|
|
125
|
+
], // 需要检测的JS接口列表
|
|
126
|
+
success(res) {
|
|
127
|
+
// 以键值对的形式返回,可用的api值true,不可用为false
|
|
128
|
+
// 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
.catch((err) => {
|
|
134
|
+
console.error(err);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async startWeComRecording(options = {}) {
|
|
139
|
+
if (this.isRecording) {
|
|
140
|
+
throw new Error('录音已在进行中');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return new Promise((resolve, reject) => {
|
|
144
|
+
wx.ready(() => {
|
|
145
|
+
wx.onVoiceRecordEnd({
|
|
146
|
+
complete: (res) => {
|
|
147
|
+
if (!this.isRecording) return;
|
|
148
|
+
this.isRecording = false;
|
|
149
|
+
console.log('录音满1分钟自动停止,开始处理...');
|
|
150
|
+
this._uploadAndSave(res.localId)
|
|
151
|
+
.then((fileInfo) => {
|
|
152
|
+
if (
|
|
153
|
+
options.onAutoStopSuccess &&
|
|
154
|
+
typeof options.onAutoStopSuccess === 'function'
|
|
155
|
+
) {
|
|
156
|
+
options.onAutoStopSuccess(fileInfo);
|
|
157
|
+
}
|
|
158
|
+
})
|
|
159
|
+
.catch((error) => {
|
|
160
|
+
if (
|
|
161
|
+
options.onAutoStopError &&
|
|
162
|
+
typeof options.onAutoStopError === 'function'
|
|
163
|
+
) {
|
|
164
|
+
options.onAutoStopError(error);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
wx.startRecord({
|
|
170
|
+
success: () => {
|
|
171
|
+
this.isRecording = true;
|
|
172
|
+
console.log('录音已开始...');
|
|
173
|
+
resolve();
|
|
174
|
+
},
|
|
175
|
+
fail: (err) => {
|
|
176
|
+
console.error('startRecord failed:', err);
|
|
177
|
+
reject(new Error('开始录音失败'));
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async stopWeComRecording() {
|
|
185
|
+
if (!this.isRecording) {
|
|
186
|
+
return Promise.reject(new Error('当前没有正在进行的录音'));
|
|
187
|
+
}
|
|
188
|
+
return new Promise((resolve, reject) => {
|
|
189
|
+
wx.ready(() => {
|
|
190
|
+
wx.stopRecord({
|
|
191
|
+
success: (res) => {
|
|
192
|
+
this.isRecording = false;
|
|
193
|
+
console.log('用户手动停止录音,开始处理...');
|
|
194
|
+
this._uploadAndSave(res.localId).then(resolve).catch(reject);
|
|
195
|
+
},
|
|
196
|
+
fail: (err) => {
|
|
197
|
+
this.isRecording = false;
|
|
198
|
+
console.error('stopRecord failed:', err);
|
|
199
|
+
reject(new Error('停止录音失败'));
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
async _uploadAndSave(localId) {
|
|
206
|
+
return new Promise((resolve, reject) => {
|
|
207
|
+
wx.uploadVoice({
|
|
208
|
+
localId: localId,
|
|
209
|
+
isShowProgressTips: 1,
|
|
210
|
+
success: (uploadRes) => {
|
|
211
|
+
this._saveVoiceToServer(uploadRes.serverId)
|
|
212
|
+
.then(resolve)
|
|
213
|
+
.catch(reject);
|
|
214
|
+
},
|
|
215
|
+
fail: (err) => {
|
|
216
|
+
console.error('wx.uploadVoice failed:', err);
|
|
217
|
+
reject(new Error('上传语音至微信服务器失败'));
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
async _saveVoiceToServer(serverId) {
|
|
223
|
+
if (!this.corpId || !this.agentId) {
|
|
224
|
+
return Promise.reject(new Error('corpId 或 agentId 未初始化'));
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// 后端接口使用 @RequestParam,对应 'application/x-www-form-urlencoded'
|
|
228
|
+
// const params = new URLSearchParams();
|
|
229
|
+
// params.append('corpId', this.corpId);
|
|
230
|
+
// params.append('agentId', this.agentId);
|
|
231
|
+
// params.append('mediaId', serverId);
|
|
232
|
+
|
|
233
|
+
try {
|
|
234
|
+
const response = await ajax({
|
|
235
|
+
method: 'post',
|
|
236
|
+
url: config.upmsServerContext + '/manage/ibpWxCpBaseinfo/handleVoice',
|
|
237
|
+
data: {
|
|
238
|
+
corpId: this.corpId,
|
|
239
|
+
agentId: this.agentId,
|
|
240
|
+
mediaId: this.serverId,
|
|
241
|
+
},
|
|
242
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
243
|
+
});
|
|
244
|
+
if (response.data && response.data.code === 1) {
|
|
245
|
+
console.log('后端处理成功,返回 FileInfoVO:', response.data.data);
|
|
246
|
+
return response.data.data; // 返回 FileInfoVO 对象
|
|
247
|
+
} else {
|
|
248
|
+
throw new Error(response.data.msg || '服务器处理录音文件失败');
|
|
249
|
+
}
|
|
250
|
+
} catch (err) {
|
|
251
|
+
console.error('调用后端 /handleVoice 接口失败:', err);
|
|
252
|
+
throw err;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* 获取定位
|
|
257
|
+
* 2025-11-28 15:49:23 修改,增加审计日志回调函数auditLog,在不同阶段会调用该回调函数,调用参数如下
|
|
258
|
+
* {
|
|
259
|
+
* seg: 阶段,当前有 beforeCheck、checkError、afterCheck、beforeLocation、successLocation、errorLocation1、errorLocation2
|
|
260
|
+
* title: 对阶段的文字描述
|
|
261
|
+
* }
|
|
262
|
+
* 业务系统有需要对定位进行审计的需求,在调用定位的时候,在options中增加auditLog属性,并根据需要记录所需记录日志的阶段或者全部记录
|
|
263
|
+
* @param {*} options
|
|
264
|
+
* @returns
|
|
265
|
+
*/
|
|
266
|
+
async getLocation(options) {
|
|
267
|
+
return new Promise((resolve, reject) => {
|
|
268
|
+
wx.ready(async () => {
|
|
269
|
+
// 解决在 URL 变化时,由于 wx.config 和 wx.ready 的异步特性导致的微信接口调用使用旧配置、签名失效或调用失败的问题
|
|
270
|
+
// 新增重试机制检查接口可用性
|
|
271
|
+
let retryInterval;
|
|
272
|
+
if (options.auditLog && options.auditLog instanceof Function) {
|
|
273
|
+
options.auditLog({
|
|
274
|
+
seg: 'beforeCheck',
|
|
275
|
+
title: '开始检测企业微信jssdk授权状态',
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
try {
|
|
279
|
+
await new Promise((retryResolve, retryReject) => {
|
|
280
|
+
let retryCount = 0;
|
|
281
|
+
const maxRetries = 30; // 最大重试次数 (30*100ms=3秒超时)
|
|
282
|
+
retryInterval = setInterval(async () => {
|
|
283
|
+
if (retryCount++ >= maxRetries) {
|
|
284
|
+
clearInterval(retryInterval);
|
|
285
|
+
retryReject(new Error('JS-SDK接口初始化超时'));
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// 检查getLocation接口是否可用
|
|
290
|
+
wx.checkJsApi({
|
|
291
|
+
jsApiList: ['getLocation'],
|
|
292
|
+
success: (res) => {
|
|
293
|
+
if (res.checkResult.getLocation === true) {
|
|
294
|
+
clearInterval(retryInterval);
|
|
295
|
+
retryResolve();
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
fail: () => {
|
|
299
|
+
/* 失败不计入重试,继续轮询 */
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
}, 100); // 每100ms检查一次
|
|
303
|
+
});
|
|
304
|
+
} catch (error) {
|
|
305
|
+
if (options.auditLog && options.auditLog instanceof Function) {
|
|
306
|
+
options.auditLog({
|
|
307
|
+
seg: 'checkError',
|
|
308
|
+
title: '检测企业微信jssdk授权状态异常并中止定位',
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
reject(new Error(`接口初始化失败: ${error.message}`));
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (options.auditLog && options.auditLog instanceof Function) {
|
|
316
|
+
options.auditLog({
|
|
317
|
+
seg: 'afterCheck',
|
|
318
|
+
title: '检测企业微信jssdk授权状态结束',
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// 检查 options.type,如果为空或者不含有 'wgs84' 或 'bd09',则设置为 'gcj02'
|
|
323
|
+
let locationType = options.type;
|
|
324
|
+
if (
|
|
325
|
+
!options.type ||
|
|
326
|
+
(options.type !== 'wgs84' && options.type !== 'bd09')
|
|
327
|
+
) {
|
|
328
|
+
locationType = 'gcj02';
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const fetchLocation = (type) => {
|
|
332
|
+
return new Promise((resolve, reject) => {
|
|
333
|
+
if (options.auditLog && options.auditLog instanceof Function) {
|
|
334
|
+
options.auditLog({
|
|
335
|
+
seg: 'beforeLocation',
|
|
336
|
+
title: '企业微信调用jssdk发起定位',
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
wx.getLocation({
|
|
340
|
+
...options,
|
|
341
|
+
type,
|
|
342
|
+
success: (location) => {
|
|
343
|
+
const unifiedLocation = {
|
|
344
|
+
latitude: location.latitude || location.lat || null, // 统一纬度属性
|
|
345
|
+
longitude: location.longitude || location.lng || null, // 统一经度属性
|
|
346
|
+
accuracy: location.accuracy || null, // 精确度,如果有的话
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
if (options.auditLog && options.auditLog instanceof Function) {
|
|
350
|
+
options.auditLog({
|
|
351
|
+
seg: 'successLocation',
|
|
352
|
+
title:
|
|
353
|
+
'企业微信调用jssdk定位成功' +
|
|
354
|
+
JSON.stringify(unifiedLocation),
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (!unifiedLocation.latitude || !unifiedLocation.longitude) {
|
|
359
|
+
if (
|
|
360
|
+
options.auditLog &&
|
|
361
|
+
options.auditLog instanceof Function
|
|
362
|
+
) {
|
|
363
|
+
options.auditLog({
|
|
364
|
+
seg: 'errorLocation1',
|
|
365
|
+
title: '企业微信调用jssdk定位异常,未取到经纬度',
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
return reject(new Error('Invalid location data'));
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
resolve(unifiedLocation);
|
|
372
|
+
},
|
|
373
|
+
fail: (err) => {
|
|
374
|
+
console.error('getLocation failed:', err);
|
|
375
|
+
if (options.auditLog && options.auditLog instanceof Function) {
|
|
376
|
+
options.auditLog({
|
|
377
|
+
seg: 'errorLocation2',
|
|
378
|
+
title: '企业微信调用jssdk定位异常,' + JSON.stringify(err),
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
reject(err);
|
|
382
|
+
},
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
if (locationType === 'bd09') {
|
|
388
|
+
// 先获取 gcj02 坐标
|
|
389
|
+
fetchLocation('gcj02')
|
|
390
|
+
.then((unifiedLocation) => {
|
|
391
|
+
// 将 gcj02 坐标转换为 bd09
|
|
392
|
+
const [bd09Lng, bd09Lat] = coordtransform.gcj02tobd09(
|
|
393
|
+
unifiedLocation.longitude,
|
|
394
|
+
unifiedLocation.latitude
|
|
395
|
+
);
|
|
396
|
+
unifiedLocation.longitude = bd09Lng;
|
|
397
|
+
unifiedLocation.latitude = bd09Lat;
|
|
398
|
+
resolve(unifiedLocation);
|
|
399
|
+
})
|
|
400
|
+
.catch((err) => {
|
|
401
|
+
reject(err);
|
|
402
|
+
});
|
|
403
|
+
} else {
|
|
404
|
+
fetchLocation(locationType).then(resolve).catch(reject);
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
async openLocation(options) {
|
|
411
|
+
return new Promise((resolve, reject) => {
|
|
412
|
+
wx.ready(() => {
|
|
413
|
+
wx.openLocation({
|
|
414
|
+
latitude: options.latitude,
|
|
415
|
+
longitude: options.longitude,
|
|
416
|
+
name: options.name || '',
|
|
417
|
+
address: options.address || '',
|
|
418
|
+
scale: options.scale || 1,
|
|
419
|
+
infoUrl: options.infoUrl || '',
|
|
420
|
+
success: () => {
|
|
421
|
+
console.log('openLocation success');
|
|
422
|
+
resolve();
|
|
423
|
+
},
|
|
424
|
+
fail: (err) => {
|
|
425
|
+
console.error('openLocation failed:', err);
|
|
426
|
+
reject(err);
|
|
427
|
+
},
|
|
428
|
+
});
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
async scanCode(options) {
|
|
434
|
+
return new Promise((resolve, reject) => {
|
|
435
|
+
wx.ready(() => {
|
|
436
|
+
wx.scanQRCode({
|
|
437
|
+
...options,
|
|
438
|
+
needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果
|
|
439
|
+
success: (res) => {
|
|
440
|
+
console.log('scanQRCode success:', res);
|
|
441
|
+
resolve(res); // 当needResult 为 1 时,扫码返回的结果
|
|
442
|
+
},
|
|
443
|
+
fail: (err) => {
|
|
444
|
+
console.error('scanQRCode failed:', err);
|
|
445
|
+
reject(err);
|
|
446
|
+
},
|
|
447
|
+
});
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
async takePhoto(options) {
|
|
453
|
+
return new Promise((resolve, reject) => {
|
|
454
|
+
wx.ready(() => {
|
|
455
|
+
wx.chooseImage({
|
|
456
|
+
...options,
|
|
457
|
+
// count: 1, // 默认9,设置为1表示只选择一张图片
|
|
458
|
+
// sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
|
|
459
|
+
// sourceType: ['camera','album'], // 可以指定来源是相册还是相机,默认二者都有
|
|
460
|
+
success: async (res) => {
|
|
461
|
+
const imageInfo = res.localIds[0]; // 返回选定照片的第一个本地ID
|
|
462
|
+
const results = {};
|
|
463
|
+
|
|
464
|
+
// 检查 outputType 是否为空或不包含 'info', 'data', 'oss' 中的任意一个值
|
|
465
|
+
if (
|
|
466
|
+
!options.outputType ||
|
|
467
|
+
!['info', 'data', 'oss'].some((type) =>
|
|
468
|
+
options.outputType.includes(type)
|
|
469
|
+
)
|
|
470
|
+
) {
|
|
471
|
+
options.outputType = ['info', 'data', 'oss'];
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
if (options.outputType.includes('info')) {
|
|
475
|
+
results.imageInfo = imageInfo;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
if (options.outputType.includes('data')) {
|
|
479
|
+
await new Promise((resolve, reject) => {
|
|
480
|
+
wx.getLocalImgData({
|
|
481
|
+
localId: imageInfo,
|
|
482
|
+
success: (dataRes) => {
|
|
483
|
+
results.imageData = dataRes.localData;
|
|
484
|
+
resolve();
|
|
485
|
+
},
|
|
486
|
+
fail: (err) => {
|
|
487
|
+
console.error('getLocalImgData failed:', err);
|
|
488
|
+
reject(err);
|
|
489
|
+
},
|
|
490
|
+
});
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
if (options.outputType.includes('oss')) {
|
|
495
|
+
await new Promise((resolve, reject) => {
|
|
496
|
+
wx.getLocalImgData({
|
|
497
|
+
localId: imageInfo,
|
|
498
|
+
success: (dataRes) => {
|
|
499
|
+
const fileName = new Date().getTime() + '.png';
|
|
500
|
+
let file;
|
|
501
|
+
if (options.method == 'file') {
|
|
502
|
+
file = this.dataURLtoFile(dataRes.localData, fileName);
|
|
503
|
+
} else {
|
|
504
|
+
file = this.dataUrltoBlob(dataRes.localData, fileName);
|
|
505
|
+
}
|
|
506
|
+
this.uploadToOSS(file, options)
|
|
507
|
+
.then((ossResult) => {
|
|
508
|
+
results.imageOss = ossResult;
|
|
509
|
+
resolve();
|
|
510
|
+
})
|
|
511
|
+
.catch((err) => {
|
|
512
|
+
console.error('uploadToOSS failed:', err);
|
|
513
|
+
reject(err);
|
|
514
|
+
});
|
|
515
|
+
},
|
|
516
|
+
fail: (err) => {
|
|
517
|
+
console.error('getLocalImgData failed:', err);
|
|
518
|
+
reject(err);
|
|
519
|
+
},
|
|
520
|
+
});
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
resolve(results);
|
|
525
|
+
},
|
|
526
|
+
fail: (err) => {
|
|
527
|
+
console.error('chooseImage failed:', err);
|
|
528
|
+
reject(err);
|
|
529
|
+
},
|
|
530
|
+
});
|
|
531
|
+
});
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
dataURLtoFile(dataurl, filename) {
|
|
536
|
+
const arr = dataurl.split(',');
|
|
537
|
+
const mime = arr[0].match(/:(.*?);/)[1];
|
|
538
|
+
const bstr = atob(arr[1]);
|
|
539
|
+
let n = bstr.length;
|
|
540
|
+
const u8arr = new Uint8Array(n);
|
|
541
|
+
while (n--) {
|
|
542
|
+
u8arr[n] = bstr.charCodeAt(n);
|
|
543
|
+
}
|
|
544
|
+
return new File([u8arr], filename, { type: mime });
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
dataUrltoBlob(dataurl, filename) {
|
|
548
|
+
const arr = dataurl.split(',');
|
|
549
|
+
const mime = arr[0].match(/:(.*?);/)[1];
|
|
550
|
+
console.log('base64^^^^^', arr[1]);
|
|
551
|
+
console.log('mime is ^^^^^^^', mime);
|
|
552
|
+
return this.base64ToBlob(arr[1], mime);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
base64ToBlob(base64Data, contentType) {
|
|
556
|
+
contentType = contentType || '';
|
|
557
|
+
const sliceSize = 1024;
|
|
558
|
+
const byteCharacters = atob(base64Data);
|
|
559
|
+
const bytesLength = byteCharacters.length;
|
|
560
|
+
const slicesCount = Math.ceil(bytesLength / sliceSize);
|
|
561
|
+
const byteArrays = new Array(slicesCount);
|
|
562
|
+
|
|
563
|
+
for (let sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
|
|
564
|
+
const begin = sliceIndex * sliceSize;
|
|
565
|
+
const end = Math.min(begin + sliceSize, bytesLength);
|
|
566
|
+
|
|
567
|
+
const bytes = new Array(end - begin);
|
|
568
|
+
for (let offset = begin, i = 0; offset < end; ++i, ++offset) {
|
|
569
|
+
bytes[i] = byteCharacters[offset].charCodeAt(0);
|
|
570
|
+
}
|
|
571
|
+
byteArrays[sliceIndex] = new Uint8Array(bytes);
|
|
572
|
+
}
|
|
573
|
+
return new Blob(byteArrays, { type: contentType });
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
uploadToOSS(file, options) {
|
|
577
|
+
if (options.method == 'file') {
|
|
578
|
+
return new Promise((resolve, reject) => {
|
|
579
|
+
const formData = new FormData();
|
|
580
|
+
formData.append('file', file);
|
|
581
|
+
ajax
|
|
582
|
+
.post(options.ossServerContext + options.ossImgPutUrl, formData, {
|
|
583
|
+
payload: true,
|
|
584
|
+
})
|
|
585
|
+
.then((response) => {
|
|
586
|
+
if (response.data.code === 1) {
|
|
587
|
+
const result = response.data.data;
|
|
588
|
+
if (result.length > 0) {
|
|
589
|
+
resolve(result[0]);
|
|
590
|
+
} else {
|
|
591
|
+
reject(new Error('No fileId returned'));
|
|
592
|
+
}
|
|
593
|
+
} else {
|
|
594
|
+
reject(new Error('Upload failed'));
|
|
595
|
+
}
|
|
596
|
+
})
|
|
597
|
+
.catch((error) => {
|
|
598
|
+
reject(error);
|
|
599
|
+
});
|
|
600
|
+
});
|
|
601
|
+
} else {
|
|
602
|
+
return new Promise((resolve, reject) => {
|
|
603
|
+
let formData = new FormData();
|
|
604
|
+
console.log('upload to oss file is ^^^^', file);
|
|
605
|
+
formData.append(
|
|
606
|
+
'file',
|
|
607
|
+
file,
|
|
608
|
+
file.name || new Date().getTime() + '.png'
|
|
609
|
+
);
|
|
610
|
+
for (var value of formData.values()) {
|
|
611
|
+
console.log('upload to oss data is ^^^^', value);
|
|
612
|
+
}
|
|
613
|
+
ajax({
|
|
614
|
+
method: 'post',
|
|
615
|
+
url: options.ossServerContext + options.ossImgPutUrl,
|
|
616
|
+
headers: { 'Content-Type': 'multipart/form-data' },
|
|
617
|
+
data: formData,
|
|
618
|
+
payload: true,
|
|
619
|
+
})
|
|
620
|
+
.then((response) => {
|
|
621
|
+
if (response.data.code == 1) {
|
|
622
|
+
const result = response.data.data;
|
|
623
|
+
if (result.length > 0) {
|
|
624
|
+
resolve(result[0]);
|
|
625
|
+
} else {
|
|
626
|
+
reject(new Error('No fileId returned'));
|
|
627
|
+
}
|
|
628
|
+
} else {
|
|
629
|
+
reject(new Error('Upload failed'));
|
|
630
|
+
}
|
|
631
|
+
})
|
|
632
|
+
.catch((err) => {
|
|
633
|
+
reject(err);
|
|
634
|
+
});
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
async getPlatform(options = {}) {
|
|
640
|
+
// 获取初始化信息
|
|
641
|
+
return {
|
|
642
|
+
appId: this.corpId,
|
|
643
|
+
platform: 'WeCom',
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
export default WeComAdapter;
|