import { INVESTIGATION_DEV_NETWORK } from "./investigation-dev-network"; import type { AnswerUiBlock } from "@/features/agent"; import { createPresentationRecord, createUiRecord, serializeInvestigationDevJsonl } from "./investigation-dev-preview"; export const complexInvestigationDevCases = [ { id: "complex_investigation", label: "复杂调查:多图多表联动", expected: "压力与管流分别聚合,另有方案柱状图、2 张表与合成覆盖面;右侧切换对象,下方控制图例。" }, { id: "complex_tables", label: "复杂表格:宽表、长文本与边界数据", expected: "50 行 8 列宽表、空表和含零值、负数、重复值的对照表;检查搜索、数值排序和横向滚动。" }, { id: "complex_charts", label: "复杂图表:多测点与长时序", expected: "8 个压力点与 4 个管段各含 96 个时刻、当前曲线与七日历史散点,聚合为 2 个子图表,由总图表窗口统一管理,另有方案柱状图。" } ] as const; type ComplexCaseId = (typeof complexInvestigationDevCases)[number]["id"]; type Node = AnswerUiBlock["spec"]["elements"][string]; const ui = (id: string, node: Node) => createUiRecord({ version: "answer-ui@1", block_id: `dev-complex-${id}`, phase: "final", fallback_text: "本地合成展示数据,不代表实际监测、调查结论或现场方案。", spec: { root: "result", elements: { result: node } } }); const table = (id: string, title: string, columns: string[], rows: string[][]) => ui(id, { type: "Table", props: { title, columns, rows }, children: [] }); const times = Array.from({ length: 96 }, (_, index) => `${String(Math.floor(index / 4)).padStart(2, "0")}:${String(index % 4 * 15).padStart(2, "0")}`); const comparisonChart = (id: string, title: string, axis: string, baseline: number[], current: number[]) => ({ title: `${id} ${title}`, chart_type: "time_comparison" as const, x_axis_name: "时间", y_axis_name: axis, x_data: times, series: [{ name: `${id} 当前 2026-07-16`, type: "line" as const, data: current, sample_times: times.map((time) => `2026-07-16T${time}:00+08:00`) }, ...Array.from({ length: 7 }, (_, day) => { const date = `2026-07-${String(9 + day).padStart(2, "0")}`; return { name: `${id} ${date}`, type: "scatter" as const, data: times.map((_, index) => index >= 40 && index <= 42 ? Number((baseline[index] + day * 0.1).toFixed(2)) : null), sample_times: times.map((time, index) => index >= 40 && index <= 42 ? `${date}T${time}:00+08:00` : null) }; })] }); const pressure = Array.from({ length: 8 }, (_, object) => { const baseline = times.map((_, index) => Number((34 + object * 0.6 + Math.sin(index / 7 + object) * 2.4).toFixed(2))); return comparisonChart(INVESTIGATION_DEV_NETWORK.nodeAnchors[object].id, "合成全天压力对比", "压力水头(m)", baseline, baseline.map((value, index) => Number((value - (index >= 32 && index < 44 ? 7 - object * 0.4 : 0)).toFixed(2)))); }); const flow = Array.from({ length: 4 }, (_, object) => { const baseline = times.map((_, index) => Number((120 + object * 28 + Math.sin(index / 9 + object) * 24).toFixed(1))); return comparisonChart(INVESTIGATION_DEV_NETWORK.pipeIds[object], "合成分区流量趋势", "流量(m³/h)", baseline, baseline.map((value, index) => Number((value + (index >= 32 && index < 44 ? 38 : 0)).toFixed(1)))); }); const chart = (id: string, value: ReturnType) => createPresentationRecord({ action: "open_chart", chart_id: `dev-complex-${id}`, evidence_refs: ["dev:synthetic"], chart: value }); const objectCharts = () => [ ...pressure.map((value, index) => chart(`pressure-${index + 1}`, value)), ...flow.map((value, index) => chart(`flow-${index + 1}`, value)) ]; const comparison = { title: "合成候选方案影响对比", chart_type: "bar" as const, x_data: ["合成方案 A:局部隔离", "合成方案 B:扩大核查", "合成方案 C:保持供水", "合成方案 D:分段验证", "合成方案 E:待补充资料"], series: [{ name: "合成影响用户数(户)", data: [245, 610, 0, 128, 72] }] }; const columns = ["序号", "管段 ID", "合成片区", "长度(m)", "压力变化(m)", "影响户数(户)", "核查状态", "核查说明"]; const rows = Array.from({ length: 50 }, (_, index) => [ String(index + 1), INVESTIGATION_DEV_NETWORK.pipeIds[index], `合成片区 ${index % 5 + 1} · ${index % 2 ? "学校与居民区交界" : "工业园区及长距离末端支线"}`, String(80 + index * 13.5), (index % 7 === 0 ? 0 : -(index % 13) / 2).toFixed(1), String(index % 6 === 0 ? 0 : (index * 37) % 600), ["待现场核验", "资料待补充", "合成候选,未确认"][index % 3], index % 5 === 0 ? `仅供本地测试:样例记录 ${String(index + 1).padStart(3, "0")} 包含较长的核查说明,用于检查换行、滚动、筛选及放大后阅读。请分别核对供水边界、阀门状态与现场回执。合成引用 SYNTHETIC_REFERENCE_${"LONG_SEGMENT_".repeat(8)}${index + 1},不是真实证据。` : `仅为合成候选资料,样例记录 ${String(index + 1).padStart(3, "0")};不代表已确认故障或已执行操作。` ]); export function createComplexInvestigationDevCase(caseId: ComplexCaseId, [longitude, latitude]: [number, number]): string { if (caseId === "complex_charts") return serializeInvestigationDevJsonl([ ...objectCharts(), createPresentationRecord({ action: "open_chart", chart_id: "dev-complex-plans", evidence_refs: ["dev:synthetic"], chart: comparison }) ]); if (caseId === "complex_tables") return serializeInvestigationDevJsonl([ table("wide-table", "合成候选核查宽表", columns, rows), table("empty-table", "合成空结果表", ["对象", "核查结果", "说明"], []), table("edge-table", "合成排序与缺口对照", ["对象", "变化量", "完成率", "说明"], [ ["合成对象 A", "0", "0%", "零值不是缺失"], ["合成对象 B", "-2.5", "50%", "负数与百分比排序"], ["合成对象 C", "10", "100%", "按数值排列,不按文本排列"], ["合成对象 D", "2", "50%", "重复值保持可读"], ["合成对象 E", "2", "50%", "重复值第二行"], ["合成对象 F", "未提供", "未提供", "缺失不替换为零"] ]) ]); const point = (dx: number, dy: number): [number, number] => [Math.max(-180, Math.min(180, longitude + dx)), Math.max(-89.99, Math.min(89.99, latitude + dy))]; return serializeInvestigationDevJsonl([ createPresentationRecord({ action: "set_overlay", mode: "geometry", overlay_id: "dev-complex-coverage", title: "合成分区覆盖示意", evidence_id: "dev:synthetic", data: { type: "FeatureCollection", features: [-0.002, 0.002].map((dx, index) => ({ type: "Feature", properties: { project_code: INVESTIGATION_DEV_NETWORK.projectCode, origin: "synthetic", label: `合成片区 ${index + 1}` }, geometry: { type: "Polygon", coordinates: [[point(dx - 0.001, -0.001), point(dx + 0.001, -0.001), point(dx + 0.001, 0.001), point(dx - 0.001, 0.001), point(dx - 0.001, -0.001)]] } })) } }), ...objectCharts(), createPresentationRecord({ action: "open_chart", chart_id: "dev-complex-plans", evidence_refs: ["dev:synthetic"], chart: comparison }), table("candidates", "合成候选方案核查", columns, rows.slice(0, 24)), table("valves", "合成阀门核查清单", ["阀门", "合成片区", "位置描述", "核查要求", "当前状态"], INVESTIGATION_DEV_NETWORK.valveIds.map((id, index) => [id, `合成片区 ${index % 3 + 1}`, "合成居民区与主干管交界处,位置尚未现场核验", "核对可操作性、实际开度及现场回执;不执行关阀", "待核查"])) ]); }