95 lines
7.6 KiB
TypeScript
95 lines
7.6 KiB
TypeScript
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<typeof comparisonChart>) => 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}`, "合成居民区与主干管交界处,位置尚未现场核验", "核对可操作性、实际开度及现场回执;不执行关阀", "待核查"]))
|
||
]);
|
||
}
|