diff --git a/src/page/home/index.tsx b/src/page/home/index.tsx index 2b87c77..1595481 100644 --- a/src/page/home/index.tsx +++ b/src/page/home/index.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from "react" +import { useCallback, useMemo, useState } from "react" import jp from "jsonpath" import JsonTreeNode from "@/components/json-tree-node" @@ -22,6 +22,7 @@ export default function Home() { const [jsonInput, setJsonInput] = useState(JSON.stringify(initialData, null, 2)) const [query, setQuery] = useState("$.staff_members[*].name") + const [copied, setCopied] = useState(false) // 计算匹配结果 const result = useMemo(() => { @@ -31,13 +32,36 @@ export default function Home() { return { parsed, matchedPaths: nodes.map((n) => jp.stringify(n.path)), + matchedValues: nodes.map((n) => n.value), error: null, } } catch (e) { - return { parsed: null, matchedPaths: [], error: (e as Error).message } + return { parsed: null, matchedPaths: [], matchedValues: [], error: (e as Error).message } } }, [jsonInput, query]) + // 复制为 CSV + const copyAsCsv = useCallback(() => { + if (result.matchedValues.length === 0) return + + const escapeCsvValue = (val: unknown): string => { + const str = typeof val === "object" ? JSON.stringify(val) : String(val) + if (str.includes(",") || str.includes('"') || str.includes("\n")) { + return `"${str.replace(/"/g, '""')}"` + } + return str + } + + const header = query + const rows = result.matchedValues.map(escapeCsvValue) + const csv = [header, ...rows].join("\n") + + navigator.clipboard.writeText(csv).then(() => { + setCopied(true) + setTimeout(() => setCopied(false), 2000) + }) + }, [query, result.matchedValues]) + return (
{/* 左侧输入面板 - 40% */} @@ -76,9 +100,18 @@ export default function Home() { Visualised Result - - {result.matchedPaths.length} matches - +
+ + {result.matchedPaths.length} matches + + +