227 lines
5.4 KiB
TypeScript
227 lines
5.4 KiB
TypeScript
import React from 'react';
|
|||
|
|
import { Card, Typography, Table, Statistic, Row, Col, Tag } from 'antd';
|
||
|
|
import { DollarOutlined, FileTextOutlined, CheckCircleOutlined } from '@ant-design/icons';
|
||
|
|
|
||
|
|
const { Title, Paragraph } = Typography;
|
||
|
|
|
||
|
|
const FinancePage: React.FC = () => {
|
||
|
|
// 统计数据
|
||
|
|
const stats = [
|
||
|
|
{
|
||
|
|
title: '本月总收入',
|
||
|
|
value: 125000,
|
||
|
|
prefix: '¥',
|
||
|
|
icon: <DollarOutlined />,
|
||
|
|
trend: '+12%',
|
||
|
|
color: '#3f8600',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: '本月总支出',
|
||
|
|
value: 68000,
|
||
|
|
prefix: '¥',
|
||
|
|
icon: <FileTextOutlined />,
|
||
|
|
trend: '-5%',
|
||
|
|
color: '#cf1322',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: '待审批报销',
|
||
|
|
value: 15000,
|
||
|
|
prefix: '¥',
|
||
|
|
icon: <CheckCircleOutlined />,
|
||
|
|
trend: '+3%',
|
||
|
|
color: '#1890ff',
|
||
|
|
},
|
||
|
|
];
|
||
|
|
|
||
|
|
// 财务记录数据
|
||
|
|
const dataSource = [
|
||
|
|
{
|
||
|
|
key: '1',
|
||
|
|
date: '2026-03-10',
|
||
|
|
type: '收入',
|
||
|
|
category: '项目回款',
|
||
|
|
project: '项目 A',
|
||
|
|
amount: 50000,
|
||
|
|
status: '已入账',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
key: '2',
|
||
|
|
date: '2026-03-09',
|
||
|
|
type: '支出',
|
||
|
|
category: '报销',
|
||
|
|
project: '项目 B',
|
||
|
|
amount: 8000,
|
||
|
|
status: '已付款',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
key: '3',
|
||
|
|
date: '2026-03-08',
|
||
|
|
type: '支出',
|
||
|
|
category: '预支',
|
||
|
|
project: '项目 C',
|
||
|
|
amount: 5000,
|
||
|
|
status: '已付款',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
key: '4',
|
||
|
|
date: '2026-03-07',
|
||
|
|
type: '收入',
|
||
|
|
category: '项目回款',
|
||
|
|
project: '项目 D',
|
||
|
|
amount: 75000,
|
||
|
|
status: '已入账',
|
||
|
|
},
|
||
|
|
];
|
||
|
|
|
||
|
|
// 桌面端表格列
|
||
|
|
const desktopColumns = [
|
||
|
|
{
|
||
|
|
title: '日期',
|
||
|
|
dataIndex: 'date',
|
||
|
|
key: 'date',
|
||
|
|
sorter: (a: any, b: any) => a.date.localeCompare(b.date),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: '类型',
|
||
|
|
dataIndex: 'type',
|
||
|
|
key: 'type',
|
||
|
|
render: (type: string) => (
|
||
|
|
<span style={{ color: type === '收入' ? 'green' : 'red' }}>
|
||
|
|
{type === '收入' ? '↑ 收入' : '↓ 支出'}
|
||
|
|
</span>
|
||
|
|
),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: '类别',
|
||
|
|
dataIndex: 'category',
|
||
|
|
key: 'category',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: '项目',
|
||
|
|
dataIndex: 'project',
|
||
|
|
key: 'project',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: '金额',
|
||
|
|
dataIndex: 'amount',
|
||
|
|
key: 'amount',
|
||
|
|
render: (amount: number) => `¥${amount.toLocaleString()}`,
|
||
|
|
sorter: (a: any, b: any) => a.amount - b.amount,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: '状态',
|
||
|
|
dataIndex: 'status',
|
||
|
|
key: 'status',
|
||
|
|
render: (status: string) => {
|
||
|
|
const colorMap: Record<string, string> = {
|
||
|
|
'已入账': 'green',
|
||
|
|
'已付款': 'blue',
|
||
|
|
'处理中': 'orange',
|
||
|
|
};
|
||
|
|
return <Tag color={colorMap[status] || 'default'}>{status}</Tag>;
|
||
|
|
},
|
||
|
|
},
|
||
|
|
];
|
||
|
|
|
||
|
|
// 移动端简化表格列
|
||
|
|
const mobileColumns = [
|
||
|
|
{
|
||
|
|
title: '日期',
|
||
|
|
dataIndex: 'date',
|
||
|
|
key: 'date',
|
||
|
|
width: 100,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: '类型',
|
||
|
|
dataIndex: 'type',
|
||
|
|
key: 'type',
|
||
|
|
width: 60,
|
||
|
|
render: (type: string) => (
|
||
|
|
<span style={{ color: type === '收入' ? 'green' : 'red', fontSize: 12 }}>
|
||
|
|
{type === '收入' ? '↑' : '↓'}
|
||
|
|
</span>
|
||
|
|
),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: '金额',
|
||
|
|
dataIndex: 'amount',
|
||
|
|
key: 'amount',
|
||
|
|
render: (amount: number) => (
|
||
|
|
<div style={{ fontWeight: 'bold' }}>¥{amount.toLocaleString()}</div>
|
||
|
|
),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: '状态',
|
||
|
|
dataIndex: 'status',
|
||
|
|
key: 'status',
|
||
|
|
render: (status: string) => (
|
||
|
|
<Tag color={status === '已入账' ? 'green' : 'blue'} style={{ fontSize: 10 }}>
|
||
|
|
{status}
|
||
|
|
</Tag>
|
||
|
|
),
|
||
|
|
},
|
||
|
|
];
|
||
|
|
|
||
|
|
const [isMobile, setIsMobile] = React.useState(false);
|
||
|
|
|
||
|
|
React.useEffect(() => {
|
||
|
|
const checkMobile = () => {
|
||
|
|
setIsMobile(window.innerWidth <= 768);
|
||
|
|
};
|
||
|
|
|
||
|
|
checkMobile();
|
||
|
|
window.addEventListener('resize', checkMobile);
|
||
|
|
return () => window.removeEventListener('resize', checkMobile);
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div>
|
||
|
|
<div style={{ marginBottom: 16 }}>
|
||
|
|
<Title level={3} style={{ marginBottom: 8 }}>财务管理</Title>
|
||
|
|
<Paragraph type="secondary" style={{ marginBottom: 0 }}>
|
||
|
|
查看公司财务状况、收支明细
|
||
|
|
</Paragraph>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 统计卡片 - 移动端优化 */}
|
||
|
|
<Row gutter={[8, 8]} style={{ marginBottom: 16 }}>
|
||
|
|
{stats.map((stat, index) => (
|
||
|
|
<Col xs={24} sm={8} key={index}>
|
||
|
|
<Card size="small" style={{ textAlign: 'center' }}>
|
||
|
|
<Statistic
|
||
|
|
title={<span style={{ fontSize: 12 }}>{stat.title}</span>}
|
||
|
|
value={stat.value}
|
||
|
|
prefix={stat.prefix}
|
||
|
|
suffix={stat.trend}
|
||
|
|
valueStyle={{
|
||
|
|
color: stat.color,
|
||
|
|
fontSize: isMobile ? 18 : undefined
|
||
|
|
}}
|
||
|
|
/>
|
||
|
|
</Card>
|
||
|
|
</Col>
|
||
|
|
))}
|
||
|
|
</Row>
|
||
|
|
|
||
|
|
{/* 财务明细表 */}
|
||
|
|
<Card
|
||
|
|
title="财务明细"
|
||
|
|
size="small"
|
||
|
|
styles={{ body: { padding: isMobile ? 8 : 24 } }}
|
||
|
|
>
|
||
|
|
<Table
|
||
|
|
dataSource={dataSource}
|
||
|
|
columns={isMobile ? mobileColumns : desktopColumns}
|
||
|
|
pagination={{
|
||
|
|
pageSize: 5,
|
||
|
|
size: isMobile ? 'small' : 'default'
|
||
|
|
}}
|
||
|
|
scroll={isMobile ? { x: 500 } : undefined}
|
||
|
|
size={isMobile ? 'small' : 'middle'}
|
||
|
|
/>
|
||
|
|
</Card>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
export default FinancePage;
|