Compare commits

...

20 Commits

Author SHA1 Message Date
stt
f32934e0e6 Merge branch 'main' of http://192.168.1.22:3000/Web/admin-govern 2025-12-05 11:05:08 +08:00
stt
460962cead 删除多余代码 2025-12-05 11:05:05 +08:00
guanj
fa75fc2923 联调实时数据 2025-12-05 10:44:35 +08:00
stt
f953b560c7 暂态电能质量分析时间修改 2025-12-04 20:27:05 +08:00
stt
8f3426eb1f 稳态治理效果分析时间修改 2025-12-04 20:08:37 +08:00
stt
c2a2a4afd6 稳态电能质量分析时间修改 2025-12-04 19:47:31 +08:00
stt
d2357d4ad2 稳态电能质量分析时间修改 2025-12-04 19:11:21 +08:00
stt
1b23355134 实时数据页面提交 2025-12-04 16:29:46 +08:00
guanj
ce9caa8729 Merge branch 'main' of http://192.168.1.22:3000/Web/admin-govern 2025-12-04 15:25:31 +08:00
guanj
2d0349c1b6 微调 2025-12-04 15:25:22 +08:00
stt
8355fc6aed Merge branch 'main' of http://192.168.1.22:3000/Web/admin-govern 2025-12-04 14:51:25 +08:00
stt
23bc2d8f05 组件查询时间加必填校验 2025-12-04 14:51:21 +08:00
guanj
43caddffa3 修改 echart样式 2025-12-04 10:33:48 +08:00
stt
3accaf3079 日期下拉默认修改 2025-12-04 10:30:19 +08:00
guanj
5687367602 Merge branch 'main' of http://192.168.1.22:3000/Web/admin-govern 2025-12-04 09:37:58 +08:00
guanj
b8ee530557 修改驾驶舱zoom缩放问题 2025-12-04 09:37:38 +08:00
stt
0518127792 公共时间修改 2025-12-03 16:30:42 +08:00
guanj
5db43cd4b1 微调 2025-12-03 15:37:08 +08:00
guanj
bf0657cbbc 在线设备录入添加参数
修改组件管理时间线配置
2025-12-03 14:56:57 +08:00
stt
bcb1535d4d 日历只月的时候调接口 2025-12-03 13:26:03 +08:00
31 changed files with 2420 additions and 2296 deletions

View File

@@ -25,3 +25,12 @@ export function offlineDataUploadMakeUp(data: any) {
data data
}) })
} }
//设备补召操作
// 根据id集合获取敏感负荷用户列表
export function getListByIds() {
return createAxios({
url: '/cs-harmonic-boot/pqSensitiveUser/getListByIds',
method: 'POST',
})
}

View File

