From ea2904d7ca03b42f5783cd659fe71c0fbedd2277 Mon Sep 17 00:00:00 2001 From: skyouc Date: 星期一, 11 八月 2025 17:05:21 +0800 Subject: [PATCH] Merge branch 'devlop' of http://47.97.1.152:5880/r/wms-master into devlop --- rsf-admin/src/page/dashboard/NbChart.jsx | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 117 insertions(+), 0 deletions(-) diff --git a/rsf-admin/src/page/dashboard/NbChart.jsx b/rsf-admin/src/page/dashboard/NbChart.jsx new file mode 100644 index 0000000..a0b6373 --- /dev/null +++ b/rsf-admin/src/page/dashboard/NbChart.jsx @@ -0,0 +1,117 @@ +import * as React from 'react'; +import { Card, CardHeader, CardContent } from '@mui/material'; +import { + ResponsiveContainer, + AreaChart, + Area, + XAxis, + YAxis, + CartesianGrid, + Tooltip, +} from 'recharts'; +import { useTranslate } from 'react-admin'; +import { format, subDays, addDays } from 'date-fns'; + +const lastDay = new Date(); +const lastMonthDays = Array.from({ length: 30 }, (_, i) => subDays(lastDay, i)); +const aMonthAgo = subDays(new Date(), 30); + +const dateFormatter = (date) => + new Date(date).toLocaleDateString(); + +const aggregateOrdersByDay = (orders) => + orders + .filter((order) => order.status !== 'cancelled') + .reduce( + (acc, curr) => { + const day = format(curr.date, 'yyyy-MM-dd'); + if (!acc[day]) { + acc[day] = 0; + } + acc[day] += curr.total; + return acc; + }, + {} + ); + +const getRevenuePerDay = (orders) => { + const daysWithRevenue = aggregateOrdersByDay(orders); + return lastMonthDays.map(date => ({ + date: date.getTime(), + total: daysWithRevenue[format(date, 'yyyy-MM-dd')] || 0, + })); +}; + +const NbChart = (props) => { + const { orders } = props; + const translate = useTranslate(); + if (!orders) return null; + + return ( + <Card> + <CardHeader title={translate('pos.dashboard.month_history')} /> + <CardContent> + <div style={{ width: '100%', height: 300 }}> + <ResponsiveContainer> + <AreaChart data={getRevenuePerDay(orders)}> + <defs> + <linearGradient + id="colorUv" + x1="0" + y1="0" + x2="0" + y2="1" + > + <stop + offset="5%" + stopColor="#5091abff" + stopOpacity={0.8} + /> + <stop + offset="95%" + stopColor="#5091abff" + stopOpacity={0} + /> + </linearGradient> + </defs> + <XAxis + dataKey="date" + name="Date" + type="number" + scale="time" + domain={[ + addDays(aMonthAgo, 1).getTime(), + new Date().getTime(), + ]} + tickFormatter={dateFormatter} + /> + <YAxis dataKey="total" name="Revenue" unit="鈧�" /> + <CartesianGrid strokeDasharray="3 3" /> + <Tooltip + cursor={{ strokeDasharray: '3 3' }} + formatter={(value) => + new Intl.NumberFormat(undefined, { + style: 'currency', + currency: 'USD', + }).format(value) + } + labelFormatter={(label) => + dateFormatter(label) + } + /> + <Area + type="monotone" + dataKey="total" + stroke="#5091abff" + strokeWidth={2} + fill="url(#colorUv)" + /> + </AreaChart> + </ResponsiveContainer> + </div> + </CardContent> + </Card> + ); +}; + +export default NbChart; -- Gitblit v1.9.1