Files
zkxw/mobile-ui/zkxw-mobile-oa-list-empty-demos.html
T
2026-08-13 14:31:57 +08:00

485 lines
20 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, maximum-scale=1" />
<title>mobile-h5 · OA 列表空态 Demo</title>
<style>
:root {
--brand: #0a9f6d;
--brand-dark: #087f57;
--brand-soft: #e9f9f2;
--warn: #d97706;
--warn-soft: #fff7e8;
--nav-bg: #ecfdf5;
--page-bg: #f5f6f8;
--text: #1f2a26;
--text-muted: #6b7b74;
}
* { box-sizing: border-box; }
body {
margin: 0;
font-family: "PingFang SC", "Hiragino Sans GB", "Noto Sans SC", -apple-system, system-ui, sans-serif;
color: var(--text);
background:
radial-gradient(900px 420px at 8% -8%, rgba(10, 159, 109, 0.12), transparent 55%),
radial-gradient(700px 380px at 92% 0%, rgba(214, 163, 67, 0.1), transparent 50%),
linear-gradient(180deg, #f8fffc 0%, #f4f7fb 50%, #f7f8fa 100%);
line-height: 1.45;
}
.stage { max-width: 1280px; margin: 0 auto; padding: 28px 16px 56px; }
.hero h1 { margin: 0 0 8px; font-size: 22px; font-weight: 720; }
.hero p { margin: 0; color: #64748b; font-size: 14px; max-width: 800px; }
.hero .note {
margin-top: 12px; display: inline-block; padding: 8px 12px;
border-radius: 10px; background: #fff; border: 1px solid #e2e8f0;
font-size: 12px; color: #64748b;
}
.hero .note strong { color: #0f766e; }
.pain {
margin-top: 14px; padding: 12px 14px; border-radius: 12px;
background: #fff1f2; border: 1px solid #fecdd3;
font-size: 13px; color: #9f1239;
}
.tabs { display: flex; flex-wrap: wrap; gap: 10px; margin: 20px 0 16px; }
.tab {
appearance: none; border: 1px solid #e2e8f0; background: #fff;
border-radius: 999px; padding: 10px 16px; font-size: 13px;
font-weight: 600; color: #475569; cursor: pointer;
}
.tab.is-active {
color: var(--brand-dark); border-color: var(--brand);
background: var(--brand-soft);
box-shadow: 0 0 0 3px rgba(10, 159, 109, 0.16);
}
.tab .badge {
margin-left: 6px; font-size: 10px; padding: 2px 6px;
border-radius: 999px; background: #ecfdf5; color: #047857; font-weight: 700;
}
.layout {
display: grid;
grid-template-columns: minmax(240px, 300px) 1fr;
gap: 20px; align-items: start;
}
@media (max-width: 900px) { .layout { grid-template-columns: 1fr; } }
.panel {
background: rgba(255,255,255,.94);
border: 1px solid #e2e8f0; border-radius: 16px; padding: 16px;
box-shadow: 0 10px 28px rgba(15,23,42,.05);
}
.panel h2 { margin: 0 0 4px; font-size: 15px; }
.panel .sub { margin: 0 0 10px; font-size: 12px; color: #64748b; }
.panel ul { margin: 0; padding-left: 18px; font-size: 13px; color: #475569; }
.panel li { margin: 5px 0; }
.panel .pick {
margin-top: 12px; padding: 10px 12px; border-radius: 10px;
background: var(--brand-soft); border: 1px solid #b7ebd4;
font-size: 12px; color: #166534;
}
.phones { display: flex; flex-wrap: wrap; gap: 18px; justify-content: center; }
.phone {
width: 375px; background: #fff; border-radius: 28px; overflow: hidden;
box-shadow: 0 0 0 1px rgb(15 23 42 / 6%), 0 18px 40px rgb(15 23 42 / 12%);
}
.cap {
text-align: center; font-size: 11px; font-weight: 650; color: #64748b;
padding: 8px; background: #f8fafc; border-bottom: 1px solid #eef2f0;
}
.nav {
height: 44px; display: flex; align-items: center; padding: 0 8px 0 4px;
background: var(--nav-bg); border-bottom: 1px solid #d8f3e5; position: relative;
}
.nav-back {
width: 36px; height: 36px; display: flex; align-items: center; justify-content: center;
}
.nav-back::before {
content: ""; width: 10px; height: 10px;
border-left: 2px solid #0f291e; border-bottom: 2px solid #0f291e;
transform: rotate(45deg); margin-left: 4px;
}
.nav-title {
position: absolute; left: 50%; transform: translateX(-50%);
font-size: 16px; font-weight: 650; color: #0f291e;
}
.nav-right {
margin-left: auto; padding: 0 10px; font-size: 14px;
font-weight: 650; color: var(--brand-dark);
}
.page { background: var(--page-bg); min-height: 520px; }
.search-wrap { padding: 10px 12px; background: #fff; border-bottom: 1px solid #f1f5f9; }
.search {
height: 36px; display: flex; align-items: center; gap: 8px;
padding: 0 12px; border-radius: 10px; border: 1px solid #e8eaed;
background: #fafafa; font-size: 13px; color: #94a3b8;
}
.search::before {
content: ""; width: 12px; height: 12px; border: 1.5px solid #94a3b8;
border-radius: 50%; flex-shrink: 0;
}
/* —— A0 现状 —— */
.e0 {
padding: 72px 16px; text-align: center;
font-size: 14px; color: #5f7a6d; letter-spacing: 0.04em;
}
/* —— E1 插画 + 主副文案 —— */
.e1 {
display: flex; flex-direction: column; align-items: center;
padding: 56px 28px 40px; text-align: center;
}
.e1-art {
width: 120px; height: 120px; border-radius: 50%;
background: radial-gradient(circle at 35% 30%, #fff, #d8f3e7 72%);
display: flex; align-items: center; justify-content: center;
margin-bottom: 18px;
box-shadow: 0 10px 28px rgba(10, 159, 109, 0.12);
}
.e1-art svg { width: 56px; height: 56px; }
.e1-title { font-size: 16px; font-weight: 700; color: #1f2a26; margin-bottom: 8px; }
.e1-desc { font-size: 13px; color: #6b7b74; line-height: 1.55; max-width: 240px; }
/* —— E2 虚线软卡(对齐首页 VanEmpty) —— */
.e2-wrap { padding: 28px 16px; }
.e2 {
display: flex; flex-direction: column; align-items: center;
padding: 36px 20px 28px; text-align: center;
border-radius: 16px;
background: linear-gradient(165deg, #eef9f3 0%, #ffffff 55%);
border: 1.5px dashed #b7e5d0;
}
.e2-blob {
width: 72px; height: 72px; border-radius: 50%;
background: radial-gradient(circle at 35% 30%, #fff, #d8f3e7 70%);
display: flex; align-items: center; justify-content: center;
margin-bottom: 12px;
}
.e2-blob svg { width: 32px; height: 32px; }
.e2-title { font-size: 14px; font-weight: 650; color: #5d746a; margin-bottom: 6px; }
.e2-desc { font-size: 12px; color: #8aa198; line-height: 1.5; }
/* —— E3 带主按钮 CTA —— */
.e3 {
display: flex; flex-direction: column; align-items: center;
padding: 48px 28px 36px; text-align: center;
}
.e3-ico {
width: 88px; height: 88px; border-radius: 28px;
background: linear-gradient(145deg, #e9f9f2, #d1fae5);
border: 1px solid #b7ebd4;
display: flex; align-items: center; justify-content: center;
margin-bottom: 16px;
box-shadow: 0 8px 22px rgba(10, 159, 109, 0.12);
}
.e3-ico svg { width: 40px; height: 40px; }
.e3-title { font-size: 16px; font-weight: 700; margin-bottom: 8px; }
.e3-desc { font-size: 13px; color: #6b7b74; margin-bottom: 20px; max-width: 250px; line-height: 1.55; }
.e3-btn {
height: 44px; padding: 0 28px; border: 0; border-radius: 12px;
background: linear-gradient(135deg, #0a9f6d, #087f57); color: #fff;
font-size: 15px; font-weight: 700; cursor: pointer;
box-shadow: 0 8px 18px rgba(10, 159, 109, 0.28);
}
.e3-link {
margin-top: 14px; font-size: 13px; color: var(--brand-dark);
font-weight: 650; cursor: pointer;
}
/* —— E4 场景插画卡片 —— */
.e4-wrap { padding: 24px 16px; }
.e4 {
background: #fff; border-radius: 18px; padding: 28px 20px 24px;
text-align: center;
box-shadow: 0 8px 24px rgba(15, 23, 42, 0.05);
}
.e4-scene {
height: 110px; margin-bottom: 16px; position: relative;
display: flex; align-items: flex-end; justify-content: center;
}
.e4-desk {
width: 160px; height: 14px; border-radius: 8px;
background: #e2e8e6; position: absolute; bottom: 8px;
}
.e4-paper {
width: 72px; height: 88px; border-radius: 10px;
background: #fff; border: 2px solid #c6f0dc;
box-shadow: 0 8px 16px rgba(15,23,42,.06);
position: relative; z-index: 1;
display: flex; flex-direction: column; gap: 8px; padding: 14px 12px;
}
.e4-paper i {
display: block; height: 6px; border-radius: 3px; background: #d8f3e5;
}
.e4-paper i:nth-child(2) { width: 70%; }
.e4-paper i:nth-child(3) { width: 45%; }
.e4-badge {
position: absolute; right: 88px; top: 10px; z-index: 2;
width: 36px; height: 36px; border-radius: 50%;
background: var(--warn-soft); border: 2px solid #f0d9a8;
color: var(--warn); font-size: 18px; font-weight: 700;
display: flex; align-items: center; justify-content: center;
}
.e4-title { font-size: 15px; font-weight: 700; margin-bottom: 6px; }
.e4-desc { font-size: 12px; color: #6b7b74; line-height: 1.5; margin-bottom: 16px; }
.e4-btn {
height: 40px; padding: 0 22px; border-radius: 10px; border: 0;
background: var(--brand); color: #fff; font-size: 13px; font-weight: 700;
cursor: pointer;
}
/* —— E5 搜索无结果变体 —— */
.e5 {
display: flex; flex-direction: column; align-items: center;
padding: 48px 28px; text-align: center;
}
.e5-ico {
width: 80px; height: 80px; border-radius: 50%;
background: #f1f5f9;
display: flex; align-items: center; justify-content: center;
margin-bottom: 14px;
}
.e5-ico svg { width: 36px; height: 36px; }
.e5-title { font-size: 15px; font-weight: 700; margin-bottom: 6px; }
.e5-desc { font-size: 13px; color: #6b7b74; margin-bottom: 16px; }
.e5-chip {
height: 34px; padding: 0 16px; border-radius: 999px;
border: 1px solid #d8e3de; background: #fff;
font-size: 13px; font-weight: 650; color: var(--brand-dark);
cursor: pointer;
}
/* —— E6 极简大字 + 微插画 —— */
.e6 {
padding: 64px 24px; text-align: center;
}
.e6-emoji {
width: 64px; height: 64px; margin: 0 auto 14px;
border-radius: 20px; background: var(--brand-soft);
display: flex; align-items: center; justify-content: center;
}
.e6-emoji svg { width: 30px; height: 30px; }
.e6-title { font-size: 15px; font-weight: 650; color: #334155; margin-bottom: 6px; }
.e6-desc { font-size: 12px; color: #94a3b8; }
</style>
</head>
<body>
<div class="stage">
<div class="hero">
<h1>OA 列表空态 · 风格选型</h1>
<p>
针对草稿箱 / 待办 / 已办 / 抄送等列表页。现状仅为灰色「暂无草稿」一行字。
Token 对齐三墙绿;可与首页已有虚线软卡空态统一或做列表专用加强版。
</p>
<div class="note">请选 <strong>E1–E6</strong>(或组合:如 E3 布局 + E4 插画)。选定后落到 <code>mobile-h5</code>。</div>
<div class="pain">现状痛点:信息弱、无引导、与钉钉风列表不协调。</div>
</div>
<div class="tabs" id="tabs">
<button class="tab is-active" data-k="e0">E0 现状</button>
<button class="tab" data-k="e1">E1 圆形插画</button>
<button class="tab" data-k="e2">E2 虚线软卡</button>
<button class="tab" data-k="e3">E3 带 CTA<span class="badge">推荐</span></button>
<button class="tab" data-k="e4">E4 场景卡片</button>
<button class="tab" data-k="e5">E5 搜索无结果</button>
<button class="tab" data-k="e6">E6 极简加强</button>
</div>
<div class="layout">
<div class="panel" id="desc"></div>
<div class="phones" id="phones"></div>
</div>
</div>
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="i-inbox" viewBox="0 0 24 24" fill="none" stroke="#0a9f6d" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
<polyline points="22 12 16 12 14 15 10 15 8 12 2 12"/>
<path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/>
</symbol>
<symbol id="i-doc" viewBox="0 0 24 24" fill="none" stroke="#0a9f6d" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
<polyline points="14 2 14 8 20 8"/>
<line x1="8" y1="13" x2="16" y2="13"/>
<line x1="8" y1="17" x2="13" y2="17"/>
</symbol>
<symbol id="i-search" viewBox="0 0 24 24" fill="none" stroke="#94a3b8" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<circle cx="11" cy="11" r="7"/>
<line x1="21" y1="21" x2="16.65" y2="16.65"/>
</symbol>
<symbol id="i-check" viewBox="0 0 24 24" fill="none" stroke="#0a9f6d" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/>
<polyline points="22 4 12 14.01 9 11.01"/>
</symbol>
</svg>
<script>
const DESCS = {
e0: {
title: "E0 · 现状对照",
sub: "OA 列表页当前实现:一行灰字。",
items: ["无插画、无说明、无下一步引导", "与钉钉风卡片列表反差大", "仅作对照"],
pick: "不建议保留。"
},
e1: {
title: "E1 · 圆形插画",
sub: "大圆形浅绿底 + 图标 + 主副文案,居中留白。",
items: ["视觉重心明确", "无按钮,适合纯浏览空列表", "实现成本低"],
pick: "适合已办/抄送等「没有也正常」的列表。"
},
e2: {
title: "E2 · 虚线软卡",
sub: "与首页 VanEmpty(方案 B)一致。",
items: ["全站空态统一", "虚线卡略像「占位块」", "可直接复用组件"],
pick: "想和首页空态完全一致时选 E2。"
},
e3: {
title: "E3 · 插画 + 主按钮(推荐)",
sub: "说明原因,并给出「去发起审批」主行动。",
items: ["解决「空了之后做什么」", "主按钮视觉符合三墙绿", "可加次级文字链(如下拉刷新说明)"],
pick: "草稿箱 / 我发起的 最推荐。"
},
e4: {
title: "E4 · 场景卡片",
sub: "白卡片内嵌简易场景插画(纸张 + 草稿标记)。",
items: ["更有「产品感」", "CSS 绘制、无额外图片依赖", "带一个主按钮"],
pick: "想要比 E3 更精致一点时选 E4。"
},
e5: {
title: "E5 · 搜索无结果",
sub: "有关键词但搜不到时的专用空态。",
items: ["文案强调「未找到」", "提供「清空搜索」胶囊按钮", "与「真的没有数据」区分"],
pick: "建议与 E3/E4 搭配:无数据用 E3,搜索空用 E5。"
},
e6: {
title: "E6 · 极简加强",
sub: "比现状多一个图标底板,仍保持克制。",
items: ["改动最小", "仍偏素", "适合不想加按钮的页面"],
pick: "过渡方案;长期更建议 E3/E4。"
}
};
function shell(cap, body, opts) {
opts = opts || {};
var kw = opts.keyword || "";
return (
'<div class="phone"><div class="cap">' + cap + '</div>' +
'<div class="nav"><div class="nav-back"></div><div class="nav-title">草稿箱</div><div class="nav-right">管理</div></div>' +
'<div class="page"><div class="search-wrap"><div class="search">' +
(kw || "搜索流程名称") +
'</div></div>' + body + '</div></div>'
);
}
const RENDER = {
e0: function () {
return shell("现状 · 纯文字", '<div class="e0">暂无草稿</div>');
},
e1: function () {
return shell("圆形插画",
'<div class="e1">' +
'<div class="e1-art"><svg><use href="#i-inbox"/></svg></div>' +
'<div class="e1-title">暂无草稿</div>' +
'<div class="e1-desc">发起审批时保存的草稿会显示在这里</div>' +
'</div>'
) + shell("待办变体",
'<div class="e1">' +
'<div class="e1-art"><svg><use href="#i-check"/></svg></div>' +
'<div class="e1-title">暂无待办</div>' +
'<div class="e1-desc">当前没有需要你处理的审批</div>' +
'</div>'
);
},
e2: function () {
return shell("虚线软卡 · 对齐首页",
'<div class="e2-wrap"><div class="e2">' +
'<div class="e2-blob"><svg><use href="#i-inbox"/></svg></div>' +
'<div class="e2-title">暂无草稿</div>' +
'<div class="e2-desc">保存过的审批草稿会出现在这里</div>' +
'</div></div>'
);
},
e3: function () {
return shell("推荐 · 带主按钮",
'<div class="e3">' +
'<div class="e3-ico"><svg><use href="#i-doc"/></svg></div>' +
'<div class="e3-title">暂无草稿</div>' +
'<div class="e3-desc">填写审批时可随时保存为草稿,方便下次继续</div>' +
'<button class="e3-btn">去发起审批</button>' +
'<div class="e3-link">了解如何使用草稿</div>' +
'</div>'
) + shell("待办 · 无 CTA 也可",
'<div class="e3">' +
'<div class="e3-ico"><svg><use href="#i-check"/></svg></div>' +
'<div class="e3-title">暂无待办</div>' +
'<div class="e3-desc">真棒,当前没有待你处理的审批</div>' +
'</div>'
);
},
e4: function () {
return shell("场景插画卡",
'<div class="e4-wrap"><div class="e4">' +
'<div class="e4-scene">' +
'<div class="e4-badge">!</div>' +
'<div class="e4-paper"><i></i><i></i><i></i></div>' +
'<div class="e4-desk"></div>' +
'</div>' +
'<div class="e4-title">还没有草稿</div>' +
'<div class="e4-desc">从发起审批开始,未提交的内容会自动出现在这里</div>' +
'<button class="e4-btn">去发起审批</button>' +
'</div></div>'
);
},
e5: function () {
return shell("搜索无结果",
'<div class="e5">' +
'<div class="e5-ico"><svg><use href="#i-search"/></svg></div>' +
'<div class="e5-title">未找到相关草稿</div>' +
'<div class="e5-desc">没有匹配「入帐」的结果,试试其他关键词</div>' +
'<button class="e5-chip">清空搜索</button>' +
'</div>',
{ keyword: "入帐" }
);
},
e6: function () {
return shell("极简加强",
'<div class="e6">' +
'<div class="e6-emoji"><svg><use href="#i-inbox"/></svg></div>' +
'<div class="e6-title">暂无草稿</div>' +
'<div class="e6-desc">保存的草稿会显示在这里</div>' +
'</div>'
);
}
};
const descEl = document.getElementById("desc");
const phonesEl = document.getElementById("phones");
const tabs = document.getElementById("tabs");
function show(k) {
var d = DESCS[k];
descEl.innerHTML =
"<h2>" + d.title + "</h2>" +
'<p class="sub">' + d.sub + "</p>" +
"<ul>" + d.items.map(function (i) { return "<li>" + i + "</li>"; }).join("") + "</ul>" +
'<div class="pick">' + d.pick + "</div>";
phonesEl.innerHTML = RENDER[k]();
}
tabs.addEventListener("click", function (e) {
var btn = e.target.closest(".tab");
if (!btn) return;
tabs.querySelectorAll(".tab").forEach(function (t) {
t.classList.toggle("is-active", t === btn);
});
show(btn.getAttribute("data-k"));
});
show("e0");
</script>
</body>
</html>