@@ -116,3 +116,11 @@ export const start = (params: any) => {
params params
}) })
} }
// 查询监测对象类型
export const getDicDataByTypeCode = (params: any) => {
return request({
url: '/system-boot/dictData/getDicDataByTypeCode',
method: 'get',
params
})
}

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<!--F47曲线 --> <!--F47曲线 -->
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader> <TableHeader ref="TableHeaderRef" :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>
@@ -38,15 +38,20 @@ import waveFormAnalysis from '@/views/govern/device/control/tabs/components/wave
import TableHeader from '@/components/table/header/index.vue' import TableHeader from '@/components/table/header/index.vue'
import { analyseWave } from '@/api/common' import { analyseWave } from '@/api/common'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { getTime } from '@/utils/formatTime'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
h: { type: [String, Number] }, h: { type: [String, Number] },
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const TableHeaderRef = ref()
const headerHeight = ref(57) const headerHeight = ref(57)
const dialogTitle = ref('波形分析') const dialogTitle = ref('波形分析')
@@ -100,8 +105,7 @@ const tableStore: any = new TableStore({
column: [], column: [],
beforeSearchFun: () => { beforeSearchFun: () => {
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0] setTime()
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
}, },
loadCallback: () => { loadCallback: () => {
const gongData = gongfunction(tableStore.table.data) const gongData = gongfunction(tableStore.table.data)
@@ -238,6 +242,25 @@ const tableRef = ref()
provide('tableRef', tableRef) provide('tableRef', tableRef)
provide('tableStore', tableStore) provide('tableStore', tableStore)
const setTime = () => {
const time = getTime(
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
}
}
function gongfunction(arr: any) { function gongfunction(arr: any) {
let standI = 0 let standI = 0
let unstandI = 0 let unstandI = 0

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<!--暂降方向统计 --> <!--暂降方向统计 -->
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader> <TableHeader ref="TableHeaderRef" :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>
@@ -10,12 +10,8 @@ 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 TableHeader from '@/components/table/header/index.vue' import TableHeader from '@/components/table/header/index.vue'
import { useRoute } from 'vue-router' import { getTime } from '@/utils/formatTime'
import { useTimeCacheStore } from '@/stores/timeCache'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
@@ -23,13 +19,13 @@ const prop = defineProps({
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const headerHeight = ref(57) const headerHeight = ref(57)
const route = useRoute() const TableHeaderRef = ref()
const timeCacheStore = useTimeCacheStore()
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => { const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
headerHeight.value = height headerHeight.value = height
@@ -128,8 +124,7 @@ const tableStore: any = new TableStore({
column: [], column: [],
beforeSearchFun: () => { beforeSearchFun: () => {
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0] setTime()
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
}, },
loadCallback: () => {} loadCallback: () => {}
}) })
@@ -139,6 +134,25 @@ provide('tableRef', tableRef)
provide('tableStore', tableStore) provide('tableStore', tableStore)
const setTime = () => {
const time = getTime(
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
}
}
// 点击行 // 点击行
const cellClickEvent = ({ row, column }: any) => { const cellClickEvent = ({ row, column }: any) => {
if (column.field != 'name') { if (column.field != 'name') {

View File

@@ -1,7 +1,13 @@
<template> <template>
<div> <div>
<!--指标越限程度 --> <!--指标越限程度 -->
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader> <TableHeader
ref="TableHeaderRef"
:showReset="false"
@selectChange="selectChange"
datePicker
v-if="fullscreen"
></TableHeader>
<my-echart <my-echart
class="tall" class="tall"
:options="echartList" :options="echartList"
@@ -25,8 +31,7 @@ import TableHeader from '@/components/table/header/index.vue'
import MyEchart from '@/components/echarts/MyEchart.vue' import MyEchart from '@/components/echarts/MyEchart.vue'
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 { getTime } from '@/utils/formatTime'
import { useTimeCacheStore } from '@/stores/timeCache'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
@@ -34,9 +39,12 @@ const prop = defineProps({
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const TableHeaderRef = ref()
const headerHeight = ref(57) const headerHeight = ref(57)
const dialogTrendChart = ref(false) const dialogTrendChart = ref(false)
@@ -146,8 +154,7 @@ const tableStore: any = new TableStore({
} }
], ],
beforeSearchFun: () => { beforeSearchFun: () => {
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0] setTime()
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
}, },
loadCallback: () => { loadCallback: () => {
// 定义 x 轴标签顺序 // 定义 x 轴标签顺序
@@ -207,6 +214,25 @@ const cellClickEvent = ({ row, column }: any) => {
} }
} }
const setTime = () => {
const time = getTime(
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
}
}
onMounted(() => { onMounted(() => {
tableStore.index() tableStore.index()
}) })
@@ -219,12 +245,7 @@ watch(
watch( watch(
() => prop.timeValue, () => prop.timeValue,
(newVal, oldVal) => { (newVal, oldVal) => {
// 当外部时间值变化时,更新表格的时间参数
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() tableStore.index()
}
}, },
{ {
deep: true deep: true

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<!--治理效果报表 --> <!--治理效果报表 -->
<TableHeader :showReset="false" datePicker @selectChange="selectChange" v-if="fullscreen"> <TableHeader :showReset="false" ref="TableHeaderRef" datePicker @selectChange="selectChange" v-if="fullscreen">
<template v-slot:select> <template v-slot:select>
<el-form-item label="报表模板"> <el-form-item label="报表模板">
<el-select v-model="tableStore.table.params.tempId" placeholder="请选择报表模板" clearable> <el-select v-model="tableStore.table.params.tempId" placeholder="请选择报表模板" clearable>
@@ -36,7 +36,7 @@ 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 { getTemplateList } from '@/api/harmonic-boot/luckyexcel' import { getTemplateList } from '@/api/harmonic-boot/luckyexcel'
import { getListByIds } from '@/api/harmonic-boot/cockpit/cockpit' import { getListByIds } from '@/api/harmonic-boot/cockpit/cockpit'
import Json from './index.json' import { getTime } from '@/utils/formatTime'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
@@ -44,9 +44,12 @@ const prop = defineProps({
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const TableHeaderRef = ref()
// 报表模板列表 // 报表模板列表
const templateList = ref() const templateList = ref()
@@ -114,8 +117,7 @@ const tableStore: any = new TableStore({
exportName: '治理效果报表', exportName: '治理效果报表',
column: [], column: [],
beforeSearchFun: () => { beforeSearchFun: () => {
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0] setTime()
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
if (!tableStore.table.params.sensitiveUserId && idList.value?.length > 0) { if (!tableStore.table.params.sensitiveUserId && idList.value?.length > 0) {
tableStore.table.params.sensitiveUserId = idList.value[0].id tableStore.table.params.sensitiveUserId = idList.value[0].id
} }
@@ -142,6 +144,25 @@ provide('tableRef', tableRef)
provide('tableStore', tableStore) provide('tableStore', tableStore)
const setTime = () => {
const time = getTime(
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
}
}
watch( watch(
() => prop.timeKey, () => prop.timeKey,
val => { val => {
@@ -151,12 +172,7 @@ watch(
watch( watch(
() => prop.timeValue, () => prop.timeValue,
(newVal, oldVal) => { (newVal, oldVal) => {
// 当外部时间值变化时,更新表格的时间参数
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() tableStore.index()
}
}, },
{ {
deep: true deep: true

View File

@@ -1,7 +1,13 @@
<template> <template>
<div> <div>
<!--电网侧指标越限统计 --> <!--电网侧指标越限统计 -->
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader> <TableHeader
:showReset="false"
ref="TableHeaderRef"
@selectChange="selectChange"
datePicker
v-if="fullscreen"
></TableHeader>
<my-echart <my-echart
class="tall" class="tall"
:options="echartList" :options="echartList"
@@ -27,9 +33,8 @@ import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/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 OverLimitDetails from '@/components/cockpit/gridSideStatistics/components/overLimitDetails.vue' import OverLimitDetails from '@/components/cockpit/gridSideStatistics/components/overLimitDetails.vue'
import { useRoute } from 'vue-router'
import { useTimeCacheStore } from '@/stores/timeCache'
import { gridSideLimitStatisticsData } from '@/api/harmonic-boot/cockpit/cockpit' import { gridSideLimitStatisticsData } from '@/api/harmonic-boot/cockpit/cockpit'
import { getTime } from '@/utils/formatTime'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
@@ -37,13 +42,16 @@ const prop = defineProps({
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const headerHeight = ref(57) const headerHeight = ref(57)
const echartList = ref({}) const echartList = ref({})
const TableHeaderRef = ref()
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => { const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
headerHeight.value = height headerHeight.value = height
@@ -188,8 +196,7 @@ const tableStore: any = new TableStore({
} }
], ],
beforeSearchFun: () => { beforeSearchFun: () => {
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0] setTime()
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)`
@@ -216,6 +223,25 @@ const cellClickEvent = ({ row, column }: any) => {
onMounted(() => { onMounted(() => {
tableStore.index() tableStore.index()
}) })
const setTime = () => {
const time = getTime(
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
}
}
watch( watch(
() => prop.timeKey, () => prop.timeKey,
val => { val => {
@@ -226,12 +252,7 @@ watch(
watch( watch(
() => prop.timeValue, () => prop.timeValue,
(newVal, oldVal) => { (newVal, oldVal) => {
// 当外部时间值变化时,更新表格的时间参数
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() tableStore.index()
}
}, },
{ {
deep: true deep: true

View File

@@ -7,7 +7,7 @@
@selectChange="selectChange" @selectChange="selectChange"
datePicker datePicker
v-if="fullscreen" v-if="fullscreen"
:timeCacheFlag="false" :timeKeyList="['3']"
></TableHeader> ></TableHeader>
<el-calendar <el-calendar
v-model="value" v-model="value"
@@ -44,6 +44,7 @@ import { ref, onMounted, provide, reactive, watch, h } from 'vue'
import TableStore from '@/utils/tableStore' import TableStore from '@/utils/tableStore'
import TableHeader from '@/components/table/header/index.vue' import TableHeader from '@/components/table/header/index.vue'
import { dayjs } from 'element-plus' import { dayjs } from 'element-plus'
import { getTime } from '@/utils/formatTime'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
@@ -51,7 +52,8 @@ const prop = defineProps({
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const headerHeight = ref(57) const headerHeight = ref(57)
@@ -96,10 +98,7 @@ const tableStore: any = new TableStore({
showPage: false, showPage: false,
column: [], column: [],
beforeSearchFun: () => { beforeSearchFun: () => {
if (!fullscreen.value && prop.timeValue && Array.isArray(prop.timeValue)) { setTime()
tableStore.table.params.searchBeginTime = prop.timeValue[0]
tableStore.table.params.searchEndTime = prop.timeValue[1]
}
}, },
loadCallback: () => { loadCallback: () => {
value.value = tableStore.table.params.searchBeginTime value.value = tableStore.table.params.searchBeginTime
@@ -144,35 +143,34 @@ provide('tableStore', tableStore)
onMounted(() => { onMounted(() => {
nextTick(() => { nextTick(() => {
if (TableHeaderRef.value && typeof TableHeaderRef.value.setDatePicker === 'function') {
TableHeaderRef.value.setDatePicker([{ label: '月份', value: 3 }])
}
if (fullscreen.value) {
TableHeaderRef.value.setInterval(3)
}
tableStore.index() tableStore.index()
}) })
}) })
watch(
() => prop.timeKey, const setTime = () => {
val => { const time = getTime(
tableStore.index() (TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
} }
) }
watch( watch(
() => prop.timeValue, () => prop.timeValue,
// (newVal, oldVal) => { (newVal, oldVal) => {
// // 当外部时间值变化时,更新表格的时间参数
// 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()
// }
// },
val => {
tableStore.index() tableStore.index()
}, },
{ {
deep: true deep: true
} }

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<!--指标越限概率分布 --> <!--指标越限概率分布 -->
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"> <TableHeader :showReset="false" ref="TableHeaderRef" @selectChange="selectChange" datePicker v-if="fullscreen">
<template v-slot:select> <template v-slot:select>
<el-form-item label="监测点"> <el-form-item label="监测点">
<el-select size="small" v-model="tableStore.table.params.lineId"> <el-select size="small" v-model="tableStore.table.params.lineId">
@@ -41,6 +41,7 @@ import TableStore from '@/utils/tableStore'
import TableHeader from '@/components/table/header/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 { limitProbabilityData, cslineList } from '@/api/harmonic-boot/cockpit/cockpit' import { limitProbabilityData, cslineList } from '@/api/harmonic-boot/cockpit/cockpit'
import { getTime } from '@/utils/formatTime'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
@@ -48,7 +49,8 @@ const prop = defineProps({
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
// const options = ref(JSON.parse(window.localStorage.getItem('lineIdList') || '[]')) // const options = ref(JSON.parse(window.localStorage.getItem('lineIdList') || '[]'))
@@ -57,6 +59,8 @@ const lineList = ref()
const headerHeight = ref(57) const headerHeight = ref(57)
const TableHeaderRef = ref()
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => { const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
headerHeight.value = height headerHeight.value = height
@@ -187,43 +191,18 @@ const initProbabilityData = () => {
type: 'category', type: 'category',
name: '越限程度', name: '越限程度',
nameLocation: 'middle', nameLocation: 'middle',
nameGap: 30, nameGap: 50,
data: ['0-20%', '20-40%', '40-60%', '60-80%', '80-100%'], data: ['0-20%', '20-40%', '40-60%', '60-80%', '80-100%']
axisLine: {
lineStyle: {
color: '#111'
}
},
axisLabel: {
color: '#111',
margin: 15
},
nameTextStyle: {
color: '#111'
}
}, },
yAxis3D: { yAxis3D: {
type: 'category', type: 'category',
name: '指标类型', name: '指标类型',
nameLocation: 'middle', nameLocation: 'middle',
nameGap: 30, nameGap: 50,
data: yAxisData, data: yAxisData,
nameTextStyle: {
color: '#111'
},
axisLine: {
show: true,
lineStyle: {
color: '#111'
}
},
axisLabel: {
color: '#111',
margin: 15
},
splitLine: { splitLine: {
lineStyle: { lineStyle: {
color: ['#111'],
type: 'dashed', type: 'dashed',
opacity: 0.5 opacity: 0.5
} }
@@ -234,19 +213,8 @@ const initProbabilityData = () => {
name: '越限次数', name: '越限次数',
nameLocation: 'middle', nameLocation: 'middle',
nameGap: 30, nameGap: 30,
nameTextStyle: { minInterval: 10
color: '#111'
},
axisLine: {
lineStyle: {
color: '#111'
}
},
axisLabel: {
color: '#111'
},
min: 0,
max: zAxisMax // 使用计算出的最大值加5
// max: 100 // max: 100
}, },
grid3D: { grid3D: {
@@ -402,8 +370,7 @@ const tableStore: any = new TableStore({
showPage: false, showPage: false,
column: [], column: [],
beforeSearchFun: () => { beforeSearchFun: () => {
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0] setTime()
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
// 只有当 lineList 已加载且有数据时才设置默认 lineId // 只有当 lineList 已加载且有数据时才设置默认 lineId
if (!tableStore.table.params.lineId && lineList.value && lineList.value.length > 0) { if (!tableStore.table.params.lineId && lineList.value && lineList.value.length > 0) {
tableStore.table.params.lineId = lineList.value[0].lineId tableStore.table.params.lineId = lineList.value[0].lineId
@@ -455,6 +422,25 @@ provide('tableStore', tableStore)
onMounted(() => { onMounted(() => {
initLineList() initLineList()
}) })
const setTime = () => {
const time = getTime(
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
}
}
watch( watch(
() => prop.timeKey, () => prop.timeKey,
val => { val => {
@@ -464,12 +450,7 @@ watch(
watch( watch(
() => prop.timeValue, () => prop.timeValue,
(newVal, oldVal) => { (newVal, oldVal) => {
// 当外部时间值变化时,更新表格的时间参数
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() tableStore.index()
}
}, },
{ {
deep: true deep: true

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<!--主要监测点列表 --> <!--主要监测点列表 -->
<TableHeader :showReset="false" @selectChange="selectChange" v-if="fullscreen" datePicker ref="tableHeaderRef"> <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.keywords" clearable placeholder="请输关键字" /> <el-input v-model="tableStore.table.params.keywords" clearable placeholder="请输关键字" />
@@ -22,11 +22,10 @@ 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 { getTimeOfTheMonth } from '@/utils/formatTime' import { getTime } from '@/utils/formatTime'
import OverLimitDetails from '@/components/cockpit/indicatorFittingChart/components/overLimitDetails.vue' import OverLimitDetails from '@/components/cockpit/indicatorFittingChart/components/overLimitDetails.vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { useTimeCacheStore } from '@/stores/timeCache' import { useTimeCacheStore } from '@/stores/timeCache'
import { log } from 'console'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
@@ -34,7 +33,8 @@ const prop = defineProps({
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const OverLimitDetailsRef = ref() const OverLimitDetailsRef = ref()
const headerHeight = ref(57) const headerHeight = ref(57)
@@ -42,7 +42,7 @@ const headerHeight = ref(57)
const route = useRoute() const route = useRoute()
const timeCacheStore = useTimeCacheStore() const timeCacheStore = useTimeCacheStore()
const tableHeaderRef = ref() const TableHeaderRef = ref()
// 计算是否全屏展示 // 计算是否全屏展示
const fullscreen = computed(() => { const fullscreen = computed(() => {
@@ -104,8 +104,7 @@ const tableStore: any = new TableStore({
{ title: '主要存在的电能质量问题', field: 'problems', minWidth: '150', showOverflow: true } { title: '主要存在的电能质量问题', field: 'problems', minWidth: '150', showOverflow: true }
], ],
beforeSearchFun: () => { beforeSearchFun: () => {
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0] setTime()
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)`
@@ -128,25 +127,34 @@ const cellClickEvent = ({ row, column }: any) => {
} }
} }
const setTime = () => {
const time = getTime(
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
// TableHeaderRef.value?.setInterval(time[2] - 0)
// TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
}
}
// 在组件挂载时设置缓存值到 DatePicker // 在组件挂载时设置缓存值到 DatePicker
onMounted(() => { onMounted(() => {
tableStore.index() tableStore.index()
}) })
watch(
() => prop.timeKey,
val => {
tableStore.index()
}
)
watch( watch(
() => prop.timeValue, () => prop.timeValue,
(newVal, oldVal) => { (newVal, oldVal) => {
// 当外部时间值变化时,更新表格的时间参数
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() tableStore.index()
}
}, },
{ {
deep: true deep: true

View File

@@ -1,7 +1,13 @@
<template> <template>
<div> <div>
<!--指标拟合图 --> <!--指标拟合图 -->
<TableHeader datePicker @selectChange="selectChange" v-if="fullscreen"> <TableHeader
datePicker
@selectChange="selectChange"
v-if="fullscreen"
ref="TableHeaderRef"
:timeKeyList="['4', '5']"
>
<template v-slot:select> <template v-slot:select>
<el-form-item label="监测点"> <el-form-item label="监测点">
<el-select v-model="tableStore.table.params.lineId" placeholder="请选择监测点" clearable> <el-select v-model="tableStore.table.params.lineId" placeholder="请选择监测点" clearable>
@@ -75,6 +81,7 @@ import { useConfig } from '@/stores/config'
import { cslineList, fittingData } from '@/api/harmonic-boot/cockpit/cockpit' import { cslineList, fittingData } from '@/api/harmonic-boot/cockpit/cockpit'
import { queryByCode, queryCsDictTree } from '@/api/system-boot/dictTree' import { queryByCode, queryCsDictTree } from '@/api/system-boot/dictTree'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { getTime } from '@/utils/formatTime'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
@@ -82,17 +89,18 @@ const prop = defineProps({
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const TableHeaderRef = ref()
const config = useConfig() const config = useConfig()
const lineList: any = ref() const lineList: any = ref()
const powerList: any = ref() const powerList: any = ref()
const countData: any = ref([])
const chartsList = ref<any>([]) const chartsList = ref<any>([])
// 计算是否全屏展示 // 计算是否全屏展示
@@ -131,7 +139,6 @@ const echartList = ref()
const headerHeight = ref(57) const headerHeight = ref(57)
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => { const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
headerHeight.value = height headerHeight.value = height
if (datePickerValue && datePickerValue.timeValue) { if (datePickerValue && datePickerValue.timeValue) {
// 更新时间参数 // 更新时间参数
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0] tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
@@ -255,6 +262,7 @@ const initCode = () => {
tableStore.table.params.power = powerList.value[0].id tableStore.table.params.power = powerList.value[0].id
tableStore.table.params.indicator = indicatorList.value[0].id tableStore.table.params.indicator = indicatorList.value[0].id
nextTick(() => { nextTick(() => {
// setTime()
tableStore.index() tableStore.index()
}) })
}) })
@@ -268,10 +276,7 @@ const tableStore: any = new TableStore({
exportName: '主要监测点列表', exportName: '主要监测点列表',
column: [], column: [],
beforeSearchFun: () => { beforeSearchFun: () => {
// 设置时间参数 setTime()
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
// 只有当 lineList 已加载且有数据时才设置默认 lineId // 只有当 lineList 已加载且有数据时才设置默认 lineId
if (!tableStore.table.params.lineId && lineList.value && lineList.value.length > 0) { if (!tableStore.table.params.lineId && lineList.value && lineList.value.length > 0) {
tableStore.table.params.lineId = lineList.value[0].lineId tableStore.table.params.lineId = lineList.value[0].lineId
@@ -377,28 +382,42 @@ onMounted(() => {
initCode() initCode()
}) })
}) })
watch( watch(
() => prop.timeKey, () => prop.timeKey,
val => { val => {
tableStore.index() tableStore.index()
} }
) )
const setTime = () => {
const time = getTime(
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
}
}
watch( watch(
() => prop.timeValue, () => prop.timeValue,
(newVal, oldVal) => { (newVal, oldVal) => {
// 当外部时间值变化时,更新表格的时间参数
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() tableStore.index()
}
}, },
{ {
deep: true deep: true
} }
) )
const addMenu = () => {}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
// :deep(.el-select) { // :deep(.el-select) {

View File

@@ -1,7 +1,13 @@
<template> <template>
<div> <div>
<!-- 监测点列表 --> <!-- 监测点列表 -->
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader> <TableHeader
ref="TableHeaderRef"
:showReset="false"
@selectChange="selectChange"
datePicker
v-if="fullscreen"
></TableHeader>
<Table <Table
ref="tableRef" ref="tableRef"
@cell-click="cellClickEvent" @cell-click="cellClickEvent"
@@ -46,6 +52,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
import OverLimitDetails from '@/components/cockpit/monitoringPointList/components/overLimitDetails.vue' import OverLimitDetails from '@/components/cockpit/monitoringPointList/components/overLimitDetails.vue'
import TableHeader from '@/components/table/header/index.vue' import TableHeader from '@/components/table/header/index.vue'
import { uploadReport, getReportUrl } from '@/api/harmonic-boot/cockpit/cockpit' import { uploadReport, getReportUrl } from '@/api/harmonic-boot/cockpit/cockpit'
import { getTime } from '@/utils/formatTime'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
@@ -53,11 +60,14 @@ const prop = defineProps({
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const headerHeight = ref(57) const headerHeight = ref(57)
const TableHeaderRef = ref()
// 上传相关 // 上传相关
const uploadDialogVisible = ref(false) const uploadDialogVisible = ref(false)
const currentUploadRow = ref<any>(null) const currentUploadRow = ref<any>(null)
@@ -209,8 +219,7 @@ const tableStore: any = new TableStore({
} }
], ],
beforeSearchFun: () => { beforeSearchFun: () => {
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0] setTime()
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)`
@@ -222,6 +231,25 @@ provide('tableRef', tableRef)
tableStore.table.params.keywords = '' tableStore.table.params.keywords = ''
provide('tableStore', tableStore) provide('tableStore', tableStore)
const setTime = () => {
const time = getTime(
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
}
}
// 点击行 // 点击行
const cellClickEvent = ({ row, column }: any) => { const cellClickEvent = ({ row, column }: any) => {
if (column.field == 'lineName') { if (column.field == 'lineName') {
@@ -326,12 +354,7 @@ watch(
watch( watch(
() => prop.timeValue, () => prop.timeValue,
(newVal, oldVal) => { (newVal, oldVal) => {
// 当外部时间值变化时,更新表格的时间参数
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() tableStore.index()
}
}, },
{ {
deep: true deep: true

View File

@@ -1,7 +1,13 @@
<template> <template>
<div> <div>
<!--总体指标越限统计 --> <!--总体指标越限统计 -->
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader> <TableHeader
:showReset="false"
ref="TableHeaderRef"
@selectChange="selectChange"
datePicker
v-if="fullscreen"
></TableHeader>
<my-echart <my-echart
class="tall" class="tall"
:options="echartList" :options="echartList"
@@ -30,6 +36,7 @@ import OverLimitDetails from '@/components/cockpit/overLimitStatistics/component
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { useTimeCacheStore } from '@/stores/timeCache' import { useTimeCacheStore } from '@/stores/timeCache'
import { totalLimitStatisticsData } from '@/api/harmonic-boot/cockpit/cockpit' import { totalLimitStatisticsData } from '@/api/harmonic-boot/cockpit/cockpit'
import { getTime } from '@/utils/formatTime'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
@@ -37,13 +44,13 @@ const prop = defineProps({
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const headerHeight = ref(57) const headerHeight = ref(57)
const route = useRoute() const TableHeaderRef = ref()
const timeCacheStore = useTimeCacheStore()
const echartList = ref({}) const echartList = ref({})
@@ -191,8 +198,7 @@ const tableStore: any = new TableStore({
} }
], ],
beforeSearchFun: () => { beforeSearchFun: () => {
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0] setTime()
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)`
@@ -219,6 +225,26 @@ const cellClickEvent = ({ row, column }: any) => {
onMounted(() => { onMounted(() => {
tableStore.index() tableStore.index()
}) })
const setTime = () => {
const time = getTime(
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
}
}
watch( watch(
() => prop.timeKey, () => prop.timeKey,
val => { val => {
@@ -229,12 +255,7 @@ watch(
watch( watch(
() => prop.timeValue, () => prop.timeValue,
(newVal, oldVal) => { (newVal, oldVal) => {
// 当外部时间值变化时,更新表格的时间参数
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() tableStore.index()
}
}, },
{ {
deep: true deep: true

View File

@@ -1,8 +1,19 @@
<template> <template>
<div> <div>
<!--敏感负荷列表 --> <!--敏感负荷列表 -->
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader> <TableHeader
<Table ref="tableRef" @cell-click="cellClickEvent" :height="`calc(${prop.height} - ${headerHeight}px + ${fullscreen ? -58 : 56}px )`" isGroup></Table> ref="TableHeaderRef"
:showReset="false"
@selectChange="selectChange"
datePicker
v-if="fullscreen"
></TableHeader>
<Table
ref="tableRef"
@cell-click="cellClickEvent"
:height="`calc(${prop.height} - ${headerHeight}px + ${fullscreen ? -58 : 56}px )`"
isGroup
></Table>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -10,25 +21,26 @@ 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 TableHeader from '@/components/table/header/index.vue'
import { useRoute } from 'vue-router'
import { useTimeCacheStore } from '@/stores/timeCache'
import { useDictData } from '@/stores/dictData' import { useDictData } from '@/stores/dictData'
import { getTime } from '@/utils/formatTime'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number]}, w: { type: [String, Number] },
h: { type: [String, Number]}, h: { type: [String, Number] },
width: { type: [String, Number]}, width: { type: [String, Number] },
height: { type: [String, Number]}, height: { type: [String, Number] },
timeKey: { type: [String, Number]}, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const headerHeight = ref(57) const headerHeight = ref(57)
const TableHeaderRef = ref()
const dictData = useDictData() const dictData = useDictData()
const sensitiveUserType = dictData.getBasicData('Sensitive_User_Type') const sensitiveUserType = dictData.getBasicData('Sensitive_User_Type')
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => { const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
headerHeight.value = height headerHeight.value = height
@@ -51,7 +63,6 @@ const fullscreen = computed(() => {
} }
}) })
const OverLimitDetailsRef = ref() const OverLimitDetailsRef = ref()
const tableStore: any = new TableStore({ const tableStore: any = new TableStore({
url: '/cs-harmonic-boot/pqSensitiveUser/getList', url: '/cs-harmonic-boot/pqSensitiveUser/getList',
@@ -92,12 +103,10 @@ const tableStore: any = new TableStore({
} }
], ],
beforeSearchFun: () => { beforeSearchFun: () => {
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0] setTime()
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
}, },
loadCallback: () => { loadCallback: () => {}
}
}) })
const tableRef = ref() const tableRef = ref()
@@ -113,6 +122,25 @@ const cellClickEvent = ({ row, column }: any) => {
} }
} }
const setTime = () => {
const time = getTime(
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
}
}
onMounted(() => { onMounted(() => {
setTimeout(() => { setTimeout(() => {
tableStore.index() tableStore.index()
@@ -127,17 +155,11 @@ watch(
watch( watch(
() => prop.timeValue, () => prop.timeValue,
(newVal, oldVal) => { (newVal, oldVal) => {
// 当外部时间值变化时,更新表格的时间参数
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() tableStore.index()
}
}, },
{ {
deep: true deep: true
} }
) )
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

View File

@@ -7,7 +7,7 @@
@selectChange="selectChange" @selectChange="selectChange"
datePicker datePicker
v-if="fullscreen" v-if="fullscreen"
:timeCacheFlag="false" :timeKeyList="['3']"
></TableHeader> ></TableHeader>
<el-calendar <el-calendar
v-model="value" v-model="value"
@@ -61,6 +61,7 @@ import TableStore from '@/utils/tableStore'
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 TableHeader from '@/components/table/header/index.vue'
import { getTime } from '@/utils/formatTime'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
@@ -68,7 +69,8 @@ const prop = defineProps({
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const headerHeight = ref(57) const headerHeight = ref(57)
@@ -119,10 +121,7 @@ const tableStore: any = new TableStore({
column: [], column: [],
beforeSearchFun: () => { beforeSearchFun: () => {
if (!fullscreen.value && prop.timeValue && Array.isArray(prop.timeValue)) { setTime()
tableStore.table.params.searchBeginTime = prop.timeValue[0]
tableStore.table.params.searchEndTime = prop.timeValue[1]
}
}, },
loadCallback: () => { loadCallback: () => {
@@ -148,42 +147,41 @@ provide('tableStore', tableStore)
onMounted(() => { onMounted(() => {
nextTick(() => { nextTick(() => {
if (TableHeaderRef.value && typeof TableHeaderRef.value.setDatePicker === 'function') {
TableHeaderRef.value.setDatePicker([{ label: '月份', value: 3 }])
}
if (fullscreen.value) {
TableHeaderRef.value.setInterval(3)
}
tableStore.index() tableStore.index()
}) })
}) })
watch(
() => prop.timeKey, const setTime = () => {
val => { const time = getTime(
tableStore.index() (TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
} }
) }
watch( watch(
() => prop.timeValue, () => prop.timeValue,
// (newVal, oldVal) => { (newVal, oldVal) => {
// // 当外部时间值变化时,更新表格的时间参数
// 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()
// }
// },
val => {
tableStore.index() tableStore.index()
}, },
{ {
deep: true deep: true
} }
) )
// 电压暂降点击事件 // 电压暂降点击事件
const descentClick = (item:any) => { const descentClick = (item: any) => {
transientListRef.value.open(item.name) transientListRef.value.open(item.name)
} }
</script> </script>

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<!--暂态事件概率分布 --> <!--暂态事件概率分布 -->
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader> <TableHeader ref="TableHeaderRef" :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
<my-echart <my-echart
class="tall" class="tall"
:options="echartList" :options="echartList"
@@ -26,6 +26,7 @@ import TableStore from '@/utils/tableStore'
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 TableHeader from '@/components/table/header/index.vue' import TableHeader from '@/components/table/header/index.vue'
import { getTime } from '@/utils/formatTime'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
@@ -33,9 +34,12 @@ const prop = defineProps({
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const TableHeaderRef = ref()
const headerHeight = ref(57) const headerHeight = ref(57)
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => { const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
@@ -66,135 +70,7 @@ const echartList = ref({})
const echartList1 = ref({}) const echartList1 = ref({})
// const echartList1 = ref({
// title: {
// text: '越限时间概率分布'
// },
// xAxis: {
// // name: '时间',
// // data: ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
// type: 'time',
// axisLabel: {
// formatter: {
// day: '{MM}-{dd}',
// month: '{MM}',
// year: '{yyyy}'
// }
// }
// },
// yAxis: {
// name: '次' // 给X轴加单位
// },
// grid: {
// left: '10px',
// right: '20px'
// },
// options: {
// series: [
// {
// type: 'line',
// showSymbol: false,
// // smooth: true,
// name: '电压中断',
// color: '#FF9100',
// data: [
// ['2025-10-16 07:00:00', 10],
// ['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]
// ]
// },
// {
// type: 'line',
// showSymbol: false,
// // smooth: true,
// color: '#FFBF00',
// name: '电压暂降',
// data: [
// ['2025-10-16 07:00:00', 1],
// ['2025-10-16 07:15:00', 1],
// ['2025-10-16 07:30:00', 1],
// ['2025-10-16 07:45:00', 1],
// ['2025-10-16 08:00:00', 3],
// ['2025-10-16 08:15:00', 5],
// ['2025-10-16 08:30:00', 6],
// ['2025-10-16 08:45:00', 7],
// ['2025-10-16 09:00:00', 10],
// ['2025-10-16 09:15:00', 12],
// ['2025-10-16 09:30:00', 13],
// ['2025-10-16 09:45:00', 14],
// ['2025-10-16 10:00:00', 16],
// ['2025-10-16 10:15:00', 16],
// ['2025-10-16 10:30:00', 13],
// ['2025-10-16 10:45:00', 12],
// ['2025-10-16 11:00:00', 14],
// ['2025-10-16 11:15:00', 8],
// ['2025-10-16 11:30:00', 7],
// ['2025-10-16 11:45:00', 9],
// ['2025-10-16 12:00:00', 6],
// ['2025-10-16 12:15:00', 6],
// ['2025-10-16 12:30:00', 6],
// ['2025-10-16 12:45:00', 6]
// ]
// },
// {
// type: 'line',
// showSymbol: false,
// // smooth: true,
// name: '电压暂升',
// color: config.layout.elementUiPrimary[0],
// data: [
// ['2025-10-16 07:00:00', 19],
// ['2025-10-16 07:15:00', 19],
// ['2025-10-16 07:30:00', 19],
// ['2025-10-16 07:45:00', 19],
// ['2025-10-16 08:00:00', 39],
// ['2025-10-16 08:15:00', 59],
// ['2025-10-16 08:30:00', 69],
// ['2025-10-16 08:45:00', 79],
// ['2025-10-16 09:00:00', 109],
// ['2025-10-16 09:15:00', 129],
// ['2025-10-16 09:30:00', 139],
// ['2025-10-16 09:45:00', 149],
// ['2025-10-16 10:00:00', 169],
// ['2025-10-16 10:15:00', 169],
// ['2025-10-16 10:30:00', 139],
// ['2025-10-16 10:45:00', 129],
// ['2025-10-16 11:00:00', 149],
// ['2025-10-16 11:15:00', 89],
// ['2025-10-16 11:30:00', 79],
// ['2025-10-16 11:45:00', 99],
// ['2025-10-16 12:00:00', 69],
// ['2025-10-16 12:15:00', 69],
// ['2025-10-16 12:30:00', 69],
// ['2025-10-16 12:45:00', 69]
// ]
// }
// ]
// }
// })
const processDataForChart = (rawData: any[]) => { const processDataForChart = (rawData: any[]) => {
// 将后端返回的扁平数据转换为 ECharts 需要的三维坐标格式 [x, y, z] // 将后端返回的扁平数据转换为 ECharts 需要的三维坐标格式 [x, y, z]
const chartData = rawData.map(item => [item.x, item.y, item.z]) const chartData = rawData.map(item => [item.x, item.y, item.z])
@@ -208,8 +84,7 @@ const tableStore: any = new TableStore({
showPage: false, showPage: false,
column: [], column: [],
beforeSearchFun: () => { beforeSearchFun: () => {
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0] setTime()
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
}, },
loadCallback: () => { loadCallback: () => {
const processedData = processDataForChart(tableStore.table.data.innerList || []) const processedData = processDataForChart(tableStore.table.data.innerList || [])
@@ -302,34 +177,17 @@ const tableStore: any = new TableStore({
type: 'category', type: 'category',
name: '特征幅值', name: '特征幅值',
data: xLabels, data: xLabels,
axisLine: { nameGap: 40,
lineStyle: {
color: '#111'
}
},
axisLabel: {
color: '#111'
}
}, },
yAxis3D: { yAxis3D: {
type: 'category', type: 'category',
name: '持续时间', name: '持续时间',
data: yLabels, data: yLabels,
nameTextStyle: { nameGap: 40,
color: '#111'
},
axisLine: {
show: true,
lineStyle: {
color: '#111'
}
},
axisLabel: {
color: '#111'
},
splitLine: { splitLine: {
lineStyle: { lineStyle: {
color: ['#111'],
type: 'dashed', type: 'dashed',
opacity: 0.5 opacity: 0.5
} }
@@ -337,15 +195,16 @@ const tableStore: any = new TableStore({
}, },
zAxis3D: { zAxis3D: {
type: 'value', type: 'value',
splitNumber: 10,
minInterval: 10, minInterval: 10,
name: '暂态事件次数' name: '暂态事件次数',
nameGap: 30,
}, },
grid3D: { grid3D: {
viewControl: { viewControl: {
projection: 'perspective', projection: 'perspective',
distance: 250 distance: 250
}, },
boxWidth: 200, boxWidth: 200,
boxDepth: 80, boxDepth: 80,
light: { light: {
@@ -369,20 +228,8 @@ const tableStore: any = new TableStore({
borderWidth: 1 borderWidth: 1
} }
}, },
itemStyle: {
opacity: 1
},
emphasis: {
label: {
textStyle: {
fontSize: 20,
color: '#900'
}
},
itemStyle: {
color: '#900'
}
}
} }
] ]
} }
@@ -419,26 +266,41 @@ provide('tableStore', tableStore)
onMounted(() => { onMounted(() => {
tableStore.index() tableStore.index()
}) })
const setTime = () => {
const time = getTime(
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
}
}
watch( watch(
() => prop.timeKey, () => prop.timeKey,
val => { val => {
tableStore.index() tableStore.index()
} }
) )
watch( watch(
() => prop.timeValue, () => prop.timeValue,
(newVal, oldVal) => { (newVal, oldVal) => {
// 当外部时间值变化时,更新表格的时间参数
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() tableStore.index()
}
}, },
{ {
deep: true deep: true
} }
) )
const addMenu = () => {}
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

View File

@@ -1,7 +1,13 @@
<template> <template>
<div> <div>
<!--暂态事件统计 --> <!--暂态事件统计 -->
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader> <TableHeader
ref="TableHeaderRef"
:showReset="false"
@selectChange="selectChange"
datePicker
v-if="fullscreen"
></TableHeader>
<my-echart <my-echart
class="tall" class="tall"
:options="echartList" :options="echartList"
@@ -28,6 +34,7 @@ import { useConfig } from '@/stores/config'
import TransientStatisticsDetail from '@/components/cockpit/transientStatistics/components/transientStatisticsDetail.vue' import TransientStatisticsDetail from '@/components/cockpit/transientStatistics/components/transientStatisticsDetail.vue'
import TableHeader from '@/components/table/header/index.vue' import TableHeader from '@/components/table/header/index.vue'
import { netEventEcharts } from '@/api/harmonic-boot/cockpit/cockpit' import { netEventEcharts } from '@/api/harmonic-boot/cockpit/cockpit'
import { getTime } from '@/utils/formatTime'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
@@ -35,9 +42,12 @@ const prop = defineProps({
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const TableHeaderRef = ref()
const headerHeight = ref(57) const headerHeight = ref(57)
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => { const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
@@ -199,8 +209,7 @@ const tableStore: any = new TableStore({
} }
], ],
beforeSearchFun: () => { beforeSearchFun: () => {
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0] setTime()
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
}, },
loadCallback: () => { loadCallback: () => {
eventEcharts() eventEcharts()
@@ -223,6 +232,25 @@ const cellClickEvent = ({ row, column }: any) => {
} }
} }
const setTime = () => {
const time = getTime(
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
}
}
onMounted(() => { onMounted(() => {
setTimeout(() => { setTimeout(() => {
tableStore.index() tableStore.index()
@@ -237,12 +265,7 @@ watch(
watch( watch(
() => prop.timeValue, () => prop.timeValue,
(newVal, oldVal) => { (newVal, oldVal) => {
// 当外部时间值变化时,更新表格的时间参数
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() tableStore.index()
}
}, },
{ {
deep: true deep: true

View File

@@ -1,7 +1,14 @@
<template> <template>
<div> <div>
<!--趋势对比 --> <!--趋势对比 -->
<TableHeader datePicker :showReset="false" @selectChange="selectChange" v-if="fullscreen"> <TableHeader
datePicker
ref="TableHeaderRef"
:timeKeyList="['4', '5']"
:showReset="false"
@selectChange="selectChange"
v-if="fullscreen"
>
<template v-slot:select> <template v-slot:select>
<el-form-item label="监测对象"> <el-form-item label="监测对象">
<el-select v-model="tableStore.table.params.sensitiveUserId" placeholder="请选择监测对象" clearable> <el-select v-model="tableStore.table.params.sensitiveUserId" placeholder="请选择监测对象" clearable>
@@ -77,10 +84,9 @@ import TableStore from '@/utils/tableStore'
import TableHeader from '@/components/table/header/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 { useConfig } from '@/stores/config' import { useConfig } from '@/stores/config'
import { useRoute } from 'vue-router'
import { useTimeCacheStore } from '@/stores/timeCache'
import { queryByCode, queryCsDictTree } from '@/api/system-boot/dictTree' import { queryByCode, queryCsDictTree } from '@/api/system-boot/dictTree'
import { getListByIds } from '@/api/harmonic-boot/cockpit/cockpit' import { getListByIds } from '@/api/harmonic-boot/cockpit/cockpit'
import { getTime } from '@/utils/formatTime'
const prop = defineProps({ const prop = defineProps({
w: { type: [String, Number] }, w: { type: [String, Number] },
@@ -88,15 +94,13 @@ const prop = defineProps({
width: { type: [String, Number] }, width: { type: [String, Number] },
height: { type: [String, Number] }, height: { type: [String, Number] },
timeKey: { type: [String, Number] }, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object },
interval: { type: Number }
}) })
const route = useRoute() const TableHeaderRef = ref()
const timeCacheStore = useTimeCacheStore()
const config = useConfig() const config = useConfig()
const lineIdList = ref(JSON.parse(window.localStorage.getItem('lineIdList') || '[]'))
// 计算是否全屏展示 // 计算是否全屏展示
const fullscreen = computed(() => { const fullscreen = computed(() => {
const w = Number(prop.w) const w = Number(prop.w)
@@ -231,7 +235,7 @@ const setEchart = () => {
data: afterGroupedByPhase[phase], data: afterGroupedByPhase[phase],
itemStyle: { itemStyle: {
normal: { normal: {
color:color color: color
} }
}, },
lineStyle: { lineStyle: {
@@ -324,8 +328,7 @@ const tableStore: any = new TableStore({
exportName: '趋势对比', exportName: '趋势对比',
column: [], column: [],
beforeSearchFun: () => { beforeSearchFun: () => {
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0] setTime()
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
if (!tableStore.table.params.sensitiveUserId && idList.value?.length > 0) { if (!tableStore.table.params.sensitiveUserId && idList.value?.length > 0) {
tableStore.table.params.sensitiveUserId = idList.value[0].id tableStore.table.params.sensitiveUserId = idList.value[0].id
} }
@@ -370,6 +373,25 @@ onMounted(() => {
initListByIds() initListByIds()
}) })
const setTime = () => {
const time = getTime(
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
prop.timeKey,
fullscreen.value
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
: prop.timeValue
)
if (Array.isArray(time)) {
tableStore.table.params.searchBeginTime = time[0]
tableStore.table.params.searchEndTime = time[1]
TableHeaderRef.value?.setInterval(time[2] - 0)
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
} else {
console.warn('获取时间失败time 不是一个有效数组')
}
}
// 判断是否应该显示谐波次数选择框 // 判断是否应该显示谐波次数选择框
const shouldShowHarmonicCount = () => { const shouldShowHarmonicCount = () => {
if (!tableStore.table.params.indicator || !indicatorList.value) return false if (!tableStore.table.params.indicator || !indicatorList.value) return false
@@ -405,12 +427,7 @@ watch(
watch( watch(
() => prop.timeValue, () => prop.timeValue,
(newVal, oldVal) => { (newVal, oldVal) => {
// 当外部时间值变化时,更新表格的时间参数
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() tableStore.index()
}
}, },
{ {
deep: true deep: true
@@ -433,7 +450,6 @@ watch(
} }
) )
const addMenu = () => {}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
// :deep(.el-select) { // :deep(.el-select) {

View File

@@ -5,7 +5,7 @@
style="min-width: 90px; width: 90px; margin-right: 10px" style="min-width: 90px; width: 90px; margin-right: 10px"
@change="timeChange" @change="timeChange"
> >
<el-option v-for="item in timeOptions" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in filteredTimeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
<el-date-picker <el-date-picker
v-model.trim="timeValue" v-model.trim="timeValue"
@@ -35,13 +35,15 @@ interface Props {
theCurrentTime?: boolean theCurrentTime?: boolean
initialInterval?: number initialInterval?: number
initialTimeValue?: any initialTimeValue?: any
timeKeyList?: string[] //日期下拉
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
nextFlag: false, nextFlag: false,
theCurrentTime: true, theCurrentTime: true,
initialInterval: 3, initialInterval: 3,
initialTimeValue: undefined initialTimeValue: undefined,
timeKeyList: () => []
}) })
const emit = defineEmits(['change']) const emit = defineEmits(['change'])
@@ -89,6 +91,19 @@ const shortcuts = [
} }
} }
] ]
// 计算过滤后的 timeOptions
const filteredTimeOptions = computed(() => {
if (!props.timeKeyList || props.timeKeyList.length === 0) {
return timeOptions.value
}
return timeOptions.value.filter((option: any) =>
props.timeKeyList.includes(option.value.toString())
)
})
onMounted(() => { onMounted(() => {
// 使用传入的初始值 // 使用传入的初始值
if (props.initialInterval !== undefined) { if (props.initialInterval !== undefined) {

View File

@@ -15,6 +15,7 @@
:nextFlag="nextFlag" :nextFlag="nextFlag"
:theCurrentTime="theCurrentTime" :theCurrentTime="theCurrentTime"
@change="handleDatePickerChange" @change="handleDatePickerChange"
:timeKeyList="props.timeKeyList"
></DatePicker> ></DatePicker>
</el-form-item> </el-form-item>
@@ -89,6 +90,7 @@ interface Props {
showReset?: boolean //是否显示重置 showReset?: boolean //是否显示重置
showExport?: boolean //导出控制 showExport?: boolean //导出控制
timeCacheFlag?: boolean //是否取缓存时间 timeCacheFlag?: boolean //是否取缓存时间
timeKeyList?: Array<string> //日期下拉列表
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
@@ -99,7 +101,8 @@ const props = withDefaults(defineProps<Props>(), {
theCurrentTime: true, theCurrentTime: true,
showReset: true, showReset: true,
showExport: false, showExport: false,
timeCacheFlag: true timeCacheFlag: true,
timeKeyList: () => [] // 修改为箭头函数返回空数组
}) })
// 处理 DatePicker 值变化事件 // 处理 DatePicker 值变化事件

View File

@@ -352,7 +352,9 @@ export function getTimeOfTheMonth(key: any): [string, string] {
const dayOfWeek = now.getDay() // 0是周日 const dayOfWeek = now.getDay() // 0是周日
const diff = now.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1) // 调整为周一 const diff = now.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1) // 调整为周一
const weekStart = new Date(year, month, diff) const weekStart = new Date(year, month, diff)
return [formatDate(weekStart, 'YYYY-MM-DD'), formatDate(now, 'YYYY-MM-DD')] const weekEnd = new Date(weekStart)
weekEnd.setDate(weekEnd.getDate() + 6)
return [formatDate(weekStart, 'YYYY-MM-DD'), formatDate(weekEnd, 'YYYY-MM-DD')]
case '5': // 日 case '5': // 日
return [formatDate(now, 'YYYY-MM-DD'), formatDate(now, 'YYYY-MM-DD')] return [formatDate(now, 'YYYY-MM-DD'), formatDate(now, 'YYYY-MM-DD')]
@@ -361,3 +363,23 @@ export function getTimeOfTheMonth(key: any): [string, string] {
throw new Error('Invalid key') throw new Error('Invalid key')
} }
} }
/**
* 获取当月时间
* @param interval 组件外部时间 1 年 2 季 3 月 4 周 5 日
* @param timeList 驾驶舱里面组件勾选时间 []
* @param externalTime //外部传入时间
* @param fullscreen // 全屏是否全屏
*/
export function getTime(interval: number | 3, timeList: any, externalTime: any) {
console.log('🚀 ~ getTime ~ timeList:', timeList)
// 1、先匹配时间
// 检查 interval 是否在 timeList 中
if (timeList && timeList.includes(interval.toString())) {
return [externalTime[0], externalTime[1], interval]
} else {
if (timeList && timeList.length > 0) {
return [...getTimeOfTheMonth(timeList[0]), timeList[0]]
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -142,7 +142,7 @@ 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.open(
'http://192.168.1.179:4001' + 'http://192.168.1.128:4001' +
`/zutai/?id=${e.id}&&name=${e.name}&&preview=false&&graphicDisplay=${VITE_FLAG ? 'ypt' : 'zl'}` `/zutai/?id=${e.id}&&name=${e.name}&&preview=false&&graphicDisplay=${VITE_FLAG ? 'ypt' : 'zl'}`
) )
} }

View File

@@ -16,7 +16,6 @@
<el-button type="primary" icon="el-icon-Tools" @click="settings">设置</el-button> <el-button type="primary" icon="el-icon-Tools" @click="settings">设置</el-button>
</template> </template>
</TableHeader> </TableHeader>
<GridLayout <GridLayout
v-model:layout="layout" v-model:layout="layout"
:row-height="rowHeight" :row-height="rowHeight"
@@ -26,6 +25,7 @@
:vertical-compact="false" :vertical-compact="false"
prevent-collision prevent-collision
:col-num="12" :col-num="12"
:style="{ zoom: zoom }"
> >
<template #item="{ item }"> <template #item="{ item }">
<div class="box"> <div class="box">
@@ -34,8 +34,8 @@
<Icon class="HelpFilled" :name="(item as LayoutItem).icon" /> <Icon class="HelpFilled" :name="(item as LayoutItem).icon" />
{{ (item as LayoutItem).name }} {{ (item as LayoutItem).name }}
</div> </div>
<!-- <FullScreen class="HelpFilled" style="cursor: pointer" @click="zoom(item)" /> --> <!-- <FullScreen class="HelpFilled" style="cursor: pointer" @click="setZoom(item)" /> -->
<img :src="flag ? img : img1" style="cursor: pointer; height: 16px" @click="zoom(item)" /> <img :src="flag ? img : img1" style="cursor: pointer; height: 16px" @click="setZoom(item)" />
</div> </div>
<div> <div>
<component <component
@@ -46,7 +46,7 @@
:timeValue="datePickerRef?.timeValue || 3" :timeValue="datePickerRef?.timeValue || 3"
: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).timeKeys"
:interval="datePickerRef?.interval" :interval="datePickerRef?.interval"
:w="item.w" :w="item.w"
:h="item.h" :h="item.h"
@@ -80,13 +80,14 @@ const timeCacheStore = useTimeCacheStore()
defineOptions({ defineOptions({
// name: 'dashboard/index' // name: 'dashboard/index'
}) })
// 定义类型 // 定义类型
interface LayoutItem { interface LayoutItem {
x: number x: number
y: number y: number
w: number w: number
h: number h: number
timeKey: number | string timeKeys: any
i: string | number i: string | number
name: string name: string
path: string path: string
@@ -95,6 +96,7 @@ interface LayoutItem {
loading?: boolean loading?: boolean
error?: any error?: any
} }
const zoom = ref(1)
const RoutingConfigRef = ref() const RoutingConfigRef = ref()
const key = ref(0) const key = ref(0)
const img = new URL(`@/assets/img/amplify.png`, import.meta.url).href const img = new URL(`@/assets/img/amplify.png`, import.meta.url).href
@@ -120,13 +122,16 @@ const componentMap = reactive(new Map<string, Component | string>())
const dataList: any = ref({}) const dataList: any = ref({})
// 获取主内容区域高度 // 获取主内容区域高度
const getMainHeight = () => { const getMainHeight = () => {
const elMain = document.querySelector('.el-main') const elMain = document.querySelector('.el-main') as HTMLElement | null
return (elMain?.offsetHeight || 0) - 70 zoom.value =
layout.value.length == 1 ? 1 : (elMain?.offsetHeight ?? 0) > 1080 ? 1 : (elMain?.offsetHeight ?? 0) / 1080
// console.log('🚀 ~ getMainHeight ~ elMain:', elMain?.offsetHeight)
return ((elMain?.offsetHeight || 0) - 70) / zoom.value
} }
// 获取主内容区域高度 // 获取主内容区域高度
const getMainWidth = () => { const getMainWidth = () => {
const elMain = document.querySelector('.el-main') const elMain = document.querySelector('.el-main') as HTMLElement | null
return (elMain?.offsetWidth || 0) - 20 return ((elMain?.offsetWidth || 0) - 20) / zoom.value
} }
// 初始化行高 // 初始化行高
@@ -170,8 +175,9 @@ const registerComponent = (path: string): Component | string | null => {
return null return null
} }
} }
// 缩放 // 缩放
const zoom = (value: any) => { const setZoom = (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 {
@@ -181,7 +187,6 @@ const zoom = (value: any) => {
component: registerComponent(item.path) component: registerComponent(item.path)
})) }))
} }
console.log("🚀 ~ zoom ~ layout.value:", layout.value)
flag.value = !flag.value flag.value = !flag.value

View File

@@ -1,459 +0,0 @@
<template>
<div class="container">
<!-- 使用 v-for 遍历四个角落 -->
<div v-for="corner in corners" v-show="corner.show" :key="corner.id" :class="['corner', corner.className]">
<div class="content">
<div class="title" style="display: flex">
<img src="@/assets/img/lightning.png" class="title_img" />
<span>{{ corner.title }}</span>
</div>
<vxe-table
:data="corner.data"
size="small"
border
show-header
:header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
height="200"
style="padding: 5px;"
>
<vxe-column field="name" title="名称"></vxe-column>
<vxe-column field="a" title="A" width="40"></vxe-column>
<vxe-column field="b" title="B" width="40"></vxe-column>
<vxe-column field="c" title="C" width="40"></vxe-column>
</vxe-table>
</div>
<span class="close-btn" @click="closeCorner(corner.id)">
<Close />
</span>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, nextTick, reactive } from 'vue'
// import { clickImage } from "@/api/manage_wx";
import { Close } from '@element-plus/icons-vue'
import socketClient from '@/utils/webSocketClient'
//开始创建webSocket客户端
const dataSocket = reactive({
socketServe: socketClient.Instance
})
// 定义四个角落的数据
const corners = ref([
{
id: 'topLeft',
title: '左上',
className: 'top-left',
show: false,
data: [
{ name: '电压', a: 1098, b: 2080, c: 3006 },
{ name: '电流', a: 15, b: 25, c: 35 },
{ name: '电压畸变率', a: 12, b: 22, c: 32 },
{ name: '电流畸变率', a: 18, b: 28, c: 38 },
{ name: '电压偏值', a: 12, b: 22, c: 32 },
{ name: '电压不平衡', a: 18, b: 28, c: 38 }
] as any[],
elementId: '', // 记录该角落对应的元素ID
raceLists: [] as any[] // 为每个角落添加独立的跑马灯数据存储
},
{
id: 'topRight',
title: '右上',
className: 'top-right',
show: false,
data: [] as any[],
elementId: '',
raceLists: [] as any[] // 为每个角落添加独立的跑马灯数据存储
}
// {
// id: "bottomLeft",
// title: "左下",
// className: "bottom-left",
// show: false,
// data: [] as { label: string; value: string }[],
// elementId: "",
// },
// {
// id: "bottomRight",
// title: "右下",
// className: "bottom-right",
// show: false,
// data: [] as { label: string; value: string }[],
// elementId: "",
// },
])
interface DataTableItem {
name: string
a: number
b: number
c: number
}
const tableData = ref<DataTableItem[]>([
{ name: '电压', a: 1098, b: 2080, c: 3006 },
{ name: '电流', a: 15, b: 25, c: 35 },
{ name: '电压畸变率', a: 12, b: 22, c: 32 },
{ name: '电流畸变率', a: 18, b: 28, c: 38 },
{ name: '电压偏值', a: 12, b: 22, c: 32 },
{ name: '电压不平衡', a: 18, b: 28, c: 38 }
])
const steadyStateList = ref([])
const selectedId = ref('')
// 内部响应式数据
const eventList = ref<any[]>([])
// const handleClickImage = async (elementId: string) => {
// // 检查 elementId 是否有值,没有值则直接返回空数组
// if (!elementId) {
// eventList.value = [];
// return;
// }
// try {
// // 发送点击图片请求
// const res = await clickImage({ lineId: elementId });
// // 确保返回的数据是数组格式,并且过滤掉 null/undefined 元素
// let dataToStore: any[] = [];
// if (Array.isArray(res.data)) {
// dataToStore = res.data.filter(
// (item:any) => item !== null && item !== undefined
// );
// } else if (res.data && Array.isArray(res.data.records)) {
// dataToStore = res.data.records.filter(
// (item:any) => item !== null && item !== undefined
// );
// } else if (res.data) {
// // 如果是单个对象且不为 null
// if (res.data !== null && res.data !== undefined) {
// dataToStore = [res.data];
// }
// }
// eventList.value = dataToStore;
// } catch (error) {
// console.error("调用 clickImage 接口出错:", error);
// // 出错时设置为空数组,避免后续处理出错
// eventList.value = [];
// }
// };
// 记录显示顺序,用于循环替换
const displayOrder = ref<number[]>([])
// 更新指定角落数据的函数
const updateCornerData = (cornerIndex: number, dataItem: any, elementId: string) => {
// 更新标题为 objName
if (dataItem.objName) {
corners.value[cornerIndex].title = dataItem.objName
} else {
corners.value[cornerIndex].title = dataItem.stationName
}
// 格式化数据
corners.value[cornerIndex].data = [
{ label: '监测点', value: dataItem.lineName },
// {
// label: "暂降次数",
// value: dataItem.eventIds.length,
// },
{
label: '暂降次数',
value: ``
},
// { label: "稳态指标", value: "Ua:65.5 Ub:65.02 Uc:65.27 Uac:112.85 Uab:112.67 Ubc:112.85" },
{
label: '稳态指标',
value: ``
}
]
// 记录该角落对应的元素ID
corners.value[cornerIndex].elementId = elementId
corners.value[cornerIndex].show = true
}
// 显示下一个角落的函数
const showNextCorner = (elementId: string) => {
// 检查该元素ID是否已经显示过
const existingCornerIndex = corners.value.findIndex(corner => corner.elementId === elementId && corner.show)
if (existingCornerIndex !== -1) {
// 如果该元素已经显示过,不更新数据
return
}
// 确保 eventList.value 是数组并且过滤掉 null/undefined 元素
if (!Array.isArray(eventList.value)) {
console.warn('eventList.value 不是数组格式:', eventList.value)
return
}
// 过滤掉 null 和 undefined 元素,然后查找匹配项
const validItems = eventList.value.filter(item => item !== null && item !== undefined)
const dataItem = validItems.find(item => item.lineId === elementId)
// 如果没有找到匹配的数据项,则不更新数据
if (!dataItem) {
console.warn('未找到匹配的数据项:', elementId)
return
}
// 查找一个未显示的角落
const availableCornerIndex = corners.value.findIndex(corner => !corner.show)
if (availableCornerIndex !== -1) {
// 有空闲角落,显示在该角落
updateCornerData(availableCornerIndex, dataItem, elementId)
// 将事件数据存储到该角落
corners.value[availableCornerIndex].raceLists = dataItem.eventList || []
// 记录显示顺序
displayOrder.value.push(availableCornerIndex)
} else {
// 没有空闲角落,按顺序替换角落
// 获取需要替换的角落索引(循环替换)
const replaceIndex = displayOrder.value.shift() || 0
updateCornerData(replaceIndex, dataItem, elementId)
// 将事件数据存储到该角落
corners.value[replaceIndex].raceLists = dataItem.eventList || []
// 将替换的索引重新加入队列末尾
displayOrder.value.push(replaceIndex)
}
}
// 关闭指定角落的函数
const closeCorner = (id: string) => {
const cornerIndex = corners.value.findIndex(c => c.id === id)
if (cornerIndex !== -1) {
corners.value[cornerIndex].show = false
corners.value[cornerIndex].elementId = '' // 清空元素ID记录
// 从显示顺序中移除该角落索引
const orderIndex = displayOrder.value.indexOf(cornerIndex)
if (orderIndex !== -1) {
displayOrder.value.splice(orderIndex, 1)
}
}
send()
}
// 关闭所有角落的函数
const closeAllCorners = () => {
corners.value.forEach(corner => {
corner.show = false
corner.elementId = ''
})
displayOrder.value = []
}
// 组件挂载后初始化监听器
onMounted(() => {
init()
// 初始化时不显示任何内容
})
// 连接webSocket客户端
const init = () => {
if (!dataSocket.socketServe) {
console.error('WebSocket 客户端实例不存在')
return
}
dataSocket.socketServe.connect(new Date().getTime())
dataSocket.socketServe.registerCallBack('message', (res: any) => {
if (res.type == 1) {
//稳态指标数据
let steadyState = JSON.parse(res.message)
// console.log(steadyState, "8990hhhhh");
if (steadyState == null || steadyState.length == 0) return
steadyStateList.value = steadyState
corners.value.forEach((corner, index) => {
let str = ``
steadyState
.filter((item: any) => item.lineId == corner.elementId)
.forEach((item: any) => {
if (item.value == 3.1415926) {
str += `<div>${item.statisticalName}/</div>`
} else {
str += `<div>${item.statisticalName}${item.value}${item.unit}</div>`
}
})
corner.data.length > 0
? (corner.data[2].value = `<div style="max-height: 100px;overflow-y: auto;">${str} </div>`)
: ''
})
}
})
}
const time = ref(null)
// 推送消息
const send = () => {
dataSocket.socketServe.send({
pageId: selectedId.value,
lineIdList: corners.value.filter(item => item.show == true).map(corner => corner.elementId)
})
if (time.value) {
clearTimeout(time.value)
}
if (corners.value.filter(item => item.show == true).map(corner => corner.elementId).length == 0) return
time.value = setInterval(() => {
dataSocket.socketServe.send({
pageId: selectedId.value,
lineIdList: corners.value.filter(item => item.show == true).map(corner => corner.elementId)
})
}, 1000 * 60)
}
// 监听来自 iframe 的消息
window.addEventListener('message', async function (event) {
// 安全起见可以验证消息来源origin
// if (event.origin !== 'https://trusted-origin.com') return;
// 处理从 iframe 发送过来的消息
if (event.data.action === 'coreClick') {
const clickedElementId = event.data.coreId
selectedId.value = event.data.selectedId
// 调用接口获取最新数据
// await handleClickImage(clickedElementId);
// 根据接收到的元素LineId显示对应数据
await showNextCorner(clickedElementId)
await send()
}
})
// 页面卸载时清除定时器
onBeforeUnmount(() => {
clearTimeout(time.value)
dataSocket.socketServe?.closeWs()
})
</script>
<style scoped lang="scss">
.container {
position: relative;
}
.corner {
width: 240px;
/* height: 135px; */
background-color: #fff;
position: absolute;
color: #000;
/* font-weight: bold; */
/* 添加弹出动画 */
opacity: 0;
transform: scale(0.3);
transition: all 0.4s ease-out;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}
/* 显示状态的样式 */
.corner:not([style*='display: none']):not([style*='display:none']) {
opacity: 1;
transform: scale(1);
}
.top-left {
top: 10px;
left: 10px;
}
.top-right {
top: 10px;
right: 10px;
}
.bottom-left {
top: 170px;
left: 10px;
}
.bottom-right {
top: 170px;
right: 10px;
}
.content {
width: 100%;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.title {
font-size: 16px;
// text-align: center;
padding: 5px;
color: #fff;
border-bottom: 1px solid #444;
background-color: var(--el-color-primary);
border-radius: 8px 8px 0 0;
}
.title_img {
width: 25px;
height: 25px;
margin-right: 10px;
}
.data-item {
display: flex;
margin-bottom: 4px;
font-size: 12px;
}
.label {
/* font-weight: bold; */
width: 55px;
flex-shrink: 0;
}
.value {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 关闭按钮样式 */
.close-btn {
position: absolute;
top: 10px;
right: 10px;
width: 14px;
color: white;
font-size: 14px;
font-weight: bold;
cursor: pointer;
}
.indicator {
display: flex;
}
.table {
width: 100%;
border-collapse: collapse;
}
.table th,
.table td {
border: 1px solid #000;
text-align: center;
font-size: 12px;
}
</style>

View File

@@ -2,13 +2,13 @@
<div class="default-main" :style="{ padding: prop.height ? '0px !important' : '10px' }"> <div class="default-main" :style="{ padding: prop.height ? '0px !important' : '10px' }">
<!-- 实时数据 --> <!-- 实时数据 -->
<!-- 添加加载事件监听 --> <!-- 添加加载事件监听 -->
<div class="dataBox" :style="{ height: prop.height || pageHeight.height }" > <div class="dataBox" :style="{ height: prop.height || pageHeight.height }">
<div <div
class="iframe-container" class="iframe-container"
:style="{ :style="{
boxShadow: `var(--el-box-shadow-light)` boxShadow: `var(--el-box-shadow-light)`
}" }"
style="position: relative;" style="position: relative"
> >
<iframe <iframe
:src="iframeSrc" :src="iframeSrc"
@@ -19,17 +19,20 @@
id="iframeLeft" id="iframeLeft"
@load="onIframeLoad" @load="onIframeLoad"
></iframe> ></iframe>
<IframeDia
style="position: absolute; top: 0px; right: 0px; left: 0px"
/>
</div> </div>
<el-card class="bottom-container " style="min-height: 230px;"> <el-card class="bottom-container" style="min-height: 230px">
<div class="buttonBox"> <div class="buttonBox">
<el-button type="primary" icon="el-icon-Aim" @click="reset">复位</el-button> <el-button type="primary" icon="el-icon-Aim" @click="reset">复位</el-button>
</div> </div>
<div class="tableBox"> <div class="tableBox">
<Table ref="tableRef" height="100%"></Table> <!-- <Table ref="tableRef" height="100%"></Table> -->
<vxe-table border auto-resize height="100%" :data="tableData" ref="tableRef">
<vxe-column type="seq" title="序号" align="center" width="80px"></vxe-column>
<vxe-column field="date" align="center" title="时间" width="200px"></vxe-column>
<vxe-column field="name" align="center" title="监测点名" width="200px"></vxe-column>
<vxe-column field="address" align="center" title="事件描述"></vxe-column>
</vxe-table>
</div> </div>
</el-card> </el-card>
</div> </div>
@@ -40,7 +43,6 @@ import { ref, watch, onMounted, onUnmounted, provide } from 'vue'
import Table from '@/components/table/index.vue' import Table from '@/components/table/index.vue'
import TableStore from '@/utils/tableStore' import TableStore from '@/utils/tableStore'
import { mainHeight } from '@/utils/layout' import { mainHeight } from '@/utils/layout'
import IframeDia from './iframeDia.vue'
// import { getActive } from "@/api/manage_wx/index"; // import { getActive } from "@/api/manage_wx/index";
// const props = defineProps<{ // const props = defineProps<{
@@ -48,85 +50,115 @@ import IframeDia from './iframeDia.vue'
// }>() // }>()
const prop = defineProps({ const prop = defineProps({
width: { type: [String, Number]}, width: { type: [String, Number] },
height: { type: [String, Number]}, height: { type: [String, Number] },
timeKey: { type: [String, Number]}, timeKey: { type: [String, Number] },
timeValue: { type: Object } timeValue: { type: Object }
}) })
const tableStore: any = new TableStore({ const tableData = ref()
url: '/user-boot/role/selectRoleDetail?id=0',
method: 'POST',
showPage: false, // 在父页面中添加事件监听器
window.addEventListener('message', function (event) {
const { action, data } = event.data
column: [ if (action == 'securityDetailData') {
{ console.log('tableArray:', data)
field: 'index', // 处理接收到的 tableArray 数据
title: '序号', tableData.value = data
width: '80',
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{
title: '时间',
field: 'whetherToGovern',
minWidth: '70'
},
{
title: '监测点名',
field: 'name',
minWidth: '90'
// render: 'customTemplate',
// customTemplate: (row: any) => {
// return `<span style='cursor: pointer;text-decoration: underline;'>${row.name}</span>`
// }
},
{ title: '事件描述', field: 'question', minWidth: '200' }
],
beforeSearchFun: () => {
// tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
// tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
},
loadCallback: () => {
tableStore.table.data = [
{
name: '10kV1#电动机',
type: '电动机',
whetherToGovern: '2025-01-01 15:00:00',
question: '3次谐波电压、5次谐波电流、电压不平衡度超标'
},
{
name: '10kV2#(治理后)',
type: '电焊机',
whetherToGovern: '2025-05-01 16:00:00',
question: '所有指标均合格'
},
{
name: '380V电焊机(治理前)',
type: '电焊机',
whetherToGovern: '2025-06-01 15:00:00',
question: '5次谐波电流、电压不平衡度超标'
},
{
name: '380V水泵机',
type: '电动机',
whetherToGovern: '2025-08-01 15:00:00',
question: '所有指标均合格'
}
]
} }
}) })
// const tableStore: any = new TableStore({
// url: '/user-boot/role/selectRoleDetail?id=0',
// method: 'POST',
// showPage: false,
// column: [
// {
// field: 'index',
// title: '序号',
// width: '80',
// formatter: (row: any) => {
// return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
// }
// },
// {
// title: '时间',
// field: 'whetherToGovern',
// minWidth: '70'
// },
// {
// title: '监测点名',
// field: 'name',
// minWidth: '90'
// // render: 'customTemplate',
// // customTemplate: (row: any) => {
// // return `<span style='cursor: pointer;text-decoration: underline;'>${row.name}</span>`
// // }
// },
// { title: '事件描述', field: 'question', minWidth: '200' }
// ],
// beforeSearchFun: () => {
// // tableStore.table.params.searchBeginTime = prop.timeValue?.[0] || getTimeOfTheMonth(prop.timeKey)[0]
// // tableStore.table.params.searchEndTime = prop.timeValue?.[1] || getTimeOfTheMonth(prop.timeKey)[1]
// },
// loadCallback: () => {
// tableStore.table.data = [
// {
// name: '10kV1#电动机',
// type: '电动机',
// whetherToGovern: '2025-01-01 15:00:00',
// question: '3次谐波电压、5次谐波电流、电压不平衡度超标'
// },
// {
// name: '10kV2#(治理后)',
// type: '电焊机',
// whetherToGovern: '2025-05-01 16:00:00',
// question: '所有指标均合格'
// },
// {
// name: '380V电焊机(治理前)',
// type: '电焊机',
// whetherToGovern: '2025-06-01 15:00:00',
// question: '5次谐波电流、电压不平衡度超标'
// },
// {
// name: '380V水泵机',
// type: '电动机',
// whetherToGovern: '2025-08-01 15:00:00',
// question: '所有指标均合格'
// }
// ]
// }
// })
const tableRef = ref() const tableRef = ref()
provide('tableRef', tableRef) // provide('tableRef', tableRef)
const pageHeight = mainHeight(40) // const pageHeight = mainHeight(40)
provide('tableStore', tableStore) // provide('tableStore', tableStore)
const reset = () => { const reset = () => {
tableRef.value.reset() // 向 iframe 发送复位事件
sendResetToIframe();
// 清空表格数据
// tableData.value = [];
}
// 向 iframe 发送复位消息的函数
const sendResetToIframe = () => {
const iframe = document.getElementById('iframeLeft') as HTMLIFrameElement;
if (iframe && iframe.contentWindow) {
iframe.contentWindow.postMessage(
{
type: 'RESET_EVENT',
payload: true
},
'*' // 生产环境中应替换为具体的域名
);
}
} }
const iframeSrc = ref('') const iframeSrc = ref('')
@@ -154,10 +186,9 @@ const iframeSrc = ref('')
onMounted(() => { onMounted(() => {
iframeSrc.value = iframeSrc.value =
'http://192.168.1.179:4001' + 'http://192.168.1.128:4001' + `/zutai/?id=4b4f7f4260198776594f5f9d93a532e8&&name=stt&&preview=true#/preview_YPT`
`/zutai/?id=4b4f7f4260198776594f5f9d93a532e8&&name=stt&&preview=true#/preview_YPT`
tableStore.index() // tableStore.index()
// 监听来自 eventStatistics 组件的消息 // 监听来自 eventStatistics 组件的消息
window.addEventListener('message', handleMessage) window.addEventListener('message', handleMessage)

View File

@@ -337,7 +337,7 @@ function dragEnd(row: any) {
name: row.name, name: row.name,
path: row.path, path: row.path,
icon: row.icon, icon: row.icon,
timeKey: row.timeKey timeKeys: row.timeKeys
}) })
gridLayout.value.dragEvent('dragend', dragItem.i, dragItem.x, dragItem.y, dragItem.h, dragItem.w) gridLayout.value.dragEvent('dragend', dragItem.i, dragItem.x, dragItem.y, dragItem.h, dragItem.w)
const item = gridLayout.value.getItem(dropId) const item = gridLayout.value.getItem(dropId)

View File

@@ -43,7 +43,7 @@
:timeValue="datePickerRef.timeValue" :timeValue="datePickerRef.timeValue"
: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.timeKey" :timeKey="item.timeKeys"
/> />
<div v-else class="pd10">组件加载失败...</div> <div v-else class="pd10">组件加载失败...</div>
</div> </div>

View File

@@ -1,14 +1,25 @@
<template> <template>
<el-dialog draggable class="cn-operate-dialog" v-model="dialogVisible" width="1000px" :title="title" <el-dialog
@close="cancel"> draggable
class="cn-operate-dialog"
v-model="dialogVisible"
width="1000px"
:title="title"
@close="cancel"
>
<div style="display: flex"> <div style="display: flex">
<el-form :inline="false" :model="form" label-width="auto" :rules="rules" ref="formRef" style="flex: 1"> <el-form :inline="false" :model="form" label-width="auto" :rules="rules" ref="formRef" style="flex: 1">
<el-form-item class="top" label="组件名称" prop="name"> <el-form-item class="top" label="组件名称" prop="name">
<el-input v-model="form.name" placeholder="请输入组件名称"></el-input> <el-input v-model="form.name" placeholder="请输入组件名称"></el-input>
</el-form-item> </el-form-item>
<el-form-item class="top" label="父组件节点" prop="system"> <el-form-item class="top" label="父组件节点" prop="system">
<el-cascader v-model="form.system" :options="customDeptOption" :props="props" placeholder="请选择父组件节点" <el-cascader
style="width: 100%" /> v-model="form.system"
:options="customDeptOption"
:props="props"
placeholder="请选择父组件节点"
style="width: 100%"
/>
</el-form-item> </el-form-item>
<el-form-item label="组件图标" prop="icon"> <el-form-item label="组件图标" prop="icon">
<IconSelector v-model="form.icon" placeholder="请选择图标" /> <IconSelector v-model="form.icon" placeholder="请选择图标" />
@@ -19,24 +30,39 @@
<el-form-item class="top" label="组件路径" prop="path"> <el-form-item class="top" label="组件路径" prop="path">
<el-input v-model="form.path" placeholder="请输入组件路径"></el-input> <el-input v-model="form.path" placeholder="请输入组件路径"></el-input>
</el-form-item> </el-form-item>
<!-- <el-form-item class="top" label="组件查询时间"> <el-form-item class="top" label="组件查询时间" prop="timeKeys">
<el-radio-group v-model="form.timeKey" style="width: 100%"> <!-- <el-radio-group v-model="form.timeKeys" style="width: 100%">
<el-radio-button label="年" value="1" /> <el-radio-button label="年" value="1" />
<el-radio-button label="季" value="2" /> <el-radio-button label="季" value="2" />
<el-radio-button label="月" value="3" /> <el-radio-button label="月" value="3" />
<el-radio-button label="周" value="4" /> <el-radio-button label="周" value="4" />
<el-radio-button label="日" value="5" /> <el-radio-button label="日" value="5" />
</el-radio-group> </el-radio-group> -->
</el-form-item> --> <el-checkbox-group v-model="form.timeKeys">
<el-checkbox-button value="1"></el-checkbox-button>
<el-checkbox-button value="2"></el-checkbox-button>
<el-checkbox-button value="3"></el-checkbox-button>
<el-checkbox-button value="4"></el-checkbox-button>
<el-checkbox-button value="5"></el-checkbox-button>
</el-checkbox-group>
</el-form-item>
<el-form-item class="top" label="组件排序" prop="sort"> <el-form-item class="top" label="组件排序" prop="sort">
<el-input v-model="form.sort" placeholder="请输入组件排序"></el-input> <el-input v-model="form.sort" placeholder="请输入组件排序"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div style="width: 600px; height: 390px; overflow: hidden"> <div style="width: 600px; height: 390px; overflow: hidden">
<div class="ml10" style="font-weight: 600">组件展示</div> <div class="ml10" style="font-weight: 600">组件展示</div>
<component :is="registerComponent(form.path)" v-if="registerComponent(form.path)" <component
class="pd10 GridLayout" :key="form.path" :height="'350px'" :width="'580px'" :is="registerComponent(form.path)"
:timeKey="form.timeKey" :w="12" :h="6"/> v-if="registerComponent(form.path)"
class="pd10 GridLayout"
:key="form.path"
:height="'350px'"
:width="'580px'"
:timeKey="form.timeKeys"
:w="12"
:h="6"
/>
<!-- <div class="pd10">组件加载失败...</div> --> <!-- <div class="pd10">组件加载失败...</div> -->
<el-empty v-else description="未查询到组件" style="height: 350px; width: 533px" /> <el-empty v-else description="未查询到组件" style="height: 350px; width: 533px" />
</div> </div>
@@ -57,7 +83,7 @@ import { useDictData } from '@/stores/dictData'
import { getFatherComponent, componentAdd, componentEdit } from '@/api/user-boot/dept' import { getFatherComponent, componentAdd, componentEdit } from '@/api/user-boot/dept'
import IconSelector from '@/components/baInput/components/iconSelector.vue' import IconSelector from '@/components/baInput/components/iconSelector.vue'
import html2canvas from 'html2canvas' import html2canvas from 'html2canvas'
const emit = defineEmits(['cancel','submit']) const emit = defineEmits(['cancel', 'submit'])
const dictData = useDictData() const dictData = useDictData()
const dialogVisible = ref(false) const dialogVisible = ref(false)
const title = ref('') const title = ref('')
@@ -67,7 +93,7 @@ const form = ref<anyObj>({
name: '', name: '',
sort: 100, sort: 100,
system: [], system: [],
timeKey: '3', timeKeys: ['1', '2', '3', '4', '5'],
code: '', code: '',
path: '' path: ''
}) })
@@ -78,7 +104,8 @@ const rules = {
system: [{ required: true, message: '请先择父组件节点', trigger: 'change' }], system: [{ required: true, message: '请先择父组件节点', trigger: 'change' }],
icon: [{ required: true, message: '请先择组件图标', trigger: 'change' }], icon: [{ required: true, message: '请先择组件图标', trigger: 'change' }],
path: [{ required: true, message: '请输入组件路径', trigger: 'blur' }], path: [{ required: true, message: '请输入组件路径', trigger: 'blur' }],
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }] sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
timeKeys: [{ required: true, message: '请选择组件查询时间', trigger: 'change' }]
} }
const customDeptOption: any = ref([]) const customDeptOption: any = ref([])
onMounted(() => { onMounted(() => {
@@ -98,6 +125,8 @@ const open = (text: string, data?: anyObj) => {
let Data = JSON.parse(JSON.stringify(data)) let Data = JSON.parse(JSON.stringify(data))
form.value = Data form.value = Data
form.value.system = [Data.systemType, Data.pid] form.value.system = [Data.systemType, Data.pid]
// form.value.timeKeys = Data.timeKeys.split(',').map(Number)
form.value.timeKeys = Data.timeKeys || []
} }
} }
const submit = () => { const submit = () => {
@@ -105,7 +134,6 @@ const submit = () => {
if (valid) { if (valid) {
let url = '' let url = ''
await html2canvas(document.querySelector('.GridLayout'), { await html2canvas(document.querySelector('.GridLayout'), {
scale: 2 scale: 2
}).then(canvas => { }).then(canvas => {
@@ -117,6 +145,7 @@ const submit = () => {
systemType: form.value.system[0], systemType: form.value.system[0],
pid: form.value.system[1], pid: form.value.system[1],
image: url image: url
}).then(res => { }).then(res => {
ElMessage.success('新增成功!') ElMessage.success('新增成功!')
emit('submit') emit('submit')

View File

@@ -38,6 +38,7 @@ import { useDictData } from '@/stores/dictData'
import { getFatherComponent, componentAdd, componentEdit } from '@/api/user-boot/dept' import { getFatherComponent, componentAdd, componentEdit } from '@/api/user-boot/dept'
import { componentTree } from '@/api/user-boot/user' import { componentTree } from '@/api/user-boot/user'
import { pid } from 'process'
const dictData = useDictData() const dictData = useDictData()
const emit = defineEmits(['cancel', 'submit']) const emit = defineEmits(['cancel', 'submit'])
const dialogVisible = ref(false) const dialogVisible = ref(false)
@@ -47,7 +48,10 @@ const formRef = ref()
const form = ref<anyObj>({ const form = ref<anyObj>({
name: '', name: '',
sort: 100, sort: 100,
system: '' system: [],
timeKey: '3',
code: 'base',
}) })
const props = { label: 'name', value: 'id', checkStrictly: true } const props = { label: 'name', value: 'id', checkStrictly: true }
const rules = { const rules = {
@@ -78,7 +82,7 @@ const getFather = () => {
} }
// 递归删除path不为null的数据 // 递归删除path不为null的数据
function deletePathNotNull(data:any) { function deletePathNotNull(data: any) {
// 若为数组,遍历处理每个元素 // 若为数组,遍历处理每个元素
if (Array.isArray(data)) { if (Array.isArray(data)) {
const filtered = [] const filtered = []
@@ -110,7 +114,7 @@ const submit = () => {
await componentAdd({ await componentAdd({
...form.value, ...form.value,
systemType: form.value.system[0], systemType: form.value.system[0],
pid: form.value.system[1] pid: form.value.system?.at(-1)
}).then(res => { }).then(res => {
ElMessage.success('新增成功!') ElMessage.success('新增成功!')
emit('submit') emit('submit')

View File

@@ -90,15 +90,13 @@ const tableStore = new TableStore({
title: '确定删除?' title: '确定删除?'
}, },
click: row => { click: row => {
if (row.path == '' || row.path == null) {
} else {
deleteSubassembly({ id: row.id }).then(() => { deleteSubassembly({ id: row.id }).then(() => {
ElMessage.success('删除成功!') ElMessage.success('删除成功!')
tableStore.index() tableStore.index()
}) })
} }
} }
}
] ]
} }
], ],