新增能源報表
This commit is contained in:
		
							parent
							
								
									7f4d1e6e07
								
							
						
					
					
						commit
						cd0bfafa35
					
				
							
								
								
									
										4
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							@ -13,6 +13,8 @@ declare module 'vue' {
 | 
				
			|||||||
    ElCard: typeof import('element-plus/es')['ElCard']
 | 
					    ElCard: typeof import('element-plus/es')['ElCard']
 | 
				
			||||||
    ElCol: typeof import('element-plus/es')['ElCol']
 | 
					    ElCol: typeof import('element-plus/es')['ElCol']
 | 
				
			||||||
    ElContainer: typeof import('element-plus/es')['ElContainer']
 | 
					    ElContainer: typeof import('element-plus/es')['ElContainer']
 | 
				
			||||||
 | 
					    ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
 | 
				
			||||||
 | 
					    ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
 | 
				
			||||||
    ElHeader: typeof import('element-plus/es')['ElHeader']
 | 
					    ElHeader: typeof import('element-plus/es')['ElHeader']
 | 
				
			||||||
    ElInput: typeof import('element-plus/es')['ElInput']
 | 
					    ElInput: typeof import('element-plus/es')['ElInput']
 | 
				
			||||||
    ElMain: typeof import('element-plus/es')['ElMain']
 | 
					    ElMain: typeof import('element-plus/es')['ElMain']
 | 
				
			||||||
@ -23,8 +25,10 @@ declare module 'vue' {
 | 
				
			|||||||
    ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
 | 
					    ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
 | 
				
			||||||
    EnergyBar: typeof import('./src/components/EnergyBar.vue')['default']
 | 
					    EnergyBar: typeof import('./src/components/EnergyBar.vue')['default']
 | 
				
			||||||
    EnergyLine: typeof import('./src/components/EnergyLine.vue')['default']
 | 
					    EnergyLine: typeof import('./src/components/EnergyLine.vue')['default']
 | 
				
			||||||
 | 
					    EnergyPie: typeof import('./src/components/EnergyPie.vue')['default']
 | 
				
			||||||
    EnergySankey: typeof import('./src/components/EnergySankey.vue')['default']
 | 
					    EnergySankey: typeof import('./src/components/EnergySankey.vue')['default']
 | 
				
			||||||
    Navbar: typeof import('./src/components/Navbar.vue')['default']
 | 
					    Navbar: typeof import('./src/components/Navbar.vue')['default']
 | 
				
			||||||
 | 
					    PdfContent: typeof import('./src/components/PdfContent.vue')['default']
 | 
				
			||||||
    RouterLink: typeof import('vue-router')['RouterLink']
 | 
					    RouterLink: typeof import('vue-router')['RouterLink']
 | 
				
			||||||
    RouterView: typeof import('vue-router')['RouterView']
 | 
					    RouterView: typeof import('vue-router')['RouterView']
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1280
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1280
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -14,12 +14,14 @@
 | 
				
			|||||||
    "element-plus": "^2.9.6",
 | 
					    "element-plus": "^2.9.6",
 | 
				
			||||||
    "pinia": "^3.0.2",
 | 
					    "pinia": "^3.0.2",
 | 
				
			||||||
    "vue": "^3.5.13",
 | 
					    "vue": "^3.5.13",
 | 
				
			||||||
    "vue-router": "^4.5.0"
 | 
					    "vue-router": "^4.5.0",
 | 
				
			||||||
 | 
					    "vue3-html2pdf": "^1.1.2"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@types/node": "^22.13.11",
 | 
					    "@types/node": "^22.13.11",
 | 
				
			||||||
    "@vitejs/plugin-vue": "^5.2.1",
 | 
					    "@vitejs/plugin-vue": "^5.2.1",
 | 
				
			||||||
    "@vue/tsconfig": "^0.7.0",
 | 
					    "@vue/tsconfig": "^0.7.0",
 | 
				
			||||||
 | 
					    "sass-embedded": "^1.87.0",
 | 
				
			||||||
    "typescript": "~5.7.2",
 | 
					    "typescript": "~5.7.2",
 | 
				
			||||||
    "unplugin-auto-import": "^19.1.1",
 | 
					    "unplugin-auto-import": "^19.1.1",
 | 
				
			||||||
    "unplugin-vue-components": "^28.4.1",
 | 
					    "unplugin-vue-components": "^28.4.1",
 | 
				
			||||||
 | 
				
			|||||||
@ -170,6 +170,8 @@ watch(
 | 
				
			|||||||
onMounted(async () => {
 | 
					onMounted(async () => {
 | 
				
			||||||
  // 等待數據加載
 | 
					  // 等待數據加載
 | 
				
			||||||
  await storeDemand.getElecDemandFromBaja();
 | 
					  await storeDemand.getElecDemandFromBaja();
 | 
				
			||||||
 | 
					  // 測試
 | 
				
			||||||
 | 
					  await storeDemand.getElecDatatTestBaja();
 | 
				
			||||||
  // 初始化圖表
 | 
					  // 初始化圖表
 | 
				
			||||||
  chartInstance = echarts.init(demand_chart.value);
 | 
					  chartInstance = echarts.init(demand_chart.value);
 | 
				
			||||||
  chartInstance.setOption(chartOption.value);
 | 
					  chartInstance.setOption(chartOption.value);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										91
									
								
								src/components/EnergyPie.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/components/EnergyPie.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					<script setup>
 | 
				
			||||||
 | 
					import { ref, onMounted, watch, onUnmounted } from "vue";
 | 
				
			||||||
 | 
					import * as echarts from "echarts";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const chartContainer = ref(null);
 | 
				
			||||||
 | 
					let chartInstance = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const chartData = ref({
 | 
				
			||||||
 | 
					  series: [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: "電表01",
 | 
				
			||||||
 | 
					      value: 2200,  
 | 
				
			||||||
 | 
					      itemStyle: { color: "#5470c6" }, 
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: "電表02",
 | 
				
			||||||
 | 
					      value: 3600, 
 | 
				
			||||||
 | 
					      itemStyle: { color: "#91cc75" }, 
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: "電表03",
 | 
				
			||||||
 | 
					      value: 1600, 
 | 
				
			||||||
 | 
					      itemStyle: { color: "#fac858" }, 
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const initChart = () => {
 | 
				
			||||||
 | 
					  chartInstance = echarts.init(chartContainer.value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const option = {
 | 
				
			||||||
 | 
					    tooltip: {
 | 
				
			||||||
 | 
					      trigger: "item",
 | 
				
			||||||
 | 
					      formatter: "{a} <br/>{b} : {c} ({d}%)",  // 显示数据格式
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    legend: {
 | 
				
			||||||
 | 
					      orient: "vertical", 
 | 
				
			||||||
 | 
					      left: "right", 
 | 
				
			||||||
 | 
					      bottom: "0%",
 | 
				
			||||||
 | 
					      data: chartData.value.series.map((item) => item.name), //  添加图例
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    series: [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: "電表費用",
 | 
				
			||||||
 | 
					        type: "pie",
 | 
				
			||||||
 | 
					        radius: "70%",  // 饼图大小
 | 
				
			||||||
 | 
					        center: ["50%", "50%"], // 饼图中心位置
 | 
				
			||||||
 | 
					        data: chartData.value.series,
 | 
				
			||||||
 | 
					        emphasis: {
 | 
				
			||||||
 | 
					          itemStyle: {
 | 
				
			||||||
 | 
					            shadowBlur: 10,
 | 
				
			||||||
 | 
					            shadowOffsetX: 0,
 | 
				
			||||||
 | 
					            shadowColor: "rgba(0, 0, 0, 0.5)",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  chartInstance.setOption(option);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(() => {
 | 
				
			||||||
 | 
					  initChart();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(
 | 
				
			||||||
 | 
					  () => chartData.value,
 | 
				
			||||||
 | 
					  (newChartData) => {
 | 
				
			||||||
 | 
					    if (chartInstance) {
 | 
				
			||||||
 | 
					      chartInstance.setOption({
 | 
				
			||||||
 | 
					        series: [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            data: newChartData.series,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  { deep: true }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onUnmounted(() => {
 | 
				
			||||||
 | 
					  if (chartInstance) {
 | 
				
			||||||
 | 
					    chartInstance.dispose();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div ref="chartContainer" style="width: 100%; height: 250px"></div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
@ -5,12 +5,13 @@
 | 
				
			|||||||
    mode="horizontal"
 | 
					    mode="horizontal"
 | 
				
			||||||
    @select="handleSelect"
 | 
					    @select="handleSelect"
 | 
				
			||||||
  >
 | 
					  >
 | 
				
			||||||
    <el-menu-item index="chart">能源圖表 </el-menu-item>
 | 
					    <el-menu-item index="chart">能源圖表</el-menu-item>
 | 
				
			||||||
    <el-sub-menu index="elecPricing">
 | 
					    <el-sub-menu index="elecPricing">
 | 
				
			||||||
      <template #title>電價表</template>
 | 
					      <template #title>電價表</template>
 | 
				
			||||||
      <el-menu-item index="elecPricingSimple">住宅型</el-menu-item>
 | 
					      <el-menu-item index="elecPricingSimple">住宅型</el-menu-item>
 | 
				
			||||||
      <el-menu-item index="elecPricingStandard">標準型</el-menu-item>
 | 
					      <el-menu-item index="elecPricingStandard">標準型</el-menu-item>
 | 
				
			||||||
    </el-sub-menu>
 | 
					    </el-sub-menu>
 | 
				
			||||||
 | 
					    <el-menu-item index="monthlyReport">能源報表</el-menu-item>
 | 
				
			||||||
  </el-menu>
 | 
					  </el-menu>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -36,6 +37,10 @@ const handleSelect = (key: string, keyPath: string[]) => {
 | 
				
			|||||||
      router.push({ name: "ElecPricingStandard" });
 | 
					      router.push({ name: "ElecPricingStandard" });
 | 
				
			||||||
      activeIndex.value = "elecPricingStandard";
 | 
					      activeIndex.value = "elecPricingStandard";
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					    case "monthlyReport":
 | 
				
			||||||
 | 
					      router.push({ name: "monthlyReport" });
 | 
				
			||||||
 | 
					      activeIndex.value = "monthlyReport";
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										221
									
								
								src/components/PdfContent.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								src/components/PdfContent.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,221 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <el-row :gutter="20">
 | 
				
			||||||
 | 
					    <el-col :span="12">
 | 
				
			||||||
 | 
					      <el-descriptions class="margin-top" title="報表資訊" :column="1" border>
 | 
				
			||||||
 | 
					        <el-descriptions-item>
 | 
				
			||||||
 | 
					          <template #label>
 | 
				
			||||||
 | 
					            <div class="cell-item">報表名稱</div>
 | 
				
			||||||
 | 
					          </template>
 | 
				
			||||||
 | 
					          智慧大樓電表月報表
 | 
				
			||||||
 | 
					        </el-descriptions-item>
 | 
				
			||||||
 | 
					        <el-descriptions-item>
 | 
				
			||||||
 | 
					          <template #label>
 | 
				
			||||||
 | 
					            <div class="cell-item">報表期間</div>
 | 
				
			||||||
 | 
					          </template>
 | 
				
			||||||
 | 
					          2025/02/01 ~ 2025/02/29
 | 
				
			||||||
 | 
					        </el-descriptions-item>
 | 
				
			||||||
 | 
					        <el-descriptions-item>
 | 
				
			||||||
 | 
					          <template #label>
 | 
				
			||||||
 | 
					            <div class="cell-item">編製日期</div>
 | 
				
			||||||
 | 
					          </template>
 | 
				
			||||||
 | 
					          2025/3/1
 | 
				
			||||||
 | 
					        </el-descriptions-item>
 | 
				
			||||||
 | 
					        <el-descriptions-item>
 | 
				
			||||||
 | 
					          <template #label>
 | 
				
			||||||
 | 
					            <div class="cell-item">編製人員</div>
 | 
				
			||||||
 | 
					          </template>
 | 
				
			||||||
 | 
					          能源管理部
 | 
				
			||||||
 | 
					        </el-descriptions-item>
 | 
				
			||||||
 | 
					      </el-descriptions>
 | 
				
			||||||
 | 
					    </el-col>
 | 
				
			||||||
 | 
					    <el-col :span="12">
 | 
				
			||||||
 | 
					      <el-descriptions
 | 
				
			||||||
 | 
					        class="margin-top"
 | 
				
			||||||
 | 
					        title="單價(NTD/kWh)"
 | 
				
			||||||
 | 
					        :column="1"
 | 
				
			||||||
 | 
					        border
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <el-descriptions-item>
 | 
				
			||||||
 | 
					          <template #label>
 | 
				
			||||||
 | 
					            <div class="cell-item">尖峰單價</div>
 | 
				
			||||||
 | 
					          </template>
 | 
				
			||||||
 | 
					          6
 | 
				
			||||||
 | 
					        </el-descriptions-item>
 | 
				
			||||||
 | 
					        <el-descriptions-item>
 | 
				
			||||||
 | 
					          <template #label>
 | 
				
			||||||
 | 
					            <div class="cell-item">半尖峰單價</div>
 | 
				
			||||||
 | 
					          </template>
 | 
				
			||||||
 | 
					          4
 | 
				
			||||||
 | 
					        </el-descriptions-item>
 | 
				
			||||||
 | 
					        <el-descriptions-item>
 | 
				
			||||||
 | 
					          <template #label>
 | 
				
			||||||
 | 
					            <div class="cell-item">離峰單價</div>
 | 
				
			||||||
 | 
					          </template>
 | 
				
			||||||
 | 
					          2
 | 
				
			||||||
 | 
					        </el-descriptions-item>
 | 
				
			||||||
 | 
					      </el-descriptions>
 | 
				
			||||||
 | 
					    </el-col>
 | 
				
			||||||
 | 
					  </el-row>
 | 
				
			||||||
 | 
					  <el-row :gutter="20">
 | 
				
			||||||
 | 
					    <el-col :span="24">
 | 
				
			||||||
 | 
					      <table>
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					          <tr>
 | 
				
			||||||
 | 
					            <th colspan="2" class="bg-info">基本資料</th>
 | 
				
			||||||
 | 
					            <th colspan="3" class="bg-orange">前期比較</th>
 | 
				
			||||||
 | 
					            <th colspan="4" class="bg-green">用電量(kWh)</th>
 | 
				
			||||||
 | 
					            <th colspan="4" class="bg-yellow">費用(NTD)</th>
 | 
				
			||||||
 | 
					          </tr>
 | 
				
			||||||
 | 
					          <tr>
 | 
				
			||||||
 | 
					            <th class="bg-info">電表編號</th>
 | 
				
			||||||
 | 
					            <th class="bg-info">區域/用途</th>
 | 
				
			||||||
 | 
					            <th class="bg-orange">上月用電量(kWh)</th>
 | 
				
			||||||
 | 
					            <th class="bg-orange">用電變化量(kWh)</th>
 | 
				
			||||||
 | 
					            <th class="bg-orange">用電變化率(%)</th>
 | 
				
			||||||
 | 
					            <th class="bg-green">總用電量</th>
 | 
				
			||||||
 | 
					            <th class="bg-green">尖峰用電</th>
 | 
				
			||||||
 | 
					            <th class="bg-green">半尖峰用電</th>
 | 
				
			||||||
 | 
					            <th class="bg-green">離峰用電</th>
 | 
				
			||||||
 | 
					            <th class="bg-yellow">尖峰費用</th>
 | 
				
			||||||
 | 
					            <th class="bg-yellow">半尖峰費用</th>
 | 
				
			||||||
 | 
					            <th class="bg-yellow">離峰費用</th>
 | 
				
			||||||
 | 
					            <th class="bg-yellow">總費用</th>
 | 
				
			||||||
 | 
					          </tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody>
 | 
				
			||||||
 | 
					          <tr>
 | 
				
			||||||
 | 
					            <td>電表01</td>
 | 
				
			||||||
 | 
					            <td>辦公室南區</td>
 | 
				
			||||||
 | 
					            <td>549</td>
 | 
				
			||||||
 | 
					            <td>51</td>
 | 
				
			||||||
 | 
					            <td>9.29</td>
 | 
				
			||||||
 | 
					            <td>600</td>
 | 
				
			||||||
 | 
					            <td>150</td>
 | 
				
			||||||
 | 
					            <td>200</td>
 | 
				
			||||||
 | 
					            <td>250</td>
 | 
				
			||||||
 | 
					            <td>900</td>
 | 
				
			||||||
 | 
					            <td>800</td>
 | 
				
			||||||
 | 
					            <td>500</td>
 | 
				
			||||||
 | 
					            <td>2200</td>
 | 
				
			||||||
 | 
					          </tr>
 | 
				
			||||||
 | 
					          <tr>
 | 
				
			||||||
 | 
					            <td>電表02</td>
 | 
				
			||||||
 | 
					            <td>電梯機房</td>
 | 
				
			||||||
 | 
					            <td>969</td>
 | 
				
			||||||
 | 
					            <td>-69</td>
 | 
				
			||||||
 | 
					            <td>-7.12</td>
 | 
				
			||||||
 | 
					            <td>900</td>
 | 
				
			||||||
 | 
					            <td>300</td>
 | 
				
			||||||
 | 
					            <td>300</td>
 | 
				
			||||||
 | 
					            <td>300</td>
 | 
				
			||||||
 | 
					            <td>1800</td>
 | 
				
			||||||
 | 
					            <td>1200</td>
 | 
				
			||||||
 | 
					            <td>600</td>
 | 
				
			||||||
 | 
					            <td>3600</td>
 | 
				
			||||||
 | 
					          </tr>
 | 
				
			||||||
 | 
					          <tr>
 | 
				
			||||||
 | 
					            <td>電表03</td>
 | 
				
			||||||
 | 
					            <td>會議室</td>
 | 
				
			||||||
 | 
					            <td>489</td>
 | 
				
			||||||
 | 
					            <td>-39</td>
 | 
				
			||||||
 | 
					            <td>-7.98</td>
 | 
				
			||||||
 | 
					            <td>450</td>
 | 
				
			||||||
 | 
					            <td>100</td>
 | 
				
			||||||
 | 
					            <td>150</td>
 | 
				
			||||||
 | 
					            <td>200</td>
 | 
				
			||||||
 | 
					            <td>600</td>
 | 
				
			||||||
 | 
					            <td>600</td>
 | 
				
			||||||
 | 
					            <td>400</td>
 | 
				
			||||||
 | 
					            <td>1600</td>
 | 
				
			||||||
 | 
					          </tr>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					      </table>
 | 
				
			||||||
 | 
					    </el-col>
 | 
				
			||||||
 | 
					  </el-row>
 | 
				
			||||||
 | 
					  <el-row :gutter="20">
 | 
				
			||||||
 | 
					    <el-col :span="12">
 | 
				
			||||||
 | 
					      <el-card style="border-radius: 8px; height: 100%">
 | 
				
			||||||
 | 
					        <h3 class="">各電表總費用佔比</h3>
 | 
				
			||||||
 | 
					        <EnergyPie />
 | 
				
			||||||
 | 
					      </el-card>
 | 
				
			||||||
 | 
					    </el-col>
 | 
				
			||||||
 | 
					    <el-col :span="12">
 | 
				
			||||||
 | 
					      <el-card style="border-radius: 8px; height: 100%">
 | 
				
			||||||
 | 
					        <h3 class="">各電表用電量比較(kWh)</h3>
 | 
				
			||||||
 | 
					        <EnergyBar :chartData="elecUsageData" />
 | 
				
			||||||
 | 
					      </el-card>
 | 
				
			||||||
 | 
					    </el-col>
 | 
				
			||||||
 | 
					  </el-row>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { ref } from "vue";
 | 
				
			||||||
 | 
					import EnergyPie from "../components/EnergyPie.vue";
 | 
				
			||||||
 | 
					import EnergyBar from "../components/EnergyBar.vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const elecUsageData = ref({
 | 
				
			||||||
 | 
					  categories: ["電表01", "電表02", "電表03"],
 | 
				
			||||||
 | 
					  series: [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: "尖峰用電",
 | 
				
			||||||
 | 
					      type: "bar",
 | 
				
			||||||
 | 
					      data: [150, 300, 100],
 | 
				
			||||||
 | 
					      itemStyle: { color: "#5470c6" },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: "半尖峰用電",
 | 
				
			||||||
 | 
					      type: "bar",
 | 
				
			||||||
 | 
					      data: [200, 300, 150],
 | 
				
			||||||
 | 
					      itemStyle: { color: "#91cc75" },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: "離峰用電",
 | 
				
			||||||
 | 
					      type: "bar",
 | 
				
			||||||
 | 
					      data: [250, 300, 200],
 | 
				
			||||||
 | 
					      itemStyle: { color: "#fac858" },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped>
 | 
				
			||||||
 | 
					.el-row {
 | 
				
			||||||
 | 
					  padding-top: 20px;
 | 
				
			||||||
 | 
					  padding-right: 20px;
 | 
				
			||||||
 | 
					  padding-left: 20px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					h3 {
 | 
				
			||||||
 | 
					  margin: 0;
 | 
				
			||||||
 | 
					  font-weight: 700;
 | 
				
			||||||
 | 
					  font-size: 15px;
 | 
				
			||||||
 | 
					  color: #141414;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					th,
 | 
				
			||||||
 | 
					td {
 | 
				
			||||||
 | 
					  border: 1px solid #ebeef5;
 | 
				
			||||||
 | 
					  text-align: center;
 | 
				
			||||||
 | 
					  padding: 8px 11px;
 | 
				
			||||||
 | 
					  background: #fff;
 | 
				
			||||||
 | 
					  color: #303133;
 | 
				
			||||||
 | 
					  font-size: 12px;
 | 
				
			||||||
 | 
					  text-wrap: nowrap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.bg-info {
 | 
				
			||||||
 | 
					  background: #add8e6;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.bg-orange {
 | 
				
			||||||
 | 
					  background: #ffdab9;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.bg-green {
 | 
				
			||||||
 | 
					  background: #90ee90;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.bg-yellow {
 | 
				
			||||||
 | 
					  background: #ffd700;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@ -22,6 +22,11 @@ const routes: Array<RouteRecordRaw> = [
 | 
				
			|||||||
        name: "ElecPricingStandard",
 | 
					        name: "ElecPricingStandard",
 | 
				
			||||||
        component: () => import("../views/ElecPriceStd.vue"),
 | 
					        component: () => import("../views/ElecPriceStd.vue"),
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        path: "monthlyReport",
 | 
				
			||||||
 | 
					        name: "monthlyReport",
 | 
				
			||||||
 | 
					        component: () => import("../views/MonthlyReport.vue"),
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ import type { NiagaraElecDemandData } from "../utils/types";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const useElecDemandStore = defineStore("elecDemand", () => {
 | 
					const useElecDemandStore = defineStore("elecDemand", () => {
 | 
				
			||||||
  const elecData = ref<NiagaraElecDemandData[]>([]);
 | 
					  const elecData = ref<NiagaraElecDemandData[]>([]);
 | 
				
			||||||
  const subscribers = ref<any[]>([]); 
 | 
					  const subscribers = ref<any[]>([]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // get data from baja
 | 
					  // get data from baja
 | 
				
			||||||
  const getElecDemandFromBaja = () => {
 | 
					  const getElecDemandFromBaja = () => {
 | 
				
			||||||
@ -59,8 +59,8 @@ const useElecDemandStore = defineStore("elecDemand", () => {
 | 
				
			|||||||
          try {
 | 
					          try {
 | 
				
			||||||
            if (prop && prop.getName() === "out") {
 | 
					            if (prop && prop.getName() === "out") {
 | 
				
			||||||
              // 取得 out 的新值
 | 
					              // 取得 out 的新值
 | 
				
			||||||
              const match = prop.$display.match(/^(\d+(\.\d+)?)/); 
 | 
					              const match = prop.$display.match(/^(\d+(\.\d+)?)/);
 | 
				
			||||||
              const newValue = match ? parseFloat(match[0]) : 0; 
 | 
					              const newValue = match ? parseFloat(match[0]) : 0;
 | 
				
			||||||
              // 更新 elecData 中對應的 out 值
 | 
					              // 更新 elecData 中對應的 out 值
 | 
				
			||||||
              const updatedIndex = elecData.value.findIndex(
 | 
					              const updatedIndex = elecData.value.findIndex(
 | 
				
			||||||
                (data) => data.slotPath === item.slotPath
 | 
					                (data) => data.slotPath === item.slotPath
 | 
				
			||||||
@ -72,11 +72,8 @@ const useElecDemandStore = defineStore("elecDemand", () => {
 | 
				
			|||||||
                  ...newElecData[updatedIndex],
 | 
					                  ...newElecData[updatedIndex],
 | 
				
			||||||
                  out: Number(newValue),
 | 
					                  out: Number(newValue),
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
                elecData.value = newElecData; 
 | 
					                elecData.value = newElecData;
 | 
				
			||||||
                console.log(
 | 
					                console.log(`Niagara 用電需求 ${item.name} 更新:`, newValue);
 | 
				
			||||||
                  `Niagara 用電需求 ${item.name} 更新:`,
 | 
					 | 
				
			||||||
                  newValue
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          } catch (error: any) {
 | 
					          } catch (error: any) {
 | 
				
			||||||
@ -109,7 +106,35 @@ const useElecDemandStore = defineStore("elecDemand", () => {
 | 
				
			|||||||
    console.log("所有訂閱已清除");
 | 
					    console.log("所有訂閱已清除");
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return { getElecDemandFromBaja, elecData, clearAllSubscriber };
 | 
					  // 測試
 | 
				
			||||||
 | 
					  const getElecDatatTestBaja = () => {
 | 
				
			||||||
 | 
					    // @ts-ignore
 | 
				
			||||||
 | 
					    window.require &&
 | 
				
			||||||
 | 
					      // @ts-ignore
 | 
				
			||||||
 | 
					      window.requirejs(["baja!"], (baja: any) => {
 | 
				
			||||||
 | 
					        console.log("進入 bajaSubscriber 準備執行 BQL 訂閱");
 | 
				
			||||||
 | 
					        baja.Ord.make(
 | 
				
			||||||
 | 
					          `local:|foxs:4918|history:/testStation_MJM/MGCB_KWH?period=timerange;start=2025-04-20T00:00:00.000+08:00;end=2025-04-21T00:00:00.000+08:00|bql:history:HistoryRollup.rollup(baja:RelTime '3600000')`
 | 
				
			||||||
 | 
					        ).get({
 | 
				
			||||||
 | 
					          cursor: {
 | 
				
			||||||
 | 
					            before: () => {},
 | 
				
			||||||
 | 
					            each: (record: any) => {
 | 
				
			||||||
 | 
					              console.log("recordtest", record);
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            after: () => {},
 | 
				
			||||||
 | 
					            limit: -1,
 | 
				
			||||||
 | 
					            offset: 0,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    getElecDemandFromBaja,
 | 
				
			||||||
 | 
					    elecData,
 | 
				
			||||||
 | 
					    clearAllSubscriber,
 | 
				
			||||||
 | 
					    getElecDatatTestBaja,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default useElecDemandStore;
 | 
					export default useElecDemandStore;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										56
									
								
								src/views/MonthlyReport.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/views/MonthlyReport.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <el-row :gutter="20">
 | 
				
			||||||
 | 
					    <el-col :span="24">
 | 
				
			||||||
 | 
					      <div style="display: flex; justify-content: flex-end">
 | 
				
			||||||
 | 
					        <el-button type="primary" :icon="Printer" @click="generatePDF"
 | 
				
			||||||
 | 
					          >列印報表</el-button
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </el-col>
 | 
				
			||||||
 | 
					  </el-row>
 | 
				
			||||||
 | 
					   <!-- 顯示在畫面上的內容 -->
 | 
				
			||||||
 | 
					  <PdfContent />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   <!-- 給 vue3-html2pdf 用的內容 -->
 | 
				
			||||||
 | 
					  <vue3-html2pdf
 | 
				
			||||||
 | 
					    ref="html2Pdf"
 | 
				
			||||||
 | 
					    :show-layout="false"
 | 
				
			||||||
 | 
					    :float-layout="true"
 | 
				
			||||||
 | 
					    :enable-download="true"
 | 
				
			||||||
 | 
					    :preview-modal="true"
 | 
				
			||||||
 | 
					    :filename="pdfFileName"
 | 
				
			||||||
 | 
					    :pdf-quality="2"
 | 
				
			||||||
 | 
					    :manual-pagination="false"
 | 
				
			||||||
 | 
					    :paginate-elements-by-height="1000"
 | 
				
			||||||
 | 
					    pdf-format="a4"
 | 
				
			||||||
 | 
					    pdf-orientation="landscape"
 | 
				
			||||||
 | 
					    pdf-content-width="1120px"
 | 
				
			||||||
 | 
					  >
 | 
				
			||||||
 | 
					    <template #pdf-content>
 | 
				
			||||||
 | 
					       <PdfContent />
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					  </vue3-html2pdf>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { ref } from "vue";
 | 
				
			||||||
 | 
					import PdfContent from "../components/PdfContent.vue";
 | 
				
			||||||
 | 
					import { Printer } from "@element-plus/icons-vue";
 | 
				
			||||||
 | 
					import Vue3Html2pdf from "vue3-html2pdf";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PDF 文件名稱
 | 
				
			||||||
 | 
					const pdfFileName = ref("智慧大樓電表月報表");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 引用 vue-html2pdf 實例
 | 
				
			||||||
 | 
					const html2Pdf = ref<InstanceType<typeof Vue3Html2pdf> | null>(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 觸發 PDF 生成和下載
 | 
				
			||||||
 | 
					const generatePDF = async () => {
 | 
				
			||||||
 | 
					  if (html2Pdf.value) {
 | 
				
			||||||
 | 
					    await html2Pdf.value.generatePdf();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped>
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
							
								
								
									
										6
									
								
								src/vite-env.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								src/vite-env.d.ts
									
									
									
									
										vendored
									
									
								
							@ -8,6 +8,12 @@ declare module "*.vue" {
 | 
				
			|||||||
  export default component;
 | 
					  export default component;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare module "vue3-html2pdf" {
 | 
				
			||||||
 | 
					  import { DefineComponent } from "vue";
 | 
				
			||||||
 | 
					  const component: DefineComponent<{}, {}, any>;
 | 
				
			||||||
 | 
					  export default component;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 聲明環境變數 ( .env 檔案)
 | 
					// 聲明環境變數 ( .env 檔案)
 | 
				
			||||||
interface ImportMetaEnv {
 | 
					interface ImportMetaEnv {
 | 
				
			||||||
  readonly VITE_APP_TITLE: string; 
 | 
					  readonly VITE_APP_TITLE: string; 
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user