|
|
@@ -1,4 +1,4 @@
|
|
|
-import { useState, useEffect } from 'react'
|
|
|
+import React, { useState, useEffect, useMemo } from 'react'
|
|
|
import { useNavigate } from 'react-router-dom'
|
|
|
import { Card, Row, Col, Statistic, Button, DatePicker, Table, Empty, Spin, message, Alert } from 'antd'
|
|
|
import {
|
|
|
@@ -264,41 +264,79 @@ function Dashboard() {
|
|
|
|
|
|
// Table columns for yearly summary
|
|
|
const monthNames = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
|
|
|
+
|
|
|
+ // Transform yearly summary data to split settled/unsettled into separate rows
|
|
|
+ const transformedYearlyData = useMemo(() => {
|
|
|
+ if (!yearlySummary?.persons) return []
|
|
|
+ const rows = []
|
|
|
+ yearlySummary.persons.forEach(person => {
|
|
|
+ // Settled row
|
|
|
+ rows.push({
|
|
|
+ key: `${person.person_id}-settled`,
|
|
|
+ person_id: person.person_id,
|
|
|
+ person_name: person.person_name,
|
|
|
+ settlement_type: '已结算',
|
|
|
+ is_unsettled: false,
|
|
|
+ monthly_data: person.monthly_settled || Array(12).fill(0),
|
|
|
+ row_total: person.settled_total || 0
|
|
|
+ })
|
|
|
+ // Unsettled row
|
|
|
+ rows.push({
|
|
|
+ key: `${person.person_id}-unsettled`,
|
|
|
+ person_id: person.person_id,
|
|
|
+ person_name: person.person_name,
|
|
|
+ settlement_type: '未结算',
|
|
|
+ is_unsettled: true,
|
|
|
+ monthly_data: person.monthly_unsettled || Array(12).fill(0),
|
|
|
+ row_total: person.unsettled_total || 0
|
|
|
+ })
|
|
|
+ })
|
|
|
+ return rows
|
|
|
+ }, [yearlySummary])
|
|
|
+
|
|
|
const yearlySummaryColumns = [
|
|
|
{
|
|
|
title: '人员',
|
|
|
dataIndex: 'person_name',
|
|
|
key: 'person_name',
|
|
|
fixed: 'left',
|
|
|
- width: 100
|
|
|
+ width: 100,
|
|
|
+ onCell: (record) => ({
|
|
|
+ style: record.is_unsettled ? { backgroundColor: '#fff7e6' } : {}
|
|
|
+ })
|
|
|
},
|
|
|
{
|
|
|
title: '结算状态',
|
|
|
- key: 'settlement_status',
|
|
|
- width: 200,
|
|
|
- render: (_, record) => (
|
|
|
- <div>
|
|
|
- <div style={{ color: '#52c41a' }}>已结算: ¥{(record.settled_total || 0).toFixed(2)}</div>
|
|
|
- <div style={{ color: '#fa8c16' }}>未结算: ¥{(record.unsettled_total || 0).toFixed(2)}</div>
|
|
|
- </div>
|
|
|
+ dataIndex: 'settlement_type',
|
|
|
+ key: 'settlement_type',
|
|
|
+ width: 80,
|
|
|
+ render: (value, record) => (
|
|
|
+ <span style={{ color: record.is_unsettled ? '#fa8c16' : '#52c41a' }}>
|
|
|
+ {value}
|
|
|
+ </span>
|
|
|
)
|
|
|
},
|
|
|
...monthNames.map((name, index) => ({
|
|
|
title: name,
|
|
|
- dataIndex: ['monthly_earnings', index],
|
|
|
key: `month_${index}`,
|
|
|
align: 'right',
|
|
|
width: 80,
|
|
|
- render: (value) => value ? `¥${value.toFixed(2)}` : '¥0.00'
|
|
|
+ render: (_, record) => {
|
|
|
+ const value = record.monthly_data?.[index] || 0
|
|
|
+ return value ? `¥${value.toFixed(2)}` : '¥0.00'
|
|
|
+ }
|
|
|
})),
|
|
|
{
|
|
|
title: '年度合计',
|
|
|
- dataIndex: 'yearly_total',
|
|
|
- key: 'yearly_total',
|
|
|
+ dataIndex: 'row_total',
|
|
|
+ key: 'row_total',
|
|
|
align: 'right',
|
|
|
fixed: 'right',
|
|
|
width: 100,
|
|
|
- render: (value) => <strong>¥{(value || 0).toFixed(2)}</strong>
|
|
|
+ render: (value) => <strong>¥{(value || 0).toFixed(2)}</strong>,
|
|
|
+ onCell: (record) => ({
|
|
|
+ style: record.is_unsettled ? { backgroundColor: '#fff7e6' } : {}
|
|
|
+ })
|
|
|
}
|
|
|
]
|
|
|
|
|
|
@@ -589,11 +627,12 @@ function Dashboard() {
|
|
|
{yearlySummary?.persons?.length > 0 ? (
|
|
|
<Table
|
|
|
columns={yearlySummaryColumns}
|
|
|
- dataSource={yearlySummary.persons}
|
|
|
- rowKey="person_id"
|
|
|
+ dataSource={transformedYearlyData}
|
|
|
+ rowKey="key"
|
|
|
pagination={false}
|
|
|
size="small"
|
|
|
scroll={{ x: 1400 }}
|
|
|
+ rowClassName={(record) => record.is_unsettled ? 'unsettled-row' : ''}
|
|
|
summary={() => (
|
|
|
<Table.Summary fixed>
|
|
|
<Table.Summary.Row>
|
|
|
@@ -601,18 +640,31 @@ function Dashboard() {
|
|
|
<strong>合计</strong>
|
|
|
</Table.Summary.Cell>
|
|
|
<Table.Summary.Cell index={1}>
|
|
|
- <div>
|
|
|
- <div style={{ color: '#52c41a' }}>已结算: ¥{(yearlySummary.settled_grand_total || 0).toFixed(2)}</div>
|
|
|
- <div style={{ color: '#fa8c16' }}>未结算: ¥{(yearlySummary.unsettled_grand_total || 0).toFixed(2)}</div>
|
|
|
- </div>
|
|
|
+ <span style={{ color: '#52c41a' }}>已结算</span>
|
|
|
</Table.Summary.Cell>
|
|
|
- {(yearlySummary.monthly_totals || []).map((total, index) => (
|
|
|
+ {(yearlySummary.monthly_settled_totals || []).map((total, index) => (
|
|
|
<Table.Summary.Cell key={index} index={index + 2} align="right">
|
|
|
<strong>¥{(total || 0).toFixed(2)}</strong>
|
|
|
</Table.Summary.Cell>
|
|
|
))}
|
|
|
<Table.Summary.Cell index={14} align="right" fixed="right">
|
|
|
- <strong>¥{(yearlySummary.grand_total || 0).toFixed(2)}</strong>
|
|
|
+ <strong>¥{(yearlySummary.settled_grand_total || 0).toFixed(2)}</strong>
|
|
|
+ </Table.Summary.Cell>
|
|
|
+ </Table.Summary.Row>
|
|
|
+ <Table.Summary.Row className="unsettled-row">
|
|
|
+ <Table.Summary.Cell index={0} fixed="left" style={{ backgroundColor: '#fff7e6' }}>
|
|
|
+ <strong>合计</strong>
|
|
|
+ </Table.Summary.Cell>
|
|
|
+ <Table.Summary.Cell index={1}>
|
|
|
+ <span style={{ color: '#fa8c16' }}>未结算</span>
|
|
|
+ </Table.Summary.Cell>
|
|
|
+ {(yearlySummary.monthly_unsettled_totals || []).map((total, index) => (
|
|
|
+ <Table.Summary.Cell key={index} index={index + 2} align="right">
|
|
|
+ <strong>¥{(total || 0).toFixed(2)}</strong>
|
|
|
+ </Table.Summary.Cell>
|
|
|
+ ))}
|
|
|
+ <Table.Summary.Cell index={14} align="right" fixed="right" style={{ backgroundColor: '#fff7e6' }}>
|
|
|
+ <strong>¥{(yearlySummary.unsettled_grand_total || 0).toFixed(2)}</strong>
|
|
|
</Table.Summary.Cell>
|
|
|
</Table.Summary.Row>
|
|
|
</Table.Summary>
|