// 项目数据 const projectsData = [ { id: 1, title: "智慧工厂", date: "2024-06-08 15:56:35", type: "industrial", image: "🏭", favorite: true }, { id: 2, title: "智慧水务", date: "2023-01-10 12:09:04", type: "smart", image: "💧", favorite: false }, { id: 3, title: "数字工厂", date: "2024-06-07 06:57:46", type: "industrial", image: "🏗️", favorite: false }, { id: 4, title: "智慧监控", date: "2024-07-28 17:38:02", type: "smart", image: "📊", favorite: true }, { id: 5, title: "工业设计平台", date: "2025-02-28 18:00:05", type: "design", image: "🎨", favorite: false } ]; // DOM 元素 const createProjectBtn = document.getElementById('createProjectBtn'); const createProjectModal = document.getElementById('createProjectModal'); const importProjectModal = document.getElementById('importProjectModal'); const closeCreateModal = document.getElementById('closeCreateModal'); const closeImportModal = document.getElementById('closeImportModal'); const cancelCreate = document.getElementById('cancelCreate'); const cancelImport = document.getElementById('cancelImport'); const confirmCreate = document.getElementById('confirmCreate'); const confirmImport = document.getElementById('confirmImport'); const projectsGrid = document.getElementById('projectsGrid'); const uploadZone = document.getElementById('uploadZone'); const fileInput = document.getElementById('fileInput'); const projectNameInput = document.getElementById('projectName'); // 搜索和过滤相关元素 let searchBtn, filterBtn, searchFilterArea, searchInput, sortSelect, typeFilter; // 过滤和排序状态 let filteredProjects = [...projectsData]; let currentSearchTerm = ''; let currentSortBy = 'date-desc'; let currentTypeFilter = 'all'; // 初始化 document.addEventListener('DOMContentLoaded', function() { initializeSearchElements(); renderProjects(); initEventListeners(); }); // 初始化搜索相关元素 function initializeSearchElements() { searchBtn = document.getElementById('searchBtn'); filterBtn = document.getElementById('filterBtn'); searchFilterArea = document.getElementById('searchFilterArea'); searchInput = document.getElementById('searchInput'); sortSelect = document.getElementById('sortSelect'); typeFilter = document.getElementById('typeFilter'); } // 渲染项目列表 function renderProjects() { projectsGrid.innerHTML = ''; // 应用过滤和排序 applyFiltersAndSort(); if (filteredProjects.length === 0) { projectsGrid.innerHTML = `

没有找到匹配的项目

