399 lines
7.4 KiB
Vue
399 lines
7.4 KiB
Vue
<template>
|
||
<div class="file-manager">
|
||
<!-- 左侧菜单 -->
|
||
<div class="sidebar">
|
||
<!-- Logo -->
|
||
<div class="logo">
|
||
<router-link to="/" class="back-btn">
|
||
<i class="icon">←</i>
|
||
</router-link>
|
||
<img src="@/assets/logo.svg" alt="Logo"/>
|
||
<span>Flow Design</span>
|
||
</div>
|
||
|
||
<!-- 新建按钮组 -->
|
||
<div class="action-buttons">
|
||
<button class="btn-new" @click="handleCreate">
|
||
<i class="icon">+</i>
|
||
新建
|
||
</button>
|
||
<button class="btn-template" @click="openTemplateDialog">
|
||
<i class="icon">📋</i>
|
||
从模板新建
|
||
</button>
|
||
</div>
|
||
|
||
<!-- 菜单列表 -->
|
||
<nav class="menu-list">
|
||
<router-link
|
||
to="/files/my-files"
|
||
class="menu-item"
|
||
active-class="active"
|
||
>
|
||
<i class="icon">📁</i>
|
||
我的文件
|
||
</router-link>
|
||
<router-link
|
||
to="/files/favorites"
|
||
class="menu-item"
|
||
active-class="active"
|
||
>
|
||
<i class="icon">⭐</i>
|
||
我的收藏
|
||
</router-link>
|
||
<router-link
|
||
to="/files/recent"
|
||
class="menu-item"
|
||
active-class="active"
|
||
>
|
||
<i class="icon">🕒</i>
|
||
最近
|
||
</router-link>
|
||
<div class="menu-divider"></div>
|
||
<router-link
|
||
to="/files/recommended"
|
||
class="menu-item"
|
||
active-class="active"
|
||
>
|
||
<i class="icon">🔥</i>
|
||
推荐
|
||
</router-link>
|
||
<router-link
|
||
to="/files/community"
|
||
class="menu-item"
|
||
active-class="active"
|
||
>
|
||
<i class="icon">👥</i>
|
||
社区
|
||
</router-link>
|
||
<div class="menu-divider"></div>
|
||
<router-link
|
||
to="/files/trash"
|
||
class="menu-item"
|
||
active-class="active"
|
||
>
|
||
<i class="icon">🗑️</i>
|
||
回收站
|
||
</router-link>
|
||
</nav>
|
||
</div>
|
||
|
||
<!-- 右侧内容区 -->
|
||
<div class="content">
|
||
<!-- 顶部搜索栏 -->
|
||
<div class="search-bar">
|
||
<div class="search-input">
|
||
<i class="icon">🔍</i>
|
||
<input type="text" placeholder="搜索文件"/>
|
||
</div>
|
||
<div class="view-options">
|
||
<button class="btn-view active">
|
||
<i class="icon">📊</i>
|
||
</button>
|
||
<button class="btn-view">
|
||
<i class="icon">📋</i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 路由出口 -->
|
||
<router-view/>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { useRouter } from 'vue-router'
|
||
import nodesData from '@/assets/data/nodes.json'
|
||
import businessProcess from '@/assets/examples/business-process.svg'
|
||
import mindMap from '@/assets/examples/mind-map.svg'
|
||
import umlDiagram from '@/assets/examples/uml.svg'
|
||
import orgChart from '@/assets/examples/org-chart.svg'
|
||
import defaultAvatar from '@/assets/avatars/default-avatar.svg'
|
||
|
||
const router = useRouter()
|
||
|
||
// 图片映射
|
||
const previewMap = {
|
||
'business-process': businessProcess,
|
||
'mind-map': mindMap,
|
||
'uml': umlDiagram,
|
||
'org-chart': orgChart,
|
||
'default-avatar': defaultAvatar
|
||
}
|
||
|
||
// 提供给子组件的数据
|
||
const processedData = {
|
||
files: nodesData.files.map(file => ({
|
||
...file,
|
||
preview: previewMap[file.preview as keyof typeof previewMap]
|
||
})),
|
||
templates: nodesData.templates.map(template => ({
|
||
...template,
|
||
preview: previewMap[template.preview as keyof typeof previewMap]
|
||
})),
|
||
communityItems: nodesData.communityItems.map(item => ({
|
||
...item,
|
||
preview: previewMap[item.preview as keyof typeof previewMap],
|
||
authorAvatar: previewMap[item.authorAvatar as keyof typeof previewMap]
|
||
})),
|
||
deletedFiles: nodesData.deletedFiles.map(file => ({
|
||
...file,
|
||
preview: previewMap[file.preview as keyof typeof previewMap]
|
||
}))
|
||
}
|
||
|
||
// 导出处理后的数据供子组件使用
|
||
defineExpose(processedData)
|
||
|
||
const handleCreate = () => {
|
||
router.push('/flow-editor')
|
||
}
|
||
|
||
const openTemplateDialog = () => {
|
||
router.push('/flow-editor')
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.file-manager {
|
||
display: flex;
|
||
min-height: 100vh;
|
||
width: 100vw;
|
||
background: #fff;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.sidebar {
|
||
width: 240px;
|
||
min-width: 240px;
|
||
background: #fff;
|
||
border-right: 1px solid #e4e7ed;
|
||
padding: 20px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 100%;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.logo {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding: 0 12px;
|
||
margin-bottom: 24px;
|
||
}
|
||
|
||
.logo img {
|
||
height: 32px;
|
||
}
|
||
|
||
.logo span {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
color: #1a1a1a;
|
||
}
|
||
|
||
.action-buttons {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
margin-bottom: 24px;
|
||
}
|
||
|
||
.btn-new, .btn-template {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding: 12px;
|
||
border: none;
|
||
border-radius: 6px;
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.btn-new {
|
||
background: #409eff;
|
||
color: #fff;
|
||
}
|
||
|
||
.btn-new:hover {
|
||
background: #66b1ff;
|
||
}
|
||
|
||
.btn-template {
|
||
background: #f5f7fa;
|
||
color: #606266;
|
||
}
|
||
|
||
.btn-template:hover {
|
||
background: #e4e7ed;
|
||
}
|
||
|
||
.menu-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4px;
|
||
}
|
||
|
||
.menu-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding: 12px;
|
||
border-radius: 6px;
|
||
color: #606266;
|
||
text-decoration: none;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.menu-item:hover {
|
||
background: #f5f7fa;
|
||
}
|
||
|
||
.menu-item.active {
|
||
background: #ecf5ff;
|
||
color: #409eff;
|
||
}
|
||
|
||
.menu-divider {
|
||
height: 1px;
|
||
background: #e4e7ed;
|
||
margin: 12px 0;
|
||
}
|
||
|
||
.content {
|
||
flex: 1;
|
||
padding: 20px;
|
||
background: #f5f7fa;
|
||
overflow-y: auto;
|
||
height: 100%;
|
||
width: calc(100% - 240px);
|
||
}
|
||
|
||
.search-bar {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 24px;
|
||
}
|
||
|
||
.search-input {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
background: #fff;
|
||
padding: 8px 16px;
|
||
border-radius: 6px;
|
||
width: 300px;
|
||
}
|
||
|
||
.search-input input {
|
||
border: none;
|
||
outline: none;
|
||
font-size: 14px;
|
||
width: 100%;
|
||
}
|
||
|
||
.view-options {
|
||
display: flex;
|
||
gap: 8px;
|
||
}
|
||
|
||
.btn-view {
|
||
padding: 8px;
|
||
border: none;
|
||
border-radius: 4px;
|
||
background: #fff;
|
||
cursor: pointer;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.btn-view:hover, .btn-view.active {
|
||
background: #ecf5ff;
|
||
color: #409eff;
|
||
}
|
||
|
||
.file-list {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||
gap: 20px;
|
||
}
|
||
|
||
.file-card {
|
||
background: #fff;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
transition: transform 0.2s;
|
||
}
|
||
|
||
.file-card:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.file-preview {
|
||
aspect-ratio: 16/9;
|
||
background: #f5f7fa;
|
||
}
|
||
|
||
.file-preview img {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
}
|
||
|
||
.file-info {
|
||
padding: 12px;
|
||
}
|
||
|
||
.file-info h3 {
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
color: #1a1a1a;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.file-info p {
|
||
font-size: 12px;
|
||
color: #909399;
|
||
}
|
||
|
||
.back-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 24px;
|
||
height: 24px;
|
||
border-radius: 4px;
|
||
color: #606266;
|
||
text-decoration: none;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.back-btn:hover {
|
||
background: #f5f7fa;
|
||
color: #409eff;
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.sidebar {
|
||
width: 200px;
|
||
min-width: 200px;
|
||
}
|
||
|
||
.content {
|
||
width: calc(100% - 200px);
|
||
}
|
||
|
||
.search-input {
|
||
width: 200px;
|
||
}
|
||
}
|
||
</style> |