|
|
@@ -15,7 +15,7 @@ import requests
|
|
|
import yaml
|
|
|
|
|
|
|
|
|
-VERSION = "2.1.2"
|
|
|
+VERSION = "2.2.0"
|
|
|
|
|
|
|
|
|
# === 配置管理 ===
|
|
|
@@ -1509,6 +1509,7 @@ def render_html_content(
|
|
|
<meta charset="UTF-8">
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
<title>热点新闻分析</title>
|
|
|
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js" integrity="sha512-BNaRQnYJYiPSqHHDb58B0yaPfCu+Wgds8Gp/gU33kqBtgNS4tSPHuGibyoeqMV/TJlSKda6FXzoEyYGjTe+vXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
|
<style>
|
|
|
* { box-sizing: border-box; }
|
|
|
body {
|
|
|
@@ -1534,6 +1535,33 @@ def render_html_content(
|
|
|
color: white;
|
|
|
padding: 32px 24px;
|
|
|
text-align: center;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+
|
|
|
+ .save-btn {
|
|
|
+ position: absolute;
|
|
|
+ top: 16px;
|
|
|
+ right: 16px;
|
|
|
+ background: rgba(255, 255, 255, 0.2);
|
|
|
+ border: 1px solid rgba(255, 255, 255, 0.3);
|
|
|
+ color: white;
|
|
|
+ padding: 8px 16px;
|
|
|
+ border-radius: 6px;
|
|
|
+ cursor: pointer;
|
|
|
+ font-size: 13px;
|
|
|
+ font-weight: 500;
|
|
|
+ transition: all 0.2s ease;
|
|
|
+ backdrop-filter: blur(10px);
|
|
|
+ }
|
|
|
+
|
|
|
+ .save-btn:hover {
|
|
|
+ background: rgba(255, 255, 255, 0.3);
|
|
|
+ border-color: rgba(255, 255, 255, 0.5);
|
|
|
+ transform: translateY(-1px);
|
|
|
+ }
|
|
|
+
|
|
|
+ .save-btn:active {
|
|
|
+ transform: translateY(0);
|
|
|
}
|
|
|
|
|
|
.header-title {
|
|
|
@@ -1837,22 +1865,63 @@ def render_html_content(
|
|
|
font-family: 'SF Mono', Consolas, monospace;
|
|
|
}
|
|
|
|
|
|
+ .footer {
|
|
|
+ margin-top: 32px;
|
|
|
+ padding: 20px 24px;
|
|
|
+ background: #f8f9fa;
|
|
|
+ border-top: 1px solid #e5e7eb;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .footer-content {
|
|
|
+ font-size: 13px;
|
|
|
+ color: #6b7280;
|
|
|
+ line-height: 1.4;
|
|
|
+ }
|
|
|
+
|
|
|
+ .footer-link {
|
|
|
+ color: #4f46e5;
|
|
|
+ text-decoration: none;
|
|
|
+ font-weight: 500;
|
|
|
+ transition: color 0.2s ease;
|
|
|
+ }
|
|
|
+
|
|
|
+ .footer-link:hover {
|
|
|
+ color: #7c3aed;
|
|
|
+ text-decoration: underline;
|
|
|
+ }
|
|
|
+
|
|
|
+ .project-name {
|
|
|
+ font-weight: 600;
|
|
|
+ color: #374151;
|
|
|
+ }
|
|
|
+
|
|
|
@media (max-width: 480px) {
|
|
|
body { padding: 12px; }
|
|
|
.header { padding: 24px 20px; }
|
|
|
.content { padding: 20px; }
|
|
|
+ .footer { padding: 16px 20px; }
|
|
|
.header-info { grid-template-columns: 1fr; gap: 12px; }
|
|
|
.news-header { gap: 6px; }
|
|
|
.news-content { padding-right: 45px; }
|
|
|
.news-item { gap: 8px; }
|
|
|
.new-item { gap: 8px; }
|
|
|
.news-number { width: 20px; height: 20px; font-size: 12px; }
|
|
|
+ .save-btn {
|
|
|
+ position: static;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ display: block;
|
|
|
+ width: fit-content;
|
|
|
+ margin-left: auto;
|
|
|
+ margin-right: auto;
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
<div class="container">
|
|
|
<div class="header">
|
|
|
+ <button class="save-btn" onclick="saveAsImage()">保存为图片</button>
|
|
|
<div class="header-title">热点新闻分析</div>
|
|
|
<div class="header-info">
|
|
|
<div class="info-item">
|
|
|
@@ -2082,7 +2151,95 @@ def render_html_content(
|
|
|
|
|
|
html += """
|
|
|
</div>
|
|
|
+
|
|
|
+ <div class="footer">
|
|
|
+ <div class="footer-content">
|
|
|
+ 由 <span class="project-name">TrendRadar</span> 生成 ·
|
|
|
+ <a href="https://github.com/sansan0/TrendRadar" target="_blank" class="footer-link">
|
|
|
+ GitHub 开源项目
|
|
|
+ </a>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
+
|
|
|
+ <script>
|
|
|
+ async function saveAsImage() {
|
|
|
+ const button = document.querySelector('.save-btn');
|
|
|
+ const originalText = button.textContent;
|
|
|
+
|
|
|
+ try {
|
|
|
+ button.textContent = '生成中...';
|
|
|
+ button.disabled = true;
|
|
|
+ window.scrollTo(0, 0);
|
|
|
+
|
|
|
+ // 等待页面稳定
|
|
|
+ await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
+
|
|
|
+ // 截图前隐藏按钮
|
|
|
+ button.style.visibility = 'hidden';
|
|
|
+
|
|
|
+ // 再次等待确保按钮完全隐藏
|
|
|
+ await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
+
|
|
|
+ const container = document.querySelector('.container');
|
|
|
+
|
|
|
+ // 获取容器的精确位置和尺寸
|
|
|
+ const rect = container.getBoundingClientRect();
|
|
|
+ const computedStyle = window.getComputedStyle(container);
|
|
|
+
|
|
|
+ const canvas = await html2canvas(container, {
|
|
|
+ backgroundColor: '#ffffff',
|
|
|
+ scale: 1.5,
|
|
|
+ useCORS: true,
|
|
|
+ allowTaint: false,
|
|
|
+ imageTimeout: 10000,
|
|
|
+ removeContainer: false,
|
|
|
+ foreignObjectRendering: false,
|
|
|
+ logging: false,
|
|
|
+ width: container.offsetWidth,
|
|
|
+ height: container.offsetHeight,
|
|
|
+ x: 0,
|
|
|
+ y: 0,
|
|
|
+ scrollX: 0,
|
|
|
+ scrollY: 0,
|
|
|
+ windowWidth: window.innerWidth,
|
|
|
+ windowHeight: window.innerHeight
|
|
|
+ });
|
|
|
+
|
|
|
+ button.style.visibility = 'visible';
|
|
|
+
|
|
|
+ const link = document.createElement('a');
|
|
|
+ const now = new Date();
|
|
|
+ const filename = `TrendRadar_热点新闻分析_${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')}_${String(now.getHours()).padStart(2, '0')}${String(now.getMinutes()).padStart(2, '0')}.png`;
|
|
|
+
|
|
|
+ link.download = filename;
|
|
|
+ link.href = canvas.toDataURL('image/png', 1.0);
|
|
|
+
|
|
|
+ // 触发下载
|
|
|
+ document.body.appendChild(link);
|
|
|
+ link.click();
|
|
|
+ document.body.removeChild(link);
|
|
|
+
|
|
|
+ button.textContent = '保存成功!';
|
|
|
+ setTimeout(() => {
|
|
|
+ button.textContent = originalText;
|
|
|
+ button.disabled = false;
|
|
|
+ }, 2000);
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ button.style.visibility = 'visible';
|
|
|
+ button.textContent = '保存失败';
|
|
|
+ setTimeout(() => {
|
|
|
+ button.textContent = originalText;
|
|
|
+ button.disabled = false;
|
|
|
+ }, 2000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ document.addEventListener('DOMContentLoaded', function() {
|
|
|
+ window.scrollTo(0, 0);
|
|
|
+ });
|
|
|
+ </script>
|
|
|
</body>
|
|
|
</html>
|
|
|
"""
|