EnergyReportDialog.vue 8.55 KB
<template>
  <el-dialog
    :model-value="visible"
    @update:model-value="$emit('update:visible', $event)"
    title=""
    width="calc(100vw - 40px)"
    :style="{ maxWidth: '1400px' }"
    top="3vh"
    destroy-on-close
    class="ereport-dialog"
  >
    <template #header>
      <div class="dialog-header">
        <span class="title-text">{{ device?.name || '能耗设备1' }} 能耗报表</span>
        <div class="header-right">
          <el-icon :size="16" style="cursor:pointer;color:#409eff;"><FullScreen /></el-icon>
          <el-icon :size="16" style="cursor:pointer;color:#409eff;margin-left:8px;" @click="$emit('update:visible', false)"><Close /></el-icon>
        </div>
      </div>
    </template>

    <div class="report-body">
      <!-- 上排:6个能耗卡片 + 碳排放统计 -->
      <div class="top-section">
        <div class="energy-cards-grid">
          <div v-for="(card, idx) in energyCards" :key="idx" :class="['energy-card-item', card.color]">
            <span class="card-label">{{ card.label }}</span>
            <span class="card-val">{{ card.value }}<small>{{ card.unit }}</small></span>
          </div>
        </div>
        <div class="carbon-panel">
          <div class="carbon-title">碳排放统计 <i style="font-size:12px;">▼</i></div>
          <div class="carbon-sub">碳排放系数0</div>
          <div v-for="item in carbonItems" :key="item.label" :class="['carbon-row', item.color]">
            {{ item.label }}{{ item.val }}
          </div>
        </div>
      </div>

      <!-- 下排:3个图表 -->
      <div class="charts-grid">
        <!-- 时能耗 -->
        <div class="chart-card">
          <div class="chart-header">
            <span class="chart-title">时能耗</span>
            <div class="chart-tools">
              <label><input type="radio" name="t1" checked /> 2025-04-28</label>&nbsp;
              <label><input type="radio" name="t2" checked /> 昨日日期</label>
              <el-icon :size="14"><ZoomIn /></el-icon>
            </div>
          </div>
          <div class="chart-body">
            <svg viewBox="0 0 500 220">
              <g font-size="10" fill="#999" text-anchor="end">
                <text x="24" y="20">1</text><text x="24" y="60">0.8</text><text x="24" y="100">0.6</text>
                <text x="24" y="140">0.4</text><text x="24" y="180">0.2</text><text x="24" y="210">0</text>
              </g>
              <line x1="30" y1="206" x2="490" y2="206" stroke="#ddd"/>
              <g font-size="9" fill="#666" text-anchor="middle">
                <template v-for="i in 25" :key="'th'+i"><text :x="36+i*18" y="218">{{ i-1 }}</text></template>
              </g>
              <polyline points="36,206 54,206 72,206 90,206 108,206 126,206 144,206 162,206 180,206 198,206 216,206 234,206 252,206 270,206 288,206 306,206 324,206 342,206 360,206 378,206 396,206 414,206 432,206 450,206 468,206 486,206"
                fill="none" stroke="#409eff" stroke-width="1.5"/>
            </svg>
          </div>
        </div>

        <!-- 日能耗 -->
        <div class="chart-card">
          <div class="chart-header">
            <span class="chart-title">日能耗</span>
            <div class="chart-tools">
              <label><input type="radio" checked/> 2025-04</label>&nbsp;
              <label><input type="radio" checked/> 昨日日期</label>
              <el-icon :size="14"><ZoomIn /></el-icon>
            </div>
          </div>
          <div class="chart-body">
            <svg viewBox="0 0 500 220">
              <g font-size="10" fill="#999" text-anchor="end">
                <text x="24" y="20">1</text><text x="24" y="60">0.8</text><text x="24" y="100">0.6</text>
                <text x="24" y="140">0.4</text><text x="24" y="180">0.2</text><text x="24" y="210">0</text>
              </g>
              <line x1="30" y1="206" x2="490" y2="206" stroke="#ddd"/>
              <g font-size="9" fill="#666" text-anchor="middle">
                <template v-for="i in 31" :key="'dh'+i"><text :x="32+(i-1)*15" y="218">{{ i }}</text></template>
              </g>
              <polyline fill="none" stroke="#67c23a" stroke-width="1.5"/>
            </svg>
          </div>
        </div>

        <!-- 月能耗 -->
        <div class="chart-card full-width">
          <div class="chart-header">
            <span class="chart-title">月能耗</span>
            <div class="chart-tools">
              <label><input type="radio" checked/> 2025</label>
              <el-icon :size="14"><ZoomIn /></el-icon>
            </div>
          </div>
          <div class="chart-body">
            <svg viewBox="0 0 500 180">
              <g font-size="10" fill="#999" text-anchor="end">
                <text x="22" y="18">1</text><text x="22" y="53">0.8</text><text x="22" y="88">0.6</text>
                <text x="22" y="123">0.4</text><text x="22" y="158">0.2</text>
              </g>
              <line x1="28" y1="164" x2="488" y2="164" stroke="#ddd"/>
              <g font-size="9" fill="#666" text-anchor="middle">
                <template v-for="i in 12" :key="'mh'+i"><text :x="34+(i-1)*39" y="177">{{ i }}</text></template>
              </g>
            </svg>
          </div>
        </div>
      </div>
    </div>
  </el-dialog>
