fix: align asset customer data with OneOS and refine statistics display
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
@@ -34,7 +34,7 @@ import {
|
||||
deriveInventoryView,
|
||||
deriveModalVehicleView,
|
||||
formatLocalDateTime,
|
||||
getWeeklyFlowRange,
|
||||
getRecentFlowRange,
|
||||
selectFlowDetails,
|
||||
type VehicleModalSelection,
|
||||
type FlowSelection,
|
||||
@@ -84,10 +84,10 @@ export default function AssetsModule() {
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [lastUpdate, setLastUpdate] = useState<string>(() => formatLocalDateTime(new Date()));
|
||||
const [modalLoading, setModalLoading] = useState(false);
|
||||
const [flowRange, setFlowRange] = useState(() => getWeeklyFlowRange());
|
||||
const [flowRange, setFlowRange] = useState(() => getRecentFlowRange());
|
||||
const [flowStats, setFlowStats] = useState<FlowStatsResponse | null>(null);
|
||||
const [flowLoading, setFlowLoading] = useState(false);
|
||||
const [flowDailyExpanded, setFlowDailyExpanded] = useState(false);
|
||||
const [flowDailyExpanded, setFlowDailyExpanded] = useState(true);
|
||||
const [selectedFlow, setSelectedFlow] = useState<FlowSelection | null>(null);
|
||||
|
||||
// Dept/Region/Customer data
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import React from 'react';
|
||||
import { ChevronDown, Filter, Loader2, Search } from 'lucide-react';
|
||||
import { motion } from 'motion/react';
|
||||
import type { SubjectOption } from '../api';
|
||||
@@ -30,42 +30,6 @@ const TABS = [
|
||||
{ id: 'customer', label: '按客户' },
|
||||
];
|
||||
|
||||
function MarqueeBanner() {
|
||||
const trackRef = useRef<HTMLDivElement>(null);
|
||||
const innerRef = useRef<HTMLDivElement>(null);
|
||||
const [overflow, setOverflow] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const check = () => {
|
||||
if (!trackRef.current || !innerRef.current) return;
|
||||
setOverflow(innerRef.current.scrollWidth > trackRef.current.clientWidth);
|
||||
};
|
||||
check();
|
||||
const ro = new ResizeObserver(check);
|
||||
ro.observe(trackRef.current!);
|
||||
return () => ro.disconnect();
|
||||
}, []);
|
||||
|
||||
const text = '车辆资产已于 2026 年 6 月 18 日完成“运营状态”与“业务关联”校验';
|
||||
|
||||
return (
|
||||
<div className="relative -mx-6 mb-4 bg-green-50 border-y border-green-200">
|
||||
<div ref={trackRef} className="overflow-hidden">
|
||||
<div className={`flex w-max py-2 ${overflow ? 'animate-marquee' : 'w-full justify-center'}`}>
|
||||
<span ref={innerRef} className="inline-block whitespace-nowrap px-6 text-xs text-green-700 font-medium">
|
||||
{text}
|
||||
</span>
|
||||
{overflow && (
|
||||
<span className="inline-block whitespace-nowrap px-6 text-xs text-green-700 font-medium">
|
||||
{text}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function AssetsHeader({
|
||||
activeTab,
|
||||
setActiveTab,
|
||||
@@ -246,16 +210,16 @@ export function AssetsHeader({
|
||||
))}
|
||||
</div>
|
||||
{/* Status row */}
|
||||
<div className="flex items-center justify-center gap-4 py-1.5 text-[10px] text-gray-400">
|
||||
<div className="flex flex-wrap items-center justify-center gap-x-1 gap-y-0.5 px-3 py-1.5 text-[10px] text-gray-400">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="w-1 h-1 rounded-full bg-blue-400 inline-block" />
|
||||
最后更新: {lastUpdate}
|
||||
数据更新时间:{lastUpdate.slice(0, 16)}
|
||||
</div>
|
||||
<span aria-hidden="true">|</span>
|
||||
<span className="whitespace-nowrap">运维台账每日统计口径:当日17:00</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* OneOS 迁移提示滚动条 */}
|
||||
<MarqueeBanner />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useRef, useState } from 'react';
|
||||
import { ArrowRight, CalendarDays, Check, ChevronDown, ChevronLeft, ChevronRight, X } from 'lucide-react';
|
||||
import { getWeeklyFlowRange, type DateRange } from '../../model';
|
||||
import { getRecentFlowRange, getWeeklyFlowRange, type DateRange } from '../../model';
|
||||
|
||||
const weekdays = ['一', '二', '三', '四', '五', '六', '日'];
|
||||
const ymd = (date: Date) => `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
||||
@@ -25,7 +25,7 @@ export function FlowDateRangePicker({ value, onChange }: { value: DateRange; onC
|
||||
{ label: '今天', range: { start: today, end: today } },
|
||||
{ label: '昨天', range: { start: ymd(shiftDay(new Date(), -1)), end: ymd(shiftDay(new Date(), -1)) } },
|
||||
{ label: '业务周', range: getWeeklyFlowRange() },
|
||||
{ label: '近 7 天', range: { start: ymd(shiftDay(new Date(), -6)), end: today } },
|
||||
{ label: '近 7 天', range: getRecentFlowRange() },
|
||||
{ label: '近 30 天', range: { start: ymd(shiftDay(new Date(), -29)), end: today } },
|
||||
];
|
||||
const open = () => {
|
||||
|
||||
@@ -86,7 +86,7 @@ export function FlowStatisticsCard({
|
||||
{flowLoading && (
|
||||
<div className="rounded-xl bg-slate-50 px-3 py-4 text-center text-[11px] font-bold text-slate-400">正在加载交还车统计...</div>
|
||||
)}
|
||||
{!flowLoading && flowStats?.daily.map((day) => (
|
||||
{!flowLoading && flowStats?.daily.slice().sort((a, b) => b.date.localeCompare(a.date)).map((day) => (
|
||||
<div key={day.date} className="rounded-2xl border border-slate-100 bg-white px-3 py-3 shadow-sm">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="text-[11px] font-black text-slate-400">{day.date}</div>
|
||||
|
||||
@@ -126,6 +126,13 @@ function addDays(date: Date, days: number): Date {
|
||||
}
|
||||
|
||||
// 资产流转周报按周六至周五统计;周末查看时仍停留在刚结束的周五。
|
||||
export function getRecentFlowRange(referenceDate = new Date()): DateRange {
|
||||
return {
|
||||
start: formatLocalDate(addDays(referenceDate, -6)),
|
||||
end: formatLocalDate(referenceDate),
|
||||
};
|
||||
}
|
||||
|
||||
export function getWeeklyFlowRange(referenceDate = new Date()): DateRange {
|
||||
const day = referenceDate.getDay();
|
||||
const end = day === 6
|
||||
|
||||
Reference in New Issue
Block a user