| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- "use client";
- import type { InspectorModule } from "@/lib/types";
- import { LongValueDisclosure } from "@/components/inspector/LongValueDisclosure";
- interface Props {
- module: InspectorModule;
- value: unknown;
- label?: string;
- }
- /** Business-only renderer. Raw JSON belongs to the source column, never here. */
- export function BusinessValueRenderer({ module, value, label }: Props) {
- if (module.id === "conditions" && Array.isArray(value) && value.length === 0) {
- return <p className="comparisonEmptyValue">本次调用没有保存额外输入条件。</p>;
- }
- if (module.id === "activities" && Array.isArray(value) && value.length === 0) {
- return <p className="comparisonEmptyValue">本次运行没有保存可下钻的结构化查询记录。</p>;
- }
- if (module.id === "completeness") {
- if (label === "完整返回" && value === false) {
- return <p className="comparisonEmptyValue">仅保存了摘要,完整返回不可用。</p>;
- }
- if (label === "截断说明") {
- return <p className="comparisonEmptyValue">返回内容超过安全展示上限,已省略 {typeof value === "number" ? value : "部分"} 个字符。</p>;
- }
- }
- if (typeof value === "string" || value === null || value === undefined) {
- return <LongValueDisclosure value={value} label={label || "完整内容"} />;
- }
- if (module.id === "mode" && isStringPair(value)) {
- return <dl className="businessDefinitionList">
- <BusinessDefinition label="规划方式" value={value[0]} emphasis />
- <BusinessDefinition label="为什么这样规划" value={value[1]} />
- </dl>;
- }
- if (Array.isArray(value)) {
- if (value.every((item) => typeof item === "string")) {
- return <ul className="businessBulletList">{value.map((item, index) => <li key={index}>{item}</li>)}</ul>;
- }
- if (value.every(isPlanRoute)) return <PlanRoutes routes={value} />;
- return <BusinessRecordList values={value} />;
- }
- if (isRecord(value)) {
- if (Array.isArray(value.paths)) {
- return <div className="businessRevisionSummary">
- <dl className="businessDefinitionList">
- {typeof value.mode === "string" ? <BusinessDefinition label="保存的规划方式" value={value.mode} emphasis /> : null}
- <BusinessDefinition label="保存结果" value={`已保存 ${value.paths.length} 条实现路线`} />
- </dl>
- {typeof value.note === "string" ? <section className="businessNarrative"><h5>保存时的说明</h5><p>{value.note}</p></section> : null}
- </div>;
- }
- return <BusinessRecord value={value} rowLabel={label} />;
- }
- return <p className="comparisonReadableText">{String(value)}</p>;
- }
- function PlanRoutes({ routes }: { routes: PlanRoute[] }) {
- if (!routes.length) return <p className="comparisonEmptyValue">没有保存具体路线。</p>;
- return <div className="businessPlanRoutes">{routes.map((route, index) => <article key={`${route.path_index || index}-${route.target || "route"}`} className="businessPlanRoute">
- <header><span>{route.path_index || index + 1}</span><div><h5>路线 {route.path_index || index + 1}</h5>{route.path_type ? <small>{friendlyValue(route.path_type)}</small> : null}</div></header>
- <dl>
- {route.target ? <BusinessDefinition label="要实现什么" value={route.target} /> : null}
- {route.method ? <BusinessDefinition label="怎么实现" value={friendlyValue(route.method)} /> : null}
- {route.action ? <BusinessDefinition label="具体动作" value={friendlyValue(route.action)} /> : null}
- {route.emphasis ? <BusinessDefinition label="这条路线的重点" value={route.emphasis} /> : null}
- </dl>
- </article>)}</div>;
- }
- function BusinessRecordList({ values }: { values: unknown[] }) {
- return <div className="businessRecordList">{values.map((value, index) => <section key={index} className="businessRecordItem">
- <h5>第 {index + 1} 项</h5>
- {isRecord(value) ? <BusinessRecord value={value} /> : <p>{printSimple(value)}</p>}
- </section>)}</div>;
- }
- function BusinessRecord({ value, rowLabel }: { value: Record<string, unknown>; rowLabel?: string }) {
- const primary = value.value;
- const entries = Object.entries(value).filter(([key, item]) => {
- if (TECHNICAL_KEYS.has(key) || key === "value" || item === undefined || item === null || item === "") return false;
- if (rowLabel && ["label", "title", "subject", "summary"].includes(key) && String(item) === rowLabel) return false;
- return true;
- });
- if (!entries.length && (primary === undefined || primary === null || primary === "")) return <p className="comparisonEmptyValue">这条记录没有可展示的业务内容。</p>;
- return <>{primary !== undefined && primary !== null && primary !== "" ? <LongValueDisclosure value={primary} label="完整内容" /> : null}<dl className="businessDefinitionList">{entries.map(([key, item]) => <BusinessDefinition key={key} label={fieldLabel(key)} value={printSimple(item)} />)}</dl></>;
- }
- function BusinessDefinition({ label, value, emphasis = false }: { label: string; value: string; emphasis?: boolean }) {
- return <div className={emphasis ? "is-emphasis" : ""}><dt>{label}</dt><dd>{value}</dd></div>;
- }
- type PlanRoute = {
- action?: string;
- method?: string;
- target?: string;
- emphasis?: string;
- path_type?: string;
- path_index?: string | number;
- };
- const TECHNICAL_KEYS = new Set(["id", "path_index", "detailRef", "event_id", "eventId", "sourceNotice"]);
- const FIELD_LABELS: Record<string, string> = {
- mode: "规划方式",
- note: "说明",
- goal: "目标",
- target: "要实现什么",
- method: "怎么实现",
- action: "具体动作",
- emphasis: "重点",
- path_type: "路线类型",
- status: "状态",
- summary: "结果摘要",
- reason: "原因",
- reasoning: "判断理由",
- decision: "最终取舍",
- result: "结果",
- count: "数量",
- task: "任务",
- scope: "范围",
- content: "内容",
- label: "名称",
- title: "标题",
- subtitle: "补充说明",
- kind: "类型",
- resultCount: "返回数量",
- meta: "关键信息",
- sections: "内容详情",
- query: "查询内容",
- keyword: "关键词",
- keywords: "关键词",
- account: "账号",
- platform: "平台",
- score: "匹配分数",
- url: "链接",
- input: "输入",
- output: "输出",
- error: "失败原因",
- criteria: "评审标准",
- suggestion: "建议",
- conclusion: "结论",
- issues: "发现的问题",
- strengths: "已经达成",
- next_step: "下一步",
- };
- function isRecord(value: unknown): value is Record<string, unknown> { return Boolean(value) && typeof value === "object" && !Array.isArray(value); }
- function isStringPair(value: unknown): value is [string, string] { return Array.isArray(value) && value.length === 2 && value.every((item) => typeof item === "string"); }
- function isPlanRoute(value: unknown): value is PlanRoute { return isRecord(value) && ("target" in value || "method" in value || "emphasis" in value) && ("path_index" in value || "path_type" in value); }
- function fieldLabel(key: string) { return FIELD_LABELS[key] || "补充信息"; }
- function friendlyValue(value: string) { return ({ "增": "新增", "改": "修改", "删": "删除", "内容": "内容路线" } as Record<string, string>)[value] || value; }
- function printSimple(value: unknown): string {
- if (typeof value === "string") return value;
- if (typeof value === "number" || typeof value === "boolean") return String(value);
- if (Array.isArray(value)) return value.map(printSimple).filter(Boolean).join(";");
- if (isRecord(value)) return Object.entries(value).filter(([key]) => !TECHNICAL_KEYS.has(key)).map(([key, item]) => `${fieldLabel(key)}:${printSimple(item)}`).join(";");
- return String(value ?? "");
- }
|