云文件管理系统上传组件优化

This commit is contained in:
2026-04-02 15:02:54 +08:00
parent 5053d396f8
commit 45e1fe5260
9 changed files with 206 additions and 121 deletions

View File

@@ -34,69 +34,67 @@
<el-table-column label="操作" width="180" fixed="right" align="center">
<template #default="{ row }">
<template v-if="menuType === 'trash'">
<el-button link type="primary" @click="$emit('restore', row)">
<el-icon><RefreshLeft /></el-icon>
<span style="margin-left: 2px">还原</span>
</el-button>
<el-button link type="danger" @click="$emit('delete-permanent', row)">
<el-icon><Delete /></el-icon>
<span style="margin-left: 2px">彻底删除</span>
</el-button>
<el-tooltip content="还原" placement="top">
<el-button link type="primary" @click="$emit('restore', row)">
<el-icon><RefreshLeft /></el-icon>
</el-button>
</el-tooltip>
<el-tooltip content="彻底删除" placement="top">
<el-button link type="danger" @click="$emit('delete-permanent', row)">
<el-icon><Delete /></el-icon>
</el-button>
</el-tooltip>
</template>
<template v-else-if="menuType === 'my-files'">
<el-button link @click="$emit('preview', row)" v-if="canPreview(row)">
<el-icon><View /></el-icon>
<span style="margin-left: 2px">预览</span>
</el-button>
<el-dropdown trigger="click" @command="(cmd) => handleCommand(cmd, row)">
<el-button link>
<span>更多</span>
<el-tooltip content="共享" placement="top">
<el-button link @click="$emit('share', row)">
<el-icon><Share /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="share">
<el-icon><Share /></el-icon>
<span>共享</span>
</el-dropdown-item>
<el-dropdown-item command="rename">
<el-icon><Edit /></el-icon>
<span>重命名</span>
</el-dropdown-item>
<el-dropdown-item command="download" v-if="row.type !== 'folder'">
<el-icon><Download /></el-icon>
<span>下载</span>
</el-dropdown-item>
<el-dropdown-item command="delete" divided>
<el-icon><Delete /></el-icon>
<span style="color: #f56c6c">删除</span>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-tooltip>
<el-tooltip content="重命名" placement="top">
<el-button link @click="$emit('rename', row)">
<el-icon><Edit /></el-icon>
</el-button>
</el-tooltip>
<el-tooltip content="下载" placement="top" v-if="row.type !== 'folder'">
<el-button link @click="$emit('download', row)">
<el-icon><Download /></el-icon>
</el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="danger" @click="$emit('delete', row)">
<el-icon><Delete /></el-icon>
</el-button>
</el-tooltip>
</template>
<template v-else-if="menuType === 'my-share'">
<el-button link @click="$emit('preview', row)" v-if="canPreview(row)">
<el-icon><View /></el-icon>
<span style="margin-left: 2px">预览</span>
</el-button>
<el-button link @click="$emit('download', row)" v-if="row.type !== 'folder'">
<el-icon><Download /></el-icon>
<span style="margin-left: 2px">下载</span>
</el-button>
<el-button link type="warning" @click="$emit('cancel-share', row)" v-if="!inFolder">
<el-icon><CloseBold /></el-icon>
<span style="margin-left: 2px">取消共享</span>
</el-button>
<el-tooltip content="预览" placement="top" v-if="canPreview(row)">
<el-button link @click="$emit('preview', row)">
<el-icon><View /></el-icon>
</el-button>
</el-tooltip>
<el-tooltip content="下载" placement="top" v-if="row.type !== 'folder'">
<el-button link @click="$emit('download', row)">
<el-icon><Download /></el-icon>
</el-button>
</el-tooltip>
<el-tooltip content="取消共享" placement="top" v-if="!inFolder">
<el-button link type="warning" @click="$emit('cancel-share', row)">
<el-icon><CloseBold /></el-icon>
</el-button>
</el-tooltip>
</template>
<template v-else-if="menuType === 'shared-to-me'">
<el-button link @click="$emit('preview', row)" v-if="canPreview(row)">
<el-icon><View /></el-icon>
<span style="margin-left: 2px">预览</span>
</el-button>
<el-button link @click="$emit('download', row)" v-if="row.type !== 'folder'">
<el-icon><Download /></el-icon>
<span style="margin-left: 2px">下载</span>
</el-button>
<el-tooltip content="预览" placement="top" v-if="canPreview(row)">
<el-button link @click="$emit('preview', row)">
<el-icon><View /></el-icon>
</el-button>
</el-tooltip>
<el-tooltip content="下载" placement="top" v-if="row.type !== 'folder'">
<el-button link @click="$emit('download', row)">
<el-icon><Download /></el-icon>
</el-button>
</el-tooltip>
</template>
</template>
</el-table-column>
@@ -107,7 +105,7 @@
<script setup>
import {
Document, Folder, Picture, VideoPlay, Headset, RefreshLeft, Delete, View, Share, Download, CloseBold, Edit,
Tickets, Notebook, Reading, Files, DocumentCopy
Tickets, Notebook, Reading, Files, DocumentCopy, MoreFilled
} from '@element-plus/icons-vue'
import FileIcon from './FileIcon.vue'

