This commit is contained in:
liamzi
2025-01-17 17:47:21 +08:00
parent c229f2dbc4
commit 0e71c0e8b2
2 changed files with 54 additions and 48 deletions

View File

@@ -7,7 +7,7 @@ import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
const { Title, Text } = Typography;
import { EXCHANGE_RATE,defaultSymbol } from '@/utils/exchange_rate';
import { EXCHANGE_RATE, defaultSymbol } from '@/utils/exchange_rate';
const QuotationPreview = () => {
const { id } = useParams();
@@ -114,17 +114,6 @@ const QuotationPreview = () => {
}
};
// 导出按钮组件
const ExportPDFButton = () => (
<Button
type="primary"
icon={<DownloadOutlined />}
onClick={exportPDF}
>
导出PDF
</Button>
);
if (loading) {
return (
<div className="flex justify-center items-center h-full">
@@ -139,52 +128,69 @@ const QuotationPreview = () => {
const currencySymbol = EXCHANGE_RATE[attributes.currency]?.symbol || defaultSymbol;
return (
<div className="max-w-4xl mx-auto p-6">
<div className="min-h-screen bg-gradient-to-b from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 p-6 transition-colors duration-200">
<Card
title={
className="max-w-4xl mx-auto shadow-lg rounded-2xl bg-white dark:bg-gray-800 transition-colors duration-200"
bodyStyle={{ padding: 0 }}
>
<div className="p-6 border-b border-gray-200 dark:border-gray-700">
<div className="flex justify-between items-center">
<Space>
<FileTextOutlined className="text-blue-500" />
<span>报价单预览</span>
<FileTextOutlined className="text-blue-500 dark:text-blue-400" />
<span className="text-gray-800 dark:text-gray-200 font-medium">报价单预览</span>
</Space>
<ExportPDFButton />
</div>
}
<Button
type="primary"
icon={<DownloadOutlined />}
onClick={exportPDF}
className="bg-blue-500 hover:bg-blue-600 border-none rounded-full shadow-md hover:shadow-lg transition-all duration-200"
>
<div id="quotation-content" className="p-6">
<div className="text-center mb-8">
<Title level={2}>{attributes.quataName}</Title>
<Text type="secondary">创建日期{new Date(quotation.created_at).toLocaleDateString()}</Text>
导出PDF
</Button>
</div>
</div>
<div className="bg-gray-50 p-4 rounded-lg mb-6">
<Title level={4}>基本信息</Title>
<div className="grid grid-cols-2 gap-4">
<div id="quotation-content" className="p-8 bg-white" style={{ width: '210mm', margin: '0 auto' }}>
<div className="text-center mb-8">
<Title level={2} className="dark:text-gray-200">{attributes.quataName}</Title>
<Text type="secondary" className="dark:text-gray-400">
创建日期{new Date(quotation.created_at).toLocaleDateString()}
</Text>
</div>
<div className="bg-gray-50 dark:bg-gray-700 p-6 rounded-2xl mb-6">
<Title level={4} className="dark:text-gray-200 mb-4">基本信息</Title>
<div className="grid grid-cols-2 gap-6">
<div>
<Text type="secondary">客户</Text>
<Space>
<Text type="secondary" className="dark:text-gray-400">客户</Text>
<Space className="mt-2">
{attributes.customers?.map(customer => (
<Tag key={customer.id} color="blue">{customer.name}</Tag>
<Tag
key={customer.id}
className="px-3 py-1 rounded-full bg-blue-100 text-blue-600 dark:bg-blue-900 dark:text-blue-200 border-none"
>
{customer.name}
</Tag>
))}
</Space>
</div>
<div>
<Text type="secondary">货币类型</Text>
<Text>{attributes.currency}</Text>
<Text type="secondary" className="dark:text-gray-400">货币类型</Text>
<Text className="dark:text-gray-200 ml-2">{attributes.currency}</Text>
</div>
</div>
</div>
{attributes.sections?.map((section, sIndex) => (
<div key={sIndex} className="mb-6">
<div className="flex items-center gap-2 h-full">
<div key={sIndex} className="mb-8">
<div className="flex items-center gap-3 mb-4">
<div className="h-4 w-1 bg-blue-500 rounded-full" />
<h2>{section.sectionName}</h2>
<h2 className="text-lg font-medium dark:text-gray-200">{section.sectionName}</h2>
</div>
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<div className="overflow-x-auto rounded-2xl border border-gray-200 dark:border-gray-700">
<table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead className="bg-gray-50 dark:bg-gray-800">
<tr>
<th className="px-4 py-3 text-left text-sm font-medium text-gray-500">项目明细</th>
<th className="px-4 py-3 text-left text-sm font-medium text-gray-500">描述/备注</th>
@@ -194,9 +200,9 @@ const QuotationPreview = () => {
<th className="px-4 py-3 text-right text-sm font-medium text-gray-500">小计</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
<tbody className="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
{section.items.map((item, iIndex) => (
<tr key={iIndex}>
<tr key={iIndex} className="hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors duration-150">
<td className="px-4 py-3 text-sm text-gray-900">{item.name}</td>
<td className="px-4 py-3 text-sm text-gray-500">{item.description}</td>
<td className="px-4 py-3 text-sm text-gray-500">{item.unit}</td>
@@ -216,9 +222,9 @@ const QuotationPreview = () => {
))}
{/* 金额汇总 */}
<div className="mt-8 border-t pt-4">
<div className="flex justify-end space-y-2">
<div className="w-64 space-y-2">
<div className="mt-8 border-t border-gray-200 dark:border-gray-700 pt-6">
<div className="flex justify-end">
<div className="w-64 space-y-3">
<div className="flex justify-between">
<Text>税前总计</Text>
<Text>{currencySymbol}{attributes.beforeTaxAmount?.toLocaleString()}</Text>
@@ -238,9 +244,9 @@ const QuotationPreview = () => {
</div>
)}
<Divider className="my-2" />
<div className="flex justify-between">
<Text strong>最终金额</Text>
<Text strong className="text-blue-500 text-xl">
<div className="flex justify-between items-center">
<Text strong className="dark:text-gray-200">最终金额</Text>
<Text strong className="text-xl text-blue-500 dark:text-blue-400">
{currencySymbol}{(attributes.discount || attributes.afterTaxAmount)?.toLocaleString()}
</Text>
</div>
@@ -251,9 +257,9 @@ const QuotationPreview = () => {
{/* 补充说明 */}
{attributes.description && (
<div className="mt-8">
<Title level={4}>补充说明</Title>
<div className="bg-gray-50 p-4 rounded-lg">
<Text>{attributes.description}</Text>
<Title level={4} className="dark:text-gray-200">补充说明</Title>
<div className="bg-gray-50 dark:bg-gray-700 p-6 rounded-2xl">
<Text className="dark:text-gray-300">{attributes.description}</Text>
</div>
</div>
)}