"use client"; import { useEffect, useState } from "react"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm, type Resolver } from "react-hook-form"; import { z } from "zod/v4"; import { ProjectDialog } from "@/components/project-dialog"; import { Button } from "@/components/ui/button"; import { Field, FieldContent, FieldError, FieldLabel } from "@/components/ui/field"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { fetchKnowledgeFAQ, type CreateKnowledgeFAQPayload, type KnowledgeFAQ, } from "@/lib/api/admin"; type FAQEditDialogProps = { open: boolean; saving: boolean; itemId: number | null; knowledgeBaseId: number | null; onOpenChange: (open: boolean) => void; onSubmit: (payload: CreateKnowledgeFAQPayload) => Promise; }; const formSchema = z.object({ question: z.string().trim().min(1, "问题不能为空").max(500, "问题最多500个字符"), answer: z.string().trim().min(1, "答案不能为空"), similarQuestionsText: z.string(), remark: z.string().trim().max(500, "备注最多500个字符"), }); type EditForm = z.infer; const resolver = zodResolver(formSchema as never) as Resolver< z.input, undefined, z.output >; const emptyForm: EditForm = { question: "", answer: "", similarQuestionsText: "", remark: "", }; function buildForm(item: KnowledgeFAQ | null): EditForm { if (!item) { return emptyForm; } return { question: item.question, answer: item.answer, similarQuestionsText: (item.similarQuestions ?? []).join("\n"), remark: item.remark ?? "", }; } function buildPayload(form: EditForm, knowledgeBaseId: number): CreateKnowledgeFAQPayload { return { knowledgeBaseId, question: form.question.trim(), answer: form.answer.trim(), similarQuestions: form.similarQuestionsText .split("\n") .map((item) => item.trim()) .filter(Boolean), remark: form.remark.trim(), }; } export function FAQEditDialog({ open, saving, itemId, knowledgeBaseId, onOpenChange, onSubmit, }: FAQEditDialogProps) { if (!open || !knowledgeBaseId) { return null; } return ( ); } type FAQEditDialogBodyProps = { open: boolean; saving: boolean; itemId: number | null; knowledgeBaseId: number; onOpenChange: (open: boolean) => void; onSubmit: (payload: CreateKnowledgeFAQPayload) => Promise; }; function FAQEditDialogBody({ open, saving, itemId, knowledgeBaseId, onOpenChange, onSubmit, }: FAQEditDialogBodyProps) { const [loading, setLoading] = useState(false); const formId = "knowledge-faq-edit-form"; const form = useForm< z.input, undefined, z.output >({ resolver, defaultValues: emptyForm, }); const { handleSubmit, reset, register, formState: { errors }, } = form; useEffect(() => { async function loadDetail() { if (!itemId) { reset(emptyForm); return; } setLoading(true); try { const data = await fetchKnowledgeFAQ(itemId); reset(buildForm(data)); } finally { setLoading(false); } } if (open) { void loadDetail(); } }, [itemId, open, reset]); async function onFormSubmit(values: EditForm) { await onSubmit(buildPayload(values, knowledgeBaseId)); } return ( } > {loading ? (
加载中...
) : (
标准问题 答案