View File

@@ -40,7 +40,7 @@
</div>
<!-- 第二行面包屑导航 -->
<div class="toolbar-bottom" v-if="menuType !== 'trash'">
<div class="toolbar-bottom">
<el-icon class="breadcrumb-icon"><Folder /></el-icon>
<el-breadcrumb separator="/" v-if="folderStack.length > 0">
<el-breadcrumb-item>

View File

@@ -1,7 +1,7 @@
<template>
<template>
<el-dialog
v-model="visible"
:title="previewFile?.name || '预览'"
title="预览"
width="60%"
top="5vh"
class="preview-dialog-center"

View File

@@ -2,7 +2,7 @@
<el-dialog
v-model="visible"
title="共享文件"
width="500px"
width="400px"
class="custom-dialog"
>
<el-form label-width="80px">

View File

@@ -4,43 +4,65 @@
<div class="logo-icon">
<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="hex-top" x1="24" y1="2" x2="24" y2="46" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#4db6ac"/>
<stop offset="50%" stop-color="#009688"/>
<stop offset="100%" stop-color="#004d40"/>
<!-- 主色调渐变 -->
<linearGradient id="hex-face1" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#00bcd4"/>
<stop offset="100%" stop-color="#0097a7"/>
</linearGradient>
<linearGradient id="hex-front" x1="10" y1="22" x2="38" y2="46" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#26a69a"/>
<stop offset="100%" stop-color="#00796b"/>
<linearGradient id="hex-face2" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#26c6da"/>
<stop offset="100%" stop-color="#00acc1"/>
</linearGradient>
<linearGradient id="hex-side" x1="4" y1="14" x2="24" y2="44" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#00796b"/>
<stop offset="100%" stop-color="#004d40"/>
<linearGradient id="hex-face3" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#4dd0e1"/>
<stop offset="100%" stop-color="#26c6da"/>
</linearGradient>
<linearGradient id="hex-highlight" x1="24" y1="4" x2="24" y2="26" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="rgba(255,255,255,0.5)"/>
<!-- 高光效果 -->
<linearGradient id="hex-shine" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="rgba(255,255,255,0.6)"/>
<stop offset="100%" stop-color="rgba(255,255,255,0)"/>
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="0.5" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
<!-- 阴影滤镜 -->
<filter id="dropShadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="0" dy="2" stdDeviation="2" flood-color="rgba(0,0,0,0.3)"/>
</filter>
</defs>
<!-- 3D Hexagon: side (left) -->
<polygon points="4,14 10,10 10,34 4,38" fill="url(#hex-side)" opacity="0.85"/>
<!-- 3D Hexagon: front face -->
<polygon points="10,10 38,10 44,14 44,38 38,42 10,42 4,38 4,14" fill="url(#hex-front)"/>
<!-- 3D Hexagon: top face -->
<polygon points="10,10 24,3 38,10 10,10" fill="url(#hex-top)" opacity="0.9"/>
<!-- Highlight on top -->
<polygon points="12,10 24,5 36,10" fill="url(#hex-highlight)" opacity="0.6"/>
<!-- Inner subtle line for depth -->
<polygon points="10,10 38,10 44,14 4,14" fill="none" stroke="rgba(255,255,255,0.15)" stroke-width="0.5"/>
<!-- Center icon: stylized folder/cloud -->
<path d="M19 22h-1a3 3 0 00-3 3v6a3 3 0 003 3h12a3 3 0 003-3v-4a3 3 0 00-3-3h-2l-1.5-2H19z" fill="rgba(255,255,255,0.9)" filter="url(#glow)"/>
<!-- 3D 六边形主体 -->
<g filter="url(#dropShadow)">
<!-- 左侧面 -->
<polygon points="24,4 8,12 8,32 24,40" fill="url(#hex-face3)"/>
<!-- 右侧面 -->
<polygon points="24,4 40,12 40,32 24,40" fill="url(#hex-face1)"/>
<!-- 顶面 -->
<polygon points="8,12 24,4 40,12 24,20" fill="url(#hex-face2)"/>
</g>
<!-- 高光边缘 -->
<polygon points="8,12 24,4 40,12" fill="none" stroke="rgba(255,255,255,0.4)" stroke-width="1"/>
<polygon points="8,12 8,32 24,40" fill="none" stroke="rgba(0,0,0,0.1)" stroke-width="0.5"/>
<!-- 文件图标 -->
<g transform="translate(14, 16)">
<!-- 文件夹 -->
<path d="M2 4h6l2 2h8v10H2V4z" fill="rgba(255,255,255,0.95)"/>
<path d="M2 6h18v10H2V6z" fill="rgba(255,255,255,0.85)"/>
<!-- 文件角标 -->
<rect x="12" y="2" width="8" height="10" rx="1" fill="#fff"/>
<rect x="13" y="3" width="6" height="1" fill="#00bcd4"/>
<rect x="13" y="5" width="4" height="1" fill="#b2ebf2"/>
<rect x="13" y="7" width="5" height="1" fill="#b2ebf2"/>
</g>
<!-- 聊天气泡 -->
<g transform="translate(26, 22)">
<ellipse cx="8" cy="8" rx="8" ry="6" fill="#fff"/>
<path d="M6 14l2-2 2 2-2 2z" fill="#fff"/>
<!-- 消息点 -->
<circle cx="5" cy="8" r="1.2" fill="#00bcd4"/>
<circle cx="8" cy="8" r="1.2" fill="#00bcd4"/>
<circle cx="11" cy="8" r="1.2" fill="#00bcd4"/>
</g>
</svg>
</div>
<span class="system-title">云文件管理系统</span>
@@ -67,6 +89,9 @@
<el-dropdown-item command="profile">
<el-icon><User /></el-icon> 个人信息
</el-dropdown-item>
<el-dropdown-item command="changePassword">
<el-icon><Lock /></el-icon> 修改密码
</el-dropdown-item>
<el-dropdown-item divided command="logout">
<el-icon><SwitchButton /></el-icon> 退出系统
</el-dropdown-item>
@@ -80,6 +105,7 @@
<!-- 个人信息弹窗 -->
<ProfileDialog v-model="profileVisible" />
<PasswordDialog v-model="passwordVisible" />
</div>
</template>
@@ -87,18 +113,21 @@
import { ref, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessageBox, ElMessage } from 'element-plus'
import { Folder, ChatDotRound, ArrowDown, User, SwitchButton } from '@element-plus/icons-vue'
import { Folder, ChatDotRound, ArrowDown, User, SwitchButton, Lock } from '@element-plus/icons-vue'
import { useUserStore } from '@/store/user'
import ChatDialog from './ChatDialog.vue'
import ProfileDialog from './ProfileDialog.vue'
import PasswordDialog from './PasswordDialog.vue'
import { chatService } from '@/services/chat'
import { getUnreadCount } from '@/api/message'
import request from '@/api/request'
const router = useRouter()
const userStore = useUserStore()
const chatVisible = ref(false)
const profileVisible = ref(false)
const passwordVisible = ref(false)
const totalUnread = ref(0)
const updateUnread = () => {
@@ -145,6 +174,8 @@ onUnmounted(() => {
const handleUserCommand = (command) => {
if (command === 'profile') {
profileVisible.value = true
} else if (command === 'changePassword') {
passwordVisible.value = true
} else if (command === 'logout') {
ElMessageBox.confirm('确定退出登录吗?', '提示', { type: 'warning' }).then(() => {
userStore.logout()