import { useMemo, useState } from "react"; import TextField from "@mui/material/TextField"; import { Button } from "@/shared/ui/Button.jsx"; import styles from "@/shared/ui/JsonEditorField.module.css"; export function JsonEditorField({ className = "", disabled = false, label, minRows = 6, onChange, required = false, value, }) { const [validated, setValidated] = useState(false); const validation = useMemo(() => validateJsonObject(value), [value]); const showError = validated && !validation.valid; const helperText = showError ? validation.message : validated ? "JSON 格式正确" : "支持格式化和校验,内容必须是 JSON 对象"; const lineCount = Math.max(1, String(value || "").split("\n").length); const formatJson = () => { const result = parseJsonObject(value); setValidated(true); if (!result.valid) { return; } onChange(JSON.stringify(result.value, null, 2)); }; return (
{label} {required ? * : null}
setValidated(true)} onChange={(event) => { setValidated(false); onChange(event.target.value); }} />
{helperText}
); } export function normalizeJsonObjectString(raw) { const result = parseJsonObject(raw); if (!result.valid) { throw new Error(result.message); } return JSON.stringify(result.value); } function validateJsonObject(raw) { return parseJsonObject(raw); } function parseJsonObject(raw) { const value = String(raw || "").trim(); if (!value) { return { valid: true, value: {} }; } try { const parsed = JSON.parse(value); if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) { return { valid: false, message: '配置 JSON 必须是对象,例如 {"app_id": 123}' }; } return { valid: true, value: parsed }; } catch (err) { return { valid: false, message: `JSON 格式错误:${err.message}` }; } }