feat: 新增思想实验室模块与配套功能

- 新增5个物理仿真实验室:黑洞模拟、日地轨道、3D太阳系、π推导、拉格朗日点
- 新增思想实验室后端路由与鉴权逻辑
- 首页新增思想实验室页签与前端渲染逻辑
- 修复中韩半导体监控标的配置错误
- 新增市场技能推送白名单过滤逻辑与单元测试
This commit is contained in:
yangxiangyuan
2026-08-06 13:39:48 +08:00
parent 6a7a2b089a
commit ea379116cc
19 changed files with 2831 additions and 17 deletions
+45 -1
View File
@@ -100,6 +100,7 @@ class ToolboxHome {
this.loadIcons();
this.loadBookmarks();
this.loadTools();
this.loadThoughtLabs();
this.loadFitnessDiaryReminder();
this.loadWeeklyReportReminder();
}
@@ -143,6 +144,7 @@ class ToolboxHome {
tabBar.innerHTML = `
<button class="tab-btn active" data-tab="high" type="button">Yang's 高频 Tools</button>
<button class="tab-btn" data-tab="low" type="button">Yang's 低频 Tools</button>
<button class="tab-btn" data-tab="labs" type="button">Yang's 思想实验室</button>
<button class="tab-btn" data-tab="bookmarks" type="button">Yang's 书签导航</button>
`;
@@ -167,6 +169,15 @@ class ToolboxHome {
lowToolGrid.id = 'tool-grid-low';
lowToolsPage.appendChild(lowToolGrid);
// 思想实验室页面(卡片形式与高/低频一致,数据来自 /api/thought_lab/labs)
const labsPage = document.createElement('div');
labsPage.className = 'tab-page';
labsPage.dataset.tab = 'labs';
const labGrid = document.createElement('div');
labGrid.className = 'tool-grid';
labGrid.id = 'tool-grid-labs';
labsPage.appendChild(labGrid);
// 书签导航页面
const bookmarksPage = document.createElement('div');
bookmarksPage.className = 'tab-page';
@@ -271,6 +282,7 @@ class ToolboxHome {
tabPages.appendChild(highToolsPage);
tabPages.appendChild(lowToolsPage);
tabPages.appendChild(bookmarksPage);
tabPages.appendChild(labsPage);
// 组装页面
mainContainer.appendChild(header);
@@ -362,9 +374,12 @@ class ToolboxHome {
this.tabBar = tabBar;
this.highToolGrid = highToolGrid;
this.lowToolGrid = lowToolGrid;
this.labGrid = labGrid;
this.toolsPage = highToolsPage;
this.bookmarksPage = bookmarksPage;
this.tabPages = [highToolsPage, lowToolsPage, bookmarksPage];
this.labsPage = labsPage;
this.labTools = [];
this.tabPages = [highToolsPage, lowToolsPage, bookmarksPage, labsPage];
this.bookmarkContainer = bookmarkSections;
this.bookmarkEmpty = bookmarkEmpty;
this.bookmarkAdmin = bookmarkAdmin;
@@ -469,6 +484,35 @@ class ToolboxHome {
renderGrid(this.lowToolGrid, this.lowFreqTools);
}
async loadThoughtLabs() {
try {
const res = await fetch('/api/thought_lab/labs?t=' + Date.now());
if (!res.ok) return;
const data = await res.json();
if (!data || !data.ok) return;
this.labTools = Array.isArray(data.labs) ? data.labs : [];
this.renderLabs();
} catch (err) {
console.error('加载思想实验室列表失败:', err);
}
}
renderLabs() {
if (!this.labGrid) return;
this.labGrid.innerHTML = '';
this.labTools.forEach(lab => {
const card = document.createElement('a');
card.className = 'tool-card';
card.href = lab.href || '#';
if (lab.desc) card.title = lab.desc;
card.innerHTML = `
<div class="tool-icon">${lab.icon || '🧪'}</div>
<div class="tool-text">${lab.name || lab.id || '未命名 lab'}</div>
`;
this.labGrid.appendChild(card);
});
}
openAdmin() {
this.adminVisible = true;
if (this.bookmarkAdmin) this.bookmarkAdmin.classList.add('active');