`; return; } filteredProjects.forEach(project => { const projectCard = document.createElement('div'); projectCard.className = 'project-card'; projectCard.innerHTML = `
${project.title}
${project.favorite ? '' : ''}
${project.image}
${getProjectTypeLabel(project.type)}
`; // 项目卡片点击事件(排除菜单按钮) projectCard.addEventListener('click', (e) => { if (!e.target.closest('.project-menu')) { openProject(project.id); } }); // 菜单按钮点击事件 const menuBtn = projectCard.querySelector('.project-menu'); menuBtn.addEventListener('click', (e) => { e.stopPropagation(); showProjectMenu(project.id, menuBtn); }); projectsGrid.appendChild(projectCard); }); } // 应用过滤和排序 function applyFiltersAndSort() { // 首先应用搜索过滤 filteredProjects = projectsData.filter(project => { const matchesSearch = currentSearchTerm === '' || project.title.toLowerCase().includes(currentSearchTerm.toLowerCase()); const matchesType = currentTypeFilter === 'all' || project.type === currentTypeFilter; return matchesSearch && matchesType; }); // 然后应用排序 filteredProjects.sort((a, b) => { switch (currentSortBy) { case 'date-desc': return new Date(b.date) - new Date(a.date); case 'date-asc': return new Date(a.date) - new Date(b.date); case 'name-asc': return a.title.localeCompare(b.title); case 'name-desc': return b.title.localeCompare(a.title); default: return 0; } }); } // 初始化事件监听器 function initEventListeners() { // 创建项目按钮 - 顶部和侧边栏 createProjectBtn.addEventListener('click', () => { showModal(createProjectModal); }); const sidebarCreateBtn = document.getElementById('sidebarCreateBtn'); const sidebarImportBtn = document.getElementById('sidebarImportBtn'); if (sidebarCreateBtn) { sidebarCreateBtn.addEventListener('click', () => { showModal(createProjectModal); }); } if (sidebarImportBtn) { sidebarImportBtn.addEventListener('click', () => { showModal(importProjectModal); }); } // 关闭模态框 closeCreateModal.addEventListener('click', () => { hideModal(createProjectModal); }); closeImportModal.addEventListener('click', () => { hideModal(importProjectModal); }); // 取消按钮 cancelCreate.addEventListener('click', () => { hideModal(createProjectModal); }); cancelImport.addEventListener('click', () => { hideModal(importProjectModal); }); // 确认按钮 confirmCreate.addEventListener('click', () => { createProject(); }); confirmImport.addEventListener('click', () => { importProject(); }); // 树状结构展开/折叠 initTreeStructure(); // 搜索和过滤功能 initSearchAndFilter(); // 模板选择 const templateItems = document.querySelectorAll('.template-item'); templateItems.forEach(item => { item.addEventListener('click', () => { templateItems.forEach(t => t.classList.remove('selected')); item.classList.add('selected'); updateTemplateDescription(item.dataset.template); }); }); // 文件上传 uploadZone.addEventListener('click', () => { fileInput.click(); }); uploadZone.addEventListener('dragover', (e) => { e.preventDefault(); uploadZone.classList.add('dragover'); }); uploadZone.addEventListener('dragleave', () => { uploadZone.classList.remove('dragover'); }); uploadZone.addEventListener('drop', (e) => { e.preventDefault(); uploadZone.classList.remove('dragover'); handleFileUpload(e.dataTransfer.files); }); fileInput.addEventListener('change', (e) => { handleFileUpload(e.target.files); }); // 点击模态框外部关闭 createProjectModal.addEventListener('click', (e) => { if (e.target === createProjectModal) { hideModal(createProjectModal); } }); importProjectModal.addEventListener('click', (e) => { if (e.target === importProjectModal) { hideModal(importProjectModal); } }); // 导航菜单项点击 const navItems = document.querySelectorAll('.nav-item'); navItems.forEach(item => { item.addEventListener('click', () => { navItems.forEach(nav => nav.classList.remove('active')); item.classList.add('active'); // 更新面包屑导航 updateBreadcrumb(item); // 根据页面类型过滤项目 const pageType = item.dataset.page; if (pageType) { filterProjectsByPage(pageType); } }); }); // 浏览位置按钮 const browseLocationBtn = document.getElementById('browseLocation'); if (browseLocationBtn) { browseLocationBtn.addEventListener('click', () => { browseProjectLocation(); }); } // 视图切换 const viewBtns = document.querySelectorAll('.view-btn[data-view]'); viewBtns.forEach(btn => { btn.addEventListener('click', () => { viewBtns.forEach(v => v.classList.remove('active')); btn.classList.add('active'); const view = btn.dataset.view; if (view === 'list') { projectsGrid.style.gridTemplateColumns = '1fr'; } else { projectsGrid.style.gridTemplateColumns = 'repeat(auto-fill, minmax(280px, 1fr))'; } }); }); // 添加导入项目的快捷方式 const importBtn = document.createElement('button'); importBtn.className = 'btn-secondary'; importBtn.innerHTML = ' 导入'; importBtn.style.marginLeft = '10px'; importBtn.addEventListener('click', () => { showModal(importProjectModal); }); const topActions = document.querySelector('.top-actions'); topActions.insertBefore(importBtn, createProjectBtn); } // 显示模态框 function showModal(modal) { modal.classList.add('show'); document.body.style.overflow = 'hidden'; } // 隐藏模态框 function hideModal(modal) { modal.classList.remove('show'); document.body.style.overflow = 'auto'; // 重置表单 if (modal === createProjectModal) { projectNameInput.value = ''; document.querySelectorAll('.template-item').forEach(item => { item.classList.remove('selected'); }); } } // 创建项目 function createProject() { const projectName = projectNameInput.value.trim(); const selectedTemplate = document.querySelector('.template-item.selected'); if (!projectName) { alert('请输入项目名称'); return; } if (!selectedTemplate) { alert('请选择项目模板'); return; } const templateType = selectedTemplate.dataset.template; const templateIcons = { empty: '📄', industrial: '🏭', vr: '🥽', smart: '📊', game: '🎮' }; const newProject = { id: projectsData.length + 1, title: projectName, date: new Date().toLocaleString('zh-CN'), type: templateType, image: templateIcons[templateType] || '📄' }; projectsData.unshift(newProject); renderProjects(); hideModal(createProjectModal); // 显示成功消息 showNotification('项目创建成功!', 'success'); } // 导入项目 function importProject() { const files = fileInput.files; if (files.length === 0) { alert('请选择要导入的文件'); return; } // 模拟导入过程 showNotification('正在导入项目...', 'info'); setTimeout(() => { const newProject = { id: projectsData.length + 1, title: `导入的项目_${Date.now()}`, date: new Date().toLocaleString('zh-CN'), type: 'imported', image: '📦' }; projectsData.unshift(newProject); renderProjects(); hideModal(importProjectModal); showNotification('项目导入成功!', 'success'); }, 2000); } // 处理文件上传 function handleFileUpload(files) { if (files.length > 0) { const file = files[0]; const allowedTypes = ['.zip', '.rar', '.7z']; const fileExtension = '.' + file.name.split('.').pop().toLowerCase(); if (allowedTypes.includes(fileExtension)) { fileInput.files = files; uploadZone.innerHTML = `

