"use client" import { zodResolver } from "@hookform/resolvers/zod" import { useState } from "react" import { useForm } from "react-hook-form" import { toast } from "sonner" import { z } from "zod" import { getDeduction } from "@/actions/cust" import { Button } from "@/components/ui/button" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { Field, FieldError, FieldLabel } from "@/components/ui/field" import { Input } from "@/components/ui/input" import type { Cust } from "@/models/cust" const Schema = z.object({ deduction: z .string() .min(1, "请输入余额") .refine(val => !Number.isNaN(Number(val)), "请输入有效的数字") .refine(val => Number(val) >= 0, "余额不能为负数"), }) type FormValues = z.infer interface UpdateDeductionDialogProps { open: boolean onOpenChange: (open: boolean) => void currentUser: Cust | null onSuccess: () => void } export function DeductionDialog({ open, onOpenChange, currentUser, onSuccess, }: UpdateDeductionDialogProps) { const [isLoading, setIsLoading] = useState(false) const { register, handleSubmit, reset, setValue, formState: { errors }, } = useForm({ resolver: zodResolver(Schema), defaultValues: { deduction: "", }, }) const onSubmit = async (data: FormValues) => { if (!currentUser) return setIsLoading(true) try { const result = await getDeduction({ user_id: currentUser.id, amount: data.deduction, }) if (result.success) { toast.success("扣款成功") onOpenChange(false) reset() onSuccess() } else { toast.error(result.message || "扣款失败") } } catch (error) { const message = error instanceof Error ? error.message : error toast.error(`网络错误,请稍后重试: ${message}`) } finally { setIsLoading(false) } } const handleOpenChange = (open: boolean) => { if (!open) { reset() } onOpenChange(open) } return ( 扣款 用户 {currentUser?.name || currentUser?.username} 的金额
扣款(元) { if (!value) return "" const num = Number(value) if (Number.isNaN(num)) return value return num.toFixed(2) }, })} onInput={(e: React.ChangeEvent) => { let value = e.target.value if (value.startsWith("-")) { value = value.replace("-", "") } if (value.includes(".")) { const parts = value.split(".") if (parts[1] && parts[1].length > 2) { value = `${parts[0]}.${parts[1].slice(0, 2)}` } } setValue("deduction", value) }} /> {errors.deduction?.message}
) }