import { Hono } from "hono"; import { eq } from "drizzle-orm"; import { useDrizzle } from "@/lib/db.js"; import { tariff } from "@/db/schema.js"; import type { HonoEnv } from "@/types/hono.ts"; import type { PriceTier, TariffSlot } from "@/db/tariff-schema.ts"; const app = new Hono(); /** GET /api/tariff — 返回当前生效的电价配置(任何已登录用户) */ app.get("/", async (c) => { const db = useDrizzle(); const [row] = await db.select().from(tariff).where(eq(tariff.isActive, true)).limit(1); if (!row) return c.json(null); return c.json(rowToPayload(row)); }); /** PUT /api/tariff — 更新/初始化电价配置(仅管理员) */ app.put("/", async (c) => { const currentUser = c.get("user"); if (currentUser?.role !== "admin") { return c.json({ error: "Forbidden" }, 403); } type TierPricing = { electricityPrice: number; serviceFee: number }; type TariffBody = { slots: TariffSlot[]; prices: Record; }; let body: TariffBody; try { body = await c.req.json(); } catch { return c.json({ error: "Invalid JSON" }, 400); } const { slots, prices } = body; if (!Array.isArray(slots) || !prices) { return c.json({ error: "Missing slots or prices" }, 400); } const db = useDrizzle(); // 停用旧配置 await db.update(tariff).set({ isActive: false }); const [row] = await db .insert(tariff) .values({ id: crypto.randomUUID(), slots, peakElectricityPrice: fenFromCny(prices.peak?.electricityPrice), peakServiceFee: fenFromCny(prices.peak?.serviceFee), valleyElectricityPrice: fenFromCny(prices.valley?.electricityPrice), valleyServiceFee: fenFromCny(prices.valley?.serviceFee), flatElectricityPrice: fenFromCny(prices.flat?.electricityPrice), flatServiceFee: fenFromCny(prices.flat?.serviceFee), isActive: true, }) .returning(); return c.json(rowToPayload(row)); }); // ── helpers ──────────────────────────────────────────────────────────────── function fenFromCny(cny: number | undefined): number { if (typeof cny !== "number" || isNaN(cny)) return 0; return Math.round(cny * 100); } function rowToPayload(row: typeof tariff.$inferSelect) { return { id: row.id, slots: row.slots as TariffSlot[], prices: { peak: { electricityPrice: row.peakElectricityPrice / 100, serviceFee: row.peakServiceFee / 100, }, valley: { electricityPrice: row.valleyElectricityPrice / 100, serviceFee: row.valleyServiceFee / 100, }, flat: { electricityPrice: row.flatElectricityPrice / 100, serviceFee: row.flatServiceFee / 100, }, }, createdAt: row.createdAt, updatedAt: row.updatedAt, }; } export default app;