adtec-core-package 3.1.6 → 3.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/adtec-core-package/adtec-core-package.css +1 -0
  2. package/adtec-core-package/adtec-core-package.js +41216 -0
  3. package/adtec-core-package/adtec-core-package.umd.cjs +87 -0
  4. package/adtec-core-package/favicon.ico +0 -0
  5. package/adtec-core-package-3.1.7.tgz +0 -0
  6. package/package/.editorconfig +6 -0
  7. package/package/adtec-core-package/adtec-core-package.css +1 -0
  8. package/package/adtec-core-package/adtec-core-package.js +41216 -0
  9. package/package/adtec-core-package/adtec-core-package.umd.cjs +87 -0
  10. package/package/adtec-core-package/favicon.ico +0 -0
  11. package/package/index.html +13 -0
  12. package/package/prebuilt/umo-editor/favicon.ico +0 -0
  13. package/package/prebuilt/umo-editor/umo-editor.css +1 -0
  14. package/package/public/favicon.ico +0 -0
  15. package/package/src/assets/base.css +86 -0
  16. package/package/src/assets/main.css +35 -0
  17. package/package/src/components/editor-main/src/extensions/bookmark.js +110 -0
  18. package/package.json +4 -2
  19. package/src/api/DocumentApi.ts +11 -1
  20. package/src/components/upload/DocxJsViewer.vue +286 -0
  21. package/src/components/upload/ExcelJsViewer.vue +444 -0
  22. package/src/components/upload/FileView.vue +102 -159
  23. package/src/components/upload/OfficePreview.vue +481 -0
  24. package/src/components/upload/OfficePreviewHeaderBar.vue +315 -0
  25. package/src/components/upload/OfficePreviewToolbar.vue +203 -0
  26. package/src/components/upload/PdfJsViewer.vue +920 -0
  27. package/src/utils/docxPreviewUtil.ts +108 -0
  28. package/src/utils/excelPreviewUtil.ts +307 -0
  29. package/src/utils/officePreviewUtil.ts +122 -0
  30. package/src/utils/pdfSearchUtil.ts +127 -0
  31. package/src/utils/toSameOriginFileUrl.ts +1 -1
