统计查询

This commit is contained in:
geting 2024-12-19 10:27:39 +08:00
parent 0a70a9a7d8
commit 4e338a2c4a
4 changed files with 220 additions and 124 deletions

View File

@ -16,6 +16,15 @@ export const historyReq = (data: any) => {
})
}
export const windowReq = (data: any) => {
return createAxios({
url: '/api/data/windows',
method: 'post',
data: data,
timeout: 60 * 1000,
})
}
export const runAirBlowerReq = (
data: {
deviceId: string

View File

@ -4,6 +4,7 @@ export default {
trendComparison: '多机对比',
deviceId: '风机',
attributes: '测点名称',
calFunction: '方法',
interval: '间隔',
search: '查询',
import: '下载',

View File

@ -28,6 +28,17 @@
<el-option v-for="v in statAnalysisSelectOptions.interval" :key="v.value" :label="v.label" :value="v.value"></el-option>
</el-select>
</div>
<div class="selectPart">
<span>{{ t('statAnalysis.calFunction') }}</span>
<el-select
:disabled="statAnalysisSelect.interval == 'NONE'"
v-model="statAnalysisSelect.calFunction"
:placeholder="'请选择' + t('statAnalysis.calFunction')"
class="statAnalysisSelect"
>
<el-option v-for="v in statAnalysisSelectOptions.calFunction" :key="v.value" :label="v.label" :value="v.value"></el-option>
</el-select>
</div>
<el-button class="addline" type="primary" :icon="Plus" @click="addTime()"> 增加时间</el-button>
</div>
<div class="topRight">
@ -99,7 +110,7 @@
<script setup lang="ts">
import { reactive, ref, onMounted, markRaw } from 'vue'
import { useI18n } from 'vue-i18n'
import { queryWindTurbinesPages, historyReq, trendAnalyseExport } from '/@/api/backend/statAnalysis/request'
import { queryWindTurbinesPages, historyReq, trendAnalyseExport, windowReq } from '/@/api/backend/statAnalysis/request'
import { ElMessage } from 'element-plus'
import { DArrowRight, Plus, Delete, Close } from '@element-plus/icons-vue'
import MeasurementPage from './analysisAttributes.vue'
@ -115,6 +126,7 @@ const statAnalysisSelect = reactive({
interval: '1h',
time: '',
unit: '',
calFunction: 'interpolation',
})
const getFormattedDate = (offset: number) => {
const date = new Date()
@ -236,6 +248,14 @@ const option: any = {
},
series: [],
grid: {},
dataZoom: [
{
type: 'slider',
},
{
type: 'inside',
},
],
}
const statAnalysisSelectOptions: any = reactive({
@ -248,6 +268,12 @@ const statAnalysisSelectOptions: any = reactive({
{ label: '一天', value: '1d' },
{ label: '原始', value: 'NONE' },
],
calFunction: [
{ label: '插值', value: 'interpolation' },
{ label: '平均值', value: 'average' },
{ label: '最大值', value: 'max' },
{ label: '最小值', value: 'min' },
],
deviceId: [],
})
const customName = reactive([statAnalysisSelect.attributes + '1'])
@ -446,21 +472,36 @@ const statAnalysisOperate = () => {
},
],
interval: statAnalysisSelect.interval || '5m',
calFunction: statAnalysisSelect.calFunction,
startTime: new Date(time[0]).getTime(),
endTime: new Date(time[1]).getTime(),
}
const promise = new Promise((resolve, reject) => {
historyReq(requestData)
.then((res) => {
if (res.code == 200) {
resolve(res.data)
} else {
ElMessage.warning('查询失败')
}
})
.catch((error) => {
reject(error)
})
if (statAnalysisSelect.calFunction == 'interpolation') {
historyReq(requestData)
.then((res) => {
if (res.code == 200) {
resolve(res.data)
} else {
ElMessage.warning('查询失败')
}
})
.catch((error) => {
reject(error)
})
} else {
windowReq(requestData)
.then((res) => {
if (res.code == 200) {
resolve(res.data)
} else {
ElMessage.warning('查询失败')
}
})
.catch((error) => {
reject(error)
})
}
})
promises.push(promise)
}
@ -474,52 +515,56 @@ const historyDataReq = (promises: any) => {
isLoading.value = false
const deviceId = statAnalysisSelect.deviceId
const attributeCode = statAnalysisSelect.attributeCode
results.forEach((res: any, index: number) => {
const resData = (res && deviceId in res && res[deviceId][attributeCode]) || undefined
if (!resData['values'].length) {
ElMessage.info(`${customName[index]}数据为空`)
return
}
const alltimes = getTimestamps(
new Date(times[index][0]).getTime(),
new Date(times[index][1]).getTime(),
statAnalysisSelect.interval || '5m'
)
const fillData = fillMissingData(alltimes, resData)
const xData = fillData['times']
const yData = fillData['values']
xDatas.push({
series: String(customName[index]),
data: xData,
if (results.length) {
results.forEach((res: any, index: number) => {
const resData = (res && deviceId in res && res[deviceId][attributeCode]) || undefined
if (!resData['values'].length) {
ElMessage.info(`${customName[index]}数据为空`)
return
}
const alltimes = getTimestamps(
new Date(times[index][0]).getTime(),
new Date(times[index][1]).getTime(),
statAnalysisSelect.interval || '5m'
)
const fillData = fillMissingData(alltimes, resData)
const xData = fillData['times']
const yData = fillData['values']
xDatas.push({
series: String(customName[index]),
data: xData,
})
option.tooltip = {
show: true,
trigger: 'axis',
formatter: function (params: any) {
return params
.map((item: any) => {
const matchData = xDatas.filter((x: any) => x.series == item.seriesName)
const x = timestampToTime(matchData[0]['data'][item.dataIndex])
return `${item.marker}${item.seriesName} (${x}): ${item.data.value}${statAnalysisSelect.unit}`
})
.join('<br/>')
},
}
option.xAxis.data = Array.from({ length: xData.length }, (_, index) => index)
const seriesData = {
name: customName[index],
type: 'line',
data: yData.map((value: any) => ({
value: getCutDecimalsValue(value, 2),
})),
smooth: true,
symbolSize: 5,
symbol: 'circle',
}
option.legend.data.push(customName[index])
option.series.push(seriesData)
chart.value.setOption(option)
})
option.tooltip = {
show: true,
trigger: 'axis',
formatter: function (params: any) {
return params
.map((item: any) => {
const matchData = xDatas.filter((x: any) => x.series == item.seriesName)
const x = timestampToTime(matchData[0]['data'][item.dataIndex])
return `${item.marker}${item.seriesName} (${x}): ${item.data.value}${statAnalysisSelect.unit}`
})
.join('<br/>')
},
}
option.xAxis.data = Array.from({ length: xData.length }, (_, index) => index)
const seriesData = {
name: customName[index],
type: 'line',
data: yData.map((value: any) => ({
value: getCutDecimalsValue(value, 2),
})),
smooth: true,
symbolSize: 5,
symbol: 'circle',
}
option.legend.data.push(customName[index])
option.series.push(seriesData)
chart.value.setOption(option)
})
} else {
ElMessage.warning('查询结果为空')
}
})
.catch((error) => {
isLoading.value = false
@ -547,7 +592,6 @@ const statAnalysisExport = () => {
requestData.push(devices)
}
})
console.log('🚀 ~ times.forEach ~ requestData:', requestData)
trendAnalyseExport(requestData).then((res: any) => {
const downloadUrl = window.URL.createObjectURL(res)
@ -729,6 +773,7 @@ const timestampToTime = (timestamp: any) => {
align-items: center;
height: 40px;
margin-right: 20px;
white-space: nowrap;
span {
margin-right: 10px;
}

View File

@ -20,6 +20,17 @@
<el-option v-for="v in statAnalysisSelectOptions.interval" :key="v.value" :label="v.label" :value="v.value"></el-option>
</el-select>
</div>
<div class="selectPart">
<span>{{ t('statAnalysis.calFunction') }}</span>
<el-select
:disabled="statAnalysisInterval == 'NONE'"
v-model="statAnalysisSelectcalFunction"
:placeholder="'请选择' + t('statAnalysis.calFunction')"
class="statAnalysisSelect"
>
<el-option v-for="v in statAnalysisSelectOptions.calFunction" :key="v.value" :label="v.label" :value="v.value"></el-option>
</el-select>
</div>
<el-button type="primary" :icon="Crop" class="addline" @click="openMeasure">测点选择</el-button>
</div>
<div class="topRight">
@ -129,7 +140,7 @@
<script setup lang="ts">
import { markRaw, reactive, ref, watch, nextTick, onMounted, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { queryWindTurbinesPages, historyReq, trendContrastExport } from '/@/api/backend/statAnalysis/request'
import { queryWindTurbinesPages, historyReq, trendContrastExport, windowReq } from '/@/api/backend/statAnalysis/request'
import { ElMessage, ElMenu } from 'element-plus'
import { DArrowRight, Plus, Crop, Close } from '@element-plus/icons-vue'
import * as echarts from 'echarts'
@ -139,6 +150,7 @@ import { getCutDecimalsValue } from '/@/views/backend/equipment/airBlower/utils'
const { t } = useI18n()
const statAnalysisInterval = ref('1h')
const statAnalysisSelectcalFunction = ref('interpolation')
const statAnalysisSelectOptions: any = reactive({
interval: [
{ label: '一分钟', value: '1m' },
@ -149,6 +161,12 @@ const statAnalysisSelectOptions: any = reactive({
{ label: '一天', value: '1d' },
{ label: '原始', value: 'NONE' },
],
calFunction: [
{ label: '插值', value: 'interpolation' },
{ label: '平均值', value: 'average' },
{ label: '最大值', value: 'max' },
{ label: '最小值', value: 'min' },
],
})
const getFormattedDate = (offset: number) => {
const date = new Date()
@ -189,6 +207,14 @@ const option: any = {
},
series: [],
grid: {},
dataZoom: [
{
type: 'slider',
},
{
type: 'inside',
},
],
}
const chart: any = ref(null)
@ -200,7 +226,6 @@ onMounted(() => {
queryWindTurbines().then((res) => {
selectedLeft.value = [tableDataLeft.value[0]]
getCompleteData().then((attrRes: any) => {
console.log('🚀 ~ getCompleteData ~ attrRes:', attrRes)
multipleSelection.value = [
{
attributeName: attrRes.attributeName,
@ -446,69 +471,85 @@ const historyDataReq = (data: any) => {
const selectAllDevices = [...selectedLeft.value, ...selectedMid.value, ...selectedRight.value].sort((a: any, b: any) => {
return a.index - b.index
})
historyReq(data)
.then((res) => {
isLoading.value = false
if (res.code == 200) {
const resData = res.data
const deviceIdKeys = Object.keys(resData)
if (deviceIdKeys.length) {
selectAllDevices.forEach((item: any) => {
if (!resData[item.irn]) {
ElMessage.info(`${item.name}没有数据`)
return
}
const deviceName = item.name
Object.keys(resData[item.irn]).forEach((val) => {
const attRow = multipleSelection.value.filter((value: any) => value.attributeCode === val)
const attName = attRow[0]['attributeName']
const unit = attRow[0]['unit']
const historyData = resData[item.irn][val]
const xData = historyData['times']
const yData = historyData['values']
if (!yData.length) {
ElMessage.info(`${deviceName + attName}数据为空`)
return
}
const seriesData = {
name: deviceName + attName,
type: 'line',
data: yData.map((value: any) => ({
value: getCutDecimalsValue(value, 2),
unit: unit, //
})),
smooth: true,
symbolSize: 5,
symbol: 'circle',
}
option.tooltip = {
show: true,
trigger: 'axis',
formatter: function (params: any) {
return params
.map((item: any) => {
return `${item.marker} ${item.seriesName} (${timestampToTime(xData[item.dataIndex])}): ${item.value} ${item.data.unit}`
})
.join('<br/>')
},
}
option.legend.data.push(deviceName + attName)
option.xAxis.data = xData.map((item: any) => timestampToTime(item))
option.series.push(seriesData)
chart.value.setOption(option)
})
})
}
} else {
if (statAnalysisSelectcalFunction.value == 'interpolation') {
historyReq(data)
.then((res) => {
handleRes(res, selectAllDevices)
})
.catch((error) => {
isLoading.value = false
ElMessage.warning('查询失败')
}
})
.catch((error) => {
isLoading.value = false
console.error(error)
ElMessage.warning(error)
})
console.error(error)
ElMessage.warning(error)
})
} else {
windowReq(data)
.then((res) => {
handleRes(res, selectAllDevices)
})
.catch((error) => {
isLoading.value = false
console.error(error)
ElMessage.warning(error)
})
}
}
const handleRes = (res: any, selectAllDevices: any) => {
isLoading.value = false
if (res.code == 200) {
const resData = res.data
const deviceIdKeys = Object.keys(resData)
if (deviceIdKeys.length) {
selectAllDevices.forEach((item: any) => {
if (!resData[item.irn]) {
ElMessage.info(`${item.name}没有数据`)
return
}
const deviceName = item.name
Object.keys(resData[item.irn]).forEach((val) => {
const attRow = multipleSelection.value.filter((value: any) => value.attributeCode === val)
const attName = attRow[0]['attributeName']
const unit = attRow[0]['unit']
const historyData = resData[item.irn][val]
const xData = historyData['times']
const yData = historyData['values']
if (!yData.length) {
ElMessage.info(`${deviceName + attName}数据为空`)
return
}
const seriesData = {
name: deviceName + attName,
type: 'line',
data: yData.map((value: any) => ({
value: getCutDecimalsValue(value, 2),
unit: unit, //
})),
smooth: true,
symbolSize: 5,
symbol: 'circle',
}
option.tooltip = {
show: true,
trigger: 'axis',
formatter: function (params: any) {
return params
.map((item: any) => {
return `${item.marker} ${item.seriesName} (${timestampToTime(xData[item.dataIndex])}): ${item.value} ${item.data.unit}`
})
.join('<br/>')
},
}
option.legend.data.push(deviceName + attName)
option.xAxis.data = xData.map((item: any) => timestampToTime(item))
option.series.push(seriesData)
chart.value.setOption(option)
})
})
}
} else {
isLoading.value = false
ElMessage.warning('查询失败')
}
}
const statAnalysisExport = () => {
@ -531,9 +572,8 @@ const getRequestData = () => {
interval: statAnalysisInterval.value || '5m',
startTime: new Date(statAnalysisTime.value[0]).getTime(),
endTime: new Date(statAnalysisTime.value[1]).getTime(),
calFunction: statAnalysisSelectcalFunction.value,
}
console.log('🚀 ~ getRequestData ~ requestData:', requestData)
return requestData
}
@ -599,6 +639,7 @@ const timestampToTime = (timestamp: any) => {
align-items: center;
height: 40px;
margin-right: 20px;
white-space: nowrap;
span {
margin-right: 10px;
}