Merge remote-tracking branch 'origin/main'

This commit is contained in:
fengrong 2024-11-26 17:38:14 +08:00
commit b1389fab4e
4 changed files with 200 additions and 76 deletions

View File

@ -38,48 +38,48 @@
<div class="cardLabel">实时预览</div>
<div class="overviewDataSection" ref="listContainer">
<div class="overviewDataSectionItem">
<span class="realLeft">网侧A相电压</span>
<span class="reafRight">{{ overviewData.iul1_690v }}</span>
<span class="realLeft">机组运行状态</span>
<span class="reafRight">{{ realTimeDataState }}</span>
</div>
<div class="overviewDataSectionItem">
<span class="realLeft">网侧B相电压</span>
<span class="reafRight">{{ overviewData.iul2_690v }}</span>
<span class="realLeft">风速</span>
<span class="reafRight">{{ overviewData.iwindspeed }}</span>
</div>
<div class="overviewDataSectionItem">
<span class="realLeft">网侧C相电压</span>
<span class="reafRight">{{ overviewData.iul3_690v }}</span>
<span class="realLeft">风向</span>
<span class="reafRight">{{ overviewData.iwinddirection }}</span>
</div>
<div class="overviewDataSectionItem">
<span class="realLeft">发电机转速</span>
<span class="reafRight">{{ overviewData.igenspeed }}</span>
</div>
<div class="overviewDataSectionItem">
<span class="realLeft">有功功率</span>
<span class="reafRight">{{ overviewData.igenpower }}</span>
</div>
<div class="overviewDataSectionItem">
<span class="realLeft">给定有功功率</span>
<span class="reafRight">{{ overviewData.iactivepowersetpointvalue }}</span>
</div>
<div class="overviewDataSectionItem">
<span class="realLeft">无功功率</span>
<span class="reafRight">{{ overviewData.ireactivepower }}</span>
</div>
<div class="overviewDataSectionItem">
<span class="realLeft">功率因素</span>
<span class="reafRight">{{ overviewData.icosphi }}</span>
<span class="realLeft">给定无功功率</span>
<span class="reafRight">{{ overviewData.ireactivepowersetpointvalue }}</span>
</div>
<div class="overviewDataSectionItem">
<span class="realLeft">主轴承温度A</span>
<span class="reafRight">{{ overviewData.itemprotorbeara_1sec }}</span>
<span class="realLeft">限电原因</span>
<span class="reafRight">{{ overviewData.powerlimitsource }}</span>
</div>
<div class="overviewDataSectionItem">
<span class="realLeft">主轴承温度B</span>
<span class="reafRight">{{ overviewData.itemprotorbeara_1sec }}</span>
<span class="realLeft">机舱位置</span>
<span class="reafRight">{{ overviewData.ivanedirection }}</span>
</div>
<div class="overviewDataSectionItem">
<span class="realLeft">总扭缆角度</span>
<span class="reafRight">{{ overviewData.icabletwisttotal }}</span>
</div>
<div class="overviewDataSectionItem">
<span class="realLeft">发动机驱动侧轴承温度</span>
<span class="reafRight">{{ overviewData.itempgenbearde_1sec }}</span>
</div>
<div class="overviewDataSectionItem">
<span class="realLeft">发动机非驱动侧轴承温度</span>
<span class="reafRight">{{ overviewData.itempgenbearnde_1sec }}</span>
<span class="realLeft">日发电量</span>
<span class="reafRight">{{ overviewData.ikwhthisday }}</span>
</div>
</div>
<div class="overviewDataBtn">
@ -326,17 +326,17 @@ let timer: any = null
let myTable = ref<TableInstance>()
const overviewData = reactive({
iul1_690v: '-',
iul2_690v: '-',
iul3_690v: '-',
// iturbineoperationmode: '-',
iwindspeed: '-',
iwinddirection: '-',
igenspeed: '-',
igenpower: '-',
iactivepowersetpointvalue: '-',
ireactivepower: '-',
icosphi: '-',
itemprotorbeara_1sec: '-',
itemprotorbearb_1sec: '-',
icabletwisttotal: '-',
itempgenbearde_1sec: '-',
itempgenbearnde_1sec: '-',
ireactivepowersetpointvalue: '-',
powerlimitsource: '-',
ivanedirection: '-',
ikwhthisday: '-',
})
const realTimeDataForSingle = ref<any>({
@ -1008,7 +1008,6 @@ const createRealTimeData = async () => {
{ type138: [], type140: [], type199: [] },
]
modelList.forEach((item: any) => {
const realVal = realData[item.attributeCode.toLowerCase()]
let val = getCutDecimalsValue(realVal)
if (enumStore.keys.includes(item.attributeCode)) {
@ -1018,7 +1017,11 @@ const createRealTimeData = async () => {
realTimeDataForSingle.value[item.attributeCode.toLowerCase()] = val === '-' ? val : val
}
if (overviewDatakeys.includes(item.attributeCode.toLowerCase())) {
overviewData[item.attributeCode.toLowerCase() as keyof typeof overviewData] = val === '-' ? val : val + item.unit
if (enumStore.keys.includes(item.attributeCode)) {
overviewData[item.attributeCode.toLowerCase() as keyof typeof overviewData] = val as string
} else {
overviewData[item.attributeCode.toLowerCase() as keyof typeof overviewData] = val === '-' ? val : val + item.unit
}
}
const showData = {
name: item.attributeName,
@ -1374,19 +1377,11 @@ const sendManualCommand = (type: 1 | 0) => {
const getAlarmList = () => {
const start = dayjs().startOf('day').toDate().getTime()
const end = dayjs().endOf('day').toDate().getTime()
console.log({
startTime: start,
endTime: end,
deviceCode: [route.query.deviceCode],
},'----------------------------------');
getAlarmListReq({
startTime: start,
endTime: end,
deviceCode: [route.query.deviceCode],
}).then((res) => {
console.log(res,'------------------------');
if (res.rows) {
tableData.value = res.rows.map((item: any) => {
return {

View File

@ -191,7 +191,14 @@
</template>
</el-dialog>
<el-dialog v-model="realDataLineChartVisible" title="实时曲线" @close="closeLineChart">
<RealDataChart :visible="realDataLineChartVisible" :id="clickRowId"></RealDataChart>
<RealDataChart ref="realDataChartRef" :visible="realDataLineChartVisible" :id="clickRowId"></RealDataChart>
<template #header>
<div>
<span style="font-size: 18px">实时曲线</span>
<el-button class="saveBtn" @click="saveLineChart" type="primary" plain>保存</el-button>
<el-button v-if="linePause" class="continueBtn" @click="continueLineChart" type="primary" plain>继续</el-button>
</div>
</template>
</el-dialog>
</template>
@ -203,7 +210,7 @@ import { getAirBlowerListReq, getBelongLineListReq } from '/@/api/backend/airBlo
import { CircleCheck, CircleClose, Loading, Crop, Download } from '@element-plus/icons-vue'
import { ElMessage, TableInstance, ElPopconfirm } from 'element-plus'
import { useRouter, useRoute } from 'vue-router'
import { getRealTimeState, getCutDecimalsValue } from './utils'
import { getRealTimeState, getCutDecimalsValue, getEnumToValue } from './utils'
import { sendCommandReq } from '/@/api/backend/control/request'
import { adminBaseRoutePath } from '/@/router/static/adminBase'
import { getRealValueListReq } from '/@/api/backend/deviceModel/request'
@ -380,6 +387,7 @@ const defaultColumn: TableColumnType[] = [
prop: 'name',
align: 'center',
custom: 'default',
width: 120,
},
{
label: '实时曲线',
@ -399,6 +407,7 @@ const defaultColumn: TableColumnType[] = [
prop: 'iturbineoperationmode',
align: 'center',
custom: 'default',
width: 100,
},
]
const dynamicColumn: TableColumnType[] = [
@ -493,7 +502,7 @@ const dynamicColumn: TableColumnType[] = [
width: 100,
},
{
label: '总发电量 (kWh)',
label: '总发电量 (kWh)',
prop: 'ikwhoverall',
align: 'center',
custom: 'header',
@ -547,7 +556,8 @@ const getTableData = () => {
const data = airBlowerIdList.map((id) => {
const realData: any = {}
Object.keys(res.data[id]).forEach((key) => {
realData[key] = getCutDecimalsValue(res.data[id][key])
const cutVal = getCutDecimalsValue(res.data[id][key])
realData[key] = getEnumToValue(key, cutVal)
})
const state = getRealTimeState(res.data[id])
return {
@ -565,7 +575,6 @@ const getTableData = () => {
if (airBlowerSelect.belongLine === '全部' && airBlowerSelect.iturbineoperationmode === 987654321) {
tableData.value = data
console.log(tableData.value)
} else {
const irn = tableData.value.map((item) => item.irn)
const result: TableDataObjType[] = []
@ -616,21 +625,23 @@ const selectTable = (selected: TableDataObjType[]) => {
const autoUpdate = ref(true)
const autoUpdateInterval = ref<any>(null)
watch(autoUpdate, (newVal: boolean) => {
if (newVal) {
if (autoUpdateInterval.value) return
ElMessage.success('开启自动刷新')
autoUpdateInterval.value = setInterval(() => {
getTableData()
}, 2000)
} else {
if (realDataLineChartVisible.value) {
ElMessage.warning('关闭自动刷新')
watch(
() => autoUpdate.value,
(newVal: boolean) => {
if (newVal) {
if (autoUpdateInterval.value) return
autoUpdateInterval.value = setInterval(() => {
getTableData()
}, 2000)
} else {
clearInterval(autoUpdateInterval.value)
autoUpdateInterval.value = null
}
clearInterval(autoUpdateInterval.value)
autoUpdateInterval.value = null
},
{
immediate: true,
}
})
)
const openWindTurbine = (row: TableDataObjType) => {
if (!router.hasRoute('windTurbine')) {
@ -758,16 +769,52 @@ const downFun = () => {
document.body.removeChild(link)
}
const realDataChartRef = ref()
const clickRowId = ref('')
const realDataLineChartVisible = ref(false)
const openLineChart = (row: TableDataObjType) => {
clickRowId.value = row.irn
realDataLineChartVisible.value = true
autoUpdate.value = false
linePause.value = false
}
const closeLineChart = () => {
autoUpdate.value = true
}
const linePause = ref(false)
const saveLineChart = () => {
const data = realDataChartRef.value?.saveChart()
linePause.value = true
const info = 'deviceCode:' + clickRowId.value + '\n'
let title = 'TimeStamp;'
let columns = ''
data.time.forEach((item: any, index: number) => {
columns += item
data.chartData.forEach((item: any) => {
if (index === 0) {
title += `${item.id};`
}
const val = item.data[index]
columns += `;${val}`
})
columns += '\n'
})
let str = info + title + '\n' + columns
let uri = 'data:text/plain;charset=utf-8,' + encodeURIComponent(str)
let link = document.createElement('a')
link.href = uri
link.download = clickRowId.value + 'ChartData' + '.txt'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
const continueLineChart = () => {
realDataChartRef.value?.continueChart()
linePause.value = false
}
onUnmounted(() => {
autoUpdateInterval.value && clearInterval(autoUpdateInterval.value)
autoUpdateInterval.value = null
@ -890,4 +937,8 @@ getBlongLineList()
height: 40px;
}
}
.saveBtn {
margin-left: 164px;
}
</style>

View File

@ -4,10 +4,16 @@
<el-col :span="8" class="leftPart">
<div class="leftHeader">
<el-button type="primary" @click="addPoint">添加测点</el-button>
<span>显示区间</span>
<el-select v-model="showTimeInterval">
<el-option label="5分钟" :value="300"></el-option>
<el-option label="10分钟" :value="600"></el-option>
<el-option label="15分钟" :value="900"></el-option>
</el-select>
</div>
<div class="leftMain">
<el-scrollbar>
<el-checkbox-group v-model="selectList">
<el-checkbox-group v-model="selectList" @change="changeCheck">
<el-checkbox
v-for="item in realDataList"
:key="item.prop"
@ -42,13 +48,14 @@ import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
import * as echarts from 'echarts'
import SelectPoint from '/@/views/backend/equipment/airBlower/selectPoint.vue'
import { getRealValueListReq } from '/@/api/backend/deviceModel/request'
import { dayjs } from 'element-plus'
import { dayjs, ElMessage } from 'element-plus'
import { getCutDecimalsValue } from './utils'
const props = withDefaults(defineProps<{ id: string; visible: boolean }>(), {
id: '',
visible: false,
})
const showTimeInterval = ref(300)
//#region
const defaultList = [
{
@ -109,18 +116,28 @@ const defaultList = [
]
//#endregion
const selectList = ref([])
watch(
() => selectList.value,
() => {
if (!timer && selectList.value[0]) {
createTimer()
}
if (selectList.value.length === 0) {
clearTimer()
chartInstance && chartInstance.clear()
}
const changeCheck = () => {
if (!timer && selectList.value[0]) {
createTimer()
}
)
if (selectList.value.length === 0) {
clearTimer()
chartInstance && chartInstance.clear()
}
}
// watch(
// () => selectList.value,
// () => {
// if (!timer && selectList.value[0]) {
// createTimer()
// }
// if (selectList.value.length === 0) {
// clearTimer()
// chartInstance && chartInstance.clear()
// }
// }
// )
const realDataList = ref<any[]>(JSON.parse(JSON.stringify(defaultList)))
const chartRef = ref()
@ -153,7 +170,7 @@ const getRandomDarkColor = () => {
}
const createChartData = (data: { [k: string]: number }, time: string) => {
if (realDataXAxis.length > 120) {
if (realDataXAxis.length > showTimeInterval.value) {
realDataXAxis.shift()
realDataSeries.forEach((item: any) => {
item.data.shift()
@ -183,16 +200,17 @@ const createChartData = (data: { [k: string]: number }, time: string) => {
}
const seriesData = attrCode.map((item) => {
const curVal = getCutDecimalsValue(data[item], 2)
if (lastSeriesId.includes(item)) {
const cur = realDataSeries.find((val: any) => val.id === item)
cur.data.push(data[item])
cur.data.push(curVal)
return cur
} else {
const info = realDataList.value.find((val) => val.prop === item)
const list = realDataSeries?.[0]?.data ?? []
const len = list.length
const fillData = new Array(len).fill('')
fillData.push(data[item])
fillData.push(curVal)
return {
id: item,
name: info.name + info.unit,
@ -343,6 +361,8 @@ const saveSelectPoint = () => {
}
})
realDataList.value = selectList
selectPointVisible.value = false
ElMessage.success('添加成功')
}
}
let timer: any = null
@ -357,6 +377,29 @@ const clearTimer = () => {
realDataSeries = []
realDataXAxis = []
}
const pauseState = ref(false)
const saveChart = () => {
timer && clearInterval(timer)
pauseState.value = true
return {
time: realDataXAxis,
chartData: realDataSeries,
}
}
const continueChart = () => {
pauseState.value = false
const fillVal = new Array(5).fill('')
realDataXAxis.push(...fillVal)
realDataSeries.forEach((item: any) => {
item.data.push(...fillVal)
})
createTimer()
}
defineExpose({
saveChart,
continueChart,
})
onMounted(() => {
if (selectList.value.length > 0) {
createTimer()
@ -389,7 +432,19 @@ watch(
height: 100%;
border-right: 1px solid #edf2fa;
.leftHeader {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
span {
margin-left: auto;
}
.el-select {
width: 100px;
}
:deep(.el-select__wrapper) {
width: 100px;
}
}
.leftMain {
width: 100%;
@ -418,4 +473,11 @@ watch(
}
}
}
.selectPointDialogFooter {
text-align: center;
.el-button {
width: 120px;
height: 40px;
}
}
</style>

View File

@ -1,3 +1,7 @@
import { useEnumStore } from '/@/stores/enums'
const enumStore = useEnumStore()
export const getRealTimeState = (data: any) => {
if (data.iturbineoperationmode) {
if (data.iturbineoperationmode > 1 && data.iturbineoperationmode < 6) {
@ -20,3 +24,15 @@ export const getCutDecimalsValue = (data: number, num = 3) => {
const n = Math.pow(10, num)
return data === 0 ? 0 : data ? (data % 1 === 0 ? data : Math.floor(data * n) / n) : '-'
}
export const getEnumToValue = (key: string, value: any) => {
const enumData: any = {}
enumStore.keys.forEach(item => {
enumData[item.toLowerCase()] = enumStore.data[item]
})
if (enumData[key]) {
return enumData[key]?.[value] ?? value
} else {
return value
}
}