import React, { useState, useEffect } from 'react' import { useNavigate } from 'react-router-dom' import { Table, Button, Modal, Form, Input, Select, message, Space, Tag, Card, Row, Col, InputNumber, Tabs, Descriptions, Upload } from 'antd' import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined, UploadOutlined } from '@ant-design/icons' import type { ColumnsType } from 'antd/es/table' import dayjs from 'dayjs' import { useLanguageStore } from '../store/languageStore' interface Product { id: number name: string code: string category: string specification: string unit: string stock_quantity: number safety_stock: number brand: string remark: string created_at: string } interface Category { id: number name: string } const ProductPage: React.FC = () => { const { t, currentLanguage } = useLanguageStore(); const [products, setProducts] = useState([]) const [loading, setLoading] = useState(false) const [categories, setCategories] = useState([]) const [selectedCategory, setSelectedCategory] = useState(null) const [modalVisible, setModalVisible] = useState(false) const [detailModalVisible, setDetailModalVisible] = useState(false) const [editingProduct, setEditingProduct] = useState(null) const [viewingProduct, setViewingProduct] = useState(null) const [form] = Form.useForm() const navigate = useNavigate() const fetchProducts = async () => { setLoading(true) try { const params = new URLSearchParams() if (selectedCategory) params.append('category', selectedCategory) const response = await fetch(`/api/products?${params}`) const data = await response.json() if (data.success) { setProducts(data.data) } else { message.error(t('product.getListFailed')) } } catch (error) { console.error('获取产品列表失败:', error) message.error(t('product.getListFailed')) } finally { setLoading(false) } } const fetchCategories = async () => { try { const response = await fetch('/api/categories') const data = await response.json() if (data.success) { setCategories(data.data) } } catch (error) { console.error('获取分类列表失败:', error) } } const fetchProductDetail = async (id: number) => { try { const response = await fetch(`/api/products/${id}`) const data = await response.json() if (data.success) { setViewingProduct(data.data) setDetailModalVisible(true) } else { message.error(t('product.getDetailFailed')) } } catch (error) { console.error('获取产品详情失败:', error) message.error(t('product.getDetailFailed')) } } useEffect(() => { fetchCategories() }, []) useEffect(() => { fetchProducts() }, [selectedCategory]) const handleCreate = () => { setEditingProduct(null) form.resetFields() setModalVisible(true) } const handleEdit = (record: Product) => { setEditingProduct(record) form.setFieldsValue(record) setModalVisible(true) } const handleDelete = async (id: number) => { try { const response = await fetch(`/api/products/${id}`, { method: 'DELETE' }) const data = await response.json() if (data.success) { message.success(t('product.deleteSuccess')) fetchProducts() } else { message.error(t('product.deleteFailed')) } } catch (error) { console.error('删除产品失败:', error) message.error(t('product.deleteFailed')) } } const handleSave = async () => { try { const values = await form.validateFields() let response if (editingProduct) { response = await fetch(`/api/products/${editingProduct.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(values) }) } else { response = await fetch('/api/products', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(values) }) } const data = await response.json() if (data.success) { message.success(editingProduct ? t('common.updateSuccess') : t('common.createSuccess')) setModalVisible(false) fetchProducts() } else { message.error(t('common.operationFailed')) } } catch (error) { console.error('保存产品失败:', error) message.error(t('common.operationFailed')) } } const getCategoryColor = (category: string): string => { const colorMap: Record = { material: 'blue', equipment: 'green', pole: 'orange', other: 'default' }; const c = categories.find(cat => cat.id == Number(category)); const name = c ? c.name : category; if (name === '材料') return 'blue'; if (name === '设备') return 'green'; if (name === '电杆') return 'orange'; return 'default'; } const columns: ColumnsType = [ { title: t('product.code'), dataIndex: 'code', key: 'code', width: 120 }, { title: t('product.name'), dataIndex: 'name', key: 'name', width: 150, render: (v: string, r: Product) => ( fetchProductDetail(r.id)} style={{ fontWeight: 500 }}>{v} ) }, { title: t('product.category'), dataIndex: 'category', key: 'category', width: 80, render: (category: string) => { const c = categories.find(cat => cat.id == Number(category)) return {c ? c.name : category} } }, { title: t('product.spec'), dataIndex: 'specification', key: 'specification', width: 150, ellipsis: true }, { title: t('product.unit'), dataIndex: 'unit', key: 'unit', width: 60 }, { title: t('product.stock'), dataIndex: 'stock_quantity', key: 'stock_quantity', width: 100, align: 'right', render: (v: number, r: Product) => ( {v} {r.unit} ) }, { title: t('product.safetyStock'), dataIndex: 'safety_stock', key: 'safety_stock', width: 80, align: 'right' }, { title: t('product.remark'), dataIndex: 'remark', key: 'remark', width: 200, ellipsis: true, render: (v: string) => v || '-' }, { title: t('product.action'), key: 'actions', width: 150, fixed: 'right', render: (_, record) => ( ) } ] return (

{t('product.title')}

{t('product.description')}

} onClick={handleCreate}> {t('product.addProduct')} } > {/* 编辑/新建弹窗 */} { form.resetFields(); setModalVisible(false); }} footer={[ , ]} destroyOnClose width={600} >
{/* 详情弹窗 */} setDetailModalVisible(false)} footer={null} width={700} > {viewingProduct && ( {viewingProduct.code} {viewingProduct.name} {categories.find(c => c.id == Number(viewingProduct.category))?.name || viewingProduct.category} {viewingProduct.specification || '-'} {viewingProduct.unit} {viewingProduct.brand || '-'} {viewingProduct.stock_quantity} {viewingProduct.unit} {viewingProduct.safety_stock} {viewingProduct.unit} {viewingProduct.remark || '-'} {viewingProduct.created_at} )} ) } export default ProductPage