修改测试bug
This commit is contained in:
@@ -1,10 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="default-main device-control"
|
||||
:style="{ height: pageHeight.height }"
|
||||
v-loading="loading"
|
||||
style="position: relative"
|
||||
>
|
||||
<div class="default-main device-control" :style="{ height: pageHeight.height }" v-loading="loading"
|
||||
style="position: relative">
|
||||
<!-- @init="nodeClick" -->
|
||||
<PointTree @node-click="nodeClick" @pointTypeChange="pointTypeChange"></PointTree>
|
||||
<div class="device-control-right" v-if="deviceData">
|
||||
@@ -19,12 +15,8 @@
|
||||
<el-button v-if="deviceType == '1'" type="primary" icon="el-icon-Monitor" @click="handleaddDevice">
|
||||
在线补召
|
||||
</el-button> -->
|
||||
<el-button
|
||||
v-if="deviceType == '1'"
|
||||
type="primary"
|
||||
icon="el-icon-Tickets"
|
||||
@click="handleAnalysisList"
|
||||
>
|
||||
<el-button v-if="deviceType == '1'" type="primary" icon="el-icon-Tickets"
|
||||
@click="handleAnalysisList">
|
||||
补召
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -38,10 +30,10 @@
|
||||
devData.conType == 0
|
||||
? '星型接线'
|
||||
: devData.conType == 1
|
||||
? '角型接线'
|
||||
: devData.conType == 2
|
||||
? 'V型接线'
|
||||
: '/'
|
||||
? '角型接线'
|
||||
: devData.conType == 2
|
||||
? 'V型接线'
|
||||
: '/'
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
|
||||
@@ -50,18 +42,13 @@
|
||||
</el-descriptions-item> -->
|
||||
|
||||
<el-descriptions-item label="PT变比" width="160">
|
||||
{{
|
||||
devData.ptRatio == null
|
||||
? '/'
|
||||
: devData.ptRatio + (devData.pt2Ratio == null ? '' : ':' + devData.pt2Ratio)
|
||||
}}
|
||||
{{ devData.ptRatio || 1 }} :
|
||||
{{ devData.pt2Ratio || 1 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="CT变比" width="160">
|
||||
{{
|
||||
devData.ctRatio == null
|
||||
? '/'
|
||||
: devData.ctRatio + (devData.ct2Ratio == null ? '' : ':' + devData.ct2Ratio)
|
||||
}}
|
||||
{{ devData.ctRatio || 1 }} :
|
||||
{{ devData.ct2Ratio || 1 }}
|
||||
|
||||
</el-descriptions-item>
|
||||
|
||||
<!-- <el-descriptions-item label="名称">
|
||||
@@ -85,14 +72,8 @@
|
||||
</el-descriptions-item> -->
|
||||
</el-descriptions>
|
||||
<el-tabs v-model.trim="dataSet" type="border-card" class="device-control-box-card" @tab-click="handleClick">
|
||||
<el-tab-pane
|
||||
lazy
|
||||
:label="item.name"
|
||||
:name="item.id"
|
||||
v-for="(item, index) in deviceData.dataSetList"
|
||||
:key="index"
|
||||
:disabled="tableLoading"
|
||||
>
|
||||
<el-tab-pane lazy :label="item.name" :name="item.id" v-for="(item, index) in deviceData.dataSetList"
|
||||
:key="index" :disabled="tableLoading">
|
||||
<template #label>
|
||||
<span class="custom-tabs-label">
|
||||
<!-- <el-icon>
|
||||
@@ -126,36 +107,25 @@
|
||||
</span>
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
<TableHeader
|
||||
:showSearch="false"
|
||||
v-if="
|
||||
(dataSet.indexOf('_trenddata') == -1 &&
|
||||
<TableHeader :showSearch="false" v-if="
|
||||
(dataSet.indexOf('_trenddata') == -1 &&
|
||||
dataSet.indexOf('_kilowattHour') == -1 &&
|
||||
dataSet.indexOf('_realtimedata') == -1 &&
|
||||
dataSet.indexOf('_event') == -1) ||
|
||||
realTimeFlag
|
||||
"
|
||||
>
|
||||
dataSet.indexOf('_realtimedata') == -1 &&
|
||||
dataSet.indexOf('_event') == -1) ||
|
||||
realTimeFlag
|
||||
">
|
||||
<template #select>
|
||||
<el-form-item
|
||||
label="日期"
|
||||
v-show="
|
||||
dataSet.includes('_items') ||
|
||||
dataSet.indexOf('_history') != -1 ||
|
||||
dataSet.indexOf('_moduleData') != -1 ||
|
||||
dataSet.indexOf('_devRunTrend') != -1
|
||||
"
|
||||
>
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
<el-form-item label="日期" v-show="dataSet.includes('_items') ||
|
||||
dataSet.indexOf('_history') != -1 ||
|
||||
dataSet.indexOf('_moduleData') != -1 ||
|
||||
dataSet.indexOf('_devRunTrend') != -1
|
||||
">
|
||||
<DatePicker ref="datePickerRef" :timeKeyList="['3', '4', '5']"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item label="数据类型" v-if="!dataSet.includes('_')">
|
||||
<el-select v-model.trim="formInline.targetType" @change="handleTargetTypeChange">
|
||||
<el-option
|
||||
v-for="item in queryList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
<el-option v-for="item in queryList" :key="item.id" :label="item.name"
|
||||
:value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@@ -165,16 +135,15 @@
|
||||
<el-option value="Primary" label="一次值"></el-option>
|
||||
<el-option value="Secondary" label="二次值"></el-option>
|
||||
</el-select> -->
|
||||
<el-radio-group
|
||||
v-model.trim="formInline.dataLevel"
|
||||
v-if="
|
||||
!dataSet.includes('_devRunTrend') &&
|
||||
!dataSet.includes('_moduleData') &&
|
||||
TrendList?.lineType == 1
|
||||
"
|
||||
:disabled="TrendList?.lineType != 1"
|
||||
@change="handleClick"
|
||||
>
|
||||
<!-- _realtimedata
|
||||
-->
|
||||
|
||||
<el-radio-group v-model.trim="formInline.dataLevel" v-if="
|
||||
!dataSet.includes('_devRunTrend') &&
|
||||
!dataSet.includes('_moduleData') &&
|
||||
TrendList?.lineType == 1
|
||||
" :disabled="TrendList?.lineType != 1"
|
||||
@change="dataSet.includes('_realtimedata') ? realtimeChange() : handleClick()">
|
||||
<el-radio-button label="一次值" value="Primary" />
|
||||
<el-radio-button label="二次值" value="Secondary" />
|
||||
</el-radio-group>
|
||||
@@ -182,102 +151,56 @@
|
||||
|
||||
<el-form-item label="谐波次数" v-show="oddAndEvenFlag && !dataSet.includes('_')">
|
||||
<el-select v-model.trim="oddAndEven" style="min-width: 120px !important">
|
||||
<el-option
|
||||
v-for="item in oddAndEvenList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
<el-option v-for="item in oddAndEvenList" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="数据来源" v-if="dataSet.includes('_items')">
|
||||
<el-select v-model.trim="formInline.dataSource" placeholder="请选择数据来源" clearable>
|
||||
<el-option
|
||||
v-for="item in dataSourceList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
<el-option v-for="item in dataSourceList" :key="item.id" :label="item.name"
|
||||
:value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="关键字筛选" v-if="!dataSet.includes('_')">
|
||||
<el-input
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
v-model.trim="searchValue"
|
||||
autocomplete="off"
|
||||
clearable
|
||||
@input="handleSearch"
|
||||
placeholder="请输入关键字筛选"
|
||||
style="width: 180px !important"
|
||||
></el-input>
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="searchValue" autocomplete="off"
|
||||
clearable @input="handleSearch" placeholder="请输入关键字筛选"
|
||||
style="width: 180px !important"></el-input>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #operation>
|
||||
<el-button
|
||||
type="primary"
|
||||
<el-button type="primary"
|
||||
:icon="dataSet.indexOf('_realtimedata') != -1 ? 'el-icon-Refresh' : 'el-icon-Search'"
|
||||
@click="handleClick"
|
||||
>
|
||||
@click="handleClick" :loading="tableLoading">
|
||||
{{ dataSet.indexOf('_realtimedata') != -1 ? '刷新' : '查询' }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
v-if="dataSet.indexOf('_moduleData') != -1 && moduleFlag"
|
||||
:icon="Refresh"
|
||||
@click="refreshTheState"
|
||||
>
|
||||
<el-button type="primary" v-if="dataSet.indexOf('_moduleData') != -1 && moduleFlag"
|
||||
:icon="Refresh" @click="refreshTheState">
|
||||
刷新状态
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="tableLoading"
|
||||
v-if="showButton"
|
||||
:icon="DataLine"
|
||||
@click="handleTrend"
|
||||
>
|
||||
<el-button type="primary" :disabled="tableLoading" v-if="showButton" :icon="DataLine"
|
||||
@click="handleTrend">
|
||||
谐波频谱
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
v-if="showButton"
|
||||
:icon="TrendCharts"
|
||||
@click="handleHarmonicSpectrum"
|
||||
:disabled="tableLoading"
|
||||
>
|
||||
<el-button type="primary" v-if="showButton" :icon="TrendCharts" @click="handleHarmonicSpectrum"
|
||||
:disabled="tableLoading">
|
||||
实时趋势
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
v-if="showButton"
|
||||
:icon="Download"
|
||||
@click="downloadTxt"
|
||||
:disabled="tableLoading"
|
||||
>
|
||||
<el-button type="primary" v-if="showButton" :icon="Download" @click="downloadTxt"
|
||||
:disabled="tableLoading">
|
||||
下载数据
|
||||
</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
<div
|
||||
class="data_time"
|
||||
:style="{
|
||||
height: realTimeFlag ? '30px' : '40px',
|
||||
alignItems: realTimeFlag ? 'flex-end' : 'center'
|
||||
}"
|
||||
v-if="dataSet.includes('_realtimedata') && mqttMessage && mqttMessage.dataTime && sonTab != 2"
|
||||
>
|
||||
<p class="mb5">
|
||||
<span v-if="trendDataTime && !realTimeFlag">数据时间:{{ trendDataTime }}</span>
|
||||
<span v-if="realTimeFlag">数据时间:{{ mqttMessage.dataTime }}</span>
|
||||
<div class="data_time" :style="{
|
||||
alignItems: realTimeFlag ? 'flex-end' : 'center'
|
||||
}" v-if="dataSet.includes('_realtimedata') && sonTab != 2 && trendDataTime && !realTimeFlag">
|
||||
<p class="mb10 mt10">
|
||||
<span>数据时间:{{ trendDataTime || '-' }}</span>
|
||||
|
||||
</p>
|
||||
|
||||
<el-button
|
||||
v-if="!realTimeFlag && dataSet.includes('_realtimedata')"
|
||||
style="float: right !important"
|
||||
:icon="Back"
|
||||
@click="handleReturn"
|
||||
:loading="tableLoading"
|
||||
>
|
||||
<el-button v-if="!realTimeFlag && dataSet.includes('_realtimedata')" style="float: right !important"
|
||||
:icon="Back" @click="handleReturn" :loading="tableLoading">
|
||||
返回
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -293,52 +216,32 @@
|
||||
></div> -->
|
||||
<!-- v-loading="tableLoading" -->
|
||||
<div :style="{ height: tableHeight }" v-loading="tableLoading" v-if="!dataSet.includes('_')">
|
||||
<div
|
||||
style="overflow: auto"
|
||||
:style="{ height: tableHeight }"
|
||||
v-if="
|
||||
dataSet.indexOf('_trenddata') == -1 &&
|
||||
dataSet.indexOf('_kilowattHour') == -1 &&
|
||||
dataSet.indexOf('_realtimedata') == -1 &&
|
||||
dataSet.indexOf('_event') == -1 &&
|
||||
tableData.length != 0
|
||||
"
|
||||
>
|
||||
<div
|
||||
class="mb5 mt5"
|
||||
v-if="dataSet.indexOf('_history') == -1"
|
||||
style="font-weight: 800; font-size: 16px; text-align: center"
|
||||
>
|
||||
统计时间:{{ tableData[0]?.time || '' }}
|
||||
<div style="overflow: auto" :style="{ height: tableHeight }" v-if="
|
||||
dataSet.indexOf('_trenddata') == -1 &&
|
||||
dataSet.indexOf('_kilowattHour') == -1 &&
|
||||
dataSet.indexOf('_realtimedata') == -1 &&
|
||||
dataSet.indexOf('_event') == -1 &&
|
||||
tableData.length != 0
|
||||
">
|
||||
<div class="mb10 mt10" v-if="dataSet.indexOf('_history') == -1"
|
||||
style="font-weight: 700; font-size: 13px; text-align: center">
|
||||
最新数据时标:{{ tableData[0]?.time || '-' }}
|
||||
</div>
|
||||
|
||||
<nearRealTimeData
|
||||
ref="nearRealTimeDataRef"
|
||||
v-if="dataSet.indexOf('_history') == -1"
|
||||
:style="{ height: tableHeightBox, overflow: 'auto' }"
|
||||
/>
|
||||
<nearRealTimeData ref="nearRealTimeDataRef" v-if="dataSet.indexOf('_history') == -1"
|
||||
:style="{ height: tableHeightBox, overflow: 'auto' }" />
|
||||
|
||||
<!-- 循环渲染的card 最新数据/历史数据显示 -->
|
||||
<div
|
||||
class="content"
|
||||
<div class="content"
|
||||
v-if="tableData.length != 0 && !tableLoading && dataSet.indexOf('_history') != -1"
|
||||
:style="{ height: tableHeightBox }"
|
||||
>
|
||||
<el-card
|
||||
class="box-card"
|
||||
:class="dataSet.indexOf('_history') == -1 ? 'box-card-new' : ''"
|
||||
v-for="(item, index) in tableData"
|
||||
:key="index"
|
||||
>
|
||||
:style="{ height: tableHeightBox }">
|
||||
<el-card class="box-card" :class="dataSet.indexOf('_history') == -1 ? 'box-card-new' : ''"
|
||||
v-for="(item, index) in tableData" :key="index">
|
||||
<template #header>
|
||||
<div class="clearfix">
|
||||
<span style="flex: 1">{{ item.name }}</span>
|
||||
<Icon
|
||||
name="el-icon-TrendCharts"
|
||||
class="ml10"
|
||||
@click="getDeviceDataTrend(item)"
|
||||
style="font-size: 26px; cursor: pointer; color: #fff"
|
||||
></Icon>
|
||||
<Icon name="el-icon-TrendCharts" class="ml10" @click="getDeviceDataTrend(item)"
|
||||
style="font-size: 26px; cursor: pointer; color: #fff"></Icon>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -352,49 +255,37 @@
|
||||
</div>
|
||||
<div v-else-if="item.children.length" class="box-card-div">
|
||||
<div style="display: flex; align-items: center">
|
||||
<el-tag
|
||||
effect="dark"
|
||||
type="danger"
|
||||
style="width: 40px; text-align: center"
|
||||
class="mr10"
|
||||
>
|
||||
<el-tag effect="dark" type="danger" style="width: 40px; text-align: center"
|
||||
class="mr10">
|
||||
MAX
|
||||
</el-tag>
|
||||
{{
|
||||
item.children[0].maxValue === 3.1415956 ||
|
||||
typeof item.children[0].maxValue != 'number'
|
||||
typeof item.children[0].maxValue != 'number'
|
||||
? '暂无数据'
|
||||
: item.children[0].maxValue
|
||||
}}
|
||||
</div>
|
||||
<div style="display: flex; align-items: center">
|
||||
<el-tag
|
||||
effect="dark"
|
||||
type="success"
|
||||
style="width: 40px; text-align: center"
|
||||
class="mr10"
|
||||
>
|
||||
<el-tag effect="dark" type="success" style="width: 40px; text-align: center"
|
||||
class="mr10">
|
||||
AVG
|
||||
</el-tag>
|
||||
{{
|
||||
item.children[0].avgValue === 3.1415956 ||
|
||||
typeof item.children[0].avgValue != 'number'
|
||||
typeof item.children[0].avgValue != 'number'
|
||||
? '暂无数据'
|
||||
: item.children[0].avgValue
|
||||
}}
|
||||
</div>
|
||||
<div style="display: flex; align-items: center">
|
||||
<el-tag
|
||||
effect="dark"
|
||||
type="warning"
|
||||
style="width: 40px; text-align: center"
|
||||
class="mr10"
|
||||
>
|
||||
<el-tag effect="dark" type="warning" style="width: 40px; text-align: center"
|
||||
class="mr10">
|
||||
MIN
|
||||
</el-tag>
|
||||
{{
|
||||
item.children[0].minValue === 3.1415956 ||
|
||||
typeof item.children[0].minValue != 'number'
|
||||
typeof item.children[0].minValue != 'number'
|
||||
? '暂无数据'
|
||||
: item.children[0].minValue
|
||||
}}
|
||||
@@ -403,82 +294,10 @@
|
||||
</el-card>
|
||||
<el-empty description="暂无数据" v-if="tableData.length === 0"></el-empty>
|
||||
</div>
|
||||
<!-- <div class="content" v-if="tableData.length != 0 && !tableLoading"
|
||||
:style="{ height: tableHeightBox }">
|
||||
|
||||
<el-card class="box-card" :class="dataSet.indexOf('_history') == -1 ? 'box-card-new' : ''"
|
||||
v-for="(item, index) in tableData" :key="index">
|
||||
<template #header>
|
||||
<div class="clearfix">
|
||||
<span style="flex: 1">{{ item.name }}</span>
|
||||
<Icon name="el-icon-TrendCharts" class="ml10" @click="getDeviceDataTrend(item)"
|
||||
style="font-size: 26px; cursor: pointer; color: #fff"></Icon>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="box-card-content" v-if="dataSet.indexOf('_history') == -1">
|
||||
<div class="box-card-div">
|
||||
<div v-for="(child, childIndex) in item.children" :key="childIndex">
|
||||
{{ child.anotherName }}:
|
||||
{{ child.dataValue === 3.1415926 ? '暂无数据' : child.dataValue }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div v-else-if="item.children.length" class="box-card-div">
|
||||
<div style="display: flex; align-items: center">
|
||||
<el-tag effect="dark" type="danger" style="width: 40px; text-align: center"
|
||||
class="mr10">
|
||||
MAX
|
||||
</el-tag>
|
||||
{{
|
||||
item.children[0].maxValue === 3.1415956 ||
|
||||
typeof item.children[0].maxValue != 'number'
|
||||
? '暂无数据'
|
||||
: item.children[0].maxValue
|
||||
}}
|
||||
</div>
|
||||
<div style="display: flex; align-items: center">
|
||||
<el-tag effect="dark" type="success" style="width: 40px; text-align: center"
|
||||
class="mr10">
|
||||
AVG
|
||||
</el-tag>
|
||||
{{
|
||||
item.children[0].avgValue === 3.1415956 ||
|
||||
typeof item.children[0].avgValue != 'number'
|
||||
? '暂无数据'
|
||||
: item.children[0].avgValue
|
||||
}}
|
||||
</div>
|
||||
<div style="display: flex; align-items: center">
|
||||
<el-tag effect="dark" type="warning" style="width: 40px; text-align: center"
|
||||
class="mr10">
|
||||
MIN
|
||||
</el-tag>
|
||||
{{
|
||||
item.children[0].minValue === 3.1415956 ||
|
||||
typeof item.children[0].minValue != 'number'
|
||||
? '暂无数据'
|
||||
: item.children[0].minValue
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-empty description="暂无数据" v-if="tableData.length === 0"></el-empty>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- <el-pagination v-if="
|
||||
tableData.length &&
|
||||
dataSet.indexOf('_trenddata') == -1 &&
|
||||
dataSet.indexOf('_realtimedata') == -1 &&
|
||||
dataSet.indexOf('_event') == -1
|
||||
" background class="mr2 mt10" style="float: right" @size-change="handleSizeChange"
|
||||
@current-change="pageChange" :current-page="formInline.pageNum" :page-sizes="[20, 30, 40, 50, 100]"
|
||||
:page-size="formInline.pageSize" layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="formInline.total"></el-pagination> -->
|
||||
|
||||
|
||||
<!-- 趋势数据 -->
|
||||
<div style="height: calc(100vh - 340px)" v-if="dataSet.indexOf('_trenddata') != -1">
|
||||
@@ -489,68 +308,47 @@
|
||||
<electroplating ref="electroplatingRef" :TrendList="TrendList"></electroplating>
|
||||
</div>
|
||||
<!-- 实时数据 -->
|
||||
<div
|
||||
:style="`height: calc(100vh - (${sonTab == 1 ? '378px' : sonTab == 2 ? '340px' : '425px'}))`"
|
||||
v-if="dataSet.indexOf('_realtimedata') != -1"
|
||||
v-loading="tableLoading"
|
||||
>
|
||||
<div :style="`height: calc(100vh - (${sonTab == 1 ? '346px' : sonTab == 2 ? '308px' : '393px'}))`"
|
||||
v-if="dataSet.indexOf('_realtimedata') != -1" v-loading="tableLoading"
|
||||
>
|
||||
<!-- <div class="view_top_btn" v-if="realTimeFlag">
|
||||
<el-button type="primary" :icon="Platform" @click="handleRecordWaves">
|
||||
实时录波
|
||||
</el-button>
|
||||
</div> -->
|
||||
<div
|
||||
class="view_top_btn"
|
||||
v-if="dataSet.includes('_realtimedata') && !realTimeFlag && mqttMessage.dataTime && sonTab == 2"
|
||||
>
|
||||
<div class="view_top_btn"
|
||||
v-if="dataSet.includes('_realtimedata') && !realTimeFlag && mqttMessage.dataTime && sonTab == 2">
|
||||
<el-button :icon="Back" @click="handleReturn" :loading="tableLoading">返回</el-button>
|
||||
</div>
|
||||
<!-- 实时数据主界面组件 -->
|
||||
<realTime v-if="realTimeFlag" ref="realTimeRef"></realTime>
|
||||
<realTime v-if="realTimeFlag" ref="realTimeRef" :dataTime="mqttMessage.dataTime"></realTime>
|
||||
<!-- 实时数据-实时录波组件 -->
|
||||
<recordWoves v-if="!realTimeFlag && sonTab == 0"></recordWoves>
|
||||
<!-- 实时数据-实时趋势组件 -->
|
||||
<realTrend
|
||||
v-if="!realTimeFlag && sonTab == 1"
|
||||
ref="realTrendRef"
|
||||
@changeTrendType="changeTrendType"
|
||||
></realTrend>
|
||||
<realTrend v-if="!realTimeFlag && sonTab == 1" ref="realTrendRef"
|
||||
@changeTrendType="changeTrendType">
|
||||
</realTrend>
|
||||
<!-- 实时数据-谐波频谱组件 -->
|
||||
<harmonicSpectrum
|
||||
v-show="!realTimeFlag && sonTab == 2"
|
||||
ref="harmonicSpectrumRef"
|
||||
></harmonicSpectrum>
|
||||
<harmonicSpectrum v-show="!realTimeFlag && sonTab == 2" ref="harmonicSpectrumRef">
|
||||
</harmonicSpectrum>
|
||||
</div>
|
||||
<!-- 暂态事件 -->
|
||||
<div
|
||||
style="height: calc(100vh - 340px)"
|
||||
v-if="dataSet.indexOf('_event') != -1"
|
||||
v-loading="tableLoading"
|
||||
>
|
||||
<div style="height: calc(100vh - 340px)" v-if="dataSet.indexOf('_event') != -1">
|
||||
<Event ref="eventRef" :deviceType="deviceType"></Event>
|
||||
</div>
|
||||
<!-- 测试项记录 -->
|
||||
<div
|
||||
style="height: calc(100vh - 395px)"
|
||||
v-if="dataSet.indexOf('_items') != -1"
|
||||
v-loading="tableLoading"
|
||||
>
|
||||
<div style="height: calc(100vh - 395px)" v-if="dataSet.indexOf('_items') != -1"
|
||||
v-loading="tableLoading">
|
||||
<testItemRecords ref="testItemRecordsRef" @onSubmit="handleClick" />
|
||||
</div>
|
||||
<!-- 模块数据 -->
|
||||
<div
|
||||
style="height: calc(100vh - 395px)"
|
||||
v-if="dataSet.indexOf('_moduleData') != -1"
|
||||
v-loading="tableLoading"
|
||||
>
|
||||
<div style="height: calc(100vh - 395px)" v-if="dataSet.indexOf('_moduleData') != -1"
|
||||
v-loading="tableLoading">
|
||||
<moduleData ref="moduleDataRef" @onSubmit="handleClick" />
|
||||
</div>
|
||||
<!-- 运行趋势 -->
|
||||
<div
|
||||
style="height: calc(100vh - 395px)"
|
||||
v-if="dataSet.indexOf('_devRunTrend') != -1"
|
||||
v-loading="tableLoading"
|
||||
>
|
||||
<div style="height: calc(100vh - 395px)" v-if="dataSet.indexOf('_devRunTrend') != -1"
|
||||
v-loading="tableLoading">
|
||||
<operatingTrend ref="operatingTrendRef" @onSubmit="handleClick" />
|
||||
</div>
|
||||
<div v-if="!tableData" style="height: 42px"></div>
|
||||
@@ -592,7 +390,7 @@ import harmonicSpectrum from './tabs/components/harmonicSpectrum.vue' //实时
|
||||
import recordWoves from './tabs/components/recordwoves.vue' //实时数据-实时录波子页面
|
||||
import offLineDataImport from './offLineDataImport/index.vue'
|
||||
import Event from './tabs/event.vue'
|
||||
import nearRealTimeData from './nearRealTimeData.vue'
|
||||
import nearRealTimeData from './nearRealTimeData.vue'//最新数据
|
||||
import testItemRecords from './testItemRecords.vue'
|
||||
import moduleData from './moduleData.vue'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
@@ -694,7 +492,7 @@ const volConTypeList = dictData.getBasicData('Dev_Connect')
|
||||
const realTrendRef = ref()
|
||||
const txtContent = ref('')
|
||||
const operatingTrendRef = ref()
|
||||
const electroplatingRef = ref()
|
||||
const electroplatingRef = ref()
|
||||
const changeTrendType = (val: any) => {
|
||||
trendDataTime.value = ''
|
||||
activeTrendName.value = val * 1
|
||||
@@ -739,7 +537,7 @@ const handleTrend = async () => {
|
||||
.then((res: any) => {
|
||||
if (res.code == 'A0000') {
|
||||
trendDataTime.value = ''
|
||||
ElMessage.success('设备应答成功')
|
||||
// ElMessage.success('设备应答成功')
|
||||
//每隔30s调用一下接口,通知后台推送mqtt消息
|
||||
trendTimer.value = window.setInterval(() => {
|
||||
if (!dataSet.value.includes('_realtimedata')) return
|
||||
@@ -781,7 +579,7 @@ const handleHarmonicSpectrum = async () => {
|
||||
// getRealDataMqttMsg()
|
||||
await getBasicRealData(lineId.value).then((res: any) => {
|
||||
if (res.code == 'A0000') {
|
||||
ElMessage.success('设备应答成功')
|
||||
// ElMessage.success('设备应答成功')
|
||||
// mqttMessage.value = {}
|
||||
showButton.value = true
|
||||
realDataTimer.value = window.setInterval(() => {
|
||||
@@ -811,7 +609,7 @@ const handleReturn = async () => {
|
||||
tableLoading.value = true
|
||||
await getBasicRealData(lineId.value).then((res: any) => {
|
||||
if (res.code == 'A0000') {
|
||||
ElMessage.success('设备应答成功')
|
||||
// ElMessage.success('设备应答成功')
|
||||
showButton.value = true
|
||||
// mqttMessage.value = {}
|
||||
realDataTimer.value = window.setInterval(() => {
|
||||
@@ -905,7 +703,7 @@ const nodeClick = async (e: anyObj, node?: any) => {
|
||||
}
|
||||
|
||||
//选中设备名称后,点击标签页也能查询数据,要求点击设备名称后,点击标签页默认查询第一个监测点数据
|
||||
if (e.level == 3 ) {
|
||||
if (e.level == 3) {
|
||||
engineeringName.value = node?.parent.parent.data.name
|
||||
|
||||
await queryDictType({
|
||||
@@ -1008,6 +806,7 @@ const bindMqttMessage = (handler: (topic: any, message: any) => void) => {
|
||||
mqttRef.value.on('message', handler)
|
||||
}
|
||||
|
||||
|
||||
const connectMqtt = () => {
|
||||
if (mqttRef.value) {
|
||||
if (mqttRef.value.connected) {
|
||||
@@ -1039,7 +838,7 @@ const getRealDataMqttMsg = async () => {
|
||||
await getBasicRealData(lineId.value)
|
||||
.then((res: any) => {
|
||||
if (res.code == 'A0000') {
|
||||
ElMessage.success('设备应答成功')
|
||||
// ElMessage.success('设备应答成功')
|
||||
mqttMessage.value = {}
|
||||
showButton.value = true
|
||||
realDataTimer.value = window.setInterval(async () => {
|
||||
@@ -1064,7 +863,7 @@ const getRealDataMqttMsg = async () => {
|
||||
tableLoading.value = false
|
||||
}, 6000)
|
||||
} else {
|
||||
ElMessage.success('设备应答失败')
|
||||
ElMessage.warning('设备应答失败')
|
||||
tableLoading.value = false
|
||||
}
|
||||
})
|
||||
@@ -1078,147 +877,150 @@ const getRealDataMqttMsg = async () => {
|
||||
|
||||
const realDataTimer: any = ref()
|
||||
const mqttMessage = ref<any>({})
|
||||
|
||||
const realtimeMessage = ref<any>({})
|
||||
const realtimeChange = () => {
|
||||
onMqttRealDataMessage('', realtimeMessage.value)
|
||||
}
|
||||
/** 实时数据 / 实时趋势 MQTT 消息(命名函数,便于 off 避免重复注册) */
|
||||
const onMqttRealDataMessage = (topic: any, message: any) => {
|
||||
let obj = decodeMqttPayload(message)
|
||||
|
||||
if (lineId.value != obj.lineId || adminInfo.userIndex != obj.userId) return
|
||||
|
||||
realtimeMessage.value = message
|
||||
//处理mqtt数据 1转2除 2转1乘
|
||||
//如果消息返回值是二次值,下拉框是二次值只需要单位换算 除以1000
|
||||
//如果消息返回值是一次值,下拉框是一次值只需要单位换算 除以1000
|
||||
if (obj.dataLevel == formInline.dataLevel) {
|
||||
obj = {
|
||||
...obj,
|
||||
// 电压有效值
|
||||
vRmsA: obj.vRmsA,
|
||||
vRmsB: obj.vRmsB,
|
||||
vRmsC: obj.vRmsC,
|
||||
//基波电压幅值
|
||||
v1A: obj.v1A,
|
||||
v1B: obj.v1B,
|
||||
v1C: obj.v1C,
|
||||
//有功功率
|
||||
pA: obj.pA,
|
||||
pB: obj.pB,
|
||||
pC: obj.pC,
|
||||
pTot: obj.pTot,
|
||||
//无功功率
|
||||
qA: obj.qA,
|
||||
qB: obj.qB,
|
||||
qC: obj.qC,
|
||||
qTot: obj.qTot,
|
||||
//视在功率
|
||||
sA: obj.sA,
|
||||
sB: obj.sB,
|
||||
sC: obj.sC,
|
||||
sTot: obj.sTot
|
||||
}
|
||||
}
|
||||
//如果消息返回值是二次值,下拉框是一次值需要单位换算 除以1000 并且乘以pt ct
|
||||
if (obj.dataLevel == 'Secondary' && formInline.dataLevel == 'Primary') {
|
||||
obj = {
|
||||
...obj,
|
||||
// 电压有效值
|
||||
vRmsA: (obj.vRmsA * obj.pt) / 1000,
|
||||
vRmsB: (obj.vRmsB * obj.pt) / 1000,
|
||||
vRmsC: (obj.vRmsC * obj.pt) / 1000,
|
||||
// 电流有效值
|
||||
iRmsA: obj.iRmsA * obj.ct,
|
||||
iRmsB: obj.iRmsB * obj.ct,
|
||||
iRmsC: obj.iRmsC * obj.ct,
|
||||
//基波电压幅值
|
||||
v1A: (obj.v1A * obj.pt) / 1000,
|
||||
v1B: (obj.v1B * obj.pt) / 1000,
|
||||
v1C: (obj.v1C * obj.pt) / 1000,
|
||||
//基波电流幅值
|
||||
i1A: obj.i1A * obj.ct,
|
||||
i1B: obj.i1B * obj.ct,
|
||||
i1C: obj.i1C * obj.ct,
|
||||
//有功功率
|
||||
pA: (obj.pA * obj.pt * obj.ct) / 1000,
|
||||
pB: (obj.pB * obj.pt * obj.ct) / 1000,
|
||||
pC: (obj.pC * obj.pt * obj.ct) / 1000,
|
||||
pTot: (obj.pTot * obj.pt * obj.ct) / 1000,
|
||||
//无功功率
|
||||
qA: (obj.qA * obj.pt * obj.ct) / 1000,
|
||||
qB: (obj.qB * obj.pt * obj.ct) / 1000,
|
||||
qC: (obj.qC * obj.pt * obj.ct) / 1000,
|
||||
qTot: (obj.qTot * obj.pt * obj.ct) / 1000,
|
||||
//视在功率
|
||||
sA: (obj.sA * obj.pt * obj.ct) / 1000,
|
||||
sB: (obj.sB * obj.pt * obj.ct) / 1000,
|
||||
sC: (obj.sC * obj.pt * obj.ct) / 1000,
|
||||
sTot: (obj.sTot * obj.pt * obj.ct) / 1000
|
||||
}
|
||||
}
|
||||
//如果消息返回值是一次值,下拉框是二次值需要单位换算 乘以1000 并且除以pt ct
|
||||
if (obj.dataLevel == 'Primary' && formInline.dataLevel == 'Secondary') {
|
||||
obj = {
|
||||
...obj,
|
||||
// 电压有效值
|
||||
vRmsA: (obj.vRmsA / obj.pt) * 1000,
|
||||
vRmsB: (obj.vRmsB / obj.pt) * 1000,
|
||||
vRmsC: (obj.vRmsC / obj.pt) * 1000,
|
||||
// 电流有效值
|
||||
iRmsA: obj.iRmsA / obj.ct,
|
||||
iRmsB: obj.iRmsB / obj.ct,
|
||||
iRmsC: obj.iRmsC / obj.ct,
|
||||
//基波电压幅值
|
||||
v1A: (obj.v1A / obj.pt) * 1000,
|
||||
v1B: (obj.v1B / obj.pt) * 1000,
|
||||
v1C: (obj.v1C / obj.pt) * 1000,
|
||||
//基波电流幅值
|
||||
i1A: obj.i1A / obj.ct,
|
||||
i1B: obj.i1B / obj.ct,
|
||||
i1C: obj.i1C / obj.ct,
|
||||
//有功功率
|
||||
pA: (obj.pA / obj.pt / obj.ct) * 1000,
|
||||
pB: (obj.pB / obj.pt / obj.ct) * 1000,
|
||||
pC: (obj.pC / obj.pt / obj.ct) * 1000,
|
||||
pTot: (obj.pTot / obj.pt / obj.ct) * 1000,
|
||||
//无功功率
|
||||
qA: (obj.qA / obj.pt / obj.ct) * 1000,
|
||||
qB: (obj.qB / obj.pt / obj.ct) * 1000,
|
||||
qC: (obj.qC / obj.pt / obj.ct) * 1000,
|
||||
qTot: (obj.qTot / obj.pt / obj.ct) * 1000,
|
||||
//视在功率
|
||||
sA: (obj.sA / obj.pt / obj.ct) * 1000,
|
||||
sB: (obj.sB / obj.pt / obj.ct) * 1000,
|
||||
sC: (obj.sC / obj.pt / obj.ct) * 1000,
|
||||
sTot: (obj.sTot / obj.pt / obj.ct) * 1000
|
||||
}
|
||||
}
|
||||
//保留两位小数
|
||||
for (var i in obj) {
|
||||
if (typeof obj[i] == 'number' && obj[i] != 0 && Math.abs(obj[i]) % 1 != 0) {
|
||||
obj[i] = obj[i].toFixed(2)
|
||||
}
|
||||
}
|
||||
if (obj.hasOwnProperty('pA') && obj.hasOwnProperty('pB')) {
|
||||
mqttMessage.value = obj
|
||||
txtContent.value = JSON.stringify(obj)
|
||||
//如果消息返回值是二次值,下拉框是二次值只需要单位换算 除以1000
|
||||
//如果消息返回值是一次值,下拉框是一次值只需要单位换算 除以1000
|
||||
if (obj.dataLevel == formInline.dataLevel) {
|
||||
obj = {
|
||||
...obj,
|
||||
// 电压有效值
|
||||
vRmsA: obj.vRmsA,
|
||||
vRmsB: obj.vRmsB,
|
||||
vRmsC: obj.vRmsC,
|
||||
//基波电压幅值
|
||||
v1A: obj.v1A,
|
||||
v1B: obj.v1B,
|
||||
v1C: obj.v1C,
|
||||
//有功功率
|
||||
pA: obj.pA,
|
||||
pB: obj.pB,
|
||||
pC: obj.pC,
|
||||
pTot: obj.pTot,
|
||||
//无功功率
|
||||
qA: obj.qA,
|
||||
qB: obj.qB,
|
||||
qC: obj.qC,
|
||||
qTot: obj.qTot,
|
||||
//视在功率
|
||||
sA: obj.sA,
|
||||
sB: obj.sB,
|
||||
sC: obj.sC,
|
||||
sTot: obj.sTot
|
||||
}
|
||||
}
|
||||
//如果消息返回值是二次值,下拉框是一次值需要单位换算 除以1000 并且乘以pt ct
|
||||
if (obj.dataLevel == 'Secondary' && formInline.dataLevel == 'Primary') {
|
||||
obj = {
|
||||
...obj,
|
||||
// 电压有效值
|
||||
vRmsA: (obj.vRmsA * obj.pt) / 1000,
|
||||
vRmsB: (obj.vRmsB * obj.pt) / 1000,
|
||||
vRmsC: (obj.vRmsC * obj.pt) / 1000,
|
||||
// 电流有效值
|
||||
iRmsA: obj.iRmsA * obj.ct,
|
||||
iRmsB: obj.iRmsB * obj.ct,
|
||||
iRmsC: obj.iRmsC * obj.ct,
|
||||
//基波电压幅值
|
||||
v1A: (obj.v1A * obj.pt) / 1000,
|
||||
v1B: (obj.v1B * obj.pt) / 1000,
|
||||
v1C: (obj.v1C * obj.pt) / 1000,
|
||||
//基波电流幅值
|
||||
i1A: obj.i1A * obj.ct,
|
||||
i1B: obj.i1B * obj.ct,
|
||||
i1C: obj.i1C * obj.ct,
|
||||
//有功功率
|
||||
pA: (obj.pA * obj.pt * obj.ct) / 1000,
|
||||
pB: (obj.pB * obj.pt * obj.ct) / 1000,
|
||||
pC: (obj.pC * obj.pt * obj.ct) / 1000,
|
||||
pTot: (obj.pTot * obj.pt * obj.ct) / 1000,
|
||||
//无功功率
|
||||
qA: (obj.qA * obj.pt * obj.ct) / 1000,
|
||||
qB: (obj.qB * obj.pt * obj.ct) / 1000,
|
||||
qC: (obj.qC * obj.pt * obj.ct) / 1000,
|
||||
qTot: (obj.qTot * obj.pt * obj.ct) / 1000,
|
||||
//视在功率
|
||||
sA: (obj.sA * obj.pt * obj.ct) / 1000,
|
||||
sB: (obj.sB * obj.pt * obj.ct) / 1000,
|
||||
sC: (obj.sC * obj.pt * obj.ct) / 1000,
|
||||
sTot: (obj.sTot * obj.pt * obj.ct) / 1000
|
||||
}
|
||||
}
|
||||
//如果消息返回值是一次值,下拉框是二次值需要单位换算 乘以1000 并且除以pt ct
|
||||
if (obj.dataLevel == 'Primary' && formInline.dataLevel == 'Secondary') {
|
||||
obj = {
|
||||
...obj,
|
||||
// 电压有效值
|
||||
vRmsA: (obj.vRmsA / obj.pt) * 1000,
|
||||
vRmsB: (obj.vRmsB / obj.pt) * 1000,
|
||||
vRmsC: (obj.vRmsC / obj.pt) * 1000,
|
||||
// 电流有效值
|
||||
iRmsA: obj.iRmsA / obj.ct,
|
||||
iRmsB: obj.iRmsB / obj.ct,
|
||||
iRmsC: obj.iRmsC / obj.ct,
|
||||
//基波电压幅值
|
||||
v1A: (obj.v1A / obj.pt) * 1000,
|
||||
v1B: (obj.v1B / obj.pt) * 1000,
|
||||
v1C: (obj.v1C / obj.pt) * 1000,
|
||||
//基波电流幅值
|
||||
i1A: obj.i1A / obj.ct,
|
||||
i1B: obj.i1B / obj.ct,
|
||||
i1C: obj.i1C / obj.ct,
|
||||
//有功功率
|
||||
pA: (obj.pA / obj.pt / obj.ct) * 1000,
|
||||
pB: (obj.pB / obj.pt / obj.ct) * 1000,
|
||||
pC: (obj.pC / obj.pt / obj.ct) * 1000,
|
||||
pTot: (obj.pTot / obj.pt / obj.ct) * 1000,
|
||||
//无功功率
|
||||
qA: (obj.qA / obj.pt / obj.ct) * 1000,
|
||||
qB: (obj.qB / obj.pt / obj.ct) * 1000,
|
||||
qC: (obj.qC / obj.pt / obj.ct) * 1000,
|
||||
qTot: (obj.qTot / obj.pt / obj.ct) * 1000,
|
||||
//视在功率
|
||||
sA: (obj.sA / obj.pt / obj.ct) * 1000,
|
||||
sB: (obj.sB / obj.pt / obj.ct) * 1000,
|
||||
sC: (obj.sC / obj.pt / obj.ct) * 1000,
|
||||
sTot: (obj.sTot / obj.pt / obj.ct) * 1000
|
||||
}
|
||||
}
|
||||
//保留两位小数
|
||||
for (var i in obj) {
|
||||
if (typeof obj[i] == 'number' && obj[i] != 0 && Math.abs(obj[i]) % 1 != 0) {
|
||||
obj[i] = obj[i].toFixed(2)
|
||||
}
|
||||
}
|
||||
if (obj.hasOwnProperty('pA') && obj.hasOwnProperty('pB')) {
|
||||
mqttMessage.value = obj
|
||||
txtContent.value = JSON.stringify(obj)
|
||||
|
||||
//更新实时数据主页面值
|
||||
realTimeFlag.value &&
|
||||
realTimeRef.value &&
|
||||
realTimeRef.value.setRealData(mqttMessage.value, formInline.dataLevel)
|
||||
tableLoading.value = false
|
||||
//更新实时趋势折线图数据
|
||||
if (sonTab.value == 2) {
|
||||
!realTimeFlag.value &&
|
||||
sonTab.value == 2 &&
|
||||
harmonicSpectrumRef.value &&
|
||||
harmonicSpectrumRef.value.setHarmonicSpectrumData(mqttMessage.value)
|
||||
}
|
||||
}
|
||||
//更新实时数据主页面值
|
||||
realTimeFlag.value &&
|
||||
realTimeRef.value &&
|
||||
realTimeRef.value.setRealData(mqttMessage.value, formInline.dataLevel)
|
||||
tableLoading.value = false
|
||||
//更新实时趋势折线图数据
|
||||
if (sonTab.value == 2) {
|
||||
!realTimeFlag.value &&
|
||||
sonTab.value == 2 &&
|
||||
harmonicSpectrumRef.value &&
|
||||
harmonicSpectrumRef.value.setHarmonicSpectrumData(mqttMessage.value)
|
||||
}
|
||||
}
|
||||
|
||||
//更新谐波频谱数据
|
||||
// !realTimeFlag.value &&
|
||||
// sonTab.value == 1 &&
|
||||
// realTrendRef.value &&
|
||||
// realTrendRef.value.setRealTrendData(obj)
|
||||
//更新谐波频谱数据
|
||||
// !realTimeFlag.value &&
|
||||
// sonTab.value == 1 &&
|
||||
// realTrendRef.value &&
|
||||
// realTrendRef.value.setRealTrendData(obj)
|
||||
}
|
||||
|
||||
const handleClick = async (tab?: any) => {
|
||||
@@ -1499,7 +1301,7 @@ const refreshTheState = () => {
|
||||
moduleDataRef.value.getModule(deviceData.value.ndid)
|
||||
}
|
||||
//模版下载
|
||||
const handleDownLoadTemplate = () => {}
|
||||
const handleDownLoadTemplate = () => { }
|
||||
//补召日志
|
||||
const analysisListRef = ref()
|
||||
//打开补召日志
|
||||
@@ -1565,7 +1367,7 @@ const downloadTxt = () => {
|
||||
URL.revokeObjectURL(url)
|
||||
}
|
||||
|
||||
onMounted(() => {})
|
||||
onMounted(() => { })
|
||||
onBeforeUnmount(() => {
|
||||
clearInterval(realDataTimer.value)
|
||||
clearInterval(trendTimer.value)
|
||||
@@ -1689,14 +1491,14 @@ onBeforeUnmount(() => {
|
||||
|
||||
.data_time {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
// height: 40px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
p {
|
||||
font-weight: 800;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
font-size: 13px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,116 +1,200 @@
|
||||
<template>
|
||||
<div class="near-realtime-data">
|
||||
<div class="view_bot">
|
||||
<template v-for="(section, sectionIndex) in tableSections" :key="sectionIndex">
|
||||
<vxe-table class="near-realtime-table" border height="" width="100%" :data="[section.row]"
|
||||
:column-config="tableColumnConfig" :tooltip-config="tableTooltipConfig">
|
||||
<vxe-colgroup v-for="(item, colIndex) in section.abcItems" :key="`abc-${colIndex}`" align="center"
|
||||
:title="item.otherName" :width="getMetricWidth(section)">
|
||||
<vxe-column align="center" :field="`v${colIndex}A`" title="A相" :width="getPhaseWidth(section)"
|
||||
:formatter="cellFormatter"></vxe-column>
|
||||
<vxe-column align="center" :field="`v${colIndex}B`" title="B相" :width="getPhaseWidth(section)"
|
||||
:formatter="cellFormatter"></vxe-column>
|
||||
<vxe-column align="center" :field="`v${colIndex}C`" title="C相" :width="getPhaseWidth(section)"
|
||||
:formatter="cellFormatter"></vxe-column>
|
||||
</vxe-colgroup>
|
||||
<vxe-column v-for="(item, colIndex) in section.scalarItems" :key="`scalar-${colIndex}`"
|
||||
align="center" :field="`s${colIndex}`" :title="item.otherName" :width="getMetricWidth(section)"
|
||||
show-overflow :formatter="cellFormatter"></vxe-column>
|
||||
<vxe-column v-for="emptyIndex in section.emptySlotCount" :key="`empty-${emptyIndex}`" align="center"
|
||||
:width="getMetricWidth(section)"></vxe-column>
|
||||
</vxe-table>
|
||||
<div v-if="sectionIndex < tableSections.length - 1" class="table-gap"></div>
|
||||
</template>
|
||||
|
||||
<div>
|
||||
<vxe-table auto-resize :data="dataList" v-bind="defaultAttribute" :key="key" :mergeCells="mergeCells"
|
||||
v-if="flag">
|
||||
<vxe-column v-for="item in column" :field="item.field" :title="item.title" :formatter="formatter"
|
||||
:width="item.width"></vxe-column>
|
||||
|
||||
</vxe-table>
|
||||
<vxe-table v-if="flag1" auto-resize :data="dataList1" v-bind="defaultAttribute" :key="key"
|
||||
:mergeCells="mergeCells">
|
||||
<vxe-column field="otherName" title="名称"></vxe-column>
|
||||
<vxe-column field="valueM" title="数据" :formatter="formatter"></vxe-column>
|
||||
<vxe-column field="otherName1" title="名称"></vxe-column>
|
||||
<vxe-column field="valueM1" title="数据" :formatter="formatter"></vxe-column>
|
||||
|
||||
</vxe-table>
|
||||
<el-empty :style="height" description="暂无数据" v-if="!flag && !flag1"></el-empty>
|
||||
<el-empty :style="height" description="暂无数据" v-if="tableSections.length === 0" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script setup lang='ts'>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { ref, reactive } from 'vue'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import type { VxeTablePropTypes } from 'vxe-table'
|
||||
const props = defineProps(['tableData'])
|
||||
const height = mainHeight(325)
|
||||
const dataList: any = ref([])
|
||||
const key: any = ref(0)
|
||||
const column: any = ref([])
|
||||
const dataList1: any = ref([])
|
||||
const targetName: any = ref('')
|
||||
const flag = ref(true)
|
||||
const flag1 = ref(true)
|
||||
import { ref } from 'vue'
|
||||
|
||||
const mergeCells: any = ref<VxeTablePropTypes.MergeCells>([
|
||||
// { row: 0, col: 1, rowspan: 1, colspan: 3 },
|
||||
const ROW_WITH_ABC = 4
|
||||
const ROW_SCALAR_ONLY = 5
|
||||
|
||||
])
|
||||
const setData = (data: any, targetType: any) => {
|
||||
let list = JSON.parse(JSON.stringify(data))
|
||||
// dataList1.value = []
|
||||
let list1: any = []
|
||||
dataList.value = []
|
||||
dataList1.value = []
|
||||
flag.value = true
|
||||
flag1.value = true
|
||||
targetName.value = targetType[0].name
|
||||
if (targetType[0].name == '基本数据') {
|
||||
flag.value = false
|
||||
flag1.value = false
|
||||
list.forEach((item: any, index: number) => {
|
||||
if (item.valueA == null && item.valueB == null && item.valueC == null) {
|
||||
list1.push(item)
|
||||
|
||||
flag1.value = true
|
||||
} else {
|
||||
dataList.value.push(item)
|
||||
flag.value = true
|
||||
}
|
||||
|
||||
})
|
||||
if (list1.length > 0) {
|
||||
list1.forEach((item: any, index: number) => {
|
||||
if (index % 2 == 0) {
|
||||
dataList1.value.push(item)
|
||||
} else {
|
||||
dataList1.value[dataList1.value.length - 1].otherName1 = item.otherName
|
||||
dataList1.value[dataList1.value.length - 1].valueM1 = item.valueM
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
column.value = [
|
||||
{ field: 'otherName', title: '名称', },
|
||||
{ field: 'valueA', title: 'A相', },
|
||||
{ field: 'valueB', title: 'B相', },
|
||||
{ field: 'valueC', title: 'C相', },
|
||||
// { field: 'valueM', title: '', },
|
||||
]
|
||||
} else {
|
||||
dataList.value = list
|
||||
flag.value = true
|
||||
|
||||
flag1.value = false
|
||||
column.value = [
|
||||
{ field: 'otherName', title: '谐波次数', },
|
||||
{ field: 'valueA', title: 'A相', },
|
||||
{ field: 'valueB', title: 'B相', },
|
||||
{ field: 'valueC', title: 'C相', },
|
||||
]
|
||||
}
|
||||
key.value += 1
|
||||
interface MetricItem {
|
||||
type: 'abc' | 'scalar'
|
||||
data: any
|
||||
}
|
||||
const formatter = (row: any) => {
|
||||
if (row.column.property == 'valueM1') {
|
||||
if (row.row.otherName1 == null) {
|
||||
row.cellValue == ''
|
||||
} else {
|
||||
return row.cellValue == null ? '/' : row.cellValue == 3.14159 ? '/' : row.cellValue
|
||||
|
||||
}
|
||||
interface TableSection {
|
||||
abcItems: any[]
|
||||
scalarItems: any[]
|
||||
row: Record<string, unknown>
|
||||
slotsPerRow: number
|
||||
emptySlotCount: number
|
||||
}
|
||||
|
||||
} else {
|
||||
return row.cellValue == null ? '/' : row.cellValue == 3.14159 ? '/' : row.cellValue
|
||||
const height = mainHeight(345)
|
||||
const tableSections = ref<TableSection[]>([])
|
||||
|
||||
const tableColumnConfig = { resizable: false, tooltip: true }
|
||||
const tableTooltipConfig = { enterable: true }
|
||||
|
||||
const getMetricWidth = (section: TableSection) => `${100 / section.slotsPerRow}%`
|
||||
|
||||
const getPhaseWidth = (section: TableSection) => `${100 / section.slotsPerRow / 3}%`
|
||||
|
||||
const formatCellValue = (value: unknown): string | number => {
|
||||
if (value == null || value === 3.14159) return '/'
|
||||
return typeof value === 'number' || typeof value === 'string' ? value : String(value)
|
||||
}
|
||||
|
||||
const cellFormatter = ({ cellValue }: { cellValue: unknown }) => formatCellValue(cellValue)
|
||||
|
||||
const hasAbcValues = (item: any) =>
|
||||
item.valueA != null || item.valueB != null || item.valueC != null
|
||||
|
||||
const buildRow = (abcItems: any[], scalarItems: any[]) => {
|
||||
const row: Record<string, unknown> = {}
|
||||
abcItems.forEach((item, index) => {
|
||||
row[`v${index}A`] = item.valueA
|
||||
row[`v${index}B`] = item.valueB
|
||||
row[`v${index}C`] = item.valueC
|
||||
})
|
||||
scalarItems.forEach((item, index) => {
|
||||
row[`s${index}`] = item.valueM
|
||||
})
|
||||
return row
|
||||
}
|
||||
|
||||
const buildTableSections = (abcList: any[], scalarList: any[]) => {
|
||||
const unified: MetricItem[] = [
|
||||
...abcList.map((data) => ({ type: 'abc' as const, data })),
|
||||
...scalarList.map((data) => ({ type: 'scalar' as const, data })),
|
||||
]
|
||||
|
||||
const sections: TableSection[] = []
|
||||
let index = 0
|
||||
|
||||
while (index < unified.length) {
|
||||
const hasAbc = unified[index].type === 'abc'
|
||||
const maxCount = hasAbc ? ROW_WITH_ABC : ROW_SCALAR_ONLY
|
||||
const chunk = unified.slice(index, index + maxCount)
|
||||
index += chunk.length
|
||||
|
||||
const abcItems = chunk.filter((item) => item.type === 'abc').map((item) => item.data)
|
||||
const scalarItems = chunk.filter((item) => item.type === 'scalar').map((item) => item.data)
|
||||
const slotsPerRow = abcItems.length > 0 ? ROW_WITH_ABC : ROW_SCALAR_ONLY
|
||||
const metricCount = abcItems.length + scalarItems.length
|
||||
sections.push({
|
||||
abcItems,
|
||||
scalarItems,
|
||||
row: buildRow(abcItems, scalarItems),
|
||||
slotsPerRow,
|
||||
emptySlotCount: slotsPerRow - metricCount,
|
||||
})
|
||||
}
|
||||
|
||||
return sections
|
||||
}
|
||||
|
||||
const setData = (data: any, _targetType: any) => {
|
||||
const list = JSON.parse(JSON.stringify(data))
|
||||
const abcList: any[] = []
|
||||
const scalarList: any[] = []
|
||||
|
||||
list.forEach((item: any) => {
|
||||
if (hasAbcValues(item)) {
|
||||
abcList.push(item)
|
||||
} else {
|
||||
scalarList.push(item)
|
||||
}
|
||||
})
|
||||
|
||||
tableSections.value = buildTableSections(abcList, scalarList)
|
||||
}
|
||||
|
||||
defineExpose({ setData })
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.near-realtime-data {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.view_bot {
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.table-gap {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
:deep(.view_bot) {
|
||||
.near-realtime-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.near-realtime-table .vxe-table--render-wrapper,
|
||||
.near-realtime-table .vxe-table--main-wrapper,
|
||||
.near-realtime-table .vxe-table--header-wrapper,
|
||||
.near-realtime-table .vxe-table--body-wrapper,
|
||||
.near-realtime-table .vxe-table--layout-wrapper {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.near-realtime-table table {
|
||||
width: 100% !important;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.near-realtime-table .vxe-header--column .vxe-cell,
|
||||
.near-realtime-table .vxe-body--column .vxe-cell {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
height: 22px !important;
|
||||
}
|
||||
|
||||
.vxe-table--render-default .vxe-body--column:not(.col--ellipsis),
|
||||
.vxe-table--render-default .vxe-footer--column:not(.col--ellipsis),
|
||||
.vxe-table--render-default .vxe-header--column:not(.col--ellipsis) {
|
||||
padding: 5px !important;
|
||||
}
|
||||
|
||||
.vxe-table--body-wrapper {
|
||||
min-height: 32px !important;
|
||||
}
|
||||
|
||||
.vxe-body--row {
|
||||
height: 32px !important;
|
||||
}
|
||||
|
||||
.vxe-table--render-default {
|
||||
font-size: 13px !important;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.vxe-table--render-default .vxe-body--column.col--ellipsis, .vxe-table--render-default .vxe-footer--column.col--ellipsis, .vxe-table--render-default .vxe-header--column.col--ellipsis, .vxe-table--render-default.vxe-editable .vxe-body--column) {
|
||||
height: 32px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<TableHeader>
|
||||
<template v-slot:select>
|
||||
<el-form-item label="设备类型">
|
||||
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备类型" /> -->
|
||||
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备类型" /> -->
|
||||
<el-select v-model.trim="tableStore.table.params.devType" clearable @change="devTypeChange"
|
||||
placeholder="请选择设备类型">
|
||||
<el-option v-for="item in devTypeOptions" :key="item.value" :label="item.label"
|
||||
@@ -49,11 +49,11 @@
|
||||
:before-close="resetForm" draggable width="40%">
|
||||
<el-form :model="form" label-width="120px" :rules="rules" ref="ruleFormRef">
|
||||
<el-form-item label="设备名称:" prop="name">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.name" autocomplete="off" clearable
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.name" autocomplete="off" clearable
|
||||
placeholder="请输入(项目名称+设备名称)"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="网络设备ID:" prop="ndid" class="top">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.ndid" autocomplete="off"
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.ndid" autocomplete="off"
|
||||
placeholder="请输入"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备类型:" prop="devType" class="top">
|
||||
@@ -76,7 +76,7 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="合同号:" prop="cntractNo" class="top">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.cntractNo" autocomplete="off"
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.cntractNo" autocomplete="off"
|
||||
placeholder="请输入"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<TableHeader ref="tableHeaderRef" :showSearch="false" @selectChange="selectChange">
|
||||
<template v-slot:select>
|
||||
<el-form-item>
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
<DatePicker ref="datePickerRef" :timeKeyList="[ '3', '4', '5']"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item label="电度指标" label-width="80px">
|
||||
<el-select style="width: 200px" multiple :multiple-limit="3" collapse-tags filterable
|
||||
@@ -37,7 +37,7 @@
|
||||
</el-form-item> -->
|
||||
</template>
|
||||
<template #operation>
|
||||
<el-button type="primary" icon="el-icon-Search" @click="init()">查询</el-button>
|
||||
<el-button type="primary" icon="el-icon-Search" @click="init()" :loading="loading">查询</el-button>
|
||||
<el-button :type="timeControl ? 'primary' : ''" icon="el-icon-Sort" @click="setTimeControl">
|
||||
缺失数据
|
||||
</el-button>
|
||||
|
||||
@@ -19,6 +19,7 @@ import { ArrowLeft, Message } from '@element-plus/icons-vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { analyseWave, getFileByEventId } from '@/api/common'
|
||||
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
const tableParams: any = ref({})
|
||||
const refheader = ref()
|
||||
const view = ref(true)
|
||||
@@ -38,7 +39,9 @@ const props = defineProps({
|
||||
default: '0'
|
||||
}
|
||||
})
|
||||
|
||||
const dictData = useDictData()
|
||||
const ReasonList: any = dictData.getBasicData('Event_Reason')
|
||||
const EventTypeList: any = dictData.getBasicData('Event_Type')
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/cs-device-boot/csGroup/deviceDataByType',
|
||||
publicHeight: 215,
|
||||
@@ -52,16 +55,16 @@ const tableStore: any = new TableStore({
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ field: 'startTime', title: '暂降发生时刻', minWidth: 180, sortable: true },
|
||||
{ field: 'startTime', title: '发生时刻', minWidth: 180, sortable: true },
|
||||
|
||||
{
|
||||
field: 'featureAmplitude',
|
||||
title: '暂降(骤升)幅值(%)',
|
||||
minWidth: 160,
|
||||
title: '暂降幅值(%)',
|
||||
minWidth: 120,
|
||||
sortable: true,
|
||||
formatter: (row: any) => {
|
||||
//row.cellValue = row.cellValue + '' ? row.cellValue.toFixed(2) : '/'
|
||||
row.cellValue = row.cellValue != null ? Number(row.cellValue).toFixed(2) : '/'
|
||||
row.cellValue = row.cellValue != null ? Number(row.cellValue).toFixed(2) : '-'
|
||||
if (String(row.cellValue).split('.')[1] == '00') {
|
||||
row.cellValue = String(row.cellValue).split('.')[0]
|
||||
}
|
||||
@@ -76,7 +79,7 @@ const tableStore: any = new TableStore({
|
||||
formatter: (row: any) => {
|
||||
// console.log('🚀 ~ row.cellValue:', row.cellValue)
|
||||
|
||||
return row.cellValue ? (row.cellValue - 0).toFixed(2) : '/'
|
||||
return row.cellValue ? (row.cellValue - 0).toFixed(2) : '-'
|
||||
},
|
||||
sortable: true
|
||||
},
|
||||
@@ -85,12 +88,27 @@ const tableStore: any = new TableStore({
|
||||
title: '相别',
|
||||
minWidth: 80,
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
return row.cellValue || '-'
|
||||
}
|
||||
},
|
||||
{ field: 'showName', title: '触发类型', minWidth: 120 },
|
||||
{
|
||||
title: '暂降原因', field: 'advanceReason', minWidth: 100, align: 'center', formatter: (row: any) => {
|
||||
return ReasonList.find((item: any) => item.value == row.cellValue)?.label || '未知'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '暂降类型', field: 'advanceType', minWidth: 100, align: 'center', formatter: (row: any) => {
|
||||
return EventTypeList.find((item: any) => item.value == row.cellValue)?.label || '未知'
|
||||
}
|
||||
},
|
||||
{ title: '电压等级(kV)', field: 'lineVoltage', minWidth: 120, align: 'center', sortable: true, },
|
||||
{
|
||||
title: '发生位置', field: 'sagSource', minWidth: 120, align: 'center', formatter: (row: any) => {
|
||||
|
||||
|
||||
return row.cellValue == 1 ? '上游' : row.cellValue == 2 ? '下游' : '未知'
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: '操作',
|
||||
@@ -150,7 +168,7 @@ const tableStore: any = new TableStore({
|
||||
icon: 'el-icon-DataLine',
|
||||
render: 'basicButton',
|
||||
disabled: row => {
|
||||
return row.wavePath
|
||||
return row.wavePath
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -165,6 +183,7 @@ const tableStore: any = new TableStore({
|
||||
return !row.wavePath
|
||||
},
|
||||
click: row => {
|
||||
row.loading2 = true
|
||||
ElMessage.info('下载中......')
|
||||
getFileZip({ eventId: row.id }).then(res => {
|
||||
let blob = new Blob([res], { type: 'application/zip' }) // console.log(blob) // var href = window.URL.createObjectURL(blob); //创建下载的链接
|
||||
@@ -176,6 +195,9 @@ const tableStore: any = new TableStore({
|
||||
link.click() //执行下载
|
||||
document.body.removeChild(link) //释放标签
|
||||
ElMessage.success('波形下载成功')
|
||||
row.loading2 = false
|
||||
}).catch(() => {
|
||||
row.loading2 = false
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
@@ -85,25 +85,78 @@ function fillDataFromFirstTime(data, interval = 10) {
|
||||
return filledData
|
||||
}
|
||||
|
||||
const COLOR_NORMAL = '#2ab914'
|
||||
const COLOR_INTERRUPT = '#e26257'
|
||||
|
||||
/** 分段着色:水平段用当前状态色,切换垂直段用目标状态色 */
|
||||
const buildColoredStepSeries = (data: any[]) => {
|
||||
const points = data.map((item: any) => [item.time, item.type == 0 ? 1 : 10])
|
||||
if (points.length === 0) return []
|
||||
|
||||
const series: any[] = []
|
||||
let i = 0
|
||||
|
||||
while (i < points.length) {
|
||||
const value = points[i][1]
|
||||
const color = value === 1 ? COLOR_INTERRUPT : COLOR_NORMAL
|
||||
const segment: any[] = []
|
||||
|
||||
// 垂直切换段由目标状态 series 绘制(正常→中断红线,中断→正常绿线)
|
||||
if (i > 0 && points[i][1] !== points[i - 1][1]) {
|
||||
segment.push([points[i][0], points[i - 1][1]])
|
||||
}
|
||||
|
||||
segment.push(points[i])
|
||||
let j = i + 1
|
||||
|
||||
while (j < points.length && points[j][1] === value) {
|
||||
segment.push(points[j])
|
||||
j++
|
||||
}
|
||||
|
||||
// 仅水平延伸到切换时刻,垂直段由下一段绘制
|
||||
if (j < points.length) {
|
||||
segment.push([points[j][0], value])
|
||||
}
|
||||
|
||||
series.push({
|
||||
name: '运行数据',
|
||||
type: 'line',
|
||||
step: 'end',
|
||||
showSymbol: false,
|
||||
data: segment,
|
||||
lineStyle: { color, width: 2 }
|
||||
})
|
||||
|
||||
i = j
|
||||
}
|
||||
|
||||
return series
|
||||
}
|
||||
|
||||
const getStatusText = (val: number | string) => {
|
||||
if (val === 1 || val === '1') return '中断'
|
||||
if (val === 10 || val === '10') return '正常'
|
||||
return ''
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
options1.value = {
|
||||
title: {
|
||||
text: '运行状态'
|
||||
text: '运行数据'
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function (params: any) {
|
||||
var res = params[0].data[0] + '<br/>运行状态:'
|
||||
var texts = ''
|
||||
if (params[0].data[1] === 1 || params[0].data[1] === '1') {
|
||||
texts = '中断'
|
||||
} else if (params[0].data[1] === 10 || params[0].data[1] === '10') {
|
||||
texts = '正常'
|
||||
}
|
||||
res = res + texts
|
||||
return res
|
||||
const items = (Array.isArray(params) ? params : [params]).filter(p => p?.data?.[1] != null)
|
||||
if (!items.length) return ''
|
||||
// 切换节点取目标状态(后一段 series 的值)
|
||||
const item = items[items.length - 1]
|
||||
const val = item.data[1]
|
||||
return `${item.data[0]}<br/>运行数据:${getStatusText(val)}`
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
@@ -146,16 +199,7 @@ const init = () => {
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '运行状态',
|
||||
data: list.value.map((item: any, index: number) => [item.time, item.type == 0 ? 1 : 10]),
|
||||
type: 'line',
|
||||
showSymbol: false,
|
||||
|
||||
step: 'end'
|
||||
}
|
||||
]
|
||||
series: buildColoredStepSeries(list.value)
|
||||
}
|
||||
}
|
||||
defineExpose({
|
||||
|
||||
@@ -1,52 +1,61 @@
|
||||
<template>
|
||||
<div class="view" v-loading="loading">
|
||||
<el-collapse v-model.trim="activeNames">
|
||||
<el-collapse-item title="基础数据" name="1">
|
||||
<div class="view_top">
|
||||
<!-- 左侧仪表盘 -->
|
||||
<div class="view_top_left">
|
||||
<div class="left_charts_title">电压有效值({{ voltageUnit }})</div>
|
||||
<div class="left_charts">
|
||||
<MyEchart :pieInterVal="true" ref="pieChart1" :options="echartsDataV1"></MyEchart>
|
||||
|
||||
<div class="charts-panel">
|
||||
<el-collapse v-model="activeNames" class="charts-collapse">
|
||||
<el-collapse-item name="1">
|
||||
<template #title>
|
||||
<div class="charts-collapse-header">
|
||||
<div style="font-weight: 700; font-size: 13px; text-align: center">数据时间:{{ dataTime || '-' }}</div>
|
||||
</div>
|
||||
<div class="left_charts">
|
||||
<MyEchart :pieInterVal="true" ref="pieChart2" :options="echartsDataV2"></MyEchart>
|
||||
</template>
|
||||
<template #icon>
|
||||
<span class="charts-collapse-action">
|
||||
<span class="charts-collapse-text">{{ chartPanelExpanded ? '收起' : '展开' }}</span>
|
||||
<el-icon class="charts-collapse-icon" :class="{ 'is-expanded': chartPanelExpanded }">
|
||||
<ArrowDown />
|
||||
</el-icon>
|
||||
</span>
|
||||
</template>
|
||||
<div class="view_top mb10">
|
||||
<div class="view_top_left">
|
||||
<div class="left_charts_title">电压有效值({{ voltageUnit }})</div>
|
||||
<div class="left_charts">
|
||||
<MyEchart :pieInterVal="true" ref="pieChart1" :options="echartsDataV1"></MyEchart>
|
||||
</div>
|
||||
<div class="left_charts">
|
||||
<MyEchart :pieInterVal="true" ref="pieChart2" :options="echartsDataV2"></MyEchart>
|
||||
</div>
|
||||
<div class="left_charts">
|
||||
<MyEchart :pieInterVal="true" ref="pieChart3" :options="echartsDataV3"></MyEchart>
|
||||
</div>
|
||||
</div>
|
||||
<div class="left_charts">
|
||||
<MyEchart :pieInterVal="true" ref="pieChart3" :options="echartsDataV3"></MyEchart>
|
||||
<div class="view_top_mid">
|
||||
<div class="mid_charts_title">基波电压/电流幅值(相位)</div>
|
||||
<div class="mid_charts">
|
||||
<MyEchart :pieInterVal="true" :options="echartsData1"></MyEchart>
|
||||
</div>
|
||||
</div>
|
||||
<div class="view_top_right">
|
||||
<div class="right_charts_title">电流有效值(A)</div>
|
||||
<div class="right_charts">
|
||||
<MyEchart :pieInterVal="true" ref="pieChart4" :options="echartsDataA1"></MyEchart>
|
||||
</div>
|
||||
<div class="right_charts">
|
||||
<MyEchart :pieInterVal="true" ref="pieChart5" :options="echartsDataA2"></MyEchart>
|
||||
</div>
|
||||
<div class="right_charts">
|
||||
<MyEchart :pieInterVal="true" ref="pieChart6" :options="echartsDataA3"></MyEchart>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="view_top_mid">
|
||||
<div class="mid_charts_title">基波电压/电流幅值(相位)</div>
|
||||
<div class="mid_charts">
|
||||
<MyEchart :pieInterVal="true" :options="echartsData1"></MyEchart>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧仪表盘 -->
|
||||
<div class="view_top_right">
|
||||
<div class="right_charts_title">电流有效值(A)</div>
|
||||
<div class="right_charts">
|
||||
<MyEchart :pieInterVal="true" ref="pieChart4" :options="echartsDataA1"></MyEchart>
|
||||
</div>
|
||||
<div class="right_charts">
|
||||
<MyEchart :pieInterVal="true" ref="pieChart5" :options="echartsDataA2"></MyEchart>
|
||||
</div>
|
||||
<div class="right_charts">
|
||||
<MyEchart :pieInterVal="true" ref="pieChart6" :options="echartsDataA3"></MyEchart>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</div>
|
||||
|
||||
<div class="view_bot">
|
||||
<vxe-table
|
||||
border
|
||||
height=""
|
||||
:data="realList"
|
||||
:column-config="{ resizable: true, tooltip: true }"
|
||||
:tooltip-config="{ enterable: true }"
|
||||
>
|
||||
<vxe-table border height="" :data="realList" :column-config="{ resizable: true, tooltip: true }"
|
||||
:tooltip-config="{ enterable: true }">
|
||||
<vxe-colgroup align="center" :title="`电压有效值(${voltageUnit})`">
|
||||
<vxe-column align="center" field="vRmsA" title="A相"></vxe-column>
|
||||
<vxe-column align="center" field="vRmsB" title="B相"></vxe-column>
|
||||
@@ -69,13 +78,8 @@
|
||||
</vxe-colgroup>
|
||||
</vxe-table>
|
||||
<br />
|
||||
<vxe-table
|
||||
border
|
||||
height=""
|
||||
:data="realList"
|
||||
:column-config="{ resizable: true, tooltip: true }"
|
||||
:tooltip-config="{ enterable: true }"
|
||||
>
|
||||
<vxe-table border height="" :data="realList" :column-config="{ resizable: true, tooltip: true }"
|
||||
:tooltip-config="{ enterable: true }">
|
||||
<vxe-column align="center" field="freq" width="140" title="频率(Hz)"></vxe-column>
|
||||
<vxe-column align="center" field="freqDev" width="120" title="频率偏差(Hz)"></vxe-column>
|
||||
<vxe-column align="center" width="180" field="vUnbalance" title="电压不平衡度(%)"></vxe-column>
|
||||
@@ -92,13 +96,8 @@
|
||||
</vxe-colgroup>
|
||||
</vxe-table>
|
||||
<br />
|
||||
<vxe-table
|
||||
border
|
||||
height=""
|
||||
:data="realList"
|
||||
:column-config="{ resizable: true, tooltip: true }"
|
||||
:tooltip-config="{ enterable: true }"
|
||||
>
|
||||
<vxe-table border height="" :data="realList" :column-config="{ resizable: true, tooltip: true }"
|
||||
:tooltip-config="{ enterable: true }">
|
||||
<vxe-colgroup align="center" title="电压偏差(%)">
|
||||
<vxe-column align="center" field="vDevA" title="A相"></vxe-column>
|
||||
<vxe-column align="center" field="vDevB" title="B相"></vxe-column>
|
||||
@@ -122,13 +121,8 @@
|
||||
</vxe-colgroup>
|
||||
</vxe-table>
|
||||
<br />
|
||||
<vxe-table
|
||||
border
|
||||
height=""
|
||||
:data="realList"
|
||||
:column-config="{ resizable: true, tooltip: true }"
|
||||
:tooltip-config="{ enterable: true }"
|
||||
>
|
||||
<vxe-table border height="" :data="realList" :column-config="{ resizable: true, tooltip: true }"
|
||||
:tooltip-config="{ enterable: true }">
|
||||
<vxe-colgroup align="center" :title="`无功功率(${reactivePowerUnit})`">
|
||||
<vxe-column align="center" field="qA" title="A相"></vxe-column>
|
||||
<vxe-column align="center" field="qB" title="B相"></vxe-column>
|
||||
@@ -162,18 +156,23 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import { ArrowDown } from '@element-plus/icons-vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { getRealTimeTableList } from '@/api/cs-device-boot/EquipmentDelivery'
|
||||
const pieChartRef: any = ref()
|
||||
const activeNames = ref(['1'])
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
dataTime: String
|
||||
})
|
||||
const activeNames = ref<string[]>(['1'])
|
||||
const chartPanelExpanded = computed(() => activeNames.value.includes('1'))
|
||||
const pieChart1: any = ref()
|
||||
const pieChart2: any = ref()
|
||||
const pieChart3: any = ref()
|
||||
const pieChart4: any = ref()
|
||||
const pieChart5: any = ref()
|
||||
const pieChart6: any = ref()
|
||||
const echartsData: any = ref({})
|
||||
const echartsData1: any = ref({})
|
||||
//电压有效值
|
||||
const echartsDataV1: any = ref({})
|
||||
@@ -187,7 +186,170 @@ const echartsDataA3: any = ref({})
|
||||
const currentDataLevel = ref('Primary')
|
||||
const previousDataLevel = ref('')
|
||||
|
||||
//渲染中间相角图
|
||||
const PHASE_COLORS = {
|
||||
A: '#DAA520',
|
||||
B: '#2E8B57',
|
||||
C: '#A52a2a',
|
||||
}
|
||||
|
||||
const PHASE_RING_COLOR = '#9D322D'
|
||||
|
||||
type GaugeAlign = 'left' | 'right'
|
||||
|
||||
const createPhaseGaugeData = (name: string, value: number, color: string) => ({
|
||||
name,
|
||||
value,
|
||||
itemStyle: { color, shadowBlur: 0, shadowColor: 'transparent' },
|
||||
})
|
||||
|
||||
const createRmsGaugeOptions = (name: string, color: string, align: GaugeAlign) => {
|
||||
const isLeft = align === 'left'
|
||||
return {
|
||||
options: {
|
||||
tooltip: {},
|
||||
toolbox: { show: false },
|
||||
series: [
|
||||
{
|
||||
type: 'gauge',
|
||||
startAngle: isLeft ? 180 : 90,
|
||||
endAngle: isLeft ? 90 : 0,
|
||||
min: 0,
|
||||
max: 12,
|
||||
radius: '180%',
|
||||
center: isLeft ? ['70%', '95%'] : ['30%', '95%'],
|
||||
splitNumber: 2,
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
width: 5,
|
||||
shadowBlur: 0,
|
||||
color: [[1, color]],
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: true,
|
||||
distance: -5,
|
||||
length: 12,
|
||||
lineStyle: {
|
||||
color,
|
||||
width: 2,
|
||||
type: 'solid',
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
distance: 12,
|
||||
color,
|
||||
fontSize: 12,
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
distance: -5,
|
||||
length: 20,
|
||||
lineStyle: {
|
||||
color,
|
||||
width: 3,
|
||||
type: 'solid',
|
||||
},
|
||||
},
|
||||
title: {
|
||||
show: true,
|
||||
fontWeight: 'bolder',
|
||||
fontSize: 12,
|
||||
color,
|
||||
offsetCenter: isLeft ? ['-130%', '-20%'] : ['130%', '-20%'],
|
||||
},
|
||||
detail: {
|
||||
fontSize: 14,
|
||||
color,
|
||||
valueAnimation: true,
|
||||
formatter: '{value}',
|
||||
offsetCenter: isLeft ? ['50%', '-35%'] : ['-45%', '-35%'],
|
||||
},
|
||||
pointer: {
|
||||
length: '80%',
|
||||
width: 3,
|
||||
shadowBlur: 0,
|
||||
shadowColor: 'transparent',
|
||||
itemStyle: {
|
||||
color,
|
||||
shadowBlur: 0,
|
||||
shadowColor: 'transparent',
|
||||
},
|
||||
},
|
||||
itemStyle: {
|
||||
color,
|
||||
shadowBlur: 0,
|
||||
shadowColor: 'transparent',
|
||||
},
|
||||
data: [createPhaseGaugeData(name, 0, color)],
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const applyGaugePhaseColor = (options: any, color: string) => {
|
||||
const series = options.series[0]
|
||||
series.axisLine.lineStyle.color = [[1, color]]
|
||||
series.itemStyle = { color, shadowBlur: 0, shadowColor: 'transparent' }
|
||||
series.pointer = {
|
||||
...series.pointer,
|
||||
itemStyle: { color, shadowBlur: 0, shadowColor: 'transparent' },
|
||||
shadowBlur: 0,
|
||||
shadowColor: 'transparent',
|
||||
}
|
||||
series.axisTick.lineStyle.color = color
|
||||
series.splitLine.lineStyle.color = color
|
||||
series.axisLabel.color = color
|
||||
series.title.color = color
|
||||
series.detail.color = color
|
||||
if (series.data?.[0]) {
|
||||
series.data[0].itemStyle = { color, shadowBlur: 0, shadowColor: 'transparent' }
|
||||
}
|
||||
}
|
||||
|
||||
const buildPhaseLegendGraphic = () => {
|
||||
const phases = [
|
||||
{ key: 'A', label: 'A相', color: PHASE_COLORS.A },
|
||||
{ key: 'B', label: 'B相', color: PHASE_COLORS.B },
|
||||
{ key: 'C', label: 'C相', color: PHASE_COLORS.C },
|
||||
]
|
||||
const voltageValues = [
|
||||
realData.value.v1AngA ?? 0,
|
||||
realData.value.v1AngB ?? 0,
|
||||
realData.value.v1AngC ?? 0,
|
||||
]
|
||||
const currentValues = [
|
||||
realData.value.i1AngA ?? 0,
|
||||
realData.value.i1AngB ?? 0,
|
||||
realData.value.i1AngC ?? 0,
|
||||
]
|
||||
|
||||
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'group',
|
||||
right: 20,
|
||||
bottom: 20,
|
||||
// children,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
const updateRmsGaugeChart = (
|
||||
chartRef: any,
|
||||
chartData: any,
|
||||
name: string,
|
||||
value: number,
|
||||
color: string
|
||||
) => {
|
||||
chartData.value.options.series[0].max = value == 0 ? 1 : Math.ceil(value * 1.2)
|
||||
chartData.value.options.series[0].data = [createPhaseGaugeData(name, value || 0, color)]
|
||||
applyGaugePhaseColor(chartData.value.options, color)
|
||||
chartRef.value?.initChart()
|
||||
}
|
||||
const initRadioCharts = () => {
|
||||
echartsData1.value = {
|
||||
options: {
|
||||
@@ -234,34 +396,34 @@ const initRadioCharts = () => {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: [
|
||||
[0.25, '#9D322D'],
|
||||
[0.5, '#9D322D'],
|
||||
[0.75, '#9D322D'],
|
||||
[1, '#9D322D']
|
||||
[0.25, PHASE_RING_COLOR],
|
||||
[0.5, PHASE_RING_COLOR],
|
||||
[0.75, PHASE_RING_COLOR],
|
||||
[1, PHASE_RING_COLOR],
|
||||
],
|
||||
width: 2
|
||||
}
|
||||
width: 2,
|
||||
},
|
||||
},
|
||||
// 表盘细分数
|
||||
axisTick: {
|
||||
show: true,
|
||||
splitNumber: 5,
|
||||
distance: 4,
|
||||
length: 4,
|
||||
lineStyle: {
|
||||
color: '#9D322D',
|
||||
color: PHASE_RING_COLOR,
|
||||
width: 1,
|
||||
type: 'solid'
|
||||
}
|
||||
type: 'solid',
|
||||
},
|
||||
},
|
||||
// 分割线
|
||||
splitLine: {
|
||||
show: true,
|
||||
distance: 4,
|
||||
length: 10,
|
||||
lineStyle: {
|
||||
color: '#9D322D',
|
||||
color: PHASE_RING_COLOR,
|
||||
width: 2,
|
||||
type: 'solid'
|
||||
}
|
||||
type: 'solid',
|
||||
},
|
||||
},
|
||||
// 分割线标识
|
||||
axisLabel: {
|
||||
@@ -287,7 +449,9 @@ const initRadioCharts = () => {
|
||||
icon: 'path://m368.01136,209.80637l173.00807,-193.72679c19.14653,-21.43943 50.16392,-21.43943 69.31045,0l172.93149,193.72679c1.22537,1.37213 1.22537,3.51607 0,4.8882l-47.63657,53.34133c-1.22538,1.37213 -3.14003,1.37213 -4.36541,0l-113.65381,-127.26452c-1.91465,-2.14395 -5.20785,-0.60031 -5.20785,2.40122l0,731.94254c0,1.88667 -1.37855,3.43031 -3.06345,3.43031l-67.39579,0c-1.6849,0 -3.06345,-1.54364 -3.06345,-3.43031l0,-731.94254c0,-3.08728 -3.2932,-4.54517 -5.20785,-2.40122l-113.65381,127.26452c-1.22538,1.37213 -3.14003,1.37213 -4.36541,0l-47.63657,-53.34133c-1.22537,-1.37213 -1.22537,-3.51607 0,-4.88819l0,-0.00001M539,861.23064h73v800h-73z',
|
||||
length: '90%',
|
||||
width: 15,
|
||||
opacity: 1
|
||||
opacity: 1,
|
||||
shadowBlur: 0,
|
||||
shadowColor: 'transparent',
|
||||
},
|
||||
detail: {
|
||||
show: false
|
||||
@@ -297,21 +461,21 @@ const initRadioCharts = () => {
|
||||
value: 0,
|
||||
name: 'A相',
|
||||
itemStyle: {
|
||||
color: '#DAA520'
|
||||
color: PHASE_COLORS.A
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 0,
|
||||
name: 'B相',
|
||||
itemStyle: {
|
||||
color: '#2E8B57'
|
||||
color: PHASE_COLORS.B
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 0,
|
||||
name: 'C相',
|
||||
itemStyle: {
|
||||
color: '#A52a2a'
|
||||
color: PHASE_COLORS.C
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -341,34 +505,34 @@ const initRadioCharts = () => {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: [
|
||||
[0.25, '#9D322D'],
|
||||
[0.5, '#9D322D'],
|
||||
[0.75, '#9D322D'],
|
||||
[1, '#9D322D']
|
||||
[0.25, PHASE_RING_COLOR],
|
||||
[0.5, PHASE_RING_COLOR],
|
||||
[0.75, PHASE_RING_COLOR],
|
||||
[1, PHASE_RING_COLOR],
|
||||
],
|
||||
width: 1.5
|
||||
}
|
||||
width: 1.5,
|
||||
},
|
||||
},
|
||||
// 表盘细分数
|
||||
axisTick: {
|
||||
show: true,
|
||||
splitNumber: 5,
|
||||
distance: 5,
|
||||
length: 6,
|
||||
lineStyle: {
|
||||
color: '#9D322D',
|
||||
color: PHASE_RING_COLOR,
|
||||
width: 1,
|
||||
type: 'solid'
|
||||
}
|
||||
type: 'solid',
|
||||
},
|
||||
},
|
||||
// 分割线
|
||||
splitLine: {
|
||||
show: true,
|
||||
distance: 5,
|
||||
length: 10,
|
||||
lineStyle: {
|
||||
color: '#9D322D',
|
||||
color: PHASE_RING_COLOR,
|
||||
width: 2,
|
||||
type: 'solid'
|
||||
}
|
||||
type: 'solid',
|
||||
},
|
||||
},
|
||||
// 分割线标识
|
||||
axisLabel: {
|
||||
@@ -394,7 +558,9 @@ const initRadioCharts = () => {
|
||||
icon: 'path://m368.01136,209.80637l173.00807,-193.72679c19.14653,-21.43943 50.16392,-21.43943 69.31045,0l172.93149,193.72679c1.22537,1.37213 1.22537,3.51607 0,4.8882l-47.63657,53.34133c-1.22538,1.37213 -3.14003,1.37213 -4.36541,0l-113.65381,-127.26452c-1.91465,-2.14395 -5.20785,-0.60031 -5.20785,2.40122l0,731.94254c0,1.88667 -1.37855,3.43031 -3.06345,3.43031l-67.39579,0c-1.6849,0 -3.06345,-1.54364 -3.06345,-3.43031l0,-731.94254c0,-3.08728 -3.2932,-4.54517 -5.20785,-2.40122l-113.65381,127.26452c-1.22538,1.37213 -3.14003,1.37213 -4.36541,0l-47.63657,-53.34133c-1.22537,-1.37213 -1.22537,-3.51607 0,-4.88819l0,-0.00001M539,861.23064h73v800h-73z',
|
||||
length: '90%',
|
||||
width: 15,
|
||||
opacity: 1
|
||||
opacity: 1,
|
||||
shadowBlur: 0,
|
||||
shadowColor: 'transparent',
|
||||
},
|
||||
detail: {
|
||||
show: false
|
||||
@@ -404,21 +570,21 @@ const initRadioCharts = () => {
|
||||
value: 0,
|
||||
name: 'A相',
|
||||
itemStyle: {
|
||||
color: '#DAA520'
|
||||
color: PHASE_COLORS.A
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 0,
|
||||
name: 'B相',
|
||||
itemStyle: {
|
||||
color: '#2E8B57'
|
||||
color: PHASE_COLORS.B
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 0,
|
||||
name: 'C相',
|
||||
itemStyle: {
|
||||
color: '#A52a2a'
|
||||
color: PHASE_COLORS.C
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -459,75 +625,17 @@ const initRadioCharts = () => {
|
||||
echartsData1.value.options.series[i].endAngle = -360
|
||||
echartsData1.value.options.series[i].center = ['50%', '50%']
|
||||
}
|
||||
|
||||
echartsData1.value.options.graphic = buildPhaseLegendGraphic()
|
||||
}
|
||||
//渲染echarts
|
||||
const init = () => {
|
||||
echartsData.value = {
|
||||
options: {
|
||||
tooltip: {},
|
||||
toolbox: {
|
||||
show: false
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'gauge',
|
||||
startAngle: 180,
|
||||
endAngle: 0,
|
||||
min: 0,
|
||||
max: 450,
|
||||
radius: '150%',
|
||||
center: ['55%', '76%'],
|
||||
splitNumber: 2, //刻度数量
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
width: 10,
|
||||
shadowBlur: 0,
|
||||
color: [
|
||||
[0.3, '#91c7a1'],
|
||||
[0.7, '#63869e'],
|
||||
[1, '#002B6A']
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
itemStyle: {
|
||||
normal: {
|
||||
shadowBlur: 10
|
||||
}
|
||||
},
|
||||
//标题位置
|
||||
title: {
|
||||
fontWeight: 'bolder',
|
||||
fontSize: 12,
|
||||
offsetCenter: ['-130%', '-20%']
|
||||
},
|
||||
//数值位置
|
||||
detail: {
|
||||
fontSize: 12,
|
||||
valueAnimation: true,
|
||||
formatter: '{value}',
|
||||
offsetCenter: ['0%', '25%']
|
||||
},
|
||||
data: [
|
||||
{
|
||||
value: 0,
|
||||
name: 'A相'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
echartsDataV1.value = JSON.parse(JSON.stringify(echartsData.value))
|
||||
echartsDataV2.value = JSON.parse(JSON.stringify(echartsData.value))
|
||||
echartsDataV3.value = JSON.parse(JSON.stringify(echartsData.value))
|
||||
echartsDataV1.value.options.series[0].max = 12
|
||||
echartsDataV2.value.options.series[0].max = 12
|
||||
echartsDataV3.value.options.series[0].max = 12
|
||||
echartsDataA1.value = echartsData.value
|
||||
echartsDataA2.value = echartsData.value
|
||||
echartsDataA3.value = echartsData.value
|
||||
echartsDataV1.value = createRmsGaugeOptions('A相', PHASE_COLORS.A, 'left')
|
||||
echartsDataV2.value = createRmsGaugeOptions('B相', PHASE_COLORS.B, 'left')
|
||||
echartsDataV3.value = createRmsGaugeOptions('C相', PHASE_COLORS.C, 'left')
|
||||
echartsDataA1.value = createRmsGaugeOptions('A相', PHASE_COLORS.A, 'right')
|
||||
echartsDataA2.value = createRmsGaugeOptions('B相', PHASE_COLORS.B, 'right')
|
||||
echartsDataA3.value = createRmsGaugeOptions('C相', PHASE_COLORS.C, 'right')
|
||||
}
|
||||
//接收父组件传递的table数据
|
||||
const dataList: any = ref([])
|
||||
@@ -603,57 +711,12 @@ const setRealData = (val: any, dataLevel: string) => {
|
||||
realData.value = val
|
||||
realList.value = [val]
|
||||
initRadioCharts()
|
||||
//新的
|
||||
echartsDataV1.value.options.series[0].max = realData.value.vRmsA == 0 ? 1 : Math.ceil(realData.value.vRmsA * 1.2)
|
||||
// console.log("🚀 ~ setRealData ~ realData.value.vRmsA:", realData.value.vRmsA)
|
||||
echartsDataV1.value.options.series[0].data = [
|
||||
{
|
||||
name: 'A相',
|
||||
value: realData.value.vRmsA || 0
|
||||
}
|
||||
]
|
||||
pieChart1.value.initChart()
|
||||
echartsDataV2.value.options.series[0].max = realData.value.vRmsB == 0 ? 1 : Math.ceil(realData.value.vRmsB * 1.2)
|
||||
echartsDataV2.value.options.series[0].data = [
|
||||
{
|
||||
name: 'B相',
|
||||
value: realData.value.vRmsB || 0
|
||||
}
|
||||
]
|
||||
pieChart2.value.initChart()
|
||||
echartsDataV3.value.options.series[0].max = realData.value.vRmsC == 0 ? 1 : Math.ceil(realData.value.vRmsC * 1.2)
|
||||
echartsDataV3.value.options.series[0].data = [
|
||||
{
|
||||
name: 'C相',
|
||||
value: realData.value.vRmsC || 0
|
||||
}
|
||||
]
|
||||
pieChart3.value.initChart()
|
||||
//新的电流有效值
|
||||
echartsDataA1.value.options.series[0].max = realData.value.iRmsA == 0 ? 1 : Math.ceil(realData.value.iRmsA * 1.2)
|
||||
echartsDataA1.value.options.series[0].data = [
|
||||
{
|
||||
name: 'A相',
|
||||
value: realData.value.iRmsA || 0
|
||||
}
|
||||
]
|
||||
pieChart4.value.initChart()
|
||||
echartsDataA2.value.options.series[0].max = realData.value.iRmsB == 0 ? 1 : Math.ceil(realData.value.iRmsB * 1.2)
|
||||
echartsDataA2.value.options.series[0].data = [
|
||||
{
|
||||
name: 'B相',
|
||||
value: realData.value.iRmsB || 0
|
||||
}
|
||||
]
|
||||
pieChart5.value.initChart()
|
||||
echartsDataA3.value.options.series[0].max = realData.value.iRmsC == 0 ? 1 : Math.ceil(realData.value.iRmsC * 1.2)
|
||||
echartsDataA3.value.options.series[0].data = [
|
||||
{
|
||||
name: 'C相',
|
||||
value: realData.value.iRmsC || 0
|
||||
}
|
||||
]
|
||||
pieChart6.value.initChart()
|
||||
updateRmsGaugeChart(pieChart1, echartsDataV1, 'A相', realData.value.vRmsA, PHASE_COLORS.A)
|
||||
updateRmsGaugeChart(pieChart2, echartsDataV2, 'B相', realData.value.vRmsB, PHASE_COLORS.B)
|
||||
updateRmsGaugeChart(pieChart3, echartsDataV3, 'C相', realData.value.vRmsC, PHASE_COLORS.C)
|
||||
updateRmsGaugeChart(pieChart4, echartsDataA1, 'A相', realData.value.iRmsA, PHASE_COLORS.A)
|
||||
updateRmsGaugeChart(pieChart5, echartsDataA2, 'B相', realData.value.iRmsB, PHASE_COLORS.B)
|
||||
updateRmsGaugeChart(pieChart6, echartsDataA3, 'C相', realData.value.iRmsC, PHASE_COLORS.C)
|
||||
}
|
||||
defineExpose({ setRealData })
|
||||
onMounted(() => {
|
||||
@@ -662,6 +725,87 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.charts-panel {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
min-height: 32px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.charts-collapse {
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
|
||||
:deep(.el-collapse-item) {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
:deep(.el-collapse-item__header) {
|
||||
// position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
width: 100%;
|
||||
height: 32px !important;
|
||||
min-height: 32px !important;
|
||||
border: none;
|
||||
background: transparent;
|
||||
padding: 0 12px;
|
||||
font-size: 13px !important;
|
||||
line-height: 30px;
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
:deep(.el-collapse-item__wrap) {
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
:deep(.el-collapse-item__arrow) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.charts-collapse-header {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 32px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.charts-collapse-action {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 4px;
|
||||
min-width: 56px;
|
||||
color: var(--el-color-primary);
|
||||
font-size: 13px;
|
||||
line-height: 32px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.charts-collapse-text {
|
||||
display: inline-block;
|
||||
min-width: 28px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.charts-collapse-icon {
|
||||
font-size: 12px;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.charts-collapse-icon.is-expanded {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.view {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -676,7 +820,7 @@ onMounted(() => {
|
||||
justify-content: space-between;
|
||||
//border: 1px solid #eee;
|
||||
// padding: 10px;
|
||||
margin-top: 10px;
|
||||
// margin-top: 10px;
|
||||
|
||||
.view_top_left,
|
||||
.view_top_right {
|
||||
@@ -734,7 +878,6 @@ onMounted(() => {
|
||||
|
||||
.view_bot {
|
||||
// min-height: 300px;
|
||||
margin: 10px 0 0 0;
|
||||
overflow: auto !important;
|
||||
flex: 1 !important;
|
||||
// padding-bottom: 200px !important;
|
||||
@@ -835,6 +978,7 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
:deep(.view_bot) {
|
||||
|
||||
.vxe-table--render-default .vxe-body--column:not(.col--ellipsis),
|
||||
.vxe-table--render-default .vxe-footer--column:not(.col--ellipsis),
|
||||
.vxe-table--render-default .vxe-header--column:not(.col--ellipsis) {
|
||||
@@ -846,8 +990,7 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-collapse-item__header {
|
||||
font-size: 16px !important;
|
||||
font-weight: 800 !important;
|
||||
:deep(.vxe-table--render-default) {
|
||||
font-size: 13px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,44 +5,25 @@
|
||||
<TableHeader ref="tableHeaderRef" :showSearch="false" @selectChange="selectChange">
|
||||
<template v-slot:select>
|
||||
<el-form-item>
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
<DatePicker ref="datePickerRef" :timeKeyList="[ '3', '4', '5']"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item label="统计指标" label-width="80px">
|
||||
<el-select
|
||||
style="width: 200px"
|
||||
multiple
|
||||
:multiple-limit="3"
|
||||
collapse-tags
|
||||
filterable
|
||||
collapse-tags-tooltip
|
||||
v-model="searchForm.index"
|
||||
placeholder="请选择统计指标"
|
||||
@change="onIndexChange($event)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in indexOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
></el-option>
|
||||
<el-select style="width: 200px" multiple :multiple-limit="3" collapse-tags filterable
|
||||
collapse-tags-tooltip v-model="searchForm.index" placeholder="请选择统计指标"
|
||||
@change="onIndexChange($event)">
|
||||
<el-option v-for="item in indexOptions" :key="item.id" :label="item.name"
|
||||
:value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio-group
|
||||
v-model="searchForm.dataLevel"
|
||||
:disabled="props?.TrendList?.lineType != 1"
|
||||
@change="init()"
|
||||
>
|
||||
<el-radio-group v-model="searchForm.dataLevel" :disabled="props?.TrendList?.lineType != 1"
|
||||
@change="init()">
|
||||
<el-radio-button label="一次值" value="Primary" />
|
||||
<el-radio-button label="二次值" value="Secondary" />
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="统计类型">
|
||||
<el-select
|
||||
style="min-width: 120px !important"
|
||||
placeholder="请选择"
|
||||
v-model="searchForm.valueType"
|
||||
>
|
||||
<el-select style="min-width: 120px !important" placeholder="请选择" v-model="searchForm.valueType">
|
||||
<el-option value="max" label="最大值"></el-option>
|
||||
<el-option value="min" label="最小值"></el-option>
|
||||
<el-option value="avg" label="平均值"></el-option>
|
||||
@@ -50,34 +31,21 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<div
|
||||
class="history_count"
|
||||
v-for="(item, index) in countData"
|
||||
:key="index"
|
||||
v-show="item.countOptions.length != 0"
|
||||
>
|
||||
<div class="history_count" v-for="(item, index) in countData" :key="index"
|
||||
v-show="item.countOptions.length != 0">
|
||||
<span class="mr12">
|
||||
{{ item.name.includes('次数') ? item.name : item.name + '谐波次数' }}
|
||||
</span>
|
||||
<el-select
|
||||
v-model="item.count"
|
||||
@change="onCountChange($event, index)"
|
||||
placeholder="请选择谐波次数"
|
||||
style="width: 100px"
|
||||
class="mr20"
|
||||
>
|
||||
<el-option
|
||||
v-for="vv in item.countOptions"
|
||||
:key="vv"
|
||||
:label="item.name.includes('间谐波') ? vv - 0.5 : vv"
|
||||
:value="vv"
|
||||
></el-option>
|
||||
<el-select v-model="item.count" @change="onCountChange($event, index)" placeholder="请选择谐波次数"
|
||||
style="width: 100px" class="mr20">
|
||||
<el-option v-for="vv in item.countOptions" :key="vv"
|
||||
:label="item.name.includes('间谐波') ? vv - 0.5 : vv" :value="vv"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #operation>
|
||||
<el-button type="primary" icon="el-icon-Search" @click="init()">查询</el-button>
|
||||
<el-button type="primary" icon="el-icon-Search" @click="init()" :loading="loading">查询</el-button>
|
||||
<el-button :type="timeControl ? 'primary' : ''" icon="el-icon-Sort" @click="setTimeControl">
|
||||
缺失数据
|
||||
</el-button>
|
||||
@@ -163,8 +131,8 @@ queryByCode(
|
||||
props?.TrendList?.lineType == 0
|
||||
? 'apf-harmonic'
|
||||
: props?.TrendList?.conType == 1
|
||||
? 'portable-harmonic-jx'
|
||||
: 'portable-harmonic'
|
||||
? 'portable-harmonic-jx'
|
||||
: 'portable-harmonic'
|
||||
).then(res => {
|
||||
queryCsDictTree(res.data.id).then(item => {
|
||||
//排序
|
||||
@@ -479,10 +447,10 @@ const setEchart = () => {
|
||||
return item.anotherName == '电压负序分量'
|
||||
? '电压不平衡'
|
||||
: item.anotherName == '电压正序分量'
|
||||
? '电压不平衡'
|
||||
: item.anotherName == '电压零序分量'
|
||||
? '电压不平衡'
|
||||
: item.anotherName
|
||||
? '电压不平衡'
|
||||
: item.anotherName == '电压零序分量'
|
||||
? '电压不平衡'
|
||||
: item.anotherName
|
||||
})
|
||||
)
|
||||
]
|
||||
@@ -516,10 +484,10 @@ const setEchart = () => {
|
||||
(kk[0].anotherName == '电压负序分量'
|
||||
? '电压不平衡'
|
||||
: kk[0].anotherName == '电压正序分量'
|
||||
? '电压不平衡'
|
||||
: kk[0].anotherName == '电压零序分量'
|
||||
? '电压不平衡'
|
||||
: kk[0].anotherName)
|
||||
? '电压不平衡'
|
||||
: kk[0].anotherName == '电压零序分量'
|
||||
? '电压不平衡'
|
||||
: kk[0].anotherName)
|
||||
)
|
||||
|
||||
let seriesList: any = []
|
||||
@@ -600,8 +568,10 @@ const handleExport = async () => {
|
||||
cell8 = obj.capacitySi,
|
||||
cell9 = obj.capacitySscb,
|
||||
cell10 = obj.capacitySt,
|
||||
cell11 = obj.pt && obj.pt1 ? obj.pt / obj.pt1 + '\b' : '/',
|
||||
cell12 = obj.ct && obj.ct1 ? obj.ct / obj.ct1 + '\b' : '/',
|
||||
cell11 = obj.pt || 1 + ':' + obj.pt1 || 1,
|
||||
cell12 = obj.ct || 1 + ':' + obj.ct1 || 1,
|
||||
// cell11 = obj.pt && obj.pt1 ? obj.pt / obj.pt1 + '\b' : '/',
|
||||
// cell12 = obj.ct && obj.ct1 ? obj.ct / obj.ct1 + '\b' : '/',
|
||||
cell13 = obj.startTime ? obj.startTime : '/',
|
||||
cell14 = obj.endTime ? obj.endTime : '/',
|
||||
cell15 = obj.location
|
||||
@@ -867,6 +837,7 @@ defineExpose({ getTrendRequest })
|
||||
min-width: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-select__selected-item) {
|
||||
.is-closable {
|
||||
width: 100px !important;
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
class="cn-operate-dialog"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-input
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
<el-input maxlength="32" show-word-limit
|
||||
|
||||
|
||||
v-model.trim="filterText"
|
||||
icon="el-icon-Search"
|
||||
placeholder="请输入内容"
|
||||
@@ -82,7 +82,7 @@ import { ref, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
const pageHeight = mainHeight(60)
|
||||
const loading = ref(true)
|
||||
const loading = ref(false)
|
||||
|
||||
const tableHeight = mainHeight(173)
|
||||
const user: any = ref({})
|
||||
|
||||
@@ -2,18 +2,14 @@
|
||||
<template>
|
||||
<div class="default-main main" :style="{ height: pageHeight.height }">
|
||||
<div class="main_left">
|
||||
<DeviceTree @node-click="nodeClick" @deviceTypeChange="deviceTypeChange"></DeviceTree>
|
||||
<DeviceTree @node-click="nodeClick" @deviceTypeChange="deviceTypeChange" @init="nodeClick"></DeviceTree>
|
||||
</div>
|
||||
<div class="main_right" v-loading="loading">
|
||||
<div class="right_nav">
|
||||
<div class="menu" v-if="activePathList.length != 0">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item
|
||||
v-for="(item, index) in activePathList"
|
||||
style="cursor: pointer"
|
||||
:key="index"
|
||||
@click="handleIntoByPath(item)"
|
||||
>
|
||||
<el-breadcrumb-item v-for="(item, index) in activePathList" style="cursor: pointer" :key="index"
|
||||
@click="handleIntoByPath(item)">
|
||||
<span>{{ outPutPath(item, index) }}</span>
|
||||
</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
@@ -24,27 +20,14 @@
|
||||
</div>
|
||||
|
||||
<div class="filter" v-if="activePathList.length != 0">
|
||||
<el-input
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
style="width: 240px; height: 32px"
|
||||
placeholder="请输入文件或文件夹名称"
|
||||
clearable
|
||||
v-model.trim="filterText"
|
||||
type="text"
|
||||
></el-input>
|
||||
<el-input maxlength="32" show-word-limit style="width: 240px; height: 32px" placeholder="请输入文件或文件夹名称"
|
||||
clearable v-model.trim="filterText" type="text"></el-input>
|
||||
<el-button type="primary" @click="handleSearch" :icon="Search">搜索</el-button>
|
||||
<!-- <el-button @click="handleRefresh" :icon="Refresh">重置</el-button> -->
|
||||
<el-upload
|
||||
v-if="activePath != '/'"
|
||||
action=""
|
||||
:auto-upload="false"
|
||||
:show-file-list="false"
|
||||
:on-change="(file: any, fileList: any) => {
|
||||
<el-upload v-if="activePath != '/'" action="" :auto-upload="false" :show-file-list="false" :on-change="(file: any, fileList: any) => {
|
||||
handleUpload(file, fileList, activePath)
|
||||
}
|
||||
"
|
||||
>
|
||||
">
|
||||
<el-button>
|
||||
文件上传
|
||||
<el-icon class="el-icon--right">
|
||||
@@ -62,29 +45,19 @@
|
||||
</div>
|
||||
<!-- 以列表形式展示 -->
|
||||
<div :style="tableHeight">
|
||||
<vxe-table
|
||||
style="margin-top: 10px"
|
||||
border
|
||||
auto-resize
|
||||
height="auto"
|
||||
:data="dirList"
|
||||
v-bind="defaultAttribute"
|
||||
>
|
||||
<vxe-table style="margin-top: 10px" border auto-resize height="auto" :data="dirList"
|
||||
v-bind="defaultAttribute">
|
||||
<vxe-column type="seq" title="序号" width="80"></vxe-column>
|
||||
<vxe-column field="prjDataPath" align="center" title="名称" minWidth="180" #default="{ row }">
|
||||
<span
|
||||
style="cursor: pointer; color: #551a8b"
|
||||
:style="{
|
||||
'text-decoration': row.type == 'dir' ? 'underline' : 'none',
|
||||
color: row.type == 'dir' ? '#551a8b' : '#000'
|
||||
}"
|
||||
@click="handleIntoDir(row)"
|
||||
>
|
||||
<span style="cursor: pointer; color: #551a8b" :style="{
|
||||
'text-decoration': row.type == 'dir' ? 'underline' : 'none',
|
||||
color: row.type == 'dir' ? '#551a8b' : '#000'
|
||||
}" @click="handleIntoDir(row)">
|
||||
{{
|
||||
row &&
|
||||
row?.prjDataPath &&
|
||||
row?.prjDataPath.includes(activePath) &&
|
||||
row?.prjDataPath.length > activePath.length
|
||||
row?.prjDataPath &&
|
||||
row?.prjDataPath.includes(activePath) &&
|
||||
row?.prjDataPath.length > activePath.length
|
||||
? row?.prjDataPath.replace(activePath, ' ').replace('/', ' ')
|
||||
: row?.prjDataPath.replace('/', ' ')
|
||||
}}
|
||||
@@ -110,13 +83,8 @@
|
||||
<vxe-column title="操作" width="120px" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link size="small" type="danger" @click="handleDelDirOrFile(row)">删除</el-button>
|
||||
<el-button
|
||||
v-if="row.type == 'file'"
|
||||
link
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="handleDownLoad(row)"
|
||||
>
|
||||
<el-button v-if="row.type == 'file'" link size="small" type="primary" :loading="row.loading"
|
||||
@click="handleDownLoad(row)">
|
||||
下载
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -127,13 +95,8 @@
|
||||
<div class="list" v-if="dirList.length != 0 && !loading" style="display: none">
|
||||
<div class="list_item" v-for="(item, index) in dirList" :key="index">
|
||||
<div class="item_download">
|
||||
<el-button
|
||||
v-if="activePath && activePath != '/'"
|
||||
type="danger"
|
||||
size="small"
|
||||
@click="handleDelDirOrFile(item)"
|
||||
circle
|
||||
>
|
||||
<el-button v-if="activePath && activePath != '/'" type="danger" size="small"
|
||||
@click="handleDelDirOrFile(item)" circle>
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
@@ -145,19 +108,15 @@
|
||||
</el-button>
|
||||
</div>
|
||||
<img v-if="item?.type == 'dir'" @click="handleIntoDir(item)" src="@/assets/img/wenjianjia.svg" />
|
||||
<img
|
||||
class="img_file"
|
||||
@click="handleIntoDir(item)"
|
||||
v-if="item?.type == 'file'"
|
||||
src="@/assets/img/wenjian.svg"
|
||||
/>
|
||||
<img class="img_file" @click="handleIntoDir(item)" v-if="item?.type == 'file'"
|
||||
src="@/assets/img/wenjian.svg" />
|
||||
<!-- <span v-if="!item.type">暂无数据</span> -->
|
||||
<p>
|
||||
{{
|
||||
item &&
|
||||
item?.prjDataPath &&
|
||||
item?.prjDataPath.includes(activePath) &&
|
||||
item?.prjDataPath.length > activePath.length
|
||||
item?.prjDataPath &&
|
||||
item?.prjDataPath.includes(activePath) &&
|
||||
item?.prjDataPath.length > activePath.length
|
||||
? item?.prjDataPath.replace(activePath, ' ').replace('/', ' ')
|
||||
: item?.prjDataPath.replace('/', ' ')
|
||||
}}
|
||||
@@ -167,18 +126,9 @@
|
||||
<!-- <el-empty v-if="dirList.length === 0" /> -->
|
||||
</div>
|
||||
<popup ref="fileRef"></popup>
|
||||
<el-dialog
|
||||
v-model.trim="addDeviceDirOpen"
|
||||
:destroy-on-close="true"
|
||||
title="新建文件夹目录"
|
||||
width="500"
|
||||
@closed="close"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="{ path: [{ required: true, message: '请输入文件夹名称', trigger: 'blur' }] }"
|
||||
>
|
||||
<el-dialog v-model.trim="addDeviceDirOpen" :destroy-on-close="true" title="新建文件夹目录" width="500" @closed="close">
|
||||
<el-form ref="formRef" :model="form"
|
||||
:rules="{ path: [{ required: true, message: '请输入文件夹名称', trigger: 'blur' }] }">
|
||||
<el-form-item label="文件夹名称" prop="path">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.path" placeholder="请输入文件夹名称" />
|
||||
</el-form-item>
|
||||
@@ -235,6 +185,7 @@ const isRoot = ref<boolean>(true)
|
||||
const activePathList: any = ref([])
|
||||
const devConType = ref<string>('')
|
||||
const deviceTypeChange = (val: any, obj: any) => {
|
||||
|
||||
nodeClick(obj)
|
||||
}
|
||||
const nodeClick = (e: any) => {
|
||||
@@ -650,15 +601,19 @@ const changeType = ref<any>('')
|
||||
const fileRef = ref()
|
||||
const handleDownLoad = async (row: any) => {
|
||||
if (devConType.value == 'CLD') {
|
||||
row.loading = true
|
||||
ElMessage.info('下载中,请稍等...')
|
||||
downloadFileFromFrontr({
|
||||
devId: devId.value,
|
||||
filePath: row.prjDataPath
|
||||
}).then(res => {
|
||||
downLoadFile(row.name, row.name, res)
|
||||
row.loading = false
|
||||
}).catch(e => {
|
||||
row.loading = false
|
||||
})
|
||||
} else {
|
||||
;(await nDid.value) && fileRef.value && fileRef.value.open(row, nDid.value)
|
||||
; (await nDid.value) && fileRef.value && fileRef.value.open(row, nDid.value)
|
||||
// fileName.value = row?.prjDataPath.split('/')[row?.prjDataPath.split('/').length - 1]
|
||||
// localStorage.setItem('fileName', fileName.value)
|
||||
changeType.value = 'download'
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="接入方式">
|
||||
{{ deviceData.devAccessMethod || '/' }}
|
||||
{{ deviceData.devAccessMethod =='CLD'?'1056协议':deviceData.devAccessMethod || '/' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="网络设备ID">
|
||||
{{ deviceData.ndid || '/' }}
|
||||
@@ -75,7 +75,7 @@
|
||||
style="width: 100%"
|
||||
>
|
||||
<vxe-column type="seq" title="序号" width="80"></vxe-column>
|
||||
<vxe-column field="name" title="数据名称"></vxe-column>
|
||||
<vxe-column field="name" title="指标名称"></vxe-column>
|
||||
<vxe-column field="phasic" title="相别"></vxe-column>
|
||||
<vxe-column field="type" title="数据类型"></vxe-column>
|
||||
<vxe-column field="unit" title="单位"></vxe-column>
|
||||
|
||||
@@ -1,154 +1,154 @@
|
||||
<template>
|
||||
<el-dialog class="cn-operate-dialog device-manage-popup" v-model.trim="dialogVisible" title="设备模版分组">
|
||||
<el-descriptions class="mb10" :column="3" border>
|
||||
<el-descriptions-item label="名称">
|
||||
{{ popupData.deviceData.name }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="网络设备ID">
|
||||
{{ popupData.deviceData.ndid }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :title="'数据集名称: ' + popupData.dataSetName" size="small" :column="2" border>
|
||||
<template #extra>
|
||||
<div v-if="newGroupVisible" style="display: flex; align-items: center">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="groupName" autocomplete="off" clearable
|
||||
placeholder="请输入分组名称"></el-input>
|
||||
<el-button class="ml10" ctype="primary" size="small" @click="newGroupVisible = false">取消</el-button>
|
||||
<el-button class="ml10" type="primary" size="small" @click="addNewGroup">完成</el-button>
|
||||
</div>
|
||||
<template v-else>
|
||||
<el-button type="primary" size="small" @click="selectGroup">
|
||||
{{ selectAll ? '取消全选' : '全选' }}
|
||||
</el-button>
|
||||
<el-button type="primary" size="small" @click="newGroupVisible = true">新增分组</el-button>
|
||||
</template>
|
||||
</template>
|
||||
</el-descriptions>
|
||||
<div style="flex: 1; overflow: auto">
|
||||
<el-tree :data="popupData.tree" node-key="id" draggable :allow-drop="allowDrop" :allow-drag="allowDrag">
|
||||
<template #default="{ node, data }">
|
||||
<div class="group-tree-node">
|
||||
<span>{{ node.label }}</span>
|
||||
<div v-if="node.level == 1" style="display: flex; align-items: center">
|
||||
<el-popconfirm :title="'确定删除' + node.label + '吗?'" @confirm="deleteGroup(node)">
|
||||
<template #reference>
|
||||
<Icon name="el-icon-Delete"></Icon>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<el-checkbox v-model.trim="data.isShow" @click.stop.native="" class="ml5"></el-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
<template #footer="">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submit">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, inject } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { updateGroArr } from '@/api/cs-device-boot/csGroArr'
|
||||
import type Node from 'element-plus/es/components/tree/src/model/node'
|
||||
import type { AllowDropType } from 'element-plus/es/components/tree/src/tree.type'
|
||||
const newGroupVisible = ref(false)
|
||||
const dialogVisible = ref(false)
|
||||
const selectAll = ref(false)
|
||||
const popupData = ref<any>([])
|
||||
const groupName = ref('')
|
||||
const submit = () => {
|
||||
let data = JSON.parse(JSON.stringify(popupData.value.tree))
|
||||
const call = (data: any) => {
|
||||
data.forEach((item: any) => {
|
||||
item.isShow = item.isShow ? 1 : 0
|
||||
delete item.label
|
||||
if (item.children && item.children.length > 0) {
|
||||
call(item.children)
|
||||
}
|
||||
})
|
||||
}
|
||||
call(data)
|
||||
data.forEach((item: any) => {
|
||||
item.children = item.children.map((item: any) => item.id)
|
||||
})
|
||||
updateGroArr({
|
||||
setId: popupData.value.dataSet,
|
||||
data: data
|
||||
}).then((res: any) => {
|
||||
ElMessage.success('保存成功')
|
||||
dialogVisible.value = false
|
||||
})
|
||||
}
|
||||
const deleteGroup = (node: any) => {
|
||||
if (node.data.children && node.data.children.length > 0) {
|
||||
ElMessage.error('该分组下有指标,不能删除')
|
||||
return
|
||||
}
|
||||
let index = popupData.value.tree.findIndex((item: any) => item.id === node.data.id || item.name === node.data.name)
|
||||
popupData.value.tree.splice(index, 1)
|
||||
}
|
||||
const selectGroup = () => {
|
||||
if (selectAll.value) {
|
||||
popupData.value.tree.forEach((item: any) => {
|
||||
item.isShow = false
|
||||
})
|
||||
selectAll.value = false
|
||||
} else {
|
||||
popupData.value.tree.forEach((item: any) => {
|
||||
item.isShow = true
|
||||
})
|
||||
selectAll.value = true
|
||||
}
|
||||
}
|
||||
const addNewGroup = () => {
|
||||
if (groupName.value === '') {
|
||||
ElMessage.warning('请输入分组名称')
|
||||
return
|
||||
}
|
||||
if (popupData.value.tree.some((item: any) => item.name === groupName.value)) {
|
||||
ElMessage.warning('分组名称已存在')
|
||||
|
||||
return
|
||||
}
|
||||
newGroupVisible.value = false
|
||||
popupData.value.tree.splice(0, 0, {
|
||||
id: '',
|
||||
label: groupName.value,
|
||||
name: groupName.value,
|
||||
isShow: true,
|
||||
children: []
|
||||
})
|
||||
groupName.value = ''
|
||||
}
|
||||
const allowDrop = (draggingNode: Node, dropNode: Node, type: AllowDropType) => {
|
||||
return (dropNode.level === 2 && type !== 'inner') || (dropNode.level === 1 && type === 'inner')
|
||||
}
|
||||
const allowDrag = (draggingNode: Node) => {
|
||||
return draggingNode.level === 2
|
||||
}
|
||||
const open = (data: any[]) => {
|
||||
dialogVisible.value = true
|
||||
popupData.value = data
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.device-manage-popup {
|
||||
.group-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<el-dialog class="cn-operate-dialog device-manage-popup" v-model.trim="dialogVisible" title="设备模版分组">
|
||||
<el-descriptions class="mb10" :column="3" border>
|
||||
<el-descriptions-item label="名称">
|
||||
{{ popupData.deviceData.name }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="网络设备ID">
|
||||
{{ popupData.deviceData.ndid }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :title="'数据集名称: ' + popupData.dataSetName" size="small" :column="2" border>
|
||||
<template #extra>
|
||||
<div v-if="newGroupVisible" style="display: flex; align-items: center">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="groupName" autocomplete="off" clearable
|
||||
placeholder="请输入分组名称"></el-input>
|
||||
<el-button class="ml10" ctype="primary" size="small" @click="newGroupVisible = false">取消</el-button>
|
||||
<el-button class="ml10" type="primary" size="small" @click="addNewGroup">完成</el-button>
|
||||
</div>
|
||||
<template v-else>
|
||||
<el-button type="primary" size="small" @click="selectGroup">
|
||||
{{ selectAll ? '取消全选' : '全选' }}
|
||||
</el-button>
|
||||
<el-button type="primary" size="small" @click="newGroupVisible = true">新增分组</el-button>
|
||||
</template>
|
||||
</template>
|
||||
</el-descriptions>
|
||||
<div style="flex: 1; overflow: auto">
|
||||
<el-tree :data="popupData.tree" node-key="id" draggable :allow-drop="allowDrop" :allow-drag="allowDrag">
|
||||
<template #default="{ node, data }">
|
||||
<div class="group-tree-node">
|
||||
<span>{{ node.label }}</span>
|
||||
<div v-if="node.level == 1" style="display: flex; align-items: center">
|
||||
<el-popconfirm :title="'确定删除' + node.label + '吗?'" @confirm="deleteGroup(node)">
|
||||
<template #reference>
|
||||
<Icon name="el-icon-Delete"></Icon>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<el-checkbox v-model.trim="data.isShow" @click.stop.native="" class="ml5"></el-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
<template #footer="">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submit">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, inject } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { updateGroArr } from '@/api/cs-device-boot/csGroArr'
|
||||
import type Node from 'element-plus/es/components/tree/src/model/node'
|
||||
import type { AllowDropType } from 'element-plus/es/components/tree/src/tree.type'
|
||||
const newGroupVisible = ref(false)
|
||||
const dialogVisible = ref(false)
|
||||
const selectAll = ref(false)
|
||||
const popupData = ref<any>([])
|
||||
const groupName = ref('')
|
||||
const submit = () => {
|
||||
let data = JSON.parse(JSON.stringify(popupData.value.tree))
|
||||
const call = (data: any) => {
|
||||
data.forEach((item: any) => {
|
||||
item.isShow = item.isShow ? 1 : 0
|
||||
delete item.label
|
||||
if (item.children && item.children.length > 0) {
|
||||
call(item.children)
|
||||
}
|
||||
})
|
||||
}
|
||||
call(data)
|
||||
data.forEach((item: any) => {
|
||||
item.children = item.children.map((item: any) => item.id)
|
||||
})
|
||||
updateGroArr({
|
||||
setId: popupData.value.dataSet,
|
||||
data: data
|
||||
}).then((res: any) => {
|
||||
ElMessage.success('保存成功')
|
||||
dialogVisible.value = false
|
||||
})
|
||||
}
|
||||
const deleteGroup = (node: any) => {
|
||||
if (node.data.children && node.data.children.length > 0) {
|
||||
ElMessage.error('该分组下有指标,不能删除')
|
||||
return
|
||||
}
|
||||
let index = popupData.value.tree.findIndex((item: any) => item.id === node.data.id || item.name === node.data.name)
|
||||
popupData.value.tree.splice(index, 1)
|
||||
}
|
||||
const selectGroup = () => {
|
||||
if (selectAll.value) {
|
||||
popupData.value.tree.forEach((item: any) => {
|
||||
item.isShow = false
|
||||
})
|
||||
selectAll.value = false
|
||||
} else {
|
||||
popupData.value.tree.forEach((item: any) => {
|
||||
item.isShow = true
|
||||
})
|
||||
selectAll.value = true
|
||||
}
|
||||
}
|
||||
const addNewGroup = () => {
|
||||
if (groupName.value === '') {
|
||||
ElMessage.warning('请输入分组名称')
|
||||
return
|
||||
}
|
||||
if (popupData.value.tree.some((item: any) => item.name === groupName.value)) {
|
||||
ElMessage.warning('分组名称已存在')
|
||||
|
||||
return
|
||||
}
|
||||
newGroupVisible.value = false
|
||||
popupData.value.tree.splice(0, 0, {
|
||||
id: '',
|
||||
label: groupName.value,
|
||||
name: groupName.value,
|
||||
isShow: true,
|
||||
children: []
|
||||
})
|
||||
groupName.value = ''
|
||||
}
|
||||
const allowDrop = (draggingNode: Node, dropNode: Node, type: AllowDropType) => {
|
||||
return (dropNode.level === 2 && type !== 'inner') || (dropNode.level === 1 && type === 'inner')
|
||||
}
|
||||
const allowDrag = (draggingNode: Node) => {
|
||||
return draggingNode.level === 2
|
||||
}
|
||||
const open = (data: any[]) => {
|
||||
dialogVisible.value = true
|
||||
popupData.value = data
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.device-manage-popup {
|
||||
.group-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -62,9 +62,9 @@
|
||||
<div class="dialog-section">
|
||||
<div class="section-header">
|
||||
<span>工程列表</span>
|
||||
<el-input
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
<el-input maxlength="32" show-word-limit
|
||||
|
||||
|
||||
v-model.trim="filterText"
|
||||
placeholder="搜索工程"
|
||||
clearable
|
||||
@@ -94,9 +94,9 @@
|
||||
<div class="dialog-section">
|
||||
<div class="section-header">
|
||||
<span>设备列表</span>
|
||||
<el-input
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
<el-input maxlength="32" show-word-limit
|
||||
|
||||
|
||||
v-model.trim="deviceFilterText"
|
||||
placeholder="搜索设备"
|
||||
clearable
|
||||
@@ -154,7 +154,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
const pageHeight = mainHeight(60)
|
||||
const pageHeight1 = mainHeight(125)
|
||||
const loading = ref(true)
|
||||
const loading = ref(false)
|
||||
|
||||
const user: any = ref({})
|
||||
const tableData = ref([])
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
<el-form :model="form" scroll-to-error label-width="140px" :rules="rules1" ref="ruleFormRef1" class="form-one"
|
||||
v-if="popupType == 0 || popupType == 1">
|
||||
<el-form-item label="方案名称:" prop="itemName">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.itemName" placeholder="请输入方案名称" />
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.itemName" placeholder="请输入方案名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="方案描述:" prop="describe">
|
||||
<el-input maxlength="300" show-word-limit type="textarea" v-model.trim="form.describe"
|
||||
<el-input show-word-limit maxlength="300" type="textarea" v-model.trim="form.describe"
|
||||
placeholder="请输入方案描述" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@@ -18,7 +18,7 @@
|
||||
<el-form :model="form1" ref="ruleFormRef2" scroll-to-error class="form-two" label-width="140px"
|
||||
:rules="rules2">
|
||||
<el-form-item label="测试项名称:" prop="itemName">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form1.itemName" placeholder="请输入测试项名称" />
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form1.itemName" placeholder="请输入测试项名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="测量间隔:" prop="statisticalInterval">
|
||||
<el-select v-model.trim="form1.statisticalInterval" placeholder="请选择测量间隔" clearable
|
||||
@@ -41,7 +41,7 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="最小短路容量:" prop="capacitySscmin">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form1.capacitySscmin" oninput="value=value.replace(/[^\-?\d.]/g,'')
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form1.capacitySscmin" oninput="value=value.replace(/[^\-?\d.]/g,'')
|
||||
.replace(/^\./g,'').replace('.','$#$').replace(/\./g,'').replace('$#$','.')
|
||||
.replace('-','$#$').replace(/\-/g,'').replace('$#$','-')" autocomplete="off" placeholder="请选择最小短路容量">
|
||||
<template #append>MVA</template>
|
||||
@@ -49,7 +49,7 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="用户协议容量:" prop="capacitySi">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form1.capacitySi" autocomplete="off"
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form1.capacitySi" autocomplete="off"
|
||||
oninput="value=value.replace(/[^\-?\d.]/g,'')
|
||||
.replace(/^\./g,'').replace('.','$#$').replace(/\./g,'').replace('$#$','.')
|
||||
.replace('-','$#$').replace(/\-/g,'').replace('$#$','-')" placeholder="请输入用户协议容量">
|
||||
@@ -58,7 +58,7 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="基准短路容量:" prop="capacitySscb">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form1.capacitySscb" oninput="value=value.replace(/[^\-?\d.]/g,'')
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form1.capacitySscb" oninput="value=value.replace(/[^\-?\d.]/g,'')
|
||||
.replace(/^\./g,'').replace('.','$#$').replace(/\./g,'').replace('$#$','.')
|
||||
.replace('-','$#$').replace(/\-/g,'').replace('$#$','-')" placeholder="请输入基准短路容量">
|
||||
<template #append>MVA</template>
|
||||
@@ -66,26 +66,26 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="供电设备容量:" prop="capacitySt">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form1.capacitySt" oninput="value=value.replace(/[^\-?\d.]/g,'')
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form1.capacitySt" oninput="value=value.replace(/[^\-?\d.]/g,'')
|
||||
.replace(/^\./g,'').replace('.','$#$').replace(/\./g,'').replace('$#$','.')
|
||||
.replace('-','$#$').replace(/\-/g,'').replace('$#$','-')" placeholder="请输入供电设备容量">
|
||||
<template #append>MVA</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="PT变比:" prop="pt">
|
||||
<el-input maxlength="32" show-word-limit style="width: 48%" v-model.number.trim="form1.pt"
|
||||
<el-input maxlength="32" show-word-limit style="width: 48%" v-model.number.trim="form1.pt"
|
||||
autocomplete="off" placeholder="请输入PT变比" oninput="value=value.replace(/[^0-9.]/g,'')" />
|
||||
<el-input maxlength="32" show-word-limit style="width: 48%" v-model.number.trim="form1.pt1"
|
||||
<el-input maxlength="32" show-word-limit style="width: 48%" v-model.number.trim="form1.pt1"
|
||||
autocomplete="off" placeholder="请输入PT变比" oninput="value=value.replace(/[^0-9.]/g,'')" />
|
||||
</el-form-item>
|
||||
<el-form-item label="CT变比:" prop="ct">
|
||||
<el-input maxlength="32" show-word-limit v-model.number.trim="form1.ct" style="width: 48%"
|
||||
<el-input maxlength="32" show-word-limit v-model.number.trim="form1.ct" style="width: 48%"
|
||||
autocomplete="off" oninput="value=value.replace(/[^0-9.]/g,'')" placeholder="请输入CT变比" />
|
||||
<el-input maxlength="32" show-word-limit v-model.number.trim="form1.ct1" style="width: 48%"
|
||||
<el-input maxlength="32" show-word-limit v-model.number.trim="form1.ct1" style="width: 48%"
|
||||
autocomplete="off" oninput="value=value.replace(/[^0-9.]/g,'')" placeholder="请输入CT变比" />
|
||||
</el-form-item>
|
||||
<el-form-item label="监测位置:" prop="location" style="width: 100%">
|
||||
<el-input maxlength="300" show-word-limit type="textarea" v-model.trim="form1.location"
|
||||
<el-input show-word-limit maxlength="300" type="textarea" v-model.trim="form1.location"
|
||||
placeholder="请输入监测位置" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
style="cursor: pointer" />
|
||||
<div class="cn-tree" :style="{ opacity: menuCollapse ? 0 : 1, display: menuCollapse ? 'none' : '' }">
|
||||
<div style="display: flex; align-items: center" class="mb10">
|
||||
<el-input maxlength="32" v-model.trim="filterText" placeholder="请输入内容" clearable>
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="filterText" placeholder="请输入内容" clearable>
|
||||
<template #prefix>
|
||||
<Icon name="el-icon-Search" style="font-size: 16px" />
|
||||
</template>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<Table ref="tableRef" v-show="!isWaveCharts" />
|
||||
<div v-show="!isWaveCharts">
|
||||
<Table ref="tableRef" />
|
||||
</div>
|
||||
<waveFormAnalysis v-loading="loading" v-if="isWaveCharts" ref="waveFormAnalysisRef"
|
||||
@handleHideCharts="isWaveCharts = false" :wp="wp" />
|
||||
</div>
|
||||
@@ -22,11 +24,15 @@ import waveFormAnalysis from '@/views/govern/device/control/tabs/components/wave
|
||||
import { analyseWave } from '@/api/common'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
const props = defineProps({
|
||||
activeName: String,
|
||||
activeColName: [Object, String]
|
||||
})
|
||||
const loading = ref(false)
|
||||
const dictData = useDictData()
|
||||
const ReasonList: any = dictData.getBasicData('Event_Reason')
|
||||
const EventTypeList: any = dictData.getBasicData('Event_Type')
|
||||
const waveFormAnalysisRef = ref()
|
||||
const isWaveCharts = ref(false)
|
||||
const boxoList: any = ref([])
|
||||
@@ -44,11 +50,11 @@ const tableStore = new TableStore({
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ field: 'startTime', title: '暂降发生时刻', minWidth: 170, sortable: true },
|
||||
{ field: 'startTime', title: '发生时刻', minWidth: 170, sortable: true },
|
||||
{
|
||||
field: 'featureAmplitude',
|
||||
title: '暂降(骤升)幅值(%)',
|
||||
minWidth: 160,
|
||||
title: '暂降幅值(%)',
|
||||
minWidth: 120,
|
||||
formatter: (row: any) => {
|
||||
row.cellValue = row.cellValue + '' ? row.cellValue.toFixed(2) : '/'
|
||||
if (String(row.cellValue).split('.')[1] == '00') {
|
||||
@@ -78,6 +84,25 @@ const tableStore = new TableStore({
|
||||
|
||||
|
||||
{ field: 'showName', title: '触发类型', minWidth: 170 },
|
||||
{
|
||||
title: '暂降原因', field: 'advanceReason', minWidth: 100, align: 'center', formatter: (row: any) => {
|
||||
return ReasonList.find((item: any) => item.value == row.cellValue)?.label || '未知'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '暂降类型', field: 'advanceType', minWidth: 100, align: 'center', formatter: (row: any) => {
|
||||
return EventTypeList.find((item: any) => item.value == row.cellValue)?.label || '未知'
|
||||
}
|
||||
},
|
||||
{ title: '监测点名称', field: 'lineName', minWidth: 120, align: 'center' },
|
||||
{ title: '电压等级(kV)', field: 'lineVoltage', minWidth: 120, align: 'center', sortable: true, },
|
||||
{ title: '设备名称', field: 'devName', minWidth: 120, align: 'center' },
|
||||
{
|
||||
title: '发生位置', field: 'sagSource', minWidth: 120, align: 'center', formatter: (row: any) => {
|
||||
|
||||
return row.cellValue == 1 ? '上游' : row.cellValue == 2 ? '下游' : '未知'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '操作', fixed: 'right',
|
||||
width: 180,
|
||||
@@ -105,6 +130,8 @@ const tableStore = new TableStore({
|
||||
row.loading1 = false
|
||||
if (res != undefined) {
|
||||
boxoList.value = row
|
||||
boxoList.value.featureAmplitude =
|
||||
row.featureAmplitude != '-' ? (row.featureAmplitude - 0) / 100 : null
|
||||
boxoList.value.systemType = 'YPT'
|
||||
wp.value = res.data
|
||||
|
||||
@@ -145,6 +172,7 @@ const tableStore = new TableStore({
|
||||
return !row.wavePath
|
||||
},
|
||||
click: row => {
|
||||
row.loading2 = true
|
||||
ElMessage.info('下载中......')
|
||||
getFileZip({ eventId: row.id }).then(res => {
|
||||
let blob = new Blob([res], { type: 'application/zip' }) // console.log(blob) // var href = window.URL.createObjectURL(blob); //创建下载的链接
|
||||
@@ -156,6 +184,9 @@ const tableStore = new TableStore({
|
||||
link.click() //执行下载
|
||||
document.body.removeChild(link) //释放标签
|
||||
ElMessage.success('波形下载成功')
|
||||
row.loading2 = false
|
||||
}).catch(() => {
|
||||
row.loading2 = false
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -1,291 +1,292 @@
|
||||
<template>
|
||||
<div class="transferTreeBox" v-if="fromData.length != 0 || toData.length != 0">
|
||||
<!-- 左侧待选内容 -->
|
||||
<div class="SelectBox">
|
||||
<div class="boxTitle" @click="clickAllSelect">未绑定数据</div>
|
||||
<div class="boxCenter">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="filterText" :suffix-icon="Search"
|
||||
style="width: 100%" placeholder="请输入搜索内容" clearable></el-input>
|
||||
<el-tree ref="leftTree" default-expand-all :data="leftData" :props="defaultProps" show-checkbox
|
||||
node-key="id" :filter-node-method="filterNode">
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
||||
v-if="data.icon" />
|
||||
<span style="margin-left: 4px">{{ node.label }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 中间穿梭按钮 -->
|
||||
<div class="transferBtn">
|
||||
<el-button type="primary" @click="towardsRight">
|
||||
绑定
|
||||
<el-icon>
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-button type="primary" @click="towardsLeft">
|
||||
<el-icon>
|
||||
<ArrowLeft />
|
||||
</el-icon>
|
||||
解绑</el-button>
|
||||
</div>
|
||||
<!-- 右侧已选内容 -->
|
||||
<div class="SelectBox">
|
||||
<div class="boxTitle" @click="clickCancelAllSelect">已绑定数据</div>
|
||||
<div class="boxCenter">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="filterText1" :suffix-icon="Search"
|
||||
style="width: 100%" placeholder="请输入搜索内容" clearable></el-input>
|
||||
<el-tree ref="rightTree" default-expand-all :data="rightData" :props="defaultProps" show-checkbox
|
||||
node-key="id" :filter-node-method="filterNode">
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
||||
v-if="data.icon" />
|
||||
<span style="margin-left: 4px">{{ node.label }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Search, ArrowRight, ArrowLeft } from '@element-plus/icons-vue'
|
||||
</script>
|
||||
<script>
|
||||
import { useConfig } from '@/stores/config'
|
||||
export default {
|
||||
layout: 'login',
|
||||
props: ['fromData', 'toData'],
|
||||
data() {
|
||||
return {
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'name'
|
||||
},
|
||||
leftData: [],
|
||||
rightData: [],
|
||||
filterText: '',
|
||||
filterText1: ''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
fromData(val, oldVal) {
|
||||
if (val) {
|
||||
this.leftData = val
|
||||
const config = useConfig()
|
||||
this.leftData.forEach(item => {
|
||||
item.icon = 'el-icon-HomeFilled'
|
||||
item.color = config.getColorVal('elementUiPrimary')
|
||||
item.children.forEach(item2 => {
|
||||
item2.icon = 'el-icon-List'
|
||||
item2.color = config.getColorVal('elementUiPrimary')
|
||||
item2.children.forEach(item3 => {
|
||||
item3.icon = 'el-icon-Platform'
|
||||
item3.color = config.getColorVal('elementUiPrimary')
|
||||
if (item3.comFlag === 1) {
|
||||
item3.color = '#e26257 !important'
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
toData(val, oldVal) {
|
||||
if (val) {
|
||||
this.rightData = val
|
||||
const config = useConfig()
|
||||
this.$emit('getData', this.rightData)
|
||||
this.rightData.forEach(item => {
|
||||
item.icon = 'el-icon-HomeFilled'
|
||||
item.color = config.getColorVal('elementUiPrimary')
|
||||
item.children.forEach(item2 => {
|
||||
item2.icon = 'el-icon-List'
|
||||
item2.color = config.getColorVal('elementUiPrimary')
|
||||
item2.children.forEach(item3 => {
|
||||
item3.icon = 'el-icon-Platform'
|
||||
item3.color = config.getColorVal('elementUiPrimary')
|
||||
if (item3.comFlag === 1) {
|
||||
item3.color = '#e26257 !important'
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
filterText(val) {
|
||||
this.$refs.leftTree.filter(val)
|
||||
},
|
||||
filterText1(val) {
|
||||
this.$refs.rightTree.filter(val)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$forceUpdate()
|
||||
this.$emit('getData', this.rightData)
|
||||
},
|
||||
methods: {
|
||||
// 点击向右穿梭
|
||||
towardsRight() {
|
||||
// (leafOnly, includeHalfChecked) 接收两个 boolean 类型的参数,
|
||||
// 1. 是否只是叶子节点,默认值为 false 2. 是否包含半选节点,默认值为 false
|
||||
this.$nextTick(() => {
|
||||
const checkedNodes = this.$refs.leftTree.getCheckedNodes(false, true) // 包含半选
|
||||
const checkedKeys = this.$refs.leftTree.getCheckedKeys(false)
|
||||
const copyNodes = JSON.parse(JSON.stringify(checkedNodes))
|
||||
copyNodes.forEach(x => {
|
||||
x.children = []
|
||||
if (!this.$refs.rightTree.getNode(x.id)) {
|
||||
this.$refs.rightTree.append(x, x.pid)
|
||||
}
|
||||
})
|
||||
checkedKeys.forEach(x => {
|
||||
this.$refs.leftTree.remove(x)
|
||||
})
|
||||
this.afterToward()
|
||||
this.$forceUpdate()
|
||||
})
|
||||
},
|
||||
// 点击向左穿梭
|
||||
towardsLeft() {
|
||||
this.$nextTick(() => {
|
||||
const checkedNodes = this.$refs.rightTree.getCheckedNodes(false, true) // 包含半选
|
||||
const checkedKeys = this.$refs.rightTree.getCheckedKeys(false)
|
||||
const copyNodes = JSON.parse(JSON.stringify(checkedNodes))
|
||||
copyNodes.forEach(x => {
|
||||
x.children = []
|
||||
if (!this.$refs.leftTree.getNode(x.id)) {
|
||||
this.$refs.leftTree.append(x, x.pid)
|
||||
}
|
||||
})
|
||||
checkedKeys.forEach(x => {
|
||||
this.$refs.rightTree.remove(x)
|
||||
})
|
||||
|
||||
this.$forceUpdate()
|
||||
this.afterToward()
|
||||
})
|
||||
},
|
||||
// 点击全选
|
||||
clickAllSelect() {
|
||||
return;
|
||||
this.$refs.leftTree.setCheckedNodes(this.leftData)
|
||||
this.towardsRight()
|
||||
},
|
||||
// 点击取消全选
|
||||
clickCancelAllSelect() {
|
||||
return;
|
||||
this.$refs.rightTree.setCheckedNodes(this.rightData)
|
||||
this.towardsLeft()
|
||||
},
|
||||
// 数据穿梭后
|
||||
afterToward() {
|
||||
this.$refs.leftTree.setCheckedKeys([])
|
||||
this.$refs.rightTree.setCheckedKeys([])
|
||||
this.$emit('getData', this.rightData)
|
||||
this.$forceUpdate()
|
||||
},
|
||||
//组件搜索
|
||||
filterNode(value, data, node) {
|
||||
if (!value) return true
|
||||
// return data.name.includes(value)
|
||||
if (data.name) {
|
||||
|
||||
return this.chooseNode(value, data, node)
|
||||
}
|
||||
},
|
||||
|
||||
// 过滤父节点 / 子节点 (如果输入的参数是父节点且能匹配,则返回该节点以及其下的所有子节点;如果参数是子节点,则返回该节点的父节点。name是中文字符,enName是英文字符.
|
||||
chooseNode(value, data, node) {
|
||||
|
||||
if (data.name.indexOf(value) !== -1) {
|
||||
return true
|
||||
}
|
||||
const level = node.level
|
||||
// 如果传入的节点本身就是一级节点就不用校验了
|
||||
if (level === 1) {
|
||||
return false
|
||||
}
|
||||
// 先取当前节点的父节点
|
||||
let parentData = node.parent
|
||||
// 遍历当前节点的父节点
|
||||
let index = 0
|
||||
while (index < level - 1) {
|
||||
// 如果匹配到直接返回,此处name值是中文字符,enName是英文字符。判断匹配中英文过滤
|
||||
if (parentData.data.name.indexOf(value) !== -1) {
|
||||
return true
|
||||
}
|
||||
// 否则的话再往上一层做匹配
|
||||
parentData = parentData.parent
|
||||
index++
|
||||
}
|
||||
// 没匹配到返回false
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.transferTreeBox {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-around;
|
||||
padding: 10px 10px 50px 10px;
|
||||
|
||||
.SelectBox {
|
||||
height: 400px;
|
||||
width: 40%;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
|
||||
.boxTitle {
|
||||
background: var(--el-color-primary);
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
border-bottom: 2px solid #eee;
|
||||
cursor: pointer;
|
||||
border: 2px solid var(--el-color-primary);
|
||||
}
|
||||
|
||||
.boxCenter {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-y: scroll;
|
||||
background: #fff;
|
||||
padding: 0 10px;
|
||||
border: 1px solid #eee;
|
||||
|
||||
.el-input {
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.transferBtn {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100px;
|
||||
flex: 1;
|
||||
|
||||
.pickBtn {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
background: var(--el-color-primary);
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
border-radius: 5px;
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="transferTreeBox" v-if="fromData.length != 0 || toData.length != 0">
|
||||
<!-- 左侧待选内容 -->
|
||||
<div class="SelectBox">
|
||||
<div class="boxTitle" @click="clickAllSelect">未绑定数据</div>
|
||||
<div class="boxCenter">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="filterText" :suffix-icon="Search"
|
||||
style="width: 100%" placeholder="请输入搜索内容" clearable></el-input>
|
||||
<el-tree ref="leftTree" default-expand-all :data="leftData" :props="defaultProps" show-checkbox
|
||||
node-key="id" :filter-node-method="filterNode">
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
||||
v-if="data.icon" />
|
||||
<span style="margin-left: 4px">{{ node.label }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 中间穿梭按钮 -->
|
||||
<div class="transferBtn">
|
||||
<el-button type="primary" @click="towardsRight">
|
||||
绑定
|
||||
<el-icon>
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-button type="primary" class="ml0 mt10" @click="towardsLeft">
|
||||
<el-icon>
|
||||
<ArrowLeft />
|
||||
</el-icon>
|
||||
解绑</el-button>
|
||||
</div>
|
||||
<!-- 右侧已选内容 -->
|
||||
<div class="SelectBox">
|
||||
<div class="boxTitle" @click="clickCancelAllSelect">已绑定数据</div>
|
||||
<div class="boxCenter">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="filterText1" :suffix-icon="Search"
|
||||
style="width: 100%" placeholder="请输入搜索内容" clearable></el-input>
|
||||
<el-tree ref="rightTree" default-expand-all :data="rightData" :props="defaultProps" show-checkbox
|
||||
node-key="id" :filter-node-method="filterNode">
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
||||
v-if="data.icon" />
|
||||
<span style="margin-left: 4px">{{ node.label }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Search, ArrowRight, ArrowLeft } from '@element-plus/icons-vue'
|
||||
</script>
|
||||
<script>
|
||||
import { useConfig } from '@/stores/config'
|
||||
export default {
|
||||
layout: 'login',
|
||||
props: ['fromData', 'toData'],
|
||||
data() {
|
||||
return {
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'name'
|
||||
},
|
||||
leftData: [],
|
||||
rightData: [],
|
||||
filterText: '',
|
||||
filterText1: ''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
fromData(val, oldVal) {
|
||||
if (val) {
|
||||
this.leftData = val
|
||||
const config = useConfig()
|
||||
this.leftData.forEach(item => {
|
||||
item.icon = 'el-icon-HomeFilled'
|
||||
item.color = config.getColorVal('elementUiPrimary')
|
||||
item.children.forEach(item2 => {
|
||||
item2.icon = 'el-icon-List'
|
||||
item2.color = config.getColorVal('elementUiPrimary')
|
||||
item2.children.forEach(item3 => {
|
||||
item3.icon = 'el-icon-Platform'
|
||||
item3.color = config.getColorVal('elementUiPrimary')
|
||||
if (item3.comFlag === 1) {
|
||||
item3.color = '#e26257 !important'
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
toData(val, oldVal) {
|
||||
if (val) {
|
||||
this.rightData = val
|
||||
const config = useConfig()
|
||||
this.$emit('getData', this.rightData)
|
||||
this.rightData.forEach(item => {
|
||||
item.icon = 'el-icon-HomeFilled'
|
||||
item.color = config.getColorVal('elementUiPrimary')
|
||||
item.children.forEach(item2 => {
|
||||
item2.icon = 'el-icon-List'
|
||||
item2.color = config.getColorVal('elementUiPrimary')
|
||||
item2.children.forEach(item3 => {
|
||||
item3.icon = 'el-icon-Platform'
|
||||
item3.color = config.getColorVal('elementUiPrimary')
|
||||
if (item3.comFlag === 1) {
|
||||
item3.color = '#e26257 !important'
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
filterText(val) {
|
||||
this.$refs.leftTree.filter(val)
|
||||
},
|
||||
filterText1(val) {
|
||||
this.$refs.rightTree.filter(val)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$forceUpdate()
|
||||
this.$emit('getData', this.rightData)
|
||||
},
|
||||
methods: {
|
||||
// 点击向右穿梭
|
||||
towardsRight() {
|
||||
// (leafOnly, includeHalfChecked) 接收两个 boolean 类型的参数,
|
||||
// 1. 是否只是叶子节点,默认值为 false 2. 是否包含半选节点,默认值为 false
|
||||
this.$nextTick(() => {
|
||||
const checkedNodes = this.$refs.leftTree.getCheckedNodes(false, true) // 包含半选
|
||||
const checkedKeys = this.$refs.leftTree.getCheckedKeys(false)
|
||||
const copyNodes = JSON.parse(JSON.stringify(checkedNodes))
|
||||
copyNodes.forEach(x => {
|
||||
x.children = []
|
||||
if (!this.$refs.rightTree.getNode(x.id)) {
|
||||
this.$refs.rightTree.append(x, x.pid)
|
||||
}
|
||||
})
|
||||
checkedKeys.forEach(x => {
|
||||
this.$refs.leftTree.remove(x)
|
||||
})
|
||||
this.afterToward()
|
||||
this.$forceUpdate()
|
||||
})
|
||||
},
|
||||
// 点击向左穿梭
|
||||
towardsLeft() {
|
||||
this.$nextTick(() => {
|
||||
const checkedNodes = this.$refs.rightTree.getCheckedNodes(false, true) // 包含半选
|
||||
const checkedKeys = this.$refs.rightTree.getCheckedKeys(false)
|
||||
const copyNodes = JSON.parse(JSON.stringify(checkedNodes))
|
||||
copyNodes.forEach(x => {
|
||||
x.children = []
|
||||
if (!this.$refs.leftTree.getNode(x.id)) {
|
||||
this.$refs.leftTree.append(x, x.pid)
|
||||
}
|
||||
})
|
||||
checkedKeys.forEach(x => {
|
||||
this.$refs.rightTree.remove(x)
|
||||
})
|
||||
|
||||
this.$forceUpdate()
|
||||
this.afterToward()
|
||||
})
|
||||
},
|
||||
// 点击全选
|
||||
clickAllSelect() {
|
||||
return;
|
||||
this.$refs.leftTree.setCheckedNodes(this.leftData)
|
||||
this.towardsRight()
|
||||
},
|
||||
// 点击取消全选
|
||||
clickCancelAllSelect() {
|
||||
return;
|
||||
this.$refs.rightTree.setCheckedNodes(this.rightData)
|
||||
this.towardsLeft()
|
||||
},
|
||||
// 数据穿梭后
|
||||
afterToward() {
|
||||
this.$refs.leftTree.setCheckedKeys([])
|
||||
this.$refs.rightTree.setCheckedKeys([])
|
||||
this.$emit('getData', this.rightData)
|
||||
this.$forceUpdate()
|
||||
},
|
||||
//组件搜索
|
||||
filterNode(value, data, node) {
|
||||
if (!value) return true
|
||||
// return data.name.includes(value)
|
||||
if (data.name) {
|
||||
|
||||
return this.chooseNode(value, data, node)
|
||||
}
|
||||
},
|
||||
|
||||
// 过滤父节点 / 子节点 (如果输入的参数是父节点且能匹配,则返回该节点以及其下的所有子节点;如果参数是子节点,则返回该节点的父节点。name是中文字符,enName是英文字符.
|
||||
chooseNode(value, data, node) {
|
||||
|
||||
if (data.name.indexOf(value) !== -1) {
|
||||
return true
|
||||
}
|
||||
const level = node.level
|
||||
// 如果传入的节点本身就是一级节点就不用校验了
|
||||
if (level === 1) {
|
||||
return false
|
||||
}
|
||||
// 先取当前节点的父节点
|
||||
let parentData = node.parent
|
||||
// 遍历当前节点的父节点
|
||||
let index = 0
|
||||
while (index < level - 1) {
|
||||
// 如果匹配到直接返回,此处name值是中文字符,enName是英文字符。判断匹配中英文过滤
|
||||
if (parentData.data.name.indexOf(value) !== -1) {
|
||||
return true
|
||||
}
|
||||
// 否则的话再往上一层做匹配
|
||||
parentData = parentData.parent
|
||||
index++
|
||||
}
|
||||
// 没匹配到返回false
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.transferTreeBox {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-around;
|
||||
padding: 10px 10px 50px 10px;
|
||||
|
||||
.SelectBox {
|
||||
height: 400px;
|
||||
width: 43%;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
|
||||
.boxTitle {
|
||||
background: var(--el-color-primary);
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
border-bottom: 2px solid #eee;
|
||||
cursor: pointer;
|
||||
border: 2px solid var(--el-color-primary);
|
||||
}
|
||||
|
||||
.boxCenter {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-y: scroll;
|
||||
background: #fff;
|
||||
padding: 0 10px;
|
||||
border: 1px solid #eee;
|
||||
|
||||
.el-input {
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.transferBtn {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
// width: 100px;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
|
||||
.pickBtn {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
background: var(--el-color-primary);
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
border-radius: 5px;
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
<template>
|
||||
<div class="default-main device-manage" :style="{ height: pageHeight.height }">
|
||||
<!-- @node-change="nodeClick" -->
|
||||
<schemeTree
|
||||
@node-change="nodeClick"
|
||||
@node-click="nodeClick"
|
||||
@init="nodeClick"
|
||||
@onAdd="onAdd"
|
||||
@bind="bind"
|
||||
ref="schemeTreeRef"
|
||||
></schemeTree>
|
||||
<schemeTree @node-change="nodeClick" @node-click="nodeClick" @init="nodeClick" @onAdd="onAdd" @bind="bind"
|
||||
ref="schemeTreeRef"></schemeTree>
|
||||
<div class="device-manage-right" v-if="deviceData">
|
||||
<el-descriptions title="方案信息" :column="2" border>
|
||||
<!-- <template #extra>
|
||||
@@ -28,12 +22,8 @@
|
||||
<p>测试项信息</p>
|
||||
</div> -->
|
||||
<el-tabs v-model.trim="activeName" type="border-card" @tab-change="handleClickTabs">
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in deviceData?.records"
|
||||
:label="item.itemName"
|
||||
:name="item.id"
|
||||
:key="index"
|
||||
>
|
||||
<el-tab-pane v-for="(item, index) in deviceData?.records" :label="item.itemName"
|
||||
:name="item.id" :key="index">
|
||||
<template #label>
|
||||
<span class="custom-tabs-label">
|
||||
<el-icon>
|
||||
@@ -76,19 +66,23 @@
|
||||
{{ item.capacitySt }}MVA
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="PT变比" width="160">
|
||||
{{ item.pt && item.pt1 ? item.pt + '/' + item.pt1 : '/' }}
|
||||
<!-- {{ item.pt && item.pt1 ? item.pt + '/' + item.pt1 : '/' }} -->
|
||||
{{ item.pt || 1 }} :
|
||||
{{ item.pt1 || 1 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="CT变比" width="160">
|
||||
{{ item.ct && item.ct1 ? item.ct + '/' + item.ct1 : '/' }}
|
||||
<!-- {{ item.ct && item.ct1 ? item.ct + '/' + item.ct1 : '/' }} -->
|
||||
{{ item.ct || 1 }} :
|
||||
{{ item.ct1 || 1 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="起始时间" width="160">
|
||||
<span style="width: 140px; overflow: hidden; display: block">
|
||||
{{ item.startTime ||'/' }}
|
||||
{{ item.startTime || '/' }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="结束时间" width="160">
|
||||
<span style="width: 140px; overflow: hidden; display: block">
|
||||
{{ item.endTime||'/' }}
|
||||
{{ item.endTime || '/' }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="监测位置" width="160">
|
||||
@@ -119,23 +113,12 @@
|
||||
<TableHeader :showSearch="false" ref="tableHeaderRef" @selectChange="selectChange">
|
||||
<template v-slot:select :key="num">
|
||||
<el-form-item for="-" label="统计指标">
|
||||
<el-select
|
||||
style="min-width: 240px"
|
||||
filterable
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
v-model.trim="searchForm.index"
|
||||
placeholder="请选择统计指标"
|
||||
@change="onIndexChange($event)"
|
||||
multiple
|
||||
:multiple-limit="3"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in indexOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
></el-option>
|
||||
<el-select style="min-width: 240px" filterable collapse-tags
|
||||
collapse-tags-tooltip v-model.trim="searchForm.index"
|
||||
placeholder="请选择统计指标" @change="onIndexChange($event)" multiple
|
||||
:multiple-limit="3">
|
||||
<el-option v-for="item in indexOptions" :key="item.id"
|
||||
:label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
@@ -149,50 +132,29 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item for="-" label="统计类型" label-width="80px">
|
||||
<el-select
|
||||
style="width: 120px"
|
||||
v-model.trim="searchForm.type"
|
||||
placeholder="请选择值类型"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in typeOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
></el-option>
|
||||
<el-select style="width: 120px" v-model.trim="searchForm.type"
|
||||
placeholder="请选择值类型">
|
||||
<el-option v-for="item in typeOptions" :key="item.id" :label="item.name"
|
||||
:value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<div
|
||||
for="-"
|
||||
v-for="(item, index) in countData"
|
||||
:key="index"
|
||||
v-show="item.countOptions.length != 0"
|
||||
>
|
||||
<div for="-" v-for="(item, index) in countData" :key="index"
|
||||
v-show="item.countOptions.length != 0">
|
||||
<span class="mr12">
|
||||
{{
|
||||
item.name.includes('次数')
|
||||
? item.name
|
||||
: item.name.includes('幅值')
|
||||
? item.name.slice(0, -2) + '次数'
|
||||
: item.name + '谐波次数'
|
||||
? item.name.slice(0, -2) + '次数'
|
||||
: item.name + '谐波次数'
|
||||
}}
|
||||
</span>
|
||||
<el-select
|
||||
v-model.trim="item.count"
|
||||
class="mr20"
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="请选择谐波次数"
|
||||
style="width: 120px"
|
||||
>
|
||||
<el-option
|
||||
v-for="vv in item.countOptions"
|
||||
:key="vv"
|
||||
:label="vv"
|
||||
:value="vv"
|
||||
></el-option>
|
||||
<el-select v-model.trim="item.count" class="mr20" collapse-tags
|
||||
collapse-tags-tooltip placeholder="请选择谐波次数" style="width: 120px">
|
||||
<el-option v-for="vv in item.countOptions" :key="vv" :label="vv"
|
||||
:value="vv"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</el-form-item>
|
||||
@@ -217,22 +179,13 @@
|
||||
<!-- <div class="history_title">
|
||||
<p>{{ chartTitle }}</p>
|
||||
</div> -->
|
||||
<div
|
||||
class="history_chart mt5"
|
||||
v-loading="loading"
|
||||
:style="EcharHeight"
|
||||
:key="EcharHeight.height"
|
||||
ref="chartRef"
|
||||
>
|
||||
<MyEchart
|
||||
ref="historyChart"
|
||||
v-if="echartsData"
|
||||
:isExport="true"
|
||||
:options="echartsData"
|
||||
/>
|
||||
<div class="history_chart mt5" v-loading="loading" :style="EcharHeight"
|
||||
:key="EcharHeight.height" ref="chartRef">
|
||||
<MyEchart ref="historyChart" v-if="echartsData" :isExport="true"
|
||||
:options="echartsData" />
|
||||
</div>
|
||||
</div>
|
||||
<el-empty :style="EcharHeight" v-else description="未绑定数据" />
|
||||
<el-empty :style="emptyHeight" v-else description="未绑定数据" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="暂态数据" name="1">
|
||||
<transient :activeName="activeName" ref="transientRef" :activeColName="activeColName" />
|
||||
@@ -286,6 +239,7 @@ const volConTypeList = dictData.getBasicData('Dev_Connect')
|
||||
//值类型
|
||||
const pageHeight = mainHeight(20)
|
||||
const EcharHeight = ref(mainHeight(436))
|
||||
const emptyHeight = ref(mainHeight(374))
|
||||
const loading = ref(false)
|
||||
const searchForm: any = ref({})
|
||||
const typeOptions = [
|
||||
@@ -714,9 +668,8 @@ const setEchart = () => {
|
||||
} else {
|
||||
marker = `<span style="display:inline-block;border: 2px ${el.color} ${el.value[3]};margin-right:5px;width:40px;height:0px;background-color:#ffffff00;"></span>`
|
||||
}
|
||||
str += `${marker}${el.seriesName.split('(')[0]}:${
|
||||
el.value[1] ? el.value[1] + ' ' + (el.value[2] || '') : '-'
|
||||
}<br>`
|
||||
str += `${marker}${el.seriesName.split('(')[0]}:${el.value[1] ? el.value[1] + ' ' + (el.value[2] || '') : '-'
|
||||
}<br>`
|
||||
})
|
||||
return str
|
||||
}
|
||||
@@ -770,10 +723,10 @@ const setEchart = () => {
|
||||
return item.anotherName == '电压负序分量'
|
||||
? '电压不平衡'
|
||||
: item.anotherName == '电压正序分量'
|
||||
? '电压不平衡'
|
||||
: item.anotherName == '电压零序分量'
|
||||
? '电压不平衡'
|
||||
: item.anotherName
|
||||
? '电压不平衡'
|
||||
: item.anotherName == '电压零序分量'
|
||||
? '电压不平衡'
|
||||
: item.anotherName
|
||||
})
|
||||
)
|
||||
]
|
||||
@@ -806,10 +759,10 @@ const setEchart = () => {
|
||||
(kk[0].anotherName == '电压负序分量'
|
||||
? '电压不平衡'
|
||||
: kk[0].anotherName == '电压正序分量'
|
||||
? '电压不平衡'
|
||||
: kk[0].anotherName == '电压零序分量'
|
||||
? '电压不平衡'
|
||||
: kk[0].anotherName)
|
||||
? '电压不平衡'
|
||||
: kk[0].anotherName == '电压零序分量'
|
||||
? '电压不平衡'
|
||||
: kk[0].anotherName)
|
||||
)
|
||||
let seriesList: any = []
|
||||
kk.forEach((cc: any) => {
|
||||
|
||||
@@ -24,7 +24,7 @@ import { ref, onMounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { debounce } from 'lodash-es'
|
||||
const pageHeight = mainHeight(60)
|
||||
const loading = ref(true)
|
||||
const loading = ref(false)
|
||||
const defaultCheckedKeys: any = ref([])
|
||||
const tableData = ref([])
|
||||
const treeRef = ref(null)
|
||||
|
||||
Reference in New Issue
Block a user