let currentScale = 1.0;
const SCALE_STEP = 0.25;
const MIN_SCALE = 0.5;
const MAX_SCALE = 3.0;
let isMobile = /Mobi|Android|iPhone/i.test(navigator.userAgent);
// 获取URL中code值,用于获取用户信息(code只能使用一次,5分钟未被使用自动过期。)
function getURLCode() {
// 获取查询字符串(?后面的部分)
const queryString = window.location.search;
// 使用URLSearchParams解析查询字符串
const urlParams = new URLSearchParams(queryString);
// 获取code参数值
const code = urlParams.get('code');
// 检查code是否存在,并确保它是字符串(虽然从get()返回的值默认就是字符串)
if (code !== null) {
console.log('urlCode:', code);
return code;
} else {
console.log('No code parameter found in the URL.');
return null; // 或者返回一个默认值,比如空字符串 ''
}
}
$(document).ready(function() {
// 缓存DOM元素
const $reportTypeSelect = $('#reportType');
const $yearSelect = $('#year');
const $monthSelect = $('#month');
const $periodSelect = $('#period');
const $periodSelectionDiv = $('#periodSelection');
const $monthSelectionDiv = $('#monthSelection');
const $pdfViewer = $('#pdfViewer');
const $noReportSelected = $('#noReportSelected');
const $loadingSpinner = $('#loadingSpinner');
const $periodLabel = $('#periodLabel');
const $downloadBtnContainer = $('#downloadBtnContainer');
const $downloadPdfBtn = $('#downloadPdfBtn');
// 存储可用报表数据和当前PDF信息
let availableReports = {};
let currentPdfInfo = {
url: '',
filename: ''
};
let getCode ='pxj34K9lvyGH6-sN4DPWtgsmDZXwOtkN7UwMBT88dRk'
// 根据url地址获取用户code
// let getCode = getURLCode();
// 初始化 - 获取可用报表
$.get('/rept/api/reports',{code:getCode})
.done(function(data) {
availableReports = data;
console.log('Available reports:', availableReports);
// 自动加载最新周报
loadLatestWeeklyReport();
},'json')
.fail(function(error) {
console.error('Error fetching reports:', error);
showError('获取报表列表失败,请刷新页面重试');
});
// 新增函数:加载最新周报
function loadLatestWeeklyReport() {
if (!availableReports.weekly || Object.keys(availableReports.weekly).length === 0) {
console.log('没有可用的周报数据');
return;
}
// 1. 自动选择周报类型
$('#reportType').val('weekly').trigger('change');
// 2. 获取最新年份
const years = Object.keys(availableReports.weekly).sort().reverse();
const latestYear = years[0];
// 3. 选择年份并触发变更
setTimeout(() => {
$('#year').val(latestYear).trigger('change');
// 4. 获取最新月份
const months = Object.keys(availableReports.weekly[latestYear]).sort((a, b) => {
return parseInt(b) - parseInt(a); // 数字排序
});
const latestMonth = months[0];
// 5. 选择月份并触发变更
setTimeout(() => {
$('#month').val(latestMonth).trigger('change');
// 6. 获取最新周数
const weeks = availableReports.weekly[latestYear][latestMonth].sort((a, b) => b - a);
const latestWeek = weeks[0];
// 7. 选择周数并触发加载
setTimeout(() => {
$('#period').val(latestWeek).trigger('change');
}, 100);
}, 100);
}, 100);
}
// 报表类型变更事件
$reportTypeSelect.on('change', function() {
const reportType = $(this).val();
// 重置其他选择器
$yearSelect.html('<option value="">请选择年份</option>').prop('disabled', !reportType);
$monthSelect.html('<option value="">请选择月份</option>').prop('disabled', true);
$periodSelect.html('<option value="">请选择</option>').prop('disabled', true);
//
// // 隐藏PDF查看器和下载按钮
// resetPdfViewer();
// $downloadBtnContainer.hide();
if (!reportType) {
$monthSelectionDiv.hide();
$periodSelectionDiv.hide();
return;
}
// 填充年份选项
const years = availableReports[reportType];
if (reportType === 'annual') {
// 年报直接是年份数组
$.each(years, function(index, year) {
$yearSelect.append($('<option>', {
value: year,
text: year
}));
});
$monthSelectionDiv.hide();
$periodSelectionDiv.hide();
} else if (reportType === 'monthly') {
// 月报是对象,键是年份
$.each(Object.keys(years).sort().reverse(), function(index, year) {
$yearSelect.append($('<option>', {
value: year,
text: year
}));
});
$monthSelectionDiv.hide();
$periodSelectionDiv.show();
$periodLabel.text('月份');
} else if (reportType === 'weekly') {
// 周报是对象,键是年份
$.each(Object.keys(years).sort().reverse(), function(index, year) {
$yearSelect.append($('<option>', {
value: year,
text: year
}));
});
$monthSelectionDiv.show();
$periodSelectionDiv.show();
$periodLabel.text('周数');
}
});
// 年份变更事件
$yearSelect.on('change', function() {
const year = $(this).val();
const reportType = $reportTypeSelect.val();
if (!year || !reportType) {
$monthSelect.prop('disabled', true);
$periodSelect.prop('disabled', true);
return;
}
if (reportType === 'monthly') {
// 获取该年可用的月份
// const months = availableReports.monthly[year] || [];
// $periodSelect.html('<option value="">请选择</option>');
// $.each(months, function(index, month) {
// $periodSelect.append($('<option>', {
// value: month.replace('月', ''),
// text: month
// }));
// });
// $periodSelect.prop('disabled', false);
const months = availableReports.monthly[year] || [];
console.log('原始月份数据:', availableReports.monthly[year]);
// 将月份转换为数字并排序
const sortedMonths = months
.map(month => {
// 去除"月"字并转换为数字
const monthNum = parseInt(month.replace('月', ''));
return {
num: monthNum,
text: month
};
})
.sort((a, b) => a.num - b.num) // 按数字从小到大排序
.map(item => item.text); // 转换回带"月"的格式
console.log('处理后数据:', sortedMonths);
$periodSelect.html('<option value="">请选择</option>');
$.each(sortedMonths, function(index, month) {
$periodSelect.append($('<option>', {
value: month.replace('月', ''),
text: month
}));
});
$periodSelect.prop('disabled', false);
} else if (reportType === 'weekly') {
// 获取该年可用的月份
const months = Object.keys(availableReports.weekly[year] || {});
$monthSelect.html('<option value="">请选择月份</option>');
$.each(months, function(index, month) {
$monthSelect.append($('<option>', {
value: month,
text: month
}));
});
$monthSelect.prop('disabled', false);
}else if (reportType === 'annual') {
// 隐藏PDF查看器和下载按钮
resetPdfViewer();
$downloadBtnContainer.hide();
// 年报:选择年份后直接加载报表
loadReport(reportType, year, null, null);
}
});
// 月份变更事件
$monthSelect.on('change', function() {
const month = $(this).val();
const year = $yearSelect.val();
const reportType = $reportTypeSelect.val();
if (!month || !year || !reportType || reportType!== 'weekly') {
$periodSelect.prop('disabled', true);
return;
}
// 获取该月可用的周数
const weeks = availableReports.weekly[year][month] || [];
$periodSelect.html('<option value="">请选择</option>');
$.each(weeks, function(index, week) {
$periodSelect.append($('<option>', {
value: week,
text: `第${week}周`
}));
});
$periodSelect.prop('disabled', false);
});
// 周期变更事件 - 加载报表
$periodSelect.on('change', function() {
const period = $(this).val();
const year = $yearSelect.val();
const reportType = $reportTypeSelect.val();
const month = $monthSelect.val();
if (!period || !year || !reportType) return;
// 隐藏PDF查看器和下载按钮
resetPdfViewer();
$downloadBtnContainer.hide();
loadReport(reportType, year, month, period);
});
// PDF下载功能
$downloadPdfBtn.on('click', function() {
if (!currentPdfInfo.url) {
showError('当前没有可下载的报表');
return false; // 阻止后续执行
}
try {
downloadPdf(currentPdfInfo.url, currentPdfInfo.filename);
return false; // 确保不会重复执行
} catch (error) {
showError('下载失败: ' + error.message);
return false;
}
});
// 监听窗口大小变化事件,重新渲染 PDF
// 在窗口大小变化时重新计算
$(window).on('resize', debounce(function() {
if (currentPdfInfo.url) {
const containerWidth = $pdfViewer.width();
$('.pdf-page-container').each(function() {
const canvas = $(this).find('canvas')[0];
if (canvas.viewport) {
const newScale = (containerWidth - 20) / canvas.viewport.width;
currentScale = newScale;
applyZoom();
}
});
}
}, 300));
//添加手势缩放支持
$('#zoomInMobile').on('click', zoomIn);
$('#zoomOutMobile').on('click', zoomOut);
$('#zoomResetMobile').on('click', resetZoom);
$('#fitWidthMobile').on('click', fitToWidth);
const $shrinkMenuBtn = $('#shrinkMenuBtn'); // 缩小按钮
const $expandMenuBtn = $('#expandMenuBtn'); // 放大按钮
const $reportFilterCard = $('#reportFilterCard');
const $filterCardBody = $('#filterCardBody');
let isMenuShrinked = false; // 菜单缩放状态标记
$shrinkMenuBtn.on('click', function() {
toggleMenuSize(true);
});
$expandMenuBtn.on('click', function() {
toggleMenuSize(false);
});
// 菜单缩放函数
function toggleMenuSize(isShrink) {
if (isShrink === isMenuShrinked) return;
if (isShrink) {
// 缩小菜单
$reportFilterCard.addClass('shrinked');
$shrinkMenuBtn.hide();
$expandMenuBtn.show();
} else {
// 放大菜单
$reportFilterCard.removeClass('shrinked');
$shrinkMenuBtn.show();
$expandMenuBtn.hide();
}
isMenuShrinked = isShrink;
}
// 添加手势缩放支持
let initialDistance = null;
$('#pdfViewer').on('touchstart', function(e) {
if (e.touches.length === 2) {
e.preventDefault();
initialDistance = getDistance(
e.touches[0].clientX, e.touches[0].clientY,
e.touches[1].clientX, e.touches[1].clientY
);
}
});
$('#pdfViewer').on('touchmove', function(e) {
if (e.touches.length === 2) {
e.preventDefault();
const currentDistance = getDistance(
e.touches[0].clientX, e.touches[0].clientY,
e.touches[1].clientX, e.touches[1].clientY
);
if (initialDistance) {
const scale = currentDistance / initialDistance;
const newScale = Math.min(MAX_SCALE, Math.max(MIN_SCALE, currentScale * scale));
if (Math.abs(newScale - currentScale) > 0.05) { // 防抖
currentScale = newScale;
applyZoom();
}
}
initialDistance = currentDistance;
}
});
function getDistance(x1, y1, x2, y2) {
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
}
// 缩放工具函数
function zoomIn() {
if (currentScale < MAX_SCALE) {
currentScale += SCALE_STEP;
applyZoom();
}
}
function zoomOut() {
if (currentScale > MIN_SCALE) {
currentScale -= SCALE_STEP;
applyZoom();
}
}
function resetZoom() {
currentScale = 1.0;
applyZoom();
}
function fitToWidth() {
if ($('.pdf-page').length > 0) {
const containerWidth = $pdfViewer.width();
const pageWidth = $('.pdf-page')[0].width;
currentScale = containerWidth / pageWidth;
applyZoom();
}
}
function applyZoom() {
// 更新显示比例
$('.zoom-level').text(Math.round(currentScale * 100) + '%');
// 应用缩放变换
$('.pdf-page-container').css({
'transform': `scale(${currentScale})`,
'transform-origin': 'top center'
});
// 调整容器大小
$('.pdf-page').each(function() {
const canvas = this;
const scaledWidth = canvas.viewport.width * currentScale;
$(canvas).css({
'width': scaledWidth + 'px',
'height': 'auto'
});
});
}
// 工具函数:加载报表
function loadReport(reportType, year, month, period) {
// 显示加载动画
$loadingSpinner.show();
resetPdfViewer();
$noReportSelected.addClass("force-hide");
// 构建报表URL和文件名
let reportUrl, filename;
if (reportType === 'weekly') {
reportUrl = `/rept/api/reports/${reportType}/${year}/${month}/${period}`;
filename = `气象周报_${year}年${month}月第${period}周.pdf`;
} else if (reportType === 'monthly') {
reportUrl = `/rept/api/reports/${reportType}/${year}/${period}`;
filename = `气象月报_${year}年${period}月.pdf`;
} else {
reportUrl = `/rept/api/reports/${reportType}/${year}`;
filename = `气象年报_${year}年.pdf`;
}
// 存储当前PDF信息
currentPdfInfo = { url: reportUrl, filename: filename };
// 加载报表
$.ajax({
url: reportUrl,
method: 'GET',
xhrFields: {
responseType: 'blob'
},
success: function(blob) {
const objectUrl = URL.createObjectURL(blob);
renderPdf(objectUrl, filename);
},
error: function(xhr) {
console.error('Error loading report:', xhr);
$loadingSpinner.hide();
showError(xhr.status === 404 ? '报表不存在' : '加载报表时出错');
}
});
}
// 工具函数:渲染PDF
function renderPdf(url, filename) {
$pdfViewer.empty();
pdfjsLib.getDocument(url).promise.then(function(pdf) {
const containerWidth = $pdfViewer.width();
const devicePixelRatio = window.devicePixelRatio || 1; // 获取设备像素比
const renderPromises = [];
// 渲染所有页面
for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
renderPromises.push(
pdf.getPage(pageNum).then(function(page) {
// 计算基础缩放
const viewport = page.getViewport({ scale: 1 });
const scale = containerWidth / viewport.width;
// 创建高清 Canvas
const scaledViewport = page.getViewport({ scale: scale * devicePixelRatio });
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
// 设置Canvas物理尺寸
canvas.height = scaledViewport.height;
canvas.width = scaledViewport.width;
// 设置Canvas显示尺寸(CSS像素)
canvas.style.height = `${scaledViewport.height / devicePixelRatio}px`;
canvas.style.width = `${scaledViewport.width / devicePixelRatio}px`;
canvas.className = 'pdf-page';
canvas.viewport = scaledViewport;
// 添加到DOM
const pageContainer = $('<div class="pdf-page-container"></div>');
pageContainer.append(canvas);
$pdfViewer.append(pageContainer);
// 高清渲染
return page.render({
canvasContext: context,
viewport: scaledViewport
});
})
);
}
return Promise.all(renderPromises);
}).then(function() {
// 初始化缩放状态
currentScale = 1.0;
$('.zoom-level').text('100%');
$loadingSpinner.hide();
$pdfViewer.show();
$downloadBtnContainer.show();
}).catch(/* 错误处理保持不变 */);
}
// 工具函数:重新加载PDF(用于窗口大小变化时)
function reloadPdf(url) {
$loadingSpinner.show();
renderPdf(url, currentPdfInfo.filename);
}
// 工具函数:下载PDF
function downloadPdf(url, filename) {
// 检查URL有效性
if (!url || typeof url !== 'string') {
throw new Error('无效的PDF URL');
}
const a = document.createElement('a');
a.href = url;
a.download = filename || '气象报表_' + new Date().toISOString().slice(0, 10) + '.pdf';
a.style.display = 'none';
document.body.appendChild(a);
a.click();
// 显示Toast通知(仅移动端)
if (/Mobi|Android|iPhone/i.test(navigator.userAgent)) {
showToast('正在下载报表,请稍后。');
}
// 清理
setTimeout(() => {
document.body.removeChild(a);
}, 100);
}
// 新增工具函数:显示Toast
function showToast(message) {
const toastEl = document.getElementById('downloadToast');
const toastMessage = document.getElementById('toastMessage');
toastMessage.textContent = message;
const toast = new bootstrap.Toast(toastEl, {
animation: true,
autohide: true,
delay: 3000 // 3秒后自动消失
});
toast.show();
}
// 工具函数:重置PDF查看器
function resetPdfViewer() {
// 释放之前的PDF URL
if (currentPdfInfo.blobUrl) {
URL.revokeObjectURL(currentPdfInfo.blobUrl);
}
currentPdfInfo = { url: '', filename: '', blobUrl: '' };
$pdfViewer.hide().empty();
$noReportSelected.show();
$downloadBtnContainer.hide();
}
// 工具函数:显示错误信息
function showError(message) {
$noReportSelected.html(`
<div class="text-center text-danger">
<i class="bi bi-exclamation-triangle" style="font-size: 3rem;"></i>
<h3>加载失败</h3>
<p>${message}</p>
</div>
`).show();
}
// 工具函数:防抖
function debounce(func, wait) {
let timeout;
return function() {
const context = this, args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function() {
func.apply(context, args);
}, wait);
};
}
}); 用手势放大pdf后,pdfViwer左右滚动条没有在pdf最左边