diff --git a/src/modules/mileage/DailyReportView.tsx b/src/modules/mileage/DailyReportView.tsx
index 9da7f24..89a6846 100644
--- a/src/modules/mileage/DailyReportView.tsx
+++ b/src/modules/mileage/DailyReportView.tsx
@@ -83,12 +83,132 @@ function dateShift(date: string, days: number): string {
return value.toISOString().slice(0, 10);
}
+function monthShift(month: string, months: number): string {
+ const value = new Date(`${month}-01T00:00:00Z`);
+ value.setUTCMonth(value.getUTCMonth() + months);
+ return value.toISOString().slice(0, 7);
+}
+
+function reportDateLabel(value: string): string {
+ const date = new Date(`${value}T00:00:00Z`);
+ return new Intl.DateTimeFormat('zh-CN', {
+ timeZone: 'UTC',
+ year: 'numeric',
+ month: 'long',
+ day: 'numeric',
+ weekday: 'short',
+ }).format(date).replace(/日(?=周)/, '日 ');
+}
+
function initialReportDate(): string {
const params = new URLSearchParams(window.location.search);
const value = params.get('mileageReportDate');
return /^\d{4}-\d{2}-\d{2}$/.test(value || '') ? value! : shanghaiYmd(-1);
}
+function ReportDatePicker({
+ value,
+ maxDate,
+ onChange,
+}: {
+ value: string;
+ maxDate: string;
+ onChange: (date: string) => void;
+}) {
+ const [open, setOpen] = useState(false);
+ const [month, setMonth] = useState(value.slice(0, 7));
+ const monthStart = new Date(`${month}-01T00:00:00Z`);
+ const firstGridDate = new Date(monthStart);
+ firstGridDate.setUTCDate(1 - monthStart.getUTCDay());
+ const days = Array.from({ length: 42 }, (_, index) => {
+ const date = new Date(firstGridDate);
+ date.setUTCDate(firstGridDate.getUTCDate() + index);
+ return date;
+ });
+ const weekdayLabels = ['日', '一', '二', '三', '四', '五', '六'];
+ const monthLabel = new Intl.DateTimeFormat('zh-CN', {
+ timeZone: 'UTC',
+ year: 'numeric',
+ month: 'long',
+ }).format(monthStart);
+
+ return (
+
+
+
+ {open ? (
+
+
+
+
{monthLabel}
+
+
+
+ {weekdayLabels.map(day => {day})}
+ {days.map(date => {
+ const dateValue = date.toISOString().slice(0, 10);
+ const inMonth = dateValue.slice(0, 7) === month;
+ const selected = dateValue === value;
+ const disabled = dateValue > maxDate;
+ return (
+
+ );
+ })}
+
+
+ ) : null}
+
+ );
+}
+
function updateReportDateInUrl(date: string): void {
const url = new URL(window.location.href);
url.searchParams.set('mileageReportDate', date);
@@ -711,7 +831,7 @@ function roundMileageForDisplay(value: number): number {
}
export default function DailyReportView() {
- const maxDate = shanghaiYmd(-1);
+ const maxDate = shanghaiYmd();
const [selectedDate, setSelectedDate] = useState(initialReportDate);
const [report, setReport] = useState(null);
const [loading, setLoading] = useState(true);
@@ -777,10 +897,12 @@ export default function DailyReportView() {
{fmtDate(report.reportDate)} · {report.source === 'XLSX_IMPORT'
? '人工台账归档'
- : `仪表数据更新至 ${fmtDateTime(report.sourceUpdatedAt)}`}
+ : report.status === 'ARCHIVED'
+ ? `归档于 ${fmtDateTime(report.generatedAt)}`
+ : `仪表数据更新至 ${fmtDateTime(report.sourceUpdatedAt)}`}
- 统计口径:每天 00:30 自动汇总前一日里程
+ 统计周期:自然日 · 汇总频率:每日 00:30 汇总前一日里程
@@ -794,17 +916,16 @@ export default function DailyReportView() {
>
-
+
+