init
This commit is contained in:
+1113
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,105 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>苏州肛泰中医院 · 运营管理后台</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&family=Noto+Sans+SC:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<!-- 登录页 -->
|
||||
<div id="loginPage" class="login-page">
|
||||
<div class="login-bg-decor">
|
||||
<span class="orb orb-1"></span>
|
||||
<span class="orb orb-2"></span>
|
||||
<span class="orb orb-3"></span>
|
||||
</div>
|
||||
<div class="login-card">
|
||||
<div class="login-brand">
|
||||
<div class="login-logo">🏥</div>
|
||||
<h1 class="login-title">苏州肛泰中医院</h1>
|
||||
<p class="login-subtitle">运营管理后台 · Internal Console</p>
|
||||
</div>
|
||||
<form id="loginForm" class="login-form" autocomplete="off">
|
||||
<div class="form-field">
|
||||
<label for="loginUsername">账号</label>
|
||||
<input id="loginUsername" type="text" placeholder="请输入管理员账号" required />
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="loginPassword">密码</label>
|
||||
<input id="loginPassword" type="password" placeholder="请输入登录密码" required />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-block">登 录</button>
|
||||
<p class="login-hint">默认账号 <code>admin</code>,首次登录后请尽快修改密码</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主控制台 -->
|
||||
<div id="appPage" class="app-page hidden">
|
||||
<!-- 顶栏 -->
|
||||
<header class="app-header">
|
||||
<div class="app-header-left">
|
||||
<div class="app-logo">🏥</div>
|
||||
<div>
|
||||
<div class="app-title">苏州肛泰中医院</div>
|
||||
<div class="app-subtitle">运营管理后台 · v2.0</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-header-right">
|
||||
<a class="header-link" href="/api/v1/hospitals" target="_blank" rel="noreferrer">API 健康</a>
|
||||
<div class="user-chip" id="userChip">
|
||||
<span class="user-avatar">A</span>
|
||||
<span class="user-name" id="userName">管理员</span>
|
||||
</div>
|
||||
<button class="btn btn-ghost btn-sm" id="logoutBtn">退出</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="app-body">
|
||||
<!-- 侧栏 -->
|
||||
<aside class="app-side">
|
||||
<nav class="side-nav" id="sideNav">
|
||||
<a class="side-link" data-route="dashboard"><span class="side-icon">📊</span><span>概览</span></a>
|
||||
<a class="side-link" data-route="homeContent"><span class="side-icon">🏠</span><span>首页内容</span></a>
|
||||
<a class="side-link" data-route="hospitalIntro"><span class="side-icon">🏥</span><span>医院简介</span></a>
|
||||
<a class="side-link" data-route="siteConfig"><span class="side-icon">⚙️</span><span>系统设置</span></a>
|
||||
<a class="side-link" data-route="appointments"><span class="side-icon">📅</span><span>预约管理</span></a>
|
||||
<a class="side-link" data-route="leads"><span class="side-icon">📨</span><span>意向客户</span></a>
|
||||
<a class="side-link" data-route="account"><span class="side-icon">🔐</span><span>账号设置</span></a>
|
||||
</nav>
|
||||
<div class="side-foot">
|
||||
<div class="side-foot-line">© 2026 苏州肛泰中医院</div>
|
||||
<div class="side-foot-line muted">管理后台 v2.0</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 主区 -->
|
||||
<main class="app-main" id="appMain">
|
||||
<div class="page-loading">加载中…</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 通用 Toast -->
|
||||
<div id="toast" class="toast"></div>
|
||||
|
||||
<!-- 通用 Modal 容器 -->
|
||||
<div id="modal" class="modal hidden">
|
||||
<div class="modal-mask" data-modal-close></div>
|
||||
<div class="modal-card">
|
||||
<div class="modal-header">
|
||||
<h3 id="modalTitle">标题</h3>
|
||||
<button class="modal-close" data-modal-close>×</button>
|
||||
</div>
|
||||
<div class="modal-body" id="modalBody"></div>
|
||||
<div class="modal-footer" id="modalFooter"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="./app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,616 @@
|
||||
/*
|
||||
* styles.css
|
||||
* 苏州肛泰中医院 · 运营管理后台视觉系统
|
||||
* 设计原则:医疗专业感 · 克制留白 · 蓝绿主色 · 8pt 间距
|
||||
*/
|
||||
|
||||
:root {
|
||||
--color-primary: #1f7ae0;
|
||||
--color-primary-light: #4f9bff;
|
||||
--color-primary-dark: #0d5fc4;
|
||||
--color-primary-50: #eaf3ff;
|
||||
--color-accent: #15b9a3;
|
||||
--color-accent-50: #e6faf7;
|
||||
--color-success: #15b9a3;
|
||||
--color-success-bg: #e6faf7;
|
||||
--color-warning: #ff8a00;
|
||||
--color-warning-bg: #fff3e0;
|
||||
--color-error: #e5454b;
|
||||
--color-error-bg: #fdecec;
|
||||
--color-info-bg: #eaf3ff;
|
||||
|
||||
--color-bg-page: #f4f6fa;
|
||||
--color-bg-card: #ffffff;
|
||||
--color-bg-hover: #f0f3f8;
|
||||
--color-bg-elevated: #ffffff;
|
||||
|
||||
--color-text-primary: #0f172a;
|
||||
--color-text-secondary: #475569;
|
||||
--color-text-tertiary: #94a3b8;
|
||||
--color-text-disabled: #cbd5e1;
|
||||
--color-text-white: #ffffff;
|
||||
|
||||
--color-border: #e2e8f0;
|
||||
--color-border-light: #eef1f6;
|
||||
--color-divider: #eef1f6;
|
||||
|
||||
--shadow-xs: 0 1px 2px rgba(15, 23, 42, .04);
|
||||
--shadow-sm: 0 2px 8px rgba(15, 23, 42, .06);
|
||||
--shadow-md: 0 4px 16px rgba(15, 23, 42, .08);
|
||||
--shadow-lg: 0 8px 28px rgba(15, 23, 42, .10);
|
||||
--shadow-xl: 0 16px 48px rgba(15, 23, 42, .14);
|
||||
|
||||
--radius-xs: 4px;
|
||||
--radius-sm: 8px;
|
||||
--radius-md: 12px;
|
||||
--radius-lg: 16px;
|
||||
--radius-xl: 20px;
|
||||
--radius-2xl: 24px;
|
||||
--radius-pill: 999px;
|
||||
|
||||
--spacing-1: 4px;
|
||||
--spacing-2: 8px;
|
||||
--spacing-3: 12px;
|
||||
--spacing-4: 16px;
|
||||
--spacing-5: 20px;
|
||||
--spacing-6: 24px;
|
||||
--spacing-7: 32px;
|
||||
--spacing-8: 40px;
|
||||
--spacing-9: 48px;
|
||||
|
||||
--transition-fast: 0.15s cubic-bezier(.4,0,.2,1);
|
||||
--transition-base: 0.25s cubic-bezier(.4,0,.2,1);
|
||||
|
||||
--gradient-primary: linear-gradient(135deg, #1f7ae0 0%, #15b9a3 100%);
|
||||
--gradient-hero: linear-gradient(160deg, #1f7ae0 0%, #2b80f5 45%, #15b9a3 100%);
|
||||
--gradient-card: linear-gradient(180deg, #ffffff 0%, #fafbfd 100%);
|
||||
|
||||
--font-display: 'Plus Jakarta Sans', 'Noto Sans SC', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
--font-body: 'Noto Sans SC', -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
html, body { margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
color: var(--color-text-primary);
|
||||
background: var(--color-bg-page);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
button { font-family: inherit; cursor: pointer; }
|
||||
a { color: inherit; text-decoration: none; }
|
||||
code { font-family: 'SF Mono', Menlo, Consolas, monospace; font-size: 12px; background: var(--color-bg-hover); padding: 1px 6px; border-radius: 4px; color: var(--color-primary); }
|
||||
|
||||
.hidden { display: none !important; }
|
||||
|
||||
/* ============== 登录页 ============== */
|
||||
.login-page {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--gradient-hero);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.login-bg-decor { position: absolute; inset: 0; pointer-events: none; }
|
||||
.orb {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
filter: blur(60px);
|
||||
opacity: .55;
|
||||
animation: float 16s ease-in-out infinite;
|
||||
}
|
||||
.orb-1 { width: 360px; height: 360px; background: #4f9bff; top: -120px; left: -80px; }
|
||||
.orb-2 { width: 280px; height: 280px; background: #15b9a3; bottom: -100px; right: -60px; animation-delay: -4s; }
|
||||
.orb-3 { width: 200px; height: 200px; background: #7ad6ff; top: 40%; right: 20%; animation-delay: -8s; opacity: .35; }
|
||||
@keyframes float {
|
||||
0%, 100% { transform: translate(0, 0) scale(1); }
|
||||
33% { transform: translate(30px, -20px) scale(1.05); }
|
||||
66% { transform: translate(-20px, 30px) scale(.95); }
|
||||
}
|
||||
.login-card {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
margin: 24px;
|
||||
background: rgba(255, 255, 255, .96);
|
||||
backdrop-filter: blur(20px);
|
||||
border-radius: var(--radius-2xl);
|
||||
padding: 40px 36px;
|
||||
box-shadow: 0 30px 60px rgba(13, 95, 196, .25);
|
||||
animation: fadeInUp .5s var(--transition-base) both;
|
||||
}
|
||||
@keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
|
||||
.login-brand { text-align: center; margin-bottom: 28px; }
|
||||
.login-logo {
|
||||
width: 64px; height: 64px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--gradient-primary);
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
border-radius: 18px;
|
||||
box-shadow: 0 8px 24px rgba(31, 122, 224, .35);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.login-title { font-size: 22px; font-weight: 700; margin: 0 0 4px; color: var(--color-text-primary); }
|
||||
.login-subtitle { font-size: 13px; color: var(--color-text-tertiary); margin: 0; }
|
||||
.login-form { display: flex; flex-direction: column; gap: 18px; }
|
||||
.form-field { display: flex; flex-direction: column; gap: 6px; }
|
||||
.form-field label { font-size: 13px; color: var(--color-text-secondary); font-weight: 500; }
|
||||
.form-field input, .form-field select, .form-field textarea {
|
||||
width: 100%;
|
||||
padding: 12px 14px;
|
||||
border: 1.5px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
background: #fff;
|
||||
font-size: 14px;
|
||||
font-family: inherit;
|
||||
color: var(--color-text-primary);
|
||||
transition: all var(--transition-fast);
|
||||
outline: none;
|
||||
}
|
||||
.form-field input:focus, .form-field select:focus, .form-field textarea:focus {
|
||||
border-color: var(--color-primary);
|
||||
box-shadow: 0 0 0 3px rgba(31, 122, 224, .15);
|
||||
}
|
||||
.form-field textarea { min-height: 80px; resize: vertical; }
|
||||
.login-hint { text-align: center; font-size: 12px; color: var(--color-text-tertiary); margin: 0; }
|
||||
|
||||
/* ============== 按钮 ============== */
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
padding: 10px 18px;
|
||||
border: none;
|
||||
border-radius: var(--radius-md);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
background: var(--color-bg-hover);
|
||||
color: var(--color-text-primary);
|
||||
transition: all var(--transition-fast);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.btn:hover { background: var(--color-border-light); }
|
||||
.btn:active { transform: scale(.97); }
|
||||
.btn-primary {
|
||||
background: var(--gradient-primary);
|
||||
color: #fff;
|
||||
box-shadow: 0 4px 12px rgba(31, 122, 224, .25);
|
||||
}
|
||||
.btn-primary:hover { box-shadow: 0 6px 18px rgba(31, 122, 224, .35); }
|
||||
.btn-ghost { background: transparent; color: var(--color-text-secondary); }
|
||||
.btn-ghost:hover { background: var(--color-bg-hover); }
|
||||
.btn-danger { background: var(--color-error-bg); color: var(--color-error); }
|
||||
.btn-danger:hover { background: #f9d4d5; }
|
||||
.btn-success { background: var(--color-success-bg); color: var(--color-success); }
|
||||
.btn-warning { background: var(--color-warning-bg); color: var(--color-warning); }
|
||||
.btn-sm { padding: 6px 12px; font-size: 12px; }
|
||||
.btn-block { width: 100%; }
|
||||
.btn-icon { padding: 6px 8px; background: transparent; color: var(--color-text-tertiary); }
|
||||
.btn-icon:hover { background: var(--color-bg-hover); color: var(--color-text-primary); }
|
||||
|
||||
/* ============== 主控制台 ============== */
|
||||
.app-page {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--color-bg-page);
|
||||
}
|
||||
.app-header {
|
||||
height: 64px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 24px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
box-shadow: var(--shadow-xs);
|
||||
}
|
||||
.app-header-left { display: flex; align-items: center; gap: 12px; }
|
||||
.app-logo {
|
||||
width: 40px; height: 40px;
|
||||
background: var(--gradient-primary);
|
||||
color: #fff;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 22px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 12px rgba(31, 122, 224, .25);
|
||||
}
|
||||
.app-title { font-size: 15px; font-weight: 700; color: var(--color-text-primary); }
|
||||
.app-subtitle { font-size: 11px; color: var(--color-text-tertiary); margin-top: 2px; }
|
||||
.app-header-right { display: flex; align-items: center; gap: 16px; }
|
||||
.header-link { font-size: 13px; color: var(--color-text-secondary); }
|
||||
.header-link:hover { color: var(--color-primary); }
|
||||
.user-chip { display: flex; align-items: center; gap: 8px; padding: 4px 12px 4px 4px; background: var(--color-bg-hover); border-radius: 999px; }
|
||||
.user-avatar {
|
||||
width: 28px; height: 28px;
|
||||
background: var(--gradient-primary);
|
||||
color: #fff;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
border-radius: 999px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.user-name { font-size: 13px; font-weight: 500; }
|
||||
|
||||
.app-body { display: flex; flex: 1; min-height: 0; }
|
||||
.app-side {
|
||||
width: 220px;
|
||||
background: #fff;
|
||||
border-right: 1px solid var(--color-border);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.side-nav { padding: 16px 12px; flex: 1; display: flex; flex-direction: column; gap: 2px; }
|
||||
.side-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 12px;
|
||||
border-radius: var(--radius-md);
|
||||
font-size: 14px;
|
||||
color: var(--color-text-secondary);
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-fast);
|
||||
user-select: none;
|
||||
}
|
||||
.side-link:hover { background: var(--color-bg-hover); color: var(--color-text-primary); }
|
||||
.side-link.active {
|
||||
background: var(--color-primary-50);
|
||||
color: var(--color-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
.side-icon { font-size: 16px; width: 20px; text-align: center; }
|
||||
.side-foot { padding: 16px 20px; border-top: 1px solid var(--color-border-light); }
|
||||
.side-foot-line { font-size: 11px; color: var(--color-text-tertiary); }
|
||||
.side-foot-line.muted { color: var(--color-text-disabled); margin-top: 2px; }
|
||||
|
||||
.app-main {
|
||||
flex: 1;
|
||||
padding: 24px 32px;
|
||||
overflow-y: auto;
|
||||
min-width: 0;
|
||||
}
|
||||
.page-loading { text-align: center; color: var(--color-text-tertiary); padding: 60px 0; font-size: 14px; }
|
||||
|
||||
/* ============== 页面通用 ============== */
|
||||
.page { animation: fadeIn .35s var(--transition-base) both; }
|
||||
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
||||
|
||||
.subtab-bar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 8px;
|
||||
margin-bottom: 20px;
|
||||
background: #f1f5f9;
|
||||
padding: 4px;
|
||||
border-radius: 10px;
|
||||
width: fit-content;
|
||||
}
|
||||
.subtab-bar .subtab {
|
||||
padding: 8px 18px;
|
||||
font-size: 14px;
|
||||
color: var(--color-text-secondary);
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
transition: all .2s;
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
.subtab-bar .subtab.active {
|
||||
background: #fff;
|
||||
color: var(--color-primary);
|
||||
font-weight: 600;
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
.subtab-bar .subtab:hover:not(.active) { color: var(--color-text-primary); }
|
||||
|
||||
.page-head {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
}
|
||||
.page-title { font-size: 22px; font-weight: 700; margin: 0 0 4px; }
|
||||
.page-desc { font-size: 13px; color: var(--color-text-tertiary); margin: 0; }
|
||||
.page-actions { display: flex; gap: 8px; flex-wrap: wrap; }
|
||||
|
||||
/* ============== 卡片 ============== */
|
||||
.card {
|
||||
background: #fff;
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 20px 24px;
|
||||
box-shadow: var(--shadow-sm);
|
||||
border: 1px solid var(--color-border-light);
|
||||
}
|
||||
.card + .card { margin-top: 16px; }
|
||||
.card-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.card-title { font-size: 16px; font-weight: 600; margin: 0; }
|
||||
.card-subtitle { font-size: 12px; color: var(--color-text-tertiary); margin: 2px 0 0; }
|
||||
|
||||
/* ============== 统计卡 ============== */
|
||||
.stats {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 16px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.stat-card {
|
||||
background: #fff;
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 20px;
|
||||
box-shadow: var(--shadow-sm);
|
||||
border: 1px solid var(--color-border-light);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.stat-card::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0; right: 0;
|
||||
width: 80px; height: 80px;
|
||||
background: var(--color-primary-50);
|
||||
border-radius: 50%;
|
||||
transform: translate(30px, -30px);
|
||||
opacity: .5;
|
||||
}
|
||||
.stat-label { font-size: 13px; color: var(--color-text-tertiary); margin-bottom: 6px; }
|
||||
.stat-value { font-size: 28px; font-weight: 700; color: var(--color-text-primary); font-family: var(--font-display); }
|
||||
.stat-foot { font-size: 12px; color: var(--color-text-tertiary); margin-top: 6px; }
|
||||
|
||||
/* ============== 工具栏 ============== */
|
||||
.toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.toolbar .form-field { flex-direction: row; align-items: center; gap: 8px; }
|
||||
.toolbar input, .toolbar select {
|
||||
padding: 8px 12px;
|
||||
border: 1.5px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
font-size: 13px;
|
||||
outline: none;
|
||||
transition: all var(--transition-fast);
|
||||
background: #fff;
|
||||
}
|
||||
.toolbar input:focus, .toolbar select:focus { border-color: var(--color-primary); }
|
||||
.toolbar input { min-width: 220px; }
|
||||
|
||||
/* ============== 表格 ============== */
|
||||
.table-wrap {
|
||||
background: #fff;
|
||||
border-radius: var(--radius-lg);
|
||||
border: 1px solid var(--color-border-light);
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
table.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 13px;
|
||||
}
|
||||
.data-table thead th {
|
||||
text-align: left;
|
||||
padding: 12px 16px;
|
||||
background: var(--color-bg-page);
|
||||
color: var(--color-text-secondary);
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.data-table tbody td {
|
||||
padding: 14px 16px;
|
||||
border-bottom: 1px solid var(--color-border-light);
|
||||
vertical-align: middle;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
.data-table tbody tr:last-child td { border-bottom: none; }
|
||||
.data-table tbody tr:hover { background: var(--color-bg-page); }
|
||||
.data-table .avatar-cell { display: flex; align-items: center; gap: 10px; }
|
||||
.data-table .avatar {
|
||||
width: 40px; height: 40px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-bg-hover);
|
||||
object-fit: cover;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.data-table .name-cell { font-weight: 600; }
|
||||
.data-table .sub { font-size: 12px; color: var(--color-text-tertiary); margin-top: 2px; }
|
||||
.data-table .actions { display: flex; gap: 6px; justify-content: flex-end; }
|
||||
.empty-state { text-align: center; padding: 60px 20px; color: var(--color-text-tertiary); }
|
||||
|
||||
/* ============== 状态标签 ============== */
|
||||
.tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 2px 10px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
border-radius: 999px;
|
||||
background: var(--color-bg-hover);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
.tag-primary { background: var(--color-primary-50); color: var(--color-primary); }
|
||||
.tag-success { background: var(--color-success-bg); color: var(--color-success); }
|
||||
.tag-warning { background: var(--color-warning-bg); color: var(--color-warning); }
|
||||
.tag-error { background: var(--color-error-bg); color: var(--color-error); }
|
||||
|
||||
/* ============== Toast ============== */
|
||||
.toast {
|
||||
position: fixed;
|
||||
top: 24px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-100%);
|
||||
background: var(--color-text-primary);
|
||||
color: #fff;
|
||||
padding: 10px 18px;
|
||||
border-radius: var(--radius-md);
|
||||
font-size: 13px;
|
||||
z-index: 9999;
|
||||
transition: transform var(--transition-base), opacity var(--transition-base);
|
||||
opacity: 0;
|
||||
box-shadow: var(--shadow-lg);
|
||||
max-width: 80vw;
|
||||
}
|
||||
.toast.show { transform: translateX(-50%) translateY(0); opacity: 1; }
|
||||
.toast.success { background: var(--color-success); }
|
||||
.toast.error { background: var(--color-error); }
|
||||
|
||||
/* ============== Modal ============== */
|
||||
.modal {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.modal-mask {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(15, 23, 42, .55);
|
||||
backdrop-filter: blur(4px);
|
||||
animation: fadeIn .2s both;
|
||||
}
|
||||
.modal-card {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
border-radius: var(--radius-xl);
|
||||
width: 90%;
|
||||
max-width: 560px;
|
||||
max-height: 90vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: var(--shadow-xl);
|
||||
animation: modalIn .3s var(--transition-base) both;
|
||||
}
|
||||
@keyframes modalIn { from { opacity: 0; transform: scale(.92) translateY(20px); } to { opacity: 1; transform: scale(1) translateY(0); } }
|
||||
.modal-card.modal-lg { max-width: 760px; }
|
||||
.modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20px 24px;
|
||||
border-bottom: 1px solid var(--color-border-light);
|
||||
}
|
||||
.modal-header h3 { font-size: 16px; font-weight: 600; margin: 0; }
|
||||
.modal-close {
|
||||
background: transparent;
|
||||
border: none;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
color: var(--color-text-tertiary);
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
width: 28px; height: 28px;
|
||||
border-radius: var(--radius-sm);
|
||||
transition: all var(--transition-fast);
|
||||
}
|
||||
.modal-close:hover { background: var(--color-bg-hover); color: var(--color-text-primary); }
|
||||
.modal-body { padding: 20px 24px; overflow-y: auto; flex: 1; }
|
||||
.modal-body .form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
|
||||
.modal-body .form-grid .full { grid-column: 1 / -1; }
|
||||
.modal-footer {
|
||||
padding: 16px 24px;
|
||||
border-top: 1px solid var(--color-border-light);
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* ============== 开关 ============== */
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 36px; height: 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.switch input { display: none; }
|
||||
.switch .slider {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: var(--color-border);
|
||||
border-radius: 999px;
|
||||
transition: background var(--transition-fast);
|
||||
cursor: pointer;
|
||||
}
|
||||
.switch .slider::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 2px; left: 2px;
|
||||
width: 16px; height: 16px;
|
||||
background: #fff;
|
||||
border-radius: 50%;
|
||||
transition: transform var(--transition-fast);
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,.2);
|
||||
}
|
||||
.switch input:checked + .slider { background: var(--color-primary); }
|
||||
.switch input:checked + .slider::before { transform: translateX(16px); }
|
||||
|
||||
/* ============== 响应式 ============== */
|
||||
@media (max-width: 900px) {
|
||||
.app-side { width: 64px; }
|
||||
.side-link span:not(.side-icon) { display: none; }
|
||||
.side-link { justify-content: center; padding: 12px; }
|
||||
.side-foot { display: none; }
|
||||
.app-main { padding: 16px; }
|
||||
.modal-body .form-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
/* ============== Leads 问卷答案(Phase 3) ============== */
|
||||
.lead-q {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px dashed var(--color-border-light);
|
||||
font-size: 13px;
|
||||
}
|
||||
.lead-q:last-child { border-bottom: none; }
|
||||
.lead-qi {
|
||||
flex-shrink: 0;
|
||||
color: var(--color-text-tertiary);
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
}
|
||||
.lead-qtext {
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 13px;
|
||||
}
|
||||
.lead-qv {
|
||||
color: var(--color-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.text-ellipsis-2 {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
}
|
||||
Reference in New Issue
Block a user