diff --git a/src/views/bussiness-data/bussiness.vue b/src/views/bussiness-data/bussiness.vue index 4c4cb9a..550c414 100644 --- a/src/views/bussiness-data/bussiness.vue +++ b/src/views/bussiness-data/bussiness.vue @@ -114,270 +114,45 @@ - - - - - - 上传文件 - - - - 新建文件夹 - - + + - -
-
- 文件列表 ({{ fileList.length }}) -
-
- -
-
- - - - - - - - - - - -
- - - -
- 文件名 -
-
-
-
-
-
- -
- 类型 -
-
-
-
-
-
- -
- 大小 -
-
-
-
-
-
- -
- 修改时间 -
-
-
-
-
-
- 操作 -
- - - - - -
- -
- {{ file.fileName || file.name }} -
{{ file.fileName || file.name }}
-
-
-
- - - -
{{ fileTypeText(getFileExtension(file.fileName || file.name)) }}
-
- - - -
{{ formatFileListSize(file.fileSize || file.size) }}
-
- - - -
{{ formatUploadTime(file.uploadTime || file.uploadTime) }}
-
- - - -
- - - - - - - - - - - - -
-
-
-
+ -
- -
- - - - - - +
@@ -417,128 +192,13 @@ - - + - - - -
- - - - - 点击选择文件 - - - - -
- 支持 {{ allowedFileTypesText }} 等格式,单个文件不超过 {{ maxFileSizeText }} -
-
- - -
-
-
- -
-
{{ file.name }}
-
- {{ formatFileSize(file.size) }} - {{ file.error }} -
-
-
- - -
- -
- - -
- - - - - - -
-
-
-
- - - - - 根目录 - - {{ folder.name }} - - - -
-
+ :folder-list="folderList" + :current-folder-id="currentFolderId" + @upload-success="handleUploadSuccess" + /> // 导入核心依赖 import { ref, reactive, onMounted, computed, watch, nextTick, h } from 'vue'; +// 导入子组件 +import FilePagination from './components/FilePagination.vue'; +import FileHeader from './components/FileHeader.vue'; +import FileList from './components/FileList.vue'; +import FileUpload from './components/FileUpload.vue'; import { IconFolder, IconFile, IconPlus, - IconUpload, + IconMenuFold, IconMenuUnfold, IconEye, @@ -598,10 +263,10 @@ import { IconRefresh, IconEdit, IconFolderAdd, - IconStop + } from '@arco-design/web-vue/es/icon'; import { Message, Modal } from '@arco-design/web-vue'; -import axios from 'axios'; + // 导入API import { @@ -612,7 +277,7 @@ import { deleteFolderApi, deleteFileApi, downloadFileApi, - uploadFileApi, + updateFileNameApi, renameFileApi, previewFileApi @@ -665,47 +330,10 @@ const folderRules = { ] }; -// 上传相关状态 -const uploadForm = reactive({ - folderId: '' -}); -const fileListTemp = ref([]); const folderFormRef = ref(null); -const uploadFormRef = ref(null); -const uploadRef = ref(null); const folderColor = 'var(--color-primary)'; const refreshing = ref(false); const folderSubmitting = ref(false); -const uploading = ref(false); -const allowedFileTypes = '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.zip,.txt,.jpg,.jpeg,.png,.gif,.bmp,.webp'; -const allowedFileTypesText = 'PDF, Word, Excel, PPT, 压缩文件, 文本文件, 图片文件'; -const maxFileSize = 1000 * 1024 * 1024; // 1000MB -const maxFileSizeText = '1000MB'; -const cancelTokens = ref({}); - -// 计算属性:是否有文件可上传 -const hasFiles = computed(() => { - console.log('=== hasFiles计算属性执行 ==='); - console.log('原始fileListTemp:', fileListTemp.value); - console.log('fileListTemp长度:', fileListTemp.value.length); - - const validFiles = fileListTemp.value.filter(file => { - const isValid = !file.error && file.status !== 'removed' && file.status !== 'canceled'; - console.log(`文件 ${file.name}: error=${file.error}, status=${file.status}, isValid=${isValid}`); - return isValid; - }); - - console.log('过滤后的有效文件:', validFiles); - console.log('有效文件数量:', validFiles.length); - console.log('hasFiles结果:', validFiles.length > 0); - - return validFiles.length > 0; -}); - -// 计算属性:是否可以上传 -const canUpload = computed(() => { - return hasFiles.value && !uploading.value && uploadForm.folderId; -}); // 计算属性:将平铺的文件夹数据转换为树形结构 const folderTreeData = computed(() => { @@ -1040,8 +668,12 @@ const loadFiles = async (folderId) => { if (sortField.value && sortOrder.value) { apiParams.sortField = sortField.value; apiParams.sortOrder = sortOrder.value; + console.log('📤 发送排序参数:', apiParams.sortField, apiParams.sortOrder); + } else { + console.log('📤 未发送排序参数'); } + console.log('📤 发送API参数:', apiParams); const res = await getFilesApi(apiParams); // 根据后端返回的数据结构处理 @@ -1066,21 +698,34 @@ const loadFiles = async (folderId) => { // 排序处理函数 const handleSortChange = (field) => { - const backendField = sortFieldMap[field]; + console.log('=== 排序处理函数被调用 ==='); + console.log('传入的字段:', field); - if (!backendField) return; + const backendField = sortFieldMap[field]; + console.log('映射后的后端字段:', backendField); + + if (!backendField) { + console.log('❌ 找不到对应的后端字段,退出'); + return; + } + + console.log('当前排序字段:', sortField.value); + console.log('当前排序方向:', sortOrder.value); // 切换排序方向 if (sortField.value === backendField) { sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc'; + console.log('✅ 切换排序方向为:', sortOrder.value); } else { // 新字段,默认降序 sortField.value = backendField; sortOrder.value = 'desc'; + console.log('✅ 设置新排序字段:', sortField.value, '排序方向:', sortOrder.value); } // 重新加载文件列表 if (currentFolderId.value) { + console.log('🔄 重新加载文件列表,文件夹ID:', currentFolderId.value); loadFiles(currentFolderId.value); } }; @@ -1258,7 +903,7 @@ const handleRenameFolder = (folder) => { } const folderId = folder.key || folder.id; - const currentName = folder.title || folder.name; + let currentName = folder.title || folder.name; if (!folderId) { Message.error('文件夹ID不能为空'); @@ -1435,159 +1080,9 @@ const submitFolderForm = async () => { } }; -// 格式化上传时间 -const formatUploadTime = (timeStr) => { - if (!timeStr) return '未知时间'; - const date = new Date(timeStr); - return date.toLocaleString('zh-CN', { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - second: '2-digit', - hour12: false - }); -}; -// 文件变化处理 -const handleFileChange = (info) => { - console.log('=== 文件变化事件 ==='); - console.log('完整info对象:', info); - - // 安全检查:确保 info 存在且是数组 - if (!info || !Array.isArray(info)) { - console.log('❌ info 不存在或不是数组,跳过处理'); - return; - } - - const fileList = info; - console.log('文件列表:', fileList); - console.log('文件列表长度:', fileList.length); - - // 检查是否是组件内部状态触发的(可能是之前的状态) - if (fileList.length === 0) { - console.log('⚠️ 文件列表为空,可能是组件内部状态,跳过处理'); - return; - } - - // 检查是否是对话框刚打开时的触发(可能是之前的状态) - if (!uploadDialogVisible.value) { - console.log('⚠️ 对话框未显示,可能是之前的状态触发,跳过处理'); - return; - } - - // 获取当前已存在的文件UID列表,用于去重 - const existingUids = fileListTemp.value.map(f => f.uid); - console.log('已存在的文件UID:', existingUids); - - // 获取当前文件夹中已存在的文件名列表,用于检查重复 - const currentFolderFiles = fileList.value || []; - const existingFileNames = currentFolderFiles.map(f => f.fileName || f.name); - console.log('当前文件夹中的文件:', existingFileNames); - - // 强制重置上传组件状态 - if (uploadRef.value) { - try { - uploadRef.value.reset(); - console.log('已强制重置上传组件'); - } catch (error) { - console.log('重置上传组件时出错:', error); - } - } - - // 处理新选择的文件 - 支持多文件选择,同时避免重复 - fileList.forEach((file, index) => { - console.log(`处理第${index + 1}个文件:`, file); - console.log('文件名称:', file.name); - console.log('文件大小:', file.size); - console.log('文件UID:', file.uid); - console.log('文件对象结构:', Object.keys(file)); - - // 检查文件是否已存在(去重) - if (existingUids.includes(file.uid)) { - console.log('⚠️ 文件已存在,跳过:', file.name); - return; - } - - // 确保文件对象有正确的属性 - const fileObj = { - uid: file.uid, - name: file.name, - size: file.size || file.file?.size || 0, - type: file.type || file.file?.type || '', - status: 'ready', - error: '', - originFileObj: file.file || file // 保存原始File对象 - }; - - console.log('开始验证新文件...'); - - // 检查文件是否已存在于当前文件夹中 - if (existingFileNames.includes(fileObj.name)) { - fileObj.error = '文件已存在于当前文件夹中'; - console.log('⚠️ 文件已存在于文件夹中:', fileObj.name); - // 显示友好的提示信息 - Message.warning(`文件 "${fileObj.name}" 已存在于当前文件夹中,已跳过`); - return; - } - - // 验证文件 - const isValid = validateFile(fileObj); - console.log('文件验证结果:', isValid); - - if (isValid) { - // 支持多文件:添加到列表 - fileListTemp.value.push(fileObj); - console.log('✅ 成功添加文件到列表:', fileObj.name); - } else { - console.log('❌ 文件验证失败:', fileObj.name, '错误:', fileObj.error); - } - }); - - console.log('=== 当前文件列表状态 ==='); - console.log('fileListTemp长度:', fileListTemp.value.length); - console.log('fileListTemp内容:', fileListTemp.value); - console.log('hasFiles计算结果:', hasFiles.value); -}; -// 文件验证 -const validateFile = (file) => { - console.log('=== 开始验证文件 ==='); - console.log('验证文件:', file.name); - console.log('文件大小:', file.size); - - // 清除之前的错误 - file.error = ''; - - // 验证文件类型 - const ext = getFileExtension(file.name).toLowerCase(); - console.log('文件扩展名:', ext); - - const allowedExts = allowedFileTypes - .split(',') - .map(type => type.toLowerCase().replace(/^\./, '')); - - console.log('允许的扩展名:', allowedExts); - console.log('扩展名是否匹配:', allowedExts.includes(ext)); - - if (!allowedExts.includes(ext)) { - file.error = `不支持的文件类型,支持: ${allowedFileTypesText}`; - console.log('❌ 文件类型验证失败:', file.error); - return false; - } - - // 验证文件大小 - console.log('文件大小验证:', file.size, '<=', maxFileSize); - if (file.size > maxFileSize) { - file.error = `文件过大,最大支持 ${maxFileSizeText}`; - console.log('❌ 文件大小验证失败:', file.error); - return false; - } - - console.log('✅ 文件验证通过'); - return true; -}; + // 获取文件扩展名 const getFileExtension = (fileName) => { @@ -1595,157 +1090,6 @@ const getFileExtension = (fileName) => { return lastDotIndex > 0 ? fileName.slice(lastDotIndex + 1) : ''; }; -// 获取文件图标颜色 -const fileColor = (extension) => { - const colorMap = { - pdf: '#ff4d4f', - doc: '#1890ff', - docx: '#1890ff', - xls: '#52c41a', - xlsx: '#52c41a', - ppt: '#faad14', - pptx: '#faad14', - zip: '#722ed1', - txt: '#8c8c8c', - // 图片格式颜色 - jpg: '#52c41a', - jpeg: '#52c41a', - png: '#1890ff', - gif: '#faad14', - bmp: '#722ed1', - webp: '#13c2c2' - }; - return colorMap[extension.toLowerCase()] || 'var(--color-text-3)'; -}; - - - -// 移除文件 -const removeFile = (file) => { - fileListTemp.value = fileListTemp.value.filter(f => f.uid !== file.uid); - - // 如果是正在上传的文件,取消请求 - if (file.status === 'uploading' && cancelTokens.value[file.uid]) { - cancelTokens.value[file.uid].cancel('上传已取消'); - delete cancelTokens.value[file.uid]; - } -}; - -// 取消上传 -const cancelUpload = (file) => { - if (cancelTokens.value[file.uid]) { - cancelTokens.value[file.uid].cancel('上传已取消'); - file.status = 'canceled'; - } -}; - -// 提交上传 -const handleUploadSubmit = async () => { - // 过滤有效文件 - const validFiles = fileListTemp.value.filter(file => - !file.error && file.status !== 'removed' && file.status !== 'canceled' - ); - - if (validFiles.length === 0) { - Message.warning('请选择有效的文件'); - return; - } - - // 验证文件夹ID - if (!uploadForm.folderId) { - Message.warning('请选择目标文件夹'); - return; - } - - uploading.value = true; - let hasError = false; - let hasFileExists = false; - - for (const fileItem of validFiles) { - // 获取原始File对象 - const realFile = fileItem.originFileObj || fileItem; - - if (!realFile) { - hasError = true; - continue; - } - - fileItem.status = 'uploading'; - fileItem.percent = 0; - - // 创建取消令牌 - const source = axios.CancelToken.source(); - cancelTokens.value[fileItem.uid] = source; - - // 调用API - const result = await uploadFileApi( - realFile, - Number(uploadForm.folderId), - (progressEvent) => { - if (progressEvent.lengthComputable) { - fileItem.percent = Math.round((progressEvent.loaded / progressEvent.total) * 100); - } - }, - source.token - ); - - // 检查上传结果 - if (result.code === 200) { - fileItem.status = 'success'; - fileItem.percent = 100; - } else if (result.code === 400 && result.msg && result.msg.includes('已存在')) { - // 文件已存在的情况 - fileItem.status = 'error'; - fileItem.error = '文件已存在'; - hasFileExists = true; - } else { - fileItem.status = 'error'; - fileItem.error = result.msg || '上传失败'; - hasError = true; - } - } - - // 根据结果显示相应的消息 - if (hasFileExists && !hasError) { - Message.warning('文件已存在'); - } else if (hasError) { - Message.error('上传失败'); - } else { - Message.success('上传成功'); - // 刷新当前文件夹文件列表 - if (currentFolderId.value === uploadForm.folderId) { - loadFiles(currentFolderId.value); - } - } - - resetUpload(); -}; - -// 重置上传表单 -const resetUpload = () => { - console.log('=== 重置上传表单 ==='); - - // 取消所有正在进行的上传 - Object.values(cancelTokens.value).forEach(source => { - source.cancel('上传已取消'); - }); - - // 重置所有状态 - uploadDialogVisible.value = false; - uploadForm.folderId = currentFolderId.value || ''; - fileListTemp.value = []; - cancelTokens.value = {}; - uploading.value = false; - - // 清空上传组件 - if (uploadRef.value) { - uploadRef.value.reset(); - console.log('已重置上传组件'); - } - - console.log('上传表单重置完成'); -}; - // 预览文件 const handlePreview = async (file) => { try { @@ -2316,57 +1660,13 @@ const handleDelete = (file) => { }); }; -// 格式化文件大小 -const formatFileSize = (fileSize) => { - const size = Number(fileSize); - if (isNaN(size) || size < 0) return '未知'; - - if (size < 1024) return `${size} B`; - if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)} KB`; - if (size < 1024 * 1024 * 1024) return `${(size / (1024 * 1024)).toFixed(1)} MB`; - return `${(size / (1024 * 1024 * 1024)).toFixed(1)} GB`; -}; - -// 专门用于文件列表的格式化函数(假设后端返回的是KB单位) -const formatFileListSize = (fileSize) => { - const size = Number(fileSize); - if (isNaN(size) || size < 0) return '未知'; - - // 假设后端返回的是KB单位 - if (size < 1024) { - return `${size} KB`; - } else if (size < 1024 * 1024) { - return `${(size / 1024).toFixed(1)} MB`; - } else { - return `${(size / (1024 * 1024)).toFixed(1)} GB`; - } -}; -const fileTypeText = (type) => { - const types = { - pdf: 'PDF文档', - doc: 'Word文档', - docx: 'Word文档', - xls: 'Excel表格', - xlsx: 'Excel表格', - ppt: 'PPT演示', - pptx: 'PPT演示', - zip: '压缩文件', - txt: '文本文件', - // 图片格式 - jpg: 'JPG图片', - jpeg: 'JPEG图片', - png: 'PNG图片', - gif: 'GIF图片', - bmp: 'BMP图片', - webp: 'WebP图片', - unknown: '未知类型' - }; - - return types[type] || type; -}; + + + + // 侧边栏控制 const sidebarCollapsed = ref(false); @@ -2461,29 +1761,17 @@ const handleCreateFolder = () => { // 打开上传文件对话框 const handleUploadFile = () => { - // 清空文件列表,避免显示之前上传的文件 - fileListTemp.value = []; - - // 重置上传组件状态 - if (uploadRef.value) { - try { - uploadRef.value.reset(); - // 强制清空组件的内部文件列表 - if (uploadRef.value.fileList) { - uploadRef.value.fileList = []; - } - if (uploadRef.value.fileListTemp) { - uploadRef.value.fileListTemp = []; - } - } catch (error) { - console.log('重置上传组件时出错:', error); - } - } - - uploadForm.folderId = currentFolderId.value || ''; uploadDialogVisible.value = true; }; +// 上传成功回调 +const handleUploadSuccess = () => { + // 刷新当前文件夹文件列表 + if (currentFolderId.value) { + loadFiles(currentFolderId.value); + } +}; + // 侧边栏控制函数 const handleSidebarCollapse = (collapsed) => { sidebarCollapsed.value = collapsed; @@ -2500,38 +1788,7 @@ watch(currentFolderId, (newId) => { } }); -// 监听上传对话框显示状态,确保文件列表清空 -watch(uploadDialogVisible, (visible) => { - if (visible) { - console.log('=== 上传对话框已显示,确保文件列表清空 ==='); - // 立即清空文件列表 - fileListTemp.value = []; - console.log('✅ 已清空文件列表'); - - // 强制重置上传组件 - if (uploadRef.value) { - try { - uploadRef.value.reset(); - // 强制清空组件的内部文件列表 - if (uploadRef.value.fileList) { - uploadRef.value.fileList = []; - } - if (uploadRef.value.fileListTemp) { - uploadRef.value.fileListTemp = []; - } - console.log('✅ 已重置上传组件'); - } catch (error) { - console.log('❌ 重置上传组件时出错:', error); - } - } - - // 延迟再次清空,确保处理完所有可能的触发 - setTimeout(() => { - fileListTemp.value = []; - console.log('✅ 延迟清空文件列表'); - }, 100); - } -}); + @@ -2695,22 +1952,7 @@ onMounted(() => { /* 删除旧的span样式,因为现在使用.folder-name */ -/* 顶部导航样式 */ -.file-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 0 24px; - background: var(--color-bg-1); - border-bottom: 1px solid var(--color-border); - height: 64px; -} -.breadcrumbs { - display: flex; - align-items: center; - gap: 8px; -} /* 文件内容区域样式 */ .file-content { @@ -2739,360 +1981,13 @@ onMounted(() => { padding-bottom: 80px; /* 为分页器留出空间 */ } -/* 表格容器 */ -.file-grid-container { - flex: 1; - width: 100%; - margin-top: 16px; - border-radius: 8px; - border: 1px solid var(--color-border); - overflow-y: auto; - background-color: var(--color-bg-1); - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); - margin-bottom: 0; - min-height: 300px; - max-height: calc(100vh - 380px); /* 调整高度为分页器留出空间 */ -} -/* 表头行样式 */ -.table-header-row { - padding: 0 16px; - height: 48px; - line-height: 48px; - background-color: var(--color-fill-1); - border-bottom: 1px solid var(--color-border); - font-size: 13px; - color: var(--color-text-3); - font-weight: 500; -} -/* 数据行样式 */ -.table-data-row { - display: flex; - padding: 0 16px; - height: 64px; - align-items: center; - border-bottom: 1px solid var(--color-border); - transition: all 0.25s ease; - cursor: pointer; - background-color: var(--color-bg-1); - - &:last-child { - border-bottom: none; - } - - &:hover { - background-color: rgba(22, 93, 255, 0.1); - transform: translateY(-1px); - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05); - } -} -/* 通用列样式 */ -.table-column { - height: 100%; - width: 100%; - display: flex; - align-items: center; - justify-content: center; - overflow: hidden; - white-space: nowrap; - padding: 0 8px; -} -.cell-content { - display: inline-block; - width: 100%; - text-align: center; - justify-content: center; - align-items: center; -} -.name-column { - padding: 0 14px; - justify-content: flex-start !important; -} -.file-info { - display: flex; - align-items: center; - width: 100%; -} -.file-icon { - font-size: 20px; - margin-right: 12px; - width: 24px; - height: 24px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 4px; -} - -.folder-icon { - color: var(--color-primary); - background-color: var(--color-primary-light-1); -} - -.file-name { - font-size: 14px; - font-weight: 500; - max-width: 220px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - transition: color 0.2s ease; -} - -.table-data-row:hover .file-name { - color: var(--color-primary); -} - -.type-column, .size-column, .time-column { - color: var(--color-text-3); - font-size: 14px; - justify-content: center; - align-items: center; - padding: 4px; -} - -.action-column { - justify-content: center; -} - -.file-main { - display: flex; - align-items: center; - width: 100%; -} - -.file-icon-large { - font-size: 24px; - margin-right: 12px; - flex-shrink: 0; -} - -.file-name-wrap { - flex: 1; - overflow: hidden; - min-width: 0; - display: flex; - justify-content: center; -} - -.file-name { - margin: 0; - font-size: 14px; - color: var(--color-text-1); - transition: color 0.2s; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - - .table-data-row:hover & { - color: var(--color-primary); - } -} - -.file-name-small { - font-size: 14px; - color: var(--color-text-4); - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - text-align: center; - display: flex; - justify-content: center; - align-items: center; - width: 100%; -} - -/* 操作按钮区域 */ -.file-actions { - display: flex; - gap: 4px; - justify-content: center; -} - -.action-btn { - width: 24px; - height: 24px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 4px; - background: transparent; - border: none; - cursor: pointer; - transition: all 0.2s ease; - color: var(--color-text-3); - - &:hover { - background: var(--color-fill-3); - color: var(--color-primary); - } -} - -.delete-btn { - &:hover { - color: var(--color-danger); - background-color: rgba(255, 77, 77, 0.05); - } -} - -/* 响应式调整 */ -@media (max-width: 1200px) { - .name-column { - flex: 0 0 35% !important; - max-width: 35% !important; - } - .time-column { - flex: 0 0 20% !important; - max-width: 20% !important; - } -} - -@media (max-width: 992px) { - .name-column { - flex: 0 0 45% !important; - max-width: 45% !important; - } - .type-column { - flex: 0 0 20% !important; - max-width: 20% !important; - } - .time-column { - display: none; - } - .action-column { - flex: 0 0 35% !important; - max-width: 35% !important; - } - .file-actions { - justify-content: flex-end; - } -} - -@media (max-width: 768px) { - .size-column, .time-column { - display: none; - } - .type-column { - flex: 0 0 25% !important; - max-width: 25% !important; - } - .name-column { - flex: 0 0 45% !important; - max-width: 45% !important; - } - .action-column { - flex: 0 0 30% !important; - max-width: 30% !important; - } - .file-content { - padding: 12px; - } - .file-grid-container { - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } -} - -@media (max-width: 576px) { - .type-column { - display: none; - } - .name-column { - flex: 0 0 60% !important; - max-width: 60% !important; - } - .action-column { - flex: 0 0 40% !important; - max-width: 40% !important; - } - .file-header { - padding: 0 12px; - flex-wrap: wrap; - } - .breadcrumbs { - margin-bottom: 8px; - width: 100%; - } - .file-card { - min-height: auto; - } -} - -/* 浏览器缩放调整 */ -@media (max-height: 800px) { - .folder-content { - max-height: calc(100vh - 180px); - } - - .file-content { - max-height: calc(100vh - 100px); - } - - .file-grid-container { - max-height: calc(100vh - 280px); - } -} - -@media (max-height: 600px) { - .folder-content { - max-height: calc(100vh - 160px); - } - - .file-content { - max-height: calc(100vh - 80px); - } - - .file-grid-container { - max-height: calc(100vh - 260px); - } -} - -/* 空状态样式 */ -.initial-state, .empty-state { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: 64px 0; - color: var(--color-text-3); - background-color: var(--color-fill-1); - border-radius: 8px; - text-align: center; -} - -.initial-icon { - font-size: 48px; - margin-bottom: 16px; - color: var(--color-text-4); -} - -:deep(.empty-state .arco-btn) { - margin-top: 16px; - padding: 8px 16px; - background-color: var(--color-primary); - color: white; - border-radius: 4px; - border: none; - cursor: pointer; - transition: all 0.2s ease; - font-weight: 500; -} - -:deep(.empty-state .arco-btn:hover) { - background-color: var(--color-primary-dark-1); - transform: translateY(-1px); - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); -} - -:deep(.empty-state .arco-btn:active) { - transform: translateY(0); -} /* 上传区域样式 */ .upload-area { @@ -3122,141 +2017,9 @@ onMounted(() => { color: var(--color-text-3); } -.upload-hint { - margin-top: 8px; - font-size: 12px; - color: var(--color-text-4); -} -/* 上传相关样式 */ -.upload-file-list { - margin-top: 16px; - border-radius: 4px; - border: 1px solid var(--color-border); - overflow: hidden; -} -.upload-file-item { - display: flex; - align-items: center; - padding: 12px; - border-bottom: 1px solid var(--color-border); - - &:last-child { - border-bottom: none; - } - - &:hover { - background-color: var(--color-fill-1); - } -} -.file-info { - display: flex; - align-items: center; - flex: 1; - min-width: 0; -} - -.file-icon { - font-size: 20px; - margin-right: 12px; - flex-shrink: 0; -} - -.file-name { - flex: 1; - min-width: 0; -} - -.name-text { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - font-size: 14px; -} - -.file-meta { - font-size: 12px; - color: var(--color-text-4); - margin-top: 4px; -} - -.file-error { - color: var(--color-danger); - margin-left: 8px; -} - -.file-progress { - flex: 1; - margin: 0 16px; -} - -.file-actions { - flex-shrink: 0; -} - -/* 分页样式 */ -.pagination-container { - position: absolute; - bottom: 0; - left: 0; - right: 0; - background: var(--color-bg-1); - padding: 16px 24px; - border-top: 1px solid var(--color-border); - display: flex; - justify-content: flex-end; - align-items: center; - z-index: 10; - box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06); - margin-top: 0; - - .arco-pagination { - margin: 0; - - .arco-pagination-item { - border-radius: 6px; - margin: 0 4px; - transition: all 0.2s ease; - - &:hover { - border-color: var(--color-primary); - color: var(--color-primary); - } - - &.arco-pagination-item-active { - background: var(--color-primary); - border-color: var(--color-primary); - color: white; - } - } - - .arco-pagination-prev, - .arco-pagination-next { - border-radius: 6px; - transition: all 0.2s ease; - - &:hover { - border-color: var(--color-primary); - color: var(--color-primary); - } - } - - .arco-pagination-size-changer { - margin-left: 16px; - } - - .arco-pagination-jumper { - margin-left: 16px; - } - - .arco-pagination-total { - color: var(--color-text-2); - font-size: 14px; - } - } -} @@ -3546,228 +2309,14 @@ onMounted(() => { } } -/* 上传文件相关样式 */ -.upload-container { - display: flex; - flex-direction: column; - gap: 12px; -} -.upload-btn { - align-self: flex-start; - border-radius: 8px; - font-weight: 500; - transition: all 0.3s ease; - - &:hover { - transform: translateY(-1px); - box-shadow: 0 4px 12px rgba(24, 144, 255, 0.3); - } -} - -.upload-hint { - color: var(--color-text-3); - font-size: 12px; - line-height: 1.4; - padding: 8px 12px; - background: var(--color-fill-2); - border-radius: 6px; - border-left: 3px solid var(--color-primary-light-3); -} - -.upload-file-list { - margin-top: 16px; - border: 1px solid var(--color-border); - border-radius: 8px; - background: var(--color-bg-1); - max-height: 300px; - overflow-y: auto; -} - -.upload-file-item { - display: flex; - align-items: center; - padding: 12px 16px; - border-bottom: 1px solid var(--color-border); - transition: all 0.2s ease; - - &:last-child { - border-bottom: none; - } - - &:hover { - background: var(--color-fill-1); - } - - &.file-error { - background: rgba(255, 77, 79, 0.05); - border-left: 3px solid #ff4d4f; - } -} - -.file-info { - display: flex; - align-items: center; - flex: 1; - gap: 12px; - min-width: 0; -} - -.file-icon { - font-size: 20px; - flex-shrink: 0; -} - -.file-details { - flex: 1; - min-width: 0; -} - -.file-name { - font-weight: 500; - color: var(--color-text-1); - margin-bottom: 4px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.file-meta { - font-size: 12px; - color: var(--color-text-3); - display: flex; - align-items: center; - gap: 8px; -} - -.error-text { - color: #ff4d4f; - font-weight: 500; -} - -.file-progress { - margin: 0 16px; - min-width: 120px; -} - -.file-actions { - display: flex; - gap: 4px; -} - -.remove-btn { - color: var(--color-text-3); - - &:hover { - color: #ff4d4f; - background: rgba(255, 77, 79, 0.1); - } -} - -.cancel-btn { - color: var(--color-text-3); - - &:hover { - color: #faad14; - background: rgba(250, 173, 20, 0.1); - } -} @keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } -/* 文件头部容器样式 */ -.file-header-container { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 16px; - padding: 16px 0; -} -.file-title { - display: flex; - align-items: center; -} - -.file-list-title { - font-size: 16px; - font-weight: 600; - color: var(--color-text-1); - margin: 0; -} - -/* 文件搜索样式 */ -.file-search-container { - display: flex; - align-items: center; - gap: 12px; -} - -.file-search-input { - max-width: 300px; - transition: all 0.3s ease; - - &:focus-within { - box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.1); - } -} - -/* 可排序表头样式 */ -.sortable-header { - display: flex; - align-items: center; - justify-content: center; - gap: 6px; - cursor: pointer; - padding: 4px 8px; - border-radius: 4px; - transition: all 0.2s ease; - user-select: none; -} - -.sortable-header:hover { - background: var(--color-fill-2); - color: var(--color-primary); -} - -.sort-indicator { - display: flex; - flex-direction: column; - gap: 1px; - margin-left: 4px; -} - -.sort-arrow { - width: 0; - height: 0; - border-left: 3px solid transparent; - border-right: 3px solid transparent; - transition: all 0.2s ease; -} - -.sort-arrow.up { - border-bottom: 3px solid var(--color-text-4); -} - -.sort-arrow.down { - border-top: 3px solid var(--color-text-4); -} - -.sort-arrow.active { - border-bottom-color: var(--color-primary); - border-top-color: var(--color-primary); -} - -.sortable-header:hover .sort-arrow.up { - border-bottom-color: var(--color-primary); -} - -.sortable-header:hover .sort-arrow.down { - border-top-color: var(--color-primary); -} diff --git a/src/views/bussiness-data/components/FileHeader.vue b/src/views/bussiness-data/components/FileHeader.vue new file mode 100644 index 0000000..6d56a3f --- /dev/null +++ b/src/views/bussiness-data/components/FileHeader.vue @@ -0,0 +1,105 @@ + + + + + diff --git a/src/views/bussiness-data/components/FileList.vue b/src/views/bussiness-data/components/FileList.vue new file mode 100644 index 0000000..4901a88 --- /dev/null +++ b/src/views/bussiness-data/components/FileList.vue @@ -0,0 +1,669 @@ + + + + + diff --git a/src/views/bussiness-data/components/FilePagination.vue b/src/views/bussiness-data/components/FilePagination.vue new file mode 100644 index 0000000..915a632 --- /dev/null +++ b/src/views/bussiness-data/components/FilePagination.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/src/views/bussiness-data/components/FileUpload.vue b/src/views/bussiness-data/components/FileUpload.vue new file mode 100644 index 0000000..4802274 --- /dev/null +++ b/src/views/bussiness-data/components/FileUpload.vue @@ -0,0 +1,557 @@ + + + + +