vome-core 0.0.47 → 0.0.49

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.
@@ -70,20 +70,12 @@
70
70
  </div>
71
71
  <div class="vm-file-preview-viewer__actions">
72
72
  <button
73
- v-if="useDownloadAction"
74
- type="button"
75
- class="vm-file-preview-viewer__link"
76
- @click="downloadFile"
77
- >
78
- 下载
79
- </button>
80
- <button
81
- v-else
82
73
  type="button"
83
74
  class="vm-file-preview-viewer__link"
75
+ :disabled="opening"
84
76
  @click="openInNewWindow"
85
77
  >
86
- 新窗口打开
78
+ {{ opening ? '打开中…' : '新窗口打开' }}
87
79
  </button>
88
80
  <button type="button" class="vm-file-preview-viewer__close" title="关闭" @click="closeViewer">
89
81
  <i class="ri-close-line" />
@@ -169,9 +161,14 @@
169
161
  <div v-else-if="kind === 'office'" class="vm-file-preview-viewer__fallback">
170
162
  <i class="ri-file-3-line" aria-hidden="true" />
171
163
  <p>Word / PPT 等 Office 文档暂不支持浏览器内预览。</p>
172
- <p>请点击上方「下载」后使用本地 Office / WPS 查看。</p>
173
- <button type="button" class="vm-file-preview-viewer__dl-btn" @click="downloadFile">
174
- 下载文件
164
+ <p>请点击下方按钮下载后使用本地 Office / WPS 查看。</p>
165
+ <button
166
+ type="button"
167
+ class="vm-file-preview-viewer__dl-btn"
168
+ :disabled="downloading"
169
+ @click="downloadFile"
170
+ >
171
+ {{ downloading ? '下载中…' : '下载文件' }}
175
172
  </button>
176
173
  </div>
177
174
 
@@ -179,8 +176,13 @@
179
176
  <i class="ri-file-3-line" aria-hidden="true" />
180
177
  <p>该文件类型暂不支持在线预览。</p>
181
178
  <p>请点击下方按钮下载查看(如 .vome 插件包)。</p>
182
- <button type="button" class="vm-file-preview-viewer__dl-btn" @click="downloadFile">
183
- 下载文件
179
+ <button
180
+ type="button"
181
+ class="vm-file-preview-viewer__dl-btn"
182
+ :disabled="downloading"
183
+ @click="downloadFile"
184
+ >
185
+ {{ downloading ? '下载中…' : '下载文件' }}
184
186
  </button>
185
187
  </div>
186
188
  </div>
@@ -238,6 +240,8 @@ const props = withDefaults(
238
240
  radius?: number | string
239
241
  preview?: boolean
240
242
  fit?: 'cover' | 'contain'
243
+ /** 私有文件:点「下载」时先解析可访问短链 */
244
+ resolveDownloadUrl?: (url: string) => Promise<string | undefined>
241
245
  }>(),
