将静态资源移动到标准位置
This commit is contained in:
1
static/css/katex.min.css
vendored
Normal file
1
static/css/katex.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
399
static/css/style.css
Normal file
399
static/css/style.css
Normal file
@@ -0,0 +1,399 @@
|
||||
:root {
|
||||
--primary-color: #4CAF50;
|
||||
--primary-dark: #45a049;
|
||||
--secondary-color: #2c3e50;
|
||||
--light-gray: #f5f5f5;
|
||||
--card-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
--hover-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
--border-color: #e0e0e0;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: var(--light-gray);
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
background-color: white;
|
||||
padding: 30px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
width: 90%;
|
||||
max-width: 1000px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: var(--secondary-color);
|
||||
margin-bottom: 20px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.formula {
|
||||
margin: 20px 0;
|
||||
padding: 15px;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
border-left: 4px solid var(--primary-color);
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
margin: 10px 0;
|
||||
transition: background-color 0.3s, transform 0.2s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: var(--primary-dark);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
button:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 100%;
|
||||
margin: 30px auto 0;
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: var(--card-shadow);
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: var(--card-shadow);
|
||||
padding: 20px;
|
||||
transition: transform 0.3s, box-shadow 0.3s;
|
||||
border: 1px solid var(--border-color);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: var(--hover-shadow);
|
||||
}
|
||||
|
||||
.card.selected {
|
||||
border: 2px solid var(--primary-color);
|
||||
background-color: #f0f9f0;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-weight: 600;
|
||||
color: var(--secondary-color);
|
||||
margin: 0;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.card-date {
|
||||
color: #7f8c8d;
|
||||
font-size: 0.9em;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.notification {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
padding: 15px 25px;
|
||||
border-radius: 4px;
|
||||
display: none;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
||||
z-index: 1000;
|
||||
animation: slideIn 0.3s forwards;
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
#detailsContainer {
|
||||
margin-top: 30px;
|
||||
padding: 20px;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
display: none;
|
||||
border-left: 4px solid var(--primary-color);
|
||||
}
|
||||
|
||||
#detailsTable {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#detailsTable th, #detailsTable td {
|
||||
padding: 12px 15px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
#detailsTable th {
|
||||
background-color: #f2f2f2;
|
||||
font-weight: 600;
|
||||
color: var(--secondary-color);
|
||||
}
|
||||
|
||||
#detailsTable tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.formula-container {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
#downloadBtn {
|
||||
padding: 10px 20px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* 针对手机小屏幕的额外优化 */
|
||||
@media (max-width: 480px) {
|
||||
body {
|
||||
font-size: calc(var(--base-font-size) + 2px); /* 增加基础字体大小 */
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.6rem;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.1rem;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.formula-container {
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.independent-formula {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
#downloadBtn {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* 非常小的屏幕,如某些手机型号 */
|
||||
@media (max-width: 320px) {
|
||||
body {
|
||||
font-size: calc(var(--base-font-size) + 3px); /* 进一步增加字体大小 */
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.formula-container {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.accordion {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.accordion-item {
|
||||
margin-bottom: 10px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.accordion-header {
|
||||
background-color: #f1f1f1;
|
||||
padding: 15px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.accordion-header:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.accordion-content {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease-out;
|
||||
background-color: #fff;
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.accordion-content p {
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.pagination a {
|
||||
margin: 0 10px;
|
||||
text-decoration: none;
|
||||
color: #0066cc;
|
||||
}
|
||||
.pagination span {
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
|
||||
.formula {
|
||||
background-color: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin: 20px 0;
|
||||
border-left: 4px solid #3498db;
|
||||
}
|
||||
.parameter {
|
||||
margin: 5px 0;
|
||||
padding: 5px 10px;
|
||||
background-color: #eaf2f8;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.parameter strong {
|
||||
color: #2980b9;
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: #f1f1f1;
|
||||
padding: 10px 20px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.version {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#deleteBtn {
|
||||
background-color: #f44336;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
margin: 10px 0 10px 10px;
|
||||
transition: background-color 0.3s, transform 0.2s;
|
||||
}
|
||||
|
||||
#deleteBtn:hover {
|
||||
background-color: #d32f2f;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
#deleteBtn:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.pagination button {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.pagination button:hover:not(:disabled) {
|
||||
background-color: var(--primary-dark);
|
||||
}
|
||||
|
||||
.pagination button:disabled {
|
||||
background-color: #cccccc;
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.pagination span {
|
||||
margin: 0 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
BIN
static/fonts/KaTeX_Main-Regular.ttf
Normal file
BIN
static/fonts/KaTeX_Main-Regular.ttf
Normal file
Binary file not shown.
BIN
static/fonts/KaTeX_Main-Regular.woff
Normal file
BIN
static/fonts/KaTeX_Main-Regular.woff
Normal file
Binary file not shown.
BIN
static/fonts/KaTeX_Main-Regular.woff2
Normal file
BIN
static/fonts/KaTeX_Main-Regular.woff2
Normal file
Binary file not shown.
BIN
static/fonts/KaTeX_Math-Italic.ttf
Normal file
BIN
static/fonts/KaTeX_Math-Italic.ttf
Normal file
Binary file not shown.
BIN
static/fonts/KaTeX_Math-Italic.woff
Normal file
BIN
static/fonts/KaTeX_Math-Italic.woff
Normal file
Binary file not shown.
BIN
static/fonts/KaTeX_Math-Italic.woff2
Normal file
BIN
static/fonts/KaTeX_Math-Italic.woff2
Normal file
Binary file not shown.
658
static/js/afterbody.js
Normal file
658
static/js/afterbody.js
Normal file
@@ -0,0 +1,658 @@
|
||||
const version = "0.1.8";
|
||||
|
||||
function toggleFormula(element) {
|
||||
const content = element.nextElementSibling;
|
||||
content.style.display = content.style.display === "none" ? "block" : "none";
|
||||
element.textContent = element.textContent.includes("▶")
|
||||
? element.textContent.replace("▶", "▼")
|
||||
: element.textContent.replace("▼", "▶");
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
renderMathInElement(document.body, {
|
||||
delimiters: [
|
||||
{left: "$$", right: "$$", display: true},
|
||||
{left: "$", right: "$", display: false}
|
||||
],
|
||||
throwOnError: false
|
||||
});
|
||||
});
|
||||
|
||||
// 分页功能
|
||||
document.getElementById('prevPageBtn').addEventListener('click', function() {
|
||||
const currentPage = parseInt(document.getElementById('currentPage').textContent);
|
||||
if (currentPage > 1) {
|
||||
loadPage(currentPage - 1);
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('nextPageBtn').addEventListener('click', function() {
|
||||
const currentPage = parseInt(document.getElementById('currentPage').textContent);
|
||||
const totalPages = parseInt(document.getElementById('totalPages').textContent);
|
||||
if (currentPage < totalPages) {
|
||||
loadPage(currentPage + 1);
|
||||
}
|
||||
});
|
||||
|
||||
function loadPage(page) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const user_id = urlParams.get('user_id');
|
||||
|
||||
fetch(`/weather?user_id=${user_id}&page=${page}`)
|
||||
.then(response => response.text())
|
||||
.then(html => {
|
||||
// 创建一个临时DOM元素来 parse 返回的HTML
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(html, 'text/html');
|
||||
|
||||
// 获取新的卡片容器内容
|
||||
const newCardContainer = doc.getElementById('cardContainer');
|
||||
if (newCardContainer) {
|
||||
document.getElementById('cardContainer').innerHTML = newCardContainer.innerHTML;
|
||||
}
|
||||
|
||||
// 更新分页信息
|
||||
const newCurrentPage = doc.getElementById('currentPage');
|
||||
const newTotalPages = doc.getElementById('totalPages');
|
||||
if (newCurrentPage && newTotalPages) {
|
||||
document.getElementById('currentPage').textContent = newCurrentPage.textContent;
|
||||
document.getElementById('totalPages').textContent = newTotalPages.textContent;
|
||||
}
|
||||
|
||||
// 更新按钮状态
|
||||
updatePaginationButtons(parseInt(newCurrentPage.textContent), parseInt(newTotalPages.textContent));
|
||||
|
||||
// 隐藏详情容器
|
||||
document.getElementById('detailsContainer').style.display = 'none';
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
showNotification('加载页面失败', 'error');
|
||||
});
|
||||
}
|
||||
|
||||
function updatePaginationButtons(currentPage, totalPages) {
|
||||
const prevBtn = document.getElementById('prevPageBtn');
|
||||
const nextBtn = document.getElementById('nextPageBtn');
|
||||
|
||||
prevBtn.disabled = currentPage <= 1;
|
||||
nextBtn.disabled = currentPage >= totalPages;
|
||||
}
|
||||
|
||||
// 添加删除按钮事件监听
|
||||
document.getElementById('deleteBtn').addEventListener('click', function() {
|
||||
const selectedRadio = document.querySelector('input[name="selectedData"]:checked');
|
||||
if (!selectedRadio) {
|
||||
alert('请先选择一条数据');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm('确定要删除这条记录吗?此操作不可撤销!')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedId = selectedRadio.value;
|
||||
fetch('/weather/delete', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: `id=${selectedId}`
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.error) {
|
||||
showNotification(data.error, 'error');
|
||||
} else {
|
||||
showNotification(data.message);
|
||||
// 移除已删除的卡片
|
||||
const card = document.querySelector(`.card[data-id="${selectedId}"]`);
|
||||
if (card) {
|
||||
card.remove();
|
||||
}
|
||||
// 隐藏详情容器
|
||||
document.getElementById('detailsContainer').style.display = 'none';
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
showNotification('删除失败', 'error');
|
||||
});
|
||||
});
|
||||
|
||||
let weatherdata = null;
|
||||
|
||||
document.getElementById('downloadBtn').addEventListener('click', function() {
|
||||
// 保存按钮的引用
|
||||
var btn = this;
|
||||
|
||||
// 隐藏按钮(而不是移除)
|
||||
btn.style.display = 'none';
|
||||
|
||||
//
|
||||
const data = weatherdata;
|
||||
|
||||
const areaTypeMap = {
|
||||
urban: "城市",
|
||||
rural: "农村",
|
||||
};
|
||||
|
||||
|
||||
// 等待一小段时间确保按钮已隐藏
|
||||
setTimeout(function() {
|
||||
// 假设你的HTML字符串是这样的
|
||||
var htmlString = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>总体适宜度测量报表</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Arial', sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.report-container {
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
padding: 25px;
|
||||
}
|
||||
h1 {
|
||||
color: #2c3e50;
|
||||
text-align: center;
|
||||
border-bottom: 2px solid #3498db;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.divider {
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.data-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 10px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.data-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.data-row-long {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.data-label {
|
||||
font-weight: bold;
|
||||
color: #2980b9;
|
||||
margin-bottom: 4px;
|
||||
width: 200px; /* 设置你想要的固定宽度 */
|
||||
white-space: nowrap; /* 防止换行 */
|
||||
overflow: hidden; /* 隐藏溢出内容 */
|
||||
text-overflow: ellipsis; /* 添加省略号 */
|
||||
}
|
||||
.data-value {
|
||||
font-weight: normal;
|
||||
}
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin: 15px 0 5px;
|
||||
color: #34495e;
|
||||
}
|
||||
.ten-values {
|
||||
background-color: #f9f9f9;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
font-family: monospace;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 0%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%); /* 水平居中 */
|
||||
font-size: 12px;
|
||||
color: #7f8c8d;
|
||||
text-align: center; /* 文本居中 */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="report-container">
|
||||
<h1>总体适宜度测量报表</h1>
|
||||
|
||||
<div class="data-grid">
|
||||
<div class="data-row-long">
|
||||
<div class="data-label">文件编号:</div>
|
||||
<div class="data-value">${data.id}</div>
|
||||
</div>
|
||||
|
||||
<div class="data-row-long">
|
||||
<div class="data-label">检测类型:</div>
|
||||
<div class="data-value">${data.inspectiontype}</div>
|
||||
</div>
|
||||
|
||||
<div class="data-row-long">
|
||||
<div class="data-label">委托单号:</div>
|
||||
<div class="data-value">${data.assignmentnumber}</div>
|
||||
</div>
|
||||
|
||||
<div class="data-row-long">
|
||||
<div class="data-label">项目名称:</div>
|
||||
<div class="data-value">${data.title}</div>
|
||||
</div>
|
||||
|
||||
<div class="data-row-long">
|
||||
<div class="data-label">经纬度:</div>
|
||||
<div class="data-value">E ${data.longitude}, N ${data.latitude}</div>
|
||||
</div>
|
||||
|
||||
<div class="data-row-long">
|
||||
<div class="data-label">测试时间:</div>
|
||||
<div class="data-value">${formatDateToYYYYMMDD(data.date)}${data.hour}:${data.min}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="data-grid">
|
||||
<div class="data-row">
|
||||
<div class="data-label">日期序数:</div>
|
||||
<div class="data-value">${data.daysincejanfirst}</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">太阳倾角:</div>
|
||||
<div class="data-value">${data.solardeclination}°</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">太阳高度角:</div>
|
||||
<div class="data-value">${data.sunaltitude}°</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">总云量:</div>
|
||||
<div class="data-value">${data.overallcloudiness}</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">低云量:</div>
|
||||
<div class="data-value">${data.lowcloudiness}</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">辐射等级:</div>
|
||||
<div class="data-value">${data.solarradiationlevel}</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">平均风速:</div>
|
||||
<div class="data-value">${data.averagewindspeed}m/s</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">风速适宜度:</div>
|
||||
<div class="data-value">${data.windspeedsuitability}</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">平均风向:</div>
|
||||
<div class="data-value">${data.averagewinddirection}°</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">风向标准差:</div>
|
||||
<div class="data-value">${data.winddirectionstandarddeviation}°</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">风向适宜度:</div>
|
||||
<div class="data-value">${data.winddirectionsuitability}</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">大气稳定度:</div>
|
||||
<div class="data-value">${data.atmosphericstability}</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">稳定度适宜度:</div>
|
||||
<div class="data-value">${data.suitabilitydegree}</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">总体适宜度:</div>
|
||||
<div class="data-value">${replaceSuitabilityText(data.overallsuitability, "overall")}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- tbd
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="data-row">
|
||||
<div class="data-label">大气压:</div>
|
||||
<div class="data-value">tbd kPa</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">环境温度:</div>
|
||||
<div class="data-value">tbd ℃</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">环境湿度:</div>
|
||||
<div class="data-value">tbd %RH</div>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="data-grid">
|
||||
<div class="data-row-long">
|
||||
<div class="data-label">十次风速值:</div>
|
||||
<div class="data-value">
|
||||
<div class="ten-values">${data.windspeed}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="data-row-long">
|
||||
<div class="data-label">十次风向值:</div>
|
||||
<div class="data-value">
|
||||
<div class="ten-values">${data.winddirection}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="data-grid">
|
||||
`
|
||||
|
||||
// 根据条件显示相应的数据
|
||||
if (data.hasmeasuredwindspeed === true) {
|
||||
htmlString+=`
|
||||
<div class="data-row">
|
||||
<div class="data-label">实测风速:</div>
|
||||
<div class="data-value">${data.measuredwindspeed} m/s</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">转换风速:</div>
|
||||
<div class="data-value">${data.convertedwindspeed} m/s</div>
|
||||
</div>
|
||||
`
|
||||
} else {
|
||||
htmlString+=`
|
||||
<div class="data-row">
|
||||
<div class="data-label">区域类型:</div>
|
||||
<div class="data-value">${areaTypeMap[data.areatype]}</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">测点高度:</div>
|
||||
<div class="data-value">${data.measurementheight} m</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">点位风速:</div>
|
||||
<div class="data-value">${data.pointwindspeed} m/s</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">推算风速:</div>
|
||||
<div class="data-value">${data.calculatedwindspeed} m/s</div>
|
||||
</div>
|
||||
`
|
||||
};
|
||||
|
||||
htmlString += `
|
||||
</div>
|
||||
<br>
|
||||
<div class="footer">----报表结束 version:0.18----</div>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
const filename = `${data.id}-${version}.pdf`
|
||||
var opt = {
|
||||
margin: 10,
|
||||
filename: filename,
|
||||
image: {
|
||||
type: 'jpeg',
|
||||
quality: 0.98
|
||||
},
|
||||
html2canvas: {
|
||||
scale: 2
|
||||
},
|
||||
jsPDF: {
|
||||
unit: 'mm',
|
||||
format: 'a4',
|
||||
orientation: 'portrait'
|
||||
}
|
||||
};
|
||||
|
||||
// 执行下载,使用htmlString作为内容源
|
||||
html2pdf().set(opt).from(htmlString).save();
|
||||
}, 100);
|
||||
|
||||
// 下载完成后恢复按钮显示
|
||||
setTimeout(function() {
|
||||
btn.style.display = '';
|
||||
}, 2000); // 假设下载需要2秒完成,你可以根据实际情况调整
|
||||
});
|
||||
|
||||
|
||||
// 函数用于将日期格式化为 xxxx-xx-xx 形式
|
||||
function formatDateToYYYYMMDD(date) {
|
||||
// 使用Date对象解析这个日期字符串
|
||||
var date = new Date(date);
|
||||
var year = date.getFullYear(); // 获取年份
|
||||
var month = (date.getMonth() + 1).toString().padStart(2, '0'); // 获取月份,并确保两位数
|
||||
var day = date.getDate().toString().padStart(2, '0'); // 获取日期,并确保两位数
|
||||
return year + '-' + month + '-' + day; // 组合成 xxxx-xx-xx 形式
|
||||
}
|
||||
|
||||
document.getElementById('viewDetailsBtn').addEventListener('click', function() {
|
||||
const selectedRadio = document.querySelector('input[name="selectedData"]:checked');
|
||||
if (!selectedRadio) {
|
||||
alert('请先选择一条数据');
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedId = selectedRadio.value;
|
||||
fetch(`/weather/details?id=${selectedId}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
//更新全局变量
|
||||
weatherdata = data;
|
||||
const detailsTable = document.getElementById('detailsTable');
|
||||
detailsTable.innerHTML = '';
|
||||
|
||||
const row = document.createElement('div');
|
||||
row.innerHTML = `
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>${data.title}</h3>
|
||||
<h3>${data.inspectiontype}</h3>
|
||||
<h3>${data.assignmentnumber}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="info-item">
|
||||
<span class="info-label">时间:</span>
|
||||
<span class="info-value">${formatDateToYYYYMMDD(data.date)} ${data.hour}时 ${data.min}分</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">经纬度:</span>
|
||||
<span class="info-value">位置: 经度 ${data.longitude}, 纬度 ${data.latitude}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">地球公转角:</span>
|
||||
<span class="info-value">${data.theta}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">太阳倾角:</span>
|
||||
<span class="info-value">${data.solardeclination}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">太阳高度角:</span>
|
||||
<span class="info-value">${data.sunaltitude}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">云量指数:${data.cloudindex}</span>
|
||||
<span class="info-value">低云 ${data.lowcloudiness}, 总云量 ${data.overallcloudiness}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">太阳辐射等级:</span>
|
||||
<span class="info-value">${data.solarradiationlevel}</span>
|
||||
</div>
|
||||
|
||||
<div id="measured-data" style="display: none;">
|
||||
<div class="info-item">
|
||||
<span class="info-label">测量风速:</span>
|
||||
<span class="info-value" id="measured-windspeed">${data.measuredwindspeed}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">转换风速:</span>
|
||||
<span class="info-value" id="converted-windspeed">${data.convertedwindspeed}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="calculated-data" style="display: none;">
|
||||
<div class="info-item">
|
||||
<span class="info-label">测量高度:</span>
|
||||
<span class="info-value" id="measurement-height">${data.measurementheight}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">区域类型:</span>
|
||||
<span class="info-value" id="area-type">${data.areatype}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">测点风速:</span>
|
||||
<span class="info-value" id="point-windspeed">${data.pointwindspeed}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-item">
|
||||
<span class="info-label">大气稳定度:</span>
|
||||
<span class="info-value">${data.atmosphericstability}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">适宜度:</span>
|
||||
<span class="info-value">${data.suitabilitydegree}</span>
|
||||
</div>
|
||||
|
||||
<div class="info-item">
|
||||
<span class="info-label">风速:${data.windspeed}</span>
|
||||
<span class="info-value">平均风速:${data.averagewindspeed}</span>
|
||||
<span class="info-value">适宜度:${data.windspeedsuitability}</span>
|
||||
</div>
|
||||
|
||||
<div class="info-item">
|
||||
<span class="info-label">风向:${data.winddirection}</span>
|
||||
<span class="info-value">平均风向 ${data.averagewinddirection} 风向标准差 ${data.winddirectionstandarddeviation}</span>
|
||||
<span class="info-value">适宜度:${data.winddirectionsuitability}</span>
|
||||
</div>
|
||||
|
||||
<div class="info-item">
|
||||
<span class="info-label">整体适宜度:</span>
|
||||
<span class="info-value rating-high">${data.overallsuitability}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
detailsTable.appendChild(row);
|
||||
|
||||
// 根据条件显示相应的数据
|
||||
if (data.hasmeasuredwindspeed==='true') {
|
||||
document.getElementById('measured-data').style.display = 'block';
|
||||
document.getElementById('calculated-data').style.display = 'none';
|
||||
document.getElementById('measured-windspeed').textContent = data.measuredwindspeed;
|
||||
document.getElementById('converted-windspeed').textContent = data.convertedwindspeed;
|
||||
} else {
|
||||
document.getElementById('measured-data').style.display = 'none';
|
||||
document.getElementById('calculated-data').style.display = 'block';
|
||||
document.getElementById('measurement-height').textContent = data.measurementheight;
|
||||
document.getElementById('area-type').textContent = data.areatype;
|
||||
document.getElementById('point-windspeed').textContent = data.pointwindspeed;
|
||||
};
|
||||
|
||||
document.getElementById('detailsContainer').style.display = 'block';
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('获取详细信息失败');
|
||||
});
|
||||
});
|
||||
|
||||
function selectCard(card) {
|
||||
// 获取所有卡片
|
||||
const allCards = document.querySelectorAll('.card');
|
||||
|
||||
// 移除所有卡片的选中状态
|
||||
allCards.forEach(c => {
|
||||
c.classList.remove('selected');
|
||||
const radio = c.querySelector('input[type="radio"]');
|
||||
if (radio) radio.checked = false;
|
||||
});
|
||||
|
||||
// 添加当前卡片的选中状态
|
||||
card.classList.add('selected');
|
||||
const radio = card.querySelector('input[type="radio"]');
|
||||
if (radio) radio.checked = true;
|
||||
}
|
||||
|
||||
// 显示通知
|
||||
function showNotification(message, type = 'success') {
|
||||
const notification = document.getElementById('notification');
|
||||
notification.textContent = message;
|
||||
notification.style.backgroundColor = type === 'success' ? '#4CAF50' : '#f44336';
|
||||
notification.style.display = 'block';
|
||||
|
||||
setTimeout(() => {
|
||||
notification.style.display = 'none';
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
//公式相关
|
||||
function toggleAccordion(header) {
|
||||
const content = header.nextElementSibling;
|
||||
const isOpen = content.style.maxHeight !== '0px' && content.style.maxHeight !== '';
|
||||
|
||||
// 关闭所有其他面板
|
||||
document.querySelectorAll('.accordion-content').forEach(item => {
|
||||
item.style.maxHeight = '0px';
|
||||
});
|
||||
|
||||
// 切换当前面板
|
||||
if (!isOpen) {
|
||||
content.style.maxHeight = content.scrollHeight + 'px';
|
||||
}
|
||||
}
|
||||
|
||||
//稳定度描述映射
|
||||
function replaceSuitabilityText(data, type) {
|
||||
// 定义映射关系
|
||||
const suitabilityMap = {
|
||||
'a': '不利于污染物的扩散和稀释,适宜于进行无组织排放监测',
|
||||
'b': '较不利于污染物的扩散和稀释,较适宜于进行无组织排放监测',
|
||||
'c': '有利于污染物的扩散和稀释,较不适宜于进行无组织排放监测',
|
||||
'd': '很有利于污染物的扩散和稀释,不适宜于进行无组织排放监测',
|
||||
'wind0': '静风',
|
||||
'overall0': '取消监测或改期'
|
||||
};
|
||||
// 将输入转换为小写(或大写)以实现大小写不敏感
|
||||
const normalizedData = String(data).toLowerCase();
|
||||
|
||||
// 处理特殊类型
|
||||
if (type === 'wind' && normalizedData === '0')
|
||||
return suitabilityMap['wind0'];
|
||||
|
||||
if (type === 'overall' && normalizedData === '0')
|
||||
return suitabilityMap['overall0'];
|
||||
|
||||
// 处理普通类型
|
||||
if (type === 'normal' || type === "wind" || type === "overall") {
|
||||
// 检查映射表中是否存在转换后的小写字段
|
||||
if (suitabilityMap[normalizedData]) {
|
||||
return suitabilityMap[normalizedData];
|
||||
}
|
||||
// 如果找不到,返回原值
|
||||
return data;
|
||||
}
|
||||
|
||||
// 默认返回原值
|
||||
return data;
|
||||
}
|
||||
|
||||
// 初始化时关闭所有面板
|
||||
document.querySelectorAll('.accordion-content').forEach(content => {
|
||||
content.style.maxHeight = '0px';
|
||||
});
|
||||
1
static/js/auto-render.min.js
vendored
Normal file
1
static/js/auto-render.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("katex")):"function"==typeof define&&define.amd?define(["katex"],t):"object"==typeof exports?exports.renderMathInElement=t(require("katex")):e.renderMathInElement=t(e.katex)}("undefined"!=typeof self?self:this,(function(e){return function(){"use strict";var t={771:function(t){t.exports=e}},n={};function r(e){var o=n[e];if(void 0!==o)return o.exports;var i=n[e]={exports:{}};return t[e](i,i.exports,r),i.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};var o={};return function(){r.d(o,{default:function(){return d}});var e=r(771),t=r.n(e);const n=function(e,t,n){let r=n,o=0;const i=e.length;for(;r<t.length;){const n=t[r];if(o<=0&&t.slice(r,r+i)===e)return r;"\\"===n?r++:"{"===n?o++:"}"===n&&o--,r++}return-1},i=/^\\begin{/;var a=function(e,t){let r;const o=[],a=new RegExp("("+t.map((e=>e.left.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"))).join("|")+")");for(;r=e.search(a),-1!==r;){r>0&&(o.push({type:"text",data:e.slice(0,r)}),e=e.slice(r));const a=t.findIndex((t=>e.startsWith(t.left)));if(r=n(t[a].right,e,t[a].left.length),-1===r)break;const l=e.slice(0,r+t[a].right.length),s=i.test(l)?l:e.slice(t[a].left.length,r);o.push({type:"math",data:s,rawData:l,display:t[a].display}),e=e.slice(r+t[a].right.length)}return""!==e&&o.push({type:"text",data:e}),o};const l=function(e,n){const r=a(e,n.delimiters);if(1===r.length&&"text"===r[0].type)return null;const o=document.createDocumentFragment();for(let e=0;e<r.length;e++)if("text"===r[e].type)o.appendChild(document.createTextNode(r[e].data));else{const i=document.createElement("span");let a=r[e].data;n.displayMode=r[e].display;try{n.preProcess&&(a=n.preProcess(a)),t().render(a,i,n)}catch(i){if(!(i instanceof t().ParseError))throw i;n.errorCallback("KaTeX auto-render: Failed to parse `"+r[e].data+"` with ",i),o.appendChild(document.createTextNode(r[e].rawData));continue}o.appendChild(i)}return o},s=function(e,t){for(let n=0;n<e.childNodes.length;n++){const r=e.childNodes[n];if(3===r.nodeType){let o=r.textContent,i=r.nextSibling,a=0;for(;i&&i.nodeType===Node.TEXT_NODE;)o+=i.textContent,i=i.nextSibling,a++;const s=l(o,t);if(s){for(let e=0;e<a;e++)r.nextSibling.remove();n+=s.childNodes.length-1,e.replaceChild(s,r)}else n+=a}else if(1===r.nodeType){const e=" "+r.className+" ";-1===t.ignoredTags.indexOf(r.nodeName.toLowerCase())&&t.ignoredClasses.every((t=>-1===e.indexOf(" "+t+" ")))&&s(r,t)}}};var d=function(e,t){if(!e)throw new Error("No element provided to render");const n={};for(const e in t)t.hasOwnProperty(e)&&(n[e]=t[e]);n.delimiters=n.delimiters||[{left:"$$",right:"$$",display:!0},{left:"\\(",right:"\\)",display:!1},{left:"\\begin{equation}",right:"\\end{equation}",display:!0},{left:"\\begin{align}",right:"\\end{align}",display:!0},{left:"\\begin{alignat}",right:"\\end{alignat}",display:!0},{left:"\\begin{gather}",right:"\\end{gather}",display:!0},{left:"\\begin{CD}",right:"\\end{CD}",display:!0},{left:"\\[",right:"\\]",display:!0}],n.ignoredTags=n.ignoredTags||["script","noscript","style","textarea","pre","code","option"],n.ignoredClasses=n.ignoredClasses||[],n.errorCallback=n.errorCallback||console.error,n.macros=n.macros||{},s(e,n)}}(),o=o.default}()}));
|
||||
6
static/js/html2pdf.bundle.min.js
vendored
Normal file
6
static/js/html2pdf.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
static/js/katex.min.js
vendored
Normal file
1
static/js/katex.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user