Browse Source

feat: Optimize the file preview

- use `vue-files-preview` package
pull/1489/head
colin 4 months ago
parent
commit
215c9364de
  1. 1
      apps/vben5/apps/app-antd/src/store/auth.ts
  2. 5
      apps/vben5/packages/@abp/blob-management/package.json
  3. 26
      apps/vben5/packages/@abp/blob-management/src/api/useBlobsApi.ts
  4. 4
      apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFilePreviewModal.vue
  5. 106
      apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFilePreviewModal1.vue
  6. 9
      apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFileTable.vue
  7. 2
      apps/vben5/pnpm-workspace.yaml

1
apps/vben5/apps/app-antd/src/store/auth.ts

@ -180,6 +180,7 @@ export const useAuthStore = defineStore('auth', () => {
userId: userInfoRes.sub ?? abpConfig.currentUser.id,
username: userInfoRes.uniqueName ?? abpConfig.currentUser.userName,
realName:
userInfoRes.given_name ??
userInfoRes.name ??
abpConfig.currentUser.name ??
abpConfig.currentUser.userName,

5
apps/vben5/packages/@abp/blob-management/package.json

@ -37,13 +37,10 @@
"@vben/locales": "workspace:*",
"@vben/stores": "workspace:*",
"@vben/utils": "workspace:*",
"@vue-office/docx": "catalog:",
"@vue-office/excel": "catalog:",
"@vue-office/pdf": "catalog:",
"@vue-office/pptx": "catalog:",
"ant-design-vue": "catalog:",
"vue": "catalog:",
"vue-demi": "catalog:",
"vue-files-preview": "catalog:",
"vue-simple-uploader": "catalog:",
"vxe-table": "catalog:"
}

26
apps/vben5/packages/@abp/blob-management/src/api/useBlobsApi.ts

@ -32,8 +32,26 @@ export function useBlobsApi() {
});
}
function getContentApi(id: string): Promise<Blob> {
return request<Blob>(`/api/blob-management/blobs/uid/${id}/content`, {
function generateDownloadUrlApi(id: string): Promise<string> {
return request<string>(
`/api/blob-management/blobs/generate/download-url/${id}`,
{
method: 'GET',
},
);
}
function generatePreviewUrlApi(id: string): Promise<string> {
return request<string>(
`/api/blob-management/blobs/generate/preview-url/${id}`,
{
method: 'GET',
},
);
}
function downloadApi(id: string): Promise<Blob> {
return request<Blob>(`/api/blob-management/blobs/download/${id}`, {
method: 'GET',
responseType: 'blob',
});
@ -70,8 +88,10 @@ export function useBlobsApi() {
cancel,
createFolderApi,
deleteApi,
downloadApi,
getApi,
getContentApi,
generateDownloadUrlApi,
generatePreviewUrlApi,
getFolderPagedListApi,
getFilePagedListApi,
getPagedListApi,

4
apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFilePreviewModal.vue

@ -64,7 +64,7 @@ const blobType = ref<FileType>();
const errorMessage = ref<string>('');
const excelComponentKey = ref(0); // 只对 Excel 组件使用 key
const { getContentApi } = useBlobsApi();
const { downloadApi } = useBlobsApi();
// 文件类型配置
const allowFiles: Record<FileType, string[]> = {
@ -175,7 +175,7 @@ async function onInit() {
}
// 获取文件内容
const content = await getContentApi(blob.value.id);
const content = await downloadApi(blob.value.id);
// 检查文件大小
if (!isFileSizeValid(content)) {

106
apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFilePreviewModal1.vue

@ -0,0 +1,106 @@
<script setup lang="ts">
import type { BlobDto } from '../../types/blobs';
import { defineAsyncComponent, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { downloadFileFromUrl } from '@vben/utils';
import { Button, Spin } from 'ant-design-vue';
import { useBlobsApi } from '../../api/useBlobsApi';
const VueFilesPreview = defineAsyncComponent({
loader: async () => {
const res = await import('vue-files-preview');
import('vue-files-preview/lib/style.css');
return res.VueFilesPreview;
},
loadingComponent: Spin,
delay: 200,
});
const fileName = ref<string>();
const previewUrl = ref<string>();
const errorMsg = ref<string>();
const { generatePreviewUrlApi } = useBlobsApi();
const [Modal, modalApi] = useVbenModal({
showCancelButton: false,
showConfirmButton: false,
fullscreen: true,
fullscreenButton: false,
onOpenChange: async (isOpen) => {
isOpen && onInit();
},
onClosed() {
previewUrl.value = undefined;
fileName.value = undefined;
errorMsg.value = undefined;
},
});
async function onInit() {
try {
modalApi.lock();
const blob = modalApi.getData<BlobDto>();
fileName.value = blob.name;
previewUrl.value = await generatePreviewUrlApi(blob.id);
} finally {
modalApi.unlock();
}
}
async function handleDownload() {
downloadFileFromUrl({
fileName: fileName.value!,
source: previewUrl.value!,
});
}
function onError(error: Error) {
errorMsg.value = error.message;
}
</script>
<template>
<Modal :title="fileName">
<div class="preview-container">
<VueFilesPreview
v-if="previewUrl"
:url="previewUrl"
:name="fileName"
@error="onError"
/>
<!-- 下载按钮 -->
<div v-if="errorMsg && previewUrl" class="download-button">
<Button type="primary" @click="handleDownload">
{{ $t('BlobManagement.Blobs:Download') }}
</Button>
</div>
</div>
</Modal>
</template>
<style scoped lang="scss">
.preview-container {
position: relative;
height: 100%;
.error-message {
padding: 40px 20px;
text-align: center;
}
.download-button {
position: sticky;
right: 20px;
bottom: 20px;
z-index: 10;
float: right;
margin-top: 20px;
}
}
</style>

9
apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFileTable.vue

@ -35,7 +35,7 @@ const kbUnit = 1 * 1024;
const mbUnit = kbUnit * 1024;
const gbUnit = mbUnit * 1024;
const { deleteApi, getPagedListApi } = useBlobsApi();
const { deleteApi, getPagedListApi, generateDownloadUrlApi } = useBlobsApi();
const selectedKeys = ref<string[]>([]);
@ -169,7 +169,7 @@ const [BlobFileUploadModal, uploadModalApi] = useVbenModal({
});
const [BlobFilePreviewModal, previewModalApi] = useVbenModal({
connectedComponent: defineAsyncComponent(
() => import('./BlobFilePreviewModal.vue'),
() => import('./BlobFilePreviewModal1.vue'),
),
});
@ -191,10 +191,11 @@ function onDownload(row: BlobDto) {
centered: true,
content: $t('BlobManagement.BlobWellDownloadMessage', [row.name]),
onCancel: () => {},
onOk: () => {
onOk: async () => {
const downloadUrl = await generateDownloadUrlApi(row.id);
downloadFileFromUrl({
fileName: row.name,
source: `/api/blob-management/blobs/uid/${row.id}/content`,
source: downloadUrl,
});
},
title: $t('AbpUi.AreYouSure'),

2
apps/vben5/pnpm-workspace.yaml

@ -83,6 +83,7 @@ catalog:
'@vite-pwa/vitepress': ^1.1.0
'@vitejs/plugin-vue': ^6.0.4
'@vitejs/plugin-vue-jsx': ^5.1.4
'@vue-files-preview': ^0.0.0
'@vue-office/docx': ^1.6.3
'@vue-office/excel': ^1.7.14
'@vue-office/pdf': ^2.0.10
@ -235,6 +236,7 @@ catalog:
vue: ^3.5.27
vue-demi: ^0.14.6
vue-eslint-parser: ^10.2.0
vue-files-preview: ^1.0.43
vue-i18n: ^11.2.8
vue-json-viewer: ^3.0.4
vue-router: ^5.0.3

Loading…
Cancel
Save