const WeatherReport = (function () {
const BASE_WIND_COUNT = 10;
const SPOT_CHECK_COUNT = 5;
const AREA_TYPE_MAP = {
urban: "城市",
rural: "农村",
};
const SUITABILITY_MAP = {
a: "不利于污染物的扩散和稀释,适宜于进行无组织排放监测",
b: "较不利于污染物的扩散和稀释,较适宜于进行无组织排放监测",
c: "有利于污染物的扩散和稀释,较不适宜于进行无组织排放监测",
d: "很有利于污染物的扩散和稀释,不适宜于进行无组织排放监测",
wind0: "静风",
overall0: "取消监测或改期",
};
function formatDate(dateStr) {
const d = new Date(dateStr);
const y = d.getFullYear();
const m = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
return `${y}-${m}-${day}`;
}
function getSuitabilityText(value, type) {
const normalized = String(value).toLowerCase();
if (type === "wind" && normalized === "0") return SUITABILITY_MAP.wind0;
if (type === "overall" && normalized === "0") return SUITABILITY_MAP.overall0;
return SUITABILITY_MAP[normalized] || value;
}
function formatTime(hours, min) {
return `${hours}:${String(min).padStart(2, "0")}`;
}
function joinWithComma(arr, start, end) {
return arr.slice(start, end).map((v) => v ?? "").join(",");
}
function buildReportHTML(data) {
const staticPrefix = window.staticPrefix || '/static';
const timeStr = `${formatDate(data.date)} ${formatTime(data.hours, data.min)}`;
const version = data.version || "unknown";
let html = `
总体适宜度测量报表
总体适宜度测量报表
项目名称:
${data.title || "-"}
检测类型:
${data.inspectionType || "-"}
委托单号:
${data.assignmentNumber || "-"}
经度:
E ${data.longitude || "-"}
纬度:
N ${data.latitude || "-"}
日期序数:
${data.daySinceJanFirst}
太阳倾角:
${Number(data.solarDeclination).toFixed(2)}°
太阳高度角:
${Number(data.sunAltitude).toFixed(2)}°
总云量:
${data.overallCloudiness}
低云量:
${data.lowCloudiness}
辐射等级:
${data.solarRadiationLevel}
平均风速:
${data.averageWindSpeed} m/s
风速适宜度:
${data.windSpeedSuitability}
`;
if (data.hasMeasuredWindSpeed === true) {
html += `
实测风速:
${data.measuredWindSpeed} m/s
转换风速:
${data.convertedWindSpeed} m/s
`;
} else {
html += `
区域类型:
${AREA_TYPE_MAP[data.areaType] || data.areaType || "-"}
测点高度:
${data.pointHeight} m
点位风速:
${data.pointWindSpeed} m/s
推算风速:
${data.calculatedWindSpeed} m/s
`;
}
html += `
平均风向:
${data.averageWindDirection}°
风向标准差:
${data.windDirectionStandardDeviation}°
风向适宜度:
${data.windDirectionSuitability}
大气稳定度:
${data.atmosphericStability}
稳定度适宜度:
${data.suitabilityDegree}
总体适宜度:
${getSuitabilityText(data.overallSuitability, "overall")}
十次风速值:
${joinWithComma(data.windSpeed, 0, BASE_WIND_COUNT)}
十次风向值:
${joinWithComma(data.windDirection, 0, BASE_WIND_COUNT)}
`;
if (data.hasSpotCheckWindSpeed) {
html += `
抽测风速值:
${joinWithComma(data.windSpeed, BASE_WIND_COUNT, BASE_WIND_COUNT + SPOT_CHECK_COUNT)}
抽测风向值:
${joinWithComma(data.windDirection, BASE_WIND_COUNT, BASE_WIND_COUNT + SPOT_CHECK_COUNT)}
`;
}
html += `
`;
return html;
}
function downloadPDF(htmlContent, filename) {
const options = {
margin: 10,
filename: filename,
image: { type: "jpeg", quality: 0.99 },
html2canvas: { scale: 2 },
jsPDF: { unit: "mm", format: "a4", orientation: "portrait" },
};
html2pdf().set(options).from(htmlContent).save();
}
function init() {
if (typeof window.weatherData === "undefined") {
console.error("错误:window.weatherData 未定义");
return;
}
const data = window.weatherData;
console.log("【调试】从后端获取的 weatherData:", data);
console.log("【调试】inspectionType:", data.inspectionType);
console.log("【调试】assignmentNumber:", data.assignmentNumber);
console.log("【调试】title:", data.title);
const versionEl = document.querySelector(".version");
if (versionEl) {
versionEl.textContent = `版本号: ${data.version || "default"}`;
}
const html = buildReportHTML(data);
const filename = `${data.id}-${data.version || "unknown"}.pdf`;
downloadPDF(html, filename);
}
document.addEventListener("DOMContentLoaded", function () {
if (typeof renderMathInElement === "function") {
renderMathInElement(document.body, {
delimiters: [
{ left: "$$", right: "$$", display: true },
{ left: "$", right: "$", display: false },
],
throwOnError: false,
});
}
init();
});
function toggleFormula(element) {
const content = element.nextElementSibling;
const isHidden = content.style.display === "none";
content.style.display = isHidden ? "block" : "none";
element.textContent = element.textContent.includes("▶")
? element.textContent.replace("▶", "▼")
: element.textContent.replace("▼", "▶");
}
function showNotification(message, type = "success") {
const notification = document.getElementById("notification");
if (!notification) return;
notification.textContent = message;
notification.className = `notification ${type}`;
notification.style.display = "block";
setTimeout(() => {
notification.style.display = "none";
}, 3000);
}
return {
buildReportHTML,
downloadPDF,
init,
toggleFormula,
showNotification,
};
})();