feat(db): 新增 exchange_rates 汇率表,支持联合主键与基础交叉汇率数据
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
'use server';
|
||||
|
||||
import { db } from '@/db';
|
||||
import { exchangeRates } from '@/db/schema';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { z } from 'zod';
|
||||
|
||||
const updateExchangeRateSchema = z.object({
|
||||
from: z.string().min(1).max(10),
|
||||
to: z.string().min(1).max(10),
|
||||
rate: z.string().min(1),
|
||||
});
|
||||
|
||||
export async function updateExchangeRate(
|
||||
from: string,
|
||||
to: string,
|
||||
rate: string,
|
||||
) {
|
||||
const validation = updateExchangeRateSchema.safeParse({ from, to, rate });
|
||||
if (!validation.success) {
|
||||
return { success: false, error: 'Invalid input' };
|
||||
}
|
||||
|
||||
try {
|
||||
await db
|
||||
.insert(exchangeRates)
|
||||
.values({
|
||||
fromCurrency: validation.data.from.toUpperCase(),
|
||||
toCurrency: validation.data.to.toUpperCase(),
|
||||
rate: validation.data.rate,
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: [exchangeRates.fromCurrency, exchangeRates.toCurrency],
|
||||
set: {
|
||||
rate: validation.data.rate,
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
} catch (error: unknown) {
|
||||
if (
|
||||
error &&
|
||||
typeof error === 'object' &&
|
||||
'code' in error &&
|
||||
(error as { code: string }).code === '23505'
|
||||
) {
|
||||
return { success: false, error: 'Failed to update exchange rate' };
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getExchangeRate(from: string, to: string) {
|
||||
const result = await db
|
||||
.select()
|
||||
.from(exchangeRates)
|
||||
.where(
|
||||
eq(exchangeRates.fromCurrency, from.toUpperCase()),
|
||||
)
|
||||
.execute();
|
||||
|
||||
return result[0] || null;
|
||||
}
|
||||
|
||||
export async function getAllExchangeRates() {
|
||||
return db.select().from(exchangeRates).execute();
|
||||
}
|
||||
+12
-1
@@ -1,4 +1,4 @@
|
||||
import { pgTable, uuid, varchar, timestamp, pgEnum, numeric } from "drizzle-orm/pg-core";
|
||||
import { pgTable, uuid, varchar, timestamp, pgEnum, numeric, uniqueIndex } from "drizzle-orm/pg-core";
|
||||
|
||||
export const users = pgTable("users", {
|
||||
id: uuid("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
|
||||
@@ -51,3 +51,14 @@ export const transactions = pgTable("transactions", {
|
||||
createdAt: timestamp("created_at", { withTimezone: true, mode: "date" })
|
||||
.defaultNow(),
|
||||
});
|
||||
|
||||
export const exchangeRates = pgTable("exchange_rates", {
|
||||
id: uuid("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
|
||||
fromCurrency: varchar("from_currency", { length: 10 }).notNull(),
|
||||
toCurrency: varchar("to_currency", { length: 10 }).notNull(),
|
||||
rate: numeric("rate", { precision: 20, scale: 8 }).notNull(),
|
||||
updatedAt: timestamp("updated_at", { withTimezone: true, mode: "date" })
|
||||
.defaultNow(),
|
||||
}, (table) => [
|
||||
uniqueIndex("currency_pair_idx").on(table.fromCurrency, table.toCurrency),
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user