// 物品数据库管理工具 - 主要JavaScript逻辑 class ItemDatabase { constructor() { this.items = this.loadItems(); this.history = this.loadHistory(); this.init(); } // 初始化应用 init() { this.setupEventListeners(); this.renderItems(); this.updateStats(); this.initAnimations(); this.loadSampleData(); } // 设置事件监听器 setupEventListeners() { // 表单提交 document.getElementById('add-item-form').addEventListener('submit', (e) => { e.preventDefault(); this.addItem(); }); // 搜索和筛选 document.getElementById('search-input').addEventListener('input', (e) => { this.filterItems(); }); document.getElementById('filter-select').addEventListener('change', (e) => { this.filterItems(); }); // 数据导入导出 document.getElementById('export-data-btn').addEventListener('click', () => { this.exportData(); }); document.getElementById('import-data-btn').addEventListener('click', () => { document.getElementById('import-file-input').click(); }); document.getElementById('import-file-input').addEventListener('change', (e) => { this.importData(e.target.files[0]); }); // 编辑模态框 document.getElementById('edit-form').addEventListener('submit', (e) => { e.preventDefault(); this.updateItem(); }); document.getElementById('cancel-edit').addEventListener('click', () => { this.closeEditModal(); }); // 点击模态框外部关闭 document.getElementById('edit-modal').addEventListener('click', (e) => { if (e.target.id === 'edit-modal') { this.closeEditModal(); } }); } // 加载示例数据 loadSampleData() { if (this.items.length === 0) { const sampleItems = [ { id: this.generateId(), name: "明代青花瓷瓶", imageUrl: "https://images.unsplash.com/photo-1578662996442-48f60103fc96?w=400&h=300&fit=crop", description: "明代宣德年间的青花瓷瓶,品相完好,具有极高的收藏价值", tags: ["古董", "瓷器", "明代"], createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }, { id: this.generateId(), name: "清代玉雕摆件", imageUrl: "https://images.unsplash.com/photo-1605883705077-8d3d848f8a9d?w=400&h=300&fit=crop", description: "清代乾隆时期的玉雕摆件,雕工精细,玉质温润", tags: ["古董", "玉器", "清代"], createdAt: new Date(Date.now() - 86400000).toISOString(), updatedAt: new Date(Date.now() - 86400000).toISOString() }, { id: this.generateId(), name: "宋代书法作品", imageUrl: "https://images.unsplash.com/photo-1581833971358-2c8b550f87b3?w=400&h=300&fit=crop", description: "宋代书法名家作品,纸本墨迹,保存完好", tags: ["艺术品", "书法", "宋代"], createdAt: new Date(Date.now() - 172800000).toISOString(), updatedAt: new Date(Date.now() - 172800000).toISOString() }, { id: this.generateId(), name: "唐代金银器", imageUrl: "https://images.unsplash.com/photo-1578662996442-48f60103fc96?w=400&h=300&fit=crop", description: "唐代金银器,工艺精湛,具有重要历史价值", tags: ["古董", "金银器", "唐代"], createdAt: new Date(Date.now() - 259200000).toISOString(), updatedAt: new Date(Date.now() - 259200000).toISOString() }, { id: this.generateId(), name: "现代艺术画作", imageUrl: "https://images.unsplash.com/photo-1579783902614-a3fb3927b6a5?w=400&h=300&fit=crop", description: "当代知名艺术家作品,抽象风格,色彩丰富", tags: ["艺术品", "现代艺术", "画作"], createdAt: new Date(Date.now() - 345600000).toISOString(), updatedAt: new Date(Date.now() - 345600000).toISOString() }, { id: this.generateId(), name: "古代青铜器", imageUrl: "https://images.unsplash.com/photo-1605883705077-8d3d848f8a9d?w=400&h=300&fit=crop", description: "商周时期青铜器,纹饰精美,保存完好", tags: ["古董", "青铜器", "商周"], createdAt: new Date(Date.now() - 432000000).toISOString(), updatedAt: new Date(Date.now() - 432000000).toISOString() } ]; this.items = sampleItems; this.saveItems(); this.renderItems(); this.updateStats(); } } // 生成唯一ID generateId() { return Date.now().toString(36) + Math.random().toString(36).substr(2); } // 添加物品 addItem() { const name = document.getElementById('item-name').value.trim(); const imageUrl = document.getElementById('item-image').value.trim(); const description = document.getElementById('item-description').value.trim(); const tags = document.getElementById('item-tags').value.trim(); if (!name || !imageUrl) { this.showNotification('请填写必填项', 'error'); return; } const newItem = { id: this.generateId(), name, imageUrl, description, tags: tags ? tags.split(',').map(tag => tag.trim()).filter(tag => tag) : [], createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }; this.items.unshift(newItem); this.saveItems(); this.renderItems(); this.updateStats(); // 清空表单 document.getElementById('add-item-form').reset(); this.showNotification('物品添加成功', 'success'); } // 编辑物品 editItem(itemId) { const item = this.items.find(i => i.id === itemId); if (!item) return; document.getElementById('edit-item-id').value = item.id; document.getElementById('edit-item-name').value = item.name; document.getElementById('edit-item-image').value = item.imageUrl; document.getElementById('edit-item-description').value = item.description || ''; document.getElementById('edit-item-tags').value = item.tags ? item.tags.join(', ') : ''; document.getElementById('edit-modal').classList.remove('hidden'); document.getElementById('edit-modal').classList.add('flex'); } // 更新物品 updateItem() { const itemId = document.getElementById('edit-item-id').value; const item = this.items.find(i => i.id === itemId); if (!item) return; item.name = document.getElementById('edit-item-name').value.trim(); item.imageUrl = document.getElementById('edit-item-image').value.trim(); item.description = document.getElementById('edit-item-description').value.trim(); const tags = document.getElementById('edit-item-tags').value.trim(); item.tags = tags ? tags.split(',').map(tag => tag.trim()).filter(tag => tag) : []; item.updatedAt = new Date().toISOString(); this.saveItems(); this.renderItems(); this.closeEditModal(); this.showNotification('物品更新成功', 'success'); } // 关闭编辑模态框 closeEditModal() { document.getElementById('edit-modal').classList.add('hidden'); document.getElementById('edit-modal').classList.remove('flex'); } // 删除物品 deleteItem(itemId) { if (confirm('确定要删除这个物品吗?')) { this.items = this.items.filter(item => item.id !== itemId); this.saveItems(); this.renderItems(); this.updateStats(); this.showNotification('物品删除成功', 'success'); } } // 渲染物品列表 renderItems() { const grid = document.getElementById('items-grid'); const emptyState = document.getElementById('empty-state'); if (this.items.length === 0) { grid.innerHTML = ''; emptyState.classList.remove('hidden'); return; } emptyState.classList.add('hidden'); const filteredItems = this.getFilteredItems(); grid.innerHTML = filteredItems.map(item => `
${item.name}

