mirror of
https://gitee.com/wanwujie/sub2api-mobile
synced 2026-04-08 09:10:21 +08:00
feat: refine admin UI and add EAS release workflow
This commit is contained in:
45
src/lib/formatters.ts
Normal file
45
src/lib/formatters.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
export function formatCompactNumber(value: number, digits = 1) {
|
||||
const abs = Math.abs(value);
|
||||
|
||||
if (abs >= 1_000_000_000_000) {
|
||||
return `${(value / 1_000_000_000_000).toFixed(digits).replace(/\.0$/, '')}T`;
|
||||
}
|
||||
|
||||
if (abs >= 1_000_000_000) {
|
||||
return `${(value / 1_000_000_000).toFixed(digits).replace(/\.0$/, '')}B`;
|
||||
}
|
||||
|
||||
if (abs >= 1_000_000) {
|
||||
return `${(value / 1_000_000).toFixed(digits).replace(/\.0$/, '')}M`;
|
||||
}
|
||||
|
||||
if (abs >= 1_000) {
|
||||
return `${(value / 1_000).toFixed(digits).replace(/\.0$/, '')}K`;
|
||||
}
|
||||
|
||||
return `${Math.round(value)}`;
|
||||
}
|
||||
|
||||
export function formatTokenValue(value: number) {
|
||||
return formatCompactNumber(value, 1);
|
||||
}
|
||||
|
||||
export function formatDisplayTime(value?: string | null) {
|
||||
if (!value) {
|
||||
return '--';
|
||||
}
|
||||
|
||||
const date = new Date(value);
|
||||
|
||||
if (Number.isNaN(date.getTime())) {
|
||||
return value;
|
||||
}
|
||||
|
||||
const year = date.getFullYear();
|
||||
const month = `${date.getMonth() + 1}`.padStart(2, '0');
|
||||
const day = `${date.getDate()}`.padStart(2, '0');
|
||||
const hours = `${date.getHours()}`.padStart(2, '0');
|
||||
const minutes = `${date.getMinutes()}`.padStart(2, '0');
|
||||
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
||||
}
|
||||
57
src/lib/performance.ts
Normal file
57
src/lib/performance.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
type PerfMarkName =
|
||||
| 'app_start'
|
||||
| 'config_hydrated'
|
||||
| 'login_interactive'
|
||||
| 'dashboard_interactive'
|
||||
| 'users_interactive'
|
||||
| 'monitor_interactive';
|
||||
|
||||
declare global {
|
||||
var __xSapiPerfStartedAt: number | undefined;
|
||||
var __xSapiPerfMarks: Partial<Record<PerfMarkName, number>> | undefined;
|
||||
}
|
||||
|
||||
function now() {
|
||||
if (typeof globalThis !== 'undefined' && globalThis.performance?.now) {
|
||||
return globalThis.performance.now();
|
||||
}
|
||||
|
||||
return Date.now();
|
||||
}
|
||||
|
||||
function ensureStore() {
|
||||
if (!globalThis.__xSapiPerfMarks) {
|
||||
globalThis.__xSapiPerfMarks = {};
|
||||
}
|
||||
|
||||
return globalThis.__xSapiPerfMarks;
|
||||
}
|
||||
|
||||
export function markAppStart() {
|
||||
if (!globalThis.__xSapiPerfStartedAt) {
|
||||
globalThis.__xSapiPerfStartedAt = now();
|
||||
ensureStore().app_start = globalThis.__xSapiPerfStartedAt;
|
||||
}
|
||||
}
|
||||
|
||||
export function markPerformance(name: PerfMarkName) {
|
||||
ensureStore()[name] = now();
|
||||
|
||||
if (__DEV__) {
|
||||
reportPerformance(name);
|
||||
}
|
||||
}
|
||||
|
||||
export function reportPerformance(name: PerfMarkName) {
|
||||
const startedAt = globalThis.__xSapiPerfStartedAt;
|
||||
const mark = ensureStore()[name];
|
||||
|
||||
if (!startedAt || !mark) {
|
||||
return;
|
||||
}
|
||||
|
||||
const duration = Math.round(mark - startedAt);
|
||||
console.info(`[perf] ${name}: ${duration}ms since app_start`);
|
||||
}
|
||||
|
||||
markAppStart();
|
||||
Reference in New Issue
Block a user