From 3437a6d8f5d74a6905ae59e12520d3ef664b20f5 Mon Sep 17 00:00:00 2001 From: zty Date: Fri, 12 Jun 2026 10:50:18 +0800 Subject: [PATCH] =?UTF-8?q?feat(phase4):=20C=E7=AB=AF=E6=B1=A1=E6=9F=93?= =?UTF-8?q?=E6=BA=90=E8=AF=86=E5=88=AB=E6=8E=A5=E7=9C=9F=E5=AE=9E=E6=9D=90?= =?UTF-8?q?=E6=96=99=E5=BA=93+=E7=BB=9F=E4=B8=80=E5=BC=95=E6=93=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - seed 官方算例6种真实材料(PM2000000x,真实Y0/Yp/B 5污染物) - 预设样板间(rooms.ts)指向真实材料库;标准间复现官方算例 - SourceTracing 重写:从材料库拉真实参数,客户端调 predictSpace 统一引擎 实时算5项污染物浓度/超标/各材料贡献溯源/污染源标红/整改建议 (含按引擎反推的"提高通风至X次/h") - 实测标准间复现算例:甲醛0.123(PDF0.12),家具贡献90.2% Co-Authored-By: Claude Opus 4.8 (1M context) --- apps/api/prisma/seed.ts | 32 ++++ apps/web/src/data/rooms.ts | 81 ++++++++ apps/web/src/pages/SourceTracing.vue | 272 ++++++++++++++------------- 3 files changed, 256 insertions(+), 129 deletions(-) create mode 100644 apps/web/src/data/rooms.ts diff --git a/apps/api/prisma/seed.ts b/apps/api/prisma/seed.ts index 6c085aa..592994b 100644 --- a/apps/api/prisma/seed.ts +++ b/apps/api/prisma/seed.ts @@ -62,6 +62,38 @@ async function main() { } console.log(`已导入 ${MATERIALS.length} 条公共材料(散发参数为占位值,待替换真实检测数据)`); + // 官方算例 6 种材料(真实 Y0/Yp/B,5 污染物),供 C 端样板间 + 复现算例 + const ep5 = ( + hcho: number[], tvoc: number[], benzene: number[], toluene: number[], xylene: number[], + ) => ({ + hcho: { y0: hcho[0], yp: hcho[1], b: hcho[2] }, + tvoc: { y0: tvoc[0], yp: tvoc[1], b: tvoc[2] }, + benzene: { y0: benzene[0], yp: benzene[1], b: benzene[2] }, + toluene: { y0: toluene[0], yp: toluene[1], b: toluene[2] }, + xylene: { y0: xylene[0], yp: xylene[1], b: xylene[2] }, + }); + const REAL_MATERIALS = [ + { id: 'PM20000001', name: '多层实木复合地板', category: '木地板/实木地板', brand: '示例', healthGrade: 'B', ep: ep5([0.09, 0.4, 0.47], [0.074, 0.7, 0.205], [0.03, 0.186, 0.265], [0, 0, 0], [0, 0, 0]) }, + { id: 'PM20000002', name: '踢脚线', category: '其他', brand: '示例', healthGrade: 'C', ep: ep5([0.38, 2.3, 0.2], [0.25, 1.69, 0.113], [0.053, 0.446, 0.09], [0.05, 0.229, 0.1], [0.009, 0.35, 0.085]) }, + { id: 'PM20000003', name: '吸音板', category: '其他', brand: '示例', healthGrade: 'B', ep: ep5([0, 0, 0], [0.24, 1.71, 0.09], [0, 0, 0], [0, 0, 0], [0, 0, 0]) }, + { id: 'PM20000004', name: '乳胶漆涂料', category: '涂料/墙面漆', brand: '示例', healthGrade: 'A', ep: ep5([0, 0, 0], [0.04, 0.337, 0.288], [0, 0, 0], [0, 0, 0], [0, 0, 0]) }, + { id: 'PM20000005', name: '免漆木门', category: '其他', brand: '示例', healthGrade: 'C', ep: ep5([0, 0, 0], [0.46, 3.05, 0.132], [0.07, 0.53, 0.27], [0.05, 0.41, 0.29], [0.194, 1.24, 0.223]) }, + { id: 'PM20000006', name: '人造板家具', category: '家具', brand: '示例', healthGrade: 'C', ep: ep5([0.45, 2.63, 0.446], [0.14, 0.88, 0.36], [0, 0, 0], [0.08, 0.5, 0.39], [0, 0, 0]) }, + ]; + for (let i = 0; i < REAL_MATERIALS.length; i++) { + const m = REAL_MATERIALS[i]; + await prisma.material.upsert({ + where: { id: m.id }, + update: { emissionParams: m.ep, healthGrade: m.healthGrade }, + create: { + id: m.id, name: m.name, category: m.category, brand: m.brand, + healthGrade: m.healthGrade, sortOrder: 1000 + i, usageUnit: 'm²', + emissionParams: m.ep, isPublic: true, + }, + }); + } + console.log(`已导入 ${REAL_MATERIALS.length} 条官方算例真实材料(PM2000000x)`); + // 一条公共项目模板(含 1 个空间 + 2 种材料),供模板库展示 const tplId = 'T13000001'; await prisma.project.upsert({ diff --git a/apps/web/src/data/rooms.ts b/apps/web/src/data/rooms.ts new file mode 100644 index 0000000..afba220 --- /dev/null +++ b/apps/web/src/data/rooms.ts @@ -0,0 +1,81 @@ +// C 端污染源识别的预设样板间。材料指向真实材料库(PM2000000x,官方算例真实参数)。 +export interface PresetMat { + id: string; + a: number; // 使用面积 m² +} +export interface PresetRoom { + id: string; + name: string; + area: number; + height: number; + temperature: number; + humidity: number; + ventilationRate: number; + materials: PresetMat[]; +} + +export const PRESET_ROOMS: PresetRoom[] = [ + { + id: 'demo', + name: '标准间(官方算例)', + area: 19.8, + height: 3, + temperature: 22, + humidity: 45, + ventilationRate: 0.5, + materials: [ + { id: 'PM20000001', a: 20 }, + { id: 'PM20000002', a: 1.8 }, + { id: 'PM20000003', a: 20 }, + { id: 'PM20000004', a: 51.6 }, + { id: 'PM20000005', a: 3.6 }, + { id: 'PM20000006', a: 17.4 }, + ], + }, + { + id: 'zw', + name: '主卧', + area: 18, + height: 2.7, + temperature: 26, + humidity: 50, + ventilationRate: 0.5, + materials: [ + { id: 'PM20000001', a: 18 }, + { id: 'PM20000002', a: 1.6 }, + { id: 'PM20000006', a: 25 }, + { id: 'PM20000004', a: 40 }, + ], + }, + { + id: 'kt', + name: '客厅', + area: 30, + height: 2.85, + temperature: 26, + humidity: 50, + ventilationRate: 0.6, + materials: [ + { id: 'PM20000001', a: 30 }, + { id: 'PM20000004', a: 55 }, + { id: 'PM20000005', a: 6 }, + { id: 'PM20000006', a: 14 }, + { id: 'PM20000003', a: 30 }, + ], + }, + { + id: 'etf', + name: '儿童房', + area: 14, + height: 2.7, + temperature: 26, + humidity: 55, + ventilationRate: 0.5, + materials: [ + { id: 'PM20000001', a: 14 }, + { id: 'PM20000006', a: 32 }, + { id: 'PM20000004', a: 30 }, + { id: 'PM20000002', a: 1.4 }, + ], + }, +]; diff --git a/apps/web/src/pages/SourceTracing.vue b/apps/web/src/pages/SourceTracing.vue index f51c23c..f0d231e 100644 --- a/apps/web/src/pages/SourceTracing.vue +++ b/apps/web/src/pages/SourceTracing.vue @@ -3,50 +3,56 @@
返回首页 -
污染源识别SOURCE TRACING · 甲醛
+
污染源识别SOURCE TRACING · 5 项污染物
进入专业系统 → {{ auth.org?.name || '访客' }}
-
+
加载材料库…
+
房间与材料输入
输入
-
选择房间
+
选择样板间
-
{{ r.name }}
+
{{ r.name }}
-
房间面积
-
层高
m
+
面积
+
层高
m
+
+
+
+
+
温度
+
湿度
%rh
-
通风换气率 {{ (+st.n).toFixed(1) }} 次/h
- +
通风换气率 {{ (+ventilationRate).toFixed(1) }} 次/h
+
0.3 密闭1.0 一般3.0 强通风
-
装修材料清单 勾选计入 · 填写用量(m²)
+
装修材料 体积 V={{ volume.toFixed(1) }} m³ · 勾选计入、填用量
-
-
+
+
-
{{ MATS[id].name }} · 已换E0
-
{{ MATS[id].cat }} · EF {{ MATS[id].ef }}
+
{{ m.name }}
+
{{ matMap[m.id]?.category }}
-
+
-
@@ -54,60 +60,52 @@
-
识别结论
结果
-
-
{{ fmt(r.C) }}mg/m³
-
- 甲醛 {{ LEVELTXT[r.level] }} -
低于 GB/T 18883 限值 {{ LIMIT }},余量 {{ Math.round((1 - r.ratio) * 100) }}%
-
超出 GB/T 18883 限值 {{ LIMIT }}{{ Math.round((r.ratio - 1) * 100) }}%(GB 50325-I 限值 {{ LIMIT2 }})
-
-
-
-
计算预测浓度
- -
{{ r.level === 'good' ? '判定达标' : '判定超标' }}
- -
公式溯源污染材料
-
+
识别结论 · 5 项污染物
结果
+ + + + + + + + + + +
污染物预测浓度限值({{ standard }})判定
{{ labels[p].zh }}{{ fmt(r.concentration[p]) }} mg/m³{{ r.limits[p] }}{{ r.exceeded[p] ? '超标' : '达标' }}
-
溯源公式 · 稳态质量平衡
公式
-
-
C = Σ ( EFᵢ · Aᵢ )n · V
-
- 房间体积 V = 面积 × 层高 = {{ fmt(st.area, 0) }} × {{ (+st.h).toFixed(1) }} = {{ fmt(r.V, 1) }} m³ · - 通风量 n·V = {{ (+st.n).toFixed(1) }} × {{ fmt(r.V, 1) }} = {{ fmt(r.nV, 1) }} m³/h
- 总释放速率 Σ(EF·A) = {{ fmt(r.totalEmis, 2) }} mg/h ⇒ - C = {{ fmt(r.totalEmis, 2) }} ÷ {{ fmt(r.nV, 1) }} = {{ fmt(r.C) }} mg/m³ +
+
公式溯源 · 各材料贡献
+
+ {{ labels[p].zh }}
-
- -
-
公式溯源 · 各材料甲醛浓度贡献
贡献ᵢ = EFᵢ·Aᵢ /(n·V) · 已按贡献排序
-
-
{{ i + 1 }}{{ x.name }}
-
-
{{ fmt(x.c) }} {{ Math.round(x.pct * 100) }}%
+
+
+ {{ i + 1 }}{{ c.name }} + (污染源) +
+
+
{{ (c.rate * 100).toFixed(1) }}%
-
未选择任何材料
+
该污染物无材料释放
-
+
整改建议
-
{{ r.level === 'good' ? '当前方案达标 ✓' : `主要污染源:${r.items[0].name}` }}
-
预测甲醛 {{ fmt(r.C) }} mg/m³ 已低于国标限值。建议入住前仍保持 {{ (+st.n).toFixed(1) }} 次/h 以上通风,并复测确认。
-
该材料贡献 {{ Math.round(r.items[0].pct * 100) }}%({{ fmt(r.items[0].c) }} mg/m³)。将通风提升至 {{ r.requiredN.toFixed(1) }} 次/h 或更换主源材料即可达标。
-
- - +
{{ anyOver ? `${overNames} 超标` : '当前方案全部达标 ✓' }}
+
+ 主要污染源:{{ topSourceNames }}。可将通风提升至 {{ requiredACH.toFixed(1) }} 次/h,或更换/减少这些材料。 +
+
各污染物均低于 {{ standard }} 限值。建议入住前仍保持通风并复测确认。
+
+
@@ -115,104 +113,120 @@
- - -
{{ toast }}
-