feat: 新增运动节拍训练工具套件与子工具页面

新增运动节拍RepClock全套小程序页面、后端API与数据库服务,新增subhub子工具汇总页面,优化全局主页样式与配置,为web静态资源添加版本缓存参数,补充配套调试脚本
This commit is contained in:
yangxiangyuan
2026-09-09 14:43:06 +08:00
parent db7648eb4d
commit d4bf3627fd
69 changed files with 5759 additions and 297 deletions
+27 -17
View File
@@ -4,18 +4,34 @@
const $status = document.getElementById('status-tag')
const KIT_PAGES = {
personal_collect: 'kits/personal_collect/list.html'
personal_collect: 'kits/personal_collect/list.html',
rep_clock: 'kits/rep_clock/cards.html',
}
const KIT_ICONS = {
personal_collect: '📁'
personal_collect: '📁',
rep_clock: '⏱️',
}
const HERO_EMOJI = '🧘'
const HERO_TITLE = '每一次节奏,都是一次呼吸。'
const HERO_DESC = '独立工具集合,互不干扰,可独立部署,可独立关闭。'
function setStatus(text, cls) {
$status.textContent = text
$status.className = 'status-tag' + (cls ? ' ' + cls : '')
}
function escapeHtml(s) {
if (s === null || s === undefined) return ''
return String(s)
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
}
function renderKits(kits) {
if (!kits || !kits.length) {
$grid.innerHTML = '<div class="kit-empty">暂无可用工具</div>'
@@ -23,13 +39,17 @@
}
$grid.innerHTML = kits.map((kit) => {
const page = KIT_PAGES[kit.id] || '#'
const icon = KIT_ICONS[kit.id] || '🧰'
const icon = kit.icon || KIT_ICONS[kit.id] || '🧰'
const meta = kit.meta ? `<div class="kit-meta">${escapeHtml(kit.meta)}</div>` : ''
return (
`<div class="kit-card" data-kit="${kit.id}" data-page="${page}">` +
`<div class="kit-card" data-kit="${escapeHtml(kit.id)}" data-page="${escapeHtml(page)}">` +
`<div class="kit-icon">${icon}</div>` +
`<div class="kit-name">${escapeHtml(kit.name || kit.id)}</div>` +
`<div class="kit-desc">${escapeHtml(kit.description || '')}</div>` +
`<div class="kit-arrow"><span>进入</span><span>→</span></div>` +
`<div class="kit-body">` +
`<div class="kit-name">${escapeHtml(kit.name || kit.id)}</div>` +
`<div class="kit-desc">${escapeHtml(kit.description || '')}</div>` +
meta +
`</div>` +
`<div class="chevron">›</div>` +
`</div>`
)
}).join('')
@@ -47,16 +67,6 @@
})
}
function escapeHtml(s) {
if (s === null || s === undefined) return ''
return String(s)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
}
async function main() {
try {
if (!api || !api.hub) throw new Error('API 未加载')