Files
openbridge-token-usage-viewer/README.md
MAO Dongyang f2db4bff9d chore: 统一开发服务器端口为 13098
- 更新 .env.example、env.ts、vite.config.ts 默认端口
- 同步更新 sidecar.rs Rust 端口常量
- 更新 README、AGENTS.md 等文档中的端口引用
2026-01-27 11:10:21 +08:00

337 lines
9.5 KiB
Markdown
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.
# Token Usage Viewer
一个基于 **TanStack Start + Bun + Tauri** 的桌面应用,用于监控 Claude API 账户的 Token 配额使用情况。
采用 [OpenBridge Design System](https://github.com/oicl/openbridge-webcomponents) 设计规范,提供专业的航海仪表盘风格界面。
## 功能特点
- **实时配额监控**: 显示最多 4 个账户的 Claude Opus 4.5 (Thinking) 模型配额使用情况
- **可视化仪表盘**: Apple Health 风格的圆环进度指示器,颜色根据剩余配额自动变化
- **智能告警系统**:
- 当配额剩余 < 20% 时显示警告 (Warning)
- 当配额剩余 < 5% 时显示紧急告警 (Alarm)
- **主题切换**: 支持白天/夜间模式切换OpenBridge 设计系统主题
- **自动刷新**: 配额数据每 5 分钟自动刷新
- **倒计时显示**: 显示配额重置剩余时间
- **SSR 支持**: 服务端渲染,首屏即有数据
## 技术栈
### 核心框架
| 层级 | 技术 | 版本 |
|------|------|------|
| 前端框架 | React | 19.2 |
| 路由 | TanStack Router | 1.151 |
| 状态管理 | TanStack Query | 5.90 |
| SSR 框架 | TanStack Start | 1.151 |
| RPC 通信 | ORPC (类型安全契约优先) | 1.13 |
| UI 组件 | OpenBridge Web Components | 0.0.17 |
| 样式 | Tailwind CSS | v4 |
| 桌面壳 | Tauri | v2.9 |
| 运行时 | Bun | 1.3.6 |
### 后端 & 数据
| 技术 | 说明 |
|------|------|
| SQLite | Bun 内置驱动 (bun:sqlite),无需额外安装 |
| Drizzle ORM | 类型安全 ORM支持迁移 |
| Nitro | 服务端框架 (bun preset) |
| Zod | 运行时类型验证 |
### 构建工具
| 技术 | 说明 |
|------|------|
| Vite | 开发服务器 + 构建 |
| Turbo | 任务并行化 |
| Effect | 函数式构建脚本 |
| Biome | 代码格式化 + Lint |
| React Compiler | 自动优化,无需手动 memo |
## 快速开始
### 前置要求
- [Bun](https://bun.sh/) >= 1.0
- [Rust](https://www.rust-lang.org/) (Tauri 桌面应用需要)
### 安装与运行
```bash
# 1. 克隆项目
git clone <your-repo-url>
cd openbridge-token-usage-viewer
# 2. 安装依赖
bun install
# 3. 启动开发服务器
bun run dev:vite # 仅 Web (http://localhost:13098)
bun run dev # Tauri 桌面应用 + Web
```
### 构建
```bash
bun run build:vite # 构建 Web 版本 (输出到 .output/)
bun run build # 构建 Tauri 桌面安装包
```
### 构建产物位置
| 类型 | 路径 |
|------|------|
| **Vite Web 构建** | `.output/` |
| **Sidecar 二进制** | `src-tauri/binaries/app-<target>` |
| **MSI 安装包** | `src-tauri/target/release/bundle/msi/app-desktop_0.1.0_x64_en-US.msi` |
| **NSIS 安装包** | `src-tauri/target/release/bundle/nsis/app-desktop_0.1.0_x64-setup.exe` |
| **macOS DMG** | `src-tauri/target/release/bundle/dmg/app-desktop_0.1.0_aarch64.dmg` |
## 配置
### 环境变量
应用会按以下优先级读取 `TOKEN_USAGE_URL` 配置:
1. **系统环境变量** (最高优先级)
2. **可执行文件同目录的 `.env` 文件**
3. **默认值**: `http://10.0.1.1:8318/usage`
#### 方式 1: 环境变量
```bash
# Windows PowerShell
$env:TOKEN_USAGE_URL = "http://your-server:8318/usage"
.\app-desktop.exe
# Linux/macOS
TOKEN_USAGE_URL=http://your-server:8318/usage ./app-desktop
```
#### 方式 2: 配置文件
在可执行文件同目录创建 `.env` 文件:
```env
TOKEN_USAGE_URL=http://your-server:8318/usage
```
## 常用命令
### 开发
| 命令 | 说明 |
|------|------|
| `bun dev` | 启动 Tauri + Vite 开发服务器 (并行) |
| `bun dev:vite` | 仅启动 Vite 开发服务器 (http://localhost:13098) |
| `bun dev:tauri` | 仅启动 Tauri (需先启动 Vite) |
| `bun db:studio` | 打开 Drizzle Studio 数据库管理界面 |
### 构建
| 命令 | 说明 |
|------|------|
| `bun build` | 完整构建 (Vite → 编译 → Tauri 打包) |
| `bun build:vite` | 仅构建 Web 版本 (输出到 .output/) |
| `bun build:compile` | 编译 Sidecar 二进制 (使用 build.ts) |
| `bun build:tauri` | 构建 Tauri 桌面安装包 |
### 代码质量
| 命令 | 说明 |
|------|------|
| `bun typecheck` | TypeScript 类型检查 |
| `bun fix` | 自动修复格式和 Lint 问题 (Biome) |
### 数据库
| 命令 | 说明 |
|------|------|
| `bun db:init` | 初始化 SQLite 数据库 |
| `bun db:generate` | 从 schema 生成迁移文件 |
| `bun db:migrate` | 执行数据库迁移 |
| `bun db:studio` | 打开 Drizzle Studio |
## 项目结构
```
├── src/
│ ├── components/ # React 组件
│ │ ├── HealthRing.tsx # 圆环进度指示器 (Apple Health 风格)
│ │ ├── TokenUsageDashboard.tsx # 主仪表盘 (告警+主题+圆环)
│ │ ├── Error.tsx # 错误边界回退组件
│ │ └── NotFount.tsx # 404 页面
│ │
│ ├── hooks/ # React Hooks
│ │ ├── useCountdown.ts # 倒计时 Hook (useMemo 优化)
│ │ └── useTheme.ts # OpenBridge 主题切换 Hook
│ │
│ ├── orpc/ # ORPC RPC 层
│ │ ├── contracts/ # 契约定义 (Zod schema)
│ │ │ └── usage.ts # 使用量查询契约
│ │ ├── handlers/ # 服务端处理器
│ │ │ └── usage.ts # 获取配额数据+存储历史
│ │ ├── middlewares/ # ORPC 中间件
│ │ │ └── db.ts # 数据库连接 Provider
│ │ ├── client.ts # 同构客户端 (SSR/CSR 自动切换)
│ │ ├── contract.ts # 契约聚合
│ │ ├── router.ts # 路由组合
│ │ ├── server.ts # 服务端实例
│ │ └── types.ts # 类型导出
│ │
│ ├── routes/ # TanStack Router 文件路由
│ │ ├── __root.tsx # 根布局 (OpenBridge 主题集成)
│ │ ├── index.tsx # 首页 (SSR 预取+自动刷新)
│ │ └── api/rpc.$.ts # ORPC HTTP 端点
│ │
│ ├── db/ # 数据库层
│ │ ├── schema/ # Drizzle Schema
│ │ │ └── usage-history.ts # 使用量历史表
│ │ └── index.ts # 数据库连接 (SQLite WAL)
│ │
│ ├── lib/ # 工具函数
│ ├── env.ts # 环境变量验证 (t3-env)
│ └── router.tsx # 路由配置
├── src-tauri/ # Tauri 桌面应用
│ ├── src/
│ │ ├── lib.rs # Tauri 入口
│ │ └── sidecar.rs # Sidecar 进程管理
│ ├── binaries/ # 编译后的 sidecar 二进制
│ └── tauri.conf.json # Tauri 配置
├── build.ts # 跨平台构建脚本 (Effect 框架)
├── vite.config.ts # Vite 配置
├── drizzle.config.ts # Drizzle ORM 配置
└── .output/ # Vite 构建输出
```
## 架构说明
### ORPC 同构客户端
ORPC 客户端根据运行环境自动选择最优调用方式:
- **SSR (服务端)**: 直接调用 router 处理器,零网络开销
- **CSR (客户端)**: 通过 `/api/rpc` 端点进行 HTTP 调用
```tsx
// 使用 TanStack Query
const { data } = useSuspenseQuery(orpc.usage.getUsage.queryOptions())
```
### Tauri Sidecar
应用采用 Sidecar 架构:
1. **Tauri 壳**: 提供原生窗口和系统集成
2. **Bun 服务端**: 编译为独立可执行文件,处理 SSR 和 API 请求
3. **通信**: Tauri WebView 通过 localhost:13098 与 Sidecar 通信
### 数据流
```
Token API (http://10.0.1.1:8318/usage)
ORPC Handler (usage.ts)
SQLite (data/app.db) ← 历史记录存储
TanStack Query Cache
React Components (TokenUsageDashboard)
```
## 故障排除
### 清理缓存与重置
如果遇到构建问题、端口占用或缓存问题,按以下步骤重置:
#### 1. 结束所有相关进程
```powershell
# Windows PowerShell (管理员)
taskkill /F /IM "app.exe" 2>$null
taskkill /F /IM "app-desktop.exe" 2>$null
taskkill /F /IM "bun.exe" 2>$null
taskkill /F /IM "node.exe" 2>$null
```
```bash
# Linux/macOS
pkill -f "app-desktop" || true
pkill -f "bun" || true
```
#### 2. 清除所有缓存
```bash
# Turbo 缓存
rm -rf .turbo
# Vite 缓存
rm -rf node_modules/.vite
rm -rf node_modules/.cache
# 构建输出
rm -rf .output
# Tauri sidecar binaries
rm -rf src-tauri/binaries/app-*
```
#### 3. 完全清理 (可选,需要重新编译 Rust耗时 2-5 分钟)
```bash
# 清除 Rust 编译缓存
rm -rf src-tauri/target
```
#### 4. 确认端口已释放
```bash
# Windows
netstat -ano | findstr :13098
# Linux/macOS
lsof -i :13098
```
#### 5. 重新构建
```bash
bun run build
```
### 常见问题
#### "An unhandled error happened!" 错误
1. 确保没有其他进程占用端口 13098
2. 尝试完全清理缓存后重新构建
3. 检查 `.env` 文件中的 `TOKEN_USAGE_URL` 配置是否正确
#### 端口被占用 (EADDRINUSE)
```powershell
# 查找占用端口的进程
netstat -ano | findstr :13098
# 结束进程 (替换 PID 为实际进程 ID)
taskkill /F /PID <PID>
```
#### MSI 安装后无法运行
1. 卸载旧版本: 控制面板 → 程序和功能 → 卸载 app-desktop
2. 重新安装新的 MSI
3. 确保安装目录有写入权限
## 许可证
MIT