113 lines
4.0 KiB
TypeScript
Raw Normal View History

import React, { useEffect, useState } from 'react';
import { PageContainer } from '@ant-design/pro-components';
import { Card, Col, Row, Table, Spin } from 'antd';
import {
ShoppingOutlined,
InboxOutlined,
DatabaseOutlined,
DollarOutlined,
RiseOutlined,
} from '@ant-design/icons';
import { getStockSummary, getStockByColor, getStockByLocation } from '@/services/api';
import type { StockSummary, StockGroup } from '@/types/api';
import type { ColumnsType } from 'antd/es/table';
const groupColumns: ColumnsType<StockGroup> = [
{ title: '名称', dataIndex: 'name' },
{ title: '产品数', dataIndex: 'count' },
{ title: '库存量', dataIndex: 'quantity' },
];
const StatsPage: React.FC = () => {
const [summary, setSummary] = useState<StockSummary | null>(null);
const [colorData, setColorData] = useState<StockGroup[]>([]);
const [locationData, setLocationData] = useState<StockGroup[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
Promise.all([
getStockSummary(),
getStockByColor(),
getStockByLocation(),
]).then(([sumRes, colorRes, locRes]) => {
if (sumRes?.code === 0) setSummary(sumRes.data);
if (colorRes?.code === 0) setColorData(colorRes.data?.list || []);
if (locRes?.code === 0) setLocationData(locRes.data?.list || []);
}).finally(() => setLoading(false));
}, []);
if (loading) {
return (
<PageContainer>
<div style={{ display: 'flex', justifyContent: 'center', padding: 120 }}>
<Spin size="large" />
</div>
</PageContainer>
);
}
const stats = [
{ icon: <ShoppingOutlined />, title: '产品总数', value: summary?.productCount ?? 0 },
{ icon: <InboxOutlined />, title: '总匹数', value: summary?.totalPieces ?? 0 },
{ icon: <DatabaseOutlined />, title: '总盘数', value: summary?.totalRolls ?? 0 },
{ icon: <DollarOutlined />, title: '库存总值(成本)', value: `¥${summary?.totalCostValue ?? '0'}` },
{ icon: <RiseOutlined />, title: '库存总值(销售)', value: `¥${summary?.totalSalesValue ?? '0'}` },
];
return (
<PageContainer>
<Row gutter={[16, 16]} style={{ marginBottom: 24 }}>
{stats.map((s) => (
<Col xs={24} sm={12} lg={4} xl={4} key={s.title} style={{ flex: 1 }}>
<Card bordered={false} styles={{ body: { padding: '20px 18px' } }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10 }}>
<span style={{
display: 'flex', justifyContent: 'center', alignItems: 'center',
width: 34, height: 34, borderRadius: 8,
background: 'rgba(0,82,255,0.06)', color: '#0052FF', fontSize: 16,
}}>
{s.icon}
</span>
<span style={{ fontSize: 12, color: '#64748B' }}>{s.title}</span>
</div>
<div style={{ fontSize: 22, fontWeight: 700, color: '#0F172A' }}>{s.value}</div>
</Card>
</Col>
))}
</Row>
<Row gutter={16}>
<Col xs={24} lg={12}>
<Card title="按颜色分类统计" bordered={false}>
<Table<StockGroup>
dataSource={colorData}
rowKey="name"
columns={[
{ title: '颜色', dataIndex: 'name' },
...groupColumns.slice(1),
]}
pagination={false}
size="small"
/>
</Card>
</Col>
<Col xs={24} lg={12}>
<Card title="按位置分布统计" bordered={false}>
<Table<StockGroup>
dataSource={locationData}
rowKey="name"
columns={[
{ title: '存放位置', dataIndex: 'name' },
...groupColumns.slice(1),
]}
pagination={false}
size="small"
/>
</Card>
</Col>
</Row>
</PageContainer>
);
};
export default StatsPage;