feat(web): 为 Sleep Heart 官网补上多语言切换
已部署站点需要按访客语言展示导航与协议正文,因此把文案抽到语言包并加上语言选择。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
f941bf4454
commit
1bbf3b97c7
1
health-web/assets/i18n/ar.js
Normal file
1
health-web/assets/i18n/ar.js
Normal file
File diff suppressed because one or more lines are too long
1
health-web/assets/i18n/de.js
Normal file
1
health-web/assets/i18n/de.js
Normal file
File diff suppressed because one or more lines are too long
1
health-web/assets/i18n/en.js
Normal file
1
health-web/assets/i18n/en.js
Normal file
File diff suppressed because one or more lines are too long
1
health-web/assets/i18n/es.js
Normal file
1
health-web/assets/i18n/es.js
Normal file
File diff suppressed because one or more lines are too long
1
health-web/assets/i18n/fr.js
Normal file
1
health-web/assets/i18n/fr.js
Normal file
File diff suppressed because one or more lines are too long
1
health-web/assets/i18n/it.js
Normal file
1
health-web/assets/i18n/it.js
Normal file
File diff suppressed because one or more lines are too long
1
health-web/assets/i18n/ja.js
Normal file
1
health-web/assets/i18n/ja.js
Normal file
File diff suppressed because one or more lines are too long
1
health-web/assets/i18n/ko.js
Normal file
1
health-web/assets/i18n/ko.js
Normal file
File diff suppressed because one or more lines are too long
1
health-web/assets/i18n/pt.js
Normal file
1
health-web/assets/i18n/pt.js
Normal file
File diff suppressed because one or more lines are too long
1
health-web/assets/i18n/ru.js
Normal file
1
health-web/assets/i18n/ru.js
Normal file
File diff suppressed because one or more lines are too long
1
health-web/assets/i18n/zh-Hans.js
Normal file
1
health-web/assets/i18n/zh-Hans.js
Normal file
File diff suppressed because one or more lines are too long
1
health-web/assets/i18n/zh-Hant.js
Normal file
1
health-web/assets/i18n/zh-Hant.js
Normal file
File diff suppressed because one or more lines are too long
@ -72,14 +72,78 @@ a { color: var(--cyan); }
|
|||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.top-tools {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px 16px;
|
||||||
|
margin-inline-start: auto;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.nav, .foot-links {
|
.nav, .foot-links {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 6px 14px;
|
gap: 6px 14px;
|
||||||
margin-left: auto;
|
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.foot-links { margin-inline-start: auto; }
|
||||||
|
|
||||||
|
.lang-label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lang-label select {
|
||||||
|
max-width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
background: #12243d;
|
||||||
|
color: var(--text);
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
font: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lang-label { display: inline-flex; max-width: 100%; }
|
||||||
|
|
||||||
|
.lang-select {
|
||||||
|
color: var(--text);
|
||||||
|
background: #12243c;
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
font: inherit;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.visually-hidden {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
padding: 0;
|
||||||
|
margin: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[dir="rtl"] .nav,
|
||||||
|
[dir="rtl"] .foot-links {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
[dir="rtl"] .steps li { padding: 10px 46px 10px 10px; }
|
||||||
|
|
||||||
|
[dir="rtl"] .steps li::before { left: auto; right: 10px; }
|
||||||
|
|
||||||
.nav a, .foot-links a {
|
.nav a, .foot-links a {
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@ -196,9 +260,12 @@ h1 { font-size: clamp(1.7rem, 4vw, 2.4rem); }
|
|||||||
.foot strong { color: var(--text); }
|
.foot strong { color: var(--text); }
|
||||||
.foot p { margin: 4px 0 0; }
|
.foot p { margin: 4px 0 0; }
|
||||||
|
|
||||||
|
[dir="rtl"] .panel ul, [dir="rtl"] .panel ol { padding-left: 0; padding-right: 1.2rem; }
|
||||||
|
|
||||||
@media (max-width: 800px) {
|
@media (max-width: 800px) {
|
||||||
.grid { grid-template-columns: 1fr; }
|
.grid { grid-template-columns: 1fr; }
|
||||||
.nav, .foot-links { margin-left: 0; width: 100%; }
|
.top-tools, .foot-links, .lang-label, .nav { margin-inline-start: 0; width: 100%; }
|
||||||
|
.lang-label select, .lang-select { width: 100%; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 420px) {
|
@media (max-width: 420px) {
|
||||||
|
|||||||
166
health-web/assets/site.js
Normal file
166
health-web/assets/site.js
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
(function () {
|
||||||
|
var CODES = ["zh-Hans", "zh-Hant", "en", "ja", "ko", "es", "fr", "de", "pt", "ru", "ar", "th", "vi", "id", "it"];
|
||||||
|
var NAMES = {
|
||||||
|
"zh-Hans": "简体中文",
|
||||||
|
"zh-Hant": "繁體中文",
|
||||||
|
en: "English",
|
||||||
|
ja: "日本語",
|
||||||
|
ko: "한국어",
|
||||||
|
es: "Español",
|
||||||
|
fr: "Français",
|
||||||
|
de: "Deutsch",
|
||||||
|
pt: "Português",
|
||||||
|
ru: "Русский",
|
||||||
|
ar: "العربية",
|
||||||
|
th: "ไทย",
|
||||||
|
vi: "Tiếng Việt",
|
||||||
|
id: "Bahasa Indonesia",
|
||||||
|
it: "Italiano"
|
||||||
|
};
|
||||||
|
var STORAGE = "sleepheart-lang";
|
||||||
|
|
||||||
|
function match(lang) {
|
||||||
|
var l = (lang || "").toLowerCase().replace(/_/g, "-");
|
||||||
|
if (l.indexOf("zh") === 0) {
|
||||||
|
if (l.indexOf("tw") >= 0 || l.indexOf("hk") >= 0 || l.indexOf("mo") >= 0 || l.indexOf("hant") >= 0) return "zh-Hant";
|
||||||
|
return "zh-Hans";
|
||||||
|
}
|
||||||
|
var base = l.split("-")[0];
|
||||||
|
return CODES.indexOf(base) >= 0 ? base : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function preferred() {
|
||||||
|
var saved = "";
|
||||||
|
try { saved = localStorage.getItem(STORAGE) || ""; } catch (e) {}
|
||||||
|
if (CODES.indexOf(saved) >= 0) return saved;
|
||||||
|
var list = navigator.languages || [navigator.language || ""];
|
||||||
|
for (var i = 0; i < list.length; i++) {
|
||||||
|
var hit = match(list[i]);
|
||||||
|
if (hit) return hit;
|
||||||
|
}
|
||||||
|
return "zh-Hans";
|
||||||
|
}
|
||||||
|
|
||||||
|
function esc(s) {
|
||||||
|
return String(s).replace(/[&<>"']/g, function (c) {
|
||||||
|
return { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[c];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function repl(s, a, b) { return String(s).split(a).join(b); }
|
||||||
|
|
||||||
|
function linkify(s, ui) {
|
||||||
|
var html = esc(s);
|
||||||
|
html = repl(html, "{email}", '<a href="mailto:asd272940236@foxmail.com">asd272940236@foxmail.com</a>');
|
||||||
|
html = repl(html, "{home}", '<a href="/">' + esc(ui.backHome) + "</a>");
|
||||||
|
html = repl(html, "{delete}", '<a href="/delete">' + esc(ui.navDelete) + "</a>");
|
||||||
|
html = repl(html, "{privacyDoc}", '<a href="/privacy">' + esc(ui.privacyDoc) + "</a>");
|
||||||
|
html = repl(html, "{privacy}", '<a href="/privacy">' + esc(ui.navPrivacy) + "</a>");
|
||||||
|
html = repl(html, "{terms}", '<a href="/terms">' + esc(ui.navTerms) + "</a>");
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderDoc(blocks, ui) {
|
||||||
|
var html = "";
|
||||||
|
var list = "";
|
||||||
|
function closeList() {
|
||||||
|
if (!list) return;
|
||||||
|
html += list === "ol" ? "</ol>" : "</ul>";
|
||||||
|
list = "";
|
||||||
|
}
|
||||||
|
blocks.forEach(function (block) {
|
||||||
|
var tag = block[0];
|
||||||
|
var inner = linkify(block[1], ui);
|
||||||
|
if (tag === "step" || tag === "li") {
|
||||||
|
var kind = tag === "step" ? "ol" : "ul";
|
||||||
|
if (list && list !== kind) closeList();
|
||||||
|
if (!list) {
|
||||||
|
html += kind === "ol" ? '<ol class="steps">' : "<ul>";
|
||||||
|
list = kind;
|
||||||
|
}
|
||||||
|
html += "<li>" + inner + "</li>";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
closeList();
|
||||||
|
if (tag === "meta") html += '<p class="meta">' + inner + "</p>";
|
||||||
|
else if (tag === "lead") html += '<p class="lead">' + inner + "</p>";
|
||||||
|
else if (tag === "note") html += '<p class="note">' + inner + "</p>";
|
||||||
|
else html += "<" + tag + ">" + inner + "</" + tag + ">";
|
||||||
|
});
|
||||||
|
closeList();
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function apply(pack) {
|
||||||
|
var page = document.body.getAttribute("data-page") || "home";
|
||||||
|
var ui = pack.ui;
|
||||||
|
document.documentElement.lang = pack.htmlLang;
|
||||||
|
document.documentElement.dir = pack.dir || "ltr";
|
||||||
|
if (pack.titles && pack.titles[page]) document.title = pack.titles[page];
|
||||||
|
var desc = document.querySelector('meta[name="description"]');
|
||||||
|
if (desc && pack.desc && pack.desc[page]) desc.setAttribute("content", pack.desc[page]);
|
||||||
|
document.querySelectorAll("[data-i18n]").forEach(function (el) {
|
||||||
|
var key = el.getAttribute("data-i18n");
|
||||||
|
if (ui[key] == null) return;
|
||||||
|
if (el.getAttribute("data-i18n-mode") === "html") el.innerHTML = linkify(ui[key], ui);
|
||||||
|
else el.textContent = ui[key];
|
||||||
|
});
|
||||||
|
document.querySelectorAll("[data-i18n-alt]").forEach(function (el) {
|
||||||
|
var key = el.getAttribute("data-i18n-alt");
|
||||||
|
if (ui[key] != null) el.setAttribute("alt", ui[key]);
|
||||||
|
});
|
||||||
|
var doc = document.getElementById("doc");
|
||||||
|
if (doc && pack[page]) doc.innerHTML = renderDoc(pack[page], ui);
|
||||||
|
var select = document.getElementById("lang-select");
|
||||||
|
if (select) {
|
||||||
|
select.value = pack.code;
|
||||||
|
select.setAttribute("aria-label", ui.langLabel);
|
||||||
|
}
|
||||||
|
var label = document.querySelector(".lang-label span");
|
||||||
|
if (label) label.textContent = ui.langLabel;
|
||||||
|
var nav = document.querySelector(".nav");
|
||||||
|
if (nav) nav.setAttribute("aria-label", ui.navAria);
|
||||||
|
var foot = document.querySelector(".foot-links");
|
||||||
|
if (foot) foot.setAttribute("aria-label", ui.footAria);
|
||||||
|
}
|
||||||
|
|
||||||
|
function load(code) {
|
||||||
|
if (window.SH_PACKS && window.SH_PACKS[code]) return Promise.resolve(window.SH_PACKS[code]);
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
var s = document.createElement("script");
|
||||||
|
s.src = "/assets/i18n/" + code + ".js?v=20261011lang";
|
||||||
|
s.onload = function () {
|
||||||
|
if (window.SH_PACKS && window.SH_PACKS[code]) resolve(window.SH_PACKS[code]);
|
||||||
|
else reject(new Error("missing pack"));
|
||||||
|
};
|
||||||
|
s.onerror = function () { reject(new Error("load")); };
|
||||||
|
document.head.appendChild(s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function boot() {
|
||||||
|
var select = document.getElementById("lang-select");
|
||||||
|
if (select && !select.options.length) {
|
||||||
|
CODES.forEach(function (code) {
|
||||||
|
var opt = document.createElement("option");
|
||||||
|
opt.value = code;
|
||||||
|
opt.textContent = NAMES[code];
|
||||||
|
select.appendChild(opt);
|
||||||
|
});
|
||||||
|
select.addEventListener("change", function () {
|
||||||
|
var code = select.value;
|
||||||
|
try { localStorage.setItem(STORAGE, code); } catch (e) {}
|
||||||
|
load(code).then(apply).catch(function () {
|
||||||
|
if (window.SH_PACKS && window.SH_PACKS["zh-Hans"]) apply(window.SH_PACKS["zh-Hans"]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var code = preferred();
|
||||||
|
load(code).then(apply).catch(function () {
|
||||||
|
if (window.SH_PACKS && window.SH_PACKS["zh-Hans"]) apply(window.SH_PACKS["zh-Hans"]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", boot);
|
||||||
|
else boot();
|
||||||
|
})();
|
||||||
@ -6,27 +6,33 @@
|
|||||||
<title>注销 — Sleep Heart</title>
|
<title>注销 — Sleep Heart</title>
|
||||||
<meta name="description" content="Sleep Heart 应用内注销账号的真实入口和实际效果。" />
|
<meta name="description" content="Sleep Heart 应用内注销账号的真实入口和实际效果。" />
|
||||||
<link rel="icon" href="/assets/icon.png" type="image/png" />
|
<link rel="icon" href="/assets/icon.png" type="image/png" />
|
||||||
<link rel="stylesheet" href="/assets/site.css" />
|
<link rel="stylesheet" href="/assets/site.css?v=20261011lang" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body data-page="delete">
|
||||||
<header class="top">
|
<header class="top">
|
||||||
<div class="wrap top-inner">
|
<div class="wrap top-inner">
|
||||||
<a class="brand" href="/">
|
<a class="brand" href="/">
|
||||||
<img src="/assets/icon.png" width="40" height="40" alt="" />
|
<img src="/assets/icon.png" width="40" height="40" alt="" />
|
||||||
<span>Sleep Heart</span>
|
<span>Sleep Heart</span>
|
||||||
</a>
|
</a>
|
||||||
|
<div class="top-tools">
|
||||||
<nav class="nav" aria-label="页面">
|
<nav class="nav" aria-label="页面">
|
||||||
<a href="/">首页</a>
|
<a href="/" data-i18n="navHome">首页</a>
|
||||||
<a href="/download">下载</a>
|
<a href="/download" data-i18n="navDownload">下载</a>
|
||||||
<a href="/delete" aria-current="page">注销</a>
|
<a href="/delete" data-i18n="navDelete" aria-current="page">注销</a>
|
||||||
<a href="/privacy">隐私协议</a>
|
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
|
||||||
<a href="/terms">用户协议</a>
|
<a href="/terms" data-i18n="navTerms">用户协议</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
<label class="lang-label">
|
||||||
|
<span data-i18n="langLabel">语言</span>
|
||||||
|
<select id="lang-select"></select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<article class="panel">
|
<article class="panel" id="doc">
|
||||||
<h1>注销账号</h1>
|
<h1>注销账号</h1>
|
||||||
<p class="lead">注销在 Sleep Heart 应用里完成。本网站不提供在线注销表单。</p>
|
<p class="lead">注销在 Sleep Heart 应用里完成。本网站不提供在线注销表单。</p>
|
||||||
<h2>入口</h2>
|
<h2>入口</h2>
|
||||||
@ -55,16 +61,18 @@
|
|||||||
<div class="wrap foot-inner">
|
<div class="wrap foot-inner">
|
||||||
<div>
|
<div>
|
||||||
<strong>Sleep Heart</strong>
|
<strong>Sleep Heart</strong>
|
||||||
<p>上海微雨如酥网络设计有限公司</p>
|
<p data-i18n="company">上海微雨如酥网络设计有限公司</p>
|
||||||
</div>
|
</div>
|
||||||
<nav class="foot-links" aria-label="页脚">
|
<nav class="foot-links" aria-label="页脚">
|
||||||
<a href="/">首页</a>
|
<a href="/" data-i18n="navHome">首页</a>
|
||||||
<a href="/download">下载</a>
|
<a href="/download" data-i18n="navDownload">下载</a>
|
||||||
<a href="/delete" aria-current="page">注销</a>
|
<a href="/delete" data-i18n="navDelete" aria-current="page">注销</a>
|
||||||
<a href="/privacy">隐私协议</a>
|
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
|
||||||
<a href="/terms">用户协议</a>
|
<a href="/terms" data-i18n="navTerms">用户协议</a>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
<script src="/assets/i18n/zh-Hans.js?v=20261011lang"></script>
|
||||||
|
<script src="/assets/site.js?v=20261011lang"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -6,27 +6,33 @@
|
|||||||
<title>下载 — Sleep Heart</title>
|
<title>下载 — Sleep Heart</title>
|
||||||
<meta name="description" content="Sleep Heart 下载说明。应用即将上线,此处不放置未核实的应用商店地址。" />
|
<meta name="description" content="Sleep Heart 下载说明。应用即将上线,此处不放置未核实的应用商店地址。" />
|
||||||
<link rel="icon" href="/assets/icon.png" type="image/png" />
|
<link rel="icon" href="/assets/icon.png" type="image/png" />
|
||||||
<link rel="stylesheet" href="/assets/site.css" />
|
<link rel="stylesheet" href="/assets/site.css?v=20261011lang" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body data-page="download">
|
||||||
<header class="top">
|
<header class="top">
|
||||||
<div class="wrap top-inner">
|
<div class="wrap top-inner">
|
||||||
<a class="brand" href="/">
|
<a class="brand" href="/">
|
||||||
<img src="/assets/icon.png" width="40" height="40" alt="" />
|
<img src="/assets/icon.png" width="40" height="40" alt="" />
|
||||||
<span>Sleep Heart</span>
|
<span>Sleep Heart</span>
|
||||||
</a>
|
</a>
|
||||||
|
<div class="top-tools">
|
||||||
<nav class="nav" aria-label="页面">
|
<nav class="nav" aria-label="页面">
|
||||||
<a href="/">首页</a>
|
<a href="/" data-i18n="navHome">首页</a>
|
||||||
<a href="/download" aria-current="page">下载</a>
|
<a href="/download" data-i18n="navDownload" aria-current="page">下载</a>
|
||||||
<a href="/delete">注销</a>
|
<a href="/delete" data-i18n="navDelete">注销</a>
|
||||||
<a href="/privacy">隐私协议</a>
|
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
|
||||||
<a href="/terms">用户协议</a>
|
<a href="/terms" data-i18n="navTerms">用户协议</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
<label class="lang-label">
|
||||||
|
<span data-i18n="langLabel">语言</span>
|
||||||
|
<select id="lang-select"></select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<article class="panel">
|
<article class="panel" id="doc">
|
||||||
<h1>下载</h1>
|
<h1>下载</h1>
|
||||||
<p class="lead">Sleep Heart 是 iPhone 应用,应用内展示名为 SleepHeart。</p>
|
<p class="lead">Sleep Heart 是 iPhone 应用,应用内展示名为 SleepHeart。</p>
|
||||||
<p class="note">应用即将上线。目前没有已核实、可以公开打开的 App Store 或安卓应用市场地址,本页不放置商店链接。</p>
|
<p class="note">应用即将上线。目前没有已核实、可以公开打开的 App Store 或安卓应用市场地址,本页不放置商店链接。</p>
|
||||||
@ -39,16 +45,18 @@
|
|||||||
<div class="wrap foot-inner">
|
<div class="wrap foot-inner">
|
||||||
<div>
|
<div>
|
||||||
<strong>Sleep Heart</strong>
|
<strong>Sleep Heart</strong>
|
||||||
<p>上海微雨如酥网络设计有限公司</p>
|
<p data-i18n="company">上海微雨如酥网络设计有限公司</p>
|
||||||
</div>
|
</div>
|
||||||
<nav class="foot-links" aria-label="页脚">
|
<nav class="foot-links" aria-label="页脚">
|
||||||
<a href="/">首页</a>
|
<a href="/" data-i18n="navHome">首页</a>
|
||||||
<a href="/download" aria-current="page">下载</a>
|
<a href="/download" data-i18n="navDownload" aria-current="page">下载</a>
|
||||||
<a href="/delete">注销</a>
|
<a href="/delete" data-i18n="navDelete">注销</a>
|
||||||
<a href="/privacy">隐私协议</a>
|
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
|
||||||
<a href="/terms">用户协议</a>
|
<a href="/terms" data-i18n="navTerms">用户协议</a>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
<script src="/assets/i18n/zh-Hans.js?v=20261011lang"></script>
|
||||||
|
<script src="/assets/site.js?v=20261011lang"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -6,66 +6,71 @@
|
|||||||
<title>Sleep Heart</title>
|
<title>Sleep Heart</title>
|
||||||
<meta name="description" content="Sleep Heart 官网:睡眠声监测、指尖心率估算、助眠音乐与呼吸训练。测量结果仅供个人参考,不是医疗诊断。" />
|
<meta name="description" content="Sleep Heart 官网:睡眠声监测、指尖心率估算、助眠音乐与呼吸训练。测量结果仅供个人参考,不是医疗诊断。" />
|
||||||
<link rel="icon" href="/assets/icon.png" type="image/png" />
|
<link rel="icon" href="/assets/icon.png" type="image/png" />
|
||||||
<link rel="stylesheet" href="/assets/site.css" />
|
<link rel="stylesheet" href="/assets/site.css?v=20261011lang" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body data-page="home">
|
||||||
<header class="top">
|
<header class="top">
|
||||||
<div class="wrap top-inner">
|
<div class="wrap top-inner">
|
||||||
<a class="brand" href="/">
|
<a class="brand" href="/">
|
||||||
<img src="/assets/icon.png" width="40" height="40" alt="" />
|
<img src="/assets/icon.png" width="40" height="40" alt="" />
|
||||||
<span>Sleep Heart</span>
|
<span>Sleep Heart</span>
|
||||||
</a>
|
</a>
|
||||||
|
<div class="top-tools">
|
||||||
<nav class="nav" aria-label="页面">
|
<nav class="nav" aria-label="页面">
|
||||||
<a href="/" aria-current="page">首页</a>
|
<a href="/" data-i18n="navHome" aria-current="page">首页</a>
|
||||||
<a href="/download">下载</a>
|
<a href="/download" data-i18n="navDownload">下载</a>
|
||||||
<a href="/delete">注销</a>
|
<a href="/delete" data-i18n="navDelete">注销</a>
|
||||||
<a href="/privacy">隐私协议</a>
|
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
|
||||||
<a href="/terms">用户协议</a>
|
<a href="/terms" data-i18n="navTerms">用户协议</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
<label class="lang-label">
|
||||||
|
<span data-i18n="langLabel">语言</span>
|
||||||
|
<select id="lang-select"></select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<section class="hero">
|
<section class="hero">
|
||||||
<img src="/assets/icon.png" width="148" height="148" alt="Sleep Heart 图标" />
|
<img src="/assets/icon.png" width="148" height="148" alt="Sleep Heart 图标" data-i18n-alt="iconAlt" />
|
||||||
<div>
|
<div>
|
||||||
<h1>Sleep Heart</h1>
|
<h1>Sleep Heart</h1>
|
||||||
<p class="lead">在这台 iPhone 上查看夜间声音环境、估算指尖心率,并记下你自己填写的日常健康数字。可以听助眠音乐,按节奏做呼吸练习,登录后也可以在广场发帖。</p>
|
<p class="lead" data-i18n="lead">在这台 iPhone 上查看夜间声音环境、估算指尖心率,并记下你自己填写的日常健康数字。可以听助眠音乐,按节奏做呼吸练习,登录后也可以在广场发帖。</p>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<a class="btn btn-primary" href="/download">下载</a>
|
<a class="btn btn-primary" href="/download" data-i18n="navDownload">下载</a>
|
||||||
<a class="btn btn-ghost" href="/privacy">隐私协议</a>
|
<a class="btn btn-ghost" href="/privacy" data-i18n="navPrivacy">隐私协议</a>
|
||||||
<a class="btn btn-ghost" href="/terms">用户协议</a>
|
<a class="btn btn-ghost" href="/terms" data-i18n="navTerms">用户协议</a>
|
||||||
</div>
|
</div>
|
||||||
<p class="note">测量和监测结果只供个人参考,不是医疗诊断,不能代替血压计、血糖仪、血氧仪、体温计或就医。</p>
|
<p class="note" data-i18n="note">测量和监测结果只供个人参考,不是医疗诊断,不能代替血压计、血糖仪、血氧仪、体温计或就医。</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="section">
|
<section class="section">
|
||||||
<h2>可以做什么</h2>
|
<h2 data-i18n="homeH2">可以做什么</h2>
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<article class="card">
|
<article class="card">
|
||||||
<h3>音乐</h3>
|
<h3 data-i18n="musicT">音乐</h3>
|
||||||
<p>播放助眠内容。场景包括自然白噪、深度冥想、呼吸疗愈、治愈乐器和脑波音乐。播放方式有顺序、随机、循环和勾选播放。</p>
|
<p data-i18n="musicP">播放助眠内容。场景包括自然白噪、深度冥想、呼吸疗愈、治愈乐器和脑波音乐。播放方式有顺序、随机、循环和勾选播放。</p>
|
||||||
</article>
|
</article>
|
||||||
<article class="card">
|
<article class="card">
|
||||||
<h3>心率</h3>
|
<h3 data-i18n="heartT">心率</h3>
|
||||||
<p>用后置相机和闪光灯做指尖光学估算。画面在本机处理,不会上传。同一页可以手填体重、步数、血压、血糖、经期、血氧、体温和饮水。</p>
|
<p data-i18n="heartP">用后置相机和闪光灯做指尖光学估算。画面在本机处理,不会上传。同一页可以手填体重、步数、血压、血糖、经期、血氧、体温和饮水。</p>
|
||||||
</article>
|
</article>
|
||||||
<article class="card">
|
<article class="card">
|
||||||
<h3>睡眠</h3>
|
<h3 data-i18n="sleepT">睡眠</h3>
|
||||||
<p>打开监测后使用麦克风,在本机识别夜间声音并保存可回放的短片段。录音和识别结果只留在这台 iPhone,不会上传。</p>
|
<p data-i18n="sleepP">打开监测后使用麦克风,在本机识别夜间声音并保存可回放的短片段。录音和识别结果只留在这台 iPhone,不会上传。</p>
|
||||||
</article>
|
</article>
|
||||||
<article class="card">
|
<article class="card">
|
||||||
<h3>发现</h3>
|
<h3 data-i18n="discoverT">发现</h3>
|
||||||
<p>进入广场和呼吸训练。呼吸练习有箱式、4-7-8、舒缓吸呼和共振四种节奏,可以静音,也可以用喜欢的音乐做背景。</p>
|
<p data-i18n="discoverP">进入广场和呼吸训练。呼吸练习有箱式、4-7-8、舒缓吸呼和共振四种节奏,可以静音,也可以用喜欢的音乐做背景。</p>
|
||||||
</article>
|
</article>
|
||||||
<article class="card">
|
<article class="card">
|
||||||
<h3>我的</h3>
|
<h3 data-i18n="profileT">我的</h3>
|
||||||
<p>管理账号、会员、主题、语言和意见反馈。已登录后,注销入口在「设置」里的「账号与安全」。</p>
|
<p data-i18n="profileP">管理账号、会员、主题、语言和意见反馈。已登录后,注销入口在「设置」里的「账号与安全」。</p>
|
||||||
</article>
|
</article>
|
||||||
<article class="card">
|
<article class="card">
|
||||||
<h3>会员</h3>
|
<h3 data-i18n="vipT">会员</h3>
|
||||||
<p>会员音频可完整播放并收藏,本地音频导入不限数量,指尖心率测量不限次数。不购买也可以使用免费音频、本机健康记录、睡眠声监测和呼吸训练。</p>
|
<p data-i18n="vipP">会员音频可完整播放并收藏,本地音频导入不限数量,指尖心率测量不限次数。不购买也可以使用免费音频、本机健康记录、睡眠声监测和呼吸训练。</p>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@ -75,16 +80,18 @@
|
|||||||
<div class="wrap foot-inner">
|
<div class="wrap foot-inner">
|
||||||
<div>
|
<div>
|
||||||
<strong>Sleep Heart</strong>
|
<strong>Sleep Heart</strong>
|
||||||
<p>上海微雨如酥网络设计有限公司</p>
|
<p data-i18n="company">上海微雨如酥网络设计有限公司</p>
|
||||||
</div>
|
</div>
|
||||||
<nav class="foot-links" aria-label="页脚">
|
<nav class="foot-links" aria-label="页脚">
|
||||||
<a href="/">首页</a>
|
<a href="/" data-i18n="navHome">首页</a>
|
||||||
<a href="/download">下载</a>
|
<a href="/download" data-i18n="navDownload">下载</a>
|
||||||
<a href="/delete">注销</a>
|
<a href="/delete" data-i18n="navDelete">注销</a>
|
||||||
<a href="/privacy">隐私协议</a>
|
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
|
||||||
<a href="/terms">用户协议</a>
|
<a href="/terms" data-i18n="navTerms">用户协议</a>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
<script src="/assets/i18n/zh-Hans.js?v=20261011lang"></script>
|
||||||
|
<script src="/assets/site.js?v=20261011lang"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -6,27 +6,33 @@
|
|||||||
<title>隐私协议 — Sleep Heart</title>
|
<title>隐私协议 — Sleep Heart</title>
|
||||||
<meta name="description" content="Sleep Heart 软件隐私权政策。上海微雨如酥网络设计有限公司。" />
|
<meta name="description" content="Sleep Heart 软件隐私权政策。上海微雨如酥网络设计有限公司。" />
|
||||||
<link rel="icon" href="/assets/icon.png" type="image/png" />
|
<link rel="icon" href="/assets/icon.png" type="image/png" />
|
||||||
<link rel="stylesheet" href="/assets/site.css" />
|
<link rel="stylesheet" href="/assets/site.css?v=20261011lang" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body data-page="privacy">
|
||||||
<header class="top">
|
<header class="top">
|
||||||
<div class="wrap top-inner">
|
<div class="wrap top-inner">
|
||||||
<a class="brand" href="/">
|
<a class="brand" href="/">
|
||||||
<img src="/assets/icon.png" width="40" height="40" alt="" />
|
<img src="/assets/icon.png" width="40" height="40" alt="" />
|
||||||
<span>Sleep Heart</span>
|
<span>Sleep Heart</span>
|
||||||
</a>
|
</a>
|
||||||
|
<div class="top-tools">
|
||||||
<nav class="nav" aria-label="页面">
|
<nav class="nav" aria-label="页面">
|
||||||
<a href="/">首页</a>
|
<a href="/" data-i18n="navHome">首页</a>
|
||||||
<a href="/download">下载</a>
|
<a href="/download" data-i18n="navDownload">下载</a>
|
||||||
<a href="/delete">注销</a>
|
<a href="/delete" data-i18n="navDelete">注销</a>
|
||||||
<a href="/privacy" aria-current="page">隐私协议</a>
|
<a href="/privacy" data-i18n="navPrivacy" aria-current="page">隐私协议</a>
|
||||||
<a href="/terms">用户协议</a>
|
<a href="/terms" data-i18n="navTerms">用户协议</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
<label class="lang-label">
|
||||||
|
<span data-i18n="langLabel">语言</span>
|
||||||
|
<select id="lang-select"></select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<article class="panel">
|
<article class="panel" id="doc">
|
||||||
<h1>Sleep Heart 软件隐私权政策</h1>
|
<h1>Sleep Heart 软件隐私权政策</h1>
|
||||||
<p class="meta">适用于 Sleep Heart 网站(health.wyrs365.com)及 Sleep Heart 应用。</p>
|
<p class="meta">适用于 Sleep Heart 网站(health.wyrs365.com)及 Sleep Heart 应用。</p>
|
||||||
<p>上海微雨如酥网络设计有限公司(以下简称「本公司」或「我们」)非常重视用户个人信息及隐私权的保护,因此我们制订了涵盖如何收集、存储、使用、共享和保护用户信息以及访问、更新、删除和保护这些信息方式的隐私政策。</p>
|
<p>上海微雨如酥网络设计有限公司(以下简称「本公司」或「我们」)非常重视用户个人信息及隐私权的保护,因此我们制订了涵盖如何收集、存储、使用、共享和保护用户信息以及访问、更新、删除和保护这些信息方式的隐私政策。</p>
|
||||||
@ -126,16 +132,18 @@
|
|||||||
<div class="wrap foot-inner">
|
<div class="wrap foot-inner">
|
||||||
<div>
|
<div>
|
||||||
<strong>Sleep Heart</strong>
|
<strong>Sleep Heart</strong>
|
||||||
<p>上海微雨如酥网络设计有限公司</p>
|
<p data-i18n="company">上海微雨如酥网络设计有限公司</p>
|
||||||
</div>
|
</div>
|
||||||
<nav class="foot-links" aria-label="页脚">
|
<nav class="foot-links" aria-label="页脚">
|
||||||
<a href="/">首页</a>
|
<a href="/" data-i18n="navHome">首页</a>
|
||||||
<a href="/download">下载</a>
|
<a href="/download" data-i18n="navDownload">下载</a>
|
||||||
<a href="/delete">注销</a>
|
<a href="/delete" data-i18n="navDelete">注销</a>
|
||||||
<a href="/privacy" aria-current="page">隐私协议</a>
|
<a href="/privacy" data-i18n="navPrivacy" aria-current="page">隐私协议</a>
|
||||||
<a href="/terms">用户协议</a>
|
<a href="/terms" data-i18n="navTerms">用户协议</a>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
<script src="/assets/i18n/zh-Hans.js?v=20261011lang"></script>
|
||||||
|
<script src="/assets/site.js?v=20261011lang"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -6,27 +6,33 @@
|
|||||||
<title>用户协议 — Sleep Heart</title>
|
<title>用户协议 — Sleep Heart</title>
|
||||||
<meta name="description" content="Sleep Heart 软件用户服务协议。上海微雨如酥网络设计有限公司。" />
|
<meta name="description" content="Sleep Heart 软件用户服务协议。上海微雨如酥网络设计有限公司。" />
|
||||||
<link rel="icon" href="/assets/icon.png" type="image/png" />
|
<link rel="icon" href="/assets/icon.png" type="image/png" />
|
||||||
<link rel="stylesheet" href="/assets/site.css" />
|
<link rel="stylesheet" href="/assets/site.css?v=20261011lang" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body data-page="terms">
|
||||||
<header class="top">
|
<header class="top">
|
||||||
<div class="wrap top-inner">
|
<div class="wrap top-inner">
|
||||||
<a class="brand" href="/">
|
<a class="brand" href="/">
|
||||||
<img src="/assets/icon.png" width="40" height="40" alt="" />
|
<img src="/assets/icon.png" width="40" height="40" alt="" />
|
||||||
<span>Sleep Heart</span>
|
<span>Sleep Heart</span>
|
||||||
</a>
|
</a>
|
||||||
|
<div class="top-tools">
|
||||||
<nav class="nav" aria-label="页面">
|
<nav class="nav" aria-label="页面">
|
||||||
<a href="/">首页</a>
|
<a href="/" data-i18n="navHome">首页</a>
|
||||||
<a href="/download">下载</a>
|
<a href="/download" data-i18n="navDownload">下载</a>
|
||||||
<a href="/delete">注销</a>
|
<a href="/delete" data-i18n="navDelete">注销</a>
|
||||||
<a href="/privacy">隐私协议</a>
|
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
|
||||||
<a href="/terms" aria-current="page">用户协议</a>
|
<a href="/terms" data-i18n="navTerms" aria-current="page">用户协议</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
<label class="lang-label">
|
||||||
|
<span data-i18n="langLabel">语言</span>
|
||||||
|
<select id="lang-select"></select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<article class="panel">
|
<article class="panel" id="doc">
|
||||||
<h1>Sleep Heart 软件用户服务协议</h1>
|
<h1>Sleep Heart 软件用户服务协议</h1>
|
||||||
<p class="meta">适用于 Sleep Heart 网站(health.wyrs365.com)及 Sleep Heart 应用。</p>
|
<p class="meta">适用于 Sleep Heart 网站(health.wyrs365.com)及 Sleep Heart 应用。</p>
|
||||||
<p class="meta">本版本发布时间:2026年10月2日</p>
|
<p class="meta">本版本发布时间:2026年10月2日</p>
|
||||||
@ -103,16 +109,18 @@
|
|||||||
<div class="wrap foot-inner">
|
<div class="wrap foot-inner">
|
||||||
<div>
|
<div>
|
||||||
<strong>Sleep Heart</strong>
|
<strong>Sleep Heart</strong>
|
||||||
<p>上海微雨如酥网络设计有限公司</p>
|
<p data-i18n="company">上海微雨如酥网络设计有限公司</p>
|
||||||
</div>
|
</div>
|
||||||
<nav class="foot-links" aria-label="页脚">
|
<nav class="foot-links" aria-label="页脚">
|
||||||
<a href="/">首页</a>
|
<a href="/" data-i18n="navHome">首页</a>
|
||||||
<a href="/download">下载</a>
|
<a href="/download" data-i18n="navDownload">下载</a>
|
||||||
<a href="/delete">注销</a>
|
<a href="/delete" data-i18n="navDelete">注销</a>
|
||||||
<a href="/privacy">隐私协议</a>
|
<a href="/privacy" data-i18n="navPrivacy">隐私协议</a>
|
||||||
<a href="/terms" aria-current="page">用户协议</a>
|
<a href="/terms" data-i18n="navTerms" aria-current="page">用户协议</a>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
<script src="/assets/i18n/zh-Hans.js?v=20261011lang"></script>
|
||||||
|
<script src="/assets/site.js?v=20261011lang"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user