'use client' import { useState, useEffect } from 'react' import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card" import { Label } from "@/components/ui/label" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { Plus, Minus, Package, Trash2, Search, BarChart, Download, Upload, Edit2, Save, Warehouse } from 'lucide-react' import { motion } from "framer-motion" import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { BarChart as RechartsBarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts' import { Badge } from "@/components/ui/badge" import { Tooltip as ShadTooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" interface InventoryItem { id: number; name: string; quantity: number; warehouse: string; location: string; price: number; totalValue: number; } const fadeIn = { initial: { opacity: 0, y: 20 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.5 } } export default function InventoryManagement() { const [inventory, setInventory] = useState([]) const [newItemName, setNewItemName] = useState("") const [newItemQuantity, setNewItemQuantity] = useState("") const [newItemWarehouse, setNewItemWarehouse] = useState("") const [searchTerm, setSearchTerm] = useState("") const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false) const [itemToDelete, setItemToDelete] = useState(null) const [editingItemId, setEditingItemId] = useState(null) const [editingItemName, setEditingItemName] = useState("") const [editingItemPrice, setEditingItemPrice] = useState("") const [warehouses, setWarehouses] = useState([]) const [activeTab, setActiveTab] = useState("inventory") const [newItemLocation, setNewItemLocation] = useState("") const [newItemPrice, setNewItemPrice] = useState("") const [sortColumn, setSortColumn] = useState('name') const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc') const [editingItemLocation, setEditingItemLocation] = useState("") const [editingItemWarehouse, setEditingItemWarehouse] = useState("") // 组件挂载时从localStorage加载库存和仓库数据 useEffect(() => { const savedInventory = localStorage.getItem('inventory') const savedWarehouses = localStorage.getItem('warehouses') if (savedInventory) setInventory(JSON.parse(savedInventory)) if (savedWarehouses) setWarehouses(JSON.parse(savedWarehouses)) }, []) // 库存或仓库数据变化时保存到localStorage useEffect(() => { localStorage.setItem('inventory', JSON.stringify(inventory)) localStorage.setItem('warehouses', JSON.stringify(warehouses)) }, [inventory, warehouses]) const addItem = () => { if (newItemName && newItemQuantity && newItemWarehouse && newItemLocation && newItemPrice) { const quantity = parseInt(newItemQuantity) || 0; const price = parseFloat(newItemPrice) || 0; const newItem: InventoryItem = { id: Date.now(), name: newItemName, quantity: quantity, warehouse: newItemWarehouse, location: newItemLocation, price: price, totalValue: quantity * price, } setInventory([...inventory, newItem]) setNewItemName("") setNewItemQuantity("") setNewItemWarehouse("") setNewItemLocation("") setNewItemPrice("") } } const updateQuantity = (id: number, change: number) => { setInventory(inventory.map(item => { if (item.id === id) { const newQuantity = Math.max(0, (item.quantity || 0) + change); const price = item.price || 0; return { ...item, quantity: newQuantity, totalValue: newQuantity * price }; } return item; })); } const confirmDelete = (id: number) => { setItemToDelete(id) setDeleteConfirmOpen(true) } const deleteItem = () => { if (itemToDelete !== null) { setInventory(inventory.filter(item => item.id !== itemToDelete)) setDeleteConfirmOpen(false) setItemToDelete(null) } } const startEditing = (id: number, name: string, price: number, location: string, warehouse: string) => { setEditingItemId(id) setEditingItemName(name) setEditingItemPrice(price.toString()) setEditingItemLocation(location) setEditingItemWarehouse(warehouse) } const saveEdit = () => { if (editingItemId !== null) { setInventory(inventory.map(item => { if (item.id === editingItemId) { const newPrice = parseFloat(editingItemPrice) || item.price; return { ...item, name: editingItemName, price: newPrice, location: editingItemLocation, warehouse: editingItemWarehouse, totalValue: item.quantity * newPrice } } return item })) setEditingItemId(null) setEditingItemName("") setEditingItemPrice("") setEditingItemLocation("") setEditingItemWarehouse("") } } const handleSort = (column: keyof InventoryItem) => { if (column === sortColumn) { setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc') } else { setSortColumn(column) setSortDirection('asc') } } const filteredInventory = inventory.filter(item => item.name.toLowerCase().includes(searchTerm.toLowerCase()) || item.warehouse.toLowerCase().includes(searchTerm.toLowerCase()) || item.location.toLowerCase().includes(searchTerm.toLowerCase()) ) const sortedInventory = [...filteredInventory].sort((a, b) => { if (a[sortColumn] < b[sortColumn]) return sortDirection === 'asc' ? -1 : 1 if (a[sortColumn] > b[sortColumn]) return sortDirection === 'asc' ? 1 : -1 return 0 }) const exportData = () => { const dataStr = JSON.stringify({ inventory, warehouses }) const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr) const exportFileDefaultName = 'inventory_backup.json' const linkElement = document.createElement('a') linkElement.setAttribute('href', dataUri) linkElement.setAttribute('download', exportFileDefaultName) linkElement.click() } const importData = (event: React.ChangeEvent) => { const file = event.target.files?.[0] if (file) { const reader = new FileReader() reader.onload = (e) => { try { const importedData = JSON.parse(e.target?.result as string) setInventory(importedData.inventory) setWarehouses(importedData.warehouses) } catch (error) { console.error('Error parsing imported data:', error) alert('导入失败,请确保文件格式正确。') } } reader.readAsText(file) } } const getInventoryChartData = () => { return inventory.map(item => ({ name: item.name, quantity: item.quantity || 0, totalValue: (item.quantity || 0) * (item.price || 0), warehouse: item.warehouse })) } return (

库存管理系统

高效管理家里的众多小破烂

库存管理 数据分析 仓库管理
入库 添加新商品到库存
setNewItemName(e.target.value)} placeholder="输入商品名称" />
setNewItemQuantity(e.target.value)} placeholder="输入数量" />
setNewItemLocation(e.target.value)} placeholder="输入货品位置" />
setNewItemPrice(e.target.value)} placeholder="输入单价" />
库存概览 查看和管理现有库存
setSearchTerm(e.target.value)} className="mr-2" />
操作 {sortedInventory.map((item) => ( {editingItemId === item.id ? setEditingItemName(e.target.value)} className="w-full" /> : item.name } {item.quantity} {editingItemId === item.id ? : item.warehouse } {editingItemId === item.id ? setEditingItemLocation(e.target.value)} className="w-full" /> : item.location } {editingItemId === item.id ? setEditingItemPrice(e.target.value)} className="w-full" /> : ¥{item.price?.toFixed(2) ?? '0.00'}

点击编辑按钮修改单价

}
¥{item.totalValue?.toFixed(2) ?? '0.00'}
{editingItemId === item.id ? ( ) : ( )}
))}
所有货品数量图表 展示所有货品的库存数量
确认删除 您确定要删除这个商品吗?此操作无法撤销。 取消 确认删除
) } function WarehouseManagement({ warehouses, setWarehouses, inventory, setInventory }: { warehouses: string[], setWarehouses: React.Dispatch>, inventory: InventoryItem[], setInventory: React.Dispatch> }) { const [newWarehouse, setNewWarehouse] = useState("") const [editingWarehouse, setEditingWarehouse] = useState(null) const [editedWarehouseName, setEditedWarehouseName] = useState("") const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false) const [warehouseToDelete, setWarehouseToDelete] = useState(null) const [confirmDeleteName, setConfirmDeleteName] = useState("") const addWarehouse = () => { if (newWarehouse && !warehouses.includes(newWarehouse)) { setWarehouses([...warehouses, newWarehouse]) setNewWarehouse("") } } const startEditing = (warehouse: string) => { setEditingWarehouse(warehouse) setEditedWarehouseName(warehouse) } const saveEdit = () => { if (editingWarehouse && editedWarehouseName) { setWarehouses(warehouses.map(w => w === editingWarehouse ? editedWarehouseName : w)) setEditingWarehouse(null) setEditedWarehouseName("") setInventory(inventory.map(item => item.warehouse === editingWarehouse ? { ...item, warehouse: editedWarehouseName } : item )) } } const confirmDelete = (warehouse: string) => { setWarehouseToDelete(warehouse) setDeleteConfirmOpen(true) setConfirmDeleteName("") } const deleteWarehouse = () => { if (warehouseToDelete && confirmDeleteName === warehouseToDelete) { setWarehouses(warehouses.filter(w => w !== warehouseToDelete)) setInventory(inventory.filter(item => item.warehouse !== warehouseToDelete)) setDeleteConfirmOpen(false) setWarehouseToDelete(null) setConfirmDeleteName("") } } return ( 仓库管理 添加、编辑或删除仓库
setNewWarehouse(e.target.value)} placeholder="输入新仓库名称" />
仓库名称 操作 {warehouses.map((warehouse) => ( {editingWarehouse === warehouse ? ( setEditedWarehouseName(e.target.value)} className="w-full" /> ) : ( warehouse )}
{editingWarehouse === warehouse ? ( ) : ( )}
))}
确认删除仓库 您确定要删除仓库 "{warehouseToDelete}" 吗?此操作无法撤销。请输入仓库名称以确认删除。
setConfirmDeleteName(e.target.value)} placeholder="输入仓库名称" />
取消 确认删除
) }