docs(prototype): confirm p0 web and app flows
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>App 登录与设备绑定 - 低保真原型</title>
|
||||
<style>
|
||||
:root{color-scheme:light;--ink:#17212b;--muted:#5e6b76;--line:#cdd4da;--surface:#fff;--bg:#eef1f3;--primary:#176b52;--primary-dark:#0f5540;--danger:#a13a32;--focus:#c57414}
|
||||
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:15px/1.5 system-ui,-apple-system,"Segoe UI","Microsoft YaHei",sans-serif;letter-spacing:0;padding-top:38px}
|
||||
.prototype{position:fixed;z-index:20;top:0;left:0;right:0;height:38px;display:grid;place-items:center;background:#2d343a;color:#fff;font-size:12px;font-weight:700}
|
||||
.phone{width:min(100%,420px);min-height:calc(100vh - 38px);margin:auto;background:#f8f9fa;border-inline:1px solid var(--line)}
|
||||
header{height:58px;display:flex;align-items:center;padding:0 20px;background:var(--surface);border-bottom:1px solid var(--line)}h1{font-size:20px;margin:0}
|
||||
main{padding:24px 20px 32px}.eyebrow{margin:0 0 6px;color:var(--primary);font-size:13px;font-weight:700}.intro{margin:0 0 24px;color:var(--muted)}
|
||||
form{display:grid;gap:18px}.field{display:grid;gap:7px}label{font-weight:650}.hint{color:var(--muted);font-size:13px}.input-wrap{display:flex}
|
||||
input,select,button{font:inherit}input,select{width:100%;min-height:48px;padding:10px 12px;border:1px solid #8f9aa3;border-radius:6px;background:#fff;color:var(--ink)}
|
||||
input:focus,select:focus,button:focus-visible,a:focus-visible{outline:3px solid color-mix(in srgb,var(--focus) 45%,transparent);outline-offset:2px}
|
||||
.input-wrap input{border-radius:6px 0 0 6px}.icon-button{width:54px;min-height:48px;border:1px solid #8f9aa3;border-left:0;border-radius:0 6px 6px 0;background:#fff;font-weight:700}
|
||||
.device{padding:14px;border-left:4px solid var(--primary);background:#e9f3ef}.device strong,.device span{display:block}.device span{margin-top:3px;color:var(--muted);font-size:13px}
|
||||
.error{display:none;padding:12px;border:1px solid #d9a09a;background:#fff1ef;color:#76271f}.error.show{display:block}
|
||||
.primary{min-height:50px;border:0;border-radius:6px;background:var(--primary);color:#fff;font-weight:750}.primary:hover{background:var(--primary-dark)}button:disabled{opacity:.58;cursor:not-allowed}
|
||||
.privacy{margin:18px 0 0;color:var(--muted);font-size:12px}.status{min-height:24px;margin:0;color:var(--primary);font-weight:650}
|
||||
@media(max-width:420px){.phone{border:0}main{padding-inline:18px}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="prototype">PROTOTYPE - 仅供确认布局和交互,不是生产实现</div>
|
||||
<div class="phone">
|
||||
<header><h1>采购执行</h1></header>
|
||||
<main>
|
||||
<p class="eyebrow">人员与设备身份</p>
|
||||
<p class="intro">登录后将绑定当前测试设备,并检查采购所需能力。</p>
|
||||
<form id="loginForm" novalidate>
|
||||
<div class="field">
|
||||
<label for="account">采购账号</label>
|
||||
<input id="account" autocomplete="username" value="buyer.demo" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="password">密码</label>
|
||||
<div class="input-wrap">
|
||||
<input id="password" type="password" autocomplete="current-password" required>
|
||||
<button class="icon-button" id="togglePassword" type="button" aria-label="显示密码">显示</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="device">设备身份</label>
|
||||
<select id="device">
|
||||
<option>测试设备 A · 本机</option>
|
||||
<option>重新登记此设备</option>
|
||||
</select>
|
||||
<div class="device" aria-label="设备状态">
|
||||
<strong>设备可登记</strong>
|
||||
<span>仅上报版本和就绪能力,不上传设备中的敏感内容</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="scenario">原型提交结果</label>
|
||||
<select id="scenario">
|
||||
<option value="success">登录成功</option>
|
||||
<option value="invalid">账号或密码不正确</option>
|
||||
<option value="network">网络连接失败</option>
|
||||
<option value="disabled">账号或设备已停用</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="error" id="error" role="alert">请输入账号和密码。</div>
|
||||
<button class="primary" id="submit" type="submit">登录并绑定设备</button>
|
||||
<p class="status" id="status" role="status" aria-live="polite"></p>
|
||||
</form>
|
||||
<p class="privacy">登录凭据由 Android 安全存储处理。原型不保存任何输入。</p>
|
||||
</main>
|
||||
</div>
|
||||
<script>
|
||||
const form=document.querySelector("#loginForm"),password=document.querySelector("#password"),account=document.querySelector("#account"),error=document.querySelector("#error"),submit=document.querySelector("#submit"),status=document.querySelector("#status"),scenario=document.querySelector("#scenario");
|
||||
document.querySelector("#togglePassword").addEventListener("click",e=>{const hidden=password.type==="password";password.type=hidden?"text":"password";e.currentTarget.textContent=hidden?"隐藏":"显示";e.currentTarget.setAttribute("aria-label",hidden?"隐藏密码":"显示密码")});
|
||||
form.addEventListener("submit",e=>{e.preventDefault();error.classList.remove("show");if(!account.value.trim()||!password.value){error.textContent="请输入账号和密码。";error.classList.add("show");(!account.value.trim()?account:password).focus();return}submit.disabled=true;submit.textContent="正在登录";status.textContent="正在建立人员与设备身份…";setTimeout(()=>{if(scenario.value==="success"){status.textContent="身份已建立,即将进入任务主页。";submit.textContent="已登录";location.hash="success";return}password.value="";submit.disabled=false;submit.textContent="登录并绑定设备";status.textContent="";error.textContent=scenario.value==="invalid"?"账号或密码不正确。":scenario.value==="network"?"网络连接失败,账号已保留,请重试。":"账号或设备已停用,请联系管理员。";error.classList.add("show");password.focus()},650)});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user