Files
hms/docs/design/media-library-ui-options.html
iven a12fe0e8a9 docs(health): 媒体库与轮播图管理设计规格 + UI 可视化方案
新增设计规格涵盖:
- media_folder / media_item / banner 三个实体
- 媒体库 API(CRUD + 上传 + 裁剪 + 文件夹管理)
- 轮播图管理 API(CRUD + 排序 + 定时上下架)
- 公开端点(签名 URL 机制)+ 公开/私有访问控制
- 管理后台 UI(方案 A 左树+网格)+ MediaPicker 组件
- 小程序访客页改造(动态轮播图 + 文章卡片列表)
2026-05-10 11:32:38 +08:00

1219 lines
43 KiB
HTML
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>HMS 媒体库 + 轮播图 + 文章列表 — UI 方案选择</title>
<style>
/* ===== 设计 TokenWarm 主题) ===== */
:root {
--pri: #C4623A;
--pri-light: #D4845F;
--pri-bg: rgba(196,98,58,0.08);
--success: #5B7A5E;
--warn: #C4873A;
--error: #B54A4A;
--bg: #F5F0EB;
--card: #ffffff;
--border: #E8E2DC;
--text: #2D2A26;
--text2: #7A756E;
--text3: #A09A93;
--radius: 12px;
--radius-sm: 8px;
--shadow: 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04);
--shadow-lg: 0 8px 24px rgba(0,0,0,0.08);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Noto Sans SC', -apple-system, 'PingFang SC', 'Microsoft YaHei', sans-serif;
background: var(--bg);
color: var(--text);
font-size: 14px;
line-height: 1.5;
}
/* ===== 导航切换 ===== */
.nav-bar {
position: sticky; top: 0; z-index: 100;
background: var(--card);
border-bottom: 1px solid var(--border);
padding: 0 24px;
display: flex;
align-items: center;
height: 56px;
gap: 8px;
}
.nav-bar h1 {
font-size: 16px; font-weight: 600; margin-right: 32px;
color: var(--pri);
}
.nav-tab {
padding: 6px 16px;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s;
font-size: 13px;
color: var(--text2);
border: none;
background: none;
}
.nav-tab:hover { background: var(--pri-bg); color: var(--pri); }
.nav-tab.active { background: var(--pri); color: #fff; font-weight: 500; }
/* ===== 面板 ===== */
.panel { display: none; padding: 24px; max-width: 1400px; margin: 0 auto; }
.panel.active { display: block; }
.panel-title {
font-size: 20px; font-weight: 600; margin-bottom: 4px;
}
.panel-desc { font-size: 13px; color: var(--text2); margin-bottom: 24px; }
/* ===== 方案对比容器 ===== */
.compare-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
}
.compare-card {
background: var(--card);
border-radius: var(--radius);
box-shadow: var(--shadow);
overflow: hidden;
border: 2px solid transparent;
transition: border-color 0.2s;
}
.compare-card:hover { border-color: var(--pri-light); }
.compare-header {
padding: 16px 20px;
border-bottom: 1px solid var(--border);
display: flex;
justify-content: space-between;
align-items: center;
}
.compare-header h3 { font-size: 15px; font-weight: 600; }
.compare-tag {
font-size: 11px;
padding: 2px 8px;
border-radius: 4px;
font-weight: 500;
}
.compare-tag.recommend { background: #E8F5E9; color: #2E7D32; }
.compare-tag.alternative { background: #FFF3E0; color: #E65100; }
.compare-body { padding: 20px; }
/* ===== Ant Design 风格组件 ===== */
/* 按钮 */
.btn {
display: inline-flex; align-items: center; gap: 6px;
padding: 6px 16px;
border-radius: var(--radius-sm);
font-size: 13px;
cursor: pointer;
border: 1px solid var(--border);
background: var(--card);
color: var(--text);
transition: all 0.2s;
}
.btn:hover { border-color: var(--pri); color: var(--pri); }
.btn-primary {
background: var(--pri);
color: #fff;
border-color: var(--pri);
}
.btn-primary:hover { background: var(--pri-light); }
.btn-sm { padding: 3px 10px; font-size: 12px; }
/* 输入框 */
.input {
padding: 6px 12px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
font-size: 13px;
outline: none;
transition: border-color 0.2s;
width: 100%;
}
.input:focus { border-color: var(--pri); box-shadow: 0 0 0 2px rgba(196,98,58,0.1); }
/* 标签 */
.tag {
display: inline-block;
padding: 1px 8px;
border-radius: 4px;
font-size: 11px;
font-weight: 500;
}
.tag-green { background: #E8F5E9; color: #2E7D32; }
.tag-blue { background: #E3F2FD; color: #1565C0; }
.tag-orange { background: #FFF3E0; color: #E65100; }
.tag-gray { background: #F5F5F5; color: #757575; }
/* 表格 */
.table { width: 100%; border-collapse: collapse; }
.table th {
text-align: left;
padding: 10px 12px;
font-size: 12px;
font-weight: 500;
color: var(--text2);
border-bottom: 1px solid var(--border);
background: #FAFAF8;
}
.table td {
padding: 10px 12px;
font-size: 13px;
border-bottom: 1px solid var(--border);
vertical-align: middle;
}
.table tr:hover td { background: rgba(196,98,58,0.03); }
/* 缩略图占位 */
.thumb {
width: 40px; height: 40px;
border-radius: 6px;
background: linear-gradient(135deg, #E8E2DC, #D5CFC8);
display: flex; align-items: center; justify-content: center;
font-size: 16px; color: var(--text3);
}
.thumb-lg {
width: 100%; aspect-ratio: 4/3;
border-radius: var(--radius-sm);
background: linear-gradient(135deg, #E8E2DC, #D5CFC8);
display: flex; align-items: center; justify-content: center;
font-size: 24px; color: var(--text3);
overflow: hidden;
}
.thumb-lg img { width: 100%; height: 100%; object-fit: cover; }
/* ===== 方案 A: 左树 + 右网格 ===== */
.layout-tree-grid {
display: flex;
height: 480px;
border: 1px solid var(--border);
border-radius: var(--radius);
overflow: hidden;
}
.tree-sidebar {
width: 200px;
border-right: 1px solid var(--border);
padding: 12px;
flex-shrink: 0;
}
.tree-sidebar h4 { font-size: 12px; color: var(--text2); margin-bottom: 8px; font-weight: 500; }
.tree-item {
padding: 6px 8px;
border-radius: 6px;
font-size: 13px;
cursor: pointer;
display: flex;
align-items: center;
gap: 6px;
margin-bottom: 2px;
}
.tree-item:hover { background: var(--pri-bg); }
.tree-item.active { background: var(--pri-bg); color: var(--pri); font-weight: 500; }
.tree-item .icon { font-size: 14px; }
.grid-main {
flex: 1;
display: flex;
flex-direction: column;
}
.grid-toolbar {
padding: 12px 16px;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
gap: 8px;
}
.grid-toolbar .spacer { flex: 1; }
.grid-content {
flex: 1;
padding: 16px;
overflow-y: auto;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
align-content: start;
}
.media-card {
border: 1px solid var(--border);
border-radius: var(--radius-sm);
overflow: hidden;
cursor: pointer;
transition: all 0.2s;
position: relative;
}
.media-card:hover { border-color: var(--pri); box-shadow: var(--shadow); }
.media-card .actions {
position: absolute; top: 6px; right: 6px;
display: none; gap: 4px;
}
.media-card:hover .actions { display: flex; }
.media-card .info {
padding: 8px;
}
.media-card .info .name {
font-size: 12px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.media-card .info .meta {
font-size: 11px;
color: var(--text3);
}
.public-badge {
position: absolute; top: 6px; left: 6px;
font-size: 10px;
padding: 1px 6px;
border-radius: 3px;
background: rgba(255,255,255,0.9);
color: var(--success);
display: flex; align-items: center; gap: 3px;
}
/* ===== 方案 B: 全宽网格 + 筛选 ===== */
.layout-full-grid {
border: 1px solid var(--border);
border-radius: var(--radius);
overflow: hidden;
height: 480px;
display: flex;
flex-direction: column;
}
.filter-bar {
padding: 12px 16px;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.filter-bar .spacer { flex: 1; }
.filter-group {
display: flex; align-items: center; gap: 6px;
}
.filter-group label { font-size: 12px; color: var(--text2); white-space: nowrap; }
.select {
padding: 4px 8px;
border: 1px solid var(--border);
border-radius: 6px;
font-size: 12px;
background: var(--card);
min-width: 100px;
}
.full-grid-content {
flex: 1;
padding: 16px;
overflow-y: auto;
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 12px;
align-content: start;
}
/* ===== 分页 ===== */
.pagination {
padding: 12px 16px;
border-top: 1px solid var(--border);
display: flex;
justify-content: flex-end;
align-items: center;
gap: 4px;
font-size: 12px;
color: var(--text2);
}
.page-btn {
width: 28px; height: 28px;
border: 1px solid var(--border);
border-radius: 6px;
display: flex; align-items: center; justify-content: center;
cursor: pointer;
background: var(--card);
font-size: 12px;
}
.page-btn.active { background: var(--pri); color: #fff; border-color: var(--pri); }
/* ===== 全宽展示(方案 C 轮播图/小程序) ===== */
.full-width-card {
background: var(--card);
border-radius: var(--radius);
box-shadow: var(--shadow);
overflow: hidden;
max-width: 1400px;
margin: 0 auto;
}
.full-width-header {
padding: 16px 20px;
border-bottom: 1px solid var(--border);
display: flex;
justify-content: space-between;
align-items: center;
}
.full-width-body { padding: 20px; }
/* ===== Drawer 模拟 ===== */
.drawer-overlay {
position: fixed; top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.3);
z-index: 200;
display: none;
justify-content: flex-end;
}
.drawer-overlay.open { display: flex; }
.drawer {
width: 480px;
background: var(--card);
height: 100%;
overflow-y: auto;
box-shadow: -4px 0 16px rgba(0,0,0,0.1);
display: flex;
flex-direction: column;
}
.drawer-header {
padding: 16px 20px;
border-bottom: 1px solid var(--border);
display: flex;
justify-content: space-between;
align-items: center;
}
.drawer-header h3 { font-size: 16px; font-weight: 600; }
.drawer-close {
width: 28px; height: 28px;
border-radius: 6px;
display: flex; align-items: center; justify-content: center;
cursor: pointer;
border: none;
background: none;
font-size: 16px;
color: var(--text2);
}
.drawer-close:hover { background: #f5f5f5; }
.drawer-body { flex: 1; padding: 20px; }
.drawer-footer {
padding: 12px 20px;
border-top: 1px solid var(--border);
display: flex;
justify-content: flex-end;
gap: 8px;
}
/* 表单 */
.form-item { margin-bottom: 16px; }
.form-label {
display: block;
font-size: 13px;
font-weight: 500;
margin-bottom: 6px;
color: var(--text);
}
.form-hint { font-size: 11px; color: var(--text3); margin-top: 4px; }
.form-required { color: var(--error); margin-left: 2px; }
/* 图片选择占位 */
.image-select {
border: 2px dashed var(--border);
border-radius: var(--radius-sm);
height: 160px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
color: var(--text3);
cursor: pointer;
transition: border-color 0.2s;
}
.image-select:hover { border-color: var(--pri); color: var(--pri); }
.image-select .icon { font-size: 28px; }
.image-selected {
border: 2px solid var(--pri);
border-radius: var(--radius-sm);
height: 160px;
overflow: hidden;
position: relative;
}
.image-selected img { width: 100%; height: 100%; object-fit: cover; }
.image-selected .change-btn {
position: absolute; bottom: 8px; right: 8px;
padding: 4px 10px;
border-radius: 4px;
background: rgba(0,0,0,0.5);
color: #fff;
font-size: 11px;
cursor: pointer;
border: none;
}
/* ===== 小程序模拟 ===== */
.mp-frame {
width: 375px;
margin: 0 auto;
background: var(--bg);
border-radius: 24px;
overflow: hidden;
box-shadow: var(--shadow-lg);
border: 8px solid #1a1a1a;
}
.mp-statusbar {
height: 44px;
background: #1a1a1a;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 12px;
}
.mp-content {
height: 667px;
overflow-y: auto;
}
.mp-carousel {
height: 180px;
position: relative;
overflow: hidden;
}
.mp-carousel-bg {
width: 100%; height: 100%;
object-fit: cover;
}
.mp-carousel-overlay {
position: absolute; bottom: 0; left: 0; right: 0;
padding: 16px;
background: linear-gradient(transparent, rgba(0,0,0,0.5));
color: #fff;
}
.mp-carousel-overlay h3 { font-size: 18px; font-weight: 600; margin-bottom: 4px; }
.mp-carousel-overlay p { font-size: 12px; opacity: 0.9; }
.mp-carousel-dots {
position: absolute; bottom: 10px; right: 16px;
display: flex; gap: 5px;
}
.mp-carousel-dots span {
width: 6px; height: 6px; border-radius: 3px;
background: rgba(255,255,255,0.4);
}
.mp-carousel-dots span.active {
background: #fff;
width: 16px;
}
.mp-section {
padding: 16px;
}
.mp-section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
.mp-section-title {
font-size: 16px;
font-weight: 600;
color: var(--text);
}
.mp-section-more {
font-size: 12px;
color: var(--pri);
}
.mp-article-card {
background: var(--card);
border-radius: 10px;
overflow: hidden;
margin-bottom: 10px;
box-shadow: 0 1px 2px rgba(0,0,0,0.04);
}
.mp-article-card .card-img {
height: 120px;
overflow: hidden;
}
.mp-article-card .card-img img {
width: 100%; height: 100%; object-fit: cover;
}
.mp-article-card .card-body {
padding: 10px 12px;
}
.mp-article-card .card-body h4 {
font-size: 14px;
font-weight: 500;
margin-bottom: 4px;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
.mp-article-card .card-body p {
font-size: 12px;
color: var(--text2);
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.mp-article-list {
display: flex;
flex-direction: column;
gap: 10px;
}
/* 两列卡片 */
.mp-article-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
}
.mp-article-grid .mp-article-card .card-img { height: 90px; }
/* ===== 方案标注 ===== */
.note-box {
margin-top: 16px;
padding: 12px 16px;
background: #FFF8F0;
border-left: 3px solid var(--warn);
border-radius: 0 8px 8px 0;
font-size: 13px;
color: var(--text);
}
.note-box strong { color: var(--warn); }
.choice-row {
display: flex;
gap: 12px;
margin-top: 16px;
}
.choice-btn {
flex: 1;
padding: 10px;
border: 2px solid var(--border);
border-radius: var(--radius-sm);
background: var(--card);
cursor: pointer;
text-align: center;
font-size: 14px;
font-weight: 500;
transition: all 0.2s;
}
.choice-btn:hover { border-color: var(--pri); color: var(--pri); }
.choice-btn.selected { border-color: var(--pri); background: var(--pri-bg); color: var(--pri); }
</style>
</head>
<body>
<!-- 导航 -->
<nav class="nav-bar">
<h1>HMS UI 方案选择</h1>
<button class="nav-tab active" onclick="switchPanel('media')">1. 媒体库</button>
<button class="nav-tab" onclick="switchPanel('banner')">2. 轮播图管理</button>
<button class="nav-tab" onclick="switchPanel('mp')">3. 小程序访客页</button>
</nav>
<!-- ==================== 面板 1: 媒体库 ==================== -->
<div class="panel active" id="panel-media">
<div class="panel-title">媒体库管理页面 — 布局方案</div>
<div class="panel-desc">两种布局风格,选择一种作为实施方案。左侧树+网格适合图片量大的场景,全宽网格适合图片量少的场景。</div>
<div class="compare-grid">
<!-- 方案 A -->
<div class="compare-card">
<div class="compare-header">
<h3>方案 A左树 + 右网格</h3>
<span class="compare-tag recommend">推荐</span>
</div>
<div class="compare-body">
<div class="layout-tree-grid">
<!-- 左侧树 -->
<div class="tree-sidebar">
<h4>文件夹</h4>
<div class="tree-item active">
<span class="icon">📁</span> 全部资源
</div>
<div class="tree-item">
<span class="icon">📂</span> 轮播图
</div>
<div class="tree-item">
<span class="icon">📂</span> 文章插图
</div>
<div class="tree-item">
<span class="icon">📂</span> 活动图片
</div>
<div class="tree-item">
<span class="icon">📂</span> 产品图片
</div>
<div style="margin-top:12px;">
<button class="btn btn-sm" style="width:100%">+ 新建文件夹</button>
</div>
</div>
<!-- 右侧网格 -->
<div class="grid-main">
<div class="grid-toolbar">
<button class="btn btn-primary btn-sm">+ 上传图片</button>
<span class="spacer"></span>
<input class="input" style="width:180px" placeholder="搜索文件名...">
<select class="select"><option>全部类型</option><option>JPEG</option><option>PNG</option></select>
<select class="select"><option>全部状态</option><option>公开</option><option>私有</option></select>
</div>
<div class="grid-content">
<!-- 图片卡片 x8 -->
<div class="media-card">
<div class="public-badge">🌐 公开</div>
<div class="actions">
<button class="btn btn-sm" style="padding:2px 6px">📋</button>
<button class="btn btn-sm" style="padding:2px 6px">✏️</button>
<button class="btn btn-sm" style="padding:2px 6px;color:var(--error)">🗑</button>
</div>
<div class="thumb-lg" style="background:linear-gradient(135deg,#C4623A 30%,#D4845F 100%)">🏞</div>
<div class="info">
<div class="name">血透中心环境.jpg</div>
<div class="meta">1920×1080 · 2.4MB</div>
</div>
</div>
<div class="media-card">
<div class="public-badge">🌐 公开</div>
<div class="actions">
<button class="btn btn-sm" style="padding:2px 6px">📋</button>
<button class="btn btn-sm" style="padding:2px 6px">✏️</button>
<button class="btn btn-sm" style="padding:2px 6px;color:var(--error)">🗑</button>
</div>
<div class="thumb-lg" style="background:linear-gradient(135deg,#5B7A5E 30%,#7A9A7D 100%)">🌿</div>
<div class="info">
<div class="name">健康宣教封面.jpg</div>
<div class="meta">1200×800 · 1.8MB</div>
</div>
</div>
<div class="media-card">
<div class="actions">
<button class="btn btn-sm" style="padding:2px 6px">📋</button>
<button class="btn btn-sm" style="padding:2px 6px">✏️</button>
<button class="btn btn-sm" style="padding:2px 6px;color:var(--error)">🗑</button>
</div>
<div class="thumb-lg" style="background:linear-gradient(135deg,#C4873A 30%,#D4A75F 100%)">🏥</div>
<div class="info">
<div class="name">医生团队合照.png</div>
<div class="meta">2400×1600 · 3.1MB</div>
</div>
</div>
<div class="media-card">
<div class="actions">
<button class="btn btn-sm" style="padding:2px 6px">📋</button>
<button class="btn btn-sm" style="padding:2px 6px">✏️</button>
<button class="btn btn-sm" style="padding:2px 6px;color:var(--error)">🗑</button>
</div>
<div class="thumb-lg" style="background:linear-gradient(135deg,#8B6F4E 30%,#A8927A 100%)">📊</div>
<div class="info">
<div class="name">健康数据分析.png</div>
<div class="meta">800×600 · 0.5MB</div>
</div>
</div>
<div class="media-card">
<div class="public-badge">🌐 公开</div>
<div class="actions">
<button class="btn btn-sm" style="padding:2px 6px">📋</button>
<button class="btn btn-sm" style="padding:2px 6px">✏️</button>
<button class="btn btn-sm" style="padding:2px 6px;color:var(--error)">🗑</button>
</div>
<div class="thumb-lg" style="background:linear-gradient(135deg,#B54A4A 30%,#D47A7A 100%)">❤️</div>
<div class="info">
<div class="name">心脏健康插图.jpg</div>
<div class="meta">1600×1200 · 1.2MB</div>
</div>
</div>
<div class="media-card">
<div class="actions">
<button class="btn btn-sm" style="padding:2px 6px">📋</button>
<button class="btn btn-sm" style="padding:2px 6px">✏️</button>
<button class="btn btn-sm" style="padding:2px 6px;color:var(--error)">🗑</button>
</div>
<div class="thumb-lg" style="background:linear-gradient(135deg,#3D5A40 30%,#5B7A5E 100%)">🩺</div>
<div class="info">
<div class="name">体检报告模板.png</div>
<div class="meta">1000×700 · 0.8MB</div>
</div>
</div>
<div class="media-card">
<div class="public-badge">🌐 公开</div>
<div class="actions">
<button class="btn btn-sm" style="padding:2px 6px">📋</button>
<button class="btn btn-sm" style="padding:2px 6px">✏️</button>
<button class="btn btn-sm" style="padding:2px 6px;color:var(--error)">🗑</button>
</div>
<div class="thumb-lg" style="background:linear-gradient(135deg,#2D2A26 30%,#5A5550 100%)">🏠</div>
<div class="info">
<div class="name">机构外景.jpg</div>
<div class="meta">3000×2000 · 4.2MB</div>
</div>
</div>
<div class="media-card">
<div class="actions">
<button class="btn btn-sm" style="padding:2px 6px">📋</button>
<button class="btn btn-sm" style="padding:2px 6px">✏️</button>
<button class="btn btn-sm" style="padding:2px 6px;color:var(--error)">🗑</button>
</div>
<div class="thumb-lg" style="background:linear-gradient(135deg,#C4623A 30%,#E8C0A0 100%)">💊</div>
<div class="info">
<div class="name">药品展示.jpg</div>
<div class="meta">1200×900 · 1.5MB</div>
</div>
</div>
</div>
<div class="pagination">
共 24 个资源
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn">2</button>
<button class="page-btn">3</button>
<button class="page-btn"></button>
</div>
</div>
</div>
<div class="note-box">
<strong>特点:</strong>文件夹导航清晰,图片分类一目了然。适合图片数量多、需要分类管理的场景。与主流 CMSWordPress、Strapi体验一致。
</div>
</div>
</div>
<!-- 方案 B -->
<div class="compare-card">
<div class="compare-header">
<h3>方案 B全宽网格 + 筛选条</h3>
<span class="compare-tag alternative">备选</span>
</div>
<div class="compare-body">
<div class="layout-full-grid">
<div class="filter-bar">
<button class="btn btn-primary btn-sm">+ 上传图片</button>
<span class="spacer"></span>
<div class="filter-group">
<label>文件夹</label>
<select class="select"><option>全部</option><option>轮播图</option><option>文章插图</option><option>活动图片</option></select>
</div>
<div class="filter-group">
<label>类型</label>
<select class="select"><option>全部</option><option>JPEG</option><option>PNG</option></select>
</div>
<div class="filter-group">
<label>状态</label>
<select class="select"><option>全部</option><option>公开</option><option>私有</option></select>
</div>
<input class="input" style="width:160px" placeholder="搜索...">
</div>
<div class="full-grid-content">
<div class="media-card">
<div class="public-badge">🌐 公开</div>
<div class="thumb-lg" style="background:linear-gradient(135deg,#C4623A 30%,#D4845F 100%)">🏞</div>
<div class="info">
<div class="name">血透中心环境.jpg</div>
<div class="meta">1920×1080 · 2.4MB</div>
</div>
</div>
<div class="media-card">
<div class="public-badge">🌐 公开</div>
<div class="thumb-lg" style="background:linear-gradient(135deg,#5B7A5E 30%,#7A9A7D 100%)">🌿</div>
<div class="info">
<div class="name">健康宣教封面.jpg</div>
<div class="meta">1200×800 · 1.8MB</div>
</div>
</div>
<div class="media-card">
<div class="thumb-lg" style="background:linear-gradient(135deg,#C4873A 30%,#D4A75F 100%)">🏥</div>
<div class="info">
<div class="name">医生团队合照.png</div>
<div class="meta">2400×1600 · 3.1MB</div>
</div>
</div>
<div class="media-card">
<div class="thumb-lg" style="background:linear-gradient(135deg,#8B6F4E 30%,#A8927A 100%)">📊</div>
<div class="info">
<div class="name">健康数据分析.png</div>
<div class="meta">800×600 · 0.5MB</div>
</div>
</div>
<div class="media-card">
<div class="public-badge">🌐 公开</div>
<div class="thumb-lg" style="background:linear-gradient(135deg,#B54A4A 30%,#D47A7A 100%)">❤️</div>
<div class="info">
<div class="name">心脏健康插图.jpg</div>
<div class="meta">1600×1200 · 1.2MB</div>
</div>
</div>
<div class="media-card">
<div class="thumb-lg" style="background:linear-gradient(135deg,#3D5A40 30%,#5B7A5E 100%)">🩺</div>
<div class="info">
<div class="name">体检报告模板.png</div>
<div class="meta">1000×700 · 0.8MB</div>
</div>
</div>
<div class="media-card">
<div class="public-badge">🌐 公开</div>
<div class="thumb-lg" style="background:linear-gradient(135deg,#2D2A26 30%,#5A5550 100%)">🏠</div>
<div class="info">
<div class="name">机构外景.jpg</div>
<div class="meta">3000×2000 · 4.2MB</div>
</div>
</div>
<div class="media-card">
<div class="thumb-lg" style="background:linear-gradient(135deg,#C4623A 30%,#E8C0A0 100%)">💊</div>
<div class="info">
<div class="name">药品展示.jpg</div>
<div class="meta">1200×900 · 1.5MB</div>
</div>
</div>
<div class="media-card">
<div class="public-badge">🌐 公开</div>
<div class="thumb-lg" style="background:linear-gradient(135deg,#D4845F 30%,#E8C0A0 100%)">📋</div>
<div class="info">
<div class="name">健康指南封面.jpg</div>
<div class="meta">1400×1000 · 2.0MB</div>
</div>
</div>
<div class="media-card">
<div class="thumb-lg" style="background:linear-gradient(135deg,#7A9A7D 30%,#A0C0A3 100%)">🧬</div>
<div class="info">
<div class="name">基因检测报告.png</div>
<div class="meta">900×600 · 0.6MB</div>
</div>
</div>
</div>
<div class="pagination">
共 24 个资源
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn">2</button>
<button class="page-btn">3</button>
<button class="page-btn"></button>
</div>
</div>
<div class="note-box">
<strong>特点:</strong>空间利用率高,展示更多图片。文件夹通过下拉筛选切换,操作路径更短。适合图片数量少、不需要频繁切换分类的场景。
</div>
</div>
</div>
</div>
<div class="choice-row">
<div class="choice-btn" onclick="selectChoice(this, 'media', 'A')">选择方案 A左树+网格)</div>
<div class="choice-btn" onclick="selectChoice(this, 'media', 'B')">选择方案 B全宽网格</div>
</div>
</div>
<!-- ==================== 面板 2: 轮播图管理 ==================== -->
<div class="panel" id="panel-banner">
<div class="panel-title">轮播图管理页面</div>
<div class="panel-desc">管理后台的轮播图 CRUD + 小程序预览。点击"新增轮播图"查看表单 Drawer。</div>
<div class="full-width-card">
<div class="full-width-header">
<div>
<h3 style="font-size:16px;font-weight:600;">轮播图管理</h3>
<p style="font-size:12px;color:var(--text2);margin-top:2px;">管理小程序访客首页轮播图,拖拽行调整展示顺序</p>
</div>
<div style="display:flex;gap:8px;">
<button class="btn">查看小程序效果</button>
<button class="btn btn-primary" onclick="openDrawer()">+ 新增轮播图</button>
</div>
</div>
<div class="full-width-body" style="padding:0;">
<table class="table">
<thead>
<tr>
<th style="width:50px">排序</th>
<th style="width:80px">图片</th>
<th>标题</th>
<th>副标题</th>
<th>跳转</th>
<th style="width:80px">状态</th>
<th style="width:160px">生效时间</th>
<th style="width:120px">操作</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center;color:var(--text3)">1</td>
<td><div class="thumb" style="background:linear-gradient(135deg,#C4623A,#D4845F)">🏞</div></td>
<td><strong>专业血透中心</strong></td>
<td style="color:var(--text2)">三甲级医护团队全程守护</td>
<td><span class="tag tag-gray">无跳转</span></td>
<td><span class="tag tag-green">生效中</span></td>
<td style="font-size:12px;color:var(--text2)">长期</td>
<td>
<button class="btn btn-sm">编辑</button>
<button class="btn btn-sm" style="color:var(--error)">删除</button>
</td>
</tr>
<tr>
<td style="text-align:center;color:var(--text3)">2</td>
<td><div class="thumb" style="background:linear-gradient(135deg,#5B7A5E,#7A9A7D)">🌿</div></td>
<td><strong>智慧健康管理</strong></td>
<td style="color:var(--text2)">AI 驱动个性化健康方案</td>
<td><span class="tag tag-blue">文章</span></td>
<td><span class="tag tag-green">生效中</span></td>
<td style="font-size:12px;color:var(--text2)">长期</td>
<td>
<button class="btn btn-sm">编辑</button>
<button class="btn btn-sm" style="color:var(--error)">删除</button>
</td>
</tr>
<tr>
<td style="text-align:center;color:var(--text3)">3</td>
<td><div class="thumb" style="background:linear-gradient(135deg,#8B6F4E,#A8927A)">🏥</div></td>
<td><strong>温馨就医环境</strong></td>
<td style="color:var(--text2)">舒适安全的治疗体验</td>
<td><span class="tag tag-gray">无跳转</span></td>
<td><span class="tag tag-green">生效中</span></td>
<td style="font-size:12px;color:var(--text2)">长期</td>
<td>
<button class="btn btn-sm">编辑</button>
<button class="btn btn-sm" style="color:var(--error)">删除</button>
</td>
</tr>
<tr>
<td style="text-align:center;color:var(--text3)">4</td>
<td><div class="thumb" style="background:linear-gradient(135deg,#C4873A,#D4A75F)">🎉</div></td>
<td><strong>世界肾脏日活动</strong></td>
<td style="color:var(--text2)">3月14日线下健康讲座</td>
<td><span class="tag tag-orange">外部链接</span></td>
<td><span class="tag tag-orange">待生效</span></td>
<td style="font-size:12px;color:var(--text2)">2026-03-10 ~ 2026-03-14</td>
<td>
<button class="btn btn-sm">编辑</button>
<button class="btn btn-sm" style="color:var(--error)">删除</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- ==================== 面板 3: 小程序访客页 ==================== -->
<div class="panel" id="panel-mp">
<div class="panel-title">小程序访客首页 — 效果预览</div>
<div class="panel-desc">轮播图从后台动态获取,文章列表按分类筛选展示。"核心功能"区域改为文章卡片列表。</div>
<div style="display:flex;gap:40px;justify-content:center;flex-wrap:wrap;">
<!-- 当前效果(静态) -->
<div>
<div style="text-align:center;margin-bottom:12px;font-size:13px;color:var(--text2);">当前效果(硬编码)</div>
<div class="mp-frame">
<div class="mp-statusbar">9:41</div>
<div class="mp-content">
<div class="mp-carousel" style="background:linear-gradient(135deg,#C4623A 0%,#D4845F 60%,#E8C0A0 100%)">
<div class="mp-carousel-overlay">
<h3>专业血透中心</h3>
<p>三甲级医护团队全程守护</p>
</div>
<div class="mp-carousel-dots">
<span class="active"></span><span></span><span></span>
</div>
</div>
<div class="mp-section">
<div class="mp-section-header">
<div class="mp-section-title">核心功能</div>
</div>
<div style="display:flex;flex-direction:column;gap:10px;">
<div style="background:var(--card);border-radius:10px;padding:14px;box-shadow:0 1px 2px rgba(0,0,0,0.04);">
<div style="font-size:14px;font-weight:500;margin-bottom:4px;">健康数据管理</div>
<div style="font-size:12px;color:var(--text2);">记录并追踪您的体征数据</div>
</div>
<div style="background:var(--card);border-radius:10px;padding:14px;box-shadow:0 1px 2px rgba(0,0,0,0.04);">
<div style="font-size:14px;font-weight:500;margin-bottom:4px;">智能预约排班</div>
<div style="font-size:12px;color:var(--text2);">在线预约透析和治疗</div>
</div>
<div style="background:var(--card);border-radius:10px;padding:14px;box-shadow:0 1px 2px rgba(0,0,0,0.04);">
<div style="font-size:14px;font-weight:500;margin-bottom:4px;">AI 健康分析</div>
<div style="font-size:12px;color:var(--text2);">个性化健康趋势解读</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 优化后效果 -->
<div>
<div style="text-align:center;margin-bottom:12px;font-size:13px;color:var(--pri);font-weight:500;">优化后效果(动态数据)</div>
<div class="mp-frame">
<div class="mp-statusbar">9:41</div>
<div class="mp-content">
<!-- 动态轮播图 -->
<div class="mp-carousel">
<div class="mp-carousel-bg" style="background:linear-gradient(135deg,#C4623A 0%,#D4845F 60%,#E8C0A0 100%);display:flex;align-items:center;justify-content:center;">
<span style="font-size:40px;">🏞</span>
</div>
<div class="mp-carousel-overlay">
<h3>专业血透中心</h3>
<p>三甲级医护团队全程守护</p>
</div>
<div class="mp-carousel-dots">
<span class="active"></span><span></span><span></span>
</div>
</div>
<!-- 文章列表 -->
<div class="mp-section">
<div class="mp-section-header">
<div class="mp-section-title">健康资讯</div>
<span class="mp-section-more">查看更多 </span>
</div>
<div class="mp-article-grid">
<div class="mp-article-card">
<div class="card-img" style="background:linear-gradient(135deg,#5B7A5E,#7A9A7D);display:flex;align-items:center;justify-content:center;">
<span style="font-size:24px;">🌿</span>
</div>
<div class="card-body">
<h4>高血压患者的日常管理指南</h4>
<p>科学控制血压,从日常生活细节做起</p>
</div>
</div>
<div class="mp-article-card">
<div class="card-img" style="background:linear-gradient(135deg,#C4623A,#D4845F);display:flex;align-items:center;justify-content:center;">
<span style="font-size:24px;">🩺</span>
</div>
<div class="card-body">
<h4>透析患者饮食注意事项</h4>
<p>合理膳食是透析治疗的重要补充</p>
</div>
</div>
</div>
<div style="margin-top:10px;">
<div class="mp-article-card" style="display:flex;flex-direction:row;">
<div style="width:100px;flex-shrink:0;background:linear-gradient(135deg,#C4873A,#D4A75F);display:flex;align-items:center;justify-content:center;">
<span style="font-size:20px;">💊</span>
</div>
<div class="card-body" style="flex:1;">
<h4>常见降压药物的服用须知</h4>
<p>正确服药提高疗效,减少副作用</p>
</div>
</div>
</div>
<div style="margin-top:10px;">
<div class="mp-article-card" style="display:flex;flex-direction:row;">
<div style="width:100px;flex-shrink:0;background:linear-gradient(135deg,#8B6F4E,#A8927A);display:flex;align-items:center;justify-content:center;">
<span style="font-size:20px;">🧬</span>
</div>
<div class="card-body" style="flex:1;">
<h4>肾功能指标解读</h4>
<p>教你读懂化验单上的关键数据</p>
</div>
</div>
</div>
</div>
<!-- 底部登录引导 -->
<div style="padding:16px;">
<div style="background:var(--card);border-radius:10px;padding:16px;text-align:center;box-shadow:0 1px 2px rgba(0,0,0,0.04);">
<div style="font-size:13px;color:var(--text2);margin-bottom:10px;">登录后解锁更多健康服务</div>
<button style="width:100%;padding:10px;background:var(--pri);color:#fff;border:none;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;">立即登录</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Drawer: 新增轮播图 -->
<div class="drawer-overlay" id="drawer-overlay" onclick="closeDrawer(event)">
<div class="drawer" onclick="event.stopPropagation()">
<div class="drawer-header">
<h3>新增轮播图</h3>
<button class="drawer-close" onclick="closeDrawer()"></button>
</div>
<div class="drawer-body">
<div class="form-item">
<label class="form-label">轮播图片 <span class="form-required">*</span></label>
<div class="image-selected">
<div style="width:100%;height:100%;background:linear-gradient(135deg,#C4623A,#D4845F);display:flex;align-items:center;justify-content:center;">
<span style="font-size:40px;">🏞</span>
</div>
<button class="change-btn">从媒体库选择</button>
</div>
<div class="form-hint">建议尺寸 750×360px支持 JPG/PNG不超过 5MB</div>
</div>
<div class="form-item">
<label class="form-label">标题</label>
<input class="input" placeholder="轮播图标题(选填)" value="专业血透中心">
<div class="form-hint">为空则使用图片的替代文本</div>
</div>
<div class="form-item">
<label class="form-label">副标题</label>
<input class="input" placeholder="简短描述(选填)" value="三甲级医护团队全程守护">
</div>
<div class="form-item">
<label class="form-label">跳转设置</label>
<div style="display:flex;gap:8px;">
<select class="select" style="flex:1;">
<option>无跳转</option>
<option selected>文章</option>
<option>外部链接</option>
</select>
<input class="input" style="flex:2;" placeholder="选择文章或输入链接" value="关于我们中心">
</div>
</div>
<div class="form-item">
<label class="form-label">生效时间(选填)</label>
<div style="display:flex;gap:8px;">
<input class="input" type="date" style="flex:1;" placeholder="开始时间">
<span style="color:var(--text3);line-height:32px;">~</span>
<input class="input" type="date" style="flex:1;" placeholder="结束时间">
</div>
<div class="form-hint">留空表示永久生效</div>
</div>
<div class="form-item">
<label class="form-label">排序</label>
<input class="input" type="number" value="1" style="width:120px;">
</div>
<div class="form-item">
<label class="form-label">状态</label>
<div style="display:flex;align-items:center;gap:8px;">
<div style="width:40px;height:22px;background:var(--success);border-radius:11px;position:relative;cursor:pointer;">
<div style="width:18px;height:18px;background:#fff;border-radius:50%;position:absolute;right:2px;top:2px;box-shadow:0 1px 2px rgba(0,0,0,0.1);"></div>
</div>
<span style="font-size:13px;">启用</span>
</div>
</div>
</div>
<div class="drawer-footer">
<button class="btn">取消</button>
<button class="btn btn-primary">保存</button>
</div>
</div>
</div>
<script>
function switchPanel(name) {
document.querySelectorAll('.panel').forEach(p => p.classList.remove('active'));
document.querySelectorAll('.nav-tab').forEach(t => t.classList.remove('active'));
document.getElementById('panel-' + name).classList.add('active');
event.target.classList.add('active');
}
function selectChoice(el, group, choice) {
const row = el.parentElement;
row.querySelectorAll('.choice-btn').forEach(b => b.classList.remove('selected'));
el.classList.add('selected');
}
function openDrawer() {
document.getElementById('drawer-overlay').classList.add('open');
}
function closeDrawer(e) {
if (e && e.target !== document.getElementById('drawer-overlay')) return;
document.getElementById('drawer-overlay').classList.remove('open');
}
</script>
</body>
</html>