- Electron + React + TypeScript 架构 - 三栏布局: Sidebar | ChatPanel | DetailPanel - 9 个内置工具 (文件系统/网络/记忆/命令) - SQLite 持久化 (better-sqlite3) - MUI 暗色/亮色主题系统 - Agent Loop ReAct 状态机引擎 - DeepSeek / Agnes AI / Ollama Provider 适配器 - MCP 协议集成 - 系统托盘 + 全局快捷键 - Tailwind CSS v4 + Tailwind Merge - 修复: Sidebar 缺失 TextField 导入导致黑屏
59 lines
2.0 KiB
TypeScript
59 lines
2.0 KiB
TypeScript
/**
|
||
* 格式化工具函数
|
||
*
|
||
* 日期格式化使用 date-fns(成熟第三方库,禁止自写)。
|
||
* Token 数、文件大小等简单格式化为 < 20 行纯函数,允许自写。
|
||
*
|
||
* @see standard/开发规范.md — 第一铁律
|
||
*/
|
||
|
||
import { formatDistanceToNow, format } from 'date-fns';
|
||
import { zhCN } from 'date-fns/locale';
|
||
|
||
// ===== 日期格式化(使用 date-fns)=====
|
||
|
||
/** 相对时间(如 "3 分钟前"、"昨天") */
|
||
export function formatRelativeTime(timestamp: number): string {
|
||
return formatDistanceToNow(new Date(timestamp), { addSuffix: true, locale: zhCN });
|
||
}
|
||
|
||
/** 短时间格式(如 "14:30") */
|
||
export function formatTime(timestamp: number): string {
|
||
return format(new Date(timestamp), 'HH:mm');
|
||
}
|
||
|
||
// ===== Token 格式化(< 20 行纯函数,允许自写)=====
|
||
|
||
export function formatTokens(count: number): string {
|
||
if (count < 1000) return String(count);
|
||
if (count < 10000) return `${(count / 1000).toFixed(1)}K`;
|
||
if (count < 1000000) return `${Math.round(count / 1000)}K`;
|
||
return `${(count / 1000000).toFixed(1)}M`;
|
||
}
|
||
|
||
// ===== 文件大小格式化(< 20 行纯函数,允许自写)=====
|
||
|
||
export function formatFileSize(bytes: number): string {
|
||
if (bytes < 1024) return `${bytes} B`;
|
||
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
||
if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
||
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
|
||
}
|
||
|
||
// ===== 耗时格式化(< 20 行纯函数,允许自写)=====
|
||
|
||
export function formatDuration(ms: number): string {
|
||
if (ms < 1000) return `${ms}ms`;
|
||
if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
|
||
const minutes = Math.floor(ms / 60000);
|
||
const seconds = Math.round((ms % 60000) / 1000);
|
||
return `${minutes}m${seconds}s`;
|
||
}
|
||
|
||
// ===== 截断文本(< 20 行纯函数,允许自写)=====
|
||
|
||
export function truncate(text: string, maxLength: number): string {
|
||
if (text.length <= maxLength) return text;
|
||
return text.slice(0, maxLength - 1) + '…';
|
||
}
|