@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/demo/index.vue CHANGED
@@ -1,517 +1,517 @@
1
- <template>
2
- <demo-section>
3
- <demo-block title="初始化信息">
4
- <pre v-show="initInfo"><code>{{ initInfo }}</code></pre>
5
- </demo-block>
6
- <demo-block title="初始化地图Key">
7
- <van-button @click="initKey">初始化地图Key</van-button>
8
- <pre v-show="initKeyMessage"><code>{{ initKeyMessage }}</code></pre>
9
- </demo-block>
10
- <demo-block title="获取定位">
11
- <van-button @click="getLocation">获取定位</van-button>
12
- <pre v-show="location"><code>{{ location }}</code></pre>
13
- </demo-block>
14
- <demo-block title="扫码">
15
- <van-button @click="scanCode">扫码</van-button>
16
- <pre v-show="scanResult"><code>{{ scanResult }}</code></pre>
17
- </demo-block>
18
- <demo-block title="拍照">
19
- <van-button @click="takePhoto">拍照</van-button>
20
- <pre v-show="photoResult"><code>{{ photoResult }}</code></pre>
21
- <div v-show="photoPreviews.length" :class="gridClass">
22
- <div v-for="(preview, index) in photoPreviews" :key="index" class="photo-container">
23
- <img :src="preview" alt="Photo Preview" class="photo">
24
- </div>
25
- </div>
26
- </demo-block>
27
- <demo-block title="打开位置">
28
- <van-button @click="openLocation">打开位置</van-button>
29
- <pre v-show="openLocationResult"><code>{{ openLocationResult }}</code></pre>
30
- </demo-block>
31
- <demo-block title="文件预览">
32
- <a href="javascript:void(0);" @click="filePreview">点击这里预览文件</a>
33
- </demo-block>
34
- <demo-block title="录音(仅在Flutter环境下可用)">
35
- <van-button @click="startRecording">开始录音</van-button>
36
- <van-button @click="startAutoRecording" style="margin-left: 5px">自动录音</van-button>
37
- <van-button @click="stopRecording" style="margin-left: 5px">停止录音</van-button>
38
- <van-button @click="startWeComRecording" style="margin-left: 5px;">企业微信开始录音</van-button>
39
- <van-button @click="stopWeComRecording" style="margin-left: 5px;">企业微信停止录音</van-button>
40
- <van-button @click="startCcworkRecording" style="margin-left: 5px;">云上协同开始录音</van-button>
41
- <div v-if="recordingStatus === 'recording'">
42
- <p>正在录音中...</p>
43
- </div>
44
- <div v-else-if="recordingStatus === 'not started'">
45
- <p>录音未开始</p>
46
- </div>
47
- <div v-else-if="recordingStatus === 'stopped'">
48
- <p>录音结束</p>
49
- </div>
50
- <div v-else-if="recordingStatus === 'failed'">
51
- <p>录音失败</p>
52
- </div>
53
- <div v-if="audioUrl">
54
- <h3>录音已完成</h3>
55
- <audio :src="audioUrl" controls></audio>
56
- <p>FileUrl:{{ audioUrl }}</p>
57
- <p>FilePath:{{ audioPath }}</p>
58
- <p>FileData:{{ audioData }}</p>
59
- </div>
60
- </demo-block>
61
- <demo-block title="下载">
62
- <van-button @click="downloadFile">下载文件</van-button>
63
- <p v-if="downloadLink">文件已下载,路径:{{ downloadLink }}</p>
64
- </demo-block>
65
- <demo-block title="生物认证">
66
- <div class="auth-buttons">
67
- <van-button @click="localAuth" class="auth-button">生物认证</van-button>
68
- <van-button
69
- @click="getAvailableBiometrics"
70
- class="auth-button"
71
- style="margin-left: 12px"
72
- >
73
- 获取生物特征
74
- </van-button>
75
- </div>
76
-
77
- <div v-if="localAuthResult" class="result-box">
78
- <p class="result-title">认证结果:</p>
79
- <pre><code>{{ localAuthResult }}</code></pre>
80
- </div>
81
-
82
- <div v-if="availableBiometrics" class="result-box">
83
- <p class="result-title">支持的特征:</p>
84
- <pre><code>{{ availableBiometrics }}</code></pre>
85
- </div>
86
- </demo-block>
87
- </demo-section>
88
- </template>
89
-
90
- <script>
91
- import LamboJsBridge from "../src/sdk/LamboJsBridge";
92
- import {PRINTER_PLUGIN} from "../src/sdk/YunTuAdapter";
93
-
94
- export default {
95
- name: 'js-bridge-demo',
96
- data() {
97
- return {
98
- lamboBridge: null,
99
- initInfo: '',
100
- location: '',
101
- scanResult: '',
102
- photoResult: '',
103
- openLocationResult: '', // 添加用于存储打开位置的返回值
104
- latitude: 117.129, // 存储纬度
105
- longitude: 36.662, // 存储经度
106
- ossServerContext: 'ibp-upms-server',
107
- ossImgPutUrl: '/oss/file/put',
108
- ossImgGetUrl: '/oss/file/get/',
109
- scale: 8,
110
- name:'这里是位置名称name',
111
- address:'这里是详细位置address',
112
- wechatId: 'wx92fab9d3885b0298',
113
- weComId: 'wx0eb3ba9d89eca3cb',
114
- agentId:'1000065',
115
- dingTalkId: '',
116
- photoPreviews: [],
117
- initKeyMessage: '', // 用于存储 initKey 的返回消息
118
- recordingWeComStatus: '',
119
- recordingCcWorkStatus: '',
120
- recordingFileInfo: {},
121
- audioUrl: null, // 用于存储录音文件的 URL
122
- audioPath: null,
123
- audioData: null,
124
- recordingStatus: "not started", // 用于记录当前录音状态
125
- downloadLink : null,
126
- localAuthResult: '', // 生物认证结果
127
- availableBiometrics: '' // 支持的生物特征
128
- };
129
- },
130
- computed: {
131
- gridClass() {
132
- const {length} = this.photoPreviews;
133
- if (length === 1) {
134
- return 'grid-single';
135
- } if (length > 1 && length <= 4) {
136
- return 'grid-two';
137
- } if (length > 4) {
138
- return 'grid-three';
139
- }
140
- return '';
141
- }
142
- },
143
- async created() {
144
- const script = document.createElement('script')
145
- script.src = '//dev.sunquan.tech/inspect/target.js'
146
- script.async = true
147
- document.getElementsByTagName('head')[0].appendChild(script)
148
- const options = {
149
- // 初始化参数,根据需要填写
150
- wechatId:this.wechatId,
151
- weComId:this.weComId,
152
- agentId:this.agentId,
153
- dingTalkId:this.dingTalkId,
154
- pluginConfig:["localAuthPlugin","amapPlugin","tabBarPlugin","scanCodePlugin","filePreviewPlugin","autoRecordPlugin","downloadFilePlugin", PRINTER_PLUGIN],
155
- };
156
- this.$lamboJsBridge = new LamboJsBridge(options);
157
- await this.getPlatform();
158
- // await this.$lamboJsBridge.initializePlugin(options.pluginConfig);
159
- },
160
- methods: {
161
- async getPlatform() {
162
- try {
163
- const info = await this.$lamboJsBridge.getPlatform(); // 获取初始化信息
164
- this.initInfo = JSON.stringify(info, null, 2); // 美化输出
165
- console.log('Init Info:', info);
166
- } catch (error) {
167
- console.error('Error getting init info:', error);
168
- }
169
- },
170
-
171
- async startWeComRecording() {
172
- this.recordingWeComStatus = 'processing';
173
- this.recordingFileInfo = null;
174
- try {
175
- await this.$lamboJsBridge.startWeComRecording({
176
- // 当60秒自动停止并成功时:
177
- onAutoStopSuccess: (fileInfo) => {
178
- console.log('【自动停止】处理成功:', fileInfo);
179
- this.recordingFileInfo = fileInfo;
180
- this.recordingWeComStatus = 'done';
181
- },
182
- // 当60秒自动停止但失败时:
183
- onAutoStopError: (error) => {
184
- console.error('【自动停止】处理失败:', error);
185
- this.recordingWeComStatus = 'error';
186
- }
187
- });
188
-
189
- this.recordingWeComStatus = 'recording';
190
-
191
- } catch (error) {
192
- console.error("开始录音失败:", error);
193
- this.recordingWeComStatus = 'error';
194
- }
195
- },
196
-
197
- async stopWeComRecording() {
198
- this.recordingWeComStatus = 'processing';
199
- try {
200
- const fileInfo = await this.$lamboJsBridge.stopWeComRecording();
201
- console.log('【手动停止】处理成功:', fileInfo);
202
- this.recordingFileInfo = fileInfo;
203
- this.recordingWeComStatus = 'done';
204
-
205
- } catch (error) {
206
- console.error('【手动停止】处理失败:', error);
207
- this.recordingWeComStatus = 'error';
208
- }
209
- },
210
-
211
- async startCcworkRecording() {
212
- this.recordingCcWorkStatus = 'processing';
213
- this.recordingFileInfo = null;
214
-
215
- try {
216
- console.log('正在调用 startCcworkRecording...');
217
- const fileInfo = await this.$lamboJsBridge.startCcworkRecording();
218
- console.log('【录音上传】处理成功:', fileInfo);
219
- this.recordingFileInfo = fileInfo;
220
- this.recordingCcWorkStatus = 'done';
221
-
222
- } catch (error) {
223
- console.error('【录音上传】处理失败:', error);
224
- this.recordingCcWorkStatus = 'error';
225
- }
226
- },
227
-
228
- // 开始手动录音
229
- async startRecording() {
230
- // 清空之前的录音数据
231
- this.audioUrl = null;
232
- this.recordingStatus = 'recording';
233
- try {
234
- // 传入 { auto: false } 表示手动录音
235
- const result = await this.$lamboJsBridge.startRecording({ auto: false });
236
- console.log("录音开始成功:", result);
237
- } catch (error) {
238
- console.error("录音开始失败:", error);
239
- this.recordingStatus = 'failed';
240
- }
241
- },
242
-
243
- // 开始自动录音
244
- async startAutoRecording() {
245
- // 清空之前的录音数据
246
- this.audioUrl = null;
247
- this.recordingStatus = 'recording';
248
- try {
249
- // 传入 { auto: true } 表示启用自动录音
250
- const result = await this.$lamboJsBridge.startRecording({ auto: true , silenceDelay: 1, silenceStopSeconds: 2, volumeThreshold: 60});
251
- console.log("自动录音开始成功:", result);
252
- } catch (error) {
253
- console.error("自动录音开始失败:", error);
254
- this.recordingStatus = 'failed';
255
- }
256
- },
257
-
258
- // 停止录音
259
- async stopRecording() {
260
- try {
261
- const result = await this.$lamboJsBridge.stopRecording();
262
- console.log("录音停止成功:", result);
263
- this.recordingStatus = 'stopped';
264
- // 更新录音文件信息
265
- this.audioUrl = result.fileUrl || result.msg;
266
- // 如果你非要用全局函数更新,也可以调用它
267
- this.updateAudioDisplay(result);
268
- } catch (error) {
269
- console.error("录音停止失败:", error);
270
- this.recordingStatus = 'failed';
271
- }
272
- },
273
-
274
- // 如果你希望借助类似全局函数的形式更新页面,可以这样定义:
275
- updateAudioDisplay(data) {
276
- // 更新组件中的数据,页面会自动响应
277
- this.recordingStatus = 'stopped';
278
- this.audioUrl = data.fileUrl;
279
- this.audioPath = data.filePath;
280
- this.audioData = data.fileData;
281
- },
282
-
283
-
284
- async downloadFile(){
285
- try {
286
- const fileUrl = 'http://10.110.34.27/sampleFile.txt'; // 要下载的文件 URL
287
- const fileName = '下载文件.txt'; // 文件名称(建议带上扩展名)
288
- // 注意传递的参数键需与插件内部代码一致:title 和 path
289
- let result = await this.$lamboJsBridge.downloadFile({ title: fileName, path: fileUrl });
290
- console.log('Download initiated, result:', result);
291
-
292
- // 如果返回的数据为字符串,则尝试解析为对象
293
- if (typeof result === 'string') {
294
- try {
295
- result = JSON.parse(result);
296
- } catch (e) {
297
- console.error('解析下载结果失败:', e);
298
- }
299
- }
300
-
301
- // 假设返回的对象中包含 path 属性(如果没有则直接使用 result)
302
- const filePath = result.path || result;
303
- // 更新组件数据,显示文件下载路径
304
- this.downloadLink = filePath;
305
- } catch (error){
306
- console.error('Download failed:', error);
307
- }
308
- },
309
-
310
- async getLocation() {
311
- try {
312
- const options ={
313
- // 初始化参数,根据需要填写
314
- };
315
- const location = await this.$lamboJsBridge.getLocation(options);
316
- console.log("location",location)
317
- this.location += `${JSON.stringify(location)}\n`; // 追加新数据
318
- this.latitude = location.latitude; // 存储纬度
319
- this.longitude = location.longitude; // 存储经度
320
- console.log("this.latitude:",this.latitude);
321
- console.log("this.longitude:",this.longitude);
322
- // console.log('Location:', location);
323
- } catch (error) {
324
- console.error('Error getting location:', error);
325
- }
326
- },
327
- async scanCode() {
328
- try {
329
- const options ={
330
- // 初始化参数,根据需要填写
331
- };
332
- const result = await this.$lamboJsBridge.scanCode(options);
333
- this.scanResult += `${JSON.stringify(result)}\n`; // 追加新数据
334
- // console.log('Scan result:', result);
335
- } catch (error) {
336
- console.error('Error scanning code:', error);
337
- }
338
- },
339
- async takePhoto() {
340
- try {
341
- const options = {
342
- ossServerContext: this.ossServerContext,
343
- ossImgPutUrl: this.ossImgPutUrl,
344
- ossImgGetUrl: this.ossImgGetUrl,
345
- outputType: ['info','data','oss'],
346
- method: 'file',
347
- // sourceType: 'gallery'
348
- };
349
- const photos = await this.$lamboJsBridge.takePhoto(options);
350
- this.photoResult += `${JSON.stringify(photos)}\n`;
351
- console.log("Photo result:", photos); // 调试输出
352
- console.log("oss:",photos.imageOss)
353
-
354
- photos.forEach(photo => {
355
- if (photo.imageOss && photo.imageOss.url) {
356
- this.photoPreviews.push(photo.imageOss.url); // 将图片URL添加到数组中
357
- } else if (photo.imageData) {
358
- this.photoPreviews.push(photo.imageData); // 如果OSS URL不存在,使用本地数据
359
- }
360
- });
361
-
362
- console.log("Updated photoPreviews:", this.photoPreviews); // 调试输出
363
- } catch (error) {
364
- console.error('Error taking photo:', error);
365
- }
366
- },
367
- async openLocation() {
368
- try {
369
- if (this.latitude !== null && this.longitude !== null) {
370
- const options = {
371
- // 初始化参数,根据需要修改
372
- latitude: this.latitude,
373
- longitude: this.longitude,
374
- name: this.name,
375
- address: this.address,
376
- scale: this.scale,
377
- type:"amap"
378
- };
379
- await this.$lamboJsBridge.openLocation(options);
380
- this.openLocationResult = '位置已成功打开'; // 成功打开位置时存储信息
381
- console.log('Location opened successfully');
382
- } else {
383
- this.openLocationResult = '没有可用的位置信息,请先获取定位。'; // 没有位置信息时存储错误信息
384
- console.error('No location data available. Please get the location first.');
385
- }
386
- } catch (error) {
387
- this.openLocationResult = `打开位置时出错: ${error.message}`; // 存储错误信息
388
- console.error('Error opening location:', error);
389
- }
390
- },
391
- async filePreview() {
392
- try {
393
- const options = {
394
- title: '预览文件.txt', // 文件的标题
395
- path: 'http://160.mall.eap.lambo.top/ecm-runtime-server/api/file/get/123456' ,// 文件的URL路径
396
- tokenKey:"lambo-token-ibp"
397
- };
398
- const result = await this.$lamboJsBridge.filePreview(options);
399
- console.log('File preview result:', result);
400
- } catch (error) {
401
- console.error('Error previewing file:', error);
402
- }
403
- },
404
- async initKey() {
405
- try {
406
- const result = await this.$lamboJsBridge.initKey( {"androidKey":"41c4c1f35d8d14f5bf1907c173924147","iosKey":"465abf5da8c8d62e3caa63952a0957a5"});
407
- console.log('initKey result:', result);
408
- this.initKeyMessage = `initKey result: ${JSON.stringify(result)}`;
409
- } catch (error) {
410
- this.initKeyMessage = `初始化 Key 时出错: ${error.message}`;
411
- console.error('Error initializing key:', error);
412
- }
413
- },
414
- async localAuth() {
415
- try {
416
- const options = {
417
- localizedReason: 'A1',
418
- biometricHint: 'A2',
419
- cancelButton: 'A3',
420
- signInTitle: 'A4'
421
- }
422
- const result = await this.$lamboJsBridge.localAuthPlugin(options)
423
- this.localAuthResult = JSON.stringify(result, null, 2)
424
- console.log('localAuthResult:', result);
425
- this.availableBiometrics = '' // 清空另一个结果
426
- } catch (error) {
427
- // 结构化错误处理
428
- const errorMessage = error.msg || error.message || '未知错误';
429
- const authId = error.authId || '未知设备';
430
-
431
- this.localAuthResult = `认证失败:${errorMessage},authId:${authId}`;
432
- console.error('完整错误信息:', error);
433
- }
434
- },
435
- async getAvailableBiometrics() {
436
- try {
437
-
438
- const result = await this.$lamboJsBridge.getAvailableBiometrics()
439
- this.availableBiometrics = JSON.stringify(result, null, 2)
440
- this.localAuthResult = '' // 清空另一个结果
441
- } catch (error) {
442
- this.availableBiometrics = `获取失败: ${error.message}`
443
- }
444
- },
445
- },
446
- mounted() {
447
- window.updateAudioDisplay = this.updateAudioDisplay;
448
- },
449
- beforeRouteEnter (to, from, next) {
450
- next(vm => {
451
- if (from.name !== null) {
452
- vm.$nextTick(() => {
453
- window.location.reload();
454
- });
455
- }
456
- });
457
- }
458
- };
459
- </script>
460
-
461
- <style scoped>
462
- pre {
463
- background-color: #f5f5f5;
464
- padding: 10px;
465
- border-radius: 4px;
466
- overflow: auto;
467
- }
468
-
469
- code {
470
- white-space: pre-wrap;
471
- }
472
-
473
- .grid-single {
474
- display: grid;
475
- grid-template-columns: 1fr;
476
- }
477
-
478
- .grid-two {
479
- display: grid;
480
- grid-template-columns: repeat(2, 1fr);
481
- gap: 10px;
482
- }
483
-
484
- .grid-three {
485
- display: grid;
486
- grid-template-columns: repeat(3, 1fr);
487
- gap: 10px;
488
- }
489
-
490
- .photo-container {
491
- margin-top: 10px;
492
- }
493
-
494
- .photo {
495
- max-width: 100%;
496
- border-radius: 4px;
497
- }
498
- .auth-buttons {
499
- margin-bottom: 16px;
500
- }
501
-
502
- .auth-button {
503
- min-width: 120px;
504
- }
505
-
506
- .result-box {
507
- margin-top: 12px;
508
- border-top: 1px solid #eee;
509
- padding-top: 12px;
510
- }
511
-
512
- .result-title {
513
- color: #666;
514
- font-size: 12px;
515
- margin-bottom: 8px;
516
- }
517
- </style>
1
+ <template>
2
+ <demo-section>
3
+ <demo-block title="初始化信息">
4
+ <pre v-show="initInfo"><code>{{ initInfo }}</code></pre>
5
+ </demo-block>
6
+ <demo-block title="初始化地图Key">
7
+ <van-button @click="initKey">初始化地图Key</van-button>
8
+ <pre v-show="initKeyMessage"><code>{{ initKeyMessage }}</code></pre>
9
+ </demo-block>
10
+ <demo-block title="获取定位">
11
+ <van-button @click="getLocation">获取定位</van-button>
12
+ <pre v-show="location"><code>{{ location }}</code></pre>
13
+ </demo-block>
14
+ <demo-block title="扫码">
15
+ <van-button @click="scanCode">扫码</van-button>
16
+ <pre v-show="scanResult"><code>{{ scanResult }}</code></pre>
17
+ </demo-block>
18
+ <demo-block title="拍照">
19
+ <van-button @click="takePhoto">拍照</van-button>
20
+ <pre v-show="photoResult"><code>{{ photoResult }}</code></pre>
21
+ <div v-show="photoPreviews.length" :class="gridClass">
22
+ <div v-for="(preview, index) in photoPreviews" :key="index" class="photo-container">
23
+ <img :src="preview" alt="Photo Preview" class="photo">
24
+ </div>
25
+ </div>
26
+ </demo-block>
27
+ <demo-block title="打开位置">
28
+ <van-button @click="openLocation">打开位置</van-button>
29
+ <pre v-show="openLocationResult"><code>{{ openLocationResult }}</code></pre>
30
+ </demo-block>
31
+ <demo-block title="文件预览">
32
+ <a href="javascript:void(0);" @click="filePreview">点击这里预览文件</a>
33
+ </demo-block>
34
+ <demo-block title="录音(仅在Flutter环境下可用)">
35
+ <van-button @click="startRecording">开始录音</van-button>
36
+ <van-button @click="startAutoRecording" style="margin-left: 5px">自动录音</van-button>
37
+ <van-button @click="stopRecording" style="margin-left: 5px">停止录音</van-button>
38
+ <van-button @click="startWeComRecording" style="margin-left: 5px;">企业微信开始录音</van-button>
39
+ <van-button @click="stopWeComRecording" style="margin-left: 5px;">企业微信停止录音</van-button>
40
+ <van-button @click="startCcworkRecording" style="margin-left: 5px;">云上协同开始录音</van-button>
41
+ <div v-if="recordingStatus === 'recording'">
42
+ <p>正在录音中...</p>
43
+ </div>
44
+ <div v-else-if="recordingStatus === 'not started'">
45
+ <p>录音未开始</p>
46
+ </div>
47
+ <div v-else-if="recordingStatus === 'stopped'">
48
+ <p>录音结束</p>
49
+ </div>
50
+ <div v-else-if="recordingStatus === 'failed'">
51
+ <p>录音失败</p>
52
+ </div>
53
+ <div v-if="audioUrl">
54
+ <h3>录音已完成</h3>
55
+ <audio :src="audioUrl" controls></audio>
56
+ <p>FileUrl:{{ audioUrl }}</p>
57
+ <p>FilePath:{{ audioPath }}</p>
58
+ <p>FileData:{{ audioData }}</p>
59
+ </div>
60
+ </demo-block>
61
+ <demo-block title="下载">
62
+ <van-button @click="downloadFile">下载文件</van-button>
63
+ <p v-if="downloadLink">文件已下载,路径:{{ downloadLink }}</p>
64
+ </demo-block>
65
+ <demo-block title="生物认证">
66
+ <div class="auth-buttons">
67
+ <van-button @click="localAuth" class="auth-button">生物认证</van-button>
68
+ <van-button
69
+ @click="getAvailableBiometrics"
70
+ class="auth-button"
71
+ style="margin-left: 12px"
72
+ >
73
+ 获取生物特征
74
+ </van-button>
75
+ </div>
76
+
77
+ <div v-if="localAuthResult" class="result-box">
78
+ <p class="result-title">认证结果:</p>
79
+ <pre><code>{{ localAuthResult }}</code></pre>
80
+ </div>
81
+
82
+ <div v-if="availableBiometrics" class="result-box">
83
+ <p class="result-title">支持的特征:</p>
84
+ <pre><code>{{ availableBiometrics }}</code></pre>
85
+ </div>
86
+ </demo-block>
87
+ </demo-section>
88
+ </template>
89
+
90
+ <script>
91
+ import LamboJsBridge from "../src/sdk/LamboJsBridge";
92
+ import {PRINTER_PLUGIN} from "../src/sdk/YunTuAdapter";
93
+
94
+ export default {
95
+ name: 'js-bridge-demo',
96
+ data() {
97
+ return {
98
+ lamboBridge: null,
99
+ initInfo: '',
100
+ location: '',
101
+ scanResult: '',
102
+ photoResult: '',
103
+ openLocationResult: '', // 添加用于存储打开位置的返回值
104
+ latitude: 117.129, // 存储纬度
105
+ longitude: 36.662, // 存储经度
106
+ ossServerContext: 'ibp-upms-server',
107
+ ossImgPutUrl: '/oss/file/put',
108
+ ossImgGetUrl: '/oss/file/get/',
109
+ scale: 8,
110
+ name:'这里是位置名称name',
111
+ address:'这里是详细位置address',
112
+ wechatId: 'wx92fab9d3885b0298',
113
+ weComId: 'wx0eb3ba9d89eca3cb',
114
+ agentId:'1000065',
115
+ dingTalkId: '',
116
+ photoPreviews: [],
117
+ initKeyMessage: '', // 用于存储 initKey 的返回消息
118
+ recordingWeComStatus: '',
119
+ recordingCcWorkStatus: '',
120
+ recordingFileInfo: {},
121
+ audioUrl: null, // 用于存储录音文件的 URL
122
+ audioPath: null,
123
+ audioData: null,
124
+ recordingStatus: "not started", // 用于记录当前录音状态
125
+ downloadLink : null,
126
+ localAuthResult: '', // 生物认证结果
127
+ availableBiometrics: '' // 支持的生物特征
128
+ };
129
+ },
130
+ computed: {
131
+ gridClass() {
132
+ const {length} = this.photoPreviews;
133
+ if (length === 1) {
134
+ return 'grid-single';
135
+ } if (length > 1 && length <= 4) {
136
+ return 'grid-two';
137
+ } if (length > 4) {
138
+ return 'grid-three';
139
+ }
140
+ return '';
141
+ }
142
+ },
143
+ async created() {
144
+ const script = document.createElement('script')
145
+ script.src = '//dev.sunquan.tech/inspect/target.js'
146
+ script.async = true
147
+ document.getElementsByTagName('head')[0].appendChild(script)
148
+ const options = {
149
+ // 初始化参数,根据需要填写
150
+ wechatId:this.wechatId,
151
+ weComId:this.weComId,
152
+ agentId:this.agentId,
153
+ dingTalkId:this.dingTalkId,
154
+ pluginConfig:["localAuthPlugin","amapPlugin","tabBarPlugin","scanCodePlugin","filePreviewPlugin","autoRecordPlugin","downloadFilePlugin", PRINTER_PLUGIN],
155
+ };
156
+ this.$lamboJsBridge = new LamboJsBridge(options);
157
+ await this.getPlatform();
158
+ // await this.$lamboJsBridge.initializePlugin(options.pluginConfig);
159
+ },
160
+ methods: {
161
+ async getPlatform() {
162
+ try {
163
+ const info = await this.$lamboJsBridge.getPlatform(); // 获取初始化信息
164
+ this.initInfo = JSON.stringify(info, null, 2); // 美化输出
165
+ console.log('Init Info:', info);
166
+ } catch (error) {
167
+ console.error('Error getting init info:', error);
168
+ }
169
+ },
170
+
171
+ async startWeComRecording() {
172
+ this.recordingWeComStatus = 'processing';
173
+ this.recordingFileInfo = null;
174
+ try {
175
+ await this.$lamboJsBridge.startWeComRecording({
176
+ // 当60秒自动停止并成功时:
177
+ onAutoStopSuccess: (fileInfo) => {
178
+ console.log('【自动停止】处理成功:', fileInfo);
179
+ this.recordingFileInfo = fileInfo;
180
+ this.recordingWeComStatus = 'done';
181
+ },
182
+ // 当60秒自动停止但失败时:
183
+ onAutoStopError: (error) => {
184
+ console.error('【自动停止】处理失败:', error);
185
+ this.recordingWeComStatus = 'error';
186
+ }
187
+ });
188
+
189
+ this.recordingWeComStatus = 'recording';
190
+
191
+ } catch (error) {
192
+ console.error("开始录音失败:", error);
193
+ this.recordingWeComStatus = 'error';
194
+ }
195
+ },
196
+
197
+ async stopWeComRecording() {
198
+ this.recordingWeComStatus = 'processing';
199
+ try {
200
+ const fileInfo = await this.$lamboJsBridge.stopWeComRecording();
201
+ console.log('【手动停止】处理成功:', fileInfo);
202
+ this.recordingFileInfo = fileInfo;
203
+ this.recordingWeComStatus = 'done';
204
+
205
+ } catch (error) {
206
+ console.error('【手动停止】处理失败:', error);
207
+ this.recordingWeComStatus = 'error';
208
+ }
209
+ },
210
+
211
+ async startCcworkRecording() {
212
+ this.recordingCcWorkStatus = 'processing';
213
+ this.recordingFileInfo = null;
214
+
215
+ try {
216
+ console.log('正在调用 startCcworkRecording...');
217
+ const fileInfo = await this.$lamboJsBridge.startCcworkRecording();
218
+ console.log('【录音上传】处理成功:', fileInfo);
219
+ this.recordingFileInfo = fileInfo;
220
+ this.recordingCcWorkStatus = 'done';
221
+
222
+ } catch (error) {
223
+ console.error('【录音上传】处理失败:', error);
224
+ this.recordingCcWorkStatus = 'error';
225
+ }
226
+ },
227
+
228
+ // 开始手动录音
229
+ async startRecording() {
230
+ // 清空之前的录音数据
231
+ this.audioUrl = null;
232
+ this.recordingStatus = 'recording';
233
+ try {
234
+ // 传入 { auto: false } 表示手动录音
235
+ const result = await this.$lamboJsBridge.startRecording({ auto: false });
236
+ console.log("录音开始成功:", result);
237
+ } catch (error) {
238
+ console.error("录音开始失败:", error);
239
+ this.recordingStatus = 'failed';
240
+ }
241
+ },
242
+
243
+ // 开始自动录音
244
+ async startAutoRecording() {
245
+ // 清空之前的录音数据
246
+ this.audioUrl = null;
247
+ this.recordingStatus = 'recording';
248
+ try {
249
+ // 传入 { auto: true } 表示启用自动录音
250
+ const result = await this.$lamboJsBridge.startRecording({ auto: true , silenceDelay: 1, silenceStopSeconds: 2, volumeThreshold: 60});
251
+ console.log("自动录音开始成功:", result);
252
+ } catch (error) {
253
+ console.error("自动录音开始失败:", error);
254
+ this.recordingStatus = 'failed';
255
+ }
256
+ },
257
+
258
+ // 停止录音
259
+ async stopRecording() {
260
+ try {
261
+ const result = await this.$lamboJsBridge.stopRecording();
262
+ console.log("录音停止成功:", result);
263
+ this.recordingStatus = 'stopped';
264
+ // 更新录音文件信息
265
+ this.audioUrl = result.fileUrl || result.msg;
266
+ // 如果你非要用全局函数更新,也可以调用它
267
+ this.updateAudioDisplay(result);
268
+ } catch (error) {
269
+ console.error("录音停止失败:", error);
270
+ this.recordingStatus = 'failed';
271
+ }
272
+ },
273
+
274
+ // 如果你希望借助类似全局函数的形式更新页面,可以这样定义:
275
+ updateAudioDisplay(data) {
276
+ // 更新组件中的数据,页面会自动响应
277
+ this.recordingStatus = 'stopped';
278
+ this.audioUrl = data.fileUrl;
279
+ this.audioPath = data.filePath;
280
+ this.audioData = data.fileData;
281
+ },
282
+
283
+
284
+ async downloadFile(){
285
+ try {
286
+ const fileUrl = 'http://10.110.34.27/sampleFile.txt'; // 要下载的文件 URL
287
+ const fileName = '下载文件.txt'; // 文件名称(建议带上扩展名)
288
+ // 注意传递的参数键需与插件内部代码一致:title 和 path
289
+ let result = await this.$lamboJsBridge.downloadFile({ title: fileName, path: fileUrl });
290
+ console.log('Download initiated, result:', result);
291
+
292
+ // 如果返回的数据为字符串,则尝试解析为对象
293
+ if (typeof result === 'string') {
294
+ try {
295
+ result = JSON.parse(result);
296
+ } catch (e) {
297
+ console.error('解析下载结果失败:', e);
298
+ }
299
+ }
300
+
301
+ // 假设返回的对象中包含 path 属性(如果没有则直接使用 result)
302
+ const filePath = result.path || result;
303
+ // 更新组件数据,显示文件下载路径
304
+ this.downloadLink = filePath;
305
+ } catch (error){
306
+ console.error('Download failed:', error);
307
+ }
308
+ },
309
+
310
+ async getLocation() {
311
+ try {
312
+ const options ={
313
+ // 初始化参数,根据需要填写
314
+ };
315
+ const location = await this.$lamboJsBridge.getLocation(options);
316
+ console.log("location",location)
317
+ this.location += `${JSON.stringify(location)}\n`; // 追加新数据
318
+ this.latitude = location.latitude; // 存储纬度
319
+ this.longitude = location.longitude; // 存储经度
320
+ console.log("this.latitude:",this.latitude);
321
+ console.log("this.longitude:",this.longitude);
322
+ // console.log('Location:', location);
323
+ } catch (error) {
324
+ console.error('Error getting location:', error);
325
+ }
326
+ },
327
+ async scanCode() {
328
+ try {
329
+ const options ={
330
+ // 初始化参数,根据需要填写
331
+ };
332
+ const result = await this.$lamboJsBridge.scanCode(options);
333
+ this.scanResult += `${JSON.stringify(result)}\n`; // 追加新数据
334
+ // console.log('Scan result:', result);
335
+ } catch (error) {
336
+ console.error('Error scanning code:', error);
337
+ }
338
+ },
339
+ async takePhoto() {
340
+ try {
341
+ const options = {
342
+ ossServerContext: this.ossServerContext,
343
+ ossImgPutUrl: this.ossImgPutUrl,
344
+ ossImgGetUrl: this.ossImgGetUrl,
345
+ outputType: ['info','data','oss'],
346
+ method: 'file',
347
+ // sourceType: 'gallery'
348
+ };
349
+ const photos = await this.$lamboJsBridge.takePhoto(options);
350
+ this.photoResult += `${JSON.stringify(photos)}\n`;
351
+ console.log("Photo result:", photos); // 调试输出
352
+ console.log("oss:",photos.imageOss)
353
+
354
+ photos.forEach(photo => {
355
+ if (photo.imageOss && photo.imageOss.url) {
356
+ this.photoPreviews.push(photo.imageOss.url); // 将图片URL添加到数组中
357
+ } else if (photo.imageData) {
358
+ this.photoPreviews.push(photo.imageData); // 如果OSS URL不存在,使用本地数据
359
+ }
360
+ });
361
+
362
+ console.log("Updated photoPreviews:", this.photoPreviews); // 调试输出
363
+ } catch (error) {
364
+ console.error('Error taking photo:', error);
365
+ }
366
+ },
367
+ async openLocation() {
368
+ try {
369
+ if (this.latitude !== null && this.longitude !== null) {
370
+ const options = {
371
+ // 初始化参数,根据需要修改
372
+ latitude: this.latitude,
373
+ longitude: this.longitude,
374
+ name: this.name,
375
+ address: this.address,
376
+ scale: this.scale,
377
+ type:"amap"
378
+ };
379
+ await this.$lamboJsBridge.openLocation(options);
380
+ this.openLocationResult = '位置已成功打开'; // 成功打开位置时存储信息
381
+ console.log('Location opened successfully');
382
+ } else {
383
+ this.openLocationResult = '没有可用的位置信息,请先获取定位。'; // 没有位置信息时存储错误信息
384
+ console.error('No location data available. Please get the location first.');
385
+ }
386
+ } catch (error) {
387
+ this.openLocationResult = `打开位置时出错: ${error.message}`; // 存储错误信息
388
+ console.error('Error opening location:', error);
389
+ }
390
+ },
391
+ async filePreview() {
392
+ try {
393
+ const options = {
394
+ title: '预览文件.txt', // 文件的标题
395
+ path: 'http://160.mall.eap.lambo.top/ecm-runtime-server/api/file/get/123456' ,// 文件的URL路径
396
+ tokenKey:"lambo-token-ibp"
397
+ };
398
+ const result = await this.$lamboJsBridge.filePreview(options);
399
+ console.log('File preview result:', result);
400
+ } catch (error) {
401
+ console.error('Error previewing file:', error);
402
+ }
403
+ },
404
+ async initKey() {
405
+ try {
406
+ const result = await this.$lamboJsBridge.initKey( {"androidKey":"41c4c1f35d8d14f5bf1907c173924147","iosKey":"465abf5da8c8d62e3caa63952a0957a5"});
407
+ console.log('initKey result:', result);
408
+ this.initKeyMessage = `initKey result: ${JSON.stringify(result)}`;
409
+ } catch (error) {
410
+ this.initKeyMessage = `初始化 Key 时出错: ${error.message}`;
411
+ console.error('Error initializing key:', error);
412
+ }
413
+ },
414
+ async localAuth() {
415
+ try {
416
+ const options = {
417
+ localizedReason: 'A1',
418
+ biometricHint: 'A2',
419
+ cancelButton: 'A3',
420
+ signInTitle: 'A4'
421
+ }
422
+ const result = await this.$lamboJsBridge.localAuthPlugin(options)
423
+ this.localAuthResult = JSON.stringify(result, null, 2)
424
+ console.log('localAuthResult:', result);
425
+ this.availableBiometrics = '' // 清空另一个结果
426
+ } catch (error) {
427
+ // 结构化错误处理
428
+ const errorMessage = error.msg || error.message || '未知错误';
429
+ const authId = error.authId || '未知设备';
430
+
431
+ this.localAuthResult = `认证失败:${errorMessage},authId:${authId}`;
432
+ console.error('完整错误信息:', error);
433
+ }
434
+ },
435
+ async getAvailableBiometrics() {
436
+ try {
437
+
438
+ const result = await this.$lamboJsBridge.getAvailableBiometrics()
439
+ this.availableBiometrics = JSON.stringify(result, null, 2)
440
+ this.localAuthResult = '' // 清空另一个结果
441
+ } catch (error) {
442
+ this.availableBiometrics = `获取失败: ${error.message}`
443
+ }
444
+ },
445
+ },
446
+ mounted() {
447
+ window.updateAudioDisplay = this.updateAudioDisplay;
448
+ },
449
+ beforeRouteEnter (to, from, next) {
450
+ next(vm => {
451
+ if (from.name !== null) {
452
+ vm.$nextTick(() => {
453
+ window.location.reload();
454
+ });
455
+ }
456
+ });
457
+ }
458
+ };
459
+ </script>
460
+
461
+ <style scoped>
462
+ pre {
463
+ background-color: #f5f5f5;
464
+ padding: 10px;
465
+ border-radius: 4px;
466
+ overflow: auto;
467
+ }
468
+
469
+ code {
470
+ white-space: pre-wrap;
471
+ }
472
+
473
+ .grid-single {
474
+ display: grid;
475
+ grid-template-columns: 1fr;
476
+ }
477
+
478
+ .grid-two {
479
+ display: grid;
480
+ grid-template-columns: repeat(2, 1fr);
481
+ gap: 10px;
482
+ }
483
+
484
+ .grid-three {
485
+ display: grid;
486
+ grid-template-columns: repeat(3, 1fr);
487
+ gap: 10px;
488
+ }
489
+
490
+ .photo-container {
491
+ margin-top: 10px;
492
+ }
493
+
494
+ .photo {
495
+ max-width: 100%;
496
+ border-radius: 4px;
497
+ }
498
+ .auth-buttons {
499
+ margin-bottom: 16px;
500
+ }
501
+
502
+ .auth-button {
503
+ min-width: 120px;
504
+ }
505
+
506
+ .result-box {
507
+ margin-top: 12px;
508
+ border-top: 1px solid #eee;
509
+ padding-top: 12px;
510
+ }
511
+
512
+ .result-title {
513
+ color: #666;
514
+ font-size: 12px;
515
+ margin-bottom: 8px;
516
+ }
517
+ </style>