Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kne-components/components-admin",
"version": "1.1.39",
"version": "1.1.40",
"description": "用于实现一个后台管理系统的必要组件",
"scripts": {
"init": "husky",
Expand Down
12 changes: 12 additions & 0 deletions src/components/Apis/getApis.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,22 @@ const getApis = options => {
method: 'POST'
},
statistics: {
/**
* 历史统计看板(GET)。
* Query:`range`(7d|1m|1y)、`timezone`(IANA,与「今日」划界一致)。
* 响应字段约定见 `src/components/Task/doc/api.md`「任务统计 HTTP」。
*/
getOverview: {
url: `${prefix}/task/statistics`,
method: 'GET'
},
/**
* 实时统计(Server-Sent Events,GET)。
* Query:`interval`、`token`、`timezone`(见 `useRealtimeStatisticsSSE` 与 Task `getClientIanaTimezone`)。
* 每条 `message` 的 `data` 为 JSON 对象(或 `{ data: {...} }` 包裹),字段约定见 `src/components/Task/doc/api.md`「任务实时统计 SSE」。
* 看板手动区:条数用 `waitingByRunnerType.manual` / `completedToday.manual`;主时长用
* `waitingQueueMaxWaitMsByRunnerType.manual`(队列最长等待)、`completedTodayTotalDurationMsByRunnerType.manual`(当日完成创建→完成之和)。
*/
sse: {
url: `${prefix}/task/statistics/sse`,
method: 'GET'
Expand Down
71 changes: 56 additions & 15 deletions src/components/MessageManger/Dashboard/HistorySection.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,24 @@ import SectionHeader from './SectionHeader';
import { getClientIanaTimezone } from '../utils';
import style from './dashboard.module.scss';

const RANGE_DAY_COUNT = { '7d': 7, '1m': 30, '1y': 365 };

/** 本地日历上从 range 起点到今天的日期轴(YYYY-MM-DD) */
const buildLocalDateAxisForRange = rangeKey => {
const days = RANGE_DAY_COUNT[rangeKey] || 7;
const dates = [];
for (let i = days - 1; i >= 0; i -= 1) {
const d = new Date();
d.setHours(0, 0, 0, 0);
d.setDate(d.getDate() - i);
const y = d.getFullYear();
const m = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
dates.push(`${y}-${m}-${day}`);
}
return dates;
};

const HistorySection = createWithRemoteLoader({
modules: ['components-thirdparty:Echart']
})(
Expand Down Expand Up @@ -70,12 +88,18 @@ const HistorySection = createWithRemoteLoader({
const trendOption = (() => {
const recentTrend = data?.recentTrend || [];
const recentTrendByType = data?.recentTrendByType || [];
if (recentTrend.length === 0) return null;
const axisDates = recentTrend.length > 0 ? null : buildLocalDateAxisForRange(range);

const dateMap = {};
recentTrend.forEach(item => {
dateMap[item.date] = { date: item.date, total: item.count };
});
if (recentTrend.length > 0) {
recentTrend.forEach(item => {
dateMap[item.date] = { date: item.date, total: item.count };
});
} else {
axisDates.forEach(d => {
dateMap[d] = { date: d, total: 0 };
});
}
recentTrendByType.forEach(item => {
if (!dateMap[item.date]) {
dateMap[item.date] = { date: item.date, total: 0 };
Expand Down Expand Up @@ -155,7 +179,32 @@ const HistorySection = createWithRemoteLoader({
const codePieOption = (() => {
const byCode = data?.byCode || {};
const entries = Object.entries(byCode);
if (entries.length === 0) return null;
if (entries.length === 0) {
return {
tooltip: { show: false },
legend: { show: false },
graphic: [
{
type: 'text',
left: 'center',
top: 'center',
style: {
text: formatMessage({ id: 'NoData' }),
fill: '#94a3b8',
fontSize: 14,
fontWeight: 500
}
}
],
series: [
{
...pieSeries(['50%', '42%'], ['44%', '62%']),
silent: true,
data: [{ value: 1, name: '', itemStyle: { color: '#f1f5f9' }, label: { show: false } }]
}
]
};
}
return {
color: PALETTE.pie,
tooltip: itemTooltipStyle,
Expand Down Expand Up @@ -232,11 +281,7 @@ const HistorySection = createWithRemoteLoader({
</div>

<BoxCard className={`${style.chartCardSurface} ${style.historyTrendCard}`}>
{trendOption ? (
<Echart style={{ height: 380 }} option={trendOption} />
) : (
<div className={style.emptyState}>{formatMessage({ id: 'NoData' })}</div>
)}
<Echart style={{ height: 380 }} option={trendOption} />
</BoxCard>

<Row gutter={[20, 24]} className={style.historyPiesRow}>
Expand All @@ -247,11 +292,7 @@ const HistorySection = createWithRemoteLoader({
</Col>
<Col xs={24} lg={12} className={style.chartCol}>
<BoxCard className={style.chartCardSurface} title={formatMessage({ id: 'ByCodeStats' })} style={{ height: '100%' }}>
{codePieOption ? (
<Echart style={{ height: 320 }} option={codePieOption} />
) : (
<div className={style.emptyState}>{formatMessage({ id: 'NoData' })}</div>
)}
<Echart style={{ height: 320 }} option={codePieOption} />
</BoxCard>
</Col>
</Row>
Expand Down
Loading
Loading