import React, { useEffect, useState } from 'react'; import { Card, Table, Button, message, Popconfirm, Tag, Space, Spin, Modal, Empty, Select, Typography, Statistic, Divider } from 'antd'; import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined,CopyOutlined, FileAddOutlined, AppstoreOutlined } from '@ant-design/icons'; import { useResources } from '@/hooks/resource/useResource'; import { useNavigate } from 'react-router-dom'; import {supabase}from '@/config/supabase' const CURRENCY_SYMBOLS = { CNY: "¥", TWD: "NT$", USD: "$", }; const QuotationPage = () => { const navigate = useNavigate(); const [pagination, setPagination] = useState({ current: 1, pageSize: 10 }); const [sorter, setSorter] = useState({ field: 'created_at', order: 'descend' }); const [isModalVisible, setIsModalVisible] = useState(false); const [selectedTemplateId, setSelectedTemplateId] = useState(null); const [templates, setTemplates] = useState([]); const [loading, setLoading] = useState(false); const [selectedCategory, setSelectedCategory] = useState('all'); const [categories, setCategories] = useState([]); const { resources: quotations, loading: loadingQuotations, total, fetchResources: fetchQuotations, deleteResource: deleteQuotation } = useResources(pagination, sorter, 'quota'); useEffect(() => { fetchQuotations(); }, []); const handleTableChange = (pagination, filters, sorter) => { setPagination(pagination); setSorter(sorter); fetchQuotations({ current: pagination.current, pageSize: pagination.pageSize, field: sorter.field, order: sorter.order, }); }; const handleDelete = async (id) => { try { await deleteQuotation(id); message.success('删除成功'); fetchQuotations(); } catch (error) { message.error('删除失败:' + error.message); } }; const fetchTemplates = async () => { try { setLoading(true); const { data: services, error } = await supabase .from("resources") .select("*") .eq("type", "serviceTemplate") .order("created_at", { ascending: false }); if (error) throw error; setTemplates(services); } catch (error) { console.error("获取服务模板失败:", error); message.error("获取服务模板失败"); } finally { setLoading(false); } }; useEffect(() => { if (isModalVisible) { fetchTemplates(); } }, [isModalVisible]); useEffect(() => { if (templates.length > 0) { setCategories(getAllCategories(templates)); } }, [templates]); const handleTemplateSelect = (templateId) => { setSelectedTemplateId(templateId); }; const handleConfirm = () => { if (selectedTemplateId) { navigate(`/company/quotaInfo?templateId=${selectedTemplateId}`); } else { navigate('/company/quotaInfo'); } setIsModalVisible(false); setSelectedTemplateId(null); }; const getAllCategories = (templates) => { const categorySet = new Set(); templates.forEach(template => { template.attributes.category?.forEach(cat => { categorySet.add(JSON.stringify(cat)); }); }); return Array.from(categorySet).map(cat => JSON.parse(cat)); }; const getFilteredTemplates = () => { if (selectedCategory === 'all') return templates; return templates.filter(template => template.attributes.category?.some(cat => cat.id === selectedCategory) ); }; const columns = [ { title: '报价单名称', dataIndex: ['attributes', 'quataName'], key: 'quataName', ellipsis: true, }, { title: '客户信息', dataIndex: ['attributes', 'customers'], key: 'customers', render: (customers,record) => ( {customers?.map(customer => ( { navigate(`/company/customerInfo/${customer.id}`) }} > {customer.name} ))} ), }, { title: '报价总额', dataIndex: ['attributes'], key: 'totalAmount', align: 'right', width: 200, render: (attributes) => { // 获取货币符号 const currencySymbol = CURRENCY_SYMBOLS[attributes.currency] || '¥'; return (
税前:{currencySymbol}{attributes.beforeTaxAmount?.toLocaleString()}
); }, }, { title: '创建日期', dataIndex: 'created_at', key: 'created_at', sorter: true, width: 120, render: (text) => ( {new Date(text).toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' })} ), }, { title: '操作', key: 'action', width:250, render: (_, record) => ( handleDelete(record.id)} okText="确定" cancelText="取消" okButtonProps={{ danger: true }} > ), }, ]; const getTemplatesByCategory = () => { const groups = new Map(); // 添加未分类组 groups.set('uncategorized', { name: '未分类', templates: templates.filter(t => !t.attributes.category || t.attributes.category.length === 0) }); // 按分类分组 templates.forEach(template => { if (template.attributes.category) { template.attributes.category.forEach(cat => { if (!groups.has(cat.id)) { groups.set(cat.id, { name: cat.name, templates: [] }); } groups.get(cat.id).templates.push(template); }); } }); return Array.from(groups.values()).filter(group => group.templates.length > 0); }; return ( <> 报价单管理 {total} 个报价单 } className='h-full w-full overflow-auto' extra={ } > `共 ${total} 条记录`, }} /> { setIsModalVisible(false); setSelectedTemplateId(null); }} footer={[ , , ]} width={800} > {loading ? (
) : templates.length === 0 ? ( ) : (
{getTemplatesByCategory().map((group, groupIndex) => (

{group.name} ({group.templates.length})

{group.templates.map(template => (
handleTemplateSelect(template.id)} >

{template.attributes.templateName}

{template.attributes.description || '暂无描述'}

¥{template.attributes.totalAmount?.toLocaleString()}
{template.attributes.sections.map((section, index) => (
{section.sectionName} {section.items.length}项
))}
))}
))}
)}
); }; export default QuotationPage;