-
Notifications
You must be signed in to change notification settings - Fork 1
Configuration
全部配置都走环境变量,没有配置文件、没有构建期注入。
| 变量 | 必填 | 说明 |
|---|---|---|
DEEPSEEK_API_KEY |
否 | DeepSeek API Key(余额查询),在 https://platform.deepseek.com/api_keys 获取 |
VOLC_ACCESS_KEY_ID |
否 | 火山方舟 Access Key ID(管控面 API 签名) |
VOLC_SECRET_KEY |
否 | 火山方舟 Secret Access Key |
ZHIPU_API_KEY |
否 | 智谱开放平台 API Key(资源包/余额),在 https://open.bigmodel.cn/usercenter/apikeys 获取 |
ALIYUN_ACCESS_KEY_ID |
否 | 阿里云 AccessKey ID(BSS 资源包 + Token Plan 组织/座席),在 https://ram.console.aliyun.com/manage/ak 创建 |
ALIYUN_SECRET_KEY |
否 | 阿里云 AccessKey Secret |
ALIYUN_TOKENPLAN_COOKIE |
否 | 百炼控制台 Cookie 中 login_aliyunid_ticket 的值(Token Plan 个人版用量,无需授权) |
GITEE_AI_API_KEY |
否 | 模力方舟(Gitee AI)访问令牌(资源包余额),在 https://ai.gitee.com 生成 |
GITEE_AI_SESSION_COOKIE |
否 | 模力方舟 Web 会话 Cookie(代金券查询;整段含空格,平台面板需填编码值) |
BAIDU_ACCESS_KEY_ID |
否 | 百度智能云千帆 Access Key ID(BCE 签名),在 https://console.bce.baidu.com/iam/#/iam/accesslist 创建 |
BAIDU_SECRET_KEY |
否 | 百度智能云千帆 Secret Access Key(建议子账号 + QianfanServiceReadAccessPolicy 只读) |
OPENROUTER_API_KEY |
否 | OpenRouter 剩余额度与限额,在 https://openrouter.ai/keys 获取 |
KIMI_API_KEY |
否 | Kimi For Coding Token Plan 额度,在 https://platform.moonshot.cn 获取 |
MINIMAX_API_KEY |
否 | MiniMax Token Plan 额度,在 https://platform.minimaxi.com 获取 |
OPENCODE_GO_API_KEY |
否 | OpenCode Go 订阅额度(5 小时/7 天/30 天窗口),在 https://opencode.ai 获取 |
NEWAPI_BASE_URL |
否 | New API 站点地址(自托管,形如 https://ai.example.com/),多站点按 _2 / _3 追加 |
NEWAPI_TOKEN |
否 | New API 系统访问令牌(管理接口鉴权),多站点按 _2 / _3 追加 |
NEWAPI_USER_ID |
否 | 管理接口需要按用户查询时的用户 ID(与 NEWAPI_BASE_URL 同序号配对,选填) |
NEWAPI_LABEL |
否 | 站点别名(与 NEWAPI_BASE_URL 同序号配对,选填) |
SITE_NAME |
否 | 站点名称(导航栏品牌位 + 浏览器标签页标题),默认「LLM 用量监控」 |
SITE_LOGO_URL |
否 | 明亮模式 Logo 图片地址(须 https;浏览器直连,不受 CORS 限制),未配置则只显示文字标题 |
SITE_LOGO_URL_DARK |
否 | 暗黑模式专用 Logo 地址(须 https);未配置则暗黑模式沿用 SITE_LOGO_URL
|
SITE_FAVICON_URL |
否 | 标签页图标地址(须 https),未配置则保留自带的 /favicon.ico
|
REFRESH_INTERVAL_SECONDS |
否 | 前端自动刷新间隔(秒),默认 180,允许 10–3600 |
HOST |
否 | 监听地址,默认 127.0.0.1
|
PORT |
否 | 监听端口,默认 8787
|
所有平台变量都是可选的:配齐哪几家就显示哪几家。
每个凭据变量都支持同序号的 *_LABEL / *_LABEL_N 别名(详见
多账号与别名)。
火山方舟 Access Key 在 https://console.volcengine.com/iam/keymanage 创建; 出于安全考虑建议使用 IAM 子用户并仅授予方舟相关权限。
阿里云 AccessKey 建议使用 RAM 子用户:Token Plan 组织/座席区块需要
AliyunTokenPlanReadOnlyAccess 策略;资源包区块需要费用中心
(bss:QueryResourcePackageInstances)只读权限,可按需分别授权。
个人版用量用会话 Cookie 即可,无需任何授权。
更细的权限与凭据说明见 凭据与多账号。
同一段说明只在一处维护:
| 文件 | 用途 |
|---|---|
.env.example |
主模板:变量最全、说明最详细,也是平台面板填变量时的参考 |
.dev.vars.example |
Cloudflare Workers 版:同集合同顺序,只讲 Workers 专属差异 |
.env |
本机真实值(gitignored、不入库),分组顺序与 .env.example 一致 |
全部变量(含账号别名 *_LABEL)都登记在 server/env-vars.ts 的 SERVER_ENV_VARS 里 ——
那是唯一的事实来源。新增平台时改它,.env.example 与 .dev.vars.example 会被
server/env-vars.test.ts 校对:漏登记会直接测试失败,不会出现「文档写着有、配了却不生效」。
OpenCode Go 的用量接口在 200 响应中为每个窗口附带 status(ok / rate-limited)。
当某窗口被上游限流时,接口报 percent: 100 且 status: "rate-limited" ——
两者语义不同,因此面板会把该状态单独标为「上游限流中」并附说明,而不是只显示 100%。
New API 是自托管网关,同一套服务端可能开启两种计费模式:
- 钱包余额:充值的额度,只减不重置;
- 订阅额度:按周期窗口重置,常见 30 天。
服务端用管理接口返回的配额字段与订阅状态共同判定该账号属于哪一类,并据此把它归到正确的 Tab ——
所以「提交的 Key 到底属于哪种模式」不需要你手工声明。
两种都开启时(mode: 'both')以订阅为主读数、钱包作次要读数,
弹窗里给出站点的扣费偏好(subscription_first / wallet_first)。
站点地址由你填写,因此卡片上的「控制台 ↗」({baseUrl}/dashboard)与
「可用模型 ↗」({baseUrl}/pricing)都按该地址拼接;多站点时不给出卡片级链接
(一个链接指不了两个站点),改在各自弹窗内提供。
平台面板(Vercel / EdgeOne Makers / Cloudflare Workers)原样保存变量值、不做变量展开; 本地
.env/.dev.vars会展开$。含$的值(如百炼 ticket)在本地必须转义。
站点名 / Logo / favicon / 刷新间隔四项都用环境变量配置。
为什么不做成前端构建期变量(VITE_*):同一份构建产物要跑在
Bun / Cloudflare Workers / EdgeOne / Vercel 四种宿主上,而部署流程让用户在平台面板里配的
就是运行时变量 —— 用构建期变量会把「换个站点名」变成「重新构建并重传产物」。
服务端在启动时读取这些变量并随 /api/status 下发,因此改完重启服务即生效,无需重新构建前端。
| 变量 | 默认值 | 作用 |
|---|---|---|
SITE_NAME |
LLM 用量监控 |
导航栏品牌位 + 标签页标题;留空则只显示 Logo |
SITE_LOGO_URL |
无(只显示文字) | 明亮模式的 Logo(也是暗黑模式的回落值) |
SITE_LOGO_URL_DARK |
沿用 SITE_LOGO_URL
|
暗黑模式专用的 Logo |
SITE_FAVICON_URL |
自带的 /favicon.ico
|
浏览器标签页图标 |
REFRESH_INTERVAL_SECONDS |
180 |
前端自动刷新间隔(秒),允许 10–3600 |
-
可以留空:
SITE_NAME=(显式留空)表示品牌位只显示 Logo —— Logo 本身已是「图形 + 品牌名」的完整字标时很常见,再并一个站点名会读成两个品牌名。 注意「留空」与「不配」不同:不配SITE_NAME会显示默认名LLM 用量监控; 留空才只显示 Logo。留空时浏览器标签页标题回落到默认名(空标题在标签栏里是一片空白)。 - 过长会截断:品牌位用省略号截断,不会把导航顶出视口。
-
可配两套图:
SITE_LOGO_URL(明亮)与SITE_LOGO_URL_DARK(暗黑)。 深色字标落在深色导航上会糊成一片,所以「字标型」Logo 两套都配才完整。 切换主题时即时换图(另一套在首屏已预热,不会出现加载空档让站点名左右抖动)。 - 回落是有序的:当前主题那套没配或加载失败 → 自动换另一套;两套都不可用才退回纯文字。 「暗色图忘了配」不会让品牌位空掉,只是对比度差一些(更容易被发现并补上)。
-
不受 CORS 限制:Logo 与 favicon 由浏览器通过
<img>/new Image()直接加载, 服务端既不代理也不读像素 —— 需要crossorigin的是 canvas 读回,不是显示。跨域图床可以直接用。 - 必须 https:http 资源在 https 页面上会被按混合内容拦掉,表现为「配了却一直看不到」。 用内网图床时尤其容易踩。
- 加载失败会自动降级:Logo 先换另一套、仍不行才退回纯文字品牌位;favicon 失败保留自带图标。 都不留破图,地址写错不会把页面搞坏,只是看不到自定义效果。
Logo 采用高度固定、宽度自适应,高度与宽度上限按断点收缩:
| 断点 | Logo 高度 | 宽度上限 | 品牌位与站点名的间距 |
|---|---|---|---|
| 桌面 | 24px | 132px | 12px |
| 平板 | 24px | 108px | 12px |
| 手机 | 20px | 72px | 8px |
高度取 24px 而不是更大,是因为常见的 Logo 是「图形 + 品牌名」的横版字标,
字标部分通常只占画布高度的 ~70%:盒子给 28px 时字标实际会画到约 19px,
比 18px 的站点名还大,两个词标叠在一起就分不出主次;给 24px 时字标约 16.6px,与站点名齐平。
宽度上限反过来必须留够(手机 72px ≈ 20px × 3.6),否则 object-fit: contain 会把整幅
画布按宽度压扁,字标反而更小。见 src/assets/layout.css 第 5 节。
导航在 ≤1199px 时会把「更新于 / 下次刷新」从导航行下移到内容区顶部(手机原本就这么做): 实测 768 视口下导航行已无余量,站点名会被挤压成「AI…」。时间文案晚一步出现,站点名才完整。
刷新间隔做了 10–3600 秒钳制:填 0 或非数字回落成默认 180 秒
(setInterval(fn, 0) 会退化成尽可能快的忙循环,等于把「自动刷新」变成打爆上游请求),
超出范围钳到最近的边界。页面隐藏时自动暂停不受该变量影响。