<template>
|
|
<div class="task-container">
|
<!-- 右上角关闭按钮 -->
|
<div class="close-container">
|
<el-button type="text" icon="el-icon-back" @click="handleClose" class="close-btn">
|
</el-button>
|
</div>
|
|
<!-- 新增文件弹窗 -->
|
<el-dialog :title="dialogType === 'create' ? '上传文件或文件夹' : ''" :visible.sync="dialogVisible" width="800px"
|
custom-class="task-dialog" @closed="handleDialogClose" :close-on-click-modal="false"
|
:close-on-press-escape="false">
|
<!-- 新增文件时显示上传区域 -->
|
<div v-if="dialogType === 'create'" class="upload-area">
|
<!-- 文件选择区域 - 已重构为支持拖拽 -->
|
<div class="upload-container">
|
<!-- 文件拖拽区域 -->
|
<div class="upload-wrapper drag-area" @dragover.prevent="handleDragOver" @dragleave="handleDragLeave"
|
@drop.prevent="handleDrop" :class="{ 'drag-over': isDragOver }">
|
<div class="drag-content">
|
<i class="el-icon-upload"></i>
|
<div class="el-upload__text">拖拽文件或文件夹到此处上传</div>
|
<div class="upload-tip">或</div>
|
<div class="action-buttons">
|
<el-button type="primary" size="small" @click.stop="triggerFileInput">选择文件</el-button>
|
<el-button type="primary" size="small" @click.stop="triggerFolderInput">选择文件夹</el-button>
|
</div>
|
</div>
|
<input type="file" ref="fileInput" multiple style="display: none" @change="handleFileChange">
|
<input type="file" ref="folderInput" webkitdirectory style="display: none" @change="handleFolderChange">
|
</div>
|
</div>
|
|
<!-- 上传文件列表 -->
|
<div class="file-list">
|
<div class="list-header">
|
<!-- <div>图标</div> -->
|
<div>类型</div>
|
<div>名称</div>
|
<div>操作</div>
|
</div>
|
<div class="list-items">
|
<div v-for="(item, index) in uploadList" :key="index" class="file-item">
|
<!-- <div class="item-icon">
|
<i :class="item.type === 'folder' ? 'el-icon-folder' : 'el-icon-document'"></i>
|
</div> -->
|
<div class="item-type">{{ item.type === 'folder' ? '文件夹' : item.fileType || '文件' }}</div>
|
<div class="item-name">{{ item.name }}</div>
|
<div class="item-action">
|
<i class="el-icon-delete" @click="removeFileItem(index)"></i>
|
</div>
|
</div>
|
<div v-if="uploadList.length === 0" class="empty-tip">
|
暂无文件
|
</div>
|
</div>
|
</div>
|
</div>
|
|
<span slot="footer">
|
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-button type="primary" @click="submitTask" :loading="isUploading" :disabled="isUploading">
|
<span v-if="isUploading">上传中...</span>
|
<span v-else>保存</span>
|
</el-button>
|
</span>
|
</el-dialog>
|
|
<!-- 搜索和操作栏 -->
|
<div class="search-bar">
|
<el-input v-model="searchKey" placeholder="请输入名称" clearable class="search-input"></el-input>
|
<el-button type="primary" @click="handleSearch">查询</el-button>
|
<el-button @click="handleReset">重置</el-button>
|
<el-button type="primary" class="new-btn" @click="handleCreate()"><i class="el-icon-plus"></i> 新增文件</el-button>
|
</div>
|
|
<!-- 在表格区域上方添加全局加载状态 -->
|
<div class="global-loading" v-if="isUploading">
|
<div class="loading-content">
|
<i class="el-icon-loading"></i>
|
<p>文件上传中,请稍候...</p>
|
</div>
|
</div>
|
<!-- 任务表格(精确列宽配置) -->
|
<el-table :data="tableData" style="width: 100%" class="data-table" :header-cell-style="{
|
background: '#f5f7fa',
|
color: '#606266'
|
}">
|
<!-- 选择列 -->
|
<!-- <el-table-column type="selection" width="auto" min-width="5%"></el-table-column> -->
|
|
|
<!-- 文件ID -->
|
<el-table-column prop="id" label="文件ID" v-if="false">
|
<template #default="{ row }">
|
<span class="text-ellipsis">{{ row.id }}</span>
|
</template>
|
</el-table-column>
|
<!-- 文件URl -->
|
<el-table-column prop="fileUrl" label="文件URl" v-if="false">
|
<template #default="{ row }">
|
<span class="text-ellipsis">{{ row.fileUrl }}</span>
|
</template>
|
</el-table-column>
|
<!-- 名称 -->
|
<el-table-column prop="fileName" label="名称" width="auto" min-width="180px">
|
<template #default="{ row }">
|
<span class="text-ellipsis">{{ row.fileName }}</span>
|
</template>
|
</el-table-column>
|
<!-- 分块数 -->
|
<el-table-column prop="totalChunks" label="分块数" width="auto" min-width="80px">
|
<template #default="{ row }">
|
<!-- <el-tag class="text-ellipsis">{{ row.modelName }}</el-tag> -->
|
{{ row.totalChunks }}
|
</template>
|
</el-table-column>
|
|
<!-- 上传时间 -->
|
<el-table-column prop="createTime" label="上传时间" width="auto" min-width="80px">
|
<template #default="{ row }">
|
<!-- <span class="level level-1 text-ellipsis">{{ row.createTime }}</span> -->
|
<!-- {{ row.createTime }} -->
|
{{ formatDateTime(row.createTime) }}
|
</template>
|
</el-table-column>
|
<!-- 解析方法 -->
|
<el-table-column prop="parserType" label="解析方法" width="auto" min-width="180px">
|
<template #default="{ row }">
|
<div class="multi-tags">
|
{{ row.parserType }}
|
</div>
|
</template>
|
</el-table-column>
|
|
<!-- 操作 -->
|
<el-table-column label="操作" width="auto" min-width="80px">
|
<template #default="{ row }">
|
<div style="display: flex; gap: 8px">
|
<el-button type="text" icon="el-icon-delete" @click="handleDelete(row)"></el-button>
|
<el-button type="text" icon="el-icon-download" @click="handleDownload(row)"></el-button>
|
</div>
|
</template>
|
</el-table-column>
|
</el-table>
|
|
<!-- 分页 -->
|
<div class="pagination">
|
<el-pagination @current-change="handleCurrentChange" :page-size="10" layout="prev, pager, next"
|
:total="this.pagination.total"></el-pagination>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import Inspection from "@/api/KnowledgeView"
|
export default {
|
props: {
|
knowledgeId: {
|
type: [Number, String],
|
required: true
|
}
|
},
|
data() {
|
return {
|
isUploading: false,
|
uploadList: [], // 上传文件列表
|
isDragOver: false, // 拖拽状态
|
// 新增搜索参数
|
searchParams: {
|
searchKey: '',
|
},
|
// 新增分页参数
|
pagination: {
|
page: 1,
|
pageSize: 10,
|
total: 100,
|
totalPage: 1
|
},
|
// 新增状态管理
|
dialogType: 'create',
|
dialogVisible: false,
|
taskForm: {
|
id: null,
|
fileName: '',
|
taskDescription: "",
|
modelId: '',
|
totalChunks: '',
|
createTime: '',
|
eventLevelName: '',
|
videoIds: [],
|
videoCamera: [],
|
workingTimes: [],
|
checkContents: [],
|
warningRules: []
|
},
|
searchKey: '',
|
currentPage: 1,
|
tableData: []
|
}
|
},
|
mounted() {
|
|
this.handleReset()
|
this.fetchTableData() // 初始化加载数据
|
},
|
methods: {
|
// 添加下载方法
|
async handleDownload(row) {
|
window.location.href="/api/v1/knowledge/download?id="+row.id
|
// try {
|
// const response = await Inspection.downloadFiles({
|
// id: row.id
|
// }, {
|
// responseType: 'blob' // 关键:声明响应类型为二进制数据
|
// });
|
|
// // 创建Blob对象
|
// const blob = new Blob([response.data]);
|
|
// // 创建下载链接
|
// const url = URL.createObjectURL(blob);
|
// const link = document.createElement('a');
|
// link.href = url;
|
|
// // 设置文件名(从响应头提取或使用row.fileName)
|
// const fileName = row.fileName || `file_${row.id}`;
|
// link.download = fileName;
|
|
// // 触发下载
|
// document.body.appendChild(link);
|
// link.click();
|
|
// // 清理资源
|
// setTimeout(() => {
|
// document.body.removeChild(link);
|
// URL.revokeObjectURL(url);
|
// }, 100);
|
|
// } catch (error) {
|
// console.error('下载失败:', error);
|
// this.$message.error('下载失败');
|
// }
|
},
|
// 处理文件拖拽进入区域
|
handleDragOver(e) {
|
e.preventDefault();
|
this.isDragOver = true;
|
},
|
|
// 处理文件拖拽离开区域
|
handleDragLeave() {
|
this.isDragOver = false;
|
},
|
|
// 处理文件放下(拖拽上传)
|
handleDrop(e) {
|
this.isDragOver = false;
|
const items = e.dataTransfer.items;
|
|
if (items) {
|
// 处理文件夹拖拽
|
for (let i = 0; i < items.length; i++) {
|
const entry = items[i].webkitGetAsEntry();
|
if (entry) {
|
this.traverseEntry(entry);
|
}
|
}
|
} else {
|
// 处理文件拖拽
|
const files = e.dataTransfer.files;
|
this.processFiles(Array.from(files));
|
}
|
},
|
|
// 遍历文件系统条目(用于文件夹拖拽)
|
async traverseEntry(entry, path = '') {
|
if (entry.isFile) {
|
const file = await this.getFileFromEntry(entry);
|
this.addFileToList(file);
|
} else if (entry.isDirectory) {
|
const directoryReader = entry.createReader();
|
const entries = await this.readDirectoryEntries(directoryReader);
|
|
// 添加文件夹到列表
|
// this.uploadList.push({
|
// type: 'folder',
|
// name: entry.name,
|
// fileCount: entries.length,
|
// files: [] // 实际文件中我们只展示文件夹名
|
// });
|
|
for (let i = 0; i < entries.length; i++) {
|
await this.traverseEntry(entries[i], `${path}/${entry.name}`);
|
}
|
}
|
},
|
|
// 从文件系统条目获取文件
|
getFileFromEntry(entry) {
|
return new Promise((resolve) => {
|
entry.file(file => {
|
resolve(file);
|
});
|
});
|
},
|
|
// 读取文件夹条目
|
readDirectoryEntries(directoryReader) {
|
return new Promise((resolve) => {
|
directoryReader.readEntries(entries => {
|
resolve(entries);
|
});
|
});
|
},
|
|
// 处理选择的文件
|
processFiles(files) {
|
if (!files.length) return;
|
|
files.forEach(file => {
|
// 跳过空文件和文件夹
|
if (file.size > 0 || file.type !== '') {
|
this.addFileToList(file);
|
}
|
});
|
},
|
|
// 添加文件到上传列表
|
addFileToList(file) {
|
const fileType = this.getFileType(file.name);
|
this.uploadList.push({
|
type: 'file',
|
name: file.name,
|
fileType,
|
size: file.size,
|
file
|
});
|
},
|
// 触发文件选择
|
triggerFileInput() {
|
this.$refs.fileInput.click();
|
},
|
|
// 触发文件夹选择
|
triggerFolderInput() {
|
this.$refs.folderInput.click();
|
},
|
|
// 处理文件选择
|
handleFileChange(e) {
|
const files = Array.from(e.target.files);
|
if (files.length === 0) return;
|
|
files.forEach(file => {
|
const fileType = this.getFileType(file.name);
|
this.uploadList.push({
|
type: 'file',
|
name: file.name,
|
fileType,
|
size: file.size,
|
file
|
});
|
});
|
e.target.value = '';
|
},
|
|
// 处理文件夹选择
|
handleFolderChange(e) {
|
const files = Array.from(e.target.files);
|
if (files.length === 0) return;
|
|
// 获取文件夹名称
|
const folderName = this.extractFolderName(files);
|
|
// this.uploadList.push({
|
// type: 'folder',
|
// name: folderName,
|
// fileCount: files.length,
|
// files
|
// });
|
e.target.value = '';
|
},
|
|
// 从文件列表中提取文件夹名
|
extractFolderName(files) {
|
if (files.length === 0) return '未命名文件夹';
|
const path = files[0].webkitRelativePath;
|
const parts = path.split('/');
|
return parts.length > 1 ? parts[0] : '未命名文件夹';
|
},
|
|
// 获取文件类型(根据扩展名)
|
getFileType(fileName) {
|
const ext = fileName.split('.').pop().toLowerCase();
|
const types = {
|
jpg: '图片',
|
jpeg: '图片',
|
png: '图片',
|
gif: '图片',
|
pdf: 'PDF',
|
doc: 'Word',
|
docx: 'Word',
|
xls: 'Excel',
|
xlsx: 'Excel',
|
ppt: 'PPT',
|
pptx: 'PPT',
|
txt: '文本',
|
zip: '压缩包',
|
rar: '压缩包',
|
mp4: '视频',
|
mov: '视频',
|
avi: '视频'
|
};
|
return types[ext] || '文件';
|
},
|
|
// 移除文件项
|
removeFileItem(index) {
|
this.uploadList.splice(index, 1);
|
},
|
|
// 新增搜索处理方法
|
handleSearch() {
|
this.pagination.page = 1; // 搜索时重置到第一页
|
this.fetchTableData();
|
},
|
// 新增重置处理方法
|
handleReset() {
|
this.searchKey = '';
|
},
|
// 分页处理
|
handleCurrentChange(page) {
|
this.pagination.page = page
|
this.fetchTableData()
|
// console.info(this.pagination)
|
},
|
// 新增操作
|
handleCreate() {
|
this.dialogType = 'create'
|
this.dialogVisible = true
|
this.uploadList = []
|
this.taskForm = {
|
id: 0,
|
fileName: '',
|
taskDescription: "",
|
modelId: 1,
|
totalChunks: '',
|
createTime: 1,
|
eventLevelName: '',
|
videoIds: [],
|
videoCamera: [],
|
workingTimes: [],
|
checkContents: [],
|
warningRules: []
|
}
|
},
|
|
// 删除操作
|
async handleDelete(row) {
|
this.$confirm('确认删除该文件吗?', '提示', {
|
type: 'warning'
|
}).then(async () => {
|
// this.tableData = this.tableData.filter(item => item.taskName !== row.taskName)
|
try {
|
await Inspection.deleteDocument({
|
id: row.id
|
}).then(async (rsp) => {
|
if (rsp && rsp.status === 200) {
|
// 删除成功后自动修正页码
|
if (this.files.length === 1 && this.pagination.page > 1) {
|
this.pagination.page -= 1
|
}
|
await this.handleReset()
|
await this.fetchTableData()
|
this.$message({
|
type: "success",
|
message: "删除成功"
|
})
|
} else {
|
this.$message({
|
type: "error",
|
message: rsp.msg
|
})
|
}
|
})
|
|
} catch (error) {
|
this.$message.error('删除失败')
|
console.error('API Error:', error)
|
}
|
}).catch(() => {
|
|
})
|
},
|
// 弹窗打开时的处理
|
handleDialogOpen() {
|
this.$nextTick(() => {
|
this.$refs.taskForm.clearValidate()
|
})
|
},
|
// 弹窗关闭时的处理
|
handleDialogClose() {
|
this.$refs.taskForm.resetFields()
|
},
|
// 新增数据获取方法
|
async fetchTableData() {
|
console.info("knowledgeId :" + this.knowledgeId)
|
try {
|
// 模拟接口请求
|
const res = await Inspection.getDocumentList({
|
page: this.pagination.page,
|
pageSize: this.pagination.pageSize,
|
knowId: this.knowledgeId,
|
searchName: this.searchKey // 添加搜索参数
|
})
|
// 更新分页数据前先校验当前页码
|
const totalPage = res.data.pagination.totalPage
|
const currentPage = this.pagination.page > totalPage
|
? totalPage
|
: res.data.pagination.page
|
this.pagination = {
|
...this.pagination,
|
page: currentPage,
|
total: res.data.pagination.total,
|
totalPage: totalPage
|
}
|
this.pagination.total = res.data.pagination.total
|
this.pagination.totalPage = res.data.pagination.totalPage
|
this.tableData = res.data.list
|
// this.tableData = [{
|
// id: 1,
|
// fileName: '安全生产任务111111111111111111111111',
|
// fileUrl: "D:/新建文件夹/解决ide编译报错/说明.jpg",
|
// totalChunks: '分数块',
|
// createTime: '上传时间',
|
// parserType: "解析方法"
|
// }]
|
} catch (error) {
|
this.$message.error('数据加载失败' + error.message)
|
}
|
},
|
|
// 提交方法
|
async submitTask() {
|
if (this.dialogType === 'create') {
|
// 处理上传逻辑
|
if (this.uploadList.length === 0) {
|
this.$message.warning('请至少上传一个文件或文件夹');
|
return;
|
}
|
// 设置上传状态
|
this.isUploading = true;
|
try {
|
// 1. 创建FormData用于文件上传
|
let formData = new FormData();
|
|
// 2. 添加实际文件内容到FormData
|
this.uploadList.forEach(item => {
|
if (item.file) {
|
// 添加文件时指定正确的文件字段名(根据API要求)
|
formData.append('file', item.file);
|
}
|
});
|
// formData.append('file', this.uploadList[0].file);//后端暂时只支持单文件
|
// 3. 添加其他必要参数(如知识库ID)
|
const knowledgeId = this.knowledgeId;
|
if (knowledgeId) {
|
formData.append('knowId', knowledgeId);
|
}
|
|
for (var pair of formData.entries()) {
|
console.log(pair[0] + ', ' + pair[1]);
|
}
|
// 4. 调用实际的上传API
|
const response = await Inspection.uploadFiles(formData);
|
if (response.status == 200) {
|
this.$message.success('文件上传成功');
|
this.dialogVisible = false;
|
this.uploadList = [];
|
} else {
|
this.$message.error(response.msg);
|
}
|
} catch (error) {
|
this.$message.error('文件上传失败: ' + error.message);
|
console.error('Upload error:', error);
|
} finally {
|
// 无论成功失败,都结束加载状态
|
this.isUploading = false;
|
}
|
} else {
|
// 原有的编辑任务逻辑
|
// ...(保留原有编辑任务的提交逻辑)...
|
}
|
// 刷新列表
|
await this.handleReset()
|
await this.fetchTableData()
|
},
|
//关闭组件方法
|
handleClose() {
|
// this.$router.push({
|
// name: 'knowledge' // 返回到知识库列表路由
|
// })
|
this.$emit('back') // 触发返回事件
|
},
|
// 格式化开始时间
|
formatDateTime(dateTimeStr) {
|
if (!dateTimeStr) return '';
|
|
try {
|
// 处理UTC格式日期字符串
|
const dateObj = new Date(dateTimeStr);
|
|
// 格式化为年月日 时分秒(补零)
|
return dateObj.toLocaleString('zh-CN', {
|
year: 'numeric',
|
month: '2-digit',
|
day: '2-digit',
|
hour: '2-digit',
|
minute: '2-digit',
|
second: '2-digit',
|
hour12: false
|
}).replace(/\//g, '-');
|
} catch (e) {
|
console.error('日期格式转换错误:', e);
|
// 回退处理:只提取年月日时分秒部分
|
return dateTimeStr.slice(0, 19);
|
}
|
},
|
},
|
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.task-container {
|
padding: 20px;
|
background: #fff;
|
|
|
.close-container {
|
position: absolute;
|
top: 15px;
|
left: 20px;
|
|
.close-btn {
|
font-size: 26px;
|
color: #606266;
|
// background: #f5f7fa;
|
// padding: 8px 15px;
|
// border-radius: 4px;
|
// box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
|
}
|
}
|
|
.search-bar {
|
float: right;
|
display: flex;
|
gap: 10px;
|
margin-bottom: 20px;
|
|
.search-input {
|
width: 300px;
|
}
|
|
.new-btn {
|
// margin-left: auto;
|
}
|
}
|
|
.data-table {
|
::v-deep {
|
|
.el-table__header,
|
.el-table__body {
|
|
th,
|
td {
|
border-right: 1px solid #ebeef5;
|
|
&:last-child {
|
border-right: none;
|
}
|
}
|
}
|
|
.el-table__row td {
|
padding: 12px 0;
|
}
|
|
.cell {
|
overflow: visible !important;
|
}
|
}
|
|
.text-ellipsis {
|
display: inline-block;
|
max-width: 100%;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
vertical-align: middle;
|
}
|
|
.level {
|
display: inline-block;
|
padding: 4px 12px;
|
border-radius: 4px;
|
font-size: 12px;
|
|
&-1 {
|
background: #fef0f0;
|
color: #f56c6c;
|
}
|
}
|
|
.check-tag {
|
margin: 2px;
|
}
|
|
.kb-btn {
|
padding: 5px 10px;
|
}
|
|
.multi-tags {
|
display: flex;
|
flex-wrap: nowrap;
|
overflow: hidden;
|
gap: 4px;
|
|
.tag-item {
|
flex-shrink: 1;
|
max-width: 100px;
|
margin: 2px;
|
}
|
}
|
|
.check-items {
|
display: flex;
|
flex-wrap: wrap;
|
max-height: 36px;
|
overflow: hidden;
|
gap: 4px;
|
|
.check-tag {
|
max-width: 120px;
|
flex-shrink: 1;
|
}
|
}
|
|
.kb-buttons {
|
display: flex;
|
flex-wrap: nowrap;
|
overflow: hidden;
|
gap: 4px;
|
|
.kb-btn {
|
max-width: 100px;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
padding: 5px 8px;
|
|
span {
|
display: block;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
}
|
}
|
}
|
}
|
|
.pagination {
|
display: flex;
|
justify-content: flex-end;
|
margin-top: 20px;
|
}
|
}
|
|
.task-dialog {
|
.el-dialog__header {
|
border-bottom: 1px solid #ebeef5;
|
padding: 15px 20px;
|
}
|
|
.el-dialog__title {
|
font-size: 16px;
|
color: #303133;
|
}
|
|
.el-form-item {
|
margin-bottom: 18px;
|
|
.el-input__inner,
|
.el-textarea__inner {
|
border-radius: 4px;
|
}
|
}
|
|
.el-select {
|
width: 100%;
|
}
|
|
.el-button--primary {
|
padding: 10px 20px;
|
}
|
}
|
|
/* 查看详情弹窗样式 */
|
.view-dialog {
|
.el-dialog__header {
|
border-bottom: 1px solid #ebeef5;
|
padding: 15px 20px;
|
}
|
|
.el-dialog__title {
|
font-size: 16px;
|
color: #303133;
|
}
|
|
.el-form-item {
|
margin-bottom: 18px;
|
|
.el-input__inner,
|
.el-textarea__inner {
|
border-radius: 4px;
|
}
|
}
|
|
.el-select {
|
width: 100%;
|
}
|
|
.el-button--primary {
|
padding: 10px 20px;
|
}
|
}
|
|
.time-dialog {
|
.el-dialog__body {
|
padding: 20px;
|
}
|
|
.time-period-component {
|
margin: 15px 0;
|
}
|
}
|
|
.time-setting-btn {
|
margin-left: 10px;
|
}
|
|
//上传文件样式
|
.upload-area {
|
padding: 15px 0;
|
}
|
|
.upload-container {
|
|
//拖拽区域样式
|
.drag-area {
|
border: 2px dashed #c0c4cc;
|
border-radius: 6px;
|
padding: 30px;
|
text-align: center;
|
transition: all 0.3s;
|
cursor: pointer;
|
position: relative;
|
|
&.drag-over {
|
border-color: #409eff;
|
background-color: rgba(64, 158, 255, 0.05);
|
|
i,
|
.el-upload__text {
|
color: #409eff;
|
}
|
}
|
|
.drag-content {
|
i {
|
font-size: 50px;
|
color: #c0c4cc;
|
margin-bottom: 15px;
|
display: block;
|
}
|
|
.el-upload__text {
|
font-size: 16px;
|
font-weight: 500;
|
color: #606266;
|
}
|
|
.upload-tip {
|
color: #909399;
|
margin: 10px 0;
|
}
|
|
.action-buttons {
|
margin-top: 15px;
|
|
.el-button {
|
margin: 0 5px;
|
}
|
}
|
}
|
}
|
|
//点击选择区域样式
|
display: flex;
|
gap: 20px;
|
margin-bottom: 20px;
|
|
.upload-wrapper {
|
flex: 1;
|
border: 1px dashed #dcdfe6;
|
border-radius: 4px;
|
padding: 40px 0;
|
text-align: center;
|
cursor: pointer;
|
transition: border-color 0.3s;
|
|
&:hover {
|
border-color: #409eff;
|
|
i,
|
.el-upload__text {
|
color: #409eff;
|
}
|
}
|
|
i {
|
font-size: 50px;
|
color: #8c939d;
|
margin-bottom: 15px;
|
}
|
|
.el-upload__text {
|
font-size: 14px;
|
color: #606266;
|
}
|
|
&.folder {
|
background-color: #f8faff;
|
}
|
}
|
}
|
|
.file-list {
|
border: 1px solid #ebeef5;
|
border-radius: 4px;
|
overflow: hidden;
|
|
.list-header {
|
display: grid;
|
grid-template-columns: 50px 1fr 80px;
|
background-color: #f5f7fa;
|
padding: 10px 15px;
|
font-weight: bold;
|
color: #606266;
|
}
|
|
.list-items {
|
max-height: 300px;
|
overflow-y: auto;
|
}
|
|
.file-item {
|
display: grid;
|
grid-template-columns: 50px 1fr 80px;
|
align-items: center;
|
padding: 10px 15px;
|
border-bottom: 1px solid #ebeef5;
|
|
&:hover {
|
background-color: #f8fafc;
|
}
|
|
.item-icon {
|
i {
|
font-size: 24px;
|
|
&.el-icon-folder {
|
color: #e6a23c;
|
}
|
|
&.el-icon-document {
|
color: #409eff;
|
}
|
}
|
}
|
|
.item-type {
|
color: #606266;
|
}
|
|
.item-name {
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
padding-right: 10px;
|
}
|
|
.item-action {
|
i {
|
font-size: 18px;
|
color: #f56c6c;
|
cursor: pointer;
|
|
&:hover {
|
color: #e53935;
|
}
|
}
|
}
|
}
|
|
.empty-tip {
|
text-align: center;
|
padding: 20px;
|
color: #909399;
|
font-size: 14px;
|
}
|
}
|
|
/* 新增全局加载样式 */
|
.global-loading {
|
position: fixed;
|
top: 0;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
background-color: rgba(0, 0, 0, 0.8);
|
z-index: 9999;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
|
.loading-content {
|
text-align: center;
|
// background: white;
|
// padding: 30px 50px;
|
// border-radius: 8px;
|
// box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
|
|
.el-icon-loading {
|
font-size: 40px;
|
color: #409eff;
|
margin-bottom: 15px;
|
}
|
|
p {
|
margin: 0;
|
font-size: 16px;
|
color: #606266;
|
}
|
}
|
}
|
</style>
|