Files
shanxia2.0/docs/fresh-mint-pl-plan-stop-products-vs-contract-demo.html
T
2026-08-27 14:23:18 +08:00

637 lines
32 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>运输计划 · 合同产品与段产品去重 Demo</title>
<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;
--table-head: #f8fafc;
--row-alt: #fafafa;
--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;
--danger: #dc2626;
--info: #0284c7;
--info-bg: #f0f9ff;
--delivery-accent: #0284c7;
--delivery-bg: #f0f9ff;
--dialog-max: 1280px;
}
* { box-sizing: border-box; }
body {
margin: 0; min-height: 100vh;
font-family: Inter, -apple-system, BlinkMacSystemFont, sans-serif;
font-size: 14px; line-height: 1.5; color: var(--text); background: var(--bg-page);
}
.page { max-width: 1440px; margin: 0 auto; padding: 24px 20px 80px; }
.hero {
background: linear-gradient(135deg, #ecfdf5 0%, #fff 50%, #fffbeb 100%);
border: 1px solid var(--border); border-radius: var(--radius);
padding: 22px 24px; margin-bottom: 18px; box-shadow: var(--shadow);
}
.hero h1 { margin: 0 0 8px; font-size: 22px; font-weight: 700; }
.hero h1 em { font-style: normal; color: var(--primary-dark); }
.hero p { margin: 0; color: var(--text-muted); max-width: 980px; }
.pills { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.pill {
display: inline-flex; 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.warn { background: var(--warn-bg); color: var(--warn); border-color: rgba(217,119,6,.25); }
.pill.muted { background: #f1f5f9; color: var(--text-muted); border-color: #e2e8f0; }
.problem-diagram {
display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
margin-top: 16px;
}
@media (max-width: 900px) { .problem-diagram { grid-template-columns: 1fr; } }
.problem-box {
border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px;
background: #fff; font-size: 12px;
}
.problem-box h4 { margin: 0 0 6px; font-size: 12px; color: var(--text-muted); }
.problem-box strong { display: block; margin-bottom: 4px; }
.problem-box .dup { color: var(--warn); font-weight: 600; }
.scheme-tabs {
display: flex; flex-wrap: wrap; gap: 6px;
background: #fff; border: 1px solid var(--border);
border-radius: var(--radius) var(--radius) 0 0; padding: 10px 12px 0;
}
.scheme-tab {
border: none; background: transparent; cursor: pointer;
padding: 10px 14px; font-size: 13px; font-weight: 600;
color: var(--text-muted); border-bottom: 2px solid transparent; font-family: inherit;
}
.scheme-tab.active { color: var(--primary-dark); border-bottom-color: var(--primary); }
.scheme-tab.recommended::after {
content: "推荐"; margin-left: 6px; font-size: 10px; font-weight: 700;
color: #fff; background: var(--primary-dark); padding: 1px 6px; border-radius: 999px;
}
.scheme-panel {
display: none; background: #fff; border: 1px solid var(--border); border-top: none;
border-radius: 0 0 var(--radius) var(--radius); padding: 16px 18px 22px; box-shadow: var(--shadow);
}
.scheme-panel.active { display: block; }
.scheme-desc {
margin: 0 0 14px; padding: 10px 12px; border-radius: 8px; font-size: 12px;
border: 1px solid #bae6fd; background: var(--info-bg); color: #0369a1;
}
.scheme-desc.ok { border-color: #a7f3d0; background: var(--primary-bg); color: var(--primary-dark); }
.scheme-desc.warn { border-color: rgba(217,119,6,.3); background: var(--warn-bg); color: #92400e; }
.dialog-sim {
width: var(--dialog-max); max-width: 100%; margin: 0 auto;
border: 1px solid var(--border); border-radius: var(--radius);
background: #fff; box-shadow: var(--shadow-lg); overflow: hidden;
}
.dialog-sim__hd { padding: 14px 18px; border-bottom: 1px solid var(--border); font-weight: 700; }
.dialog-sim__bd { padding: 16px 18px 20px; background: #fafcfb; }
.layer-label {
font-size: 11px; font-weight: 600; color: var(--text-muted);
margin: 0 0 6px; display: flex; align-items: center; gap: 6px;
}
.layer-label .badge {
padding: 1px 6px; border-radius: 4px; font-size: 10px;
background: #f1f5f9; border: 1px solid #e2e8f0;
}
.layer-label .badge.plan { background: var(--primary-bg); color: var(--primary-dark); border-color: #a7f3d0; }
.layer-label .badge.contract { background: #fef3c7; color: #92400e; border-color: #fcd34d; }
.layer-label .badge.stop { background: var(--info-bg); color: var(--info); border-color: #bae6fd; }
.section { margin-bottom: 14px; }
.section-title {
margin: 0 0 8px; font-size: 14px; font-weight: 700;
display: flex; align-items: center; gap: 8px;
}
.section-title::before {
content: ""; width: 3px; height: 14px; border-radius: 2px; background: var(--primary);
}
/* 装卸货分栏 */
.stops-split {
display: grid; grid-template-columns: 1fr 1fr;
border: 1px solid var(--border); border-radius: var(--radius);
overflow: hidden; background: #fff; min-height: 320px;
}
.stop-pane { display: flex; flex-direction: column; min-width: 0; }
.stop-pane + .stop-pane { border-left: 1px solid var(--border); }
.stop-pane__hd {
padding: 10px 12px; border-bottom: 1px solid var(--border);
font-size: 13px; font-weight: 700; flex-shrink: 0;
}
.stop-pane--load .stop-pane__hd { background: linear-gradient(180deg, #ecfdf5, #f8fffc); }
.stop-pane--delivery .stop-pane__hd { background: linear-gradient(180deg, #f0f9ff, #f8fcff); }
.stop-pane__bd { padding: 12px; flex: 1; overflow: auto; }
.party-row { display: grid; grid-template-columns: 1.2fr 0.8fr; gap: 10px; margin-bottom: 8px; }
.field label { display: block; font-size: 11px; color: var(--text-muted); margin-bottom: 4px; }
.field input, .field select {
width: 100%; height: 34px; border: 1px solid var(--border);
border-radius: 8px; padding: 0 8px; font: inherit;
}
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 8px; }
.span-2 { grid-column: span 2; }
.btn {
display: inline-flex; align-items: center; gap: 4px; height: 28px; padding: 0 10px;
border-radius: 8px; border: 1px solid var(--border); background: #fff;
font: inherit; font-weight: 600; font-size: 11px; cursor: pointer;
}
.btn.ghost { background: #fff; }
.btn.link { border: none; background: none; color: var(--info); padding: 0 4px; height: auto; }
/* 合同卡片 - 现状(带产品表) */
.contract-card {
border: 1px solid var(--border); border-radius: 8px; margin-bottom: 8px; overflow: hidden;
}
.contract-card__hd {
display: flex; justify-content: space-between; align-items: center;
padding: 8px 10px; background: var(--table-head); border-bottom: 1px solid var(--border);
font-size: 12px;
}
.contract-card__hd .no { font-weight: 700; }
.tag {
display: inline-flex; padding: 1px 6px; border-radius: 4px;
font-size: 10px; font-weight: 600;
}
.tag.amber { background: #d97706; color: #fff; }
.tag.danger { background: var(--danger); color: #fff; }
/* 合同摘要 chips(推荐方案) */
.contract-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.contract-chip {
display: inline-flex; align-items: center; gap: 6px;
padding: 6px 10px; border: 1px solid #fcd34d; border-radius: 8px;
background: #fffbeb; font-size: 11px;
}
.contract-chip__no { font-weight: 700; color: #92400e; }
.contract-chip__meta { color: var(--text-muted); }
.contract-chip__actions { display: flex; gap: 4px; margin-left: 4px; }
/* 折叠合同 */
.contract-collapse { border: 1px solid var(--border); border-radius: 8px; margin-bottom: 8px; }
.contract-collapse__hd {
display: flex; justify-content: space-between; align-items: center;
padding: 8px 10px; cursor: pointer; font-size: 12px; background: #fff;
}
.contract-collapse__hd:hover { background: var(--table-head); }
.contract-collapse__bd { display: none; padding: 0 8px 8px; border-top: 1px dashed var(--border); }
.contract-collapse.is-open .contract-collapse__bd { display: block; }
.contract-collapse.is-open .contract-collapse__toggle { transform: rotate(180deg); }
table.data {
width: 100%; border-collapse: collapse; font-size: 11px; table-layout: fixed;
}
table.data th, table.data td {
border-bottom: 1px solid var(--border); padding: 5px 6px; text-align: left;
}
table.data th { background: var(--table-head); color: var(--text-muted); font-size: 10px; font-weight: 600; }
table.data tr:last-child td { border-bottom: none; }
table.data.wide { min-width: 520px; }
.table-scroll { overflow-x: auto; border: 1px solid var(--border); border-radius: 6px; }
.table-scroll::after {
content: "← 合同产品表横向滚动 →"; display: block; text-align: center;
font-size: 10px; color: var(--warn); background: var(--warn-bg); padding: 3px;
}
.subline { display: block; font-size: 10px; color: var(--text-muted); margin-top: 2px; }
.num { text-align: right; }
.center { text-align: center; }
.products-head {
display: flex; align-items: center; justify-content: space-between;
margin: 10px 0 6px; padding-top: 8px; border-top: 1px solid var(--border);
}
.products-head__title { font-size: 12px; font-weight: 600; color: var(--text); }
.products-head__hint { font-size: 10px; color: var(--text-muted); }
.ref-col { font-size: 10px; color: #92400e; background: #fffbeb; }
.divider-role {
margin: 8px 0; padding: 6px 8px; border-radius: 6px; font-size: 11px;
background: #f8fafc; border-left: 3px solid var(--border); color: var(--text-muted);
}
.divider-role strong { color: var(--text); }
.mini-plan {
border: 1px solid #a7f3d0; border-radius: 8px; padding: 8px; margin-bottom: 12px;
background: linear-gradient(180deg, #f0fdf9, #fff);
}
.pros-cons {
display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 14px;
}
.pros-cons > div {
border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; font-size: 12px;
}
.pros-cons h4 { margin: 0 0 6px; font-size: 12px; }
.pros-cons ul { margin: 0; padding-left: 18px; color: var(--text-muted); }
.highlight-box {
border: 2px dashed var(--warn); border-radius: 8px; padding: 8px;
margin-bottom: 8px; position: relative;
}
.highlight-box::before {
content: "重复区域"; position: absolute; top: -9px; left: 10px;
background: var(--warn-bg); color: var(--warn); font-size: 10px; font-weight: 700;
padding: 0 6px; border-radius: 4px;
}
@media (max-width: 1100px) {
.stops-split { grid-template-columns: 1fr; }
.stop-pane + .stop-pane { border-left: none; border-top: 1px solid var(--border); }
}
</style>
</head>
<body>
<div class="page">
<header class="hero">
<h1>合同产品 vs 段产品 · <em>去重设计 Demo</em></h1>
<p>
当前装货/送货窄栏内同时出现<strong>合同卡片产品表</strong>(CRM 合同明细,只读)和<strong>段内装货/送货产品表</strong>(可编辑计划数量),
字段高度重叠,用户难以区分「合同约束」与「本段实际操作量」。
</p>
<div class="pills">
<span class="pill warn">问题:同一 pane 内两张产品表</span>
<span class="pill">计划级产品信息仍保留全宽 10 列</span>
<span class="pill muted">段内只保留一张「可操作产品表」</span>
</div>
<div class="problem-diagram">
<div class="problem-box">
<h4>层级 ① 计划产品信息(全宽)</h4>
<strong>计划总量 · 可编辑</strong>
添加产品、别名品牌、计划数量<br />
<span class="dup">↑ 权威来源</span>
</div>
<div class="problem-box">
<h4>层级 ② 合同产品(段内卡片)</h4>
<strong>合同约束 · 只读</strong>
选合同后展开 CRM 合同明细表<br />
<span class="dup">与 ③ 字段重复</span>
</div>
<div class="problem-box">
<h4>层级 ③ 段产品(装货/送货)</h4>
<strong>本段分装 · 可编辑</strong>
同步计划产品、改段内计划数量<br />
<span class="dup">与 ② 字段重复</span>
</div>
</div>
</header>
<div class="scheme-tabs">
<button class="scheme-tab active" data-scheme="current" type="button">现状 · 双表并列</button>
<button class="scheme-tab recommended" data-scheme="chips" type="button">方案 A · 合同摘要 + 段产品表</button>
<button class="scheme-tab" data-scheme="collapse" type="button">方案 B · 合同可折叠</button>
<button class="scheme-tab" data-scheme="inline" type="button">方案 C · 合同量并入段表</button>
</div>
<!-- 现状 -->
<section class="scheme-panel active" id="panel-current">
<p class="scheme-desc warn">
<strong>现状问题:</strong>选合同后卡片内展开完整产品表(8~9 列),下方又有「装货产品」紧凑表,窄栏内纵向很长且信息重复。
</p>
<div class="dialog-sim">
<div class="dialog-sim__hd">编辑运输计划 · 现状</div>
<div class="dialog-sim__bd">
<div class="mini-plan">
<p class="layer-label"><span class="badge plan">计划层</span> 产品信息(全宽,略)</p>
<table class="data">
<thead><tr><th>产品</th><th>计划数量</th><th>包装</th><th>送货方式</th></tr></thead>
<tbody><tr><td>97% 精制硫酸</td><td class="num">30</td><td>槽罐</td><td>一票制</td></tr></tbody>
</table>
</div>
<p class="section-title">装卸货信息</p>
<div class="stops-split">
<div class="stop-pane stop-pane--load">
<div class="stop-pane__hd">装货信息</div>
<div class="stop-pane__bd">
<div class="party-row">
<div class="field"><label>装货客户</label><select><option>XX 硫酸供应商</option></select></div>
<div class="field"><label>装货合同</label><button class="btn ghost" style="width:100%">选合同</button></div>
</div>
<div class="highlight-box">
<p class="layer-label" style="margin-top:4px"><span class="badge contract">合同层</span> 合同卡片 · 带产品表</p>
<div class="contract-card">
<div class="contract-card__hd">
<span><span class="no">HT2026-001</span> · 采购合同 · 2 个产品</span>
<span><button class="btn link">查看</button> <button class="btn link" style="color:var(--danger)">移除</button></span>
</div>
<div class="table-scroll">
<table class="data wide">
<thead>
<tr><th>产品</th><th>别名</th><th>品牌</th><th>规格</th><th>数量</th><th>单位</th><th>包装</th><th>送货</th></tr>
</thead>
<tbody>
<tr><td>硫酸</td><td>工业硫酸</td><td>不限</td><td>CP</td><td class="num">50</td><td>吨</td><td>槽罐</td><td>一票制</td></tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="products-head" style="border-top:none;padding-top:0">
<span class="products-head__title">装货产品</span>
<button class="btn ghost">同步</button>
</div>
<p class="layer-label"><span class="badge stop">段层</span> 装货产品 · 紧凑表(又与上面重复)</p>
<table class="data">
<thead><tr><th>#</th><th>产品</th><th>计划数量</th><th>包装</th><th>送货方式</th></tr></thead>
<tbody>
<tr>
<td class="center">1</td>
<td>97% 精制硫酸<span class="subline">工业硫酸 · 不限 · CP · 吨</span></td>
<td class="num"><input value="30" style="width:100%;height:26px" /></td>
<td><select style="width:100%;height:26px"><option>槽罐</option></select></td>
<td><select style="width:100%;height:26px"><option>一票制</option></select></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="stop-pane stop-pane--delivery">
<div class="stop-pane__hd">送货信息(同理重复)</div>
<div class="stop-pane__bd">
<p style="font-size:12px;color:var(--text-muted);margin:20px 0">送货段同样:合同产品表 + 送货产品表 …</p>
</div>
</div>
</div>
</div>
</div>
<div class="pros-cons">
<div><h4>为何混乱</h4><ul><li>两张表列字段几乎相同</li><li>用户不知道改哪张</li><li>窄栏 + 合同表横向滚动</li></ul></div>
<div><h4>保留价值</h4><ul><li>合同表提供「合同约束数量」参照</li><li>需保留入口查看合同原文</li></ul></div>
</div>
</section>
<!-- 方案 A -->
<section class="scheme-panel" id="panel-chips">
<p class="scheme-desc ok">
<strong>推荐:</strong>段内<strong>不再展开合同产品表</strong>,合同区改为摘要 Chip(合同号 + 类型 + N 个产品 +「查看」弹窗)。
本 pane 内<strong>只保留一张「装货/送货产品」表</strong>作为唯一可操作清单。计划层「产品信息」仍是总量权威来源。
</p>
<div class="dialog-sim">
<div class="dialog-sim__hd">编辑运输计划 · 方案 A</div>
<div class="dialog-sim__bd">
<div class="mini-plan">
<p class="layer-label"><span class="badge plan">计划层</span> 产品信息 — 总量权威、添加/编辑产品</p>
<table class="data">
<thead><tr><th>产品</th><th>别名</th><th>品牌</th><th>计划数量</th><th>包装</th><th>送货方式</th></tr></thead>
<tbody><tr><td>97% 精制硫酸 <span class="tag danger">毒</span></td><td class="center">工业硫酸</td><td class="center">不限</td><td class="num">30</td><td>槽罐</td><td>一票制</td></tr></tbody>
</table>
</div>
<p class="section-title">装卸货信息</p>
<div class="stops-split">
<div class="stop-pane stop-pane--load">
<div class="stop-pane__hd">装货信息</div>
<div class="stop-pane__bd">
<div class="party-row">
<div class="field"><label>装货客户 *</label><select><option>XX 硫酸供应商</option></select></div>
<div class="field"><label>装货合同 *</label><button class="btn ghost" style="width:100%">选合同</button></div>
</div>
<p class="layer-label"><span class="badge contract">合同层</span> 仅摘要,不展开产品表</p>
<div class="contract-chips">
<div class="contract-chip">
<span class="contract-chip__no">HT2026-001</span>
<span class="contract-chip__meta">采购 · 2 产品</span>
<span class="contract-chip__actions">
<button class="btn link">查看合同</button>
<button class="btn link" style="color:var(--danger)">移除</button>
</span>
</div>
</div>
<p style="margin:0 0 8px;font-size:10px;color:var(--text-muted)">合同明细在「查看合同」弹窗中阅读,不占段内纵向空间</p>
<div class="grid-2">
<div class="field"><label>装货时间</label><input value="2026-08-26" /></div>
<div class="field"><label>联系方式</label><input value="张工" /></div>
<div class="field span-2"><label>装货地址</label><input value="安庆市 …" /></div>
</div>
<div class="products-head">
<div>
<span class="products-head__title">装货产品</span>
<span class="products-head__hint"> · 本段唯一产品表</span>
</div>
<button class="btn ghost">从计划同步</button>
</div>
<div class="divider-role"><strong>段层</strong>:编辑本段计划数量 / 包装 / 送货方式 / 备注</div>
<table class="data">
<thead><tr><th style="width:8%">#</th><th>产品</th><th style="width:22%">计划数量</th><th style="width:22%">包装</th><th style="width:22%">送货方式</th></tr></thead>
<tbody>
<tr>
<td class="center">1</td>
<td>97% 精制硫酸 <span class="tag danger">毒</span><span class="subline">工业硫酸 · 不限 · CP · 吨</span></td>
<td class="num"><input value="30" style="width:100%;height:26px" /></td>
<td><select style="width:100%;height:26px"><option>槽罐</option></select></td>
<td><select style="width:100%;height:26px"><option>一票制</option></select></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="stop-pane stop-pane--delivery">
<div class="stop-pane__hd">送货信息 · #1 客户甲</div>
<div class="stop-pane__bd">
<div class="party-row">
<div class="field"><label>送货客户</label><select><option>客户甲</option></select></div>
<div class="field"><label>送货合同</label><button class="btn ghost" style="width:100%">选合同</button></div>
</div>
<div class="contract-chips">
<div class="contract-chip" style="border-color:#bae6fd;background:#f0f9ff">
<span class="contract-chip__no" style="color:#0369a1">HT2026-002</span>
<span class="contract-chip__meta">销售 · 1 产品</span>
<button class="btn link">查看</button>
</div>
</div>
<div class="products-head">
<span class="products-head__title">送货产品</span>
<button class="btn ghost">同步</button>
</div>
<table class="data">
<thead><tr><th>#</th><th>产品</th><th>计划数量</th><th>包装</th><th>送货方式</th></tr></thead>
<tbody>
<tr><td class="center">1</td><td>97% 精制硫酸</td><td class="num"><input value="10" style="width:100%;height:26px" /></td><td>槽罐</td><td>一票制</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="pros-cons">
<div><h4>优点</h4><ul><li>段内<strong>只有一张产品表</strong>,认知清晰</li><li>合同仍可选、可查看、可移除</li><li>实现:PlPlanContractMultiSelect 增加 <code>compact</code> 模式隐藏 card body</li></ul></div>
<div><h4>注意</h4><ul><li>对照合同数量需点「查看合同」</li><li>内部客户免合同时 chips 区隐藏</li></ul></div>
</div>
</section>
<!-- 方案 B -->
<section class="scheme-panel" id="panel-collapse">
<p class="scheme-desc">
合同卡片保留,但<strong>默认折叠</strong>只显示合同号摘要;用户需要对照时再「展开合同产品」。
段产品表始终可见。比现状省高度,但仍有两张表。
</p>
<div class="dialog-sim">
<div class="dialog-sim__hd">方案 B · 合同默认折叠</div>
<div class="dialog-sim__bd">
<div class="stops-split" style="min-height:280px">
<div class="stop-pane stop-pane--load">
<div class="stop-pane__hd">装货信息</div>
<div class="stop-pane__bd">
<div class="party-row">
<div class="field"><label>装货客户</label><select><option>XX 供应商</option></select></div>
<div class="field"><label>装货合同</label><button class="btn ghost" style="width:100%">选合同</button></div>
</div>
<div class="contract-collapse" id="collapseDemo">
<div class="contract-collapse__hd" onclick="toggleCollapse()">
<span><strong>HT2026-001</strong> · 采购 · 2 产品</span>
<span><button class="btn link">查看</button> <span class="contract-collapse__toggle">▼ 展开合同产品</span></span>
</div>
<div class="contract-collapse__bd">
<table class="data" style="margin-top:6px">
<thead><tr><th>产品</th><th>合同数量</th><th>单位</th></tr></thead>
<tbody><tr><td>硫酸</td><td class="num">50</td><td>吨</td></tr></tbody>
</table>
</div>
</div>
<div class="products-head">
<span class="products-head__title">装货产品(主表)</span>
<button class="btn ghost">同步</button>
</div>
<table class="data">
<thead><tr><th>#</th><th>产品</th><th>计划数量</th><th>包装</th></tr></thead>
<tbody><tr><td>1</td><td>硫酸</td><td class="num"><input value="30" style="width:100%;height:26px" /></td><td>槽罐</td></tr></tbody>
</table>
</div>
</div>
<div class="stop-pane stop-pane--delivery"><div class="stop-pane__hd">送货</div><div class="stop-pane__bd"><p style="color:var(--text-muted);font-size:12px">同上</p></div></div>
</div>
</div>
</div>
<div class="pros-cons">
<div><h4>优点</h4><ul><li>改动小,保留合同 inline 对照能力</li><li>默认界面更干净</li></ul></div>
<div><h4>缺点</h4><ul><li>展开后仍重复</li><li>折叠状态用户可能找不到合同量</li></ul></div>
</div>
</section>
<!-- 方案 C -->
<section class="scheme-panel" id="panel-inline">
<p class="scheme-desc">
取消合同卡片产品表;在<strong>段产品表增加「合同数量」只读列</strong>(选合同后自动匹配产品行带入)。
一张表同时看到约束与操作量。适合强约束「段数量 ≤ 合同余量」场景。
</p>
<div class="dialog-sim">
<div class="dialog-sim__hd">方案 C · 合同量并入段表</div>
<div class="dialog-sim__bd">
<div class="stops-split" style="min-height:280px">
<div class="stop-pane stop-pane--load">
<div class="stop-pane__hd">装货信息</div>
<div class="stop-pane__bd">
<div class="party-row">
<div class="field"><label>装货客户</label><select><option>XX 供应商</option></select></div>
<div class="field"><label>装货合同</label><button class="btn ghost" style="width:100%">HT2026-001 ✓</button></div>
</div>
<div class="products-head" style="border-top:none;padding-top:0">
<span class="products-head__title">装货产品(含合同参照)</span>
<button class="btn ghost">同步</button>
</div>
<table class="data">
<thead>
<tr>
<th style="width:8%">#</th>
<th>产品</th>
<th style="width:18%" class="ref-col">合同数量</th>
<th style="width:18%">本段数量</th>
<th style="width:18%">包装</th>
</tr>
</thead>
<tbody>
<tr>
<td class="center">1</td>
<td>97% 精制硫酸<span class="subline">工业硫酸 · CP · 吨</span></td>
<td class="num ref-col">50</td>
<td class="num"><input value="30" style="width:100%;height:26px" /></td>
<td><select style="width:100%;height:26px"><option>槽罐</option></select></td>
</tr>
</tbody>
</table>
<p style="margin:6px 0 0;font-size:10px;color:var(--text-muted)">合同数量列只读;多合同合并时取汇总或分合同 Tab</p>
</div>
</div>
<div class="stop-pane stop-pane--delivery"><div class="stop-pane__hd">送货</div><div class="stop-pane__bd"><p style="color:var(--text-muted);font-size:12px">同上</p></div></div>
</div>
</div>
</div>
<div class="pros-cons">
<div><h4>优点</h4><ul><li>一表看清约束 vs 操作量</li><li>便于做超量校验提示</li></ul></div>
<div><h4>缺点</h4><ul><li>窄栏多一列,仍可能挤</li><li>多合同多产品匹配逻辑复杂</li></ul></div>
</div>
</section>
<!-- 三层职责总结 -->
<section style="margin-top:20px;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:16px 18px;box-shadow:var(--shadow)">
<h2 style="margin:0 0 12px;font-size:16px">推荐信息架构(方案 A)</h2>
<table class="data" style="font-size:12px">
<thead>
<tr><th style="width:18%">层级</th><th style="width:22%">区域</th><th>展示什么</th><th style="width:18%">是否产品表</th></tr>
</thead>
<tbody>
<tr>
<td><span class="badge plan">计划</span></td>
<td>产品信息(全宽)</td>
<td>计划总量、添加产品、别名品牌编辑</td>
<td class="center">完整 10 列</td>
</tr>
<tr>
<td><span class="badge contract">合同</span></td>
<td>段内合同区</td>
<td>Chip:合同号 + 类型 + 产品数 + 查看/移除</td>
<td class="center"><strong>不展示</strong></td>
</tr>
<tr>
<td><span class="badge stop">段</span></td>
<td>装货/送货产品</td>
<td>本段分装数量、包装、送货方式(从计划同步)</td>
<td class="center">紧凑 5 列</td>
</tr>
</tbody>
</table>
</section>
</div>
<script>
document.querySelectorAll('.scheme-tab').forEach((tab) => {
tab.addEventListener('click', () => {
const scheme = tab.dataset.scheme
document.querySelectorAll('.scheme-tab').forEach((t) => t.classList.toggle('active', t === tab))
document.querySelectorAll('.scheme-panel').forEach((p) => p.classList.toggle('active', p.id === `panel-${scheme}`))
})
})
function toggleCollapse() {
document.getElementById('collapseDemo')?.classList.toggle('is-open')
}
document.documentElement.style.setProperty('--dialog-max', '1280px')
</script>
</body>
</html>