| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647 |
- <!doctype html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>Fresh Mint · 运输计划安排 · 合同数量校验 / 框架提醒 Demo</title>
- <link rel="preconnect" href="https://fonts.googleapis.com" />
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
- <style>
- :root {
- --primary: #10b981;
- --primary-dark: #059669;
- --primary-bg: #ecfdf5;
- --text: #1e293b;
- --text-muted: #64748b;
- --border: #d9e8e2;
- --surface: #ffffff;
- --bg-page: #f1f5f9;
- --shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
- --shadow-lg: 0 12px 40px rgba(15, 23, 42, 0.14);
- --radius: 10px;
- --warn: #d97706;
- --warn-bg: #fffbeb;
- --warn-border: #fde68a;
- --danger: #dc2626;
- --danger-bg: #fef2f2;
- --danger-border: #fecaca;
- --info: #0284c7;
- --info-bg: #f0f9ff;
- --info-border: #bae6fd;
- --qty-plan: #059669;
- }
- * { box-sizing: border-box; }
- body {
- margin: 0;
- min-height: 100vh;
- font-family: Inter, -apple-system, BlinkMacSystemFont, "PingFang SC", sans-serif;
- font-size: 14px;
- line-height: 1.5;
- color: var(--text);
- background: var(--bg-page);
- }
- .demo-page { max-width: 1180px; margin: 0 auto; padding: 28px 24px 80px; }
- .demo-head { margin-bottom: 18px; }
- .demo-head h1 { margin: 0 0 8px; font-size: 22px; font-weight: 700; letter-spacing: -0.02em; }
- .demo-head h1 span { color: var(--primary); }
- .demo-head p { margin: 0; color: var(--text-muted); max-width: 900px; }
- .meta { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
- .pill {
- display: inline-flex; align-items: center; gap: 6px;
- padding: 4px 10px; border-radius: 999px; font-size: 12px; font-weight: 500;
- background: var(--primary-bg); color: var(--primary-dark); border: 1px solid #a7f3d0;
- }
- .pill.muted { background: #f1f5f9; color: var(--text-muted); border-color: #e2e8f0; }
- .pill.warn { background: var(--warn-bg); color: var(--warn); border-color: var(--warn-border); }
- .pill.danger { background: var(--danger-bg); color: var(--danger); border-color: var(--danger-border); }
- .brief {
- display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px;
- }
- @media (max-width: 900px) { .brief { grid-template-columns: 1fr; } }
- .card {
- background: var(--surface); border: 1px solid var(--border);
- border-radius: var(--radius); padding: 14px 16px; box-shadow: var(--shadow);
- }
- .card h2 {
- margin: 0 0 8px; font-size: 14px; font-weight: 600;
- padding-left: 10px; border-left: 3px solid var(--primary);
- color: var(--primary-dark);
- }
- .card.danger-card h2 { border-left-color: var(--danger); color: var(--danger); }
- .card.warn-card h2 { border-left-color: var(--warn); color: var(--warn); }
- .card ul { margin: 0; padding-left: 18px; color: var(--text-muted); font-size: 13px; }
- .card li { margin: 4px 0; }
- .card li strong { color: var(--text); }
- .formula {
- margin-top: 8px; padding: 8px 10px; border-radius: 8px;
- background: var(--primary-bg); color: var(--primary-dark);
- font-size: 12px; font-weight: 500;
- }
- .formula.warn { background: var(--warn-bg); color: #92400e; }
- .formula.danger { background: var(--danger-bg); color: #991b1b; }
- .scenario-tabs {
- display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap;
- }
- .scenario-tab {
- appearance: none; border: 1px solid var(--border); background: #fff;
- height: 36px; padding: 0 14px; border-radius: 8px; cursor: pointer;
- font-size: 13px; font-weight: 500; color: var(--text);
- }
- .scenario-tab:hover { border-color: #a7f3d0; color: var(--primary-dark); }
- .scenario-tab.active {
- background: var(--primary-bg); border-color: #a7f3d0; color: var(--primary-dark);
- }
- .panel {
- background: var(--surface); border: 1px solid var(--border);
- border-radius: 12px; box-shadow: var(--shadow-lg); overflow: hidden;
- }
- .panel-top {
- display: flex; align-items: center; justify-content: space-between;
- gap: 12px; padding: 14px 18px; border-bottom: 1px solid var(--border); flex-wrap: wrap;
- }
- .panel-top h3 {
- margin: 0; font-size: 16px; font-weight: 600;
- display: inline-flex; align-items: center; gap: 8px;
- }
- .panel-top h3::before {
- content: ""; width: 3px; height: 16px; border-radius: 2px; background: var(--primary);
- }
- .toolbar { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
- .btn {
- appearance: none; display: inline-flex; align-items: center; gap: 6px;
- height: 32px; padding: 0 12px; border-radius: 8px; font-size: 13px; font-weight: 500;
- border: 1px solid var(--border); background: #fff; color: var(--text); cursor: pointer;
- }
- .btn:hover { border-color: #a7f3d0; color: var(--primary-dark); }
- .btn.primary { background: var(--primary); border-color: var(--primary); color: #fff; }
- .btn.primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); color: #fff; }
- .btn.ghost { background: transparent; }
- .btn.warn { background: var(--warn); border-color: var(--warn); color: #fff; }
- .btn.warn:hover { filter: brightness(0.95); color: #fff; }
- .btn.danger { background: var(--danger); border-color: var(--danger); color: #fff; }
- .btn.danger:hover { filter: brightness(0.95); color: #fff; }
- .kv-row {
- display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;
- padding: 14px 18px; border-bottom: 1px solid #eef2f7;
- }
- @media (max-width: 900px) { .kv-row { grid-template-columns: 1fr 1fr; } }
- .kv-item .label { font-size: 11px; color: var(--text-muted); margin-bottom: 2px; }
- .kv-item .value { font-size: 13px; font-weight: 500; }
- .section {
- padding: 14px 18px 18px;
- }
- .section-title {
- margin: 0 0 10px; font-size: 13px; font-weight: 600; color: var(--primary-dark);
- }
- table {
- width: 100%; border-collapse: collapse; font-size: 13px;
- }
- th, td {
- border: 1px solid var(--border); padding: 8px 10px; text-align: left;
- vertical-align: middle;
- }
- th {
- background: #f8fafc; font-weight: 600; color: #334155; font-size: 12px;
- }
- th.num, td.num { text-align: right; font-variant-numeric: tabular-nums; }
- th.plan-qty, td.plan-qty { color: var(--qty-plan); }
- th.plan-qty { background: #ecfdf5; }
- td.over { color: var(--danger); font-weight: 600; background: #fef2f2; }
- .tag {
- display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 4px;
- font-size: 12px; font-weight: 500; color: #fff; background: var(--primary-dark);
- }
- .tag.warn { background: var(--warn); }
- .tag.info { background: var(--info); }
- .tag.muted { background: transparent; color: var(--text); border: 1px solid #cbd5e1; }
- .hint-inline {
- margin-top: 10px; padding: 10px 12px; border-radius: 8px;
- font-size: 13px; display: none;
- }
- .hint-inline.show { display: block; }
- .hint-inline.danger {
- background: var(--danger-bg); border: 1px solid var(--danger-border); color: #991b1b;
- }
- .hint-inline.warn {
- background: var(--warn-bg); border: 1px solid var(--warn-border); color: #92400e;
- }
- .hint-inline.info {
- background: var(--info-bg); border: 1px solid var(--info-border); color: #075985;
- }
- .hint-inline strong { font-weight: 600; }
- /* Modal */
- .mask {
- position: fixed; inset: 0; background: rgba(15, 23, 42, 0.45);
- display: none; align-items: center; justify-content: center;
- padding: 24px; z-index: 50;
- /* 无背景模糊,对齐规范 */
- backdrop-filter: none;
- }
- .mask.show { display: flex; }
- .modal {
- width: min(780px, 100%);
- background: #fff; border-radius: 12px;
- border: 1px solid var(--border); box-shadow: var(--shadow-lg);
- overflow: hidden;
- }
- .modal-header {
- display: flex; align-items: center; justify-content: space-between;
- padding: 14px 18px; border-bottom: 1px solid var(--border);
- }
- .modal-header h4 { margin: 0; font-size: 15px; font-weight: 600; }
- .modal-body { padding: 16px 18px; }
- .modal-body p { margin: 0 0 10px; color: var(--text); font-size: 13px; }
- .modal-body .calc {
- margin: 12px 0; padding: 10px 12px; border-radius: 8px;
- background: #f8fafc; border: 1px solid #e2e8f0; font-size: 13px;
- }
- .modal-body .calc .row {
- display: flex; justify-content: space-between; gap: 12px; padding: 3px 0;
- }
- .modal-body .calc .row.total {
- margin-top: 6px; padding-top: 8px; border-top: 1px dashed #cbd5e1;
- font-weight: 600;
- }
- .modal-body .calc .row.over .v { color: var(--danger); }
- .modal-footer {
- display: flex; justify-content: flex-end; gap: 8px;
- padding: 12px 18px; border-top: 1px solid var(--border);
- }
- .choice-note {
- margin-top: 16px; padding: 12px 14px; border-radius: 10px;
- background: #fff; border: 1px dashed #a7f3d0; color: var(--text-muted); font-size: 13px;
- }
- .choice-note strong { color: var(--primary-dark); }
- .hidden { display: none !important; }
- </style>
- </head>
- <body>
- <div class="demo-page">
- <header class="demo-head">
- <h1>运输计划安排 · <span>合同数量校验</span> & 框架合同提醒</h1>
- <p>
- 预览「安排运输」时的两类提示:① 有数量合同 — 已安排 + 本次是否超合同总量;
- ② 框架采购/销售合同(无固定数量)— 每次提醒累计已安排数量。数量口径对齐合同详情三列:
- <code>已安排合计 = 已归档 + 未归档已安排</code>(按停靠段 <code>plan_qty</code> / product_id)。
- </p>
- <div class="meta">
- <span class="pill">路径 · /#/pl/plan-module/plan</span>
- <span class="pill muted">触发点 · 安排运输 / 保存并安排</span>
- <span class="pill danger">场景 A · 超量硬拦截</span>
- <span class="pill warn">场景 B · 框架累计提醒</span>
- <span class="pill">场景 C · 未超限提醒剩余</span>
- </div>
- </header>
- <div class="brief">
- <div class="card danger-card">
- <h2>A. 有数量合同(销售/采购等)</h2>
- <ul>
- <li>合同产品行存在<strong>有效数量</strong>时参与校验</li>
- <li>校验式:<strong>已安排合计 + 本次 planQty ≤ 合同数量</strong></li>
- <li>超限:安排<strong>前提交拦截</strong>,弹窗说明差额,必须改数量</li>
- <li>未超限:安排<strong>成功之后</strong>弹窗提醒<strong>剩余可安排量</strong></li>
- <li>汇总口径:有绑合同的段都校验;已安排合计按该合同挂接停靠段(同合同详情三列)</li>
- </ul>
- <div class="formula danger">超限 → 事前硬拦;未超限 → 成功后提醒剩余</div>
- </div>
- <div class="card warn-card">
- <h2>B. 框架合同(无数量)</h2>
- <ul>
- <li>类型:<strong>框架销售 / 框架采购</strong>(含历史 framework)</li>
- <li>产品数量为「按客户需求」或空 → <strong>不拦数量</strong></li>
- <li>安排<strong>成功之后</strong>提醒:本次 + 累计已安排(无「剩余」)</li>
- </ul>
- <div class="formula warn">成功后提醒,不阻断安排</div>
- </div>
- </div>
- <div class="scenario-tabs" role="tablist">
- <button type="button" class="scenario-tab active" data-scenario="fixed" role="tab">场景 A · 有数量合同超量</button>
- <button type="button" class="scenario-tab" data-scenario="framework" role="tab">场景 B · 框架合同提醒</button>
- <button type="button" class="scenario-tab" data-scenario="ok" role="tab">场景 C · 未超限 · 提醒剩余量</button>
- </div>
- <!-- 场景 A -->
- <section id="panel-fixed" class="panel" data-panel="fixed">
- <div class="panel-top">
- <h3>安排运输 · 绑定有数量合同</h3>
- <div class="toolbar">
- <span class="tag">销售合同</span>
- <button type="button" class="btn primary" id="btn-arrange-fixed">▶ 安排运输</button>
- </div>
- </div>
- <div class="kv-row">
- <div class="kv-item"><div class="label">计划编号</div><div class="value">YP20260830012</div></div>
- <div class="kv-item"><div class="label">装货合同</div><div class="value">HT-2026-0318 · 硫酸销售合同</div></div>
- <div class="kv-item"><div class="label">合同数量口径</div><div class="value">产品行 quantity</div></div>
- <div class="kv-item"><div class="label">策略</div><div class="value">超量硬拦截</div></div>
- </div>
- <div class="section">
- <div class="section-title">本次装货产品 vs 合同用量</div>
- <table>
- <thead>
- <tr>
- <th>产品</th>
- <th class="num">合同数量</th>
- <th class="num plan-qty">已安排合计</th>
- <th class="num">本次安排</th>
- <th class="num">安排后合计</th>
- <th class="num">剩余可安排</th>
- <th>结果</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>98% 硫酸</td>
- <td class="num">100.000</td>
- <td class="num plan-qty">80.000</td>
- <td class="num">30.000</td>
- <td class="num over">110.000</td>
- <td class="num over">-10.000</td>
- <td><span class="tag" style="background:#dc2626">超量</span></td>
- </tr>
- <tr>
- <td>液碱 32%</td>
- <td class="num">50.000</td>
- <td class="num plan-qty">20.000</td>
- <td class="num">10.000</td>
- <td class="num">30.000</td>
- <td class="num">20.000</td>
- <td><span class="tag">正常</span></td>
- </tr>
- </tbody>
- </table>
- <div class="hint-inline danger show" id="inline-fixed">
- <strong>校验提示:</strong>产品「98% 硫酸」安排后合计 110 超过合同数量 100(超出 10)。请调减本次数量或更换合同后再安排。
- </div>
- </div>
- </section>
- <!-- 场景 B -->
- <section id="panel-framework" class="panel hidden" data-panel="framework">
- <div class="panel-top">
- <h3>安排运输 · 框架销售合同</h3>
- <div class="toolbar">
- <span class="tag warn">框架销售合同</span>
- <button type="button" class="btn primary" id="btn-arrange-fw">▶ 安排运输</button>
- </div>
- </div>
- <div class="kv-row">
- <div class="kv-item"><div class="label">计划编号</div><div class="value">YP20260830018</div></div>
- <div class="kv-item"><div class="label">送货合同</div><div class="value">HT-KJ-2026-008 · 年度框架销售</div></div>
- <div class="kv-item"><div class="label">合同数量</div><div class="value">按客户需求(无固定量)</div></div>
- <div class="kv-item"><div class="label">校验策略</div><div class="value">仅累计提醒,不拦截</div></div>
- </div>
- <div class="section">
- <div class="section-title">本次产品安排(框架无总量上限)</div>
- <table>
- <thead>
- <tr>
- <th>产品</th>
- <th class="num">合同数量</th>
- <th class="num plan-qty">已安排合计</th>
- <th class="num">本次安排</th>
- <th class="num plan-qty">安排后已安排</th>
- <th>结果</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>工业盐酸</td>
- <td class="num" style="color:var(--text-muted)">按客户需求</td>
- <td class="num plan-qty">126.500</td>
- <td class="num">28.000</td>
- <td class="num plan-qty">154.500</td>
- <td><span class="tag warn">提醒</span></td>
- </tr>
- <tr>
- <td>片碱</td>
- <td class="num" style="color:var(--text-muted)">按客户需求</td>
- <td class="num plan-qty">40.000</td>
- <td class="num">12.000</td>
- <td class="num plan-qty">52.000</td>
- <td><span class="tag warn">提醒</span></td>
- </tr>
- </tbody>
- </table>
- <div class="hint-inline warn show">
- <strong>框架合同提醒(安排成功后):</strong>无固定数量上限。工业盐酸累计已安排 <strong>154.500</strong>,片碱累计已安排 <strong>52.000</strong>。
- </div>
- </div>
- </section>
- <!-- 场景 C:未超限,提醒剩余 -->
- <section id="panel-ok" class="panel hidden" data-panel="ok">
- <div class="panel-top">
- <h3>安排运输 · 有数量且未超限</h3>
- <div class="toolbar">
- <span class="tag">采购合同</span>
- <button type="button" class="btn primary" id="btn-arrange-ok">▶ 安排运输</button>
- </div>
- </div>
- <div class="kv-row">
- <div class="kv-item"><div class="label">计划编号</div><div class="value">YP20260830021</div></div>
- <div class="kv-item"><div class="label">装货合同</div><div class="value">HT-CG-2026-102 · 液碱采购</div></div>
- <div class="kv-item"><div class="label">合同数量</div><div class="value">200.000</div></div>
- <div class="kv-item"><div class="label">校验结果</div><div class="value">通过 · 成功后提醒剩余</div></div>
- </div>
- <div class="section">
- <div class="section-title">本次产品安排</div>
- <table>
- <thead>
- <tr>
- <th>产品</th>
- <th class="num">合同数量</th>
- <th class="num plan-qty">已安排合计</th>
- <th class="num">本次安排</th>
- <th class="num">安排后合计</th>
- <th class="num">安排后剩余</th>
- <th>结果</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>液碱 32%</td>
- <td class="num">200.000</td>
- <td class="num plan-qty">150.000</td>
- <td class="num">40.000</td>
- <td class="num">190.000</td>
- <td class="num plan-qty">10.000</td>
- <td><span class="tag">成功后提醒</span></td>
- </tr>
- </tbody>
- </table>
- <div class="hint-inline info show">
- <strong>未超限:</strong>先完成安排;成功后再弹窗告知「剩余可安排量」(知悉即可,非二次确认)。
- </div>
- </div>
- </section>
- <p class="choice-note">
- <strong>已确认:</strong>超量事前硬拦;未超限 / 框架 → 安排成功后弹窗提醒;校验范围 = 有绑合同的段,已安排合计口径对齐合同详情三列。点击「安排运输」预览弹窗。
- </p>
- </div>
- <!-- 超量弹窗:硬拦 · 按合同分组表格 -->
- <div class="mask" id="mask-over-hard" role="dialog" aria-modal="true">
- <div class="modal">
- <div class="modal-header">
- <h4 style="color:var(--danger)">无法安排运输</h4>
- <button type="button" class="btn ghost" data-close>×</button>
- </div>
- <div class="modal-body">
- <p style="margin:0 0 12px;color:var(--text-muted);font-size:13px;">以下产品「已安排 + 本次」超过合同数量,请调整后再安排:</p>
- <div style="margin:0 0 14px;">
- <div style="font-size:14px;font-weight:600;margin:0 0 8px;padding-left:8px;border-left:3px solid var(--primary);">安徽某某化工 - HT-2026-0318(装货)</div>
- <table>
- <thead>
- <tr>
- <th>产品名称</th>
- <th>规格型号</th>
- <th class="num">合同数量</th>
- <th>单位</th>
- <th class="num">已安排</th>
- <th class="num">剩余</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>98% 硫酸</td>
- <td>工业级</td>
- <td class="num">100.000</td>
- <td>吨</td>
- <td class="num">110.000</td>
- <td class="num over">-10.000</td>
- </tr>
- <tr>
- <td>液碱 32%</td>
- <td>—</td>
- <td class="num">50.000</td>
- <td>吨</td>
- <td class="num">30.000</td>
- <td class="num plan-qty">20.000</td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- <div class="modal-footer">
- <button type="button" class="btn primary" data-close>✓ 知道了</button>
- </div>
- </div>
- </div>
- <!-- 框架提醒 · 按合同分组表格 -->
- <div class="mask" id="mask-framework" role="dialog" aria-modal="true">
- <div class="modal">
- <div class="modal-header">
- <h4 style="color:var(--warn)">安排成功 · 框架合同累计</h4>
- <button type="button" class="btn ghost" data-close>×</button>
- </div>
- <div class="modal-body">
- <p style="margin:0 0 12px;color:var(--text-muted);font-size:13px;">运输安排已成功。框架合同无固定数量上限,累计已安排如下:</p>
- <div style="margin:0 0 14px;">
- <div style="font-size:14px;font-weight:600;margin:0 0 8px;padding-left:8px;border-left:3px solid var(--primary);">某某贸易公司 - HT-KJ-2026-008(送货)</div>
- <table>
- <thead>
- <tr>
- <th>产品名称</th>
- <th>规格型号</th>
- <th class="num">合同数量</th>
- <th>单位</th>
- <th class="num">已安排</th>
- <th class="num">剩余</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>工业盐酸</td>
- <td>31%</td>
- <td class="num" style="color:var(--text-muted)">按客户需求</td>
- <td>吨</td>
- <td class="num plan-qty">154.500</td>
- <td class="num">—</td>
- </tr>
- <tr>
- <td>片碱</td>
- <td>—</td>
- <td class="num" style="color:var(--text-muted)">按客户需求</td>
- <td>吨</td>
- <td class="num plan-qty">52.000</td>
- <td class="num">—</td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- <div class="modal-footer">
- <button type="button" class="btn primary" data-close>✓ 知道了</button>
- </div>
- </div>
- </div>
- <!-- 未超限:双侧合同示意 -->
- <div class="mask" id="mask-ok" role="dialog" aria-modal="true">
- <div class="modal">
- <div class="modal-header">
- <h4 style="color:var(--primary-dark)">安排成功 · 合同剩余数量</h4>
- <button type="button" class="btn ghost" data-close>×</button>
- </div>
- <div class="modal-body">
- <p style="margin:0 0 12px;color:var(--text-muted);font-size:13px;">运输安排已成功。各产品剩余可安排量如下:</p>
- <div style="margin:0 0 14px;">
- <div style="font-size:14px;font-weight:600;margin:0 0 8px;padding-left:8px;border-left:3px solid var(--primary);">云栋供应商 - HT-CG-2026-102(装货)</div>
- <table>
- <thead>
- <tr>
- <th>产品名称</th>
- <th>规格型号</th>
- <th class="num">合同数量</th>
- <th>单位</th>
- <th class="num">已安排</th>
- <th class="num">剩余</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>液碱 32%</td>
- <td>—</td>
- <td class="num">200.000</td>
- <td>吨</td>
- <td class="num">190.000</td>
- <td class="num plan-qty">10.000</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div style="margin:0 0 4px;">
- <div style="font-size:14px;font-weight:600;margin:0 0 8px;padding-left:8px;border-left:3px solid var(--primary);">某某贸易公司 - HT-XS-2026-088(送货)</div>
- <table>
- <thead>
- <tr>
- <th>产品名称</th>
- <th>规格型号</th>
- <th class="num">合同数量</th>
- <th>单位</th>
- <th class="num">已安排</th>
- <th class="num">剩余</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>液碱 32%</td>
- <td>—</td>
- <td class="num">180.000</td>
- <td>吨</td>
- <td class="num">40.000</td>
- <td class="num plan-qty">140.000</td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- <div class="modal-footer">
- <button type="button" class="btn primary" data-close>✓ 知道了</button>
- </div>
- </div>
- </div>
- <script>
- (function () {
- function showPanel(name) {
- document.querySelectorAll('[data-panel]').forEach(function (el) {
- el.classList.toggle('hidden', el.getAttribute('data-panel') !== name)
- })
- document.querySelectorAll('.scenario-tab').forEach(function (tab) {
- tab.classList.toggle('active', tab.getAttribute('data-scenario') === name)
- })
- }
- document.querySelectorAll('.scenario-tab').forEach(function (tab) {
- tab.addEventListener('click', function () {
- showPanel(tab.getAttribute('data-scenario'))
- })
- })
- function openMask(id) {
- document.getElementById(id).classList.add('show')
- }
- function closeAll() {
- document.querySelectorAll('.mask').forEach(function (m) { m.classList.remove('show') })
- }
- document.querySelectorAll('[data-close]').forEach(function (btn) {
- btn.addEventListener('click', closeAll)
- })
- document.querySelectorAll('.mask').forEach(function (mask) {
- mask.addEventListener('click', function (e) {
- if (e.target === mask) closeAll()
- })
- })
- document.getElementById('btn-arrange-fixed').addEventListener('click', function () {
- openMask('mask-over-hard')
- })
- document.getElementById('btn-arrange-fw').addEventListener('click', function () {
- openMask('mask-framework')
- })
- document.getElementById('btn-arrange-ok').addEventListener('click', function () {
- openMask('mask-ok')
- })
- })()
- </script>
- </body>
- </html>
|