map/ui/dasadmin/src/views/backend/realData/index.vue
2024-10-29 16:20:19 +08:00

708 lines
24 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="default-main">
<el-dialog v-model="visible" title="测点选择" width="1000" :before-close="handleClose" :show-close="false">
<!-- <el-transfer v-model="value" :data="data" />-->
<el-row :gutter="20">
<el-col :span="14">
<div class="transferLeft">
<div class="transferHeader">
<span class="transferTitle">可添加的测点</span>
<el-radio-group v-model="radioActiveName" @change="handleradioChange">
<el-radio value="138">模拟量</el-radio>
<el-radio value="140">状态量</el-radio>
</el-radio-group>
</div>
<el-main class="mainPart">
<el-table class="tablePart"
ref="tableRef"
:data="modalTbleData"
@selectionChange="selectTable"
:row-key="getRowKey">
<el-table-column type="selection" width="55" :reserve-selection="true"/>
<el-table-column prop="porder" label="序号" width="60" />
<el-table-column prop="attributeCode" sortable label="名称" />
<el-table-column prop="attributeName" sortable label="描述" />
</el-table>
<div class="mainFooter" style="display: flex; justify-content: left">
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="currentPageSize"
:total="pageTotal"
:page-sizes="pagePagination"
background
:pager-count="5"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
layout="prev, pager, next,sizes"
></el-pagination>
</div>
</el-main>
</div>
</el-col>
<el-col :span="10">
<div class="transferRight">
<div class="transferHeader">
<span class="transferTitle">已选择<span>{{Statistic}}</span>项</span>
<div @click="clearList" style="color: rgb(0, 100, 170);cursor: pointer;">清空</div>
</div>
<el-main class="transferMain">
<el-scrollbar>
<div class="selectItem" v-for="(item, index) in multipleSelection"
:key="item.attributeCode">
{{item.attributeName}}
<div>
<el-icon :size="20" @click="moveUp(index)"><Top /></el-icon>
<el-icon :size="20" @click="moveDown(index)"><Bottom /></el-icon>
</div>
</div>
</el-scrollbar>
</el-main>
<div class="mainFooter" style="display: flex; justify-content: left">
<el-pagination
v-model:current-page="selectcurrentPage"
v-model:page-size="selectcurrentPageSize"
:total="selectpageTotal"
background
:pager-count="4"
@size-change="selecthandleSizeChange"
@current-change="selecthandleCurrentChange"
layout="prev, pager, next"
></el-pagination>
</div>
</div>
</el-col>
</el-row>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="sureBtn">确定</el-button>
<el-button @click="visible = false">关闭</el-button>
</div>
</template>
</el-dialog>
<div class="realConter">
<div class="header">
<el-button type="primary" :icon="Crop" class="defaultBtn" @click="openMeasure">测点选择</el-button>
<el-button style="color: rgb(0, 100, 170);;" :icon="Download" class="defaultBtn" @click="downFun(tableColumn,tableData)">数据导出</el-button>
<div class="selectPart">
<span>自动更新:</span>
<el-switch
v-model="autoUpdate"
class="ml-2"
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
></el-switch>
</div>
</div>
<div class="realTable">
<el-table height="100%" :data="tableData">
<template v-for="item in tableColumn">
<el-table-column :prop="item.prop" :label="item.label" :align="item.align" />
<!-- <el-table-column v-if="item.custom === 'default'" :prop="item.prop" :label="item.label" :align="item.align" />
<el-table-column v-if="item.custom === 'header'" :prop="item.prop" :label="item.label+item.unit" :align="item.align" />-->
</template>
</el-table>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {Crop,Download,Top,Bottom} from '@element-plus/icons-vue'
import {onMounted, onUnmounted, reactive, ref, watch,computed,nextTick} from 'vue'
import {ElMessage} from 'element-plus'
import {equipList,getModelAttributeList,getsnapshotData} from "/@/api/backend/realData/request.ts";
const tableData = ref()
const tableItem0: any = [
{
label: '风机列表',
unit:' ',
prop: 'code',
align: 'center',
custom: 'default',
name:''
}]
const tableItem1: any = [
{
label: '风速 (m/s)',
unit:' (m/s)',
prop: 'iwindspeed',
align: 'center',
custom: 'header',
name:'iWindSpeed',
title: '风速'
},
{
label: '有功功率 (MW)',
unit:' (MW)',
prop: 'igenpower',
align: 'center',
custom: 'header',
name:'iGenPower',
title: '有功功率'
},
{
label: '日发电量 (kWh)',
unit:' (kWh)',
prop: 'ikwhthisday',
align: 'center',
custom: 'header',
name:'iKWhThisDay',
title: '日发电量'
},
{
label: '总发电量 (万kWh)',
unit:' (万kWh)',
prop: 'ikwhoverall',
align: 'center',
custom: 'header',
name:'iKWhOverall',
title: '总发电量'
},
{
label: '机舱角度',
unit:'',
prop: 'ivanedirection',
align: 'center',
custom: 'header',
name:'iVaneDirection',
title: '机舱角度'
},
{
label: '叶轮转速 (rmp)',
unit:' (rmp)',
prop: 'irotorspeed',
align: 'center',
custom: 'header',
name:'iRotorSpeed',
title: '叶轮转速'
},
{
label: '发电机转速 (rmp)',
unit:' (rmp)',
prop: 'igenspeed',
align: 'center',
custom: 'header',
name:'iGenSpeed',
title: '发电机转速'
},
{
label: '机舱温度 (℃)',
unit:' (℃)',
prop: 'itempnacelle_1sec',
align: 'center',
custom: 'header',
name:'iItemPnAcelle_1Sec',
title: '机舱温度'
},
{
label: '主油路压力 (kpa)',
unit:' (kpa)',
prop: 'ihydrpress',
align: 'center',
custom: 'header',
name:'iHydrPress',
title: '主油路压力'
},
{
label: '变桨角度',
unit:' ',
//prop: 'ipitchangle1',
prop: 'ipitchangle',
align: 'center',
custom: 'header',
name:'iPitchAngle1',
title: '变桨角度'
}
]
const tableColumn=ref(
[...tableItem0,...tableItem1]
)
const deviceList = ref()
const tableList=ref()
const modalTbleData=ref<any[]>([])
const devicelistData = reactive({
objectType: 10002,
})
const objectType= ref(10002);
const iotModelId=ref()
const radioActiveName=ref('138')
const selectedIndex=ref(0)
const deviceQuery = (data: any) => {
equipList(data).then((res) => {
deviceList.value = res.data
tableData.value = res.data
iotModelId.value=res.data[0].iotModelId
defaultdeviceQuery()
})
}
const defaultdeviceQuery = () => {
const deviceId=deviceList.value.map((item) => item.id);
let attributesCode:any[]=[]
deviceId.forEach((item,index) => {
objparms.deviceId=item
attributesCode=tableColumn.value.map((item1)=>item1.prop)
attributesCode.push('iPitchAngle1','iPitchAngle2', 'iPitchAngle3')
objparms.attributes=attributesCode
snapshotParms.push({...objparms})
})
getsnapshotData(snapshotParms).then((res) => {
if (res.code == 200) {
const tsnapshotVoObject: any = res.data;
const tsnapshotVoMap = new Map(Object.entries(tsnapshotVoObject));
const updatedTableData = tableColumn.value.reduce((acc, item1) => {
acc.forEach((item, i) => {
const itemKey = item.id;
if (tsnapshotVoMap.has(itemKey)) {
const tsnapshotVoItem = tsnapshotVoMap.get(itemKey);
//const attributeCodeLower = item1.attributeCode?.toLowerCase();
const attributeCodeLower = item1.prop;
if(attributeCodeLower!='code'){
if (attributeCodeLower) {
const ipitchangle=Math.min(tsnapshotVoItem.ipitchangle1, tsnapshotVoItem.ipitchangle2, tsnapshotVoItem.ipitchangle3)
let ipitchanglevalue;
if(isNaN(ipitchangle)){
ipitchanglevalue='-'
}else{
ipitchanglevalue=ipitchangle !== undefined ? (ipitchangle % 1 === 0 ? ipitchangle : ipitchangle.toFixed(3)) : '-';
}
const value=tsnapshotVoItem[attributeCodeLower];
const formattedValue = value !== undefined ? (value % 1 === 0 ? value : value.toFixed(3)) : '-';
acc[i] = { ...item, [attributeCodeLower]: formattedValue,ipitchangle:ipitchanglevalue};
}
}
}
});
return acc;
}, [...tableData.value]);
tableData.value = updatedTableData;
} else {
ElMessage.error({
message: res.msg,
type: 'error',
})
}
})
}
const queryListData = reactive({
pageSize: 20,
pageNum: 1,
iotModelId: '',
attributeType: '138'
})
const modelAttributeList=(data: any) =>{
getModelAttributeList(data).then((res) => {
if (res.code == 200) {
modalTbleData.value = res.rows
pageTotal.value = res.total
} else {
ElMessage.error({
message: res.msg,
type: 'error',
})
}
})
}
interface TableType {
attributeCode:string
attributeName:string
attributeType:number
dataType:string
highSpeed:number
id:string
iotModelId:string
porder:number
revision:number
subSystem:string
unit:string
visible:number | null
}
const selectList=ref([])
const getSel = () => {
debugger
selectList.value=[]
tableColumn.value.forEach(item => {
if (item.prop) {
if(item.prop!='code'){
selectList.value.push({
attributeName: item.title,
attributeCode: item.name,
});
}
}
});
//tableRef.value.clearSelection()
if (selectList.value.length > 0) {
//setTimeout(()=>{
selectList.value.forEach((item1, index1) => {
tableRef.value.toggleRowSelection(item1, true);
});
//},0)
}
};
const tableRef=ref()
const multipleSelection = ref<TableType[]>([])
const Statistic = computed(() => multipleSelection.value.length)
const selectTable = (selected: TableType[] | null) => {
if (!selected) {
console.error('Selected is null or undefined')
return
}
if (Array.isArray(selected) && Array.isArray(multipleSelection.value)) {
const selectedAttributeCodes = new Set(selected.map(item => item?.attributeCode));
multipleSelection.value = multipleSelection.value.filter(item => selectedAttributeCodes.has(item?.attributeCode));
selected.forEach((item, index) => {
if (!multipleSelection.value.some(item1 => item1.attributeCode === item.attributeCode)) {
multipleSelection.value.push(item);
}
});
}
//multipleSelection.value = selected
}
//const getRowKey = (row) => row.id;
const getRowKey = (row) => row.attributeCode;
const visible = ref(false)
const openMeasure=() =>{
visible.value=true
queryListData.iotModelId=iotModelId.value
queryListData.attributeType=radioActiveName.value
modelAttributeList(queryListData)
nextTick(() => {
//tableRef.value.clearSelection()
getSel()
})
}
const moveUp = (index:number) => {
if (index > 0) {
const temp = multipleSelection.value[index];
multipleSelection.value[index] = multipleSelection.value[index - 1];
multipleSelection.value[index - 1] = temp;
selectedIndex.value = index - 1;
}
};
const moveDown = (index:number) => {
if (index < multipleSelection.value.length - 1) {
const temp = multipleSelection.value[index];
multipleSelection.value[index] = multipleSelection.value[index + 1];
multipleSelection.value[index + 1] = temp;
selectedIndex.value = index + 1;
}
};
const clearList=() => {
Statistic.value=0
multipleSelection.value = [];
tableRef.value.clearSelection()
queryListData.iotModelId=iotModelId.value
queryListData.attributeType=radioActiveName.value
modelAttributeList(queryListData)
}
const handleradioChange=() => {
//multipleSelection.value = [];
queryListData.iotModelId=iotModelId.value
queryListData.attributeType=radioActiveName.value
modelAttributeList(queryListData)
}
const autoUpdate = ref(false)
const autoUpdateInterval = ref<any>(null)
watch(autoUpdate, (newVal: boolean) => {
if (newVal) {
if (autoUpdateInterval.value) return
ElMessage.success('开启自动刷新')
autoUpdateInterval.value = setInterval(() => {
defaultdeviceQuery()
//getTableData()
}, 2000)
} else {
ElMessage.warning('关闭自动刷新')
clearInterval(autoUpdateInterval.value)
autoUpdateInterval.value = null
}
})
const currentPage = ref(1)
//const currentPageSize = ref(20)
const currentPageSize = ref(20)
const pageTotal = ref(0)
const pagePagination = ref([20, 50, 100])
const handleSizeChange = (val: number) => {
queryListData.pageSize = val
queryListData.iotModelId=iotModelId.value
queryListData.attributeType=radioActiveName.value
modelAttributeList(queryListData)
}
const handleCurrentChange = (val: number) => {
queryListData.pageNum = val
queryListData.iotModelId=iotModelId.value
queryListData.attributeType=radioActiveName.value
modelAttributeList(queryListData)
}
const selectcurrentPage = ref(1)
const selectcurrentPageSize = ref(10)
const selectpageTotal = ref(0)
const selecthandleSizeChange = (val: number) => {
}
const selecthandleCurrentChange = (val: number) => {
}
const handleClose = (done: () => void) => {
visible.value = false
}
const snapshotParms = reactive([])
const objparms = reactive({
deviceId: '',
attributes: [],
})
const getTableData = () => {
debugger
const deviceId=deviceList.value.map((item) => item.id);
const tableColumnEnds = ref([]);
const tableColumnup = ref([]);
const tableColumnMap = new Map();
tableColumn.value.forEach(item1 => {
if (item1.prop) {
tableColumnMap.set(item1.prop, item1);
tableColumnup.value.push({
label: item1.label,
unit:item1.unit,
prop: item1.prop,
align: 'center',
custom: 'header',
});
}
});
if(multipleSelection.value.length === 0){
tableColumn.value = [...tableItem0, ...tableColumnEnds.value];
}else{
multipleSelection.value.forEach(item => {
if (item.attributeCode) {
const attributeCodeLower = item.attributeCode.toLowerCase();
//if (!tableColumnMap.has(attributeCodeLower)) {
if(attributeCodeLower==='ipitchangle1'||attributeCodeLower==='ipitchangle2'||attributeCodeLower==='ipitchangle3'){
tableColumnEnds.value.push({
label: '变桨角度',
unit:'',
prop: 'ipitchangle',
align: 'center',
custom: 'header',
});
}else{
tableColumnEnds.value.push({
label: item.attributeName+'\n'+item.unit,
unit:item.unit,
prop: attributeCodeLower,
align: 'center',
custom: 'header',
name: item.attributeCode,
title: item.attributeName,
});
}
//}
}
});
tableColumn.value = [...tableItem0, ...tableColumnEnds.value];
//tableColumn.value = [...tableColumnup.value, ...tableColumnEnds.value];
}
//tableColumn.value = [...tableItem0, ...tableColumnEnds.value];
deviceId.forEach((item,index) => {
objparms.deviceId=item
objparms.attributes=multipleSelection.value.map((item) => item.attributeCode)
snapshotParms.push({...objparms})
})
getsnapshotData(snapshotParms).then((res) => {
if (res.code == 200) {
const tsnapshotVoObject: any = res.data;
multipleSelection.value.map((item1: any) => {
tableData.value.forEach((item: any, i: number, arr: any) => {
for (const itemKey in tsnapshotVoObject) {
if (item.id === itemKey) {
const attributeCodeLower = item1.attributeCode?.toLowerCase();
const ipitchangle='';
const ipitchangle1=Math.min(item1.ipitchangle1, item1.ipitchangle2, item1.ipitchangle3)
let ipitchanglevalue;
if(isNaN(ipitchangle1)){
ipitchanglevalue='-'
}else{
ipitchanglevalue=ipitchangle1 !== undefined ? (ipitchangle1 % 1 === 0 ? ipitchangle1 : ipitchangle1.toFixed(3)) : '-';
}
const value = tsnapshotVoObject[itemKey]?.[attributeCodeLower];
const formattedValue =value ? (value % 1 === 0 ? value : value.toFixed(3)) : '-';
arr[i] = { ...item, [attributeCodeLower]: formattedValue,[ipitchangle]: ipitchanglevalue};
}
}
});
})
} else {
ElMessage.error({
message: res.msg,
type: 'error',
})
}
})
}
const sureBtn = (done: () => void) => {
getTableData()
visible.value = false
}
const downFun=(tableColumn,tableData)=>{
debugger
const itemsWithoutAge = tableData.map(item => {
const { id, belongLine, iotModelId, location,madeinFactory,model,name,nominalCapacity,objectType,parentEquipmentId,remarks,standard,...rest } = item;
return rest;
});
let addobj = {}
tableColumn.map((v, i) => {
addobj['rowData' + i] = v.label
})
let tableDatadown = JSON.parse(JSON.stringify(itemsWithoutAge))
tableDatadown.unshift(addobj)
let str = ``;
for(let i = 0; i < tableDatadown.length; i++) {
for(let item in tableDatadown[i]) {
if (typeof tableDatadown[i][item] === 'string') {
tableDatadown[i][item] = tableDatadown[i][item].replace(/[\n,]/g, match => match === '\n' ? ' ' : '');
} else {
console.warn(`tableDatadown[${i}][${item}] is not a string`);
}
str += `${tableDatadown[i][item] + '\t'},`;
}
str += '\n';
}
let uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str);
let link = document.createElement('a');
link.href = uri;
link.download = Date.now() + ".csv";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
onUnmounted(() => {
autoUpdateInterval.value && clearInterval(autoUpdateInterval.value)
autoUpdateInterval.value = null
//selectList.value=[]
})
onMounted(() => {
deviceQuery(devicelistData)
//queryListData.pageSize=200
modelAttributeList(queryListData)
//tableRef.value.toggleRowSelection(modalTbleData.value[0], true);
})
</script>
<style scoped lang="scss">
$paginationHeight: 32px;
.default-main {
.realConter {
.header {
display: flex;
.el-button{
width: 140px;
height: 40px;
}
.selectPart{
display: flex;
align-items: center;
margin-left: 20px;
}
}
.realTable{
margin-top: 20px;
}
}
.el-dialog{
.transferHeader{
height: 40px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
color: #333333;
background: #F7F9FC;
border-bottom: 1px solid #E1EDF6;
border-radius: 6px 6px 0 0;
}
.transferLeft{
width: 550px;
height: 700px;
border: 1px solid #E1EDF6;
border-radius: 6px;
.mainPart{
padding: 10px;
height: 625px;
overflow: hidden;
.tablePart {
height: calc(100% - $paginationHeight);
}
.mainFooter{
margin-top: 10px;
}
}
}
.transferRight{
height: 700px;
border: 1px solid #E1EDF6;
border-radius: 6px;
.transferMain{
height: 600px;
/*padding: 10px;*/
padding:0;
::v-deep .el-table__row{
height: 40px;
padding: 0 20px;
background: #EFF0F1;
border-radius: 4px;
}
.selectItem{
height: 40px;
padding: 0 20px;
background: #EFF0F1;
border-radius: 4px;
margin: 10px;
list-style: none;
display: flex;
justify-content: space-between;
align-items: center;
.el-icon{
cursor: pointer;
}
}
}
.mainFooter{
padding: 10px;
}
}
.dialog-footer{
text-align: center;
.el-button{
width: 120px;
height: 40px;
}
}
}
}
</style>