diff --git a/config/vite.config.base.ts b/config/vite.config.base.ts index 30efaf66017a18a68b571549494d63c0203740d3..3e56dbab8616fe541e06357f2383c7d6aa5ea3b6 100644 --- a/config/vite.config.base.ts +++ b/config/vite.config.base.ts @@ -3,6 +3,7 @@ import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import vueJsx from '@vitejs/plugin-vue-jsx'; import svgLoader from 'vite-svg-loader'; +import monacoEditorPlugin from 'vite-plugin-monaco-editor'; import configArcoStyleImportPlugin from './plugin/arcoStyleImport'; export default defineConfig({ @@ -11,6 +12,9 @@ export default defineConfig({ vueJsx(), svgLoader({ svgoConfig: {} }), configArcoStyleImportPlugin(), + monacoEditorPlugin({ + languageWorkers: ['json', 'css', 'html', 'typescript'], + }), ], resolve: { alias: [ diff --git a/package.json b/package.json index 0ef8faf6cf93c8771c00efafe1c4072c09866224..dd41e537fdb528fe21bc4710540d4364dc4f504a 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "echarts": "^5.4.0", "gsap": "^3.13.0", "mitt": "^3.0.0", + "monaco-editor": "^0.54.0", "motion-v": "^1.7.4", "nprogress": "^0.2.0", "pinia": "^2.0.23", @@ -46,9 +47,12 @@ "radash": "^12.1.0", "sortablejs": "^1.15.0", "spark-md5": "^3.0.2", + "vite-plugin-monaco-editor": "^1.1.0", "vue": "^3.2.40", "vue-echarts": "^6.2.3", - "vue-router": "^4.0.14" + "vue-router": "^4.0.14", + "xgplayer": "^3.0.23", + "xgplayer-music": "^3.0.23" }, "devDependencies": { "@arco-plugins/vite-vue": "^1.4.5", diff --git a/src/api/file.ts b/src/api/file.ts index 7adddc070dce50db6da4bdc20fd077a4b800fe5c..c2474124b15ac0c2ff14504fc56d9d1ff12802fb 100644 --- a/src/api/file.ts +++ b/src/api/file.ts @@ -182,5 +182,12 @@ export function unfavoriteFile(fileIds: string[]) { }); } +/** + * 获取文件访问URL + */ +export function getFilePreviewUrl(fileId: string, expireSeconds = 180) { + return request.get(`/apis/file/url/${fileId}`, { params: { expireSeconds } }); +} + // 导出类型以便在组件中使用 export type { FileListParams, FileItem }; diff --git a/src/components/audio-player/index.vue b/src/components/audio-player/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..8e9af450885a9501bac9e976810ba36e31de8e04 --- /dev/null +++ b/src/components/audio-player/index.vue @@ -0,0 +1,153 @@ + + + + + + + + + + + diff --git a/src/components/code-player/index.vue b/src/components/code-player/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..9534fa0a39c24429a77da4e57b3e59314ea05875 --- /dev/null +++ b/src/components/code-player/index.vue @@ -0,0 +1,134 @@ + + + + + + + diff --git a/src/components/pdf-player/index.vue b/src/components/pdf-player/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..4160c24cf2ec99c499f9544a23e99bce7d635c90 --- /dev/null +++ b/src/components/pdf-player/index.vue @@ -0,0 +1,79 @@ + + + + + + + + + + + + + diff --git a/src/components/video-player/index.vue b/src/components/video-player/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..05f543f434b7987b1788d36b43db1faa0d6530f6 --- /dev/null +++ b/src/components/video-player/index.vue @@ -0,0 +1,71 @@ + + + + + + + diff --git a/src/views/files/components/file-grid-view.vue b/src/views/files/components/file-grid-view.vue index 2bc341899ad007a755f55b3abca80680a6197617..60594240ba538de5f447e1dee0b63167d0cd865f 100644 --- a/src/views/files/components/file-grid-view.vue +++ b/src/views/files/components/file-grid-view.vue @@ -113,6 +113,10 @@ + + + 预览 + 分享 @@ -162,6 +166,7 @@ IconRefresh, IconApps, IconList, + IconEye, } from '@arco-design/web-vue/es/icon'; import type { FileItem } from '@/types/modules/file'; import { getFileIconPath } from '@/utils/file-icon'; @@ -187,6 +192,7 @@ (e: 'update:selectedKeys', keys: string[]): void; (e: 'update:viewMode', value: 'list' | 'grid'): void; (e: 'refresh'): void; + (e: 'preview', file: FileItem): void; }>(); const isSelected = (fileId: string) => { diff --git a/src/views/files/components/file-previewer.vue b/src/views/files/components/file-previewer.vue new file mode 100644 index 0000000000000000000000000000000000000000..4c5a5389c3356d2d906a66b87957282cf1a47b76 --- /dev/null +++ b/src/views/files/components/file-previewer.vue @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 暂不支持预览.{{ fileExtension }} 类型的文件 + + 点击下载 + + + + + + + + + + diff --git a/src/views/files/components/index.ts b/src/views/files/components/index.ts index 88ef0c7aca3360d023a938bbc30c5a0a8ad6424d..c0167e02859bb2232e304c04e99f4149076e0324 100644 --- a/src/views/files/components/index.ts +++ b/src/views/files/components/index.ts @@ -18,3 +18,4 @@ export { default as DeleteConfirmModal } from './delete-confirm-modal.vue'; export { default as RecycleBinView } from './recycle-bin-view.vue'; export { default as MySharesView } from './my-shares-view.vue'; export { default as UploadPanel } from './upload-panel.vue'; +export { default as FilePreviewer } from './file-previewer.vue'; \ No newline at end of file diff --git a/src/views/files/hooks/use-file-operations.ts b/src/views/files/hooks/use-file-operations.ts index 4968076b53bce718c24d80a374f2f7986ce99570..dc6213e45d3fb534ac7463c9e45be299f5ed654e 100644 --- a/src/views/files/hooks/use-file-operations.ts +++ b/src/views/files/hooks/use-file-operations.ts @@ -10,6 +10,7 @@ import { createFolder, favoriteFile, unfavoriteFile, + getFilePreviewUrl, } from '@/api/file'; import type { FileItem } from '@/types/modules/file'; @@ -43,6 +44,10 @@ export default function useFileOperations(refreshCallback: () => void) { const deletingFile = ref(null); const deletingFiles = ref([]); + // 预览相关 + const previewModalVisible = ref(false); + const previewFile = ref({ fileName: '', fileUrl: '', fileSuffix: '' }); + /** * 打开上传弹窗 */ @@ -360,6 +365,23 @@ export default function useFileOperations(refreshCallback: () => void) { }); }; + /** + * 预览文件 + */ + const openPreview = async (file: FileItem) => { + previewModalVisible.value = true; + try { + const res = await getFilePreviewUrl(file.id); + previewFile.value = { + fileName: file.originalName, + fileSuffix: file.suffix, + fileUrl: res.data, + }; + } catch (e) { + Message.error('预览失败,请联系管理员'); + } + }; + return { // 上传相关 uploadModalVisible, @@ -406,5 +428,10 @@ export default function useFileOperations(refreshCallback: () => void) { // 收藏 handleFavorite, + + // 预览 + previewModalVisible, + openPreview, + previewFile, }; } diff --git a/src/views/files/index.vue b/src/views/files/index.vue index 3d4250b7bc78c40aa618f7ce0723886ef925b8c4..47b3dc2be7c12f21cd5e552c8ca8bd1a2063f591 100644 --- a/src/views/files/index.vue +++ b/src/views/files/index.vue @@ -138,6 +138,7 @@ @move="operations.openMoveModal" @favorite="handleFavorite" @refresh="fileList.refresh" + @preview="operations.openPreview" /> @@ -153,6 +154,7 @@ style="display: none" @change="handleFileSelect" /> + + + + @@ -233,6 +241,8 @@ DeleteConfirmModal, RecycleBinView, MySharesView, + UploadPanel, + FilePreviewer, } from './components'; const route = useRoute();
暂不支持预览.{{ fileExtension }} 类型的文件