tanghaolin
8 天以前 7ccfc3503f5484373e922da4aa149db43152c312
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
<template>
    <div class="container mx-auto px-4 py-8">
        <!-- Breadcrumb -->
        <el-breadcrumb separator=">" class="mb-6">
            <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item v-if="fromType && fromType == 'product'"
                :to="{ path: '/certified-products' }">能效产品</el-breadcrumb-item>
            <el-breadcrumb-item>{{ m_curSeriesNode.ModelType }}</el-breadcrumb-item>
        </el-breadcrumb>
 
        <!-- Product Display Section -->
        <div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-8">
            <!-- Product Image -->
            <div class="bg-white p-4 rounded-lg shadow flex justify-center flex-col">
                <img :src="m_curSeriesNode.PhysicalPicturePath"  :alt="m_curSeriesNode.ModelType"
                    class="w-full max-w-md mx-auto h-[475px]" style="object-fit: contain;" />
                <h2 class="text-xl font-bold mt-4 text-center">{{ m_curSeriesNode.ModelType }}</h2>
            </div>
 
            <!-- Product Info Tabs -->
            <div class="bg-white rounded-lg shadow">
                <el-tabs class="w-full h-full" v-model="activeTab" type="border-card" @tab-change="changeTab">
                    <el-tab-pane label="概述" name="properties">
                        <div class="p-4" style="white-space: pre-wrap;">
                            <p class="text-gray-700">{{ currentDescription?.description || "" }}</p>
                        </div>
                    </el-tab-pane>
                    <el-tab-pane label="行业应用" name="features">
                        <div class="p-4" style="white-space: pre-wrap;">
                            {{ currentDescription?.hangyeDisc || "" }}
                        </div>
                    </el-tab-pane>
                    <el-tab-pane label="三维动画" name="bim" class="h-full">
                        <el-empty description="暂未上传" v-if="!hasBimFile" />
                        <template v-if="hasBimFile">
                            <div style="box-sizing: border-box; height: calc(100% - 2px);"  v-loading="loading_frm">
                                <model-3D ref="model3dCtrl"></model-3D>
                            </div>
                        </template>
                    </el-tab-pane>
                    <el-tab-pane label="产品视频" name="video">
                        <div>
                            <el-empty description="暂未上传" />
                        </div>
                    </el-tab-pane>
                </el-tabs>
            </div>
        </div>
 
        <!-- Search Section -->
        <div class="bg-[#f1f1f1] rounded-lg mb-8">
            <h3 class="text-lg font-bold p-6" style="border-bottom: 1px solid #d8d8d8;">筛选</h3>
            <el-form :model="searchForm" :inline="true" class="p-6">
                <el-form-item label="型号">
                    <el-input v-model="searchForm.model" placeholder="请输入型号" clearable />
                </el-form-item>
                <el-form-item label="能效等级">
                    <el-select style="width:180px" v-model="searchForm.energyLevel" placeholder="请选择能效等级" clearable>
                        <el-option label="全部" :value="0" />
                        <el-option label="1级能效" :value="1" />
                        <el-option label="2级能效" :value="2" />
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="handleSearch">查询</el-button>
                    <el-button @click="handleReset">重置</el-button>
                </el-form-item>
            </el-form>
        </div>
 
        <!-- Table Section -->
        <div class="bg-white rounded-lg shadow">
            <el-table :data="tableData" style="width: 100%" stripe border height="500px">
                <el-table-column prop="model" align="center">
                    <template #header>
                        <div class="text-center">
                            <div>型号</div>
                        </div>
                    </template>
                    <template #default="scope">
                        <div class="text-[#003a8f]" style="cursor: pointer;" @click="handleSeriesClick(scope.row)">
                            {{ scope.row.model }}
                        </div>
                    </template>
                </el-table-column>
                <el-table-column prop="eec" align="center">
                    <template #header>
                        <div class="text-center">
                            <div>能效等级</div>
                        </div>
                    </template>
                    <template #default="scope">
                        <div class="flex items-center eec-level-div" v-if="scope.row.eec !==-1">
                            <img :src="EecLevelEnum[scope.row.eec].icon" />
                        </div>
                        <template v-else>
                            {{ scope.row.eec ==-1?"":"" }}
                        </template>
                    </template>
                </el-table-column>
                <el-table-column prop="flow" align="center">
                    <template #header>
                        <div class="text-center">
                            <div>流量</div>
                            <div class="text-xs text-gray-500">(m³/h)</div>
                        </div>
                    </template>
                </el-table-column>
                <el-table-column prop="head" align="center">
                    <template #header>
                        <div class="text-center">
                            <div>扬程</div>
                            <div class="text-xs text-gray-500">(m)</div>
                        </div>
                    </template>
                </el-table-column>
                <!-- <el-table-column prop="power" align="center">
                    <template #header>
                        <div class="text-center">
                            <div>功率</div>
                            <div class="text-xs text-gray-500">(kw)</div>
                        </div>
                    </template>
                </el-table-column> -->
                <el-table-column prop="speed" align="center">
                    <template #header>
                        <div class="text-center">
                            <div>转速</div>
                            <div class="text-xs text-gray-500">(r/min)</div>
                        </div>
                    </template>
                </el-table-column>
                <el-table-column prop="eta" align="center">
                    <template #header>
                        <div class="text-center">
                            <div>效率</div>
                            <div class="text-xs text-gray-500">(%)</div>
                        </div>
                    </template>
                </el-table-column>
            </el-table>
 
            <!-- Pagination -->
            <div class="flex justify-center items-center p-4">
                <div class="flex justify-center mt-8">
                    <el-pagination v-model:current-page="m_paginationConfig.currentPage"
                        :page-size="m_paginationConfig.pageSize" :background="true"
                        layout="total,sizes,  prev, pager, next, jumper" :total="catalogItemList.length"
                        @size-change="handleSizeChange" @current-change="handlePageChange" />
                </div>
            </div>
 
 
        </div>
    </div>
