284 lines
9.7 KiB
JavaScript
284 lines
9.7 KiB
JavaScript
// 周报生成器 v3版本 JavaScript
|
||
togglePreview = function (mode) {
|
||
const previewBtn = document.getElementById('preview-toggle');
|
||
const sourceBtn = document.getElementById('source-toggle');
|
||
const reportContent = document.getElementById('report-content');
|
||
const markdownSource = document.getElementById('markdown-source');
|
||
const sourceContent = document.getElementById('source-content');
|
||
|
||
if (mode === 'preview') {
|
||
previewBtn.classList.add('active');
|
||
sourceBtn.classList.remove('active');
|
||
reportContent.style.display = 'block';
|
||
markdownSource.style.display = 'none';
|
||
} else {
|
||
previewBtn.classList.remove('active');
|
||
sourceBtn.classList.add('active');
|
||
reportContent.style.display = 'none';
|
||
markdownSource.style.display = 'block';
|
||
|
||
// 显示原始Markdown源代码
|
||
const markdown = reportContent.getAttribute('data-markdown');
|
||
sourceContent.textContent = markdown;
|
||
}
|
||
};
|
||
|
||
// 页面加载时获取可用的周次列表
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
loadAvailableWeeks();
|
||
});
|
||
|
||
// 加载可用的周次列表
|
||
function loadAvailableWeeks() {
|
||
fetch('/v3/api/weekly_report/weeks')
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
if (data.success) {
|
||
const weekSelect = document.getElementById('week');
|
||
weekSelect.innerHTML = '<option value="">请选择周次...</option>';
|
||
|
||
data.data.weeks.forEach(week => {
|
||
const option = document.createElement('option');
|
||
option.value = week.week;
|
||
option.textContent = week.display;
|
||
weekSelect.appendChild(option);
|
||
});
|
||
|
||
// 设置默认选择为当前周
|
||
const currentDate = new Date();
|
||
const year = currentDate.getFullYear();
|
||
const weekNumber = getWeekNumber(currentDate);
|
||
const currentWeek = `${year}-${weekNumber.toString().padStart(2, '0')}`;
|
||
|
||
weekSelect.value = currentWeek;
|
||
} else {
|
||
console.error('获取周次列表失败:', data.error);
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('网络错误:', error);
|
||
});
|
||
}
|
||
|
||
// 获取周数
|
||
function getWeekNumber(date) {
|
||
const firstDayOfYear = new Date(date.getFullYear(), 0, 1);
|
||
const pastDaysOfYear = (date - firstDayOfYear) / 86400000;
|
||
return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7);
|
||
}
|
||
|
||
function showLoading(message = '正在生成周报,请稍候...') {
|
||
document.getElementById('loading').style.display = 'block';
|
||
document.getElementById('loading-details').textContent = message;
|
||
document.getElementById('report-container').style.display = 'none';
|
||
document.getElementById('error').style.display = 'none';
|
||
}
|
||
|
||
function hideLoading() {
|
||
document.getElementById('loading').style.display = 'none';
|
||
document.getElementById('loading-details').textContent = '';
|
||
}
|
||
|
||
function showError(message) {
|
||
document.getElementById('error').style.display = 'block';
|
||
document.getElementById('error').textContent = message;
|
||
}
|
||
|
||
function generateCurrentWeekReport() {
|
||
const currentDate = new Date();
|
||
const year = currentDate.getFullYear();
|
||
const weekNumber = getWeekNumber(currentDate);
|
||
const currentWeek = `${year}-${weekNumber.toString().padStart(2, '0')}`;
|
||
|
||
document.getElementById('week').value = currentWeek;
|
||
generateReport();
|
||
}
|
||
|
||
function generateReport() {
|
||
const week = document.getElementById('week').value;
|
||
const useDeepseek = document.getElementById('use-deepseek').checked;
|
||
|
||
if (!week) {
|
||
showError('请选择周次');
|
||
return;
|
||
}
|
||
|
||
showLoading(useDeepseek ? '正在生成周报(使用DeepSeek AI增强)...' : '正在生成周报...');
|
||
|
||
fetch('/v3/api/weekly_report/generate', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
week: week,
|
||
use_deepseek: useDeepseek
|
||
})
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
hideLoading();
|
||
|
||
if (data.success) {
|
||
// 保存原始Markdown内容到data属性
|
||
document.getElementById('report-content').setAttribute('data-markdown', data.data.report);
|
||
|
||
// 使用专业的Markdown解析器将Markdown转换为HTML并显示
|
||
const htmlContent = parseMarkdownWithTables(data.data.report);
|
||
document.getElementById('report-content').innerHTML = htmlContent;
|
||
|
||
// 重置为预览模式
|
||
togglePreview('preview');
|
||
|
||
document.getElementById('report-container').style.display = 'block';
|
||
|
||
// 启用图片导出按钮
|
||
updateImageExportButtonState();
|
||
|
||
// 显示统计数据
|
||
if (data.data.statistics) {
|
||
// 显示分类图表
|
||
if (data.data.statistics.category_breakdown) {
|
||
displayCategoryChart(data.data.statistics.category_breakdown);
|
||
document.getElementById('category-chart').style.display = 'block';
|
||
}
|
||
}
|
||
} else {
|
||
showError('生成周报失败:' + data.error);
|
||
}
|
||
})
|
||
.catch(error => {
|
||
hideLoading();
|
||
showError('网络错误:' + error.message);
|
||
});
|
||
}
|
||
|
||
function displayCategoryChart(categories) {
|
||
const categoryItems = document.getElementById('category-items');
|
||
categoryItems.innerHTML = '';
|
||
|
||
Object.entries(categories).forEach(([category, percentage]) => {
|
||
const categoryItem = document.createElement('div');
|
||
categoryItem.className = 'category-item';
|
||
categoryItem.innerHTML = `
|
||
<span style="min-width: 120px;">${category}</span>
|
||
<div class="category-bar" style="width: ${percentage * 2}px;"></div>
|
||
<span style="min-width: 40px; text-align: right;">${percentage}%</span>
|
||
`;
|
||
categoryItems.appendChild(categoryItem);
|
||
});
|
||
}
|
||
|
||
function exportReport() {
|
||
const reportContent = document.getElementById('report-content').getAttribute('data-markdown');
|
||
if (!reportContent) {
|
||
showError('请先生成周报');
|
||
return;
|
||
}
|
||
|
||
const week = document.getElementById('week').value;
|
||
const blob = new Blob([reportContent], {type: 'text/markdown'});
|
||
const url = URL.createObjectURL(blob);
|
||
const a = document.createElement('a');
|
||
a.href = url;
|
||
a.download = `运营周报_v3_${week}.md`;
|
||
document.body.appendChild(a);
|
||
a.click();
|
||
document.body.removeChild(a);
|
||
URL.revokeObjectURL(url);
|
||
}
|
||
|
||
/**
|
||
* 导出报告为图片
|
||
*/
|
||
async function exportReportAsImage() {
|
||
const exportBtn = document.getElementById('image-export-btn');
|
||
const reportContent = document.getElementById('report-content');
|
||
|
||
if (!reportContent || reportContent.innerHTML.trim() === '') {
|
||
alert('请先生成周报内容');
|
||
return;
|
||
}
|
||
|
||
if (typeof convertAndDownload === 'undefined') {
|
||
alert('图片导出功能未加载,请刷新页面重试');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
// 显示加载中状态
|
||
const originalText = exportBtn.textContent;
|
||
exportBtn.disabled = true;
|
||
exportBtn.textContent = '导出中...';
|
||
|
||
// 获取当前周数 - 修复选择器
|
||
const week = document.getElementById('week').value || '当前';
|
||
const filename = `运营周报_v3_${week}.png`;
|
||
|
||
console.log('开始导出图片...');
|
||
console.log('目标元素:', reportContent);
|
||
console.log('文件名:', filename);
|
||
|
||
await convertAndDownload(reportContent, filename, {
|
||
scale: 2,
|
||
backgroundColor: '#ffffff',
|
||
useCORS: true,
|
||
allowTaint: false
|
||
});
|
||
|
||
console.log('图片导出成功');
|
||
alert('图片导出成功!');
|
||
|
||
} catch (error) {
|
||
console.error('图片导出失败:', error);
|
||
alert(`图片导出失败: ${error.message || error}`);
|
||
} finally {
|
||
// 恢复按钮状态
|
||
exportBtn.disabled = false;
|
||
exportBtn.textContent = '导出图片';
|
||
}
|
||
}
|
||
|
||
// 启用/禁用图片导出按钮
|
||
function updateImageExportButtonState() {
|
||
const reportContent = document.getElementById('report-content');
|
||
const imageExportBtn = document.getElementById('image-export-btn');
|
||
|
||
if (reportContent && reportContent.innerHTML.trim()) {
|
||
imageExportBtn.disabled = false;
|
||
imageExportBtn.classList.remove('disabled');
|
||
} else {
|
||
imageExportBtn.disabled = true;
|
||
imageExportBtn.classList.add('disabled');
|
||
}
|
||
}
|
||
|
||
// 支持回车键生成报告
|
||
document.getElementById('week').addEventListener('keypress', function (e) {
|
||
if (e.key === 'Enter') {
|
||
generateReport();
|
||
}
|
||
});
|
||
|
||
// 使用专业的Markdown解析器解析Markdown文本,支持表格
|
||
function parseMarkdownWithTables(markdown) {
|
||
if (typeof MarkdownParser !== 'undefined' && typeof MergeTableParser !== 'undefined') {
|
||
const parser = new MarkdownParser();
|
||
return parser.parseFull(markdown);
|
||
} else {
|
||
// 回退到简单的markdown渲染
|
||
return markdownToHtml(markdown);
|
||
}
|
||
}
|
||
|
||
// 简单的Markdown转HTML函数(备用)
|
||
function markdownToHtml(markdown) {
|
||
return markdown
|
||
.replace(/\n/g, '<br>')
|
||
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
||
.replace(/\*(.*?)\*/g, '<em>$1</em>')
|
||
.replace(/^#\s+(.*)$/gm, '<h1>$1</h1>')
|
||
.replace(/^##\s+(.*)$/gm, '<h2>$1</h2>')
|
||
.replace(/^###\s+(.*)$/gm, '<h3>$1</h3>')
|
||
.replace(/`(.*?)`/g, '<code>$1</code>');
|
||
} |