Add legacy Electron app
build-winui / winui (push) Has been cancelled

This commit is contained in:
QWQLwToo
2026-06-26 13:29:02 +08:00
parent 079ee4eaeb
commit 46a3674381
115 changed files with 55280 additions and 0 deletions
+155
View File
@@ -0,0 +1,155 @@
// src/js/tools/baiduHotTool.js
import BaseTool from '../baseTool.js';
class BaiduHotTool extends BaseTool {
constructor() {
super('baidu-hot', '百度热搜');
this.abortController = null;
// 定义分榜信息
this.boards = [
{ id: 'hot-search', name: '热搜榜' },
{ id: 'hot-meme', name: '热梗榜' },
{ id: 'finance', name: '财经榜' },
{ id: 'livelihood', name: '民生榜' },
];
}
render() {
return `
<div class="page-container" style="display: flex; flex-direction: column; height: 100%;">
<div class="section-header">
<button id="back-to-toolbox-btn" class="back-btn ripple"><i class="fas fa-arrow-left"></i> 返回工具箱</button>
<h1 style="flex-grow: 1; text-align: center;">${this.name}</h1>
</div>
<div class="sys-info-tabs baidu-hot-tabs" id="baidu-hot-tabs">
${this.boards.map(board => `
<button class="sys-info-tab" data-board-name="${board.name}">${board.name}</button>
`).join('')}
</div>
<div id="baidu-hot-results-container" class="content-area" style="padding: 0 20px 10px 10px; flex-grow: 1; overflow-y: auto;">
<div class="loading-container">
<img src="./assets/loading.gif" alt="加载中..." class="loading-gif">
<p class="loading-text">正在加载热搜...</p>
</div>
</div>
</div>`;
}
init() {
this._log('工具已初始化');
document.getElementById('back-to-toolbox-btn')?.addEventListener('click', () => {
window.mainPage.navigateTo('toolbox');
window.mainPage.updateActiveNavButton(document.getElementById('toolbox-btn'));
});
const tabs = document.querySelectorAll('#baidu-hot-tabs .sys-info-tab');
tabs.forEach(tab => {
tab.addEventListener('click', (e) => {
tabs.forEach(t => t.classList.remove('active'));
e.currentTarget.classList.add('active');
const boardName = e.currentTarget.dataset.boardName;
this._fetchAndRenderData(boardName);
});
});
// 默认加载第一个榜单
if (tabs.length > 0) {
tabs[0].click();
}
}
async _fetchAndRenderData(boardName) {
if (this.abortController) this.abortController.abort();
this.abortController = new AbortController();
const resultsContainer = document.getElementById('baidu-hot-results-container');
if (!resultsContainer) return;
resultsContainer.innerHTML = `
<div class="loading-container">
<img src="./assets/loading.gif" alt="加载中..." class="loading-gif">
<p class="loading-text">正在加载 ${boardName}...</p>
</div>`;
try {
const apiUrl = `https://api.suyanw.cn/api/bdrs.php?msg=${encodeURIComponent(boardName)}`;
const response = await fetch(apiUrl, { signal: this.abortController.signal });
if (!response.ok) throw new Error(`网络请求失败: ${response.status}`);
const blob = await response.blob();
await window.electronAPI.addTraffic(blob.size);
const textData = await blob.text();
this._log(`成功获取 ${boardName} 数据`);
this._renderList(textData);
} catch (error) {
if (error.name === 'AbortError') return;
const errorMessage = error.message.includes('API') ? error.message : `解析数据失败或网络异常`;
this._log(`获取 ${boardName} 失败: ${errorMessage}`);
resultsContainer.innerHTML = `<div class="loading-container"><p class="error-message"><i class="fas fa-exclamation-triangle"></i> 获取失败: ${errorMessage}</p></div>`;
}
}
_renderList(textData) {
const resultsContainer = document.getElementById('baidu-hot-results-container');
const lines = textData.split('\n').filter(line => line.trim() !== '' && !line.startsWith('----'));
if (lines.length === 0) {
throw new Error('API返回数据为空或格式无法解析');
}
// [修复] 改为使用 Flex 布局的 div 结构 (灵动岛风格),而非之前的 table
const itemsHtml = lines.map((line, index) => {
const match = line.match(/^(\d+)(.*)/);
if (!match) return '';
const rank = match[1];
const title = match[2].trim();
const searchUrl = `https://www.baidu.com/s?wd=${encodeURIComponent(title)}`;
let rankClass = '';
let iconClass = 'fa-fire';
let iconColor = 'var(--text-secondary)';
if (rank <= 3) {
rankClass = `rank-top-3 rank-${rank}`; // 复用 hotboardTool 的样式
iconClass = 'fa-fire-alt';
iconColor = 'var(--error-color)';
}
// 使用 island-card 样式 (在 style.css 中已定义)
return `
<div class="island-card ripple" style="height: auto; min-height: 60px; margin-bottom: 10px; padding: 15px;" data-link="${searchUrl}">
<div class="island-icon-box" style="width: 40px; height: 40px; border-radius: 10px; background: rgba(var(--bg-color-rgb), 0.5);">
<span class="hotboard-rank ${rankClass}" style="margin: 0; font-size: 16px;">${rank}</span>
</div>
<div class="island-content" style="flex-grow: 1; padding-left: 15px;">
<h3 class="island-title" style="margin: 0; white-space: normal;">${title}</h3>
</div>
<div class="island-action">
<i class="fas fa-chevron-right arrow-icon"></i>
</div>
</div>
`;
}).join('');
resultsContainer.innerHTML = `<div style="animation: contentFadeIn 0.5s;">${itemsHtml}</div>`;
resultsContainer.querySelectorAll('.island-card[data-link]').forEach(card => {
card.addEventListener('click', (e) => {
e.preventDefault();
window.electronAPI.openExternalLink(e.currentTarget.dataset.link);
});
});
}
destroy() {
if (this.abortController) this.abortController.abort();
this._log('工具已销毁');
super.destroy();
}
}
export default BaiduHotTool;