|
@@ -1,121 +1,68 @@
|
|
|
<script setup lang="ts">
|
|
|
import CommonFileUpload from '@/components/form/CommonFileUpload.vue'
|
|
|
-import type CustomTable from '@/components/table/CustomTable.vue'
|
|
|
+
|
|
|
import { useRequest } from '@/hooks/useRequest.ts'
|
|
|
|
|
|
-import {
|
|
|
- FilterType,
|
|
|
- type QueryInfo,
|
|
|
- type TableFieldInfo,
|
|
|
- type TablePaginationSetting,
|
|
|
- type TableToolsConfig
|
|
|
-} from '@/types/table.ts'
|
|
|
+import { FilterType, type QueryInfo } from '@/types/table.ts'
|
|
|
import axiosInstance from '@/utils/axios/axiosInstance.ts'
|
|
|
-import { ElMessageBox } from 'element-plus'
|
|
|
-import { ref, reactive } from 'vue'
|
|
|
-import HeaderCard from '@/components/dataAnalysis/HeaderCard.vue'
|
|
|
-import type { ReqConfig } from '@/types/dataAnalysis'
|
|
|
+import { ElMessageBox, type FormInstance } from 'element-plus'
|
|
|
+import { ref, onMounted } from 'vue'
|
|
|
|
|
|
-const { AllApi } = useRequest()
|
|
|
+interface PaginationConfig {
|
|
|
+ curPage: number
|
|
|
+ curSize: number
|
|
|
+ sizeList: Array<number>
|
|
|
+ total: number
|
|
|
+}
|
|
|
|
|
|
-// 表格请求配置
|
|
|
-const requestConfig = reactive<ReqConfig>({
|
|
|
- url: AllApi.fileList,
|
|
|
- otherOptions: {}
|
|
|
-})
|
|
|
+interface FileInfo {
|
|
|
+ id: number
|
|
|
+ file_name: string
|
|
|
+ type: number
|
|
|
+ dir: string
|
|
|
+ local_path: string
|
|
|
+ cos_path: string
|
|
|
+ createdAt: string // 或者使用 Date 类型
|
|
|
+ updatedAt: string // 或者使用 Date 类型
|
|
|
+}
|
|
|
|
|
|
-// --- Refs ---
|
|
|
-const headerCard = ref<InstanceType<typeof HeaderCard> | null>(null)
|
|
|
+interface FileQueryField {
|
|
|
+ search: string
|
|
|
+}
|
|
|
+
|
|
|
+const { AllApi } = useRequest()
|
|
|
+
|
|
|
+// 上传组件引用
|
|
|
const uploadRef = ref<InstanceType<typeof CommonFileUpload> | null>(null)
|
|
|
-const fileListTable = ref<InstanceType<typeof CustomTable> | null>(null)
|
|
|
-
|
|
|
-// 表格分页设置
|
|
|
-const pagingConfig = reactive<TablePaginationSetting>({
|
|
|
- limit: 20,
|
|
|
- currentPage: 1,
|
|
|
- total: 0,
|
|
|
- pageSizeList: [20, 30]
|
|
|
-})
|
|
|
|
|
|
-// 表格字段信息
|
|
|
-const tableFieldsInfo = reactive<Array<TableFieldInfo>>([
|
|
|
- {
|
|
|
- name: 'id',
|
|
|
- cnName: 'ID',
|
|
|
- isShow: false,
|
|
|
- needSort: false
|
|
|
- },
|
|
|
- {
|
|
|
- name: 'file_name',
|
|
|
- cnName: '文件名',
|
|
|
- isShow: true,
|
|
|
- needSort: false
|
|
|
- },
|
|
|
- {
|
|
|
- name: 'local_path',
|
|
|
- cnName: '本地路径',
|
|
|
- isShow: true,
|
|
|
- needSort: false
|
|
|
- },
|
|
|
- {
|
|
|
- name: 'cos_path',
|
|
|
- cnName: 'COS路径',
|
|
|
- isShow: true,
|
|
|
- needSort: false
|
|
|
- },
|
|
|
- {
|
|
|
- name: 'createdAt',
|
|
|
- cnName: '创建时间',
|
|
|
- isShow: true,
|
|
|
- needSort: false
|
|
|
- },
|
|
|
- {
|
|
|
- name: 'updatedAt',
|
|
|
- cnName: '更新时间',
|
|
|
- isShow: true,
|
|
|
- needSort: false
|
|
|
- }
|
|
|
-])
|
|
|
+// 当前路径面包屑列表
|
|
|
+const breadcrumbList = ref<string[]>([])
|
|
|
|
|
|
-/**
|
|
|
- * 触发新增
|
|
|
- */
|
|
|
-const addNewEvent = () => {
|
|
|
- // eventDialog.value.addForm()
|
|
|
- uploadRef.value?.openDialog()
|
|
|
-}
|
|
|
+// 当前目录下的文件/文件夹列表
|
|
|
+const fileListData = ref<FileInfo[]>([])
|
|
|
|
|
|
-// 工具栏配置
|
|
|
-const tableToolsConfig: TableToolsConfig = {
|
|
|
- add: true,
|
|
|
- filterFields: true,
|
|
|
- refresh: true,
|
|
|
- download: false
|
|
|
-}
|
|
|
+// 选中的文件记录,key 为文件 id
|
|
|
+const selectedRecord = ref<Record<number, boolean>>({})
|
|
|
|
|
|
-const deleteFile = async (row: any) => {
|
|
|
- try {
|
|
|
- const confirmRes = await ElMessageBox.confirm('确认删除该配置吗', '警告', {
|
|
|
- confirmButtonText: '确定',
|
|
|
- cancelButtonText: '取消',
|
|
|
- type: 'warning',
|
|
|
- closeOnClickModal: false
|
|
|
- })
|
|
|
- if (!confirmRes) return
|
|
|
- const delRes = (await axiosInstance.post(AllApi.fileManageDeleteFile, {
|
|
|
- fileId: row.id
|
|
|
- })) as { code: number }
|
|
|
- if (delRes.code !== 0) {
|
|
|
- ElMessage.error('删除失败')
|
|
|
- return
|
|
|
- }
|
|
|
- ElMessage.success('删除成功')
|
|
|
- } catch (err) {
|
|
|
- console.error(err)
|
|
|
- } finally {
|
|
|
- fileListTable.value?.updateTableData()
|
|
|
- }
|
|
|
-}
|
|
|
+// 是否处于文件管理(多选)模式
|
|
|
+const selectedAble = ref<boolean>(false)
|
|
|
+
|
|
|
+// 是否全选所有文件
|
|
|
+const selectedAll = ref<boolean>(false)
|
|
|
+
|
|
|
+// 是否正在加载文件列表
|
|
|
+const isLoadData = ref<boolean>(false)
|
|
|
+
|
|
|
+// 创建文件夹表单引用
|
|
|
+const makeDirForm = ref<FormInstance | null>(null)
|
|
|
+
|
|
|
+// 分页配置
|
|
|
+const paginationConfig = ref<PaginationConfig>({
|
|
|
+ curPage: 1,
|
|
|
+ sizeList: [10, 20, 30],
|
|
|
+ curSize: 10,
|
|
|
+ total: 0
|
|
|
+})
|
|
|
|
|
|
// 查询字段设置
|
|
|
const queryInfo: Array<QueryInfo> = [
|
|
@@ -128,16 +75,53 @@ const queryInfo: Array<QueryInfo> = [
|
|
|
}
|
|
|
]
|
|
|
|
|
|
+// 查询表单数据
|
|
|
+const queryFormData = ref<FileQueryField>({
|
|
|
+ search: ''
|
|
|
+})
|
|
|
+
|
|
|
+// 文件是否正在上传
|
|
|
+const fileUploading = ref<boolean>(false)
|
|
|
+
|
|
|
+// 创建文件夹弹窗配置
|
|
|
+const makeDirDialogConfig = ref({
|
|
|
+ visible: false,
|
|
|
+ formData: {
|
|
|
+ name: ''
|
|
|
+ },
|
|
|
+ rules: {
|
|
|
+ name: [
|
|
|
+ { required: true, message: '请输入文件夹名称', trigger: 'blur' },
|
|
|
+ { min: 1, max: 50, message: '长度应在 1 到 50 个字符之间', trigger: 'blur' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+/**
|
|
|
+ * 获取当前文件路径的完整路径
|
|
|
+ * @returns 返回完整路径字符串,如 /a/b/
|
|
|
+ */
|
|
|
+const getFullPath = () => {
|
|
|
+ let fullPath = '/' + breadcrumbList.value.join('/')
|
|
|
+ if (fullPath !== '/') fullPath += '/'
|
|
|
+ return fullPath
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 提交上传的文件
|
|
|
+ * @param file 需要上传的文件对象
|
|
|
+ */
|
|
|
const handleSubmit = async (file: File) => {
|
|
|
- const tableData = fileListTable.value?.outGetTableData()
|
|
|
- if (tableData) {
|
|
|
- const hasSameFileName = tableData.some((item) => item.file_name === file.name)
|
|
|
- if (hasSameFileName) {
|
|
|
- ElMessage.error('文件名重复')
|
|
|
- return
|
|
|
- }
|
|
|
+ const fileList = fileListData.value
|
|
|
+
|
|
|
+ const hasSameFileName = fileList.some((item) => item.file_name === file.name)
|
|
|
+ if (hasSameFileName) {
|
|
|
+ ElMessage.error('文件名重复')
|
|
|
+ return
|
|
|
}
|
|
|
+
|
|
|
try {
|
|
|
+ fileUploading.value = true
|
|
|
const uploadUrl = AllApi.fileUploadToServer
|
|
|
const tencentUrl = AllApi.fileUploadToTencent
|
|
|
const formData = new FormData()
|
|
@@ -150,8 +134,11 @@ const handleSubmit = async (file: File) => {
|
|
|
ElMessage.error('上传失败')
|
|
|
return
|
|
|
}
|
|
|
+
|
|
|
+ const fullPath = getFullPath()
|
|
|
const uploadToTencent = (await axiosInstance.post(tencentUrl, {
|
|
|
- filePath: uploadRes.path
|
|
|
+ filePath: uploadRes.path,
|
|
|
+ dir: fullPath
|
|
|
})) as {
|
|
|
code: number
|
|
|
path: string
|
|
@@ -161,68 +148,363 @@ const handleSubmit = async (file: File) => {
|
|
|
return
|
|
|
}
|
|
|
ElMessage.success('上传成功')
|
|
|
- fileListTable.value?.updateTableData()
|
|
|
+ await getFileList()
|
|
|
} catch (err) {
|
|
|
console.error(err)
|
|
|
} finally {
|
|
|
uploadRef.value?.closeDialog()
|
|
|
+ fileUploading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 对文件列表进行排序:文件夹排在文件前
|
|
|
+ * @param data 原始文件数据列表
|
|
|
+ * @returns 排序后的文件列表
|
|
|
+ */
|
|
|
+const sortTableData = (data: FileInfo[]) => {
|
|
|
+ return data.sort((a, b) => {
|
|
|
+ // 文件夹 (type 2) 放前面,文件 (type 1) 放后面
|
|
|
+ return a.type === b.type ? 0 : a.type === 2 ? -1 : 1
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 获取当前目录下的文件列表
|
|
|
+ */
|
|
|
+const getFileList = async () => {
|
|
|
+ try {
|
|
|
+ isLoadData.value = true
|
|
|
+ const dir = getFullPath()
|
|
|
+ const { curSize, curPage } = paginationConfig.value
|
|
|
+ // http://localhost:8113/fileList
|
|
|
+ const res = (await axiosInstance.post(AllApi.fileList, {
|
|
|
+ dir,
|
|
|
+ limit: curSize,
|
|
|
+ offset: (curPage - 1) * curSize,
|
|
|
+ search: queryFormData.value.search
|
|
|
+ })) as {
|
|
|
+ code: number
|
|
|
+ count: number
|
|
|
+ data: Array<FileInfo>
|
|
|
+ }
|
|
|
+ if (res.code !== 0) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let finalData = res.data ?? []
|
|
|
+ sortTableData(finalData)
|
|
|
+ fileListData.value.splice(0, fileListData.value.length, ...finalData)
|
|
|
+ paginationConfig.value.total = res.count
|
|
|
+ } catch (err) {
|
|
|
+ console.error(err)
|
|
|
+ ElMessage.error('获取文件列表失败')
|
|
|
+ } finally {
|
|
|
+ isLoadData.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 打开上传文件弹窗
|
|
|
+ */
|
|
|
+const openUploadFile = () => {
|
|
|
+ uploadRef.value?.openDialog()
|
|
|
+ // console.log(selectedRecord.value)
|
|
|
+ // console.log(Object.values(selectedRecord).filter((item) => item).length === 1)
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 切换管理文件操作状态
|
|
|
+ */
|
|
|
+const manageFile = () => {
|
|
|
+ selectedAble.value = !selectedAble.value
|
|
|
+ if (!selectedAble.value) {
|
|
|
+ selectedRecord.value = {}
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 文件或文件夹双击事件处理
|
|
|
+ * @param id 被双击项的 id
|
|
|
+ */
|
|
|
+const handleDbClick = (id: number) => {
|
|
|
+ // 处于管理模式下,不触发双击事件
|
|
|
+ if (selectedAble.value) return
|
|
|
+ console.log(id)
|
|
|
+ const selectedItem = fileListData.value.find((item) => item.id === id)
|
|
|
+
|
|
|
+ if (!selectedItem) {
|
|
|
+ ElMessage.warning('未选中文件,请重试')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 是文件就返回
|
|
|
+ if (selectedItem.type === 1) return
|
|
|
+ breadcrumbList.value.push(selectedItem.file_name)
|
|
|
+
|
|
|
+ getFileList()
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 选择或取消选择全部文件
|
|
|
+ * @param isSelected 是否选中
|
|
|
+ */
|
|
|
+const handleSelectAll = (isSelected: boolean) => {
|
|
|
+ fileListData.value.forEach((item) => {
|
|
|
+ selectedRecord.value[item.id] = isSelected
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 鼠标移出取消选中状态
|
|
|
+ */
|
|
|
+const handleOver = () => {
|
|
|
+ selectedAble.value = false
|
|
|
+ selectedRecord.value = {}
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 每页显示条数变更时触发
|
|
|
+ * @param newSize 新的每页条数
|
|
|
+ */
|
|
|
+const handleSizeChange = (newSize: number) => {
|
|
|
+ paginationConfig.value.curSize = newSize
|
|
|
+ paginationConfig.value.curPage = 1
|
|
|
+ getFileList()
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 当前页码变更时触发
|
|
|
+ * @param newPage 新的页码
|
|
|
+ */
|
|
|
+const handleCurPageChange = (newPage: number) => {
|
|
|
+ paginationConfig.value.curPage = newPage
|
|
|
+ getFileList()
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 面包屑导航点击跳转目录
|
|
|
+ * @param index 点击的面包屑索引
|
|
|
+ */
|
|
|
+const handleBreadcrumbNav = (index: number) => {
|
|
|
+ if (index === breadcrumbList.value.length) return
|
|
|
+ breadcrumbList.value.splice(index, breadcrumbList.value.length)
|
|
|
+ getFileList()
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 打开新建文件夹弹窗
|
|
|
+ */
|
|
|
+const openCreateFolder = () => {
|
|
|
+ makeDirDialogConfig.value.visible = true
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 创建新文件夹
|
|
|
+ */
|
|
|
+const handleCreate = async () => {
|
|
|
+ const isValid = await makeDirForm.value?.validate()
|
|
|
+ if (!isValid) return
|
|
|
+ const res = (await axiosInstance.post(AllApi.makeDir, {
|
|
|
+ dir: getFullPath(),
|
|
|
+ dirName: makeDirDialogConfig.value.formData.name
|
|
|
+ })) as { code: number }
|
|
|
+ if (res.code !== 0) {
|
|
|
+ ElMessage.error('创建文件夹失败')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ ElMessage.success('创建文件夹成功')
|
|
|
+ handleClose()
|
|
|
+ await getFileList()
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 关闭弹窗并重置表单
|
|
|
+ */
|
|
|
+const handleClose = () => {
|
|
|
+ makeDirDialogConfig.value.visible = false
|
|
|
+ makeDirForm.value?.resetFields()
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 删除选中的文件或文件夹
|
|
|
+ */
|
|
|
+const handleDel = async () => {
|
|
|
+ let fileId = -1
|
|
|
+ for (let [k, v] of Object.entries(selectedRecord.value)) {
|
|
|
+ if (v && fileId === -1) {
|
|
|
+ fileId = parseInt(k) ?? -1
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ if (isNaN(fileId)) {
|
|
|
+ ElMessage.warning('删除错误,请重试')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const fileItem = fileListData.value.find((item) => item.id === fileId)
|
|
|
+ if (!fileItem) {
|
|
|
+ console.log(fileItem)
|
|
|
+ ElMessage.warning('删除错误,请重试')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const type = fileItem.type
|
|
|
+ const tipText =
|
|
|
+ type === 1
|
|
|
+ ? '确定删除该文件吗'
|
|
|
+ : '确定删除该文件夹吗<br/><strong>删除文件夹会导致该文件夹下所有文件都被删除</strong>'
|
|
|
+
|
|
|
+ const confirm = await ElMessageBox.confirm(tipText, '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning',
|
|
|
+ dangerouslyUseHTMLString: true
|
|
|
+ })
|
|
|
+ if (!confirm) return
|
|
|
+ const res = (await axiosInstance.post(AllApi.fileManageDeleteFile, {
|
|
|
+ fileId
|
|
|
+ })) as { code: number }
|
|
|
+ if (res.code !== 0) {
|
|
|
+ ElMessage.error('删除失败')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ selectedRecord.value[fileId] = false
|
|
|
+ ElMessage.success('删除成功')
|
|
|
+
|
|
|
+ await getFileList()
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 页面加载完成后,获取文件列表
|
|
|
+ */
|
|
|
+onMounted(async () => {
|
|
|
+ await getFileList()
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
- <div class="fileList">
|
|
|
- <div class="breadcrumbBox">
|
|
|
- <HeaderCard
|
|
|
- ref="headerCard"
|
|
|
- :need-breadcrumb="false"
|
|
|
- :title="'文件列表'"
|
|
|
- :need-pf-select="false"
|
|
|
- ></HeaderCard>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="fileListBox">
|
|
|
- <CustomTable
|
|
|
- ref="fileListTable"
|
|
|
- :request-config="requestConfig"
|
|
|
- :open-page-query="true"
|
|
|
- :pagination-config="pagingConfig"
|
|
|
- :table-fields-info="tableFieldsInfo"
|
|
|
- :open-filter-query="true"
|
|
|
- :open-remote-query="true"
|
|
|
- :tools="tableToolsConfig"
|
|
|
+ <div class="fileListContainer">
|
|
|
+ <div :class="['queryContainer', isLoadData ? 'disableHandle' : '']">
|
|
|
+ <table-filter-form
|
|
|
+ :queryFormData="queryFormData"
|
|
|
:query-info="queryInfo"
|
|
|
- @add-new-item="addNewEvent"
|
|
|
+ @query="getFileList"
|
|
|
+ ></table-filter-form>
|
|
|
+ </div>
|
|
|
+ <div :class="['toolContainer', isLoadData ? 'disableHandle' : '']">
|
|
|
+ <el-button class="toolBtn" color="#197afb" @click="openUploadFile">上传文件</el-button>
|
|
|
+ <el-button class="toolBtn" color="#197afb" plain @click="openCreateFolder"
|
|
|
+ >新建文件夹</el-button
|
|
|
>
|
|
|
- <template #tableOperation>
|
|
|
- <el-table-column label="操作" align="center">
|
|
|
- <template #default="scope">
|
|
|
- <el-button
|
|
|
- size="small"
|
|
|
- class="operationBtn"
|
|
|
- type="danger"
|
|
|
- @click="deleteFile(scope.row)"
|
|
|
- >删除</el-button
|
|
|
- >
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </template>
|
|
|
- </CustomTable>
|
|
|
+ <el-button class="toolBtn" color="#197afb" plain @click="manageFile">管理</el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="folderContainer" v-loading="isLoadData">
|
|
|
+ <div class="operationContainer">
|
|
|
+ <!-- 批量操作 -->
|
|
|
+ <div class="batchOperationContainer" v-if="selectedAble">
|
|
|
+ <div class="selectedAll">
|
|
|
+ <CustomCheckBox v-model="selectedAll" @click="handleSelectAll"></CustomCheckBox>
|
|
|
+ <span class="commonTxt">全选</span>
|
|
|
+ </div>
|
|
|
+ <div class="operationGroup">
|
|
|
+ <el-button
|
|
|
+ class="toolBtn delBtn"
|
|
|
+ color="#F56C6C"
|
|
|
+ :disabled="Object.values(selectedRecord).filter((item) => item).length !== 1"
|
|
|
+ @click="handleDel"
|
|
|
+ >删除
|
|
|
+ </el-button>
|
|
|
+ <el-button class="toolBtn" color="#197afb" plain @click="handleOver">完成</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 面包屑导航 -->
|
|
|
+ <div class="breadcrumbContainer" v-else>
|
|
|
+ <el-breadcrumb separator="/">
|
|
|
+ <el-breadcrumb-item @click="handleBreadcrumbNav(0)">
|
|
|
+ <span class="el-breadcrumb__separator">/</span>
|
|
|
+ <span class="breadcrumbSeparatorItem">全部</span>
|
|
|
+ </el-breadcrumb-item>
|
|
|
+ <el-breadcrumb-item
|
|
|
+ v-for="(item, index) in breadcrumbList"
|
|
|
+ :key="item"
|
|
|
+ @click="handleBreadcrumbNav(index + 1)"
|
|
|
+ >
|
|
|
+ <span class="breadcrumbSeparatorItem">{{ item }}</span>
|
|
|
+ </el-breadcrumb-item>
|
|
|
+ </el-breadcrumb>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="fileContainer">
|
|
|
+ <FileItem
|
|
|
+ v-for="item in fileListData"
|
|
|
+ :key="item.file_name"
|
|
|
+ :name="item.file_name"
|
|
|
+ :type="item.type === 1 ? 'file' : 'folder'"
|
|
|
+ :selected-able="selectedAble"
|
|
|
+ v-model="selectedRecord[item.id]"
|
|
|
+ @dblclick="handleDbClick(item.id)"
|
|
|
+ ></FileItem>
|
|
|
+ </div>
|
|
|
+ <div class="paginationContainer">
|
|
|
+ <el-pagination
|
|
|
+ v-model:current-page="paginationConfig.curPage"
|
|
|
+ v-model:page-size="paginationConfig.curSize"
|
|
|
+ :page-sizes="paginationConfig.sizeList"
|
|
|
+ :total="paginationConfig.total"
|
|
|
+ layout="total, prev, pager, next,sizes, jumper"
|
|
|
+ @size-change="handleSizeChange"
|
|
|
+ @current-change="handleCurPageChange"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
<div class="uploadFileBox">
|
|
|
- <CommonFileUpload ref="uploadRef" @submit="handleSubmit">
|
|
|
+ <CommonFileUpload :upload-loading="fileUploading" ref="uploadRef" @submit="handleSubmit">
|
|
|
<template #tip>
|
|
|
<div class="el-upload__tip">每次只能上传一个文件,且文件名不能重复</div>
|
|
|
</template>
|
|
|
</CommonFileUpload>
|
|
|
+
|
|
|
+ <div class="makeDir">
|
|
|
+ <el-dialog
|
|
|
+ v-model="makeDirDialogConfig.visible"
|
|
|
+ title="新建文件夹"
|
|
|
+ @close="handleClose"
|
|
|
+ class="make-dir-dialog"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ >
|
|
|
+ <el-form
|
|
|
+ :model="makeDirDialogConfig.formData"
|
|
|
+ :rules="makeDirDialogConfig.rules"
|
|
|
+ label-width="120px"
|
|
|
+ label-position="left"
|
|
|
+ class="make-dir-form-row"
|
|
|
+ ref="makeDirForm"
|
|
|
+ >
|
|
|
+ <el-form-item label="文件夹名称" prop="name" class="make-dir-form-item">
|
|
|
+ <el-input
|
|
|
+ v-model="makeDirDialogConfig.formData.name"
|
|
|
+ placeholder="请输入文件夹名称"
|
|
|
+ class="make-dir-input"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <div class="make-dir-footer">
|
|
|
+ <el-button class="make-dir-btn confirm" type="primary" @click="handleCreate"
|
|
|
+ >确定</el-button
|
|
|
+ >
|
|
|
+ <el-button class="make-dir-btn cancel" @click="handleClose">取消</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<style scoped>
|
|
|
/* Styles adapted with renamed classes */
|
|
|
-.fileList {
|
|
|
+.fileListContainer {
|
|
|
/* Renamed from eventManage */
|
|
|
width: 98%;
|
|
|
margin: 1% auto;
|
|
@@ -231,69 +513,98 @@ const handleSubmit = async (file: File) => {
|
|
|
position: relative; /* Keep relative positioning for the absolute positioned handleFileActions */
|
|
|
}
|
|
|
|
|
|
-.breadcrumbBox {
|
|
|
- background-color: white;
|
|
|
+.folderContainer {
|
|
|
+ /* Renamed from eventTableBox */
|
|
|
box-sizing: border-box;
|
|
|
- height: 64px;
|
|
|
- font-size: 16px;
|
|
|
- color: #17233d;
|
|
|
- font-weight: 600;
|
|
|
- /* padding: 0 24px; */ /* Kept original style */
|
|
|
- line-height: 64px;
|
|
|
+ /* Add padding-bottom if needed to avoid overlap with potential footers */
|
|
|
+ padding: 0 24px 24px;
|
|
|
}
|
|
|
|
|
|
-.fileListBox {
|
|
|
- /* Renamed from eventTableBox */
|
|
|
+.queryContainer {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.toolContainer {
|
|
|
+ width: 100%;
|
|
|
box-sizing: border-box;
|
|
|
- /* Add padding-bottom if needed to avoid overlap with potential footers */
|
|
|
padding: 0 24px 24px;
|
|
|
}
|
|
|
|
|
|
-.handleFileActions {
|
|
|
- /* Renamed from handleEvent */
|
|
|
- position: absolute;
|
|
|
- /* width: 12%; */ /* Kept original style */
|
|
|
- background-color: white;
|
|
|
+.toolBtn {
|
|
|
+ min-width: 80px;
|
|
|
+ height: 28px;
|
|
|
+ margin-right: 16px;
|
|
|
+ /*border: 1px solid #197afb;*/
|
|
|
+ border-radius: 3px;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 500;
|
|
|
+ font-family:
|
|
|
+ PingFang SC,
|
|
|
+ Microsoft YaHei UI,
|
|
|
+ Microsoft YaHei,
|
|
|
+ Helvetica Neue,
|
|
|
+ Helvetica,
|
|
|
+ Hiragino Sans GB,
|
|
|
+ Arial,
|
|
|
+ sans-serif;
|
|
|
+}
|
|
|
+
|
|
|
+.delBtn {
|
|
|
+ color: white;
|
|
|
+}
|
|
|
+
|
|
|
+.operationContainer,
|
|
|
+.fileContainer {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.fileContainer {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+}
|
|
|
+
|
|
|
+.batchOperationContainer,
|
|
|
+.breadcrumbContainer {
|
|
|
+ width: 100%;
|
|
|
box-sizing: border-box;
|
|
|
- /* height: 48px; */ /* Kept original style */
|
|
|
- font-size: 16px;
|
|
|
- font-weight: 600;
|
|
|
- top: 20px; /* Kept original position */
|
|
|
- right: 24px; /* Kept original position */
|
|
|
- /* position: relative; */ /* Kept original style (commented) */
|
|
|
- /* justify-content: flex-end; */ /* Kept original style (commented) */
|
|
|
- z-index: 10; /* Ensure buttons are above the table box if overlap occurs */
|
|
|
+ padding-bottom: 22px;
|
|
|
}
|
|
|
|
|
|
-.fileGroup {
|
|
|
- width: 100%; /* Kept original style */
|
|
|
- display: flex; /* Added to align buttons nicely */
|
|
|
- justify-content: flex-end; /* Align buttons to the right */
|
|
|
+.batchOperationContainer {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
}
|
|
|
|
|
|
-.fileBtn {
|
|
|
- margin-left: 10px; /* Changed from margin-right for flex-end alignment */
|
|
|
+.selectedAll,
|
|
|
+.operationGroup {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
}
|
|
|
-.fileBtn:first-child {
|
|
|
- margin-left: 0; /* Remove margin for the first button */
|
|
|
+
|
|
|
+.commonTxt {
|
|
|
+ display: inline-block;
|
|
|
+ height: 16px;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 16px;
|
|
|
+ vertical-align: middle;
|
|
|
}
|
|
|
|
|
|
-/* Basic styling for the new table */
|
|
|
-.file-list-table {
|
|
|
+.paginationContainer {
|
|
|
width: 100%;
|
|
|
- border-collapse: collapse;
|
|
|
- margin-top: 20px; /* Add some space below the header/action buttons area */
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.breadcrumbSeparatorItem {
|
|
|
+ cursor: pointer;
|
|
|
}
|
|
|
|
|
|
-.file-list-table th,
|
|
|
-.file-list-table td {
|
|
|
- border: 1px solid #dfe6ec; /* Example border */
|
|
|
- padding: 8px 12px;
|
|
|
- text-align: left;
|
|
|
+.breadcrumbSeparatorItem:hover {
|
|
|
+ color: #409eff;
|
|
|
}
|
|
|
|
|
|
-.file-list-table th {
|
|
|
- background-color: #f8f8f9; /* Example header background */
|
|
|
- font-weight: 600;
|
|
|
+/* 创建文件夹表单 */
|
|
|
+.make-dir-btn {
|
|
|
+ margin-right: 10px;
|
|
|
}
|
|
|
</style>
|