<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>
|