@@ -0,0 +1,315 @@
1
+ <template>
2
+ <div class="office-preview-header">
3
+ <div v-if="title" class="header-title" :title="title">{{ title }}</div>
4
+
5
+ <div v-if="showSearch" class="header-search">
6
+ <el-input
7
+ v-model="searchText"
8
+ class="search-input"
9
+ clearable
10
+ placeholder="搜索文档内容"
11
+ @keyup.enter="emitSearch"
12
+ @clear="emit('search-clear')"
13
+ >
14
+ <template #prefix>
15
+ <el-icon><Search /></el-icon>
16
+ </template>
17
+ </el-input>
18
+ <span v-if="searchTotal > 0" class="search-count">{{ searchIndex + 1 }}/{{ searchTotal }}</span>
19
+ <button
20
+ v-if="searchTotal > 0"
21
+ class="toolbar-btn"
22
+ type="button"
23
+ title="上一处"
24
+ @click="emit('search-prev')"
25
+ >
26
+ <el-icon><ArrowUp /></el-icon>
27
+ </button>
28
+ <button
29
+ v-if="searchTotal > 0"
30
+ class="toolbar-btn"
31
+ type="button"
32
+ title="下一处"
33
+ @click="emit('search-next')"
34
+ >
35
+ <el-icon><ArrowDown /></el-icon>
36
+ </button>
37
+ </div>
38
+
39
+ <div class="header-actions">
40
+ <template v-if="showPageNav && totalPages > 0">
41
+ <button class="toolbar-btn" type="button" title="上一页" :disabled="currentPage <= 1" @click="emit('page-prev')">
42
+ <el-icon><ArrowLeft /></el-icon>
43
+ </button>
44
+ <span class="page-label">{{ currentPage }} / {{ totalPages }}</span>
45
+ <button
46
+ class="toolbar-btn"
47
+ type="button"
48
+ title="下一页"
49
+ :disabled="currentPage >= totalPages"
50
+ @click="emit('page-next')"
51
+ >
52
+ <el-icon><ArrowRight /></el-icon>
53
+ </button>
54
+ <span class="toolbar-divider" />
55
+ </template>
56
+
57
+ <template v-if="showZoom">
58
+ <button class="toolbar-btn" type="button" title="缩小" :disabled="zoom <= minZoom" @click="emit('zoom-out')">
59
+ <el-icon><ZoomOut /></el-icon>
60
+ </button>
61
+ <span class="zoom-label">{{ zoomPercent }}%</span>
62
+ <button class="toolbar-btn" type="button" title="放大" :disabled="zoom >= maxZoom" @click="emit('zoom-in')">
63
+ <el-icon><ZoomIn /></el-icon>
64
+ </button>
65
+ <button class="toolbar-btn" type="button" title="重置缩放" @click="emit('zoom-reset')">
66
+ <el-icon><RefreshRight /></el-icon>
67
+ </button>
68
+ <span class="toolbar-divider" />
69
+ </template>
70
+
71
+ <button
72
+ v-if="showDownload"
73
+ class="toolbar-btn"
74
+ type="button"
75
+ title="下载"
76
+ :disabled="downloadLoading"
77
+ @click="emit('download')"
78
+ >
79
+ <el-icon v-if="downloadLoading" class="is-loading"><Loading /></el-icon>
80
+ <el-icon v-else><Download /></el-icon>
81
+ </button>
82
+
83
+ <button v-if="showRefresh" class="toolbar-btn" type="button" title="刷新附件" @click="emit('refresh')">
84
+ <el-icon><Refresh /></el-icon>
85
+ </button>
86
+
87
+ <button
88
+ v-if="showFullscreen"
89
+ class="toolbar-btn"
90
+ type="button"
91
+ :title="fullscreen ? '退出全屏' : '全屏'"
92
+ @click="emit('toggle-fullscreen')"
93
+ >
94
+ <el-icon><Close v-if="fullscreen" /><FullScreen v-else /></el-icon>
95
+ </button>
96
+
97
+ <button
98
+ v-if="showClose"
99
+ class="toolbar-btn toolbar-btn--close"
100
+ type="button"
101
+ title="关闭"
102
+ @click="emit('close')"
103
+ >
104
+ <el-icon><Close /></el-icon>
105
+ </button>
106
+ </div>
107
+ </div>
108
+ </template>
109
+
110
+ <script setup lang="ts">
111
+ import {
112
+ ArrowDown,
113
+ ArrowLeft,
114
+ ArrowRight,
115
+ ArrowUp,
116
+ Close,
117
+ Download,
118
+ FullScreen,
119
+ Loading,
120
+ Refresh,
121
+ RefreshRight,
122
+ Search,
123
+ ZoomIn,
124
+ ZoomOut,
125
+ } from '@element-plus/icons-vue'
126
+ import { ElIcon, ElInput } from 'element-plus'
127
+ import { computed, ref, watch } from 'vue'
128
+ import { MAX_PDF_ZOOM, MIN_OFFICE_ZOOM } from '../../utils/officePreviewUtil.ts'
129
+
130
+ const props = withDefaults(
131
+ defineProps<{
132
+ title?: string
133
+ zoom?: number
134
+ currentPage?: number
135
+ totalPages?: number
136
+ searchQuery?: string
137
+ searchIndex?: number
138
+ searchTotal?: number
139
+ showSearch?: boolean
140
+ showPageNav?: boolean
141
+ showZoom?: boolean
142
+ showDownload?: boolean
143
+ showRefresh?: boolean
144
+ showFullscreen?: boolean
145
+ showClose?: boolean
146
+ fullscreen?: boolean
147
+ downloadLoading?: boolean
148
+ minZoom?: number
149
+ maxZoom?: number
150
+ }>(),
151
+ {
152
+ title: '',
153
+ zoom: 1,
154
+ currentPage: 1,
155
+ totalPages: 0,
156
+ searchQuery: '',
157
+ searchIndex: -1,
158
+ searchTotal: 0,
159
+ showSearch: true,
160
+ showPageNav: true,
161
+ showZoom: true,
162
+ showDownload: false,
163
+ showRefresh: false,
164
+ showFullscreen: false,
165
+ showClose: false,
166
+ fullscreen: false,
167
+ downloadLoading: false,
168
+ minZoom: MIN_OFFICE_ZOOM,
169
+ maxZoom: MAX_PDF_ZOOM,
170
+ },
171
+ )
172
+
173
+ const emit = defineEmits<{
174
+ 'zoom-in': []
175
+ 'zoom-out': []
176
+ 'zoom-reset': []
177
+ download: []
178
+ refresh: []
179
+ 'toggle-fullscreen': []
180
+ close: []
181
+ 'page-prev': []
182
+ 'page-next': []
183
+ search: [query: string]
184
+ 'search-clear': []
185
+ 'search-prev': []
186
+ 'search-next': []
187
+ }>()
188
+
189
+ const searchText = ref(props.searchQuery)
190
+ const zoomPercent = computed(() => Math.round(props.zoom * 100))
191
+
192
+ watch(
193
+ () => props.searchQuery,
194
+ (value) => {
195
+ searchText.value = value
196
+ },
197
+ )
198
+
199
+ const emitSearch = () => {
200
+ emit('search', searchText.value.trim())
201
+ }
202
+ </script>
203
+
204
+ <style scoped lang="scss">
205
+ .office-preview-header {
206
+ display: flex;
207
+ align-items: center;
208
+ gap: 12px;
209
+ min-height: 44px;
210
+ padding: 6px 12px;
211
+ background: #fff;
212
+ border-bottom: 1px solid #e5e7eb;
213
+ flex-shrink: 0;
214
+ }
215
+
216
+ .header-title {
217
+ max-width: 180px;
218
+ font-size: 13px;
219
+ font-weight: 600;
220
+ color: #374151;
221
+ white-space: nowrap;
222
+ overflow: hidden;
223
+ text-overflow: ellipsis;
224
+ flex-shrink: 0;
225
+ }
226
+
227
+ .header-search {
228
+ display: flex;
229
+ align-items: center;
230
+ gap: 4px;
231
+ flex: 1;
232
+ min-width: 0;
233
+ }
234
+
235
+ .search-input {
236
+ flex: 1;
237
+ min-width: 120px;
238
+ max-width: 360px;
239
+ }
240
+
241
+ .search-count {
242
+ min-width: 48px;
243
+ font-size: 12px;
244
+ color: #6b7280;
245
+ text-align: center;
246
+ }
247
+
248
+ .header-actions {
249
+ display: inline-flex;
250
+ align-items: center;
251
+ gap: 2px;
252
+ margin-left: auto;
253
+ flex-shrink: 0;
254
+ }
255
+
256
+ .toolbar-btn {
257
+ display: inline-flex;
258
+ align-items: center;
259
+ justify-content: center;
260
+ width: 32px;
261
+ height: 32px;
262
+ padding: 0;
263
+ border: none;
264
+ border-radius: 8px;
265
+ background: transparent;
266
+ color: #4b5563;
267
+ cursor: pointer;
268
+ transition: background-color 0.2s ease, color 0.2s ease;
269
+
270
+ &:hover:not(:disabled) {
271
+ background: #f3f4f6;
272
+ color: #111827;
273
+ }
274
+
275
+ &:disabled {
276
+ color: #d1d5db;
277
+ cursor: not-allowed;
278
+ }
279
+
280
+ &--close:hover:not(:disabled) {
281
+ background: #fee2e2;
282
+ color: #dc2626;
283
+ }
284
+ }
285
+
286
+ .zoom-label,
287
+ .page-label {
288
+ min-width: 52px;
289
+ text-align: center;
290
+ font-size: 12px;
291
+ font-weight: 600;
292
+ color: #374151;
293
+ user-select: none;
294
+ }
295
+
296
+ .toolbar-divider {
297
+ width: 1px;
298
+ height: 20px;
299
+ margin: 0 4px;
300
+ background: #e5e7eb;
301
+ }
302
+
303
+ .is-loading {
304
+ animation: rotating 1.2s linear infinite;
305
+ }
306
+
307
+ @keyframes rotating {
308
+ from {
309
+ transform: rotate(0deg);
310
+ }
311
+ to {
312
+ transform: rotate(360deg);
313
+ }
314
+ }
315
+ </style>
@@ -0,0 +1,203 @@
1
+ <template>
2
+ <div class="office-preview-toolbar">
3
+ <template v-if="showZoom">
4
+ <button
5
+ class="toolbar-btn"
6
+ type="button"
7
+ title="缩小"
8
+ :disabled="zoom <= minZoom"
9
+ @click="$emit('zoom-out')"
10
+ >
11
+ <el-icon><ZoomOut /></el-icon>
12
+ </button>
13
+ <span class="zoom-label">{{ zoomPercent }}%</span>
14
+ <button
15
+ class="toolbar-btn"
16
+ type="button"
17
+ title="放大"
18
+ :disabled="zoom >= maxZoom"
19
+ @click="$emit('zoom-in')"
20
+ >
21
+ <el-icon><ZoomIn /></el-icon>
22
+ </button>
23
+ <button class="toolbar-btn" type="button" title="重置缩放" @click="$emit('zoom-reset')">
24
+ <el-icon><RefreshRight /></el-icon>
25
+ </button>
26
+ <span class="toolbar-divider" />
27
+ </template>
28
+
29
+ <button
30
+ v-if="showDownload"
31
+ class="toolbar-btn"
32
+ type="button"
33
+ title="下载"
34
+ :disabled="downloadLoading"
35
+ @click="$emit('download')"
36
+ >
37
+ <el-icon v-if="downloadLoading" class="is-loading"><Loading /></el-icon>
38
+ <el-icon v-else><Download /></el-icon>
39
+ </button>
40
+
41
+ <button
42
+ v-if="showRefresh"
43
+ class="toolbar-btn"
44
+ type="button"
45
+ title="刷新附件"
46
+ @click="$emit('refresh')"
47
+ >
48
+ <el-icon><Refresh /></el-icon>
49
+ </button>
50
+
51
+ <button
52
+ v-if="showFullscreen"
53
+ class="toolbar-btn"
54
+ type="button"
55
+ :title="fullscreen ? '退出全屏' : '全屏'"
56
+ @click="$emit('toggle-fullscreen')"
57
+ >
58
+ <el-icon><Close v-if="fullscreen" /><FullScreen v-else /></el-icon>
59
+ </button>
60
+
61
+ <button
62
+ v-if="showClose"
63
+ class="toolbar-btn toolbar-btn--close"
64
+ type="button"
65
+ title="关闭"
66
+ @click="$emit('close')"
67
+ >
68
+ <el-icon><Close /></el-icon>
69
+ </button>
70
+ </div>
71
+ </template>
72
+
73
+ <script setup lang="ts">
74
+ import {
75
+ Close,
76
+ Download,
77
+ FullScreen,
78
+ Loading,
79
+ Refresh,
80
+ RefreshRight,
81
+ ZoomIn,
82
+ ZoomOut,
83
+ } from '@element-plus/icons-vue'
84
+ import { ElIcon } from 'element-plus'
85
+ import { computed } from 'vue'
86
+ import { MAX_OFFICE_ZOOM, MIN_OFFICE_ZOOM } from '../../utils/officePreviewUtil.ts'
87
+
88
+ const props = withDefaults(
89
+ defineProps<{
90
+ zoom?: number
91
+ showZoom?: boolean
92
+ showDownload?: boolean
93
+ showRefresh?: boolean
94
+ showFullscreen?: boolean
95
+ showClose?: boolean
96
+ fullscreen?: boolean
97
+ downloadLoading?: boolean
98
+ minZoom?: number
99
+ maxZoom?: number
100
+ }>(),
101
+ {
102
+ zoom: 1,
103
+ showZoom: false,
104
+ showDownload: false,
105
+ showRefresh: false,
106
+ showFullscreen: false,
107
+ showClose: false,
108
+ fullscreen: false,
109
+ downloadLoading: false,
110
+ minZoom: MIN_OFFICE_ZOOM,
111
+ maxZoom: MAX_OFFICE_ZOOM,
112
+ },
113
+ )
114
+
115
+ defineEmits<{
116
+ 'zoom-in': []
117
+ 'zoom-out': []
118
+ 'zoom-reset': []
119
+ download: []
120
+ refresh: []
121
+ 'toggle-fullscreen': []
122
+ close: []
123
+ }>()
124
+
125
+ const zoomPercent = computed(() => Math.round(props.zoom * 100))
126
+ </script>
127
+
128
+ <style scoped lang="scss">
129
+ .office-preview-toolbar {
130
+ display: inline-flex;
131
+ align-items: center;
132
+ gap: 2px;
133
+ padding: 4px 8px;
134
+ border-radius: 10px;
135
+ background: rgba(255, 255, 255, 0.96);
136
+ border: 1px solid rgba(0, 0, 0, 0.06);
137
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
138
+ backdrop-filter: blur(8px);
139
+ }
140
+
141
+ .toolbar-btn {
142
+ display: inline-flex;
143
+ align-items: center;
144
+ justify-content: center;
145
+ width: 32px;
146
+ height: 32px;
147
+ padding: 0;
148
+ border: none;
149
+ border-radius: 8px;
150
+ background: transparent;
151
+ color: #4b5563;
152
+ cursor: pointer;
153
+ transition: background-color 0.2s ease, color 0.2s ease;
154
+
155
+ &:hover:not(:disabled) {
156
+ background: #f3f4f6;
157
+ color: #111827;
158
+ }
159
+
160
+ &:disabled {
161
+ color: #d1d5db;
162
+ cursor: not-allowed;
163
+ }
164
+
165
+ &--close {
166
+ color: #6b7280;
167
+
168
+ &:hover:not(:disabled) {
169
+ background: #fee2e2;
170
+ color: #dc2626;
171
+ }
172
+ }
173
+ }
174
+
175
+ .zoom-label {
176
+ min-width: 44px;
177
+ text-align: center;
178
+ font-size: 12px;
179
+ font-weight: 600;
180
+ color: #374151;
181
+ user-select: none;
182
+ }
183
+
184
+ .toolbar-divider {
185
+ width: 1px;
186
+ height: 20px;
187
+ margin: 0 4px;
188
+ background: #e5e7eb;
189
+ }
190
+
191
+ .is-loading {
192
+ animation: rotating 1.2s linear infinite;
193
+ }
194
+
195
+ @keyframes rotating {
196
+ from {
197
+ transform: rotate(0deg);
198
+ }
199
+ to {
200
+ transform: rotate(360deg);
201
+ }
202
+ }
203
+ </style>