354 lines
15 KiB
HTML
354 lines
15 KiB
HTML
<!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>OA 附件 · Vant 缩略图美化 Demo</title>
|
||
<style>
|
||
:root {
|
||
--brand: #0a9f6d;
|
||
--brand-dark: #087f57;
|
||
--brand-soft: #e9f9f2;
|
||
--page-bg: #f5f6f8;
|
||
--text: #1f2a26;
|
||
--nav-bg: #ecfdf5;
|
||
}
|
||
* { 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%),
|
||
linear-gradient(180deg, #f8fffc 0%, #f4f7fb 55%, #f7f8fa 100%);
|
||
line-height: 1.45;
|
||
}
|
||
.stage { max-width: 920px; margin: 0 auto; padding: 28px 16px 64px; }
|
||
h1 { margin: 0 0 8px; font-size: 22px; font-weight: 720; }
|
||
.lead { margin: 0; color: #64748b; font-size: 14px; max-width: 720px; }
|
||
.goals {
|
||
margin-top: 14px; padding: 12px 14px; border-radius: 12px;
|
||
background: #ecfdf5; border: 1px solid #a7f3d0;
|
||
font-size: 13px; color: #065f46;
|
||
}
|
||
.goals ul { margin: 6px 0 0; padding-left: 18px; }
|
||
|
||
.grid {
|
||
margin-top: 22px;
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||
gap: 18px;
|
||
}
|
||
.card {
|
||
background: rgba(255,255,255,.95);
|
||
border: 1px solid #e2e8f0;
|
||
border-radius: 16px;
|
||
padding: 14px;
|
||
box-shadow: 0 10px 28px rgba(15,23,42,.05);
|
||
}
|
||
.card h2 {
|
||
margin: 0 0 4px; font-size: 15px;
|
||
display: flex; align-items: center; gap: 8px;
|
||
}
|
||
.card .sub { margin: 0 0 12px; font-size: 12px; color: #64748b; }
|
||
.pill {
|
||
display: inline-block; padding: 2px 8px; border-radius: 999px;
|
||
font-size: 10px; font-weight: 700;
|
||
}
|
||
.pill.now { background: #fff1f2; color: #be123c; border: 1px solid #fecdd3; }
|
||
.pill.rec { background: #ecfdf5; color: #047857; border: 1px solid #a7f3d0; }
|
||
|
||
.phone {
|
||
width: 100%; max-width: 360px; margin: 0 auto;
|
||
border-radius: 28px; border: 1px solid #cbd5e1; background: #0f172a;
|
||
padding: 10px; box-shadow: 0 18px 40px rgba(15,23,42,.12);
|
||
}
|
||
.screen {
|
||
border-radius: 20px; overflow: hidden; background: var(--page-bg); min-height: 420px;
|
||
}
|
||
.nav {
|
||
display: flex; align-items: center; gap: 8px; min-height: 48px;
|
||
padding: 10px 12px;
|
||
background: linear-gradient(180deg, #d1fae5 0%, var(--nav-bg) 100%);
|
||
border-bottom: 1px solid #bbf7d0;
|
||
}
|
||
.nav__back {
|
||
width: 28px; height: 28px; border-radius: 999px; display: grid; place-items: center;
|
||
color: var(--brand-dark); font-weight: 700; background: rgba(255,255,255,.55);
|
||
}
|
||
.nav__title { flex: 1; font-size: 15px; font-weight: 700; color: #064e3b; }
|
||
.body { padding: 14px 12px; }
|
||
.label { font-size: 13px; font-weight: 650; color: #334155; margin-bottom: 10px; }
|
||
.mode {
|
||
display: inline-block; margin-bottom: 10px; padding: 3px 8px; border-radius: 6px;
|
||
font-size: 11px; font-weight: 650;
|
||
}
|
||
.mode.edit { background: #eff6ff; color: #1d4ed8; }
|
||
.mode.view { background: #f1f5f9; color: #475569; }
|
||
|
||
/* ===== 现状(默认 Vant 感) ===== */
|
||
.now-grid { display: flex; flex-wrap: wrap; gap: 8px; }
|
||
.now-tile {
|
||
position: relative; width: 80px; height: 80px; border-radius: 8px;
|
||
background: #f7f8fa; border: 1px solid #ebedf0; overflow: hidden;
|
||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||
padding: 6px;
|
||
}
|
||
.now-tile.img {
|
||
background: linear-gradient(145deg, #86efac, #22c55e); color: #fff;
|
||
font-size: 11px; font-weight: 700; padding: 0;
|
||
}
|
||
.now-tile .fname {
|
||
font-size: 10px; color: #969799; text-align: center; word-break: break-all;
|
||
line-height: 1.2; max-height: 36px; overflow: hidden;
|
||
}
|
||
.now-tile .dl {
|
||
position: absolute; left: 0; right: 0; bottom: 0;
|
||
background: rgba(15,23,42,.55); color: #fff; font-size: 9px;
|
||
text-align: center; padding: 2px;
|
||
}
|
||
.now-tile .x {
|
||
position: absolute; top: 0; right: 0; width: 14px; height: 14px;
|
||
border-radius: 0 0 0 12px; background: rgba(0,0,0,.7); color: #fff;
|
||
font-size: 10px; display: grid; place-items: center; line-height: 1;
|
||
}
|
||
.now-add {
|
||
width: 80px; height: 80px; border-radius: 8px; background: #f7f8fa;
|
||
display: grid; place-items: center; color: #dcdee0; font-size: 28px;
|
||
}
|
||
|
||
/* ===== 美化后(仍是缩略图格) ===== */
|
||
.nice-grid { display: flex; flex-wrap: wrap; gap: 10px; }
|
||
.nice-tile {
|
||
position: relative;
|
||
width: 84px; height: 84px;
|
||
border-radius: 14px;
|
||
background: #fff;
|
||
border: 1px solid #e4eee9;
|
||
box-shadow: 0 4px 12px rgba(20, 55, 40, 0.06);
|
||
overflow: hidden;
|
||
display: flex; flex-direction: column;
|
||
align-items: center; justify-content: center;
|
||
padding: 8px 6px 18px;
|
||
}
|
||
.nice-tile.img {
|
||
padding: 0;
|
||
background:
|
||
linear-gradient(145deg, rgba(74, 222, 128, 0.35), rgba(10, 159, 109, 0.55)),
|
||
#0a9f6d;
|
||
color: #fff; font-size: 11px; font-weight: 700;
|
||
border-color: #bbf7d0;
|
||
}
|
||
.nice-tile .file-ico {
|
||
width: 28px; height: 28px; border-radius: 8px;
|
||
display: grid; place-items: center; color: #fff; margin-bottom: 4px;
|
||
box-shadow: 0 3px 8px rgba(15, 40, 30, 0.15);
|
||
}
|
||
.nice-tile.ft-pdf .file-ico { background: linear-gradient(145deg, #f07171, #ef4444); }
|
||
.nice-tile.ft-xls .file-ico { background: linear-gradient(145deg, #4fbf8a, #10b981); }
|
||
.nice-tile.ft-doc .file-ico { background: linear-gradient(145deg, #6ea8ff, #3b82f6); }
|
||
.nice-tile .file-ico svg { width: 15px; height: 15px; }
|
||
.nice-tile .fname {
|
||
font-size: 10px; color: #4d635a; text-align: center;
|
||
line-height: 1.25; max-height: 26px; overflow: hidden;
|
||
word-break: break-all; font-weight: 600;
|
||
}
|
||
.nice-tile .dl {
|
||
position: absolute; left: 0; right: 0; bottom: 0;
|
||
padding: 4px 4px 5px;
|
||
font-size: 10px; font-weight: 650; letter-spacing: 0.02em;
|
||
text-align: center; color: #fff;
|
||
background: linear-gradient(180deg, rgba(8, 127, 87, 0.0), rgba(8, 127, 87, 0.92));
|
||
}
|
||
.nice-tile.img .dl {
|
||
background: linear-gradient(180deg, transparent, rgba(15, 23, 42, 0.55));
|
||
font-weight: 600;
|
||
}
|
||
.nice-tile .x {
|
||
position: absolute; top: 4px; right: 4px;
|
||
width: 20px; height: 20px; border-radius: 999px;
|
||
background: rgba(15, 23, 42, 0.55);
|
||
backdrop-filter: blur(4px);
|
||
color: #fff; font-size: 12px;
|
||
display: grid; place-items: center; line-height: 1;
|
||
box-shadow: 0 2px 6px rgba(0,0,0,.18);
|
||
}
|
||
.nice-add {
|
||
width: 84px; height: 84px; border-radius: 14px;
|
||
border: 1.5px dashed #9ad9be;
|
||
background: linear-gradient(145deg, #f7fdf9, #e9f9f2);
|
||
display: flex; flex-direction: column;
|
||
align-items: center; justify-content: center; gap: 4px;
|
||
color: var(--brand);
|
||
}
|
||
.nice-add .plus {
|
||
width: 28px; height: 28px; border-radius: 9px;
|
||
background: linear-gradient(145deg, #4ade80, #0a9f6d);
|
||
color: #fff; display: grid; place-items: center;
|
||
font-size: 18px; font-weight: 700;
|
||
box-shadow: 0 4px 10px rgba(10, 159, 109, 0.28);
|
||
}
|
||
.nice-add .txt { font-size: 11px; font-weight: 650; color: var(--brand-dark); }
|
||
|
||
.tabs { margin-top: 18px; display: flex; gap: 8px; flex-wrap: wrap; }
|
||
.tab {
|
||
border: 1px solid #cbd5e1; background: #fff; border-radius: 999px;
|
||
padding: 8px 14px; font-size: 13px; font-weight: 650; color: #475569; cursor: pointer;
|
||
}
|
||
.tab.is-on {
|
||
background: var(--brand-soft); border-color: #86efac; color: var(--brand-dark);
|
||
}
|
||
.panel[hidden] { display: none !important; }
|
||
.footnote {
|
||
margin-top: 18px; font-size: 12px; color: #64748b;
|
||
padding: 12px 14px; border-radius: 12px; background: #fff; border: 1px solid #e2e8f0;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="stage">
|
||
<h1>附件上传 · 保留 Vant 缩略图,只美化样式</h1>
|
||
<p class="lead">
|
||
交互不变:格子预览、右上角删除、非图点按下载、详情禁用删除。仅圆角、阴影、删除钮、下载条、添加格做三墙风格打磨。
|
||
</p>
|
||
<div class="goals">
|
||
<strong>美化点</strong>
|
||
<ul>
|
||
<li>预览格:14px 圆角 + 浅绿描边/轻阴影</li>
|
||
<li>删除:圆形半透明钮(替代直角小三角)</li>
|
||
<li>下载条:品牌绿渐变底 + 更清晰「点击下载」</li>
|
||
<li>添加格:虚线框 + 绿色渐变 + 号</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="tabs">
|
||
<button class="tab is-on" type="button" data-panel="edit">发起 / 编辑</button>
|
||
<button class="tab" type="button" data-panel="view">详情(无删除)</button>
|
||
</div>
|
||
|
||
<div class="panel grid" id="panel-edit">
|
||
<section class="card">
|
||
<h2>现状 <span class="pill now">修改前</span></h2>
|
||
<p class="sub">默认 Vant 灰格,删除钮生硬,下载条发黑。</p>
|
||
<div class="phone"><div class="screen">
|
||
<div class="nav"><div class="nav__back">‹</div><div class="nav__title">发起 · 附件</div></div>
|
||
<div class="body">
|
||
<div class="mode edit">编辑态</div>
|
||
<div class="label">相关附件</div>
|
||
<div class="now-grid">
|
||
<div class="now-tile img">现场照<span class="x">×</span></div>
|
||
<div class="now-tile">
|
||
<div class="fname">报销单.pdf</div>
|
||
<div class="dl">点击下载</div>
|
||
<span class="x">×</span>
|
||
</div>
|
||
<div class="now-tile">
|
||
<div class="fname">费用.xlsx</div>
|
||
<div class="dl">点击下载</div>
|
||
<span class="x">×</span>
|
||
</div>
|
||
<div class="now-add">+</div>
|
||
</div>
|
||
</div>
|
||
</div></div>
|
||
</section>
|
||
|
||
<section class="card">
|
||
<h2>美化后 <span class="pill rec">推荐</span></h2>
|
||
<p class="sub">仍是缩略图格;类型小图标 + 文件名更易认。</p>
|
||
<div class="phone"><div class="screen">
|
||
<div class="nav"><div class="nav__back">‹</div><div class="nav__title">发起 · 附件</div></div>
|
||
<div class="body">
|
||
<div class="mode edit">编辑态</div>
|
||
<div class="label">相关附件</div>
|
||
<div class="nice-grid">
|
||
<div class="nice-tile img">现场照<span class="x">×</span></div>
|
||
<div class="nice-tile ft-pdf">
|
||
<div class="file-ico">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><path d="M14 2v6h6"/></svg>
|
||
</div>
|
||
<div class="fname">报销单.pdf</div>
|
||
<div class="dl">点击下载</div>
|
||
<span class="x">×</span>
|
||
</div>
|
||
<div class="nice-tile ft-xls">
|
||
<div class="file-ico">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><path d="M14 2v6h6"/><path d="M8 13h8M8 17h5"/></svg>
|
||
</div>
|
||
<div class="fname">费用.xlsx</div>
|
||
<div class="dl">点击下载</div>
|
||
<span class="x">×</span>
|
||
</div>
|
||
<div class="nice-add"><div class="plus">+</div><div class="txt">添加</div></div>
|
||
</div>
|
||
</div>
|
||
</div></div>
|
||
</section>
|
||
</div>
|
||
|
||
<div class="panel grid" id="panel-view" hidden>
|
||
<section class="card">
|
||
<h2>现状 · 详情</h2>
|
||
<p class="sub">无删除;下载条仍偏黑。</p>
|
||
<div class="phone"><div class="screen">
|
||
<div class="nav"><div class="nav__back">‹</div><div class="nav__title">详情 · 附件</div></div>
|
||
<div class="body">
|
||
<div class="mode view">只读</div>
|
||
<div class="label">相关附件</div>
|
||
<div class="now-grid">
|
||
<div class="now-tile img">现场照</div>
|
||
<div class="now-tile"><div class="fname">报销单.pdf</div><div class="dl">点击下载</div></div>
|
||
<div class="now-tile"><div class="fname">费用.xlsx</div><div class="dl">点击下载</div></div>
|
||
</div>
|
||
</div>
|
||
</div></div>
|
||
</section>
|
||
<section class="card">
|
||
<h2>美化后 · 详情 <span class="pill rec">推荐</span></h2>
|
||
<p class="sub">无删除钮;保留下载条。</p>
|
||
<div class="phone"><div class="screen">
|
||
<div class="nav"><div class="nav__back">‹</div><div class="nav__title">详情 · 附件</div></div>
|
||
<div class="body">
|
||
<div class="mode view">只读</div>
|
||
<div class="label">相关附件</div>
|
||
<div class="nice-grid">
|
||
<div class="nice-tile img">现场照</div>
|
||
<div class="nice-tile ft-pdf">
|
||
<div class="file-ico">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><path d="M14 2v6h6"/></svg>
|
||
</div>
|
||
<div class="fname">报销单.pdf</div>
|
||
<div class="dl">点击下载</div>
|
||
</div>
|
||
<div class="nice-tile ft-xls">
|
||
<div class="file-ico">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><path d="M14 2v6h6"/><path d="M8 13h8M8 17h5"/></svg>
|
||
</div>
|
||
<div class="fname">费用.xlsx</div>
|
||
<div class="dl">点击下载</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div></div>
|
||
</section>
|
||
</div>
|
||
|
||
<div class="footnote">
|
||
实现方式:继续用 <code>van-uploader</code>,用 scoped <code>:deep</code> 覆盖预览格 / 删除钮 / 上传触发区,并增强 <code>preview-cover</code> 下载条。
|
||
不改成文件行卡。
|
||
</div>
|
||
</div>
|
||
<script>
|
||
document.querySelectorAll('.tab').forEach((btn) => {
|
||
btn.addEventListener('click', () => {
|
||
document.querySelectorAll('.tab').forEach((b) => b.classList.remove('is-on'))
|
||
btn.classList.add('is-on')
|
||
const id = btn.getAttribute('data-panel')
|
||
document.getElementById('panel-edit').hidden = id !== 'edit'
|
||
document.getElementById('panel-view').hidden = id !== 'view'
|
||
})
|
||
})
|
||
</script>
|
||
</body>
|
||
</html>
|