1281 lines
39 KiB
HTML
1281 lines
39 KiB
HTML
<!doctype html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>缴退费财务确认 · 布局方案 Demo</title>
|
|
<style>
|
|
*,
|
|
*::before,
|
|
*::after {
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
:root {
|
|
--primary: #10b981;
|
|
--primary-dark: #059669;
|
|
--primary-bg: #ecfdf5;
|
|
--mint-border: #c5e0d4;
|
|
--text: #1e293b;
|
|
--muted: #64748b;
|
|
--surface: #fff;
|
|
--page-bg: #f0f2f5;
|
|
--border: #e2e8f0;
|
|
--warning: #d97706;
|
|
--warning-bg: #fffbeb;
|
|
}
|
|
|
|
body {
|
|
font-family:
|
|
Inter,
|
|
-apple-system,
|
|
BlinkMacSystemFont,
|
|
'PingFang SC',
|
|
'Hiragino Sans GB',
|
|
'Microsoft YaHei',
|
|
sans-serif;
|
|
font-size: 14px;
|
|
line-height: 1.5;
|
|
color: var(--text);
|
|
background: var(--page-bg);
|
|
padding: 32px 24px 64px;
|
|
}
|
|
|
|
.page-head {
|
|
max-width: 1200px;
|
|
margin: 0 auto 28px;
|
|
}
|
|
|
|
.page-head h1 {
|
|
font-size: 20px;
|
|
font-weight: 600;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.page-head p {
|
|
color: var(--muted);
|
|
max-width: 860px;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.scheme-nav {
|
|
max-width: 1200px;
|
|
margin: 0 auto 20px;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
}
|
|
|
|
.scheme-nav a {
|
|
padding: 6px 14px;
|
|
border-radius: 999px;
|
|
border: 1px solid var(--border);
|
|
background: var(--surface);
|
|
color: var(--muted);
|
|
font-size: 12px;
|
|
text-decoration: none;
|
|
transition: all 0.15s;
|
|
}
|
|
|
|
.scheme-nav a:hover {
|
|
border-color: var(--mint-border);
|
|
color: var(--primary-dark);
|
|
}
|
|
|
|
.demo-block {
|
|
max-width: 1200px;
|
|
margin: 0 auto 32px;
|
|
background: var(--surface);
|
|
border: 1px solid var(--border);
|
|
border-radius: 10px;
|
|
overflow: hidden;
|
|
box-shadow: 0 1px 3px rgb(15 23 42 / 6%);
|
|
}
|
|
|
|
.demo-label {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: 16px;
|
|
padding: 14px 20px;
|
|
border-bottom: 1px solid var(--border);
|
|
background: #fafbfc;
|
|
}
|
|
|
|
.demo-label strong {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
display: block;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.demo-label .tag-rec {
|
|
flex-shrink: 0;
|
|
padding: 3px 10px;
|
|
border-radius: 999px;
|
|
background: var(--primary-bg);
|
|
color: var(--primary-dark);
|
|
font-size: 11px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.demo-label span {
|
|
font-size: 12px;
|
|
color: var(--muted);
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.panel-shell {
|
|
min-height: 480px;
|
|
}
|
|
|
|
/* ── 共用:面板标题 ── */
|
|
.panel-top {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 16px 24px;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.title-bar-heading {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.title-bar-heading::before {
|
|
content: '';
|
|
width: 4px;
|
|
height: 14px;
|
|
border-radius: 999px;
|
|
background: var(--primary-dark);
|
|
}
|
|
|
|
/* ── 共用:胶囊 Tab(缴费/退费) ── */
|
|
.type-capsule {
|
|
display: inline-flex;
|
|
gap: 4px;
|
|
padding: 4px;
|
|
background: #f1f5f9;
|
|
border: 1px solid var(--border);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.type-capsule__btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 8px 18px;
|
|
border: none;
|
|
border-radius: 6px;
|
|
background: transparent;
|
|
font-size: 13px;
|
|
font-weight: 500;
|
|
color: var(--muted);
|
|
cursor: pointer;
|
|
white-space: nowrap;
|
|
transition: all 0.15s;
|
|
}
|
|
|
|
.type-capsule__btn:hover:not(.is-active) {
|
|
color: var(--text);
|
|
background: rgb(255 255 255 / 60%);
|
|
}
|
|
|
|
.type-capsule__btn.is-active {
|
|
background: #fff;
|
|
color: var(--primary-dark);
|
|
box-shadow: 0 1px 3px rgb(15 23 42 / 8%);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.type-capsule__badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-width: 18px;
|
|
height: 18px;
|
|
padding: 0 5px;
|
|
border-radius: 999px;
|
|
background: var(--warning-bg);
|
|
color: var(--warning);
|
|
font-size: 11px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.type-capsule__btn.is-active .type-capsule__badge {
|
|
background: var(--primary-bg);
|
|
color: var(--primary-dark);
|
|
}
|
|
|
|
/* ── 共用:筛选区 ── */
|
|
.filter-block {
|
|
padding: 16px 24px;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.filter-grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr 280px;
|
|
gap: 12px 16px;
|
|
}
|
|
|
|
.filter-field label {
|
|
display: block;
|
|
font-size: 11px;
|
|
font-weight: 500;
|
|
color: var(--muted);
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.filter-field input,
|
|
.filter-field .fake-date {
|
|
width: 100%;
|
|
height: 36px;
|
|
padding: 0 12px;
|
|
border: 1px solid var(--border);
|
|
border-radius: 8px;
|
|
font-size: 14px;
|
|
color: var(--text);
|
|
background: #fff;
|
|
}
|
|
|
|
.filter-actions-row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
margin-top: 12px;
|
|
}
|
|
|
|
.filter-hint {
|
|
font-size: 12px;
|
|
color: var(--muted);
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.filter-actions-end {
|
|
display: flex;
|
|
gap: 8px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
height: 36px;
|
|
padding: 0 16px;
|
|
border-radius: 8px;
|
|
font-size: 14px;
|
|
cursor: pointer;
|
|
border: 1px solid var(--border);
|
|
background: #fff;
|
|
color: var(--text);
|
|
}
|
|
|
|
.btn-main {
|
|
border-color: var(--primary);
|
|
background: var(--primary);
|
|
color: #fff;
|
|
}
|
|
|
|
/* ── 共用:Tag ── */
|
|
.tag {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.tag.warning {
|
|
background: var(--warning-bg);
|
|
color: var(--warning);
|
|
}
|
|
|
|
.tag.success {
|
|
background: var(--primary-bg);
|
|
color: var(--primary-dark);
|
|
}
|
|
|
|
.tag.info {
|
|
background: #f1f5f9;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.tag.muted {
|
|
background: #f8fafc;
|
|
color: var(--muted);
|
|
}
|
|
|
|
/* ── 共用:确认卡片 ── */
|
|
.confirm-card {
|
|
border: 1px solid var(--border);
|
|
border-radius: 10px;
|
|
background: #fff;
|
|
padding: 16px 18px;
|
|
transition: box-shadow 0.15s, border-color 0.15s;
|
|
}
|
|
|
|
.confirm-card:hover {
|
|
border-color: var(--mint-border);
|
|
box-shadow: 0 2px 8px rgb(15 23 42 / 5%);
|
|
}
|
|
|
|
.confirm-card.is-pending {
|
|
border-left: 3px solid var(--warning);
|
|
}
|
|
|
|
.confirm-card.is-confirmed {
|
|
border-left: 3px solid var(--primary);
|
|
opacity: 0.92;
|
|
}
|
|
|
|
.confirm-card__head {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.confirm-card__name {
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
margin-bottom: 2px;
|
|
}
|
|
|
|
.confirm-card__sub {
|
|
font-size: 12px;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.confirm-card__amount {
|
|
text-align: right;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.confirm-card__amount-val {
|
|
font-size: 18px;
|
|
font-weight: 700;
|
|
color: var(--primary-dark);
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.confirm-card__amount-label {
|
|
font-size: 11px;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.confirm-card__grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 8px 16px;
|
|
margin-bottom: 14px;
|
|
}
|
|
|
|
.confirm-card__field label {
|
|
display: block;
|
|
font-size: 11px;
|
|
color: var(--muted);
|
|
margin-bottom: 2px;
|
|
}
|
|
|
|
.confirm-card__field span {
|
|
font-size: 13px;
|
|
color: var(--text);
|
|
}
|
|
|
|
.confirm-card__foot {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
padding-top: 12px;
|
|
border-top: 1px solid #f1f5f9;
|
|
}
|
|
|
|
.confirm-card__meta {
|
|
font-size: 12px;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.btn-op {
|
|
height: 32px;
|
|
padding: 0 14px;
|
|
border-radius: 8px;
|
|
font-size: 13px;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
border: 1px solid var(--primary);
|
|
background: var(--primary);
|
|
color: #fff;
|
|
}
|
|
|
|
.btn-op.ghost {
|
|
border-color: var(--border);
|
|
background: #fff;
|
|
color: var(--text);
|
|
}
|
|
|
|
/* ── 分区标题 ── */
|
|
.section-head {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 16px 24px 12px;
|
|
}
|
|
|
|
.section-head h3 {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.section-head h3::before {
|
|
content: '';
|
|
width: 4px;
|
|
height: 12px;
|
|
border-radius: 999px;
|
|
background: var(--primary-dark);
|
|
}
|
|
|
|
.section-head.is-pending h3::before {
|
|
background: var(--warning);
|
|
}
|
|
|
|
.section-count {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-width: 22px;
|
|
height: 22px;
|
|
padding: 0 6px;
|
|
border-radius: 999px;
|
|
background: #f1f5f9;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.section-head.is-pending .section-count {
|
|
background: var(--warning-bg);
|
|
color: var(--warning);
|
|
}
|
|
|
|
.section-toggle {
|
|
font-size: 12px;
|
|
color: var(--primary-dark);
|
|
background: none;
|
|
border: none;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.card-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
|
|
gap: 12px;
|
|
padding: 0 24px 20px;
|
|
}
|
|
|
|
.section-divider {
|
|
height: 8px;
|
|
background: #f8fafc;
|
|
border-top: 1px solid var(--border);
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
/* ============================================================
|
|
方案 A:胶囊 + 上下分区卡片(用户提议)
|
|
============================================================ */
|
|
.scheme-a .panel-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 16px;
|
|
padding: 16px 24px;
|
|
border-bottom: 1px solid var(--border);
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.scheme-a .panel-header__left {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 20px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
/* ============================================================
|
|
方案 B:双栏看板(左待确认 / 右已确认)
|
|
============================================================ */
|
|
.scheme-b .panel-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 16px 24px;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.kanban {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 0;
|
|
min-height: 420px;
|
|
}
|
|
|
|
.kanban-col {
|
|
padding: 16px 20px 24px;
|
|
min-width: 0;
|
|
}
|
|
|
|
.kanban-col:first-child {
|
|
border-right: 1px solid var(--border);
|
|
background: linear-gradient(180deg, #fffbeb 0%, #fff 120px);
|
|
}
|
|
|
|
.kanban-col:last-child {
|
|
background: linear-gradient(180deg, #ecfdf5 0%, #fff 120px);
|
|
}
|
|
|
|
.kanban-col__head {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: 14px;
|
|
}
|
|
|
|
.kanban-col__head h3 {
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.kanban-stack {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.kanban-stack .confirm-card {
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.kanban-more {
|
|
margin-top: 10px;
|
|
text-align: center;
|
|
font-size: 12px;
|
|
color: var(--muted);
|
|
padding: 8px;
|
|
border: 1px dashed var(--border);
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* ============================================================
|
|
方案 C:统计摘要 + 状态 Chip 筛选 + 卡片流
|
|
============================================================ */
|
|
.scheme-c .panel-header {
|
|
padding: 16px 24px;
|
|
border-bottom: 1px solid var(--border);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
flex-wrap: wrap;
|
|
gap: 12px;
|
|
}
|
|
|
|
.stat-row {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
gap: 12px;
|
|
padding: 16px 24px;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.stat-card {
|
|
padding: 14px 16px;
|
|
border: 1px solid var(--border);
|
|
border-radius: 10px;
|
|
background: #fafbfc;
|
|
}
|
|
|
|
.stat-card__label {
|
|
font-size: 12px;
|
|
color: var(--muted);
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.stat-card__val {
|
|
font-size: 22px;
|
|
font-weight: 700;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.stat-card__val.warning {
|
|
color: var(--warning);
|
|
}
|
|
|
|
.stat-card__val.primary {
|
|
color: var(--primary-dark);
|
|
}
|
|
|
|
.chip-filter {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 12px 24px;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.chip {
|
|
padding: 6px 14px;
|
|
border-radius: 999px;
|
|
border: 1px solid var(--border);
|
|
background: #fff;
|
|
font-size: 13px;
|
|
color: var(--muted);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.chip.is-active {
|
|
border-color: var(--primary);
|
|
background: var(--primary-bg);
|
|
color: var(--primary-dark);
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* ============================================================
|
|
方案 D:折叠分区(待确认默认展开,已确认折叠)
|
|
============================================================ */
|
|
.accordion-section {
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.accordion-section:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.accordion-trigger {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
width: 100%;
|
|
padding: 14px 24px;
|
|
border: none;
|
|
background: #fafbfc;
|
|
cursor: pointer;
|
|
text-align: left;
|
|
}
|
|
|
|
.accordion-trigger h3 {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.accordion-trigger .chevron {
|
|
font-size: 12px;
|
|
color: var(--muted);
|
|
transition: transform 0.2s;
|
|
}
|
|
|
|
.accordion-section.is-open .accordion-trigger .chevron {
|
|
transform: rotate(180deg);
|
|
}
|
|
|
|
.accordion-body {
|
|
display: none;
|
|
padding-bottom: 4px;
|
|
}
|
|
|
|
.accordion-section.is-open .accordion-body {
|
|
display: block;
|
|
}
|
|
|
|
.scheme-d .panel-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 16px 24px;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
/* ============================================================
|
|
方案 E:混合 — 待确认卡片 + 已确认紧凑表格
|
|
============================================================ */
|
|
.scheme-e .panel-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 16px 24px;
|
|
border-bottom: 1px solid var(--border);
|
|
flex-wrap: wrap;
|
|
gap: 12px;
|
|
}
|
|
|
|
.compact-table-wrap {
|
|
padding: 0 24px 20px;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.compact-table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.compact-table th,
|
|
.compact-table td {
|
|
padding: 10px 12px;
|
|
text-align: center;
|
|
border-bottom: 1px solid #f1f5f9;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.compact-table th {
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
color: var(--muted);
|
|
background: #fafbfc;
|
|
}
|
|
|
|
.compact-table tbody tr:hover {
|
|
background: #f8fafc;
|
|
}
|
|
|
|
.empty-hint {
|
|
padding: 32px 24px;
|
|
text-align: center;
|
|
color: var(--muted);
|
|
font-size: 13px;
|
|
}
|
|
|
|
@media (max-width: 900px) {
|
|
.filter-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.kanban {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.kanban-col:first-child {
|
|
border-right: none;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.stat-row {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
}
|
|
|
|
.confirm-card__grid {
|
|
grid-template-columns: 1fr 1fr;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="page-head">
|
|
<h1>缴退费财务确认 · 布局方案 Demo</h1>
|
|
<p>
|
|
当前页面存在<strong>两层 Tab</strong>(缴费/退费 大卡片切换 + 待确认/已确认 胶囊 Tab),顶部视觉层级过多。
|
|
以下 5 种方案均尝试<strong>合并或消除第二层 Tab</strong>,并将列表改为卡片或混合展示。
|
|
色值与胶囊样式对齐 Fresh Mint 规范(<code>--primary #10b981</code>)。
|
|
</p>
|
|
</div>
|
|
|
|
<nav class="scheme-nav">
|
|
<a href="#scheme-a">A · 上下分区卡片</a>
|
|
<a href="#scheme-b">B · 双栏看板</a>
|
|
<a href="#scheme-c">C · 统计 + Chip 筛选</a>
|
|
<a href="#scheme-d">D · 折叠分区</a>
|
|
<a href="#scheme-e">E · 混合(卡片+表格)</a>
|
|
</nav>
|
|
|
|
<!-- ═══════════════════════════════════════════════════════════
|
|
方案 A:用户提议 — 胶囊 + 上待确认 / 下已确认
|
|
═══════════════════════════════════════════════════════════ -->
|
|
<section class="demo-block scheme-a" id="scheme-a">
|
|
<div class="demo-label">
|
|
<div>
|
|
<strong>方案 A · 胶囊切换 + 上下分区卡片</strong>
|
|
<span>缴费/退费改为居中胶囊;取消「待确认/已确认」Tab,改为同屏上下两个区域。待确认优先展示、视觉强调;已确认区域可折叠。适合财务「先处理队列、再查历史」的工作流。</span>
|
|
</div>
|
|
<span class="tag-rec">推荐</span>
|
|
</div>
|
|
<div class="panel-shell">
|
|
<div class="panel-header">
|
|
<div class="panel-header__left">
|
|
<h2 class="title-bar-heading">缴退费财务确认</h2>
|
|
<div class="type-capsule" role="tablist">
|
|
<button type="button" class="type-capsule__btn is-active" role="tab">
|
|
缴费确认
|
|
<span class="type-capsule__badge">3</span>
|
|
</button>
|
|
<button type="button" class="type-capsule__btn" role="tab">
|
|
退费确认
|
|
<span class="type-capsule__badge">1</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="filter-block">
|
|
<div class="filter-grid">
|
|
<div class="filter-field">
|
|
<label>关键词</label>
|
|
<input type="text" placeholder="客户姓名/身份证号/新生儿姓名/新生儿身份证号" />
|
|
</div>
|
|
<div class="filter-field">
|
|
<label>应缴费时间</label>
|
|
<div class="fake-date">2026-05-30 至 2026-06-29</div>
|
|
</div>
|
|
</div>
|
|
<div class="filter-actions-row">
|
|
<span class="filter-hint">默认展示应缴费时间前后 15 天内的明细</span>
|
|
<div class="filter-actions-end">
|
|
<button type="button" class="btn">重置</button>
|
|
<button type="button" class="btn btn-main">搜索</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="section-head is-pending">
|
|
<h3>待确认 <span class="section-count">3</span></h3>
|
|
</div>
|
|
<div class="card-grid" id="cards-pending-a"></div>
|
|
|
|
<div class="section-divider"></div>
|
|
|
|
<div class="section-head">
|
|
<h3>已确认 <span class="section-count">12</span></h3>
|
|
<button type="button" class="section-toggle">收起 ▲</button>
|
|
</div>
|
|
<div class="card-grid" id="cards-confirmed-a"></div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ═══════════════════════════════════════════════════════════
|
|
方案 B:双栏看板
|
|
═══════════════════════════════════════════════════════════ -->
|
|
<section class="demo-block scheme-b" id="scheme-b">
|
|
<div class="demo-label">
|
|
<div>
|
|
<strong>方案 B · 双栏看板(左待确认 / 右已确认)</strong>
|
|
<span>一屏对比两个队列,适合宽屏。左侧琥珀色调强调待办,右侧绿色调表示已完成。每列独立滚动,底部「加载更多」。</span>
|
|
</div>
|
|
</div>
|
|
<div class="panel-shell">
|
|
<div class="panel-header">
|
|
<div class="type-capsule">
|
|
<button type="button" class="type-capsule__btn is-active">缴费确认 <span class="type-capsule__badge">3</span></button>
|
|
<button type="button" class="type-capsule__btn">退费确认 <span class="type-capsule__badge">1</span></button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="filter-block" style="padding: 12px 24px">
|
|
<div class="filter-grid" style="grid-template-columns: 1fr 240px auto; align-items: end">
|
|
<div class="filter-field">
|
|
<label>关键词</label>
|
|
<input type="text" placeholder="客户姓名/身份证号…" />
|
|
</div>
|
|
<div class="filter-field">
|
|
<label>应缴费时间</label>
|
|
<div class="fake-date">2026-05-30 至 2026-06-29</div>
|
|
</div>
|
|
<div class="filter-actions-end" style="margin-top: 0">
|
|
<button type="button" class="btn btn-main">搜索</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="kanban">
|
|
<div class="kanban-col">
|
|
<div class="kanban-col__head">
|
|
<h3><span class="tag warning">待确认</span> 3 条</h3>
|
|
</div>
|
|
<div class="kanban-stack" id="cards-pending-b"></div>
|
|
<div class="kanban-more">加载更多待确认…</div>
|
|
</div>
|
|
<div class="kanban-col">
|
|
<div class="kanban-col__head">
|
|
<h3><span class="tag success">已确认</span> 12 条</h3>
|
|
</div>
|
|
<div class="kanban-stack" id="cards-confirmed-b"></div>
|
|
<div class="kanban-more">加载更多已确认…</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ═══════════════════════════════════════════════════════════
|
|
方案 C:统计摘要 + Chip 筛选
|
|
═══════════════════════════════════════════════════════════ -->
|
|
<section class="demo-block scheme-c" id="scheme-c">
|
|
<div class="demo-label">
|
|
<div>
|
|
<strong>方案 C · 统计摘要 + 状态 Chip 筛选 + 卡片流</strong>
|
|
<span>顶部 4 个统计卡提供概览;第二层 Tab 改为轻量 Chip(全部/待确认/已确认),减少视觉重量。单区域卡片网格,切换 Chip 时过滤。</span>
|
|
</div>
|
|
</div>
|
|
<div class="panel-shell">
|
|
<div class="panel-header">
|
|
<h2 class="title-bar-heading">缴退费财务确认</h2>
|
|
<div class="type-capsule">
|
|
<button type="button" class="type-capsule__btn is-active">缴费确认</button>
|
|
<button type="button" class="type-capsule__btn">退费确认</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="stat-row">
|
|
<div class="stat-card">
|
|
<div class="stat-card__label">待确认</div>
|
|
<div class="stat-card__val warning">3</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-card__label">今日已确认</div>
|
|
<div class="stat-card__val primary">5</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-card__label">待确认金额</div>
|
|
<div class="stat-card__val warning">¥28,600</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-card__label">本月已确认</div>
|
|
<div class="stat-card__val primary">¥186,400</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="chip-filter" role="tablist">
|
|
<button type="button" class="chip is-active" data-filter="all">全部 15</button>
|
|
<button type="button" class="chip" data-filter="pending">待确认 3</button>
|
|
<button type="button" class="chip" data-filter="confirmed">已确认 12</button>
|
|
</div>
|
|
|
|
<div class="filter-block" style="padding-top: 12px">
|
|
<div class="filter-grid">
|
|
<div class="filter-field">
|
|
<label>关键词</label>
|
|
<input type="text" placeholder="客户姓名/身份证号…" />
|
|
</div>
|
|
<div class="filter-field">
|
|
<label>应缴费时间</label>
|
|
<div class="fake-date">2026-05-30 至 2026-06-29</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card-grid" id="cards-c" style="padding-top: 8px"></div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ═══════════════════════════════════════════════════════════
|
|
方案 D:折叠分区
|
|
═══════════════════════════════════════════════════════════ -->
|
|
<section class="demo-block scheme-d" id="scheme-d">
|
|
<div class="demo-label">
|
|
<div>
|
|
<strong>方案 D · 折叠手风琴分区</strong>
|
|
<span>待确认默认展开(财务主任务),已确认默认折叠节省纵向空间。比方案 A 更紧凑,适合待确认量不大、已确认历史很多的场景。</span>
|
|
</div>
|
|
</div>
|
|
<div class="panel-shell">
|
|
<div class="panel-header">
|
|
<div class="type-capsule">
|
|
<button type="button" class="type-capsule__btn is-active">缴费确认</button>
|
|
<button type="button" class="type-capsule__btn">退费确认</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="filter-block">
|
|
<div class="filter-grid">
|
|
<div class="filter-field">
|
|
<label>关键词</label>
|
|
<input type="text" placeholder="客户姓名/身份证号…" />
|
|
</div>
|
|
<div class="filter-field">
|
|
<label>应缴费时间</label>
|
|
<div class="fake-date">2026-05-30 至 2026-06-29</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="accordion-section is-open" data-accordion>
|
|
<button type="button" class="accordion-trigger">
|
|
<h3><span class="tag warning">待确认</span> <span class="section-count">3</span></h3>
|
|
<span class="chevron">▼</span>
|
|
</button>
|
|
<div class="accordion-body">
|
|
<div class="card-grid" id="cards-pending-d"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="accordion-section" data-accordion>
|
|
<button type="button" class="accordion-trigger">
|
|
<h3><span class="tag success">已确认</span> <span class="section-count">12</span></h3>
|
|
<span class="chevron">▼</span>
|
|
</button>
|
|
<div class="accordion-body">
|
|
<div class="card-grid" id="cards-confirmed-d"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ═══════════════════════════════════════════════════════════
|
|
方案 E:混合 — 待确认卡片 + 已确认表格
|
|
═══════════════════════════════════════════════════════════ -->
|
|
<section class="demo-block scheme-e" id="scheme-e">
|
|
<div class="demo-label">
|
|
<div>
|
|
<strong>方案 E · 混合布局(待确认卡片 + 已确认紧凑表格)</strong>
|
|
<span>待办用卡片突出操作;已确认历史量大、字段多,保留表格 + 分页更高效。折中方案,改动风险最低。</span>
|
|
</div>
|
|
</div>
|
|
<div class="panel-shell">
|
|
<div class="panel-header">
|
|
<h2 class="title-bar-heading">缴退费财务确认</h2>
|
|
<div class="type-capsule">
|
|
<button type="button" class="type-capsule__btn is-active">缴费确认</button>
|
|
<button type="button" class="type-capsule__btn">退费确认</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="filter-block">
|
|
<div class="filter-grid">
|
|
<div class="filter-field">
|
|
<label>关键词</label>
|
|
<input type="text" placeholder="客户姓名/身份证号…" />
|
|
</div>
|
|
<div class="filter-field">
|
|
<label>应缴费时间</label>
|
|
<div class="fake-date">2026-05-30 至 2026-06-29</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="section-head is-pending">
|
|
<h3>待确认 <span class="section-count">3</span></h3>
|
|
</div>
|
|
<div class="card-grid" id="cards-pending-e"></div>
|
|
|
|
<div class="section-divider"></div>
|
|
|
|
<div class="section-head">
|
|
<h3>已确认 <span class="section-count">12</span></h3>
|
|
</div>
|
|
<div class="compact-table-wrap">
|
|
<table class="compact-table">
|
|
<thead>
|
|
<tr>
|
|
<th>客户姓名</th>
|
|
<th>期数</th>
|
|
<th>应缴金额</th>
|
|
<th>实缴金额</th>
|
|
<th>转账时间</th>
|
|
<th>确认时间</th>
|
|
<th>状态</th>
|
|
<th>操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="table-confirmed-e"></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<script>
|
|
const MOCK_PENDING = [
|
|
{
|
|
motherName: '张丽华',
|
|
motherIdCard: '340***********1234',
|
|
newbornName: '张小宝',
|
|
installmentNo: 2,
|
|
installmentDueDate: '2026-06-18',
|
|
dueAmount: '¥12,800.00',
|
|
transferAmount: '¥12,800.00',
|
|
payMode: '分期',
|
|
transferType: '银行转账',
|
|
transferTime: '2026-06-14 10:32',
|
|
protocolStatus: '进行中',
|
|
createTime: '2026-06-14 09:15'
|
|
},
|
|
{
|
|
motherName: '王美玲',
|
|
motherIdCard: '340***********5678',
|
|
newbornName: '王乐乐',
|
|
installmentNo: 1,
|
|
installmentDueDate: '2026-06-20',
|
|
dueAmount: '¥8,600.00',
|
|
transferAmount: '¥8,600.00',
|
|
payMode: '一次性',
|
|
transferType: '微信',
|
|
transferTime: '2026-06-13 16:48',
|
|
protocolStatus: '进行中',
|
|
createTime: '2026-06-13 17:02'
|
|
},
|
|
{
|
|
motherName: '陈晓燕',
|
|
motherIdCard: '340***********9012',
|
|
newbornName: '—',
|
|
installmentNo: 3,
|
|
installmentDueDate: '2026-06-22',
|
|
dueAmount: '¥7,200.00',
|
|
transferAmount: '¥7,200.00',
|
|
payMode: '分期',
|
|
transferType: '支付宝',
|
|
transferTime: '2026-06-12 11:20',
|
|
protocolStatus: '进行中',
|
|
createTime: '2026-06-12 11:25'
|
|
}
|
|
]
|
|
|
|
const MOCK_CONFIRMED = [
|
|
{
|
|
motherName: '李婷婷',
|
|
installmentNo: 1,
|
|
dueAmount: '¥15,000.00',
|
|
transferAmount: '¥15,000.00',
|
|
transferTime: '2026-06-10 14:22',
|
|
updateTime: '2026-06-10 15:01',
|
|
financeRemark: '凭证齐全'
|
|
},
|
|
{
|
|
motherName: '赵敏',
|
|
installmentNo: 2,
|
|
dueAmount: '¥9,800.00',
|
|
transferAmount: '¥9,800.00',
|
|
transferTime: '2026-06-08 09:15',
|
|
updateTime: '2026-06-08 10:30',
|
|
financeRemark: '—'
|
|
}
|
|
]
|
|
|
|
function renderCard(item, mode) {
|
|
const isPending = mode === 'pending'
|
|
const compact = mode === 'compact'
|
|
return `
|
|
<article class="confirm-card ${isPending ? 'is-pending' : 'is-confirmed'}">
|
|
<div class="confirm-card__head">
|
|
<div>
|
|
<div class="confirm-card__name">${item.motherName}</div>
|
|
<div class="confirm-card__sub">${item.motherIdCard || ''}${item.newbornName ? ' · 新生儿 ' + item.newbornName : ''}</div>
|
|
</div>
|
|
<div class="confirm-card__amount">
|
|
<div class="confirm-card__amount-val">${item.transferAmount || item.dueAmount}</div>
|
|
<div class="confirm-card__amount-label">${isPending ? '实缴金额' : '已确认'}</div>
|
|
</div>
|
|
</div>
|
|
${
|
|
compact
|
|
? ''
|
|
: `<div class="confirm-card__grid">
|
|
<div class="confirm-card__field"><label>期数</label><span>第 ${item.installmentNo} 期</span></div>
|
|
<div class="confirm-card__field"><label>应缴时间</label><span>${item.installmentDueDate}</span></div>
|
|
<div class="confirm-card__field"><label>应缴金额</label><span>${item.dueAmount}</span></div>
|
|
<div class="confirm-card__field"><label>缴费方式</label><span>${item.payMode || '—'}</span></div>
|
|
<div class="confirm-card__field"><label>转账方式</label><span>${item.transferType || '—'}</span></div>
|
|
<div class="confirm-card__field"><label>转账时间</label><span>${item.transferTime || '—'}</span></div>
|
|
</div>`
|
|
}
|
|
<div class="confirm-card__foot">
|
|
<div class="confirm-card__meta">
|
|
${isPending ? `<span class="tag warning">缴费确认中</span> · 提交 ${item.createTime}` : `<span class="tag success">已缴费</span> · 确认 ${item.updateTime}`}
|
|
</div>
|
|
<button type="button" class="btn-op ${isPending ? '' : 'ghost'}">${isPending ? '确认收款' : '查看确认信息'}</button>
|
|
</div>
|
|
</article>
|
|
`
|
|
}
|
|
|
|
function fillCards(containerId, items, mode, limit) {
|
|
const el = document.getElementById(containerId)
|
|
if (!el) return
|
|
el.innerHTML = items.slice(0, limit ?? items.length).map((i) => renderCard(i, mode)).join('')
|
|
}
|
|
|
|
// 方案 A
|
|
fillCards('cards-pending-a', MOCK_PENDING, 'pending')
|
|
fillCards('cards-confirmed-a', MOCK_CONFIRMED, 'confirmed')
|
|
|
|
// 方案 B
|
|
fillCards('cards-pending-b', MOCK_PENDING, 'pending')
|
|
fillCards('cards-confirmed-b', MOCK_CONFIRMED, 'confirmed')
|
|
|
|
// 方案 C — 全部卡片 + Chip 筛选
|
|
const allItems = [
|
|
...MOCK_PENDING.map((i) => ({ ...i, _status: 'pending' })),
|
|
...MOCK_CONFIRMED.map((i) => ({ ...i, _status: 'confirmed' }))
|
|
]
|
|
const cardsC = document.getElementById('cards-c')
|
|
function renderC(filter) {
|
|
const list =
|
|
filter === 'all'
|
|
? allItems
|
|
: allItems.filter((i) => i._status === filter)
|
|
cardsC.innerHTML = list
|
|
.map((i) => renderCard(i, i._status === 'pending' ? 'pending' : 'confirmed'))
|
|
.join('')
|
|
}
|
|
renderC('all')
|
|
document.querySelectorAll('.chip-filter .chip').forEach((chip) => {
|
|
chip.addEventListener('click', () => {
|
|
document.querySelectorAll('.chip-filter .chip').forEach((c) => c.classList.remove('is-active'))
|
|
chip.classList.add('is-active')
|
|
renderC(chip.dataset.filter)
|
|
})
|
|
})
|
|
|
|
// 方案 D
|
|
fillCards('cards-pending-d', MOCK_PENDING, 'pending')
|
|
fillCards('cards-confirmed-d', MOCK_CONFIRMED, 'confirmed')
|
|
document.querySelectorAll('[data-accordion]').forEach((section) => {
|
|
section.querySelector('.accordion-trigger').addEventListener('click', () => {
|
|
section.classList.toggle('is-open')
|
|
})
|
|
})
|
|
|
|
// 方案 E
|
|
fillCards('cards-pending-e', MOCK_PENDING, 'pending')
|
|
document.getElementById('table-confirmed-e').innerHTML = MOCK_CONFIRMED.map(
|
|
(row) => `
|
|
<tr>
|
|
<td>${row.motherName}</td>
|
|
<td>第 ${row.installmentNo} 期</td>
|
|
<td>${row.dueAmount}</td>
|
|
<td>${row.transferAmount}</td>
|
|
<td>${row.transferTime}</td>
|
|
<td>${row.updateTime}</td>
|
|
<td><span class="tag success">已缴费</span></td>
|
|
<td><button type="button" class="btn-op ghost" style="height:28px;padding:0 10px;font-size:12px">查看</button></td>
|
|
</tr>
|
|
`
|
|
).join('')
|
|
|
|
// 胶囊切换交互(视觉演示)
|
|
document.querySelectorAll('.type-capsule').forEach((group) => {
|
|
group.querySelectorAll('.type-capsule__btn').forEach((btn) => {
|
|
btn.addEventListener('click', () => {
|
|
group.querySelectorAll('.type-capsule__btn').forEach((b) => b.classList.remove('is-active'))
|
|
btn.classList.add('is-active')
|
|
})
|
|
})
|
|
})
|
|
</script>
|
|
</body>
|
|
</html>
|