feat: 前端组件准备

This commit is contained in:
2026-05-22 15:02:31 +08:00
parent 397ccdca13
commit 5e05bf4f63
62 changed files with 6903 additions and 878 deletions
+86
View File
@@ -0,0 +1,86 @@
// server/utils/env.ts - 服务端环境变量读取与规范化
/**
* 允许 `.env` 里保留类似 Python 旧项目的写法:
* `OPENAI_API_BASE=https://example.com/v1 # 注释`
* Nuxt/Node 读到的是整行值,所以这里主动裁掉行尾注释
*/
const stripInlineComment = (value: string) => {
return value.replace(/\s+#.*$/u, "").trim();
};
/**
* 读取字符串环境变量
*
* - 空字符串视为未配置,回退到 fallback
* - 返回值统一去掉行尾注释,避免 baseURL、model 之类配置带上注释文本
*/
const readString = (key: string, fallback = "") => {
const value = process.env[key];
if (value === undefined || value === null || value.trim() === "") {
return fallback;
}
return stripInlineComment(value);
};
/** 读取可选字符串;空值统一转成 undefined,方便后续判断是否启用某能力 */
const readOptionalString = (key: string) => {
const value = readString(key);
return value || undefined;
};
/** 兼容常见布尔写法,便于 Docker、面板和手写 `.env` 配置 */
const readBoolean = (key: string, fallback: boolean) => {
const value = readString(key);
if (!value) return fallback;
return ["1", "true", "yes", "on"].includes(value.toLowerCase());
};
/** 读取整数配置;非法值不抛错,使用默认值保证服务能启动 */
const readInteger = (key: string, fallback: number) => {
const value = Number.parseInt(readString(key), 10);
return Number.isFinite(value) ? value : fallback;
};
/** 读取小数配置,主要用于 OpenAI temperature */
const readNumber = (key: string, fallback: number) => {
const value = Number.parseFloat(readString(key));
return Number.isFinite(value) ? value : fallback;
};
/** OpenAI 兼容接口 baseURL 统一不带结尾斜杠,后续再拼 `/chat/completions` */
const normalizeBaseUrl = (url: string) => {
return url.replace(/\/+$/u, "");
};
/**
* 服务端环境配置的唯一出口
*
* 业务代码不要直接读 `process.env`,这样可以把默认值、格式修正和安全边界
* 都收敛在这里,后续迁移部署平台时也只需要检查这个文件
*/
export const serverEnv = {
/** OpenAI 或兼容中转平台 API Key,仅服务端使用,不能返回给前端 */
openAiApiKey: readString("OPENAI_API_KEY"),
/** OpenAI 兼容 API base,例如 `https://api.openai.com/v1` */
openAiApiBase: normalizeBaseUrl(
readString("OPENAI_API_BASE", "https://api.openai.com/v1")
),
/** Chat Completions 使用的模型名 */
openAiModel: readString("OPENAI_MODEL", "gpt-3.5-turbo"),
/** 单次回答最大 token 数,沿用旧 Python 服务的配置语义 */
maxTokens: readInteger("MAX_TOKENS", 500),
/** 模型采样温度,越低越稳定 */
temperature: readNumber("TEMPERATURE", 0.7),
/** 可选访问令牌;配置后 API 需要 header 或 query 携带 token */
accessToken: readOptionalString("ACCESS_TOKEN"),
/** 是否启用内存缓存 */
enableCache: readBoolean("ENABLE_CACHE", true),
/** 缓存过期时间,单位秒 */
cacheExpiration: readInteger("CACHE_EXPIRATION", 86_400),
/** 预留日志级别配置,目前日志工具只负责安全输出 */
logLevel: readString("LOG_LEVEL", "INFO"),
/** 单行 SSE data 的最大字节数,用于防止异常流无限堆内存 */
maxSseLineBytes: readInteger("OPENAI_STREAM_MAX_SSE_LINE_BYTES", 1_048_576)
};