diff --git a/src/apis/common/common.ts b/src/apis/common/common.ts index c955c06..74ce0c0 100644 --- a/src/apis/common/common.ts +++ b/src/apis/common/common.ts @@ -18,3 +18,8 @@ export function listRoleDict(query?: { name: string; status: number }) { export function listCommonDict(code: string) { return http.get(`${BASE_URL}/dict/${code}`) } + +/** @desc 上传文件 */ +export function uploadFile(data: FormData) { + return http.post(`${BASE_URL}/file`, data) +} \ No newline at end of file diff --git a/src/apis/system/file.ts b/src/apis/system/file.ts new file mode 100644 index 0000000..7da1f66 --- /dev/null +++ b/src/apis/system/file.ts @@ -0,0 +1,19 @@ +import http from '@/utils/http' +import type * as System from './type' + +const BASE_URL = '/system/file' + +/** @desc 查询文件列表 */ +export function listFile(query: System.FileQuery) { + return http.get(`${BASE_URL}/list`, query) +} + +/** @desc 修改文件 */ +export function updateFile(data: any, id: string) { + return http.put(`${BASE_URL}/${id}`, data) +} + +/** @desc 删除文件 */ +export function deleteFile(ids: string | Array) { + return http.del(`${BASE_URL}/${ids}`) +} diff --git a/src/apis/system/index.ts b/src/apis/system/index.ts index 6d49212..671f65b 100644 --- a/src/apis/system/index.ts +++ b/src/apis/system/index.ts @@ -1,4 +1,5 @@ export * from './dept' export * from './log' export * from './dict' +export * from './file' export * from './storage' diff --git a/src/apis/system/type.ts b/src/apis/system/type.ts index d807ac3..b7d4923 100644 --- a/src/apis/system/type.ts +++ b/src/apis/system/type.ts @@ -91,6 +91,25 @@ export interface DictItemQuery extends PageQuery { dictId: string } +/** 系统文件类型 */ +export type FileItem = { + id: string + name: string + size: number + url: string + extension: string + type: number + storageId: string + createUserString: string + createTime: string + updateUserString: string + updateTime: string +} +export interface FileQuery extends PageQuery { + name?: string + type?: string +} + /** 系统存储类型 */ export type StorageResp = { id: string diff --git a/src/assets/icons/menu-file.svg b/src/assets/icons/menu-file.svg new file mode 100644 index 0000000..d2a1c8a --- /dev/null +++ b/src/assets/icons/menu-file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/views/system/file/components/FileAudioModal/ModalContent.vue b/src/views/system/file/components/FileAudioModal/ModalContent.vue new file mode 100644 index 0000000..ff0c30f --- /dev/null +++ b/src/views/system/file/components/FileAudioModal/ModalContent.vue @@ -0,0 +1,140 @@ + + + + + diff --git a/src/views/system/file/components/FileAudioModal/index.ts b/src/views/system/file/components/FileAudioModal/index.ts new file mode 100644 index 0000000..3537c5e --- /dev/null +++ b/src/views/system/file/components/FileAudioModal/index.ts @@ -0,0 +1,45 @@ +import type { Component } from 'vue' +import { createApp } from 'vue' +import ArcoVueIcon from '@arco-design/web-vue/es/icon' +import ArcoVue from '@arco-design/web-vue' +import type { FileItem } from '@/apis' + +import ModalContent from './ModalContent.vue' + +function createModal void }>(component: Component, options?: T) { + // 创建一个挂载容器 + const el: HTMLElement = document.createElement('div') + // 挂载组件 + document.body.appendChild(el) + + // 实例化组件, createApp 第二个参数是 props + const instance = createApp(component, { + ...options, + onClose: () => { + setTimeout(() => { + instance.unmount() + document.body.removeChild(el) + options?.callback && options?.callback() + }, 350) + } + }) + + instance.use(ArcoVue) + instance.use(ArcoVueIcon) + instance.mount(el) +} +type TFileOptions = { data: FileItem; callback?: () => void } + +/** 预览 音频文件 弹窗 */ +let fileAudioId = '' +export function previewFileAudioModal(data: FileItem) { + if (fileAudioId) return // 防止重复打开 + fileAudioId = data.id + return createModal(ModalContent, { + data: data, + // 关闭的回调 + callback: () => { + fileAudioId = '' + } + }) +} diff --git a/src/views/system/file/components/FileDetailModal/ModalContent.vue b/src/views/system/file/components/FileDetailModal/ModalContent.vue new file mode 100644 index 0000000..3c40275 --- /dev/null +++ b/src/views/system/file/components/FileDetailModal/ModalContent.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/src/views/system/file/components/FileDetailModal/index.ts b/src/views/system/file/components/FileDetailModal/index.ts new file mode 100644 index 0000000..2d69b0c --- /dev/null +++ b/src/views/system/file/components/FileDetailModal/index.ts @@ -0,0 +1,17 @@ +import type { FileItem } from '@/apis' +import { h } from 'vue' +import { Modal } from '@arco-design/web-vue' +import ModalContent from './ModalContent.vue' + +/** 打开 详情 弹窗 */ +export function openFileDetailModal(fileItem: FileItem) { + return Modal.open({ + title: fileItem.extension ? `${fileItem.name}.${fileItem.extension}` : `${fileItem.name}`, + titleAlign: 'start', + modalAnimationName: 'el-fade', + modalStyle: { maxWidth: '320px' }, + width: '90%', + footer: false, + content: () => h(ModalContent, { data: fileItem }) + }) +} diff --git a/src/views/system/file/components/FileRenameModal/ModalContent.vue b/src/views/system/file/components/FileRenameModal/ModalContent.vue new file mode 100644 index 0000000..f0da9f7 --- /dev/null +++ b/src/views/system/file/components/FileRenameModal/ModalContent.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/src/views/system/file/components/FileRenameModal/index.ts b/src/views/system/file/components/FileRenameModal/index.ts new file mode 100644 index 0000000..0abf99a --- /dev/null +++ b/src/views/system/file/components/FileRenameModal/index.ts @@ -0,0 +1,27 @@ +import { updateFile, type FileItem } from '@/apis' +import { ref, h } from 'vue' +import { Modal, Message } from '@arco-design/web-vue' +import ModalContent from './ModalContent.vue' + +export function openFileRenameModal(data: FileItem) { + const ModalContentRef = ref>() + return Modal.open({ + title: '重命名', + modalAnimationName: 'el-fade', + modalStyle: { maxWidth: '450px' }, + width: '90%', + content: () => + h(ModalContent, { + ref: (e) => { + ModalContentRef.value = e as any + } + }), + onBeforeOk: async () => { + const isInvalid = await ModalContentRef.value?.formRef?.validate() + if (isInvalid) return false + await updateFile({ name: data.name }, data.id) + Message.success('重命名成功') + return true + } + }) +} diff --git a/src/views/system/file/components/FileVideoModal/ModalContent.vue b/src/views/system/file/components/FileVideoModal/ModalContent.vue new file mode 100644 index 0000000..2bc15ec --- /dev/null +++ b/src/views/system/file/components/FileVideoModal/ModalContent.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/src/views/system/file/components/FileVideoModal/index.ts b/src/views/system/file/components/FileVideoModal/index.ts new file mode 100644 index 0000000..0e50026 --- /dev/null +++ b/src/views/system/file/components/FileVideoModal/index.ts @@ -0,0 +1,13 @@ +import { h } from 'vue' +import { Modal } from '@arco-design/web-vue' +import ModalContent from './ModalContent.vue' +import type { FileItem } from '@/apis' + +export function previewFileVideoModal(data: FileItem) { + return Modal.open({ + title: '视频播放', + width: 'auto', + modalStyle: {}, + content: () => h(ModalContent, { data: data }) + }) +} diff --git a/src/views/system/file/components/index.ts b/src/views/system/file/components/index.ts new file mode 100644 index 0000000..eca36d0 --- /dev/null +++ b/src/views/system/file/components/index.ts @@ -0,0 +1,4 @@ +export * from '../components/FileDetailModal/index' +export * from '../components/FileRenameModal/index' +export * from '../components/FileVideoModal/index' +export * from '../components/FileAudioModal/index' diff --git a/src/views/system/file/index.vue b/src/views/system/file/index.vue new file mode 100644 index 0000000..be529ad --- /dev/null +++ b/src/views/system/file/index.vue @@ -0,0 +1,25 @@ + + + + + diff --git a/src/views/system/file/main/FileAside.vue b/src/views/system/file/main/FileAside.vue new file mode 100644 index 0000000..2692a53 --- /dev/null +++ b/src/views/system/file/main/FileAside.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/src/views/system/file/main/FileMain/FileGrid.vue b/src/views/system/file/main/FileMain/FileGrid.vue new file mode 100644 index 0000000..ebd4717 --- /dev/null +++ b/src/views/system/file/main/FileMain/FileGrid.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/src/views/system/file/main/FileMain/FileImage.vue b/src/views/system/file/main/FileMain/FileImage.vue new file mode 100644 index 0000000..fa4a7ee --- /dev/null +++ b/src/views/system/file/main/FileMain/FileImage.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/src/views/system/file/main/FileMain/FileList.vue b/src/views/system/file/main/FileMain/FileList.vue new file mode 100644 index 0000000..29fb5da --- /dev/null +++ b/src/views/system/file/main/FileMain/FileList.vue @@ -0,0 +1,135 @@ + + + + + diff --git a/src/views/system/file/main/FileMain/FileRightMenu.vue b/src/views/system/file/main/FileMain/FileRightMenu.vue new file mode 100644 index 0000000..13e52e4 --- /dev/null +++ b/src/views/system/file/main/FileMain/FileRightMenu.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/src/views/system/file/main/FileMain/index.vue b/src/views/system/file/main/FileMain/index.vue new file mode 100644 index 0000000..748f0b5 --- /dev/null +++ b/src/views/system/file/main/FileMain/index.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/system/file/main/FileMain/useFileManage.ts b/src/views/system/file/main/FileMain/useFileManage.ts new file mode 100644 index 0000000..a198040 --- /dev/null +++ b/src/views/system/file/main/FileMain/useFileManage.ts @@ -0,0 +1,33 @@ +import { ref, computed } from 'vue' +import type { FileItem } from '@/apis' + +type Mode = 'grid' | 'list' + +export default function () { + const mode = ref('grid') + const selectedFileList = ref([]) // 已选的文件列表 + const selectedFileIds = computed(() => selectedFileList.value.map((i) => i.id)) + + // 切换视图 + const toggleMode = () => { + mode.value = mode.value === 'grid' ? 'list' : 'grid' + } + + // 添加选择的文件 + const addSelectedFileItem = (item: FileItem) => { + if (selectedFileIds.value.includes(item.id)) { + const index = selectedFileList.value.findIndex((i) => i.id === item.id) + selectedFileList.value.splice(index, 1) + } else { + selectedFileList.value.push(item) + } + } + + return { + mode, + selectedFileList, + selectedFileIds, + toggleMode, + addSelectedFileItem + } +}