<template>
|
<el-card shadow="never" class="aui-card--fill">
|
<div class="mod-his__index">
|
<el-form :inline="true" :model="formData" label-width="80px">
|
<el-form-item label="开始时间">
|
<el-date-picker
|
v-model="formData.startTime"
|
type="datetime"
|
format="YYYY-MM-DD HH:mm:00"
|
value-format="YYYY-MM-DD HH:mm:00"
|
placeholder="选择日期时间"/>
|
</el-form-item>
|
<el-form-item label="结束时间">
|
<el-date-picker
|
v-model="formData.endTime"
|
type="datetime"
|
format="YYYY-MM-DD HH:mm:00"
|
value-format="YYYY-MM-DD HH:mm:00"
|
placeholder="选择日期时间"/>
|
</el-form-item>
|
<el-form-item>
|
<el-button-group>
|
<el-button type="primary" plain :icon="ArrowLeft"
|
:loading="loading1" @click="leftSearchDataByRange()"/>
|
<el-button type="primary" plain :icon="Search"
|
:loading="loading1" @click="getList()">查询
|
</el-button>
|
<el-button type="primary" plain :icon="ArrowRight"
|
:loading="loading1" @click="rightSearchDataByRange()"/>
|
</el-button-group>
|
</el-form-item>
|
|
<div class="his-body">
|
<div class="his-body-left">
|
<div class="his-body-tree">
|
<el-tree
|
:data="treeData"
|
show-checkbox
|
node-key="id"
|
ref="tree"
|
highlight-current
|
:props="defaultProps"
|
@check="onCheckTree"/>
|
</div>
|
</div>
|
<div class="his-body-middle">
|
<div class="his-body-chart">
|
<el-form :inline="true" :model="formData" label-width="100px">
|
<el-row>
|
<el-col>
|
<el-form-item label="数据类型">
|
<el-checkbox-group v-model="formData.chartCheck" @change="changeChartCheck">
|
<el-checkbox v-for="item in formData.chartOptions" :label="item"
|
:key="item">{{ item }}
|
</el-checkbox>
|
</el-checkbox-group>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
<div ref="dataAnalysisChart" style="height: 500px;"></div>
|
</div>
|
</div>
|
<div class="his-body-right">
|
<ContentWrap>
|
<el-table v-loading="loading" :data="list">
|
<el-table-column label="编号" align="center" min-width="100" prop="itemno"/>
|
<el-table-column label="名称" header-align="center" align="left" min-width="200"
|
prop="resultName"/>
|
<el-table-column label="开始时间" header-align="center" align="left" min-width="200"
|
prop="startTime"/>
|
<el-table-column label="结束时间" header-align="center" align="left" min-width="200"
|
prop="endTime"/>
|
<el-table-column label="丢失时间(min)" header-align="center" align="left" min-width="100"
|
prop="gap"/>
|
<el-table-column label="随机偏差" header-align="center" align="left" min-width="200"
|
prop="random">
|
<el-input-number
|
v-model="scope.row.random"
|
:min="0"
|
placeholder="请输入随机偏差"
|
/>
|
</el-table-column>
|
<el-table-column label="操作" align="center" min-width="120" fixed="right">
|
<template #default="scope">
|
<el-button
|
link
|
type="primary"
|
@click="repair(scope.row)"
|
>
|
修复
|
</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
<!-- 分页 -->
|
<Pagination
|
:total="total"
|
v-model:page="queryParams.pageNo"
|
v-model:limit="queryParams.pageSize"
|
@pagination="getList"
|
/>
|
</ContentWrap>
|
</div>
|
</div>
|
</el-form>
|
</div>
|
</el-card>
|
</template>
|
<script lang="ts" setup>
|
import {getYMDHMS} from "@/utils/dateUtil"
|
import * as McsApi from '@/api/model/mcs'
|
import * as echarts from "echarts";
|
import {Search, ArrowLeft, ArrowRight,} from '@element-plus/icons-vue'
|
|
defineOptions({name: 'RepairformData'})
|
|
const dataAnalysisChart = ref(null);
|
const loading1 = ref(false) // 列表的加载中
|
const treeData = ref([])
|
const itemDataObject = ref()
|
const timer = ref()
|
const list = ref()
|
let myChart = null;
|
const queryParams = reactive({
|
pageNo: 1,
|
pageSize: 10,
|
})
|
|
const formData = ref({
|
startTime: '',
|
endTime: '',
|
predictTime: '',
|
chartCheck: ['T+L', '真实值'],
|
chartOptions: ['T+N', 'T+L', '真实值'],
|
checkedItemData: [],
|
isMultipleYRadio: '单坐标轴',
|
isMultipleY: false,
|
})
|
|
const repair = async (rows) => {
|
const params = reactive({
|
outIds: rows.outIds,
|
startTime: rows.startTime,
|
endTime: rows.endTime,
|
random: rows.random,
|
})
|
|
const result = await McsApi.repair(params);
|
if (result.code === 0) {
|
this.$alert('数据修复成功', '提示', {
|
confirmButtonText: '确定',
|
callback: () => {
|
this.getList();
|
}
|
});
|
} else {
|
this.$message.error(`数据修复失败`);
|
}
|
}
|
/** 查询列表 */
|
const getList = async () => {
|
loading1.value = true
|
try {
|
if (!formData.value.chartCheck) {
|
formData.value.chartCheck = ['真实值']
|
}
|
let chartCheckArray = formData.value.chartCheck;
|
if (!formData.value.checkedItemData || formData.value.checkedItemData.length == 0) {
|
return;
|
}
|
let outIds = formData.value.checkedItemData.map(item => {
|
return item.id
|
})
|
const params = reactive({
|
outIds: outIds,
|
predictTime: formData.value.predictTime,
|
startTime: formData.value.startTime,
|
endTime: formData.value.endTime
|
})
|
const data = await McsApi.getPreDataCharts(params)
|
const list = await McsApi.getPreDataMissDataList(params)
|
this.list = list
|
formData.value.predictTime = data.predictTime;
|
formData.value.startTime = data.startTime
|
formData.value.endTime = data.endTime
|
|
let xAxisData = data.categories;
|
let yAxisData = [];
|
let offset = 0;
|
let yAxisIndex = 0;
|
let legendData = [];
|
let yMaxArr = [];
|
let seriesData = [];
|
seriesData.push({
|
name: '',
|
data: [null],
|
type: 'line',
|
smooth: true,
|
color: 'green',
|
markLine: {
|
silent: true,
|
lineStyle: {
|
color: '#32a487',
|
width: 2
|
},
|
data: [{
|
xAxis: formData.value.predictTime
|
}],
|
label: {
|
normal: {
|
formatter: formData.value.predictTime
|
}
|
},
|
symbol: ['circle', 'none'],
|
},
|
});
|
itemDataObject.value = {}
|
for (let i = 0; i < data.dataViewList.length; i++) {
|
let dataView = data.dataViewList[i]
|
itemDataObject.value[dataView.outId] = dataView;
|
let maxValue = dataView.maxValue;
|
let minValue = dataView.minValue;
|
yAxisIndex = formData.value.isMultipleY ? i : 0;
|
let yMax = maxValue;
|
if (maxValue < 0) {
|
maxValue = 1;
|
} else if (maxValue < 10) {
|
yMax = (Math.ceil(maxValue * 11) / 10).toFixed(1);
|
} else if (maxValue < 100) {
|
yMax = (Math.ceil(maxValue * 1.1 / 5) * 5);
|
} else {
|
yMax = (Math.ceil(maxValue * 1.1 / 10) * 10);
|
}
|
yMaxArr.push(yMax);
|
let yMin = minValue;
|
if (minValue >= 0) {
|
yMin = 0;
|
} else if (minValue > -10) {
|
yMin = (Math.floor(minValue * 11) / 10).toFixed(1);
|
} else if (minValue > -100) {
|
yMin = (Math.floor(minValue * 1.1 / 5) * 5);
|
} else {
|
yMin = (Math.floor(minValue * 1.1 / 10) * 10);
|
}
|
yAxisData.push({
|
type: 'value',
|
name: "",
|
min: yMin,
|
max: yMax,
|
position: 'left',
|
offset: offset,
|
splitLine: {
|
show: false
|
},
|
axisLine: {
|
show: true,
|
lineStyle: {}
|
},
|
axisLabel: {
|
formatter: '{value}'
|
}
|
})
|
offset = offset + 40
|
if (chartCheckArray.indexOf('真实值') !== -1) {
|
let legendName = dataView.resultName + '(真实)';
|
legendData.push(legendName);
|
seriesData.push({
|
name: legendName,
|
data: dataView.realData || [],
|
type: 'line',
|
yAxisIndex: yAxisIndex,
|
showSymbol: false,
|
smooth: true,
|
lineStyle: {
|
width: 2
|
}
|
});
|
}
|
if (chartCheckArray.indexOf('T+N') !== -1) {
|
let legendName = dataView.resultName + '(T+N)';
|
seriesData.push({
|
name: legendName,
|
data: dataView.preDataN || [],
|
type: 'line',
|
yAxisIndex: yAxisIndex,
|
showSymbol: false,
|
smooth: true,
|
lineStyle: {
|
width: 2
|
}
|
});
|
}
|
if (chartCheckArray.indexOf('T+L') !== -1) {
|
let legendName = dataView.resultName + '(T+L)';
|
legendData.push(legendName);
|
seriesData.push({
|
name: legendName,
|
data: dataView.preDataL || [],
|
type: 'line',
|
showSymbol: false,
|
connectNulls: true,
|
yAxisIndex: yAxisIndex,
|
smooth: true,
|
lineStyle: {
|
width: 2
|
}
|
});
|
}
|
if (chartCheckArray.indexOf('当时') !== -1) {
|
let legendName = dataView.resultName + '(当时)';
|
legendData.push(legendName);
|
seriesData.push({
|
name: legendName,
|
data: dataView.curData || [],
|
type: 'line',
|
yAxisIndex: yAxisIndex,
|
showSymbol: false,
|
smooth: true,
|
lineStyle: {
|
width: 2
|
}
|
});
|
}
|
if (chartCheckArray.indexOf('调整值') !== -1) {
|
let legendName = dataView.resultName + '(调整值)';
|
legendData.push(legendName);
|
seriesData.push({
|
name: legendName,
|
data: dataView.adjData || [],
|
type: 'line',
|
yAxisIndex: yAxisIndex,
|
showSymbol: false,
|
connectNulls: true,
|
smooth: true,
|
lineStyle: {
|
width: 2,
|
type: 'dashed'
|
}
|
});
|
}
|
}
|
//如果最大值相差不大,改成一致大小
|
if (yMaxArr.length > 1) {
|
let max = Math.max.apply(null, yMaxArr);
|
let min = Math.min.apply(null, yMaxArr);
|
if (Math.abs((max - min) / max) <= 0.2) {
|
for (let i = 0; i < yAxisData.length; i++) {
|
yAxisData[i].max = max;
|
}
|
}
|
}
|
myChart = echarts.init(dataAnalysisChart.value);
|
let option = {
|
title: {
|
text: ''
|
},
|
tooltip: {
|
trigger: 'axis'
|
},
|
legend: {
|
show: true,
|
data: legendData,
|
top: 10
|
},
|
grid: {
|
top: '20%',
|
left: '3%',
|
right: '6%',
|
bottom: '3%',
|
containLabel: true
|
},
|
xAxis: {
|
type: 'category',
|
boundaryGap: false,
|
data: xAxisData
|
},
|
yAxis: formData.value.isMultipleY ? yAxisData : {
|
type: 'value',
|
splitLine: {show: false},
|
axisLine: {show: true}
|
},
|
dataZoom: [
|
{
|
type: 'inside',
|
start: 0,
|
end: 100
|
},
|
{
|
start: 0,
|
end: 10
|
}
|
],
|
series: seriesData
|
}
|
myChart.clear()
|
myChart.setOption(option)
|
} finally {
|
loading1.value = false
|
}
|
}
|
|
onMounted(() => {
|
getPreItemTree()
|
})
|
|
async function getPreItemTree() {
|
treeData.value = await McsApi.getPredictItemTree()
|
}
|
|
function leftSearchDataByRange() {
|
let mins = getRangeMins();
|
let startTime = formData.value.startTime;
|
let endTime = formData.value.endTime;
|
let predictTime = formData.value.predictTime;
|
if (predictTime) {
|
predictTime = getYMDHMS(new Date(predictTime) - 1000 * 60 * mins);
|
formData.value.predictTime = predictTime;
|
}
|
if (startTime) {
|
startTime = getYMDHMS(new Date(startTime) - 1000 * 60 * mins);
|
formData.value.startTime = startTime;
|
}
|
if (endTime) {
|
endTime = getYMDHMS(new Date(endTime) - 1000 * 60 * mins);
|
formData.value.endTime = endTime;
|
}
|
getList();
|
}
|
|
function getRangeMins() {
|
let result: string | number = 0;
|
if (formData.value.startTime && formData.value.endTime) {
|
let startStamp = new Date(formData.value.startTime).getTime();
|
let endStamp = new Date(formData.value.endTime).getTime();
|
let queryStep = ((endStamp - startStamp) / (1000 * 60)).toFixed(0);
|
result = queryStep >= 0 ? queryStep : 0;
|
}
|
return result;
|
}
|
|
function onCheckTree(data, checked, indeterminate) {
|
formData.value.checkedItemData = [];
|
if (checked.checkedNodes) {
|
formData.value.checkedItemData = [...checked.checkedNodes]
|
}
|
debounce(getList, 1000);
|
}
|
|
function debounce(func, wait) {
|
let args = [];
|
if (timer.value) {
|
clearTimeout(timer.value);
|
}
|
timer.value = setTimeout(() => {
|
func.apply(this, args);
|
timer.value = null;
|
}, wait)
|
}
|
|
function rightSearchDataByRange() {
|
let mins = getRangeMins();
|
let startTime = formData.value.startTime;
|
let endTime = formData.value.endTime;
|
let predictTime = formData.value.predictTime;
|
if (predictTime) {
|
predictTime = getYMDHMS(new Date(predictTime) - 0 + 1000 * 60 * mins);
|
formData.value.predictTime = predictTime;
|
}
|
if (startTime) {
|
startTime = getYMDHMS(new Date(startTime) - 0 + 1000 * 60 * mins);
|
formData.value.startTime = startTime;
|
}
|
if (endTime) {
|
endTime = getYMDHMS(new Date(endTime) - 0 + 1000 * 60 * mins);
|
formData.value.endTime = endTime;
|
}
|
getList();
|
}
|
</script>
|
<style scoped>
|
.el-form-item {
|
margin-bottom: 0 !important;
|
}
|
|
.his-body-chart {
|
height: 100%;
|
border: 1px solid lightgray;
|
padding: 10px;
|
}
|
|
.his-body-tree {
|
height: 100%;
|
border: 1px solid lightgray;
|
padding: 10px;
|
}
|
|
.his-body-middle{
|
width: 40%;
|
height: 100%;
|
padding: 10px 10px 0 0;
|
}
|
.his-body-right {
|
width: 40%;
|
height: 100%;
|
padding-top: 10px;
|
}
|
.his-body-left {
|
width: 20%;
|
height: 100%;
|
padding: 10px 10px 0 0;
|
}
|
|
.his-body {
|
width: 100%;
|
height: calc(calc(100vh - 68px - 38px - 160px));
|
display: flex;
|
flex-direction: row;
|
justify-content: flex-start;
|
align-content: flex-start;
|
}
|
</style>
|