sur-onlyoffice 1.0.2 → 1.0.4

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.
@@ -0,0 +1,1157 @@
1
+ <template>
2
+ <div class="onlyoffice-box" >
3
+ <header v-if="false" style="padding:8px;border-bottom:1px solid #eee;display:flex;gap:8px;align-items:center;flex-wrap:wrap;">
4
+ <strong>ONLYOFFICE Vue3 Demo</strong>
5
+ <button @click="insertText" style="background:#007bff;color:#fff;border:none;padding:6px 12px;border-radius:4px;">插入文字</button>
6
+ <button @click="insertLink" style="background:#1e88e5;color:#fff;border:none;padding:6px 12px;border-radius:4px;">
7
+ 插入链接
8
+ </button>
9
+
10
+ <!-- WordArt 按钮组 -->
11
+ <div style="display:flex;gap:4px;border-left:1px solid #ddd;padding-left:8px;">
12
+ <button @click="insertCustomWordArt" style="background:#4caf50;color:#fff;border:none;padding:6px 12px;border-radius:4px;">
13
+ 自定义WordArt
14
+ </button>
15
+ <button @click="insertClassicWordArt" style="background:#ff9800;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
16
+ 经典
17
+ </button>
18
+ <button @click="insertModernWordArt" style="background:#673ab7;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
19
+ 现代
20
+ </button>
21
+ <button @click="insertFunWordArt" style="background:#e91e63;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
22
+ 趣味
23
+ </button>
24
+ </div>
25
+
26
+ <!-- Shape 测试按钮 -->
27
+
28
+
29
+ <!-- Table 按钮组 -->
30
+ <div style="display:flex;gap:4px;border-left:1px solid #ddd;padding-left:8px;">
31
+ <button @click="insertSimpleTable" style="background:#8bc34a;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
32
+ 简单表格
33
+ </button>
34
+ <button @click="insertScheduleTable" style="background:#4caf50;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
35
+ 课程表
36
+ </button>
37
+ <button @click="insertComparisonTable" style="background:#66bb6a;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
38
+ 对比表
39
+ </button>
40
+ <button @click="insertCustomTable" style="background:#388e3c;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
41
+ 自定义
42
+ </button>
43
+ <button @click="insertDynamicTable" style="background:#2e7d32;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
44
+ 动态数据
45
+ </button>
46
+ </div>
47
+
48
+ <!-- Selection Binding 按钮组 -->
49
+ <div style="display:flex;gap:4px;border-left:1px solid #ddd;padding-left:8px;">
50
+ <button @click="analyzeSelection" style="background:#6a1b9a;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
51
+ 分析选中
52
+ </button>
53
+ <button @click="bindAsTextField" style="background:#7b1fa2;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
54
+ 绑定文本
55
+ </button>
56
+ <button @click="bindAsVariable" style="background:#8e24aa;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
57
+ 绑定变量
58
+ </button>
59
+ <button @click="bindAsDataSource" style="background:#9c27b0;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
60
+ 绑定数据源
61
+ </button>
62
+ </div>
63
+
64
+ <!-- Chart Binding 按钮组 - 新增 -->
65
+ <div style="display:flex;gap:4px;border-left:1px solid #ddd;padding-left:8px;">
66
+ <button @click="bindChartData" style="background:#e65100;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
67
+ 绑定图表数据
68
+ </button>
69
+ <button @click="getChartSummary" style="background:#ff6f00;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
70
+ 图表摘要
71
+ </button>
72
+ <button @click="testChartDetection" style="background:#ff8f00;color:#fff;border:none;padding:6px 8px;border-radius:4px;">
73
+ 测试检测
74
+ </button>
75
+ </div>
76
+
77
+ <span :style="{marginLeft:'auto', color: pluginReady ? '#28a745' : '#999'}">
78
+ {{ pluginReady ? '插件已就绪' : '等待插件就绪…' }}
79
+ </span>
80
+ </header>
81
+
82
+ <div id="editor" style="flex:1;"></div>
83
+ </div>
84
+ </template>
85
+
86
+ <script setup lang="ts">
87
+ import { onMounted, onBeforeUnmount, ref } from 'vue'
88
+
89
+ let editor: any = null
90
+ const pluginReady = ref(false)
91
+
92
+ // === 按你的环境修改 ===
93
+ // const DOCUMENT_SERVER = 'http://192.168.1.103:9998'
94
+ const DOCUMENT_SERVER = 'https://test.xuandou.vip:126'
95
+ // const DOCUMENT_SERVER = 'https://prev.xuandou.vip:126'
96
+ //const DOCUMENT_SERVER = 'http://222.187.11.98:8918'
97
+ const DOCS_API = DOCUMENT_SERVER + '/web-apps/apps/api/documents/api.js'
98
+ const FILE_URL = 'https://badges-1302420147.cos.ap-shanghai.myqcloud.com/test1.docx'
99
+ // https://badges-1302420147.cos.ap-shanghai.myqcloud.com/test1.docx
100
+ // 插件 GUID(需与插件 config.json 一致)
101
+ //9.0.4-9ade76efaf7465c8db6be392804370a8
102
+ //http://222.187.11.98:8918/8.3.3-5dd8d105cac84554276dfe74dce59789/web-apps/apps/documenteditor/main/index.html?_dc=8.3.3-18&lang=zh-CN&customer=ONLYOFFICE&type=desktop&frameEditorId=editor&isForm=false&parentOrigin=http://localhost:5174&fileType=docx
103
+ // http://192.168.1.103:9998/9.0.4-870a82e9bc8b96c4c53877e589326856/web-apps/apps/documenteditor/main/index.html?_dc=9.0.4-50&lang=zh-CN&customer=ONLYOFFICE&type=desktop&frameEditorId=editor&isForm=false&parentOrigin=http://localhost:5174&fileType=docx
104
+
105
+ //! 111
106
+ // const PLUGIN_GUID = 'asc.{0616AE85-5DBE-4B6B-A0A9-455C4F1503AD}'
107
+ // 插件 config.json(必须可 200 直连)
108
+ // const PLUGIN_CONF = DOCUMENT_SERVER + '/8.3.1-10ca0f5dd35a63800b6a3956f350bf95/sdkjs-plugins/helloworld/config.json'
109
+
110
+ //! 222
111
+ // const PLUGIN_GUID = 'asc.{6A1D2E30-1B7D-4A87-A2D7-4F3BB8A3C9E1}'
112
+ // const PLUGIN_CONF = DOCUMENT_SERVER + '/8.3.1-10ca0f5dd35a63800b6a3956f350bf95/sdkjs-plugins/onlyoffice-plugin/config.json'
113
+
114
+ //! 333 test
115
+ const PLUGIN_GUID = 'asc.{91EAC419-EF8B-440C-A960-B451C7DF3A37}'
116
+ const PLUGIN_CONF = DOCUMENT_SERVER + '/8.3.1-10ca0f5dd35a63800b6a3956f350bf95/sdkjs-plugins/example_extended_comments/config.json'
117
+
118
+
119
+ //! 444
120
+ // const PLUGIN_GUID = 'asc.{89643394-0F74-4297-9E0B-541A67F1E98C}'
121
+ // const PLUGIN_CONF = DOCUMENT_SERVER + '/8.3.1-10ca0f5dd35a63800b6a3956f350bf95/sdkjs-plugins/example_add_comment_in_cell/config.json'
122
+
123
+
124
+
125
+ //! 333 preview
126
+ // const PLUGIN_GUID = 'asc.{91EAC419-EF8B-440C-A960-B451C7DF3A37}'
127
+ // const PLUGIN_CONF = DOCUMENT_SERVER + '/8.3.3-903fa321b0e16c3ec855c98c81f29d78/sdkjs-plugins/example_extended_comments/config.json'
128
+
129
+
130
+
131
+ // ---- 动态加载 api.js ----
132
+ function loadDocsApi(): Promise<void> {
133
+ return new Promise((resolve, reject) => {
134
+ if ((window as any).DocsAPI) return resolve()
135
+ const script = document.createElement('script')
136
+ script.src = DOCS_API
137
+ script.onload = () => resolve()
138
+ script.onerror = () => reject(new Error('加载 DocsAPI 失败:' + DOCS_API))
139
+ document.head.appendChild(script)
140
+ })
141
+ }
142
+
143
+ // ---- 命令发送:带队列 + 重试,确保等插件就绪 ----
144
+ type Cmd = { cmd: string; payload: any }
145
+ const queue: Cmd[] = []
146
+ let flushTimer: number | null = null
147
+
148
+ function serviceCommandSafe(cmd: string, payload: any) {
149
+ // 未加载好编辑器
150
+ if (!editor || typeof editor.serviceCommand !== 'function') {
151
+ console.warn('[ONLYOFFICE] editor/serviceCommand 未就绪,先入队:', cmd, payload)
152
+ queue.push({ cmd, payload })
153
+ return
154
+ }
155
+ // 插件未就绪:排队等待
156
+ if (!pluginReady.value) {
157
+ console.log('[ONLYOFFICE] 插件未就绪,先入队:', cmd, payload)
158
+ queue.push({ cmd, payload })
159
+ scheduleFlush()
160
+ return
161
+ }
162
+ try {
163
+ if (typeof editor.executeCommand === 'function') {
164
+ editor.executeCommand('focus');
165
+ }
166
+ // 让浏览器完成一次光标同步,然后再发命令
167
+ setTimeout(() => editor.serviceCommand(cmd, payload), 0);
168
+ } catch (e) {
169
+ console.error('[ONLYOFFICE] serviceCommand 调用失败:', e)
170
+ }
171
+ }
172
+
173
+ function scheduleFlush() {
174
+ if (flushTimer !== null) return
175
+ flushTimer = window.setInterval(() => {
176
+ if (!editor || typeof editor.serviceCommand !== 'function') return
177
+ if (!pluginReady.value) return
178
+ // 开始出队
179
+ while (queue.length) {
180
+ const { cmd, payload } = queue.shift()!
181
+ try {
182
+ console.log('[ONLYOFFICE] 发送排队指令:', cmd, payload)
183
+ editor.serviceCommand(cmd, payload)
184
+ } catch (e) {
185
+ console.error('[ONLYOFFICE] 队列指令发送失败:', cmd, e)
186
+ }
187
+ }
188
+ if (flushTimer !== null) {
189
+ clearInterval(flushTimer)
190
+ flushTimer = null
191
+ }
192
+ }, 300)
193
+ }
194
+
195
+ // ---- 创建编辑器 ----
196
+ async function createEditor() {
197
+ await loadDocsApi()
198
+ // @ts-ignore
199
+ const DocsAPI = (window as any).DocsAPI
200
+
201
+ if (editor?.destroyEditor) editor.destroyEditor()
202
+ pluginReady.value = false
203
+
204
+ const cfg = {
205
+ document: {
206
+ fileType: 'docx',
207
+ title: 'Demo.docx',
208
+ url: FILE_URL,
209
+ key: 'test-key',
210
+ permissions: { edit: true }
211
+ },
212
+ documentType: 'word',
213
+ editorConfig: {
214
+ lang: 'zh-CN',
215
+ mode: 'edit',
216
+ user: { id: 'u1', name: 'Tester' },
217
+ plugins: {
218
+ //!
219
+ autostart: [PLUGIN_GUID],
220
+ pluginsData: [{ url: PLUGIN_CONF + '?v=2.0.' + Date.now() }] // 强刷缓存
221
+ },
222
+ },
223
+ width: '100%',
224
+ height: '100%',
225
+ events: {
226
+ onPluginsReady: () => {
227
+ console.log('[ONLYOFFICE] 插件资源已加载,但不代表已初始化');
228
+ },
229
+ onDocumentReady: () => {
230
+ console.log('[ONLYOFFICE] 文档已就绪')
231
+ // 有些插件会很快 ready,这里安排一次队列尝试
232
+ autoOpenPluginSidePanel();
233
+ scheduleFlush();
234
+
235
+ console.log('window.Asc.plugin1',window?.Asc?.plugin)
236
+
237
+ setTimeout(()=>{
238
+ console.log('window.Asc.plugin2',window)
239
+ console.log('window.Asc.plugin3-editor',editor.serviceCommand)
240
+
241
+ editor.serviceCommand('event_onAddComment', {id:111})
242
+
243
+
244
+ },2000)
245
+ },
246
+ onInfo: (e: any) => {
247
+ const msg = e?.data;
248
+ console.log('[ONLYOFFICE] Info 事件:', e.data)
249
+ if (!e) return
250
+ if (msg?.command === 'openPlugin') {
251
+ console.log('[ONLYOFFICE] openPlugin')
252
+ // 这里再把消息转发给 DS 内部,让它真的打开 UI 面板
253
+ editor.frame?.contentWindow?.Common?.Gateway?.sendInfo(msg);
254
+ }
255
+ if (e.data.command === 'pluginInitialized') {
256
+ pluginReady.value = true
257
+ console.log('[ONLYOFFICE] 插件初始化完成')
258
+ scheduleFlush()
259
+ }
260
+ if (e.data .command === 'pluginAck') {
261
+ console.log('[ONLYOFFICE] 插件确认收到:', e.data)
262
+ }
263
+ if (e.data.command === 'pluginError') {
264
+ console.error('[ONLYOFFICE] 插件错误:', e.data)
265
+ }
266
+ if (e.data.command === 'linkClicked') {
267
+ console.log('[ONLYOFFICE] 链接被点击,数据:', e.data.data)
268
+ handleLinkClick(e.data.data)
269
+ }
270
+ if (e.data.command === 'wordArtInserted') {
271
+ console.log('[ONLYOFFICE] WordArt 插入成功:', e.data.data)
272
+ handleWordArtInserted(e.data.data)
273
+ }
274
+ if (e.data.command === 'wordArtError') {
275
+ console.error('[ONLYOFFICE] WordArt 插入失败:', e.data.data)
276
+ handleWordArtError(e.data.data)
277
+ }
278
+ if (e.data.command === 'tableClicked') {
279
+ console.log('[ONLYOFFICE] 表格被点击,数据:', e.data.data)
280
+ handleTableClick(e.data.data)
281
+ }
282
+ if (e.data.command === 'selectionAnalyzed') {
283
+ console.log('[ONLYOFFICE] 选中内容分析结果:', e.data.data)
284
+ handleSelectionAnalyzed(e.data.data)
285
+ }
286
+ if (e.data.command === 'selectionBound') {
287
+ console.log('[ONLYOFFICE] 选中内容绑定完成:', e.data.data)
288
+ handleSelectionBound(e.data.data)
289
+ }
290
+ if (e.data.command === 'bindingClicked') {
291
+ console.log('[ONLYOFFICE] 绑定控件被点击:', e.data.data)
292
+ handleBindingClicked(e.data.data)
293
+ }
294
+ // 通用元素检测事件 - 新增
295
+ if (e.data.command === 'elementClicked') {
296
+ console.log('[ONLYOFFICE] 元素被点击:', e.data.data)
297
+ handleElementClicked(e.data.data)
298
+ }
299
+ // 精确表格单元格检测事件 - 新增
300
+ if (e.data.command === 'preciseTableCellClicked') {
301
+ console.log('[ONLYOFFICE] 精确表格单元格被点击:', e.data.data)
302
+ handlePreciseTableCellClicked(e.data.data)
303
+ }
304
+ // 图表点击检测事件 - 新增
305
+ if (e.data.command === 'chartClicked') {
306
+ console.log('[ONLYOFFICE] 图表被点击:', e.data.data)
307
+ handleChartClicked(e.data.data)
308
+ }
309
+ }
310
+ }
311
+ }
312
+
313
+ editor = new DocsAPI.DocEditor('editor', cfg)
314
+
315
+
316
+ window.addEventListener('message', (event) => {
317
+ // 安全检查:验证消息来源
318
+ // if (event.origin !== 'https://iframe-domain.com') return;
319
+
320
+
321
+ console.log(event,'event123')
322
+
323
+ if (event.data.eventType === 'customEventReplay') {
324
+ console.info(event,'DDD1')
325
+ }
326
+
327
+ if (event.data.eventType === 'customEventCommon') {
328
+ console.info(event,'DDD2')
329
+ }
330
+ });
331
+ }
332
+
333
+ function autoOpenPluginSidePanel() {
334
+ try {
335
+ editor.executeCommand && editor.executeCommand('focus');
336
+
337
+ console.log('123autoOpenPluginSidePanel',editor)
338
+
339
+ // 先收起左侧面板
340
+ // editor.frame?.contentWindow?.Common?.UI?.SidePanel?.hide?.();
341
+
342
+ // 或者使用命令收起
343
+ // editor.frame?.contentWindow?.Common?.Gateway?.sendInfo?.({
344
+ // command: 'toggleSidePanel',
345
+ // data: { visible: false }
346
+ // });
347
+
348
+ // editor.serviceCommand('toggleSidePanel', { visible: false });
349
+
350
+ editor.serviceCommand && editor.serviceCommand('sidePanel', {
351
+ action: 'toggle',
352
+ state: false
353
+ });
354
+
355
+ //!!!! 通过你现有的 Gateway 让 WebApp 打开插件(指令名按你那边实现)
356
+ // editor.frame?.contentWindow?.Common?.Gateway?.sendInfo?.({
357
+ // command: 'openPlugin',
358
+ // data: {
359
+ // // guid: 'asc.{91EAC419-EF8B-440C-A960-B451C7DF3A37}',
360
+ // // variation: 'side panel'
361
+ // }
362
+ // });
363
+
364
+
365
+ } catch(e) { console.error('auto-open plugin failed:', e); }
366
+ }
367
+
368
+ // ---- 按钮动作(发指令到插件)----
369
+ function insertText() {
370
+ serviceCommandSafe('insertText', '【外部插入的文字】')
371
+ }
372
+ function insertLink() {
373
+ // 例1:空链接占位(后续再填 URL)
374
+ serviceCommandSafe('insertLink', {
375
+ text: '点击这里', // 显示文字
376
+ url: '', // 允许为空;插件端会用 about:blank 占位+打Tag
377
+ bold: true, // 加粗
378
+ underline: false, // 建议加下划线
379
+ color: '#1976D2', // 蓝色(可换)
380
+ json:{name:'gm'}
381
+ });
382
+ }
383
+
384
+ // ---- WordArt 相关功能 ----
385
+ function insertCustomWordArt() {
386
+ // 自定义 WordArt 参数
387
+ serviceCommandSafe('insertWordArt', {
388
+ text: 'ONLYOFFICE',
389
+ fontSize: 36,
390
+ bold: true,
391
+ caps: true,
392
+ fontFamily: 'Arial Black',
393
+ textColor: [255, 255, 255], // 白色文字
394
+ fillColor: [76, 175, 80], // 绿色填充
395
+ strokeColor: [46, 125, 50], // 深绿色描边
396
+ strokeWidth: 2,
397
+ transform: 'textArchUp', // 拱形向上
398
+ width: 180,
399
+ height: 60,
400
+ rotation: 0
401
+ });
402
+ }
403
+
404
+ function insertClassicWordArt() {
405
+ serviceCommandSafe('insertPresetWordArt', {
406
+ preset: 'classic',
407
+ text: 'CLASSIC'
408
+ });
409
+ }
410
+
411
+ function insertModernWordArt() {
412
+ serviceCommandSafe('insertPresetWordArt', {
413
+ preset: 'modern',
414
+ text: 'MODERN'
415
+ });
416
+ }
417
+
418
+ function insertFunWordArt() {
419
+ serviceCommandSafe('insertPresetWordArt', {
420
+ preset: 'fun',
421
+ text: 'FUN!'
422
+ });
423
+ }
424
+
425
+ // ---- Shape 测试功能 ----
426
+ function testShapeInline() {
427
+ console.log('开始测试Shape内联插入可能性...');
428
+ serviceCommandSafe('testShapeInline', {});
429
+ }
430
+
431
+ // ---- Shape 内联插入功能 ----
432
+ function insertRectangleInline() {
433
+ serviceCommandSafe('insertShapeParagraph', {
434
+ shapeType: 'rect',
435
+ width: 80,
436
+ height: 40,
437
+ fillColor: [33, 150, 243], // 蓝色
438
+ strokeColor: [13, 71, 161],
439
+ strokeWidth: 1,
440
+ text: '矩形'
441
+ });
442
+ }
443
+
444
+ function insertCircleInline() {
445
+ serviceCommandSafe('insertShapeParagraph', {
446
+ shapeType: 'ellipse',
447
+ width: 60,
448
+ height: 60,
449
+ fillColor: [76, 175, 80], // 绿色
450
+ strokeColor: [46, 125, 50],
451
+ strokeWidth: 1,
452
+ text: '圆形'
453
+ });
454
+ }
455
+
456
+ function insertTriangleInline() {
457
+ serviceCommandSafe('insertShapeParagraph', {
458
+ shapeType: 'triangle',
459
+ width: 70,
460
+ height: 60,
461
+ fillColor: [255, 152, 0], // 橙色
462
+ strokeColor: [230, 81, 0],
463
+ strokeWidth: 1,
464
+ text: '三角'
465
+ });
466
+ }
467
+
468
+ // ---- Table 表格插入功能 ----
469
+ function insertSimpleTable() {
470
+ serviceCommandSafe('insertPresetTable', {
471
+ preset: 'simple'
472
+ });
473
+ }
474
+
475
+ function insertScheduleTable() {
476
+ serviceCommandSafe('insertPresetTable', {
477
+ preset: 'schedule'
478
+ });
479
+ }
480
+
481
+ function insertComparisonTable() {
482
+ serviceCommandSafe('insertPresetTable', {
483
+ preset: 'comparison'
484
+ });
485
+ }
486
+
487
+ function insertCustomTable() {
488
+ serviceCommandSafe('insertTable', {
489
+ rows: 4,
490
+ columns: 5,
491
+ widthType: 'percent',
492
+ width: 100,
493
+ headers: ['项目', 'Q1', 'Q2', 'Q3', 'Q4'],
494
+ data: [
495
+ ['销售额', '100万', '120万', '130万', '150万'],
496
+ ['利润', '20万', '25万', '28万', '35万'],
497
+ ['增长率', '10%', '20%', '8%', '15%']
498
+ ]
499
+ });
500
+ }
501
+
502
+ function insertDynamicTable() {
503
+ // 模拟从系统获取动态数据
504
+ const dynamicData = generateBusinessData();
505
+ serviceCommandSafe('insertDynamicTable', dynamicData);
506
+ }
507
+
508
+ // 模拟业务系统数据生成
509
+ function generateBusinessData() {
510
+ const products = ['iPhone 15', 'Samsung S24', 'Xiaomi 14', 'OPPO Find X7', 'vivo X100'];
511
+ const months = ['1月', '2月', '3月', '4月', '5月', '6月'];
512
+
513
+ const headers = ['产品', ...months, '总计'];
514
+ const data = [];
515
+
516
+ products.forEach(product => {
517
+ const row = [product];
518
+ let total = 0;
519
+
520
+ // 生成随机销量数据
521
+ for (let i = 0; i < 6; i++) {
522
+ const sales = Math.floor(Math.random() * 1000) + 500;
523
+ row.push(sales.toString());
524
+ total += sales;
525
+ }
526
+ row.push(total.toString());
527
+ data.push(row);
528
+ });
529
+
530
+ // 添加合计行
531
+ const totalRow = ['合计'];
532
+ for (let i = 1; i < headers.length; i++) {
533
+ const columnTotal = data.reduce((sum, row) => sum + parseInt(row[i]), 0);
534
+ totalRow.push(columnTotal.toString());
535
+ }
536
+ data.push(totalRow);
537
+
538
+ return {
539
+ title: '产品销量统计表',
540
+ headers,
541
+ data,
542
+ metadata: {
543
+ generatedAt: new Date().toLocaleString('zh-CN'),
544
+ dataSource: 'ERP系统',
545
+ category: '销售报表'
546
+ },
547
+ styling: {
548
+ headerStyle: 'bold',
549
+ totalRowStyle: 'bold',
550
+ alternateRowColors: true
551
+ }
552
+ };
553
+ }
554
+
555
+ // ---- Chart Binding 图表绑定功能 - 新增 ----
556
+
557
+ // 绑定图表数据
558
+ function bindChartData() {
559
+ const chartData = generateSampleChartData();
560
+ serviceCommandSafe('bindChartData', chartData);
561
+ }
562
+
563
+ // 获取图表绑定摘要
564
+ function getChartSummary() {
565
+ serviceCommandSafe('getChartSummary', {});
566
+ }
567
+
568
+ // 测试图表检测
569
+ function testChartDetection() {
570
+ serviceCommandSafe('chartClicked', {});
571
+ }
572
+
573
+ // 生成示例图表数据
574
+ function generateSampleChartData() {
575
+ return {
576
+ data: {
577
+ title: '销售趋势图11111',
578
+ type: 'line-chart',
579
+ dataSource: 'ERP系统',
580
+ category: '销售分析',
581
+ period: '2024年第一季度',
582
+ metrics: {
583
+ totalSales: 1250000,
584
+ growthRate: 15.8,
585
+ topProduct: 'iPhone 15',
586
+ targetAchievement: 125
587
+ },
588
+ series: [
589
+ { name: '销售额', data: [120000, 135000, 128000, 142000] },
590
+ { name: '目标', data: [125000, 130000, 135000, 140000] }
591
+ ],
592
+ categories: ['1月', '2月', '3月', '4月']
593
+ },
594
+ metadata: {
595
+ bindingId: 'chart_' + Date.now(),
596
+ boundAt: new Date().toISOString(),
597
+ dataVersion: '1.0',
598
+ refreshInterval: 3600, // 秒
599
+ lastUpdated: new Date().toLocaleString('zh-CN'),
600
+ permissions: {
601
+ canEdit: true,
602
+ canRefresh: true,
603
+ canExport: true
604
+ }
605
+ }
606
+ };
607
+ }
608
+
609
+ // 分析选中内容
610
+ function analyzeSelection() {
611
+ serviceCommandSafe('analyzeSelection', {});
612
+ }
613
+
614
+ // 绑定为文本字段
615
+ function bindAsTextField() {
616
+ const fieldName = prompt('请输入字段名称:', 'customer_name') || 'text_field';
617
+ serviceCommandSafe('bindSelection', {
618
+ type: 'text-field',
619
+ fieldName: fieldName,
620
+ dataType: 'text',
621
+ category: 'data-field',
622
+ metadata: {
623
+ rid: 'field_' + Date.now(),
624
+ tag: '{name:' + fieldName + '}',
625
+ originalText: '',
626
+ insertedAt: new Date().toISOString(),
627
+ metricType: 'text'
628
+ }
629
+ });
630
+ }
631
+
632
+ // 绑定为模板变量
633
+ function bindAsVariable() {
634
+ const varName = prompt('请输入变量名称:', 'my_variable') || 'custom_var';
635
+ serviceCommandSafe('bindSelection', {
636
+ type: 'template-variable',
637
+ fieldName: varName,
638
+ category: 'template',
639
+ metadata: {
640
+ variable: varName
641
+ }
642
+ });
643
+ }
644
+
645
+ // 绑定为数据源
646
+ function bindAsDataSource() {
647
+ const sourceName = prompt('请输入数据源名称:', 'data_table') || 'data_source';
648
+ serviceCommandSafe('bindSelection', {
649
+ type: 'table-data-source',
650
+ fieldName: sourceName,
651
+ category: 'data-binding'
652
+ });
653
+ }
654
+
655
+ // 处理链接点击事件
656
+ function handleLinkClick(data: any) {
657
+ console.log('处理链接点击事件,收到数据:', data)
658
+
659
+ if (data && typeof data === 'object') {
660
+ // 显示详细的控件信息和数据
661
+ const info = `链接控件被点击!
662
+
663
+ 控件ID: ${data.controlId || 'unknown'}
664
+ 控件标题: ${data.controlTitle || '无标题'}
665
+ 控件Tag: ${data.tag || '无Tag'}
666
+
667
+ 绑定数据:
668
+ ${JSON.stringify(data.data, null, 2)}
669
+
670
+ 完整信息:
671
+ ${JSON.stringify(data, null, 2)}`;
672
+
673
+ // alert(info);
674
+
675
+ // 你可以根据数据执行相应的操作
676
+ // 例如:打开弹窗、跳转页面、发送请求等
677
+ if (data.data && data.data.name) {
678
+ console.log('检测到用户名:', data.data.name);
679
+ }
680
+ }
681
+ }
682
+
683
+ // 处理 WordArt 插入成功事件
684
+ function handleWordArtInserted(data: any) {
685
+ console.log('WordArt 插入成功,数据:', data)
686
+
687
+ if (data && data.success) {
688
+ // 显示成功信息
689
+ const info = `WordArt 插入成功!
690
+
691
+ 文本: ${data.parameters?.text || '未知'}
692
+ 字体大小: ${data.parameters?.fontSize || '未知'}
693
+ 字体: ${data.parameters?.fontFamily || '未知'}
694
+ 变换效果: ${data.parameters?.transform || '未知'}
695
+
696
+ ${data.message || ''}`;
697
+
698
+ // 使用更友好的通知方式
699
+ if (confirm(info + '\n\n点击"确定"可继续插入更多WordArt')) {
700
+ // 可以打开WordArt配置面板或其他操作
701
+ console.log('用户选择继续操作WordArt')
702
+ }
703
+ }
704
+ }
705
+
706
+ // 处理 WordArt 插入错误事件
707
+ function handleWordArtError(data: any) {
708
+ console.error('WordArt 插入失败,错误:', data)
709
+
710
+ const errorMsg = data?.error || '未知错误'
711
+ const info = `WordArt 插入失败!
712
+
713
+ 错误信息: ${errorMsg}
714
+
715
+ 可能的原因:
716
+ - 当前位置不支持插入WordArt
717
+ - API参数错误
718
+ - OnlyOffice版本不支持WordArt功能
719
+
720
+ 请检查控制台获取详细错误信息。`;
721
+
722
+ // alert(info);
723
+ }
724
+
725
+
726
+ // 处理表格点击事件
727
+ function handleTableClick(data: any) {
728
+ console.log('处理表格点击事件,收到数据:', data)
729
+
730
+ if (data && data.success && data.data) {
731
+ const tableInfo = data.data;
732
+
733
+ // 显示详细的表格信息
734
+ let info = `表格被点击!\n\n`;
735
+
736
+ if (tableInfo.clickType === 'table') {
737
+ info += `点击类型: 表格内容\n`;
738
+ info += `表格索引: ${tableInfo.tableIndex >= 0 ? tableInfo.tableIndex : '未知'}\n`;
739
+ info += `行索引: ${tableInfo.rowIndex >= 0 ? tableInfo.rowIndex : '未知'}\n`;
740
+ info += `单元格索引: ${tableInfo.cellIndex >= 0 ? tableInfo.cellIndex : '未知'}\n`;
741
+ info += `单元格文本: "${tableInfo.cellText || '空'}"\n`;
742
+ info += `点击时间: ${tableInfo.timestamp}\n`;
743
+
744
+ if (tableInfo.tableData) {
745
+ info += `\n表格数据结构:\n`;
746
+ info += `- 行数: ${tableInfo.tableData.rows}\n`;
747
+ info += `- 列数: ${tableInfo.tableData.columns}\n`;
748
+
749
+ if (tableInfo.tableData.content && tableInfo.tableData.content.length > 0) {
750
+ info += `\n表格内容预览:\n`;
751
+ tableInfo.tableData.content.slice(0, 3).forEach((row: any[], rowIndex: number) => {
752
+ info += `第${rowIndex + 1}行: [${row.join(', ')}]\n`;
753
+ });
754
+ if (tableInfo.tableData.content.length > 3) {
755
+ info += `... 还有 ${tableInfo.tableData.content.length - 3} 行\n`;
756
+ }
757
+ }
758
+ }
759
+ } else {
760
+ info += `点击类型: 非表格区域\n`;
761
+ info += `点击时间: ${tableInfo.timestamp}\n`;
762
+ }
763
+
764
+ // alert(info);
765
+
766
+ // 你可以根据表格数据执行相应的操作
767
+ // 例如:显示表格编辑面板、发送数据到服务器等
768
+ if (tableInfo.clickType === 'table' && tableInfo.tableData) {
769
+ console.log('检测到表格点击,可以执行相关操作:', {
770
+ tableIndex: tableInfo.tableIndex,
771
+ tableData: tableInfo.tableData
772
+ });
773
+ }
774
+ } else {
775
+ console.log('表格点击检测失败:', data?.error || '未知错误');
776
+ // alert(`表格点击检测失败: ${data?.error || '未知错误'}`);
777
+ }
778
+ }
779
+
780
+ // 处理选中内容分析结果
781
+ function handleSelectionAnalyzed(data: any) {
782
+ console.log('处理选中内容分析结果,收到数据:', data)
783
+
784
+ if (data && data.success && data.data) {
785
+ const selectionInfo = data.data;
786
+
787
+ let info = `选中内容分析结果!\n\n`;
788
+ info += `选择类型: ${selectionInfo.selectionType}\n`;
789
+ info += `是否可绑定: ${selectionInfo.bindable ? '是' : '否'}\n`;
790
+ info += `选中内容: "${selectionInfo.content.substring(0, 50)}${selectionInfo.content.length > 50 ? '...' : ''}"\n\n`;
791
+
792
+ if (selectionInfo.suggestedBindings && selectionInfo.suggestedBindings.length > 0) {
793
+ info += `建议的绑定方式:\n`;
794
+ selectionInfo.suggestedBindings.slice(0, 3).forEach((binding: any, index: number) => {
795
+ info += `${index + 1}. ${binding.description} (${binding.category})\n`;
796
+ });
797
+
798
+ if (selectionInfo.suggestedBindings.length > 3) {
799
+ info += `... 还有 ${selectionInfo.suggestedBindings.length - 3} 种绑定方式\n`;
800
+ }
801
+ }
802
+
803
+ info += `\n分析时间: ${selectionInfo.timestamp}`;
804
+
805
+ // alert(info);
806
+
807
+ // 可以根据分析结果执行后续操作
808
+ if (selectionInfo.bindable) {
809
+ console.log('内容可以绑定,建议绑定方式:', selectionInfo.suggestedBindings);
810
+ }
811
+ } else {
812
+ console.log('选中内容分析失败:', data?.error || '未知错误');
813
+ // alert(`选中内容分析失败: ${data?.error || '未知错误'}`);
814
+ }
815
+ }
816
+
817
+ // 处理选中内容绑定完成
818
+ function handleSelectionBound(data: any) {
819
+ console.log('处理选中内容绑定完成,收到数据:', data)
820
+
821
+ if (data && data.success) {
822
+ const bindingInfo = data.data;
823
+
824
+ let info = `数据绑定完成!\n\n`;
825
+ info += `绑定方法: ${bindingInfo.method}\n`;
826
+ info += `绑定类型: ${bindingInfo.binding?.type || '未知'}\n`;
827
+
828
+ if (bindingInfo.binding) {
829
+ if (bindingInfo.binding.fieldName) {
830
+ info += `字段名称: ${bindingInfo.binding.fieldName}\n`;
831
+ }
832
+ if (bindingInfo.binding.dataType) {
833
+ info += `数据类型: ${bindingInfo.binding.dataType}\n`;
834
+ }
835
+ if (bindingInfo.binding.originalValue) {
836
+ info += `原始值: "${bindingInfo.binding.originalValue}"\n`;
837
+ }
838
+ }
839
+
840
+ info += `\n${bindingInfo.message}`;
841
+
842
+ // alert(info);
843
+
844
+ console.log('数据绑定成功,绑定信息:', bindingInfo.binding);
845
+ } else {
846
+ console.log('数据绑定失败:', data?.error || '未知错误');
847
+ // alert(`数据绑定失败: ${data?.error || '未知错误'}`);
848
+ }
849
+ }
850
+
851
+ // 处理通用元素检测事件 - 新增
852
+ function handleElementClicked(data: any) {
853
+ console.log('🎯 处理通用元素点击事件,收到数据:', data)
854
+
855
+ if (data && data.success && data.data) {
856
+ const elementInfo = data.data;
857
+
858
+ let info = `🎯 元素点击检测结果!\n\n`;
859
+ info += `点击类型: ${elementInfo.clickType}\n`;
860
+ info += `检测时间: ${elementInfo.timestamp}\n\n`;
861
+
862
+ // 根据不同元素类型显示详细信息
863
+ if (elementInfo.clickType === 'table') {
864
+ info += `📊 表格信息:\n`;
865
+ info += `- 表格索引: ${elementInfo.elementInfo.tableIndex}\n`;
866
+ info += `- 总行数: ${elementInfo.elementInfo.totalRows}\n`;
867
+ info += `- 总列数: ${elementInfo.elementInfo.totalColumns}\n`;
868
+
869
+ if (elementInfo.elementInfo.clickedCell) {
870
+ info += `- 点击位置: 第${elementInfo.elementInfo.clickedCell.row}行第${elementInfo.elementInfo.clickedCell.column}列\n`;
871
+ info += `- 单元格内容: "${elementInfo.elementInfo.clickedCellInfo?.content || '空'}"\n`;
872
+ }
873
+
874
+ if (elementInfo.elementInfo.sampleContent && elementInfo.elementInfo.sampleContent.length > 0) {
875
+ info += `\n📋 表格内容预览:\n`;
876
+ elementInfo.elementInfo.sampleContent.slice(0, 2).forEach((row: any[], index: number) => {
877
+ info += `第${index + 1}行: [${row.slice(0, 3).join(', ')}${row.length > 3 ? '...' : ''}]\n`;
878
+ });
879
+ }
880
+
881
+ } else if (elementInfo.clickType === 'paragraph') {
882
+ info += `📝 段落信息:\n`;
883
+ info += `- 段落索引: ${elementInfo.elementInfo.paragraphIndex}\n`;
884
+ info += `- 对齐方式: ${elementInfo.elementInfo.alignment}\n`;
885
+ info += `- 文本长度: ${elementInfo.elementInfo.metadata?.fullTextLength || 0}字符\n`;
886
+ info += `- 文本预览: "${elementInfo.elementInfo.text}"\n`;
887
+
888
+ } else if (elementInfo.clickType === 'shape') {
889
+ info += `🔷 图形信息:\n`;
890
+ info += `- 图形索引: ${elementInfo.elementInfo.shapeIndex}\n`;
891
+ info += `- 图形类型: ${elementInfo.elementInfo.shapeType}\n`;
892
+ info += `- 包含内容: ${elementInfo.elementInfo.hasContent ? '是' : '否'}\n`;
893
+
894
+ } else if (elementInfo.clickType === 'document') {
895
+ info += `📄 文档区域:\n`;
896
+ info += `- 有选区: ${elementInfo.elementInfo.hasSelection ? '是' : '否'}\n`;
897
+ info += `- 扫描元素: ${elementInfo.elementInfo.metadata?.totalElementsScanned || 0}个\n`;
898
+ }
899
+
900
+ // 显示扫描统计
901
+ if (elementInfo.fullScanResults) {
902
+ info += `\n🔍 文档扫描统计:\n`;
903
+ info += `- 表格: ${elementInfo.fullScanResults.tablesFound}个\n`;
904
+ info += `- 段落: ${elementInfo.fullScanResults.paragraphsFound}个\n`;
905
+ info += `- 图形: ${elementInfo.fullScanResults.shapesFound}个\n`;
906
+ }
907
+
908
+ // alert(info);
909
+
910
+ // 可以根据元素类型执行不同的操作
911
+ console.log('🎯 元素类型:', elementInfo.clickType, '详细信息:', elementInfo.elementInfo);
912
+
913
+ } else {
914
+ console.log('❌ 通用元素检测失败:', data?.error || '未知错误');
915
+ // 不显示失败的alert,避免过多弹窗
916
+ }
917
+ }
918
+
919
+ // 处理精确表格单元格检测事件 - 新增
920
+ function handlePreciseTableCellClicked(data: any) {
921
+ console.log('📊 处理精确表格单元格点击事件,收到数据:', data)
922
+
923
+ if (data && data.success && data.data) {
924
+ const cellInfo = data.data;
925
+
926
+ let info = `📊 精确表格单元格点击!\n\n`;
927
+ info += `🎯 单元格位置:\n`;
928
+ info += `- 行: 第${cellInfo.cellPosition.row}行\n`;
929
+ info += `- 列: 第${cellInfo.cellPosition.column}列\n`;
930
+ info += `- 单元格内容: "${cellInfo.cellContent}"\n\n`;
931
+
932
+ info += `📋 表格信息:\n`;
933
+ info += `- 总行数: ${cellInfo.tableInfo.totalRows}\n`;
934
+ info += `- 总列数: ${cellInfo.tableInfo.totalColumns}\n`;
935
+ info += `- 检测方法: ${cellInfo.detectionMethod}\n`;
936
+ info += `- 检测时间: ${cellInfo.timestamp}\n`;
937
+
938
+ // alert(info);
939
+
940
+ // 可以根据精确位置执行特定操作
941
+ console.log('📊 精确单元格信息:', {
942
+ row: cellInfo.cellPosition.row,
943
+ column: cellInfo.cellPosition.column,
944
+ content: cellInfo.cellContent,
945
+ tableInfo: cellInfo.tableInfo
946
+ });
947
+
948
+ // 示例:根据点击的单元格执行不同操作
949
+ if (cellInfo.cellPosition.row === 1) {
950
+ console.log('🎯 点击了表头行,可以执行排序等操作');
951
+ } else {
952
+ console.log('🎯 点击了数据行,可以执行编辑等操作');
953
+ }
954
+
955
+ } else {
956
+ console.log('❌ 精确表格单元格检测失败:', data?.error || '未知错误');
957
+ // 这通常是因为不是表格区域或检测方法失败,不需要alert
958
+ }
959
+ }
960
+ // 处理图表点击事件 - 新增
961
+ function handleChartClicked(data: any) {
962
+ console.log('📈 处理图表点击事件,收到数据:', data)
963
+
964
+ if (data && data.success && data.data) {
965
+ const chartInfo = data.data;
966
+
967
+ let info = `📈 图表点击检测结果!\n\n`;
968
+ info += `点击类型: ${chartInfo.clickType}\n`;
969
+ info += `检测时间: ${chartInfo.timestamp}\n\n`;
970
+
971
+ if (chartInfo.chartInfo) {
972
+ info += `📊 图表信息:\n`;
973
+ info += `- 图表索引: ${chartInfo.chartInfo.chartIndex}\n`;
974
+ info += `- 图表类型: ${chartInfo.chartInfo.chartType}\n`;
975
+
976
+ // 显示详细图表类型信息
977
+ if (chartInfo.chartInfo.detailedChartType) {
978
+ const detailed = chartInfo.chartInfo.detailedChartType;
979
+ info += `- 图表分类: ${detailed.category}\n`;
980
+ info += `- 具体类型: ${detailed.specificType}\n`;
981
+ info += `- 类型描述: ${detailed.description}\n`;
982
+ info += `- 识别置信度: ${(detailed.confidence * 100).toFixed(1)}%\n`;
983
+
984
+ if (detailed.properties && Object.keys(detailed.properties).length > 0) {
985
+ info += `- 属性信息: ${JSON.stringify(detailed.properties)}\n`;
986
+ }
987
+ }
988
+
989
+ info += `- 有绑定数据: ${chartInfo.chartInfo.hasBindingData ? '是' : '否'}\n`;
990
+ info += `- 绑定方法: ${chartInfo.chartInfo.bindingMethod || '无'}\n\n`;
991
+ }
992
+
993
+ if (chartInfo.boundData) {
994
+ info += `💾 绑定的数据:\n`;
995
+ if (chartInfo.boundData.title) {
996
+ info += `- 标题: ${chartInfo.boundData.title}\n`;
997
+ }
998
+ if (chartInfo.boundData.type) {
999
+ info += `- 类型: ${chartInfo.boundData.type}\n`;
1000
+ }
1001
+ if (chartInfo.boundData.dataSource) {
1002
+ info += `- 数据源: ${chartInfo.boundData.dataSource}\n`;
1003
+ }
1004
+ if (chartInfo.boundData.period) {
1005
+ info += `- 时间周期: ${chartInfo.boundData.period}\n`;
1006
+ }
1007
+
1008
+ if (chartInfo.boundData.metrics) {
1009
+ info += `\n📈 关键指标:\n`;
1010
+ const metrics = chartInfo.boundData.metrics;
1011
+ if (metrics.totalSales) {
1012
+ info += `- 总销售额: ¥${metrics.totalSales.toLocaleString()}\n`;
1013
+ }
1014
+ if (metrics.growthRate) {
1015
+ info += `- 增长率: ${metrics.growthRate}%\n`;
1016
+ }
1017
+ if (metrics.topProduct) {
1018
+ info += `- 热门产品: ${metrics.topProduct}\n`;
1019
+ }
1020
+ if (metrics.targetAchievement) {
1021
+ info += `- 目标达成: ${metrics.targetAchievement}%\n`;
1022
+ }
1023
+ }
1024
+
1025
+ if (chartInfo.boundData.series && chartInfo.boundData.series.length > 0) {
1026
+ info += `\n📊 数据系列:\n`;
1027
+ chartInfo.boundData.series.slice(0, 2).forEach((series: any) => {
1028
+ info += `- ${series.name}: [${series.data.slice(0, 3).join(', ')}${series.data.length > 3 ? '...' : ''}]\n`;
1029
+ });
1030
+ }
1031
+ }
1032
+
1033
+ if (chartInfo.bindingMetadata) {
1034
+ info += `\n🔗 绑定信息:\n`;
1035
+ info += `- 绑定ID: ${chartInfo.bindingMetadata.bindingId}\n`;
1036
+ info += `- 绑定时间: ${chartInfo.bindingMetadata.boundAt}\n`;
1037
+ info += `- 绑定方法: ${chartInfo.bindingMetadata.bindingMethod}\n`;
1038
+ }
1039
+
1040
+ if (chartInfo.detectionSummary) {
1041
+ info += `\n🔍 检测摘要:\n`;
1042
+ info += `- 文档中图表总数: ${chartInfo.detectionSummary.totalChartsFound}\n`;
1043
+ info += `- 有数据的图表: ${chartInfo.detectionSummary.chartsWithData}\n`;
1044
+ info += `- 有选区: ${chartInfo.detectionSummary.hasSelection ? '是' : '否'}\n`;
1045
+ }
1046
+
1047
+ // alert(info);
1048
+
1049
+ // 可以根据图表数据执行相应的操作
1050
+ console.log('📈 图表绑定数据:', chartInfo.boundData);
1051
+
1052
+ // 示例:根据图表类型执行不同操作
1053
+ if (chartInfo.boundData) {
1054
+ if (chartInfo.boundData.type === 'line-chart') {
1055
+ console.log('📈 这是线图,可以显示趋势分析');
1056
+ } else if (chartInfo.boundData.type === 'bar-chart') {
1057
+ console.log('📊 这是柱状图,可以显示比较分析');
1058
+ }
1059
+
1060
+ // 可以发送数据到外部系统进行处理
1061
+ if (chartInfo.boundData.dataSource === 'ERP系统') {
1062
+ console.log('🔄 可以触发ERP系统数据刷新');
1063
+ }
1064
+ }
1065
+
1066
+ } else if (data && data.success === false) {
1067
+ console.log('❌ 图表检测失败或无图表:', data.error || '未知错误');
1068
+ // 不显示错误alert,避免过多弹窗
1069
+ }
1070
+ }
1071
+
1072
+ function handleBindingClicked(data: any) {
1073
+ console.log('处理绑定控件点击事件,收到数据:', data)
1074
+
1075
+ if (data && data.success && data.data) {
1076
+ const bindingInfo = data.data
1077
+
1078
+ let info = `绑定控件被点击!\\n\\n`
1079
+ info += `点击类型: ${bindingInfo.clickType}\\n`
1080
+ info += `绑定类型: ${bindingInfo.bindingType}\\n`
1081
+ info += `控件索引: ${bindingInfo.controlIndex}\\n`
1082
+ info += `控件别名: ${bindingInfo.controlAlias || '无'}\\n`
1083
+ info += `控件内容: "${bindingInfo.controlContent || '空'}"\\n`
1084
+ info += `点击时间: ${bindingInfo.timestamp}\\n`
1085
+
1086
+ if (bindingInfo.bindingData) {
1087
+ info += `\\n绑定数据详情:\\n`
1088
+
1089
+ if (bindingInfo.bindingType === 'data-binding') {
1090
+ info += `- 字段名称: ${bindingInfo.bindingData.fieldName}\\n`
1091
+ info += `- 数据类型: ${bindingInfo.bindingData.dataType}\\n`
1092
+ info += `- 原始值: "${bindingInfo.bindingData.originalValue}"\\n`
1093
+ info += `- 绑定时间: ${bindingInfo.bindingData.boundAt}\\n`
1094
+ } else if (bindingInfo.bindingType === 'template-variable') {
1095
+ info += `- 变量名: ${bindingInfo.bindingData.variableName}\\n`
1096
+ info += `- 原始值: "${bindingInfo.bindingData.originalValue}"\\n`
1097
+ info += `- 绑定时间: ${bindingInfo.bindingData.boundAt}\\n`
1098
+ } else if (bindingInfo.bindingType === 'table-data-binding') {
1099
+ info += `- 表格名称: ${bindingInfo.bindingData.tableName}\\n`
1100
+ info += `- 绑定模式: ${bindingInfo.bindingData.bindingMode}\\n`
1101
+ info += `- 绑定时间: ${bindingInfo.bindingData.boundAt}\\n`
1102
+ } else if (bindingInfo.bindingType === 'paragraph-template') {
1103
+ info += `- 模板名称: ${bindingInfo.bindingData.templateName}\\n`
1104
+ info += `- 原始内容: "${bindingInfo.bindingData.originalContent?.substring(0, 50)}${bindingInfo.bindingData.originalContent?.length > 50 ? '...' : ''}"\\n`
1105
+ info += `- 绑定时间: ${bindingInfo.bindingData.boundAt}\\n`
1106
+ } else if (bindingInfo.bindingType === 'custom-binding') {
1107
+ info += `- 自定义类型: ${bindingInfo.bindingData.customType}\\n`
1108
+ info += `- 字段名称: ${bindingInfo.bindingData.fieldName}\\n`
1109
+ info += `- 原始值: "${bindingInfo.bindingData.originalValue}"\\n`
1110
+ info += `- 绑定时间: ${bindingInfo.bindingData.boundAt}\\n`
1111
+ }
1112
+ }
1113
+
1114
+ // alert(info)
1115
+
1116
+ // 可以根据绑定数据执行相应的操作
1117
+ console.log('检测到绑定控件点击,可以执行相关操作:', {
1118
+ bindingType: bindingInfo.bindingType,
1119
+ bindingData: bindingInfo.bindingData
1120
+ })
1121
+
1122
+ // 根据不同的绑定类型执行不同的操作
1123
+ if (bindingInfo.bindingType === 'data-binding') {
1124
+ // 可以打开数据编辑面板
1125
+ console.log('数据字段绑定被点击,可以打开数据编辑界面')
1126
+ } else if (bindingInfo.bindingType === 'template-variable') {
1127
+ // 可以打开变量设置面板
1128
+ console.log('模板变量绑定被点击,可以打开变量设置界面')
1129
+ } else if (bindingInfo.bindingType === 'table-data-binding') {
1130
+ // 可以打开数据源配置面板
1131
+ console.log('表格数据源绑定被点击,可以打开数据源配置界面')
1132
+ }
1133
+ } else {
1134
+ console.log('绑定控件点击检测失败或无绑定控件:', data?.error || '未知错误')
1135
+ if (data?.data?.clickType === 'non-binding') {
1136
+ console.log('当前点击位置不是绑定控件')
1137
+ }
1138
+ }
1139
+ }
1140
+
1141
+
1142
+ onMounted(() => createEditor())
1143
+ onBeforeUnmount(() => {
1144
+ if (editor?.destroyEditor) editor.destroyEditor()
1145
+ if (flushTimer !== null) clearInterval(flushTimer)
1146
+ })
1147
+ </script>
1148
+
1149
+ <style>
1150
+ .onlyoffice-box{
1151
+ height: 100%;
1152
+ }
1153
+ #editor{
1154
+ /* height: 100px;
1155
+ width: 100px; */
1156
+ }
1157
+ </style>