add tricker

This commit is contained in:
songtianlun 2025-06-14 02:55:54 +08:00
parent 65014ef907
commit 7ffe8898d9
5 changed files with 102 additions and 2 deletions

View File

@ -9,6 +9,8 @@ const updateProductSchema = z.object({
endDate: z.string().nullable().optional(),
currentNetValue: z.number().nullable().optional(),
annualRate: z.number().nullable().optional(),
currency: z.string().default("RMB"),
notes: z.string().nullable().optional(),
}).refine((data) => {
// 如果有开始时间、结束时间、本金、当前净值,则不需要年化利率(会自动计算)
// 否则至少需要当前净值或年化利率中的一个
@ -58,6 +60,8 @@ export async function PUT(
principal: Number(body.principal),
depositDate: body.depositDate || null,
endDate: body.endDate || null,
currency: body.currency || "RMB",
notes: body.notes || null,
}
console.log("Processed update request body:", processedBody)
@ -135,6 +139,8 @@ export async function PUT(
endDate: endDate,
currentNetValue: validatedData.currentNetValue || null,
annualRate: validatedData.annualRate || null,
currency: validatedData.currency,
notes: validatedData.notes,
...calculatedValues,
},
})

View File

@ -9,6 +9,8 @@ const createProductSchema = z.object({
endDate: z.string().nullable().optional(),
currentNetValue: z.number().nullable().optional(),
annualRate: z.number().nullable().optional(),
currency: z.string().default("RMB"),
notes: z.string().nullable().optional(),
}).refine((data) => {
// 如果有开始时间、结束时间、本金、当前净值,则不需要年化利率(会自动计算)
// 否则至少需要当前净值或年化利率中的一个
@ -67,6 +69,8 @@ export async function POST(request: NextRequest) {
principal: Number(body.principal),
depositDate: body.depositDate || null,
endDate: body.endDate || null,
currency: body.currency || "RMB",
notes: body.notes || null,
}
console.log("Processed request body:", processedBody)
@ -142,6 +146,8 @@ export async function POST(request: NextRequest) {
endDate: endDate,
currentNetValue: validatedData.currentNetValue || null,
annualRate: validatedData.annualRate || null,
currency: validatedData.currency,
notes: validatedData.notes,
...calculatedValues,
},
})

View File

