diff --git a/public/nzcfg.html b/public/nzcfg.html new file mode 100644 index 0000000..7fdde70 --- /dev/null +++ b/public/nzcfg.html @@ -0,0 +1,1209 @@ + + + + + + + + + NEZHA配置生成器 + + + + +
+
+
公开备注代码
+
流量监控代码
+
+ +
+ +
+ + +
+
+
+

公开备注代码配置

+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+
+ +
+ + +
+ +
+ + + +
+ +
+ +
+ + +
+
+ + + +
+
+ +
+ +
+ + +
+
+ + + +
+
+ +
+ +
+ + +
+
+ + + + + +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + + +
+
+ +
+
+
+ 163 + CN2 + CN2GIA + CMI + CMIN2 + 4837 + 10099 + IEPL + IPLC +
+
+ + +
+ +
+ + +
+ + +
+
+ +
+
+
+
+ + +
+
+
+

流量监控代码配置

+ +
+ + +
+ +
+ + +
+ +
+ +
+ + +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + + +
+ + +
+ + +
+
+ +
+
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/src/components/server.tsx b/src/components/server.tsx index a57ee60..3fcd7ef 100644 --- a/src/components/server.tsx +++ b/src/components/server.tsx @@ -1,6 +1,5 @@ import { updateServer } from "@/api/server" import { Button } from "@/components/ui/button" -import { Calendar } from "@/components/ui/calendar" import { Checkbox } from "@/components/ui/checkbox" import { Dialog, @@ -22,35 +21,14 @@ import { } from "@/components/ui/form" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" -import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" import { ScrollArea } from "@/components/ui/scroll-area" -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select" -import { Switch } from "@/components/ui/switch" import { Textarea } from "@/components/ui/textarea" import { IconButton } from "@/components/xui/icon-button" -import { - type PublicNote, - PublicNoteSchema, - applyPublicNoteDate, - applyPublicNotePatch, - detectPublicNoteMode, - normalizeISO, - parsePublicNote, - toggleEndNoExpiry, - validatePublicNote, -} from "@/lib/public-note" import { conv } from "@/lib/utils" import { asOptionalField } from "@/lib/utils" import { ModelServer } from "@/types" import { zodResolver } from "@hookform/resolvers/zod" -import { HelpCircle } from "lucide-react" -import { useState } from "react" +import { useState, useEffect } from "react" import { useForm } from "react-hook-form" import { useTranslation } from "react-i18next" import { toast } from "sonner" @@ -65,29 +43,13 @@ interface ServerCardProps { const serverFormSchema = z.object({ name: z.string().min(1), note: asOptionalField(z.string()), - public_note: asOptionalField( - z.string().refine( - (val) => { - const s = (val ?? "").trim() - if (s.length === 0) return true - try { - const obj = JSON.parse(s) - if (typeof obj !== "object" || obj === null) return true - return PublicNoteSchema.safeParse(obj).success - } catch { - // skip check if not JSON - return true - } - }, - { message: "Invalid Public Note JSON" }, - ), - ), + public_note: asOptionalField(z.string()), display_index: z.coerce.number().int(), hide_for_guest: asOptionalField(z.boolean()), enable_ddns: asOptionalField(z.boolean()), ddns_profiles: asOptionalField(z.array(z.number())), ddns_profiles_raw: asOptionalField(z.string()), - override_ddns_domains: asOptionalField(z.record(z.string(), z.array(z.string()))), + override_ddns_domains: asOptionalField(z.record(z.coerce.number().int(), z.array(z.string()))), override_ddns_domains_raw: asOptionalField( z.string().refine( (val) => { @@ -107,8 +69,8 @@ const serverFormSchema = z.object({ export const ServerCard: React.FC = ({ data, mutate }) => { const { t } = useTranslation() - const form = useForm({ - resolver: zodResolver(serverFormSchema) as any, + const form = useForm>({ + resolver: zodResolver(serverFormSchema), defaultValues: { ...data, ddns_profiles_raw: data.ddns_profiles ? conv.arrToStr(data.ddns_profiles) : undefined, @@ -123,47 +85,20 @@ export const ServerCard: React.FC = ({ data, mutate }) => { const [open, setOpen] = useState(false) - const [publicNoteObj, setPublicNoteObj] = useState( - parsePublicNote(data?.public_note), - ) - const [publicNoteErrors, setPublicNoteErrors] = useState< - Partial< - Record< - | "billing.startDate" - | "billing.endDate" - | "billing.autoRenewal" - | "billing.cycle" - | "billing.amount" - | "plan.bandwidth" - | "plan.trafficVol" - | "plan.trafficType" - | "plan.IPv4" - | "plan.IPv6" - | "plan.extra", - string - > - > - >({}) + useEffect(() => { + const handleMessage = (e: MessageEvent) => { + if (e.data?.type === 'NZCFG_JSON') { + if (e.data.target === 'public_note') { + form.setValue('public_note', e.data.payload); + toast(t("Success"), { description: "配置已通过可视化构建器自动填入" }); + } + } + }; + window.addEventListener('message', handleMessage); + return () => window.removeEventListener('message', handleMessage); + }, [form, t]); - const [publicNoteMode, setPublicNoteMode] = useState<"structured" | "raw">( - detectPublicNoteMode(data?.public_note), - ) - const [publicNoteRaw, setPublicNoteRaw] = useState(data?.public_note ?? "") - - const patchPublicNote = (path: string, value: string | undefined) => { - setPublicNoteObj((prev) => applyPublicNotePatch(prev, path, value)) - } - const patchPublicNoteDate = ( - path: "billingDataMod.startDate" | "billingDataMod.endDate", - d: Date, - ) => { - setPublicNoteObj((prev) => applyPublicNoteDate(prev, path, d)) - } - const toggleEndNoExpiryLocal = () => { - setPublicNoteObj((prev) => toggleEndNoExpiry(prev)) - } - - const onSubmit = async (values: any) => { + const onSubmit = async (values: z.infer) => { try { values.ddns_profiles = values.ddns_profiles_raw ? conv.strToArr(values.ddns_profiles_raw).map(Number) @@ -171,37 +106,6 @@ export const ServerCard: React.FC = ({ data, mutate }) => { values.override_ddns_domains = values.override_ddns_domains_raw ? JSON.parse(values.override_ddns_domains_raw) : undefined - - if (publicNoteMode === "raw") { - const raw = (publicNoteRaw ?? "").trim() - if (raw.length === 0) { - values.public_note = undefined - } else { - values.public_note = raw - } - } else { - const { errors, valid } = validatePublicNote(publicNoteObj) - if (!valid) { - setPublicNoteErrors(errors) - toast(t("Error"), { description: t("Validation.InvalidForm") }) - return - } - setPublicNoteErrors({}) - - const bd = publicNoteObj.billingDataMod - const pd = publicNoteObj.planDataMod - const pnNormalized: PublicNote = { - billingDataMod: bd && { - ...bd, - startDate: normalizeISO(bd.startDate), - endDate: normalizeISO(bd.endDate), - }, - planDataMod: pd, - } - const jsonStr = JSON.stringify(pnNormalized) - values.public_note = jsonStr.length > 2 ? jsonStr : undefined - } - await updateServer(data!.id!, values) } catch (e) { console.error(e) @@ -215,35 +119,12 @@ export const ServerCard: React.FC = ({ data, mutate }) => { form.reset() } - const handleOpenChange = (v: boolean) => { - if (v) { - form.reset({ - ...data, - ddns_profiles_raw: data.ddns_profiles - ? conv.arrToStr(data.ddns_profiles) - : undefined, - override_ddns_domains_raw: data.override_ddns_domains - ? JSON.stringify(data.override_ddns_domains) - : undefined, - }) - setPublicNoteObj(parsePublicNote(data?.public_note)) - setPublicNoteRaw(data?.public_note ?? "") - setPublicNoteMode(detectPublicNoteMode(data?.public_note)) - setPublicNoteErrors({}) - } - setOpen(v) - } - return ( - + - e.preventDefault()} - onEscapeKeyDown={(e) => e.preventDefault()} - > +
@@ -368,603 +249,34 @@ export const ServerCard: React.FC = ({ data, mutate }) => { )} /> - {/* Public Note controls (optional + dual mode) */} -
- - - {/* Toggle: when disabled, hide edit controls and submit an empty value */} -
- {/* Mode switch: Raw text / Custom fields */} -
- {/* Show 'structured' first, then 'raw' */} - - -
-
- - {/* Raw text mode: shown by default; submission uses this string */} - {publicNoteMode === "raw" && ( -
-