242
246
  {
243
247
  embedded: false,
@@ -255,6 +259,8 @@ const emit = defineEmits<{ 'update:open': [v: boolean] }>()
255
259
 
256
260
  const internalOpen = ref(false)
257
261
  const loading = ref(false)
262
+ const downloading = ref(false)
263
+ const opening = ref(false)
258
264
  const error = ref('')
259
265
  const textContent = ref('')
260
266
  const excelHtml = ref('')
@@ -331,27 +337,48 @@ const displayName = computed(() =>
331
337
  fileDisplayName(props.fileName || src.value, '未命名文件'),
332
338
  )
333
339
 
334
- /** 无法内嵌预览的类型:只提供下载,避免「新窗口打开」崩掉(如 .vome) */
335
- const useDownloadAction = computed(
336
- () => kind.value === 'unsupported' || kind.value === 'office',
337
- )
340
+ /** 无法内嵌预览的类型在正文区提供「下载文件」;顶栏统一「新窗口打开」 */
341
+
342
+ async function downloadFile() {
343
+ if (downloading.value) return
344
+ const raw = src.value
345
+ if (!raw) return
346
+ downloading.value = true
347
+ try {
348
+ let url = raw
349
+ if (props.resolveDownloadUrl) {
350
+ const signed = await props.resolveDownloadUrl(raw)
351
+ if (!signed) return
352
+ url = signed
353
+ }
354
+ const a = document.createElement('a')
355
+ a.href = url
356
+ a.download = displayName.value || 'download'
357
+ a.rel = 'noopener'
358
+ document.body.appendChild(a)
359
+ a.click()
360
+ a.remove()
361
+ } finally {
362
+ downloading.value = false
363
+ }
364
+ }
338
365
 
339
- function downloadFile() {
340
- const url = src.value
341
- if (!url) return
342
- const a = document.createElement('a')
343
- a.href = url
344
- a.download = displayName.value || 'download'
345
- a.rel = 'noopener'
346
- document.body.appendChild(a)
347
- a.click()
348
- a.remove()
349
- }
350
-
351
- function openInNewWindow() {
352
- const url = src.value
353
- if (!url) return
354
- window.open(url, '_blank', 'noopener,noreferrer')
366
+ async function openInNewWindow() {
367
+ if (opening.value) return
368
+ const raw = src.value
369
+ if (!raw) return
370
+ opening.value = true
371
+ try {
372
+ let url = raw
373
+ if (props.resolveDownloadUrl) {
374
+ const signed = await props.resolveDownloadUrl(raw)
375
+ if (!signed) return
376
+ url = signed
377
+ }
378
+ window.open(url, '_blank', 'noopener,noreferrer')
379
+ } finally {
380
+ opening.value = false
381
+ }
355
382
  }
356
383
 
357
384
  const viewerOpen = computed({
@@ -58,32 +58,24 @@
58
58
 
59
59
  <div v-if="previewSrc" class="vm-upload-item__actions">
60
60
  <button
61
- v-if="canInlinePreview"
62
61
  type="button"
63
62
  title="预览"
64
63
  @click.stop="previewOpen = true"
65
64
  >
66
65
  <i class="ri-zoom-in-line" />
67
66
  </button>
68
- <button
69
- v-else
70
- type="button"
71
- title="下载"
72
- @click.stop="downloadFile"
73
- >
74
- <i class="ri-download-2-line" />
75
- </button>
76
67
  <button v-if="!disabled" type="button" title="删除" @click.stop="emit('remove')">
77
68
  <i class="ri-delete-bin-line" />
78
69
  </button>
79
70
  </div>
80
71
 
81
72
  <vm-preview-viewer
82
- v-if="canInlinePreview"
73
+ v-if="previewSrc"
83
74
  embedded
84
75
  v-model:open="previewOpen"
85
76
  :src="previewSrc"
86
77
  :file-name="item.name || item.url"
78
+ :resolve-download-url="resolveDownloadUrl"
87
79
  />
88
80
  </div>
89
81
  </template>
@@ -91,7 +83,6 @@
91
83
  <script setup lang="ts">
92
84
  import { ref, computed, watch } from 'vue'
93
85
  import { useVideoFrame } from '../../lib/video-frame'
94
- import { getMediaPreviewKind } from '../../lib/file-preview'
95
86
  import { extname, getUploadRule } from '../../lib/upload'
96
87
  import VmPreviewViewer from './vm-preview-viewer.vue'
97
88
  import type { UploadItem } from '../../../../typings/admin/comm/upload'
@@ -103,6 +94,8 @@ const props = withDefaults(
103
94
  item: UploadItem
104
95
  disabled?: boolean
105
96
  showTag?: boolean
97
+ /** 私有文件:预览内点「下载」时先解析可访问短链 */
98
+ resolveDownloadUrl?: (url: string) => Promise<string | undefined>
106
99
  }>(),
107
100
  {
108
101
  disabled: false,
@@ -117,38 +110,6 @@ const imgBroken = ref(false)
117
110
 
118
111
  const previewSrc = computed(() => props.item.preload || props.item.url || '')
119
112
 
120
- const INLINE_KINDS = new Set([
121
- 'image',
122
- 'video',
123
- 'audio',
124
- 'pdf',
125
- 'excel',
126
- 'text',
127
- ])
128
-
129
- /** 可内嵌预览才开浮层;.vome 等直接下载,避免新窗口崩溃 */
130
- const canInlinePreview = computed(() => {
131
- const name = props.item.name || props.item.url || ''
132
- const kind = getMediaPreviewKind(name)
133
- return INLINE_KINDS.has(kind)
134
- })
135
-
136
- function downloadFile() {
137
- const url = previewSrc.value
138
- if (!url) return
139
- const base =
140
- props.item.name ||
141
- String(url).split('?')[0]?.split('/').pop() ||
142
- 'download'
143
- const a = document.createElement('a')
144
- a.href = url
145
- a.download = base
146
- a.rel = 'noopener'
147
- document.body.appendChild(a)
148
- a.click()
149
- a.remove()
150
- }
151
-
152
113
  /** 仅上传中显示;失败后隐藏,避免挡住预览/删除 */
153
114
  const showProgress = computed(() => {
154
115
  if (props.item.error) return false
@@ -38,6 +38,7 @@
38
38
  :item="item"
39
39
  :disabled="disabled"
40
40
  :show-tag="showTag"
41
+ :resolve-download-url="resolveDownloadUrl"
41
42
  @remove="remove(index)"
42
43
  />
43
44
  </div>
@@ -96,6 +97,8 @@ const props = withDefaults(
96
97
  drag?: boolean
97
98
  prefixPath?: string
98
99
  beforeUpload?: (file: File) => boolean | Promise<boolean>
100
+ /** 私有文件:预览内点「下载」时先解析可访问短链 */
101
+ resolveDownloadUrl?: (url: string) => Promise<string | undefined>
99
102
  }>(),
100
103
  {
101
104
  modelValue: '',
package/dist/index.js CHANGED
@@ -27856,7 +27856,7 @@ init_excel();
27856
27856
  // package.json
27857
27857
  var package_default = {
27858
27858
  name: "vome-core",
27859
- version: "0.0.47",
27859
+ version: "0.0.49",
27860
27860
  description: "Vome framework \u2014 shared + Bun/Elysia server + Vue admin",
27861
27861
  license: "MIT",
27862
27862
  type: "module",
@@ -31168,7 +31168,7 @@ init_excel();
31168
31168
  // package.json
31169
31169
  var package_default = {
31170
31170
  name: "vome-core",
31171
- version: "0.0.47",
31171
+ version: "0.0.49",
31172
31172
  description: "Vome framework \u2014 shared + Bun/Elysia server + Vue admin",
31173
31173
  license: "MIT",
31174
31174
  type: "module",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vome-core",
3
- "version": "0.0.47",
3
+ "version": "0.0.49",
4
4
  "description": "Vome framework — shared + Bun/Elysia server + Vue admin",
5
5
  "license": "MIT",
6
6
  "type": "module",