</template>
 
<script setup lang="ts">
import { onMounted, ref, reactive, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router';
import axios from 'axios';
import EecLevel1 from '@/assets/icons/ecc1.svg';
import EecLevel2 from '@/assets/icons/ecc2.svg';
import EecLevel3 from '@/assets/icons/ecc3.svg';
import Model3D from '@/components/model3DContainer.vue';
 
const m_RequestDataObj = {
    1: { requestPath: 'static/EecProductData/Pump.json?v=' + new Date().getTime() },
    2: { requestPath: 'static/EecProductData/AirCompressor.json?v=' + new Date().getTime() },
    3: { requestPath: 'static/EecProductData/Fan.json?v=' + new Date().getTime() },
    4: { requestPath: 'static/EecProductData/WaterChiller.json?v=' + new Date().getTime() },
    7: { requestPath: 'static/EecProductData/ElectricMachinery.json?v=' + new Date().getTime() },
};
 
const m_pumpList = {
    1: { requestPath: 'static/EecProductData/CDL.json?v=' + new Date().getTime() },
    2: { requestPath: 'static/EecProductData/NB.json?v=' + new Date().getTime() },
    3: { requestPath: 'static/EecProductData/ND.json?v=' + new Date().getTime() },
    4: { requestPath: 'static/EecProductData/NIS.json?v=' + new Date().getTime() },
    5: { requestPath: 'static/EecProductData/NZS.json?v=' + new Date().getTime() },
}
const EecLevelEnum = {
    1: { name: '一级能效', icon: EecLevel1 },
    2: { name: '二级能效', icon: EecLevel2 },
    3: { name: '三级级能效', icon: EecLevel3 },
};
 
const DescListByType = {
    1: {
        name: '水泵',
        catalog: {
            1: {
                description: "管网叠压(无负压)变频给水设备(二次供水设备)是一种在原有管网水压力基础上再次加压的供水设备。其主要功能是在市政供水管网压力的基础上进行二次加压,以满足更高的供水需求,同时确保市政管网的压力不低于设定保护压力,防止负压产生,确保供水的安全、可靠和稳定‌‌",
                hangyeDisc: "管网叠压(无负压)变频给水设备(二次供水设备)适用于‌普通住宅楼、商住楼、居民小区‌、高层建筑、高级宾馆饭店、生活小区、高层建筑的热水供应系统、综合楼、写字楼等建筑",
                videoUrl: "",
                three_D_url: ""
            },
            4: {
                description: "污水污物潜水电泵是一种专为输送含有坚硬固体和纤维的液体而设计的设备,特别适用于处理特别脏、粘或滑的液体。它在污水处理和排放系统中发挥着至关重要的作用‌",
                hangyeDisc: "污水污物潜水电泵适用于各种生活污水、工业废水、建筑工地排水、液状饲料等。在市政工程、工业、医院、建筑、饭店、水利建设等各行各业中都有广泛应用‌",
                videoUrl: "",
                three_D_url: ""
            },
            6: {
                description: "‌端吸泵‌,也称为单吸泵,是指液体从叶轮的一端进水的泵。其基本结构由泵体、叶轮、轴、密封装置等组成,进口和出口位于泵的同一侧,通常进口在泵的末端,出口在泵的前端‌这种设计使得泵的结构相对紧凑,便于安装和维护‌",
                hangyeDisc: "‌端吸泵广泛应用于建筑供水、增压、空调系统、工业循环等多种场合。",
                videoUrl: "",
                three_D_url: ""
            },
            5: {
                description: "‌立式多级泵是具有整体结构紧凑、体积小、重量轻、噪声低、节能效果显著,检修方便的离心泵。采用标准立式电机和快装式机械密封,更换非常方便。泵的过流部分均采用不锈钢(304/316)材料制成,可适用于轻度腐蚀性介质。",
                hangyeDisc: "‌‌立式多级泵适用于\n高层建筑供水‌:立式多级不锈钢离心泵适用于高层建筑的供水系统,能够提供稳定的水压,满足高层建筑的日常生活用水需求‌\n‌工业用水‌:在工业生产中,立式多级不锈钢离心泵可用于输送各种工业用水,如冷却循环水、进料水、洗涤水等,满足不同工艺的用水要求‌\n‌农田灌溉‌:该泵可用于农田灌溉,提供充足的水资源,保证农作物的生长‌\n‌水处理工程‌:在水处理工程中,立式多级不锈钢离心泵广泛应用于给水处理、反渗透、超滤等工艺,提供高质量的水源‌\n‌化工行业‌:在化工生产中,该泵具有良好的耐腐蚀性能,可用于输送含有腐蚀性、易燃性、易爆性的介质‌\n‌能源行业‌:在能源行业中,如核电站、电厂供水等,立式多级不锈钢离心泵也有广泛应用‌\n‌消防系统‌:在消防系统中,该泵能够快速将水增压到所需的高压状态,保证消防水能够喷射到较高的楼层或者较远的距离‌\n‌食品、医药、化工等行业‌:立式多级不锈钢离心泵还广泛应用于食品、医药、化工、水产养殖等领域,作为给水排水的动力设备‌\n这些应用领域展示了立式多级不锈钢离心泵的多样性和重要性,其在不同行业中发挥着关键作用。",
                videoUrl: "",
                three_D_url: ""
            },
            8: {
                description: "单级管道泵‌是一种单吸单级离心泵,属于立式结构。其进出口在同一直线上,且进出口口径相同,外形仿似一段管道,因此得名。单机管道泵可以安装在管道的任何位置,具有结构紧凑、占地面积小、安装方便等特点‌",
                hangyeDisc:"单级管道泵适用于化工、石油、制药、工业行业",
                videoUrl: "",
                three_D_url: ""
            }
        }
    },
    2: {
        name: "容积式空压机",
        catalog: {
            1: {
                description: "是依靠压缩腔的内部容积缩小来提高气体或蒸气压力的压缩机,是压缩机的一类,常被用在制冷、空调及热泵等。压缩机是压缩气体以提高气体压力的机械,如压气机、气泵等,根据压缩气体的方式不同,可分为容积式压缩机和动力式压缩机。‌",
                hangyeDisc: "",
                videoUrl: "",
                three_D_url: ""
            }
        }
    },
    3: {
        name: "通风机",
        catalog: {
            1: {
                description: "通风机是依靠输入的机械能,提高气体压力并排送气体的机械,它是一种从动的流体机械。排气压力低于1.5×10^4帕。",
                hangyeDisc: "‌",
                videoUrl: "",
                three_D_url: ""
            }
        }
    },
    4: {
        name: "水冷机组",
        catalog: {
            1: {
                description: "冷水机组(又称:冷冻机、制冷机组、冰水机组、冷却设备)是一个制冷设备。在制冷行业中分为风冷式冷水机组和水冷式冷水机组两种,根据压缩机又分为螺杆式冷水机组、涡旋式冷水机组、离心式冷水机组。",
                hangyeDisc: "",
                videoUrl: "",
                three_D_url: ""
            }
        }
    },
    7: {
        name: "电机",
        catalog: {
            1: {
                description: "",
                hangyeDisc: "",
                videoUrl: "",
                three_D_url: ""
            }
        }
    }
}
const loading_frm = ref(false)
const isLoadingBim = ref(false)
 
//BimObj为测试数据可删除
const BimObj = {
    1: {
        requestPath: "http://60.188.55.38:85/v3/ModelLibrary/GetProductDimList",
        filePath: "http://60.188.55.38:82/Data/Series1/BIM/FL/DIM.fbx",
        settingPath: "http://60.188.55.38:82/Data/Series1/BIM/FL/DIM.json",
        SeriesID: 1,
        LawID: 2,
        FileName: 'AS1-20'
 
    }
}
 
const route = useRoute()
const router = useRouter()
 
const model3dCtrl = ref(null)
const currentPage = ref(1)
const activeTab = ref('properties')
const searchForm = reactive({
    model: '',
    flow: '',
    head: '',
    energyLevel: 0,
})
 
const tableData = ref([])
 
const catalogItemList = ref([])
 
const m_paginationConfig = reactive({
    currentPage: 1,
    pageSize: 10,
})
 
const fromType = ref(null)
const catalogType = ref(1)
const seriesID = ref(1)
const catalogID = ref(1)
 
const hasBimFile = ref(false)
const m_curSeriesNode = ref({
    PhysicalPicturePath: "",
    Tip: "",
    Price: 0,
    EnergyEfficiencyClass: "",
    RecordNumber: "",
    RecordTime: "",
    ModelType: "",
    CompanyName: "",
    CertificatePath: "",
    Model: "",
    Id: "",
    CatalogID: 1
})
 
// 将方法转换为计算属性
const currentDescription = computed(() => {
    if (!m_curSeriesNode.value?.CatalogID || !catalogType.value) {
        return '';
    }
    return DescListByType[catalogType.value]?.catalog[catalogID.value];
});
 
onMounted(() => {
    // TODO: 获取产品列表
    fromType.value = route.query.ft ?? null;
    catalogType.value = route.query.type ?? 1;
    seriesID.value = route.query.sid ?? null
    catalogID.value = route.query.cid ?? null
    initCatalogList()
 
})
 
// 初始化类型列表数据
const initCatalogList = () => {
    const catalogTag = catalogType.value;
    axios({
        method: 'get',
        url: m_RequestDataObj[catalogTag].requestPath,
    })
        .then((res) => {
            let result = res.data.SeriesList;
            result = result.map((item: any, index: number) => {
                return {
                    Id: item.Id,
                    Type: item.Type,
                    ModelType: item.ModelType,
                    Model: item.Model,
                    SeriesID: item.SeriesID,
                    CatalogID: item.CatalogueID ?? 1,
                    CompanyName: item.CompanyName,
                    RecordNumber: item.RecordNumber,
                    EnergyEfficiencyClass: item.EnergyEfficiencyClass,
                    RecordTime: item.RecordTime,
                    PhysicalPicturePath: 'static/EecProductData/' + item.PhysicalPicturePath,
                    CertificatePath: `static/EecProductData/${item.CertificatePath}`,
                    Tip: `备案时间:${item.RecordTime} \n 备案号:${item.RecordNumber}`,
                };
            });
            const curSeries = result.filter(item => {
                return item.SeriesID === Number(seriesID.value)
            })
            m_curSeriesNode.value = curSeries[0]
            initPumpList()
            catalogItemList.value = result;
        })
        .catch((err) => {
            console.log(err)
        });
};
const initPumpList = () => {
    if(!m_pumpList[seriesID.value])return
    axios({
        method: 'get',
        url: m_pumpList[seriesID.value].requestPath,
    })
        .then((res) => {
            let result = res.data;
            result = result.map(item => {
                return {
                    id: item.id,
                    seriesID: item.sid,
                    model: item.model,
                    flow: item.flow,
                    head: item.head,
                    speed: item.speed,
                    eta: item.eta,
                    eec: item.nengxiao_level == "" ? -1 : Number(item.nengxiao_level)
                }
            })
            catalogItemList.value = result
            tableData.value = getSelectPageData(result);
        }).catch(err => {
            console.log(err)
        })
}
 
const handleSeriesClick = (row: object) => {
    // 找到当前点击的产品
    const currentProduct = catalogItemList.value.find((item) => item.id === row.id);
    console.log(currentProduct,m_curSeriesNode.value,418)
    currentProduct.CompanyName = m_curSeriesNode.value.CompanyName;
    currentProduct.ModelType = m_curSeriesNode.value.ModelType
    currentProduct.PhysicalPicturePath = m_curSeriesNode.value.PhysicalPicturePath
    currentProduct.RecordNumber = m_curSeriesNode.value.RecordNumber
    currentProduct.type = m_curSeriesNode.value.Type;
    currentProduct.CertificatePath = m_curSeriesNode.value.CertificatePath
    if (currentProduct) {
        // 保存产品信息到localStorage
        localStorage.setItem('currentProduct', JSON.stringify(currentProduct));
    }
    router.push({
        path: `/product/${currentProduct.id}`,
    });
};
 
const handlePageChange = (val: number) => {
    m_paginationConfig.currentPage = val;
    let allTableData = catalogItemList.value;
    let pagingData = getSelectPageData(allTableData);
    tableData.value = pagingData;
}
const handleSizeChange = (val: number) => {
    m_paginationConfig.pageSize = val;
    let allTableData = catalogItemList.value;
    let pagingData = getSelectPageData(allTableData);
    tableData.value = pagingData;
}
const changeTab = (value) => {
    console.log('我被调用了', value)
    if (value === 'bim' && !isLoadingBim.value) {
            loadModel3dView();
    }
 
}
const loadModel3dView = () => {
    if(!BimObj[seriesID.value]){
        hasBimFile.value = false; 
        return;
    }
    const fbx_file_path = BimObj[seriesID.value].filePath;
    hasBimFile.value = true; 
    loading_frm.value = true;
    nextTick(()=>{
        model3dCtrl.value.loadModel(fbx_file_path, true, (val) => {
        setModelSizeValue();
        loading_frm.value = false;
        isLoadingBim.value = true;
    });
    })
 
}
 
const setModelSizeValue = () => {
    let lawNode = BimObj[seriesID.value];
    let SeriesID = lawNode.SeriesID;
    let LawID = lawNode.LawID;
    let fileName = lawNode.FileName;
    if (SeriesID == null || SeriesID == 0) return;
    if (LawID == null || LawID == 0) return;
    axios({
        method: 'get',
        url: lawNode.requestPath,
        params: {
            SeriesID: SeriesID,
            LawID: LawID,
            FileName: fileName
        }
    }).then((res) => {
        let resData = res.data;
        console.log(resData, 300)
        model3dCtrl.value.setDimDisplay(true);
        model3dCtrl.value.updateSizeValue(resData.Data);
    }).catch(err => {
        console.log(err)
    })
}
 
const handleSearch = () => {
    let filteredData = [...catalogItemList.value];
 
    // 按型号筛选
    if (searchForm.model) {
        filteredData = filteredData.filter(item =>
            item.model.toLowerCase().includes(searchForm.model.toLowerCase())
        );
    }
 
    // 按能效等级筛选
    if (searchForm.energyLevel !== 0) {
        filteredData = filteredData.filter(item =>
            item.eec === searchForm.energyLevel
        );
    }
 
    // 重置分页到第一页
    m_paginationConfig.currentPage = 1;
 
    // 更新表格数据
    tableData.value = getSelectPageData(filteredData);
}
 
const handleReset = () => {
    // 重置表单
    searchForm.model = ''
    searchForm.energyLevel = 0
 
    // 重置分页到第一页
    m_paginationConfig.currentPage = 1;
 
    // 重置表格数据为原始数据
    tableData.value = getSelectPageData(catalogItemList.value);
}
 
//获取分页数据
const getSelectPageData = (list: any) => {
    let filterList = list.slice(
        (m_paginationConfig.currentPage - 1) * m_paginationConfig.pageSize,
        m_paginationConfig.currentPage * m_paginationConfig.pageSize
    );
    return filterList;
};
</script>
 
<style scoped>
.el-table {
    @apply w-full;
}
 
:deep(.el-table__header-wrapper) th {
    background-color: #f1f1f1 !important;
}
 
:deep(.el-table__header) th {
    background-color: #f1f1f1 !important;
}
 
.eec-level-div {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 34px;
    position: relative;
    margin-top: -2px;
}
 
.eec-level-div img {
    height: 100%;
}
 
.eec-numb {
    position: absolute;
    left: 13px;
    top: 4px;
    color: #008000;
}
 
.eec-level-name {
    /* position: absolute; */
    left: 31px;
    top: 3.5px;
    color: #008000;
    font-size: 12px;
}
</style>