Compare commits
38 Commits
2025-10
...
d8433d8d9c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8433d8d9c | ||
|
|
0f090666e9 | ||
|
|
1d849bcff9 | ||
|
|
e9b09e2193 | ||
|
|
f66dd649c7 | ||
|
|
af05b9c810 | ||
|
|
0af955d05c | ||
|
|
49dcf440ff | ||
|
|
d6bfd8b958 | ||
|
|
ea6aed9b99 | ||
|
|
cd565c03ca | ||
|
|
f82ef923ae | ||
|
|
4c2ed4aade | ||
|
|
8cd3e14922 | ||
|
|
5580d0618e | ||
|
|
c1ebcfed6f | ||
|
|
6303bd1e2c | ||
|
|
d9efb37083 | ||
|
|
e271a3be06 | ||
|
|
078488a842 | ||
|
|
384ea90acd | ||
|
|
25971e5239 | ||
|
|
c3d7e91f4e | ||
|
|
72c37c2759 | ||
|
|
d1eb7f2dad | ||
|
|
308ceb1a03 | ||
|
|
ad7b77ff92 | ||
|
|
0e76ab66f3 | ||
|
|
24afa84f29 | ||
|
|
a5f3571906 | ||
|
|
d16d262d1a | ||
|
|
593f2e2c66 | ||
|
|
d1e7aab876 | ||
|
|
8a3e0263d2 | ||
|
|
35ce7314b0 | ||
|
|
5538d18127 | ||
|
|
00dd79e000 | ||
|
|
b5aff1a837 |
@@ -53,3 +53,25 @@ export const removeMarketData = (data: any) => {
|
|||||||
params: data
|
params: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户未绑定的在运的便携式设备
|
||||||
|
*/
|
||||||
|
export const queryRunPortableDevByUseId = (data: any) => {
|
||||||
|
return createAxios({
|
||||||
|
url: '/cs-device-boot/EquipmentDelivery/getRunPortableDev',
|
||||||
|
method: 'post',
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户未绑定的工程信息
|
||||||
|
*/
|
||||||
|
export const queryUnlinkEngineeringByUseId = (data: any) => {
|
||||||
|
return createAxios({
|
||||||
|
url: '/cs-device-boot/engineering/getUnlinkedEngineering',
|
||||||
|
method: 'post',
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
29
src/api/cs-system-boot/official.ts
Normal file
29
src/api/cs-system-boot/official.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import createAxios from '@/utils/request'
|
||||||
|
|
||||||
|
// * 根据用户id查询工程和便携式设备
|
||||||
|
export const queryDevByUseId = (data: any) => {
|
||||||
|
return createAxios({
|
||||||
|
url: '/cs-system-boot/wlUser/selectDevByUserId',
|
||||||
|
method: 'POST',
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// * 用户绑定工程和便携式设备
|
||||||
|
export const add = (data: any) => {
|
||||||
|
return createAxios({
|
||||||
|
url: '/cs-system-boot/wlUser/addUserDev',
|
||||||
|
method: 'POST',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 用户取消绑定工程和便携式设备
|
||||||
|
*/
|
||||||
|
export const removeUserDev = (data: any) => {
|
||||||
|
return createAxios({
|
||||||
|
url: '/cs-system-boot/wlUser/deleteUserDev',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
92
src/api/harmonic-boot/cockpit/cockpit.ts
Normal file
92
src/api/harmonic-boot/cockpit/cockpit.ts
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 主要监测点列表查询>>分页
|
||||||
|
export function mainLineList(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/harmonic-boot/mainLine/list',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 主要监测点指标越限详情
|
||||||
|
export function statLimitRateDetails(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/harmonic-boot/mainLine/statLimitRateDetails',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询监测点列表=全部>>不分页
|
||||||
|
export function cslineList(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/cs-device-boot/csline/list',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监测点详情 趋势图数据
|
||||||
|
export function trendData(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/cs-device-boot/csGroup/trendData',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 每日越限占比统计
|
||||||
|
export function totalLimitStatisticsDetails(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/harmonic-boot/totalLimitStatistics/details',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 总体指标越限统计列表
|
||||||
|
export function totalLimitStatisticsList(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/harmonic-boot/totalLimitStatistics/list',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 总体指标越限统计数据
|
||||||
|
export function totalLimitStatisticsData(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/harmonic-boot/totalLimitStatistics/data',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 指标越限程度数据
|
||||||
|
export function limitExtentData(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/harmonic-boot/limitRateDetailD/limitExtentData',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 指标日趋势图数据
|
||||||
|
export function limitExtentDayData(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/harmonic-boot/limitRateDetailD/limitExtentDayData',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 指标越限明细日历数据
|
||||||
|
export function limitCalendarData(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/harmonic-boot/limitRateDetailD/limitCalendarData',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
11
src/api/user-boot/official.ts
Normal file
11
src/api/user-boot/official.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
/**
|
||||||
|
* 获取移动端、便携式正式用户列表
|
||||||
|
* @returns {AxiosPromise}
|
||||||
|
*/
|
||||||
|
export const getFormalUserList = () => {
|
||||||
|
return request({
|
||||||
|
url: '/user-boot/user/getFormalUserList',
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--F47曲线 -->
|
<!--F47曲线 -->
|
||||||
|
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||||
<el-descriptions class="mt2" direction="vertical" :column="4" border>
|
<el-descriptions class="mt2" direction="vertical" :column="4" border>
|
||||||
<el-descriptions-item align="center" label="名称">{{ data.name }}</el-descriptions-item>
|
<el-descriptions-item align="center" label="名称">{{ data.name }}</el-descriptions-item>
|
||||||
<el-descriptions-item align="center" label="事件总数">{{ data.gs }}</el-descriptions-item>
|
<el-descriptions-item align="center" label="事件总数">{{ data.gs }}</el-descriptions-item>
|
||||||
@@ -11,31 +12,71 @@
|
|||||||
ref="chartRef"
|
ref="chartRef"
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
:style="{ width: prop.width, height: `calc(${prop.height} - 80px)` }"
|
:style="{
|
||||||
|
width: prop.width,
|
||||||
|
height: `calc(${prop.height} - 80px - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
||||||
|
}"
|
||||||
@chart-click="handleChartClick"
|
@chart-click="handleChartClick"
|
||||||
/>
|
/>
|
||||||
<el-dialog v-model="isWaveCharts" draggable title="瞬时/RMS波形" append-to-body width="70%">
|
<el-dialog v-model="isWaveCharts" draggable title="瞬时/RMS波形" append-to-body width="70%">
|
||||||
<waveFormAnalysis v-loading="loading" v-if="isWaveCharts" ref="waveFormAnalysisRef"
|
<waveFormAnalysis
|
||||||
@handleHideCharts="isWaveCharts = false" :wp="wp" />
|
v-loading="loading"
|
||||||
|
v-if="isWaveCharts"
|
||||||
|
ref="waveFormAnalysisRef"
|
||||||
|
@handleHideCharts="isWaveCharts = false"
|
||||||
|
:wp="wp"
|
||||||
|
/>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useDictData } from '@/stores/dictData'
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
import waveFormAnalysis from '@/views/govern/device/control/tabs/components/waveFormAnalysis.vue';
|
import waveFormAnalysis from '@/views/govern/device/control/tabs/components/waveFormAnalysis.vue'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
|
import { analyseWave } from '@/api/common'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: String },
|
w: { type: [String, Number]},
|
||||||
height: { type: String },
|
h: { type: [String, Number]},
|
||||||
timeKey: { type: String },
|
width: { type: [String, Number]},
|
||||||
|
height: { type: [String, Number]},
|
||||||
|
timeKey: { type: [String, Number]},
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
|
|
||||||
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
|
headerHeight.value = height
|
||||||
|
|
||||||
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
|
// 更新时间参数
|
||||||
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const echartList = ref({})
|
const echartList = ref({})
|
||||||
|
|
||||||
const chartRef = ref()
|
const chartRef = ref()
|
||||||
@@ -46,7 +87,10 @@ const loading = ref(false)
|
|||||||
|
|
||||||
const wp = ref({})
|
const wp = ref({})
|
||||||
|
|
||||||
const OverLimitDetailsRef = ref()
|
const boxoList: any = ref({})
|
||||||
|
|
||||||
|
const waveFormAnalysisRef: any = ref(null)
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
name: '事件个数',
|
name: '事件个数',
|
||||||
gs: 0,
|
gs: 0,
|
||||||
@@ -60,9 +104,9 @@ const tableStore: any = new TableStore({
|
|||||||
showPage: false,
|
showPage: false,
|
||||||
|
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
let res = {
|
let res = {
|
||||||
@@ -373,7 +417,6 @@ onMounted(() => {
|
|||||||
|
|
||||||
// 点击事件处理函数
|
// 点击事件处理函数
|
||||||
const handleChartClick = (params: any) => {
|
const handleChartClick = (params: any) => {
|
||||||
|
|
||||||
if (params.seriesName === '可容忍事件') {
|
if (params.seriesName === '可容忍事件') {
|
||||||
// 处理可容忍事件点击
|
// 处理可容忍事件点击
|
||||||
ElMessage.info(`点击了可容忍事件: 持续时间${params.value[0]}s, 幅值${params.value[1].toFixed(2)}%`)
|
ElMessage.info(`点击了可容忍事件: 持续时间${params.value[0]}s, 幅值${params.value[1].toFixed(2)}%`)
|
||||||
@@ -386,9 +429,30 @@ const handleChartClick = (params: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 可容忍事件点击处理函数
|
// 可容忍事件点击处理函数
|
||||||
const handleTolerableEventClick = (params: any) => {
|
const handleTolerableEventClick = async (row: any) => {
|
||||||
console.log('可容忍事件详情:', params)
|
console.log('可容忍事件详情:', row)
|
||||||
isWaveCharts.value = true
|
isWaveCharts.value = true
|
||||||
|
loading.value = true
|
||||||
|
isWaveCharts.value = true
|
||||||
|
await analyseWave(row.id)
|
||||||
|
.then(res => {
|
||||||
|
row.loading1 = false
|
||||||
|
if (res != undefined) {
|
||||||
|
boxoList.value = row
|
||||||
|
boxoList.value.featureAmplitude = row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
|
||||||
|
boxoList.value.systemType = 'WX'
|
||||||
|
wp.value = res.data
|
||||||
|
}
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
row.loading1 = false
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
waveFormAnalysisRef.value && waveFormAnalysisRef.value.getWpData(wp.value, boxoList.value, true)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 不可容忍事件点击处理函数
|
// 不可容忍事件点击处理函数
|
||||||
@@ -403,12 +467,17 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--暂降方向统计 -->
|
<!--暂降方向统计 -->
|
||||||
|
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||||
<my-echart class="tall" :options="echartList" :style="{ width: prop.width, height: `calc(${prop.height} )` }" />
|
<my-echart class="tall" :options="echartList" :style="{ width: prop.width, height: `calc(${prop.height} )` }" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -12,12 +13,46 @@ import MyEchart from '@/components/echarts/MyEchart.vue'
|
|||||||
import { useDictData } from '@/stores/dictData'
|
import { useDictData } from '@/stores/dictData'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: String },
|
w: { type: [String, Number] },
|
||||||
height: { type: String },
|
h: { type: [String, Number] },
|
||||||
timeKey: { type: String },
|
width: { type: [String, Number] },
|
||||||
|
height: { type: [String, Number] },
|
||||||
|
timeKey: { type: [String, Number] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
|
|
||||||
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
|
headerHeight.value = height
|
||||||
|
|
||||||
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
|
// 更新时间参数
|
||||||
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const data = [
|
const data = [
|
||||||
{
|
{
|
||||||
name: '来自电网',
|
name: '来自电网',
|
||||||
@@ -93,8 +128,8 @@ const tableStore: any = new TableStore({
|
|||||||
|
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
},
|
},
|
||||||
loadCallback: () => {}
|
loadCallback: () => {}
|
||||||
})
|
})
|
||||||
@@ -122,12 +157,17 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,39 +1,50 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 指标日趋势图 -->
|
<!-- 指标日趋势图 -->
|
||||||
<el-dialog draggable title="指标日趋势图" v-model="dialogVisible" append-to-body width="70%">
|
<el-dialog draggable :title="dialogTitle" v-model="dialogVisible" append-to-body width="70%">
|
||||||
<my-echart
|
<div :style="pageHeight">
|
||||||
class="tall"
|
<my-echart class="tall" :options="echartList" style="width: 98%" />
|
||||||
:options="echartList"
|
</div>
|
||||||
style="width: 98%; height: 320px"
|
|
||||||
/>
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
|
import { mainHeight } from '@/utils/layout'
|
||||||
|
import { limitExtentDayData } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: String },
|
width: { type: [String, Number] },
|
||||||
height: { type: String },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: String },
|
timeKey: { type: [String, Number] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const pageHeight = mainHeight(0, 2)
|
||||||
|
|
||||||
const dialogVisible: any = ref(false)
|
const dialogVisible: any = ref(false)
|
||||||
|
|
||||||
|
const dialogTitle = ref('')
|
||||||
|
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
|
|
||||||
const echartList = ref({
|
const dialogText = ref('')
|
||||||
title: {
|
|
||||||
text: '35kV进线谐波含有率',
|
|
||||||
},
|
|
||||||
|
|
||||||
xAxis: {
|
const echartList = ref()
|
||||||
|
|
||||||
|
const init = () => {
|
||||||
|
echartList.value = {
|
||||||
|
title: {
|
||||||
|
text: dialogText.value
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
itemWidth: 20,
|
||||||
|
itemHeight: 20,
|
||||||
|
itemStyle: { opacity: 0 }, //去圆点
|
||||||
|
right: 70
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
type: 'time',
|
type: 'time',
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
formatter: {
|
formatter: {
|
||||||
@@ -45,101 +56,90 @@ const echartList = ref({
|
|||||||
},
|
},
|
||||||
|
|
||||||
yAxis: [{}, {}],
|
yAxis: [{}, {}],
|
||||||
grid: {
|
grid: {
|
||||||
left: '10px',
|
left: '1%',
|
||||||
right: '20px'
|
right: '45px',
|
||||||
},
|
bottom: '40px',
|
||||||
options: {
|
top: '15%',
|
||||||
series: [
|
containLabel: true
|
||||||
|
},
|
||||||
|
dataZoom: [
|
||||||
{
|
{
|
||||||
// name: '暂降次数',
|
type: 'inside',
|
||||||
type: 'bar',
|
height: 13,
|
||||||
name: '有功功率',
|
start: 0,
|
||||||
data: [
|
bottom: '20px',
|
||||||
['2025-10-16 07:00:00', 10],
|
end: 100
|
||||||
['2025-10-16 07:15:00', 10],
|
|
||||||
['2025-10-16 07:30:00', 10],
|
|
||||||
['2025-10-16 07:45:00', 10],
|
|
||||||
['2025-10-16 08:00:00', 30],
|
|
||||||
['2025-10-16 08:15:00', 50],
|
|
||||||
['2025-10-16 08:30:00', 60],
|
|
||||||
['2025-10-16 08:45:00', 70],
|
|
||||||
['2025-10-16 09:00:00', 100],
|
|
||||||
['2025-10-16 09:15:00', 120],
|
|
||||||
['2025-10-16 09:30:00', 130],
|
|
||||||
['2025-10-16 09:45:00', 140],
|
|
||||||
['2025-10-16 10:00:00', 160],
|
|
||||||
['2025-10-16 10:15:00', 160],
|
|
||||||
['2025-10-16 10:30:00', 130],
|
|
||||||
['2025-10-16 10:45:00', 120],
|
|
||||||
['2025-10-16 11:00:00', 140],
|
|
||||||
['2025-10-16 11:15:00', 80],
|
|
||||||
['2025-10-16 11:30:00', 70],
|
|
||||||
['2025-10-16 11:45:00', 90],
|
|
||||||
['2025-10-16 12:00:00', 60],
|
|
||||||
['2025-10-16 12:15:00', 60],
|
|
||||||
['2025-10-16 12:30:00', 60],
|
|
||||||
['2025-10-16 12:45:00', 60]
|
|
||||||
],
|
|
||||||
itemStyle: {
|
|
||||||
normal: {
|
|
||||||
//这里是颜色
|
|
||||||
color: function (params: any) {
|
|
||||||
if (params.value[1] == 0 || params.value[1] == 3.14159) {
|
|
||||||
return '#ccc'
|
|
||||||
} else {
|
|
||||||
return config.layout.elementUiPrimary[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
yAxisIndex: 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '谐波总畸变率',
|
start: 0,
|
||||||
type: 'line',
|
height: 13,
|
||||||
showSymbol: false,
|
bottom: '20px',
|
||||||
smooth: true,
|
end: 100
|
||||||
data: [
|
|
||||||
['2025-10-16 07:00:00', 0],
|
|
||||||
['2025-10-16 07:15:00', 0],
|
|
||||||
['2025-10-16 07:30:00', 0],
|
|
||||||
['2025-10-16 07:45:00', 0],
|
|
||||||
['2025-10-16 08:00:00', 0],
|
|
||||||
['2025-10-16 08:15:00', 0.1],
|
|
||||||
['2025-10-16 08:30:00', 0.1],
|
|
||||||
['2025-10-16 08:45:00', 0.1],
|
|
||||||
['2025-10-16 09:00:00', 1],
|
|
||||||
['2025-10-16 09:15:00', 1],
|
|
||||||
['2025-10-16 09:30:00', 1],
|
|
||||||
['2025-10-16 09:45:00', 1],
|
|
||||||
['2025-10-16 10:00:00', 0.8],
|
|
||||||
['2025-10-16 10:15:00', 0.8],
|
|
||||||
['2025-10-16 10:30:00', 0.8],
|
|
||||||
['2025-10-16 10:45:00', 0.8],
|
|
||||||
['2025-10-16 11:00:00', 0.8],
|
|
||||||
['2025-10-16 11:15:00', 0.1],
|
|
||||||
['2025-10-16 11:30:00', 0.1],
|
|
||||||
['2025-10-16 11:45:00', 0.1],
|
|
||||||
['2025-10-16 12:00:00', 0],
|
|
||||||
['2025-10-16 12:15:00', 0],
|
|
||||||
['2025-10-16 12:30:00', 0],
|
|
||||||
['2025-10-16 12:45:00', 0]
|
|
||||||
],
|
|
||||||
yAxisIndex: 1
|
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
options: {
|
||||||
|
series: []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
const initData = async (row: any) => {
|
||||||
|
limitExtentDayData({ code: row.code, lineId: row.lineId, time: row.time }).then(res => {
|
||||||
|
if (res.data && res.data.length > 0) {
|
||||||
|
// 重新初始化图表
|
||||||
|
init()
|
||||||
|
|
||||||
onMounted(() => {
|
// 从第一条数据中提取时间作为x轴数据
|
||||||
|
const firstItem = res.data[0]
|
||||||
|
const xAxisData = firstItem.time.split(',')
|
||||||
|
|
||||||
})
|
// 定义相位颜色映射
|
||||||
|
const phaseColors: any = {
|
||||||
|
A: '#DAA520',
|
||||||
|
B: '#2E8B57',
|
||||||
|
C: '#A52a2a'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理每条相位数据
|
||||||
|
const seriesData = res.data.map((item: any) => {
|
||||||
|
const values = xAxisData.map((time: string, index: number) => {
|
||||||
|
// 将传入的日期与时间拼接成完整的时间字符串
|
||||||
|
const fullTime = `${row.time} ${time}`
|
||||||
|
const value = parseFloat(item.value.split(',')[index]) || 0
|
||||||
|
return [fullTime, value]
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: `${item.phasic}相`,
|
||||||
|
type: 'line',
|
||||||
|
showSymbol: false,
|
||||||
|
smooth: true,
|
||||||
|
data: values,
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
// 根据相位设置对应颜色
|
||||||
|
color: phaseColors[item.phasic] || config.layout.elementUiPrimary[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 更新图表配置
|
||||||
|
echartList.value.options.series = seriesData
|
||||||
|
// 注意:使用时间轴时不需要设置 xAxis.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
onMounted(() => {})
|
||||||
|
|
||||||
const open = async (row: any) => {
|
const open = async (row: any) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = row.name + '日趋势图'
|
||||||
|
dialogText.value = `监测点:${row.lineName} 时间:${row.time} 指标:${row.name}`
|
||||||
|
nextTick(() => {
|
||||||
|
initData(row)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ open })
|
defineExpose({ open })
|
||||||
|
|||||||
@@ -1,74 +1,72 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--指标越限程度 -->
|
<!--指标越限程度 -->
|
||||||
|
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||||
<my-echart
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
:style="{ width: prop.width, height: `calc(${prop.height} / 2 )` }"
|
:style="{ width: prop.width, height: `calc(${prop.height} / 2 )` }"
|
||||||
/>
|
/>
|
||||||
<Table ref="tableRef" @cell-click="cellClickEvent" :height="`calc(${prop.height} / 2 )`" isGroup></Table>
|
<Table
|
||||||
|
ref="tableRef"
|
||||||
|
@cell-click="cellClickEvent"
|
||||||
|
:height="`calc(${prop.height} / 2 - ${headerHeight}px + ${fullscreen ? 0 : 56}px )`"
|
||||||
|
isGroup
|
||||||
|
></Table>
|
||||||
<!-- 指标日趋势图 -->
|
<!-- 指标日趋势图 -->
|
||||||
<DailyTrendChart ref="dailyTrendChartRef" />
|
<DailyTrendChart v-if="dialogTrendChart" ref="dailyTrendChartRef" @close="dialogTrendChart = false" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useDictData } from '@/stores/dictData'
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
import DailyTrendChart from '@/components/cockpit/exceedanceLevel/components/dailyTrendChart.vue'
|
import DailyTrendChart from '@/components/cockpit/exceedanceLevel/components/dailyTrendChart.vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: String },
|
w: { type: [String, Number] },
|
||||||
height: { type: String },
|
h: { type: [String, Number] },
|
||||||
timeKey: { type: String },
|
width: { type: [String, Number] },
|
||||||
|
height: { type: [String, Number] },
|
||||||
|
timeKey: { type: [String, Number] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
const echartList = ref({
|
|
||||||
title: {
|
|
||||||
text: '指标越限严重度'
|
|
||||||
},
|
|
||||||
|
|
||||||
xAxis: {
|
const headerHeight = ref(57)
|
||||||
// name: '(区域)',
|
|
||||||
data: ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
|
||||||
},
|
|
||||||
|
|
||||||
yAxis: {
|
const dialogTrendChart = ref(false)
|
||||||
name: '%', // 给X轴加单位
|
|
||||||
interval: 20
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
left: '10px',
|
|
||||||
right: '20px'
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
// name: '暂降次数',
|
|
||||||
type: 'bar',
|
|
||||||
name: '越限占比',
|
|
||||||
data: [0, 7.5, 36, 0, 80],
|
|
||||||
barMaxWidth: 30
|
|
||||||
|
|
||||||
// label: {
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
// show: true,
|
headerHeight.value = height
|
||||||
// position: 'top',
|
|
||||||
// textStyle: {
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
// //数值样式
|
// 更新时间参数
|
||||||
// color: '#000'
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
// },
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
// fontSize: 12
|
}
|
||||||
// }
|
}
|
||||||
}
|
// 计算是否全屏展示
|
||||||
]
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const echartList = ref()
|
||||||
|
|
||||||
const dailyTrendChartRef = ref()
|
const dailyTrendChartRef = ref()
|
||||||
const tableStore: any = new TableStore({
|
const tableStore: any = new TableStore({
|
||||||
url: '/user-boot/dept/deptTree',
|
url: '/harmonic-boot/limitRateDetailD/limitExtentData',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
||||||
showPage: false,
|
showPage: false,
|
||||||
@@ -90,82 +88,107 @@ const tableStore: any = new TableStore({
|
|||||||
|
|
||||||
{
|
{
|
||||||
title: '越限最大值',
|
title: '越限最大值',
|
||||||
field: 'type',
|
field: 'maxValue',
|
||||||
minWidth: '60',
|
minWidth: '60',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.type}</span>`
|
const extentValue =
|
||||||
|
row.maxValue !== null && row.maxValue !== undefined && row.maxValue !== ''
|
||||||
|
? Math.floor(row.maxValue * 100) / 100
|
||||||
|
: '/'
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${extentValue}</span>`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '国标限值',
|
title: '国标限值',
|
||||||
field: 'type1',
|
field: 'internationalValue',
|
||||||
minWidth: '60'
|
minWidth: '60'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '越限程度(%)',
|
title: '越限程度(%)',
|
||||||
field: 'type2',
|
field: 'extent',
|
||||||
minWidth: '60'
|
minWidth: '60',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
// 保留两个小数
|
||||||
|
const extentValue =
|
||||||
|
row.extent !== null && row.extent !== undefined && row.extent !== ''
|
||||||
|
? Math.floor(row.extent * 100) / 100
|
||||||
|
: '/'
|
||||||
|
return `<span>${extentValue}</span>`
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '发生日期',
|
title: '发生日期',
|
||||||
field: 'type3',
|
field: 'time',
|
||||||
minWidth: '100'
|
minWidth: '60',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
if (row.time !== null && row.time !== undefined && row.time !== '') {
|
||||||
|
return `<span>${row.time}</span>`
|
||||||
|
} else {
|
||||||
|
return `<span>/</span>`
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '越限最高监测点',
|
title: '越限最高监测点',
|
||||||
field: 'type4',
|
field: 'lineName',
|
||||||
minWidth: '90'
|
minWidth: '90',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
if (row.lineName !== null && row.lineName !== undefined && row.lineName !== '') {
|
||||||
|
return `<span>${row.lineName}</span>`
|
||||||
|
} else {
|
||||||
|
return `<span>/</span>`
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.data = [
|
// 定义 x 轴标签顺序
|
||||||
{
|
const xAxisLabels = ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
||||||
name: '闪变',
|
|
||||||
type: '0.0',
|
|
||||||
type1: '2.0',
|
|
||||||
type2: '0.0',
|
|
||||||
type3: '/',
|
|
||||||
type4: '/'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '谐波电压',
|
|
||||||
type: '1.72',
|
|
||||||
type1: '1.6',
|
|
||||||
type2: '7.5',
|
|
||||||
type3: '2025-03-09',
|
|
||||||
type4: '10kV1#电动机'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '谐波电流',
|
|
||||||
type: '27.2',
|
|
||||||
type1: '20.0',
|
|
||||||
type2: '36.0',
|
|
||||||
type3: '2025-03-16',
|
|
||||||
type4: '380V电焊机(治理前)'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '电压偏差',
|
|
||||||
type: '0.0',
|
|
||||||
type1: '2.0',
|
|
||||||
type2: '0.0',
|
|
||||||
type3: '/',
|
|
||||||
type4: '/'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '三相不平衡',
|
|
||||||
type: '3.6',
|
|
||||||
type1: '2.0',
|
|
||||||
type2: '80.0',
|
|
||||||
type3: '2025-03-01',
|
|
||||||
type4: '380V电焊机(治理前)'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
|
// 根据指标名称顺序提取对应的 extent 数据
|
||||||
|
const chartData = xAxisLabels.map(label => {
|
||||||
|
// 在表格数据中查找对应指标名称的数据项
|
||||||
|
const item = tableStore.table.data.find((row: any) => row.name === label)
|
||||||
|
// 如果找到对应项,则返回 extent 值,否则返回 0,并保留两位小数
|
||||||
|
const extentValue = item ? item.extent || 0 : 0
|
||||||
|
return Math.round(extentValue * 100) / 100
|
||||||
|
})
|
||||||
|
echartList.value = {
|
||||||
|
title: {
|
||||||
|
text: '指标越限严重度'
|
||||||
|
},
|
||||||
|
|
||||||
|
xAxis: {
|
||||||
|
data: xAxisLabels
|
||||||
|
},
|
||||||
|
|
||||||
|
yAxis: {
|
||||||
|
name: '%' // 给X轴加单位
|
||||||
|
// interval: 20
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '10px',
|
||||||
|
right: '20px'
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'bar',
|
||||||
|
name: '越限占比',
|
||||||
|
data: chartData,
|
||||||
|
barMaxWidth: 30
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -176,9 +199,11 @@ provide('tableStore', tableStore)
|
|||||||
|
|
||||||
// 点击行
|
// 点击行
|
||||||
const cellClickEvent = ({ row, column }: any) => {
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
if (column.field != 'name') {
|
dialogTrendChart.value = true
|
||||||
console.log(row)
|
if (column.field == 'maxValue' && row.lineId) {
|
||||||
dailyTrendChartRef.value.open(row)
|
nextTick(() => {
|
||||||
|
dailyTrendChartRef.value.open(row)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,12 +217,17 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--治理效果报表 -->
|
<!--治理效果报表 -->
|
||||||
<TableHeader :showReset="false" v-if="fullscreen">
|
<TableHeader :showReset="false" datePicker @selectChange="selectChange" v-if="fullscreen">
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="治理对象">
|
<el-form-item label="治理对象">
|
||||||
<el-select
|
<el-select
|
||||||
@@ -39,19 +39,18 @@ import { ref, onMounted, provide, reactive, watch, h, computed } from 'vue'
|
|||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import { exportExcel } from '@/views/govern/reportForms/export.js'
|
import { exportExcel } from '@/views/govern/reportForms/export.js'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import { useDictData } from '@/stores/dictData'
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
import Json from './index.json'
|
import Json from './index.json'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: String },
|
w: { type: [String, Number]},
|
||||||
h: { type: String },
|
h: { type: [String, Number]},
|
||||||
width: { type: String },
|
width: { type: [String, Number]},
|
||||||
height: { type: String },
|
height: { type: [String, Number]},
|
||||||
timeKey: { type: String },
|
timeKey: { type: [String, Number]},
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
@@ -66,6 +65,9 @@ const powerList: any = ref([
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
|
|
||||||
const tableStore: any = new TableStore({
|
const tableStore: any = new TableStore({
|
||||||
url: '/user-boot/role/selectRoleDetail?id=0',
|
url: '/user-boot/role/selectRoleDetail?id=0',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -73,9 +75,9 @@ const tableStore: any = new TableStore({
|
|||||||
showPage: false,
|
showPage: false,
|
||||||
exportName: '主要监测点列表',
|
exportName: '主要监测点列表',
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
},
|
},
|
||||||
loadCallback: () => {}
|
loadCallback: () => {}
|
||||||
})
|
})
|
||||||
@@ -103,6 +105,16 @@ onMounted(() => {
|
|||||||
|
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
|
|
||||||
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
|
// 更新时间参数
|
||||||
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 计算是否全屏展示
|
// 计算是否全屏展示
|
||||||
const fullscreen = computed(() => {
|
const fullscreen = computed(() => {
|
||||||
const w = Number(prop.w)
|
const w = Number(prop.w)
|
||||||
@@ -121,12 +133,17 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,184 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- 指标越限详情 -->
|
||||||
|
<el-dialog draggable title="指标越限详情" v-model="dialogVisible" append-to-body width="70%">
|
||||||
|
<TableHeader datePicker showExport :showReset="false" ref="tableHeaderRef">
|
||||||
|
<template v-slot:select>
|
||||||
|
<el-form-item label="监测点">
|
||||||
|
<el-select
|
||||||
|
v-model="tableStore.table.params.lineId"
|
||||||
|
placeholder="请选择监测点"
|
||||||
|
style="width: 150px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in options"
|
||||||
|
:key="item.lineId"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.lineId"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</TableHeader>
|
||||||
|
<Table ref="tableRef" @cell-click="cellClickEvent" isGroup :height="height"></Table>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 谐波电流、谐波电压占有率 -->
|
||||||
|
<HarmonicRatio ref="harmonicRatioRef" @close="onHarmonicRatioClose" :TrendList="TrendList" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, provide,nextTick } from 'vue'
|
||||||
|
import Table from '@/components/table/index.vue'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import TableStore from '@/utils/tableStore'
|
||||||
|
import { mainHeight } from '@/utils/layout'
|
||||||
|
import HarmonicRatio from '@/components/cockpit/indicatorFittingChart/components/harmonicRatio.vue'
|
||||||
|
import { cslineList } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
|
|
||||||
|
const dialogVisible: any = ref(false)
|
||||||
|
const harmonicRatioRef: any = ref(null)
|
||||||
|
|
||||||
|
const options = ref()
|
||||||
|
const height = mainHeight(0, 2).height as any
|
||||||
|
const tableHeaderRef = ref()
|
||||||
|
const TrendList = ref([{lineType:1}])
|
||||||
|
const loop50 = (key: string) => {
|
||||||
|
let list: any[] = []
|
||||||
|
for (let i = 2; i < 26; i++) {
|
||||||
|
list.push({
|
||||||
|
title: i + '次',
|
||||||
|
field: key + i + 'Overtime',
|
||||||
|
width: '80',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
const tableStore: any = new TableStore({
|
||||||
|
url: '/harmonic-boot/mainLine/statLimitRateDetails',
|
||||||
|
method: 'POST',
|
||||||
|
publicHeight: 30,
|
||||||
|
showPage: false,
|
||||||
|
exportName: '主要监测点列表',
|
||||||
|
column: [
|
||||||
|
{
|
||||||
|
field: 'index',
|
||||||
|
title: '序号',
|
||||||
|
width: '80',
|
||||||
|
formatter: (row: any) => {
|
||||||
|
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '日期',
|
||||||
|
field: 'time',
|
||||||
|
width: '150',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
field: 'lineName',
|
||||||
|
width: '150'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '闪变越限(分钟)',
|
||||||
|
field: 'flickerOvertime',
|
||||||
|
width: '80',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '谐波电压越限(分钟)',
|
||||||
|
children: loop50('uharm')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '谐波电流越限(分钟)',
|
||||||
|
children: loop50('iharm')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '三相不平衡度越限(分钟)',
|
||||||
|
field: 'ubalanceOvertime',
|
||||||
|
width: '100',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '电压偏差越限(分钟)',
|
||||||
|
field: 'uaberranceOvertime',
|
||||||
|
width: '100',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '频率偏差越限(分钟)',
|
||||||
|
field: 'freqDevOvertime',
|
||||||
|
width: '100',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
beforeSearchFun: () => {
|
||||||
|
},
|
||||||
|
loadCallback: () => {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
provide('tableStore', tableStore)
|
||||||
|
tableStore.table.params.sortBy = ''
|
||||||
|
tableStore.table.params.orderBy = ''
|
||||||
|
const open = async (row: any,searchBeginTime:any,searchEndTime:any) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
initCSlineList()
|
||||||
|
tableStore.table.params.lineId = row.lineId
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
tableHeaderRef.value.setTimeInterval([searchBeginTime, searchEndTime])
|
||||||
|
tableStore.table.params.searchBeginTime =searchBeginTime
|
||||||
|
tableStore.table.params.searchEndTime = searchEndTime
|
||||||
|
tableStore.index()
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击行
|
||||||
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
|
if (column.field != 'name' && column.field != 'time') {
|
||||||
|
dialogVisible.value = false
|
||||||
|
// if(column.title && column.title=='闪变越限(分钟)'){
|
||||||
|
// column.title = '1次'
|
||||||
|
// }
|
||||||
|
// harmonicRatioRef.value.openDialog(row,column.title.replace(/次/g, ""))
|
||||||
|
harmonicRatioRef.value.openDialog(row,column.field,column.title.replace(/次/g, ""))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 谐波弹窗关闭时的回调
|
||||||
|
const onHarmonicRatioClose = () => {
|
||||||
|
// 重新打开指标越限详情弹窗
|
||||||
|
nextTick(() => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const initCSlineList = async () => {
|
||||||
|
const res = await cslineList({})
|
||||||
|
options.value = res.data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@@ -1,13 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<!--电网侧指标越限统计 -->
|
<!--电网侧指标越限统计 -->
|
||||||
|
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||||
<my-echart
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
:style="{ width: prop.width, height: `calc(${prop.height} / 2 )` }"
|
:style="{
|
||||||
|
width: prop.width,
|
||||||
|
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||||||
|
}"
|
||||||
/>
|
/>
|
||||||
<Table ref="tableRef" @cell-click="cellClickEvent" :height="`calc(${prop.height} / 2 )`" isGroup></Table>
|
<Table
|
||||||
|
ref="tableRef"
|
||||||
|
@cell-click="cellClickEvent"
|
||||||
|
:height="`calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`"
|
||||||
|
isGroup
|
||||||
|
></Table>
|
||||||
<!-- 指标越限详情 -->
|
<!-- 指标越限详情 -->
|
||||||
<OverLimitDetails ref="OverLimitDetailsRef" />
|
<OverLimitDetails ref="OverLimitDetailsRef" />
|
||||||
</div>
|
</div>
|
||||||
@@ -17,16 +25,47 @@ import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
|||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useDictData } from '@/stores/dictData'
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
import OverLimitDetails from '@/components/cockpit/listOfMainMonitoringPoints/components/overLimitDetails.vue'
|
import OverLimitDetails from '@/components/cockpit/gridSideStatistics/components/overLimitDetails.vue'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: String },
|
w: { type: [String, Number] },
|
||||||
height: { type: String },
|
h: { type: [String, Number] },
|
||||||
timeKey: { type: String },
|
width: { type: [String, Number] },
|
||||||
|
height: { type: [String, Number] },
|
||||||
|
timeKey: { type: [String, Number] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
|
|
||||||
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
|
headerHeight.value = height
|
||||||
|
|
||||||
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
|
// 更新时间参数
|
||||||
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
const echartList = ref({
|
const echartList = ref({
|
||||||
title: {
|
title: {
|
||||||
text: '指标越限占比'
|
text: '指标越限占比'
|
||||||
@@ -52,7 +91,7 @@ const echartList = ref({
|
|||||||
type: 'bar',
|
type: 'bar',
|
||||||
name: '越限占比',
|
name: '越限占比',
|
||||||
data: [0, 45, 22, 0, 70],
|
data: [0, 45, 22, 0, 70],
|
||||||
barMaxWidth: 30,
|
barMaxWidth: 30
|
||||||
|
|
||||||
// label: {
|
// label: {
|
||||||
// show: true,
|
// show: true,
|
||||||
@@ -140,8 +179,8 @@ const tableStore: any = new TableStore({
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.data = [
|
tableStore.table.data = [
|
||||||
@@ -182,12 +221,17 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--指标越限明细 -->
|
<!--指标越限明细 -->
|
||||||
|
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||||
<el-calendar v-model="value" :style="{ height: prop.height, overflow: 'auto' }">
|
<el-calendar
|
||||||
|
v-model="value"
|
||||||
|
:style="{
|
||||||
|
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px )`,
|
||||||
|
overflow: 'auto'
|
||||||
|
}"
|
||||||
|
>
|
||||||
<template #date-cell="{ data }">
|
<template #date-cell="{ data }">
|
||||||
<div style="height: 100%; padding: 8px" :style="{ background: setBackground(data.day) }">
|
<div style="height: 100%; padding: 8px" :style="{ background: setBackground(data.day) }">
|
||||||
<p :class="data.isSelected ? 'is-selected' : ''">
|
<p :class="data.isSelected ? 'is-selected' : ''">
|
||||||
{{ data.day.split('-').slice(2).join('-') }}
|
{{ data.day.split('-').slice(2).join('-') }}
|
||||||
</p>
|
</p>
|
||||||
<el-tooltip
|
<el-tooltip effect="dark" placement="top" :hide-after="0" v-if="getTextForDate(data.day)">
|
||||||
effect="dark"
|
|
||||||
placement="top"
|
|
||||||
:hide-after="0"
|
|
||||||
v-if="list?.filter(item => item.time == data.day)[0]?.text || false"
|
|
||||||
>
|
|
||||||
<template #content>
|
<template #content>
|
||||||
<span v-html="list?.filter(item => item.time == data.day)[0]?.text || ''"></span>
|
<span v-html="getTextForDate(data.day)"></span>
|
||||||
</template>
|
</template>
|
||||||
<div
|
<div
|
||||||
:style="{ height: `calc(${prop.height} / 5 - 47px)`, overflow: 'auto' }"
|
:style="{
|
||||||
v-html="list?.filter(item => item.time == data.day)[0]?.text || ''"
|
height: `calc(${prop.height} / 5 ) `,
|
||||||
|
overflow: 'auto'
|
||||||
|
}"
|
||||||
|
v-html="getTextForDate(data.day)"
|
||||||
></div>
|
></div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
@@ -30,96 +34,129 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import { useDictData } from '@/stores/dictData'
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
|
||||||
import { overflow } from 'html2canvas/dist/types/css/property-descriptors/overflow'
|
|
||||||
import { dayjs } from 'element-plus'
|
import { dayjs } from 'element-plus'
|
||||||
|
|
||||||
|
const prop = defineProps({
|
||||||
|
w: { type: [String, Number] },
|
||||||
|
h: { type: [String, Number] },
|
||||||
|
width: { type: [String, Number] },
|
||||||
|
height: { type: [String, Number] },
|
||||||
|
timeKey: { type: [String, Number] },
|
||||||
|
timeValue: { type: Object }
|
||||||
|
})
|
||||||
|
|
||||||
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
|
const list = ref()
|
||||||
|
|
||||||
dayjs.en.weekStart = 1 //设置日历的周起始日为星期一
|
dayjs.en.weekStart = 1 //设置日历的周起始日为星期一
|
||||||
const value = ref(new Date())
|
const value = ref(new Date())
|
||||||
const prop = defineProps({
|
|
||||||
width: { type: String },
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
height: { type: String },
|
headerHeight.value = height
|
||||||
timeKey: { type: String },
|
|
||||||
timeValue: { type: Object }
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
})
|
// 更新时间参数
|
||||||
const list = ref([
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
{
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
time: '2025-10-01',
|
|
||||||
key: 81,
|
|
||||||
text: '3次谐波越限<br/>5次谐波越限<br/>三相不平衡越限'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
time: '2025-10-31',
|
|
||||||
key: 81,
|
|
||||||
text: '3次谐波越限<br/>5次谐波越限<br/>三相不平衡越限'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
time: '2025-10-08',
|
|
||||||
key: 20,
|
|
||||||
text: '3次谐波越限<br/>5次谐波越限<br/>三相不平衡越限'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
time: '2025-10-16',
|
|
||||||
key: 20,
|
|
||||||
text: '3次谐波越限<br/>5次谐波越限<br/>三相不平衡越限'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
time: '2025-10-23',
|
|
||||||
key: 20,
|
|
||||||
text: '3次谐波越限<br/>5次谐波越限<br/>三相不平衡越限'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
time: '2025-10-04',
|
|
||||||
key: 0,
|
|
||||||
text: ''
|
|
||||||
},
|
|
||||||
{
|
|
||||||
time: '2025-10-05',
|
|
||||||
key: 0,
|
|
||||||
text: ''
|
|
||||||
}
|
}
|
||||||
])
|
}
|
||||||
|
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const getTextForDate = (date: string) => {
|
||||||
|
const item = list.value?.find((item: any) => item.time === date)
|
||||||
|
return item ? item.text : ''
|
||||||
|
}
|
||||||
|
|
||||||
const tableStore: any = new TableStore({
|
const tableStore: any = new TableStore({
|
||||||
url: '/user-boot/dept/deptTree',
|
// url: '/user-boot/role/selectRoleDetail?id=0',
|
||||||
|
url: '/harmonic-boot/limitRateDetailD/limitCalendarData',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
||||||
showPage: false,
|
showPage: false,
|
||||||
|
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
// value.value = new Date(prop.timeValue?.[0])
|
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.data = []
|
// 将后端返回的数据整合到 list 中
|
||||||
|
// tableStore.table.data = [
|
||||||
|
// {
|
||||||
|
// "time": "2025-11-13",
|
||||||
|
// "items": [
|
||||||
|
// "闪变越限",
|
||||||
|
// "谐波电流越限"
|
||||||
|
// ],
|
||||||
|
// "status": 1
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "time": "2025-11-14",
|
||||||
|
// "items": [
|
||||||
|
// "频率偏差越限",
|
||||||
|
// "三相电压不平衡越限",
|
||||||
|
// "谐波电压越限",
|
||||||
|
// "谐波电流越限",
|
||||||
|
// "频率偏差越限",
|
||||||
|
// "三相电压不平衡越限",
|
||||||
|
// "谐波电压越限",
|
||||||
|
// "谐波电流越限",
|
||||||
|
// "频率偏差越限",
|
||||||
|
// "三相电压不平衡越限",
|
||||||
|
// "谐波电压越限",
|
||||||
|
// "谐波电流越限"
|
||||||
|
// ],
|
||||||
|
// "status": 2
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
if (tableStore.table.data && tableStore.table.data.length > 0) {
|
||||||
|
list.value = tableStore.table.data.map((item: any) => {
|
||||||
|
// 将 items 数组转换为带换行的文本
|
||||||
|
const text = item.items && item.items.length > 0 ? item.items.join('<br/>') : ''
|
||||||
|
|
||||||
|
return {
|
||||||
|
time: item.time,
|
||||||
|
key: item.status || 0,
|
||||||
|
text: text
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
list.value = []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const tableRef = ref([])
|
|
||||||
|
|
||||||
const setBackground = (value: string) => {
|
const setBackground = (value: string) => {
|
||||||
let data = []
|
const data = list.value?.find((item: any) => item.time === value)
|
||||||
data = list.value?.filter(item => item.time == value)
|
|
||||||
|
|
||||||
if (data && data?.length > 0) {
|
if (data) {
|
||||||
if (data[0].key < 10) {
|
// 根据 status 值返回对应的颜色
|
||||||
return '#33996690'
|
switch (data.key) {
|
||||||
} else if (data[0].key < 80) {
|
case 0: // 无越限
|
||||||
return '#FFCC3390'
|
return '#33996690'
|
||||||
} else if (data[0].key <= 100) {
|
case 1: // 一般越限
|
||||||
return '#Ff660090'
|
return '#FFCC3390'
|
||||||
|
case 2: // 严重越限
|
||||||
|
return '#Ff660090'
|
||||||
|
default:
|
||||||
|
return '#fff' // 默认白色背景
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return '#fff'
|
return '#fff' // 默认白色背景
|
||||||
}
|
}
|
||||||
|
|
||||||
provide('tableRef', tableRef)
|
|
||||||
|
|
||||||
provide('tableStore', tableStore)
|
provide('tableStore', tableStore)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -132,12 +169,17 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +1,225 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--指标越限概率分布 -->
|
<!--指标越限概率分布 -->
|
||||||
|
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen">
|
||||||
|
<template v-slot:select>
|
||||||
|
<el-form-item>
|
||||||
|
<el-select size="small" v-model="tableStore.table.params.searchValue">
|
||||||
|
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</TableHeader>
|
||||||
<my-echart
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
:style="{ width: prop.width, height: `calc(${prop.height} / 2 )` }"
|
:style="{
|
||||||
|
width: prop.width,
|
||||||
|
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||||||
|
}"
|
||||||
/>
|
/>
|
||||||
<my-echart
|
<my-echart
|
||||||
class="mt10"
|
class="mt10"
|
||||||
:options="echartList1"
|
:options="echartList1"
|
||||||
:style="{ width: prop.width, height: `calc(${prop.height} / 2 - 10px)` }"
|
:style="{
|
||||||
|
width: prop.width,
|
||||||
|
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||||||
|
}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useDictData } from '@/stores/dictData'
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: String },
|
w: { type: [String, Number] },
|
||||||
height: { type: String },
|
h: { type: [String, Number] },
|
||||||
timeKey: { type: String },
|
width: { type: [String, Number] },
|
||||||
|
height: { type: [String, Number] },
|
||||||
|
timeKey: { type: [String, Number] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const options = [
|
||||||
|
{
|
||||||
|
value: '1',
|
||||||
|
label: '35V进线'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
|
|
||||||
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
|
headerHeight.value = height
|
||||||
|
|
||||||
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
|
// 更新时间参数
|
||||||
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// const echartList = ref({
|
||||||
|
// options: {
|
||||||
|
// xAxis: null,
|
||||||
|
// yAxis: null,
|
||||||
|
// dataZoom: null,
|
||||||
|
// backgroundColor: '#fff',
|
||||||
|
// tooltip: {
|
||||||
|
// // trigger: 'axis'
|
||||||
|
// textStyle: {
|
||||||
|
// color: '#fff',
|
||||||
|
// fontStyle: 'normal',
|
||||||
|
// opacity: 0.35,
|
||||||
|
// fontSize: 14
|
||||||
|
// },
|
||||||
|
// backgroundColor: 'rgba(0,0,0,0.55)',
|
||||||
|
// borderWidth: 0,
|
||||||
|
// formatter: function (params: any) {
|
||||||
|
// console.log(params)
|
||||||
|
// var tips = ''
|
||||||
|
// for (var i = 0; i < params.length; i++) {
|
||||||
|
// tips += params[i].name + '</br/>'
|
||||||
|
// tips += '监测点数' + ':' + ' ' + ' ' + params[i].value + '</br/>'
|
||||||
|
// }
|
||||||
|
// return tips
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// title: {
|
||||||
|
// text: '指标越限概率分布',
|
||||||
|
// x: 'center'
|
||||||
|
// },
|
||||||
|
|
||||||
|
// visualMap: {
|
||||||
|
// max: 20,
|
||||||
|
// show: false,
|
||||||
|
// inRange: {
|
||||||
|
// color: ['#313695', '#00BB00', '#ff8000', '#a50026']
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// xAxis3D: {
|
||||||
|
// type: 'category',
|
||||||
|
// name: '指标越限',
|
||||||
|
// data: ['0-10', '10-20', '20-30', '30-40', '40-50'],
|
||||||
|
// axisLine: {
|
||||||
|
// lineStyle: {
|
||||||
|
// color: '#111'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// axisLabel: {
|
||||||
|
// color: '#111'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// yAxis3D: {
|
||||||
|
// type: 'category',
|
||||||
|
// name: '指标类型',
|
||||||
|
// data: ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡'],
|
||||||
|
// nameTextStyle: {
|
||||||
|
// color: '#111'
|
||||||
|
// },
|
||||||
|
// axisLine: {
|
||||||
|
// show: true,
|
||||||
|
// lineStyle: {
|
||||||
|
// color: '#111'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// axisLabel: {
|
||||||
|
// color: '#111'
|
||||||
|
// },
|
||||||
|
// splitLine: {
|
||||||
|
// lineStyle: {
|
||||||
|
// // 使用深浅的间隔色
|
||||||
|
// color: ['#111'],
|
||||||
|
// type: 'dashed',
|
||||||
|
// opacity: 0.5
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// zAxis3D: {
|
||||||
|
// type: 'value',
|
||||||
|
// splitNumber: 10,
|
||||||
|
// minInterval: 10,
|
||||||
|
// name: '越限占比'
|
||||||
|
// },
|
||||||
|
// grid3D: {
|
||||||
|
// viewControl: {
|
||||||
|
// projection: 'perspective',
|
||||||
|
// distance: 250
|
||||||
|
// },
|
||||||
|
// boxWidth: 200,
|
||||||
|
// boxDepth: 80,
|
||||||
|
// light: {
|
||||||
|
// main: {
|
||||||
|
// intensity: 1.2
|
||||||
|
// },
|
||||||
|
// ambient: {
|
||||||
|
// intensity: 0.3
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// series: [
|
||||||
|
// {
|
||||||
|
// type: 'bar3D',
|
||||||
|
// data: [
|
||||||
|
// [0, 0, 1],
|
||||||
|
// [0, 1, 1],
|
||||||
|
// [0.2, 1]
|
||||||
|
// ],
|
||||||
|
// shading: 'realistic',
|
||||||
|
// label: {
|
||||||
|
// show: false,
|
||||||
|
// textStyle: {
|
||||||
|
// fontSize: 16,
|
||||||
|
// borderWidth: 1
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
|
||||||
|
// itemStyle: {
|
||||||
|
// opacity: 1
|
||||||
|
// },
|
||||||
|
// emphasis: {
|
||||||
|
// label: {
|
||||||
|
// textStyle: {
|
||||||
|
// fontSize: 20,
|
||||||
|
// color: '#900'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// itemStyle: {
|
||||||
|
// color: '#900'
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
var yAxisData = ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
||||||
|
|
||||||
const echartList = ref({
|
const echartList = ref({
|
||||||
options: {
|
options: {
|
||||||
xAxis: null,
|
|
||||||
yAxis: null,
|
|
||||||
dataZoom: null,
|
|
||||||
backgroundColor: '#fff',
|
backgroundColor: '#fff',
|
||||||
tooltip: {
|
tooltip: {
|
||||||
// trigger: 'axis'
|
|
||||||
textStyle: {
|
textStyle: {
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
fontStyle: 'normal',
|
fontStyle: 'normal',
|
||||||
@@ -44,44 +229,74 @@ const echartList = ref({
|
|||||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||||
borderWidth: 0,
|
borderWidth: 0,
|
||||||
formatter: function (params: any) {
|
formatter: function (params: any) {
|
||||||
console.log(params)
|
console.log(params, '33344')
|
||||||
|
var yIndex = params.value[1] //获取y轴索引
|
||||||
var tips = ''
|
var tips = ''
|
||||||
for (var i = 0; i < params.length; i++) {
|
// tips += '指标类型: ' + params.name + '</br>'
|
||||||
tips += params[i].name + '</br/>'
|
tips += '指标类型: ' + yAxisData[yIndex] + '</br>'
|
||||||
tips += '监测点数' + ':' + ' ' + ' ' + params[i].value + '</br/>'
|
tips += '越限程度: ' + params.seriesName + '</br>'
|
||||||
}
|
// tips += '越限占比: ' + params.value + '%</br>'
|
||||||
|
tips += '越限占比: ' + params.value[2] + '%</br>'
|
||||||
return tips
|
return tips
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
text: '指标越限概率分布',
|
text: '指标越限概率分布',
|
||||||
x: 'center'
|
x: 'center',
|
||||||
},
|
textStyle: {
|
||||||
|
fontSize: 16,
|
||||||
visualMap: {
|
fontWeight: 'normal'
|
||||||
max: 20,
|
|
||||||
show: false,
|
|
||||||
inRange: {
|
|
||||||
color: ['#313695', '#00BB00', '#ff8000', '#a50026']
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
visualMap: {
|
||||||
|
max: 100,
|
||||||
|
show: true,
|
||||||
|
inRange: {
|
||||||
|
color: [
|
||||||
|
'#313695',
|
||||||
|
'#4575b4',
|
||||||
|
'#74add1',
|
||||||
|
'#abd9e9',
|
||||||
|
'#e0f3f8',
|
||||||
|
'#ffffbf',
|
||||||
|
'#fee090',
|
||||||
|
'#fdae61',
|
||||||
|
'#f46d43',
|
||||||
|
'#d73027',
|
||||||
|
'#a50026'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
// calculable: true,
|
||||||
|
// orient: 'horizontal',
|
||||||
|
// left: 'center',
|
||||||
|
// bottom: '5%'
|
||||||
|
},
|
||||||
xAxis3D: {
|
xAxis3D: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
name: '指标越限',
|
name: '越限程度',
|
||||||
data: ['0-10', '10-20', '20-30', '30-40', '40-50'],
|
nameLocation: 'middle',
|
||||||
|
nameGap: 30,
|
||||||
|
data: ['0-20%', '20-40%', '40-60%', '60-80%', '80-100%'],
|
||||||
axisLine: {
|
axisLine: {
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
color: '#111'
|
color: '#111'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
|
color: '#111',
|
||||||
|
margin: 15
|
||||||
|
},
|
||||||
|
nameTextStyle: {
|
||||||
color: '#111'
|
color: '#111'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
yAxis3D: {
|
yAxis3D: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
name: '指标类型',
|
name: '指标类型',
|
||||||
data: ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡'],
|
nameLocation: 'middle',
|
||||||
|
nameGap: 30,
|
||||||
|
// data: ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡'],
|
||||||
|
data: yAxisData,
|
||||||
nameTextStyle: {
|
nameTextStyle: {
|
||||||
color: '#111'
|
color: '#111'
|
||||||
},
|
},
|
||||||
@@ -92,11 +307,11 @@ const echartList = ref({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: '#111'
|
color: '#111',
|
||||||
|
margin: 15
|
||||||
},
|
},
|
||||||
splitLine: {
|
splitLine: {
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
// 使用深浅的间隔色
|
|
||||||
color: ['#111'],
|
color: ['#111'],
|
||||||
type: 'dashed',
|
type: 'dashed',
|
||||||
opacity: 0.5
|
opacity: 0.5
|
||||||
@@ -105,61 +320,203 @@ const echartList = ref({
|
|||||||
},
|
},
|
||||||
zAxis3D: {
|
zAxis3D: {
|
||||||
type: 'value',
|
type: 'value',
|
||||||
splitNumber: 10,
|
name: '越限占比(%)',
|
||||||
minInterval: 10,
|
nameLocation: 'middle',
|
||||||
name: '越限占比'
|
nameGap: 30,
|
||||||
|
nameTextStyle: {
|
||||||
|
color: '#111'
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#111'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: '#111'
|
||||||
|
},
|
||||||
|
min: 0,
|
||||||
|
max: 100
|
||||||
},
|
},
|
||||||
grid3D: {
|
grid3D: {
|
||||||
viewControl: {
|
viewControl: {
|
||||||
projection: 'perspective',
|
projection: 'perspective',
|
||||||
distance: 250
|
distance: 250,
|
||||||
|
rotateSensitivity: 10,
|
||||||
|
zoomSensitivity: 2
|
||||||
},
|
},
|
||||||
boxWidth: 200,
|
boxWidth: 150,
|
||||||
boxDepth: 80,
|
boxDepth: 100,
|
||||||
|
boxHeight: 100,
|
||||||
light: {
|
light: {
|
||||||
main: {
|
main: {
|
||||||
intensity: 1.2
|
intensity: 1.2
|
||||||
},
|
},
|
||||||
ambient: {
|
ambient: {
|
||||||
intensity: 0.3
|
intensity: 0.4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
type: 'bar3D',
|
type: 'bar3D',
|
||||||
|
name: '0-20%',
|
||||||
data: [
|
data: [
|
||||||
[0, 0, 1],
|
// [xIndex, yIndex, value]
|
||||||
[0, 1, 1],
|
[0, 0, 5], // 闪变 - 0-20%
|
||||||
[0.2, 1]
|
[0, 1, 10], // 谐波电压 - 0-20%
|
||||||
|
[0, 2, 8], // 谐波电流 - 0-20%
|
||||||
|
[0, 3, 15], // 电压偏差 - 0-20%
|
||||||
|
[0, 4, 12] // 三相不平衡 - 0-20%
|
||||||
],
|
],
|
||||||
shading: 'realistic',
|
shading: 'realistic',
|
||||||
label: {
|
label: {
|
||||||
show: false,
|
show: false
|
||||||
textStyle: {
|
|
||||||
fontSize: 16,
|
|
||||||
borderWidth: 1
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
opacity: 1
|
opacity: 0.9
|
||||||
},
|
},
|
||||||
emphasis: {
|
emphasis: {
|
||||||
label: {
|
label: {
|
||||||
|
show: true,
|
||||||
textStyle: {
|
textStyle: {
|
||||||
fontSize: 20,
|
fontSize: 14,
|
||||||
color: '#900'
|
color: '#000'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
color: '#900'
|
color: '#ff8000'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'bar3D',
|
||||||
|
name: '20-40%',
|
||||||
|
// data: chartData.map(function (item) {
|
||||||
|
// return {
|
||||||
|
// value: [item[1], item[0], item[2]]
|
||||||
|
// };
|
||||||
|
// }),
|
||||||
|
data: [
|
||||||
|
[1, 0, 10], // 闪变 - 20-40%
|
||||||
|
[1, 1, 20], // 谐波电压 - 20-40%
|
||||||
|
[1, 2, 15], // 谐波电流 - 20-40%
|
||||||
|
[1, 3, 25], // 电压偏差 - 20-40%
|
||||||
|
[1, 4, 18] // 三相不平衡 - 20-40%
|
||||||
|
],
|
||||||
|
shading: 'realistic',
|
||||||
|
label: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
opacity: 0.9
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: '#000'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: '#ff8000'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'bar3D',
|
||||||
|
name: '40-60%',
|
||||||
|
data: [
|
||||||
|
[2, 0, 15], // 闪变 - 40-60%
|
||||||
|
[2, 1, 25], // 谐波电压 - 40-60%
|
||||||
|
[2, 2, 30], // 谐波电流 - 40-60%
|
||||||
|
[2, 3, 35], // 电压偏差 - 40-60%
|
||||||
|
[2, 4, 28] // 三相不平衡 - 40-60%
|
||||||
|
],
|
||||||
|
shading: 'realistic',
|
||||||
|
label: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
opacity: 0.9
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: '#000'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: '#ff8000'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'bar3D',
|
||||||
|
name: '60-80%',
|
||||||
|
data: [
|
||||||
|
[3, 0, 20], // 闪变 - 60-80%
|
||||||
|
[3, 1, 30], // 谐波电压 - 60-80%
|
||||||
|
[3, 2, 35], // 谐波电流 - 60-80%
|
||||||
|
[3, 3, 40], // 电压偏差 - 60-80%
|
||||||
|
[3, 4, 35] // 三相不平衡 - 60-80%
|
||||||
|
],
|
||||||
|
shading: 'realistic',
|
||||||
|
label: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
opacity: 0.9
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: '#000'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: '#ff8000'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'bar3D',
|
||||||
|
name: '80-100%',
|
||||||
|
data: [
|
||||||
|
[4, 0, 25], // 闪变 - 80-100%
|
||||||
|
[4, 1, 35], // 谐波电压 - 80-100%
|
||||||
|
[4, 2, 40], // 谐波电流 - 80-100%
|
||||||
|
[4, 3, 45], // 电压偏差 - 80-100%
|
||||||
|
[4, 4, 42] // 三相不平衡 - 80-100%
|
||||||
|
],
|
||||||
|
shading: 'realistic',
|
||||||
|
label: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
opacity: 0.9
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: '#000'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: '#ff8000'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const echartList1 = ref({
|
const echartList1 = ref({
|
||||||
title: {
|
title: {
|
||||||
text: '越限时间概率分布'
|
text: '越限时间概率分布'
|
||||||
@@ -356,8 +713,8 @@ const tableStore: any = new TableStore({
|
|||||||
showPage: false,
|
showPage: false,
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.data = []
|
tableStore.table.data = []
|
||||||
@@ -365,6 +722,7 @@ const tableStore: any = new TableStore({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const tableRef = ref()
|
const tableRef = ref()
|
||||||
|
tableStore.table.params.searchValue = '1'
|
||||||
provide('tableRef', tableRef)
|
provide('tableRef', tableRef)
|
||||||
|
|
||||||
provide('tableStore', tableStore)
|
provide('tableStore', tableStore)
|
||||||
@@ -379,12 +737,17 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,706 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog draggable title="趋势图" v-model="dialogVisible" append-to-body width="70%">
|
||||||
|
<!-- 总体指标占比详情谐波含有率 -->
|
||||||
|
<div>
|
||||||
|
<TableHeader ref="tableHeaderRef" :showSearch="false" @selectChange="selectChange">
|
||||||
|
<template v-slot:select>
|
||||||
|
<el-form-item>
|
||||||
|
<DatePicker ref="datePickerRef"></DatePicker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="统计指标" label-width="80px">
|
||||||
|
<el-select
|
||||||
|
multiple
|
||||||
|
:multiple-limit="2"
|
||||||
|
collapse-tags
|
||||||
|
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" @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-option value="max" label="最大值"></el-option>
|
||||||
|
<el-option value="min" label="最小值"></el-option>
|
||||||
|
<el-option value="avg" label="平均值"></el-option>
|
||||||
|
<el-option value="cp95" label="cp95"></el-option>
|
||||||
|
</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"
|
||||||
|
>
|
||||||
|
<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="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="timeControl ? 'primary' : ''" icon="el-icon-Sort" @click="setTimeControl">
|
||||||
|
缺失数据
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</TableHeader>
|
||||||
|
</div>
|
||||||
|
<div class="history_chart" :style="pageHeight" v-loading="loading">
|
||||||
|
<MyEchart
|
||||||
|
ref="historyChart"
|
||||||
|
:options="echartsData"
|
||||||
|
v-if="showEchart"
|
||||||
|
/>
|
||||||
|
<el-empty :style="pageHeight" v-else description="暂无数据" />
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { mainHeight } from '@/utils/layout'
|
||||||
|
import { queryByCode, queryCsDictTree } from '@/api/system-boot/dictTree'
|
||||||
|
import { ref, onMounted, watch } from 'vue'
|
||||||
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
|
import { useDictData } from '@/stores/dictData'
|
||||||
|
import { queryStatistical } from '@/api/system-boot/csstatisticalset'
|
||||||
|
import { yMethod, exportCSV, completeTimeSeries } from '@/utils/echartMethod'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { trendData } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
|
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||||
|
import { color } from '@/components/echarts/color'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
const dictData = useDictData()
|
||||||
|
defineOptions({
|
||||||
|
// name: 'govern/device/control'
|
||||||
|
})
|
||||||
|
const props = defineProps({
|
||||||
|
TrendList: {
|
||||||
|
type: Array
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const dialogVisible: any = ref(false)
|
||||||
|
// console.log("🚀 ~ props:", props.TrendList)
|
||||||
|
const showEchart = ref(true)
|
||||||
|
const num = ref(0)
|
||||||
|
const timeControl = ref(false)
|
||||||
|
//值类型
|
||||||
|
const pageHeight = ref(mainHeight(57 * 1.6, 1.6))
|
||||||
|
const loading = ref(true)
|
||||||
|
const searchForm: any = ref({})
|
||||||
|
const tableHeaderRef = ref()
|
||||||
|
const typeOptions = [
|
||||||
|
{
|
||||||
|
name: '平均值',
|
||||||
|
id: 'avg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '最大值',
|
||||||
|
id: 'max'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '最小值',
|
||||||
|
id: 'min'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CP95值',
|
||||||
|
id: 'cp95'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
searchForm.value = {
|
||||||
|
index: [],
|
||||||
|
type: typeOptions[0].id,
|
||||||
|
count: '',
|
||||||
|
searchBeginTime: '',
|
||||||
|
searchEndTime: '',
|
||||||
|
dataLevel: 'Primary',
|
||||||
|
valueType: 'avg'
|
||||||
|
}
|
||||||
|
//统计指标
|
||||||
|
const indexOptions: any = ref([])
|
||||||
|
//谐波次数
|
||||||
|
const countOptions: any = ref([])
|
||||||
|
// Harmonic_Type
|
||||||
|
// portable-harmonic
|
||||||
|
const legendDictList: any = ref([])
|
||||||
|
|
||||||
|
const initCode = (field: string, title: string) => {
|
||||||
|
queryByCode('steady_state_limit_trend').then(res => {
|
||||||
|
queryCsDictTree(res.data.id).then(item => {
|
||||||
|
//排序
|
||||||
|
indexOptions.value = item.data.sort((a: any, b: any) => {
|
||||||
|
return a.sort - b.sort
|
||||||
|
})
|
||||||
|
const titleMap: Record<string, number> = {
|
||||||
|
flickerOvertime: 0,
|
||||||
|
uaberranceOvertime: 3,
|
||||||
|
ubalanceOvertime: 4,
|
||||||
|
freqDevOvertime: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
let defaultIndex = 0 // 默认值
|
||||||
|
|
||||||
|
if (field in titleMap) {
|
||||||
|
defaultIndex = titleMap[field]
|
||||||
|
} else if (field.includes('uharm')) {
|
||||||
|
defaultIndex = 1
|
||||||
|
} else if (field.includes('iharm')) {
|
||||||
|
defaultIndex = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
searchForm.value.index[0] = indexOptions.value[defaultIndex].id
|
||||||
|
})
|
||||||
|
queryStatistical(res.data.id).then(vv => {
|
||||||
|
legendDictList.value = vv.data
|
||||||
|
indexOptions.value.map((item: any, index: any) => {
|
||||||
|
if (!countDataCopy.value[index]) {
|
||||||
|
countDataCopy.value[index] = {
|
||||||
|
index: item.id,
|
||||||
|
countOptions: [],
|
||||||
|
count: [],
|
||||||
|
name: indexOptions.value.find((vv: any) => {
|
||||||
|
return vv.id == item.id
|
||||||
|
})?.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
legendDictList.value?.selectedList?.map((vv: any, vvs: any) => {
|
||||||
|
//查找相等的指标
|
||||||
|
if (item.id == vv.dataType) {
|
||||||
|
vv.eleEpdPqdVOS.map((kk: any, kks: any) => {
|
||||||
|
if (kk.harmStart && kk.harmEnd) {
|
||||||
|
range(0, 0, 0)
|
||||||
|
|
||||||
|
if (kk.showName == '间谐波电压含有率') {
|
||||||
|
countDataCopy.value[index].countOptions = range(kk.harmStart, kk.harmEnd, 1).map(
|
||||||
|
(item: any) => {
|
||||||
|
return item - 0.5
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
countDataCopy.value[index].countOptions = range(kk.harmStart, kk.harmEnd, 1)
|
||||||
|
}
|
||||||
|
if (title && countDataCopy.value[index].countOptions.includes(Number(title))) {
|
||||||
|
countDataCopy.value[index].count = Number(title)
|
||||||
|
} else if (title && countDataCopy.value[index].countOptions.includes(title)) {
|
||||||
|
countDataCopy.value[index].count = title
|
||||||
|
} else if (
|
||||||
|
!countDataCopy.value[index].count ||
|
||||||
|
countDataCopy.value[index].count.length == 0
|
||||||
|
) {
|
||||||
|
// 只有当count为空时才设置默认值
|
||||||
|
countDataCopy.value[index].count = countDataCopy.value[index].countOptions[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
nextTick(() => {
|
||||||
|
formatCountOptions()
|
||||||
|
})
|
||||||
|
init()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const chartsList = ref<any>([])
|
||||||
|
const chartTitle: any = ref('')
|
||||||
|
const echartsData = ref<any>(null)
|
||||||
|
//加载echarts图表
|
||||||
|
//历史趋势数据
|
||||||
|
const historyDataList: any = ref([])
|
||||||
|
const range = (start: any, end: any, step: any) => {
|
||||||
|
return Array.from({ length: (end - start) / step + 1 }, (_, i) => start + i * step)
|
||||||
|
}
|
||||||
|
//获取请求趋势数据参数
|
||||||
|
const trendRequestData = ref()
|
||||||
|
const getTrendRequest = (val: any) => {
|
||||||
|
trendRequestData.value = val
|
||||||
|
// init()
|
||||||
|
}
|
||||||
|
//初始化趋势图
|
||||||
|
const headerRef = ref()
|
||||||
|
const datePickerRef = ref()
|
||||||
|
const lineStyle = [{ type: 'solid' }, { type: 'dashed' }, { type: 'dotted' }]
|
||||||
|
const init = async () => {
|
||||||
|
loading.value = true
|
||||||
|
// 选择指标的时候切换legend内容和data数据
|
||||||
|
let list: any = []
|
||||||
|
legendDictList.value?.selectedList?.map((item: any) => {
|
||||||
|
searchForm.value.index.map((vv: any) => {
|
||||||
|
if (item.dataType == vv) {
|
||||||
|
list.push(item.eleEpdPqdVOS)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
//颜色数组
|
||||||
|
const colorList = color
|
||||||
|
//选择的指标使用方法处理
|
||||||
|
formatCountOptions()
|
||||||
|
//查询历史趋势
|
||||||
|
historyDataList.value = []
|
||||||
|
chartTitle.value = ''
|
||||||
|
|
||||||
|
searchForm.value.index.map((item: any, indexs: any) => {
|
||||||
|
indexOptions.value.map((vv: any) => {
|
||||||
|
if (vv.id == item) {
|
||||||
|
chartTitle.value += indexs == searchForm.value.index.length - 1 ? vv.name : vv.name + '/'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
let lists: any = []
|
||||||
|
let frequencys: any = null
|
||||||
|
countData.value.map((item: any, index: any) => {
|
||||||
|
if (item.name.includes('谐波含有率')) {
|
||||||
|
frequencys = item.count
|
||||||
|
} else {
|
||||||
|
frequencys = ''
|
||||||
|
}
|
||||||
|
lists[index] = {
|
||||||
|
statisticalId: item.index,
|
||||||
|
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let obj = {
|
||||||
|
//...trendRequestData.value,
|
||||||
|
lineId: trendRequestData.value.lineId,
|
||||||
|
list: lists,
|
||||||
|
dataLevel: searchForm.value.dataLevel,
|
||||||
|
valueType: searchForm.value.valueType,
|
||||||
|
searchBeginTime: datePickerRef.value && datePickerRef.value.timeValue[0],
|
||||||
|
searchEndTime: datePickerRef.value && datePickerRef.value.timeValue[1]
|
||||||
|
}
|
||||||
|
if (searchForm.value.index.length == 0) {
|
||||||
|
ElMessage.warning('请选择统计指标')
|
||||||
|
loading.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (obj.list.length != 0) {
|
||||||
|
try {
|
||||||
|
showEchart.value = true
|
||||||
|
await trendData(obj)
|
||||||
|
.then((res: any) => {
|
||||||
|
if (res.code == 'A0000') {
|
||||||
|
if (res.data.length == 0) {
|
||||||
|
loading.value = false
|
||||||
|
showEchart.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
historyDataList.value = res.data
|
||||||
|
chartsList.value = JSON.parse(JSON.stringify(res.data))
|
||||||
|
loading.value = false
|
||||||
|
setEchart()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const setEchart = () => {
|
||||||
|
loading.value = true
|
||||||
|
echartsData.value = {}
|
||||||
|
//icon图标替换legend图例
|
||||||
|
|
||||||
|
// y轴单位数组
|
||||||
|
let unitList: any = []
|
||||||
|
|
||||||
|
let groupedData = chartsList.value.reduce((acc: any, item: any) => {
|
||||||
|
let key = ''
|
||||||
|
if (item.phase == null) {
|
||||||
|
key = item.unit
|
||||||
|
} else {
|
||||||
|
key = item.anotherName
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!acc[key]) {
|
||||||
|
acc[key] = []
|
||||||
|
}
|
||||||
|
acc[key].push(item)
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
let result = Object.values(groupedData)
|
||||||
|
if (chartsList.value.length > 0) {
|
||||||
|
unitList = result.map((item: any) => {
|
||||||
|
return item[0].unit
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
echartsData.value = {
|
||||||
|
legend: {
|
||||||
|
itemWidth: 20,
|
||||||
|
itemHeight: 20,
|
||||||
|
itemStyle: { opacity: 0 }, //去圆点
|
||||||
|
type: 'scroll', // 开启滚动分页
|
||||||
|
// orient: 'vertical', // 垂直排列
|
||||||
|
top: 5,
|
||||||
|
right: 70
|
||||||
|
// width: 550,
|
||||||
|
// height: 50
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: '80px'
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
axisPointer: {
|
||||||
|
type: 'cross',
|
||||||
|
label: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 16
|
||||||
|
}
|
||||||
|
},
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
opacity: 0.35,
|
||||||
|
fontSize: 14
|
||||||
|
},
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||||
|
borderWidth: 0,
|
||||||
|
formatter(params: any) {
|
||||||
|
const xname = params[0].value[0]
|
||||||
|
let str = `${xname}<br>`
|
||||||
|
params.forEach((el: any, index: any) => {
|
||||||
|
let marker = ''
|
||||||
|
|
||||||
|
if (el.value[3] == 'dashed') {
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
marker += `<span style="display:inline-block;border: 2px ${el.color} solid;margin-right:5px;width:10px;height:0px;background-color:#ffffff00;"></span>`
|
||||||
|
}
|
||||||
|
} 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>`
|
||||||
|
}
|
||||||
|
let unit = el.value[2] ? el.value[2] : ''
|
||||||
|
str += `${marker}${el.seriesName.split('(')[0]}:${el.value[1]}${unit}
|
||||||
|
<br>`
|
||||||
|
})
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
},
|
||||||
|
color: ['#DAA520', '#2E8B57', '#A52a2a', ...color],
|
||||||
|
xAxis: {
|
||||||
|
type: 'time',
|
||||||
|
axisLabel: {
|
||||||
|
formatter: {
|
||||||
|
day: '{MM}-{dd}',
|
||||||
|
month: '{MM}',
|
||||||
|
year: '{yyyy}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: [{}],
|
||||||
|
toolbox: {
|
||||||
|
featureProps: {
|
||||||
|
myTool1: {
|
||||||
|
show: true,
|
||||||
|
title: '下载csv',
|
||||||
|
icon: 'path://M588.8 551.253333V512H352v39.253333h236.373333z m0 78.933334v-39.253334H352v39.253334h236.373333z m136.533333 78.933333V334.933333l-157.866666-157.866666H273.066667A59.306667 59.306667 0 0 0 213.333333 236.373333v551.253334a59.306667 59.306667 0 0 0 59.306667 59.306666h274.773333v42.666667H853.333333v-180.48zM568.746667 234.666667l100.266666 100.693333h-81.066666a20.053333 20.053333 0 0 1-19.626667-20.053333z m-20.48 573.013333H273.066667a19.2 19.2 0 0 1-17.493334-19.626667V236.373333a19.2 19.2 0 0 1 19.626667-19.626666h256v98.133333a58.88 58.88 0 0 0 58.88 59.306667h96.426667v334.933333h-98.133334v-39.68H352v39.68h196.266667z m100.266666 23.04a37.973333 37.973333 0 0 1-32 15.786667 38.826667 38.826667 0 0 1-32.426666-15.786667 53.76 53.76 0 0 1-10.24-32.853333 42.666667 42.666667 0 0 1 42.666666-47.786667 35.84 35.84 0 0 1 37.546667 29.866667h-12.8a23.893333 23.893333 0 0 0-24.746667-19.2c-17.066667 0-29.013333 14.08-29.013333 35.84s11.52 37.546667 28.586667 37.546666a26.453333 26.453333 0 0 0 26.453333-25.6h12.8a39.253333 39.253333 0 0 1-7.253333 22.186667z m59.733334 15.786667a35.84 35.84 0 0 1-40.106667-34.56H682.666667a23.893333 23.893333 0 0 0 26.88 23.04c12.8 0 22.613333-6.4 22.613333-15.786667s-4.266667-11.52-14.506667-13.653333l-21.333333-5.12c-17.066667-4.266667-24.32-11.52-24.32-23.893334s12.8-26.453333 34.133333-26.453333a31.573333 31.573333 0 0 1 35.413334 30.293333h-13.653334a19.626667 19.626667 0 0 0-22.613333-18.773333c-12.8 0-20.48 5.12-20.48 12.8s5.12 11.093333 17.066667 13.653333l14.933333 2.986667a42.666667 42.666667 0 0 1 20.906667 8.96 23.893333 23.893333 0 0 1 7.68 17.92c-0.426667 17.066667-14.506667 28.16-37.12 28.16z m88.746666 0h-14.506666l-32.426667-92.16h14.08l19.626667 59.733333 6.4 20.053333c0-9.386667 3.413333-12.8 5.546666-20.053333l19.2-59.733333h14.08z',
|
||||||
|
onclick: e => {
|
||||||
|
// console.log("🚀 ~ init ~ echartsData.value:", echartsData.value.options.series.map(item => item.data))
|
||||||
|
|
||||||
|
let list = echartsData.value.options.series?.map((item: any) => item.data)
|
||||||
|
let dataList = list[0]?.map((item: any, index: any) => {
|
||||||
|
let value = [item[0], item[1]]
|
||||||
|
list.forEach((item1: any, index1: any) => {
|
||||||
|
if (index1 > 0) {
|
||||||
|
value.push(item1 && item1[index] ? item1[index][1] : null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return value
|
||||||
|
})
|
||||||
|
exportCSV(
|
||||||
|
echartsData.value.options.series.map((item: any) => item.name),
|
||||||
|
dataList,
|
||||||
|
'历史趋势.csv'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
series: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log("🚀 ~ unitList.forEach ~ unitList:", unitList)
|
||||||
|
|
||||||
|
if (chartsList.value.length > 0) {
|
||||||
|
let yData: any = []
|
||||||
|
echartsData.value.yAxis = []
|
||||||
|
let setList = [...new Set(unitList)]
|
||||||
|
|
||||||
|
setList.forEach((item: any, index: any) => {
|
||||||
|
if (index > 2) {
|
||||||
|
echartsData.value.grid.right = (index - 1) * 80
|
||||||
|
}
|
||||||
|
yData.push([])
|
||||||
|
let right = {
|
||||||
|
position: 'right',
|
||||||
|
offset: (index - 1) * 80
|
||||||
|
}
|
||||||
|
// console.log("🚀 ~ unitList.forEach ~ right.index:", index)
|
||||||
|
echartsData.value.yAxis.push({
|
||||||
|
name: item,
|
||||||
|
yAxisIndex: index,
|
||||||
|
splitNumber: 5,
|
||||||
|
minInterval: 1,
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
...(index > 0 ? right : null)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// console.log("🚀 ~ result.forEach ~ result:", result)
|
||||||
|
// '电压负序分量', '电压正序分量', '电压零序分量'
|
||||||
|
let ABCName = [
|
||||||
|
...new Set(
|
||||||
|
chartsList.value.map((item: any) => {
|
||||||
|
return item.anotherName == '电压负序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: item.anotherName == '电压正序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: item.anotherName == '电压零序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: item.anotherName
|
||||||
|
})
|
||||||
|
)
|
||||||
|
]
|
||||||
|
// console.log("🚀 ~ .then ~ ABCName:", ABCName)
|
||||||
|
result.forEach((item: any, index: any) => {
|
||||||
|
let yMethodList: any = []
|
||||||
|
|
||||||
|
let ABCList = Object.values(
|
||||||
|
item.reduce((acc, item) => {
|
||||||
|
let key = ''
|
||||||
|
if (item.phase == null) {
|
||||||
|
key = item.anotherName
|
||||||
|
} else {
|
||||||
|
key = item.phase
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!acc[key]) {
|
||||||
|
acc[key] = []
|
||||||
|
}
|
||||||
|
acc[key].push(item)
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
)
|
||||||
|
// console.log("🚀 ~ ABCList.forEach ~ ABCList:", ABCList)
|
||||||
|
|
||||||
|
ABCList.forEach((kk: any) => {
|
||||||
|
let colorName = kk[0].phase?.charAt(0).toUpperCase()
|
||||||
|
let lineS = ABCName.findIndex(
|
||||||
|
item =>
|
||||||
|
item ===
|
||||||
|
(kk[0].anotherName == '电压负序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: kk[0].anotherName == '电压正序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: kk[0].anotherName == '电压零序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: kk[0].anotherName)
|
||||||
|
)
|
||||||
|
|
||||||
|
let seriesList: any = []
|
||||||
|
kk.forEach((cc: any) => {
|
||||||
|
if (cc.statisticalData !== null) {
|
||||||
|
yData[setList.indexOf(kk[0].unit)].push(cc.statisticalData?.toFixed(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
seriesList.push([cc.time, cc.statisticalData?.toFixed(2), cc.unit, lineStyle[lineS].type])
|
||||||
|
})
|
||||||
|
// console.log(kk);
|
||||||
|
|
||||||
|
echartsData.value.options.series.push({
|
||||||
|
name: kk[0].phase ? kk[0].phase + '相' + kk[0].anotherName : kk[0].anotherName,
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
color:
|
||||||
|
colorName == 'A' ? '#DAA520' : colorName == 'B' ? '#2E8B57' : colorName == 'C' ? '#A52a2a' : '',
|
||||||
|
symbol: 'none',
|
||||||
|
// data: seriesList,
|
||||||
|
data: timeControl.value ? completeTimeSeries(seriesList) : seriesList,
|
||||||
|
lineStyle: lineStyle[lineS],
|
||||||
|
yAxisIndex: setList.indexOf(kk[0].unit)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
yData.forEach((item: any, index: any) => {
|
||||||
|
let [min, max] = yMethod(item)
|
||||||
|
echartsData.value.yAxis[index].min = min
|
||||||
|
echartsData.value.yAxis[index].max = max
|
||||||
|
})
|
||||||
|
// console.log("🚀 ~ result.forEach ~ echartsData.value:", echartsData.value)
|
||||||
|
}
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
const setTimeControl = () => {
|
||||||
|
timeControl.value = !timeControl.value
|
||||||
|
setEchart()
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectChange = (flag: boolean, height: any) => {
|
||||||
|
|
||||||
|
pageHeight.value = mainHeight(height * 1.6, 1.6)
|
||||||
|
}
|
||||||
|
//导出
|
||||||
|
const historyChart = ref()
|
||||||
|
|
||||||
|
const countData: any = ref([])
|
||||||
|
const countDataCopy: any = ref([])
|
||||||
|
|
||||||
|
//根据选择的指标处理谐波次数
|
||||||
|
const formatCountOptions = () => {
|
||||||
|
countData.value = []
|
||||||
|
if (searchForm.value.index.length != 0) {
|
||||||
|
searchForm.value.index.forEach((item: any, index: any) => {
|
||||||
|
countDataCopy.value.forEach((vv: any, vvs: any) => {
|
||||||
|
if (vv.index == item) {
|
||||||
|
countData.value.push(vv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
countData.value.map((item: any, key: any) => {
|
||||||
|
if (item.name == '谐波电流有效值') {
|
||||||
|
item.name = '谐波电流次数'
|
||||||
|
} else if (item.name == '谐波电压含有率') {
|
||||||
|
item.name = '谐波电压次数'
|
||||||
|
} else if (item.name == '间谐波电压含有率') {
|
||||||
|
item.name = '间谐波电压次数'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// setTimeout(() => {
|
||||||
|
// tableHeaderRef.value.computedSearchRow()
|
||||||
|
// }, 500)
|
||||||
|
}
|
||||||
|
// 判断下拉框是否存在
|
||||||
|
const onCountChange = (val: any, index: any) => {
|
||||||
|
if (val.length == 0) {
|
||||||
|
countData.value[index].count = countData.value[index].countOptions[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const flag = ref(true)
|
||||||
|
const onIndexChange = (val: any) => {
|
||||||
|
num.value += 1
|
||||||
|
let pp: any = []
|
||||||
|
indexOptions.value.forEach((item: any) => {
|
||||||
|
const filteredResult = val.filter(vv => item.id == vv)
|
||||||
|
if (filteredResult.length > 0) {
|
||||||
|
pp.push(filteredResult[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
searchForm.value.index = pp
|
||||||
|
flag.value = true
|
||||||
|
formatCountOptions()
|
||||||
|
}
|
||||||
|
watch(
|
||||||
|
() => searchForm.value.index,
|
||||||
|
(val: any, oldval: any) => {},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const openDialog = async (row: any, field: any, title: any) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
trendRequestData.value = row
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
// 默认当天
|
||||||
|
datePickerRef.value.setInterval(5)
|
||||||
|
datePickerRef.value.timeValue = [row.time, row.time]
|
||||||
|
initCode(field, title)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ getTrendRequest, openDialog })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.history_header {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
// flex-wrap: wrap;
|
||||||
|
#history_select {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
// justify-content: flex-start;
|
||||||
|
// overflow-x: auto;
|
||||||
|
height: auto;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
flex: none !important;
|
||||||
|
// max-width: 380px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-select {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #history_select::-webkit-scrollbar {
|
||||||
|
// width: 0 !important;
|
||||||
|
// display: none !important;
|
||||||
|
// }
|
||||||
|
|
||||||
|
.history_searchBtn {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.history_chart {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
// flex: 1;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history_count {
|
||||||
|
.el-select {
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- 指标越限详情 -->
|
||||||
|
<el-dialog draggable title="指标越限详情" v-model="dialogVisible" append-to-body width="70%">
|
||||||
|
<TableHeader datePicker showExport :showReset="false" ref="tableHeaderRef">
|
||||||
|
<template v-slot:select>
|
||||||
|
<el-form-item label="监测点">
|
||||||
|
<el-select
|
||||||
|
v-model="tableStore.table.params.lineId"
|
||||||
|
placeholder="请选择监测点"
|
||||||
|
style="width: 150px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in options"
|
||||||
|
:key="item.lineId"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.lineId"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</TableHeader>
|
||||||
|
<Table ref="tableRef" @cell-click="cellClickEvent" isGroup :height="height"></Table>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 谐波电流、谐波电压占有率 -->
|
||||||
|
<HarmonicRatio
|
||||||
|
ref="harmonicRatioRef"
|
||||||
|
@close="onHarmonicRatioClose"
|
||||||
|
v-if="dialogFlag"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, provide,nextTick } from 'vue'
|
||||||
|
import Table from '@/components/table/index.vue'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import TableStore from '@/utils/tableStore'
|
||||||
|
import { mainHeight } from '@/utils/layout'
|
||||||
|
import HarmonicRatio from '@/components/cockpit/indicatorFittingChart/components/harmonicRatio.vue'
|
||||||
|
import { cslineList } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
|
|
||||||
|
const dialogVisible: any = ref(false)
|
||||||
|
const harmonicRatioRef: any = ref(null)
|
||||||
|
|
||||||
|
const dialogFlag = ref(false)
|
||||||
|
|
||||||
|
const options = ref()
|
||||||
|
const height = mainHeight(0, 2).height as any
|
||||||
|
const tableHeaderRef = ref()
|
||||||
|
const loop50 = (key: string) => {
|
||||||
|
let list: any[] = []
|
||||||
|
for (let i = 2; i < 26; i++) {
|
||||||
|
list.push({
|
||||||
|
title: i + '次',
|
||||||
|
field: key + i + 'Overtime',
|
||||||
|
width: '80',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
const tableStore: any = new TableStore({
|
||||||
|
url: '/harmonic-boot/mainLine/statLimitRateDetails',
|
||||||
|
method: 'POST',
|
||||||
|
publicHeight: 30,
|
||||||
|
showPage: false,
|
||||||
|
exportName: '主要监测点列表',
|
||||||
|
column: [
|
||||||
|
{
|
||||||
|
field: 'index',
|
||||||
|
title: '序号',
|
||||||
|
width: '80',
|
||||||
|
formatter: (row: any) => {
|
||||||
|
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '日期',
|
||||||
|
field: 'time',
|
||||||
|
width: '150',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
field: 'lineName',
|
||||||
|
width: '150'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '闪变越限(分钟)',
|
||||||
|
field: 'flickerOvertime',
|
||||||
|
width: '80',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '谐波电压越限(分钟)',
|
||||||
|
children: loop50('uharm')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '谐波电流越限(分钟)',
|
||||||
|
children: loop50('iharm')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '三相不平衡度越限(分钟)',
|
||||||
|
field: 'ubalanceOvertime',
|
||||||
|
width: '100',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '电压偏差越限(分钟)',
|
||||||
|
field: 'uaberranceOvertime',
|
||||||
|
width: '100',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '频率偏差越限(分钟)',
|
||||||
|
field: 'freqDevOvertime',
|
||||||
|
width: '100',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
beforeSearchFun: () => {
|
||||||
|
},
|
||||||
|
loadCallback: () => {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
provide('tableStore', tableStore)
|
||||||
|
tableStore.table.params.sortBy = ''
|
||||||
|
tableStore.table.params.orderBy = ''
|
||||||
|
const open = async (row: any,searchBeginTime:any,searchEndTime:any) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
initCSlineList()
|
||||||
|
tableStore.table.params.lineId = row.lineId
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
tableHeaderRef.value.setTimeInterval([searchBeginTime, searchEndTime])
|
||||||
|
tableStore.table.params.searchBeginTime =searchBeginTime
|
||||||
|
tableStore.table.params.searchEndTime = searchEndTime
|
||||||
|
tableStore.index()
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击行
|
||||||
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
|
if (column.field != 'name' && column.field != 'time') {
|
||||||
|
dialogFlag.value = true
|
||||||
|
dialogVisible.value = false
|
||||||
|
nextTick(() => {
|
||||||
|
harmonicRatioRef.value.openDialog(row,column.field,column.title.replace(/次/g, ""))
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 谐波弹窗关闭时的回调
|
||||||
|
const onHarmonicRatioClose = () => {
|
||||||
|
dialogFlag.value = false
|
||||||
|
// 重新打开指标越限详情弹窗
|
||||||
|
nextTick(() => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const initCSlineList = async () => {
|
||||||
|
const res = await cslineList({})
|
||||||
|
options.value = res.data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@@ -1,41 +1,75 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--主要监测点列表 -->
|
<!--主要监测点列表 -->
|
||||||
<TableHeader :showReset="false" >
|
<TableHeader :showReset="false" @selectChange="selectChange" v-if="fullscreen" datePicker ref="tableHeaderRef">
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="关键词">
|
<el-form-item label="关键词">
|
||||||
<el-input v-model="tableStore.table.params.searchValue" clearable placeholder="请输关键字" />
|
<el-input v-model="tableStore.table.params.keywords" clearable placeholder="请输关键字" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<Table ref="tableRef" @cell-click="cellClickEvent" :height="`calc(${prop.height} - 58px)`"></Table>
|
<Table
|
||||||
|
ref="tableRef"
|
||||||
|
@cell-click="cellClickEvent"
|
||||||
|
:height="`calc(${prop.height} - ${headerHeight}px + ${fullscreen ? -58 : 56}px )`"
|
||||||
|
></Table>
|
||||||
<!-- 指标越限详情 -->
|
<!-- 指标越限详情 -->
|
||||||
<OverLimitDetails ref="OverLimitDetailsRef" />
|
<OverLimitDetails ref="OverLimitDetailsRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch, nextTick } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import { useDictData } from '@/stores/dictData'
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
import { ElTag } from 'element-plus'
|
import OverLimitDetails from '@/components/cockpit/indicatorFittingChart/components/overLimitDetails.vue'
|
||||||
import OverLimitDetails from '@/components/cockpit/listOfMainMonitoringPoints/components/overLimitDetails.vue'
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
|
import { log } from 'console'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: String },
|
w: { type: [String, Number] },
|
||||||
height: { type: String },
|
h: { type: [String, Number] },
|
||||||
timeKey: { type: String },
|
width: { type: [String, Number] },
|
||||||
|
height: { type: [String, Number] },
|
||||||
|
timeKey: { type: [String, Number] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
const dictData = useDictData()
|
|
||||||
const OverLimitDetailsRef = ref()
|
const OverLimitDetailsRef = ref()
|
||||||
const tableStore: any = new TableStore({
|
const headerHeight = ref(57)
|
||||||
url: '/user-boot/role/selectRoleDetail?id=0',
|
|
||||||
method: 'POST',
|
|
||||||
|
|
||||||
showPage: false,
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
|
|
||||||
|
const tableHeaderRef = ref()
|
||||||
|
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
|
headerHeight.value = height
|
||||||
|
|
||||||
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
|
// 更新时间参数
|
||||||
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const tableStore: any = new TableStore({
|
||||||
|
url: '/harmonic-boot/mainLine/list',
|
||||||
|
method: 'POST',
|
||||||
|
showPage: fullscreen.value ? true : false,
|
||||||
exportName: '主要监测点列表',
|
exportName: '主要监测点列表',
|
||||||
column: [
|
column: [
|
||||||
{
|
{
|
||||||
@@ -48,79 +82,53 @@ const tableStore: any = new TableStore({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '监测点名称',
|
title: '监测点名称',
|
||||||
field: 'name',
|
field: 'lineName',
|
||||||
minWidth: '90',
|
minWidth: '90',
|
||||||
|
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.name}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.lineName}</span>`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: '监测对象类型',
|
title: '监测对象类型',
|
||||||
field: 'type',
|
field: 'objType',
|
||||||
minWidth: '90'
|
minWidth: '90'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '是否治理',
|
title: '是否治理',
|
||||||
field: 'whetherToGovern',
|
field: 'govern',
|
||||||
minWidth: '70'
|
minWidth: '70'
|
||||||
},
|
},
|
||||||
|
|
||||||
{ title: '主要存在的电能质量问题', field: 'question', minWidth: '150' }
|
{ title: '主要存在的电能质量问题', field: 'problems', minWidth: '150', showOverflow: true }
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
|
|
||||||
tableStore.table.data = [
|
|
||||||
{
|
|
||||||
name: '10kV1#电动机',
|
|
||||||
type: '电动机',
|
|
||||||
whetherToGovern: '否',
|
|
||||||
question: '3次谐波电压、5次谐波电流、电压不平衡度超标'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '10kV2#(治理后)',
|
|
||||||
type: '电焊机',
|
|
||||||
whetherToGovern: '100A APF',
|
|
||||||
question: '所有指标均合格'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '380V电焊机(治理前)',
|
|
||||||
type: '电焊机',
|
|
||||||
whetherToGovern: '100A APF',
|
|
||||||
question: '5次谐波电流、电压不平衡度超标'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '380V水泵机',
|
|
||||||
type: '电动机',
|
|
||||||
whetherToGovern: '否',
|
|
||||||
question: '所有指标均合格'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
tableStore.table.height = `calc(${prop.height} - 80px)`
|
tableStore.table.height = `calc(${prop.height} - 80px)`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const tableRef = ref()
|
const tableRef = ref()
|
||||||
provide('tableRef', tableRef)
|
provide('tableRef', tableRef)
|
||||||
tableStore.table.params.type = ''
|
tableStore.table.params.keywords = ''
|
||||||
tableStore.table.params.searchValue = ''
|
|
||||||
provide('tableStore', tableStore)
|
provide('tableStore', tableStore)
|
||||||
|
|
||||||
// 点击行
|
// 点击行
|
||||||
const cellClickEvent = ({ row, column }: any) => {
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
if (column.field == 'name') {
|
if (column.field == 'lineName') {
|
||||||
console.log(row)
|
OverLimitDetailsRef.value.open(
|
||||||
OverLimitDetailsRef.value.open(row)
|
row,
|
||||||
|
tableStore.table.params.searchBeginTime || prop.timeValue?.[0],
|
||||||
|
tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 在组件挂载时设置缓存值到 DatePicker
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
})
|
})
|
||||||
@@ -131,12 +139,17 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -7,27 +7,70 @@
|
|||||||
<el-select
|
<el-select
|
||||||
v-model="tableStore.table.params.searchValue"
|
v-model="tableStore.table.params.searchValue"
|
||||||
placeholder="请选择谐波次数"
|
placeholder="请选择谐波次数"
|
||||||
style="width: 240px"
|
style="width: 150px"
|
||||||
>
|
>
|
||||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
<el-option
|
||||||
|
v-for="item in harmonicOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="指标类型">
|
<el-form-item label="指标类型" v-show="!tableStore.table.params.checked">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="tableStore.table.params.searchValue"
|
v-model="tableStore.table.params.indicatorType"
|
||||||
placeholder="请选择指标类型"
|
placeholder="请选择指标类型"
|
||||||
style="width: 240px"
|
style="width: 150px"
|
||||||
>
|
>
|
||||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
<el-option
|
||||||
|
v-for="item in indicatorList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="指标类型1" v-show="tableStore.table.params.checked == true">
|
||||||
|
<el-select
|
||||||
|
v-model="tableStore.table.params.indicatorType1"
|
||||||
|
placeholder="请选择指标类型1"
|
||||||
|
style="width: 150px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in indicatorList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="指标类型2" v-show="tableStore.table.params.checked == true">
|
||||||
|
<el-select
|
||||||
|
v-model="tableStore.table.params.indicatorType2"
|
||||||
|
placeholder="请选择指标类型2"
|
||||||
|
style="width: 150px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in indicatorList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-checkbox v-model="tableStore.table.params.checked">指标对比分析</el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<my-echart
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
|
v-if="!tableStore.table.params.checked"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
style="width: 98%; height: 320px"
|
style="width: 98%; height: 320px"
|
||||||
/>
|
/>
|
||||||
|
<my-echart class="tall" v-else :options="echartContrastList" style="width: 98%; height: 320px" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -39,9 +82,9 @@ import { getTimeOfTheMonth } from '@/utils/formatTime'
|
|||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: String },
|
width: { type: [String, Number]},
|
||||||
height: { type: String },
|
height: { type: [String, Number]},
|
||||||
timeKey: { type: String },
|
timeKey: { type: [String, Number]},
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -55,16 +98,12 @@ const options = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
const powerList: any = ref([
|
|
||||||
{
|
const harmonicOptions = Array.from({ length: 50 }, (_, i) => ({
|
||||||
label: '三相总有功功率',
|
value: String(i + 1),
|
||||||
value: '1'
|
label: `${i + 1}次谐波`
|
||||||
},
|
}))
|
||||||
{
|
|
||||||
label: '三相总无功功率',
|
|
||||||
value: '2'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
const exceedingTheLimitList: any = ref([
|
const exceedingTheLimitList: any = ref([
|
||||||
{
|
{
|
||||||
label: '越限',
|
label: '越限',
|
||||||
@@ -95,9 +134,8 @@ const indicatorList: any = ref([
|
|||||||
])
|
])
|
||||||
const echartList = ref({
|
const echartList = ref({
|
||||||
title: {
|
title: {
|
||||||
text: '35kV进线谐波含有率',
|
text: '谐波电压含有率'
|
||||||
},
|
},
|
||||||
|
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'time',
|
type: 'time',
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
@@ -108,7 +146,6 @@ const echartList = ref({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
yAxis: [{}, {}],
|
yAxis: [{}, {}],
|
||||||
grid: {
|
grid: {
|
||||||
left: '10px',
|
left: '10px',
|
||||||
@@ -117,51 +154,171 @@ const echartList = ref({
|
|||||||
options: {
|
options: {
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
// name: '暂降次数',
|
name: 'A相',
|
||||||
type: 'bar',
|
type: 'line',
|
||||||
name: '有功功率',
|
showSymbol: false,
|
||||||
|
smooth: true,
|
||||||
data: [
|
data: [
|
||||||
['2025-10-16 07:00:00', 10],
|
['2025-10-16 07:00:00', 0.5],
|
||||||
['2025-10-16 07:15:00', 10],
|
['2025-10-16 07:15:00', 0.6],
|
||||||
['2025-10-16 07:30:00', 10],
|
['2025-10-16 07:30:00', 0.4],
|
||||||
['2025-10-16 07:45:00', 10],
|
['2025-10-16 07:45:00', 0.7],
|
||||||
['2025-10-16 08:00:00', 30],
|
['2025-10-16 08:00:00', 1.2],
|
||||||
['2025-10-16 08:15:00', 50],
|
['2025-10-16 08:15:00', 1.5],
|
||||||
['2025-10-16 08:30:00', 60],
|
['2025-10-16 08:30:00', 1.8],
|
||||||
['2025-10-16 08:45:00', 70],
|
['2025-10-16 08:45:00', 2.1],
|
||||||
['2025-10-16 09:00:00', 100],
|
['2025-10-16 09:00:00', 2.5],
|
||||||
['2025-10-16 09:15:00', 120],
|
['2025-10-16 09:15:00', 2.8],
|
||||||
['2025-10-16 09:30:00', 130],
|
['2025-10-16 09:30:00', 3.0],
|
||||||
['2025-10-16 09:45:00', 140],
|
['2025-10-16 09:45:00', 2.7],
|
||||||
['2025-10-16 10:00:00', 160],
|
['2025-10-16 10:00:00', 2.2],
|
||||||
['2025-10-16 10:15:00', 160],
|
['2025-10-16 10:15:00', 1.9],
|
||||||
['2025-10-16 10:30:00', 130],
|
['2025-10-16 10:30:00', 1.6],
|
||||||
['2025-10-16 10:45:00', 120],
|
['2025-10-16 10:45:00', 1.3],
|
||||||
['2025-10-16 11:00:00', 140],
|
['2025-10-16 11:00:00', 1.1],
|
||||||
['2025-10-16 11:15:00', 80],
|
['2025-10-16 11:15:00', 0.8],
|
||||||
['2025-10-16 11:30:00', 70],
|
['2025-10-16 11:30:00', 0.6],
|
||||||
['2025-10-16 11:45:00', 90],
|
['2025-10-16 11:45:00', 0.4],
|
||||||
['2025-10-16 12:00:00', 60],
|
['2025-10-16 12:00:00', 0.3],
|
||||||
['2025-10-16 12:15:00', 60],
|
['2025-10-16 12:15:00', 0.2],
|
||||||
['2025-10-16 12:30:00', 60],
|
['2025-10-16 12:30:00', 0.3],
|
||||||
['2025-10-16 12:45:00', 60]
|
['2025-10-16 12:45:00', 0.4]
|
||||||
],
|
],
|
||||||
itemStyle: {
|
|
||||||
normal: {
|
|
||||||
//这里是颜色
|
|
||||||
color: function (params: any) {
|
|
||||||
if (params.value[1] == 0 || params.value[1] == 3.14159) {
|
|
||||||
return '#ccc'
|
|
||||||
} else {
|
|
||||||
return config.layout.elementUiPrimary[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
yAxisIndex: 0
|
yAxisIndex: 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '谐波总畸变率',
|
name: 'B相',
|
||||||
|
type: 'line',
|
||||||
|
showSymbol: false,
|
||||||
|
smooth: true,
|
||||||
|
data: [
|
||||||
|
['2025-10-16 07:00:00', 0.4],
|
||||||
|
['2025-10-16 07:15:00', 0.5],
|
||||||
|
['2025-10-16 07:30:00', 0.3],
|
||||||
|
['2025-10-16 07:45:00', 0.6],
|
||||||
|
['2025-10-16 08:00:00', 1.0],
|
||||||
|
['2025-10-16 08:15:00', 1.3],
|
||||||
|
['2025-10-16 08:30:00', 1.6],
|
||||||
|
['2025-10-16 08:45:00', 1.9],
|
||||||
|
['2025-10-16 09:00:00', 2.2],
|
||||||
|
['2025-10-16 09:15:00', 2.5],
|
||||||
|
['2025-10-16 09:30:00', 2.7],
|
||||||
|
['2025-10-16 09:45:00', 2.4],
|
||||||
|
['2025-10-16 10:00:00', 2.0],
|
||||||
|
['2025-10-16 10:15:00', 1.7],
|
||||||
|
['2025-10-16 10:30:00', 1.4],
|
||||||
|
['2025-10-16 10:45:00', 1.1],
|
||||||
|
['2025-10-16 11:00:00', 0.9],
|
||||||
|
['2025-10-16 11:15:00', 0.7],
|
||||||
|
['2025-10-16 11:30:00', 0.5],
|
||||||
|
['2025-10-16 11:45:00', 0.3],
|
||||||
|
['2025-10-16 12:00:00', 0.2],
|
||||||
|
['2025-10-16 12:15:00', 0.1],
|
||||||
|
['2025-10-16 12:30:00', 0.2],
|
||||||
|
['2025-10-16 12:45:00', 0.3]
|
||||||
|
],
|
||||||
|
yAxisIndex: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'C相',
|
||||||
|
type: 'line',
|
||||||
|
showSymbol: false,
|
||||||
|
smooth: true,
|
||||||
|
data: [
|
||||||
|
['2025-10-16 07:00:00', 0.6],
|
||||||
|
['2025-10-16 07:15:00', 0.7],
|
||||||
|
['2025-10-16 07:30:00', 0.5],
|
||||||
|
['2025-10-16 07:45:00', 0.8],
|
||||||
|
['2025-10-16 08:00:00', 1.4],
|
||||||
|
['2025-10-16 08:15:00', 1.7],
|
||||||
|
['2025-10-16 08:30:00', 2.0],
|
||||||
|
['2025-10-16 08:45:00', 2.3],
|
||||||
|
['2025-10-16 09:00:00', 2.8],
|
||||||
|
['2025-10-16 09:15:00', 3.1],
|
||||||
|
['2025-10-16 09:30:00', 3.3],
|
||||||
|
['2025-10-16 09:45:00', 3.0],
|
||||||
|
['2025-10-16 10:00:00', 2.5],
|
||||||
|
['2025-10-16 10:15:00', 2.1],
|
||||||
|
['2025-10-16 10:30:00', 1.8],
|
||||||
|
['2025-10-16 10:45:00', 1.5],
|
||||||
|
['2025-10-16 11:00:00', 1.3],
|
||||||
|
['2025-10-16 11:15:00', 1.0],
|
||||||
|
['2025-10-16 11:30:00', 0.8],
|
||||||
|
['2025-10-16 11:45:00', 0.6],
|
||||||
|
['2025-10-16 12:00:00', 0.5],
|
||||||
|
['2025-10-16 12:15:00', 0.4],
|
||||||
|
['2025-10-16 12:30:00', 0.5],
|
||||||
|
['2025-10-16 12:45:00', 0.6]
|
||||||
|
],
|
||||||
|
yAxisIndex: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '暂降触发点',
|
||||||
|
type: 'line',
|
||||||
|
showSymbol: false,
|
||||||
|
smooth: true,
|
||||||
|
data: [
|
||||||
|
['2025-10-16 07:00:00', 3.14159],
|
||||||
|
['2025-10-16 07:15:00', 3.14159],
|
||||||
|
['2025-10-16 07:30:00', 3.14159],
|
||||||
|
['2025-10-16 07:45:00', 3.14159],
|
||||||
|
['2025-10-16 08:00:00', 3.14159],
|
||||||
|
['2025-10-16 08:15:00', 3.14159],
|
||||||
|
['2025-10-16 08:30:00', 3.14159],
|
||||||
|
['2025-10-16 08:45:00', 3.14159],
|
||||||
|
['2025-10-16 09:00:00', 3.14159],
|
||||||
|
['2025-10-16 09:15:00', 3.14159],
|
||||||
|
['2025-10-16 09:30:00', 3.14159],
|
||||||
|
['2025-10-16 09:45:00', 3.14159],
|
||||||
|
['2025-10-16 10:00:00', 3.14159],
|
||||||
|
['2025-10-16 10:15:00', 3.14159],
|
||||||
|
['2025-10-16 10:30:00', 3.14159],
|
||||||
|
['2025-10-16 10:45:00', 3.14159],
|
||||||
|
['2025-10-16 11:00:00', 3.14159],
|
||||||
|
['2025-10-16 11:15:00', 3.14159],
|
||||||
|
['2025-10-16 11:30:00', 3.14159],
|
||||||
|
['2025-10-16 11:45:00', 3.14159],
|
||||||
|
['2025-10-16 12:00:00', 3.14159],
|
||||||
|
['2025-10-16 12:15:00', 3.14159],
|
||||||
|
['2025-10-16 12:30:00', 3.14159],
|
||||||
|
['2025-10-16 12:45:00', 3.14159]
|
||||||
|
],
|
||||||
|
lineStyle: {
|
||||||
|
type: 'dashed',
|
||||||
|
color: '#ff0000' // 红色
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: '#ff0000' // 红色
|
||||||
|
},
|
||||||
|
yAxisIndex: 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const echartContrastList = ref({
|
||||||
|
title: {
|
||||||
|
text: 'A相谐波电压和A相谐波电流对比趋势图'
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'time',
|
||||||
|
axisLabel: {
|
||||||
|
formatter: {
|
||||||
|
day: '{MM}-{dd}',
|
||||||
|
month: '{MM}',
|
||||||
|
year: '{yyyy}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: [{}, {}],
|
||||||
|
grid: {
|
||||||
|
left: '10px',
|
||||||
|
right: '20px'
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: 'A相谐波电压',
|
||||||
type: 'line',
|
type: 'line',
|
||||||
showSymbol: false,
|
showSymbol: false,
|
||||||
smooth: true,
|
smooth: true,
|
||||||
@@ -191,11 +348,45 @@ const echartList = ref({
|
|||||||
['2025-10-16 12:30:00', 0],
|
['2025-10-16 12:30:00', 0],
|
||||||
['2025-10-16 12:45:00', 0]
|
['2025-10-16 12:45:00', 0]
|
||||||
],
|
],
|
||||||
|
yAxisIndex: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'A相谐波电流',
|
||||||
|
type: 'line',
|
||||||
|
showSymbol: false,
|
||||||
|
smooth: true,
|
||||||
|
data: [
|
||||||
|
['2025-10-16 07:00:00', 0],
|
||||||
|
['2025-10-16 07:15:00', 0],
|
||||||
|
['2025-10-16 07:30:00', 0],
|
||||||
|
['2025-10-16 07:45:00', 0],
|
||||||
|
['2025-10-16 08:00:00', 0],
|
||||||
|
['2025-10-16 08:15:00', 0.05],
|
||||||
|
['2025-10-16 08:30:00', 0.05],
|
||||||
|
['2025-10-16 08:45:00', 0.05],
|
||||||
|
['2025-10-16 09:00:00', 0.5],
|
||||||
|
['2025-10-16 09:15:00', 0.5],
|
||||||
|
['2025-10-16 09:30:00', 0.5],
|
||||||
|
['2025-10-16 09:45:00', 0.5],
|
||||||
|
['2025-10-16 10:00:00', 0.4],
|
||||||
|
['2025-10-16 10:15:00', 0.4],
|
||||||
|
['2025-10-16 10:30:00', 0.4],
|
||||||
|
['2025-10-16 10:45:00', 0.4],
|
||||||
|
['2025-10-16 11:00:00', 0.4],
|
||||||
|
['2025-10-16 11:15:00', 0.05],
|
||||||
|
['2025-10-16 11:30:00', 0.05],
|
||||||
|
['2025-10-16 11:45:00', 0.05],
|
||||||
|
['2025-10-16 12:00:00', 0],
|
||||||
|
['2025-10-16 12:15:00', 0],
|
||||||
|
['2025-10-16 12:30:00', 0],
|
||||||
|
['2025-10-16 12:45:00', 0]
|
||||||
|
],
|
||||||
yAxisIndex: 1
|
yAxisIndex: 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
const selectChange = (showSelect: any, height: any) => {
|
const selectChange = (showSelect: any, height: any) => {
|
||||||
headerHeight.value = height
|
headerHeight.value = height
|
||||||
@@ -219,6 +410,10 @@ tableStore.table.params.power = '1'
|
|||||||
tableStore.table.params.indicator = '1'
|
tableStore.table.params.indicator = '1'
|
||||||
tableStore.table.params.exceedingTheLimit = '1'
|
tableStore.table.params.exceedingTheLimit = '1'
|
||||||
tableStore.table.params.searchValue = ''
|
tableStore.table.params.searchValue = ''
|
||||||
|
tableStore.table.params.checked = false
|
||||||
|
tableStore.table.params.indicatorType = '' // 指标类型
|
||||||
|
tableStore.table.params.indicatorType1 = '' // 指标类型1
|
||||||
|
tableStore.table.params.indicatorType2 = '' // 指标类型2
|
||||||
provide('tableStore', tableStore)
|
provide('tableStore', tableStore)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@@ -0,0 +1,134 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 综合评估详情 -->
|
||||||
|
<el-dialog draggable title="指标合格率统计" v-model="dialogVisible" append-to-body width="70%">
|
||||||
|
<TableHeader datePicker showExport :showReset="false">
|
||||||
|
<template v-slot:select>
|
||||||
|
<el-form-item label="监测点名称">
|
||||||
|
<el-select
|
||||||
|
v-model="tableStore.table.params.searchValue"
|
||||||
|
placeholder="请选择监测点名称"
|
||||||
|
style="width: 240px"
|
||||||
|
>
|
||||||
|
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</TableHeader>
|
||||||
|
<Table ref="tableRef" isGroup :height="height"></Table>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, provide } from 'vue'
|
||||||
|
import Table from '@/components/table/index.vue'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import TableStore from '@/utils/tableStore'
|
||||||
|
import { mainHeight } from '@/utils/layout'
|
||||||
|
const dialogVisible: any = ref(false)
|
||||||
|
const options = [
|
||||||
|
{
|
||||||
|
value: '35kV进线',
|
||||||
|
label: '35kV进线'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const height = mainHeight(0, 2).height as any
|
||||||
|
const loop50 = (key: string) => {
|
||||||
|
let list: any[] = []
|
||||||
|
for (let i = 2; i < 51; i++) {
|
||||||
|
list.push({
|
||||||
|
title: i + '次',
|
||||||
|
// field: key + i,
|
||||||
|
field: 'flicker',
|
||||||
|
width: '80'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
const tableStore: any = new TableStore({
|
||||||
|
url: '/user-boot/role/selectRoleDetail?id=0',
|
||||||
|
method: 'POST',
|
||||||
|
publicHeight: 30,
|
||||||
|
showPage: false,
|
||||||
|
exportName: '主要监测点列表',
|
||||||
|
column: [
|
||||||
|
{
|
||||||
|
field: 'index',
|
||||||
|
title: '序号',
|
||||||
|
width: '80',
|
||||||
|
formatter: (row: any) => {
|
||||||
|
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '日期',
|
||||||
|
field: 'time',
|
||||||
|
width: '150'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
field: 'name',
|
||||||
|
width: '150'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '闪变越限(分钟)',
|
||||||
|
field: 'flicker',
|
||||||
|
width: '80'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '谐波电压越限(分钟)',
|
||||||
|
children: loop50('voltage')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '谐波电流越限(分钟)',
|
||||||
|
children: loop50('harmonicCurrent')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '三相不平衡度越限(分钟)',
|
||||||
|
field: 'flicker',
|
||||||
|
width: '100'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '电压偏差越限(分钟)',
|
||||||
|
field: 'flicker',
|
||||||
|
width: '100'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '频率偏差越限(分钟)',
|
||||||
|
field: 'flicker',
|
||||||
|
width: '100'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
beforeSearchFun: () => {},
|
||||||
|
loadCallback: () => {
|
||||||
|
tableStore.table.data = [
|
||||||
|
{
|
||||||
|
time: '2024-01-01 00:00:00',
|
||||||
|
name: '35kV进线',
|
||||||
|
flicker: '0',
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2024-01-01 00:00:00',
|
||||||
|
name: '35kV进线',
|
||||||
|
flicker: '0',
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2024-01-01 00:00:00',
|
||||||
|
name: '35kV进线',
|
||||||
|
flicker: '0',
|
||||||
|
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
tableStore.table.params.searchValue = ''
|
||||||
|
provide('tableStore', tableStore)
|
||||||
|
const open = async (row: any) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
<el-select
|
<el-select
|
||||||
v-model="tableStore.table.params.searchValue"
|
v-model="tableStore.table.params.searchValue"
|
||||||
placeholder="请选择监测点名称"
|
placeholder="请选择监测点名称"
|
||||||
style="width: 240px"
|
style="width: 150px"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in options"
|
v-for="item in options"
|
||||||
@@ -147,6 +147,7 @@ const open = async (row: any) => {
|
|||||||
|
|
||||||
// 点击行
|
// 点击行
|
||||||
const cellClickEvent = ({ row, column }: any) => {
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
|
console.log(row, '1111')
|
||||||
if (column.field != 'name' && column.field != 'time') {
|
if (column.field != 'name' && column.field != 'time') {
|
||||||
harmonicRatioRef.value.openDialog(row)
|
harmonicRatioRef.value.openDialog(row)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,21 @@
|
|||||||
<!--指标拟合图 -->
|
<!--指标拟合图 -->
|
||||||
<TableHeader :showReset="false" datePicker @selectChange="selectChange" v-if="fullscreen">
|
<TableHeader :showReset="false" datePicker @selectChange="selectChange" v-if="fullscreen">
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
|
<el-form-item label="监测点">
|
||||||
|
<el-select
|
||||||
|
v-model="tableStore.table.params.lineId"
|
||||||
|
placeholder="请选择监测点"
|
||||||
|
clearable
|
||||||
|
style="width: 130px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in lineList"
|
||||||
|
:key="item.lineId"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.lineId"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="用户功率">
|
<el-form-item label="用户功率">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="tableStore.table.params.power"
|
v-model="tableStore.table.params.power"
|
||||||
@@ -70,15 +85,25 @@ import { ElMessage, ElMessageBox } from 'element-plus'
|
|||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
|
import { cslineList } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: String },
|
w: { type: [String, Number]},
|
||||||
h: { type: String },
|
h: { type: [String, Number]},
|
||||||
width: { type: String },
|
width: { type: [String, Number]},
|
||||||
height: { type: String },
|
height: { type: [String, Number]},
|
||||||
timeKey: { type: String },
|
timeKey: { type: [String, Number]},
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
|
|
||||||
|
const lineList: any = ref()
|
||||||
|
|
||||||
const powerList: any = ref([
|
const powerList: any = ref([
|
||||||
{
|
{
|
||||||
label: '三相总有功功率',
|
label: '三相总有功功率',
|
||||||
@@ -94,6 +119,7 @@ const fullscreen = computed(() => {
|
|||||||
const w = Number(prop.w)
|
const w = Number(prop.w)
|
||||||
const h = Number(prop.h)
|
const h = Number(prop.h)
|
||||||
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
initLineList()
|
||||||
// 执行相应逻辑
|
// 执行相应逻辑
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
@@ -128,6 +154,16 @@ const indicatorList: any = ref([
|
|||||||
value: '4'
|
value: '4'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const initLineList = async () => {
|
||||||
|
cslineList({}).then(res => {
|
||||||
|
lineList.value = res.data
|
||||||
|
if (lineList.value && lineList.value.length > 0) {
|
||||||
|
tableStore.table.params.lineId = lineList.value[0].lineId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const echartList = ref({
|
const echartList = ref({
|
||||||
title: {
|
title: {
|
||||||
text: '谐波电压总畸变率越限与功率负荷曲线拟合图'
|
text: '谐波电压总畸变率越限与功率负荷曲线拟合图'
|
||||||
@@ -243,8 +279,23 @@ const tableStore: any = new TableStore({
|
|||||||
exportName: '主要监测点列表',
|
exportName: '主要监测点列表',
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
// 尝试从缓存获取时间值
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
let beginTime, endTime
|
||||||
|
|
||||||
|
if (fullscreen.value) {
|
||||||
|
const cached = timeCacheStore.getCache(route.path)
|
||||||
|
if (cached && cached.timeValue) {
|
||||||
|
beginTime = cached.timeValue[0]
|
||||||
|
endTime = cached.timeValue[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果缓存中没有则使用默认值
|
||||||
|
tableStore.table.params.searchBeginTime = beginTime || prop.timeValue?.[0]
|
||||||
|
tableStore.table.params.searchEndTime = endTime || prop.timeValue?.[1]
|
||||||
|
if (!tableStore.table.params.lineId && lineList.value && lineList.value.length > 0) {
|
||||||
|
tableStore.table.params.lineId = lineList.value[0].lineId
|
||||||
|
}
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.height = `calc(${prop.height} - 80px)`
|
tableStore.table.height = `calc(${prop.height} - 80px)`
|
||||||
|
|||||||
@@ -0,0 +1,184 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- 指标越限详情 -->
|
||||||
|
<el-dialog draggable title="指标越限详情" v-model="dialogVisible" append-to-body width="70%">
|
||||||
|
<TableHeader datePicker showExport :showReset="false" ref="tableHeaderRef">
|
||||||
|
<template v-slot:select>
|
||||||
|
<el-form-item label="监测点">
|
||||||
|
<el-select
|
||||||
|
v-model="tableStore.table.params.lineId"
|
||||||
|
placeholder="请选择监测点"
|
||||||
|
style="width: 150px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in options"
|
||||||
|
:key="item.lineId"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.lineId"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</TableHeader>
|
||||||
|
<Table ref="tableRef" @cell-click="cellClickEvent" isGroup :height="height"></Table>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 谐波电流、谐波电压占有率 -->
|
||||||
|
<HarmonicRatio ref="harmonicRatioRef" @close="onHarmonicRatioClose" :TrendList="TrendList" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, provide,nextTick } from 'vue'
|
||||||
|
import Table from '@/components/table/index.vue'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import TableStore from '@/utils/tableStore'
|
||||||
|
import { mainHeight } from '@/utils/layout'
|
||||||
|
import HarmonicRatio from '@/components/cockpit/indicatorFittingChart/components/harmonicRatio.vue'
|
||||||
|
import { cslineList } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
|
|
||||||
|
const dialogVisible: any = ref(false)
|
||||||
|
const harmonicRatioRef: any = ref(null)
|
||||||
|
|
||||||
|
const options = ref()
|
||||||
|
const height = mainHeight(0, 2).height as any
|
||||||
|
const tableHeaderRef = ref()
|
||||||
|
const TrendList = ref([{lineType:1}])
|
||||||
|
const loop50 = (key: string) => {
|
||||||
|
let list: any[] = []
|
||||||
|
for (let i = 2; i < 26; i++) {
|
||||||
|
list.push({
|
||||||
|
title: i + '次',
|
||||||
|
field: key + i + 'Overtime',
|
||||||
|
width: '80',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
const tableStore: any = new TableStore({
|
||||||
|
url: '/harmonic-boot/mainLine/statLimitRateDetails',
|
||||||
|
method: 'POST',
|
||||||
|
publicHeight: 30,
|
||||||
|
showPage: false,
|
||||||
|
exportName: '主要监测点列表',
|
||||||
|
column: [
|
||||||
|
{
|
||||||
|
field: 'index',
|
||||||
|
title: '序号',
|
||||||
|
width: '80',
|
||||||
|
formatter: (row: any) => {
|
||||||
|
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '日期',
|
||||||
|
field: 'time',
|
||||||
|
width: '150',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
field: 'lineName',
|
||||||
|
width: '150'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '闪变越限(分钟)',
|
||||||
|
field: 'flickerOvertime',
|
||||||
|
width: '80',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '谐波电压越限(分钟)',
|
||||||
|
children: loop50('uharm')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '谐波电流越限(分钟)',
|
||||||
|
children: loop50('iharm')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '三相不平衡度越限(分钟)',
|
||||||
|
field: 'ubalanceOvertime',
|
||||||
|
width: '100',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '电压偏差越限(分钟)',
|
||||||
|
field: 'uaberranceOvertime',
|
||||||
|
width: '100',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '频率偏差越限(分钟)',
|
||||||
|
field: 'freqDevOvertime',
|
||||||
|
width: '100',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
beforeSearchFun: () => {
|
||||||
|
},
|
||||||
|
loadCallback: () => {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
provide('tableStore', tableStore)
|
||||||
|
tableStore.table.params.sortBy = ''
|
||||||
|
tableStore.table.params.orderBy = ''
|
||||||
|
const open = async (row: any,searchBeginTime:any,searchEndTime:any) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
initCSlineList()
|
||||||
|
tableStore.table.params.lineId = row.lineId
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
tableHeaderRef.value.setTimeInterval([searchBeginTime, searchEndTime])
|
||||||
|
tableStore.table.params.searchBeginTime =searchBeginTime
|
||||||
|
tableStore.table.params.searchEndTime = searchEndTime
|
||||||
|
tableStore.index()
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击行
|
||||||
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
|
if (column.field != 'name' && column.field != 'time') {
|
||||||
|
dialogVisible.value = false
|
||||||
|
// if(column.title && column.title=='闪变越限(分钟)'){
|
||||||
|
// column.title = '1次'
|
||||||
|
// }
|
||||||
|
// harmonicRatioRef.value.openDialog(row,column.title.replace(/次/g, ""))
|
||||||
|
harmonicRatioRef.value.openDialog(row,column.field,column.title.replace(/次/g, ""))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 谐波弹窗关闭时的回调
|
||||||
|
const onHarmonicRatioClose = () => {
|
||||||
|
// 重新打开指标越限详情弹窗
|
||||||
|
nextTick(() => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const initCSlineList = async () => {
|
||||||
|
const res = await cslineList({})
|
||||||
|
options.value = res.data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--监测点列表 -->
|
<!--监测点列表 -->
|
||||||
|
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||||
<Table ref="tableRef" @cell-click="cellClickEvent" :height="`calc(${prop.height} )`"></Table>
|
<Table ref="tableRef" @cell-click="cellClickEvent" :height="`calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px )`"></Table>
|
||||||
<!-- 指标越限详情 -->
|
<!-- 指标越限详情 -->
|
||||||
<OverLimitDetails ref="OverLimitDetailsRef" />
|
<OverLimitDetails ref="OverLimitDetailsRef" />
|
||||||
</div>
|
</div>
|
||||||
@@ -11,19 +11,50 @@
|
|||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
|
||||||
import { useDictData } from '@/stores/dictData'
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
import { ElTag } from 'element-plus'
|
import { ElTag } from 'element-plus'
|
||||||
import OverLimitDetails from '@/components/cockpit/listOfMainMonitoringPoints/components/overLimitDetails.vue'
|
import OverLimitDetails from '@/components/cockpit/monitoringPointList/components/overLimitDetails.vue'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: String },
|
w: { type: [String, Number]},
|
||||||
height: { type: String },
|
h: { type: [String, Number]},
|
||||||
timeKey: { type: String },
|
width: { type: [String, Number]},
|
||||||
|
height: { type: [String, Number]},
|
||||||
|
timeKey: { type: [String, Number]},
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
const dictData = useDictData()
|
|
||||||
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
|
|
||||||
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
|
headerHeight.value = height
|
||||||
|
|
||||||
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
|
// 更新时间参数
|
||||||
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const OverLimitDetailsRef = ref()
|
const OverLimitDetailsRef = ref()
|
||||||
const tableStore: any = new TableStore({
|
const tableStore: any = new TableStore({
|
||||||
url: '/user-boot/role/selectRoleDetail?id=0',
|
url: '/user-boot/role/selectRoleDetail?id=0',
|
||||||
@@ -63,8 +94,8 @@ const tableStore: any = new TableStore({
|
|||||||
minWidth: '80',
|
minWidth: '80',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;' onclick="handleReportClick('${row.name}')">${row.type2}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;' onclick="handleReportClick('${row.name}')">${row.type2}</span>`
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
{ title: '监测点名称', field: 'type3', minWidth: '70' },
|
{ title: '监测点名称', field: 'type3', minWidth: '70' },
|
||||||
{ title: '监测类型', field: 'type4', minWidth: '60' },
|
{ title: '监测类型', field: 'type4', minWidth: '60' },
|
||||||
@@ -80,8 +111,8 @@ const tableStore: any = new TableStore({
|
|||||||
{ title: '最新数据时间', field: 'type6', minWidth: '140' }
|
{ title: '最新数据时间', field: 'type6', minWidth: '140' }
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.data = [
|
tableStore.table.data = [
|
||||||
@@ -155,31 +186,36 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const handleReportClick = (id: string) => {
|
const handleReportClick = (id: string) => {
|
||||||
const row = tableStore.table.data.find((item: any) => item.id === id)
|
const row = tableStore.table.data.find((item: any) => item.id === id)
|
||||||
if (row && row.type2 !== '/') {
|
if (row && row.type2 !== '/') {
|
||||||
// 示例:触发下载逻辑(根据你注释掉的代码)
|
// 示例:触发下载逻辑(根据你注释掉的代码)
|
||||||
// getFileZip({ eventId: id }).then(res => {
|
// getFileZip({ eventId: id }).then(res => {
|
||||||
// let blob = new Blob([res], { type: 'application/zip' })
|
// let blob = new Blob([res], { type: 'application/zip' })
|
||||||
// const url = window.URL.createObjectURL(blob)
|
// const url = window.URL.createObjectURL(blob)
|
||||||
// const link = document.createElement('a')
|
// const link = document.createElement('a')
|
||||||
// link.href = url
|
// link.href = url
|
||||||
// link.download = row.wavePath?.split('/')[2] || '报告文件.zip'
|
// link.download = row.wavePath?.split('/')[2] || '报告文件.zip'
|
||||||
// link.click()
|
// link.click()
|
||||||
// })
|
// })
|
||||||
console.log('点击了报告:', row.type2)
|
console.log('点击了报告:', row.type2)
|
||||||
} else {
|
} else {
|
||||||
ElMessage.warning('暂无报告可下载')
|
ElMessage.warning('暂无报告可下载')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 挂载到 window 供 HTML 调用
|
// 挂载到 window 供 HTML 调用
|
||||||
@@ -187,7 +223,7 @@ window.handleReportClick = handleReportClick
|
|||||||
|
|
||||||
// 组件销毁时清理全局方法
|
// 组件销毁时清理全局方法
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
delete window.handleReportClick
|
delete window.handleReportClick
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@@ -0,0 +1,705 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog draggable title="谐波电压/电流含有率" v-model="dialogVisible" append-to-body width="70%">
|
||||||
|
<!-- 总体指标占比详情谐波含有率 -->
|
||||||
|
<div>
|
||||||
|
<TableHeader ref="tableHeaderRef" :showSearch="false" @selectChange="selectChange">
|
||||||
|
<template v-slot:select>
|
||||||
|
<el-form-item>
|
||||||
|
<DatePicker ref="datePickerRef"></DatePicker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="统计指标" label-width="80px">
|
||||||
|
<el-select
|
||||||
|
multiple
|
||||||
|
:multiple-limit="2"
|
||||||
|
collapse-tags
|
||||||
|
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" @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-option value="max" label="最大值"></el-option>
|
||||||
|
<el-option value="min" label="最小值"></el-option>
|
||||||
|
<el-option value="avg" label="平均值"></el-option>
|
||||||
|
<el-option value="cp95" label="cp95"></el-option>
|
||||||
|
</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"
|
||||||
|
>
|
||||||
|
<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="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="timeControl ? 'primary' : ''" icon="el-icon-Sort" @click="setTimeControl">
|
||||||
|
缺失数据
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</TableHeader>
|
||||||
|
</div>
|
||||||
|
<div class="history_chart" :style="pageHeight" v-loading="loading">
|
||||||
|
<MyEchart
|
||||||
|
ref="historyChart"
|
||||||
|
:options="echartsData"
|
||||||
|
v-if="showEchart"
|
||||||
|
/>
|
||||||
|
<el-empty :style="pageHeight" v-else description="暂无数据" />
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { mainHeight } from '@/utils/layout'
|
||||||
|
import { queryByCode, queryCsDictTree } from '@/api/system-boot/dictTree'
|
||||||
|
import { ref, onMounted, watch } from 'vue'
|
||||||
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
|
import { useDictData } from '@/stores/dictData'
|
||||||
|
import { queryStatistical } from '@/api/system-boot/csstatisticalset'
|
||||||
|
import { yMethod, exportCSV, completeTimeSeries } from '@/utils/echartMethod'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { trendData } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
|
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||||
|
import { color } from '@/components/echarts/color'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
const dictData = useDictData()
|
||||||
|
defineOptions({
|
||||||
|
// name: 'govern/device/control'
|
||||||
|
})
|
||||||
|
const props = defineProps({
|
||||||
|
TrendList: {
|
||||||
|
type: Array
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const dialogVisible: any = ref(false)
|
||||||
|
// console.log("🚀 ~ props:", props.TrendList)
|
||||||
|
const showEchart = ref(true)
|
||||||
|
const num = ref(0)
|
||||||
|
const timeControl = ref(false)
|
||||||
|
//值类型
|
||||||
|
const pageHeight = ref(mainHeight(57 * 1.6, 1.6))
|
||||||
|
const loading = ref(true)
|
||||||
|
const searchForm: any = ref({})
|
||||||
|
const tableHeaderRef = ref()
|
||||||
|
const typeOptions = [
|
||||||
|
{
|
||||||
|
name: '平均值',
|
||||||
|
id: 'avg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '最大值',
|
||||||
|
id: 'max'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '最小值',
|
||||||
|
id: 'min'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CP95值',
|
||||||
|
id: 'cp95'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
searchForm.value = {
|
||||||
|
index: [],
|
||||||
|
type: typeOptions[0].id,
|
||||||
|
count: '',
|
||||||
|
searchBeginTime: '',
|
||||||
|
searchEndTime: '',
|
||||||
|
dataLevel: 'Primary',
|
||||||
|
valueType: 'avg'
|
||||||
|
}
|
||||||
|
//统计指标
|
||||||
|
const indexOptions: any = ref([])
|
||||||
|
//谐波次数
|
||||||
|
const countOptions: any = ref([])
|
||||||
|
// Harmonic_Type
|
||||||
|
// portable-harmonic
|
||||||
|
const legendDictList: any = ref([])
|
||||||
|
|
||||||
|
const initCode = (field: string, title: string) => {
|
||||||
|
queryByCode('steady_state_limit_trend').then(res => {
|
||||||
|
queryCsDictTree(res.data.id).then(item => {
|
||||||
|
//排序
|
||||||
|
indexOptions.value = item.data.sort((a: any, b: any) => {
|
||||||
|
return a.sort - b.sort
|
||||||
|
})
|
||||||
|
const titleMap: Record<string, number> = {
|
||||||
|
flickerOvertime: 0,
|
||||||
|
uaberranceOvertime: 3,
|
||||||
|
ubalanceOvertime: 4,
|
||||||
|
freqDevOvertime: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
let defaultIndex = 0 // 默认值
|
||||||
|
|
||||||
|
if (field in titleMap) {
|
||||||
|
defaultIndex = titleMap[field]
|
||||||
|
} else if (field.includes('uharm')) {
|
||||||
|
defaultIndex = 1
|
||||||
|
} else if (field.includes('iharm')) {
|
||||||
|
defaultIndex = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
searchForm.value.index[0] = indexOptions.value[defaultIndex].id
|
||||||
|
})
|
||||||
|
queryStatistical(res.data.id).then(vv => {
|
||||||
|
legendDictList.value = vv.data
|
||||||
|
indexOptions.value.map((item: any, index: any) => {
|
||||||
|
if (!countDataCopy.value[index]) {
|
||||||
|
countDataCopy.value[index] = {
|
||||||
|
index: item.id,
|
||||||
|
countOptions: [],
|
||||||
|
count: [],
|
||||||
|
name: indexOptions.value.find((vv: any) => {
|
||||||
|
return vv.id == item.id
|
||||||
|
})?.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
legendDictList.value?.selectedList?.map((vv: any, vvs: any) => {
|
||||||
|
//查找相等的指标
|
||||||
|
if (item.id == vv.dataType) {
|
||||||
|
vv.eleEpdPqdVOS.map((kk: any, kks: any) => {
|
||||||
|
if (kk.harmStart && kk.harmEnd) {
|
||||||
|
range(0, 0, 0)
|
||||||
|
|
||||||
|
if (kk.showName == '间谐波电压含有率') {
|
||||||
|
countDataCopy.value[index].countOptions = range(kk.harmStart, kk.harmEnd, 1).map(
|
||||||
|
(item: any) => {
|
||||||
|
return item - 0.5
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
countDataCopy.value[index].countOptions = range(kk.harmStart, kk.harmEnd, 1)
|
||||||
|
}
|
||||||
|
if (title && countDataCopy.value[index].countOptions.includes(Number(title))) {
|
||||||
|
countDataCopy.value[index].count = Number(title)
|
||||||
|
} else if (title && countDataCopy.value[index].countOptions.includes(title)) {
|
||||||
|
countDataCopy.value[index].count = title
|
||||||
|
} else if (
|
||||||
|
!countDataCopy.value[index].count ||
|
||||||
|
countDataCopy.value[index].count.length == 0
|
||||||
|
) {
|
||||||
|
// 只有当count为空时才设置默认值
|
||||||
|
countDataCopy.value[index].count = countDataCopy.value[index].countOptions[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
nextTick(() => {
|
||||||
|
formatCountOptions()
|
||||||
|
})
|
||||||
|
init()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const chartsList = ref<any>([])
|
||||||
|
const chartTitle: any = ref('')
|
||||||
|
const echartsData = ref<any>(null)
|
||||||
|
//加载echarts图表
|
||||||
|
//历史趋势数据
|
||||||
|
const historyDataList: any = ref([])
|
||||||
|
const range = (start: any, end: any, step: any) => {
|
||||||
|
return Array.from({ length: (end - start) / step + 1 }, (_, i) => start + i * step)
|
||||||
|
}
|
||||||
|
//获取请求趋势数据参数
|
||||||
|
const trendRequestData = ref()
|
||||||
|
const getTrendRequest = (val: any) => {
|
||||||
|
trendRequestData.value = val
|
||||||
|
// init()
|
||||||
|
}
|
||||||
|
//初始化趋势图
|
||||||
|
const headerRef = ref()
|
||||||
|
const datePickerRef = ref()
|
||||||
|
const lineStyle = [{ type: 'solid' }, { type: 'dashed' }, { type: 'dotted' }]
|
||||||
|
const init = async () => {
|
||||||
|
loading.value = true
|
||||||
|
// 选择指标的时候切换legend内容和data数据
|
||||||
|
let list: any = []
|
||||||
|
legendDictList.value?.selectedList?.map((item: any) => {
|
||||||
|
searchForm.value.index.map((vv: any) => {
|
||||||
|
if (item.dataType == vv) {
|
||||||
|
list.push(item.eleEpdPqdVOS)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
//颜色数组
|
||||||
|
const colorList = color
|
||||||
|
//选择的指标使用方法处理
|
||||||
|
formatCountOptions()
|
||||||
|
//查询历史趋势
|
||||||
|
historyDataList.value = []
|
||||||
|
chartTitle.value = ''
|
||||||
|
|
||||||
|
searchForm.value.index.map((item: any, indexs: any) => {
|
||||||
|
indexOptions.value.map((vv: any) => {
|
||||||
|
if (vv.id == item) {
|
||||||
|
chartTitle.value += indexs == searchForm.value.index.length - 1 ? vv.name : vv.name + '/'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
let lists: any = []
|
||||||
|
let frequencys: any = null
|
||||||
|
countData.value.map((item: any, index: any) => {
|
||||||
|
if (item.name.includes('谐波含有率')) {
|
||||||
|
frequencys = item.count
|
||||||
|
} else {
|
||||||
|
frequencys = ''
|
||||||
|
}
|
||||||
|
lists[index] = {
|
||||||
|
statisticalId: item.index,
|
||||||
|
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let obj = {
|
||||||
|
//...trendRequestData.value,
|
||||||
|
lineId: trendRequestData.value.lineId,
|
||||||
|
list: lists,
|
||||||
|
dataLevel: searchForm.value.dataLevel,
|
||||||
|
valueType: searchForm.value.valueType,
|
||||||
|
searchBeginTime: datePickerRef.value && datePickerRef.value.timeValue[0],
|
||||||
|
searchEndTime: datePickerRef.value && datePickerRef.value.timeValue[1]
|
||||||
|
}
|
||||||
|
if (searchForm.value.index.length == 0) {
|
||||||
|
ElMessage.warning('请选择统计指标')
|
||||||
|
loading.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (obj.list.length != 0) {
|
||||||
|
try {
|
||||||
|
showEchart.value = true
|
||||||
|
await trendData(obj)
|
||||||
|
.then((res: any) => {
|
||||||
|
if (res.code == 'A0000') {
|
||||||
|
if (res.data.length == 0) {
|
||||||
|
loading.value = false
|
||||||
|
showEchart.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
historyDataList.value = res.data
|
||||||
|
chartsList.value = JSON.parse(JSON.stringify(res.data))
|
||||||
|
loading.value = false
|
||||||
|
setEchart()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const setEchart = () => {
|
||||||
|
loading.value = true
|
||||||
|
echartsData.value = {}
|
||||||
|
//icon图标替换legend图例
|
||||||
|
|
||||||
|
// y轴单位数组
|
||||||
|
let unitList: any = []
|
||||||
|
|
||||||
|
let groupedData = chartsList.value.reduce((acc: any, item: any) => {
|
||||||
|
let key = ''
|
||||||
|
if (item.phase == null) {
|
||||||
|
key = item.unit
|
||||||
|
} else {
|
||||||
|
key = item.anotherName
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!acc[key]) {
|
||||||
|
acc[key] = []
|
||||||
|
}
|
||||||
|
acc[key].push(item)
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
let result = Object.values(groupedData)
|
||||||
|
if (chartsList.value.length > 0) {
|
||||||
|
unitList = result.map((item: any) => {
|
||||||
|
return item[0].unit
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
echartsData.value = {
|
||||||
|
legend: {
|
||||||
|
itemWidth: 20,
|
||||||
|
itemHeight: 20,
|
||||||
|
itemStyle: { opacity: 0 }, //去圆点
|
||||||
|
type: 'scroll', // 开启滚动分页
|
||||||
|
// orient: 'vertical', // 垂直排列
|
||||||
|
top: 5,
|
||||||
|
right: 70
|
||||||
|
// width: 550,
|
||||||
|
// height: 50
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: '80px'
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
axisPointer: {
|
||||||
|
type: 'cross',
|
||||||
|
label: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 16
|
||||||
|
}
|
||||||
|
},
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
fontStyle: 'normal',
|
||||||
|
opacity: 0.35,
|
||||||
|
fontSize: 14
|
||||||
|
},
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||||
|
borderWidth: 0,
|
||||||
|
formatter(params: any) {
|
||||||
|
const xname = params[0].value[0]
|
||||||
|
let str = `${xname}<br>`
|
||||||
|
params.forEach((el: any, index: any) => {
|
||||||
|
let marker = ''
|
||||||
|
|
||||||
|
if (el.value[3] == 'dashed') {
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
marker += `<span style="display:inline-block;border: 2px ${el.color} solid;margin-right:5px;width:10px;height:0px;background-color:#ffffff00;"></span>`
|
||||||
|
}
|
||||||
|
} 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>`
|
||||||
|
}
|
||||||
|
let unit = el.value[2] ? el.value[2] : ''
|
||||||
|
str += `${marker}${el.seriesName.split('(')[0]}:${el.value[1]}${unit}
|
||||||
|
<br>`
|
||||||
|
})
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
},
|
||||||
|
color: ['#DAA520', '#2E8B57', '#A52a2a', ...color],
|
||||||
|
xAxis: {
|
||||||
|
type: 'time',
|
||||||
|
axisLabel: {
|
||||||
|
formatter: {
|
||||||
|
day: '{MM}-{dd}',
|
||||||
|
month: '{MM}',
|
||||||
|
year: '{yyyy}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: [{}],
|
||||||
|
toolbox: {
|
||||||
|
featureProps: {
|
||||||
|
myTool1: {
|
||||||
|
show: true,
|
||||||
|
title: '下载csv',
|
||||||
|
icon: 'path://M588.8 551.253333V512H352v39.253333h236.373333z m0 78.933334v-39.253334H352v39.253334h236.373333z m136.533333 78.933333V334.933333l-157.866666-157.866666H273.066667A59.306667 59.306667 0 0 0 213.333333 236.373333v551.253334a59.306667 59.306667 0 0 0 59.306667 59.306666h274.773333v42.666667H853.333333v-180.48zM568.746667 234.666667l100.266666 100.693333h-81.066666a20.053333 20.053333 0 0 1-19.626667-20.053333z m-20.48 573.013333H273.066667a19.2 19.2 0 0 1-17.493334-19.626667V236.373333a19.2 19.2 0 0 1 19.626667-19.626666h256v98.133333a58.88 58.88 0 0 0 58.88 59.306667h96.426667v334.933333h-98.133334v-39.68H352v39.68h196.266667z m100.266666 23.04a37.973333 37.973333 0 0 1-32 15.786667 38.826667 38.826667 0 0 1-32.426666-15.786667 53.76 53.76 0 0 1-10.24-32.853333 42.666667 42.666667 0 0 1 42.666666-47.786667 35.84 35.84 0 0 1 37.546667 29.866667h-12.8a23.893333 23.893333 0 0 0-24.746667-19.2c-17.066667 0-29.013333 14.08-29.013333 35.84s11.52 37.546667 28.586667 37.546666a26.453333 26.453333 0 0 0 26.453333-25.6h12.8a39.253333 39.253333 0 0 1-7.253333 22.186667z m59.733334 15.786667a35.84 35.84 0 0 1-40.106667-34.56H682.666667a23.893333 23.893333 0 0 0 26.88 23.04c12.8 0 22.613333-6.4 22.613333-15.786667s-4.266667-11.52-14.506667-13.653333l-21.333333-5.12c-17.066667-4.266667-24.32-11.52-24.32-23.893334s12.8-26.453333 34.133333-26.453333a31.573333 31.573333 0 0 1 35.413334 30.293333h-13.653334a19.626667 19.626667 0 0 0-22.613333-18.773333c-12.8 0-20.48 5.12-20.48 12.8s5.12 11.093333 17.066667 13.653333l14.933333 2.986667a42.666667 42.666667 0 0 1 20.906667 8.96 23.893333 23.893333 0 0 1 7.68 17.92c-0.426667 17.066667-14.506667 28.16-37.12 28.16z m88.746666 0h-14.506666l-32.426667-92.16h14.08l19.626667 59.733333 6.4 20.053333c0-9.386667 3.413333-12.8 5.546666-20.053333l19.2-59.733333h14.08z',
|
||||||
|
onclick: e => {
|
||||||
|
// console.log("🚀 ~ init ~ echartsData.value:", echartsData.value.options.series.map(item => item.data))
|
||||||
|
|
||||||
|
let list = echartsData.value.options.series?.map((item: any) => item.data)
|
||||||
|
let dataList = list[0]?.map((item: any, index: any) => {
|
||||||
|
let value = [item[0], item[1]]
|
||||||
|
list.forEach((item1: any, index1: any) => {
|
||||||
|
if (index1 > 0) {
|
||||||
|
value.push(item1 && item1[index] ? item1[index][1] : null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return value
|
||||||
|
})
|
||||||
|
exportCSV(
|
||||||
|
echartsData.value.options.series.map((item: any) => item.name),
|
||||||
|
dataList,
|
||||||
|
'监测点指标趋势.csv'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
series: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log("🚀 ~ unitList.forEach ~ unitList:", unitList)
|
||||||
|
|
||||||
|
if (chartsList.value.length > 0) {
|
||||||
|
let yData: any = []
|
||||||
|
echartsData.value.yAxis = []
|
||||||
|
let setList = [...new Set(unitList)]
|
||||||
|
|
||||||
|
setList.forEach((item: any, index: any) => {
|
||||||
|
if (index > 2) {
|
||||||
|
echartsData.value.grid.right = (index - 1) * 80
|
||||||
|
}
|
||||||
|
yData.push([])
|
||||||
|
let right = {
|
||||||
|
position: 'right',
|
||||||
|
offset: (index - 1) * 80
|
||||||
|
}
|
||||||
|
// console.log("🚀 ~ unitList.forEach ~ right.index:", index)
|
||||||
|
echartsData.value.yAxis.push({
|
||||||
|
name: item,
|
||||||
|
yAxisIndex: index,
|
||||||
|
splitNumber: 5,
|
||||||
|
minInterval: 1,
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
...(index > 0 ? right : null)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// console.log("🚀 ~ result.forEach ~ result:", result)
|
||||||
|
// '电压负序分量', '电压正序分量', '电压零序分量'
|
||||||
|
let ABCName = [
|
||||||
|
...new Set(
|
||||||
|
chartsList.value.map((item: any) => {
|
||||||
|
return item.anotherName == '电压负序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: item.anotherName == '电压正序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: item.anotherName == '电压零序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: item.anotherName
|
||||||
|
})
|
||||||
|
)
|
||||||
|
]
|
||||||
|
// console.log("🚀 ~ .then ~ ABCName:", ABCName)
|
||||||
|
result.forEach((item: any, index: any) => {
|
||||||
|
let yMethodList: any = []
|
||||||
|
|
||||||
|
let ABCList = Object.values(
|
||||||
|
item.reduce((acc, item) => {
|
||||||
|
let key = ''
|
||||||
|
if (item.phase == null) {
|
||||||
|
key = item.anotherName
|
||||||
|
} else {
|
||||||
|
key = item.phase
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!acc[key]) {
|
||||||
|
acc[key] = []
|
||||||
|
}
|
||||||
|
acc[key].push(item)
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
)
|
||||||
|
// console.log("🚀 ~ ABCList.forEach ~ ABCList:", ABCList)
|
||||||
|
|
||||||
|
ABCList.forEach((kk: any) => {
|
||||||
|
let colorName = kk[0].phase?.charAt(0).toUpperCase()
|
||||||
|
let lineS = ABCName.findIndex(
|
||||||
|
item =>
|
||||||
|
item ===
|
||||||
|
(kk[0].anotherName == '电压负序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: kk[0].anotherName == '电压正序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: kk[0].anotherName == '电压零序分量'
|
||||||
|
? '电压不平衡'
|
||||||
|
: kk[0].anotherName)
|
||||||
|
)
|
||||||
|
|
||||||
|
let seriesList: any = []
|
||||||
|
kk.forEach((cc: any) => {
|
||||||
|
if (cc.statisticalData !== null) {
|
||||||
|
yData[setList.indexOf(kk[0].unit)].push(cc.statisticalData?.toFixed(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
seriesList.push([cc.time, cc.statisticalData?.toFixed(2), cc.unit, lineStyle[lineS].type])
|
||||||
|
})
|
||||||
|
// console.log(kk);
|
||||||
|
|
||||||
|
echartsData.value.options.series.push({
|
||||||
|
name: kk[0].phase ? kk[0].phase + '相' + kk[0].anotherName : kk[0].anotherName,
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
color:
|
||||||
|
colorName == 'A' ? '#DAA520' : colorName == 'B' ? '#2E8B57' : colorName == 'C' ? '#A52a2a' : '',
|
||||||
|
symbol: 'none',
|
||||||
|
// data: seriesList,
|
||||||
|
data: timeControl.value ? completeTimeSeries(seriesList) : seriesList,
|
||||||
|
lineStyle: lineStyle[lineS],
|
||||||
|
yAxisIndex: setList.indexOf(kk[0].unit)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
yData.forEach((item: any, index: any) => {
|
||||||
|
let [min, max] = yMethod(item)
|
||||||
|
echartsData.value.yAxis[index].min = min
|
||||||
|
echartsData.value.yAxis[index].max = max
|
||||||
|
})
|
||||||
|
// console.log("🚀 ~ result.forEach ~ echartsData.value:", echartsData.value)
|
||||||
|
}
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
const setTimeControl = () => {
|
||||||
|
timeControl.value = !timeControl.value
|
||||||
|
setEchart()
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectChange = (flag: boolean, height: any) => {
|
||||||
|
pageHeight.value = mainHeight(height * 1.6, 1.6)
|
||||||
|
}
|
||||||
|
//导出
|
||||||
|
const historyChart = ref()
|
||||||
|
|
||||||
|
const countData: any = ref([])
|
||||||
|
const countDataCopy: any = ref([])
|
||||||
|
|
||||||
|
//根据选择的指标处理谐波次数
|
||||||
|
const formatCountOptions = () => {
|
||||||
|
countData.value = []
|
||||||
|
if (searchForm.value.index.length != 0) {
|
||||||
|
searchForm.value.index.forEach((item: any, index: any) => {
|
||||||
|
countDataCopy.value.forEach((vv: any, vvs: any) => {
|
||||||
|
if (vv.index == item) {
|
||||||
|
countData.value.push(vv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
countData.value.map((item: any, key: any) => {
|
||||||
|
if (item.name == '谐波电流有效值') {
|
||||||
|
item.name = '谐波电流次数'
|
||||||
|
} else if (item.name == '谐波电压含有率') {
|
||||||
|
item.name = '谐波电压次数'
|
||||||
|
} else if (item.name == '间谐波电压含有率') {
|
||||||
|
item.name = '间谐波电压次数'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// setTimeout(() => {
|
||||||
|
// tableHeaderRef.value.computedSearchRow()
|
||||||
|
// }, 500)
|
||||||
|
}
|
||||||
|
// 判断下拉框是否存在
|
||||||
|
const onCountChange = (val: any, index: any) => {
|
||||||
|
if (val.length == 0) {
|
||||||
|
countData.value[index].count = countData.value[index].countOptions[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const flag = ref(true)
|
||||||
|
const onIndexChange = (val: any) => {
|
||||||
|
num.value += 1
|
||||||
|
let pp: any = []
|
||||||
|
indexOptions.value.forEach((item: any) => {
|
||||||
|
const filteredResult = val.filter(vv => item.id == vv)
|
||||||
|
if (filteredResult.length > 0) {
|
||||||
|
pp.push(filteredResult[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
searchForm.value.index = pp
|
||||||
|
flag.value = true
|
||||||
|
formatCountOptions()
|
||||||
|
}
|
||||||
|
watch(
|
||||||
|
() => searchForm.value.index,
|
||||||
|
(val: any, oldval: any) => {},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const openDialog = async (row: any, field: any, title: any) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
trendRequestData.value = row
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
// 默认当天
|
||||||
|
datePickerRef.value.setInterval(5)
|
||||||
|
datePickerRef.value.timeValue = [row.time, row.time]
|
||||||
|
initCode(field, title)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ getTrendRequest, openDialog })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.history_header {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
// flex-wrap: wrap;
|
||||||
|
#history_select {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
// justify-content: flex-start;
|
||||||
|
// overflow-x: auto;
|
||||||
|
height: auto;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
flex: none !important;
|
||||||
|
// max-width: 380px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-select {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #history_select::-webkit-scrollbar {
|
||||||
|
// width: 0 !important;
|
||||||
|
// display: none !important;
|
||||||
|
// }
|
||||||
|
|
||||||
|
.history_searchBtn {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.history_chart {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
// flex: 1;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history_count {
|
||||||
|
.el-select {
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- 指标越限详情 -->
|
||||||
|
<el-dialog draggable title="指标越限详情" v-model="dialogVisible" append-to-body width="70%">
|
||||||
|
<TableHeader datePicker showExport :showReset="false" ref="tableHeaderRef">
|
||||||
|
<template v-slot:select>
|
||||||
|
<el-form-item label="监测点">
|
||||||
|
<el-select
|
||||||
|
v-model="tableStore.table.params.lineId"
|
||||||
|
placeholder="请选择监测点"
|
||||||
|
style="width: 150px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in options"
|
||||||
|
:key="item.lineId"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.lineId"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</TableHeader>
|
||||||
|
<Table ref="tableRef" @cell-click="cellClickEvent" isGroup :height="height"></Table>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 谐波电流、谐波电压占有率 -->
|
||||||
|
<HarmonicRatio ref="harmonicRatioRef" v-if="dialogFlag" @close="onHarmonicRatioClose" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, provide,nextTick } from 'vue'
|
||||||
|
import Table from '@/components/table/index.vue'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import TableStore from '@/utils/tableStore'
|
||||||
|
import { mainHeight } from '@/utils/layout'
|
||||||
|
import HarmonicRatio from '@/components/cockpit/overLimitStatistics/components/harmonicRatio.vue'
|
||||||
|
import { cslineList } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
|
|
||||||
|
const dialogVisible: any = ref(false)
|
||||||
|
const harmonicRatioRef: any = ref(null)
|
||||||
|
|
||||||
|
const options = ref()
|
||||||
|
const height = mainHeight(0, 2).height as any
|
||||||
|
const tableHeaderRef = ref()
|
||||||
|
const dialogFlag = ref(false)
|
||||||
|
const loop50 = (key: string) => {
|
||||||
|
let list: any[] = []
|
||||||
|
for (let i = 2; i < 26; i++) {
|
||||||
|
list.push({
|
||||||
|
title: i + '次',
|
||||||
|
field: key + i + 'Overtime',
|
||||||
|
width: '80',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
const tableStore: any = new TableStore({
|
||||||
|
url: '/harmonic-boot/totalLimitStatistics/details',
|
||||||
|
method: 'POST',
|
||||||
|
publicHeight: 30,
|
||||||
|
showPage: false,
|
||||||
|
exportName: '每日越限占比统计',
|
||||||
|
column: [
|
||||||
|
{
|
||||||
|
field: 'index',
|
||||||
|
title: '序号',
|
||||||
|
width: '80',
|
||||||
|
formatter: (row: any) => {
|
||||||
|
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '日期',
|
||||||
|
field: 'time',
|
||||||
|
width: '150',
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '名称',
|
||||||
|
field: 'lineName',
|
||||||
|
width: '150'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '闪变越限(%)',
|
||||||
|
field: 'flickerOvertime',
|
||||||
|
width: '80',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '谐波电压越限(%)',
|
||||||
|
children: loop50('uharm')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '谐波电流越限(%)',
|
||||||
|
children: loop50('iharm')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '三相不平衡度越限(%)',
|
||||||
|
field: 'ubalanceOvertime',
|
||||||
|
width: '100',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '电压偏差越限(%)',
|
||||||
|
field: 'uaberranceOvertime',
|
||||||
|
width: '100',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '频率偏差越限(%)',
|
||||||
|
field: 'freqDevOvertime',
|
||||||
|
width: '100',
|
||||||
|
render: 'customTemplate',
|
||||||
|
customTemplate: (row: any) => {
|
||||||
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
beforeSearchFun: () => {
|
||||||
|
},
|
||||||
|
loadCallback: () => {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
provide('tableStore', tableStore)
|
||||||
|
tableStore.table.params.sortBy = ''
|
||||||
|
tableStore.table.params.orderBy = ''
|
||||||
|
const open = async (row: any,searchBeginTime:any,searchEndTime:any) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
initCSlineList()
|
||||||
|
tableStore.table.params.lineId = row.lineId
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
tableHeaderRef.value.setTimeInterval([searchBeginTime, searchEndTime])
|
||||||
|
tableStore.table.params.searchBeginTime =searchBeginTime
|
||||||
|
tableStore.table.params.searchEndTime = searchEndTime
|
||||||
|
tableStore.index()
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击行
|
||||||
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
|
if (column.field != 'name' && column.field != 'time') {
|
||||||
|
dialogFlag.value = true
|
||||||
|
dialogVisible.value = false
|
||||||
|
nextTick(() => {
|
||||||
|
harmonicRatioRef.value.openDialog(row,column.field,column.title.replace(/次/g, ""))
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 谐波弹窗关闭时的回调
|
||||||
|
const onHarmonicRatioClose = () => {
|
||||||
|
dialogFlag.value = false
|
||||||
|
// 重新打开指标越限详情弹窗
|
||||||
|
nextTick(() => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const initCSlineList = async () => {
|
||||||
|
const res = await cslineList({})
|
||||||
|
options.value = res.data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@@ -1,13 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<!--总体指标越限统计 -->
|
<!--总体指标越限统计 -->
|
||||||
|
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||||
<my-echart
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
:style="{ width: prop.width, height: `calc(${prop.height} / 2 )` }"
|
:style="{
|
||||||
|
width: prop.width,
|
||||||
|
height: `calc(${prop.height} / 2 )`
|
||||||
|
}"
|
||||||
/>
|
/>
|
||||||
<Table ref="tableRef" @cell-click="cellClickEvent" :height="`calc(${prop.height} / 2 )`" isGroup></Table>
|
<Table
|
||||||
|
ref="tableRef"
|
||||||
|
@cell-click="cellClickEvent"
|
||||||
|
:height="`calc(${prop.height} / 2 - ${headerHeight}px + ${fullscreen ? 0 : 56}px )`"
|
||||||
|
isGroup
|
||||||
|
></Table>
|
||||||
<!-- 指标越限详情 -->
|
<!-- 指标越限详情 -->
|
||||||
<OverLimitDetails ref="OverLimitDetailsRef" />
|
<OverLimitDetails ref="OverLimitDetailsRef" />
|
||||||
</div>
|
</div>
|
||||||
@@ -16,60 +24,103 @@
|
|||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useDictData } from '@/stores/dictData'
|
import OverLimitDetails from '@/components/cockpit/overLimitStatistics/components/overLimitDetails.vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { useRoute } from 'vue-router'
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
import OverLimitDetails from '@/components/cockpit/listOfMainMonitoringPoints/components/overLimitDetails.vue'
|
import { totalLimitStatisticsData } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: String },
|
w: { type: [String, Number] },
|
||||||
height: { type: String },
|
h: { type: [String, Number] },
|
||||||
timeKey: { type: String },
|
width: { type: [String, Number] },
|
||||||
|
height: { type: [String, Number] },
|
||||||
|
timeKey: { type: [String, Number] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
const echartList = ref({
|
|
||||||
title: {
|
|
||||||
text: '指标越限占比'
|
|
||||||
},
|
|
||||||
|
|
||||||
xAxis: {
|
const headerHeight = ref(57)
|
||||||
// name: '(区域)',
|
|
||||||
data: ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
|
||||||
},
|
|
||||||
|
|
||||||
yAxis: {
|
const route = useRoute()
|
||||||
name: '%', // 给X轴加单位
|
const timeCacheStore = useTimeCacheStore()
|
||||||
interval: 20
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
left: '10px',
|
|
||||||
right: '20px'
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
// name: '暂降次数',
|
|
||||||
type: 'bar',
|
|
||||||
name: '越限占比',
|
|
||||||
data: [0, 45, 22, 0, 70],
|
|
||||||
barMaxWidth: 30,
|
|
||||||
|
|
||||||
// label: {
|
const echartList = ref({})
|
||||||
// show: true,
|
|
||||||
// position: 'top',
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
// textStyle: {
|
headerHeight.value = height
|
||||||
// //数值样式
|
|
||||||
// color: '#000'
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
// },
|
// 更新时间参数
|
||||||
// fontSize: 12
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
// }
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
|
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const initEcharts = () => {
|
||||||
|
totalLimitStatisticsData({
|
||||||
|
searchBeginTime: tableStore.table.params.searchBeginTime,
|
||||||
|
searchEndTime: tableStore.table.params.searchEndTime
|
||||||
|
}).then((res: any) => {
|
||||||
|
const dataArray = [res.data.flicker, res.data.uharm, res.data.iharm, res.data.voltageDev, res.data.ubalance]
|
||||||
|
echartList.value = {
|
||||||
|
title: {
|
||||||
|
text: '指标越限占比'
|
||||||
|
},
|
||||||
|
|
||||||
|
xAxis: {
|
||||||
|
// name: '(区域)',
|
||||||
|
data: ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
||||||
|
},
|
||||||
|
|
||||||
|
yAxis: {
|
||||||
|
name: '%', // 给X轴加单位
|
||||||
|
interval: 20
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '10px',
|
||||||
|
right: '20px'
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
// name: '暂降次数',
|
||||||
|
type: 'bar',
|
||||||
|
name: '越限占比',
|
||||||
|
data: dataArray,
|
||||||
|
barMaxWidth: 30
|
||||||
|
|
||||||
|
// label: {
|
||||||
|
// show: true,
|
||||||
|
// position: 'top',
|
||||||
|
// textStyle: {
|
||||||
|
// //数值样式
|
||||||
|
// color: '#000'
|
||||||
|
// },
|
||||||
|
// fontSize: 12
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const OverLimitDetailsRef = ref()
|
const OverLimitDetailsRef = ref()
|
||||||
const tableStore: any = new TableStore({
|
const tableStore: any = new TableStore({
|
||||||
url: '/user-boot/dept/deptTree',
|
url: '/harmonic-boot/totalLimitStatistics/list',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
||||||
showPage: false,
|
showPage: false,
|
||||||
@@ -85,7 +136,7 @@ const tableStore: any = new TableStore({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '名称',
|
title: '名称',
|
||||||
field: 'name',
|
field: 'lineName',
|
||||||
minWidth: '90'
|
minWidth: '90'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -93,69 +144,59 @@ const tableStore: any = new TableStore({
|
|||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
title: '闪变',
|
title: '闪变',
|
||||||
field: 'type',
|
field: 'flicker',
|
||||||
minWidth: '70',
|
minWidth: '70',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.type}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flicker}</span>`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '谐波电压',
|
title: '谐波电压',
|
||||||
field: 'type1',
|
field: 'uharm',
|
||||||
minWidth: '80',
|
minWidth: '80',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.type1}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.uharm}</span>`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '谐波电流',
|
title: '谐波电流',
|
||||||
field: 'type2',
|
field: 'iharm',
|
||||||
minWidth: '80',
|
minWidth: '80',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.type2}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.iharm}</span>`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '电压偏差',
|
title: '电压偏差',
|
||||||
field: 'type3',
|
field: 'voltageDev',
|
||||||
minWidth: '80',
|
minWidth: '80',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.type3}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.voltageDev}</span>`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '三相不平衡',
|
title: '三相不平衡',
|
||||||
field: 'type4',
|
field: 'ubalance',
|
||||||
minWidth: '90',
|
minWidth: '90',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.type4}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalance}</span>`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.data = [
|
|
||||||
{
|
|
||||||
name: '10kV1#电动机',
|
|
||||||
type: '0',
|
|
||||||
type1: '45',
|
|
||||||
type2: '22',
|
|
||||||
type3: '0',
|
|
||||||
type4: '70'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
tableStore.table.height = `calc(${prop.height} - 80px)`
|
tableStore.table.height = `calc(${prop.height} - 80px)`
|
||||||
|
initEcharts()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -167,8 +208,11 @@ provide('tableStore', tableStore)
|
|||||||
// 点击行
|
// 点击行
|
||||||
const cellClickEvent = ({ row, column }: any) => {
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
if (column.field != 'name') {
|
if (column.field != 'name') {
|
||||||
console.log(row)
|
OverLimitDetailsRef.value.open(
|
||||||
OverLimitDetailsRef.value.open(row)
|
row,
|
||||||
|
tableStore.table.params.searchBeginTime || prop.timeValue?.[0],
|
||||||
|
tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,15 +223,21 @@ watch(
|
|||||||
() => prop.timeKey,
|
() => prop.timeKey,
|
||||||
val => {
|
val => {
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
|
initEcharts()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,56 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--敏感负荷列表 -->
|
<!--敏感负荷列表 -->
|
||||||
|
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||||
<Table ref="tableRef" @cell-click="cellClickEvent" :height="`calc(${prop.height})`" isGroup></Table>
|
<Table ref="tableRef" @cell-click="cellClickEvent" :height="`calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px )`" isGroup></Table>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
|
||||||
import { useDictData } from '@/stores/dictData'
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: String },
|
w: { type: [String, Number]},
|
||||||
height: { type: String },
|
h: { type: [String, Number]},
|
||||||
timeKey: { type: String },
|
width: { type: [String, Number]},
|
||||||
|
height: { type: [String, Number]},
|
||||||
|
timeKey: { type: [String, Number]},
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
|
|
||||||
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
|
headerHeight.value = height
|
||||||
|
|
||||||
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
|
// 更新时间参数
|
||||||
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
const OverLimitDetailsRef = ref()
|
const OverLimitDetailsRef = ref()
|
||||||
const tableStore: any = new TableStore({
|
const tableStore: any = new TableStore({
|
||||||
url: '/user-boot/dept/deptTree',
|
url: '/user-boot/dept/deptTree',
|
||||||
@@ -59,9 +90,10 @@ const tableStore: any = new TableStore({
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
},
|
},
|
||||||
|
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.data = [
|
tableStore.table.data = [
|
||||||
{
|
{
|
||||||
@@ -105,12 +137,17 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--暂态事件明细 -->
|
<!--暂态事件明细 -->
|
||||||
|
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||||
<el-calendar v-model="value" :style="{ height: prop.height, overflow: 'auto' }">
|
<el-calendar
|
||||||
|
v-model="value"
|
||||||
|
:style="{
|
||||||
|
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px )`,
|
||||||
|
overflow: 'auto'
|
||||||
|
}"
|
||||||
|
>
|
||||||
<template #date-cell="{ data }">
|
<template #date-cell="{ data }">
|
||||||
<div style="height: 100%; padding: 8px" :style="{ background: setBackground(data.day) }">
|
<div style="height: 100%; padding: 8px" :style="{ background: setBackground(data.day) }">
|
||||||
<p :class="data.isSelected ? 'is-selected' : ''">
|
<p :class="data.isSelected ? 'is-selected' : ''">
|
||||||
@@ -27,7 +33,7 @@
|
|||||||
:style="{ height: `calc(${prop.height} / 5 - 47px)`, overflow: 'auto' }"
|
:style="{ height: `calc(${prop.height} / 5 - 47px)`, overflow: 'auto' }"
|
||||||
v-for="item in list?.filter(item => item.time == data.day)"
|
v-for="item in list?.filter(item => item.time == data.day)"
|
||||||
>
|
>
|
||||||
<div @click="descentClick">电压暂降:{{ item.type || '' }}</div>
|
<div @click="descentClick">电压暂降:{{ item.type || '' }}</div>
|
||||||
<div>电压中断:{{ item.type1 || '' }}</div>
|
<div>电压中断:{{ item.type1 || '' }}</div>
|
||||||
<div>电压暂升:{{ item.type2 || '' }}</div>
|
<div>电压暂升:{{ item.type2 || '' }}</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -36,28 +42,57 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-calendar>
|
</el-calendar>
|
||||||
<!-- 暂态事件列表 -->
|
<!-- 暂态事件列表 -->
|
||||||
<TransientList ref="transientListRef" />
|
<TransientList ref="transientListRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
|
||||||
import { useDictData } from '@/stores/dictData'
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
import { overflow } from 'html2canvas/dist/types/css/property-descriptors/overflow'
|
|
||||||
import { dayjs } from 'element-plus'
|
import { dayjs } from 'element-plus'
|
||||||
import TransientList from './components/transientList.vue'
|
import TransientList from './components/transientList.vue'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
|
|
||||||
|
const prop = defineProps({
|
||||||
|
w: { type: [String, Number] },
|
||||||
|
h: { type: [String, Number] },
|
||||||
|
width: { type: [String, Number] },
|
||||||
|
height: { type: [String, Number] },
|
||||||
|
timeKey: { type: [String, Number] },
|
||||||
|
timeValue: { type: Object }
|
||||||
|
})
|
||||||
|
|
||||||
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
|
|
||||||
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
|
headerHeight.value = height
|
||||||
|
|
||||||
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
|
// 更新时间参数
|
||||||
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
dayjs.en.weekStart = 1 //设置日历的周起始日为星期一
|
dayjs.en.weekStart = 1 //设置日历的周起始日为星期一
|
||||||
const value = ref(new Date())
|
const value = ref(new Date())
|
||||||
const prop = defineProps({
|
|
||||||
width: { type: String },
|
|
||||||
height: { type: String },
|
|
||||||
timeKey: { type: String },
|
|
||||||
timeValue: { type: Object }
|
|
||||||
})
|
|
||||||
|
|
||||||
const transientListRef = ref()
|
const transientListRef = ref()
|
||||||
const list = ref([
|
const list = ref([
|
||||||
@@ -112,18 +147,17 @@ const tableStore: any = new TableStore({
|
|||||||
showPage: false,
|
showPage: false,
|
||||||
|
|
||||||
column: [],
|
column: [],
|
||||||
|
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
// value.value = new Date(prop.timeValue?.[0])
|
|
||||||
},
|
},
|
||||||
|
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.data = []
|
tableStore.table.data = []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const tableRef = ref([])
|
|
||||||
|
|
||||||
const setBackground = (value: string) => {
|
const setBackground = (value: string) => {
|
||||||
let data = []
|
let data = []
|
||||||
data = list.value?.filter(item => item.time == value)
|
data = list.value?.filter(item => item.time == value)
|
||||||
@@ -137,8 +171,6 @@ const setBackground = (value: string) => {
|
|||||||
return '#fff'
|
return '#fff'
|
||||||
}
|
}
|
||||||
|
|
||||||
provide('tableRef', tableRef)
|
|
||||||
|
|
||||||
provide('tableStore', tableStore)
|
provide('tableStore', tableStore)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -151,12 +183,17 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -164,8 +201,6 @@ watch(
|
|||||||
const descentClick = () => {
|
const descentClick = () => {
|
||||||
transientListRef.value.open()
|
transientListRef.value.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.el-calendar) {
|
:deep(.el-calendar) {
|
||||||
|
|||||||
@@ -1,34 +1,73 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--暂态事件概率分布 -->
|
<!--暂态事件概率分布 -->
|
||||||
|
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||||
<my-echart
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
:style="{ width: prop.width, height: `calc(${prop.height} / 2 )` }"
|
:style="{
|
||||||
|
width: prop.width,
|
||||||
|
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||||||
|
}"
|
||||||
/>
|
/>
|
||||||
<my-echart
|
<my-echart
|
||||||
class="mt10"
|
class="mt10"
|
||||||
:options="echartList1"
|
:options="echartList1"
|
||||||
:style="{ width: prop.width, height: `calc(${prop.height} / 2 - 10px)` }"
|
:style="{
|
||||||
|
width: prop.width,
|
||||||
|
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||||||
|
}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useDictData } from '@/stores/dictData'
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
const config = useConfig()
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: String },
|
w: { type: [String, Number] },
|
||||||
height: { type: String },
|
h: { type: [String, Number] },
|
||||||
timeKey: { type: String },
|
width: { type: [String, Number] },
|
||||||
|
height: { type: [String, Number] },
|
||||||
|
timeKey: { type: [String, Number] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
|
|
||||||
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
|
headerHeight.value = height
|
||||||
|
|
||||||
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
|
// 更新时间参数
|
||||||
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const config = useConfig()
|
||||||
|
|
||||||
const echartList = ref({
|
const echartList = ref({
|
||||||
options: {
|
options: {
|
||||||
xAxis: null,
|
xAxis: null,
|
||||||
@@ -308,8 +347,8 @@ const tableStore: any = new TableStore({
|
|||||||
showPage: false,
|
showPage: false,
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.data = []
|
tableStore.table.data = []
|
||||||
@@ -331,15 +370,19 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const addMenu = () => {}
|
const addMenu = () => {}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@@ -23,7 +23,15 @@
|
|||||||
<Table ref="tableRef" @cell-click="cellClickEvent" isGroup :height="height"></Table>
|
<Table ref="tableRef" @cell-click="cellClickEvent" isGroup :height="height"></Table>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- 查看波形 -->
|
<!-- 查看波形 -->
|
||||||
<HarmonicRatio ref="harmonicRatioRef" />
|
<el-dialog v-model="isWaveCharts" draggable title="瞬时/RMS波形" append-to-body width="70%">
|
||||||
|
<waveFormAnalysis
|
||||||
|
v-loading="loading"
|
||||||
|
v-if="isWaveCharts"
|
||||||
|
ref="waveFormAnalysisRef"
|
||||||
|
@handleHideCharts="isWaveCharts = false"
|
||||||
|
:wp="wp"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -32,9 +40,16 @@ import Table from '@/components/table/index.vue'
|
|||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import { mainHeight } from '@/utils/layout'
|
import { mainHeight } from '@/utils/layout'
|
||||||
import HarmonicRatio from '@/components/cockpit/listOfMainMonitoringPoints/components/harmonicRatio.vue'
|
import waveFormAnalysis from '@/views/govern/device/control/tabs/components/waveFormAnalysis.vue'
|
||||||
|
import { analyseWave } from '@/api/common'
|
||||||
const dialogVisible: any = ref(false)
|
const dialogVisible: any = ref(false)
|
||||||
const harmonicRatioRef: any = ref(null)
|
const waveFormAnalysisRef: any = ref(null)
|
||||||
|
// 波形
|
||||||
|
const isWaveCharts = ref(false)
|
||||||
|
const loading = ref(false)
|
||||||
|
const wp = ref({})
|
||||||
|
const boxoList: any = ref({})
|
||||||
|
|
||||||
const options = [
|
const options = [
|
||||||
{
|
{
|
||||||
value: '35kV进线',
|
value: '35kV进线',
|
||||||
@@ -59,7 +74,7 @@ const tableStore: any = new TableStore({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '暂态时间',
|
title: '暂态时间',
|
||||||
field: 'time',
|
field: 'time'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '测点名称',
|
title: '测点名称',
|
||||||
@@ -69,7 +84,7 @@ const tableStore: any = new TableStore({
|
|||||||
{
|
{
|
||||||
title: '暂态类型',
|
title: '暂态类型',
|
||||||
field: 'flicker',
|
field: 'flicker',
|
||||||
width: '100',
|
width: '100'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '特征幅值(%)',
|
title: '特征幅值(%)',
|
||||||
@@ -86,12 +101,12 @@ const tableStore: any = new TableStore({
|
|||||||
field: 'flicker',
|
field: 'flicker',
|
||||||
width: '100'
|
width: '100'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '严重度',
|
title: '严重度',
|
||||||
field: 'flicker',
|
field: 'flicker',
|
||||||
width: '80'
|
width: '80'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '波形',
|
title: '波形',
|
||||||
width: '100',
|
width: '100',
|
||||||
render: 'buttons',
|
render: 'buttons',
|
||||||
@@ -102,7 +117,35 @@ const tableStore: any = new TableStore({
|
|||||||
type: 'primary',
|
type: 'primary',
|
||||||
icon: 'el-icon-EditPen',
|
icon: 'el-icon-EditPen',
|
||||||
render: 'basicButton',
|
render: 'basicButton',
|
||||||
click: row => {
|
loading: 'loading1',
|
||||||
|
// disabled: row => {
|
||||||
|
// return !row.wavePath
|
||||||
|
// },
|
||||||
|
click: async row => {
|
||||||
|
row.loading1 = true
|
||||||
|
loading.value = true
|
||||||
|
isWaveCharts.value = true
|
||||||
|
await analyseWave(row.id)
|
||||||
|
.then(res => {
|
||||||
|
row.loading1 = false
|
||||||
|
if (res != undefined) {
|
||||||
|
boxoList.value = row
|
||||||
|
boxoList.value.featureAmplitude =
|
||||||
|
row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
|
||||||
|
boxoList.value.systemType = 'WX'
|
||||||
|
wp.value = res.data
|
||||||
|
}
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
row.loading1 = false
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
waveFormAnalysisRef.value &&
|
||||||
|
waveFormAnalysisRef.value.getWpData(wp.value, boxoList.value, true)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -140,11 +183,10 @@ const open = async (row: any) => {
|
|||||||
// 点击行
|
// 点击行
|
||||||
const cellClickEvent = ({ row, column }: any) => {
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
if (column.field != 'name') {
|
if (column.field != 'name') {
|
||||||
harmonicRatioRef.value.openDialog(row)
|
isWaveCharts.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
defineExpose({ open })
|
defineExpose({ open })
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@@ -1,12 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--暂态事件统计 -->
|
<!--暂态事件统计 -->
|
||||||
|
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||||
<my-echart
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
:style="{ width: prop.width, height: `calc(${prop.height} / 2 )` }"
|
:style="{
|
||||||
|
width: prop.width,
|
||||||
|
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||||||
|
}"
|
||||||
/>
|
/>
|
||||||
<Table ref="tableRef" @cell-click="cellClickEvent" :height="`calc(${prop.height} / 2 )`" isGroup></Table>
|
<Table
|
||||||
|
ref="tableRef"
|
||||||
|
@cell-click="cellClickEvent"
|
||||||
|
:height="`calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`"
|
||||||
|
isGroup
|
||||||
|
></Table>
|
||||||
<TransientStatisticsDetail ref="transientStatisticsDetailRef"></TransientStatisticsDetail>
|
<TransientStatisticsDetail ref="transientStatisticsDetailRef"></TransientStatisticsDetail>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -15,18 +24,50 @@ import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
|||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useDictData } from '@/stores/dictData'
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
import TransientStatisticsDetail from './components/transientStatisticsDetail.vue'
|
import TransientStatisticsDetail from '@/components/cockpit/transientStatistics/components/transientStatisticsDetail.vue'
|
||||||
const config = useConfig()
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: String },
|
w: { type: [String, Number] },
|
||||||
height: { type: String },
|
h: { type: [String, Number] },
|
||||||
timeKey: { type: String },
|
width: { type: [String, Number] },
|
||||||
|
height: { type: [String, Number] },
|
||||||
|
timeKey: { type: [String, Number] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
|
|
||||||
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
|
headerHeight.value = height
|
||||||
|
|
||||||
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
|
// 更新时间参数
|
||||||
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算是否全屏展示
|
||||||
|
const fullscreen = computed(() => {
|
||||||
|
const w = Number(prop.w)
|
||||||
|
const h = Number(prop.h)
|
||||||
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||||
|
// 执行相应逻辑
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const config = useConfig()
|
||||||
|
|
||||||
const data = [
|
const data = [
|
||||||
{
|
{
|
||||||
name: '电压中断',
|
name: '电压中断',
|
||||||
@@ -148,8 +189,8 @@ const tableStore: any = new TableStore({
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.data = [
|
tableStore.table.data = [
|
||||||
@@ -205,12 +246,17 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--趋势对比 -->
|
<!--趋势对比 -->
|
||||||
<TableHeader :showReset="false" @selectChange="selectChange" v-if="fullscreen">
|
<TableHeader :showReset="false" datePicker @selectChange="selectChange" v-if="fullscreen">
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="监测点名称">
|
<el-form-item label="监测点名称">
|
||||||
<el-select
|
<el-select
|
||||||
@@ -53,7 +53,10 @@
|
|||||||
<my-echart
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
:style="{ width: prop.width, height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)` }"
|
:style="{
|
||||||
|
width: prop.width,
|
||||||
|
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
||||||
|
}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -67,14 +70,19 @@ import { ElMessage, ElMessageBox } from 'element-plus'
|
|||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: String },
|
w: { type: [String, Number] },
|
||||||
h: { type: String },
|
h: { type: [String, Number] },
|
||||||
width: { type: String },
|
width: { type: [String, Number] },
|
||||||
height: { type: String },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: String },
|
timeKey: { type: [String, Number] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
const powerList: any = ref([
|
const powerList: any = ref([
|
||||||
{
|
{
|
||||||
@@ -238,8 +246,14 @@ const echartList = ref({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
const selectChange = (showSelect: any, height: any) => {
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
headerHeight.value = height
|
headerHeight.value = height
|
||||||
|
|
||||||
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
|
// 更新时间参数
|
||||||
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
|
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const tableStore: any = new TableStore({
|
const tableStore: any = new TableStore({
|
||||||
url: '/user-boot/role/selectRoleDetail?id=0',
|
url: '/user-boot/role/selectRoleDetail?id=0',
|
||||||
@@ -249,16 +263,14 @@ const tableStore: any = new TableStore({
|
|||||||
exportName: '主要监测点列表',
|
exportName: '主要监测点列表',
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
|
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
|
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.height = `calc(${prop.height} - 80px)`
|
tableStore.table.height = `calc(${prop.height} - 80px)`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const tableRef = ref()
|
|
||||||
provide('tableRef', tableRef)
|
|
||||||
tableStore.table.params.power = '1'
|
tableStore.table.params.power = '1'
|
||||||
tableStore.table.params.indicator = '1'
|
tableStore.table.params.indicator = '1'
|
||||||
tableStore.table.params.exceedingTheLimit = '1'
|
tableStore.table.params.exceedingTheLimit = '1'
|
||||||
@@ -275,12 +287,17 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue, // 监听的目标(函数形式避免直接传递 props 导致的警告)
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
tableStore.index()
|
// 当外部时间值变化时,更新表格的时间参数
|
||||||
|
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||||
|
tableStore.table.params.searchBeginTime = newVal[0]
|
||||||
|
tableStore.table.params.searchEndTime = newVal[1]
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true // 若 timeValue 是对象/数组,需开启深度监听
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
311
src/components/echarts/rmsWorker.js
Normal file
311
src/components/echarts/rmsWorker.js
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
// 辅助函数
|
||||||
|
const getMax = (temp, tempA, tempB, tempC) => {
|
||||||
|
temp = temp > tempA ? temp : tempA;
|
||||||
|
temp = temp > tempB ? temp : tempB;
|
||||||
|
if (tempC !== undefined) {
|
||||||
|
temp = temp > tempC ? temp : tempC;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getMaxTwo = (temp, tempA, tempB) => {
|
||||||
|
temp = temp > tempA ? temp : tempA;
|
||||||
|
temp = temp > tempB ? temp : tempB;
|
||||||
|
return temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getMin = (temp, tempA, tempB, tempC) => {
|
||||||
|
temp = temp < tempA ? temp : tempA;
|
||||||
|
temp = temp < tempB ? temp : tempB;
|
||||||
|
if (tempC !== undefined) {
|
||||||
|
temp = temp < tempC ? temp : tempC;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getMinOpen = (temp, tempA, tempB) => {
|
||||||
|
temp = temp < tempA ? temp : tempA;
|
||||||
|
temp = temp < tempB ? temp : tempB;
|
||||||
|
return temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 数据处理函数
|
||||||
|
const fliteWaveData = (wp, step, iphasicValue, isOpen) => {
|
||||||
|
const rmsData = wp.listRmsData;
|
||||||
|
const pt = Number(wp.pt) / 1000;
|
||||||
|
const ct = Number(wp.ct);
|
||||||
|
const titleList = wp.waveTitle;
|
||||||
|
let xishu = pt;
|
||||||
|
let aTitle = "",
|
||||||
|
bTitle = "",
|
||||||
|
cTitle = "",
|
||||||
|
unit = "电压";
|
||||||
|
let rmsvFirstX = 0,
|
||||||
|
rmsvFirstY = 0,
|
||||||
|
rmsvSecondX = 0,
|
||||||
|
rmsvSecondY = 0,
|
||||||
|
firstZhou = "a",
|
||||||
|
secondeZhou = "a";
|
||||||
|
let ifmax = 0,
|
||||||
|
ifmin = 0,
|
||||||
|
ismax = 0,
|
||||||
|
ismin = 0,
|
||||||
|
rfmax = 0,
|
||||||
|
rfmin = 0,
|
||||||
|
rsmax = 0,
|
||||||
|
rsmin = 0;
|
||||||
|
|
||||||
|
const shunshiFA = [];
|
||||||
|
const shunshiFB = [];
|
||||||
|
const shunshiFC = [];
|
||||||
|
const shunshiSA = [];
|
||||||
|
const shunshiSB = [];
|
||||||
|
const shunshiSC = [];
|
||||||
|
const rmsFA = [];
|
||||||
|
const rmsFB = [];
|
||||||
|
const rmsFC = [];
|
||||||
|
const rmsSA = [];
|
||||||
|
const rmsSB = [];
|
||||||
|
const rmsSC = [];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (titleList[iphasicValue * step + 1]?.substring(0, 1) !== "U") {
|
||||||
|
xishu = ct;
|
||||||
|
unit = "电流";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 1; i <= iphasicValue; i++) {
|
||||||
|
switch (i) {
|
||||||
|
case 1:
|
||||||
|
aTitle = titleList[iphasicValue * step + i]?.substring(1) || "";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
bTitle = titleList[iphasicValue * step + i]?.substring(1) || "";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
cTitle = titleList[iphasicValue * step + i]?.substring(1) || "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rmsData[0] && rmsData[0][iphasicValue * step + 1] !== undefined) {
|
||||||
|
rfmax = rmsData[0][iphasicValue * step + 1] * xishu;
|
||||||
|
rfmin = rmsData[0][iphasicValue * step + 1] * xishu;
|
||||||
|
rmsvFirstY = rmsData[0][iphasicValue * step + 1] * xishu;
|
||||||
|
rmsvFirstX = rmsData[0][0];
|
||||||
|
rsmax = rmsData[0][iphasicValue * step + 1];
|
||||||
|
rsmin = rmsData[0][iphasicValue * step + 1];
|
||||||
|
rmsvSecondY = rmsData[0][iphasicValue * step + 1];
|
||||||
|
rmsvSecondX = rmsData[0][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let rms = 0; rms < rmsData.length; rms++) {
|
||||||
|
if (!rmsData[rms] || rmsData[rms][iphasicValue * step + 1] === undefined) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (iphasicValue) {
|
||||||
|
case 1:
|
||||||
|
const rmsFirstA = rmsData[rms][iphasicValue * step + 1] * xishu;
|
||||||
|
rmsFA.push([rmsData[rms][0], rmsFirstA]);
|
||||||
|
rfmax = rfmax > rmsFirstA ? rfmax : rmsFirstA;
|
||||||
|
rfmin = rfmin < rmsFirstA ? rfmin : rmsFirstA;
|
||||||
|
if (rfmin < rmsvFirstY) {
|
||||||
|
rmsvFirstY = rfmin;
|
||||||
|
firstZhou = "a";
|
||||||
|
rmsvFirstX = rmsData[rms][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const rmsSecondA = rmsData[rms][iphasicValue * step + 1];
|
||||||
|
rmsSA.push([rmsData[rms][0], rmsSecondA]);
|
||||||
|
rsmax = rsmax > rmsSecondA ? rsmax : rmsSecondA;
|
||||||
|
rsmin = rsmin < rmsSecondA ? rsmin : rmsSecondA;
|
||||||
|
if (rsmin < rmsvSecondY) {
|
||||||
|
rmsvSecondY = rsmin;
|
||||||
|
secondeZhou = "a";
|
||||||
|
rmsvSecondX = rmsData[rms][0];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
const rmsFirstA2 = rmsData[rms][iphasicValue * step + 1] * xishu;
|
||||||
|
const rmsFirstB2 = rmsData[rms][iphasicValue * step + 2] * xishu;
|
||||||
|
rmsFA.push([rmsData[rms][0], rmsFirstA2]);
|
||||||
|
rmsFB.push([rmsData[rms][0], rmsFirstB2]);
|
||||||
|
rfmax = getMaxTwo(rfmax, rmsFirstA2, rmsFirstB2);
|
||||||
|
rfmin = getMinOpen(rfmin, rmsFirstA2, rmsFirstB2);
|
||||||
|
if (rfmin < rmsvFirstY) {
|
||||||
|
rmsvFirstY = rfmin;
|
||||||
|
if (rfmin === rmsFirstA2) {
|
||||||
|
firstZhou = "a";
|
||||||
|
} else if (rfmin === rmsFirstB2) {
|
||||||
|
firstZhou = "b";
|
||||||
|
}
|
||||||
|
rmsvFirstX = rmsData[rms][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const rmsSecondA2 = rmsData[rms][iphasicValue * step + 1];
|
||||||
|
const rmsSecondB2 = rmsData[rms][iphasicValue * step + 2];
|
||||||
|
rmsSA.push([rmsData[rms][0], rmsSecondA2]);
|
||||||
|
rmsSB.push([rmsData[rms][0], rmsSecondB2]);
|
||||||
|
rsmax = getMaxTwo(rsmax, rmsSecondA2, rmsSecondB2);
|
||||||
|
rsmin = getMinOpen(rsmin, rmsSecondA2, rmsSecondB2);
|
||||||
|
if (rsmin < rmsvSecondY) {
|
||||||
|
rmsvSecondY = rsmin;
|
||||||
|
if (rsmin === rmsSecondA2) {
|
||||||
|
secondeZhou = "a";
|
||||||
|
} else if (rsmin === rmsSecondB2) {
|
||||||
|
secondeZhou = "b";
|
||||||
|
}
|
||||||
|
rmsvSecondX = rmsData[rms][0];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
const rmsFirstA3 = rmsData[rms][iphasicValue * step + 1] * xishu;
|
||||||
|
const rmsFirstB3 = rmsData[rms][iphasicValue * step + 2] * xishu;
|
||||||
|
const rmsFirstC3 = rmsData[rms][iphasicValue * step + 3] * xishu;
|
||||||
|
rmsFA.push([rmsData[rms][0], rmsFirstA3]);
|
||||||
|
rmsFB.push([rmsData[rms][0], rmsFirstB3]);
|
||||||
|
rmsFC.push([rmsData[rms][0], rmsFirstC3]);
|
||||||
|
rfmax = getMax(rfmax, rmsFirstA3, rmsFirstB3, rmsFirstC3);
|
||||||
|
rfmin = isOpen
|
||||||
|
? getMinOpen(rfmin, rmsFirstA3, rmsFirstC3)
|
||||||
|
: getMin(rfmin, rmsFirstA3, rmsFirstB3, rmsFirstC3);
|
||||||
|
if (rfmin < rmsvFirstY) {
|
||||||
|
rmsvFirstY = rfmin;
|
||||||
|
if (rfmin === rmsFirstA3) {
|
||||||
|
firstZhou = "a";
|
||||||
|
} else if (rfmin === rmsFirstB3) {
|
||||||
|
firstZhou = "b";
|
||||||
|
} else {
|
||||||
|
firstZhou = "c";
|
||||||
|
}
|
||||||
|
rmsvFirstX = rmsData[rms][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const rmsSecondA3 = rmsData[rms][iphasicValue * step + 1];
|
||||||
|
const rmsSecondB3 = rmsData[rms][iphasicValue * step + 2];
|
||||||
|
const rmsSecondC3 = rmsData[rms][iphasicValue * step + 3];
|
||||||
|
rmsSA.push([rmsData[rms][0], rmsSecondA3]);
|
||||||
|
rmsSB.push([rmsData[rms][0], rmsSecondB3]);
|
||||||
|
rmsSC.push([rmsData[rms][0], rmsSecondC3]);
|
||||||
|
rsmax = getMax(rsmax, rmsSecondA3, rmsSecondB3, rmsSecondC3);
|
||||||
|
rsmin = isOpen
|
||||||
|
? getMinOpen(rsmin, rmsSecondA3, rmsSecondC3)
|
||||||
|
: getMin(rsmin, rmsSecondA3, rmsSecondB3, rmsSecondC3);
|
||||||
|
if (rsmin < rmsvSecondY) {
|
||||||
|
rmsvSecondY = rsmin;
|
||||||
|
if (rsmin === rmsSecondA3) {
|
||||||
|
secondeZhou = "a";
|
||||||
|
} else if (rsmin === rmsSecondB3) {
|
||||||
|
secondeZhou = "b";
|
||||||
|
} else {
|
||||||
|
secondeZhou = "c";
|
||||||
|
}
|
||||||
|
rmsvSecondX = rmsData[rms][0];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const instantF = { max: ifmax, min: ifmin };
|
||||||
|
const instantS = { max: ismax, min: ismin };
|
||||||
|
const RMSF = { max: rfmax, min: rfmin };
|
||||||
|
const RMSS = { max: rsmax, min: rsmin };
|
||||||
|
const RMSFMinDetail = { rmsvFirstX, rmsvFirstY, firstZhou };
|
||||||
|
const RMSSMinDetail = { rmsvSecondX, rmsvSecondY, secondeZhou };
|
||||||
|
const shunshiF = { shunshiFA, shunshiFB, shunshiFC };
|
||||||
|
const shunshiS = { shunshiSA, shunshiSB, shunshiSC };
|
||||||
|
const RMSFWave = { rmsFA, rmsFB, rmsFC };
|
||||||
|
const RMSSWave = { rmsSA, rmsSB, rmsSC };
|
||||||
|
const title = { aTitle, bTitle, cTitle, unit };
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
instantF,
|
||||||
|
instantS,
|
||||||
|
RMSF,
|
||||||
|
RMSS,
|
||||||
|
RMSFMinDetail,
|
||||||
|
RMSSMinDetail,
|
||||||
|
shunshiF,
|
||||||
|
shunshiS,
|
||||||
|
RMSFWave,
|
||||||
|
RMSSWave,
|
||||||
|
title,
|
||||||
|
unit,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听消息
|
||||||
|
self.onmessage = function (e) {
|
||||||
|
const { wp, isOpen, value, boxoList } = JSON.parse(e.data);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const iphasicValue = wp.iphasic || 1;
|
||||||
|
|
||||||
|
const picCounts = (wp.waveTitle.length - 1) / iphasicValue;
|
||||||
|
const waveDatas = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < picCounts; i++) {
|
||||||
|
const data = fliteWaveData(wp, i, iphasicValue, isOpen,boxoList);
|
||||||
|
waveDatas.push(data);
|
||||||
|
}
|
||||||
|
// 处理标题
|
||||||
|
let titles = "";
|
||||||
|
if (boxoList.systemType == "pms") {
|
||||||
|
titles =
|
||||||
|
"变电站名称:" +
|
||||||
|
boxoList.powerStationName +
|
||||||
|
" 监测点名称:" +
|
||||||
|
boxoList.measurementPointName +
|
||||||
|
" 发生时刻:" +
|
||||||
|
boxoList.startTime +
|
||||||
|
" 残余电压:" +
|
||||||
|
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||||
|
"% 持续时间:" +
|
||||||
|
boxoList.duration +
|
||||||
|
"s";
|
||||||
|
} else if (boxoList.systemType == "ZL") {
|
||||||
|
titles =
|
||||||
|
" 监测点名称:" +
|
||||||
|
boxoList.equipmentName +
|
||||||
|
" 发生时刻:" +
|
||||||
|
boxoList.startTime +
|
||||||
|
" 残余电压:" +
|
||||||
|
boxoList.evtParamVVaDepth +
|
||||||
|
" 持续时间:" +
|
||||||
|
boxoList.evtParamTm +
|
||||||
|
"s";
|
||||||
|
} else {
|
||||||
|
titles =
|
||||||
|
"变电站名称:" +
|
||||||
|
boxoList.subName +
|
||||||
|
" 监测点名称:" +
|
||||||
|
boxoList.lineName +
|
||||||
|
" 发生时刻:" +
|
||||||
|
boxoList.startTime +
|
||||||
|
" 残余电压:" +
|
||||||
|
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||||
|
"% 持续时间:" +
|
||||||
|
boxoList.duration +
|
||||||
|
"s";
|
||||||
|
}
|
||||||
|
// 发送处理结果回主线程
|
||||||
|
self.postMessage({
|
||||||
|
titles: titles,
|
||||||
|
success: true,
|
||||||
|
waveDatas,
|
||||||
|
time: wp.time,
|
||||||
|
type: wp.waveType,
|
||||||
|
severity: wp.yzd,
|
||||||
|
iphasic: iphasicValue,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
self.postMessage({
|
||||||
|
success: false,
|
||||||
|
error: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
File diff suppressed because it is too large
Load Diff
1596
src/components/echarts/rmsboxi1.vue
Normal file
1596
src/components/echarts/rmsboxi1.vue
Normal file
File diff suppressed because it is too large
Load Diff
179
src/components/echarts/shuWorker.js
Normal file
179
src/components/echarts/shuWorker.js
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
// waveData.worker.js
|
||||||
|
self.addEventListener('message', function(e) {
|
||||||
|
const { wp, value, iphasic, isOpen, boxoList } = JSON.parse(e.data);
|
||||||
|
|
||||||
|
// 处理波形数据的函数
|
||||||
|
const fliteWaveData = (wp, step) => {
|
||||||
|
// 将原有的fliteWaveData函数实现复制到这里
|
||||||
|
const shunData = wp.listWaveData;
|
||||||
|
const pt = Number(wp.pt) / 1000;
|
||||||
|
const ct = Number(wp.ct);
|
||||||
|
const titleList = wp.waveTitle;
|
||||||
|
let xishu = pt;
|
||||||
|
let aTitle = '', bTitle = '', cTitle = '', unit = '电压';
|
||||||
|
let ifmax = 0, ifmin = 0, ismax = 0, ismin = 0;
|
||||||
|
|
||||||
|
const shunshiFA = [];
|
||||||
|
const shunshiFB = [];
|
||||||
|
const shunshiFC = [];
|
||||||
|
const shunshiSA = [];
|
||||||
|
const shunshiSB = [];
|
||||||
|
const shunshiSC = [];
|
||||||
|
|
||||||
|
if (shunData.length > 0) {
|
||||||
|
if (titleList[iphasic * step + 1]?.substring(0, 1) !== 'U') {
|
||||||
|
xishu = ct;
|
||||||
|
unit = '电流';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 1; i <= iphasic; i++) {
|
||||||
|
switch (i) {
|
||||||
|
case 1:
|
||||||
|
aTitle = titleList[iphasic * step + i]?.substring(1) || '';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
bTitle = titleList[iphasic * step + i]?.substring(1) || '';
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
cTitle = titleList[iphasic * step + i]?.substring(1) || '';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shunData[0][iphasic * step + 1] !== undefined) {
|
||||||
|
ifmax = shunData[0][iphasic * step + 1] * xishu;
|
||||||
|
ifmin = shunData[0][iphasic * step + 1] * xishu;
|
||||||
|
ismax = shunData[0][iphasic * step + 1];
|
||||||
|
ismin = shunData[0][iphasic * step + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let shun = 0; shun < shunData.length; shun++) {
|
||||||
|
if (shunData[shun][iphasic * step + 1] === undefined) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (iphasic) {
|
||||||
|
case 1:
|
||||||
|
const shunFirstA = shunData[shun][iphasic * step + 1] * xishu;
|
||||||
|
shunshiFA.push([shunData[shun][0], shunFirstA]);
|
||||||
|
ifmax = Math.max(ifmax, shunFirstA);
|
||||||
|
ifmin = Math.min(ifmin, shunFirstA);
|
||||||
|
|
||||||
|
const shunSecondA = shunData[shun][iphasic * step + 1];
|
||||||
|
shunshiSA.push([shunData[shun][0], shunSecondA]);
|
||||||
|
ismax = Math.max(ismax, shunSecondA);
|
||||||
|
ismin = Math.min(ismin, shunSecondA);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
const shunFirstA2 = shunData[shun][iphasic * step + 1] * xishu;
|
||||||
|
const shunFirstB2 = shunData[shun][iphasic * step + 2] * xishu;
|
||||||
|
shunshiFA.push([shunData[shun][0], shunFirstA2]);
|
||||||
|
shunshiFB.push([shunData[shun][0], shunFirstB2]);
|
||||||
|
ifmax = Math.max(ifmax, shunFirstA2, shunFirstB2);
|
||||||
|
ifmin = Math.min(ifmin, shunFirstA2, shunFirstB2);
|
||||||
|
|
||||||
|
const shunSecondA2 = shunData[shun][iphasic * step + 1];
|
||||||
|
const shunSecondB2 = shunData[shun][iphasic * step + 2];
|
||||||
|
shunshiSA.push([shunData[shun][0], shunSecondA2]);
|
||||||
|
shunshiSB.push([shunData[shun][0], shunSecondB2]);
|
||||||
|
ismax = Math.max(ismax, shunSecondA2, shunSecondB2);
|
||||||
|
ismin = Math.min(ismin, shunSecondA2, shunSecondB2);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
const shunFirstA3 = shunData[shun][iphasic * step + 1] * xishu;
|
||||||
|
const shunFirstB3 = shunData[shun][iphasic * step + 2] * xishu;
|
||||||
|
const shunFirstC3 = shunData[shun][iphasic * step + 3] * xishu;
|
||||||
|
shunshiFA.push([shunData[shun][0], shunFirstA3]);
|
||||||
|
shunshiFB.push([shunData[shun][0], shunFirstB3]);
|
||||||
|
shunshiFC.push([shunData[shun][0], shunFirstC3]);
|
||||||
|
ifmax = Math.max(ifmax, shunFirstA3, shunFirstB3, shunFirstC3);
|
||||||
|
ifmin = isOpen ? Math.min(ifmin, shunFirstA3, shunFirstC3) : Math.min(ifmin, shunFirstA3, shunFirstB3, shunFirstC3);
|
||||||
|
|
||||||
|
const shunSecondA3 = shunData[shun][iphasic * step + 1];
|
||||||
|
const shunSecondB3 = shunData[shun][iphasic * step + 2];
|
||||||
|
const shunSecondC3 = shunData[shun][iphasic * step + 3];
|
||||||
|
shunshiSA.push([shunData[shun][0], shunSecondA3]);
|
||||||
|
shunshiSB.push([shunData[shun][0], shunSecondB3]);
|
||||||
|
shunshiSC.push([shunData[shun][0], shunSecondC3]);
|
||||||
|
ismax = Math.max(ismax, shunSecondA3, shunSecondB3, shunSecondC3);
|
||||||
|
ismin = isOpen ? Math.min(ismin, shunSecondA3, shunSecondC3) : Math.min(ismin, shunSecondA3, shunSecondB3, shunSecondC3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const instantF = { max: ifmax, min: ifmin };
|
||||||
|
const instantS = { max: ismax, min: ismin };
|
||||||
|
const shunshiF = { shunshiFA, shunshiFB, shunshiFC };
|
||||||
|
const shunshiS = { shunshiSA, shunshiSB, shunshiSC };
|
||||||
|
const title = { aTitle, bTitle, cTitle, unit };
|
||||||
|
|
||||||
|
return { instantF, instantS, shunshiF, shunshiS, title, unit };
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理标题
|
||||||
|
let titles = '';
|
||||||
|
if (boxoList.systemType == 'pms') {
|
||||||
|
titles = '变电站名称:' +
|
||||||
|
boxoList.powerStationName +
|
||||||
|
' 监测点名称:' +
|
||||||
|
boxoList.measurementPointName +
|
||||||
|
' 发生时刻:' +
|
||||||
|
boxoList.startTime +
|
||||||
|
' 残余电压:' +
|
||||||
|
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||||
|
'% 持续时间:' +
|
||||||
|
boxoList.duration +
|
||||||
|
's';
|
||||||
|
} else if (boxoList.systemType == 'ZL') {
|
||||||
|
titles = ' 监测点名称:' +
|
||||||
|
boxoList.equipmentName +
|
||||||
|
' 发生时刻:' +
|
||||||
|
boxoList.startTime +
|
||||||
|
' 残余电压:' +
|
||||||
|
boxoList.evtParamVVaDepth +
|
||||||
|
' 持续时间:' +
|
||||||
|
boxoList.evtParamTm +
|
||||||
|
's';
|
||||||
|
} else {
|
||||||
|
titles = '变电站名称:' +
|
||||||
|
boxoList.subName +
|
||||||
|
' 监测点名称:' +
|
||||||
|
boxoList.lineName +
|
||||||
|
' 发生时刻:' +
|
||||||
|
boxoList.startTime +
|
||||||
|
' 残余电压:' +
|
||||||
|
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||||
|
'% 持续时间:' +
|
||||||
|
boxoList.duration +
|
||||||
|
's';
|
||||||
|
}
|
||||||
|
|
||||||
|
const iphasicValue = wp.iphasic || 1;
|
||||||
|
const picCounts = (wp.waveTitle.length - 1) / iphasicValue;
|
||||||
|
const waveDatas = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < picCounts; i++) {
|
||||||
|
const data = fliteWaveData(wp, i);
|
||||||
|
waveDatas.push(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const time = wp.time;
|
||||||
|
const type = wp.waveType;
|
||||||
|
let severity = wp.yzd;
|
||||||
|
|
||||||
|
if (severity < 0) {
|
||||||
|
severity = '/';
|
||||||
|
type = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将处理结果发送回主线程
|
||||||
|
self.postMessage({
|
||||||
|
waveDatas,
|
||||||
|
time,
|
||||||
|
type,
|
||||||
|
severity,
|
||||||
|
titles,
|
||||||
|
iphasic: iphasicValue
|
||||||
|
});
|
||||||
|
});
|
||||||
File diff suppressed because it is too large
Load Diff
1201
src/components/echarts/shushiboxi1.vue
Normal file
1201
src/components/echarts/shushiboxi1.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="width: 540px">
|
<div style="width: 540px">
|
||||||
<el-select v-model.trim="interval" style="min-width: 90px; width: 90px; margin-right: 10px"
|
<el-select
|
||||||
@change="timeChange">
|
v-model.trim="interval"
|
||||||
|
style="min-width: 90px; width: 90px; margin-right: 10px"
|
||||||
|
@change="timeChange"
|
||||||
|
>
|
||||||
<el-option v-for="item in timeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
<el-option v-for="item in timeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
||||||
<el-date-picker v-model.trim="timeValue" type="daterange" :disabled="disabledPicker"
|
<el-date-picker
|
||||||
style="width: 220px; margin-right: 10px" unlink-panels :clearable="false" range-separator="至"
|
v-model.trim="timeValue"
|
||||||
start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" :shortcuts="shortcuts" />
|
type="daterange"
|
||||||
|
:disabled="disabledPicker"
|
||||||
|
style="width: 220px; margin-right: 10px"
|
||||||
|
unlink-panels
|
||||||
|
:clearable="false"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
:shortcuts="shortcuts"
|
||||||
|
/>
|
||||||
<el-button :disabled="backDisabled" type="primary" :icon="DArrowLeft" @click="preClick"></el-button>
|
<el-button :disabled="backDisabled" type="primary" :icon="DArrowLeft" @click="preClick"></el-button>
|
||||||
<el-button type="primary" :icon="VideoPause" @click="nowTime">当前</el-button>
|
<el-button type="primary" :icon="VideoPause" @click="nowTime">当前</el-button>
|
||||||
<el-button :disabled="preDisabled" type="primary" :icon="DArrowRight" @click="next"></el-button>
|
<el-button :disabled="preDisabled" type="primary" :icon="DArrowRight" @click="next"></el-button>
|
||||||
@@ -21,13 +34,19 @@ import { ref, onMounted, nextTick, watch } from 'vue'
|
|||||||
interface Props {
|
interface Props {
|
||||||
nextFlag?: boolean
|
nextFlag?: boolean
|
||||||
theCurrentTime?: boolean
|
theCurrentTime?: boolean
|
||||||
|
initialInterval?: number
|
||||||
|
initialTimeValue?: any
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
nextFlag: false,
|
nextFlag: false,
|
||||||
theCurrentTime: true
|
theCurrentTime: true,
|
||||||
|
initialInterval: 3,
|
||||||
|
initialTimeValue: undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['change'])
|
||||||
|
|
||||||
const interval = ref(3)
|
const interval = ref(3)
|
||||||
const timeFlag = ref(1)
|
const timeFlag = ref(1)
|
||||||
const count = ref(0)
|
const count = ref(0)
|
||||||
@@ -72,8 +91,27 @@ const shortcuts = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
// 使用传入的初始值
|
||||||
|
if (props.initialInterval !== undefined) {
|
||||||
|
interval.value = props.initialInterval
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.initialTimeValue) {
|
||||||
|
timeValue.value = props.initialTimeValue
|
||||||
|
}
|
||||||
timeChange(3)
|
timeChange(3)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 添加统一的事件触发方法
|
||||||
|
const emitChange = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
emit('change', {
|
||||||
|
interval: interval.value,
|
||||||
|
timeValue: timeValue.value,
|
||||||
|
timeFlag: timeFlag.value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
// 选择时间范围
|
// 选择时间范围
|
||||||
const timeChange = (e: number) => {
|
const timeChange = (e: number) => {
|
||||||
backDisabled.value = false
|
backDisabled.value = false
|
||||||
@@ -110,6 +148,8 @@ const timeChange = (e: number) => {
|
|||||||
} else {
|
} else {
|
||||||
timeFlag.value = 1
|
timeFlag.value = 1
|
||||||
}
|
}
|
||||||
|
// 触发 change 事件
|
||||||
|
emitChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前
|
// 当前
|
||||||
@@ -178,6 +218,9 @@ const preClick = () => {
|
|||||||
// 判断向后键的状态
|
// 判断向后键的状态
|
||||||
// var temp = NowgetEndTime()
|
// var temp = NowgetEndTime()
|
||||||
// timeStatus(temp, endTime)
|
// timeStatus(temp, endTime)
|
||||||
|
|
||||||
|
// 触发 change 事件
|
||||||
|
emitChange()
|
||||||
}
|
}
|
||||||
//下一个
|
//下一个
|
||||||
const next = () => {
|
const next = () => {
|
||||||
@@ -383,7 +426,6 @@ const next = () => {
|
|||||||
if (year >= presentY && !props.nextFlag) {
|
if (year >= presentY && !props.nextFlag) {
|
||||||
startTime = presentY + '-01-01'
|
startTime = presentY + '-01-01'
|
||||||
if (presentM < 10) {
|
if (presentM < 10) {
|
||||||
|
|
||||||
if (presentD < 10) {
|
if (presentD < 10) {
|
||||||
endTime = presentY + '-0' + presentM + '-0' + presentD
|
endTime = presentY + '-0' + presentM + '-0' + presentD
|
||||||
} else {
|
} else {
|
||||||
@@ -400,18 +442,31 @@ const next = () => {
|
|||||||
startTime = year + '-01-01'
|
startTime = year + '-01-01'
|
||||||
endTime = year + '-12-31'
|
endTime = year + '-12-31'
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!props.nextFlag) {
|
if (!props.nextFlag) {
|
||||||
if (new Date(endTime + ' 00:00:00').getTime() >= new Date(window.XEUtils.toDateString(new Date(), 'yyyy-MM-dd ') + ' 00:00:00').getTime()) {
|
if (
|
||||||
|
new Date(endTime + ' 00:00:00').getTime() >=
|
||||||
|
new Date(window.XEUtils.toDateString(new Date(), 'yyyy-MM-dd ') + ' 00:00:00').getTime()
|
||||||
|
) {
|
||||||
preDisabled.value = true
|
preDisabled.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
timeValue.value = [startTime, endTime]
|
timeValue.value = [startTime, endTime]
|
||||||
|
|
||||||
|
// 触发 change 事件
|
||||||
|
emitChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 监听值变化并触发事件
|
||||||
|
watch(
|
||||||
|
[interval, timeValue],
|
||||||
|
() => {
|
||||||
|
emitChange()
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
const setTime = (flag = 0, e = 0) => {
|
const setTime = (flag = 0, e = 0) => {
|
||||||
let dd = window.XEUtils.toDateString(new Date().getTime() - e * 3600 * 1000 * 24, 'dd')
|
let dd = window.XEUtils.toDateString(new Date().getTime() - e * 3600 * 1000 * 24, 'dd')
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,12 @@
|
|||||||
:inline="true"
|
:inline="true"
|
||||||
>
|
>
|
||||||
<el-form-item label="日期" v-if="datePicker" style="grid-column: span 2; max-width: 570px">
|
<el-form-item label="日期" v-if="datePicker" style="grid-column: span 2; max-width: 570px">
|
||||||
<DatePicker ref="datePickerRef" :nextFlag="nextFlag" :theCurrentTime="theCurrentTime"></DatePicker>
|
<DatePicker
|
||||||
|
ref="datePickerRef"
|
||||||
|
:nextFlag="nextFlag"
|
||||||
|
:theCurrentTime="theCurrentTime"
|
||||||
|
@change="handleDatePickerChange"
|
||||||
|
></DatePicker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="区域" v-if="area">
|
<el-form-item label="区域" v-if="area">
|
||||||
@@ -57,6 +62,9 @@ import { mainHeight } from '@/utils/layout'
|
|||||||
import { useDictData } from '@/stores/dictData'
|
import { useDictData } from '@/stores/dictData'
|
||||||
import { Search, RefreshLeft } from '@element-plus/icons-vue'
|
import { Search, RefreshLeft } from '@element-plus/icons-vue'
|
||||||
import { defineProps } from 'vue'
|
import { defineProps } from 'vue'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
const emit = defineEmits(['selectChange'])
|
const emit = defineEmits(['selectChange'])
|
||||||
|
|
||||||
const tableStore = inject('tableStore') as TableStore
|
const tableStore = inject('tableStore') as TableStore
|
||||||
@@ -67,6 +75,11 @@ const areaRef = ref()
|
|||||||
const headerForm = ref()
|
const headerForm = ref()
|
||||||
const headerFormSecond = ref()
|
const headerFormSecond = ref()
|
||||||
const num = ref(0)
|
const num = ref(0)
|
||||||
|
|
||||||
|
// 获取路由和缓存 store
|
||||||
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
datePicker?: boolean
|
datePicker?: boolean
|
||||||
area?: boolean
|
area?: boolean
|
||||||
@@ -86,6 +99,18 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
showReset: true,
|
showReset: true,
|
||||||
showExport: false
|
showExport: false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 处理 DatePicker 值变化事件
|
||||||
|
const handleDatePickerChange = (value: any) => {
|
||||||
|
// 将值缓存到 timeCache
|
||||||
|
// if (value) {
|
||||||
|
// timeCacheStore.setCache(route.path, value.interval, value.timeValue)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 将 datePicker 的变化传递给父组件
|
||||||
|
emit('selectChange', true, tableHeader.value.offsetHeight, value)
|
||||||
|
}
|
||||||
|
|
||||||
// 动态计算table高度
|
// 动态计算table高度
|
||||||
let resizeObserver = new ResizeObserver(entries => {
|
let resizeObserver = new ResizeObserver(entries => {
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
@@ -105,16 +130,31 @@ const headerFormSecondStyleClose = {
|
|||||||
padding: '0'
|
padding: '0'
|
||||||
}
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (props.datePicker && tableStore) {
|
// 设置初始值到 DatePicker
|
||||||
tableStore.table.params.searchBeginTime = datePickerRef.value?.timeValue[0]
|
if (props.datePicker && datePickerRef.value) {
|
||||||
tableStore.table.params.searchEndTime = datePickerRef.value?.timeValue[1]
|
// 从缓存中获取值并设置
|
||||||
tableStore.table.params.startTime = datePickerRef.value?.timeValue[0]
|
const cached = timeCacheStore.getCache(route.path)
|
||||||
tableStore.table.params.endTime = datePickerRef.value?.timeValue[1]
|
if (cached) {
|
||||||
|
if (cached.interval !== undefined) {
|
||||||
|
datePickerRef.value.setInterval(cached.interval)
|
||||||
|
}
|
||||||
|
if (cached.timeValue) {
|
||||||
|
datePickerRef.value.timeValue = cached.timeValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新 tableStore 参数
|
||||||
|
tableStore.table.params.searchBeginTime = datePickerRef.value?.timeValue?.[0]
|
||||||
|
tableStore.table.params.searchEndTime = datePickerRef.value?.timeValue?.[1]
|
||||||
|
tableStore.table.params.startTime = datePickerRef.value?.timeValue?.[0]
|
||||||
|
tableStore.table.params.endTime = datePickerRef.value?.timeValue?.[1]
|
||||||
tableStore.table.params.timeFlag = datePickerRef.value?.timeFlag
|
tableStore.table.params.timeFlag = datePickerRef.value?.timeFlag
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.area) {
|
if (props.area) {
|
||||||
tableStore.table.params.deptIndex = dictData.state.area[0].id
|
tableStore.table.params.deptIndex = dictData.state.area[0].id
|
||||||
}
|
}
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
resizeObserver.observe(tableHeader.value)
|
resizeObserver.observe(tableHeader.value)
|
||||||
computedSearchRow()
|
computedSearchRow()
|
||||||
@@ -189,12 +229,29 @@ const onResetForm = () => {
|
|||||||
const setInterval = (val: any) => {
|
const setInterval = (val: any) => {
|
||||||
datePickerRef.value.setInterval(val)
|
datePickerRef.value.setInterval(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setTimeInterval = (val: any) => {
|
||||||
|
datePickerRef.value.timeValue = val
|
||||||
|
tableStore.table.params.searchBeginTime = val[0]
|
||||||
|
tableStore.table.params.searchEndTime = val[1]
|
||||||
|
tableStore.table.params.startTime = val[0]
|
||||||
|
tableStore.table.params.endTime = val[1]
|
||||||
|
}
|
||||||
// 导出
|
// 导出
|
||||||
const onExport = () => {
|
const onExport = () => {
|
||||||
tableStore.onTableAction('export', { showAllFlag: true })
|
tableStore.onTableAction('export', { showAllFlag: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ onComSearch, areaRef, setDatePicker, setInterval, datePickerRef, showSelectChange, computedSearchRow })
|
defineExpose({
|
||||||
|
onComSearch,
|
||||||
|
areaRef,
|
||||||
|
setDatePicker,
|
||||||
|
setInterval,
|
||||||
|
setTimeInterval,
|
||||||
|
datePickerRef,
|
||||||
|
showSelectChange,
|
||||||
|
computedSearchRow
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -1,24 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :style="{ height: typeof props.height === 'string' ? props.height : tableStore.table.height }">
|
<div :style="{ height: typeof props.height === 'string' ? props.height : tableStore.table.height }">
|
||||||
<vxe-table ref="tableRef" height="auto" :key="key" :data="tableStore.table.data"
|
<vxe-table
|
||||||
v-loading="tableStore.table.loading" v-bind="Object.assign({}, defaultAttribute, $attrs)"
|
ref="tableRef"
|
||||||
@checkbox-all="selectChangeEvent" @checkbox-change="selectChangeEvent" :showOverflow="showOverflow"
|
height="auto"
|
||||||
:sort-config="{ remote: true }" @sort-change="handleSortChange">
|
:key="key"
|
||||||
|
:data="tableStore.table.data"
|
||||||
|
v-loading="tableStore.table.loading"
|
||||||
|
v-bind="Object.assign({}, defaultAttribute, $attrs)"
|
||||||
|
@checkbox-all="selectChangeEvent"
|
||||||
|
@checkbox-change="selectChangeEvent"
|
||||||
|
:showOverflow="showOverflow"
|
||||||
|
:sort-config="{ remote: true }"
|
||||||
|
@sort-change="handleSortChange"
|
||||||
|
>
|
||||||
|
|
||||||
<!-- Column 组件内部是 el-table-column -->
|
<!-- Column 组件内部是 el-table-column -->
|
||||||
<template v-if="isGroup">
|
<template v-if="isGroup">
|
||||||
<GroupColumn :column="tableStore.table.column" />
|
<GroupColumn :column="tableStore.table.column" />
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<Column :attr="item" :key="key + '-column'" v-for="(item, key) in tableStore.table.column"
|
<Column
|
||||||
:tree-node="item.treeNode">
|
:attr="item"
|
||||||
|
:key="key + '-column'"
|
||||||
|
v-for="(item, key) in tableStore.table.column"
|
||||||
|
:tree-node="item.treeNode"
|
||||||
|
>
|
||||||
<!-- tableStore 预设的列 render 方案 -->
|
<!-- tableStore 预设的列 render 方案 -->
|
||||||
<template v-if="item.render" #default="scope">
|
<template v-if="item.render" #default="scope">
|
||||||
<FieldRender :field="item" :row="scope.row" :column="scope.column" :index="scope.rowIndex" :key="key +
|
<FieldRender
|
||||||
'-' +
|
:field="item"
|
||||||
item.render +
|
:row="scope.row"
|
||||||
'-' +
|
:column="scope.column"
|
||||||
(item.field ? '-' + item.field + '-' + scope.row[item.field] : '')
|
:index="scope.rowIndex"
|
||||||
" />
|
:key="
|
||||||
|
key +
|
||||||
|
'-' +
|
||||||
|
item.render +
|
||||||
|
'-' +
|
||||||
|
(item.field ? '-' + item.field + '-' + scope.row[item.field] : '')
|
||||||
|
"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
</template>
|
</template>
|
||||||
@@ -27,11 +48,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="tableStore.showPage" class="table-pagination">
|
<div v-if="tableStore.showPage" class="table-pagination">
|
||||||
<el-pagination :currentPage="tableStore.table.params!.pageNum" :page-size="tableStore.table.params!.pageSize"
|
<el-pagination
|
||||||
:page-sizes="pageSizes" background
|
:currentPage="tableStore.table.params!.pageNum"
|
||||||
|
:page-size="tableStore.table.params!.pageSize"
|
||||||
|
:page-sizes="pageSizes"
|
||||||
|
background
|
||||||
:layout="config.layout.shrink ? 'prev, next, jumper' : 'sizes,total, ->, prev, pager, next, jumper'"
|
:layout="config.layout.shrink ? 'prev, next, jumper' : 'sizes,total, ->, prev, pager, next, jumper'"
|
||||||
:total="tableStore.table.total" @size-change="onTableSizeChange"
|
:total="tableStore.table.total"
|
||||||
@current-change="onTableCurrentChange"></el-pagination>
|
@size-change="onTableSizeChange"
|
||||||
|
@current-change="onTableCurrentChange"
|
||||||
|
></el-pagination>
|
||||||
</div>
|
</div>
|
||||||
<slot name="footer"></slot>
|
<slot name="footer"></slot>
|
||||||
</template>
|
</template>
|
||||||
@@ -66,6 +92,8 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
})
|
})
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
tableStore.table.ref = tableRef.value as VxeTableInstance
|
tableStore.table.ref = tableRef.value as VxeTableInstance
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
// console.log(props)
|
// console.log(props)
|
||||||
const onTableSizeChange = (val: number) => {
|
const onTableSizeChange = (val: number) => {
|
||||||
@@ -125,6 +153,7 @@ watch(
|
|||||||
() => tableStore.table.allFlag,
|
() => tableStore.table.allFlag,
|
||||||
newVal => {
|
newVal => {
|
||||||
if (tableStore.table.allFlag) {
|
if (tableStore.table.allFlag) {
|
||||||
|
console.log('🚀 ~ tableStore.table.allData:', tableStore.table.allData)
|
||||||
|
|
||||||
tableRef.value?.exportData({
|
tableRef.value?.exportData({
|
||||||
filename: tableStore.exportName || document.querySelectorAll('.ba-nav-tab.active')[0].textContent || '', // 文件名字
|
filename: tableStore.exportName || document.querySelectorAll('.ba-nav-tab.active')[0].textContent || '', // 文件名字
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
:class="menuCollapse ? 'unfold' : ''" size='18' class='fold ml10 menu-collapse'
|
:class="menuCollapse ? 'unfold' : ''" size='18' class='fold ml10 menu-collapse'
|
||||||
style='cursor: pointer' v-if='props.canExpand' /> -->
|
style='cursor: pointer' v-if='props.canExpand' /> -->
|
||||||
</div>
|
</div>
|
||||||
<el-tree :style="{ height: 'calc(100vh - 200px)' }"
|
<el-tree :style="{ height: 'calc(100vh - 110px)' }"
|
||||||
style=' overflow: auto;' ref='treeRef' :props='defaultProps' highlight-current
|
style=' overflow: auto;' ref='treeRef' :props='defaultProps' highlight-current :default-expand-all="false"
|
||||||
@check-change="checkTreeNodeChange" :filter-node-method='filterNode' node-key='id' v-bind='$attrs'>
|
@check-change="checkTreeNodeChange" :filter-node-method='filterNode' node-key='id' v-bind='$attrs'>
|
||||||
<template #default='{ node, data }'>
|
<template #default='{ node, data }'>
|
||||||
<span class='custom-tree-node'>
|
<span class='custom-tree-node'>
|
||||||
@@ -75,7 +75,6 @@ const filterNode = (value: string, data: any, node: any) => {
|
|||||||
|
|
||||||
// 过滤父节点 / 子节点 (如果输入的参数是父节点且能匹配,则返回该节点以及其下的所有子节点;如果参数是子节点,则返回该节点的父节点。name是中文字符,enName是英文字符.
|
// 过滤父节点 / 子节点 (如果输入的参数是父节点且能匹配,则返回该节点以及其下的所有子节点;如果参数是子节点,则返回该节点的父节点。name是中文字符,enName是英文字符.
|
||||||
const chooseNode = (value: string, data: any, node: any) => {
|
const chooseNode = (value: string, data: any, node: any) => {
|
||||||
|
|
||||||
if (data.name.indexOf(value) !== -1) {
|
if (data.name.indexOf(value) !== -1) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getMarketList } from '@/api/user-boot/user'
|
import { getMarketList } from '@/api/user-boot/user'
|
||||||
import Tree from '../index.vue'
|
import Tree from '../cloudDevice.vue'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
import { ref, reactive, nextTick } from 'vue'
|
import { ref, reactive, nextTick } from 'vue'
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
|
|||||||
29
src/components/tree/govern/officialUserTree.vue
Normal file
29
src/components/tree/govern/officialUserTree.vue
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<Tree ref="treRef" :data="tree" />
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { getFormalUserList } from '@/api/user-boot/official'
|
||||||
|
import Tree from '../cloudDevice.vue'
|
||||||
|
import { useConfig } from '@/stores/config'
|
||||||
|
import { ref, reactive, nextTick } from 'vue'
|
||||||
|
const config = useConfig()
|
||||||
|
const tree = ref()
|
||||||
|
const treRef = ref()
|
||||||
|
const emit = defineEmits(['selectUser'])
|
||||||
|
getFormalUserList().then((res: any) => {
|
||||||
|
if (res.code === 'A0000') {
|
||||||
|
tree.value = res.data.map((item: any) => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
icon: 'el-icon-User',
|
||||||
|
color: 'royalblue'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
emit('selectUser', tree.value[0])
|
||||||
|
nextTick(() => {
|
||||||
|
treRef.value.treeRef.setCurrentKey(tree.value[0].id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-tree :style="{ height: 'calc(100vh - 200px)' }"
|
<el-tree :style="{ height: 'calc(100vh - 200px)' }"
|
||||||
style=' overflow: auto;' ref='treeRef' :props='defaultProps' highlight-current
|
style=' overflow: auto;' ref='treeRef' :props='defaultProps' highlight-current :default-expand-all="false"
|
||||||
@check-change="checkTreeNodeChange" :filter-node-method='filterNode' node-key='id' v-bind='$attrs'>
|
@check-change="checkTreeNodeChange" :filter-node-method='filterNode' node-key='id' v-bind='$attrs'>
|
||||||
<template #default='{ node, data }'>
|
<template #default='{ node, data }'>
|
||||||
<span class='custom-tree-node'>
|
<span class='custom-tree-node'>
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
@node-click="handleNodeClick"
|
@node-click="handleNodeClick"
|
||||||
:default-checked-keys="defaultCheckedKeys"
|
:default-checked-keys="defaultCheckedKeys"
|
||||||
v-bind='$attrs'
|
v-bind='$attrs'
|
||||||
|
:default-expand-all="false"
|
||||||
>
|
>
|
||||||
<template #default='{ node, data }'>
|
<template #default='{ node, data }'>
|
||||||
<span class='custom-tree-node'>
|
<span class='custom-tree-node'>
|
||||||
@@ -119,8 +120,69 @@ const handleNodeClick = (data: any, node: any, event: any) => {
|
|||||||
// 存储所有勾选的节点
|
// 存储所有勾选的节点
|
||||||
const checkedNodes = ref<any[]>([])
|
const checkedNodes = ref<any[]>([])
|
||||||
const defaultCheckedKeys = ref<string[]>([])
|
const defaultCheckedKeys = ref<string[]>([])
|
||||||
|
|
||||||
// 处理节点勾选变化
|
// 处理节点勾选变化
|
||||||
const handleCheckChange = (data: any, checkInfo: any) => {
|
const handleCheckChange = (data: any, checkInfo: any) => {
|
||||||
|
const { checkedNodes: nodes } = checkInfo
|
||||||
|
// 过滤出监测点层级(level=3)的节点
|
||||||
|
const monitoringPointNodes = nodes.filter((node: any) => {
|
||||||
|
return node.level === 3
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 限制最多只能勾选5个监测点
|
||||||
|
if (monitoringPointNodes.length > 5) {
|
||||||
|
// 获取之前选中的节点
|
||||||
|
const previousCheckedNodes = checkedNodes.value || []
|
||||||
|
|
||||||
|
// 计算新增的节点
|
||||||
|
const newNodes = monitoringPointNodes.filter(
|
||||||
|
(node: any) => !previousCheckedNodes.some((prev: any) => prev.id === node.id)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 如果是从父级勾选导致超过限制,保留前几个直到达到限制数量
|
||||||
|
if (newNodes.length > 0) {
|
||||||
|
const allowedNewCount = 5 - previousCheckedNodes.length
|
||||||
|
if (allowedNewCount > 0) {
|
||||||
|
// 允许添加allowedNewCount个新节点
|
||||||
|
const allowedNewNodes = newNodes.slice(0, allowedNewCount)
|
||||||
|
const finalNodes = [...previousCheckedNodes, ...allowedNewNodes]
|
||||||
|
|
||||||
|
checkedNodes.value = finalNodes
|
||||||
|
|
||||||
|
// 设置树的勾选状态为正确的节点
|
||||||
|
treeRef.value?.setCheckedNodes(finalNodes)
|
||||||
|
|
||||||
|
// 将勾选的监测点节点暴露出去
|
||||||
|
emit('checkedNodesChange', finalNodes)
|
||||||
|
|
||||||
|
// 更新节点的可勾选状态
|
||||||
|
updateNodeCheckStatus(finalNodes.length)
|
||||||
|
|
||||||
|
// 只有在真正超过5个时才提示警告
|
||||||
|
if (monitoringPointNodes.length > 5) {
|
||||||
|
ElMessage.warning('最多只能选择5个监测点')
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他情况回滚到之前的状态
|
||||||
|
ElMessage.warning('最多只能选择5个监测点')
|
||||||
|
treeRef.value?.setCheckedNodes(checkedNodes.value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
checkedNodes.value = monitoringPointNodes
|
||||||
|
|
||||||
|
// 将勾选的监测点节点暴露出去
|
||||||
|
emit('checkedNodesChange', monitoringPointNodes)
|
||||||
|
|
||||||
|
// 更新节点的可勾选状态
|
||||||
|
updateNodeCheckStatus(monitoringPointNodes.length)
|
||||||
|
}
|
||||||
|
// 处理节点勾选变化
|
||||||
|
const handleCheckChange2 = (data: any, checkInfo: any) => {
|
||||||
const { checkedNodes: nodes } = checkInfo
|
const { checkedNodes: nodes } = checkInfo
|
||||||
// 过滤出监测点层级(level=3)的节点
|
// 过滤出监测点层级(level=3)的节点
|
||||||
const monitoringPointNodes = nodes.filter((node: any) => {
|
const monitoringPointNodes = nodes.filter((node: any) => {
|
||||||
|
|||||||
34
src/stores/timeCache.ts
Normal file
34
src/stores/timeCache.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
// src/stores/timeCache.ts
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { RouteLocationNormalizedLoaded } from 'vue-router'
|
||||||
|
|
||||||
|
// 时间组件的缓存值 用于驾驶舱放大的时候和内部的时间组件同步
|
||||||
|
interface TimeCacheState {
|
||||||
|
cache: Map<string, {
|
||||||
|
interval: number | undefined // 时间组件的月份、年份、时间、时间格式的缓存值
|
||||||
|
timeValue: any // 时间组件的值
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useTimeCacheStore = defineStore('timeCache', {
|
||||||
|
state: (): TimeCacheState => ({
|
||||||
|
cache: new Map()
|
||||||
|
}),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
setCache(routePath: string, interval: number | undefined, timeValue: any) {
|
||||||
|
this.cache.set(routePath, {
|
||||||
|
interval,
|
||||||
|
timeValue
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getCache(routePath: string) {
|
||||||
|
return this.cache.get(routePath)
|
||||||
|
},
|
||||||
|
|
||||||
|
hasCache(routePath: string) {
|
||||||
|
return this.cache.has(routePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { number } from 'vue-types'
|
||||||
|
|
||||||
const dataProcessing = (arr: any[]) => {
|
const dataProcessing = (arr: any[]) => {
|
||||||
return arr
|
return arr
|
||||||
.filter(item => typeof item === 'number' || (typeof item === 'string' && !isNaN(parseFloat(item))))
|
.filter(item => typeof item === 'number' || (typeof item === 'string' && !isNaN(parseFloat(item))))
|
||||||
@@ -12,6 +14,7 @@ const calculateValue = (o: number, value: number, num: number, isMin: boolean) =
|
|||||||
} else if (value > -1 && value < 0 && isMin == false) {
|
} else if (value > -1 && value < 0 && isMin == false) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
let base
|
let base
|
||||||
if (Math.abs(o) >= 100) {
|
if (Math.abs(o) >= 100) {
|
||||||
base = 100
|
base = 100
|
||||||
@@ -20,8 +23,11 @@ const calculateValue = (o: number, value: number, num: number, isMin: boolean) =
|
|||||||
} else if (Math.abs(o) >= 1) {
|
} else if (Math.abs(o) >= 1) {
|
||||||
base = 1
|
base = 1
|
||||||
} else {
|
} else {
|
||||||
base = 0.1
|
const multiple = 1 / 0.1
|
||||||
|
|
||||||
|
base = Math.ceil(Math.abs(o) * multiple) / multiple
|
||||||
}
|
}
|
||||||
|
|
||||||
let calculatedValue
|
let calculatedValue
|
||||||
if (isMin) {
|
if (isMin) {
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
@@ -36,6 +42,7 @@ const calculateValue = (o: number, value: number, num: number, isMin: boolean) =
|
|||||||
calculatedValue = value + num * value
|
calculatedValue = value + num * value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base === 0.1) {
|
if (base === 0.1) {
|
||||||
return parseFloat(calculatedValue.toFixed(1))
|
return parseFloat(calculatedValue.toFixed(1))
|
||||||
} else if (isMin) {
|
} else if (isMin) {
|
||||||
@@ -55,8 +62,9 @@ export const yMethod = (arr: any) => {
|
|||||||
let min = 0
|
let min = 0
|
||||||
maxValue = Math.max(...numList)
|
maxValue = Math.max(...numList)
|
||||||
minValue = Math.min(...numList)
|
minValue = Math.min(...numList)
|
||||||
const o = maxValue - minValue
|
const o = maxValue - minValue == 0 ? maxValue : maxValue - minValue
|
||||||
min = calculateValue(o, minValue, num, true)
|
min = calculateValue(o, minValue, num, true)
|
||||||
|
|
||||||
max = calculateValue(o, maxValue, num, false)
|
max = calculateValue(o, maxValue, num, false)
|
||||||
// if (-100 >= minValue) {
|
// if (-100 >= minValue) {
|
||||||
// min = Math.floor((minValue + num * minValue) / 100) * 100
|
// min = Math.floor((minValue + num * minValue) / 100) * 100
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ interface TableStoreParams {
|
|||||||
publicHeight?: number //计算高度
|
publicHeight?: number //计算高度
|
||||||
resetCallback?: () => void // 重置
|
resetCallback?: () => void // 重置
|
||||||
loadCallback?: () => void // 接口调用后的回调
|
loadCallback?: () => void // 接口调用后的回调
|
||||||
|
exportProcessingData?: () => void //导出处理数据
|
||||||
beforeSearchFun?: () => void // 接口调用前的回调
|
beforeSearchFun?: () => void // 接口调用前的回调
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,9 +48,11 @@ export default class TableStore {
|
|||||||
column: [],
|
column: [],
|
||||||
loadCallback: null,
|
loadCallback: null,
|
||||||
resetCallback: null,
|
resetCallback: null,
|
||||||
|
exportProcessingData: null,
|
||||||
beforeSearchFun: null,
|
beforeSearchFun: null,
|
||||||
height: '',
|
height: '',
|
||||||
publicHeight: 0
|
publicHeight: 0,
|
||||||
|
filename: '',
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor(public options: TableStoreParams) {
|
constructor(public options: TableStoreParams) {
|
||||||
@@ -64,6 +67,7 @@ export default class TableStore {
|
|||||||
this.table.publicHeight = options.publicHeight || 0
|
this.table.publicHeight = options.publicHeight || 0
|
||||||
this.table.resetCallback = options.resetCallback || null
|
this.table.resetCallback = options.resetCallback || null
|
||||||
this.table.loadCallback = options.loadCallback || null
|
this.table.loadCallback = options.loadCallback || null
|
||||||
|
this.table.exportProcessingData = options.exportProcessingData || null
|
||||||
this.table.beforeSearchFun = options.beforeSearchFun || null
|
this.table.beforeSearchFun = options.beforeSearchFun || null
|
||||||
Object.assign(this.table.params, options.params)
|
Object.assign(this.table.params, options.params)
|
||||||
this.table.height = mainHeight(20 + (this.showPage ? 58 : 0) + this.table.publicHeight).height as string
|
this.table.height = mainHeight(20 + (this.showPage ? 58 : 0) + this.table.publicHeight).height as string
|
||||||
@@ -102,8 +106,10 @@ export default class TableStore {
|
|||||||
this.table.webPagingData = window.XEUtils.chunk(this.table.data, this.table.params.pageSize)
|
this.table.webPagingData = window.XEUtils.chunk(this.table.data, this.table.params.pageSize)
|
||||||
this.table.data = this.table.webPagingData[this.table.params.pageNum - 1]
|
this.table.data = this.table.webPagingData[this.table.params.pageNum - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
this.table.loadCallback && this.table.loadCallback()
|
this.table.loadCallback && this.table.loadCallback()
|
||||||
this.table.loading = false
|
this.table.loading = false
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.table.loading = false
|
this.table.loading = false
|
||||||
@@ -139,6 +145,7 @@ export default class TableStore {
|
|||||||
'selection-change',
|
'selection-change',
|
||||||
() => {
|
() => {
|
||||||
this.table.selection = data as TableRow[]
|
this.table.selection = data as TableRow[]
|
||||||
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -187,26 +194,21 @@ export default class TableStore {
|
|||||||
[
|
[
|
||||||
'export',
|
'export',
|
||||||
() => {
|
() => {
|
||||||
ElMessage({
|
// this.index()
|
||||||
message: '正在导出,请稍等...',
|
|
||||||
type: 'info',
|
|
||||||
duration: 1000
|
|
||||||
})
|
|
||||||
let params = { ...this.table.params, pageNum: 1, pageSize: this.table.total }
|
let params = { ...this.table.params, pageNum: 1, pageSize: this.table.total }
|
||||||
setTimeout(() => {
|
createAxios(
|
||||||
createAxios(
|
Object.assign(
|
||||||
Object.assign(
|
{
|
||||||
{
|
url: this.url,
|
||||||
url: this.url,
|
method: this.method
|
||||||
method: this.method
|
},
|
||||||
},
|
requestPayload(this.method, params, this.paramsPOST)
|
||||||
requestPayload(this.method, params, this.paramsPOST)
|
)
|
||||||
)
|
).then(res => {
|
||||||
).then(res => {
|
this.table.allData = filtration(res.data.records || res.data)
|
||||||
this.table.allData = filtration(res.data.records || res.data)
|
this.table.exportProcessingData && this.table.exportProcessingData()
|
||||||
this.table.allFlag = data.showAllFlag || true
|
this.table.allFlag = data.showAllFlag || true
|
||||||
})
|
})
|
||||||
}, 1500)
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -150,6 +150,8 @@ const checkChange = (data: any) => {
|
|||||||
updateRoleMenu({
|
updateRoleMenu({
|
||||||
id: menuListId.value,
|
id: menuListId.value,
|
||||||
idList: treeRef.value.treeRef.getCheckedNodes(false, true).map((node: any) => node.id)
|
idList: treeRef.value.treeRef.getCheckedNodes(false, true).map((node: any) => node.id)
|
||||||
|
}).then(() => {
|
||||||
|
ElMessage.success('操作成功!')
|
||||||
})
|
})
|
||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -313,6 +313,7 @@ const sourceChange = (e: any) => {
|
|||||||
tableStore.table.params.engineeringid = e[1] || ''
|
tableStore.table.params.engineeringid = e[1] || ''
|
||||||
tableStore.table.params.projectId = e[2] || ''
|
tableStore.table.params.projectId = e[2] || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// tableStore.table.params.engineeringid = e[1] || ''
|
// tableStore.table.params.engineeringid = e[1] || ''
|
||||||
|
|||||||
@@ -1068,7 +1068,7 @@ const add = () => {
|
|||||||
nodeId: '',
|
nodeId: '',
|
||||||
cntractNo: '',
|
cntractNo: '',
|
||||||
sort: 0,
|
sort: 0,
|
||||||
nodeProcess: '自动分配',
|
nodeProcess: '',
|
||||||
})
|
})
|
||||||
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
|
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
|
||||||
// 清理监测点数据
|
// 清理监测点数据
|
||||||
@@ -1325,7 +1325,7 @@ const remove = () => {
|
|||||||
message: res.message
|
message: res.message
|
||||||
})
|
})
|
||||||
reaseStatus()
|
reaseStatus()
|
||||||
console.log('engineeringId',engineeringId)
|
|
||||||
if (engineeringId) {
|
if (engineeringId) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
treedata(engineeringId)
|
treedata(engineeringId)
|
||||||
@@ -1359,7 +1359,7 @@ const remove = () => {
|
|||||||
case 4: // 监测点层级
|
case 4: // 监测点层级
|
||||||
|
|
||||||
const deviceId = nodeData.value.pids ? nodeData.value.pids.split(',')[3] : null
|
const deviceId = nodeData.value.pids ? nodeData.value.pids.split(',')[3] : null
|
||||||
console.log(deviceId)
|
|
||||||
deleteLine(nodeData.value.id).then((res: any) => {
|
deleteLine(nodeData.value.id).then((res: any) => {
|
||||||
ElMessage({
|
ElMessage({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
@@ -1421,7 +1421,7 @@ const next = async () => {
|
|||||||
nodeId: '',
|
nodeId: '',
|
||||||
cntractNo: '',
|
cntractNo: '',
|
||||||
sort: 0,
|
sort: 0,
|
||||||
nodeProcess: '自动分配',
|
nodeProcess: '',
|
||||||
})
|
})
|
||||||
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
|
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
|
||||||
nextfalg.value = false
|
nextfalg.value = false
|
||||||
@@ -1536,9 +1536,8 @@ const submitAllLevelData = () => {
|
|||||||
|
|
||||||
// 项目信息
|
// 项目信息
|
||||||
const projectData = tempAllLevelData.value.projects.length > 0
|
const projectData = tempAllLevelData.value.projects.length > 0
|
||||||
? tempAllLevelData.value.projects[0]
|
? tempAllLevelData.value.projects.find(project => project !== undefined) || {}
|
||||||
: (projectInfoList.value[0] || {})
|
: (projectInfoList.value[0] || {})
|
||||||
|
|
||||||
// 如果是从根节点开始新增工程和项目
|
// 如果是从根节点开始新增工程和项目
|
||||||
if (nodeData.value.level === 0) {
|
if (nodeData.value.level === 0) {
|
||||||
submitData = {
|
submitData = {
|
||||||
@@ -1557,10 +1556,9 @@ const submitAllLevelData = () => {
|
|||||||
case 2: // 工程 + 项目 + 设备
|
case 2: // 工程 + 项目 + 设备
|
||||||
// 工程信息
|
// 工程信息
|
||||||
const engineeringData2 = tempAllLevelData.value.engineering || { ...engineeringParam.value }
|
const engineeringData2 = tempAllLevelData.value.engineering || { ...engineeringParam.value }
|
||||||
|
|
||||||
// 项目信息
|
// 项目信息
|
||||||
const projectData2 = tempAllLevelData.value.projects.length > 0
|
const projectData2 = tempAllLevelData.value.projects.length > 0
|
||||||
? tempAllLevelData.value.projects[0]
|
? tempAllLevelData.value.projects.find(project => project !== undefined) || {}
|
||||||
: (projectInfoList.value[0] || {})
|
: (projectInfoList.value[0] || {})
|
||||||
|
|
||||||
// 设备信息
|
// 设备信息
|
||||||
@@ -1615,8 +1613,8 @@ const submitAllLevelData = () => {
|
|||||||
const engineeringData3 = tempAllLevelData.value.engineering || { ...engineeringParam.value }
|
const engineeringData3 = tempAllLevelData.value.engineering || { ...engineeringParam.value }
|
||||||
|
|
||||||
// 项目信息
|
// 项目信息
|
||||||
const projectData3 = tempAllLevelData.value.projects.length > 0
|
const projectData3 = tempAllLevelData.value.projects.length > 0
|
||||||
? tempAllLevelData.value.projects[0]
|
? tempAllLevelData.value.projects.find(project => project !== undefined) || {}
|
||||||
: (projectInfoList.value[0] || {})
|
: (projectInfoList.value[0] || {})
|
||||||
|
|
||||||
// 设备信息
|
// 设备信息
|
||||||
@@ -1771,9 +1769,8 @@ const submitAllLevelData = () => {
|
|||||||
pageStatus.value = 1
|
pageStatus.value = 1
|
||||||
// 清空所有表单
|
// 清空所有表单
|
||||||
resetAllForms()
|
resetAllForms()
|
||||||
|
|
||||||
// 刷新树并选中合适的节点
|
// 刷新树并选中合适的节点
|
||||||
TerminalRef.value.info().then(() => {
|
TerminalRef.value.info()
|
||||||
// 等待树更新完成后,根据之前点击的节点层级选中合适的节点
|
// 等待树更新完成后,根据之前点击的节点层级选中合适的节点
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
let nodeIdToSelect: string|null|undefined = null;
|
let nodeIdToSelect: string|null|undefined = null;
|
||||||
@@ -1808,7 +1805,7 @@ const submitAllLevelData = () => {
|
|||||||
treedata(); // 选中根节点
|
treedata(); // 选中根节点
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -2120,7 +2117,7 @@ const handleBusBarTabsEdit = (targetName: any, action: any) => {
|
|||||||
nodeId: '',
|
nodeId: '',
|
||||||
cntractNo: '',
|
cntractNo: '',
|
||||||
sort: 0,
|
sort: 0,
|
||||||
nodeProcess: '自动分配',
|
nodeProcess: '',
|
||||||
})
|
})
|
||||||
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
|
busBarIndex.value = (deviceInfoList.value.length - 1).toString()
|
||||||
} else if (action === 'remove') {
|
} else if (action === 'remove') {
|
||||||
@@ -2240,6 +2237,7 @@ const tabChange = (type: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const treedata = (selectedNodeId?: string) => {
|
const treedata = (selectedNodeId?: string) => {
|
||||||
|
|
||||||
if (selectedNodeId) {
|
if (selectedNodeId) {
|
||||||
TerminalRef.value.info(selectedNodeId);
|
TerminalRef.value.info(selectedNodeId);
|
||||||
} else {
|
} else {
|
||||||
@@ -2296,10 +2294,15 @@ const area = () => {
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
nodeData.value.level = 0
|
nodeData.value.level = 0
|
||||||
const dom = document.getElementById('navigation-splitpanes')
|
nextTick(() => {
|
||||||
if (dom) {
|
const dom = document.getElementById('navigation-splitpanes')
|
||||||
size.value = Math.round((180 / dom.offsetHeight) * 100)
|
if (dom && dom.offsetHeight > 0) {
|
||||||
}
|
size.value = Math.round((180 / dom.offsetHeight) * 100)
|
||||||
|
} else {
|
||||||
|
// 设置默认值
|
||||||
|
size.value = 20
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
area()
|
area()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
|
|||||||
const pageHeight = mainHeight(20)
|
const pageHeight = mainHeight(20)
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
|
|
||||||
const tableHeight = mainHeight(140)
|
const tableHeight = mainHeight(135)
|
||||||
const user: any = ref({})
|
const user: any = ref({})
|
||||||
const tableData = ref([])
|
const tableData = ref([])
|
||||||
const tableData2 = ref([])
|
const tableData2 = ref([])
|
||||||
|
|||||||
331
src/views/govern/device/officialUser/index.vue
Normal file
331
src/views/govern/device/officialUser/index.vue
Normal file
@@ -0,0 +1,331 @@
|
|||||||
|
<template>
|
||||||
|
<div class="default-main device-manage" :style="{ height: pageHeight.height }" v-loading="loading">
|
||||||
|
<OfficialUserTree @node-click="selectUser" @selectUser="selectUser"></OfficialUserTree>
|
||||||
|
<div class="device-manage-right" :style="{ height: pageHeight.height }">
|
||||||
|
<div class="el-descriptions__header">
|
||||||
|
<el-button type="primary" @click="getEnginnerDev">添加工程 / 设备</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 使用flex布局平均分配高度 -->
|
||||||
|
<div class="tables-container">
|
||||||
|
<div class="table-wrapper">
|
||||||
|
<vxe-table v-bind="defaultAttribute" :data="tableData" height="auto" style="width: 100%">
|
||||||
|
<vxe-column field="name" title="工程名称"></vxe-column>
|
||||||
|
<vxe-column title="操作" width="200px">
|
||||||
|
<template v-slot:default="scoped">
|
||||||
|
<el-button link size="small" type="danger" @click="deleteEngineering(scoped.row)">
|
||||||
|
移除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
</vxe-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 新增设备列表 -->
|
||||||
|
<div class="device-list-section table-wrapper">
|
||||||
|
<vxe-table v-bind="defaultAttribute" :data="deviceTableData" height="auto" style="width: 100%">
|
||||||
|
<vxe-column field="name" title="设备名称"></vxe-column>
|
||||||
|
<vxe-column title="操作" width="200px">
|
||||||
|
<template v-slot:default="scoped">
|
||||||
|
<el-button link size="small" type="danger" @click="deleteDevice(scoped.row)">
|
||||||
|
移除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</vxe-column>
|
||||||
|
</vxe-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 对话框为左右布局 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model.trim="dialogVisible"
|
||||||
|
title="添加工程 / 设备"
|
||||||
|
class="cn-operate-dialog"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
|
||||||
|
>
|
||||||
|
<div class="dialog-content">
|
||||||
|
<!-- 工程部分 -->
|
||||||
|
<div class="dialog-section">
|
||||||
|
<div class="section-header">
|
||||||
|
<span>工程列表</span>
|
||||||
|
<el-input
|
||||||
|
maxlength="32"
|
||||||
|
show-word-limit
|
||||||
|
v-model.trim="filterText"
|
||||||
|
placeholder="搜索工程"
|
||||||
|
clearable
|
||||||
|
class="search-input"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<Icon name="el-icon-Search" style="font-size: 16px" />
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<vxe-table
|
||||||
|
ref="tableRef"
|
||||||
|
v-bind="defaultAttribute"
|
||||||
|
:data="tableData2.filter((item: any) => {
|
||||||
|
return item.name.includes(filterText)
|
||||||
|
})"
|
||||||
|
height="400px"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<vxe-column type="checkbox" width="60"></vxe-column>
|
||||||
|
<vxe-column field="name" title="工程名称"></vxe-column>
|
||||||
|
</vxe-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 设备部分 -->
|
||||||
|
<div class="dialog-section">
|
||||||
|
<div class="section-header">
|
||||||
|
<span>设备列表</span>
|
||||||
|
<el-input
|
||||||
|
maxlength="32"
|
||||||
|
show-word-limit
|
||||||
|
v-model.trim="deviceFilterText"
|
||||||
|
placeholder="搜索设备"
|
||||||
|
clearable
|
||||||
|
class="search-input"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<Icon name="el-icon-Search" style="font-size: 16px" />
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<vxe-table
|
||||||
|
ref="deviceTableRef"
|
||||||
|
v-bind="defaultAttribute"
|
||||||
|
:data="deviceTableData2.filter((item: any) => {
|
||||||
|
return item.name.includes(deviceFilterText)
|
||||||
|
})"
|
||||||
|
height="400px"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<vxe-column type="checkbox" width="60"></vxe-column>
|
||||||
|
<vxe-column field="name" title="设备名称"></vxe-column>
|
||||||
|
</vxe-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="addData">确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineOptions({
|
||||||
|
name: 'govern/officialUser/index'
|
||||||
|
})
|
||||||
|
|
||||||
|
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||||
|
import OfficialUserTree from '@/components/tree/govern/officialUserTree.vue'
|
||||||
|
import { mainHeight } from '@/utils/layout'
|
||||||
|
import { queryRunPortableDevByUseId ,queryUnlinkEngineeringByUseId} from '@/api/cs-device-boot/user'
|
||||||
|
import { add, removeUserDev, queryDevByUseId } from '@/api/cs-system-boot/official'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
|
||||||
|
const pageHeight = mainHeight(20)
|
||||||
|
const loading = ref(true)
|
||||||
|
|
||||||
|
const user: any = ref({})
|
||||||
|
const tableData = ref([])
|
||||||
|
const deviceTableData = ref([]) // 设备表格数据
|
||||||
|
const tableData2 = ref([]) // 工程数据源
|
||||||
|
const deviceTableData2 = ref([]) // 设备数据源
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const filterText = ref('') // 工程搜索文本
|
||||||
|
const deviceFilterText = ref('') // 设备搜索文本
|
||||||
|
const tableRef = ref()
|
||||||
|
const deviceTableRef = ref() // 设备表格引用
|
||||||
|
|
||||||
|
const selectUser = (e: any) => {
|
||||||
|
user.value = e
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
|
queryDevByUseId({ userId: e.id }).then((engineeringRes) => {
|
||||||
|
loading.value = false
|
||||||
|
tableData.value = engineeringRes.data.engineeringList || []
|
||||||
|
deviceTableData.value = engineeringRes.data.portableDevList || []
|
||||||
|
}).catch(() => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getEnginnerDev = () => {
|
||||||
|
filterText.value = ''
|
||||||
|
deviceFilterText.value = ''
|
||||||
|
|
||||||
|
// 同时获取工程和设备数据
|
||||||
|
Promise.all([
|
||||||
|
queryUnlinkEngineeringByUseId({ userId: user.value.id }),
|
||||||
|
queryRunPortableDevByUseId({ userId: user.value.id })
|
||||||
|
]).then(([engineeringRes, deviceRes]) => {
|
||||||
|
tableData2.value = engineeringRes.data || []
|
||||||
|
deviceTableData2.value = deviceRes.data || []
|
||||||
|
dialogVisible.value = true
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
tableRef.value?.clearCheckboxRow()
|
||||||
|
deviceTableRef.value?.clearCheckboxRow()
|
||||||
|
}, 0)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteEngineering = (row: any) => {
|
||||||
|
ElMessageBox.confirm('是否移出该工程?', '请确认', {
|
||||||
|
confirmButtonText: '确认',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
// 只移除工程,设备列表为空
|
||||||
|
const form = {
|
||||||
|
engineeringList: [row.id], // 要移除的工程ID
|
||||||
|
portableDevList: [], // 设备列表为空
|
||||||
|
userId: user.value.id
|
||||||
|
}
|
||||||
|
|
||||||
|
removeUserDev(form).then((res: any) => {
|
||||||
|
ElMessage.success(res.message)
|
||||||
|
selectUser(user.value)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除设备方法
|
||||||
|
const deleteDevice = (row: any) => {
|
||||||
|
console.log('删除设备', row)
|
||||||
|
ElMessageBox.confirm('是否移出该设备?', '请确认', {
|
||||||
|
confirmButtonText: '确认',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
// 只移除设备,工程列表为空
|
||||||
|
const form = {
|
||||||
|
engineeringList: [], // 工程列表为空
|
||||||
|
portableDevList: [row.id], // 要移除的设备ID
|
||||||
|
userId: user.value.id
|
||||||
|
}
|
||||||
|
|
||||||
|
removeUserDev(form).then((res: any) => {
|
||||||
|
ElMessage.success(res.message)
|
||||||
|
selectUser(user.value)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const addData = () => {
|
||||||
|
const selectedEngineers = tableRef.value.getCheckboxRecords()
|
||||||
|
const selectedDevices = deviceTableRef.value.getCheckboxRecords()
|
||||||
|
|
||||||
|
// 如果没有选择任何项,则提示
|
||||||
|
if (selectedEngineers.length === 0 && selectedDevices.length === 0) {
|
||||||
|
ElMessage.warning('请至少选择一项工程或设备')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造请求参数对象
|
||||||
|
const form = {
|
||||||
|
engineeringList: [] as any[],
|
||||||
|
portableDevList: [] as any[],
|
||||||
|
userId: user.value.id
|
||||||
|
}
|
||||||
|
|
||||||
|
// // 处理已有的工程数据
|
||||||
|
// tableData.value.forEach((item: any) => {
|
||||||
|
// form.engineeringList.push(item.id)
|
||||||
|
// })
|
||||||
|
|
||||||
|
// // 处理已有的设备数据
|
||||||
|
// deviceTableData.value.forEach((item: any) => {
|
||||||
|
// form.portableDevList.push(item.id)
|
||||||
|
// })
|
||||||
|
|
||||||
|
// 添加新选择的工程
|
||||||
|
selectedEngineers.forEach((item: any) => {
|
||||||
|
form.engineeringList.push( item.id)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 添加新选择的设备
|
||||||
|
selectedDevices.forEach((item: any) => {
|
||||||
|
form.portableDevList.push(item.id)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
add(form).then((res: any) => {
|
||||||
|
ElMessage.success(res.message)
|
||||||
|
selectUser(user.value)
|
||||||
|
dialogVisible.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.device-manage {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
&-right {
|
||||||
|
overflow: hidden;
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px 10px 10px 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.el-descriptions__header {
|
||||||
|
height: 27px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end; /* 靠右显示 */
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tables-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.table-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-content {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
|
.dialog-section {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -96,14 +96,14 @@ const tableStore = new TableStore({
|
|||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
render: 'tag',
|
render: 'tag',
|
||||||
custom: {
|
custom: {
|
||||||
功能调试: 'warning',
|
2: 'warning',
|
||||||
出厂调试: 'warning',
|
3: 'warning',
|
||||||
正式投运: 'success'
|
4: 'success'
|
||||||
},
|
},
|
||||||
replaceValue: {
|
replaceValue: {
|
||||||
功能调试: '功能调试',
|
2: '功能调试',
|
||||||
出厂调试: '出厂调试',
|
3: '出厂调试',
|
||||||
正式投运: '正式投运'
|
4: '正式投运'
|
||||||
},
|
},
|
||||||
minWidth: 80
|
minWidth: 80
|
||||||
},
|
},
|
||||||
@@ -142,11 +142,14 @@ const tableStore = new TableStore({
|
|||||||
{ title: '完整性(%)', fixed: 'right', width: 100, field: 'integrity', sortable: true }
|
{ title: '完整性(%)', fixed: 'right', width: 100, field: 'integrity', sortable: true }
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {},
|
beforeSearchFun: () => {},
|
||||||
loadCallback: () => {
|
exportProcessingData: () => {
|
||||||
tableStore.table.data.forEach(item => {
|
tableStore.table.allData = tableStore.table.allData.filter(item => {
|
||||||
item.process = item.process == 2 ? '功能调试' : item.process == 3 ? '出厂调试' : '正式投运'
|
item.process = item.process == 2 ? '功能调试' : item.process == 3 ? '出厂调试' : '正式投运'
|
||||||
|
return item
|
||||||
})
|
})
|
||||||
|
console.log('🚀 ~ tableStore.table.allData:', tableStore.table.allData)
|
||||||
|
},
|
||||||
|
loadCallback: () => {
|
||||||
let name = tableStore.table.params.name
|
let name = tableStore.table.params.name
|
||||||
let data = tableStore.table.copyData.filter(item => {
|
let data = tableStore.table.copyData.filter(item => {
|
||||||
// 处理latestTime默认值
|
// 处理latestTime默认值
|
||||||
@@ -182,7 +185,10 @@ const exportTab = () => {
|
|||||||
sheetName: 'Sheet1',
|
sheetName: 'Sheet1',
|
||||||
type: 'xlsx', //导出文件类型 xlsx 和 csv
|
type: 'xlsx', //导出文件类型 xlsx 和 csv
|
||||||
useStyle: true,
|
useStyle: true,
|
||||||
data: tableStore.table.copyData, // 数据源 // 过滤那个字段导出
|
data: tableStore.table.copyData.filter(item => {
|
||||||
|
item.process = item.process == 2 ? '功能调试' : item.process == 3 ? '出厂调试' : '正式投运'
|
||||||
|
return item
|
||||||
|
}), // 数据源 // 过滤那个字段导出
|
||||||
columnFilterMethod: function (column: any) {
|
columnFilterMethod: function (column: any) {
|
||||||
return !(
|
return !(
|
||||||
column.column.title === undefined ||
|
column.column.title === undefined ||
|
||||||
|
|||||||
@@ -107,8 +107,8 @@ const editd = (e: any) => {
|
|||||||
}
|
}
|
||||||
// 设计
|
// 设计
|
||||||
const Aclick = (e: any) => {
|
const Aclick = (e: any) => {
|
||||||
// window.open(window.location.origin + `/zutai/?id=${e.id}&&name=${e.name}&&preview=false&&graphicDisplay=zl`)
|
|
||||||
window.open(window.location.origin + `/zutai/?id=${e.id}&&name=${e.name}&&preview=false&&graphicDisplay=zl`)
|
window.open(window.location.origin + `/zutai/?id=${e.id}&&name=${e.name}&&preview=false&&graphicDisplay=zl`)
|
||||||
|
// window.open('http://192.168.1.128:4001' + `/zutai/?id=${e.id}&&name=${e.name}&&preview=false&&graphicDisplay=zl`)
|
||||||
|
|
||||||
}
|
}
|
||||||
// 删除
|
// 删除
|
||||||
@@ -143,8 +143,8 @@ const deleted = (e: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const imgData = (e: any) => {
|
const imgData = (e: any) => {
|
||||||
// window.open(window.location.origin + `/zutai/?id=${e.id}&&name=${e.name}&&preview=true&&graphicDisplay=zl#/preview_ZL`)
|
window.open(window.location.origin + `/zutai/?id=${e.id}&&name=${e.name}&&preview=true&&graphicDisplay=zl#/preview_ZL`)
|
||||||
window.open(window.location.origin + `/zutai/?id=${e.id}&&name=${e.name}&&preview=true&&graphicDisplay=zl#/preview_ZL`)
|
// window.open('http://192.168.1.128:4001' + `/zutai/?id=${e.id}&&name=${e.name}&&preview=true&&graphicDisplay=zl#/preview_ZL`)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,11 +99,15 @@ tableStore.table.params.resourceType = 1
|
|||||||
tableStore.table.params.customType = 1
|
tableStore.table.params.customType = 1
|
||||||
const flag = ref(true)
|
const flag = ref(true)
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const dom = document.getElementById('navigation-splitpanes')
|
nextTick(() => {
|
||||||
if (dom) {
|
const dom = document.getElementById('navigation-splitpanes')
|
||||||
|
if (dom && dom.offsetHeight > 0) {
|
||||||
size.value = ((280 / (dom.offsetWidth - 7)) * 100)
|
size.value = ((280 / (dom.offsetWidth - 7)) * 100)
|
||||||
}
|
} else {
|
||||||
|
// 设置默认值
|
||||||
|
size.value = 20
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// getTemplateByDept({ id: dictData.state.area[0].id }).then((res: any) => {
|
// getTemplateByDept({ id: dictData.state.area[0].id }).then((res: any) => {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template v-slot:operation>
|
<template v-slot:operation>
|
||||||
<el-button type="primary" class="ml10" @click="add" icon="el-icon-Plus">新增</el-button>
|
<el-button type="primary" class="ml10" @click="add" icon="el-icon-Plus">新增</el-button>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<Table
|
<Table
|
||||||
@@ -81,17 +82,7 @@
|
|||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<el-popconfirm
|
<el-popconfirm title="确定重启吗?" placement="bottom" @confirm="restart(data)">
|
||||||
class="box-item"
|
|
||||||
title="确定重启吗?"
|
|
||||||
placement="bottom"
|
|
||||||
@confirm="restart(data)"
|
|
||||||
>
|
|
||||||
<template #actions="{ confirm, cancel }">
|
|
||||||
<el-button size="small" @click="cancel">取消</el-button>
|
|
||||||
<el-button type="warning" size="small" @click="confirm">确认</el-button>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-tooltip content="重启" placement="top">
|
<el-tooltip content="重启" placement="top">
|
||||||
<el-button
|
<el-button
|
||||||
@@ -99,10 +90,13 @@
|
|||||||
icon="el-icon-Refresh"
|
icon="el-icon-Refresh"
|
||||||
type="warning"
|
type="warning"
|
||||||
link
|
link
|
||||||
@click.stop
|
/>
|
||||||
></el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</template>
|
</template>
|
||||||
|
<template #actions="{ confirm, cancel }">
|
||||||
|
<el-button size="small" @click="cancel">取消</el-button>
|
||||||
|
<el-button type="warning" size="small" @click="confirm">确认</el-button>
|
||||||
|
</template>
|
||||||
</el-popconfirm>
|
</el-popconfirm>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -433,6 +427,7 @@ const currentChangeEvent = () => {
|
|||||||
|
|
||||||
// 重启进程
|
// 重启进程
|
||||||
const restart = (data: any) => {
|
const restart = (data: any) => {
|
||||||
|
|
||||||
restartProcess({
|
restartProcess({
|
||||||
nodeId: nodeId.value,
|
nodeId: nodeId.value,
|
||||||
processNo: data.processNo
|
processNo: data.processNo
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main">
|
<div class="default-main">
|
||||||
<TableHeader :showSearch="false" v-if="flag">
|
<TableHeader :showSearch="false" v-show="flag">
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="日期">
|
<el-form-item label="日期">
|
||||||
<DatePicker ref="datePickerRef" :nextFlag="false" :theCurrentTime="true"></DatePicker>
|
<DatePicker
|
||||||
|
ref="datePickerRef"
|
||||||
|
:nextFlag="false"
|
||||||
|
:theCurrentTime="true"
|
||||||
|
@change="handleDatePickerChange"
|
||||||
|
></DatePicker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:operation>
|
<template v-slot:operation>
|
||||||
@@ -42,6 +47,7 @@
|
|||||||
:height="rowHeight * item.h - seRowHeight(item.h) + 'px'"
|
:height="rowHeight * item.h - seRowHeight(item.h) + 'px'"
|
||||||
:width="rowWidth * item.w - 30 + 'px'"
|
:width="rowWidth * item.w - 30 + 'px'"
|
||||||
:timeKey="(item as LayoutItem).timeKey"
|
:timeKey="(item as LayoutItem).timeKey"
|
||||||
|
:interval="datePickerRef?.interval"
|
||||||
:w="item.w"
|
:w="item.w"
|
||||||
:h="item.h"
|
:h="item.h"
|
||||||
/>
|
/>
|
||||||
@@ -51,7 +57,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<!-- 设置 -->
|
<!-- 设置 -->
|
||||||
<RoutingConfig ref="RoutingConfigRef" />
|
<RoutingConfig ref="RoutingConfigRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -63,10 +69,13 @@ import DatePicker from '@/components/form/datePicker/index.vue'
|
|||||||
import { useDebounceFn } from '@vueuse/core'
|
import { useDebounceFn } from '@vueuse/core'
|
||||||
import { queryActivatePage, queryByPagePath } from '@/api/system-boot/csstatisticalset'
|
import { queryActivatePage, queryByPagePath } from '@/api/system-boot/csstatisticalset'
|
||||||
import RoutingConfig from '@/views/pqs/cockpit/homePage/components/routingConfig.vue'
|
import RoutingConfig from '@/views/pqs/cockpit/homePage/components/routingConfig.vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
const { push } = useRouter()
|
const { push } = useRouter()
|
||||||
const datePickerRef = ref()
|
const datePickerRef = ref()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
const timeCacheStore = useTimeCacheStore()
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
// name: 'dashboard/index'
|
// name: 'dashboard/index'
|
||||||
@@ -166,13 +175,16 @@ const zoom = (value: any) => {
|
|||||||
if (flag.value) {
|
if (flag.value) {
|
||||||
layout.value = [{ ...value, x: 0, y: 0, w: 12, h: 6 }]
|
layout.value = [{ ...value, x: 0, y: 0, w: 12, h: 6 }]
|
||||||
} else {
|
} else {
|
||||||
layout.value = layoutCopy.value.map((item:any, index: number) => ({
|
layout.value = layoutCopy.value.map((item: any, index: number) => ({
|
||||||
...item,
|
...item,
|
||||||
i: item.i || index, // 确保有唯一标识
|
i: item.i || index, // 确保有唯一标识
|
||||||
component: registerComponent(item.path)
|
component: registerComponent(item.path)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
console.log("🚀 ~ zoom ~ layout.value:", layout.value)
|
||||||
|
|
||||||
flag.value = !flag.value
|
flag.value = !flag.value
|
||||||
|
|
||||||
initRowHeight()
|
initRowHeight()
|
||||||
key.value += 1
|
key.value += 1
|
||||||
}
|
}
|
||||||
@@ -210,7 +222,7 @@ const fetchLayoutData = async () => {
|
|||||||
// 窗口大小变化处理 - 使用防抖
|
// 窗口大小变化处理 - 使用防抖
|
||||||
const handleResize = useDebounceFn(() => {
|
const handleResize = useDebounceFn(() => {
|
||||||
initRowHeight()
|
initRowHeight()
|
||||||
key.value += 1
|
// key.value += 1
|
||||||
}, 200)
|
}, 200)
|
||||||
|
|
||||||
// 修改
|
// 修改
|
||||||
@@ -225,6 +237,15 @@ const editd = (e: any) => {
|
|||||||
const settings = () => {
|
const settings = () => {
|
||||||
RoutingConfigRef.value.open()
|
RoutingConfigRef.value.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理 DatePicker 值变化事件
|
||||||
|
const handleDatePickerChange = (value: any) => {
|
||||||
|
// 将值缓存到 timeCache
|
||||||
|
if (value) {
|
||||||
|
timeCacheStore.setCache(route.path, value.interval, value.timeValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 生命周期钩子
|
// 生命周期钩子
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// initRowHeight()
|
// initRowHeight()
|
||||||
|
|||||||
@@ -48,9 +48,9 @@ import IframeDia from './iframeDia.vue'
|
|||||||
// }>()
|
// }>()
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: String },
|
width: { type: [String, Number]},
|
||||||
height: { type: String },
|
height: { type: [String, Number]},
|
||||||
timeKey: { type: String },
|
timeKey: { type: [String, Number]},
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ const tableStore: any = new TableStore({
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
||||||
showPage: false,
|
showPage: false,
|
||||||
exportName: '主要监测点列表',
|
|
||||||
column: [
|
column: [
|
||||||
{
|
{
|
||||||
field: 'index',
|
field: 'index',
|
||||||
|
|||||||
@@ -358,11 +358,11 @@ const onSubmit = () => {
|
|||||||
|
|
||||||
formRef.value.validate(async (valid: boolean) => {
|
formRef.value.validate(async (valid: boolean) => {
|
||||||
let url = ''
|
let url = ''
|
||||||
await html2canvas(document.querySelector('.GridLayout'), {
|
// await html2canvas(document.querySelector('.GridLayout'), {
|
||||||
useCORS: true
|
// useCORS: true
|
||||||
}).then(canvas => {
|
// }).then(canvas => {
|
||||||
url = canvas.toDataURL('image/png')
|
// url = canvas.toDataURL('image/png')
|
||||||
})
|
// })
|
||||||
form.pagePath = form.pagePath || ''
|
form.pagePath = form.pagePath || ''
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
|||||||
23
types/table.d.ts
vendored
23
types/table.d.ts
vendored
@@ -8,8 +8,9 @@ declare global {
|
|||||||
interface CnTable {
|
interface CnTable {
|
||||||
ref: VxeTableInstance | null
|
ref: VxeTableInstance | null
|
||||||
data: TableRow[] | any
|
data: TableRow[] | any
|
||||||
copyData: TableRow[] | any
|
|
||||||
allData: TableRow[] | any
|
allData: TableRow[] | any
|
||||||
|
copyData: TableRow[] | any
|
||||||
|
filename: any
|
||||||
allFlag: Boolean
|
allFlag: Boolean
|
||||||
// 前端分页数据
|
// 前端分页数据
|
||||||
webPagingData: TableRow[][]
|
webPagingData: TableRow[][]
|
||||||
@@ -29,6 +30,7 @@ declare global {
|
|||||||
loadCallback: (() => void) | null
|
loadCallback: (() => void) | null
|
||||||
resetCallback: (() => void) | null
|
resetCallback: (() => void) | null
|
||||||
beforeSearchFun: (() => void) | null
|
beforeSearchFun: (() => void) | null
|
||||||
|
exportProcessingData: (() => void) | null
|
||||||
height: string
|
height: string
|
||||||
publicHeight: number
|
publicHeight: number
|
||||||
}
|
}
|
||||||
@@ -50,6 +52,7 @@ declare global {
|
|||||||
| 'buttons'
|
| 'buttons'
|
||||||
| 'slot'
|
| 'slot'
|
||||||
| 'customTemplate'
|
| 'customTemplate'
|
||||||
|
| 'renderFormatter'
|
||||||
| 'customRender'
|
| 'customRender'
|
||||||
// 默认值
|
// 默认值
|
||||||
default?: any
|
default?: any
|
||||||
@@ -59,14 +62,15 @@ declare global {
|
|||||||
custom?: any
|
custom?: any
|
||||||
// 值替换数据,如{open: '开'}
|
// 值替换数据,如{open: '开'}
|
||||||
replaceValue?: any
|
replaceValue?: any
|
||||||
|
effect?: any
|
||||||
// 时间格式化
|
// 时间格式化
|
||||||
timeFormat?: string
|
timeFormat?: string
|
||||||
// 开关控制
|
// 开关控制
|
||||||
onChangeField?: (row: TableRow, value: any) => void
|
onChangeField?: (row: TableRow, value: any) => void
|
||||||
activeValue?: string
|
activeValue?: string
|
||||||
inactiveValue?: string
|
inactiveValue?: string
|
||||||
activeText?: string
|
activeText?: string
|
||||||
inactiveText?: string
|
inactiveText?: string
|
||||||
// 自定义组件/函数渲染
|
// 自定义组件/函数渲染
|
||||||
customRender?: string | Component
|
customRender?: string | Component
|
||||||
// 使用了 render 属性时,渲染前对字段值的预处理方法,请返回新值
|
// 使用了 render 属性时,渲染前对字段值的预处理方法,请返回新值
|
||||||
@@ -80,6 +84,8 @@ declare global {
|
|||||||
index: number
|
index: number
|
||||||
) => string
|
) => string
|
||||||
children?: TableColumn[]
|
children?: TableColumn[]
|
||||||
|
property?: string
|
||||||
|
clickable?: boolean // 是否可点击
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 表格右侧操作按钮 */
|
/* 表格右侧操作按钮 */
|
||||||
@@ -90,15 +96,16 @@ declare global {
|
|||||||
title?: string
|
title?: string
|
||||||
text?: string
|
text?: string
|
||||||
class?: string
|
class?: string
|
||||||
loading?: string
|
|
||||||
type: ButtonType
|
type: ButtonType
|
||||||
icon: string
|
icon: string
|
||||||
popconfirm?: Partial<Mutable<PopconfirmProps>>
|
popconfirm?: Partial<Mutable<PopconfirmProps>>
|
||||||
disabledTip?: boolean
|
disabledTip?: boolean
|
||||||
// 自定义点击事件
|
// 自定义点击事件
|
||||||
click?: (row: TableRow, field: TableColumn) => void
|
click?: (row: TableRow, field: TableColumn) => void
|
||||||
|
|
||||||
// 按钮是否禁用,请返回布尔值
|
// 按钮是否禁用,请返回布尔值
|
||||||
disabled?: (row: TableRow, field: TableColumn) => boolean
|
disabled?: (row: TableRow, field: TableColumn) => boolean
|
||||||
|
showDisabled?: (row: TableRow, field: TableColumn) => boolean
|
||||||
// 自定义el-button属性
|
// 自定义el-button属性
|
||||||
attr?: Partial<Mutable<ButtonProps>>
|
attr?: Partial<Mutable<ButtonProps>>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user