|
@@ -0,0 +1,304 @@
|
|
|
+<script setup name="prepare">
|
|
|
+import searchCop from './components/search.vue'
|
|
|
+import excelCop from '@/components/excel.vue'
|
|
|
+import treeCop from '@/components/tree.vue'
|
|
|
+import tableCop from './components/table.vue'
|
|
|
+import { ElMessage } from 'element-plus';
|
|
|
+import { onMounted, ref, onActivated } from 'vue'
|
|
|
+import CurrentScatterChart from './components/current-scatter-chart.vue'
|
|
|
+import request from '@/api/axios.js'
|
|
|
+import {baseURL, socketURL} from '@/api/axios.js'
|
|
|
+import dayjs from 'dayjs';
|
|
|
+/**配置参数 */
|
|
|
+const tableHeight = ref(window.innerHeight - 314 + 'px')
|
|
|
+const treeHeight = ref(window.innerHeight - 260 + 'px') //tree高度
|
|
|
+const excelHeight = ref(window.innerHeight - 260 + 'px') //excel高度
|
|
|
+/**excel 开始 */
|
|
|
+const excelList = ref([])
|
|
|
+const funExcelChange = async (obj) => { //点击excel项时
|
|
|
+ activeTab.value = '1'
|
|
|
+ tableShowId.value = obj.id
|
|
|
+ tableName.value = obj.name
|
|
|
+ tableLoading.value = true
|
|
|
+ const res = await request.get('/power/prepare/show', { params: { id: obj.id } })
|
|
|
+ if(res.code === 200){
|
|
|
+ tableColumn.value = res.data.title.map(o => {
|
|
|
+ return {
|
|
|
+ prop: o.key,
|
|
|
+ label: o.des,
|
|
|
+ width: o.des==='时间'? 100: 80,
|
|
|
+ }
|
|
|
+ })
|
|
|
+ tableData.value = res.data.data
|
|
|
+ tableLoading.value = false
|
|
|
+ }else{
|
|
|
+ tableLoading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+/**tree 开始 */
|
|
|
+const treeData = ref([])
|
|
|
+const funRepeatMap = (arr) => {
|
|
|
+ return arr.map(o => {
|
|
|
+ if (o.children) {
|
|
|
+ const findIndex = o.children.findIndex(p => !!p.type)
|
|
|
+ if (findIndex !== -1) {
|
|
|
+ o.childs = o.children
|
|
|
+ o.children = []
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ ...o,
|
|
|
+ children: o.children?.length ? funRepeatMap(o.children) : []
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+const funGetTree = async () => {
|
|
|
+ const res = await request.get("/power/prepare/tree")
|
|
|
+ treeData.value = funRepeatMap(res.data)
|
|
|
+ excelList.value = []
|
|
|
+}
|
|
|
+const funCurrentChange = ({ current, currentNode }) => {
|
|
|
+ if (current.childs) {
|
|
|
+ excelList.value = current.childs.map(o => {
|
|
|
+ return {
|
|
|
+ id: o.id,
|
|
|
+ interval: o.interval,
|
|
|
+ path: o.path,
|
|
|
+ prepareid: o.prepareid,
|
|
|
+ station: o.station,
|
|
|
+ time: o.time,
|
|
|
+ type: o.type,
|
|
|
+ windturbine: o.windturbine,
|
|
|
+ name: o.path.substring(o.path.indexOf(o.station + '_') + (o.station + '_').length)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ excelList.value = []
|
|
|
+ }
|
|
|
+}
|
|
|
+/**table 开始 */
|
|
|
+const tableShowId = ref('')
|
|
|
+const tableName = ref('')
|
|
|
+const tableColumn = ref([])
|
|
|
+const tableLoading = ref(false)
|
|
|
+const tableData = ref([])
|
|
|
+const funExport = async () => {
|
|
|
+ const a = document.createElement('a')
|
|
|
+ a.href = baseURL + '/power/prepare/download?id=' + tableShowId.value
|
|
|
+ a.download = ''
|
|
|
+ a.click()
|
|
|
+}
|
|
|
+/**tab */
|
|
|
+const activeTab = ref('1')
|
|
|
+/**chart Data */
|
|
|
+const xAxisData = ref([])
|
|
|
+const chartRef = ref() //chart 的ref
|
|
|
+const seriesData = ref([])
|
|
|
+const dataSet = ref('')
|
|
|
+const funChartSelect = async (batch) => {
|
|
|
+ return false
|
|
|
+}
|
|
|
+/**submit */
|
|
|
+const funSubmit = async (params) => {
|
|
|
+ activeTab.value = '2'
|
|
|
+ tableShowId.value = 1
|
|
|
+ tableName.value = ''
|
|
|
+ tableLoading.value = true
|
|
|
+ const res = await request.get('/agc/deviate', { params: params })
|
|
|
+ tableColumn.value = [
|
|
|
+ {
|
|
|
+ prop: 'ts',
|
|
|
+ label: '时间',
|
|
|
+ width: 100,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'ygsdxz',
|
|
|
+ label: '有功设定限值',
|
|
|
+ width: 80,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'sfyg',
|
|
|
+ label: '实发有功',
|
|
|
+ width: 80,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'llgl',
|
|
|
+ label: '理论功率',
|
|
|
+ width: 80,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'pcsx',
|
|
|
+ label: '偏差上限',
|
|
|
+ width: 80,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'pcxx',
|
|
|
+ label: '偏差下限',
|
|
|
+ width: 100,
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ const tableArr = []
|
|
|
+ const tsArr = []
|
|
|
+ const ygsdxz = []
|
|
|
+ const sfyg = []
|
|
|
+ const llgl = []
|
|
|
+ const pcsx = []
|
|
|
+ const pcxx = []
|
|
|
+ res['有功设定限值'].values.map((o, index) => {
|
|
|
+ tsArr.push(dayjs(o.ts).format('YYYY-MM-DD HH:mm:ss'))
|
|
|
+ ygsdxz.push(Number(o.value).toFixed(2))
|
|
|
+ sfyg.push(Number(res['实发有功'].values[index].value).toFixed(2))
|
|
|
+ llgl.push(Number(res['理论功率'].values[index].value).toFixed(2))
|
|
|
+ pcsx.push(Number(res['偏差上限'].values[index].value).toFixed(2))
|
|
|
+ pcxx.push(Number(res['偏差下限'].values[index].value).toFixed(2))
|
|
|
+ tableArr.push({
|
|
|
+ ts: dayjs(o.ts).format('YYYY-MM-DD HH:mm:ss'),
|
|
|
+ ygsdxz: Number(o.value).toFixed(2),
|
|
|
+ sfyg: Number(res['实发有功'].values[index].value).toFixed(2),
|
|
|
+ llgl: Number(res['理论功率'].values[index].value).toFixed(2),
|
|
|
+ pcsx: Number(res['偏差上限'].values[index].value).toFixed(2),
|
|
|
+ pcxx: Number(res['偏差下限'].values[index].value).toFixed(2),
|
|
|
+ })
|
|
|
+ })
|
|
|
+ xAxisData.value = tableArr.map(o => o.ts)
|
|
|
+ seriesData.value = [
|
|
|
+ {
|
|
|
+ name: "有功设定限值",
|
|
|
+ type: "line",
|
|
|
+ symbol: "line", //设定为实心点
|
|
|
+ symbolSize: 0, //设定实心点的大小
|
|
|
+ smooth: false, //这个是把线变成曲线
|
|
|
+ data: ygsdxz,
|
|
|
+ xAxisIndex: 0,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "实发有功",
|
|
|
+ type: "line",
|
|
|
+ symbol: "line", //设定为实心点
|
|
|
+ symbolSize: 0, //设定实心点的大小
|
|
|
+ smooth: false, //这个是把线变成曲线
|
|
|
+ data: sfyg,
|
|
|
+ xAxisIndex: 0,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "理论功率",
|
|
|
+ type: "line",
|
|
|
+ symbol: "line", //设定为实心点
|
|
|
+ symbolSize: 0, //设定实心点的大小
|
|
|
+ smooth: false, //这个是把线变成曲线
|
|
|
+ data: llgl,
|
|
|
+ xAxisIndex: 0,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "偏差上限",
|
|
|
+ type: "line",
|
|
|
+ symbol: "line", //设定为实心点
|
|
|
+ symbolSize: 0, //设定实心点的大小
|
|
|
+ smooth: false, //这个是把线变成曲线
|
|
|
+ data: pcsx,
|
|
|
+ xAxisIndex: 0,
|
|
|
+ lineStyle: {
|
|
|
+ opacity: 0
|
|
|
+ },
|
|
|
+ areaStyle: {
|
|
|
+ color: '#ccc',
|
|
|
+ },
|
|
|
+ symbol: 'none'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "偏差下限",
|
|
|
+ type: "line",
|
|
|
+ symbol: "line", //设定为实心点
|
|
|
+ symbolSize: 0, //设定实心点的大小
|
|
|
+ smooth: false, //这个是把线变成曲线
|
|
|
+ data: pcxx,
|
|
|
+ xAxisIndex: 0,
|
|
|
+ lineStyle: {
|
|
|
+ opacity: 0
|
|
|
+ },
|
|
|
+ areaStyle: {
|
|
|
+ color: '#fff',
|
|
|
+ opacity: 1
|
|
|
+ },
|
|
|
+ symbol: 'none'
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ tableData.value = tableArr
|
|
|
+ tableLoading.value = false
|
|
|
+
|
|
|
+
|
|
|
+ // if (res.code === 200) {
|
|
|
+ // if(res.data.sjgl?.length){
|
|
|
+ // for(const wtObj of res.data.sjgl){
|
|
|
+ // seriesData.value.push(
|
|
|
+ // {
|
|
|
+ // name: wtObj.obj.windturbine + "\n实际功率",
|
|
|
+ // type: "line",
|
|
|
+ // symbol: "line", //设定为实心点
|
|
|
+ // symbolSize: 0, //设定实心点的大小
|
|
|
+ // smooth: true, //这个是把线变成曲线
|
|
|
+ // data: wtObj.sjgl || [],
|
|
|
+ // xAxisIndex: 0,
|
|
|
+ // },
|
|
|
+ // )
|
|
|
+ // wtData.value.push(wtObj.obj)
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+}
|
|
|
+/**created */
|
|
|
+// funGetTree()
|
|
|
+/**mounted */
|
|
|
+onMounted(() => {
|
|
|
+ tableHeight.value = window.innerHeight - 314 + 'px'
|
|
|
+ excelHeight.value = window.innerHeight - 260 + 'px'
|
|
|
+ treeHeight.value = window.innerHeight - 260 + 'px'
|
|
|
+ window.addEventListener('resize', () => {
|
|
|
+ tableHeight.value = window.innerHeight - 314 + 'px'
|
|
|
+ excelHeight.value = window.innerHeight - 260 + 'px'
|
|
|
+ treeHeight.value = window.innerHeight - 260 + 'px'
|
|
|
+ })
|
|
|
+})
|
|
|
+/**activated */
|
|
|
+onActivated(() => {
|
|
|
+ // funGetTree()
|
|
|
+ // funSubmit()
|
|
|
+})
|
|
|
+</script>
|
|
|
+<template>
|
|
|
+ <div class="bg-white py-[10px] px-[10px] relative">
|
|
|
+ <search-cop class="mb-[20px] shadow rounded-[6px] shadow-blue-500" @submit="funSubmit">
|
|
|
+ </search-cop>
|
|
|
+ <div class="relative shadow rounded-[6px] shadow-blue-500 px-[10px] pt-[20px] pb-[10px]">
|
|
|
+ <div class="text-[14px] absolute top-[-7px] text-[#838383] left-[20px]">数据展示</div>
|
|
|
+ <el-row :gutter="10">
|
|
|
+ <!-- <el-col :span="5">
|
|
|
+ <tree-cop :data="treeData" :height="treeHeight" @currentChange="funCurrentChange" @refresh="funGetTree">
|
|
|
+ </tree-cop>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="3">
|
|
|
+ <excel-cop :data="excelList" :height="excelHeight" @excelChange="funExcelChange"></excel-cop>
|
|
|
+ </el-col> -->
|
|
|
+ <el-col :span="24">
|
|
|
+ <div class="px-[10px] shadow rounded-[6px] shadow-blue-500 ">
|
|
|
+ <el-tabs v-model="activeTab">
|
|
|
+ <el-tab-pane label="表格数据" name="1">
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="图表展示" name="2">
|
|
|
+ </el-tab-pane>
|
|
|
+ <table-cop v-show="activeTab === '1'" :data="tableData" :loading="tableLoading" :column="tableColumn"
|
|
|
+ :height="tableHeight" :tableId="tableShowId" :tableName="tableName"></table-cop>
|
|
|
+ <div v-show="activeTab === '2'"
|
|
|
+ :style="{ height: typeof tableHeight === 'string' ? tableHeight : tableHeight + 'px' }"
|
|
|
+ class="p-[10px]">
|
|
|
+ <CurrentScatterChart ref="chartRef" width="100%" :height="`calc( ${tableHeight} - 20px )`" :chartTitle="''"
|
|
|
+ :xAxisData="xAxisData" :yAxisData="{ splitLine: { show: false } }" :seriesData="seriesData"
|
|
|
+ :showLegend="true" :brushSelected="false" :dataSet="dataSet" @getSelected="funChartSelect" />
|
|
|
+ </div>
|
|
|
+ </el-tabs>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|