已选择文件: ${file.name}

`; } else { alert('请选择支持的文件格式 (.zip, .rar, .7z)'); } } } // 打开项目 function openProject(projectId) { const project = projectsData.find(p => p.id === projectId); if (project) { showNotification(`正在打开项目: ${project.title}`, 'info'); // 这里可以添加实际的项目打开逻辑 } } // 显示通知 function showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.className = `notification ${type}`; notification.textContent = message; notification.style.cssText = ` position: fixed; top: 20px; right: 20px; padding: 15px 20px; background: ${type === 'success' ? '#10b981' : type === 'error' ? '#ef4444' : '#3b82f6'}; color: white; border-radius: 8px; z-index: 3000; animation: slideIn 0.3s ease; `; document.body.appendChild(notification); setTimeout(() => { notification.style.animation = 'slideOut 0.3s ease'; setTimeout(() => { if (document.body.contains(notification)) { document.body.removeChild(notification); } }, 300); }, 3000); } // 打开项目 function openProject(projectId) { const project = projectsData.find(p => p.id === projectId); if (project) { showNotification(`正在打开项目: ${project.title}`, 'info'); // 这里可以添加实际的项目打开逻辑 } } // 显示通知 function showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.className = `notification ${type}`; notification.textContent = message; notification.style.cssText = ` position: fixed; top: 20px; right: 20px; padding: 15px 20px; background: ${type === 'success' ? '#10b981' : type === 'error' ? '#ef4444' : '#3b82f6'}; color: white; border-radius: 8px; z-index: 3000; animation: slideIn 0.3s ease; `; document.body.appendChild(notification); setTimeout(() => { notification.style.animation = 'slideOut 0.3s ease'; setTimeout(() => { if (document.body.contains(notification)) { document.body.removeChild(notification); } }, 300); }, 3000); } // 更新模板描述 function updateTemplateDescription(templateType) { const templateDescription = document.getElementById('templateDescription'); if (!templateDescription) return; const descriptions = { empty: { title: '空白项目模板', description: '从零开始创建项目,适合有经验的开发者。提供基础的项目结构和配置文件,您可以根据需要自由定制。' }, industrial: { title: '工业项目模板', description: '专为工业应用设计的项目模板。包含工业设备监控、数据采集、生产流程管理等常用功能模块和界面组件。' }, vr: { title: 'VR虚拟现实模板', description: '虚拟现实项目模板,集成VR交互组件和3D场景管理。适合创建沉浸式体验、虚拟展示和培训应用。' }, smart: { title: '智能可视化大屏模板', description: '智能数据可视化大屏模板,包含丰富的图表组件、实时数据展示和响应式布局。适合创建监控中心和数据分析平台。' }, game: { title: '游戏开发模板', description: '游戏开发项目模板,提供游戏引擎集成、资源管理、场景编辑等功能。适合2D/3D游戏和交互应用开发。' } }; const template = descriptions[templateType]; if (template) { templateDescription.innerHTML = `

${template.title}

${template.description}

