Files
lotteryAdmin/src/lib/admin-datetime.ts
kang 24fd7c10bd feat(settlement, admin): introduce new types and functions for downline share and settlement period hints
Added new types for downline share breakdown and settlement period open hints to enhance the agent settlement API. Updated the admin console components to support these new features, improving the user experience with better data presentation and interaction. Additionally, refined the date range field to accommodate new calendar markers and hints, ensuring a more intuitive interface for managing settlement periods.
2026-06-12 16:01:42 +08:00

166 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { AdminApiLocale } from "@/lib/admin-locale";
function formatParts(date: Date, timeZone?: string): string {
const parts = new Intl.DateTimeFormat("en-CA", {
timeZone,
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hourCycle: "h23",
}).formatToParts(date);
const map = new Map(parts.map((part) => [part.type, part.value]));
const year = map.get("year") ?? "0000";
const month = map.get("month") ?? "00";
const day = map.get("day") ?? "00";
const hour = map.get("hour") ?? "00";
const minute = map.get("minute") ?? "00";
const second = map.get("second") ?? "00";
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
}
const WEEKDAY_KEYS = [
"sunday",
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
] as const;
export type AdminWeekdayKey = (typeof WEEKDAY_KEYS)[number];
export function adminWeekdayKeyForDate(date: Date = new Date()): AdminWeekdayKey {
return WEEKDAY_KEYS[date.getDay()] ?? "sunday";
}
/**
* 仪表盘顶栏日期:数字日期 + i18n 星期(避免 Intl 在 ne 等语言下回退到系统中文)。
*/
export function formatAdminCalendarToday(locale: AdminApiLocale, weekdayLabel: string): string {
const d = new Date();
const y = d.getFullYear();
const m = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
const datePart = locale === "en" ? `${m}/${day}/${y}` : `${y}-${m}-${day}`;
return `${datePart} ${weekdayLabel}`;
}
const NAIVE_SCHEDULE_CLOCK_RE =
/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/;
/** 浏览器本地时区短标签(如 CST、GMT+8用于界面说明。 */
export function getAdminBrowserTimeZoneLabel(date = new Date()): string {
try {
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const parts = new Intl.DateTimeFormat(undefined, {
timeZone,
timeZoneName: "short",
}).formatToParts(date);
return parts.find((part) => part.type === "timeZoneName")?.value ?? timeZone;
} catch {
return "Local";
}
}
/**
* 将接口 ISO 8601 时间转为本地时区的 `YYYY-MM-DD HH:mm:ss`(表单预填、期号展示)。
*/
export function isoToAdminLocalScheduleValue(
iso: string | null | undefined,
): string {
if (iso == null || iso === "") {
return "";
}
const ms = Date.parse(iso);
if (Number.isNaN(ms)) {
return "";
}
return formatParts(new Date(ms));
}
/**
* 将本地时区下的计划时刻转为指定排期时区(默认 UTC的 naive `YYYY-MM-DD HH:mm:ss`,供创建/编辑期号 API。
*/
export function adminLocalScheduleValueToTimezoneNaive(
clock: string,
scheduleTimezone = "UTC",
): string {
const trimmed = clock.trim();
if (trimmed === "") {
return "";
}
const match = NAIVE_SCHEDULE_CLOCK_RE.exec(trimmed);
if (!match) {
return trimmed;
}
const [, y, mo, d, h, mi, s] = match;
const localMs = new Date(
Number(y),
Number(mo) - 1,
Number(d),
Number(h),
Number(mi),
Number(s),
).getTime();
if (Number.isNaN(localMs)) {
return trimmed;
}
try {
return formatParts(new Date(localMs), scheduleTimezone);
} catch {
return trimmed;
}
}
/**
* 将接口返回的 ISO 时间串格式化为浏览器本地时区下的 `YYYY-MM-DD HH:mm:ss`。
*/
export function formatAdminInstant(
iso: string | null | undefined,
options: {
locale: AdminApiLocale;
},
): string {
void options;
if (iso == null || iso === "") {
return "—";
}
const ms = Date.parse(iso);
if (Number.isNaN(ms)) {
return "—";
}
return formatParts(new Date(ms));
}
/**
* 将接口返回的 ISO 时间串格式化到指定时区,便于并列展示多个地区的时间。
*/
export function formatAdminInstantInTimeZone(
iso: string | null | undefined,
options: {
locale: AdminApiLocale;
timeZone: string;
},
): string {
void options.locale;
if (iso == null || iso === "") {
return "—";
}
const ms = Date.parse(iso);
if (Number.isNaN(ms)) {
return "—";
}
try {
return formatParts(new Date(ms), options.timeZone);
} catch {
return formatParts(new Date(ms));
}
}