調整報表管理頁面,新增各單位用電(月)比較

This commit is contained in:
koko 2025-08-27 15:11:56 +08:00
parent 2a1b35b2ed
commit 134714cad2

View File

@ -7,17 +7,21 @@
<div class="col-sm-12 col-xl-2">
<div class="rounded border border-white">
<!-- nav-menu-reset will reset the font colors -->
<ul class="nav-menu nav-menu-reset nav-menu-compact mb-sm-4 mb-md-0 rounded border border-white"
data-nav-accordion="true">
<ul
class="nav-menu nav-menu-reset nav-menu-compact mb-sm-4 mb-md-0 rounded border border-white"
data-nav-accordion="true"
>
<li class="active">
<a name="reportTypeRadio" href="javascript:;" data-value="day">
<span class="nav-link-text"> 電錶 - 日報表 </span>
</a>
</li>
<li>
<a name="reportTypeRadio"
href="javascript:;"
data-value="month">
<a
name="reportTypeRadio"
href="javascript:;"
data-value="month"
>
<span class="nav-link-text"> 電錶 - 月報表 </span>
</a>
</li>
@ -27,24 +31,40 @@
</a>
</li>
<li>
<a name="reportTypeRadio"
href="javascript:;"
data-value="compare">
<a
name="reportTypeRadio"
href="javascript:;"
data-value="compare"
>
<span class="nav-link-text"> 電錶 - 同期比較 </span>
</a>
</li>
<li>
<a name="reportTypeRadio"
href="javascript:;"
data-value="day"
data-type="compare">
<a
name="reportTypeRadio"
href="javascript:;"
data-value="day"
data-type="compare"
>
<span class="nav-link-text">
電錶 - 總盤與分盤 - 月份比較
</span>
</a>
</li>
<li>
<a
name="reportTypeRadio"
href="javascript:;"
data-value="elec"
data-type="elec"
>
<span class="nav-link-text"> 電錶 - 各單位用電(月)比較 </span>
</a>
</li>
</ul>
<div class="filter-message js-filter-message m-0 text-left pl-4 py-3 fw-500"></div>
<div
class="filter-message js-filter-message m-0 text-left pl-4 py-3 fw-500"
></div>
</div>
</div>
<div class="col-12 col-xl-10">
@ -53,94 +73,138 @@
<div class="col-auto price">
<span class="report-type-name"></span>費每度單價
</div>
<input type="text"
id="elecPriceDegree"
class="form-control col-1 price" />
<div id="compareTypeBtnsDiv"
class="item btn-group btn-group-toggle offset-1"
data-toggle="buttons"
style="display: none">
<label class="btn btn-outline-success waves-effect active waves-themed">
<input type="radio"
name="compareTypeRadio"
id="compareMonth"
value="month"
checked />
<input
type="text"
id="elecPriceDegree"
class="form-control col-1 price"
/>
<div
id="compareTypeBtnsDiv"
class="item btn-group btn-group-toggle offset-1"
data-toggle="buttons"
style="display: none"
>
<label
class="btn btn-outline-success waves-effect active waves-themed"
>
<input
type="radio"
name="compareTypeRadio"
id="compareMonth"
value="month"
checked
/>
年度同月比較
</label>
<label class="btn btn-outline-success waves-effect waves-themed">
<input type="radio"
name="compareTypeRadio"
id="compareDay"
value="day" />
<label
class="btn btn-outline-success waves-effect waves-themed"
>
<input
type="radio"
name="compareTypeRadio"
id="compareDay"
value="day"
/>
月份同日比較
</label>
</div>
<div id="compareAreaBtnsDiv"
class="item btn-group btn-group-toggle"
data-toggle="buttons"
style="display: none">
<label class="btn btn-outline-success waves-effect active waves-themed">
<input type="radio"
name="compareEleRadio"
id="compareAll"
value="0"
checked />
<div
id="compareAreaBtnsDiv"
class="item btn-group btn-group-toggle"
data-toggle="buttons"
style="display: none"
>
<label
class="btn btn-outline-success waves-effect active waves-themed"
>
<input
type="radio"
name="compareEleRadio"
id="compareAll"
value="0"
checked
/>
總計含分盤資料
</label>
<label class="btn btn-outline-success waves-effect waves-themed">
<input type="radio"
name="compareEleRadio"
id="compareSeperate"
value="1" />
<label
class="btn btn-outline-success waves-effect waves-themed"
>
<input
type="radio"
name="compareEleRadio"
id="compareSeperate"
value="1"
/>
總計不含分盤資料
</label>
</div>
<div class="col-auto offset-1">
<div class="col-auto">
選擇<span id="elecTimeText">單一月份</span>
</div>
<input type="text"
id="elecMonthDate"
class="form-control col-2" />
<input type="text"
id="elecYearDate"
class="form-control col-2"
style="display: none" />
<div id="elecStartEndDiv"
class="row m-0 align-items-center"
style="display: none">
<input type="text"
id="elecSYearDate"
class="form-control col-4" />
<input
type="text"
id="elecMonthDate"
class="form-control col-2"
/>
<input
type="text"
id="elecYearDate"
class="form-control col-2"
style="display: none"
/>
<div
id="elecStartEndDiv"
class="row m-0 align-items-center"
style="display: none"
>
<input
type="text"
id="elecSYearDate"
class="form-control col-4"
/>
<span class="px-2">~</span>
<input type="text"
id="elecEYearDate"
class="form-control col-4" />
<input
type="text"
id="elecEYearDate"
class="form-control col-4"
/>
</div>
<div id="elecCompareDiv"
class="row m-0 align-items-center"
style="display: none">
<div
id="elecCompareDiv"
class="row m-0 align-items-center"
style="display: none"
>
<div id="elecComYearDiv" class="row m-0 align-items-center">
<input type="text"
id="elecCom1YearDate"
class="form-control col-4" />
<input
type="text"
id="elecCom1YearDate"
class="form-control col-4"
/>
<span class="px-2"></span>
<input type="text"
id="elecCom2YearDate"
class="form-control col-4" />
<input
type="text"
id="elecCom2YearDate"
class="form-control col-4"
/>
</div>
<div id="elecComMonthDiv"
class="row m-0 align-items-center"
style="display: none">
<input type="text"
id="elecCom1MonthDate"
class="form-control col-4" />
<div
id="elecComMonthDiv"
class="row m-0 align-items-center"
style="display: none"
>
<input
type="text"
id="elecCom1MonthDate"
class="form-control col-4"
/>
<span class="px-2"></span>
<input type="text"
id="elecCom2MonthDate"
class="form-control col-4" />
<input
type="text"
id="elecCom2MonthDate"
class="form-control col-4"
/>
</div>
</div>
</h2>
@ -148,15 +212,19 @@
<div class="panel-hdr" style="min-height: auto">
<h2 class="py-2 col-12" id="school_zone">
<div class="col-1">校區</div>
<div class="item btn-group btn-group-toggle"
data-toggle="buttons"></div>
<div
class="item btn-group btn-group-toggle"
data-toggle="buttons"
></div>
</h2>
</div>
<div class="panel-hdr" style="min-height: auto">
<h2 class="py-2 col-12" id="building">
<div class="col-1">棟別</div>
<div class="item btn-group btn-group-toggle"
data-toggle="buttons"></div>
<div
class="item btn-group btn-group-toggle"
data-toggle="buttons"
></div>
</h2>
</div>
<div class="panel-hdr" style="min-height: auto">
@ -186,22 +254,44 @@
</h2> -->
</div>
<div class="d-flex my-2">
<button type="button"
class="btn btn-primary"
onclick="getMeterData()">
<button
type="button"
class="btn btn-primary"
onclick="getMeterData()"
>
查詢
</button>
<button type="button"
class="btn btn-danger ml-2"
onclick="setExportList()">
<button
type="button"
class="btn btn-danger mx-2"
onclick="setExportList()"
>
匯出
</button>
<div id="tableLoading"
class="row m-0 align-items-center"
style="display: none">
<div class="spinner-border text-info mx-2"
role="status"
style="width: 1.2rem; height: 1.2rem">
<div id="ArchiveBtnDiv" style="display: none">
<button
type="button"
class="btn btn-info"
id="recalculateBtn"
onclick="recalculateArchive()"
>
重新計算
</button>
<span class="h6 text-light pl-2" id="lastUpdateTime"
>最後更新時間 :
</span>
</div>
<div
id="tableLoading"
class="row m-0 align-items-center"
style="display: none"
>
<div
class="spinner-border text-info mx-2"
role="status"
style="width: 1.2rem; height: 1.2rem"
>
<span class="sr-only">Loading...</span>
</div>
<span id="tableLoadingText">列表讀取中</span>
@ -211,8 +301,10 @@
<button type="button" class="btn btn-info allbtn ml-2" onclick="LookRealTime()">查看即時資訊</button> -->
</div>
<span class="d-flex justify-content-end">單位kWh </span>
<table id="report_table"
class="table table-bordered table-striped text-center m-0 w-100"></table>
<table
id="report_table"
class="table table-bordered table-striped text-center m-0 w-100"
></table>
</div>
</div>
</div>
@ -248,6 +340,7 @@
year: "ExportElectricList",
compare: "ExportElectricCompareList",
compareForEachTotal: "ExportElectricEachTotalCompareList",
depCampareExcel: "ElecData/ExportDepCampareExcel",
},
},
};
@ -456,6 +549,7 @@
).hide();
$("#compareTypeBtnsDiv").hide();
$("#compareAreaBtnsDiv").hide();
$("#ArchiveBtnDiv").hide();
const value = $(this).data("value");
const type = $(this).data("type");
@ -472,6 +566,13 @@
$("#school_zone").hide();
$("#building").hide();
$(".price").hide();
} else if (type === "elec") {
$("#elecTimeText").text("月份");
$("#elecMonthDate").show();
$("#ArchiveBtnDiv").show();
$("#school_zone").hide();
$("#building").hide();
$(".price").hide();
} else if (value === "day") {
$("#elecTimeText").text("月份");
$("#elecMonthDate").show();
@ -572,20 +673,20 @@
tableType == "day"
? $("#elecMonthDate").val()
: tableType == "month"
? $("#elecYearDate").val()
: tableType == "year"
? $("#elecSYearDate").val()
: tableType == "compare"
? compareType == "month"
? !$("#elecCom1YearDate").val() || !$("#elecCom2YearDate").val()
? null
: [$("#elecCom1YearDate").val(), $("#elecCom2YearDate").val()]
: compareType == "day"
? !$("#elecCom1MonthDate").val() || !$("#elecCom2MonthDate").val()
? null
: [$("#elecCom1MonthDate").val(), $("#elecCom2MonthDate").val()]
: null
: null;
? $("#elecYearDate").val()
: tableType == "year"
? $("#elecSYearDate").val()
: tableType == "compare" || tableType == "elec"
? compareType == "month"
? !$("#elecCom1YearDate").val() || !$("#elecCom2YearDate").val()
? null
: [$("#elecCom1YearDate").val(), $("#elecCom2YearDate").val()]
: compareType == "day"
? !$("#elecCom1MonthDate").val() || !$("#elecCom2MonthDate").val()
? null
: [$("#elecCom1MonthDate").val(), $("#elecCom2MonthDate").val()]
: null
: null;
if (!startTime) {
toast_error("請選擇日期");
@ -605,33 +706,33 @@
let sent_data = Mode
? {
tableType: "month",
building_tag: "",
floor_tag: $("[name=floorCheckbox]:checked")
.map((i, e) => $(e).val())
.toArray(),
startTime: startTime,
endTime: endTime,
price: $("#elecPriceDegree").val()
? parseFloat($("#elecPriceDegree").val())
: null,
Mode: parseInt(Mode),
}
tableType: "month",
building_tag: "",
floor_tag: $("[name=floorCheckbox]:checked")
.map((i, e) => $(e).val())
.toArray(),
startTime: startTime,
endTime: endTime,
price: $("#elecPriceDegree").val()
? parseFloat($("#elecPriceDegree").val())
: null,
Mode: parseInt(Mode),
}
: {
tableType:
$("li.active [name=reportTypeRadio]").data("value") == "compare"
? $("[name=compareTypeRadio]:checked").val()
: $("li.active [name=reportTypeRadio]").data("value"),
building_tag: SelectBuildings.join(","),
floor_tag: $("[name=floorCheckbox]:checked")
.map((i, e) => $(e).val())
.toArray(),
startTime: startTime,
endTime: endTime,
price: $("#elecPriceDegree").val()
? parseFloat($("#elecPriceDegree").val())
: null,
};
tableType:
$("li.active [name=reportTypeRadio]").data("value") == "compare"
? $("[name=compareTypeRadio]:checked").val()
: $("li.active [name=reportTypeRadio]").data("value"),
building_tag: SelectBuildings.join(","),
floor_tag: $("[name=floorCheckbox]:checked")
.map((i, e) => $(e).val())
.toArray(),
startTime: startTime,
endTime: endTime,
price: $("#elecPriceDegree").val()
? parseFloat($("#elecPriceDegree").val())
: null,
};
if (Array.isArray(startTime)) {
sent_data = [Object.assign({}, sent_data), Object.assign({}, sent_data)];
@ -663,80 +764,104 @@
toast_error("請選擇樓層");
return;
}
var url =
baseApiUrl +
"/api/" +
`${sent_data[0]?.Mode?.toString()
? reportTypeDict["RElec"]["listApiUrlForTotal"]
: reportTypeDict["RElec"]["listApiUrl"]
}`;
var url;
var isElecType =
$("li.active [name=reportTypeRadio]").data("type") === "elec";
setLoading(true);
sent_data.forEach((sdata, i) => {
if (isElecType) {
// 取得月份
var date = $("#elecMonthDate").val();
url = baseApiUrl + "/ElecData/GetMonthElecCompData?Date=" + date;
$.ajax({
type: "POST",
type: "GET",
headers: {
Authorization: "Bearer " + token,
},
url: url,
async: false,
data: JSON.stringify(sdata),
contentType: "application/json; charset=utf-8",
success: function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
} else {
toast_warning(rel.msg);
}
return;
}
if (i == 0) {
result = result.concat(rel.data);
result.forEach((r) => {
r._compare_price = null;
r._compare_total = null;
r._compare_total_price = null;
});
} else {
rel.data.forEach((r) => {
let target =
result.find(
(d) =>
d.building_tag == r.building_tag &&
d.device_serial_tag == r.device_serial_tag &&
d.device_master == r.device_master &&
d.floor_tag == r.floor_tag
) ?? null;
let _target = {};
// if(!target){
// result.push(target);
// target = {};
// }
_target.rawData = (target?.rawData ?? []).concat(r.rawData);
_target._compare_price = r.price;
_target._compare_total = r.total;
_target._compare_total_price = r.total_price;
if (!target) {
_target = Object.assign(_target, r);
_target.price = null;
_target.total = null;
_target.total_price = null;
result.push(_target);
return;
}
target = Object.assign(target, _target);
});
}
result = rel.data;
},
complete: () => {
if (sent_data.length - 1 == i) {
setLoading(false);
}
setLoading(false);
},
});
});
} else {
url =
baseApiUrl +
"/api/" +
`${
sent_data[0]?.Mode?.toString()
? reportTypeDict["RElec"]["listApiUrlForTotal"]
: reportTypeDict["RElec"]["listApiUrl"]
}`;
sent_data.forEach((sdata, i) => {
$.ajax({
type: "POST",
headers: {
Authorization: "Bearer " + token,
},
url: url,
async: false,
data: JSON.stringify(sdata),
contentType: "application/json; charset=utf-8",
success: function (rel) {
if (rel.code != "0000") {
if (rel.code == "9999") {
toast_error(rel.msg);
} else {
toast_warning(rel.msg);
}
return;
}
if (i == 0) {
result = result.concat(rel.data);
result.forEach((r) => {
r._compare_price = null;
r._compare_total = null;
r._compare_total_price = null;
});
} else {
rel.data.forEach((r) => {
let target =
result.find(
(d) =>
d.building_tag == r.building_tag &&
d.device_serial_tag == r.device_serial_tag &&
d.device_master == r.device_master &&
d.floor_tag == r.floor_tag
) ?? null;
let _target = {};
// if(!target){
// result.push(target);
// target = {};
// }
_target.rawData = (target?.rawData ?? []).concat(r.rawData);
_target._compare_price = r.price;
_target._compare_total = r.total;
_target._compare_total_price = r.total_price;
if (!target) {
_target = Object.assign(_target, r);
_target.price = null;
_target.total = null;
_target.total_price = null;
result.push(_target);
return;
}
target = Object.assign(target, _target);
});
}
},
complete: () => {
if (sent_data.length - 1 == i) {
setLoading(false);
}
},
});
});
}
setReportTable(result);
}
@ -878,30 +1003,26 @@
$("#report_table").empty();
}
const ElecEachTotal =
$("li.active [name=reportTypeRadio]").data("type") === "compare";
if (ElecEachTotal) {
let preDate = new Date($("#elecMonthDate").val().split("-") + "-01");
preDate.setMonth(preDate.getMonth() - 1);
const [year, month] = $("#elecMonthDate").val().split("-");
const preYear = preDate.getFullYear();
const preMonth = (preDate.getMonth() + 1).toString().padStart(2, '0');
const ElecEachTotal = $("li.active [name=reportTypeRadio]").data("type");
if (ElecEachTotal === "compare") {
let preDate = new Date($("#elecMonthDate").val().split("-") + "-01");
preDate.setMonth(preDate.getMonth() - 1);
const [year, month] = $("#elecMonthDate").val().split("-");
const preYear = preDate.getFullYear();
const preMonth = (preDate.getMonth() + 1).toString().padStart(2, "0");
datesColumns = [
{
label: "選擇月份 <br>" + `${year}${month}` + "(A)",
value: $("#elecMonthDate").val(),
},
{
label:
"前一月份 <br>" +
`${preYear}${preMonth}` +
"(B)",
value: `${preYear}-${preMonth}`,
label: "前一月份 <br>" + `${preYear}${preMonth}` + "(B)",
value: `${preYear}-${preMonth}`,
},
{
label:
"差異比較 <br>" +
`${year}${month}(A)-${preYear}${preMonth}(B)`,
"差異比較 <br>" + `${year}${month}(A)-${preYear}${preMonth}(B)`,
value: "last month different",
},
{
@ -915,19 +1036,63 @@
].map((dc) => {
return { title: dc.label, data: dc.value, width: "120px" };
});
} else if (ElecEachTotal === "elec") {
let preDate = new Date($("#elecMonthDate").val().split("-") + "-01");
preDate.setMonth(preDate.getMonth() - 1);
const [year, month] = $("#elecMonthDate").val().split("-");
const preYear = preDate.getFullYear();
const preMonth = (preDate.getMonth() + 1).toString().padStart(2, "0");
datesColumns = [
{ title: "項次", data: "rowIndex", width: "60px" },
{ title: "單位", data: "dep_name", width: "120px" },
{
title: `選擇月份 <br>${year}${month}(A)`,
data: "now_month_kWh",
width: "120px",
},
{
title: "當月用電度數/(第一校區+第二校區)%",
data: "proportion",
width: "120px",
},
{
title: `前一月份 <br>${preYear}${preMonth}(B)`,
data: "last_month_kWh",
width: "120px",
},
{
title: `差異比較 <br>${year}${month}(A)-${preYear}${preMonth}(B)`,
data: "compare_last_month",
width: "120px",
},
{
title: `去年同期 <br>${year - 1}${month}(C)`,
data: "last_year_same_month",
width: "120px",
},
{
title: `同期差異 <br>${year - 1}${month}(A)-${year}${month}(C)`,
data: "compare_last_year",
width: "120px",
},
];
// 自動加 rowIndex
datas = datas.map((d, idx) => ({ ...d, rowIndex: idx + 1 }));
} else {
datesColumns = setTableColumns();
}
const compareType = $("label.active [name=compareTypeRadio]").val();
datas.forEach((td) => {
td.rawData.forEach((rd) => {
td[rd.timeStamp] = rd.avg_rawdata;
if (ElecEachTotal !== "elec") {
datas.forEach((td) => {
td.rawData.forEach((rd) => {
td[rd.timeStamp] = rd.avg_rawdata;
});
datesColumns.forEach((dc) => {
td[dc.data] = td[dc.data] === undefined ? null : td[dc.data];
});
});
datesColumns.forEach((dc) => {
td[dc.data] = td[dc.data] === undefined ? null : td[dc.data];
});
});
}
let totalColumns = [
{
@ -997,24 +1162,28 @@
language: { url: "/file/BajascriptTest/js/dataTables/zh-HANT.json" },
aaSorting: [],
columns: [
{
title: "棟別",
data: "building_name",
className: "text-nowrap",
width: "100px",
},
{
title: "樓層",
data: "floor_tag",
width: "8%",
className: "text-nowrap",
},
{
title: "設備",
data: "device_full_name",
width: "300px",
className: "text-nowrap",
},
...(ElecEachTotal === "elec"
? []
: [
{
title: "棟別",
data: "building_name",
className: "text-nowrap",
width: "100px",
},
{
title: "樓層",
data: "floor_tag",
width: "8%",
className: "text-nowrap",
},
{
title: "設備",
data: "device_full_name",
width: "300px",
className: "text-nowrap",
},
]),
...datesColumns,
...(ElecEachTotal ? [] : totalColumns),
],
@ -1025,6 +1194,8 @@
const tableType =
$("li.active [name=reportTypeRadio]").data("type") === "compare"
? "compareForEachTotal"
: $("li.active [name=reportTypeRadio]").data("type") === "elec"
? "depCampareExcel"
: $("li.active [name=reportTypeRadio]").data("value");
var sent_data = getListSendData();
if (!Array.isArray(sent_data)) {
@ -1038,10 +1209,15 @@
// toast_error("請選擇樓層");
// return;
// }
var url =
baseApiUrl +
"/api/" +
reportTypeDict["RElec"]["exportListApiUrl"][tableType];
var isElecType =
$("li.active [name=reportTypeRadio]").data("type") === "elec";
var url = isElecType
? baseApiUrl +
"/" +
reportTypeDict["RElec"]["exportListApiUrl"][tableType]
: baseApiUrl +
"/api/" +
reportTypeDict["RElec"]["exportListApiUrl"][tableType];
setLoading(true, "匯出中");
$.ajax({
@ -1069,6 +1245,39 @@
});
}
function recalculateArchive() {
var url = baseApiUrl + "/ElecData/ArchiveDepCampare";
$("#recalculateBtn").prop("disabled", true);
setLoading(true, "重新計算中");
$.ajax({
type: "POST",
headers: {
Authorization: "Bearer " + token,
},
url: url,
async: true,
contentType: "application/json; charset=utf-8",
success: function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
} else {
var now = moment(rel.data[0].execute_time).format(
"YYYY-MM-DD HH:mm:ss"
);
$("#lastUpdateTime").html("最後更新時間 : " + now);
toast_ok("重新計算完成");
}
},
error: function () {
toast_error("重新計算失敗");
},
complete: function () {
setLoading(false);
$("#recalculateBtn").prop("disabled", false);
},
});
}
function setLoading(type = true, text = "列表讀取中") {
if (type) {
$("#tableLoading").fadeIn(200);
@ -1196,8 +1405,9 @@
rel.data.forEach(({ system_key, system_value }) => {
htmlStr += `
<label
class="btn btn-outline-success waves-effect waves-themed ${school_zone === system_key ? "active" : ""
}"
class="btn btn-outline-success waves-effect waves-themed ${
school_zone === system_key ? "active" : ""
}"
>
<input type="radio" name="buildingRadio" value=${system_key} />${system_value}
</label>`;