release: v0.17.0
GitHub Pages / build (push) Canceled after 0s
GitHub Pages / deploy (push) Canceled after 0s
Docker image / meta (push) Successful in 24s
Docs Docker image / meta (push) Successful in 7s
Docker image / build (amd64, linux/amd64, ubuntu-latest) (push) Failing after 59s
Docs Docker image / build (amd64, linux/amd64, ubuntu-latest) (push) Failing after 30s
Docker image / merge (push) Canceled after 0s
Docs Docker image / merge (push) Canceled after 0s
Docker image / build (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
Docs Docker image / build (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s

This commit is contained in:
Qiufeng
2026-08-19 22:09:49 +08:00
parent 9414048f9d
commit 84e9e7bff5
469 changed files with 19997 additions and 39561 deletions
@@ -0,0 +1,3 @@
.middleChartPanel {
margin-top: 16px;
}
@@ -0,0 +1,47 @@
import React, { useState } from 'react';
import { Col, Row, Card } from 'tdesign-react';
import ReactEcharts from 'echarts-for-react';
import useDynamicChart from 'hooks/useDynamicChart';
import LastWeekDatePicker from 'components/DatePicker';
import { getLineChartOptions, getPieChartOptions } from '../chart';
import Style from './MiddleChart.module.less';
const lineOptions = getLineChartOptions();
const pieOptions = getPieChartOptions();
const MiddleChart = () => {
const [customOptions, setCustomOptions] = useState(lineOptions);
const onTimeChange = (value: Array<string>) => {
const options = getLineChartOptions(value);
setCustomOptions(options);
};
const dynamicLineChartOption = useDynamicChart(customOptions, {
placeholderColor: ['legend.textStyle.color', 'xAxis.axisLabel.color', 'yAxis.axisLabel.color'],
borderColor: ['series.0.itemStyle.borderColor', 'series.1.itemStyle.borderColor'],
});
const dynamicPieChartOption = useDynamicChart(pieOptions, {
placeholderColor: ['legend.textStyle.color'],
containerColor: ['series.0.itemStyle.borderColor'],
textColor: ['label.color', 'label.color'],
});
return (
<Row gutter={[16, 16]} className={Style.middleChartPanel}>
<Col xs={12} xl={9}>
<Card title='统计数据' subtitle='(万元)' actions={LastWeekDatePicker(onTimeChange)} bordered={false}>
<ReactEcharts option={dynamicLineChartOption} notMerge={true} lazyUpdate={false} />
</Card>
</Col>
<Col xs={12} xl={3}>
<Card title='销售渠道' subtitle='2021-12' bordered={false}>
<ReactEcharts option={dynamicPieChartOption} notMerge={true} lazyUpdate={true} />
</Card>
</Col>
</Row>
);
};
export default React.memo(MiddleChart);
@@ -0,0 +1,5 @@
.overviewPanel {
background-color: var(--td-bg-color-container);
border-radius: 3px;
margin-top: 16px;
}
@@ -0,0 +1,69 @@
import React, { useState } from 'react';
import { Button, Col, Row, Card } from 'tdesign-react';
import ReactEcharts from 'echarts-for-react';
import useDynamicChart from 'hooks/useDynamicChart';
import Board, { ETrend } from 'components/Board';
import LastWeekDatePicker from 'components/DatePicker';
import { getBarChartOptions } from '../chart';
import Style from './Overview.module.less';
const options = getBarChartOptions();
const Overview = (): React.ReactElement => {
const [customOptions, setCustomOptions] = useState(options);
const onTimeChange = (value: any) => {
// eslint-disable-next-line no-shadow
const options = getBarChartOptions(value);
setCustomOptions(options);
};
const dynamicChartOption = useDynamicChart(customOptions, {
placeholderColor: ['legend.textStyle.color', 'xAxis.axisLabel.color', 'yAxis.axisLabel.color'],
});
return (
<div className={Style.overviewPanel}>
<Row>
<Col xs={12} xl={9} span={12}>
<Card title=' 出入库概览 ' subtitle='(件)' actions={LastWeekDatePicker(onTimeChange)} bordered={false}>
<ReactEcharts
option={dynamicChartOption} // option:图表配置项
notMerge={true}
lazyUpdate={true}
style={{ height: 351 }}
/>
</Card>
</Col>
<Col xs={12} xl={3} span={12}>
<Card actions={<Button>导出数据</Button>} bordered={false}>
<Row>
<Col xl={12} xs={6} span={12}>
<Board
title='本月出库总计(件)'
count='1726'
trend={ETrend.down}
trendNum='20.3%'
desc='自从上周以来'
border={false}
style={{ height: '168px' }}
/>
</Col>
<Col xl={12} xs={6} span={12}>
<Board
title='活跃用户(个)'
count='1126'
trend={ETrend.down}
trendNum='20.5%'
desc='自从上周以来'
border={false}
style={{ height: '168px' }}
/>
</Col>
</Row>
</Card>
</Col>
</Row>
</div>
);
};
export default React.memo(Overview);
@@ -0,0 +1,19 @@
.rankListPanel {
margin-top: 16px;
}
.rankIndex {
display: inline-flex;
width: 24px;
height: 24px;
border-radius: 50%;
color: #fff;
font-size: 14px;
background-color: var(--td-gray-color-5);
align-items: center;
justify-content: center;
font-weight: 700;
}
.rankIndexTop {
background: var(--td-brand-color);
}
@@ -0,0 +1,133 @@
import React from 'react';
import { Col, Radio, Row, Table, Button, Card } from 'tdesign-react';
import { TdPrimaryTableProps } from 'tdesign-react/es/table';
import classnames from 'classnames';
import { TrendIcon, ETrend } from 'components/Board';
import { PURCHASE_TREND_LIST, SALE_TREND_LIST } from '../constant';
import Style from './RankList.module.less';
const DateRadioGroup = (
<Radio.Group defaultValue='recent_week'>
<Radio.Button value='recent_week'>本周</Radio.Button>
<Radio.Button value='recent_month'>近三个月</Radio.Button>
</Radio.Group>
);
const SALE_COLUMNS: TdPrimaryTableProps['columns'] = [
{
align: 'center',
colKey: 'index',
title: '排名',
width: 80,
fixed: 'left',
cell: ({ rowIndex }) => (
<span className={classnames(Style.rankIndex, { [Style.rankIndexTop]: rowIndex < 3 })}>{rowIndex + 1}</span>
),
},
{
align: 'left',
ellipsis: true,
colKey: 'productName',
title: '客户名称',
width: 200,
},
{
align: 'center',
colKey: 'growUp',
width: 100,
title: '较上周',
cell: ({ row }) => <TrendIcon trend={row.growUp < 0 ? ETrend.down : ETrend.up} trendNum={Math.abs(row.growUp)} />,
},
{
align: 'center',
colKey: 'count',
title: '订单量',
width: 100,
},
{
align: 'center',
colKey: 'date',
width: 140,
title: '合同签订日期',
},
{
align: 'center',
colKey: 'operation',
fixed: 'right',
title: '操作',
width: 80,
cell: ({ row }) => (
<Button variant='text' theme='primary' onClick={() => console.log(row)}>
操作
</Button>
),
},
];
const PURCHASE_COLUMNS: TdPrimaryTableProps['columns'] = [
{
align: 'center',
colKey: 'index',
title: '排名',
width: 80,
fixed: 'left',
cell: ({ rowIndex }) => (
<span className={classnames(Style.rankIndex, { [Style.rankIndexTop]: rowIndex < 3 })}>{rowIndex + 1}</span>
),
},
{
align: 'left',
ellipsis: true,
colKey: 'productName',
title: '供应商名称',
width: 200,
},
{
align: 'center',
colKey: 'growUp',
width: 100,
title: '较上周',
cell: ({ row }) => <TrendIcon trend={row.growUp < 0 ? ETrend.down : ETrend.up} trendNum={Math.abs(row.growUp)} />,
},
{
align: 'center',
colKey: 'count',
title: '订单量',
width: 100,
},
{
align: 'center',
colKey: 'date',
width: 140,
title: '合同签订日期',
},
{
align: 'center',
colKey: 'operation',
title: '操作',
fixed: 'right',
width: 80,
cell: ({ row }) => (
<Button variant='text' theme='primary' onClick={() => console.log(row)}>
操作
</Button>
),
},
];
const RankList = () => (
<Row gutter={[16, 16]} className={Style.rankListPanel}>
<Col xs={12} xl={6} span={12}>
<Card title='销售订单排名' actions={DateRadioGroup} bordered={false}>
<Table columns={SALE_COLUMNS} rowKey='productName' size='medium' data={SALE_TREND_LIST} />
</Card>
</Col>
<Col xs={12} xl={6} span={12}>
<Card title='采购订单排名' actions={DateRadioGroup} bordered={false}>
<Table columns={PURCHASE_COLUMNS} rowKey='productName' size='medium' data={PURCHASE_TREND_LIST} />
</Card>
</Col>
</Row>
);
export default React.memo(RankList);
@@ -0,0 +1,35 @@
.iconWrap {
display: inline-flex;
align-items: center;
justify-content: center;
width: 56px;
height: 56px;
background: var(--td-brand-color-1);
border-radius: 50%;
position: absolute;
top: 32px;
right: 32px;
}
.svgIcon {
font-size: 24px;
color: var(--td-brand-color);
}
.paneLineChart {
width: 103px;
height: 56px;
overflow: hidden;
position: absolute;
top: 55px;
right: 32px;
}
.paneBarChart {
width: 103px;
height: 36px;
-webkit-tap-highlight-color: transparent;
user-select: none;
position: absolute;
top: 55px;
right: 32px;
}
@@ -0,0 +1,92 @@
import React, { memo } from 'react';
import { Col, Row } from 'tdesign-react';
import { UsergroupIcon, FileIcon } from 'tdesign-icons-react';
import ReactEcharts from 'echarts-for-react';
import Board, { ETrend, IBoardProps } from 'components/Board';
import useDynamicChart from 'hooks/useDynamicChart';
import { MICRO_CHART_OPTIONS_BAR, MICRO_CHART_OPTIONS_LINE } from '../chart';
import Style from './TopPanel.module.less';
const BarChartIcon = memo(() => {
const dynamicChartOption = useDynamicChart(MICRO_CHART_OPTIONS_BAR);
return (
<div className={Style.paneBarChart}>
<ReactEcharts
option={dynamicChartOption} // option:图表配置项
notMerge={true}
lazyUpdate={true}
style={{ height: 36 }}
/>
</div>
);
});
const PieChartIcon = memo(() => (
<div className={Style.paneLineChart}>
<ReactEcharts
option={MICRO_CHART_OPTIONS_LINE} // option:图表配置项
notMerge={true}
lazyUpdate={true}
style={{ height: 56 }}
/>
</div>
));
const PANE_LIST: Array<IBoardProps> = [
{
title: '总收入',
count: '¥ 28,425.00',
trend: ETrend.up,
trendNum: '20.5%',
Icon: <PieChartIcon />,
},
{
title: '总退款',
count: '¥ 768.00',
trend: ETrend.down,
trendNum: '20.5%',
Icon: <BarChartIcon />,
},
{
title: '活跃用户(个)',
count: '1126',
trend: ETrend.down,
trendNum: '20.5%',
Icon: (
<div className={Style.iconWrap}>
<UsergroupIcon className={Style.svgIcon} />
</div>
),
},
{
title: '产生订单(个)',
count: '527',
trend: ETrend.down,
trendNum: '20.5%',
Icon: (
<div className={Style.iconWrap}>
<FileIcon className={Style.svgIcon} />
</div>
),
},
];
const TopPanel = () => (
<Row gutter={[16, 16]}>
{PANE_LIST.map((item, index) => (
<Col key={item.title} xs={6} xl={3}>
<Board
title={item.title}
trend={item.trend}
trendNum={item.trendNum}
count={item.count}
desc={'自从上周以来'}
Icon={item.Icon}
dark={index === 0}
/>
</Col>
))}
</Row>
);
export default React.memo(TopPanel);