${escapeHtml(item.name)}
+ v${escapeHtml(item.version || "-")} + ${escapeHtml(CATEGORY_NAMES[item.category] || "其他")} +${escapeHtml(item.description || "暂无简介")}
+ +From c8cfe683619fdc426c1a495caf4c9ad1cf0530d0 Mon Sep 17 00:00:00 2001 From: lwt <215586800@qq.com> Date: Mon, 8 Jun 2026 20:53:14 +0800 Subject: [PATCH] feat: add software download center --- .gitignore | 8 + admin/software.html | 137 ++++ assets/css/components.css | 12 + assets/css/software.css | 1012 ++++++++++++++++++++++++++++++ assets/icons/software.svg | 19 + assets/js/login.js | 61 ++ assets/js/software-admin.js | 214 +++++++ assets/js/software.js | 321 ++++++++++ index.html | 19 + login.html | 51 ++ package-lock.json | 1007 +++++++++++++++++++++++++++++ package.json | 15 + server/data/players.json | 12 + server/data/software.json | 85 +++ server/server.js | 617 ++++++++++++++++++ server/uploads/icons/.gitkeep | 1 + server/uploads/packages/.gitkeep | 1 + software.html | 146 +++++ 18 files changed, 3738 insertions(+) create mode 100644 .gitignore create mode 100644 admin/software.html create mode 100644 assets/css/software.css create mode 100644 assets/icons/software.svg create mode 100644 assets/js/login.js create mode 100644 assets/js/software-admin.js create mode 100644 assets/js/software.js create mode 100644 login.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 server/data/players.json create mode 100644 server/data/software.json create mode 100644 server/server.js create mode 100644 server/uploads/icons/.gitkeep create mode 100644 server/uploads/packages/.gitkeep create mode 100644 software.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..78b8f96 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +node_modules/ +server/uploads/packages/* +server/uploads/icons/* +!server/uploads/packages/.gitkeep +!server/uploads/icons/.gitkeep +.env +npm-debug.log* +server-test.*.log diff --git a/admin/software.html b/admin/software.html new file mode 100644 index 0000000..ff821cd --- /dev/null +++ b/admin/software.html @@ -0,0 +1,137 @@ + + +
+ + + + +令牌通过请求头发送到服务端,用于新增、上传和更新软件。
+正在加载...
+${escapeHtml(item.description || "暂无简介")}
+ +${escapeHtml(item.description || "暂无简介")}
+ + ${downloadButton(item)} +${escapeHtml(item.description || "暂无简介")}
+${escapeHtml(item.description || "暂无简介")}
+ +暂无办公软件。
`; + els.topicDev.innerHTML = byCategory("dev").map(topicItem).join("") || `暂无开发工具。
`; + els.topicSecurity.innerHTML = byCategory("security").map(topicItem).join("") || `暂无安全工具。
`; +} + +function render() { + const filtered = getFilteredItems(); + const featured = filtered.filter((item) => item.featured).slice(0, 8); + + els.featuredList.innerHTML = (featured.length ? featured : filtered.slice(0, 8)).map(softwareCard).join(""); + els.allList.innerHTML = filtered.map(softwareRow).join(""); + els.emptyState.hidden = filtered.length > 0; + els.resultSummary.textContent = `共找到 ${filtered.length} 款软件`; + renderStats(); + renderTopics(); + renderPlayerStatus(); +} + +async function loadAuth() { + try { + const response = await fetch("/api/auth/me", { headers: { Accept: "application/json" } }); + const payload = await response.json(); + state.player = payload.authenticated ? payload.player : null; + } catch { + state.player = null; + } finally { + state.authLoaded = true; + render(); + } +} + +async function loadSoftware() { + try { + const response = await fetch("/api/software", { headers: { Accept: "application/json" } }); + if (!response.ok) throw new Error(`HTTP ${response.status}`); + state.items = normalizeItems(await response.json()); + } catch (error) { + state.items = FALLBACK_SOFTWARE; + } + render(); +} + +els.year.textContent = new Date().getFullYear(); +els.keyword.addEventListener("input", (event) => { + state.keyword = event.target.value; + render(); +}); + +els.categoryButtons.forEach((button) => { + button.addEventListener("click", () => { + state.category = button.dataset.category; + els.categoryButtons.forEach((item) => item.classList.toggle("is-active", item === button)); + render(); + }); +}); + +els.refreshButton.addEventListener("click", loadSoftware); +els.playerStatus.addEventListener("click", async (event) => { + if (!event.target.closest("#player-logout")) return; + await fetch("/api/auth/logout", { method: "POST", headers: { Accept: "application/json" } }); + state.player = null; + state.authLoaded = true; + render(); +}); + +loadAuth(); +loadSoftware(); diff --git a/index.html b/index.html index 83c602f..c7b0002 100644 --- a/index.html +++ b/index.html @@ -33,9 +33,21 @@ 连接状态 + + + 软件下载 + diff --git a/login.html b/login.html new file mode 100644 index 0000000..80b5ddc --- /dev/null +++ b/login.html @@ -0,0 +1,51 @@ + + + + + + + +Player Access
+登录后即可下载软件中心里的安装包。
+Official Download Center
+统一沉淀安装包、版本号、更新记录和下载入口,让常用软件找得到、下得准、更新快。
+常用安装包、版本和更新记录集中展示。
+正在加载软件列表...
+没有找到匹配的软件。
+