Browse Source

报表调整

learshaw 2 weeks ago
parent
commit
e3c9e97e02

+ 56 - 3
ems-ui-cloud/src/api/mgr/pgSupplyH.js

@@ -42,7 +42,20 @@ export function delPgSupplyH(id) {
     method: 'delete'
   })
 }
-// 查询光伏供应计量
+
+// ==================== 光伏产能统计相关接口 ====================
+
+/**
+ * 查询光伏供应计量(统一接口,支持日/月/年统计)
+ * @param {Object} query - 查询参数
+ * @param {String} query.areaCode - 区域代码
+ * @param {String} query.timeDimension - 时间维度:day/month/year
+ * @param {String} query.startRecTime - 开始时间
+ * @param {String} query.endRecTime - 结束时间
+ * @param {String} query.orderFlag - 排序方式:asc/desc
+ * @param {Number} query.pageNum - 页码
+ * @param {Number} query.pageSize - 每页数量
+ */
 export function listPvSupplyH(query) {
   return request({
     url: '/ems/prod/pv/hour/list',
@@ -50,10 +63,50 @@ export function listPvSupplyH(query) {
     params: query
   })
 }
-// 查询发电量根据日
+
+/**
+ * 查询发电量-按日统计(简化版)
+ * @param {Object} query - 查询参数
+ * @param {String} query.areaCode - 区域代码
+ * @param {String} query.startRecTime - 开始日期 yyyy-MM-dd
+ * @param {String} query.endRecTime - 结束日期 yyyy-MM-dd
+ */
 export function listPvSupplyD(query) {
+  // ✅ 统一使用 hour/list 接口,通过 timeDimension 参数指定为日统计
+  return request({
+    url: '/ems/prod/pv/hour/list',
+    method: 'get',
+    params: {
+      ...query,
+      timeDimension: 'day',  // 指定为日统计
+      orderFlag: 'asc',      // 按日期升序
+      pageNum: 1,
+      pageSize: 1000         // 图表展示,获取所有数据
+    }
+  }).then(response => {
+    // ✅ 转换数据格式,适配原有的图表组件
+    if (response.code === 200 && response.rows) {
+      return {
+        code: 200,
+        data: response.rows.map(item => ({
+          date: item.statisticDate || item.statisticMonth || item.statisticYear,
+          genElecQuantity: item.genElecQuantity || 0,
+          useElecQuantity: item.useElecQuantity || 0,
+          upElecQuantity: item.upElecQuantity || 0,
+          upElecEarn: item.upElecEarn || 0
+        }))
+      }
+    }
+    return { code: 500, data: [] }
+  })
+}
+
+/**
+ * 查询光伏产能汇总统计
+ */
+export function getPvSupplySummary(query) {
   return request({
-    url: '/ems/prod/pv/day/list',
+    url: '/ems/prod/pv/hour/summary',
     method: 'get',
     params: query
   })

+ 151 - 146
ems-ui-cloud/src/views/analysis/report/statement-consume.vue

@@ -63,30 +63,7 @@
             </el-radio-group>
           </el-form-item>
 
-          <!-- 时间范围选择 -->
-          <el-form-item label="开始时间" prop="startRecTime">
-            <el-date-picker
-              v-model="queryParams.startRecTime"
-              type="datetime"
-              value-format="yyyy-MM-dd HH:mm:ss"
-              :picker-options="startPickerOptions"
-              placeholder="请选择开始时间"
-              @change="handleTimeChange('startRecTime')"
-            />
-          </el-form-item>
-
-          <el-form-item label="结束时间" prop="endRecTime">
-            <el-date-picker
-              v-model="queryParams.endRecTime"
-              type="datetime"
-              value-format="yyyy-MM-dd HH:mm:ss"
-              :picker-options="endPickerOptions"
-              placeholder="请选择结束时间"
-              @change="handleTimeChange('endRecTime')"
-            />
-          </el-form-item>
-
-          <!-- 时间维度选择 -->
+          <!-- 统计维度选择 -->
           <el-form-item label="统计维度">
             <el-radio-group v-model="queryParams.timeDimension" @change="handleTimeDimensionChange">
               <el-radio-button label="day">日</el-radio-button>
@@ -95,6 +72,49 @@
             </el-radio-group>
           </el-form-item>
 
+          <!-- 日期选择 - 根据统计维度显示不同控件 -->
+          <el-form-item label="统计时间">
+            <!-- 日维度:日期范围选择 -->
+            <el-date-picker
+              v-if="queryParams.timeDimension === 'day'"
+              v-model="dateRange"
+              type="daterange"
+              value-format="yyyy-MM-dd"
+              range-separator="-"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              :picker-options="dayPickerOptions"
+              style="width: 260px"
+              @change="handleDateRangeChange"
+            />
+
+            <!-- 月维度:月份范围选择 -->
+            <el-date-picker
+              v-if="queryParams.timeDimension === 'month'"
+              v-model="monthRange"
+              type="monthrange"
+              value-format="yyyy-MM"
+              range-separator="-"
+              start-placeholder="开始月份"
+              end-placeholder="结束月份"
+              :picker-options="monthPickerOptions"
+              style="width: 260px"
+              @change="handleMonthRangeChange"
+            />
+
+            <!-- 年维度:年份选择 -->
+            <el-date-picker
+              v-if="queryParams.timeDimension === 'year'"
+              v-model="yearValue"
+              type="year"
+              value-format="yyyy"
+              placeholder="选择年份"
+              :picker-options="yearPickerOptions"
+              style="width: 150px"
+              @change="handleYearChange"
+            />
+          </el-form-item>
+
           <!-- 操作按钮 -->
           <el-form-item>
             <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
@@ -280,6 +300,11 @@ export default {
       activeName: 'areaConsume',
       filterText: '',
 
+      // 日期选择
+      dateRange: [],      // 日维度的日期范围
+      monthRange: [],     // 月维度的月份范围
+      yearValue: '',      // 年维度的年份
+
       // 树形选择器
       treeOptions: [],
       defaultProps: {
@@ -340,33 +365,25 @@ export default {
         facsCategory: 'Z',
         energyType: 'elec',
         timeDimension: 'month',
-        startRecTime: this.getDefaultStartTime(),
-        endRecTime: this.getDefaultEndTime(),
+        startRecTime: null,
+        endRecTime: null,
         orderFlag: 'desc'
       },
 
-      // 时间选择器配置
-      startPickerOptions: {
+      // 日期选择器配置
+      dayPickerOptions: {
         disabledDate: (time) => {
-          const ninetyDaysAgo = new Date()
-          ninetyDaysAgo.setDate(ninetyDaysAgo.getDate() - 90)
-          return time.getTime() > Date.now() - 8.64e7 || time.getTime() < ninetyDaysAgo.getTime()
+          return time.getTime() > Date.now()
         }
       },
-      endPickerOptions: {
+      monthPickerOptions: {
         disabledDate: (time) => {
-          if (this.queryParams.startRecTime) {
-            const startDate = new Date(this.queryParams.startRecTime)
-            const endDateLimit = new Date(startDate)
-            endDateLimit.setDate(endDateLimit.getDate() + 90)
-
-            return time.getTime() < startDate.getTime() ||
-              time.getTime() > endDateLimit.getTime() ||
-              time.getTime() > Date.now() - 8.64e7
-          }
-          const ninetyDaysAgo = new Date()
-          ninetyDaysAgo.setDate(ninetyDaysAgo.getDate() - 90)
-          return time.getTime() > Date.now() - 8.64e7 || time.getTime() < ninetyDaysAgo.getTime()
+          return time.getTime() > Date.now()
+        }
+      },
+      yearPickerOptions: {
+        disabledDate: (time) => {
+          return time.getTime() > Date.now()
         }
       }
     }
@@ -385,12 +402,92 @@ export default {
   methods: {
     // 初始化数据
     async initializeData() {
+      this.initDefaultDateRange()
       await this.loadTreeData()
       await this.loadSupportedMeterTypes()
       await this.getConsumptionList()
       await this.getConsumptionSummary()
     },
 
+    // 初始化默认日期范围
+    initDefaultDateRange() {
+      const today = new Date()
+      const currentYear = today.getFullYear()
+      const currentMonth = today.getMonth()
+
+      if (this.queryParams.timeDimension === 'day') {
+        // 日维度:当月1号到今天
+        const startDate = new Date(currentYear, currentMonth, 1)
+        this.dateRange = [
+          this.formatDate(startDate),
+          this.formatDate(today)
+        ]
+        this.queryParams.startRecTime = this.formatDate(startDate) + ' 00:00:00'
+        this.queryParams.endRecTime = this.formatDate(today) + ' 23:59:59'
+      } else if (this.queryParams.timeDimension === 'month') {
+        // 月维度:当年1月到当前月
+        this.monthRange = [
+          `${currentYear}-01`,
+          `${currentYear}-${String(currentMonth + 1).padStart(2, '0')}`
+        ]
+        this.queryParams.startRecTime = `${currentYear}-01-01 00:00:00`
+        this.queryParams.endRecTime = this.formatDate(new Date(currentYear, currentMonth + 1, 0)) + ' 23:59:59'
+      } else if (this.queryParams.timeDimension === 'year') {
+        // 年维度:当年
+        this.yearValue = String(currentYear)
+        this.queryParams.startRecTime = `${currentYear}-01-01 00:00:00`
+        this.queryParams.endRecTime = `${currentYear}-12-31 23:59:59`
+      }
+    },
+
+    // 格式化日期 yyyy-MM-dd
+    formatDate(date) {
+      const year = date.getFullYear()
+      const month = String(date.getMonth() + 1).padStart(2, '0')
+      const day = String(date.getDate()).padStart(2, '0')
+      return `${year}-${month}-${day}`
+    },
+
+    // 日期范围变化处理(日维度)
+    handleDateRangeChange() {
+      if (this.dateRange && this.dateRange.length === 2) {
+        this.queryParams.startRecTime = this.dateRange[0] + ' 00:00:00'
+        this.queryParams.endRecTime = this.dateRange[1] + ' 23:59:59'
+      } else {
+        this.queryParams.startRecTime = null
+        this.queryParams.endRecTime = null
+      }
+    },
+
+    // 月份范围变化处理(月维度)
+    handleMonthRangeChange() {
+      if (this.monthRange && this.monthRange.length === 2) {
+        const [startYear, startMonth] = this.monthRange[0].split('-')
+        const [endYear, endMonth] = this.monthRange[1].split('-')
+
+        // 开始时间:月初第一天 00:00:00
+        this.queryParams.startRecTime = `${startYear}-${startMonth}-01 00:00:00`
+
+        // 结束时间:月末最后一天 23:59:59
+        const lastDay = new Date(parseInt(endYear), parseInt(endMonth), 0).getDate()
+        this.queryParams.endRecTime = `${endYear}-${endMonth}-${String(lastDay).padStart(2, '0')} 23:59:59`
+      } else {
+        this.queryParams.startRecTime = null
+        this.queryParams.endRecTime = null
+      }
+    },
+
+    // 年份变化处理(年维度)
+    handleYearChange() {
+      if (this.yearValue) {
+        this.queryParams.startRecTime = `${this.yearValue}-01-01 00:00:00`
+        this.queryParams.endRecTime = `${this.yearValue}-12-31 23:59:59`
+      } else {
+        this.queryParams.startRecTime = null
+        this.queryParams.endRecTime = null
+      }
+    },
+
     // 加载支持的电量类型
     async loadSupportedMeterTypes() {
       if (this.queryParams.energyType !== 'elec') {
@@ -403,10 +500,9 @@ export default {
         const response = await getElechourTypes(query)
 
         if (response.data && Array.isArray(response.data)) {
-          // 过滤并排序电量类型
           const types = response.data
             .filter(type => type !== null && type !== undefined && this.meterTypeMap[type])
-            .sort((a, b) => Number(b) - Number(a)) // 从大到小排序(尖峰到深谷)
+            .sort((a, b) => Number(b) - Number(a))
             .map(type => ({
               value: type,
               ...this.meterTypeMap[type]
@@ -414,7 +510,6 @@ export default {
 
           this.supportedMeterTypes = types
         } else {
-          // 如果没有返回数据,使用默认全部类型
           this.supportedMeterTypes = Object.keys(this.meterTypeMap)
             .sort((a, b) => Number(b) - Number(a))
             .map(type => ({
@@ -424,7 +519,6 @@ export default {
         }
       } catch (error) {
         console.error('加载电量类型失败:', error)
-        // 出错时使用默认全部类型
         this.supportedMeterTypes = Object.keys(this.meterTypeMap)
           .sort((a, b) => Number(b) - Number(a))
           .map(type => ({
@@ -511,10 +605,8 @@ export default {
           children: response.data || []
         }]
 
-        // 设置默认展开第一级
         this.defaultExpandedKeys = ['-1']
 
-        // 默认选中全部
         this.$nextTick(() => {
           if (this.$refs.tree) {
             this.$refs.tree.setCurrentKey('-1')
@@ -531,7 +623,6 @@ export default {
         const response = await getFacsCategoryTree()
         this.treeOptions = this.flattenFacsTreeData(response.data || [])
 
-        // 设置默认展开第一级
         if (this.treeOptions.length > 0) {
           this.defaultExpandedKeys = this.treeOptions.map(item => item.id)
         }
@@ -566,7 +657,6 @@ export default {
         const query = formatQueryParams(this.queryParams)
         let response
 
-        // 根据能源类型和对象类型调用不同接口
         if (this.activeName === 'areaConsume') {
           if (this.queryParams.energyType === 'elec') {
             response = await getAreaElecConsumptionList(query)
@@ -598,7 +688,6 @@ export default {
         const query = formatQueryParams(this.queryParams)
         let response
 
-        // 根据能源类型和对象类型调用不同接口
         if (this.activeName === 'areaConsume') {
           if (this.queryParams.energyType === 'elec') {
             response = await getAreaElecConsumptionSummary(query)
@@ -663,45 +752,14 @@ export default {
 
     // 时间维度变化处理
     async handleTimeDimensionChange() {
-      this.adjustTimeRange()
+      // 重新初始化日期范围
+      this.initDefaultDateRange()
       this.queryParams.pageNum = 1
       await this.loadSupportedMeterTypes()
       await this.getConsumptionList()
       await this.getConsumptionSummary()
     },
 
-    // 调整时间范围
-    adjustTimeRange() {
-      const now = new Date()
-
-      switch (this.queryParams.timeDimension) {
-        case 'day':
-          this.queryParams.startRecTime = this.formatDateTime(this.getTodayStart())
-          this.queryParams.endRecTime = this.formatDateTime(now)
-          break
-        case 'month':
-          this.queryParams.startRecTime = this.formatDateTime(this.getMonthStart())
-          this.queryParams.endRecTime = this.formatDateTime(now)
-          break
-        case 'year':
-          this.queryParams.startRecTime = this.formatDateTime(this.getYearStart())
-          this.queryParams.endRecTime = this.formatDateTime(now)
-          break
-      }
-    },
-
-    // 时间变化处理
-    handleTimeChange(field) {
-      if (field === 'startRecTime' && this.queryParams.endRecTime) {
-        const startDate = new Date(this.queryParams.startRecTime)
-        const endDate = new Date(this.queryParams.endRecTime)
-
-        if (endDate < startDate) {
-          this.queryParams.endRecTime = this.formatDateTime(startDate)
-        }
-      }
-    },
-
     // 搜索处理
     async handleQuery() {
       this.queryParams.pageNum = 1
@@ -717,10 +775,9 @@ export default {
         ...this.queryParams,
         areaCode: null,
         objCode: null,
-        startRecTime: this.getDefaultStartTime(),
-        endRecTime: this.getDefaultEndTime(),
         pageNum: 1
       }
+      this.initDefaultDateRange()
       await this.handleQuery()
     },
 
@@ -728,12 +785,14 @@ export default {
     async handleExport() {
       try {
         this.$modal.loading('正在导出数据,请稍候...')
-        const query = formatQueryParams(this.queryParams)
+        const query = formatQueryParams({
+          ...this.queryParams,
+          orderFlag: 'asc'
+        })
 
         let response
         let filename = ''
 
-        // 根据能源类型和对象类型调用不同导出接口
         if (this.activeName === 'areaConsume') {
           if (this.queryParams.energyType === 'elec') {
             response = await exportAreaElecConsumption(query)
@@ -858,51 +917,6 @@ export default {
       }
     },
 
-    // 工具方法
-    getDefaultStartTime() {
-      const date = new Date()
-      date.setDate(1)
-      date.setHours(0, 0, 0, 0)
-      return this.formatDateTime(date)
-    },
-
-    getDefaultEndTime() {
-      return this.formatDateTime(new Date())
-    },
-
-    getTodayStart() {
-      const date = new Date()
-      date.setHours(0, 0, 0, 0)
-      return date
-    },
-
-    getMonthStart() {
-      const date = new Date()
-      date.setDate(1)
-      date.setHours(0, 0, 0, 0)
-      return date
-    },
-
-    getYearStart() {
-      const date = new Date()
-      date.setMonth(0, 1)
-      date.setHours(0, 0, 0, 0)
-      return date
-    },
-
-    formatDateTime(date) {
-      if (!date) return ''
-
-      const year = date.getFullYear()
-      const month = String(date.getMonth() + 1).padStart(2, '0')
-      const day = String(date.getDate()).padStart(2, '0')
-      const hours = String(date.getHours()).padStart(2, '0')
-      const minutes = String(date.getMinutes()).padStart(2, '0')
-      const seconds = String(date.getSeconds()).padStart(2, '0')
-
-      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
-    },
-
     formatNumber(num, decimals = 2) {
       if (num === null || num === undefined || isNaN(num)) {
         return '0.' + '0'.repeat(decimals)
@@ -921,16 +935,7 @@ export default {
   min-height: calc(100vh - 84px);
 }
 
-/* 内容包装器样式 */
-.content-wrapper {
-  background: #fff;
-  border-radius: 8px;
-  padding: 20px;
-  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
-  min-height: calc(100vh - 200px);
-}
-
-/* 树容器样式 - 采用产能分析界面的美化设计 */
+/* 树容器样式 */
 .head-container {
   background: #fff;
   padding: 15px;
@@ -963,7 +968,7 @@ export default {
   background: #a8a8a8;
 }
 
-/* 树节点样式 - 优化版 */
+/* 树节点样式 */
 /deep/ .el-tree {
   background: transparent;
 }

+ 306 - 283
ems-ui-cloud/src/views/analysis/report/statement-prod.vue

@@ -49,72 +49,82 @@
         <div class="content-wrapper">
           <!-- 标题区域 -->
           <div class="content-header">
-            <div class="header-left">
-              <h3 class="page-title">
-                <i class="el-icon-sunny"></i>
-                光伏发电统计【{{ selectedLabel }}】
-              </h3>
-            </div>
-            <div class="header-right">
-              <el-button-group class="period-toggle">
-                <el-button
-                  v-for="item in periodOptions"
-                  :key="item.value"
-                  size="small"
-                  :type="tabPosition === item.value ? 'primary' : ''"
-                  @click="tabPosition = item.value"
-                >
-                  {{ item.label }}
-                </el-button>
-              </el-button-group>
-            </div>
+            <h3 class="page-title">
+              <i class="el-icon-sunny"></i>
+              光伏发电统计【{{ selectedLabel }}】
+            </h3>
           </div>
 
           <!-- 查询条件区域 -->
-          <div class="search-container">
-            <el-form :model="queryParams" ref="queryForm" size="small" :inline="true">
-              <el-form-item label="开始时间" prop="startRecTime">
-                <el-date-picker
-                  v-model="queryParams.startRecTime"
-                  type="datetime"
-                  value-format="yyyy-MM-dd HH:00:00"
-                  :picker-options="startPickerOptions"
-                  placeholder="请选择开始时间"
-                  @change="handleTimeChange('startRecTime')"
-                />
-              </el-form-item>
-
-              <el-form-item label="结束时间" prop="endRecTime">
-                <el-date-picker
-                  v-model="queryParams.endRecTime"
-                  type="datetime"
-                  value-format="yyyy-MM-dd HH:00:00"
-                  :picker-options="endPickerOptions"
-                  placeholder="请选择结束时间"
-                  @change="handleTimeChange('endRecTime')"
-                />
-              </el-form-item>
-
-              <el-form-item class="search-buttons">
-                <el-button icon="el-icon-search" type="primary" size="mini" @click="handleQuery">
-                  搜索
-                </el-button>
-                <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">
-                  重置
-                </el-button>
-                <el-button
-                  type="warning"
-                  plain
-                  icon="el-icon-download"
-                  size="mini"
-                  v-hasPermi="['ems:EmsEcoD:export']"
-                  @click="handleExport"
-                >
-                  导出
-                </el-button>
-              </el-form-item>
-            </el-form>
-          </div>
+          <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="80px">
+            <!-- 统计维度选择 -->
+            <el-form-item label="统计维度">
+              <el-radio-group v-model="tabPosition" @change="handleTimeDimensionChange">
+                <el-radio-button label="day">日</el-radio-button>
+                <el-radio-button label="month">月</el-radio-button>
+                <el-radio-button label="year">年</el-radio-button>
+              </el-radio-group>
+            </el-form-item>
+
+            <!-- 日期选择 - 根据统计维度显示不同控件 -->
+            <el-form-item label="统计时间">
+              <!-- 日维度:日期范围选择 -->
+              <el-date-picker
+                v-if="tabPosition === 'day'"
+                v-model="dateRange"
+                type="daterange"
+                value-format="yyyy-MM-dd"
+                range-separator="-"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                :picker-options="dayPickerOptions"
+                style="width: 260px"
+                @change="handleDateRangeChange"
+              />
+
+              <!-- 月维度:月份范围选择 -->
+              <el-date-picker
+                v-if="tabPosition === 'month'"
+                v-model="monthRange"
+                type="monthrange"
+                value-format="yyyy-MM"
+                range-separator="-"
+                start-placeholder="开始月份"
+                end-placeholder="结束月份"
+                :picker-options="monthPickerOptions"
+                style="width: 260px"
+                @change="handleMonthRangeChange"
+              />
+
+              <!-- 年维度:年份选择 -->
+              <el-date-picker
+                v-if="tabPosition === 'year'"
+                v-model="yearValue"
+                type="year"
+                value-format="yyyy"
+                placeholder="选择年份"
+                :picker-options="yearPickerOptions"
+                style="width: 150px"
+                @change="handleYearChange"
+              />
+            </el-form-item>
+
+            <!-- 操作按钮 -->
+            <el-form-item>
+              <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+              <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+              <el-button
+                type="warning"
+                plain
+                icon="el-icon-download"
+                size="mini"
+                v-hasPermi="['ems:EmsEcoD:export']"
+                @click="handleExport"
+              >
+                导出
+              </el-button>
+            </el-form-item>
+          </el-form>
 
           <!-- 数据统计卡片 -->
           <div class="stats-cards">
@@ -174,14 +184,24 @@
               class="data-table"
               stripe
             >
+              <el-table-column label="区域名称" align="center" prop="areaName" min-width="150" show-overflow-tooltip>
+                <template slot-scope="scope">
+                  <span class="area-name">
+                    <i class="el-icon-location-outline"></i>
+                    {{ scope.row.areaName || '-' }}
+                  </span>
+                </template>
+              </el-table-column>
               <el-table-column label="日期" align="center" prop="date" width="180">
                 <template slot-scope="scope">
-                  <span class="date-text">{{ parseTime(scope.row.date, '{y}-{m}-{d}') }}</span>
+                  <span class="date-text">{{ formatDateColumn(scope.row) }}</span>
                 </template>
               </el-table-column>
-              <el-table-column label="时间" align="center" prop="time">
+              <el-table-column label="时间维度" align="center" prop="timeDimension" width="100">
                 <template slot-scope="scope">
-                  <el-tag size="mini" type="info">{{ scope.row.time }}</el-tag>
+                  <el-tag size="mini" :type="getDimensionTagType(scope.row.timeDimension)">
+                    {{ getDimensionLabel(scope.row.timeDimension) }}
+                  </el-tag>
                 </template>
               </el-table-column>
               <el-table-column label="总发电量" align="center" prop="genElecQuantity">
@@ -226,7 +246,6 @@
 <script>
 import { areaTreeByFacsCategory } from '@/api/basecfg/area'
 import { listPvSupplyH } from "@/api/mgr/pgSupplyH"
-import { DateTool } from "@/utils/DateTool"
 
 export default {
   name: "PvSupplyStatistics",
@@ -251,20 +270,23 @@ export default {
         children: "children",
         label: "label"
       },
-      // 时间周期选项
-      periodOptions: [
-        { label: '日', value: 'day' },
-        { label: '月', value: 'month' },
-        { label: '年', value: 'year' }
-      ],
+      // 统计维度
       tabPosition: 'month',
+
+      // 日期选择
+      dateRange: [],      // 日维度的日期范围
+      monthRange: [],     // 月维度的月份范围
+      yearValue: '',      // 年维度的年份
+
       // 查询参数
       queryParams: {
         pageNum: 1,
         pageSize: 10,
         areaCode: '-1',
-        startRecTime: this.getFirstDayOfMonth(),
-        endRecTime: this.getTodayEndTime(),
+        startRecTime: null,
+        endRecTime: null,
+        timeDimension: 'month',  // ✅ 时间维度参数
+        orderFlag: 'desc'        // ✅ 默认降序
       },
       // 统计数据
       totalStats: {
@@ -273,73 +295,135 @@ export default {
         upElecQuantity: 0,
         upElecEarn: 0
       },
-      // 时间选择器配置
-      startPickerOptions: {
+      // 日期选择器配置
+      dayPickerOptions: {
         disabledDate: (time) => {
-          const ninetyDaysAgo = new Date();
-          ninetyDaysAgo.setDate(ninetyDaysAgo.getDate() - 90);
-          return time.getTime() > Date.now() - 8.64e7 || time.getTime() < ninetyDaysAgo.getTime();
-        },
-        selectableRange: this.generateHourRanges()
+          return time.getTime() > Date.now()
+        }
       },
-      endPickerOptions: {
+      monthPickerOptions: {
         disabledDate: (time) => {
-          if (this.queryParams.startRecTime) {
-            const startDate = new Date(this.queryParams.startRecTime);
-            const endDateLimit = new Date(startDate);
-            endDateLimit.setDate(endDateLimit.getDate() + 90);
-            endDateLimit.setHours(23, 59, 59);
-
-            return time.getTime() < startDate.getTime() ||
-              time.getTime() > endDateLimit.getTime() ||
-              time.getTime() > Date.now() - 8.64e7;
-          }
-          const ninetyDaysAgo = new Date();
-          ninetyDaysAgo.setDate(ninetyDaysAgo.getDate() - 90);
-          return time.getTime() > Date.now() - 8.64e7 || time.getTime() < ninetyDaysAgo.getTime();
-        },
-        selectableRange: this.generateHourRanges()
+          return time.getTime() > Date.now()
+        }
+      },
+      yearPickerOptions: {
+        disabledDate: (time) => {
+          return time.getTime() > Date.now()
+        }
       }
     };
   },
-  watch: {
-    tabPosition(val) {
-      if (!val) return;
-
-      if (val === 'day') {
-        this.queryParams.startRecTime = DateTool.now(DateTool.DateFormat.YYYY_MM_DD_00_00_00);
-        this.queryParams.endRecTime = DateTool.now(DateTool.DateFormat.YYYY_MM_DD_23_59_59);
-      } else if (val === 'month') {
-        this.queryParams.startRecTime = DateTool.thisMonth(DateTool.DateFormat.YYYY_MM_01_00_00_00);
-        this.queryParams.endRecTime = DateTool.now(DateTool.DateFormat.YYYY_MM_DD_23_59_59);
-      } else if (val === 'year') {
-        this.queryParams.startRecTime = DateTool.thisYear(DateTool.DateFormat.YYYY_01_01_00_00_00);
-        this.queryParams.endRecTime = DateTool.now(DateTool.DateFormat.YYYY_MM_DD_23_59_59);
-      }
-
-      this.getList();
-    }
-  },
   created() {
-    if (this.queryParams.startRecTime) {
-      this.queryParams.startRecTime = this.formatDateTime(this.queryParams.startRecTime);
-    }
-    if (this.queryParams.endRecTime) {
-      this.queryParams.endRecTime = this.formatDateTime(this.queryParams.endRecTime);
-    }
-    this.getAreaList();
-    this.getList();
+    // ✅ 确保 timeDimension 与 tabPosition 同步
+    this.queryParams.timeDimension = this.tabPosition
+    this.initDefaultDateRange()
+    this.getAreaList()
+    this.getList()
   },
   methods: {
+    // 初始化默认日期范围
+    initDefaultDateRange() {
+      const today = new Date()
+      const currentYear = today.getFullYear()
+      const currentMonth = today.getMonth()
+
+      if (this.tabPosition === 'day') {
+        // 日维度:当月1号到今天
+        const startDate = new Date(currentYear, currentMonth, 1)
+        this.dateRange = [
+          this.formatDate(startDate),
+          this.formatDate(today)
+        ]
+        this.queryParams.startRecTime = this.formatDate(startDate) + ' 00:00:00'
+        this.queryParams.endRecTime = this.formatDate(today) + ' 23:59:59'
+      } else if (this.tabPosition === 'month') {
+        // 月维度:当年1月到当前月
+        this.monthRange = [
+          `${currentYear}-01`,
+          `${currentYear}-${String(currentMonth + 1).padStart(2, '0')}`
+        ]
+        this.queryParams.startRecTime = `${currentYear}-01-01 00:00:00`
+        this.queryParams.endRecTime = this.formatDate(new Date(currentYear, currentMonth + 1, 0)) + ' 23:59:59'
+      } else if (this.tabPosition === 'year') {
+        // 年维度:当年
+        this.yearValue = String(currentYear)
+        this.queryParams.startRecTime = `${currentYear}-01-01 00:00:00`
+        this.queryParams.endRecTime = `${currentYear}-12-31 23:59:59`
+      }
+    },
+
+    // 格式化日期 yyyy-MM-dd
+    formatDate(date) {
+      const year = date.getFullYear()
+      const month = String(date.getMonth() + 1).padStart(2, '0')
+      const day = String(date.getDate()).padStart(2, '0')
+      return `${year}-${month}-${day}`
+    },
+
+    // 日期范围变化处理(日维度)
+    handleDateRangeChange() {
+      if (this.dateRange && this.dateRange.length === 2) {
+        this.queryParams.startRecTime = this.dateRange[0] + ' 00:00:00'
+        this.queryParams.endRecTime = this.dateRange[1] + ' 23:59:59'
+      } else {
+        this.queryParams.startRecTime = null
+        this.queryParams.endRecTime = null
+      }
+    },
+
+    // 月份范围变化处理(月维度)
+    handleMonthRangeChange() {
+      if (this.monthRange && this.monthRange.length === 2) {
+        const [startYear, startMonth] = this.monthRange[0].split('-')
+        const [endYear, endMonth] = this.monthRange[1].split('-')
+
+        // 开始时间:月初第一天 00:00:00
+        this.queryParams.startRecTime = `${startYear}-${startMonth}-01 00:00:00`
+
+        // 结束时间:月末最后一天 23:59:59
+        const lastDay = new Date(parseInt(endYear), parseInt(endMonth), 0).getDate()
+        this.queryParams.endRecTime = `${endYear}-${endMonth}-${String(lastDay).padStart(2, '0')} 23:59:59`
+      } else {
+        this.queryParams.startRecTime = null
+        this.queryParams.endRecTime = null
+      }
+    },
+
+    // 年份变化处理(年维度)
+    handleYearChange() {
+      if (this.yearValue) {
+        this.queryParams.startRecTime = `${this.yearValue}-01-01 00:00:00`
+        this.queryParams.endRecTime = `${this.yearValue}-12-31 23:59:59`
+      } else {
+        this.queryParams.startRecTime = null
+        this.queryParams.endRecTime = null
+      }
+    },
+
+    // 统计维度变化处理
+    handleTimeDimensionChange() {
+      // ✅ 同步更新 queryParams 中的 timeDimension
+      this.queryParams.timeDimension = this.tabPosition
+
+      // 重新初始化日期范围
+      this.initDefaultDateRange()
+      this.queryParams.pageNum = 1
+      this.getList()
+    },
+
     // 获取数据列表
     getList() {
-      this.loading = true;
+      this.loading = true
       listPvSupplyH(this.queryParams).then(response => {
-        this.pvSupplyHList = response.rows;
-        this.total = response.total;
-        this.calculateStats(response.rows);
-        this.loading = false;
-      });
+        this.pvSupplyHList = response.rows
+        this.total = response.total
+        this.calculateStats(response.rows)
+        this.loading = false
+      }).catch(error => {
+        console.error('查询失败:', error)
+        this.loading = false
+        this.$message.error('查询数据失败,请稍后重试')
+      })
     },
 
     // 计算统计数据
@@ -349,21 +433,21 @@ export default {
         useElecQuantity: 0,
         upElecQuantity: 0,
         upElecEarn: 0
-      };
+      }
 
       if (data && data.length > 0) {
         data.forEach(item => {
-          this.totalStats.genElecQuantity += parseFloat(item.genElecQuantity || 0);
-          this.totalStats.useElecQuantity += parseFloat(item.useElecQuantity || 0);
-          this.totalStats.upElecQuantity += parseFloat(item.upElecQuantity || 0);
-          this.totalStats.upElecEarn += parseFloat(item.upElecEarn || 0);
-        });
+          this.totalStats.genElecQuantity += parseFloat(item.genElecQuantity || 0)
+          this.totalStats.useElecQuantity += parseFloat(item.useElecQuantity || 0)
+          this.totalStats.upElecQuantity += parseFloat(item.upElecQuantity || 0)
+          this.totalStats.upElecEarn += parseFloat(item.upElecEarn || 0)
+        })
 
         // 保留两位小数
-        this.totalStats.genElecQuantity = this.totalStats.genElecQuantity.toFixed(2);
-        this.totalStats.useElecQuantity = this.totalStats.useElecQuantity.toFixed(2);
-        this.totalStats.upElecQuantity = this.totalStats.upElecQuantity.toFixed(2);
-        this.totalStats.upElecEarn = this.totalStats.upElecEarn.toFixed(2);
+        this.totalStats.genElecQuantity = this.totalStats.genElecQuantity.toFixed(2)
+        this.totalStats.useElecQuantity = this.totalStats.useElecQuantity.toFixed(2)
+        this.totalStats.upElecQuantity = this.totalStats.upElecQuantity.toFixed(2)
+        this.totalStats.upElecEarn = this.totalStats.upElecEarn.toFixed(2)
       }
     },
 
@@ -374,132 +458,117 @@ export default {
           id: '-1',
           label: '全部',
           children: response.data || []
-        }];
+        }]
 
         // 设置默认展开第一级
-        this.defaultExpandedKeys = ['-1'];
+        this.defaultExpandedKeys = ['-1']
 
         // 默认选中全部
         this.$nextTick(() => {
           if (this.$refs.tree) {
-            this.$refs.tree.setCurrentKey('-1');
+            this.$refs.tree.setCurrentKey('-1')
           }
-        });
-      });
+        })
+      })
     },
 
     // 获取树节点图标
     getTreeIcon(data) {
       if (data.facsCategory === 'E') {
-        return 'el-icon-sunny';
+        return 'el-icon-sunny'
       }
       if (data.id === '-1') {
-        return 'el-icon-s-home';
-      }
-      return 'el-icon-office-building';
-    },
-
-    // 生成整点时间范围
-    generateHourRanges() {
-      const ranges = [];
-      for (let i = 0; i < 24; i++) {
-        const start = `${i.toString().padStart(2, '0')}:00:00`;
-        const end = `${i.toString().padStart(2, '0')}:59:59`;
-        ranges.push(`${start} - ${end}`);
-      }
-      return ranges;
-    },
-
-    // 时间选择处理
-    handleTimeChange(field) {
-      this.tabPosition = "";
-      if (this.queryParams[field]) {
-        const date = new Date(this.queryParams[field]);
-        const formatDate = (d) => {
-          const pad = (n) => String(n).padStart(2, '0');
-          return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:00:00`;
-        };
-        this.queryParams[field] = formatDate(date);
-      }
-
-      if (field === 'startRecTime' && this.queryParams.endRecTime) {
-        this.$nextTick(() => {
-          this.$refs.queryForm.validateField('endRecTime');
-        });
+        return 'el-icon-s-home'
       }
+      return 'el-icon-office-building'
     },
 
     // 搜索按钮操作
     handleQuery() {
-      this.queryParams.pageNum = 1;
-      this.getList();
+      this.queryParams.pageNum = 1
+      this.getList()
     },
 
     // 重置按钮操作
     resetQuery() {
-      this.resetForm("queryForm");
-      this.tabPosition = 'month';
-      this.handleQuery();
+      this.resetForm("queryForm")
+      this.tabPosition = 'month'
+      this.queryParams.areaCode = '-1'
+      this.queryParams.timeDimension = 'month'  // ✅ 同步重置
+      this.queryParams.orderFlag = 'desc'       // ✅ 重置为降序
+      this.initDefaultDateRange()
+      this.handleQuery()
     },
 
     // 导出按钮操作
     handleExport() {
-      this.download('ems/prod/pv/hour/export', {
-        ...this.queryParams
-      }, `产能报表_${new Date().getTime()}.xlsx`);
-    },
+      const dimensionLabel = this.getDimensionLabel(this.queryParams.timeDimension)
 
-    // 获取本月1号 00:00:00
-    getFirstDayOfMonth() {
-      const date = new Date();
-      date.setDate(1);
-      date.setHours(0, 0, 0, 0);
-      return this.formatDateTime(date);
-    },
-
-    // 获取当天 23:59:59
-    getTodayEndTime() {
-      const date = new Date();
-      date.setHours(23, 59, 59, 999);
-      return this.formatDateTime(date);
-    },
-
-    // 格式化日期时间
-    formatDateTime(date) {
-      if (!date) return '';
-      if (typeof date === 'string') {
-        date = new Date(date);
-      }
-
-      const year = date.getFullYear();
-      const month = String(date.getMonth() + 1).padStart(2, '0');
-      const day = String(date.getDate()).padStart(2, '0');
-      const hours = String(date.getHours()).padStart(2, '0');
-      const minutes = String(date.getMinutes()).padStart(2, '0');
-      const seconds = String(date.getSeconds()).padStart(2, '0');
-
-      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+      // ✅ 导出时使用升序排列,使用若依框架的 download 方法
+      this.download('ems/prod/pv/hour/export', {
+        ...this.queryParams,
+        orderFlag: 'asc'  // ✅ 导出按升序排列
+      }, `光伏产能统计_${dimensionLabel}_${new Date().getTime()}.xlsx`)
     },
 
     // 筛选节点
     filterNode(value, data) {
-      if (!value) return true;
-      return data.label.indexOf(value) !== -1;
+      if (!value) return true
+      return data.label.indexOf(value) !== -1
     },
 
     // 过滤树
     filterTree() {
-      this.$refs.tree.filter(this.areaName);
+      this.$refs.tree.filter(this.areaName)
     },
 
     // 节点单击事件
     handleNodeClick(data) {
-      this.queryParams.areaCode = data.id;
-      this.selectedLabel = data.label;
-      this.getList();
+      this.queryParams.areaCode = data.id
+      this.selectedLabel = data.label
+      this.queryParams.pageNum = 1  // ✅ 重置页码
+      this.getList()
+    },
+
+    // ✅ 格式化表格日期列
+    formatDateColumn(row) {
+      if (row.timeDimension === 'DAY' || row.timeDimension === 'day') {
+        return this.parseTime(row.statisticDate, '{y}-{m}-{d}')
+      } else if (row.timeDimension === 'MONTH' || row.timeDimension === 'month') {
+        return row.statisticMonth || this.parseTime(row.statisticDate, '{y}-{m}')
+      } else if (row.timeDimension === 'YEAR' || row.timeDimension === 'year') {
+        return row.statisticYear || this.parseTime(row.statisticDate, '{y}')
+      }
+      return this.parseTime(row.statisticDate, '{y}-{m}-{d}')
+    },
+
+    // ✅ 获取维度标签
+    getDimensionLabel(dimension) {
+      const map = {
+        'day': '日',
+        'DAY': '日',
+        'month': '月',
+        'MONTH': '月',
+        'year': '年',
+        'YEAR': '年'
+      }
+      return map[dimension] || '未知'
+    },
+
+    // ✅ 获取维度标签类型
+    getDimensionTagType(dimension) {
+      const map = {
+        'day': 'success',
+        'DAY': 'success',
+        'month': 'primary',
+        'MONTH': 'primary',
+        'year': 'warning',
+        'YEAR': 'warning'
+      }
+      return map[dimension] || 'info'
     }
   }
-};
+}
 </script>
 
 <style lang="scss" scoped>
@@ -594,9 +663,6 @@ export default {
     min-height: calc(100vh - 160px);
 
     .content-header {
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
       margin-bottom: 20px;
       padding-bottom: 15px;
       border-bottom: 2px solid #f0f2f5;
@@ -612,44 +678,6 @@ export default {
           color: #409eff;
         }
       }
-
-      .period-toggle {
-        ::v-deep .el-button {
-          padding: 8px 20px;
-
-          &.el-button--primary {
-            background: linear-gradient(90deg, #409eff 0%, #53a8ff 100%);
-            border-color: #409eff;
-          }
-        }
-      }
-    }
-
-    .search-container {
-      background: #f9fbfd;
-      border-radius: 8px;
-      padding: 15px;
-      margin-bottom: 20px;
-
-      ::v-deep .el-form {
-        .el-form-item {
-          margin-bottom: 0;
-          margin-right: 15px;
-
-          .el-form-item__label {
-            font-weight: 500;
-            color: #606266;
-          }
-        }
-
-        .search-buttons {
-          margin-right: 0;
-
-          .el-button {
-            padding: 7px 15px;
-          }
-        }
-      }
     }
 
     .stats-cards {
@@ -714,6 +742,19 @@ export default {
         }
 
         ::v-deep .el-table__body {
+          .area-name {
+            display: inline-flex;
+            align-items: center;
+            font-weight: 500;
+            color: #303133;
+
+            i {
+              margin-right: 5px;
+              color: #409eff;
+              font-size: 14px;
+            }
+          }
+
           .date-text {
             font-weight: 500;
             color: #606266;
@@ -761,24 +802,6 @@ export default {
     }
 
     .content-wrapper {
-      .content-header {
-        flex-direction: column;
-        align-items: flex-start;
-
-        .period-toggle {
-          margin-top: 10px;
-        }
-      }
-
-      .search-container {
-        ::v-deep .el-form {
-          .el-form-item {
-            display: block;
-            margin-bottom: 10px;
-          }
-        }
-      }
-
       .stats-cards {
         .el-col {
           margin-bottom: 10px;