import type Database from "bun:sqlite"; import { desc, eq, like } from "drizzle-orm"; import type { CreateProviderRequest, Provider, ProviderOption, UpdateProviderRequest } from "../../shared/api"; import type { Logger } from "../logger"; import { paginateQuery, wrap } from "./connection"; import { providers } from "./schema"; export function createProvider( raw: Database, request: CreateProviderRequest, logger: Logger, ): { error: string; status: number } | { provider: Provider } { const db = wrap(raw); const name = request.name.trim(); if (!name) return { error: "供应商名称不能为空", status: 400 }; const baseUrl = request.baseUrl.trim(); if (!baseUrl) return { error: "Base URL 不能为空", status: 400 }; const apiKey = request.apiKey.trim(); if (!apiKey) return { error: "API Key 不能为空", status: 400 }; const id = crypto.randomUUID(); const now = new Date().toISOString(); try { db.insert(providers) .values({ apiKey, baseUrl, createdAt: now, id, name, type: request.type, updatedAt: now, }) .run(); } catch (e: unknown) { const msg = e instanceof Error ? e.message : String(e); if (msg.includes("UNIQUE constraint")) { return { error: "供应商名称已存在", status: 409 }; } logger.error({ error: msg, operation: "create", table: "providers" }, "数据库操作失败"); throw e; } const row = db.select().from(providers).where(eq(providers.id, id)).get(); return { provider: toProvider(row!) }; } export function deleteProvider( raw: Database, id: string, _logger: Logger, ): { error: string; status: number } | { success: true } { const db = wrap(raw); const existing = db.select().from(providers).where(eq(providers.id, id)).get(); if (!existing) return { error: "供应商不存在", status: 404 }; db.delete(providers).where(eq(providers.id, id)).run(); return { success: true }; } 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(); if (!row) return { error: "供应商不存在", status: 404 }; 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 }, ): { items: Provider[]; page: number; pageSize: number; total: number } { const conditions = []; if (options.keyword) { const pattern = `%${options.keyword}%`; conditions.push(like(providers.name, pattern)); } return paginateQuery(raw, providers, { conditions, mapRow: toProvider, orderBy: () => desc(providers.createdAt), page: options.page, pageSize: options.pageSize, }); } export function updateProvider( raw: Database, id: string, request: UpdateProviderRequest, logger: Logger, ): { 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 }; const updates: Partial = { updatedAt: new Date().toISOString(), }; const name = request.name?.trim(); if (name === "") return { error: "供应商名称不能为空", status: 400 }; if (name !== undefined && name !== existing.name) { updates.name = name; } const baseUrl = request.baseUrl?.trim(); if (baseUrl === "") return { error: "Base URL 不能为空", status: 400 }; if (baseUrl !== undefined) { updates.baseUrl = baseUrl; } const apiKey = request.apiKey?.trim(); if (apiKey === "") return { error: "API Key 不能为空", status: 400 }; if (apiKey !== undefined) { updates.apiKey = apiKey; } if (request.type !== undefined) { updates.type = request.type; } if (Object.keys(updates).length === 1 && updates.updatedAt) { return { provider: toProvider(existing) }; } try { db.update(providers).set(updates).where(eq(providers.id, id)).run(); } catch (e: unknown) { const msg = e instanceof Error ? e.message : String(e); if (msg.includes("UNIQUE constraint")) { return { error: "供应商名称已存在", status: 409 }; } logger.error({ error: msg, operation: "update", table: "providers" }, "数据库操作失败"); throw e; } const updated = db.select().from(providers).where(eq(providers.id, id)).get(); return { provider: toProvider(updated!) }; } function toProvider(row: typeof providers.$inferSelect): Provider { return { apiKey: row.apiKey, baseUrl: row.baseUrl, createdAt: row.createdAt, id: row.id, name: row.name, type: row.type, updatedAt: row.updatedAt, }; }