2026-04-19 19:15:01 +08:00
|
|
|
import React, { useState, useEffect } from 'react';
|
|
|
|
|
import { Card, Typography, Table, DatePicker, Button, Row, Col, Tag } from 'antd';
|
|
|
|
|
import { DownloadOutlined } from '@ant-design/icons';
|
|
|
|
|
|
|
|
|
|
const { Title, Paragraph } = Typography;
|
|
|
|
|
|
|
|
|
|
const ReportsPage: React.FC = () => {
|
|
|
|
|
const [isMobile, setIsMobile] = useState(false);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const checkMobile = () => {
|
|
|
|
|
setIsMobile(window.innerWidth <= 768);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
checkMobile();
|
|
|
|
|
window.addEventListener('resize', checkMobile);
|
|
|
|
|
return () => window.removeEventListener('resize', checkMobile);
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
// 报表数据 - 从API获取或为空数组
|
|
|
|
|
const dataSource: any[] = [];
|
|
|
|
|
|
|
|
|
|
// 桌面端表格列
|
|
|
|
|
const desktopColumns = [
|
|
|
|
|
{
|
|
|
|
|
title: '月份',
|
|
|
|
|
dataIndex: 'month',
|
|
|
|
|
key: 'month',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '总收入',
|
|
|
|
|
dataIndex: 'income',
|
|
|
|
|
key: 'income',
|
|
|
|
|
render: (amount: number) => `¥${amount.toLocaleString()}`,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '总支出',
|
|
|
|
|
dataIndex: 'expense',
|
|
|
|
|
key: 'expense',
|
|
|
|
|
render: (amount: number) => `¥${amount.toLocaleString()}`,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '净利润',
|
|
|
|
|
dataIndex: 'profit',
|
|
|
|
|
key: 'profit',
|
|
|
|
|
render: (amount: number) => (
|
|
|
|
|
<span style={{ color: amount > 0 ? 'green' : 'red' }}>
|
|
|
|
|
¥{amount.toLocaleString()}
|
|
|
|
|
</span>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '项目数量',
|
|
|
|
|
dataIndex: 'projects',
|
|
|
|
|
key: 'projects',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '操作',
|
|
|
|
|
key: 'action',
|
|
|
|
|
render: () => (
|
|
|
|
|
<Button size="small" icon={<DownloadOutlined />}>导出</Button>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// 移动端简化表格列
|
|
|
|
|
const mobileColumns = [
|
|
|
|
|
{
|
|
|
|
|
title: '月份',
|
|
|
|
|
dataIndex: 'month',
|
|
|
|
|
key: 'month',
|
|
|
|
|
render: (month: string) => month.replace('-', '/'),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '收入',
|
|
|
|
|
dataIndex: 'income',
|
|
|
|
|
key: 'income',
|
|
|
|
|
render: (amount: number) => (
|
|
|
|
|
<div style={{ color: 'green' }}>¥{(amount / 10000).toFixed(0)}万</div>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '支出',
|
|
|
|
|
dataIndex: 'expense',
|
|
|
|
|
key: 'expense',
|
|
|
|
|
render: (amount: number) => (
|
|
|
|
|
<div style={{ color: 'red' }}>¥{(amount / 10000).toFixed(0)}万</div>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '利润',
|
|
|
|
|
dataIndex: 'profit',
|
|
|
|
|
key: 'profit',
|
|
|
|
|
render: (amount: number) => (
|
|
|
|
|
<div style={{ fontWeight: 'bold', color: amount > 0 ? 'green' : 'red' }}>
|
|
|
|
|
¥{(amount / 10000).toFixed(0)}万
|
|
|
|
|
</div>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div style={{ padding: isMobile ? 8 : 24 }}>
|
|
|
|
|
<div style={{ marginBottom: isMobile ? 12 : 24 }}>
|
|
|
|
|
<Title level={isMobile ? 3 : 2} style={{ marginBottom: 8 }}>统计报表</Title>
|
|
|
|
|
<Paragraph type="secondary" style={{ marginBottom: 0 }}>
|
|
|
|
|
查看项目财务报表和统计分析数据
|
|
|
|
|
</Paragraph>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<Card
|
|
|
|
|
title="月度财务报表"
|
|
|
|
|
size="small"
|
|
|
|
|
styles={{ body: { padding: isMobile ? 8 : 24 } }}
|
|
|
|
|
extra={
|
|
|
|
|
isMobile ? (
|
|
|
|
|
<Button size="small" icon={<DownloadOutlined />} />
|
|
|
|
|
) : (
|
|
|
|
|
<DatePicker picker="month" style={{ marginRight: 8 }} />
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
<Table
|
|
|
|
|
dataSource={dataSource}
|
|
|
|
|
columns={isMobile ? mobileColumns : desktopColumns}
|
|
|
|
|
pagination={false}
|
|
|
|
|
scroll={isMobile ? { x: 350 } : undefined}
|
|
|
|
|
size={isMobile ? 'small' : 'middle'}
|
|
|
|
|
summary={(pageData) => {
|
|
|
|
|
let totalIncome = 0;
|
|
|
|
|
let totalExpense = 0;
|
|
|
|
|
let totalProfit = 0;
|
|
|
|
|
let totalProjects = 0;
|
|
|
|
|
|
|
|
|
|
pageData.forEach(({ income, expense, profit, projects }) => {
|
|
|
|
|
totalIncome += income;
|
|
|
|
|
totalExpense += expense;
|
|
|
|
|
totalProfit += profit;
|
|
|
|
|
totalProjects += projects;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Table.Summary fixed>
|
|
|
|
|
<Table.Summary.Row>
|
|
|
|
|
<Table.Summary.Cell index={0}>
|
|
|
|
|
<strong>合计</strong>
|
|
|
|
|
</Table.Summary.Cell>
|
|
|
|
|
<Table.Summary.Cell index={1}>
|
|
|
|
|
<strong>¥{(totalIncome / 10000).toFixed(0)}万</strong>
|
|
|
|
|
</Table.Summary.Cell>
|
|
|
|
|
<Table.Summary.Cell index={2}>
|
|
|
|
|
<strong>¥{(totalExpense / 10000).toFixed(0)}万</strong>
|
|
|
|
|
</Table.Summary.Cell>
|
|
|
|
|
<Table.Summary.Cell index={3}>
|
|
|
|
|
<strong style={{ color: totalProfit > 0 ? 'green' : 'red' }}>
|
|
|
|
|
¥{(totalProfit / 10000).toFixed(0)}万
|
|
|
|
|
</strong>
|
|
|
|
|
</Table.Summary.Cell>
|
|
|
|
|
{!isMobile && (
|
|
|
|
|
<>
|
|
|
|
|
<Table.Summary.Cell index={4}>
|
|
|
|
|
<strong>{totalProjects}</strong>
|
|
|
|
|
</Table.Summary.Cell>
|
|
|
|
|
<Table.Summary.Cell index={5} />
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</Table.Summary.Row>
|
|
|
|
|
</Table.Summary>
|
|
|
|
|
);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</Card>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-25 23:55:36 +07:00
|
|
|
export default ReportsPage;
|