@ -1,4 +1,5 @@
import type { Metadata } from 'next'
import Script from 'next/script'
import './globals.css'
import { ThemeProvider } from '@/components/theme-provider'
import NextAuthSessionProvider from '@/components/providers/session-provider'
@ -27,6 +28,18 @@ export default function RootLayout({
{children}
</ThemeProvider>
</NextAuthSessionProvider>
{/* 监控脚本 */}
<Script
src="https://rybbit.frytea.com/api/script.js"
data-site-id="8"
strategy="afterInteractive"
/>
<Script
src="https://umami.frytea.com/script.js"
data-website-id="cb16db9a-36bd-4eae-a279-4ff57a89aa19"
strategy="afterInteractive"
/>
</body>
</html>
)

View File

@ -10,6 +10,7 @@ import { Label } from "@/components/ui/label"
import { CalendarIcon, PlusCircle, Trash2, LogIn, Edit, Check, X } from "lucide-react"
import { Calendar } from "@/components/ui/calendar"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { cn } from "@/lib/utils"
import { format } from "date-fns"
import { zhCN } from "date-fns/locale"
@ -28,6 +29,8 @@ interface FinanceProduct {
monthlyProfit: number | null
calculatedAnnualRate: number | null
averageAnnualProfit: number | null
currency: string
notes: string | null
createdAt?: Date
updatedAt?: Date
}
@ -38,6 +41,8 @@ interface NewProduct {
endDate: Date | null
currentNetValue: number | null
annualRate: number | null
currency: string
notes: string | null
}
export default function FinanceCalculator() {
@ -61,6 +66,8 @@ export default function FinanceCalculator() {
endDate: null,
currentNetValue: null,
annualRate: null,
currency: lastProduct ? lastProduct.currency : "RMB",
notes: null,
}
}
@ -131,6 +138,8 @@ export default function FinanceCalculator() {
endDate: newProduct.endDate?.toISOString() || null,
currentNetValue: newProduct.currentNetValue,
annualRate: newProduct.annualRate,
currency: newProduct.currency,
notes: newProduct.notes,
}
console.log('Sending data to API:', requestData)
@ -190,6 +199,8 @@ export default function FinanceCalculator() {
endDate: product.endDate,
currentNetValue: product.currentNetValue,
annualRate: product.annualRate,
currency: product.currency,
notes: product.notes,
})
}
@ -220,6 +231,8 @@ export default function FinanceCalculator() {
endDate: editingProduct.endDate?.toISOString() || null,
currentNetValue: editingProduct.currentNetValue,
annualRate: editingProduct.annualRate,
currency: editingProduct.currency,
notes: editingProduct.notes,
}
console.log('Updating product with data:', requestData)
@ -463,6 +476,35 @@ export default function FinanceCalculator() {
/>
</div>
<div className="space-y-2">
<Label htmlFor="currency"></Label>
<Select value={newProduct.currency} onValueChange={(value) => setNewProduct({ ...newProduct, currency: value })}>
<SelectTrigger>
<SelectValue placeholder="选择货币" />
</SelectTrigger>
<SelectContent>
<SelectItem value="RMB"> (RMB)</SelectItem>
<SelectItem value="USD"> (USD)</SelectItem>
<SelectItem value="EUR"> (EUR)</SelectItem>
<SelectItem value="JPY"> (JPY)</SelectItem>
<SelectItem value="GBP"> (GBP)</SelectItem>
<SelectItem value="HKD"> (HKD)</SelectItem>
<SelectItem value="SGD"> (SGD)</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="notes"></Label>
<Input
id="notes"
type="text"
value={newProduct.notes || ""}
onChange={(e) => setNewProduct({ ...newProduct, notes: e.target.value || null })}
placeholder="输入备注"
/>
</div>
<div className="flex items-end">
<Button onClick={handleAddProduct} className="w-full" disabled={isSubmitting}>
<PlusCircle className="mr-2 h-4 w-4" />
@ -493,6 +535,8 @@ export default function FinanceCalculator() {
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead> (%)</TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
@ -503,7 +547,7 @@ export default function FinanceCalculator() {
<TableBody>
{products.length === 0 ? (
<TableRow>
<TableCell colSpan={10} className="text-center">
<TableCell colSpan={12} className="text-center">
</TableCell>
</TableRow>
@ -596,7 +640,34 @@ export default function FinanceCalculator() {
placeholder="自动计算"
/>
</TableCell>
<TableCell>-</TableCell>
<TableCell>
<Select value={editingProduct.currency} onValueChange={(value) => setEditingProduct({ ...editingProduct, currency: value })}>
<SelectTrigger className="w-24">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="RMB">RMB</SelectItem>
<SelectItem value="USD">USD</SelectItem>
<SelectItem value="EUR">EUR</SelectItem>
<SelectItem value="JPY">JPY</SelectItem>
<SelectItem value="GBP">GBP</SelectItem>
<SelectItem value="HKD">HKD</SelectItem>
<SelectItem value="SGD">SGD</SelectItem>
</SelectContent>
</Select>
</TableCell>
<TableCell>
<Input
type="text"
value={editingProduct.notes || ""}
onChange={(e) => setEditingProduct({
...editingProduct,
notes: e.target.value || null
})}
className="w-32"
placeholder="备注"
/>
</TableCell>
<TableCell>-</TableCell>
<TableCell>-</TableCell>
<TableCell>-</TableCell>
@ -635,6 +706,8 @@ export default function FinanceCalculator() {
{product.currentNetValue !== null ? product.currentNetValue.toFixed(2) : "-"}
</TableCell>
<TableCell>{product.annualRate !== null ? product.annualRate.toFixed(2) : "-"}</TableCell>
<TableCell>{product.currency}</TableCell>
<TableCell>{product.notes}</TableCell>
<TableCell
className={cn(
product.profit && product.profit > 0

View File

@ -71,6 +71,8 @@ model FinanceProduct {
monthlyProfit Float?
calculatedAnnualRate Float?
averageAnnualProfit Float?
currency String @default("RMB")
notes String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt