|
@@ -0,0 +1,964 @@
|
|
|
|
|
+<!DOCTYPE html>
|
|
|
|
|
+<html lang="zh-CN">
|
|
|
|
|
+<head>
|
|
|
|
|
+ <meta charset="UTF-8" />
|
|
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
|
|
|
+ <title>待办详情 · 底栏操作折叠 & 默认备注 Demo</title>
|
|
|
|
|
+ <style>
|
|
|
|
|
+ :root {
|
|
|
|
|
+ --ink: #0f172a;
|
|
|
|
|
+ --muted: #64748b;
|
|
|
|
|
+ --line: #e2e8f0;
|
|
|
|
|
+ --brand: #22c55e;
|
|
|
|
|
+ --brand-dark: #16a34a;
|
|
|
|
|
+ --brand-deep: #15803d;
|
|
|
|
|
+ --brand-soft: #ecfdf5;
|
|
|
|
|
+ --danger: #ef4444;
|
|
|
|
|
+ --warn: #d97706;
|
|
|
|
|
+ }
|
|
|
|
|
+ * { box-sizing: border-box; }
|
|
|
|
|
+ html, body { margin: 0; min-height: 100%; }
|
|
|
|
|
+ body {
|
|
|
|
|
+ font-family: "PingFang SC", "Hiragino Sans GB", "Noto Sans SC", -apple-system, system-ui, sans-serif;
|
|
|
|
|
+ color: var(--ink);
|
|
|
|
|
+ background:
|
|
|
|
|
+ radial-gradient(900px 420px at 8% -8%, rgba(52, 211, 153, 0.16), transparent 55%),
|
|
|
|
|
+ radial-gradient(700px 380px at 92% 0%, rgba(148, 163, 184, 0.14), transparent 50%),
|
|
|
|
|
+ linear-gradient(180deg, #f8fffc 0%, #f4f7fb 50%, #f7f8fa 100%);
|
|
|
|
|
+ line-height: 1.45;
|
|
|
|
|
+ }
|
|
|
|
|
+ .wrap {
|
|
|
|
|
+ max-width: 1180px;
|
|
|
|
|
+ margin: 0 auto;
|
|
|
|
|
+ padding: 28px 18px 96px;
|
|
|
|
|
+ }
|
|
|
|
|
+ h1 {
|
|
|
|
|
+ margin: 0 0 8px;
|
|
|
|
|
+ font-size: 24px;
|
|
|
|
|
+ letter-spacing: -0.02em;
|
|
|
|
|
+ font-weight: 720;
|
|
|
|
|
+ }
|
|
|
|
|
+ .sub {
|
|
|
|
|
+ margin: 0;
|
|
|
|
|
+ max-width: 760px;
|
|
|
|
|
+ color: var(--muted);
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .note {
|
|
|
|
|
+ margin: 14px 0 22px;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ border-radius: 10px;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border: 1px solid var(--line);
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: var(--muted);
|
|
|
|
|
+ }
|
|
|
|
|
+ .note strong { color: var(--brand-deep); }
|
|
|
|
|
+
|
|
|
|
|
+ .layout {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: 1fr minmax(300px, 360px);
|
|
|
|
|
+ gap: 22px;
|
|
|
|
|
+ align-items: start;
|
|
|
|
|
+ }
|
|
|
|
|
+ @media (max-width: 920px) {
|
|
|
|
|
+ .layout { grid-template-columns: 1fr; }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .schemes { display: grid; gap: 12px; }
|
|
|
|
|
+ .scheme {
|
|
|
|
|
+ appearance: none;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ text-align: left;
|
|
|
|
|
+ border: 1px solid var(--line);
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 16px;
|
|
|
|
|
+ padding: 14px 16px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ transition: border-color .15s, box-shadow .15s, background .15s;
|
|
|
|
|
+ font-family: inherit;
|
|
|
|
|
+ color: inherit;
|
|
|
|
|
+ }
|
|
|
|
|
+ .scheme:hover {
|
|
|
|
|
+ border-color: #cbd5e1;
|
|
|
|
|
+ box-shadow: 0 8px 24px rgba(15, 23, 42, 0.05);
|
|
|
|
|
+ }
|
|
|
|
|
+ .scheme.is-on {
|
|
|
|
|
+ border-color: var(--brand);
|
|
|
|
|
+ background: linear-gradient(180deg, #f0fdf4, #fff);
|
|
|
|
|
+ box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.18);
|
|
|
|
|
+ }
|
|
|
|
|
+ .scheme-top {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+ margin-bottom: 6px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .letter {
|
|
|
|
|
+ width: 28px; height: 28px;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ display: grid; place-items: center;
|
|
|
|
|
+ font-size: 13px; font-weight: 750;
|
|
|
|
|
+ background: #f1f5f9;
|
|
|
|
|
+ color: #334155;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ .scheme.is-on .letter {
|
|
|
|
|
+ background: var(--brand-soft);
|
|
|
|
|
+ color: var(--brand-deep);
|
|
|
|
|
+ }
|
|
|
|
|
+ .scheme h2 {
|
|
|
|
|
+ margin: 0;
|
|
|
|
|
+ font-size: 15px;
|
|
|
|
|
+ font-weight: 680;
|
|
|
|
|
+ }
|
|
|
|
|
+ .scheme p {
|
|
|
|
|
+ margin: 0 0 10px;
|
|
|
|
|
+ font-size: 12.5px;
|
|
|
|
|
+ color: var(--muted);
|
|
|
|
|
+ padding-left: 38px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .tag {
|
|
|
|
|
+ display: inline-block;
|
|
|
|
|
+ margin: 0 0 0 38px;
|
|
|
|
|
+ padding: 2px 8px;
|
|
|
|
|
+ border-radius: 999px;
|
|
|
|
|
+ font-size: 11px;
|
|
|
|
|
+ font-weight: 650;
|
|
|
|
|
+ background: #f1f5f9;
|
|
|
|
|
+ color: #475569;
|
|
|
|
|
+ }
|
|
|
|
|
+ .scheme.is-on .tag {
|
|
|
|
|
+ background: var(--brand-soft);
|
|
|
|
|
+ color: var(--brand-deep);
|
|
|
|
|
+ }
|
|
|
|
|
+ .tag.rec {
|
|
|
|
|
+ background: #ecfdf5;
|
|
|
|
|
+ color: #047857;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .defaults {
|
|
|
|
|
+ margin-top: 18px;
|
|
|
|
|
+ padding: 14px 16px;
|
|
|
|
|
+ border-radius: 16px;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border: 1px solid var(--line);
|
|
|
|
|
+ }
|
|
|
|
|
+ .defaults h3 {
|
|
|
|
|
+ margin: 0 0 10px;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: 680;
|
|
|
|
|
+ }
|
|
|
|
|
+ .defaults table {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ border-collapse: collapse;
|
|
|
|
|
+ font-size: 12.5px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .defaults th,
|
|
|
|
|
+ .defaults td {
|
|
|
|
|
+ text-align: left;
|
|
|
|
|
+ padding: 8px 6px;
|
|
|
|
|
+ border-bottom: 1px solid #f1f5f9;
|
|
|
|
|
+ vertical-align: top;
|
|
|
|
|
+ }
|
|
|
|
|
+ .defaults th {
|
|
|
|
|
+ color: var(--muted);
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ font-size: 11px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .defaults code {
|
|
|
|
|
+ display: inline-block;
|
|
|
|
|
+ padding: 2px 6px;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ background: #f8fafc;
|
|
|
|
|
+ border: 1px solid #e2e8f0;
|
|
|
|
|
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ color: #0f172a;
|
|
|
|
|
+ }
|
|
|
|
|
+ .defaults .hint {
|
|
|
|
|
+ margin: 10px 0 0;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ color: var(--muted);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* —— Phone preview —— */
|
|
|
|
|
+ .preview-col { position: sticky; top: 16px; }
|
|
|
|
|
+ .phone {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ max-width: 360px;
|
|
|
|
|
+ margin: 0 auto;
|
|
|
|
|
+ border-radius: 28px;
|
|
|
|
|
+ border: 1px solid #cbd5e1;
|
|
|
|
|
+ background: #0f172a;
|
|
|
|
|
+ padding: 10px;
|
|
|
|
|
+ box-shadow: 0 24px 60px rgba(15, 23, 42, 0.18);
|
|
|
|
|
+ }
|
|
|
|
|
+ .phone-inner {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ height: 640px;
|
|
|
|
|
+ border-radius: 20px;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ }
|
|
|
|
|
+ .status-bar {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ padding: 8px 16px 4px;
|
|
|
|
|
+ font-size: 11px;
|
|
|
|
|
+ font-weight: 650;
|
|
|
|
|
+ color: #334155;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ }
|
|
|
|
|
+ .nav {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ padding: 8px 12px 10px;
|
|
|
|
|
+ border-bottom: 1px solid #f1f5f9;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ }
|
|
|
|
|
+ .nav .back {
|
|
|
|
|
+ width: 28px; height: 28px;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ display: grid; place-items: center;
|
|
|
|
|
+ background: #f1f5f9;
|
|
|
|
|
+ color: #475569;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .nav h4 {
|
|
|
|
|
+ margin: 0;
|
|
|
|
|
+ font-size: 15px;
|
|
|
|
|
+ font-weight: 700;
|
|
|
|
|
+ }
|
|
|
|
|
+ .scroll {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ overflow: auto;
|
|
|
|
|
+ padding: 12px 12px 108px;
|
|
|
|
|
+ background: #f8fafc;
|
|
|
|
|
+ -webkit-overflow-scrolling: touch;
|
|
|
|
|
+ }
|
|
|
|
|
+ .card {
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 14px;
|
|
|
|
|
+ border: 1px solid #eef2f6;
|
|
|
|
|
+ padding: 12px 14px;
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .card .title-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .card h5 {
|
|
|
|
|
+ margin: 0;
|
|
|
|
|
+ font-size: 15px;
|
|
|
|
|
+ font-weight: 700;
|
|
|
|
|
+ }
|
|
|
|
|
+ .pill {
|
|
|
|
|
+ padding: 2px 8px;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ font-size: 11px;
|
|
|
|
|
+ font-weight: 650;
|
|
|
|
|
+ color: var(--warn);
|
|
|
|
|
+ background: #fffbeb;
|
|
|
|
|
+ }
|
|
|
|
|
+ .field {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ gap: 12px;
|
|
|
|
|
+ padding: 8px 0;
|
|
|
|
|
+ border-top: 1px solid #f1f5f9;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .field:first-of-type { border-top: none; }
|
|
|
|
|
+ .field .k { color: var(--muted); }
|
|
|
|
|
+ .field .v { color: #0f172a; font-weight: 560; text-align: right; }
|
|
|
|
|
+ .timeline {
|
|
|
|
|
+ font-size: 12.5px;
|
|
|
|
|
+ color: #334155;
|
|
|
|
|
+ }
|
|
|
|
|
+ .timeline .item {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: 14px 1fr;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .dot {
|
|
|
|
|
+ width: 10px; height: 10px;
|
|
|
|
|
+ margin-top: 4px;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ background: var(--brand);
|
|
|
|
|
+ box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.18);
|
|
|
|
|
+ }
|
|
|
|
|
+ .dot.mute { background: #94a3b8; box-shadow: none; }
|
|
|
|
|
+ .timeline .t { font-weight: 650; }
|
|
|
|
|
+ .timeline .m { color: var(--muted); margin-top: 2px; }
|
|
|
|
|
+
|
|
|
|
|
+ .ft {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ left: 0; right: 0; bottom: 0;
|
|
|
|
|
+ z-index: 5;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ padding: 10px 12px calc(10px + env(safe-area-inset-bottom, 0px));
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-top: 1px solid #eef2f6;
|
|
|
|
|
+ box-shadow: 0 -4px 16px rgba(15, 23, 42, 0.04);
|
|
|
|
|
+ }
|
|
|
|
|
+ .btn {
|
|
|
|
|
+ appearance: none;
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ height: 40px;
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ font: inherit;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: 650;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ padding: 0 12px;
|
|
|
|
|
+ transition: opacity .12s, transform .12s;
|
|
|
|
|
+ }
|
|
|
|
|
+ .btn:active { opacity: 0.88; transform: scale(0.98); }
|
|
|
|
|
+ .btn-close {
|
|
|
|
|
+ flex: 0 0 auto;
|
|
|
|
|
+ min-width: 56px;
|
|
|
|
|
+ background: #f1f5f9;
|
|
|
|
|
+ color: #334155;
|
|
|
|
|
+ }
|
|
|
|
|
+ .btn-ghost {
|
|
|
|
|
+ flex: 1 1 0;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ border: 1px solid #e2e8f0;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ color: #334155;
|
|
|
|
|
+ }
|
|
|
|
|
+ .btn-primary {
|
|
|
|
|
+ flex: 1.2 1 0;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ background: var(--brand);
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ font-weight: 750;
|
|
|
|
|
+ }
|
|
|
|
|
+ .btn-more {
|
|
|
|
|
+ flex: 0 0 auto;
|
|
|
|
|
+ width: 44px;
|
|
|
|
|
+ padding: 0;
|
|
|
|
|
+ border: 1px solid #e2e8f0;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ color: #334155;
|
|
|
|
|
+ font-size: 18px;
|
|
|
|
|
+ letter-spacing: 1px;
|
|
|
|
|
+ line-height: 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ .btn-more.wide {
|
|
|
|
|
+ width: auto;
|
|
|
|
|
+ min-width: 72px;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ letter-spacing: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* before (crowded) */
|
|
|
|
|
+ .ft.before .btn {
|
|
|
|
|
+ flex: 1 1 auto;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ padding: 0 6px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .ft.before .btn-primary { flex: 1.1 1 auto; }
|
|
|
|
|
+
|
|
|
|
|
+ /* overlay */
|
|
|
|
|
+ .mask {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ inset: 0;
|
|
|
|
|
+ background: rgba(15, 23, 42, 0.42);
|
|
|
|
|
+ z-index: 10;
|
|
|
|
|
+ opacity: 0;
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+ transition: opacity .18s;
|
|
|
|
|
+ }
|
|
|
|
|
+ .mask.is-on {
|
|
|
|
|
+ opacity: 1;
|
|
|
|
|
+ pointer-events: auto;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .sheet {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ left: 0; right: 0; bottom: 0;
|
|
|
|
|
+ z-index: 12;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 18px 18px 0 0;
|
|
|
|
|
+ transform: translateY(110%);
|
|
|
|
|
+ transition: transform .22s ease;
|
|
|
|
|
+ padding: 8px 0 calc(12px + env(safe-area-inset-bottom, 0px));
|
|
|
|
|
+ box-shadow: 0 -8px 28px rgba(15, 23, 42, 0.12);
|
|
|
|
|
+ }
|
|
|
|
|
+ .sheet.is-on { transform: translateY(0); }
|
|
|
|
|
+ .sheet .handle {
|
|
|
|
|
+ width: 36px; height: 4px;
|
|
|
|
|
+ border-radius: 999px;
|
|
|
|
|
+ background: #e2e8f0;
|
|
|
|
|
+ margin: 4px auto 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .sheet .row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 12px;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ padding: 14px 18px;
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ background: transparent;
|
|
|
|
|
+ font: inherit;
|
|
|
|
|
+ font-size: 15px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #0f172a;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ text-align: left;
|
|
|
|
|
+ }
|
|
|
|
|
+ .sheet .row:active { background: #f8fafc; }
|
|
|
|
|
+ .sheet .row .ico {
|
|
|
|
|
+ width: 32px; height: 32px;
|
|
|
|
|
+ border-radius: 10px;
|
|
|
|
|
+ display: grid; place-items: center;
|
|
|
|
|
+ background: #f1f5f9;
|
|
|
|
|
+ color: #475569;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .sheet .row.danger { color: var(--danger); }
|
|
|
|
|
+ .sheet .row.danger .ico { background: #fef2f2; color: var(--danger); }
|
|
|
|
|
+ .sheet .cancel {
|
|
|
|
|
+ margin: 8px 12px 0;
|
|
|
|
|
+ height: 44px;
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ background: #f1f5f9;
|
|
|
|
|
+ font: inherit;
|
|
|
|
|
+ font-size: 15px;
|
|
|
|
|
+ font-weight: 650;
|
|
|
|
|
+ color: #334155;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ width: calc(100% - 24px);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .popover {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ right: 12px;
|
|
|
|
|
+ bottom: 62px;
|
|
|
|
|
+ z-index: 12;
|
|
|
|
|
+ min-width: 148px;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border: 1px solid #e2e8f0;
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ box-shadow: 0 12px 32px rgba(15, 23, 42, 0.14);
|
|
|
|
|
+ padding: 6px;
|
|
|
|
|
+ opacity: 0;
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+ transform: translateY(6px);
|
|
|
|
|
+ transition: opacity .15s, transform .15s;
|
|
|
|
|
+ }
|
|
|
|
|
+ .popover.is-on {
|
|
|
|
|
+ opacity: 1;
|
|
|
|
|
+ pointer-events: auto;
|
|
|
|
|
+ transform: translateY(0);
|
|
|
|
|
+ }
|
|
|
|
|
+ .popover button {
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ text-align: left;
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ background: transparent;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ font: inherit;
|
|
|
|
|
+ font-size: 13.5px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #0f172a;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ .popover button:active { background: #f8fafc; }
|
|
|
|
|
+ .popover button.danger { color: var(--danger); }
|
|
|
|
|
+
|
|
|
|
|
+ .dialog {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ left: 50%;
|
|
|
|
|
+ top: 42%;
|
|
|
|
|
+ z-index: 14;
|
|
|
|
|
+ width: calc(100% - 48px);
|
|
|
|
|
+ max-width: 300px;
|
|
|
|
|
+ transform: translate(-50%, -50%) scale(0.96);
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 16px;
|
|
|
|
|
+ padding: 16px 16px 12px;
|
|
|
|
|
+ box-shadow: 0 20px 48px rgba(15, 23, 42, 0.2);
|
|
|
|
|
+ opacity: 0;
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+ transition: opacity .15s, transform .15s;
|
|
|
|
|
+ }
|
|
|
|
|
+ .dialog.is-on {
|
|
|
|
|
+ opacity: 1;
|
|
|
|
|
+ pointer-events: auto;
|
|
|
|
|
+ transform: translate(-50%, -50%) scale(1);
|
|
|
|
|
+ }
|
|
|
|
|
+ .dialog h3 {
|
|
|
|
|
+ margin: 0 0 10px;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ font-weight: 720;
|
|
|
|
|
+ }
|
|
|
|
|
+ .dialog textarea {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ min-height: 84px;
|
|
|
|
|
+ resize: none;
|
|
|
|
|
+ border: 1px solid #e2e8f0;
|
|
|
|
|
+ border-radius: 10px;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ font: inherit;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ color: #0f172a;
|
|
|
|
|
+ background: #f8fafc;
|
|
|
|
|
+ outline: none;
|
|
|
|
|
+ }
|
|
|
|
|
+ .dialog textarea:focus {
|
|
|
|
|
+ border-color: #86efac;
|
|
|
|
|
+ box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.15);
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ }
|
|
|
|
|
+ .dialog .tip {
|
|
|
|
|
+ margin: 8px 0 0;
|
|
|
|
|
+ font-size: 11.5px;
|
|
|
|
|
+ color: var(--muted);
|
|
|
|
|
+ }
|
|
|
|
|
+ .dialog .acts {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: 1fr 1fr;
|
|
|
|
|
+ margin-top: 12px;
|
|
|
|
|
+ border-top: 1px solid #f1f5f9;
|
|
|
|
|
+ }
|
|
|
|
|
+ .dialog .acts button {
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ background: transparent;
|
|
|
|
|
+ height: 42px;
|
|
|
|
|
+ font: inherit;
|
|
|
|
|
+ font-size: 15px;
|
|
|
|
|
+ font-weight: 650;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ .dialog .acts .cancel { color: #64748b; border-right: 1px solid #f1f5f9; }
|
|
|
|
|
+ .dialog .acts .ok { color: var(--brand-deep); font-weight: 750; }
|
|
|
|
|
+
|
|
|
|
|
+ .toast {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ left: 50%;
|
|
|
|
|
+ bottom: 88px;
|
|
|
|
|
+ z-index: 20;
|
|
|
|
|
+ transform: translateX(-50%) translateY(8px);
|
|
|
|
|
+ background: rgba(15, 23, 42, 0.88);
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ padding: 8px 14px;
|
|
|
|
|
+ border-radius: 999px;
|
|
|
|
|
+ font-size: 12.5px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ opacity: 0;
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+ transition: opacity .18s, transform .18s;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ max-width: 90%;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
|
+ }
|
|
|
|
|
+ .toast.is-on {
|
|
|
|
|
+ opacity: 1;
|
|
|
|
|
+ transform: translateX(-50%) translateY(0);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .actions {
|
|
|
|
|
+ margin-top: 14px;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ }
|
|
|
|
|
+ .chip {
|
|
|
|
|
+ appearance: none;
|
|
|
|
|
+ border: 1px solid var(--line);
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border-radius: 999px;
|
|
|
|
|
+ padding: 8px 12px;
|
|
|
|
|
+ font: inherit;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ font-weight: 650;
|
|
|
|
|
+ color: #475569;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ .chip:hover { border-color: #94a3b8; }
|
|
|
|
|
+ </style>
|
|
|
|
|
+</head>
|
|
|
|
|
+<body>
|
|
|
|
|
+ <div class="wrap">
|
|
|
|
|
+ <h1>待办详情 · 底栏操作折叠 & 默认备注</h1>
|
|
|
|
|
+ <p class="sub">
|
|
|
|
|
+ 对齐现网 <code>mobile-oa-h5</code> 审批详情底栏:默认只露出「同意 / 打回」,其余收入「更多」;
|
|
|
|
|
+ 需要意见的操作弹窗预填默认备注,用户可改。
|
|
|
|
|
+ </p>
|
|
|
|
|
+ <div class="note">
|
|
|
|
|
+ <strong>推荐方案 A</strong>:底栏「⋯ / 打回 / 同意」;更多用底部 ActionSheet。
|
|
|
|
|
+ 右侧手机可点击交互。默认备注见下方表格,可在弹窗内修改。
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="layout">
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <div class="schemes" id="schemes">
|
|
|
|
|
+ <button type="button" class="scheme is-on" data-scheme="A">
|
|
|
|
|
+ <div class="scheme-top">
|
|
|
|
|
+ <span class="letter">A</span>
|
|
|
|
|
+ <h2>⋯ + 打回 + 同意(推荐)</h2>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <p>主路径最清晰:主操作同意、次操作打回常显;拒绝 / 加签 / 转交 / 打印 / 关闭进更多(底部 ActionSheet)。</p>
|
|
|
|
|
+ <span class="tag rec">推荐 · 对齐「默认只展示同意、打回」</span>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button type="button" class="scheme" data-scheme="B">
|
|
|
|
|
+ <div class="scheme-top">
|
|
|
|
|
+ <span class="letter">B</span>
|
|
|
|
|
+ <h2>关闭常显 + ⋯ + 打回 + 同意</h2>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <p>保留「关闭」快捷退出;更多里放拒绝 / 加签 / 转交 / 打印。比 A 多一颗常驻按钮。</p>
|
|
|
|
|
+ <span class="tag">可选 · 退出路径更短</span>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button type="button" class="scheme" data-scheme="C">
|
|
|
|
|
+ <div class="scheme-top">
|
|
|
|
|
+ <span class="letter">C</span>
|
|
|
|
|
+ <h2>⋯文字「更多」+ 气泡菜单</h2>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <p>底栏文案「更多」替代三点;点击后右下角 Popover 列出次要操作,不遮挡整屏。</p>
|
|
|
|
|
+ <span class="tag">可选 · 轻量气泡</span>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button type="button" class="scheme" data-scheme="before">
|
|
|
|
|
+ <div class="scheme-top">
|
|
|
|
|
+ <span class="letter">旧</span>
|
|
|
|
|
+ <h2>现状:全部平铺</h2>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <p>关闭 / 打印 / 拒绝 / 打回 / 加签 / 转交 / 同意 一排挤开,字号被迫缩小。</p>
|
|
|
|
|
+ <span class="tag">对比</span>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="defaults">
|
|
|
|
|
+ <h3>默认备注文案(弹窗预填,可改)</h3>
|
|
|
|
|
+ <table>
|
|
|
|
|
+ <thead>
|
|
|
|
|
+ <tr><th>操作</th><th>默认备注</th><th>说明</th></tr>
|
|
|
|
|
+ </thead>
|
|
|
|
|
+ <tbody>
|
|
|
|
|
+ <tr><td>同意</td><td><code>同意</code></td><td>意见可选,预填后可直接确定</td></tr>
|
|
|
|
|
+ <tr><td>打回</td><td><code>请修改后重新提交</code></td><td>意见必填;预填满足必填,可改</td></tr>
|
|
|
|
|
+ <tr><td>拒绝</td><td><code>拒绝</code></td><td>意见可选</td></tr>
|
|
|
|
|
+ <tr><td>加签</td><td><code>加签</code></td><td>说明可选;选人后仍可改备注</td></tr>
|
|
|
|
|
+ <tr><td>转交</td><td><code>转交</code></td><td>说明可选;选人后仍可改备注</td></tr>
|
|
|
|
|
+ </tbody>
|
|
|
|
|
+ </table>
|
|
|
|
|
+ <p class="hint">点右侧「同意 / 打回 / 拒绝」可看预填弹窗;加签 / 转交在本 Demo 仅 Toast 示意(真实页仍为选人面板 + 预填说明)。</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="preview-col">
|
|
|
|
|
+ <div class="phone">
|
|
|
|
|
+ <div class="phone-inner" id="phone">
|
|
|
|
|
+ <div class="status-bar"><span>9:41</span><span>●●●</span></div>
|
|
|
|
|
+ <div class="nav">
|
|
|
|
|
+ <span class="back">‹</span>
|
|
|
|
|
+ <h4>审批详情</h4>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="scroll">
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <div class="title-row">
|
|
|
|
|
+ <h5>请假申请 · 张三</h5>
|
|
|
|
|
+ <span class="pill">处理中</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="field"><span class="k">请假类型</span><span class="v">年假</span></div>
|
|
|
|
|
+ <div class="field"><span class="k">开始时间</span><span class="v">2026-08-18 09:00</span></div>
|
|
|
|
|
+ <div class="field"><span class="k">结束时间</span><span class="v">2026-08-19 18:00</span></div>
|
|
|
|
|
+ <div class="field"><span class="k">时长</span><span class="v">2 天</span></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card timeline">
|
|
|
|
|
+ <div class="item"><span class="dot"></span><div><div class="t">发起人 · 张三</div><div class="m">已提交 · 08-12 10:02</div></div></div>
|
|
|
|
|
+ <div class="item"><span class="dot mute"></span><div><div class="t">审批人 · 我</div><div class="m">待处理</div></div></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <footer class="ft" id="ft"></footer>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="mask" id="mask"></div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="sheet" id="sheet">
|
|
|
|
|
+ <div class="handle"></div>
|
|
|
|
|
+ <div id="sheetRows"></div>
|
|
|
|
|
+ <button type="button" class="cancel" id="sheetCancel">取消</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="popover" id="popover"></div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="dialog" id="dialog">
|
|
|
|
|
+ <h3 id="dialogTitle">同意</h3>
|
|
|
|
|
+ <textarea id="dialogText" maxlength="500"></textarea>
|
|
|
|
|
+ <p class="tip" id="dialogTip">可修改默认备注后确定</p>
|
|
|
|
|
+ <div class="acts">
|
|
|
|
|
+ <button type="button" class="cancel" id="dialogCancel">取消</button>
|
|
|
|
|
+ <button type="button" class="ok" id="dialogOk">确定</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="toast" id="toast"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="actions">
|
|
|
|
|
+ <button type="button" class="chip" data-demo="approve">演示 · 同意弹窗</button>
|
|
|
|
|
+ <button type="button" class="chip" data-demo="return">演示 · 打回弹窗</button>
|
|
|
|
|
+ <button type="button" class="chip" data-demo="reject">演示 · 拒绝弹窗</button>
|
|
|
|
|
+ <button type="button" class="chip" data-demo="more">演示 · 打开更多</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <script>
|
|
|
|
|
+ const DEFAULTS = {
|
|
|
|
|
+ approve: { title: '同意', text: '同意', tip: '意见可选,已预填默认备注', required: false },
|
|
|
|
|
+ return: { title: '打回', text: '请修改后重新提交', tip: '意见必填;已预填,可直接确定或修改', required: true },
|
|
|
|
|
+ reject: { title: '拒绝', text: '拒绝', tip: '意见可选,已预填默认备注', required: false },
|
|
|
|
|
+ addSign: { title: '加签', text: '加签', tip: '说明可选', required: false },
|
|
|
|
|
+ transfer: { title: '转交', text: '转交', tip: '说明可选', required: false }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const MORE_ITEMS = [
|
|
|
|
|
+ { key: 'reject', label: '拒绝', danger: true, ico: '✕' },
|
|
|
|
|
+ { key: 'addSign', label: '加签', ico: '+' },
|
|
|
|
|
+ { key: 'transfer', label: '转交', ico: '⇄' },
|
|
|
|
|
+ { key: 'print', label: '打印', ico: '🖨' },
|
|
|
|
|
+ { key: 'close', label: '关闭', ico: '◁' }
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ let scheme = 'A'
|
|
|
|
|
+ let commentKind = 'approve'
|
|
|
|
|
+ let toastTimer = null
|
|
|
|
|
+
|
|
|
|
|
+ const ft = document.getElementById('ft')
|
|
|
|
|
+ const mask = document.getElementById('mask')
|
|
|
|
|
+ const sheet = document.getElementById('sheet')
|
|
|
|
|
+ const sheetRows = document.getElementById('sheetRows')
|
|
|
|
|
+ const popover = document.getElementById('popover')
|
|
|
|
|
+ const dialog = document.getElementById('dialog')
|
|
|
|
|
+ const dialogTitle = document.getElementById('dialogTitle')
|
|
|
|
|
+ const dialogText = document.getElementById('dialogText')
|
|
|
|
|
+ const dialogTip = document.getElementById('dialogTip')
|
|
|
|
|
+ const toastEl = document.getElementById('toast')
|
|
|
|
|
+
|
|
|
|
|
+ function toast(msg) {
|
|
|
|
|
+ toastEl.textContent = msg
|
|
|
|
|
+ toastEl.classList.add('is-on')
|
|
|
|
|
+ clearTimeout(toastTimer)
|
|
|
|
|
+ toastTimer = setTimeout(() => toastEl.classList.remove('is-on'), 1600)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function closeOverlays() {
|
|
|
|
|
+ mask.classList.remove('is-on')
|
|
|
|
|
+ sheet.classList.remove('is-on')
|
|
|
|
|
+ popover.classList.remove('is-on')
|
|
|
|
|
+ dialog.classList.remove('is-on')
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function openComment(kind) {
|
|
|
|
|
+ const cfg = DEFAULTS[kind]
|
|
|
|
|
+ if (!cfg) return
|
|
|
|
|
+ commentKind = kind
|
|
|
|
|
+ closeOverlays()
|
|
|
|
|
+ dialogTitle.textContent = cfg.title
|
|
|
|
|
+ dialogText.value = cfg.text
|
|
|
|
|
+ dialogTip.textContent = cfg.tip
|
|
|
|
|
+ mask.classList.add('is-on')
|
|
|
|
|
+ dialog.classList.add('is-on')
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ dialogText.focus()
|
|
|
|
|
+ dialogText.select()
|
|
|
|
|
+ }, 50)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function onMoreAction(key) {
|
|
|
|
|
+ closeOverlays()
|
|
|
|
|
+ if (key === 'reject') {
|
|
|
|
|
+ openComment('reject')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (key === 'addSign') {
|
|
|
|
|
+ toast('加签:选人面板 + 默认备注「加签」')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (key === 'transfer') {
|
|
|
|
|
+ toast('转交:选人面板 + 默认备注「转交」')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (key === 'print') {
|
|
|
|
|
+ toast('打印')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (key === 'close') {
|
|
|
|
|
+ toast('关闭详情')
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function renderMoreContent(includeClose) {
|
|
|
|
|
+ const items = MORE_ITEMS.filter((x) => includeClose || x.key !== 'close')
|
|
|
|
|
+ sheetRows.innerHTML = items.map((it) => `
|
|
|
|
|
+ <button type="button" class="row ${it.danger ? 'danger' : ''}" data-more="${it.key}">
|
|
|
|
|
+ <span class="ico">${it.ico}</span>
|
|
|
|
|
+ <span>${it.label}</span>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ `).join('')
|
|
|
|
|
+ popover.innerHTML = items.map((it) => `
|
|
|
|
|
+ <button type="button" class="${it.danger ? 'danger' : ''}" data-more="${it.key}">${it.label}</button>
|
|
|
|
|
+ `).join('')
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function openMore() {
|
|
|
|
|
+ dialog.classList.remove('is-on')
|
|
|
|
|
+ if (scheme === 'C') {
|
|
|
|
|
+ mask.classList.add('is-on')
|
|
|
|
|
+ popover.classList.add('is-on')
|
|
|
|
|
+ sheet.classList.remove('is-on')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ mask.classList.add('is-on')
|
|
|
|
|
+ sheet.classList.add('is-on')
|
|
|
|
|
+ popover.classList.remove('is-on')
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function renderFooter() {
|
|
|
|
|
+ closeOverlays()
|
|
|
|
|
+ ft.className = 'ft'
|
|
|
|
|
+ if (scheme === 'before') {
|
|
|
|
|
+ ft.classList.add('before')
|
|
|
|
|
+ ft.innerHTML = `
|
|
|
|
|
+ <button type="button" class="btn btn-close" data-act="close">关闭</button>
|
|
|
|
|
+ <button type="button" class="btn btn-ghost" data-act="print">打印</button>
|
|
|
|
|
+ <button type="button" class="btn btn-ghost" data-act="reject">拒绝</button>
|
|
|
|
|
+ <button type="button" class="btn btn-ghost" data-act="return">打回</button>
|
|
|
|
|
+ <button type="button" class="btn btn-ghost" data-act="addSign">加签</button>
|
|
|
|
|
+ <button type="button" class="btn btn-ghost" data-act="transfer">转交</button>
|
|
|
|
|
+ <button type="button" class="btn btn-primary" data-act="approve">同意</button>
|
|
|
|
|
+ `
|
|
|
|
|
+ renderMoreContent(true)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (scheme === 'A') {
|
|
|
|
|
+ ft.innerHTML = `
|
|
|
|
|
+ <button type="button" class="btn btn-more" data-act="more" aria-label="更多">⋯</button>
|
|
|
|
|
+ <button type="button" class="btn btn-ghost" data-act="return">打回</button>
|
|
|
|
|
+ <button type="button" class="btn btn-primary" data-act="approve">同意</button>
|
|
|
|
|
+ `
|
|
|
|
|
+ renderMoreContent(true)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (scheme === 'B') {
|
|
|
|
|
+ ft.innerHTML = `
|
|
|
|
|
+ <button type="button" class="btn btn-close" data-act="close">关闭</button>
|
|
|
|
|
+ <button type="button" class="btn btn-more" data-act="more" aria-label="更多">⋯</button>
|
|
|
|
|
+ <button type="button" class="btn btn-ghost" data-act="return">打回</button>
|
|
|
|
|
+ <button type="button" class="btn btn-primary" data-act="approve">同意</button>
|
|
|
|
|
+ `
|
|
|
|
|
+ renderMoreContent(false)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (scheme === 'C') {
|
|
|
|
|
+ ft.innerHTML = `
|
|
|
|
|
+ <button type="button" class="btn btn-more wide" data-act="more">更多</button>
|
|
|
|
|
+ <button type="button" class="btn btn-ghost" data-act="return">打回</button>
|
|
|
|
|
+ <button type="button" class="btn btn-primary" data-act="approve">同意</button>
|
|
|
|
|
+ `
|
|
|
|
|
+ renderMoreContent(true)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ document.getElementById('schemes').addEventListener('click', (e) => {
|
|
|
|
|
+ const btn = e.target.closest('.scheme')
|
|
|
|
|
+ if (!btn) return
|
|
|
|
|
+ document.querySelectorAll('.scheme').forEach((el) => el.classList.toggle('is-on', el === btn))
|
|
|
|
|
+ scheme = btn.dataset.scheme
|
|
|
|
|
+ renderFooter()
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ ft.addEventListener('click', (e) => {
|
|
|
|
|
+ const btn = e.target.closest('[data-act]')
|
|
|
|
|
+ if (!btn) return
|
|
|
|
|
+ const act = btn.dataset.act
|
|
|
|
|
+ if (act === 'more') {
|
|
|
|
|
+ openMore()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (act === 'approve' || act === 'return' || act === 'reject') {
|
|
|
|
|
+ openComment(act)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (act === 'addSign') {
|
|
|
|
|
+ toast('加签:选人面板 + 默认备注「加签」')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (act === 'transfer') {
|
|
|
|
|
+ toast('转交:选人面板 + 默认备注「转交」')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (act === 'print') {
|
|
|
|
|
+ toast('打印')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (act === 'close') {
|
|
|
|
|
+ toast('关闭详情')
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ sheetRows.addEventListener('click', (e) => {
|
|
|
|
|
+ const btn = e.target.closest('[data-more]')
|
|
|
|
|
+ if (!btn) return
|
|
|
|
|
+ onMoreAction(btn.dataset.more)
|
|
|
|
|
+ })
|
|
|
|
|
+ popover.addEventListener('click', (e) => {
|
|
|
|
|
+ const btn = e.target.closest('[data-more]')
|
|
|
|
|
+ if (!btn) return
|
|
|
|
|
+ onMoreAction(btn.dataset.more)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ mask.addEventListener('click', closeOverlays)
|
|
|
|
|
+ document.getElementById('sheetCancel').addEventListener('click', closeOverlays)
|
|
|
|
|
+ document.getElementById('dialogCancel').addEventListener('click', closeOverlays)
|
|
|
|
|
+ document.getElementById('dialogOk').addEventListener('click', () => {
|
|
|
|
|
+ const cfg = DEFAULTS[commentKind]
|
|
|
|
|
+ const text = String(dialogText.value || '').trim()
|
|
|
|
|
+ if (cfg?.required && !text) {
|
|
|
|
|
+ toast('请填写意见')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ closeOverlays()
|
|
|
|
|
+ toast(`${cfg.title} · ${text || '(无备注)'}`)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ document.querySelector('.actions').addEventListener('click', (e) => {
|
|
|
|
|
+ const chip = e.target.closest('[data-demo]')
|
|
|
|
|
+ if (!chip) return
|
|
|
|
|
+ const d = chip.dataset.demo
|
|
|
|
|
+ if (d === 'more') {
|
|
|
|
|
+ if (scheme === 'before') {
|
|
|
|
|
+ toast('请先切到方案 A/B/C')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ openMore()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ openComment(d)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ renderFooter()
|
|
|
|
|
+ </script>
|
|
|
|
|
+</body>
|
|
|
|
|
+</html>
|