* 开发环境启动排查清单 — 页面交互
* 仅使用 localStorage 保存勾选进度;无网络请求、无遥测。
*/
(function () {
"use strict";
var Core = window.ChecklistCore;
if (!Core) {
document.body.innerHTML =
"<p>无法加载核心脚本 checklist-core.js。请确认与本页位于同一文件夹。</p>";
return;
}
var state = Core.emptyState();
var els = {};
function $(id) {
return document.getElementById(id);
}
function loadState() {
try {
var raw = window.localStorage.getItem(Core.STORAGE_KEY);
state = Core.parseStorageJson(raw);
} catch (e) {
state = Core.emptyState();
}
}
function persist() {
state.updatedAt = new Date().toISOString();
try {
window.localStorage.setItem(Core.STORAGE_KEY, JSON.stringify(state));
setSaveHint("进度已保存在本机浏览器(可清除)。");
} catch (e) {
setSaveHint("无法写入本地存储(可能被禁用);当前会话仍可继续勾选。");
}
updateProgress();
}
function setSaveHint(text) {
if (els.saveHint) els.saveHint.textContent = text;
}
function renderSymptoms() {
var box = els.symptomList;
box.innerHTML = "";
Core.SYMPTOMS.forEach(function (s) {
var id = "sym-" + s.id;
var label = document.createElement("label");
label.className = "symptom-card";
label.htmlFor = id;
var input = document.createElement("input");
input.type = "checkbox";
input.id = id;
input.checked = !!state.symptoms[s.id];
input.addEventListener("change", function () {
state.symptoms[s.id] = input.checked;
persist();
renderSteps();
renderDiffHint();
});
var title = document.createElement("span");
title.className = "symptom-title";
title.textContent = s.label;
var hint = document.createElement("span");
hint.className = "symptom-hint";
hint.textContent = s.hint;
label.appendChild(input);
label.appendChild(title);
label.appendChild(hint);
box.appendChild(label);
});
}
function renderDiffHint() {
var selected = Core.selectedSymptomIds(state);
var show =
selected.length === 0 ||
(selected.indexOf("blank") >= 0 &&
selected.indexOf("empty_workspace") >= 0);
els.diffHint.hidden = !show && selected.length !== 0;
if (selected.length === 0) {
els.diffHint.hidden = false;
}
}
function renderSteps() {
var host = els.stepsHost;
host.innerHTML = "";
var groups = Core.stepsForSelection(Core.selectedSymptomIds(state));
if (groups.length === 0) {
var empty = document.createElement("p");
empty.className = "muted";
empty.textContent = "请先勾选上方至少一种症状,再查看对应排查步骤。";
host.appendChild(empty);
updateProgress();
return;
}
groups.forEach(function (g) {
var section = document.createElement("section");
section.className = "step-group";
section.setAttribute("aria-labelledby", "group-" + g.symptomId);
var h = document.createElement("h3");
h.id = "group-" + g.symptomId;
h.textContent = g.label;
section.appendChild(h);
var list = document.createElement("ol");
list.className = "step-list";
g.steps.forEach(function (step) {
var li = document.createElement("li");
li.className = "step-item";
var head = document.createElement("div");
head.className = "step-head";
var title = document.createElement("strong");
title.textContent = step.title;
var select = document.createElement("select");
select.className = "status-select";
select.setAttribute("aria-label", step.title + " 的状态");
["pending", "checked", "na"].forEach(function (key) {
var opt = document.createElement("option");
opt.value = key;
opt.textContent = Core.STATUS[key];
select.appendChild(opt);
});
select.value = state.steps[step.id] || "pending";
select.addEventListener("change", function () {
state.steps[step.id] = select.value;
persist();
li.dataset.status = select.value;
});
head.appendChild(title);
head.appendChild(select);
var detail = document.createElement("p");
detail.className = "step-detail";
detail.textContent = step.detail;
li.dataset.status = select.value;
li.appendChild(head);
li.appendChild(detail);
list.appendChild(li);
});
section.appendChild(list);
host.appendChild(section);
});
updateProgress();
}
function updateProgress() {
var p = Core.countProgress(state);
els.progressText.textContent =
"已选步骤 " +
p.total +
" 项:已检查 " +
p.checked +
" · 不适用 " +
p.na +
" · 待验证 " +
p.pending;
}
function renderNotes() {
els.notes.value = state.notes || "";
}
function showPreview(md) {
els.preview.hidden = false;
els.previewText.textContent = md;
els.preview.scrollIntoView({ behavior: "smooth", block: "nearest" });
}
function hidePreview() {
els.preview.hidden = true;
els.previewText.textContent = "";
}
function downloadText(filename, text) {
var blob = new Blob([text], { type: "text/markdown;charset=utf-8" });
var url = URL.createObjectURL(blob);
var a = document.createElement("a");
a.href = url;
a.download = filename;
a.rel = "noopener";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
setTimeout(function () {
URL.revokeObjectURL(url);
}, 1000);
}
function onExportPreview() {
var md = Core.exportMarkdown(state, new Date().toISOString());
showPreview(md);
setSaveHint("已生成预览。确认无敏感信息后再下载。");
}
function onExportDownload() {
var md = Core.exportMarkdown(state, new Date().toISOString());
showPreview(md);
downloadText("startup-checklist-record.md", md);
setSaveHint("已触发本机下载。请再次检查文件内容后再分享。");
}
function onClearStorage() {
if (
!window.confirm(
"清除本机保存的勾选进度?当前页面上的选择也会重置。"
)
) {
return;
}
try {
window.localStorage.removeItem(Core.STORAGE_KEY);
} catch (e) {
}
state = Core.emptyState();
hidePreview();
renderAll();
setSaveHint("已清除本机进度。");
}
function onResetSession() {
if (!window.confirm("重置当前勾选与备注?(仍会写入空进度到本机存储)")) {
return;
}
state = Core.emptyState();
hidePreview();
renderAll();
persist();
setSaveHint("已重置。");
}
function renderAll() {
renderSymptoms();
renderDiffHint();
renderSteps();
renderNotes();
updateProgress();
}
function bind() {
els.symptomList = $("symptom-list");
els.diffHint = $("diff-hint");
els.stepsHost = $("steps-host");
els.progressText = $("progress-text");
els.saveHint = $("save-hint");
els.notes = $("notes");
els.preview = $("export-preview");
els.previewText = $("export-preview-text");
els.notes.addEventListener("input", function () {
state.notes = els.notes.value.slice(0, 2000);
persist();
});
$("btn-export-preview").addEventListener("click", onExportPreview);
$("btn-export-download").addEventListener("click", onExportDownload);
$("btn-hide-preview").addEventListener("click", hidePreview);
$("btn-clear-storage").addEventListener("click", onClearStorage);
$("btn-reset").addEventListener("click", onResetSession);
}
document.addEventListener("DOMContentLoaded", function () {
bind();
loadState();
renderAll();
setSaveHint(
state.updatedAt
? "已恢复本机上次进度。"
: "勾选后会自动保存在本机浏览器。"
);
});
})();