refactor: 简化模型管理,移除启用/禁用,优化测试和布局
- 移除供应商/模型启用禁用能力,清理DB schema/migration/API/前端 - 供应商测试改为Base URL连通性+/models探测 - 新增POST /api/models/test模型连接测试 - 新增GET /api/providers/options专用供应商选项接口 - 统一工具栏为ModelsToolbar,参考项目管理布局 - 模型弹窗优化:默认能力、响应式3列标签、并排数值 - 前后端正整数校验、供应商下拉loading/error/empty状态 - 表格列宽统一,操作列/名称列固定宽度
This commit is contained in:
@@ -36,7 +36,6 @@ export function createModel(
|
||||
capabilities: JSON.stringify(capabilities),
|
||||
contextLength: request.contextLength ?? null,
|
||||
createdAt: now,
|
||||
enabled: true,
|
||||
id,
|
||||
maxOutputTokens: request.maxOutputTokens ?? null,
|
||||
modelId,
|
||||
@@ -66,32 +65,6 @@ export function deleteModel(raw: Database, id: string): { error: string; status:
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
export function disableModel(raw: Database, id: string): { error: string; status: number } | { model: Model } {
|
||||
const db = wrap(raw);
|
||||
const existing = db.select().from(models).where(eq(models.id, id)).get();
|
||||
if (!existing) return { error: "模型不存在", status: 404 };
|
||||
if (!existing.enabled) return { error: "模型已禁用", status: 409 };
|
||||
|
||||
const now = new Date().toISOString();
|
||||
db.update(models).set({ enabled: false, updatedAt: now }).where(eq(models.id, id)).run();
|
||||
|
||||
const updated = db.select().from(models).where(eq(models.id, id)).get();
|
||||
return { model: toModel(updated!) };
|
||||
}
|
||||
|
||||
export function enableModel(raw: Database, id: string): { error: string; status: number } | { model: Model } {
|
||||
const db = wrap(raw);
|
||||
const existing = db.select().from(models).where(eq(models.id, id)).get();
|
||||
if (!existing) return { error: "模型不存在", status: 404 };
|
||||
if (existing.enabled) return { error: "模型已启用", status: 409 };
|
||||
|
||||
const now = new Date().toISOString();
|
||||
db.update(models).set({ enabled: true, updatedAt: now }).where(eq(models.id, id)).run();
|
||||
|
||||
const updated = db.select().from(models).where(eq(models.id, id)).get();
|
||||
return { model: toModel(updated!) };
|
||||
}
|
||||
|
||||
export function getModel(raw: Database, id: string): { error: string; status: number } | { model: Model } {
|
||||
const db = wrap(raw);
|
||||
const row = db.select().from(models).where(eq(models.id, id)).get();
|
||||
@@ -222,7 +195,6 @@ function toModel(row: typeof models.$inferSelect): Model {
|
||||
capabilities: JSON.parse(row.capabilities) as ModelCapability[],
|
||||
contextLength: row.contextLength,
|
||||
createdAt: row.createdAt,
|
||||
enabled: row.enabled,
|
||||
id: row.id,
|
||||
maxOutputTokens: row.maxOutputTokens,
|
||||
modelId: row.modelId,
|
||||
|
||||
@@ -3,7 +3,7 @@ import type Database from "bun:sqlite";
|
||||
import { and, desc, eq, like, sql } from "drizzle-orm";
|
||||
import { drizzle } from "drizzle-orm/bun-sqlite";
|
||||
|
||||
import type { CreateProviderRequest, Provider, UpdateProviderRequest } from "../../shared/api";
|
||||
import type { CreateProviderRequest, Provider, ProviderOption, UpdateProviderRequest } from "../../shared/api";
|
||||
|
||||
import { providers } from "./schema";
|
||||
|
||||
@@ -30,7 +30,6 @@ export function createProvider(
|
||||
apiKey,
|
||||
baseUrl,
|
||||
createdAt: now,
|
||||
enabled: true,
|
||||
id,
|
||||
name,
|
||||
type: request.type,
|
||||
@@ -58,32 +57,6 @@ export function deleteProvider(raw: Database, id: string): { error: string; stat
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
export function disableProvider(raw: Database, id: string): { error: string; status: number } | { provider: Provider } {
|
||||
const db = wrap(raw);
|
||||
const existing = db.select().from(providers).where(eq(providers.id, id)).get();
|
||||
if (!existing) return { error: "供应商不存在", status: 404 };
|
||||
if (!existing.enabled) return { error: "供应商已禁用", status: 409 };
|
||||
|
||||
const now = new Date().toISOString();
|
||||
db.update(providers).set({ enabled: false, updatedAt: now }).where(eq(providers.id, id)).run();
|
||||
|
||||
const updated = db.select().from(providers).where(eq(providers.id, id)).get();
|
||||
return { provider: toProvider(updated!) };
|
||||
}
|
||||
|
||||
export function enableProvider(raw: Database, id: string): { error: string; status: number } | { provider: Provider } {
|
||||
const db = wrap(raw);
|
||||
const existing = db.select().from(providers).where(eq(providers.id, id)).get();
|
||||
if (!existing) return { error: "供应商不存在", status: 404 };
|
||||
if (existing.enabled) return { error: "供应商已启用", status: 409 };
|
||||
|
||||
const now = new Date().toISOString();
|
||||
db.update(providers).set({ enabled: true, updatedAt: now }).where(eq(providers.id, id)).run();
|
||||
|
||||
const updated = db.select().from(providers).where(eq(providers.id, id)).get();
|
||||
return { provider: toProvider(updated!) };
|
||||
}
|
||||
|
||||
export function getProvider(raw: Database, id: string): { error: string; status: number } | { provider: Provider } {
|
||||
const db = wrap(raw);
|
||||
const row = db.select().from(providers).where(eq(providers.id, id)).get();
|
||||
@@ -92,6 +65,17 @@ export function getProvider(raw: Database, id: string): { error: string; status:
|
||||
return { provider: toProvider(row) };
|
||||
}
|
||||
|
||||
export function listProviderOptions(raw: Database): ProviderOption[] {
|
||||
const db = wrap(raw);
|
||||
const rows = db
|
||||
.select({ id: providers.id, name: providers.name, type: providers.type })
|
||||
.from(providers)
|
||||
.orderBy(desc(providers.createdAt))
|
||||
.all();
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
export function listProviders(
|
||||
raw: Database,
|
||||
options: { keyword?: string; page: number; pageSize: number },
|
||||
@@ -189,7 +173,6 @@ function toProvider(row: typeof providers.$inferSelect): Provider {
|
||||
apiKey: row.apiKey,
|
||||
baseUrl: row.baseUrl,
|
||||
createdAt: row.createdAt,
|
||||
enabled: row.enabled,
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
type: row.type,
|
||||
|
||||
@@ -16,7 +16,6 @@ export const providers = sqliteTable("providers", {
|
||||
apiKey: text("api_key").notNull(),
|
||||
baseUrl: text("base_url").notNull(),
|
||||
createdAt: text("created_at").notNull(),
|
||||
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
||||
id: text("id").primaryKey(),
|
||||
name: text("name").notNull().unique(),
|
||||
type: text("type", { enum: ["anthropic", "openai", "openai-compatible"] })
|
||||
@@ -31,7 +30,6 @@ export const models = sqliteTable(
|
||||
capabilities: text("capabilities").notNull(),
|
||||
contextLength: integer("context_length"),
|
||||
createdAt: text("created_at").notNull(),
|
||||
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
||||
id: text("id").primaryKey(),
|
||||
maxOutputTokens: integer("max_output_tokens"),
|
||||
modelId: text("model_id").notNull(),
|
||||
|
||||
Reference in New Issue
Block a user