浏览代码

https://qhome.usky.cn/dist2/#/index.htmlmerge branch 'master' of http://47.111.81.118:3000/fanghuisheng/admin-fiveFollowing into wangtao

wangtao 1 周之前
父节点
当前提交
b023da18e0

+ 49 - 0
src/api/energyManage/index.js

@@ -0,0 +1,49 @@
+import request from '@/utils/request'
+
+/**
+ * 能源管理接口集合
+ * @method Statistics 概览统计
+ * @method Select 列表查询
+ * @method Update 列表修改
+ * @method Insert 列表新增
+ * @method Delete 列表删除
+ * @method EchartsHistoryData 图表历史数据
+ */
+export function energyApi() {
+    return {
+        Statistics: (params) => {
+            return request({
+                url: `/htAnalogData/getEnergyConsumption`,
+                method: 'GET',
+                params,
+            });
+        },
+        Update: (data) => {
+            return request({
+                url: `/service-eg/egDevice`,
+                method: 'PUT',
+                data,
+            });
+        },
+        Insert: (data) => {
+            return request({
+                url: `/service-eg/egDevice`,
+                method: 'POST',
+                data,
+            });
+        },
+        Delete: (data) => {
+            return request({
+                url: `/service-eg/egDevice/` + data,
+                method: 'DELETE',
+            });
+        },
+        EchartsData: (params) => {
+            return request({
+                url: `/htAnalogData/getSegmentedData`,
+                method: 'GET',
+                params,
+            });
+        },
+    };
+}

+ 16 - 3
src/assets/css/global.scss

