feat(workbench): expand SCADA monitoring and investigation presentation
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import { formatDateTime, formatTime } from "@/shared/utils/date-time";
|
||||
|
||||
const zonedTime = /(?<![\w/+:.-])(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?)(Z|[+-]\d{2}:\d{2})(?![\w:+/-])/g;
|
||||
const utcMarker = String.raw`(?:Z|(?:[((]\s*)?UTC(?:\s*\+?0(?::00)?)?(?:\s*[))])?)(?![\w:+/-])`;
|
||||
const utcRange = new RegExp(String.raw`(?<![\w/+:.-])(?:(\d{4}-\d{2}-\d{2})[T ])?(\d{2}:\d{2})\s*[–—~至-]\s*(\d{2}:\d{2})\s*${utcMarker}`, "g");
|
||||
const utcPoint = new RegExp(String.raw`(?<![\w/+:.-])(?:(\d{4}-\d{2}-\d{2})[T ])?(\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?)\s*${utcMarker}`, "g");
|
||||
|
||||
function parseTime(day: string, clock: string, zone = "Z"): number | null {
|
||||
const date = new Date(`${day}T00:00:00Z`);
|
||||
const [hours, minutes, seconds = "0"] = clock.split(":");
|
||||
if (!Number.isFinite(date.getTime()) || date.toISOString().slice(0, 10) !== day
|
||||
|| Number(hours) > 23 || Number(minutes) > 59 || Number(seconds) >= 60) return null;
|
||||
const value = Date.parse(`${day}T${clock}${zone}`);
|
||||
return Number.isFinite(value) ? value : null;
|
||||
}
|
||||
|
||||
/** Display historical report prose without changing stored facts, IDs, URLs or code. */
|
||||
export function formatDisplayText(text: string | null | undefined): string {
|
||||
if (!text) return text ?? "";
|
||||
return text.split(/(https?:\/\/\S+|tjwater:\/\/\S+|`[^`]*`)/g).map((part, index) => {
|
||||
if (index % 2) return part;
|
||||
return part.replace(utcRange, (original, day: string | undefined, start: string, end: string) => {
|
||||
const startAt = parseTime(day ?? "2000-01-01", start);
|
||||
let endAt = parseTime(day ?? "2000-01-01", end);
|
||||
if (startAt === null || endAt === null) return original;
|
||||
if (endAt < startAt) endAt += 24 * 60 * 60_000;
|
||||
const dateOptions = { year: "numeric", month: "numeric", day: "numeric" } as const;
|
||||
const crossesDay = formatDateTime(startAt, dateOptions) !== formatDateTime(endAt, dateOptions);
|
||||
const startLabel = day ? formatDateTime(startAt, { ...dateOptions, hour: "2-digit", minute: "2-digit" }) : formatTime(startAt);
|
||||
const endLabel = crossesDay && day
|
||||
? formatDateTime(endAt, { ...dateOptions, hour: "2-digit", minute: "2-digit" })
|
||||
: `${crossesDay ? "次日 " : ""}${formatTime(endAt)}`;
|
||||
return `${startLabel}–${endLabel}(UTC+8)`;
|
||||
}).replace(zonedTime, (original, day: string, clock: string, zone: string) => {
|
||||
const value = parseTime(day, clock, zone);
|
||||
return value === null ? original : `${formatDateTime(value)}(UTC+8)`;
|
||||
}).replace(utcPoint, (original, day: string | undefined, clock: string) => {
|
||||
const value = parseTime(day ?? "2000-01-01", clock);
|
||||
if (value === null) return original;
|
||||
return `${day ? formatDateTime(value) : formatTime(value)}(UTC+8)`;
|
||||
});
|
||||
}).join("");
|
||||
}
|
||||
Reference in New Issue
Block a user