| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747 |
- <!DOCTYPE html>
- <html>
- <head>
- <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 {
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
- margin: 0;
- padding: 16px;
- background: #fafafa;
- color: #333;
- line-height: 1.5;
- }
- .container {
- max-width: 600px;
- margin: 0 auto;
- background: white;
- border-radius: 12px;
- overflow: hidden;
- box-shadow: 0 2px 16px rgba(0, 0, 0, 0.06);
- }
- .header {
- background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
- color: white;
- padding: 32px 24px;
- text-align: center;
- position: relative;
- }
- .save-buttons {
- position: absolute;
- top: 16px;
- right: 16px;
- display: flex;
- gap: 8px;
- }
- .save-btn {
- 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);
- white-space: nowrap;
- }
- .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);
- }
- .save-btn:disabled {
- opacity: 0.6;
- cursor: not-allowed;
- }
- .header-title {
- font-size: 22px;
- font-weight: 700;
- margin: 0 0 20px 0;
- }
- .header-info {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 16px;
- font-size: 14px;
- opacity: 0.95;
- }
- .info-item {
- text-align: center;
- }
- .info-label {
- display: block;
- font-size: 12px;
- opacity: 0.8;
- margin-bottom: 4px;
- }
- .info-value {
- font-weight: 600;
- font-size: 16px;
- }
- .content {
- padding: 24px;
- }
- .word-group {
- margin-bottom: 40px;
- }
- .word-group:first-child {
- margin-top: 0;
- }
- .word-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 20px;
- padding-bottom: 8px;
- border-bottom: 1px solid #f0f0f0;
- }
- .word-info {
- display: flex;
- align-items: center;
- gap: 12px;
- }
- .word-name {
- font-size: 17px;
- font-weight: 600;
- color: #1a1a1a;
- }
- .word-count {
- color: #666;
- font-size: 13px;
- font-weight: 500;
- }
- .word-count.hot {
- color: #dc2626;
- font-weight: 600;
- }
- .word-count.warm {
- color: #ea580c;
- font-weight: 600;
- }
- .word-index {
- color: #999;
- font-size: 12px;
- }
- .news-item {
- margin-bottom: 20px;
- padding: 16px 0;
- border-bottom: 1px solid #f5f5f5;
- position: relative;
- display: flex;
- gap: 12px;
- align-items: center;
- }
- .news-item:last-child {
- border-bottom: none;
- }
- .news-number {
- color: #999;
- font-size: 13px;
- font-weight: 600;
- min-width: 20px;
- text-align: center;
- flex-shrink: 0;
- background: #f8f9fa;
- border-radius: 50%;
- width: 24px;
- height: 24px;
- display: flex;
- align-items: center;
- justify-content: center;
- align-self: flex-start;
- margin-top: 8px;
- }
- .news-content {
- flex: 1;
- min-width: 0;
- }
- .news-header {
- display: flex;
- align-items: center;
- gap: 8px;
- margin-bottom: 8px;
- flex-wrap: wrap;
- }
- .source-name {
- color: #666;
- font-size: 12px;
- font-weight: 500;
- }
- .rank-num {
- color: #fff;
- background: #6b7280;
- font-size: 10px;
- font-weight: 700;
- padding: 2px 6px;
- border-radius: 10px;
- min-width: 18px;
- text-align: center;
- }
- .rank-num.top {
- background: #dc2626;
- }
- .rank-num.high {
- background: #ea580c;
- }
- .time-info {
- color: #999;
- font-size: 11px;
- }
- .count-info {
- color: #059669;
- font-size: 11px;
- font-weight: 500;
- }
- .news-title {
- font-size: 15px;
- line-height: 1.4;
- color: #1a1a1a;
- margin: 0;
- }
- .news-link {
- color: #2563eb;
- text-decoration: none;
- }
- .news-link:hover {
- text-decoration: underline;
- }
- .news-link:visited {
- color: #7c3aed;
- }
- .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.6;
- }
- .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-item {
- gap: 8px;
- }
- .news-number {
- width: 20px;
- height: 20px;
- font-size: 12px;
- }
- .save-buttons {
- position: static;
- margin-bottom: 16px;
- display: flex;
- gap: 8px;
- justify-content: center;
- flex-direction: column;
- width: 100%;
- }
- .save-btn {
- width: 100%;
- }
- }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="header">
- <div class="save-buttons">
- <button class="save-btn" onclick="saveAsImage()">保存为图片</button>
- <button class="save-btn" onclick="saveAsMultipleImages()">分段保存</button>
- </div>
- <div class="header-title">热点新闻分析</div>
- <div class="header-info">
- <div class="info-item">
- <span class="info-label">报告类型</span>
- <span class="info-value">当日汇总</span>
- </div>
- <div class="info-item">
- <span class="info-label">新闻总数</span>
- <span class="info-value">387 条</span>
- </div>
- <div class="info-item">
- <span class="info-label">热点新闻</span>
- <span class="info-value">5 条</span>
- </div>
- <div class="info-item">
- <span class="info-label">生成时间</span>
- <span class="info-value">06-16 07:17</span>
- </div>
- </div>
- </div>
- <div class="content">
- <div class="word-group">
- <div class="word-header">
- <div class="word-info">
- <div class="word-name">ai 人工智能</div>
- <div class="word-count hot">3 条</div>
- </div>
- <div class="word-index">1/4</div>
- </div>
- <div class="news-item">
- <div class="news-number">1</div>
- <div class="news-content">
- <div class="news-header">
- <span class="source-name">财联社热门</span>
- <span class="rank-num high">7-8</span>
- <span class="time-info">00:23~07:17</span>
- <span class="count-info">15次</span>
- </div>
- <div class="news-title">
- <a href="https://www.cls.cn/detail/2057563" target="_blank" class="news-link">上市首日暴涨140% 军用无人机公司登陆纽交所 AI打造产品核心竞争力</a>
- </div>
- </div>
- </div>
- <div class="news-item">
- <div class="news-number">2</div>
- <div class="news-content">
- <div class="news-header">
- <span class="source-name">tieba</span>
- <span class="rank-num">18-19</span>
- <span class="time-info">00:23~07:17</span>
- <span class="count-info">15次</span>
- </div>
- <div class="news-title">
- <a href="https://tieba.baidu.com/hottopic/browse/hottopic?topic_id=28342819&topic_name=%E4%BC%8A%E6%9C%97%E7%96%91%E7%94%A8AI%E4%BC%AA%E9%80%A0%E4%BB%A5%E5%86%9BF35%E6%AE%8B%E9%AA%B8%E5%9B%BE" target="_blank" class="news-link">伊朗疑用AI伪造以军F35残骸图</a>
- </div>
- </div>
- </div>
- <div class="news-item">
- <div class="news-number">3</div>
- <div class="news-content">
- <div class="news-header">
- <span class="source-name">zhihu</span>
- <span class="rank-num top">5-13</span>
- <span class="time-info">00:23~07:17</span>
- <span class="count-info">15次</span>
- </div>
- <div class="news-title">
- <a href="https://www.zhihu.com/question/596907281" target="_blank" class="news-link">罗杰·彭罗斯说无论意识是什么,都绝对不是一种计算。意思是:任何 AI 都不可能产生意识?</a>
- </div>
- </div>
- </div>
- </div>
- <div class="word-group">
- <div class="word-header">
- <div class="word-info">
- <div class="word-name">DeepSeek 梁文锋</div>
- <div class="word-count">1 条</div>
- </div>
- <div class="word-index">2/4</div>
- </div>
- <div class="news-item">
- <div class="news-number">1</div>
- <div class="news-content">
- <div class="news-header">
- <span class="source-name">华尔街见闻</span>
- <span class="rank-num high">8-9</span>
- <span class="time-info">00:23~07:17</span>
- <span class="count-info">15次</span>
- </div>
- <div class="news-title">
- <a href="https://wallstreetcn.com/articles/3749141" target="_blank" class="news-link">恒生生科指数1月以来涨超60%,中国创新药的"DeepSeek时刻"超过了AI</a>
- </div>
- </div>
- </div>
- </div>
- <div class="word-group">
- <div class="word-header">
- <div class="word-info">
- <div class="word-name">哪吒 饺子</div>
- <div class="word-count">1 条</div>
- </div>
- <div class="word-index">3/4</div>
- </div>
- <div class="news-item">
- <div class="news-number">1</div>
- <div class="news-content">
- <div class="news-header">
- <span class="source-name">百度热搜</span>
- <span class="rank-num">24-30</span>
- <span class="time-info">00:57~06:55</span>
- <span class="count-info">7次</span>
- </div>
- <div class="news-title">
- <a href="https://www.baidu.com/s?wd=%E3%80%8A%E5%93%AA%E5%90%922%E3%80%8B%E7%89%87%E6%96%B9%E6%88%96%E5%88%86%E8%B4%A652%E4%BA%BF%E5%85%83" target="_blank" class="news-link">《哪吒2》片方或分账52亿元</a>
- </div>
- </div>
- </div>
- </div>
- <div class="word-group">
- <div class="word-header">
- <div class="word-info">
- <div class="word-name">米哈游 原神 星穹铁道</div>
- <div class="word-count">1 条</div>
- </div>
- <div class="word-index">4/4</div>
- </div>
- <div class="news-item">
- <div class="news-number">1</div>
- <div class="news-content">
- <div class="news-header">
- <span class="source-name">zhihu</span>
- <span class="rank-num top">5</span>
- <span class="time-info">06:55~07:17</span>
- <span class="count-info">2次</span>
- </div>
- <div class="news-title">
- <a href="https://www.zhihu.com/question/1905395386765537540" target="_blank" class="news-link">目前原神所有自机角色谁最有可能出新形态?</a>
- </div>
- </div>
- </div>
- </div>
- </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 = event.target;
- const originalText = button.textContent;
-
- try {
- button.textContent = '生成中...';
- button.disabled = true;
- window.scrollTo(0, 0);
-
- await new Promise(resolve => setTimeout(resolve, 200));
-
- const buttons = document.querySelector('.save-buttons');
- buttons.style.visibility = 'hidden';
-
- await new Promise(resolve => setTimeout(resolve, 100));
-
- const container = document.querySelector('.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
- });
-
- buttons.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) {
- const buttons = document.querySelector('.save-buttons');
- buttons.style.visibility = 'visible';
- button.textContent = '保存失败';
- setTimeout(() => {
- button.textContent = originalText;
- button.disabled = false;
- }, 2000);
- }
- }
-
- async function saveAsMultipleImages() {
- const button = event.target;
- const originalText = button.textContent;
- const container = document.querySelector('.container');
- const scale = 1.5;
- const maxHeight = 5000 / scale;
-
- try {
- button.textContent = '分析中...';
- button.disabled = true;
-
- const wordGroups = Array.from(container.querySelectorAll('.word-group'));
- const header = container.querySelector('.header');
- const footer = container.querySelector('.footer');
-
- const containerRect = container.getBoundingClientRect();
- const elements = [];
-
- elements.push({
- type: 'header',
- element: header,
- top: 0,
- bottom: header.offsetHeight,
- height: header.offsetHeight
- });
-
- wordGroups.forEach(group => {
- const groupRect = group.getBoundingClientRect();
- const wordHeader = group.querySelector('.word-header');
- if (wordHeader) {
- const headerRect = wordHeader.getBoundingClientRect();
- elements.push({
- type: 'word-header',
- top: groupRect.top - containerRect.top,
- bottom: headerRect.bottom - containerRect.top,
- height: headerRect.height
- });
- }
-
- group.querySelectorAll('.news-item').forEach(item => {
- const rect = item.getBoundingClientRect();
- elements.push({
- type: 'news-item',
- top: rect.top - containerRect.top,
- bottom: rect.bottom - containerRect.top,
- height: rect.height
- });
- });
- });
-
- const footerRect = footer.getBoundingClientRect();
- elements.push({
- type: 'footer',
- top: footerRect.top - containerRect.top,
- bottom: footerRect.bottom - containerRect.top,
- height: footer.offsetHeight
- });
-
- const segments = [];
- let currentSegment = { start: 0, end: 0, height: 0 };
- let headerHeight = header.offsetHeight;
- currentSegment.height = headerHeight;
-
- for (let i = 1; i < elements.length; i++) {
- const element = elements[i];
- const potentialHeight = element.bottom - currentSegment.start;
-
- if (potentialHeight > maxHeight && currentSegment.height > headerHeight) {
- currentSegment.end = elements[i - 1].bottom;
- segments.push(currentSegment);
-
- currentSegment = {
- start: currentSegment.end,
- end: 0,
- height: element.bottom - currentSegment.end
- };
- } else {
- currentSegment.height = potentialHeight;
- currentSegment.end = element.bottom;
- }
- }
-
- if (currentSegment.height > 0) {
- currentSegment.end = container.offsetHeight;
- segments.push(currentSegment);
- }
-
- button.textContent = `生成中 (0/${segments.length})...`;
-
- const buttons = document.querySelector('.save-buttons');
- buttons.style.visibility = 'hidden';
-
- const images = [];
- for (let i = 0; i < segments.length; i++) {
- const segment = segments[i];
- button.textContent = `生成中 (${i + 1}/${segments.length})...`;
-
- const tempContainer = document.createElement('div');
- tempContainer.style.cssText = `
- position: absolute;
- left: -9999px;
- top: 0;
- width: ${container.offsetWidth}px;
- background: white;
- `;
-
- const clonedContainer = container.cloneNode(true);
- const clonedButtons = clonedContainer.querySelector('.save-buttons');
- if (clonedButtons) {
- clonedButtons.style.display = 'none';
- }
-
- tempContainer.appendChild(clonedContainer);
- document.body.appendChild(tempContainer);
-
- await new Promise(resolve => setTimeout(resolve, 100));
-
- const canvas = await html2canvas(clonedContainer, {
- backgroundColor: '#ffffff',
- scale: scale,
- useCORS: true,
- allowTaint: false,
- imageTimeout: 10000,
- logging: false,
- width: container.offsetWidth,
- height: segment.end - segment.start,
- x: 0,
- y: segment.start,
- windowWidth: window.innerWidth,
- windowHeight: window.innerHeight
- });
-
- images.push(canvas.toDataURL('image/png', 1.0));
- document.body.removeChild(tempContainer);
- }
-
- buttons.style.visibility = 'visible';
-
- const now = new Date();
- const baseFilename = `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')}`;
-
- for (let i = 0; i < images.length; i++) {
- const link = document.createElement('a');
- link.download = `${baseFilename}_part${i + 1}.png`;
- link.href = images[i];
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
-
- await new Promise(resolve => setTimeout(resolve, 100));
- }
-
- button.textContent = `已保存 ${segments.length} 张图片!`;
- setTimeout(() => {
- button.textContent = originalText;
- button.disabled = false;
- }, 2000);
-
- } catch (error) {
- console.error('分段保存失败:', error);
- const buttons = document.querySelector('.save-buttons');
- buttons.style.visibility = 'visible';
- button.textContent = '保存失败';
- setTimeout(() => {
- button.textContent = originalText;
- button.disabled = false;
- }, 2000);
- }
- }
-
- document.addEventListener('DOMContentLoaded', function() {
- window.scrollTo(0, 0);
- });
- </script>
- </body>
- </html>
|