@@ -112,12 +112,16 @@ a {
         .count {
             display: flex;
             flex-wrap: wrap;
-            width: 238px;
+            width: 100%;
             height: 132px;
             padding: 10px;
             background: #F2F3F8;
             border: 1px solid #E9E9F3;
 
+            &+.count {
+                margin-top: 20px;
+            }
+
             .title {
                 width: 60%;
                 font-size: 14px;
@@ -131,16 +135,25 @@ a {
             }
 
             .value {
+                display: flex;
+                white-space: nowrap;
                 width: 100%;
                 text-align: center;
                 font-size: 18px;
                 font-weight: 600;
+                justify-content: center;
+
+                >.image {
+                    width: 12px;
+                    height: 8px;
+                }
             }
         }
 
         .chart {
-            width: calc(100% - 258px);
-            margin: auto auto auto 20px;
+            width: 100%;
+            height: 100%;
+            margin: auto;
         }
 
         >.countValue {

+ 26 - 26
src/router/index.js

@@ -205,32 +205,32 @@ export const asyncRoutes = [
     },
 
 
-    // {
-    //     meta: { icon: 'dataManage', title: '能源管理', },
-    //     path: '/energyManage',
-    //     component: Layout,
-    //     redirect: '/energyManage/totalEnergyC/index',
-    //     children: [
-    //         {
-    //             meta: { icon: 'totalEnergyC', title: '总能耗', },
-    //             path: 'totalEnergyC',
-    //             component: () =>
-    //                 import('@/views/energyManage/totalEnergyC/index'),
-    //         },
-    //         {
-    //             meta: { icon: 'energyStatistics', title: '能源统计', },
-    //             path: 'energyStatistics',
-    //             component: () =>
-    //                 import('@/views/energyManage/energyStatistics/index'),
-    //         },
-    //         {
-    //             meta: { icon: 'energyReport', title: '能源报表', },
-    //             path: 'energyReport',
-    //             component: () =>
-    //                 import('@/views/energyManage/energyReport/index'),
-    //         },
-    //     ]
-    // },
+    {
+        meta: { icon: 'dataManage', title: '能源管理', },
+        path: '/energyManage',
+        component: Layout,
+        redirect: '/energyManage/totalEnergyC/index',
+        children: [
+            {
+                meta: { icon: 'totalEnergyC', title: '总能耗', },
+                path: 'totalEnergyC',
+                component: () =>
+                    import('@/views/energyManage/totalEnergyC/index'),
+            },
+            {
+                meta: { icon: 'energyStatistics', title: '能源统计', },
+                path: 'energyStatistics',
+                component: () =>
+                    import('@/views/energyManage/energyStatistics/index'),
+            },
+            // {
+            //     meta: { icon: 'energyReport', title: '能源报表', },
+            //     path: 'energyReport',
+            //     component: () =>
+            //         import('@/views/energyManage/energyReport/index'),
+            // },
+        ]
+    },
 
 
     {

+ 46 - 0
src/utils/timeProcessing.utils.js

@@ -0,0 +1,46 @@
+
+import dayjs from 'dayjs';
+
+/**
+ * @description 获取以日、月、年为时间节点的数组
+ * @param dateType 时间类型
+ * @param incrementTime 递增时间
+ */
+export function GetTimeIntervals(dateType, incrementTime) {
+    let intervals = [];
+
+    if (dateType == 'currentDay') {
+        let startTime = dayjs().startOf('day'); // 起始时间:当天00:00
+        const endTime = dayjs();// 结束时间:当前时间
+        // 循环生成分钟间隔节点,直到超过当前时间
+        while (startTime.isBefore(endTime) || startTime.isSame(endTime)) {
+            intervals.push(startTime.format('HH:mm'));// 格式化当前节点为 HH:mm
+            startTime = startTime.add(incrementTime, 'minute'); // 增加分钟
+            // 若下一个节点超过当前时间,则停止(避免生成超出范围的节点)
+            if (startTime.isAfter(endTime)) {
+                break;
+            }
+        }
+    } else if (dateType == 'day') {
+        let startTime = dayjs().startOf('day'); // 起始时间:当天00:00
+        const endTime = dayjs().endOf('day');// 结束时间:当天23.59
+        // 循环生成分钟间隔节点,直到超过当前时间
+        while (startTime.isBefore(endTime) || startTime.isSame(endTime)) {
+            intervals.push(startTime.format('HH:mm'));// 格式化当前节点为 HH:mm
+            startTime = startTime.add(incrementTime, 'minute'); // 增加分钟
+            // 若下一个节点超过当前时间,则停止(避免生成超出范围的节点)
+        }
+    } else if (dateType == 'month') {
+        let startOfMonth = dayjs().startOf('month');
+        const endOfMonth = dayjs().endOf('month');
+        // 创建一个数组来存储每个月的日期
+        while (startOfMonth.isBefore(endOfMonth) || startOfMonth.isSame(endOfMonth, 'day')) {
+            intervals.push(startOfMonth.format('DD') + '日'); // 格式化日期为YYYY-MM-DD字符串并添加到数组中
+            startOfMonth = startOfMonth.add(incrementTime, 'day'); // 增加天
+        }
+    } else if (dateType == 'year') {
+        intervals = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
+    }
+
+    return intervals;
+}

+ 204 - 0
src/views/energyManage/energyStatistics/branch.vue

@@ -0,0 +1,204 @@
+<template>
+    <el-row :gutter="20" style="height:calc(100% - 52px)">
+        <el-col :md="24" :lg="6" style="height: calc(50% - 20px); margin-bottom: 20px;">
+            <el-card class="card-area" style="height: calc(50% - 10px); margin-bottom: 20px;"
+                :body-style="{ height: '100%', flexWrap: 'wrap', display: 'flex', placeContent: 'space-between' }">
+                <div class="card-area-header">
+                    <div class="title">本月用电(kWh)</div>
+                </div>
+                <div class="card-area-center">
+                    <div class="countValue font-36">122439</div>
+                </div>
+                <div class="card-area-footer">
+                    <div class="title">上月同期:</div>
+                    <div class="value">34073.99</div>
+                    <div class="percent" style="color: #FF0000;">259.33%</div>
+                    <img class="image" src="@/assets/images/energyManage/CaretTop.png" alt="整体图片">
+                </div>
+            </el-card>
+
+            <el-card class="card-area" style="height: calc(50% - 10px); "
+                :body-style="{ height: '100%', flexWrap: 'wrap', display: 'flex', placeContent: 'space-between' }">
+                <div class="card-area-header">
+                    <div class="title">今日用电(kWh)</div>
+                </div>
+                <div class="card-area-center">
+                    <div class="countValue font-36">4206</div>
+                </div>
+                <div class="card-area-footer">
+                    <div class="title">上月同期:</div>
+                    <div class="value">4026</div>
+                    <div class="percent" style="color: #FF0000;">4.47%</div>
+                    <img class="image" src="@/assets/images/energyManage/CaretTop.png" alt="整体图片">
+                </div>
+            </el-card>
+        </el-col>
+        <el-col :md="24" :lg="18" style="height: calc(50% - 20px); margin-bottom: 20px;">
+            <el-card class="card-area" style="height: 100%;" :body-style="{ height: '100%' }">
+                <div class="card-area-header" style="margin-bottom: 20px;">
+                    <img class="image" src="@/assets/images/energyManage/onThatDay.png" alt="整体图片">
+                    <div class="title">今日支路用电</div>
+                </div>
+
+                <div class="card-area-center" style="height: calc(100% - 40px);">
+                    <countChart ref="oneChartRef" class="chart" height="100%" :chartData="oneChartData"
+                        v-loading="oneChartLoading" />
+                </div>
+            </el-card>
+        </el-col>
+        <el-col :md="24" :lg="6" style="height: calc(50%);margin-bottom: 20px;">
+            <el-card class="card-area" style="height: 100%;" :body-style="{ height: '100%' }">
+                <div class="card-area-header" style="margin-bottom: 20px;">
+                    <img class="image" src="@/assets/images/energyManage/electricity.png" alt="整体图片">
+                    <div class="title">今日支路用电</div>
+                </div>
+
+                <div class="card-area-center" style="height: calc(100% - 40px);">
+                    <pieChart ref="pieChartRef" class="chart" height="100%" :chartData="pieChartData"
+                        v-loading="oneChartLoading" />
+                </div>
+            </el-card>
+        </el-col>
+        <el-col :md="24" :lg="18" style="height: calc(50%);margin-bottom: 20px;">
+            <el-card class="card-area" style="height: 100%;" :body-style="{ height: '100%' }">
+                <div class="card-area-header" style="margin-bottom: 20px;">
+                    <img class="image" src="@/assets/images/energyManage/onThatDay.png" alt="整体图片">
+                    <div class="title">支路用电</div>
+                    <div class="subTitle">
+                        <el-radio-group v-model="timeRangeType.value" size="small" @change="handlechange">
+                            <el-radio-button value="dayValue">日</el-radio-button>
+                            <el-radio-button value="monthValue">月</el-radio-button>
+                            <el-radio-button value="yearValue">年</el-radio-button>
+                        </el-radio-group>
+                    </div>
+                </div>
+
+                <div class="card-area-center" style="height: calc(100% - 40px);">
+                    <countChart ref="twoChartRef" class="chart" height="100%" style="width: 75%;" :chartData="twoChartData"
+                        v-loading="twoChartLoading" />
+                    <div style="width: 25%;height: 100%;">
+
+                    </div>
+                </div>
+            </el-card>
+        </el-col>
+    </el-row>
+</template>
+<script setup>
+/*----------------------------------依赖引入-----------------------------------*/
+import { ElMessage, ElNotification } from 'element-plus'
+import { ref, onMounted, watch, getCurrentInstance, reactive, toRefs } from 'vue'
+/*----------------------------------接口引入-----------------------------------*/
+/*----------------------------------组件引入-----------------------------------*/
+import pieChart from './components/pieChart.vue'
+import countChart from './components/countChart.vue'
+/*----------------------------------store引入-----------------------------------*/
+/*----------------------------------公共方法引入-----------------------------------*/
+import { GetTimeIntervals } from '@/utils/timeProcessing.utils.js'
+/*----------------------------------公共变量-----------------------------------*/
+const props = defineProps({
+    dataType: String
+}) //数据双向绑定
+const emit = defineEmits([]);
+const { proxy } = getCurrentInstance();
+/*----------------------------------变量声明-----------------------------------*/
+const state = reactive({
+    oneChartLoading: true,
+    oneChartData: {
+        subtext: 'kWh',
+        legendData: ['今日', '昨日'],
+        xAxisData: [],
+        seriesData: [
+            { name: '今日', type: 'bar', data: [], },
+            { name: '昨日', type: 'bar', data: [], }
+        ]
+    },
+    twoChartLoading: true,
+    twoChartData: {
+        subtext: 'kWh',
+        legendData: ['今日', '昨日'],
+        xAxisData: [],
+        seriesData: [
+            { name: '今日', type: 'bar', data: [], },
+            { name: '昨日', type: 'bar', data: [], }
+        ]
+    },
+    timeRangeType: {
+        value: "dayValue"
+    },
+    pieChartData: {
+        text: 'GYJLG_183(-21117)/用电(-21117) (kWh)',
+        seriesData: [
+            {
+                value: 100,
+                name: 'GYJLG_183',
+                itemStyle: {
+                    color: '#ccc' // 环形的颜色,可根据需求调整
+                }
+            },
+        ]
+    }
+})
+const { oneChartLoading, oneChartData, twoChartLoading, twoChartData, timeRangeType, pieChartData } = toRefs(state)
+
+function initChartData() {
+    proxy.$refs["pieChartRef"].initEcharts()
+
+
+    state.timeRangeType.value = 'dayValue'
+
+    state.oneChartData.subtext = "kWh"
+    state.oneChartData.xAxisData = []
+    state.oneChartData.seriesData[0].data = []
+    state.oneChartData.seriesData[1].data = []
+
+    state.oneChartData.xAxisData = GetTimeIntervals('currentDay', 15);//获取以15分钟为节点的数据
+    state.oneChartData.xAxisData.forEach(() => {
+        state.oneChartData.seriesData[0].data.push(0)
+        state.oneChartData.seriesData[1].data.push(0)
+    })
+
+    proxy.$refs["oneChartRef"].initEcharts()
+    state.oneChartLoading = false
+
+
+    handlechange('dayValue');
+}
+
+
+function handlechange(val) {
+    state.twoChartLoading = true
+    state.twoChartData.subtext = "kWh"
+    state.twoChartData.xAxisData = []
+    state.twoChartData.seriesData[0].data = []
+    state.twoChartData.seriesData[1].data = []
+
+    if (val == 'dayValue') {
+        state.twoChartData.xAxisData = GetTimeIntervals('day', 60);//获取以小时为节点的数据
+    } else if (val == 'monthValue') {
+        state.twoChartData.xAxisData = GetTimeIntervals('month', 1);//获取以天为节点的数据
+    } else if (val == 'yearValue') {
+        state.twoChartData.xAxisData = GetTimeIntervals('year', null);//获取以天为节点的数据
+    }
+
+    state.twoChartData.xAxisData.forEach(() => {
+        state.twoChartData.seriesData[0].data.push(0)
+        state.twoChartData.seriesData[1].data.push(0)
+    })
+    proxy.$refs["twoChartRef"].initEcharts()
+    state.twoChartLoading = false
+}
+
+onMounted(() => {
+    initChartData()
+})
+
+// 暴露变量
+defineExpose({
+    oneChartData,
+    twoChartData,
+    initChartData,
+    handlechange
+});
+</script>
+<style lang="scss" scoped></style>

+ 73 - 0
src/views/energyManage/energyStatistics/index.vue

@@ -0,0 +1,73 @@
+<template>
+  <div class="app-container page-nesting energyStatistics">
+    <!-- 筛选start -->
+    <div class="filter-container mb-20" style="justify-content: left">
+      <div class="filter-item">
+        <div class="title">标签:</div>
+        <el-radio-group v-model="tagType.value" @change="(val) => handlechange(val, 3)">
+          <el-radio-button value="branch">支路</el-radio-button>
+          <el-radio-button value="subitem">分项</el-radio-button>
+        </el-radio-group>
+      </div>
+
+      <div class="filter-item">
+        <div class="title">选择支路:</div>
+        <el-select v-model="branchValue" placeholder="Select" style="width: 200px">
+          <el-option v-for="item in branchData" :key="item.value" :label="item.label" :value="item.value" />
+        </el-select>
+      </div>
+    </div>
+    <!-- 筛选end -->
+
+    <!-- 支路 -->
+    <branch v-if="tagType.value == 'branch'" ref="branchRef" :dataType="tagType.value"></branch>
+    <!-- 分项 -->
+    <expense v-if="tagType.value == 'subitem'" ref="subitemRef" :dataType="tagType.value"></expense>
+  </div>
+</template>
+
+<script setup>
+/*----------------------------------依赖引入-----------------------------------*/
+import { ElMessage, ElNotification } from 'element-plus'
+import {
+  ref,
+  onMounted,
+  watch,
+  getCurrentInstance,
+  reactive,
+  toRefs,
+} from 'vue'
+/*----------------------------------接口引入-----------------------------------*/
+/*----------------------------------组件引入-----------------------------------*/
+import branch from './branch.vue'
+/*----------------------------------store引入-----------------------------------*/
+/*----------------------------------公共方法引入-----------------------------------*/
+/*----------------------------------公共变量-----------------------------------*/
+const props = defineProps({}) //数据双向绑定
+const emit = defineEmits([])
+const { proxy } = getCurrentInstance()
+/*----------------------------------变量声明-----------------------------------*/
+const state = reactive({
+  tagType: {
+    value: 'branch',
+  },
+
+  branchValue: 1,
+  branchData: [
+    { label: 'D4KXG_C1', value: 1 }
+  ]
+})
+const { tagType, branchValue, branchData } = toRefs(state)
+
+function handlechange(val, type) {
+  if (val == 'branch') {
+    proxy.$refs['branchRef'].initChartData()
+  } else {
+    console.log(1)
+  }
+}
+
+onMounted(() => { })
+</script>
+
+<style lang="scss" scoped></style>

+ 52 - 0
src/views/energyManage/totalEnergyC/components/StatPanelItem.vue

@@ -0,0 +1,52 @@
+<template>
+    <div class="card-area-center">
+        <div class="value col-3">{{ props.title[0] }}:{{ props.value[0] || 0 }}</div>
+        <div class="value col-3">{{ props.title[1] }}:{{ props.value[1] || 0 }}</div>
+        <div class="value col-3">
+            同期环比:
+            <span :style="{ color: isPositiveNumber(props.value[2]).color, marginRight: '5px' }">
+                {{ props.value[2] || 0 }}%</span>
+            <img class="image" :src="isPositiveNumber(props.value[2]).icons" alt="整体图片" />
+        </div>
+    </div>
+    <el-divider class="card-area-divider" v-if="props.isDivider" />
+</template>
+  
+<script setup>
+/*----------------------------------依赖引入-----------------------------------*/
+import { ref, onMounted, watch, getCurrentInstance, reactive, toRefs } from 'vue'
+/*----------------------------------接口引入-----------------------------------*/
+/*----------------------------------组件引入-----------------------------------*/
+/*----------------------------------store引入-----------------------------------*/
+/*----------------------------------公共方法引入-----------------------------------*/
+/*----------------------------------公共变量-----------------------------------*/
+const props = defineProps({
+    title: Object,
+    value: Object,
+    isDivider: {
+        type: Boolean,
+        default: false
+    }
+}) //数据双向绑定
+const emit = defineEmits([]);
+/*----------------------------------变量声明-----------------------------------*/
+
+
+function isPositiveNumber(value) {
+    let list = {}
+
+    if (value == 0 || value == null) {
+        list.color = '#cacaca'
+        list.icons = '/images/energyManage/CaretCenter.png'
+    } else if (typeof value === 'number' && !Number.isNaN(value) && value > 0 && value !== Infinity) {
+        list.color = '#FF0000'
+        list.icons = '/images/energyManage/CaretTop.png'
+    } else {
+        list.color = '#00C309'
+        list.icons = '/images/energyManage/CaretBottom.png'
+    }
+
+    return list
+};
+
+</script>

+ 46 - 0
src/views/energyManage/totalEnergyC/components/StatSideItem.vue

@@ -0,0 +1,46 @@
+<template>
+    <div class="count">
+        <div class="title"> {{ props.title }} </div>
+        <div class="subTitle"> {{ props.subTitle }} </div>
+        <div class="value" style="color: #41BED8;">{{ value[0] || 0 }} </div>
+        <div class="value flex" v-if="props.value.length > 1">
+            <span :style="{ color: isPositiveNumber(props.value[1]).color, marginRight: '7px' }">
+                {{ props.value[1] || 0 }}%</span>
+            <img class="image" style="margin-top: 7px" :src="isPositiveNumber(props.value[1]).icons" alt="整体图片" />
+        </div>
+    </div>
+</template>
+  
+<script setup>
+/*----------------------------------依赖引入-----------------------------------*/
+import { ref, onMounted, watch, getCurrentInstance, reactive, toRefs } from 'vue'
+/*----------------------------------接口引入-----------------------------------*/
+/*----------------------------------组件引入-----------------------------------*/
+/*----------------------------------store引入-----------------------------------*/
+/*----------------------------------公共方法引入-----------------------------------*/
+/*----------------------------------公共变量-----------------------------------*/
+const props = defineProps({
+    title: String,
+    subTitle: String,
+    value: Object
+}) //数据双向绑定
+const emit = defineEmits([]);
+/*----------------------------------变量声明-----------------------------------*/
+
+
+function isPositiveNumber(value) {
+    let list = {}
+    if (value == 0 || value == null) {
+        list.color = '#cacaca'
+        list.icons = '/images/energyManage/CaretCenter.png'
+    } else if (typeof value === 'number' && !Number.isNaN(value) && value > 0 && value !== Infinity) {
+        list.color = '#FF0000'
+        list.icons = '/images/energyManage/CaretTop.png'
+    } else {
+        list.color = '#00C309'
+        list.icons = '/images/energyManage/CaretBottom.png'
+    }
+    return list
+};
+
+</script>

+ 118 - 0
src/views/energyManage/totalEnergyC/components/countChart.vue

@@ -0,0 +1,118 @@
+<template>
+  <div shadow="never" class="homeBoxCard">
+    <div class="height400" ref="lineChartBanlance" :style="{ height: props.height }" />
+  </div>
+</template>
+<script setup>
+/*----------------------------------依赖引入-----------------------------------*/
+import * as echarts from 'echarts'
+import { ElMessage, ElNotification } from 'element-plus'
+import { ref, onMounted, watch, getCurrentInstance, reactive, toRefs } from 'vue'
+/*----------------------------------接口引入-----------------------------------*/
+/*----------------------------------组件引入-----------------------------------*/
+/*----------------------------------store引入-----------------------------------*/
+/*----------------------------------公共方法引入-----------------------------------*/
+/*----------------------------------公共变量-----------------------------------*/
+const props = defineProps({
+  chartData: Object,
+  height: String
+}) //数据双向绑定
+/*----------------------------------变量声明-----------------------------------*/
+let lineChartBanlance = ref(null)
+
+function initEcharts() {
+  let myChart = echarts.init(lineChartBanlance.value)
+  // 绘制图表
+  myChart.setOption({
+    // backgroundColor: "pink",
+    color: ['#41BED8', '#FCD011'],
+    title: {
+      subtext: props.chartData.subtext
+    },
+    tooltip: {
+      trigger: 'axis'
+    },
+    legend: {
+      bottom: '0',
+      data: props.chartData.legendData
+    },
+    grid: {
+      left: '20',
+      right: '40',
+      top: '40',
+      bottom: '30',
+      containLabel: true,
+    },
+    calculable: true,
+    xAxis: [
+      {
+        type: 'category',
+        // prettier-ignore
+        data: props.chartData.xAxisData,
+      }
+    ],
+    yAxis: [
+      {
+        type: 'value',
+        align: 'center',
+        axisLabel: {
+          align: 'center'  // 设置标签居中
+        },
+      }
+    ],
+    series: props.chartData.seriesData
+  })
+  window.addEventListener('resize', () => {
+    myChart.resize()
+  })
+}
+
+function writeValue(val) {
+  // getData()
+  initEcharts()
+}
+
+//监听变化
+watch(
+  () => props.chartData,
+  (newVal, oldVal, clear) => {
+    // 如果 watch 监听被重复执行了,则会先清除上次未完成的异步任务
+    clear(() => clearTimeout(writeValue(newVal, oldVal)))
+  },
+  { lazy: true }
+)
+
+// 暴露变量
+defineExpose({
+  initEcharts,
+});
+</script>
+<style lang="scss" scoped>
+.homeBoxCard {
+
+  ::v-deep(.el-card__header) {
+    padding-left: 12px;
+    padding-right: 12px;
+  }
+
+  ::v-deep(.el-card__body) {
+    padding: 12px;
+    font-size: 14px;
+    line-height: 1.5715;
+  }
+
+  ::v-deep(.el-divider) {
+    margin: 8px 0;
+  }
+
+  .num {
+    font-size: 30px;
+    color: #515a6e;
+  }
+
+  .height400 {
+    width: 100%;
+    height: 100%;
+  }
+}
+</style>

+ 100 - 0
src/views/energyManage/totalEnergyC/components/pieChart.vue

@@ -0,0 +1,100 @@
+<template>
+    <div shadow="never" class="homeBox">
+        <div class="chart" ref="lineChartBanlance" :style="{ height: props.height }" />
+    </div>
+</template>
+<script setup>
+/*----------------------------------依赖引入-----------------------------------*/
+import * as echarts from 'echarts'
+import { ElMessage, ElNotification } from 'element-plus'
+import { ref, onMounted, watch, getCurrentInstance, reactive, toRefs } from 'vue'
+/*----------------------------------接口引入-----------------------------------*/
+/*----------------------------------组件引入-----------------------------------*/
+/*----------------------------------store引入-----------------------------------*/
+/*----------------------------------公共方法引入-----------------------------------*/
+/*----------------------------------公共变量-----------------------------------*/
+const props = defineProps({
+    height: Number,
+    chartData: Object
+}) //数据双向绑定
+/*----------------------------------变量声明-----------------------------------*/
+let lineChartBanlance = ref(null)
+
+function initEcharts() {
+    let myChart = echarts.init(lineChartBanlance.value)
+    // 绘制图表
+    myChart.setOption({
+        color: ['#41BED8', '#FCD011'],
+        title: [
+            {
+                text: props.chartData.text,
+                subtext: props.chartData.subtext,
+                textStyle: {
+                    fontSize: 20,
+                    color: 'black',
+                },
+                subtextStyle: {
+                    fontSize: 14,
+                    color: '#666666',
+                },
+                textAlign: 'center',
+                left: '49%',
+                top: '45%',
+            },
+        ],
+        tooltip: {
+            trigger: 'item'
+        },
+        legend: {
+            bottom: '0',
+            left: 'center'
+        },
+        series: [
+            {
+                name: '电',
+                type: 'pie',
+                radius: ['45%', '65%'],
+                avoidLabelOverlap: false,
+                label: {
+                    show: false,
+                    position: 'center'
+                },
+                labelLine: {
+                    show: false
+                },
+                data: props.chartData.seriesData
+            }
+        ],
+    })
+    window.addEventListener('resize', () => {
+        myChart.resize()
+    })
+}
+
+function writeValue(val) {
+    // getData()
+    initEcharts()
+}
+
+//监听变化
+watch(
+    () => props.chartData,
+    (newVal, oldVal, clear) => {
+        // 如果 watch 监听被重复执行了,则会先清除上次未完成的异步任务
+        clear(() => clearTimeout(writeValue(newVal, oldVal)))
+    },
+    { lazy: true }
+)
+
+// 暴露变量
+defineExpose({
+    initEcharts,
+});
+</script>
+<style lang="scss" scoped>
+.homeBox {
+    .chart {
+        height: 440px;
+    }
+}
+</style>

+ 126 - 0
src/views/energyManage/totalEnergyC/expense.vue

@@ -0,0 +1,126 @@
+<template>
+    <el-row :gutter="20">
+        <el-col :md="24" :lg="8" style="margin-bottom: 20px;">
+            <el-card class="card-area"
+                :body-style="{ height: '400px', display: 'flex', flexWrap: 'wrap', justifyContent: 'center', alignContent: 'space-between' }">
+                <div class="card-area-header">
+                    <img class="image" src="@/assets/images/energyManage/overall.png" alt="整体图片">
+                    <div class="title"> 当日总能耗 </div>
+                </div>
+                <div class="card-area-center inline">
+                    <div class="countValue">3.515</div>
+                    <div class="unit">吨标准煤</div>
+                </div>
+                <div class="card-area-footer">
+                    <span class="title">昨日同期:</span>
+                    <span class="value">2.888</span>
+                    <span class="percent" style="color: #00C309; margin-right: 5px;">-2.4%</span>
+                    <img class="image" src="@/assets/images/energyManage/CaretBottom.png" alt="整体图片">
+                </div>
+            </el-card>
+        </el-col>
+        <el-col :md="24" :lg="16" style="margin-bottom: 20px;">
+            <el-card class="card-area" :body-style="{ height: '400px' }">
+                <div class=" card-area-header" style="margin-bottom: 20px;">
+                    <img class="image" src="@/assets/images/energyManage/overall.png" alt="整体图片">
+                    <div class="title"> 当日能源同比/环比 </div>
+                </div>
+
+                <el-table :data="tableData" style="width: 100%;height: calc(100% - 60px);">
+                    <el-table-column prop="date" label="能源类型" />
+                    <el-table-column prop="name" label="能源用途" />
+                    <el-table-column prop="address" label="能源量" />
+                    <el-table-column prop="name" label="能源量 (吨标准煤)" width="240" />
+                    <el-table-column prop="address" label="同比 (吨标准煤)" width="220" />
+                    <el-table-column prop="name" label="环比 (吨标准煤)" width="220" />
+                </el-table>
+            </el-card>
+        </el-col>
+        <el-col :md="24" :lg="8" style="margin-bottom: 20px;">
+            <el-card class="card-area">
+                <div class="card-area-header">
+                    <img class="image" src="@/assets/images/energyManage/overall.png" alt="整体图片">
+                    <div class="title"> 当日用能能源占比 </div>
+                </div>
+                <div class="card-area-chart">
+                    <pieChart ref="pieChartRef" height="440px" :chartData="pieChartData" />
+                </div>
+            </el-card>
+        </el-col>
+        <el-col :md="24" :lg="16" style="margin-bottom: 20px;">
+            <el-card class="card-area">
+                <div class="card-area-header">
+                    <img class="image" src="@/assets/images/energyManage/overall.png" alt="整体图片">
+                    <div class="title"> 当日能源趋势 </div>
+                </div>
+                <div class="card-area-chart">
+                    <countChart ref="countChartRef" height="440px" :chartData="oneChartData" />
+                </div>
+            </el-card>
+        </el-col>
+    </el-row>
+</template>
+<script setup>
+/*----------------------------------依赖引入-----------------------------------*/
+import { ElMessage, ElNotification } from 'element-plus'
+import { ref, onMounted, watch, getCurrentInstance, reactive, toRefs } from 'vue'
+/*----------------------------------接口引入-----------------------------------*/
+/*----------------------------------组件引入-----------------------------------*/
+import pieChart from './components/pieChart.vue'
+import countChart from './components/countChart.vue'
+/*----------------------------------store引入-----------------------------------*/
+/*----------------------------------公共方法引入-----------------------------------*/
+import { GetTimeIntervals } from '@/utils/timeProcessing.utils.js'
+/*----------------------------------公共变量-----------------------------------*/
+const props = defineProps({
+    dataType: String
+}) //数据双向绑定
+const emit = defineEmits([]);
+const { proxy } = getCurrentInstance();
+/*----------------------------------变量声明-----------------------------------*/
+const state = reactive({
+    tableData: [],
+    oneChartLoading: true,
+    oneChartData: {
+        subtext: '吨标准煤',
+        legendData: ['电'],
+        xAxisData: [],
+        seriesData: [
+            { name: '电', type: 'bar', data: [], },
+        ]
+    },
+    pieChartData: {
+        text: '6239.05',
+        subtext: '元',
+        seriesData: [
+            { value: 1048, name: '电' },
+        ]
+    }
+})
+const { tableData, oneChartData, pieChartData } = toRefs(state)
+
+function initChartData() {
+    proxy.$refs["pieChartRef"].initEcharts()
+
+    state.oneChartData.subtext = "吨标准煤"
+    state.oneChartData.xAxisData = []
+    state.oneChartData.seriesData[0].data = []
+
+    state.oneChartData.xAxisData = GetTimeIntervals('day', 60)
+    state.oneChartData.xAxisData.forEach(() => {
+        state.oneChartData.seriesData[0].data.push(0)
+    })
+
+    proxy.$refs["countChartRef"].initEcharts()
+    state.oneChartLoading = false
+}
+
+onMounted(() => {
+    initChartData()
+})
+
+// 暴露变量
+defineExpose({
+});
+</script>
+<style lang="scss" scoped></style>

+ 112 - 0
src/views/energyManage/totalEnergyC/index.vue

@@ -0,0 +1,112 @@
+<template>
+  <div class="app-container page-nesting totalEnergyC">
+    <!-- 筛选start -->
+    <div class="filter-container mb-20" style="justify-content: left">
+      <el-radio-group v-model="timeRangeType" @change="(val) => handleTimeRangeChange(val)" style="margin-right: 50px">
+        <el-radio-button value="overview">概览</el-radio-button>
+        <el-radio-button value="day">按日</el-radio-button>
+        <el-radio-button value="month">按月</el-radio-button>
+        <el-radio-button value="year">按年</el-radio-button>
+      </el-radio-group>
+
+      <el-radio-group v-model="dataViewType" @change="(val) => handleDataViewChange(val, 3)">
+        <el-radio-button value="usage">用量</el-radio-button>
+        <el-radio-button value="cost">费用</el-radio-button>
+      </el-radio-group>
+    </div>
+    <!-- 筛选end -->
+
+    <!-- 概览(用量) -->
+    <overviewUsage v-if="timeRangeType == 'overview' && dataViewType == 'usage'" ref="overviewUsageRef"
+      :overviewLoading="overviewLoading" :overviewList="overviewList" :timeRangeType="timeRangeType" />
+    <!-- 概览(费用) -->
+    <overviewCost v-else-if="timeRangeType == 'overview' && dataViewType == 'cost'" ref="overviewCostRef"
+      :overviewLoading="overviewLoading" :overviewList="overviewList" :timeRangeType="timeRangeType" />
+    <!-- 日、月、年 -->
+    <expense v-else ref="expenseRef" :timeRangeType="timeRangeType" :dataViewType="dataViewType"></expense>
+  </div>
+</template>
+
+<script setup>
+/*----------------------------------依赖引入-----------------------------------*/
+import { ElMessage, ElNotification } from 'element-plus'
+import {
+  ref,
+  onMounted,
+  watch,
+  getCurrentInstance,
+  reactive,
+  toRefs,
+} from 'vue'
+/*----------------------------------接口引入-----------------------------------*/
+import { energyApi } from '@/api/energyManage/index.js'
+/*----------------------------------组件引入-----------------------------------*/
+import overviewUsage from './overview-usage'
+import overviewCost from './overview-cost'
+import expense from './expense.vue'
+/*----------------------------------store引入-----------------------------------*/
+/*----------------------------------公共方法引入-----------------------------------*/
+/*----------------------------------公共变量-----------------------------------*/
+const props = defineProps({}) //数据双向绑定
+const emit = defineEmits([])
+const { proxy } = getCurrentInstance()
+/*----------------------------------变量声明-----------------------------------*/
+const state = reactive({
+  timeRangeType: 'overview',
+  dataViewType: 'usage',
+
+  overviewLoading: false,
+  overviewList: [],
+})
+const { timeRangeType, dataViewType, overviewLoading, overviewList } = toRefs(state)
+
+
+
+
+function initData() {
+  state.overviewLoading = true;
+  energyApi()
+    .Statistics({
+      siteId: 395,
+      timeType: state.timeRangeType,
+      consume: state.dataViewType == "usage" ? 1 : 2
+
+    })
+    .then((requset) => {
+      state.overviewLoading = false;
+      state.overviewList = requset.data;
+    })
+    .catch((err) => {
+      state.overviewLoading = false;
+    });
+}
+
+
+function handleTimeRangeChange(val) {
+  if (val == 'overview' && state.dataViewType == 'usage') {
+    initData()
+    proxy.$refs['overviewUsageRef'].initChartData()
+    proxy.$refs['overviewUsageRef'].getDayChartData();
+    proxy.$refs['overviewUsageRef'].getMonthChartData();
+  }
+}
+
+function handleDataViewChange(val, type) {
+  initData()
+  if (state.timeRangeType == 'overview' && val == 'usage') {
+    proxy.$refs['overviewUsageRef'].initChartData()
+    proxy.$refs['overviewUsageRef'].getDayChartData();
+    proxy.$refs['overviewUsageRef'].getMonthChartData();
+  } else {
+    proxy.$refs['overviewCostRef'].initChartData()
+    proxy.$refs['overviewCostRef'].getMonthChartData();
+    proxy.$refs['overviewCostRef'].getYearChartData();
+  }
+}
+
+onMounted(() => {
+  handleTimeRangeChange("overview")
+})
+</script>
+
+<style lang="scss" scoped></style>

+ 259 - 0
src/views/energyManage/totalEnergyC/overview-cost.vue

@@ -0,0 +1,259 @@
+<template>
+    <el-row :gutter="20">
+        <el-col :md="24" :lg="12" style="margin-bottom: 20px;">
+            <el-card class="card-area" v-loading="props.overviewLoading">
+                <div class="card-area-header" style="margin-bottom: 20px;">
+                    <img class="image" src="@/assets/images/energyManage/overall.png" alt="整体图片">
+                    <div class="title"> 总费用</div>
+                    <div class="subTitle">单位:元</div>
+                </div>
+
+                <StatPanelItem
+                    :value="[props.overviewList.todayCost, props.overviewList.yesterdayCost, props.overviewList.dayCostRingRatio]"
+                    :title="['当日', '昨日', '同期环比']" :isDivider="true" />
+                <StatPanelItem
+                    :value="[props.overviewList.monthCost, props.overviewList.lastMonthCost, props.overviewList.monthCostRingRatio]"
+                    :title="['当月', '上月', '同期环比']" :isDivider="true" />
+                <StatPanelItem
+                    :value="[props.overviewList.yearCost, props.overviewList.lastYearCost, props.overviewList.yearCostRingRatio]"
+                    :title="['当年', '上一年', '同期环比']" :isDivider="false" />
+
+            </el-card>
+        </el-col>
+        <el-col :md="24" :lg="12" style="margin-bottom: 20px;">
+            <el-card class="card-area" v-loading="props.overviewLoading">
+                <div class="card-area-header" style="margin-bottom: 20px;">
+                    <img class="image" src="@/assets/images/energyManage/electricity.png" alt="整体图片">
+                    <div class="title">电</div>
+                    <div class="subTitle">单位:元</div>
+                </div>
+
+                <StatPanelItem
+                    :value="[props.overviewList.todayCost, props.overviewList.yesterdayCost, props.overviewList.dayCostRingRatio]"
+                    :title="['当日', '昨日', '同期环比']" :isDivider="true" />
+                <StatPanelItem
+                    :value="[props.overviewList.monthCost, props.overviewList.lastMonthCost, props.overviewList.monthCostRingRatio]"
+                    :title="['当月', '上月', '同期环比']" :isDivider="true" />
+                <StatPanelItem
+                    :value="[props.overviewList.yearCost, props.overviewList.lastYearCost, props.overviewList.yearCostRingRatio]"
+                    :title="['当年', '上一年', '同期环比']" :isDivider="false" />
+            </el-card>
+        </el-col>
+        <el-col :md="24" :lg="24" style="margin-bottom: 20px;">
+            <el-card class="card-area">
+                <div class="card-area-header" style="margin-bottom: 20px;">
+                    <img class="image" src="@/assets/images/energyManage/onThatDay.png" alt="整体图片">
+                    <div class="title"> 当月总费用趋势 </div>
+                </div>
+
+                <div class="card-area-center" style="flex-wrap: wrap;" v-loading="oneChartLoading">
+                    <div class="mr-20" style="width: calc(20% - 20px);">
+                        <StatSideItem :title="'当月总费用'" :subTitle="'元'" :value="[oneChartData.current]" />
+                        <StatSideItem :title="'上月同期总费用'" :subTitle="'元'"
+                            :value="[oneChartData.previous, oneChartData.ratio]" />
+                    </div>
+
+                    <countChart ref="oneChartRef" class="chart" style="width: 80%;" height="280px"
+                        :chartData="oneChartData" />
+                </div>
+            </el-card>
+        </el-col>
+        <el-col :md="24" :lg="24">
+            <el-card class="card-area">
+                <div class="card-area-header" style="margin-bottom: 20px;">
+                    <img class="image" src="@/assets/images/energyManage/theSameMonth.png" alt="整体图片">
+                    <div class="title"> 当年总费用趋势 </div>
+                </div>
+
+                <div class="card-area-center" style="flex-wrap: wrap;" v-loading="twoChartLoading">
+                    <div class="mr-20" style="width: calc(20% - 20px);">
+
+                        <StatSideItem :title="'当年总费用'" :subTitle="'元'" :value="[twoChartData.current]" />
+                        <StatSideItem :title="'上一年同期总费用'" :subTitle="'元'"
+                            :value="[twoChartData.previous, twoChartData.ratio]" />
+                    </div>
+
+                    <countChart ref="twoChartRef" class="chart" style="width: 80%;" height="280px"
+                        :chartData="twoChartData" />
+                </div>
+            </el-card>
+        </el-col>
+    </el-row>
+</template>
+<script setup>
+/*----------------------------------依赖引入-----------------------------------*/
+import { useStore } from 'vuex'
+import { ElMessage, ElNotification } from 'element-plus'
+import { ref, onMounted, watch, getCurrentInstance, reactive, toRefs } from 'vue'
+/*----------------------------------接口引入-----------------------------------*/
+import { energyApi } from '@/api/energyManage/index.js'
+/*----------------------------------组件引入-----------------------------------*/
+import StatPanelItem from './components/StatPanelItem.vue'
+import StatSideItem from './components/StatSideItem.vue'
+import countChart from './components/countChart.vue'
+/*----------------------------------store引入-----------------------------------*/
+/*----------------------------------公共方法引入-----------------------------------*/
+import dayjs from 'dayjs';
+import { GetTimeIntervals } from '@/utils/timeProcessing.utils.js'
+/*----------------------------------公共变量-----------------------------------*/
+const store = useStore()
+const props = defineProps({
+    overviewLoading: Boolean,
+    overviewList: Object,
+}) //数据双向绑定
+const emit = defineEmits([]);
+const { proxy } = getCurrentInstance();
+/*----------------------------------变量声明-----------------------------------*/
+const state = reactive({
+    oneChartLoading: true,
+    oneChartData: {
+        subtext: '吨标准煤',
+        current: 0,
+        previous: 0,
+        ratio: 0,
+        legendData: ['当月', '上月'],
+        xAxisData: [],
+        seriesData: [
+            { name: '当月', type: 'bar', data: [], },
+            { name: '上月', type: 'bar', data: [], }
+        ]
+    },
+    twoChartLoading: true,
+    twoChartData: {
+        subtext: '吨标准煤',
+        current: 0,
+        previous: 0,
+        ratio: 0,
+        legendData: ['当年', '上一年'],
+        xAxisData: [],
+        seriesData: [
+            { name: '当年', type: 'bar', data: [], },
+            { name: '上一年', type: 'bar', data: [], }
+        ]
+    },
+})
+const { oneChartLoading, oneChartData, twoChartLoading, twoChartData } = toRefs(state)
+
+
+// 取月图表数据
+function getMonthChartData() {
+    state.oneChartLoading = true
+
+    let param = {
+        siteId: 395,
+        queryPeriod: "month",
+        queryTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+        queryType: 'cost'
+    }
+    energyApi()
+        .EchartsData(param)
+        .then((item1) => {
+            param.queryTime = dayjs().subtract(1, 'month').format('YYYY-MM-DD HH:mm:ss')
+
+            energyApi()
+                .EchartsData(param)
+                .then((item2) => {
+                    state.oneChartData.current = item1.data.current
+                    state.oneChartData.previous = item1.data.previous
+                    state.oneChartData.ratio = item1.data.ratio
+                    state.oneChartData.subtext = item1.data.unit;
+                    state.oneChartData.seriesData[0].data = item1.data.amountList;
+                    state.oneChartData.seriesData[1].data = item2.data.amountList;
+                    proxy.$refs["oneChartRef"].initEcharts()
+                    state.oneChartLoading = false;
+                })
+                .catch((err) => {
+                    state.oneChartLoading = false;
+                });
+        })
+        .catch((err) => {
+            state.oneChartLoading = false;
+        });
+
+}
+
+// 取月图表数据
+function getYearChartData() {
+    state.twoChartLoading = true
+
+    let param = {
+        siteId: 395,
+        queryPeriod: "year",
+        queryTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+        queryType: 'cost'
+    }
+    energyApi()
+        .EchartsData(param)
+        .then((item1) => {
+            param.queryTime = dayjs().subtract(1, 'year').format('YYYY-MM-DD HH:mm:ss')
+
+            energyApi()
+                .EchartsData(param)
+                .then((item2) => {
+                    state.twoChartData.current = item1.data.current
+                    state.twoChartData.previous = item1.data.previous
+                    state.twoChartData.ratio = item1.data.ratio
+                    state.twoChartData.subtext = item1.data.unit;
+                    state.twoChartData.seriesData[0].data = item1.data.amountList;
+                    state.twoChartData.seriesData[1].data = item2.data.amountList;
+                    proxy.$refs["twoChartRef"].initEcharts()
+                    state.twoChartLoading = false;
+                })
+                .catch((err) => {
+                    state.twoChartLoading = false;
+                });
+        })
+        .catch((err) => {
+            state.twoChartLoading = false;
+        });
+
+}
+
+function initChartData() {
+    state.oneChartData.subtext = '元'
+    state.oneChartData.xAxisData = []
+    state.oneChartData.legendData = ['当月', '上月']
+    state.oneChartData.seriesData = [
+        { name: '当月', type: 'bar', data: [], },
+        { name: '上月', type: 'bar', data: [], }
+    ]
+
+    state.oneChartData.xAxisData = GetTimeIntervals('month', 1)
+    state.oneChartData.xAxisData.forEach(() => {
+        state.oneChartData.seriesData[0].data.push(0)
+        state.oneChartData.seriesData[1].data.push(0)
+    })
+
+    proxy.$refs["oneChartRef"].initEcharts()
+    state.oneChartLoading = false
+
+
+    state.twoChartData.subtext = '元'
+    state.twoChartData.xAxisData = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
+    state.twoChartData.legendData = ['当年', '上一年']
+    state.twoChartData.seriesData = [
+        { name: '当年', type: 'bar', data: [], },
+        { name: '上一年', type: 'bar', data: [], }
+    ]
+    state.twoChartData.xAxisData.forEach((e) => {
+        state.twoChartData.seriesData[0].data.push(0)
+        state.twoChartData.seriesData[1].data.push(0)
+    })
+    proxy.$refs["twoChartRef"].initEcharts()
+    state.twoChartLoading = false
+}
+
+onMounted(() => {
+    initChartData()
+})
+
+// 暴露变量
+defineExpose({
+    oneChartData,
+    twoChartData,
+    initChartData,
+    getMonthChartData,
+    getYearChartData,
+});
+</script>
+<style lang="scss" scoped></style>

+ 292 - 0
src/views/energyManage/totalEnergyC/overview-usage.vue

@@ -0,0 +1,292 @@
+<template>
+    <el-row :gutter="20">
+        <el-col :md="24" :lg="12" style="margin-bottom: 20px;">
+            <el-card class="card-area" v-loading="props.overviewLoading">
+                <div class="card-area-header" style="margin-bottom: 20px;">
+                    <img class="image" src="@/assets/images/energyManage/overall.png" alt="整体图片">
+                    <div class="title"> 总能耗 </div>
+                    <div class="subTitle">单位:吨标准煤</div>
+                </div>
+
+                <StatPanelItem
+                    :value="[props.overviewList.today, props.overviewList.yesterday, props.overviewList.todayRingRatio]"
+                    :title="['当日', '昨日', '同期环比']" :isDivider="true" />
+                <StatPanelItem
+                    :value="[props.overviewList.month, props.overviewList.lastMonth, props.overviewList.monthRingRatio]"
+                    :title="['当月', '上月', '同期环比']" :isDivider="true" />
+                <StatPanelItem
+                    :value="[props.overviewList.year, props.overviewList.lastYear, props.overviewList.yearRingRatio]"
+                    :title="['当年', '上一年', '同期环比']" :isDivider="false" />
+
+            </el-card>
+        </el-col>
+        <el-col :md="24" :lg="12" style="margin-bottom: 20px;">
+            <el-card class="card-area" v-loading="props.overviewLoading">
+                <div class="card-area-header" style="margin-bottom: 20px;">
+                    <img class="image" src="@/assets/images/energyManage/electricity.png" alt="整体图片">
+                    <div class="title">电</div>
+                    <div class="subTitle">单位:kwh</div>
+                </div>
+
+                <StatPanelItem
+                    :value="[props.overviewList.todayElectricity, props.overviewList.yesterdayElectricity, props.overviewList.todayRingRatio]"
+                    :title="['当日', '昨日', '同期环比']" :isDivider="true" />
+                <StatPanelItem
+                    :value="[props.overviewList.monthElectricity, props.overviewList.lastMonthElectricity, props.overviewList.monthRingRatio]"
+                    :title="['当月', '上月', '同期环比']" :isDivider="true" />
+                <StatPanelItem
+                    :value="[props.overviewList.yearElectricity, props.overviewList.lastYearElectricity, props.overviewList.yearRingRatio]"
+                    :title="['当年', '上一年', '同期环比']" :isDivider="false" />
+            </el-card>
+        </el-col>
+        <el-col :md="24" :lg="24" style="margin-bottom: 20px;">
+            <el-card class="card-area">
+                <div class="card-area-header" style="margin-bottom: 20px;">
+                    <img class="image" src="@/assets/images/energyManage/onThatDay.png" alt="整体图片">
+                    <div class="title">
+                        {{ radio1.value == 'energy' ? '当日总能耗趋势' : '当日电趋势' }}
+                    </div>
+                    <div class="subTitle">
+                        <el-radio-group v-model="radio1.value" size="small" @change="(val) => handlechange(val, 1)">
+                            <el-radio-button label="energy" value="energy">总能耗</el-radio-button>
+                            <el-radio-button label="electric " value="electric">电</el-radio-button>
+                        </el-radio-group>
+                    </div>
+                </div>
+
+                <div class="card-area-center" style="flex-wrap: wrap;" v-loading="oneChartLoading">
+                    <div class="mr-20" style="width: calc(20% - 20px);">
+                        <StatSideItem :title="radio1.value == 'energy' ? '当日总能耗' : '当日电'"
+                            :subTitle="radio1.value == 'energy' ? '吨标准煤' : 'kwh'" :value="[oneChartData.current]" />
+                        <StatSideItem :title="radio1.value == 'energy' ? '昨日同期总能耗' : '昨日同期电'"
+                            :subTitle="radio1.value == 'energy' ? '吨标准煤' : 'kwh'"
+                            :value="[oneChartData.previous, oneChartData.ratio]" />
+                    </div>
+
+                    <countChart ref="oneChartRef" class="chart" style="width: 80%;" height="280px"
+                        :chartData="oneChartData" />
+                </div>
+            </el-card>
+        </el-col>
+        <el-col :md="24" :lg="24">
+            <el-card class="card-area">
+                <div class="card-area-header" style="margin-bottom: 20px;">
+                    <img class="image" src="@/assets/images/energyManage/theSameMonth.png" alt="整体图片">
+                    <div class="title">
+                        {{ radio2.value == 'energy' ? '当月总能耗趋势' : '当月电趋势' }}
+                    </div>
+                    <div class="subTitle">
+                        <el-radio-group v-model="radio2.value" size="small" @change="(val) => handlechange(val, 2)">
+                            <el-radio-button label="energy" value="energy">总能耗</el-radio-button>
+                            <el-radio-button label="electric" value="electric">电</el-radio-button>
+                        </el-radio-group>
+                    </div>
+                </div>
+
+                <div class="card-area-center" style="flex-wrap: wrap;" v-loading="twoChartLoading">
+                    <div class="mr-20" style="width: calc(20% - 20px);">
+
+                        <StatSideItem :title="radio2.value == 'energy' ? '当月总能耗' : '当月电'"
+                            :subTitle="radio2.value == 'energy' ? '吨标准煤' : 'kwh'" :value="[twoChartData.current]" />
+                        <StatSideItem :title="radio2.value == 'energy' ? '上月同期总能耗' : '上月同期电'"
+                            :subTitle="radio2.value == 'energy' ? '吨标准煤' : 'kwh'"
+                            :value="[twoChartData.previous, twoChartData.ratio]" />
+                    </div>
+
+                    <countChart ref="twoChartRef" class="chart" style="width: 80%;" height="280px"
+                        :chartData="twoChartData" />
+                </div>
+            </el-card>
+        </el-col>
+    </el-row>
+</template>
+<script setup>
+/*----------------------------------依赖引入-----------------------------------*/
+import { useStore } from 'vuex'
+import { ElMessage, ElNotification } from 'element-plus'
+import { ref, onMounted, watch, getCurrentInstance, reactive, toRefs } from 'vue'
+/*----------------------------------接口引入-----------------------------------*/
+import { energyApi } from '@/api/energyManage/index.js'
+/*----------------------------------组件引入-----------------------------------*/
+import StatPanelItem from './components/StatPanelItem.vue'
+import StatSideItem from './components/StatSideItem.vue'
+import countChart from './components/countChart.vue'
+/*----------------------------------store引入-----------------------------------*/
+/*----------------------------------公共方法引入-----------------------------------*/
+import dayjs from 'dayjs';
+import { GetTimeIntervals } from '@/utils/timeProcessing.utils.js'
+/*----------------------------------公共变量-----------------------------------*/
+const store = useStore()
+const props = defineProps({
+    overviewLoading: Boolean,
+    overviewList: Object,
+}) //数据双向绑定
+const emit = defineEmits([]);
+const { proxy } = getCurrentInstance();
+/*----------------------------------变量声明-----------------------------------*/
+const state = reactive({
+    oneChartLoading: true,
+    oneChartData: {
+        subtext: '吨标准煤',
+        current: 0,
+        previous: 0,
+        ratio: 0,
+        legendData: ['当日', '昨日'],
+        xAxisData: [],
+        seriesData: [
+            { name: '当日', type: 'bar', data: [], },
+            { name: '昨日', type: 'bar', data: [], }
+        ]
+    },
+    twoChartLoading: true,
+    twoChartData: {
+        subtext: '吨标准煤',
+        current: 0,
+        previous: 0,
+        ratio: 0,
+        legendData: ['当月', '上月'],
+        xAxisData: [],
+        seriesData: [
+            { name: '当月', type: 'bar', data: [], },
+            { name: '上月', type: 'bar', data: [], }
+        ]
+    },
+    radio1: {
+        value: "energy"
+    },
+    radio2: {
+        value: "energy"
+    }
+})
+const { oneChartLoading, oneChartData, twoChartLoading, twoChartData, radio1, radio2 } = toRefs(state)
+
+
+// 取日图表数据
+function getDayChartData() {
+    state.oneChartLoading = true
+
+    let param = {
+        siteId: 395,
+        queryPeriod: "day",
+        queryTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+        queryType: state.radio1.value
+    }
+    energyApi()
+        .EchartsData(param)
+        .then((item1) => {
+            param.queryTime = dayjs().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss')
+
+            energyApi()
+                .EchartsData(param)
+                .then((item2) => {
+                    state.oneChartData.current = item1.data.current
+                    state.oneChartData.previous = item1.data.previous
+                    state.oneChartData.ratio = item1.data.ratio
+                    state.oneChartData.subtext = item1.data.unit;
+                    state.oneChartData.seriesData[0].data = item1.data.amountList;
+                    state.oneChartData.seriesData[1].data = item2.data.amountList;
+                    proxy.$refs["oneChartRef"].initEcharts()
+                    state.oneChartLoading = false;
+                })
+                .catch((err) => {
+                    state.oneChartLoading = false;
+                });
+        })
+        .catch((err) => {
+            state.oneChartLoading = false;
+        });
+}
+
+
+// 取月图表数据
+function getMonthChartData() {
+    state.twoChartLoading = true
+
+    let param = {
+        siteId: 395,
+        queryPeriod: "month",
+        queryTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+        queryType: state.radio2.value
+    }
+    energyApi()
+        .EchartsData(param)
+        .then((item1) => {
+            param.queryTime = dayjs().subtract(1, 'month').format('YYYY-MM-DD HH:mm:ss')
+
+            energyApi()
+                .EchartsData(param)
+                .then((item2) => {
+                    state.twoChartData.current = item1.data.current
+                    state.twoChartData.previous = item1.data.previous
+                    state.twoChartData.ratio = item1.data.ratio
+                    state.twoChartData.subtext = item1.data.unit;
+                    state.twoChartData.seriesData[0].data = item1.data.amountList;
+                    state.twoChartData.seriesData[1].data = item2.data.amountList;
+                    proxy.$refs["twoChartRef"].initEcharts()
+                    state.twoChartLoading = false;
+                })
+                .catch((err) => {
+                    state.twoChartLoading = false;
+                });
+        })
+        .catch((err) => {
+            state.twoChartLoading = false;
+        });
+
+}
+
+
+function initChartData() {
+    state.radio1.value = 'energy'
+    state.radio2.value = 'energy'
+
+    state.oneChartData.subtext = "吨标准煤"
+    state.oneChartData.xAxisData = []
+    state.oneChartData.seriesData[0].data = []
+    state.oneChartData.seriesData[1].data = []
+    state.oneChartData.xAxisData = GetTimeIntervals('day', 60)
+    state.oneChartData.xAxisData.forEach(() => {
+        state.oneChartData.seriesData[0].data.push(0)
+        state.oneChartData.seriesData[1].data.push(0)
+    })
+    proxy.$refs["oneChartRef"].initEcharts()
+    state.oneChartLoading = false
+
+
+    state.twoChartData.subtext = "吨标准煤"
+    state.twoChartData.xAxisData = []
+    state.twoChartData.seriesData[0].data = []
+    state.twoChartData.seriesData[1].data = []
+    state.twoChartData.xAxisData = GetTimeIntervals('month', 1)
+    state.twoChartData.xAxisData.forEach(() => {
+        state.twoChartData.seriesData[0].data.push(0)
+        state.twoChartData.seriesData[1].data.push(0)
+    })
+    proxy.$refs["twoChartRef"].initEcharts()
+    state.twoChartLoading = false
+}
+
+
+function handlechange(val, type) {
+    if (type == 1) {
+        state.oneChartData.subtext = val == 'energy' ? '吨标准煤' : 'kwh'
+        getDayChartData();
+    } else if (type == 2) {
+        state.twoChartData.subtext = val == 'energy' ? '吨标准煤' : 'kwh'
+        getMonthChartData()
+    }
+}
+
+onMounted(() => { })
+
+// 暴露变量
+defineExpose({
+    oneChartData,
+    twoChartData,
+    getDayChartData,
+    getMonthChartData,
+    initChartData,
+    handlechange
+});
+</script>
+<style lang="scss" scoped></style>

+ 29 - 2
src/views/historyData/curve/index.vue

@@ -46,12 +46,12 @@ const state = reactive({
         {
             title: "GYJLG_183信号",
             chartLoading: false,
+            markPointChecked: ["max", "min"],
             chartData: {
                 subtext: '',
                 legendData: ['设备信号强度'],
                 xAxisData: [],
-                seriesData: [
-                    { name: '设备信号强度', type: 'line', data: [], yAxisIndex: 0, },
+                seriesData: [{ name: '设备信号强度', type: 'line', data: [], yAxisIndex: 0, },
                 ],
                 unit: "",
                 yAxisData: []
@@ -60,6 +60,7 @@ const state = reactive({
         {
             title: "低压进线",
             chartLoading: false,
+            markPointChecked: ["max", "min", "avg"],
             chartData: {
                 subtext: '',
                 legendData: ['A相电压(V)'],
@@ -73,6 +74,7 @@ const state = reactive({
         },
         {
             title: "进线电压",
+            markPointChecked: ["max", "min"],
             chartLoading: false,
             chartData: {
                 subtext: '',
@@ -87,6 +89,7 @@ const state = reactive({
         },
         {
             title: "需量",
+            markPointChecked: ["max", "min"],
             chartLoading: false,
             chartData: {
                 subtext: '',
@@ -101,6 +104,7 @@ const state = reactive({
         },
         {
             title: "总有功功率",
+            markPointChecked: ["max", "min"],
             chartLoading: false,
             chartData: {
                 subtext: '',
@@ -115,6 +119,7 @@ const state = reactive({
         },
         {
             title: "正有功电度",
+            markPointChecked: ["max", "min"],
             chartLoading: false,
             chartData: {
                 subtext: '',
@@ -129,6 +134,7 @@ const state = reactive({
         },
         {
             title: "总进线三相电流",
+            markPointChecked: ["max", "min"],
             chartLoading: false,
             chartData: {
                 subtext: '',
@@ -145,6 +151,7 @@ const state = reactive({
         },
         {
             title: "总进线三相电压",
+            markPointChecked: ["max", "min"],
             chartLoading: false,
             chartData: {
                 subtext: '',
@@ -181,6 +188,7 @@ function generateTimeSlots(startDate, intervalMinutes) {
 }
 
 
+// 添加(尖、峰、平、谷)刻度
 function init_FPG_Data(startDate) {
     return {
         yAxisIndex: 1,
@@ -348,6 +356,24 @@ function init_yAxis_Data(num) {
     }
 }
 
+function init_markPoint(checked) {
+    let list = {}
+    if (checked.includes("max") && checked.includes("min")) {
+        list.markPoint = {
+            data: [
+                { type: 'max', name: 'Max' },
+                { type: 'min', name: 'Min' }
+            ]
+        }
+    }
+    if (checked.includes("avg")) {
+        list.markLine = {
+            data: [{ type: 'average', name: 'Avg' }]
+        }
+    }
+    return list
+}
+
 
 function initChartData() {
     const timeSlots = generateTimeSlots(state.dateTime, 5);
@@ -356,6 +382,7 @@ function initChartData() {
     state.areaData.forEach((event, index) => {
         event.chartData.xAxisData = timeSlots;
         event.chartData.seriesData.forEach((item) => {
+            Object.assign(item, init_markPoint(event.markPointChecked));
             item.data = Array.from({ length: timeSlots.length }, () => index + 800)
         })
         event.chartData.yAxisData = init_yAxis_Data(1)