Add software version manifest management

This commit is contained in:
lwt
2026-06-08 22:02:51 +08:00
parent 228d625e16
commit b272026ac9
8 changed files with 508 additions and 26 deletions
+5 -1
View File
@@ -82,6 +82,7 @@ function renderList() {
<div class="app-meta">
<span>${item.active === false ? "已隐藏" : "前台显示"}</span>
<span>${item.featured ? "精选" : "普通"}</span>
<span>${item.versionManifest ? "version.json" : "无版本清单"}</span>
<span>${escapeHtml(item.size || "未知大小")}</span>
<span>${formatDate(item.updatedAt)}</span>
</div>
@@ -128,6 +129,7 @@ function resetForm() {
els.form.elements.publisher.value = "sumi.work";
els.form.elements.sort.value = "100";
els.form.elements.active.checked = true;
els.form.elements.versionManifestContent.value = "";
els.formTitle.textContent = "新增软件";
els.submitButton.textContent = "保存软件";
setStatus(els.formStatus, "");
@@ -150,9 +152,11 @@ function fillForm(item) {
els.form.elements.featured.checked = Boolean(item.featured);
els.form.elements.icon.value = "";
els.form.elements.package.value = "";
els.form.elements.versionManifest.value = "";
els.form.elements.versionManifestContent.value = item.versionManifest ? JSON.stringify(item.versionManifest, null, 2) : "";
els.formTitle.textContent = `更新 ${item.name}`;
els.submitButton.textContent = "更新软件";
setStatus(els.formStatus, "已载入当前软件,选择新安装包即可发布新版本。", "ok");
setStatus(els.formStatus, item.versionManifest ? "已载入当前软件,可替换安装包或直接编辑版本内容 JSON。" : "已载入当前软件,上传安装包且版本内容留空时会自动生成 version.json。", "ok");
window.scrollTo({ top: 0, behavior: "smooth" });
}
+32
View File
@@ -79,6 +79,7 @@ const els = {
topicDev: document.querySelector("#topic-dev"),
topicSecurity: document.querySelector("#topic-security"),
playerStatus: document.querySelector("#player-status"),
authLinks: [...document.querySelectorAll("[data-player-auth]")],
};
function escapeHtml(value = "") {
@@ -114,6 +115,10 @@ function getDownloadHref(item) {
return `/api/software/${encodeURIComponent(item.id)}/download`;
}
function getLoginHref(next = "/software.html") {
return `login.html?next=${encodeURIComponent(next)}`;
}
function iconMarkup(item) {
const safeName = escapeHtml(item.name);
if (item.iconUrl) {
@@ -281,6 +286,16 @@ async function loadAuth() {
state.authLoaded = true;
render();
}
return state.player;
}
async function ensurePlayer(next) {
if (!state.authLoaded) {
await loadAuth();
}
if (state.player) return true;
window.location.href = getLoginHref(next);
return false;
}
async function loadSoftware() {
@@ -309,6 +324,23 @@ els.categoryButtons.forEach((button) => {
});
els.refreshButton.addEventListener("click", loadSoftware);
els.authLinks.forEach((link) => {
link.addEventListener("click", async (event) => {
const href = link.getAttribute("href") || "/software.html";
const next = link.dataset.next || href;
if (state.authLoaded && state.player) return;
event.preventDefault();
const isAuthenticated = await ensurePlayer(next);
if (!isAuthenticated) return;
if (href.startsWith("#")) {
document.querySelector(href)?.scrollIntoView({ behavior: "smooth" });
return;
}
window.location.href = href;
});
});
els.playerStatus.addEventListener("click", async (event) => {
if (!event.target.closest("#player-logout")) return;
await fetch("/api/auth/logout", { method: "POST", headers: { Accept: "application/json" } });