`; } } // 更新面包屑导航 function updateBreadcrumb(navItem) { const breadcrumb = document.getElementById('breadcrumb'); if (!breadcrumb) return; const pageNames = { 'all-projects': { section: '我的项目', page: '项目概览' }, 'favorite-projects': { section: '我的项目', page: '收藏项目' }, 'recent-projects': { section: '我的项目', page: '最近项目' }, 'industrial-projects': { section: '我的项目', page: '工业项目' }, 'smart-projects': { section: '我的项目', page: '智能项目' }, 'vr-projects': { section: '我的项目', page: 'VR项目' }, 'resource-category': { section: '内容管理', page: '资源分类' }, 'category-management': { section: '内容管理', page: '分类管理' }, 'asset-library': { section: '内容管理', page: '资源库' }, 'template-library': { section: '内容管理', page: '模板库' } }; const pageType = navItem.dataset.page; const pageInfo = pageNames[pageType]; if (pageInfo) { breadcrumb.innerHTML = ` ${pageInfo.section} / ${pageInfo.page} `; } } // 根据页面类型过滤项目 function filterProjectsByPage(pageType) { const contentHeader = document.querySelector('.content-header h1'); switch (pageType) { case 'all-projects': currentTypeFilter = 'all'; if (contentHeader) contentHeader.textContent = '全部项目'; break; case 'favorite-projects': currentTypeFilter = 'all'; if (contentHeader) contentHeader.textContent = '收藏项目'; // 这里可以添加收藏项目的过滤逻辑 break; case 'recent-projects': currentTypeFilter = 'all'; if (contentHeader) contentHeader.textContent = '最近项目'; // 按日期排序显示最近的项目 currentSortBy = 'date-desc'; break; case 'industrial-projects': currentTypeFilter = 'industrial'; if (contentHeader) contentHeader.textContent = '工业项目'; break; case 'smart-projects': currentTypeFilter = 'smart'; if (contentHeader) contentHeader.textContent = '智能项目'; break; case 'vr-projects': currentTypeFilter = 'vr'; if (contentHeader) contentHeader.textContent = 'VR项目'; break; default: currentTypeFilter = 'all'; if (contentHeader) contentHeader.textContent = '全部项目'; } // 更新过滤器选择框 if (typeFilter) { typeFilter.value = currentTypeFilter; } // 重新渲染项目 renderProjects(); } // 浏览项目位置 function browseProjectLocation() { const projectLocationInput = document.getElementById('projectLocation'); if (!projectLocationInput) return; // 尝试调用系统文件选择器 if (window.showDirectoryPicker) { // 现代浏览器支持的文件系统访问API showSystemDirectoryPicker(projectLocationInput); } else if (window.electronAPI) { // Electron环境 showElectronDirectoryDialog(projectLocationInput); } else { // 降级方案:显示自定义文件夹选择对话框 showFallbackFolderDialog(projectLocationInput); } } // 现代浏览器的目录选择器 async function showSystemDirectoryPicker(input) { try { const directoryHandle = await window.showDirectoryPicker(); const path = directoryHandle.name; input.value = path; showNotification('已选择项目位置: ' + path, 'success'); } catch (err) { if (err.name !== 'AbortError') { console.error('目录选择失败:', err); showFallbackFolderDialog(input); } } } // Electron环境的目录选择 function showElectronDirectoryDialog(input) { if (window.electronAPI && window.electronAPI.showOpenDialog) { window.electronAPI.showOpenDialog({ properties: ['openDirectory'], title: '选择项目保存位置' }).then(result => { if (!result.canceled && result.filePaths.length > 0) { const selectedPath = result.filePaths[0]; input.value = selectedPath; showNotification('已选择项目位置: ' + selectedPath, 'success'); } }).catch(err => { console.error('目录选择失败:', err); showFallbackFolderDialog(input); }); } else { showFallbackFolderDialog(input); } } // 降级方案:简化的文件夹选择 function showFallbackFolderDialog(input) { // 创建隐藏的文件输入元素来模拟文件夹选择 const fileInput = document.createElement('input'); fileInput.type = 'file'; fileInput.webkitdirectory = true; fileInput.style.display = 'none'; fileInput.addEventListener('change', (e) => { if (e.target.files.length > 0) { // 获取第一个文件的路径,然后提取目录路径 const file = e.target.files[0]; const path = file.webkitRelativePath.split('/')[0]; input.value = path || '已选择文件夹'; showNotification('已选择项目位置', 'success'); } document.body.removeChild(fileInput); }); document.body.appendChild(fileInput); fileInput.click(); } // 显示项目菜单 function showProjectMenu(projectId, menuButton) { // 移除已存在的菜单 const existingMenu = document.querySelector('.project-context-menu'); if (existingMenu) { existingMenu.remove(); } // 获取项目信息 const project = projectsData.find(p => p.id === projectId); if (!project) return; // 创建菜单 const menu = document.createElement('div'); menu.className = 'project-context-menu'; menu.innerHTML = ` `; // 定位菜单 const rect = menuButton.getBoundingClientRect(); menu.style.position = 'fixed'; menu.style.top = rect.bottom + 5 + 'px'; menu.style.left = rect.left - 150 + 'px'; // 菜单宽度约150px,向左偏移 menu.style.zIndex = '2000'; // 添加到页面 document.body.appendChild(menu); // 菜单项点击事件 menu.addEventListener('click', (e) => { const action = e.target.closest('.menu-item')?.dataset.action; if (action) { handleProjectAction(projectId, action); menu.remove(); } }); // 点击其他地方关闭菜单 setTimeout(() => { document.addEventListener('click', function closeMenu(e) { if (!menu.contains(e.target)) { menu.remove(); document.removeEventListener('click', closeMenu); } }); }, 0); } // 处理项目操作 function handleProjectAction(projectId, action) { const project = projectsData.find(p => p.id === projectId); if (!project) return; switch (action) { case 'open': openProject(projectId); break; case 'rename': renameProject(projectId); break; case 'duplicate': duplicateProject(projectId); break; case 'export': exportProject(projectId); break; case 'favorite': toggleFavorite(projectId); break; case 'delete': deleteProject(projectId); break; } } // 重命名项目 function renameProject(projectId) { const project = projectsData.find(p => p.id === projectId); if (!project) return; const newName = prompt('请输入新的项目名称:', project.title); if (newName && newName.trim() !== '') { project.title = newName.trim(); renderProjects(); showNotification('项目重命名成功', 'success'); } } // 复制项目 function duplicateProject(projectId) { const project = projectsData.find(p => p.id === projectId); if (!project) return; const newProject = { ...project, id: projectsData.length + 1, title: project.title + ' - 副本', date: new Date().toLocaleString('zh-CN') }; projectsData.unshift(newProject); renderProjects(); showNotification('项目复制成功', 'success'); } // 导出项目 function exportProject(projectId) { const project = projectsData.find(p => p.id === projectId); if (!project) return; showNotification(`正在导出项目: ${project.title}`, 'info'); // 这里可以添加实际的导出逻辑 } // 切换收藏状态 function toggleFavorite(projectId) { const project = projectsData.find(p => p.id === projectId); if (!project) return; project.favorite = !project.favorite; renderProjects(); // 重新渲染以显示收藏状态变化 showNotification(project.favorite ? '已添加到收藏' : '已从收藏中移除', 'success'); } // 删除项目 function deleteProject(projectId) { const project = projectsData.find(p => p.id === projectId); if (!project) return; if (confirm(`确定要删除项目 "${project.title}" 吗?此操作不可撤销。`)) { const index = projectsData.findIndex(p => p.id === projectId); if (index > -1) { projectsData.splice(index, 1); renderProjects(); showNotification('项目删除成功', 'success'); } } } // 获取项目类型标签 function getProjectTypeLabel(type) { const typeLabels = { 'industrial': '工业', 'smart': '智能', 'vr': 'VR', 'game': '游戏', 'design': '设计' }; return typeLabels[type] || '其他'; } // 初始化搜索和过滤功能 function initSearchAndFilter() { if (!searchBtn || !filterBtn) return; // 搜索按钮点击 searchBtn.addEventListener('click', () => { toggleSearchFilterArea(); }); // 过滤按钮点击 filterBtn.addEventListener('click', () => { toggleSearchFilterArea(); }); // 搜索输入 if (searchInput) { searchInput.addEventListener('input', (e) => { currentSearchTerm = e.target.value; renderProjects(); }); } // 排序选择 if (sortSelect) { sortSelect.addEventListener('change', (e) => { currentSortBy = e.target.value; renderProjects(); }); } // 类型过滤 if (typeFilter) { typeFilter.addEventListener('change', (e) => { currentTypeFilter = e.target.value; renderProjects(); }); } } // 切换搜索过滤区域显示 function toggleSearchFilterArea() { if (!searchFilterArea) return; if (searchFilterArea.style.display === 'none' || searchFilterArea.style.display === '') { searchFilterArea.style.display = 'flex'; if (searchInput) { searchInput.focus(); } } else { searchFilterArea.style.display = 'none'; } } // 初始化树状结构 function initTreeStructure() { // 主分区展开/折叠 const navTitles = document.querySelectorAll('.nav-title.expandable'); navTitles.forEach(title => { title.addEventListener('click', () => { const sectionId = title.dataset.section; const subsection = document.getElementById(sectionId); const icon = title.querySelector('.expand-icon'); if (subsection.classList.contains('collapsed')) { subsection.classList.remove('collapsed'); subsection.style.maxHeight = subsection.scrollHeight + 'px'; icon.style.transform = 'rotate(0deg)'; } else { subsection.classList.add('collapsed'); subsection.style.maxHeight = '0px'; icon.style.transform = 'rotate(-90deg)'; } }); }); // 设置初始状态 - 默认展开所有主分区 const allSubsections = document.querySelectorAll('.nav-subsection'); allSubsections.forEach(subsection => { subsection.style.maxHeight = subsection.scrollHeight + 'px'; }); } // 添加动画样式 const style = document.createElement('style'); style.textContent = ` @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes slideOut { from { transform: translateX(0); opacity: 1; } to { transform: translateX(100%); opacity: 0; } } `; document.head.appendChild(style);