${item.name}

${item.description || '暂无描述'}

${item.tags ? item.tags.map(tag => ` ${tag} `).join('') : ''}
创建时间: ${new Date(item.createdAt).toLocaleDateString('zh-CN')}
`).join(''); // 添加动画效果 this.animateCards(); } // 获取筛选后的物品 getFilteredItems() { const searchTerm = document.getElementById('search-input').value.toLowerCase(); const filterTag = document.getElementById('filter-select').value; return this.items.filter(item => { const matchesSearch = item.name.toLowerCase().includes(searchTerm) || item.description.toLowerCase().includes(searchTerm); const matchesFilter = !filterTag || (item.tags && item.tags.includes(filterTag)); return matchesSearch && matchesFilter; }); } // 筛选物品 filterItems() { this.renderItems(); } // 更新统计信息 updateStats() { const totalItems = this.items.length; const currentMonth = new Date().getMonth(); const currentYear = new Date().getFullYear(); const monthlyItems = this.items.filter(item => { const itemDate = new Date(item.createdAt); return itemDate.getMonth() === currentMonth && itemDate.getFullYear() === currentYear; }).length; const historyRecords = this.history.length; const totalImages = this.items.filter(item => item.imageUrl).length; document.getElementById('total-items').textContent = totalItems; document.getElementById('monthly-items').textContent = monthlyItems; document.getElementById('history-records').textContent = historyRecords; document.getElementById('total-images').textContent = totalImages; // 添加数字动画 this.animateNumbers(); } // 导出数据 exportData() { const data = { items: this.items, history: this.history, exportDate: new Date().toISOString() }; const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `items-backup-${new Date().toISOString().split('T')[0]}.json`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); this.showNotification('数据导出成功', 'success'); } // 导入数据 importData(file) { if (!file) return; const reader = new FileReader(); reader.onload = (e) => { try { const data = JSON.parse(e.target.result); if (data.items && Array.isArray(data.items)) { this.items = data.items; this.saveItems(); } if (data.history && Array.isArray(data.history)) { this.history = data.history; this.saveHistory(); } this.renderItems(); this.updateStats(); this.showNotification('数据导入成功', 'success'); } catch (error) { this.showNotification('数据格式错误', 'error'); } }; reader.readAsText(file); } // 显示通知 showNotification(message, type = 'info') { const notification = document.getElementById('notification'); const messageEl = document.getElementById('notification-message'); const iconEl = document.getElementById('notification-icon'); // 设置图标 const icons = { success: '', error: '', info: '' }; iconEl.innerHTML = icons[type] || icons.info; messageEl.textContent = message; notification.classList.add('show'); setTimeout(() => { notification.classList.remove('show'); }, 3000); } // 初始化动画 initAnimations() { // 页面加载动画 const fadeElements = document.querySelectorAll('.fade-in'); const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('visible'); } }); }); fadeElements.forEach(el => observer.observe(el)); // 标题动画 anime({ targets: '.hero-title', opacity: [0, 1], translateY: [30, 0], duration: 1000, easing: 'easeOutExpo', delay: 300 }); } // 卡片动画 animateCards() { anime({ targets: '.item-card', opacity: [0, 1], translateY: [20, 0], duration: 600, easing: 'easeOutExpo', delay: anime.stagger(100) }); } // 数字动画 animateNumbers() { anime({ targets: '#total-items, #monthly-items, #history-records, #total-images', scale: [1.2, 1], duration: 300, easing: 'easeOutBack' }); } // 数据持久化 saveItems() { localStorage.setItem('itemdb-items', JSON.stringify(this.items)); } loadItems() { const data = localStorage.getItem('itemdb-items'); return data ? JSON.parse(data) : []; } saveHistory() { localStorage.setItem('itemdb-history', JSON.stringify(this.history)); } loadHistory() { const data = localStorage.getItem('itemdb-history'); return data ? JSON.parse(data) : []; } } // 初始化应用 const itemDB = new ItemDatabase();