const apps = { "trip-card": { title: "通信大数据行程卡", icon: "trip-card/static/img_arrow@2x.png", link: "trip-card/index.html", color: "#2ba667", help_text: "

点击手机号或途经地点可以修改相关信息。

", menu: [], }, "ykm": { title: "粤康码", icon: "ykm/static/yss.jpeg", link: "ykm/index.html", color: "#aacc00", help_text: "

点击姓名、城市、场所地址等可以修改对应

点击二维码可以切换 “粤康码” 及 “粤康码场所通行” 页面。

", menu: [ { title: "场所", icon: "place", link: "ykm/checkin.html" }, { title: "核酸", icon: "vaccines", link: "ykm/detail.html" }, { title: "广州", icon: "map", link: "gwongzau-hc/checkin.html" }, ], }, "skm": { title: "苏康码", icon: "skm/src/jszwfw.png", link: "skm/index.html", color: "#a3a8eb99", help_text: "

点击姓名、证件号、场所地址等可以修改对应信息;

点击二维码可以展示签到页面。

", menu: [ { title: "场所", icon: "place", link: "skm/index.html#checkin" }, { title: "核酸", icon: "vaccines", link: "skm/detail.html" }, ], }, "jkb": { title: "北京健康宝", icon: "jkb/static/logo_jiankangbao1@2x.png", link: "jkb/index.html", color: "#fa6666", help_text: "

点击姓名、证件号可以修改对应信息;

点击照片可以更改或移除照片,超过 4MB 的图片可能无法在本地保存;

点击右上角二维码标志可以在 “本人健康码自查询” 和 “本人信息扫码登记” 间切换;

点击 “未见异常” 可以切换 “通勤” 标志。

", menu: [ { title: "扫描", icon: "qr_code_scanner", link: "jkb/scan.html" }, { title: "场所", icon: "place", link: "jkb/checkin.html" }, ], }, "tfjkt": { title: "四川天府健康通", icon: "tfjkt/static/message-icon.png", link: "tfjkt/index.html", color: "#0ba099", help_text: "

点击姓名、证件号、场所地址等可以修改对应信息;

点击“扫场所码”展示场所码。

", menu: [{ title: "场所", icon: "place", link: "tfjkt/checkin.html" }], }, "ssm": { title: "随申码", icon: "ssm/static/ssbapp-logo.png", link: "ssm/index.html", color: "#bf4046", help_text: "

点击姓名、证件号、场所地址等可以修改对应信息;

点击照片可以更改或移除照片,超过 4MB 的图片可能无法在本地保存;

点击二维码展示场所码。

", menu: [{ title: "场所", icon: "place", link: "ssm/checkin.html" }], }, "shandong-hc": { title: "山东健康通行码", icon: "shandong-hc/static/logo.png", link: "shandong-hc/index.html", color: "#68b82e", help_text: "

点击姓名、证件号、场所地址等可以修改对应信息;

点击二维码可以切换到场所码页面。

", menu: [ { title: "场所", icon: "place", link: "shandong-hc/index.html#checkin", }, { title: "威海", icon: "map", link: "weihai-hc/index.html" }, ], contributors: [ { name: "LibertyNeverDies", description: "参与制作", style: "namestrip", }, ], }, "hubei-hc": { title: "湖北健康码", icon: "hubei-hc/static/logo.png", link: "hubei-hc/index.html", color: "#9a1640", help_text: "

点击姓名、证件号码可以修改对应信息。

", }, "wuhan-hc": { title: "湖北健康码·武汉", icon: "wuhan-hc/static/QRlogo.png", link: "wuhan-hc/index.html", color: "#af9bff", help_text: "

点击姓名、证件号等可以修改对应信息;

点击通信行程卡“点击核验”可以添加行程戳;

点击“已采样”标记可以隐藏该标记。

", }, "hunan-hc": { title: "湖南电子健康卡", icon: "hunan-hc/static/logo-b18dcf7bf55c412ec04989061d0512ad.png", link: "hunan-hc/index.html", help_text: "

点击姓名、证件号、采样点、场所地址等可以修改对应信息。

点击“二维码”可以切换“健康卡”与“场所码”

", menu: [{ title: "场所", icon: "place", link: "hunan-hc/checkin.html"}], contributors: [ { name: "uodedcli", description: "参与制作", style: "namestrip" }, ], }, "fujian-hc": { title: "福建健康码", icon: "fujian-hc/static/jkm_logo.png", link: "fujian-hc/index.html", color: "#3a5eff", help_text: "

点击姓名、证件号可以修改对应信息;

点击 “扫一扫” 进入场所张贴码。

", menu: [{ title: "场所", icon: "place", link: "fujian-hc/checkin.html" }], }, "zhejiang-hc": { title: "浙江健康码", icon: "zhejiang-hc/static/logo.ico", link: "zhejiang-hc/index.html", color: "#57ac6c", help_text: "

点击城市名、姓名、证件号可以修改对应信息。

", }, "henan-hc": { title: "豫康码", icon: "henan-hc/static/logo.png", link: "henan-hc/index.html", color: "#e84336", help_text: "

点击城市名、姓名、证件号可以修改对应信息;

点击二维码可以切换至“疫情防控场所码”。

", menu: [{ title: "场所", icon: "place", link: "henan-hc/checkin.html" }], }, "tianjin-hc": { title: "天津数字防疫", icon: "tianjin-hc/static/img/logo.png", link: "tianjin-hc/index.html", help_text: "

前往“我的”一栏后点击任意位置,在配置页填写好姓名和身份证号、保存并返回后才可使用。

" }, "shaanxi-hc": { title: "陕西一码通", icon: "shaanxi-hc/static/myCode/greenLogo.png", link: "shaanxi-hc/index.html", color: "#0bae81", help_text: "

点击地点名称、姓名、证件号可以修改对应信息;

点击核酸检测时间可以切换小时数;

点击“已采样”可以切换今日是否采样。

", menu: [{ title: "场所", icon: "place", link: "shaanxi-hc/checkin.html" }], } }; function onIconFail(t) { t.closest(".app").classList.add("inactivated"); } function render() { let html = ""; for (const [name, app] of Object.entries(apps)) { let menu_html = ""; if (app.menu) { for (const menu_item of app.menu) { menu_html += `
${menu_item.title}
`; } } menu_html += `
= 0 && "active" || "" }" data-role="pin">
`; if (app.help_text) { menu_html += `
`; } let credits_html = ""; if (app.contributors) { for (const contributor of app.contributors) { if (contributor.style == "namestrip") { credits_html += `
${contributor.name} ${contributor.description}
`; } else if (contributor.style == "text") { credits_html += `
${contributor.name} ${contributor.description}
`; } } } html += `
${app.title}
${menu_html}
使用说明
${app.help_text} ${credits_html ? `
致谢
${credits_html}
` : ""}
`; } document.querySelector(".apps-list").innerHTML = html; const elements = [ ...document.querySelectorAll(".app:not(.inactivated)"), ...document.getElementsByClassName("app-menu-item") ]; if (elements.length) { for (const element of elements) { const data_link = element.attributes["data-link"] && element.attributes["data-link"].value; const data_role = element.attributes["data-role"] && element.attributes["data-role"].value; const parent_app = element.closest(".app"); if (data_link) { element.addEventListener("click", (e) => { e.stopPropagation(); if (element.classList.contains("inactivated")) return; // try { // navigator.serviceWorker.controller.postMessage({ // type: "download", // content: parent_app.attributes["data-link"].value // }); // } catch (e) {} window.location.href = data_link; }); } else if (data_role == "help") { element.addEventListener("click", (e) => { e.stopPropagation(); if (!element.classList.contains("active")) { document.querySelectorAll(".app-help").forEach(element => { element.classList.remove("active"); }); element.classList.add("active"); parent_app.querySelector(".app-help").style.display = "block"; } else { element.classList.remove("active"); parent_app.querySelector(".app-help").style.display = "none"; } }); } else if (data_role == "pin") { const item_id = parent_app.attributes["data-app-name"] && parent_app.attributes["data-app-name"].value; if (item_id) { element.addEventListener("click", (e) => { e.stopPropagation(); let list = localStorage.getItem("pinned") ? localStorage.getItem("pinned").split(",") : []; if (!element.classList.contains("active")) { element.classList.add("active"); parent_app.style.order = -1; list.push(item_id); localStorage.setItem("pinned", list.join(",")); try { const app_name = parent_app.attributes["data-app-name"].value; navigator.serviceWorker.controller.postMessage({ type: "download", content: app_name }); } catch (e) {} } else { element.classList.remove("active"); parent_app.style.order = 0; list = list.filter(x => x != item_id); if (list.length) localStorage.setItem("pinned", list.join(",")); else localStorage.removeItem("pinned"); } }); } } } } const pinned_list = localStorage.getItem("pinned") ? localStorage.getItem("pinned").split(",") : []; if (pinned_list) { for (const element of document.querySelectorAll(".app:not(.inactivated)") || []) { if (pinned_list.includes(element.attributes["data-app-name"].value)) { element.style.order = -1; } element.addEventListener("touchstart", (e) => { if (!(e.target.classList && e.target.classList[0].startsWith("app-menu-item"))) element.classList.add("selected"); }); element.addEventListener("touchmove", () => { element.classList.remove("selected"); }); element.addEventListener("touchend", () => { element.classList.remove("selected"); }); element.addEventListener("touchcancel", () => { element.classList.remove("selected"); }); } } for (const element of document.querySelectorAll(".app-menu-item[data-role=link]") || []) { element.addEventListener("touchstart", () => { element.classList.add("active"); }); element.addEventListener("touchmove", () => { element.classList.remove("active"); }); element.addEventListener("touchend", () => { element.classList.remove("active"); }); element.addEventListener("touchcancel", () => { element.classList.remove("active"); }); } for (const element of document.querySelectorAll(".app-help") || []) { element.addEventListener("click", (e) => { e.stopPropagation(); }); } window.updateServiceWorker = () => {}; if ('serviceWorker' in navigator) { navigator.serviceWorker.register('./service-worker.js', { scope: "./" }).then((e) => { window.updateServiceWorker = (t) => { t && (t.innerText = "正在检查更新..."); e.addEventListener('updatefound', () => { window.location.reload(); }); e.update().then((reg) => { if (!reg.installing) t && (t.innerText = "未发现更新"); else t && (t.innerText = "正在应用更新..."); }).catch(() => { t && (t.innerText = "检查更新失败"); }); }; let c = window.setInterval(() => { if (navigator.serviceWorker.controller) { window.clearInterval(c); // document.querySelector(".sw-progress").style.display = "block"; // document.querySelector(".sw-progress-bar").style.display = "block"; navigator.serviceWorker.controller.postMessage({ type: "download", content: ["root", "common", "trip-card"] .concat(localStorage.getItem("pinned") ? localStorage.getItem("pinned").split(",") : []) .filter((v,i,a)=>a.indexOf(v)==i) }); window.setInterval(() => { navigator.serviceWorker.controller.postMessage({ type: "check", }); }, 4000); } }, 300); }).catch((e) => { // document.querySelector(".sw-status").innerText = "页面预加载失败"; }); const setCached = (item) => { if (!item) return; const app = document.querySelector(`.app[data-app-name=${item}]`); app && (app.querySelector(".app-title-icon").attributes.src.value = "common/icons/download_done.svg"); }; navigator.serviceWorker.addEventListener("message", (e) => { if (!e.data) return; if (e.data.type == "progress") { // const percentage = parseInt(e.data.content * 100) + "%"; // document.querySelector(".sw-progress").innerText = percentage; // document.querySelector(".sw-progress").style.opacity = 0.4 + 0.6 * e.data.content; // document.querySelector(".sw-progress-bar-fill").style.width = percentage; } else if (e.data.type == "complete") { document.getElementById("sw-help-text").style.display = "flex"; // document.querySelector(".sw-progress-bar-fill").style.width = "100%"; // document.querySelector(".sw-status").innerHTML = ""; // window.setTimeout(() => { // document.querySelector(".sw-status").style.display = "none"; // }, 2000); const cached_apps = e.data.content.cached; if (typeof(cached_apps) == "string") { setCached(cached_apps); } else { for (const item of cached_apps) { setCached(item); } } if (e.data.content.version) { document.getElementById("last-update-version").innerText = `(${e.data.content.version})`; } } else if (e.data.type == "reload") { window.location.reload(); } }); } document.getElementById("clear-local-data").addEventListener("click", () => { if (navigator.serviceWorker && navigator.serviceWorker.controller) window.confirm('要清除全部填充信息与页面缓存吗?') && clearCache(); else window.confirm('要清除全部填充信息吗?') && clearCache(); }) if (!(navigator.standalone || window.matchMedia("(display-mode: standalone)").matches)) { document.querySelector(".sw-status").innerHTML = `
添加至主屏幕
`; } else { document.querySelector(".sw-status").innerHTML = `
帮助
`; } } function toggleDisplay(selector, flex = false) { const element = document.querySelector(selector); if (!element) return false; if (!element.style.display || element.style.display == "none") { element.style.display = flex ? "flex" : "block"; } else { element.style.display = "none"; } } function clearCache() { localStorage.clear(); if (navigator.serviceWorker && navigator.serviceWorker.controller) { document.querySelector(".apps-list").innerHTML = `

请稍候...

`; navigator.serviceWorker.controller.postMessage({ type: "clear", }); } else { window.location.reload(); } }