route: 路由调整
This commit is contained in:
parent
f4991929c6
commit
e39010c484
@ -1,14 +1,736 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>我的资源</h1>
|
||||
<div class="resources-content">
|
||||
<!-- 头部操作区域 -->
|
||||
<div class="resources-header">
|
||||
<div class="resources-title">
|
||||
<h1>我的资源</h1>
|
||||
</div>
|
||||
<div class="resources-actions">
|
||||
<button class="upload-btn" @click="handleUpload">
|
||||
上传文件
|
||||
</button>
|
||||
<button class="new-folder-btn" @click="handleNewFolder">
|
||||
新建文件夹
|
||||
</button>
|
||||
<button class="recycle-bin-btn" @click="handleRecycleBin">
|
||||
回收站
|
||||
</button>
|
||||
<div class="search-container">
|
||||
<input type="text" class="search-input" placeholder="请输入关键字" v-model="searchKeyword"
|
||||
@keyup.enter="handleSearch">
|
||||
<button class="search-btn" @click="handleSearch">
|
||||
搜索
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 文件网格 -->
|
||||
<div class="files-grid">
|
||||
<div v-for="file in filteredFiles" :key="file.id" class="file-item"
|
||||
:class="{ 'selected': selectedFiles.includes(file.id) }" @click="handleFileClick(file)"
|
||||
@contextmenu.prevent="handleRightClick(file, $event)" @mouseenter="hoveredFile = file.id"
|
||||
@mouseleave="hoveredFile = null">
|
||||
<!-- 文件操作菜单 -->
|
||||
<div class="file-menu">
|
||||
<button class="file-menu-btn" @click.stop="toggleMenu(file.id)">
|
||||
<img src="/images/profile/more.png" alt="更多操作" class="more-icon">
|
||||
</button>
|
||||
<div class="file-menu-dropdown" v-if="showMenuFor === file.id">
|
||||
<div class="menu-item" @click="handleEdit(file)">
|
||||
<span class="edit-icon">✏️</span>
|
||||
编辑
|
||||
</div>
|
||||
<div class="menu-item" @click="handleMove(file)">
|
||||
<span class="move-icon">📁</span>
|
||||
+ 移动
|
||||
</div>
|
||||
<div class="menu-item delete" @click="handleDelete(file)">
|
||||
<span class="delete-icon">🗑️</span>
|
||||
删除
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 文件图标 -->
|
||||
<div class="file-icon">
|
||||
<img :src="getFileIcon(file)" :alt="file.type === 'folder' ? '文件夹图标' : '文件图标'" class="folder-icon">
|
||||
</div>
|
||||
|
||||
<!-- 文件名称 -->
|
||||
<div class="file-name" :title="file.name">{{ file.name }}</div>
|
||||
|
||||
<!-- 文件详情悬浮框 -->
|
||||
<div class="file-details" v-if="hoveredFile === file.id">
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">文件名称:</span>
|
||||
<span class="detail-value">{{ file.name }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">大小:</span>
|
||||
<span class="detail-value">{{ formatFileSize(file.size) }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">修改时间:</span>
|
||||
<span class="detail-value">{{ formatDate(file.modifiedAt) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新建文件夹对话框 -->
|
||||
<div class="modal-overlay" v-if="showNewFolderModal" @click="closeNewFolderModal">
|
||||
<div class="modal-content" @click.stop>
|
||||
<h3>新建文件夹</h3>
|
||||
<input type="text" v-model="newFolderName" placeholder="请输入文件夹名称" @keyup.enter="confirmNewFolder">
|
||||
<div class="modal-actions">
|
||||
<button class="cancel-btn" @click="closeNewFolderModal">取消</button>
|
||||
<button class="confirm-btn" @click="confirmNewFolder">确定</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 文件上传对话框 -->
|
||||
<div class="modal-overlay" v-if="showUploadModal" @click="closeUploadModal">
|
||||
<div class="modal-content" @click.stop>
|
||||
<h3>上传文件</h3>
|
||||
<div class="upload-area" @click="triggerFileInput" @dragover.prevent @drop.prevent="handleDrop">
|
||||
<input ref="fileInput" type="file" multiple @change="handleFileSelect" style="display: none">
|
||||
<div class="upload-icon">📁</div>
|
||||
<p>点击选择文件或拖拽文件到此处</p>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button class="cancel-btn" @click="closeUploadModal">取消</button>
|
||||
<button class="confirm-btn" @click="confirmUpload">上传</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
|
||||
// 文件类型定义
|
||||
interface FileItem {
|
||||
id: string
|
||||
name: string
|
||||
type: 'file' | 'folder'
|
||||
size: number
|
||||
modifiedAt: string
|
||||
parentId?: string
|
||||
}
|
||||
|
||||
// 响应式数据
|
||||
const searchKeyword = ref('')
|
||||
const selectedFiles = ref<string[]>([])
|
||||
const showMenuFor = ref<string | null>(null)
|
||||
const hoveredFile = ref<string | null>(null)
|
||||
const showNewFolderModal = ref(false)
|
||||
const showUploadModal = ref(false)
|
||||
const newFolderName = ref('')
|
||||
const fileInput = ref<HTMLInputElement>()
|
||||
const selectedFilesToUpload = ref<File[]>([])
|
||||
|
||||
// 模拟文件数据
|
||||
const files = ref<FileItem[]>([
|
||||
{ id: '1', name: '图片', type: 'folder', size: 0, modifiedAt: '2024-01-15 09:25' },
|
||||
{ id: '2', name: '文档', type: 'folder', size: 0, modifiedAt: '2024-01-14 14:30' },
|
||||
{ id: '3', name: '视频', type: 'folder', size: 0, modifiedAt: '2024-01-13 16:45' },
|
||||
{ id: '4', name: '种子', type: 'file', size: 14912, modifiedAt: '2024-01-12 08:25' },
|
||||
{ id: '5', name: '音频', type: 'folder', size: 0, modifiedAt: '2024-01-11 11:20' },
|
||||
{ id: '6', name: '文件名称', type: 'file', size: 2048, modifiedAt: '2024-01-10 15:30' },
|
||||
{ id: '7', name: '文件名称', type: 'file', size: 1024, modifiedAt: '2024-01-09 10:15' },
|
||||
{ id: '8', name: '文件名称', type: 'file', size: 512, modifiedAt: '2024-01-08 13:45' },
|
||||
{ id: '9', name: '文件名称', type: 'file', size: 4096, modifiedAt: '2024-01-07 09:30' },
|
||||
{ id: '10', name: '文件名称', type: 'file', size: 8192, modifiedAt: '2024-01-06 16:20' },
|
||||
{ id: '11', name: '文件名称', type: 'file', size: 256, modifiedAt: '2024-01-05 12:10' },
|
||||
{ id: '12', name: '文件名称', type: 'file', size: 1536, modifiedAt: '2024-01-04 14:55' },
|
||||
{ id: '13', name: '文件名称', type: 'file', size: 3072, modifiedAt: '2024-01-03 11:40' },
|
||||
{ id: '14', name: '文件名称', type: 'file', size: 6144, modifiedAt: '2024-01-02 08:25' },
|
||||
{ id: '15', name: '文件名称', type: 'file', size: 128, modifiedAt: '2024-01-01 17:15' },
|
||||
{ id: '16', name: '文件名称', type: 'file', size: 768, modifiedAt: '2023-12-31 20:30' }
|
||||
])
|
||||
|
||||
// 计算属性
|
||||
const filteredFiles = computed(() => {
|
||||
let result = files.value
|
||||
|
||||
// 按关键词搜索
|
||||
if (searchKeyword.value) {
|
||||
result = result.filter((file: FileItem) =>
|
||||
file.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
||||
)
|
||||
}
|
||||
|
||||
return result
|
||||
})
|
||||
|
||||
// 方法
|
||||
const getFileIcon = (file: FileItem) => {
|
||||
if (file.type === 'folder') {
|
||||
return '/images/profile/folder.png'
|
||||
}
|
||||
// 根据文件扩展名返回不同图标
|
||||
const ext = file.name.split('.').pop()?.toLowerCase()
|
||||
switch (ext) {
|
||||
case 'jpg':
|
||||
case 'jpeg':
|
||||
case 'png':
|
||||
case 'gif':
|
||||
return '/images/profile/image.png'
|
||||
case 'mp4':
|
||||
case 'avi':
|
||||
case 'mov':
|
||||
return '/images/profile/video.png'
|
||||
case 'mp3':
|
||||
case 'wav':
|
||||
case 'flac':
|
||||
return '/images/profile/audio.png'
|
||||
case 'pdf':
|
||||
return '/images/profile/pdf.png'
|
||||
case 'doc':
|
||||
case 'docx':
|
||||
return '/images/profile/word.png'
|
||||
case 'xls':
|
||||
case 'xlsx':
|
||||
return '/images/profile/excel.png'
|
||||
case 'ppt':
|
||||
case 'pptx':
|
||||
return '/images/profile/powerpoint.png'
|
||||
default:
|
||||
return '/images/profile/file.png'
|
||||
}
|
||||
}
|
||||
|
||||
const formatFileSize = (bytes: number) => {
|
||||
if (bytes === 0) return '0 B'
|
||||
const k = 1024
|
||||
const sizes = ['B', 'KB', 'MB', 'GB']
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
|
||||
}
|
||||
|
||||
const formatDate = (dateString: string) => {
|
||||
return dateString
|
||||
}
|
||||
|
||||
const handleFileClick = (file: FileItem) => {
|
||||
if (file.type === 'folder') {
|
||||
// 进入文件夹
|
||||
console.log('进入文件夹:', file.name)
|
||||
} else {
|
||||
// 选择文件
|
||||
const index = selectedFiles.value.indexOf(file.id)
|
||||
if (index > -1) {
|
||||
selectedFiles.value.splice(index, 1)
|
||||
} else {
|
||||
selectedFiles.value.push(file.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleRightClick = (file: FileItem, event: MouseEvent) => {
|
||||
event.preventDefault()
|
||||
showMenuFor.value = file.id
|
||||
}
|
||||
|
||||
const toggleMenu = (fileId: string) => {
|
||||
showMenuFor.value = showMenuFor.value === fileId ? null : fileId
|
||||
}
|
||||
|
||||
const handleEdit = (file: FileItem) => {
|
||||
console.log('编辑文件:', file.name)
|
||||
showMenuFor.value = null
|
||||
}
|
||||
|
||||
const handleMove = (file: FileItem) => {
|
||||
console.log('移动文件:', file.name)
|
||||
showMenuFor.value = null
|
||||
}
|
||||
|
||||
const handleDelete = (file: FileItem) => {
|
||||
if (confirm(`确定要删除 "${file.name}" 吗?`)) {
|
||||
const index = files.value.findIndex((f: FileItem) => f.id === file.id)
|
||||
if (index > -1) {
|
||||
files.value.splice(index, 1)
|
||||
}
|
||||
}
|
||||
showMenuFor.value = null
|
||||
}
|
||||
|
||||
const handleSearch = () => {
|
||||
console.log('搜索:', searchKeyword.value)
|
||||
}
|
||||
|
||||
const handleUpload = () => {
|
||||
showUploadModal.value = true
|
||||
}
|
||||
|
||||
const handleNewFolder = () => {
|
||||
showNewFolderModal.value = true
|
||||
}
|
||||
|
||||
const handleRecycleBin = () => {
|
||||
console.log('打开回收站')
|
||||
}
|
||||
|
||||
const closeNewFolderModal = () => {
|
||||
showNewFolderModal.value = false
|
||||
newFolderName.value = ''
|
||||
}
|
||||
|
||||
const confirmNewFolder = () => {
|
||||
if (newFolderName.value.trim()) {
|
||||
const newFolder: FileItem = {
|
||||
id: Date.now().toString(),
|
||||
name: newFolderName.value.trim(),
|
||||
type: 'folder',
|
||||
size: 0,
|
||||
modifiedAt: new Date().toLocaleString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
}).replace(/\//g, '-')
|
||||
}
|
||||
files.value.push(newFolder)
|
||||
closeNewFolderModal()
|
||||
}
|
||||
}
|
||||
|
||||
const closeUploadModal = () => {
|
||||
showUploadModal.value = false
|
||||
selectedFilesToUpload.value = []
|
||||
}
|
||||
|
||||
const triggerFileInput = () => {
|
||||
fileInput.value?.click()
|
||||
}
|
||||
|
||||
const handleFileSelect = (event: Event) => {
|
||||
const target = event.target as HTMLInputElement
|
||||
if (target.files) {
|
||||
selectedFilesToUpload.value = Array.from(target.files)
|
||||
}
|
||||
}
|
||||
|
||||
const handleDrop = (event: DragEvent) => {
|
||||
if (event.dataTransfer?.files) {
|
||||
selectedFilesToUpload.value = Array.from(event.dataTransfer.files)
|
||||
}
|
||||
}
|
||||
|
||||
const confirmUpload = () => {
|
||||
if (selectedFilesToUpload.value.length > 0) {
|
||||
selectedFilesToUpload.value.forEach((file: File) => {
|
||||
const newFile: FileItem = {
|
||||
id: Date.now().toString() + Math.random(),
|
||||
name: file.name,
|
||||
type: 'file',
|
||||
size: file.size,
|
||||
modifiedAt: new Date().toLocaleString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
}).replace(/\//g, '-')
|
||||
}
|
||||
files.value.push(newFile)
|
||||
})
|
||||
closeUploadModal()
|
||||
}
|
||||
}
|
||||
|
||||
// 点击外部关闭菜单
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', () => {
|
||||
showMenuFor.value = null
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
.resources-content {
|
||||
padding: 0;
|
||||
background: #F5F7FA;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 头部操作区域 */
|
||||
.resources-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 0;
|
||||
background: white;
|
||||
padding: 20px 30px;
|
||||
border-bottom: 1px solid #E8E8E8;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.resources-title h1 {
|
||||
margin: 0;
|
||||
color: #333;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.resources-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.upload-btn,
|
||||
.new-folder-btn,
|
||||
.recycle-bin-btn {
|
||||
padding: 6px 16px;
|
||||
border: 1px solid #0288D1;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: all 0.3s ease;
|
||||
background: white;
|
||||
color: #0288D1;
|
||||
min-width: 70px;
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.upload-btn {
|
||||
background: #0288D1;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.upload-btn:hover {
|
||||
background: #0277BD;
|
||||
}
|
||||
|
||||
.new-folder-btn:hover,
|
||||
.recycle-bin-btn:hover {
|
||||
background: #F5F8FB;
|
||||
color: #0288D1;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: white;
|
||||
border: 1px solid #D9D9D9;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
padding: 6px 12px;
|
||||
border: none;
|
||||
outline: none;
|
||||
width: 180px;
|
||||
font-size: 14px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.search-btn {
|
||||
padding: 6px 16px;
|
||||
background: #0288D1;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
font-size: 14px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.search-btn:hover {
|
||||
background: #0277BD;
|
||||
}
|
||||
|
||||
|
||||
/* 文件网格 */
|
||||
.files-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(8, 1fr);
|
||||
gap: 20px;
|
||||
background: white;
|
||||
padding: 30px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.file-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px 15px;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
border: 1.5px solid #D8D8D8;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.file-item:hover {
|
||||
background: #F5F8FB;
|
||||
border-color: #0288D1;
|
||||
}
|
||||
|
||||
.file-item.selected {
|
||||
background: #E3F2FD;
|
||||
border-color: #0288D1;
|
||||
}
|
||||
|
||||
.file-menu {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.file-menu-btn {
|
||||
width: 6px;
|
||||
height: 24px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.file-menu-btn:hover {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.more-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.file-menu-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
background: white;
|
||||
border: 1px solid #D9D9D9;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
min-width: 120px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background 0.2s ease;
|
||||
}
|
||||
|
||||
.menu-item:hover {
|
||||
background: #F5F5F5;
|
||||
}
|
||||
|
||||
.menu-item.delete {
|
||||
color: #FF4D4F;
|
||||
}
|
||||
|
||||
.menu-item.delete:hover {
|
||||
background: #FFF2F0;
|
||||
}
|
||||
|
||||
.file-icon {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.folder-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.file-name {
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
max-width: 100px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.file-details {
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: white;
|
||||
border: 1px solid #D9D9D9;
|
||||
border-radius: 6px;
|
||||
padding: 12px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
z-index: 1000;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.detail-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 4px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 模态框样式 */
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
min-width: 400px;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.modal-content h3 {
|
||||
margin: 0 0 20px 0;
|
||||
color: #333;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.modal-content input {
|
||||
width: 100%;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid #D9D9D9;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
outline: none;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.upload-area {
|
||||
border: 2px dashed #D9D9D9;
|
||||
border-radius: 6px;
|
||||
padding: 40px 20px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.3s ease;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.upload-area:hover {
|
||||
border-color: #0288D1;
|
||||
}
|
||||
|
||||
.upload-icon {
|
||||
font-size: 48px;
|
||||
margin-bottom: 12px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.upload-area p {
|
||||
margin: 0;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.modal-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.cancel-btn,
|
||||
.confirm-btn {
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
background: #F5F5F5;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.cancel-btn:hover {
|
||||
background: #E6E6E6;
|
||||
}
|
||||
|
||||
.confirm-btn {
|
||||
background: #0288D1;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.confirm-btn:hover {
|
||||
background: #0277BD;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.resources-header {
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.resources-actions {
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.files-grid {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 15px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
min-width: 300px;
|
||||
margin: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 更小屏幕的响应式设计 */
|
||||
@media (max-width: 480px) {
|
||||
.files-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 10px;
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -84,6 +84,7 @@ import ExamTaking from '@/views/teacher/ExamPages/ExamTaking.vue'
|
||||
import ExamNoticeBeforeStart from '@/views/teacher/ExamPages/ExamNoticeBeforeStart.vue'
|
||||
|
||||
import ChapterEditor from '@/views/teacher/course/ChapterEditor.vue'
|
||||
import TeacherCourseDetail from '@/views/teacher/course/CourseDetail.vue'
|
||||
|
||||
// ========== 路由配置 ==========
|
||||
const routes: RouteRecordRaw[] = [
|
||||
@ -509,6 +510,12 @@ const routes: RouteRecordRaw[] = [
|
||||
component: CourseDetail,
|
||||
meta: { title: '课程详情' }
|
||||
},
|
||||
{
|
||||
path: '/teacher/course-detail/:id',
|
||||
name: 'TeacherCourseDetail',
|
||||
component: TeacherCourseDetail,
|
||||
meta: { title: '教师端课程详情', requiresAuth: true }
|
||||
},
|
||||
{
|
||||
path: '/course/:id/enrolled',
|
||||
name: 'CourseDetailEnrolled',
|
||||
|
3
src/views/teacher/course/CourseDetail.vue
Normal file
3
src/views/teacher/course/CourseDetail.vue
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>教师课程详情</div>
|
||||
</template>
|
Loading…
x
Reference in New Issue
Block a user