feat: 大量优化和bug修复

This commit is contained in:
2026-05-23 22:23:29 +08:00
parent 92b063c4c4
commit fc71e924e7
39 changed files with 1381 additions and 302 deletions
+103
View File
@@ -0,0 +1,103 @@
// server/utils/userConfig.ts - 用户自定义配置 JSON value 的归一化与合并
import type { Prisma } from "~~/prisma/generated/client";
import type { IUserSettingsUpdateRequest } from "~~/shared/types/settings";
export interface UserConfigValue {
useCustomConfig: boolean;
customApiBase: string | null;
customApiKey: string | null;
customModel: string | null;
customMaxTokens: number | null;
customTemperature: number | null;
}
export const DEFAULT_USER_CONFIG_VALUE: UserConfigValue = {
useCustomConfig: false,
customApiBase: null,
customApiKey: null,
customModel: null,
customMaxTokens: null,
customTemperature: null
};
const isRecord = (value: unknown): value is Record<string, unknown> =>
typeof value === "object" && value !== null && !Array.isArray(value);
const cleanString = (value: unknown): string | null => {
if (typeof value !== "string") return null;
const trimmed = value.trim();
return trimmed.length > 0 ? trimmed : null;
};
const cleanApiKey = (value: unknown): string | null => {
if (typeof value !== "string") return null;
return value.length > 0 ? value : null;
};
const cleanNumber = (value: unknown): number | null =>
typeof value === "number" && Number.isFinite(value) ? value : null;
export const normalizeUserConfigValue = (
value: unknown
): UserConfigValue => {
if (!isRecord(value)) {
return { ...DEFAULT_USER_CONFIG_VALUE };
}
return {
useCustomConfig: value.useCustomConfig === true,
customApiBase: cleanString(value.customApiBase),
customApiKey: cleanApiKey(value.customApiKey),
customModel: cleanString(value.customModel),
customMaxTokens: cleanNumber(value.customMaxTokens),
customTemperature: cleanNumber(value.customTemperature)
};
};
export const mergeUserConfigUpdate = (
current: UserConfigValue,
req: IUserSettingsUpdateRequest
): UserConfigValue => {
const next: UserConfigValue = { ...current };
if (req.useCustomConfig !== undefined) {
next.useCustomConfig = req.useCustomConfig;
}
if (req.customApiBase !== undefined) {
next.customApiBase = cleanString(req.customApiBase);
}
// 空字符串表示不修改已保存的 key,避免用户保存表单时误清空密钥
if (req.customApiKey !== undefined && req.customApiKey !== "") {
next.customApiKey = cleanApiKey(req.customApiKey);
}
if (req.customModel !== undefined) {
next.customModel = cleanString(req.customModel);
}
if (req.customMaxTokens !== undefined) {
next.customMaxTokens = cleanNumber(req.customMaxTokens);
}
if (req.customTemperature !== undefined) {
next.customTemperature = cleanNumber(req.customTemperature);
}
return next;
};
export const hasUserConfigMutation = (req: IUserSettingsUpdateRequest) =>
req.useCustomConfig !== undefined ||
req.customApiBase !== undefined ||
(req.customApiKey !== undefined && req.customApiKey !== "") ||
req.customModel !== undefined ||
req.customMaxTokens !== undefined ||
req.customTemperature !== undefined;
export const toUserConfigJson = (
value: UserConfigValue
): Prisma.InputJsonObject => ({
useCustomConfig: value.useCustomConfig,
customApiBase: value.customApiBase,
customApiKey: value.customApiKey,
customModel: value.customModel,
customMaxTokens: value.customMaxTokens,
customTemperature: value.customTemperature
});