1073 lines
44 KiB
HTML
1073 lines
44 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||
<title>协议单 · 新增/编辑表单美化 Demo(销售专员 / 地区经理)</title>
|
||
<style>
|
||
:root {
|
||
--brand: #0a9f6d;
|
||
--brand-dark: #087f57;
|
||
--brand-soft: #e9f9f2;
|
||
--brand-mid: #b8ebd4;
|
||
--barley: #d6a343;
|
||
--barley-soft: #fff7e8;
|
||
--text: #1f2a26;
|
||
--text-muted: #6b7b74;
|
||
--border: #dcebe4;
|
||
--page-bg: #f5f8f7;
|
||
--surface: #ffffff;
|
||
--danger: #d14343;
|
||
--warn: #cf8a19;
|
||
--shadow: 0 8px 28px rgba(15, 42, 34, 0.06);
|
||
--radius-card: 16px;
|
||
--radius-ctl: 12px;
|
||
}
|
||
|
||
* { box-sizing: border-box; }
|
||
body {
|
||
margin: 0;
|
||
min-height: 100vh;
|
||
font-family: "PingFang SC", "Hiragino Sans GB", "Noto Sans SC", -apple-system, system-ui, sans-serif;
|
||
color: var(--text);
|
||
background:
|
||
radial-gradient(900px 420px at 8% -8%, rgba(10, 159, 109, 0.14), transparent 55%),
|
||
radial-gradient(700px 380px at 92% 0%, rgba(214, 163, 67, 0.1), transparent 50%),
|
||
linear-gradient(180deg, #f8fffc 0%, #f4f7fb 45%, #f7f8fa 100%);
|
||
line-height: 1.45;
|
||
}
|
||
|
||
.stage { max-width: 1280px; margin: 0 auto; padding: 28px 16px 72px; }
|
||
|
||
.hero h1 { margin: 0 0 8px; font-size: 24px; font-weight: 720; letter-spacing: -0.02em; }
|
||
.hero p { margin: 0; max-width: 860px; color: #64748b; font-size: 14px; }
|
||
.hero .meta {
|
||
margin-top: 12px; display: flex; flex-wrap: wrap; gap: 8px;
|
||
}
|
||
.hero .chip {
|
||
display: inline-flex; align-items: center; gap: 6px;
|
||
padding: 6px 12px; border-radius: 999px; font-size: 12px; font-weight: 600;
|
||
background: #fff; border: 1px solid #e2e8f0; color: #475569;
|
||
}
|
||
.hero .chip strong { color: var(--brand-dark); }
|
||
|
||
.pain {
|
||
margin: 18px 0 0;
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||
gap: 10px;
|
||
}
|
||
.pain-item {
|
||
background: #fff;
|
||
border: 1px solid #fecaca;
|
||
border-radius: 12px;
|
||
padding: 10px 12px;
|
||
font-size: 12px;
|
||
color: #7f1d1d;
|
||
}
|
||
.pain-item b { color: #b91c1c; }
|
||
|
||
.tabs {
|
||
display: flex; flex-wrap: wrap; gap: 10px; margin: 22px 0 18px;
|
||
}
|
||
.tab {
|
||
appearance: none; border: 1px solid #e2e8f0; background: #fff;
|
||
border-radius: 999px; padding: 10px 16px; font-size: 13px;
|
||
font-weight: 600; color: #475569; cursor: pointer;
|
||
transition: .15s border-color, .15s box-shadow, .15s color, .15s background;
|
||
}
|
||
.tab:hover { border-color: #94a3b8; }
|
||
.tab.is-active {
|
||
color: var(--brand-dark); border-color: var(--brand);
|
||
background: var(--brand-soft);
|
||
box-shadow: 0 0 0 3px rgba(10, 159, 109, 0.18);
|
||
}
|
||
|
||
.layout {
|
||
display: grid;
|
||
grid-template-columns: minmax(280px, 360px) 1fr;
|
||
gap: 22px;
|
||
align-items: start;
|
||
}
|
||
@media (max-width: 960px) {
|
||
.layout { grid-template-columns: 1fr; }
|
||
}
|
||
|
||
.panel {
|
||
background: rgba(255,255,255,.92);
|
||
border: 1px solid #e2e8f0;
|
||
border-radius: 18px;
|
||
padding: 18px;
|
||
box-shadow: 0 10px 30px rgba(15, 23, 42, 0.05);
|
||
position: sticky;
|
||
top: 16px;
|
||
}
|
||
.panel h2 { margin: 0 0 4px; font-size: 16px; }
|
||
.panel .sub { margin: 0 0 14px; font-size: 12px; color: #64748b; }
|
||
.panel ol { margin: 0; padding-left: 18px; font-size: 13px; color: #475569; }
|
||
.panel li { margin: 0 0 8px; }
|
||
.panel li strong { color: var(--brand-dark); }
|
||
.legend {
|
||
margin-top: 16px; padding-top: 14px; border-top: 1px dashed #e2e8f0;
|
||
display: grid; gap: 8px; font-size: 12px; color: #64748b;
|
||
}
|
||
.legend span {
|
||
display: flex; align-items: center; gap: 8px;
|
||
}
|
||
.swatch {
|
||
width: 14px; height: 14px; border-radius: 4px; flex: none;
|
||
}
|
||
|
||
.phones {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
|
||
gap: 20px;
|
||
}
|
||
|
||
.phone-wrap { display: flex; flex-direction: column; gap: 10px; }
|
||
.phone-label {
|
||
display: flex; align-items: center; justify-content: space-between;
|
||
padding: 0 4px;
|
||
}
|
||
.phone-label h3 { margin: 0; font-size: 15px; font-weight: 700; }
|
||
.phone-label .tag {
|
||
font-size: 11px; font-weight: 700; padding: 4px 8px; border-radius: 999px;
|
||
}
|
||
.tag-old { background: #f1f5f9; color: #64748b; }
|
||
.tag-new { background: var(--brand-soft); color: var(--brand-dark); }
|
||
|
||
.phone {
|
||
width: 100%;
|
||
max-width: 390px;
|
||
margin: 0 auto;
|
||
height: 780px;
|
||
border-radius: 36px;
|
||
border: 10px solid #0f172a;
|
||
background: var(--page-bg);
|
||
box-shadow: 0 24px 60px rgba(15, 23, 42, 0.18);
|
||
overflow: hidden;
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
.phone::before {
|
||
content: "";
|
||
position: absolute;
|
||
top: 8px; left: 50%; transform: translateX(-50%);
|
||
width: 108px; height: 22px; border-radius: 12px;
|
||
background: #0f172a; z-index: 5;
|
||
}
|
||
|
||
/* ========== 当前样式(对照) ========== */
|
||
.old-page {
|
||
flex: 1; overflow: auto; padding: 44px 12px 88px;
|
||
background: #f5f8f7;
|
||
}
|
||
.old-nav {
|
||
position: sticky; top: 0; z-index: 2;
|
||
margin: -44px -12px 12px; padding: 40px 14px 10px;
|
||
background: #fff; border-bottom: 1px solid var(--border);
|
||
text-align: center; font-size: 16px; font-weight: 650;
|
||
}
|
||
.old-section {
|
||
margin-bottom: 12px; padding: 16px;
|
||
border: 1px solid var(--border); border-radius: 16px; background: #fff;
|
||
}
|
||
.old-section h4 {
|
||
margin: 0 0 14px; padding-left: 10px;
|
||
border-left: 3px solid var(--brand); font-size: 15px; font-weight: 650;
|
||
}
|
||
.old-field { display: grid; gap: 7px; margin-bottom: 14px; color: var(--text-muted); font-size: 13px; }
|
||
.old-field .ctl {
|
||
min-height: 44px; border: 1px solid var(--border); border-radius: 10px;
|
||
background: #fff; padding: 0 12px; display: flex; align-items: center;
|
||
color: #94a3b8; font-size: 14px;
|
||
}
|
||
.old-field .ctl.has-val { color: var(--text); }
|
||
.old-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
|
||
.old-tabs button {
|
||
min-height: 44px; border: 1px solid var(--border); border-radius: 10px;
|
||
background: #fff; color: var(--text); font-size: 14px;
|
||
}
|
||
.old-tabs button.on {
|
||
border-color: var(--brand); background: var(--brand-soft);
|
||
color: var(--brand-dark); font-weight: 600;
|
||
}
|
||
.old-bottom {
|
||
position: absolute; left: 0; right: 0; bottom: 0;
|
||
display: flex; gap: 10px; justify-content: center;
|
||
padding: 10px 14px 18px;
|
||
border-top: 1px solid var(--border); background: rgb(255 255 255 / 96%);
|
||
}
|
||
.old-bottom .btn {
|
||
min-height: 44px; min-width: 120px; max-width: 168px; flex: 0 1 168px;
|
||
border-radius: 999px; font-size: 15px; font-weight: 600; border: 1px solid var(--border);
|
||
background: #fff; color: var(--text);
|
||
}
|
||
.old-bottom .btn.primary {
|
||
border-color: var(--brand); background: var(--brand); color: #fff;
|
||
}
|
||
|
||
/* ========== 美化方案 ========== */
|
||
.new-page {
|
||
flex: 1; overflow: auto;
|
||
padding: 0 0 96px;
|
||
background:
|
||
linear-gradient(180deg, #e9f9f2 0%, #f5f8f7 120px, #f5f8f7 100%);
|
||
}
|
||
.new-nav {
|
||
position: sticky; top: 0; z-index: 3;
|
||
padding: 36px 14px 0;
|
||
background: linear-gradient(180deg, #d8f5e8 0%, #e9f9f2 70%, rgba(233,249,242,0.92) 100%);
|
||
backdrop-filter: blur(8px);
|
||
}
|
||
.new-nav__bar {
|
||
display: grid; grid-template-columns: 40px 1fr 40px;
|
||
align-items: center; margin-bottom: 10px;
|
||
}
|
||
.new-nav__back {
|
||
width: 36px; height: 36px; border-radius: 12px;
|
||
display: grid; place-items: center;
|
||
background: rgba(255,255,255,.72); border: 1px solid rgba(10,159,109,.18);
|
||
color: var(--brand-dark); font-size: 22px; line-height: 1;
|
||
}
|
||
.new-nav__title { text-align: center; font-size: 17px; font-weight: 720; color: var(--text); }
|
||
.new-nav__mode {
|
||
justify-self: end;
|
||
font-size: 11px; font-weight: 700; padding: 4px 8px; border-radius: 999px;
|
||
background: #fff; color: var(--brand-dark); border: 1px solid var(--brand-mid);
|
||
}
|
||
.new-steps {
|
||
display: flex; gap: 6px; overflow-x: auto; padding: 0 0 12px;
|
||
scrollbar-width: none;
|
||
}
|
||
.new-steps::-webkit-scrollbar { display: none; }
|
||
.step-chip {
|
||
flex: none; display: inline-flex; align-items: center; gap: 6px;
|
||
padding: 7px 12px; border-radius: 999px;
|
||
font-size: 12px; font-weight: 650; white-space: nowrap;
|
||
background: rgba(255,255,255,.65); color: var(--text-muted);
|
||
border: 1px solid transparent;
|
||
}
|
||
.step-chip .n {
|
||
width: 18px; height: 18px; border-radius: 50%;
|
||
display: grid; place-items: center; font-size: 10px; font-weight: 800;
|
||
background: #e2e8f0; color: #64748b;
|
||
}
|
||
.step-chip.is-active {
|
||
background: #fff; color: var(--brand-dark);
|
||
border-color: var(--brand-mid);
|
||
box-shadow: 0 2px 8px rgba(10,159,109,.12);
|
||
}
|
||
.step-chip.is-active .n {
|
||
background: var(--brand); color: #fff;
|
||
}
|
||
.step-chip.is-done .n {
|
||
background: var(--brand-mid); color: var(--brand-dark);
|
||
}
|
||
|
||
.new-body { padding: 4px 12px 12px; display: grid; gap: 12px; }
|
||
|
||
.card {
|
||
background: var(--surface);
|
||
border-radius: var(--radius-card);
|
||
box-shadow: var(--shadow);
|
||
border: 1px solid rgba(220, 235, 228, 0.85);
|
||
overflow: hidden;
|
||
}
|
||
.card__head {
|
||
display: flex; align-items: center; gap: 10px;
|
||
padding: 14px 14px 0;
|
||
}
|
||
.card__badge {
|
||
width: 28px; height: 28px; border-radius: 10px;
|
||
display: grid; place-items: center;
|
||
font-size: 12px; font-weight: 800; color: #fff;
|
||
background: linear-gradient(145deg, #12b981, #087f57);
|
||
box-shadow: 0 4px 10px rgba(10,159,109,.28);
|
||
}
|
||
.card__title {
|
||
flex: 1; margin: 0; font-size: 15px; font-weight: 720;
|
||
}
|
||
.card__hint {
|
||
margin: 4px 14px 0; font-size: 11px; color: var(--text-muted);
|
||
}
|
||
.card__body { padding: 12px 14px 14px; display: grid; gap: 12px; }
|
||
|
||
.field { display: grid; gap: 6px; }
|
||
.field.is-span2 { grid-column: 1 / -1; }
|
||
.field__label {
|
||
display: flex; align-items: center; gap: 4px;
|
||
font-size: 12px; font-weight: 650; color: #3d524a;
|
||
}
|
||
.field__label .req { color: var(--danger); font-weight: 800; }
|
||
.field__label .tip {
|
||
margin-left: 4px; font-size: 11px; font-weight: 500; color: var(--text-muted);
|
||
}
|
||
.field__ctl {
|
||
min-height: 46px;
|
||
border-radius: var(--radius-ctl);
|
||
border: 1px solid transparent;
|
||
background: #f4faf7;
|
||
padding: 0 14px;
|
||
display: flex; align-items: center; justify-content: space-between;
|
||
gap: 8px;
|
||
font-size: 14px; color: #94a3b8;
|
||
transition: border-color .15s, background .15s, box-shadow .15s;
|
||
}
|
||
.field__ctl.has-val { color: var(--text); background: #f7fbf9; border-color: #e3f0ea; }
|
||
.field__ctl:focus-within,
|
||
.field__ctl.is-focus {
|
||
background: #fff;
|
||
border-color: var(--brand);
|
||
box-shadow: 0 0 0 3px rgba(10, 159, 109, 0.15);
|
||
color: var(--text);
|
||
}
|
||
.field__ctl .chev { color: #9cb0a7; font-size: 16px; }
|
||
.field__ctl.textarea {
|
||
min-height: 84px; align-items: flex-start; padding: 12px 14px;
|
||
color: var(--text);
|
||
}
|
||
.field-grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 12px;
|
||
}
|
||
|
||
.seg {
|
||
display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
|
||
padding: 4px; border-radius: 14px; background: #eef6f2;
|
||
}
|
||
.seg button {
|
||
min-height: 40px; border: 0; border-radius: 11px;
|
||
background: transparent; color: var(--text-muted);
|
||
font-size: 13px; font-weight: 650; cursor: pointer;
|
||
}
|
||
.seg button.on {
|
||
background: #fff; color: var(--brand-dark);
|
||
box-shadow: 0 2px 8px rgba(15, 42, 34, 0.08);
|
||
}
|
||
|
||
.subgroup {
|
||
margin-top: 2px;
|
||
padding: 12px;
|
||
border-radius: 14px;
|
||
background: linear-gradient(180deg, #f8fffc 0%, #f4faf7 100%);
|
||
border: 1px solid #e3f0ea;
|
||
display: grid; gap: 12px;
|
||
}
|
||
.subgroup__title {
|
||
display: flex; align-items: center; gap: 8px;
|
||
font-size: 12px; font-weight: 750; color: var(--brand-dark);
|
||
}
|
||
.subgroup__title::before {
|
||
content: "";
|
||
width: 6px; height: 6px; border-radius: 50%;
|
||
background: var(--brand);
|
||
box-shadow: 0 0 0 3px var(--brand-soft);
|
||
}
|
||
|
||
.money-sync {
|
||
display: flex; align-items: center; justify-content: space-between;
|
||
gap: 10px; padding: 10px 12px; border-radius: 12px;
|
||
background: var(--barley-soft); border: 1px solid #f0e0bc;
|
||
font-size: 12px; color: #8a6419;
|
||
}
|
||
.money-sync strong { color: #92400e; font-size: 14px; }
|
||
|
||
.sample-card {
|
||
padding: 12px; border-radius: 14px;
|
||
border: 1px solid #e3f0ea; background: #fff;
|
||
display: grid; gap: 8px;
|
||
}
|
||
.sample-card__head {
|
||
display: flex; align-items: center; justify-content: space-between; gap: 8px;
|
||
}
|
||
.sample-card__head strong { font-size: 14px; }
|
||
.tag-status {
|
||
font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 999px;
|
||
background: var(--brand-soft); color: var(--brand-dark);
|
||
}
|
||
.sample-card__meta {
|
||
display: flex; flex-wrap: wrap; gap: 6px 10px;
|
||
font-size: 12px; color: var(--text-muted);
|
||
}
|
||
.sample-card__actions { display: flex; gap: 8px; }
|
||
.mini-btn {
|
||
min-height: 26px; padding: 0 10px; border-radius: 999px;
|
||
border: 0; background: #5f8f7d;
|
||
font-size: 11px; font-weight: 700; color: #fff;
|
||
box-shadow: 0 2px 5px rgba(15,42,34,.12);
|
||
}
|
||
.mini-btn.danger {
|
||
background: linear-gradient(135deg, #e35d5d, #d14343);
|
||
box-shadow: 0 2px 5px rgba(209,67,67,.2);
|
||
}
|
||
.mini-btn.primary {
|
||
background: linear-gradient(135deg, #12b981, #087f57);
|
||
box-shadow: 0 2px 6px rgba(10,159,109,.28);
|
||
}
|
||
.mini-btn.warn {
|
||
background: linear-gradient(135deg, #e5a63a, #cf8a19);
|
||
box-shadow: 0 2px 5px rgba(207,138,25,.22);
|
||
}
|
||
|
||
.toolbar-row {
|
||
display: flex; flex-wrap: wrap; gap: 8px; margin-top: 2px;
|
||
}
|
||
|
||
.upload-row {
|
||
display: flex; flex-wrap: wrap; gap: 10px;
|
||
}
|
||
.upload-card {
|
||
width: 96px; height: 72px; border-radius: 12px;
|
||
border: 1.5px dashed #a7f3d0;
|
||
background: #f7fffb;
|
||
display: grid; place-items: center; text-align: center;
|
||
font-size: 11px; color: var(--brand-dark); font-weight: 650;
|
||
gap: 2px;
|
||
}
|
||
.upload-card .plus { font-size: 20px; line-height: 1; color: var(--brand); }
|
||
.upload-file {
|
||
width: 96px; height: 72px; border-radius: 12px;
|
||
border: 1px solid var(--border); background: #fff;
|
||
padding: 8px; display: grid; align-content: space-between;
|
||
font-size: 11px; color: var(--text);
|
||
}
|
||
.upload-file .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.upload-file .rm { color: var(--danger); font-weight: 650; }
|
||
|
||
.confirm-row {
|
||
display: flex; align-items: flex-start; gap: 10px;
|
||
padding: 12px; border-radius: 14px;
|
||
background: var(--brand-soft); border: 1px solid var(--brand-mid);
|
||
font-size: 13px; color: var(--text); font-weight: 600;
|
||
}
|
||
.confirm-row .box {
|
||
width: 20px; height: 20px; border-radius: 6px; flex: none; margin-top: 1px;
|
||
border: 2px solid var(--brand); background: var(--brand);
|
||
color: #fff; display: grid; place-items: center; font-size: 12px;
|
||
}
|
||
|
||
.new-bottom {
|
||
position: absolute; left: 0; right: 0; bottom: 0; z-index: 4;
|
||
display: flex; gap: 10px;
|
||
padding: 12px 14px calc(12px + env(safe-area-inset-bottom, 8px));
|
||
background: linear-gradient(180deg, rgba(245,248,247,0), #fff 28%);
|
||
}
|
||
.new-bottom::before {
|
||
content: "";
|
||
position: absolute; inset: 0 0 auto 0; height: 1px;
|
||
background: linear-gradient(90deg, transparent, rgba(10,159,109,.18), transparent);
|
||
}
|
||
.new-bottom .btn {
|
||
position: relative;
|
||
min-height: 40px; flex: 1; border-radius: 12px;
|
||
font-size: 14px; font-weight: 700; border: 0; cursor: pointer;
|
||
color: #fff;
|
||
}
|
||
.new-bottom .btn.ghost {
|
||
background: #5f8f7d;
|
||
box-shadow: 0 3px 8px rgba(15, 42, 34, 0.14);
|
||
}
|
||
.new-bottom .btn.primary {
|
||
background: linear-gradient(135deg, #12b981 0%, #087f57 100%);
|
||
box-shadow: 0 6px 16px rgba(10, 159, 109, 0.3);
|
||
}
|
||
|
||
.variant-b .card__head {
|
||
padding: 12px 14px;
|
||
background: linear-gradient(90deg, #ecfdf5, #fff 60%);
|
||
border-bottom: 1px solid #eef6f2;
|
||
}
|
||
.variant-b .card__body { padding-top: 14px; }
|
||
.variant-b .field__ctl {
|
||
background: #fff;
|
||
border: 1px solid #e3f0ea;
|
||
}
|
||
.variant-b .field__ctl.has-val { background: #fff; }
|
||
.variant-b .seg { background: #f0f7f4; }
|
||
|
||
.note-bar {
|
||
margin-top: 18px;
|
||
padding: 14px 16px;
|
||
border-radius: 14px;
|
||
background: #fff;
|
||
border: 1px solid #e2e8f0;
|
||
font-size: 13px;
|
||
color: #475569;
|
||
}
|
||
.note-bar code {
|
||
font-size: 12px; padding: 2px 6px; border-radius: 6px;
|
||
background: #f1f5f9; color: #0f766e;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="stage">
|
||
<header class="hero">
|
||
<h1>协议单 · 新增 / 编辑表单美化</h1>
|
||
<p>
|
||
面向 <strong>销售专员 / 地区经理</strong>(mobile-oa-h5 市场模块)。
|
||
字段与分区顺序:协议信息 → 采集信息 → 客户信息 → 样本及运输 → 缴费 → 附件 → <strong>提交确认(最后)</strong>。
|
||
Token 使用三墙绿 <code style="font-size:12px;background:#e9f9f2;padding:2px 6px;border-radius:6px;">#0a9f6d</code>,不混用管理端薄荷主色。
|
||
</p>
|
||
<div class="meta">
|
||
<span class="chip"><strong>工程</strong> mobile-oa-h5</span>
|
||
<span class="chip"><strong>入口</strong> 市场 · 协议单</span>
|
||
<span class="chip"><strong>模式</strong> 新增 / 编辑</span>
|
||
</div>
|
||
<div class="pain">
|
||
<div class="pain-item"><b>现状问题</b>:白卡片 + 细描边扁平,长表单缺乏节奏</div>
|
||
<div class="pain-item"><b>现状问题</b>:label 灰色过淡,字段堆叠一列,滚动过长</div>
|
||
<div class="pain-item"><b>现状问题</b>:客户区母亲/父亲/新生儿无分组,扫读成本高</div>
|
||
<div class="pain-item"><b>现状问题</b>:底栏与内容粘连感弱,主按钮不够醒目</div>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="tabs" role="tablist">
|
||
<button type="button" class="tab is-active" data-tab="compare">对照:现状 vs 方案 A</button>
|
||
<button type="button" class="tab" data-tab="a">方案 A · 软填充(推荐)</button>
|
||
<button type="button" class="tab" data-tab="b">方案 B · 白底描边</button>
|
||
</div>
|
||
|
||
<div class="layout">
|
||
<aside class="panel" id="side-panel">
|
||
<h2>方案 A · 设计要点</h2>
|
||
<p class="sub">推荐落地;与现有 Vant 组件可渐进替换样式</p>
|
||
<ol>
|
||
<li><strong>顶区进度芯片</strong>:长表单可横向跳读分区</li>
|
||
<li><strong>编号卡片头</strong>:分区层级一眼可辨</li>
|
||
<li><strong>软填充控件</strong>:#f4faf7 底 + 聚焦描边,减少「框框墙」</li>
|
||
<li><strong>客户三分组</strong>:母亲 / 父亲 / 新生儿独立浅底块</li>
|
||
<li><strong>短字段双列</strong>:金额、性别、胎次、评分等降滚动</li>
|
||
<li><strong>实心小按钮</strong>:表单内操作统一实心,尺寸偏小;底栏取消/保存亦为实心</li>
|
||
</ol>
|
||
<div class="legend">
|
||
<span><i class="swatch" style="background:#0a9f6d"></i> 主色 / 进度 / 主按钮</span>
|
||
<span><i class="swatch" style="background:#e9f9f2"></i> 软底 / 选中态</span>
|
||
<span><i class="swatch" style="background:#fff7e8"></i> 金额同步提示</span>
|
||
<span><i class="swatch" style="background:#f4faf7;border:1px solid #dcebe4"></i> 输入控件默认底</span>
|
||
</div>
|
||
</aside>
|
||
|
||
<div class="phones" id="phone-stage">
|
||
<!-- 对照:现状 -->
|
||
<div class="phone-wrap" data-view="compare">
|
||
<div class="phone-label">
|
||
<h3>当前样式</h3>
|
||
<span class="tag tag-old">AS-IS</span>
|
||
</div>
|
||
<div class="phone">
|
||
<div class="old-page">
|
||
<div class="old-nav">新增协议单</div>
|
||
<section class="old-section">
|
||
<h4>协议信息</h4>
|
||
<div class="old-field">
|
||
<span>业务来源*</span>
|
||
<div class="old-tabs">
|
||
<button type="button" class="on">细胞存储</button>
|
||
<button type="button">科研捐赠</button>
|
||
</div>
|
||
</div>
|
||
<div class="old-field"><span>协议编号</span><div class="ctl">请输入</div></div>
|
||
<div class="old-field"><span>登记日期</span><div class="ctl">请选择</div></div>
|
||
<div class="old-field"><span>采集专员</span><div class="ctl">请选择</div></div>
|
||
<div class="old-field"><span>协议总金额</span><div class="ctl">请输入</div></div>
|
||
<div class="old-field"><span>备注</span><div class="ctl">请输入</div></div>
|
||
</section>
|
||
<section class="old-section">
|
||
<h4>采集信息</h4>
|
||
<div class="old-field"><span>市场专员</span><div class="ctl has-val">张专员</div></div>
|
||
<div class="old-field"><span>采集地区</span><div class="ctl">请选择</div></div>
|
||
<div class="old-field"><span>采集医院</span><div class="ctl">请选择</div></div>
|
||
</section>
|
||
<section class="old-section">
|
||
<h4>客户信息</h4>
|
||
<div class="old-field"><span>母亲姓名*</span><div class="ctl has-val">王女士</div></div>
|
||
<div class="old-field"><span>联系电话</span><div class="ctl">请输入</div></div>
|
||
<div class="old-field"><span>父亲姓名</span><div class="ctl">请输入</div></div>
|
||
<div class="old-field"><span>新生儿姓名</span><div class="ctl">请输入</div></div>
|
||
</section>
|
||
</div>
|
||
<div class="old-bottom">
|
||
<button type="button" class="btn">取消</button>
|
||
<button type="button" class="btn primary">保存</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 方案 A -->
|
||
<div class="phone-wrap" data-view="compare a">
|
||
<div class="phone-label">
|
||
<h3>方案 A · 软填充</h3>
|
||
<span class="tag tag-new">推荐</span>
|
||
</div>
|
||
<div class="phone" id="phone-a">
|
||
<div class="new-page">
|
||
<header class="new-nav">
|
||
<div class="new-nav__bar">
|
||
<div class="new-nav__back">‹</div>
|
||
<div class="new-nav__title">新增协议单</div>
|
||
<span class="new-nav__mode">专员</span>
|
||
</div>
|
||
<div class="new-steps">
|
||
<span class="step-chip is-active"><span class="n">1</span>协议</span>
|
||
<span class="step-chip"><span class="n">2</span>采集</span>
|
||
<span class="step-chip"><span class="n">3</span>客户</span>
|
||
<span class="step-chip"><span class="n">4</span>样本</span>
|
||
<span class="step-chip"><span class="n">5</span>缴费</span>
|
||
<span class="step-chip"><span class="n">6</span>附件</span>
|
||
<span class="step-chip"><span class="n">7</span>确认</span>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="new-body">
|
||
<!-- 1 协议 -->
|
||
<section class="card" id="sec-protocol">
|
||
<div class="card__head">
|
||
<span class="card__badge">1</span>
|
||
<h4 class="card__title">协议信息</h4>
|
||
</div>
|
||
<div class="card__body">
|
||
<div class="field">
|
||
<div class="field__label">业务来源<span class="req">*</span></div>
|
||
<div class="seg">
|
||
<button type="button" class="on">细胞存储</button>
|
||
<button type="button">科研捐赠</button>
|
||
</div>
|
||
</div>
|
||
<div class="field-grid">
|
||
<div class="field">
|
||
<div class="field__label">协议编号</div>
|
||
<div class="field__ctl">选填 / 可自动</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">登记日期</div>
|
||
<div class="field__ctl has-val">2026-10-15 <span class="chev">›</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">采集专员</div>
|
||
<div class="field__ctl">请选择 <span class="chev">›</span></div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">协议总金额<span class="tip">元</span></div>
|
||
<div class="field__ctl has-val is-focus">128000.00</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">备注</div>
|
||
<div class="field__ctl textarea">客户要求加急入库说明…</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 2 采集 -->
|
||
<section class="card">
|
||
<div class="card__head">
|
||
<span class="card__badge">2</span>
|
||
<h4 class="card__title">采集信息</h4>
|
||
</div>
|
||
<div class="card__body">
|
||
<div class="field">
|
||
<div class="field__label">市场专员</div>
|
||
<div class="field__ctl has-val">张专员 <span class="chev">›</span></div>
|
||
</div>
|
||
<div class="field-grid">
|
||
<div class="field">
|
||
<div class="field__label">采集地区</div>
|
||
<div class="field__ctl has-val">合肥 <span class="chev">›</span></div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">采集医院</div>
|
||
<div class="field__ctl">请选择 <span class="chev">›</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">地区经理</div>
|
||
<div class="field__ctl has-val">李经理 <span class="chev">›</span></div>
|
||
</div>
|
||
<div class="field-grid">
|
||
<div class="field">
|
||
<div class="field__label">样本采集时间</div>
|
||
<div class="field__ctl">请选择 <span class="chev">›</span></div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">母血采集时间</div>
|
||
<div class="field__ctl">请选择 <span class="chev">›</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 3 客户 -->
|
||
<section class="card">
|
||
<div class="card__head">
|
||
<span class="card__badge">3</span>
|
||
<h4 class="card__title">客户信息</h4>
|
||
</div>
|
||
<p class="card__hint">可搜索客户档案回填;身份证可自动推算出生年月</p>
|
||
<div class="card__body">
|
||
<div class="subgroup">
|
||
<div class="subgroup__title">母亲</div>
|
||
<div class="field">
|
||
<div class="field__label">母亲姓名<span class="req">*</span></div>
|
||
<div class="field__ctl has-val">王女士 🔍</div>
|
||
</div>
|
||
<div class="field-grid">
|
||
<div class="field">
|
||
<div class="field__label">联系电话</div>
|
||
<div class="field__ctl has-val">138****8899</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">出生年月</div>
|
||
<div class="field__ctl has-val">1992-06</div>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">母亲身份证号</div>
|
||
<div class="field__ctl has-val">3401**********1234</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">家庭住址</div>
|
||
<div class="field__ctl textarea" style="min-height:64px">合肥市蜀山区××路××号</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="subgroup">
|
||
<div class="subgroup__title">父亲</div>
|
||
<div class="field-grid">
|
||
<div class="field">
|
||
<div class="field__label">父亲姓名</div>
|
||
<div class="field__ctl">搜索档案 🔍</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">父亲电话</div>
|
||
<div class="field__ctl">请输入</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="subgroup">
|
||
<div class="subgroup__title">新生儿</div>
|
||
<div class="field-grid">
|
||
<div class="field">
|
||
<div class="field__label">新生儿姓名</div>
|
||
<div class="field__ctl">请输入</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">性别</div>
|
||
<div class="seg">
|
||
<button type="button" class="on">男</button>
|
||
<button type="button">女</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="field-grid">
|
||
<div class="field">
|
||
<div class="field__label">预产期</div>
|
||
<div class="field__ctl">请选择 <span class="chev">›</span></div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">分娩方式</div>
|
||
<div class="field__ctl">请选择 <span class="chev">›</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="field-grid">
|
||
<div class="field">
|
||
<div class="field__label">胎次</div>
|
||
<div class="field__ctl">请输入</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">体重(克)</div>
|
||
<div class="field__ctl">请输入</div>
|
||
</div>
|
||
</div>
|
||
<div class="field-grid">
|
||
<div class="field">
|
||
<div class="field__label">评分 1分钟</div>
|
||
<div class="field__ctl">请输入</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">评分 5分钟</div>
|
||
<div class="field__ctl">请输入</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 4 样本 -->
|
||
<section class="card">
|
||
<div class="card__head">
|
||
<span class="card__badge">4</span>
|
||
<h4 class="card__title">样本及运输</h4>
|
||
</div>
|
||
<p class="card__hint">规则与管理端一致</p>
|
||
<div class="card__body">
|
||
<div class="toolbar-row">
|
||
<button type="button" class="mini-btn primary">+ 添加样本</button>
|
||
<button type="button" class="mini-btn">配置运费</button>
|
||
<button type="button" class="mini-btn warn">取消运费</button>
|
||
</div>
|
||
<article class="sample-card">
|
||
<div class="sample-card__head">
|
||
<strong>☐ YB20261015001</strong>
|
||
<span class="tag-status">已采集</span>
|
||
</div>
|
||
<div class="sample-card__meta">
|
||
<span>脐带血</span>
|
||
<span>优惠价 ¥68,000</span>
|
||
<span>顺丰 · ¥120</span>
|
||
<span>ETA 10-18</span>
|
||
</div>
|
||
<div class="sample-card__actions">
|
||
<button type="button" class="mini-btn">编辑</button>
|
||
<button type="button" class="mini-btn danger">删除</button>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 5 缴费 -->
|
||
<section class="card">
|
||
<div class="card__head">
|
||
<span class="card__badge">5</span>
|
||
<h4 class="card__title">缴费信息</h4>
|
||
</div>
|
||
<div class="card__body">
|
||
<div class="money-sync">
|
||
<span>样本合同合计</span>
|
||
<strong>¥68,000.00</strong>
|
||
</div>
|
||
<article class="sample-card">
|
||
<div class="sample-card__head">
|
||
<strong>YB20261015001 · 脐带血</strong>
|
||
<span class="tag-status">分期</span>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">样本合同金额</div>
|
||
<div class="field__ctl has-val">68000</div>
|
||
</div>
|
||
<div class="field-grid">
|
||
<div class="field">
|
||
<div class="field__label">期数</div>
|
||
<div class="field__ctl has-val">3</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">间隔(月)</div>
|
||
<div class="field__ctl has-val">3</div>
|
||
</div>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 6 附件 -->
|
||
<section class="card">
|
||
<div class="card__head">
|
||
<span class="card__badge">6</span>
|
||
<h4 class="card__title">附件</h4>
|
||
</div>
|
||
<div class="card__body">
|
||
<div class="field">
|
||
<div class="field__label">协议附件</div>
|
||
<div class="upload-row">
|
||
<div class="upload-card"><span class="plus">+</span>上传</div>
|
||
<div class="upload-file">
|
||
<span class="name">协议扫描.pdf</span>
|
||
<span class="rm">删除</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">知情同意书</div>
|
||
<div class="upload-row">
|
||
<div class="upload-card"><span class="plus">+</span>上传</div>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">健康调查表</div>
|
||
<div class="upload-row">
|
||
<div class="upload-card"><span class="plus">+</span>上传</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 7 提交确认(始终最后) -->
|
||
<section class="card">
|
||
<div class="card__head">
|
||
<span class="card__badge">7</span>
|
||
<h4 class="card__title">提交确认</h4>
|
||
</div>
|
||
<p class="card__hint">请核对协议、样本、缴费与附件后再勾选</p>
|
||
<div class="card__body">
|
||
<div class="confirm-row">
|
||
<span class="box">✓</span>
|
||
<span>我已核对以上信息,确认无误后保存</span>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
</div>
|
||
<div class="new-bottom">
|
||
<button type="button" class="btn ghost">取消</button>
|
||
<button type="button" class="btn primary">保存协议单</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 方案 B(单独 tab 时显示) -->
|
||
<div class="phone-wrap" data-view="b" hidden>
|
||
<div class="phone-label">
|
||
<h3>方案 B · 白底描边</h3>
|
||
<span class="tag tag-new">备选</span>
|
||
</div>
|
||
<div class="phone variant-b">
|
||
<div class="new-page">
|
||
<header class="new-nav">
|
||
<div class="new-nav__bar">
|
||
<div class="new-nav__back">‹</div>
|
||
<div class="new-nav__title">编辑协议单</div>
|
||
<span class="new-nav__mode">经理</span>
|
||
</div>
|
||
<div class="new-steps">
|
||
<span class="step-chip is-done"><span class="n">✓</span>协议</span>
|
||
<span class="step-chip is-active"><span class="n">2</span>采集</span>
|
||
<span class="step-chip"><span class="n">3</span>客户</span>
|
||
<span class="step-chip"><span class="n">4</span>样本</span>
|
||
</div>
|
||
</header>
|
||
<div class="new-body">
|
||
<section class="card">
|
||
<div class="card__head">
|
||
<span class="card__badge">2</span>
|
||
<h4 class="card__title">采集信息</h4>
|
||
</div>
|
||
<div class="card__body">
|
||
<div class="field">
|
||
<div class="field__label">市场专员</div>
|
||
<div class="field__ctl has-val">张专员 <span class="chev">›</span></div>
|
||
</div>
|
||
<div class="field-grid">
|
||
<div class="field">
|
||
<div class="field__label">采集地区</div>
|
||
<div class="field__ctl has-val">合肥 <span class="chev">›</span></div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">采集医院</div>
|
||
<div class="field__ctl has-val">安徽省立医院 <span class="chev">›</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">地区经理</div>
|
||
<div class="field__ctl has-val">李经理 <span class="chev">›</span></div>
|
||
</div>
|
||
<div class="seg">
|
||
<button type="button" class="on">细胞存储</button>
|
||
<button type="button">科研捐赠</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<section class="card">
|
||
<div class="card__head">
|
||
<span class="card__badge">3</span>
|
||
<h4 class="card__title">客户信息 · 母亲</h4>
|
||
</div>
|
||
<div class="card__body">
|
||
<div class="field">
|
||
<div class="field__label">母亲姓名<span class="req">*</span></div>
|
||
<div class="field__ctl has-val">王女士</div>
|
||
</div>
|
||
<div class="field-grid">
|
||
<div class="field">
|
||
<div class="field__label">联系电话</div>
|
||
<div class="field__ctl has-val">138****8899</div>
|
||
</div>
|
||
<div class="field">
|
||
<div class="field__label">民族</div>
|
||
<div class="field__ctl has-val">汉族 <span class="chev">›</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
</div>
|
||
<div class="new-bottom">
|
||
<button type="button" class="btn ghost">取消</button>
|
||
<button type="button" class="btn primary">保存修改</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="note-bar">
|
||
文件路径:<code>mobile-ui/zkxw-mobile-oa-protocol-form-beautify-demo.html</code>
|
||
· 浏览器直接打开即可预览。确认方案后,可再落到
|
||
<code>mobile-oa-h5/src/styles/market.css</code> 与协议相关 Panel 组件。
|
||
业务字段不改,仅样式与信息层级。
|
||
<br />样本运输 / 缴费明细专项深化:
|
||
<code>mobile-ui/zkxw-mobile-oa-protocol-sample-pay-beautify-demo.html</code>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
const tabs = document.querySelectorAll('.tab')
|
||
const wraps = document.querySelectorAll('.phone-wrap')
|
||
const panel = document.getElementById('side-panel')
|
||
|
||
const copy = {
|
||
compare: {
|
||
title: '对照说明',
|
||
sub: '左侧现状、右侧方案 A;结构字段不变,只改视觉层级',
|
||
html: `<ol>
|
||
<li><strong>左侧</strong>:当前 market-form-section 扁平卡片</li>
|
||
<li><strong>右侧</strong>:推荐软填充 + 进度芯片 + 客户分组</li>
|
||
<li><strong>不改</strong>:校验规则、接口字段、专员/经理权限</li>
|
||
<li><strong>可改</strong>:CSS Token、卡片头、双列栅格、底栏</li>
|
||
</ol>`
|
||
},
|
||
a: {
|
||
title: '方案 A · 软填充(推荐)',
|
||
sub: '与现有 Vant 组件可渐进替换样式',
|
||
html: `<ol>
|
||
<li><strong>顶区进度芯片</strong>:长表单可横向跳读分区</li>
|
||
<li><strong>编号卡片头</strong>:分区层级一眼可辨</li>
|
||
<li><strong>软填充控件</strong>:#f4faf7 底 + 聚焦描边</li>
|
||
<li><strong>客户三分组</strong>:母亲 / 父亲 / 新生儿</li>
|
||
<li><strong>短字段双列</strong>:降滚动长度</li>
|
||
<li><strong>实心小按钮</strong>:表单内操作统一实心偏小</li>
|
||
</ol>`
|
||
},
|
||
b: {
|
||
title: '方案 B · 白底描边',
|
||
sub: '卡片头浅绿条 + 白底输入,更接近「表单纸」质感',
|
||
html: `<ol>
|
||
<li><strong>白底描边控件</strong>:更传统、对比更强</li>
|
||
<li><strong>卡片头色带</strong>:分区识别靠顶条而非填充输入</li>
|
||
<li><strong>适合</strong>:更偏好「清晰边框」的团队</li>
|
||
<li><strong>相对 A</strong>:长列表时框线略密,建议少用双线叠加</li>
|
||
</ol>`
|
||
}
|
||
}
|
||
|
||
function show(tab) {
|
||
tabs.forEach((t) => t.classList.toggle('is-active', t.dataset.tab === tab))
|
||
wraps.forEach((w) => {
|
||
const views = (w.dataset.view || '').split(/\s+/)
|
||
w.hidden = !views.includes(tab)
|
||
})
|
||
const c = copy[tab] || copy.a
|
||
panel.querySelector('h2').textContent = c.title
|
||
panel.querySelector('.sub').textContent = c.sub
|
||
const ol = panel.querySelector('ol')
|
||
ol.outerHTML = c.html
|
||
}
|
||
|
||
tabs.forEach((t) => t.addEventListener('click', () => show(t.dataset.tab)))
|
||
</script>
|
||
</body>
|
||
</html>
|