Files
lovife 7df078e0ea docs: 同步交接摘要 / PRD / 原型,并记录品牌改名「深学在线」
- 交接摘要补 §一·三十五~§一·三十八:角色与授权、需求收敛(4 角色 / 10 菜单 / 取消二期)、
  PC 端重搭后的 UI 修复与卡片式基线、品牌改名与新标识
- PRD 与功能逻辑卷只改标题行与产品代号线;**文件名不动** —— verify-docs.py 按路径读,
  全库还有 20+ 处按文件名引用,改名会连带炸脚本
- 原型 index / admin-web / teacher-app / student-app 的品牌区改「深学在线」,
  admin-web 的 .mark(10 处)换成内嵌的新标 data URI,保持原型"单文件自包含"的约定
- 根 AGENTS.md 与 frontend-pc 的规范同步:接线检查补第 ⑨ 项(SVG 资产是不是合法 XML ——
  SVG 注释里出现连续两个减号就 not well-formed,图标裂开而控制台一句话都不报)、
  「最容易写错的约定」6 -> 7 条(新增品牌标)
- deploy/docker-compose.yml 只改头注释里的项目名(compose 的 name 与七牛对象前缀都没动)
2026-10-10 16:49:04 +08:00

841 lines
52 KiB
HTML
Vendored
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>深学在线 · 学生端交互原型</title>
<style>
:root{
--ink:#1b2430; --ink2:#4a5768; --ink3:#8b95a3;
--paper:#f4f1ea; --paper2:#fbfaf7; --card:#ffffff;
--line:#e0dbd0; --line2:#cfc8b8;
--seal:#c0392b; --seal-soft:#f9ece9;
--jade:#2f6b4f; --jade-soft:#e8f0eb;
--amber:#a9761f; --amber-soft:#f8f1de;
--font-display:"Songti SC","STSong","SimSun","Noto Serif SC",serif;
--font-body:"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Source Han Sans SC",sans-serif;
--font-mono:"SF Mono","JetBrains Mono","Cascadia Mono",Consolas,monospace;
--r:14px;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{
font-family:var(--font-body);
color:var(--ink);
background:var(--paper);
background-image:
linear-gradient(rgba(207,200,184,.28) 1px,transparent 1px),
linear-gradient(90deg,rgba(207,200,184,.28) 1px,transparent 1px);
background-size:26px 26px;
-webkit-font-smoothing:antialiased;
padding:0 0 80px;
}
/* ── 图标系统:统一描边、随字号缩放 ── */
.ico{
width:1em;height:1em;flex:none;display:inline-block;vertical-align:-.14em;
fill:none;stroke:currentColor;stroke-width:1.7;
stroke-linecap:round;stroke-linejoin:round;
}
.ico.lg{width:1.35em;height:1.35em;vertical-align:-.28em}
.ico.xl{width:1.9em;height:1.9em;vertical-align:-.42em}
/* ── 页头 ── */
.masthead{
padding:38px 40px 26px;
border-bottom:1px solid var(--line2);
background:linear-gradient(180deg,var(--paper2),transparent);
position:relative;
}
.masthead::after{content:"";position:absolute;left:0;right:0;bottom:3px;height:1px;background:var(--line)}
.kicker{font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink3);font-family:var(--font-mono);margin-bottom:10px}
h1{font-family:var(--font-display);font-size:32px;font-weight:600;letter-spacing:.04em;line-height:1.25}
h1 em{font-style:normal;color:var(--seal)}
.sub{margin-top:10px;color:var(--ink2);font-size:13.5px;line-height:1.75;max-width:780px}
.sub code{font-family:var(--font-mono);font-size:12px;background:#fff;border:1px solid var(--line);border-radius:4px;padding:1px 5px}
.legend{display:flex;flex-wrap:wrap;gap:18px;margin-top:18px;font-size:12px;color:var(--ink2)}
.legend span{display:flex;align-items:center;gap:7px}
.dot{width:9px;height:9px;border-radius:50%;flex:none}
.dot.lock{background:var(--ink)} .dot.edit{background:var(--amber)}
.dot.doc{background:var(--jade)} .dot.seal{background:var(--seal)}
/* ── 画廊 ── */
.gallery{
display:grid;grid-template-columns:repeat(auto-fit,minmax(348px,1fr));
gap:36px 30px;padding:44px 40px;max-width:1560px;margin:0 auto;
}
figure{margin:0;display:flex;flex-direction:column;align-items:center}
figcaption{margin-top:16px;max-width:340px;text-align:center;font-size:12.5px;line-height:1.7;color:var(--ink2)}
figcaption b{display:block;font-family:var(--font-display);font-size:15px;color:var(--ink);letter-spacing:.03em;margin-bottom:5px;font-weight:600}
figcaption .tag{
display:inline-block;font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;
color:var(--seal);border:1px solid var(--seal);border-radius:3px;padding:1px 6px;margin-bottom:7px;opacity:.85;
}
/* ── 手机外壳 ── */
.device{
width:348px;height:752px;flex:none;background:#0e1319;border-radius:44px;padding:11px;
box-shadow:0 26px 48px -18px rgba(27,36,48,.42),0 2px 6px rgba(27,36,48,.14);
position:relative;transition:transform .4s cubic-bezier(.2,.8,.3,1),box-shadow .4s;
}
.device:hover{transform:translateY(-6px);box-shadow:0 36px 62px -20px rgba(27,36,48,.5)}
.screen{width:100%;height:100%;background:var(--paper2);border-radius:34px;overflow:hidden;display:flex;flex-direction:column;position:relative}
/* 状态栏 */
.statusbar{
height:40px;flex:none;display:flex;align-items:center;justify-content:space-between;
padding:0 20px;font-size:12px;font-family:var(--font-mono);color:var(--ink);font-weight:500;
}
.statusbar .icons{display:flex;gap:5px;align-items:center;opacity:.85;font-size:13px}
.bat{width:20px;height:10px;border:1.2px solid var(--ink);border-radius:2.5px;position:relative;flex:none}
.bat::after{content:"";position:absolute;left:1.5px;top:1.5px;bottom:1.5px;width:11px;background:var(--ink);border-radius:1px}
.bat::before{content:"";position:absolute;right:-3px;top:3px;width:2px;height:4px;background:var(--ink);border-radius:0 1px 1px 0}
/* 导航条 */
.navbar{
flex:none;height:46px;display:flex;align-items:center;gap:10px;padding:0 18px;
border-bottom:1px solid var(--line);font-size:15px;font-weight:600;letter-spacing:.02em;background:var(--paper2);
}
.navbar .back{width:17px;height:17px;flex:none;opacity:.55}
.navbar .back .ico{stroke-width:2.4}
/* 内容区 */
.body{flex:1;overflow-y:auto;padding:18px;scrollbar-width:thin}
.body::-webkit-scrollbar{width:4px}
.body::-webkit-scrollbar-thumb{background:var(--line2);border-radius:2px}
/* ── 通用元件 ── */
.panel{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:15px;margin-bottom:13px}
.panel.flush{padding:0;overflow:hidden}
.ptitle{
display:flex;align-items:center;gap:7px;font-size:12px;color:var(--ink3);
letter-spacing:.06em;margin-bottom:11px;font-family:var(--font-mono);
}
.ptitle .badge{
font-size:10px;padding:1.5px 6px;border-radius:3px;letter-spacing:.04em;
font-family:var(--font-body);font-weight:600;display:inline-flex;align-items:center;gap:4px;
}
.badge .ico{font-size:11px}
.badge.lock{background:#eef1f4;color:var(--ink2);border:1px solid var(--line2)}
.badge.edit{background:var(--amber-soft);color:var(--amber);border:1px solid #e8d9b5}
.badge.doc{background:var(--jade-soft);color:var(--jade);border:1px solid #cfe0d6}
/* 数据行 */
.row{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:8px 0;border-bottom:1px dashed var(--line)}
.row:last-child{border-bottom:0}
.row .k{font-size:13px;color:var(--ink2);flex:none}
.row .v{font-size:13.5px;color:var(--ink);text-align:right;font-weight:500;word-break:break-all}
.row .v.mono{font-family:var(--font-mono);font-size:12.5px;letter-spacing:.02em}
.row .v.dim{color:var(--ink3);font-weight:400}
/* 按钮 */
.btn{
display:block;width:100%;border:0;border-radius:11px;
font-family:var(--font-body);font-size:15.5px;font-weight:600;letter-spacing:.05em;
padding:14px;cursor:pointer;transition:.22s;text-align:center;
}
.btn.primary{background:var(--ink);color:#fff}
.btn.primary:hover{background:#2a3646}
.btn.seal{background:var(--seal);color:#fff}
.btn.seal:hover{background:#a93022}
.btn.ghost{background:transparent;color:var(--ink2);border:1px solid var(--line2)}
.btn.ghost:hover{background:#fff;color:var(--ink)}
.btn:disabled{background:#c9cdd3;color:#8f959d;cursor:not-allowed}
.btnrow{display:flex;gap:10px}
.btnrow .btn{margin:0}
.foot{flex:none;padding:13px 18px 20px;border-top:1px solid var(--line);background:var(--paper2)}
/* 输入框 */
.field{margin-bottom:15px}
.field label{display:block;font-size:12.5px;color:var(--ink2);margin-bottom:7px;letter-spacing:.04em;font-weight:500}
.field label .req{color:var(--seal);margin-left:3px}
.input{
width:100%;height:52px;border:1.5px solid var(--line2);border-radius:11px;background:var(--card);
padding:0 15px;font-size:16px;color:var(--ink);font-family:var(--font-body);letter-spacing:.02em;transition:.2s;
}
.input.mono{font-family:var(--font-mono);letter-spacing:.13em;font-size:16.5px}
.input:focus{outline:0;border-color:var(--ink);box-shadow:0 0 0 3px rgba(27,36,48,.07)}
.input::placeholder{color:#b3b9c1;letter-spacing:normal;font-size:15px}
.stepbox{display:flex;gap:10px;margin-bottom:15px}
.stepbox .sb{flex:1;display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--ink3)}
.stepbox .sb i{width:19px;height:19px;border-radius:50%;background:var(--line);color:var(--ink3);display:flex;align-items:center;justify-content:center;font-style:normal;font-size:11px;font-family:var(--font-mono);flex:none}
.stepbox .sb.on{color:var(--ink);font-weight:600}
.stepbox .sb.on i{background:var(--ink);color:#fff}
.hint{font-size:11.5px;color:var(--ink3);margin-top:6px;line-height:1.6}
.hint.warn{color:var(--amber)}
/* 页头说明块 */
.pagehead{
padding:22px 20px 20px;text-align:center;
background:linear-gradient(180deg,#fff,var(--paper2));border-bottom:1px solid var(--line);
}
.pagehead .glyph{
width:52px;height:52px;margin:0 auto 13px;border-radius:14px;
display:flex;align-items:center;justify-content:center;font-size:22px;
background:var(--seal-soft);border:1px solid #eed5cf;color:var(--seal);
}
.pagehead .glyph.ok{background:var(--jade-soft);border-color:#cfe0d6;color:var(--jade)}
.pagehead .glyph.gray{background:#eef1f4;border-color:var(--line2);color:var(--ink3)}
.pagehead h2{font-family:var(--font-display);font-size:21px;font-weight:600;letter-spacing:.05em}
.pagehead p{font-size:12.5px;color:var(--ink2);line-height:1.75;margin-top:9px;padding:0 6px}
.pagehead p b{color:var(--seal);font-weight:600}
/* 任务条 */
.taskbar{padding:13px 18px;background:#fff;border-bottom:1px solid var(--line)}
.taskbar .tname{font-size:14.5px;font-weight:600;letter-spacing:.02em}
.taskbar .tmeta{font-size:11.5px;color:var(--ink3);margin-top:5px;display:flex;gap:12px;font-family:var(--font-mono)}
/* 进度环 */
.ring{width:52px;height:52px;border-radius:50%;flex:none;position:relative;background:conic-gradient(var(--jade) calc(var(--p)*1%),#e8e4db 0)}
.ring::after{content:"";position:absolute;inset:5px;border-radius:50%;background:var(--card)}
.ring span{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:12.5px;font-family:var(--font-mono);font-weight:600;color:var(--jade);z-index:1}
/* 材料项 */
.mat{display:flex;align-items:center;gap:13px;padding:14px 15px;border-bottom:1px solid var(--line);cursor:pointer;transition:.2s;background:var(--card)}
.mat:last-child{border-bottom:0}
.mat:hover{background:#fdfcfa}
.mat .thumb{
width:46px;height:46px;border-radius:9px;flex:none;background:var(--paper);border:1px solid var(--line);
display:flex;align-items:center;justify-content:center;font-size:21px;color:var(--ink2);
}
.mat .thumb.ok{background:var(--jade-soft);border-color:#cfe0d6;color:var(--jade)}
.mat .info{flex:1;min-width:0}
.mat .mname{font-size:14px;font-weight:600;letter-spacing:.02em;display:flex;align-items:center;gap:7px}
.mat .mdesc{font-size:11px;color:var(--ink3);margin-top:4px;line-height:1.55;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mat .mdesc.done{font-family:var(--font-mono);color:var(--jade)}
.mat .state{flex:none;font-size:11px;padding:3px 9px;border-radius:20px;font-weight:600;letter-spacing:.03em}
.state.pass{background:var(--jade-soft);color:var(--jade)}
.state.warn{background:var(--amber-soft);color:var(--amber)}
.state.none{background:#eef1f4;color:var(--ink3)}
.state.crit{background:var(--seal-soft);color:var(--seal)}
/* 弹层 */
.sheet{
position:absolute;left:0;right:0;bottom:0;z-index:20;background:var(--paper2);
border-radius:22px 22px 34px 34px;box-shadow:0 -14px 40px -10px rgba(27,36,48,.28);
padding:9px 16px 22px;animation:sheetUp .34s cubic-bezier(.2,.85,.3,1);
}
@keyframes sheetUp{from{transform:translateY(102%)}to{transform:translateY(0)}}
.sheet .grab{width:38px;height:4px;border-radius:2px;background:var(--line2);margin:0 auto 15px}
.sheet h3{font-size:14.5px;font-weight:600;margin-bottom:4px;letter-spacing:.03em}
.sheet .stip{font-size:11.5px;color:var(--ink3);margin-bottom:14px;line-height:1.6}
.scard{
display:flex;align-items:center;gap:13px;padding:14px;background:var(--card);
border:1.5px solid var(--line);border-radius:12px;margin-bottom:9px;cursor:pointer;transition:.2s;
}
.scard:hover{border-color:var(--ink);transform:translateX(2px)}
.scard.rec{border-color:var(--seal);background:var(--seal-soft)}
.scard .sicon{
width:40px;height:40px;border-radius:10px;background:var(--paper);flex:none;border:1px solid var(--line);
display:flex;align-items:center;justify-content:center;font-size:20px;color:var(--ink2);
}
.scard.rec .sicon{background:#fff;border-color:#eed5cf;color:var(--seal)}
.scard .stxt{flex:1}
.scard .st{font-size:14px;font-weight:600;letter-spacing:.02em;display:flex;align-items:center;gap:7px}
.scard .sd{font-size:11px;color:var(--ink3);margin-top:3px;line-height:1.5}
.recommend{font-size:9.5px;background:var(--seal);color:#fff;padding:1.5px 6px;border-radius:3px;letter-spacing:.06em;font-weight:600}
.mask{position:absolute;inset:0;background:rgba(27,36,48,.42);z-index:15}
/* ── 文件处理卡(核心)── */
.filecard{
background:var(--card);border:1px solid var(--line);border-radius:var(--r);
padding:16px;margin-bottom:13px;position:relative;overflow:hidden;
}
.filecard::before{
content:"";position:absolute;inset:0;pointer-events:none;
background:repeating-linear-gradient(45deg,transparent,transparent 9px,rgba(192,57,43,.028) 9px,rgba(192,57,43,.028) 18px);
}
.fc-label{font-size:10.5px;font-family:var(--font-mono);letter-spacing:.12em;color:var(--ink3);margin-bottom:7px}
.fname{font-family:var(--font-mono);font-size:12.5px;line-height:1.65;word-break:break-all;letter-spacing:.01em}
.fname.old{color:var(--ink3);position:relative;display:inline-block}
.fname.old .strike{
position:absolute;left:-1px;right:-1px;top:52%;height:1.5px;background:var(--seal);
transform-origin:left;transform:scaleX(0);animation:draw .5s .5s cubic-bezier(.6,0,.3,1) forwards;
}
@keyframes draw{to{transform:scaleX(1)}}
.fname.old .fix{background:rgba(192,57,43,.14);border-bottom:1.5px solid var(--seal);border-radius:2px;padding:0 1px}
.fc-arrow{display:flex;align-items:center;gap:9px;margin:13px 0;font-size:11.5px;color:var(--jade);font-weight:600;letter-spacing:.06em}
.fc-arrow .line{flex:1;height:1px;background:linear-gradient(90deg,var(--seal),var(--jade));opacity:.4}
.fname.new{color:var(--ink);font-weight:500}
.fname.new .ok{background:var(--jade-soft);border-bottom:1.5px solid var(--jade);border-radius:2px;padding:0 1px}
/* 印章 */
.stamp{
position:absolute;right:13px;top:13px;width:60px;height:60px;border-radius:50%;
border:2.2px solid var(--seal);color:var(--seal);
display:flex;align-items:center;justify-content:center;
font-family:var(--font-display);font-size:12px;font-weight:700;letter-spacing:.06em;
transform:rotate(-13deg) scale(0);opacity:.82;
animation:stampIn .5s 1.05s cubic-bezier(.3,1.5,.5,1) forwards;
text-align:center;line-height:1.15;padding:4px;
background:radial-gradient(circle,rgba(192,57,43,.05),transparent 70%);
}
.stamp.jade{border-color:var(--jade);color:var(--jade);background:radial-gradient(circle,rgba(47,107,79,.05),transparent 70%)}
@keyframes stampIn{
0%{transform:rotate(-13deg) scale(2.4);opacity:0}
60%{transform:rotate(-13deg) scale(.92);opacity:.9}
100%{transform:rotate(-13deg) scale(1);opacity:.82}
}
/* 体积对比 */
.vol{display:flex;align-items:center;gap:10px;margin-top:5px;font-family:var(--font-mono);font-size:12px}
.vol .from{color:var(--ink3);text-decoration:line-through;text-decoration-color:var(--seal)}
.vol .to{color:var(--jade);font-weight:600;font-size:13.5px}
.vol .pct{margin-left:auto;font-size:10.5px;background:var(--jade-soft);color:var(--jade);padding:2px 8px;border-radius:20px;font-weight:600}
/* 校验条目 */
.vitem{display:flex;gap:9px;align-items:flex-start;padding:9px 0;border-top:1px dashed var(--line);font-size:12.5px;line-height:1.6}
.vitem .vi{flex:none;font-size:15px;margin-top:1px;color:var(--ink3)}
.vitem .vi.ok{color:var(--jade)} .vitem .vi.work{color:var(--seal)} .vitem .vi.wait{color:var(--line2)}
.vitem .vt{flex:1;color:var(--ink2)}
.vitem .vt b{color:var(--ink);font-weight:600}
/* 时间轴 */
.tl{padding-left:6px}
.tl .node{display:flex;gap:13px;position:relative;padding-bottom:22px}
.tl .node:last-child{padding-bottom:0}
.tl .node::before{content:"";position:absolute;left:9px;top:22px;bottom:0;width:1.5px;background:var(--line)}
.tl .node:last-child::before{display:none}
.tl .nd{
width:19px;height:19px;border-radius:50%;flex:none;z-index:1;
display:flex;align-items:center;justify-content:center;font-size:10px;color:#fff;
background:var(--line2);font-family:var(--font-mono);
}
.tl .nd .ico{font-size:11px;stroke-width:2.6}
.tl .nd.done{background:var(--jade)}
.tl .nd.now{background:var(--seal);box-shadow:0 0 0 4px var(--seal-soft)}
.tl .nc{flex:1;padding-top:1px}
.tl .nt{font-size:13.5px;font-weight:600;letter-spacing:.02em}
.tl .nt.dim{color:var(--ink3);font-weight:400}
.tl .ns{font-size:11.5px;color:var(--ink3);margin-top:4px;line-height:1.6}
/* 提醒条 */
.notice{display:flex;gap:10px;padding:12px 14px;border-radius:11px;font-size:12.5px;line-height:1.65;margin-bottom:13px;align-items:flex-start}
.notice .ni{flex:none;font-size:16px;margin-top:1px}
.notice.crit{background:var(--seal-soft);border:1px solid #eed5cf;color:#8e2d20}
.notice.warn{background:var(--amber-soft);border:1px solid #e8d9b5;color:#7d5815}
.notice.info{background:#eef1f4;border:1px solid var(--line2);color:var(--ink2)}
.notice.ok{background:var(--jade-soft);border:1px solid #cfe0d6;color:#245341}
.notice b{font-weight:600}
/* 小链接 */
.link{font-size:12px;color:var(--ink3);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.link:hover{color:var(--seal)}
.center-note{text-align:center;font-size:11.5px;color:var(--ink3);margin-top:14px;line-height:1.7}
/* 说明区 */
.apron{max-width:1560px;margin:0 auto;padding:0 40px}
.apron h3{font-family:var(--font-display);font-size:19px;letter-spacing:.05em;margin:44px 0 16px;padding-bottom:10px;border-bottom:1px solid var(--line2)}
.aside-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));gap:20px}
.aside-card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:17px;font-size:12.5px;line-height:1.8;color:var(--ink2)}
.aside-card h4{font-size:13.5px;color:var(--ink);margin-bottom:9px;letter-spacing:.03em;display:flex;align-items:center;gap:8px;font-weight:600}
.aside-card h4 .n{font-family:var(--font-mono);font-size:10.5px;color:var(--seal);border:1px solid var(--seal);border-radius:3px;padding:0 5px}
.aside-card code{font-family:var(--font-mono);font-size:11px;background:var(--paper);border:1px solid var(--line);border-radius:3px;padding:1px 4px}
</style>
</head>
<body>
<!-- ══ 内联 SVG 图标库(线性 · 1.7 描边 · currentColor)══ -->
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
<symbol id="i-back" viewBox="0 0 24 24"><path d="M15 18l-6-6 6-6"/></symbol>
<symbol id="i-lock" viewBox="0 0 24 24"><rect x="4.5" y="10.5" width="15" height="10" rx="2.2"/><path d="M8 10.5V7.5a4 4 0 0 1 8 0v3"/><path d="M12 14.5v2.5"/></symbol>
<symbol id="i-pencil" viewBox="0 0 24 24"><path d="M4.5 19.5h3.2L18.4 8.8a2.3 2.3 0 0 0-3.2-3.2L4.5 16.3z"/><path d="M14.2 6.6l3.2 3.2"/></symbol>
<symbol id="i-file" viewBox="0 0 24 24"><path d="M13.5 3.5H7A1.8 1.8 0 0 0 5.2 5.3v13.4A1.8 1.8 0 0 0 7 20.5h10a1.8 1.8 0 0 0 1.8-1.8V9z"/><path d="M13.5 3.5V9h5.3"/></symbol>
<symbol id="i-image" viewBox="0 0 24 24"><rect x="3.5" y="4.5" width="17" height="15" rx="2.2"/><circle cx="8.8" cy="9.8" r="1.6"/><path d="M4 17.5l4.5-4.5 3.5 3.5 3-3 4.5 4.5"/></symbol>
<symbol id="i-idcard" viewBox="0 0 24 24"><rect x="2.5" y="5" width="19" height="14" rx="2.2"/><circle cx="8.5" cy="11.4" r="2.1"/><path d="M5.2 16.4c.6-1.5 1.8-2.3 3.3-2.3s2.7.8 3.3 2.3"/><path d="M14.5 10.2h4.3M14.5 13.6h4.3"/></symbol>
<symbol id="i-stamp" viewBox="0 0 24 24"><circle cx="12" cy="8.8" r="5.4"/><path d="M9.4 13.4L8 20.5h8l-1.4-7.1"/></symbol>
<symbol id="i-shield" viewBox="0 0 24 24"><path d="M12 3.5l7 2.8v5.4c0 4.2-2.9 7.6-7 8.8-4.1-1.2-7-4.6-7-8.8V6.3z"/></symbol>
<symbol id="i-bulb" viewBox="0 0 24 24"><path d="M12 3.5a5.4 5.4 0 0 0-3.2 9.8c.5.4.8 1 .8 1.6v1.1h4.8v-1.1c0-.6.3-1.2.8-1.6A5.4 5.4 0 0 0 12 3.5z"/><path d="M9.8 18.6h4.4M10.4 21h3.2"/></symbol>
<symbol id="i-pin" viewBox="0 0 24 24"><path d="M12 21s6.4-5.4 6.4-10.4A6.4 6.4 0 0 0 5.6 10.6C5.6 15.6 12 21 12 21z"/><circle cx="12" cy="10.5" r="2.3"/></symbol>
<symbol id="i-sparkle" viewBox="0 0 24 24"><path d="M11 3.8l1.7 4.5 4.5 1.7-4.5 1.7L11 16.2 9.3 11.7 4.8 10l4.5-1.7z"/><path d="M18 15.4l.7 1.9 1.9.7-1.9.7-.7 1.9-.7-1.9-1.9-.7 1.9-.7z"/></symbol>
<symbol id="i-search" viewBox="0 0 24 24"><circle cx="11" cy="11" r="6.4"/><path d="M15.7 15.7l4.8 4.8"/></symbol>
<symbol id="i-help" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5"/><path d="M9.7 9.6a2.4 2.4 0 0 1 4.7.7c0 1.6-2.4 2.2-2.4 3.6"/><path d="M12 17v.5"/></symbol>
<symbol id="i-bell" viewBox="0 0 24 24"><path d="M17.4 16.4V11a5.4 5.4 0 0 0-10.8 0v5.4L5.2 18.4h13.6z"/><path d="M10 18.4a2 2 0 0 0 4 0"/></symbol>
<symbol id="i-check" viewBox="0 0 24 24"><path d="M5 12.6l4.5 4.5L19 7.4"/></symbol>
<symbol id="i-check-circle" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5"/><path d="M8.2 12.2l2.6 2.6 5-5.2"/></symbol>
<symbol id="i-refresh" viewBox="0 0 24 24"><path d="M19.6 12a7.6 7.6 0 1 1-2.3-5.4"/><path d="M19.6 4.6v4.9h-4.9"/></symbol>
<symbol id="i-clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5"/><path d="M12 7.4V12l3 2"/></symbol>
<symbol id="i-sliders" viewBox="0 0 24 24"><path d="M4 8.5h8.5M17.5 8.5h2.5M4 15.5h2.5M11.5 15.5h8.5"/><circle cx="15" cy="8.5" r="2.2"/><circle cx="9" cy="15.5" r="2.2"/></symbol>
<symbol id="i-chat" viewBox="0 0 24 24"><path d="M20 12.3c0 3.5-3.6 6.4-8 6.4-1 0-2-.2-2.9-.5L4.6 19.8l1-3.1A6.2 6.2 0 0 1 4 12.3C4 8.8 7.6 5.9 12 5.9s8 2.9 8 6.4z"/></symbol>
<symbol id="i-folder" viewBox="0 0 24 24"><path d="M3.5 6.6A1.9 1.9 0 0 1 5.4 4.7h3.3l2.1 2.6h8A1.9 1.9 0 0 1 20.7 9.2v8.4a1.9 1.9 0 0 1-1.9 1.9H5.4a1.9 1.9 0 0 1-1.9-1.9z"/></symbol>
<symbol id="i-alert" viewBox="0 0 24 24"><path d="M12 4.3l8.8 15.2H3.2z"/><path d="M12 10v3.9M12 16.9v.5"/></symbol>
<symbol id="i-signal" viewBox="0 0 24 24"><path d="M4 18v-2M9 18v-5M14 18v-8M19 18V7"/></symbol>
<symbol id="i-wifi" viewBox="0 0 24 24"><path d="M4 9.6a12.5 12.5 0 0 1 16 0M7 13a8 8 0 0 1 10 0"/><circle cx="12" cy="17.2" r="1.1"/></symbol>
<symbol id="i-user-plus" viewBox="0 0 24 24"><circle cx="9.5" cy="8.2" r="3.6"/><path d="M3.4 20.2c.7-3.6 3.1-5.6 6.1-5.6s5.4 2 6.1 5.6"/><path d="M18.6 7.6v6M15.6 10.6h6"/></symbol>
</svg>
<header class="masthead">
<div class="kicker">Prototype · 学生端 · V1.2</div>
<h1>深学在线 · <em>学生填报端</em>交互原型</h1>
<p class="sub">
10 屏完整流程:<strong>门禁核验 → 信息核对 → 选材上传 → 自动规范化 → 提交审核</strong>。<br>
<span style="font-size:12.5px;color:var(--ink3)">门禁失败只有「重新填写」一条系统内出路;确实不在名单里时由老师手工加人(系统内不展示联系方式)。</span><br>
设计方向为「档案室 / 电子卷宗」——本系统替代的是纸质材料袋与红章审批,界面应让人感到<strong>有秩序、可信、像一份正经公文</strong>。<br>
图标为内联 SVG 线性图标(统一 1.7px 描边、继承文字色),不用 emoji——避免跨平台渲染不一致,也避免消费级观感。<br>
全部文案遵循「零术语 · 指出位置 · 给出动作」三原则;数据取自真实批次 <code>24中技数控1班</code> 的 28 名学生。
</p>
<div class="legend">
<span><i class="dot lock"></i><svg class="ico"><use href="#i-lock"/></svg> 锁定:只读,名单为空则阻断发布</span>
<span><i class="dot edit"></i><svg class="ico"><use href="#i-pencil"/></svg> 预填可改:老师已填,可核对修改</span>
<span><i class="dot doc"></i><svg class="ico"><use href="#i-file"/></svg> 材料:学生唯一的重活</span>
<span><i class="dot seal"></i>朱红:印章 / 需修正</span>
</div>
</header>
<main class="gallery">
<!-- ① 门禁核验 -->
<figure>
<div class="device"><div class="screen">
<div class="statusbar"><span>9:41</span><span class="icons"><svg class="ico"><use href="#i-signal"/></svg><svg class="ico"><use href="#i-wifi"/></svg><i class="bat"></i></span></div>
<div class="navbar"><span class="back"><svg class="ico"><use href="#i-back"/></svg></span>身份核验</div>
<div class="body">
<div class="notice info">
<span class="ni"><svg class="ico lg"><use href="#i-shield"/></svg></span>
<div>为保护你的信息,请先填写<b>姓名</b>和<b>身份证号</b>,与老师提供的名单核对后才能填报。</div>
</div>
<div class="field">
<label>姓名<span class="req">*</span></label>
<input class="input" placeholder="请填写真实姓名" value="曾依豪">
</div>
<div class="field">
<label>身份证号<span class="req">*</span></label>
<input class="input mono" value="361029200907295110" readonly>
<div class="hint">共 18 位,最后一位可能是字母 X(会自动转为大写)</div>
</div>
<div class="notice ok" style="margin-top:18px">
<span class="ni"><svg class="ico lg"><use href="#i-check-circle"/></svg></span>
<div>格式检查通过</div>
</div>
</div>
<div class="foot">
<button class="btn primary">下一步</button>
<div class="center-note">填写即表示同意《个人信息处理告知同意书》</div>
</div>
</div></div>
<figcaption>
<span class="tag">STEP 01</span>
<b>门禁核验</b>
进入填报的唯一入口。身份证号用<span style="font-family:var(--font-mono)">等宽字体+字距</span>呈现,因为它是"数据"不是"文字"。<br>
<b style="display:inline;font-size:12.5px;color:var(--seal)">先在本地校验位数与校验位</b>,不合格当场提示、不发请求——既省流量,也防刷接口。
</figcaption>
</figure>
<!-- ② 形近字确认 -->
<figure>
<div class="device"><div class="screen">
<div class="statusbar"><span>9:41</span><span class="icons"><svg class="ico"><use href="#i-signal"/></svg><svg class="ico"><use href="#i-wifi"/></svg><i class="bat"></i></span></div>
<div class="navbar"><span class="back"><svg class="ico"><use href="#i-back"/></svg></span>确认姓名</div>
<div class="pagehead">
<div class="glyph"><svg class="ico xl"><use href="#i-help"/></svg></div>
<h2>你是不是曾伊豪?</h2>
<p>身份证号已和名单匹配上,但姓名不太一样。<br>请确认一下,这关系到你后续的证书信息。</p>
</div>
<div class="body">
<div class="panel">
<div class="row"><span class="k">你填写的</span><span class="v">曾依豪</span></div>
<div class="row"><span class="k">老师名单</span><span class="v" style="color:var(--jade)">曾伊豪</span></div>
</div>
<div class="notice warn">
<span class="ni"><svg class="ico lg"><use href="#i-bulb"/></svg></span>
<div>「依」和「伊」读音相同、字形相近,是最常见的写法差异。</div>
</div>
</div>
<div class="foot">
<div class="btnrow" style="margin-bottom:10px">
<button class="btn primary">是的,是我</button>
<button class="btn ghost">不是</button>
</div>
<div class="center-note">确认后姓名将按名单锁定,不可再改</div>
</div>
</div></div>
<figcaption>
<span class="tag">STEP 02</span>
<b>形近字确认</b>
不走"报错 → 重填",而是<span style="color:var(--seal)">把系统判断摆出来让用户裁决</span>。<br>
这个纠错能力来自真实数据——实测名单里就有「扬晨 ↔ 杨晨」的实例(差 1 字且拼音相同,命中规则但必须经人确认)。本屏用同类型的「曾依豪 ↔ 曾伊豪」示例,保持主角一致。
</figcaption>
</figure>
<!-- ③ 门禁失败 -->
<figure>
<div class="device"><div class="screen">
<div class="statusbar"><span>9:41</span><span class="icons"><svg class="ico"><use href="#i-signal"/></svg><svg class="ico"><use href="#i-wifi"/></svg><i class="bat"></i></span></div>
<div class="navbar"><span class="back"><svg class="ico"><use href="#i-back"/></svg></span>身份核验</div>
<div class="pagehead">
<div class="glyph gray"><svg class="ico xl"><use href="#i-search"/></svg></div>
<h2>没有找到你的信息</h2>
<p>请核对姓名和身份证号是否与老师提供的名单一致。<br>如确认已报名,请联系老师把你加入名单。</p>
</div>
<div class="body">
<div class="panel">
<div class="ptitle">本次填写 <span class="badge lock">已提交</span></div>
<div class="row"><span class="k">姓名</span><span class="v">曾伊豪</span></div>
<div class="row"><span class="k">身份证号</span><span class="v mono">361029********5511</span></div>
</div>
<div class="notice info">
<span class="ni"><svg class="ico lg"><use href="#i-shield"/></svg></span>
<div>出于隐私保护,系统<b>不会提示</b>具体是哪一项不符。</div>
</div>
</div>
<div class="foot">
<button class="btn primary" style="width:100%;margin-bottom:13px">重新填写</button>
<div class="center-note">连续 10 次未匹配将暂时锁定,1 小时后可重试</div>
</div>
</div></div>
<figcaption>
<span class="tag">STEP 03</span>
<b>门禁失败(统一提示)</b>
<span style="color:var(--seal)">故意不区分失败原因</span>——无论"号码不在名单"还是"姓名不符",文案完全一致。<br>
否则这个接口就能被用来<b style="display:inline">逐个探测身份证号是否在名单里</b>。这一屏是安全设计,不是文案设计。
<span class="note">底部只有一条<b>系统内的出路</b>:<br>
① <b>重新填写</b>(主路径)——大多数情况只是名字打错了;<br>
② 确实不在名单里时,<b>请联系老师把你加入名单</b>(由老师在任务里手工加人)。<br>
<b>系统内不展示任何联系方式</b>——学生在班级群里本来就有班主任的联系方式,系统再放一份既不必要,也带来维护与隐私成本。</span>
</figcaption>
</figure>
<!-- ④ 填报主页 -->
<figure>
<div class="device"><div class="screen">
<div class="statusbar"><span>9:41</span><span class="icons"><svg class="ico"><use href="#i-signal"/></svg><svg class="ico"><use href="#i-wifi"/></svg><i class="bat"></i></span></div>
<div class="navbar"><span class="back"><svg class="ico"><use href="#i-back"/></svg></span>我的填报</div>
<div class="taskbar">
<div class="tname">2026年9月机电专业认定材料收集</div>
<div class="tmeta"><span>截止 10-15</span><span>江西省机电技师学院</span></div>
</div>
<div class="body">
<div class="panel" style="display:flex;align-items:center;gap:14px">
<div class="ring" style="--p:50"><span>2/4</span></div>
<div>
<div style="font-size:14.5px;font-weight:600">曾伊豪 · 24中技数控1班</div>
<div style="font-size:11.5px;color:var(--ink3);margin-top:5px;line-height:1.55">还差 2 份材料,去传一下就能提交</div>
</div>
</div>
<div class="panel">
<div class="ptitle">报考信息 <span class="badge lock"><svg class="ico"><use href="#i-lock"/></svg>老师已确定</span></div>
<div class="row"><span class="k">报考职业</span><span class="v">车工</span></div>
<div class="row"><span class="k">报考工种</span><span class="v">数控车工</span></div>
<div class="row"><span class="k">报考等级</span><span class="v">四级/中级工</span></div>
</div>
<div class="panel">
<div class="ptitle">其他信息 <span class="badge edit"><svg class="ico"><use href="#i-pencil"/></svg>请核对,可改</span></div>
<div class="row"><span class="k">学历</span><span class="v">技工学校</span></div>
<div class="row"><span class="k">是否在校生</span><span class="v">是</span></div>
<div class="row"><span class="k">在读学校</span><span class="v">江西省机电技师学院</span></div>
<div class="row"><span class="k">所学专业</span><span class="v">数控加工(数控车工)</span></div>
<div class="row"><span class="k">入学时间</span><span class="v mono">2024-09-01</span></div>
<div class="row"><span class="k">联系电话</span><span class="v mono">19970570823</span></div>
</div>
<div class="panel flush">
<div style="padding:15px 15px 11px"><div class="ptitle" style="margin:0">需要上传的材料 <span class="badge doc"><svg class="ico"><use href="#i-file"/></svg>你的活</span></div></div>
<div class="mat">
<div class="thumb ok"><svg class="ico"><use href="#i-image"/></svg></div>
<div class="info"><div class="mname">一寸照片 <span class="state pass">已通过</span></div>
<div class="mdesc done">曾伊豪-...-一寸照片.jpg · 96KB</div></div>
</div>
<div class="mat">
<div class="thumb ok"><svg class="ico"><use href="#i-idcard"/></svg></div>
<div class="info"><div class="mname">身份证 <span class="state pass">已通过</span></div>
<div class="mdesc done">曾伊豪-...-身份证.jpg · 810KB</div></div>
</div>
<div class="mat">
<div class="thumb"><svg class="ico"><use href="#i-file"/></svg></div>
<div class="info"><div class="mname">学籍表 <span class="state none">未上传</span></div>
<div class="mdesc">教务系统截图,从手机相册里选</div></div>
</div>
<div class="mat">
<div class="thumb"><svg class="ico"><use href="#i-stamp"/></svg></div>
<div class="info"><div class="mname">工作证明 <span class="state none">未上传</span></div>
<div class="mdesc">打印店扫描后会发给你,从聊天记录里选</div></div>
</div>
</div>
</div>
<div class="foot"><button class="btn primary" disabled>还差 2 份材料</button></div>
</div></div>
<figcaption>
<span class="tag">STEP 04 · 核心屏</span>
<b>填报主页:一屏看完,几乎不用打字</b>
三块分区严格对应「字段三类规则」——报考信息<span style="color:var(--seal)">锁定</span>、其他信息<span style="color:var(--amber)">可核对修改</span>、材料才是学生要干的活。<br>
实测老师名单已填满 21 项中的 18 项,所以学生上来只是<b style="display:inline">核对着点两下 + 传文件</b>。
</figcaption>
</figure>
<!-- ⑤ 来源选择 -->
<figure>
<div class="device"><div class="screen">
<div class="statusbar"><span>9:41</span><span class="icons"><svg class="ico"><use href="#i-signal"/></svg><svg class="ico"><use href="#i-wifi"/></svg><i class="bat"></i></span></div>
<div class="navbar"><span class="back"><svg class="ico"><use href="#i-back"/></svg></span>上传工作证明</div>
<div class="body">
<div class="notice info">
<span class="ni"><svg class="ico lg"><use href="#i-pin"/></svg></span>
<div><b>去哪里找这份材料?</b><br>打印店扫描完会发到你的微信,通常就在<b>聊天记录</b>里。</div>
</div>
<div class="panel">
<div class="ptitle">材料要求</div>
<div class="row"><span class="k">格式</span><span class="v">JPG / PNG / PDF</span></div>
<div class="row"><span class="k">大小</span><span class="v">不超过 1M(系统会自动压缩)</span></div>
<div class="row"><span class="k">内容</span><span class="v">手签并加盖学校公章的扫描件</span></div>
<div class="row"><span class="k">命名</span><span class="v mono dim">姓名-身份证号-工作证明.jpg</span></div>
</div>
<div class="notice ok">
<span class="ni"><svg class="ico lg"><use href="#i-sparkle"/></svg></span>
<div>命名不用你操心,<b>系统会自动改好</b>。</div>
</div>
</div>
<div class="mask"></div>
<div class="sheet">
<div class="grab"></div>
<h3>选择材料来源</h3>
<div class="stip">优先从聊天记录选——文件名里带着你的信息,系统能自动识别</div>
<div class="scard rec">
<div class="sicon"><svg class="ico"><use href="#i-chat"/></svg></div>
<div class="stxt"><div class="st">从微信聊天记录选择 <span class="recommend">推荐</span></div>
<div class="sd">照相馆、打印店、老师发来的文件都在这里</div></div>
</div>
<div class="scard">
<div class="sicon"><svg class="ico"><use href="#i-image"/></svg></div>
<div class="stxt"><div class="st">从手机相册选择</div>
<div class="sd">系统截图、已有的翻拍件在这里</div></div>
</div>
<div class="scard">
<div class="sicon"><svg class="ico"><use href="#i-folder"/></svg></div>
<div class="stxt"><div class="st">从手机文件选择</div>
<div class="sd">PDF 扫描件、Word 版申报表在这里</div></div>
</div>
<div class="center-note" style="margin-top:6px">不提供"直接拍照"——所有材料都是已有的文件</div>
</div>
</div></div>
<figcaption>
<span class="tag">STEP 05</span>
<b>材料来源选择</b>
<span style="color:var(--seal)">刻意没有"拍照"入口</span>。实测 4 类材料(教务截图 / 打印店扫描件 / 照相馆电子版 / 翻拍件)<b style="display:inline">没有一类来自现场拍照</b>。<br>
「从聊天记录选」被标为推荐,因为微信会返回<b style="display:inline">原始文件名</b>——那是命名引擎最可靠的信息源。
</figcaption>
</figure>
<!-- ⑥ 处理中 -->
<figure>
<div class="device"><div class="screen">
<div class="statusbar"><span>9:41</span><span class="icons"><svg class="ico"><use href="#i-signal"/></svg><svg class="ico"><use href="#i-wifi"/></svg><i class="bat"></i></span></div>
<div class="navbar"><span class="back"><svg class="ico"><use href="#i-back"/></svg></span>正在处理</div>
<div class="body" style="display:flex;flex-direction:column;justify-content:center;min-height:100%">
<div style="text-align:center;margin-bottom:30px">
<div class="ring" style="--p:64;width:92px;height:92px;margin:0 auto 20px"><span style="font-size:19px">64%</span></div>
<div style="font-family:var(--font-display);font-size:19px;letter-spacing:.05em">正在处理你的材料</div>
<div style="font-size:12px;color:var(--ink3);margin-top:8px">请稍候,不要退出</div>
</div>
<div class="panel">
<div class="vitem" style="border-top:0"><span class="vi ok"><svg class="ico"><use href="#i-check-circle"/></svg></span><span class="vt">已上传 <b>16.14 MB</b></span></div>
<div class="vitem"><span class="vi ok"><svg class="ico"><use href="#i-check-circle"/></svg></span><span class="vt">识别为 <b>工作证明</b>(A4 扫描件)</span></div>
<div class="vitem"><span class="vi work"><svg class="ico"><use href="#i-refresh"/></svg></span><span class="vt">正在<b>规范化文件名</b>…</span></div>
<div class="vitem"><span class="vi wait"><svg class="ico"><use href="#i-clock"/></svg></span><span class="vt" style="color:var(--ink3)">压缩到 1M 以内</span></div>
<div class="vitem"><span class="vi wait"><svg class="ico"><use href="#i-clock"/></svg></span><span class="vt" style="color:var(--ink3)">校验材料一致性</span></div>
</div>
</div>
</div></div>
<figcaption>
<span class="tag">STEP 06</span>
<b>处理过程可见</b>
把"秒级黑箱"拆成可读的步骤。<br>
实测最大的扫描件有 <b style="display:inline">1.8 亿像素</b>、处理需几秒——这几秒如果不解释,用户会以为卡死并退出。
</figcaption>
</figure>
<!-- ⑦ 处理结果(核心亮点) -->
<figure>
<div class="device"><div class="screen">
<div class="statusbar"><span>9:41</span><span class="icons"><svg class="ico"><use href="#i-signal"/></svg><svg class="ico"><use href="#i-wifi"/></svg><i class="bat"></i></span></div>
<div class="navbar"><span class="back"><svg class="ico"><use href="#i-back"/></svg></span>材料已受理</div>
<div class="body">
<div class="filecard">
<div class="stamp jade">已规范</div>
<div class="fc-label">你上传的文件名</div>
<div class="fname old">曾伊豪-361029200907295110工作证明<span class="fix">.jpg.jpg</span><i class="strike"></i></div>
<div class="fc-arrow"><span class="line"></span>已自动规范化<span class="line"></span></div>
<div class="fc-label">规范后的文件名</div>
<div class="fname new">曾伊豪-361029200907295110<span class="ok">-</span>工作证明.jpg</div>
</div>
<div class="panel">
<div class="ptitle">系统为你修正了 2 处</div>
<div class="vitem" style="border-top:0">
<span class="vi"><svg class="ico"><use href="#i-sliders"/></svg></span>
<span class="vt">多余的扩展名 <b>.jpg.jpg</b> → <b>.jpg</b></span></div>
<div class="vitem">
<span class="vi"><svg class="ico"><use href="#i-sliders"/></svg></span>
<span class="vt">缺少连接符 → 已插入 <b>-</b></span></div>
</div>
<div class="panel">
<div class="ptitle">体积压缩</div>
<div class="vol">
<span class="from">16.14 MB</span>
<span style="color:var(--ink3)">→</span>
<span class="to">806 KB</span>
<span class="pct">省下 95%</span>
</div>
<div class="hint" style="margin-top:9px">已按 A4 纸张等比缩至 300dpi 标准扫描清晰度,<b>公章与手写签名仍然清晰可辨</b>。</div>
</div>
<div class="panel">
<div class="ptitle">校验结果</div>
<div class="vitem" style="border-top:0"><span class="vi ok"><svg class="ico"><use href="#i-check-circle"/></svg></span><span class="vt">身份证号与老师名单一致</span></div>
<div class="vitem"><span class="vi ok"><svg class="ico"><use href="#i-check-circle"/></svg></span><span class="vt">与你的其他材料一致</span></div>
<div class="vitem"><span class="vi ok"><svg class="ico"><use href="#i-check-circle"/></svg></span><span class="vt">体积符合要求(≤ 1M)</span></div>
</div>
</div>
<div class="foot"><button class="btn primary">确认,继续传下一份</button></div>
</div></div>
<figcaption>
<span class="tag">STEP 07 · 全原型最核心</span>
<b>上传即规范化:让用户看见系统替他干了什么</b>
这是整个产品的价值可视化。用户交上来一个 <span style="font-family:var(--font-mono);font-size:11px">.jpg.jpg</span> 的乱名文件,<span style="color:var(--seal)">红笔划掉</span>、<span style="color:var(--jade)">盖"已规范"章</span>,再报出压缩率。<br>
<b style="display:inline">刻意把"原名"留得很丑、把"新名"留得很干净</b>——对比越强烈,价值感越强。
</figcaption>
</figure>
<!-- ⑧ 传错位置 -->
<figure>
<div class="device"><div class="screen">
<div class="statusbar"><span>9:41</span><span class="icons"><svg class="ico"><use href="#i-signal"/></svg><svg class="ico"><use href="#i-wifi"/></svg><i class="bat"></i></span></div>
<div class="navbar"><span class="back"><svg class="ico"><use href="#i-back"/></svg></span>学籍表</div>
<div class="body">
<div class="notice warn">
<span class="ni"><svg class="ico lg"><use href="#i-alert"/></svg></span>
<div><b>这张看起来是工作证明,你已经传过这一项了。</b><br>要重新选一张学籍表吗?</div>
</div>
<div class="filecard" style="border-color:#e8d9b5">
<div class="fc-label">系统识别</div>
<div class="fname new">工作证明 <span style="color:var(--jade);font-weight:600">置信度 93%</span></div>
<div style="height:9px"></div>
<div class="fc-label">识别依据</div>
<div class="fname" style="font-size:11.5px;color:var(--ink2)">
检测到关键词「申报表」「职业技能等级认定」「兹证明」<br>
版面为 A4 纸张扫描件(约 1.6 亿像素)
</div>
</div>
<div class="notice info">
<span class="ni"><svg class="ico lg"><use href="#i-bulb"/></svg></span>
<div>系统只做提示,<b>不会自动移动或替换你的文件</b>。</div>
</div>
</div>
<div class="foot">
<div class="btnrow"><button class="btn seal">重新选择</button><button class="btn ghost">就放这里</button></div>
</div>
</div></div>
<figcaption>
<span class="tag">STEP 08</span>
<b>传错位置:只提示,不擅自改</b>
识别必然有误判。<b style="display:inline;color:var(--seal)">自动挪位置比传错更危险</b>——它会把用户原本放对的文件挪走。所以规则是:给依据、给建议、<b style="display:inline">把决定权留给用户</b>。<br>
<span style="color:var(--ink3);font-size:11.5px">本屏演示的是<b style="display:inline">目标槽位已占用</b>的情形——学生刚传完工作证明,再去传学籍表时误选了同一张图,系统识别为"重复"并只建议重新选择。<br>
若目标槽位<b style="display:inline">为空</b>(如工作证明还没传),系统会给出「移到『工作证明』」——<b style="display:inline">能移才移,不能移就只提示</b>。</span>
</figcaption>
</figure>
<!-- ⑨ 提交确认 -->
<figure>
<div class="device"><div class="screen">
<div class="statusbar"><span>9:41</span><span class="icons"><svg class="ico"><use href="#i-signal"/></svg><svg class="ico"><use href="#i-wifi"/></svg><i class="bat"></i></span></div>
<div class="navbar"><span class="back"><svg class="ico"><use href="#i-back"/></svg></span>提交前确认</div>
<div class="body">
<div class="panel">
<div class="ptitle">4 项材料 <span class="badge doc">3 项就绪</span></div>
<div class="vitem" style="border-top:0"><span class="vi ok"><i class="dot doc"></i></span>
<span class="vt">一寸照片 <b style="font-family:var(--font-mono);font-size:11.5px">96KB</b></span></div>
<div class="vitem"><span class="vi ok"><i class="dot doc"></i></span>
<span class="vt">身份证 <b style="font-family:var(--font-mono);font-size:11.5px">810KB</b></span></div>
<div class="vitem"><span class="vi ok"><i class="dot doc"></i></span>
<span class="vt">工作证明 <b style="font-family:var(--font-mono);font-size:11.5px">806KB</b></span></div>
<div class="vitem"><span class="vi" style="color:var(--amber)"><i class="dot edit"></i></span>
<span class="vt" style="color:var(--amber)">学籍表 分辨率偏低,放大后可能看不清</span></div>
</div>
<div class="notice warn">
<span class="ni"><svg class="ico lg"><use href="#i-alert"/></svg></span>
<div><b>1 项建议处理</b><br>学籍表这张图只有 1024×590,建议让老师重发一张更清晰的。也可以选择继续提交。</div>
</div>
<div style="display:flex;align-items:center;gap:9px;padding:12px 4px">
<input type="checkbox" id="ck" checked style="width:17px;height:17px;accent-color:var(--amber)">
<label for="ck" style="font-size:12.5px;color:var(--ink2)">我已确认,继续提交</label>
</div>
</div>
<div class="foot"><button class="btn seal">提交审核</button></div>
</div></div>
<figcaption>
<span class="tag">STEP 09</span>
<b>提交前确认:红黄绿汇总</b>
<span style="color:var(--seal)">红色</span>阻断项必须处理才能提交;<span style="color:var(--amber)">黄色</span>警告项需勾选"我已确认"后放行。<br>
注意这里<b style="display:inline">没有阻断项</b>——因为不合格的内容在<b style="display:inline">上传那一刻</b>就已经被拦下并修正了,不会累积到最后。
</figcaption>
</figure>
<!-- ⑩ 提交成功 -->
<figure>
<div class="device"><div class="screen">
<div class="statusbar"><span>9:41</span><span class="icons"><svg class="ico"><use href="#i-signal"/></svg><svg class="ico"><use href="#i-wifi"/></svg><i class="bat"></i></span></div>
<div class="navbar"><span class="back"><svg class="ico"><use href="#i-back"/></svg></span>填报进度</div>
<div class="pagehead">
<div class="glyph ok"><svg class="ico xl"><use href="#i-check"/></svg></div>
<h2>已提交,等待审核</h2>
<p>班主任审核通过后,会汇总给学校管理员终审。</p>
</div>
<div class="body">
<div class="panel">
<div class="ptitle">审核进度</div>
<div class="tl">
<div class="node"><div class="nd done"><svg class="ico"><use href="#i-check"/></svg></div>
<div class="nc"><div class="nt">材料提交完成</div><div class="ns">今天 09:41</div></div></div>
<div class="node"><div class="nd now">●</div>
<div class="nc"><div class="nt">班主任初审</div><div class="ns">李老师 · 一般 1 个工作日内处理</div></div></div>
<div class="node"><div class="nd">3</div>
<div class="nc"><div class="nt dim">学校管理员终审</div><div class="ns">初审通过后开始</div></div></div>
<div class="node"><div class="nd">4</div>
<div class="nc"><div class="nt dim">汇总上报</div><div class="ns">终审通过后由学校统一上报</div></div></div>
</div>
</div>
<div class="notice info">
<span class="ni"><svg class="ico lg"><use href="#i-bell"/></svg></span>
<div>审核结果会通过微信通知你,无需反复查看。</div>
</div>
<div style="text-align:center;margin-top:18px"><span class="link">需要修改?联系班主任</span></div>
</div>
</div></div>
<figcaption>
<span class="tag">STEP 10</span>
<b>进度透明,减少追问</b>
把"提交后一片黑"变成可见的时间轴。<br>
实测场景里班主任最常被追问的就是"我交了没""审到哪了"——<b style="display:inline">这一屏直接消灭这类沟通成本</b>。
</figcaption>
</figure>
</main>
<section class="apron">
<h3>设计依据 · 每一屏都对着一条真实数据</h3>
<div class="aside-grid">
<div class="aside-card">
<h4><span class="n">01</span>为什么学生几乎不用打字</h4>
实测老师交上来的名单里,21 个字段<b>已填满 18 个</b>(学历、在校生、学校、专业、入学时间、报考三项、联系电话全部有值)。所以学生端的任务是<b>核对 + 传文件</b>,不是填表。
</div>
<div class="aside-card">
<h4><span class="n">02</span>为什么报考信息要锁定</h4>
整班 28 人的报考三项<b>完全一致</b>(车工 / 数控车工 / 四级中级工)——这是老师按机构要求统一定的。<b>让学生去选只会制造错误。</b>要改,只能找老师。
</div>
<div class="aside-card">
<h4><span class="n">03</span>为什么没有"拍照"</h4>
学籍表是<b>教务系统截图</b>、工作证明是<b>打印店扫描件</b>、一寸照是<b>照相馆电子版</b>、身份证是翻拍件——<b>没有一类来自现场拍照</b>。拍照只会引入模糊、畸变、反光。
</div>
<div class="aside-card">
<h4><span class="n">04</span>为什么失败提示不写原因</h4>
如果提示"身份证号不在名单",这个接口就能被用来<b>逐个探测身份证号是否在名单里</b>。安全要求优先于用户体验。
</div>
<div class="aside-card">
<h4><span class="n">05</span>为什么压缩率要显式告知</h4>
用户最怕的是"你把我文件动了"。<b>把 16.14MB → 810KB 写出来</b>,并说明"300dpi 清晰度无损",才能建立信任。这也是认定机构最关心的问题。
</div>
<div class="aside-card">
<h4><span class="n">06</span>为什么识别错误不自动纠正</h4>
系统识别必然有误判。<b>自动挪文件比传错更危险</b>——它会把放对的文件挪走。所以只给建议与依据,决定权始终在用户手里。
</div>
</div>
</section>
<script>
const figs=[...document.querySelectorAll('figure')];
figs.forEach(f=>{f.style.opacity='0';f.style.transform='translateY(22px)';
f.style.transition='opacity .6s cubic-bezier(.2,.8,.3,1),transform .6s cubic-bezier(.2,.8,.3,1)';});
const io=new IntersectionObserver(es=>{es.forEach(e=>{if(e.isIntersecting){
const i=figs.indexOf(e.target);
setTimeout(()=>{e.target.style.opacity='1';e.target.style.transform='translateY(0)';},(i%3)*110);
io.unobserve(e.target);}});},{threshold:.12});
figs.forEach(f=>io.observe(f));
document.querySelectorAll('.scard').forEach(c=>{
c.addEventListener('click',()=>{
document.querySelectorAll('.scard').forEach(x=>x.style.borderColor='');
c.style.borderColor='#c0392b';
});
});
</script>
</body>
</html>