</template>

<script setup>
import { ref } from 'vue'
import { FullScreen, Close, ZoomIn } from '@element-plus/icons-vue'

defineProps({ visible: Boolean, device: Object })
defineEmits(['update:visible'])

const energyCards = [
  { label: '本小时能耗', value: '0', unit: 'kw·h', color: 'orange' },
  { label: '本日能耗', value: '0', unit: 'kw·h', color: 'green' },
  { label: '本月能耗', value: '0', unit: 'kw·h', color: 'blue' },
  { label: '上小时能耗', value: '0', unit: 'kw·h', color: 'orange' },
  { label: '昨日能耗', value: '0', unit: 'kw·h', color: 'green' },
  { label: '上月能耗', value: '0', unit: 'kw·h', color: 'blue' }
]
const carbonItems = [
  { label: '累计碳排放:', val: '0', color: 'blue' },
  { label: '时:', val: '0.00', color: 'blue' },
  { label: '日:', val: '0.00', color: 'blue' },
  { label: '月:', val: '0.00', color: 'blue' }
]
</script>

<style scoped>
.ereport-dialog :deep(.el-dialog) {
  max-height: 92vh;
  display: flex; flex-direction: column;
}
.ereport-dialog :deep(.el-dialog__header) { padding: 10px 20px; border-bottom: 1px solid #e8e8e8; margin: 0; flex-shrink: 0; }
.ereport-dialog :deep(.el-dialog__body) { overflow-y: auto; flex: 1; }
.dialog-header { display: flex; align-items: center; justify-content: space-between; }
.title-text { font-size: 15px; font-weight: bold; color: #333; }
.header-right { display: flex; align-items: center; }

.report-body { padding: 12px 0; }

.top-section { display: grid; grid-template-columns: 1fr 200px; gap: 14px; margin-bottom: 14px; padding: 0 16px; }
.energy-cards-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.energy-card-item {
  border-radius: 6px; padding: 16px 12px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; color: #fff;
}
.energy-card-item.orange { background: linear-gradient(135deg, #f56c6c, #e74c3c); }
.energy-card-item.green { background: linear-gradient(135deg, #67c23a, #52c41a); }
.energy-card-item.blue { background: linear-gradient(135deg, #409eff, #1890ff); }
.card-label { font-size: 13px; opacity: 0.9; }
.card-val { font-size: 26px; font-weight: bold; margin-top: 6px; }
.card-val small { font-size: 13px; font-weight: normal; margin-left: 2px; }

.carbon-panel { background: linear-gradient(160deg, #5b9bd5 0%, #2e75b6 100%); border-radius: 6px; padding: 14px; color: #fff; }
.carbon-title { font-size: 13px; font-weight: bold; margin-bottom: 8px; }
.carbon-sub { font-size: 11px; opacity: 0.85; margin-bottom: 10px; text-align: right; }
.carbon-row { padding: 7px 12px; border-radius: 4px; margin-bottom: 4px; font-size: 12px; background: rgba(255,255,255,0.18); }
.carbon-row.blue { background: rgba(64,158,255,0.35); }

.charts-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; padding: 0 16px; }
.chart-card { background: #fff; border: 1px solid #eee; border-radius: 6px; overflow: hidden; }
.chart-card.full-width { grid-column: 1 / -1; }
.chart-header { padding: 10px 14px; border-bottom: 1px solid #f0f0f0; display: flex; justify-content: space-between; align-items: center; }
.chart-title { font-size: 13px; font-weight: bold; color: #333; }
.chart-tools { display: flex; align-items: center; gap: 6px; font-size: 11px; color: #666; }
.chart-tools label { cursor: pointer; display: flex; align-items: center; gap: 2px; }
.chart-body { padding: 10px 14px; }
.chart-body svg { width: 100%; height: auto; }
</style>