637 lines
32 KiB
HTML
637 lines
32 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>运输计划 · 合同产品与段产品去重 Demo</title>
|
||
<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>
|