Files
bid-doctor/docs/design/ui-demo/controls.html
YANG JIANKUAN e1a9017cd1 docs(design): 新增 UI demo 页面,供 UI 精修评审
- docs/design/ui-demo/:控件总览、表单、卡片、列表与表格,以及工作台、读标两个组合页
- 只用设计规范的变量和组件;新增组件样式放在 demo.css,清单见 index
- index 列出 UI 精修待定问题 Q1–Q12
- design/README 与 AGENTS.md 进度同步

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 12:46:27 +08:00

493 lines
46 KiB
HTML
Raw 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">
<title>控件总览 · 标博士 UI demo</title>
<link rel="icon" href="../logo/favicon.svg">
<link rel="stylesheet" href="../system/tokens.css">
<link rel="stylesheet" href="../system/fonts-local.css">
<link rel="stylesheet" href="../system/components.css">
<link rel="stylesheet" href="demo.css">
</head>
<body class="demo">
<header data-demo-top></header>
<main class="d-page">
<div class="d-head">
<h1>① 控件总览</h1>
<p>每个控件按「默认 → 悬停 → 按下 → 聚焦 → 禁用 → 加载中 / 错误」陈列。灰色小字是状态名;标「可以点」的是可交互的。示意数据取自原型的「某市政务服务中心智慧大厅建设项目」。</p>
<nav class="d-toc" aria-label="本页目录">
<a href="#s-btn">01 按钮</a><a href="#s-input">02 输入框</a><a href="#s-select">03 下拉选择</a><a href="#s-date">04 日期选择</a><a href="#s-check">05 复选 · 单选 · 开关</a><a href="#s-tag">06 标签与标识</a><a href="#s-cite">07 出处</a><a href="#s-alert">08 提醒</a><a href="#s-toast">09 轻提示</a><a href="#s-dialog">10 对话框</a><a href="#s-tabs">11 标签页 · 分段 · 分页</a><a href="#s-empty">12 空状态 · 骨架屏 · 进度</a><a href="#s-tip">13 提示气泡 · 菜单 · 快捷键</a>
</nav>
</div>
<!-- 01 按钮 -->
<section class="d-sec" id="s-btn">
<div class="d-sec-h"><span class="no">01</span><h2>按钮</h2><span class="ref">规范 §7.1 · §8.3</span></div>
<div class="d-box">
<h3>类型 × 状态</h3>
<table class="d-matrix">
<thead><tr><th></th><th>默认</th><th>悬停</th><th>按下</th><th>键盘聚焦</th><th>禁用</th><th>加载中</th></tr></thead>
<tbody>
<tr><td>主按钮</td><td><button class="btn primary">发起检查</button></td><td><button class="btn primary is-hover">发起检查</button></td><td><button class="btn primary is-active">发起检查</button></td><td><button class="btn primary is-focus">发起检查</button></td><td><button class="btn primary" disabled>发起检查</button></td><td><button class="btn primary swap is-loading" aria-busy="true"><span class="idle">发起检查</span><span class="busy">正在发起…</span></button></td></tr>
<tr><td>次按钮</td><td><button class="btn">导出报告</button></td><td><button class="btn is-hover">导出报告</button></td><td><button class="btn is-active">导出报告</button></td><td><button class="btn is-focus">导出报告</button></td><td><button class="btn" disabled>导出报告</button></td><td><button class="btn swap is-loading" aria-busy="true"><span class="idle">导出报告</span><span class="busy">正在导出…</span></button></td></tr>
<tr><td>文字按钮</td><td><button class="btn text">查看处理记录</button></td><td><button class="btn text is-hover">查看处理记录</button></td><td><button class="btn text is-active">查看处理记录</button></td><td><button class="btn text is-focus">查看处理记录</button></td><td><button class="btn text" disabled>查看处理记录</button></td><td><span class="d-cap">(不用)</span></td></tr>
</tbody>
</table>
<ul class="d-rules">
<li>一屏只有一个主按钮。没有红色的危险按钮:删除用次按钮 + 确认对话框。</li>
<li>加载中把文字换成「正在…」,两段文字叠在同一格里,按较宽的定宽,切换时按钮不跳动;不加转圈图标。</li>
<li>主按钮悬停变浅 8%(用 color-mix 计算,不新增颜色变量);按下回到墨色并加一道内阴影。</li>
</ul>
</div>
<div class="d-grid c3" style="margin-top:var(--sp-6)">
<div class="d-box">
<h3>尺寸</h3>
<div class="d-row"><button class="btn sm">确认无误</button><button class="btn">确认无误</button><button class="btn lg primary">上传招标文件</button></div>
<ul class="d-rules"><li>28:表格行内 · 32:默认 · 40:登录页、空状态</li></ul>
</div>
<div class="d-box">
<h3>带图标 · 只有图标</h3>
<div class="d-row">
<button class="btn"><i data-ic="upload"></i>上传投标文件</button>
<button class="icon-btn bordered" aria-label="下载报告" data-tip="下载报告"><i data-ic="download"></i></button>
<button class="icon-btn" aria-label="处理记录" data-tip="处理记录"><i data-ic="history"></i></button>
<button class="icon-btn" aria-label="删除" data-tip="删除(不可用:项目已归档)" disabled><i data-ic="trash"></i></button>
</div>
<div class="d-row"><span class="btn-group"><button class="btn sm">上一处</button><button class="btn sm">下一处</button></span></div>
<ul class="d-rules"><li>图标必须和文字一起出现;只有图标时要有 aria-label 和悬停提示。</li></ul>
</div>
<div class="d-box">
<h3>会扣点的按钮 <small>可以点</small></h3>
<div class="d-row"><button class="btn primary swap" data-loading="检查已开始,可以离开本页,完成后会发站内通知"><span class="idle">发起检查</span><span class="busy">正在发起…</span></button><span class="cost">扣 1 次检查 · 剩 <span class="fig">12</span> 次</span></div>
<div class="d-row"><button class="btn swap" data-loading="已开始复查"><span class="idle">重新检查</span><span class="busy">正在发起…</span></button><span class="cost">24 小时内复查,不扣额度</span></div>
<div class="d-row"><button class="btn primary" data-nomore>发起检查</button><span class="cost">剩 <span class="fig">0</span> 次 · 按钮仍可点</span></div>
</div>
</div>
</section>
<!-- 02 输入框 -->
<section class="d-sec" id="s-input">
<div class="d-sec-h"><span class="no">02</span><h2>输入框与文本域</h2><span class="ref">规范 §7.13</span></div>
<div class="d-box">
<div class="d-states wide">
<div class="d-state"><small>默认(占位符用辅助灰)</small><div class="field"><label for="i1">项目名称 <small>(必填)</small></label><input class="input" id="i1" placeholder="例如:智慧大厅建设项目"></div></div>
<div class="d-state"><small>悬停</small><div class="field"><label>项目编号</label><input class="input is-hover" placeholder="招标文件封面上的编号"></div></div>
<div class="d-state"><small>聚焦(2px 墨色焦点环 + 2px 间隙)</small><div class="field"><label>项目编号</label><input class="input is-focus" value="ZC-2026-04"></div></div>
<div class="d-state"><small>已填写</small><div class="field"><label>采购人</label><input class="input" value="某市政务服务管理办公室"></div></div>
<div class="d-state"><small>错误(赭色,不用红)</small><div class="field err"><label>联系人手机</label><input class="input" value="1381234567" aria-invalid="true"><span class="msg"><span class="ico w">!</span>手机号应为 11 位数字</span></div></div>
<div class="d-state"><small>禁用</small><div class="field dis"><label>法律体系</label><input class="input" value="政府采购" disabled></div></div>
<div class="d-state"><small>只读(系统识别结果,可复制)</small><div class="field"><label>文件页数</label><input class="input" value="186 页" readonly></div></div>
<div class="d-state"><small>带说明文字</small><div class="field"><label>投标有效期</label><div class="input-unit"><input class="input" value="90"><span class="unit">天</span></div><span class="msg">从投标截止日起算,招标文件第 21 页</span></div></div>
</div>
</div>
<div class="d-grid c2" style="margin-top:var(--sp-6)">
<div class="d-box">
<h3>文本域 · 字数 <small>可以输入</small></h3>
<div class="field fill" data-count-field>
<label for="ta1">忽略原因 <small>(必填,至少 5 个字)</small></label>
<textarea class="input" id="ta1" maxlength="200" placeholder="写清楚为什么不处理,报告里会如实列出"></textarea>
<div class="msg-row"><span class="msg">报告和处理记录里会显示这段原因。</span><span class="count"><span data-n>0</span> / 200</span></div>
</div>
</div>
<div class="d-box">
<h3>搜索框</h3>
<label class="search"><i data-ic="search"></i><input class="input" placeholder="搜索项目名称、采购人、项目编号" aria-label="搜索项目"><span class="kbd">/</span></label>
<div style="height:var(--sp-4)"></div>
<label class="search" style="width:240px"><i data-ic="search"></i><input class="input" value="服务器" aria-label="搜索清单"></label>
<ul class="d-rules"><li>搜索框的放大镜只做辅助,占位符写清楚能搜什么。</li><li>输入框高 32,左右内边距 10;数值输入用 Barlow 等宽数字。</li></ul>
</div>
</div>
</section>
<!-- 03 下拉选择 -->
<section class="d-sec" id="s-select">
<div class="d-sec-h"><span class="no">03</span><h2>下拉选择</h2><span class="ref">AR10 · Reka UI Select 打底</span></div>
<div class="d-box">
<div class="d-states wide">
<div class="d-state"><small>未选择</small><div class="field"><label>采购方式 <small>(必填)</small></label>
<div class="pop" data-select><button type="button" class="select" aria-haspopup="listbox" aria-expanded="false"><span class="val"><span class="ph">请选择</span></span><i data-ic="chev-down"></i></button>
<ul class="menu" role="listbox"><li class="grp">政府采购</li><li role="option">公开招标</li><li role="option">邀请招标</li><li role="option">竞争性磋商</li><li role="option">竞争性谈判</li><li role="option">询价</li><li class="grp">招标投标</li><li role="option">公开招标(招标投标法)</li></ul></div></div></div>
<div class="d-state"><small>已选择 · 可以点</small><div class="field"><label>采购方式</label>
<div class="pop" data-select><button type="button" class="select" aria-haspopup="listbox" aria-expanded="false"><span class="val">公开招标</span><i data-ic="chev-down"></i></button>
<ul class="menu" role="listbox"><li class="grp">政府采购</li><li role="option" aria-selected="true">公开招标</li><li role="option">邀请招标</li><li role="option">竞争性磋商</li><li role="option">竞争性谈判</li><li role="option">询价</li><li class="grp">招标投标</li><li role="option">公开招标(招标投标法)</li></ul></div></div></div>
<div class="d-state d-open"><small>展开(浮层:4px 圆角 + 阴影)</small><div class="field"><label>所投的包</label>
<div class="pop"><button type="button" class="select is-focus" aria-expanded="true"><span class="val">采购包 1 · 智慧大厅软硬件集成</span><i data-ic="chev-down"></i></button>
<ul class="menu" role="listbox"><li role="option" aria-selected="true">采购包 1 · 智慧大厅软硬件集成</li><li role="option" class="is-active">采购包 2 · 机房网络设备更新</li><li role="option" aria-disabled="true">采购包 3 · 已终止<small>补遗 1</small></li></ul></div></div></div>
<div class="d-state"><small>错误</small><div class="field err"><label>资质类型 <small>(必填)</small></label>
<div class="pop" data-select><button type="button" class="select" aria-haspopup="listbox" aria-expanded="false" aria-invalid="true"><span class="val"><span class="ph">请选择</span></span><i data-ic="chev-down"></i></button>
<ul class="menu" role="listbox"><li role="option">资质证书</li><li role="option">体系认证</li><li role="option">软件著作权</li><li role="option">其他</li></ul></div>
<span class="msg"><span class="ico w">!</span>请选择资质类型,查标时按类型核对</span></div></div>
<div class="d-state"><small>禁用</small><div class="field dis"><label>法律体系</label><div class="pop"><button type="button" class="select" disabled><span class="val">政府采购</span><i data-ic="chev-down"></i></button></div><span class="msg">由招标文件识别,在项目设置里修改</span></div></div>
<div class="d-state"><small>表格行内(28 高)</small><div class="pop inline" data-select><button type="button" class="select sm" aria-haspopup="listbox" aria-expanded="false" style="width:132px"><span class="val">技术册</span><i data-ic="chev-down"></i></button>
<ul class="menu" role="listbox"><li role="option">商务册</li><li role="option" aria-selected="true">技术册</li><li role="option">报价册</li><li role="option">资格证明册</li></ul></div></div>
</div>
<ul class="d-rules"><li>键盘:↑ ↓ 移动、Enter 选中、Esc 收起。选中项加粗并在右侧打 ✓(形状 + 字重,不只靠颜色)。</li><li>不可选的项用禁用灰,并在右侧写原因。</li></ul>
</div>
</section>
<!-- 04 日期选择 -->
<section class="d-sec" id="s-date">
<div class="d-sec-h"><span class="no">04</span><h2>日期选择</h2><span class="ref">规范 §9.3 · AR10</span></div>
<div class="d-grid c3">
<div class="d-box">
<h3>收起 · 可以点</h3>
<div class="field"><label>投标截止 <small>(必填)</small></label>
<div class="dt-pair"><div class="pop" data-date data-value="2026-11-20" data-marks="2026-11-9,2026-11-20"><button type="button" class="select date-trigger" aria-haspopup="dialog" aria-expanded="false"><span class="val">2026-11-20</span><i data-ic="calendar"></i></button><div class="cal"></div></div><input class="input date-trigger" value="09:30" aria-label="时间"></div>
<span class="msg">以补遗 1 的更正为准 · 剩 <span class="fig m">17</span> 天</span></div>
<div class="field" style="margin-top:var(--sp-4)"><label>证书有效期至</label>
<div class="pop" data-date data-month="2026-11"><button type="button" class="select date-trigger" aria-haspopup="dialog" aria-expanded="false"><span class="val"><span class="ph">选择日期</span></span><i data-ic="calendar"></i></button><div class="cal"></div></div></div>
<div class="field err" style="margin-top:var(--sp-4)"><label>发证日期</label>
<div class="pop"><button type="button" class="select date-trigger" aria-invalid="true"><span class="val">2027-03-01</span><i data-ic="calendar"></i></button></div>
<span class="msg"><span class="ico w">!</span>发证日期晚于有效期,请核对证书</span></div>
</div>
<div class="d-box">
<h3>展开</h3>
<div class="pop d-open" data-date data-value="2026-11-20" data-marks="2026-11-9,2026-11-20" data-time="09:30"><div class="cal"></div></div>
<ul class="d-rules"><li>一周从周一开始;数字用 Barlow 等宽。</li><li>今天:控件灰描边;选中:墨底白字;关键日期:下方小圆点。</li></ul>
</div>
<div class="d-box">
<h3>有不可选的日期</h3>
<div class="pop d-open" data-date data-month="2026-11" data-min="2026-11-03"><div class="cal"></div></div>
<ul class="d-rules"><li>不可选的日期加删除线(不只靠变灰)。</li><li>界面显示「11月20日 09:30」,输入框里用「2026-11-20」便于核对和粘贴。</li></ul>
</div>
</div>
</section>
<!-- 05 复选 单选 开关 -->
<section class="d-sec" id="s-check">
<div class="d-sec-h"><span class="no">05</span><h2>复选 · 单选 · 开关</h2><span class="ref">规范 §8.2 批量勾选</span></div>
<div class="d-grid c3">
<div class="d-box">
<h3>复选框</h3>
<div class="d-states">
<div class="d-state"><small>未选</small><label class="choice"><input type="checkbox" class="ck">提示</label></div>
<div class="d-state"><small>已选</small><label class="choice"><input type="checkbox" class="ck" checked>提示</label></div>
<div class="d-state"><small>半选(表头全选)</small><label class="choice"><input type="checkbox" class="ck" data-indeterminate>全选</label></div>
<div class="d-state"><small>聚焦</small><label class="choice"><input type="checkbox" class="ck is-focus">重要</label></div>
<div class="d-state"><small>禁用</small><label class="choice dis" data-tip="只有「提示」级可以批量处理"><input type="checkbox" class="ck" disabled>致命</label></div>
<div class="d-state"><small>禁用 · 已选</small><label class="choice dis"><input type="checkbox" class="ck" disabled checked>已归档</label></div>
</div>
<div class="choices" style="margin-top:var(--sp-5)">
<label class="choice"><input type="checkbox" class="ck" checked><span>电子投标文件已使用 CA 数字证书加密<small>需人工核对 · 招标文件第 21 页</small></span></label>
<label class="choice"><input type="checkbox" class="ck"><span>在截止时间前于电子交易平台上传,并取得回执<small>需人工核对 · 招标文件第 6 页</small></span></label>
</div>
</div>
<div class="d-box">
<h3>单选</h3>
<div class="d-states">
<div class="d-state"><small>未选</small><label class="choice"><input type="radio" class="ck" name="r0">招标投标</label></div>
<div class="d-state"><small>已选</small><label class="choice"><input type="radio" class="ck" name="r0b" checked>政府采购</label></div>
<div class="d-state"><small>禁用</small><label class="choice dis"><input type="radio" class="ck" disabled>企业自主采购</label></div>
<div class="d-state"><small>禁用 · 已选</small><label class="choice dis"><input type="radio" class="ck" disabled checked>政府采购</label></div>
</div>
<span class="d-label" style="margin-top:var(--sp-5)">单选卡片(选项需要说明时)</span>
<div class="choices">
<label class="choice-card"><input type="radio" class="ck" name="r1" checked><span><b>政府采购</b><small>按《政府采购法》和 87 号令检查,结论用「投标无效」</small></span></label>
<label class="choice-card"><input type="radio" class="ck" name="r1"><span><b>招标投标</b><small>按《招标投标法》检查,结论用「否决投标」</small></span></label>
</div>
</div>
<div class="d-box">
<h3>开关 <small>可以点</small></h3>
<div class="d-states">
<div class="d-state"><small>关</small><button type="button" class="switch" role="switch" aria-checked="false"><span class="track"></span><span class="st"></span></button></div>
<div class="d-state"><small>开</small><button type="button" class="switch" role="switch" aria-checked="true"><span class="track"></span><span class="st"></span></button></div>
<div class="d-state"><small>禁用 · 关</small><button type="button" class="switch" role="switch" aria-checked="false" disabled><span class="track"></span><span class="st"></span></button></div>
<div class="d-state"><small>禁用 · 开</small><button type="button" class="switch" role="switch" aria-checked="true" disabled><span class="track"></span><span class="st"></span></button></div>
</div>
<div class="choices" style="margin-top:var(--sp-5)">
<label class="choice" style="justify-content:space-between;width:100%"><span>额度用到 80% 时站内提醒<small>每期只提醒一次</small></span><button type="button" class="switch" role="switch" aria-checked="true" aria-label="额度提醒"><span class="track"></span><span class="st"></span></button></label>
<label class="choice" style="justify-content:space-between;width:100%"><span>证书长期有效<small>打开后不检查有效期</small></span><button type="button" class="switch" role="switch" aria-checked="false" aria-label="长期有效"><span class="track"></span><span class="st"></span></button></label>
</div>
<ul class="d-rules"><li>规范没有定义开关。这里沿用 2px 圆角做成方形滑块(不用胶囊形),旁边写「开 / 关」,不只靠颜色。</li></ul>
</div>
</div>
</section>
<!-- 06 标签与标识 -->
<section class="d-sec" id="s-tag">
<div class="d-sec-h"><span class="no">06</span><h2>级别标签 · 状态标签 · AI 标识 · 署名</h2><span class="ref">规范 §3.3 · §7.2 · §7.5 · §7.16</span></div>
<div class="d-grid c2">
<div class="d-box">
<h3>问题级别(实心 / 描边 / 无框)</h3>
<div class="d-row"><span class="sev fatal">致命</span><span class="sev major">重要</span><span class="sev hint">提示</span><span class="d-cap" style="margin-left:var(--sp-4)">计数</span><span class="sev fatal">致命<span class="fig">3</span></span><span class="sev major">重要<span class="fig">3</span></span><span class="sev hint">提示<span class="fig">3</span></span></div>
<div class="d-row"><span class="d-cap">参数判断</span><span class="verdict fatal">疑似不满足</span><span class="verdict major">疑似不满足</span><span>满足</span><span class="verdict manual">需人工判断</span><span class="verdict major">未找到响应</span></div>
<h3 style="margin-top:var(--sp-6)">项目状态 · 就绪 · 复查标记</h3>
<div class="d-row"><span class="tag status">跟进中</span><span class="tag status">编制中</span><span class="tag status">已检查</span><span class="tag status">已递交</span><span class="tag status">已归档</span></div>
<div class="d-row"><span>未就绪</span><span class="tag status" data-tip="只表示致命问题都已处理,不代表投标文件没有问题。">就绪</span><span class="d-row" style="gap:var(--sp-2)"><span class="flag box">新增</span><span class="flag box">沿用</span><span class="flag box">本次已解决</span></span></div>
<div class="d-row"><span class="d-cap">清单状态</span><span class="tag">草稿 v3</span><span class="tag status">已确认 v2</span><span class="sign sm" style="margin:0"><span>✓</span><b>王敏</b><span class="fig">11月2日 15:12</span>确认</span></div>
<div class="d-row"><span class="d-cap">分类</span><span class="tag">资格条件</span><span class="tag">无效条款</span><span class="tag">技术参数</span><span class="tag">采购包 1</span><span class="tag">通用</span></div>
</div>
<div class="d-box">
<h3>AI 产出 → 人工确认(颜色说明谁说的)</h3>
<div class="d-row"><span class="tag ai">AI 摘要</span><span class="tag ai">AI 初稿</span><span class="src-ai">AI 提取</span><span>人工添加</span><span>补遗 1</span><span class="flag">已修改 · <a class="plain" href="#">查看记录</a></span></div>
<div class="d-stack" style="margin-top:var(--sp-5)">
<div><span class="d-label">AI 产出:蓝铅笔标签 + 左侧虚线</span>
<div class="ai-block"><span class="ai-label"><span class="tag ai">AI 摘要</span>未确认</span>预算 418.00 万元,分 2 个采购包;采购包 1 最高限价 286.00 万元。<a class="cite-src inline" href="#">招标文件 · <span class="fig">第 2 页</span></a></div></div>
<div><span class="d-label">人工确认后:墨色正文 + 实线 + 绿色署名</span>
<div class="ai-block done">预算 418.00 万元,分 2 个采购包;采购包 1 最高限价 286.00 万元。<a class="cite-src inline" href="#">招标文件 · <span class="fig">第 2 页</span></a>
<div class="sign sm"><span>✓</span><b>王敏</b><span class="fig">11月2日 14:20</span>确认无误</div></div></div>
<div><span class="d-label">问题处理后的署名行</span>
<div class="sign" style="margin:0"><span>✓</span><b>王敏</b><span class="fig">11月2日 14:20</span><span>已修改</span><a class="plain undo" href="#">撤销</a></div>
<div class="sign ign"><span>–</span><b>王敏</b><span class="fig">11月2日 14:26</span><span>已忽略:招标文件允许</span><a class="plain undo" href="#">撤销</a></div></div>
</div>
</div>
</div>
</section>
<!-- 07 出处 -->
<section class="d-sec" id="s-cite">
<div class="d-sec-h"><span class="no">07</span><h2>出处</h2><span class="ref">规范 §7.3 · 最重要的组件</span></div>
<div class="d-grid c3">
<div class="d-box">
<h3>招标原文 → 投标原文</h3>
<div class="cite"><a class="cite-src" href="#">招标文件 · <span class="fig">第 41 页</span></a><q>★ 2U机架式服务器,CPU:配置≥2颗海光架构32C 2.7GHz,<mark>内存: ≥512G DDR4</mark>,系统盘: 2块≥480G SSD……</q></div>
<div class="cite"><a class="cite-src" href="#">技术册 · <span class="fig">第 12 页</span></a><q>第 12 行 <mark>内存:256G DDR4</mark> 无偏离</q></div>
<ul class="d-rules"><li>页码用 Barlow;原句照录,不加空格、不改标点。</li></ul>
</div>
<div class="d-box">
<h3>「未找到」也是出处</h3>
<div class="cite"><a class="cite-src" href="#">招标文件 · <span class="fig">第 44 页</span></a><q>★ 支持硬件BFD,最小报文发送间隔≤50ms,<mark>提供相关证明材料(包含但不限于产品官网公开参数截图证明等)</mark>。</q></div>
<div class="cite missing"><span class="cite-src">投标文件 · 未找到</span><p>证明材料未找到 · 已查找:技术册(全部章节)、商务册(附件)</p></div>
<ul class="d-rules"><li>竖线改虚线,写明找过哪些分册、哪些章节。</li></ul>
</div>
<div class="d-box">
<h3>OCR · 截断 · 当前选中</h3>
<div class="cite on"><a class="cite-src" href="#">商务册 · <span class="fig">第 3 页</span><span class="ocr">OCR</span></a><q>投标人(电子签章):南京某信息技术有限公司  <mark>日期:2026年11月25日</mark></q></div>
<div class="cite" data-clamp><a class="cite-src" href="#">招标文件 · <span class="fig">第 23 页</span></a><q class="clamp"><mark>2.财务状况报告,至少提供:(1)本项目开标时间前6个月内任一时间截点的资产负债表的扫描件1份;(2)本项目开标时间前6个月内任何1月(不含开标当月)利润表月报表的扫描件1份。</mark>3.本项目开标时间前6个月内任何1月的依法缴纳税收和社会保障资金的相关材料的扫描件。</q><button class="expand" data-expand>展开原文</button></div>
<button class="more-cites">另有 2 处</button>
<ul class="d-rules"><li>选中的出处竖线加粗到 4px。超过 3 行截断,「展开原文」看全句。</li></ul>
</div>
</div>
</section>
<!-- 08 提醒 -->
<section class="d-sec" id="s-alert">
<div class="d-sec-h"><span class="no">08</span><h2>提醒(页内 Alert)</h2><span class="ref">规范 §7.12 · §7.15</span></div>
<div class="d-grid c2">
<div>
<div class="alert"><span class="ico i">i</span><div><p>清单未确认,检查结果以当前清单为准。</p></div><span class="act"><button class="btn sm">去确认清单</button></span></div>
<div class="alert warn"><span class="ico w">!</span><div><p><b>本期检查额度已用 80%。</b>剩 <span class="fig">4</span> 次,额度用完后续费或下期发放后可继续。</p></div><span class="act"><a class="plain cap" href="#">查看额度</a></span></div>
<div class="alert warn"><span class="ico w">!</span><div><p><b>投标截止还剩 2 天 5 小时。</b>还有 <span class="fig">3</span> 项致命问题待处理。</p><span class="sub">截止临近用赭色,不用红色;只提醒,不拦截。</span></div></div>
</div>
<div>
<div class="alert warn"><span class="ico w">!</span><div><p><b>解析失败:文件已加密。</b>已退回 1 次解析额度。请上传未加密的版本。</p><span class="sub">关于 ZC-2026-0418 的更正公告.pdf</span></div><span class="act"><button class="btn sm">重新上传</button></span></div>
<div class="alert"><span class="ico i">i</span><div><p>出了点问题,请稍后重试。本次操作未扣额度。</p><span class="sub">错误编号 <span class="errno">E-20261103-7Q4K</span> · 联系客服时请提供</span></div><span class="act"><button class="btn sm">重试</button></span></div>
<div class="alert done"><span class="ico ok">✓</span><div><p>报告已导出:智慧大厅建设项目-辅助检查报告-第 2 次.pdf</p></div></div>
</div>
</div>
<ul class="d-rules"><li>提醒放在相关内容上方,不自动消失。系统错误不用红色,用中性提醒 + 错误编号。</li></ul>
</section>
<!-- 09 轻提示 -->
<section class="d-sec" id="s-toast">
<div class="d-sec-h"><span class="no">09</span><h2>轻提示(Toast)</h2><span class="ref">规范 §7.12</span></div>
<div class="d-grid c2">
<div class="d-box">
<h3>样式</h3>
<div class="d-stack" style="display:flex;flex-direction:column;align-items:flex-start">
<div class="toast static"><span class="ok">✓</span><span>清单 v3 已确认</span></div>
<div class="toast static"><span class="ok">✓</span><span>已标记「已修改」 · 复查时会再查</span><span class="sep"></span><button class="lnk">撤销</button></div>
<div class="toast static"><span>已复制错误编号</span></div>
</div>
</div>
<div class="d-box">
<h3>触发 <small>可以点</small></h3>
<div class="d-row"><button class="btn" data-t1>保存资质</button><button class="btn" data-t2>批量确认无误</button><button class="btn" data-t3>连续触发三条</button></div>
<ul class="d-rules"><li>只用于操作结果;4 秒后消失,鼠标悬停时暂停计时。</li><li>可撤销的操作在轻提示里给「撤销」;失败不用轻提示,用页内提醒说清原因。</li><li>多条从下往上堆叠,屏幕阅读器会播报。</li></ul>
</div>
</div>
</section>
<!-- 10 对话框 -->
<section class="d-sec" id="s-dialog">
<div class="d-sec-h"><span class="no">10</span><h2>对话框</h2><span class="ref">规范 §7.14 · 只用于不可撤销的操作</span></div>
<div class="d-grid c-side">
<div class="dialog static" role="dialog" aria-labelledby="sd-t">
<h2 id="sd-t">删除项目「某区智慧社区平台运维服务」?</h2>
<div class="body">
<p>项目下的招标文件、清单、检查结果和报告会一起删除。删除后 30 天内可以在回收站恢复,之后彻底删除。</p>
<div class="field fill"><label for="sd-n">输入项目名称以确认</label><input class="input" id="sd-n" placeholder="某区智慧社区平台运维服务"></div>
</div>
<div class="foot"><button class="btn">取消</button><button class="btn primary" disabled>删除项目</button></div>
</div>
<div class="d-box">
<h3>打开真实对话框 <small>可以点</small></h3>
<div class="d-stack" style="display:flex;flex-direction:column;align-items:flex-start">
<button class="btn" data-d1><i data-ic="trash"></i>删除项目</button>
<button class="btn" data-d2><i data-ic="send"></i>标记已递交</button>
<button class="btn" data-d3>忽略并注明原因</button>
</div>
<ul class="d-rules"><li>宽 480(确认)/ 640(表单),圆角 4。</li><li>标题写要做的事,正文写后果;主操作在右,按钮写动作「删除项目」,不写「确定」。</li><li>删除没有红色:靠输入项目名确认。Esc 关闭,焦点回到触发按钮。</li></ul>
</div>
</div>
</section>
<!-- 11 标签页 分段 分页 -->
<section class="d-sec" id="s-tabs">
<div class="d-sec-h"><span class="no">11</span><h2>标签页 · 分段控件 · 分页</h2><span class="ref">规范 §5.3</span></div>
<div class="d-grid c2">
<div class="d-box">
<h3>标签页 <small>可以点,← → 切换</small></h3>
<div class="tabs" role="tablist" aria-label="项目">
<button role="tab" aria-selected="true" aria-controls="tp1">概览</button>
<button role="tab" aria-selected="false" aria-controls="tp2" tabindex="-1">读标<span class="fig muted">26</span></button>
<button role="tab" aria-selected="false" aria-controls="tp3" tabindex="-1">查标<span class="sev fatal">致命<span class="fig">3</span></span></button>
<button role="tab" aria-selected="false" aria-disabled="true" tabindex="-1" data-tip="先完成一次检查">报告</button>
</div>
<div class="tabpanel" id="tp1" role="tabpanel"><p class="muted" style="margin:0">项目要点、关键日期、文件和检查记录。</p></div>
<div class="tabpanel" id="tp2" role="tabpanel" hidden><p class="muted" style="margin:0">项目检查清单:26 条,其中待确认 2 条。</p></div>
<div class="tabpanel" id="tp3" role="tabpanel" hidden><p class="muted" style="margin:0">第 2 次检查:致命 3、重要 3、提示 3。</p></div>
</div>
<div class="d-box">
<h3>分段控件(筛选) <small>可以点</small></h3>
<div class="d-row"><div class="seg" role="group" aria-label="按状态筛选"><button aria-pressed="true">进行中 <span class="fig">4</span></button><button aria-pressed="false">全部 <span class="fig">6</span></button><button aria-pressed="false">已递交</button><button aria-pressed="false">已归档</button></div></div>
<div class="d-row"><div class="seg" role="group" aria-label="按级别筛选"><button aria-pressed="false">全部 <span class="fig">9</span></button><button aria-pressed="true"><span class="sev fatal">致命<span class="fig">3</span></span></button><button aria-pressed="false"><span class="sev major">重要<span class="fig">3</span></span></button><button aria-pressed="false"><span class="sev hint">提示<span class="fig">3</span></span></button></div></div>
</div>
</div>
<div class="d-box" style="margin-top:var(--sp-6)">
<h3>分页 <small>可以点</small></h3>
<div class="pagination" data-pager></div>
<ul class="d-rules"><li>当前页用墨色描边 + 加粗(不填色,避免和主按钮抢)。每页条数固定 20 / 50,不做无限滚动,方便「第几页第几条」沟通。</li></ul>
</div>
</section>
<!-- 12 空状态 骨架屏 进度 -->
<section class="d-sec" id="s-empty">
<div class="d-sec-h"><span class="no">12</span><h2>空状态 · 骨架屏 · 进度</h2><span class="ref">规范 §7.10 · §7.11 · §7.15</span></div>
<div class="d-grid c3">
<div class="d-box">
<h3>空状态</h3>
<div class="empty" style="padding:var(--sp-6) 0"><i data-ic="file" class="xl"></i><b>还没有招标文件</b><p>上传后,标博士会逐条提取要求,每条都附原文出处。</p><button class="btn lg primary"><i data-ic="upload"></i>上传招标文件</button><span class="cost" style="margin-top:var(--sp-2)">扣 1 次解析 · 剩 <span class="fig">37</span> 次</span></div>
</div>
<div class="d-box">
<h3>骨架屏(加载清单)</h3>
<div aria-busy="true" aria-label="正在加载清单">
<div class="skel-row"><span class="skel"></span><div><span class="skel w80"></span><span class="skel w30"></span></div><span class="skel"></span></div>
<div class="skel-row"><span class="skel"></span><div><span class="skel w60"></span><span class="skel w20"></span></div><span class="skel"></span></div>
<div class="skel-row"><span class="skel"></span><div><span class="skel w80"></span><span class="skel w30"></span></div><span class="skel"></span></div>
<div class="skel-row"><span class="skel"></span><div><span class="skel w60"></span><span class="skel w20"></span></div><span class="skel"></span></div>
</div>
<ul class="d-rules"><li>不用转圈占满屏。骨架做缓慢的明暗变化(1.6 秒),系统开了「减少动态效果」时静止。</li></ul>
</div>
<div class="d-box">
<h3>分阶段进度</h3>
<ol class="steps">
<li class="done"><span class="dot">✓</span><span>识别文件格式</span></li>
<li class="done"><span class="dot">✓</span><span>提取文字</span><span class="fig">186 页</span></li>
<li class="done"><span class="dot">✓</span><span>识别分包</span><span class="fig">2 个包</span></li>
<li class="now"><span class="dot"></span><span>提取清单</span><span class="fig">62%</span></li>
<li class="todo"><span class="dot"></span><span>核对出处</span></li>
</ol>
<div class="progress" style="margin-top:var(--sp-2)"><div class="bar"><i style="width:62%"></i></div><span class="fig">62%</span></div>
<p class="note">可以离开本页,完成后会发站内通知。</p>
</div>
</div>
<div class="d-grid c3" style="margin-top:var(--sp-6)">
<div class="d-box quota"><small>检查剩余 · 正常</small><span class="big">12</span><span class="unit">/ 20 次</span><div class="bar"><i style="width:40%"></i></div><p>已用 8 次</p></div>
<div class="d-box quota"><small>检查剩余 · 已用 80%</small><span class="big">4</span><span class="unit">/ 20 次</span><div class="bar warn"><i style="width:80%"></i></div><p class="warn">已用 80%,剩 4 次</p></div>
<div class="d-box quota"><small>检查剩余 · 已用完</small><span class="big">0</span><span class="unit">/ 20 次</span><div class="bar warn"><i style="width:100%"></i></div><p class="warn">本期检查额度已用完,续费或下期发放后可继续</p></div>
</div>
</section>
<!-- 13 提示气泡 菜单 快捷键 -->
<section class="d-sec" id="s-tip">
<div class="d-sec-h"><span class="no">13</span><h2>提示气泡 · 下拉菜单 · 快捷键</h2><span class="ref">规范 §6 · §8.2</span></div>
<div class="d-grid c3">
<div class="d-box">
<h3>提示气泡</h3>
<div class="d-row" style="padding-bottom:var(--sp-12)"><span class="tag status tip-on tip-below tip-start" data-tip="只表示致命问题都已处理,不代表投标文件没有问题。">就绪</span></div>
<div class="d-row"><button class="btn sm" data-tip="我核对过,投标文件这里没问题(例如响应写在别处)">确认无误</button><button class="btn sm" data-tip="我已经在投标文件里改了,复查时会再查">已修改</button><button class="btn sm" data-tip="我知道这个问题,决定不处理(必须填原因)">忽略并注明原因</button></div>
<ul class="d-rules"><li>处理三按钮的悬停提示写清含义(§7.4)。墨底白字,4px 圆角。</li></ul>
</div>
<div class="d-box">
<h3>下拉菜单(行内更多操作) <small>可以点</small></h3>
<div class="d-row">
<div class="pop inline" data-menu><button type="button" class="btn" data-menu-trigger aria-haspopup="menu" aria-expanded="false">更多操作<i data-ic="chev-down"></i></button>
<ul class="menu" role="menu"><li role="menuitem" data-toast="已打开处理记录"><i data-ic="history"></i>处理记录</li><li role="menuitem" data-toast="已复制项目"><i data-ic="layers"></i>复制为新项目</li><li role="menuitem" data-toast="已追加补遗"><i data-ic="upload"></i>追加补遗 / 澄清</li><hr><li role="menuitem" data-toast="已标记已递交"><i data-ic="send"></i>标记已递交</li><li role="menuitem" aria-disabled="true"><i data-ic="archive"></i>归档<small>递交后可用</small></li><li role="menuitem" data-toast="(演示)删除会打开确认对话框"><i data-ic="trash"></i>删除项目</li></ul></div>
</div>
<div class="pop d-open" style="margin-top:var(--sp-3)"><ul class="menu" role="menu" style="min-width:0;width:240px"><li role="menuitem"><i data-ic="history"></i>处理记录</li><li role="menuitem" class="is-active"><i data-ic="layers"></i>复制为新项目</li><hr><li role="menuitem"><i data-ic="send"></i>标记已递交</li><li role="menuitem" aria-disabled="true"><i data-ic="archive"></i>归档<small>递交后可用</small></li><li role="menuitem"><i data-ic="trash"></i>删除项目</li></ul></div>
</div>
<div class="d-box">
<h3>快捷键</h3>
<table class="data">
<tbody>
<tr><td><span class="kbd">J</span> / <span class="kbd">K</span></td><td>下一条 / 上一条</td></tr>
<tr><td><span class="kbd">O</span> · <span class="kbd">Enter</span></td><td>打开当前出处</td></tr>
<tr><td><span class="kbd">1</span> <span class="kbd">2</span> <span class="kbd">3</span></td><td>确认无误 / 已修改 / 忽略</td></tr>
<tr><td><span class="kbd">U</span></td><td>撤销当前条</td></tr>
<tr><td><span class="kbd">?</span></td><td>快捷键说明</td></tr>
</tbody>
</table>
<p class="note">在「④ 列表与表格」和「⑥ 读标」页可以实际用 J / K。</p>
</div>
</div>
</section>
</main>
<script src="demo.js"></script>
<script>
const { $, $$, toast, dialog, icon } = Demo;
Demo.demoTop("controls.html");
/* 文本域字数 */
$$("[data-count-field]").forEach((f) => {
const t = $("textarea", f), n = $("[data-n]", f);
t.addEventListener("input", () => { n.textContent = t.value.length; });
t.addEventListener("blur", () => { const bad = t.value.trim().length > 0 && t.value.trim().length < 5; f.classList.toggle("err", bad); $(".msg", f).innerHTML = bad ? '<span class="ico w">!</span>至少写 5 个字,说明为什么不处理' : "报告和处理记录里会显示这段原因。"; });
});
/* 展开原文 */
$$("[data-expand]").forEach((b) => b.onclick = () => { const q = b.previousElementSibling; const on = q.classList.toggle("clamp"); q.style.webkitLineClamp = on ? "" : "unset"; b.textContent = on ? "展开原文" : "收起"; });
/* 额度不足:按钮仍可点,点了说明原因 */
$("[data-nomore]").onclick = () => dialog({ title: "本期检查额度已用完", ok: "联系客服加额度", cancel: "关闭",
body: "<p>这次检查需要 1 次检查额度,本期已用完 20 次。续费或下期(2027-11-01)发放后可以继续。</p><p class='muted cap'>24 小时内对同一项目的复查不扣额度,不受影响。</p>" });
/* 轻提示 */
$("[data-t1]").onclick = () => toast("已保存「ISO/IEC 27001 信息安全管理体系」");
$("[data-t2]").onclick = () => toast("已将 3 项「提示」标记为确认无误", { undo: () => toast("已撤销", { ok: false }) });
$("[data-t3]").onclick = () => { toast("清单 v3 已确认"); setTimeout(() => toast("已核对补遗更新"), 300); setTimeout(() => toast("报告已导出"), 600); };
/* 对话框 */
$("[data-d1]").onclick = () => dialog({
title: "删除项目「某区智慧社区平台运维服务」?", ok: "删除项目",
body: `<p>项目下的招标文件、清单、检查结果和报告会一起删除。删除后 30 天内可以在回收站恢复,之后彻底删除。</p>
<div class="field fill"><label for="dn">输入项目名称以确认</label><input class="input" id="dn" placeholder="某区智慧社区平台运维服务" autocomplete="off"></div>`,
onOpen: (s) => { const ok = $("[data-ok]", s), i = $("#dn", s); ok.disabled = true; i.addEventListener("input", () => { ok.disabled = i.value.trim() !== "某区智慧社区平台运维服务"; }); },
onOk: () => toast("已删除,可在回收站恢复(30 天内)")
});
$("[data-d2]").onclick = () => dialog({
title: "标记「某市政务服务中心智慧大厅建设项目」为已递交?", ok: "标记已递交",
body: `<div class="alert warn"><span class="ico w">!</span><div><p><b>还有 3 项致命问题待处理。</b>标记已递交不受影响,处理记录会如实保留。</p></div></div>
<p style="margin-top:var(--sp-3)">标记后项目进入「已递交」,不能再发起检查;清单和检查结果保留,可以导出报告。</p>`,
onOk: () => toast("已标记为已递交")
});
$("[data-d3]").onclick = () => dialog({
title: "忽略并注明原因", wide: true, ok: "忽略这一项",
body: `<p><span class="sev major">重要</span> <b>开标一览表与分项价格表合计不一致</b></p>
<div class="field fill"><label for="ir">原因 <small>(必填,至少 5 个字)</small></label>
<div class="chips"><button type="button" class="btn" data-chip>招标文件允许</button><button type="button" class="btn" data-chip>已在其他分册响应</button><button type="button" class="btn" data-chip>与本项目无关</button></div>
<textarea class="input" id="ir" placeholder="写清楚为什么不处理,报告里会如实列出"></textarea><span class="msg">「已忽略」不等于确认无误,报告里单独列出。</span></div>`,
onOpen: (s) => { $$("[data-chip]", s).forEach((c) => c.onclick = () => { $("#ir", s).value = c.textContent; $("#ir", s).focus(); }); },
onOk: (s) => { const v = $("#ir", s).value.trim(); const f = $("#ir", s).closest(".field"); if (v.length < 5) { f.classList.add("err"); $(".msg", f).innerHTML = '<span class="ico w">!</span>至少写 5 个字,说明为什么不处理'; return false; } toast("已忽略 · 原因已记录", { undo: () => toast("已撤销", { ok: false }) }); }
});
/* 分页 */
(function pager() {
const el = $("[data-pager]"); let cur = 1; const total = 86, per = 20, pages = Math.ceil(total / per);
const render = () => {
const nums = []; for (let i = 1; i <= pages; i++) nums.push(i);
el.innerHTML = `<span class="total">共 <span class="fig">${total}</span> 条 · 每页 <span class="fig">${per}</span> 条</span>
<button class="pg" data-p="${cur - 1}" ${cur === 1 ? "disabled" : ""} aria-label="上一页">${icon("chev-left")}</button>
${nums.map((n) => `<button class="pg" data-p="${n}" ${n === cur ? 'aria-current="page"' : ""}>${n}</button>`).join("")}
<button class="pg" data-p="${cur + 1}" ${cur === pages ? "disabled" : ""} aria-label="下一页">${icon("chev-right")}</button>
<span class="jump">跳到 <input class="input" value="${cur}" aria-label="页码"> 页</span>`;
};
el.addEventListener("click", (e) => { const b = e.target.closest("[data-p]"); if (b && !b.disabled) { cur = +b.dataset.p; render(); } });
el.addEventListener("change", (e) => { const v = +e.target.value; if (v >= 1 && v <= pages) cur = v; render(); });
render();
})();
</script>
</body>
</html>