fresh-mint-pl-plan-stop-products-vs-contract-demo.html 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. <!doctype html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>运输计划 · 合同产品与段产品去重 Demo</title>
  7. <link rel="preconnect" href="https://fonts.googleapis.com" />
  8. <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  9. <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
  10. <style>
  11. :root {
  12. --primary: #10b981;
  13. --primary-dark: #059669;
  14. --primary-bg: #ecfdf5;
  15. --text: #1e293b;
  16. --text-muted: #64748b;
  17. --border: #d9e8e2;
  18. --table-head: #f8fafc;
  19. --row-alt: #fafafa;
  20. --bg-page: #f1f5f9;
  21. --shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  22. --shadow-lg: 0 12px 40px rgba(15, 23, 42, 0.14);
  23. --radius: 10px;
  24. --warn: #d97706;
  25. --warn-bg: #fffbeb;
  26. --danger: #dc2626;
  27. --info: #0284c7;
  28. --info-bg: #f0f9ff;
  29. --delivery-accent: #0284c7;
  30. --delivery-bg: #f0f9ff;
  31. --dialog-max: 1280px;
  32. }
  33. * { box-sizing: border-box; }
  34. body {
  35. margin: 0; min-height: 100vh;
  36. font-family: Inter, -apple-system, BlinkMacSystemFont, sans-serif;
  37. font-size: 14px; line-height: 1.5; color: var(--text); background: var(--bg-page);
  38. }
  39. .page { max-width: 1440px; margin: 0 auto; padding: 24px 20px 80px; }
  40. .hero {
  41. background: linear-gradient(135deg, #ecfdf5 0%, #fff 50%, #fffbeb 100%);
  42. border: 1px solid var(--border); border-radius: var(--radius);
  43. padding: 22px 24px; margin-bottom: 18px; box-shadow: var(--shadow);
  44. }
  45. .hero h1 { margin: 0 0 8px; font-size: 22px; font-weight: 700; }
  46. .hero h1 em { font-style: normal; color: var(--primary-dark); }
  47. .hero p { margin: 0; color: var(--text-muted); max-width: 980px; }
  48. .pills { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
  49. .pill {
  50. display: inline-flex; padding: 4px 10px; border-radius: 999px;
  51. font-size: 12px; font-weight: 500;
  52. background: var(--primary-bg); color: var(--primary-dark); border: 1px solid #a7f3d0;
  53. }
  54. .pill.warn { background: var(--warn-bg); color: var(--warn); border-color: rgba(217,119,6,.25); }
  55. .pill.muted { background: #f1f5f9; color: var(--text-muted); border-color: #e2e8f0; }
  56. .problem-diagram {
  57. display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
  58. margin-top: 16px;
  59. }
  60. @media (max-width: 900px) { .problem-diagram { grid-template-columns: 1fr; } }
  61. .problem-box {
  62. border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px;
  63. background: #fff; font-size: 12px;
  64. }
  65. .problem-box h4 { margin: 0 0 6px; font-size: 12px; color: var(--text-muted); }
  66. .problem-box strong { display: block; margin-bottom: 4px; }
  67. .problem-box .dup { color: var(--warn); font-weight: 600; }
  68. .scheme-tabs {
  69. display: flex; flex-wrap: wrap; gap: 6px;
  70. background: #fff; border: 1px solid var(--border);
  71. border-radius: var(--radius) var(--radius) 0 0; padding: 10px 12px 0;
  72. }
  73. .scheme-tab {
  74. border: none; background: transparent; cursor: pointer;
  75. padding: 10px 14px; font-size: 13px; font-weight: 600;
  76. color: var(--text-muted); border-bottom: 2px solid transparent; font-family: inherit;
  77. }
  78. .scheme-tab.active { color: var(--primary-dark); border-bottom-color: var(--primary); }
  79. .scheme-tab.recommended::after {
  80. content: "推荐"; margin-left: 6px; font-size: 10px; font-weight: 700;
  81. color: #fff; background: var(--primary-dark); padding: 1px 6px; border-radius: 999px;
  82. }
  83. .scheme-panel {
  84. display: none; background: #fff; border: 1px solid var(--border); border-top: none;
  85. border-radius: 0 0 var(--radius) var(--radius); padding: 16px 18px 22px; box-shadow: var(--shadow);
  86. }
  87. .scheme-panel.active { display: block; }
  88. .scheme-desc {
  89. margin: 0 0 14px; padding: 10px 12px; border-radius: 8px; font-size: 12px;
  90. border: 1px solid #bae6fd; background: var(--info-bg); color: #0369a1;
  91. }
  92. .scheme-desc.ok { border-color: #a7f3d0; background: var(--primary-bg); color: var(--primary-dark); }
  93. .scheme-desc.warn { border-color: rgba(217,119,6,.3); background: var(--warn-bg); color: #92400e; }
  94. .dialog-sim {
  95. width: var(--dialog-max); max-width: 100%; margin: 0 auto;
  96. border: 1px solid var(--border); border-radius: var(--radius);
  97. background: #fff; box-shadow: var(--shadow-lg); overflow: hidden;
  98. }
  99. .dialog-sim__hd { padding: 14px 18px; border-bottom: 1px solid var(--border); font-weight: 700; }
  100. .dialog-sim__bd { padding: 16px 18px 20px; background: #fafcfb; }
  101. .layer-label {
  102. font-size: 11px; font-weight: 600; color: var(--text-muted);
  103. margin: 0 0 6px; display: flex; align-items: center; gap: 6px;
  104. }
  105. .layer-label .badge {
  106. padding: 1px 6px; border-radius: 4px; font-size: 10px;
  107. background: #f1f5f9; border: 1px solid #e2e8f0;
  108. }
  109. .layer-label .badge.plan { background: var(--primary-bg); color: var(--primary-dark); border-color: #a7f3d0; }
  110. .layer-label .badge.contract { background: #fef3c7; color: #92400e; border-color: #fcd34d; }
  111. .layer-label .badge.stop { background: var(--info-bg); color: var(--info); border-color: #bae6fd; }
  112. .section { margin-bottom: 14px; }
  113. .section-title {
  114. margin: 0 0 8px; font-size: 14px; font-weight: 700;
  115. display: flex; align-items: center; gap: 8px;
  116. }
  117. .section-title::before {
  118. content: ""; width: 3px; height: 14px; border-radius: 2px; background: var(--primary);
  119. }
  120. /* 装卸货分栏 */
  121. .stops-split {
  122. display: grid; grid-template-columns: 1fr 1fr;
  123. border: 1px solid var(--border); border-radius: var(--radius);
  124. overflow: hidden; background: #fff; min-height: 320px;
  125. }
  126. .stop-pane { display: flex; flex-direction: column; min-width: 0; }
  127. .stop-pane + .stop-pane { border-left: 1px solid var(--border); }
  128. .stop-pane__hd {
  129. padding: 10px 12px; border-bottom: 1px solid var(--border);
  130. font-size: 13px; font-weight: 700; flex-shrink: 0;
  131. }
  132. .stop-pane--load .stop-pane__hd { background: linear-gradient(180deg, #ecfdf5, #f8fffc); }
  133. .stop-pane--delivery .stop-pane__hd { background: linear-gradient(180deg, #f0f9ff, #f8fcff); }
  134. .stop-pane__bd { padding: 12px; flex: 1; overflow: auto; }
  135. .party-row { display: grid; grid-template-columns: 1.2fr 0.8fr; gap: 10px; margin-bottom: 8px; }
  136. .field label { display: block; font-size: 11px; color: var(--text-muted); margin-bottom: 4px; }
  137. .field input, .field select {
  138. width: 100%; height: 34px; border: 1px solid var(--border);
  139. border-radius: 8px; padding: 0 8px; font: inherit;
  140. }
  141. .grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 8px; }
  142. .span-2 { grid-column: span 2; }
  143. .btn {
  144. display: inline-flex; align-items: center; gap: 4px; height: 28px; padding: 0 10px;
  145. border-radius: 8px; border: 1px solid var(--border); background: #fff;
  146. font: inherit; font-weight: 600; font-size: 11px; cursor: pointer;
  147. }
  148. .btn.ghost { background: #fff; }
  149. .btn.link { border: none; background: none; color: var(--info); padding: 0 4px; height: auto; }
  150. /* 合同卡片 - 现状(带产品表) */
  151. .contract-card {
  152. border: 1px solid var(--border); border-radius: 8px; margin-bottom: 8px; overflow: hidden;
  153. }
  154. .contract-card__hd {
  155. display: flex; justify-content: space-between; align-items: center;
  156. padding: 8px 10px; background: var(--table-head); border-bottom: 1px solid var(--border);
  157. font-size: 12px;
  158. }
  159. .contract-card__hd .no { font-weight: 700; }
  160. .tag {
  161. display: inline-flex; padding: 1px 6px; border-radius: 4px;
  162. font-size: 10px; font-weight: 600;
  163. }
  164. .tag.amber { background: #d97706; color: #fff; }
  165. .tag.danger { background: var(--danger); color: #fff; }
  166. /* 合同摘要 chips(推荐方案) */
  167. .contract-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
  168. .contract-chip {
  169. display: inline-flex; align-items: center; gap: 6px;
  170. padding: 6px 10px; border: 1px solid #fcd34d; border-radius: 8px;
  171. background: #fffbeb; font-size: 11px;
  172. }
  173. .contract-chip__no { font-weight: 700; color: #92400e; }
  174. .contract-chip__meta { color: var(--text-muted); }
  175. .contract-chip__actions { display: flex; gap: 4px; margin-left: 4px; }
  176. /* 折叠合同 */
  177. .contract-collapse { border: 1px solid var(--border); border-radius: 8px; margin-bottom: 8px; }
  178. .contract-collapse__hd {
  179. display: flex; justify-content: space-between; align-items: center;
  180. padding: 8px 10px; cursor: pointer; font-size: 12px; background: #fff;
  181. }
  182. .contract-collapse__hd:hover { background: var(--table-head); }
  183. .contract-collapse__bd { display: none; padding: 0 8px 8px; border-top: 1px dashed var(--border); }
  184. .contract-collapse.is-open .contract-collapse__bd { display: block; }
  185. .contract-collapse.is-open .contract-collapse__toggle { transform: rotate(180deg); }
  186. table.data {
  187. width: 100%; border-collapse: collapse; font-size: 11px; table-layout: fixed;
  188. }
  189. table.data th, table.data td {
  190. border-bottom: 1px solid var(--border); padding: 5px 6px; text-align: left;
  191. }
  192. table.data th { background: var(--table-head); color: var(--text-muted); font-size: 10px; font-weight: 600; }
  193. table.data tr:last-child td { border-bottom: none; }
  194. table.data.wide { min-width: 520px; }
  195. .table-scroll { overflow-x: auto; border: 1px solid var(--border); border-radius: 6px; }
  196. .table-scroll::after {
  197. content: "← 合同产品表横向滚动 →"; display: block; text-align: center;
  198. font-size: 10px; color: var(--warn); background: var(--warn-bg); padding: 3px;
  199. }
  200. .subline { display: block; font-size: 10px; color: var(--text-muted); margin-top: 2px; }
  201. .num { text-align: right; }
  202. .center { text-align: center; }
  203. .products-head {
  204. display: flex; align-items: center; justify-content: space-between;
  205. margin: 10px 0 6px; padding-top: 8px; border-top: 1px solid var(--border);
  206. }
  207. .products-head__title { font-size: 12px; font-weight: 600; color: var(--text); }
  208. .products-head__hint { font-size: 10px; color: var(--text-muted); }
  209. .ref-col { font-size: 10px; color: #92400e; background: #fffbeb; }
  210. .divider-role {
  211. margin: 8px 0; padding: 6px 8px; border-radius: 6px; font-size: 11px;
  212. background: #f8fafc; border-left: 3px solid var(--border); color: var(--text-muted);
  213. }
  214. .divider-role strong { color: var(--text); }
  215. .mini-plan {
  216. border: 1px solid #a7f3d0; border-radius: 8px; padding: 8px; margin-bottom: 12px;
  217. background: linear-gradient(180deg, #f0fdf9, #fff);
  218. }
  219. .pros-cons {
  220. display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 14px;
  221. }
  222. .pros-cons > div {
  223. border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; font-size: 12px;
  224. }
  225. .pros-cons h4 { margin: 0 0 6px; font-size: 12px; }
  226. .pros-cons ul { margin: 0; padding-left: 18px; color: var(--text-muted); }
  227. .highlight-box {
  228. border: 2px dashed var(--warn); border-radius: 8px; padding: 8px;
  229. margin-bottom: 8px; position: relative;
  230. }
  231. .highlight-box::before {
  232. content: "重复区域"; position: absolute; top: -9px; left: 10px;
  233. background: var(--warn-bg); color: var(--warn); font-size: 10px; font-weight: 700;
  234. padding: 0 6px; border-radius: 4px;
  235. }
  236. @media (max-width: 1100px) {
  237. .stops-split { grid-template-columns: 1fr; }
  238. .stop-pane + .stop-pane { border-left: none; border-top: 1px solid var(--border); }
  239. }
  240. </style>
  241. </head>
  242. <body>
  243. <div class="page">
  244. <header class="hero">
  245. <h1>合同产品 vs 段产品 · <em>去重设计 Demo</em></h1>
  246. <p>
  247. 当前装货/送货窄栏内同时出现<strong>合同卡片产品表</strong>(CRM 合同明细,只读)和<strong>段内装货/送货产品表</strong>(可编辑计划数量),
  248. 字段高度重叠,用户难以区分「合同约束」与「本段实际操作量」。
  249. </p>
  250. <div class="pills">
  251. <span class="pill warn">问题:同一 pane 内两张产品表</span>
  252. <span class="pill">计划级产品信息仍保留全宽 10 列</span>
  253. <span class="pill muted">段内只保留一张「可操作产品表」</span>
  254. </div>
  255. <div class="problem-diagram">
  256. <div class="problem-box">
  257. <h4>层级 ① 计划产品信息(全宽)</h4>
  258. <strong>计划总量 · 可编辑</strong>
  259. 添加产品、别名品牌、计划数量<br />
  260. <span class="dup">↑ 权威来源</span>
  261. </div>
  262. <div class="problem-box">
  263. <h4>层级 ② 合同产品(段内卡片)</h4>
  264. <strong>合同约束 · 只读</strong>
  265. 选合同后展开 CRM 合同明细表<br />
  266. <span class="dup">与 ③ 字段重复</span>
  267. </div>
  268. <div class="problem-box">
  269. <h4>层级 ③ 段产品(装货/送货)</h4>
  270. <strong>本段分装 · 可编辑</strong>
  271. 同步计划产品、改段内计划数量<br />
  272. <span class="dup">与 ② 字段重复</span>
  273. </div>
  274. </div>
  275. </header>
  276. <div class="scheme-tabs">
  277. <button class="scheme-tab active" data-scheme="current" type="button">现状 · 双表并列</button>
  278. <button class="scheme-tab recommended" data-scheme="chips" type="button">方案 A · 合同摘要 + 段产品表</button>
  279. <button class="scheme-tab" data-scheme="collapse" type="button">方案 B · 合同可折叠</button>
  280. <button class="scheme-tab" data-scheme="inline" type="button">方案 C · 合同量并入段表</button>
  281. </div>
  282. <!-- 现状 -->
  283. <section class="scheme-panel active" id="panel-current">
  284. <p class="scheme-desc warn">
  285. <strong>现状问题:</strong>选合同后卡片内展开完整产品表(8~9 列),下方又有「装货产品」紧凑表,窄栏内纵向很长且信息重复。
  286. </p>
  287. <div class="dialog-sim">
  288. <div class="dialog-sim__hd">编辑运输计划 · 现状</div>
  289. <div class="dialog-sim__bd">
  290. <div class="mini-plan">
  291. <p class="layer-label"><span class="badge plan">计划层</span> 产品信息(全宽,略)</p>
  292. <table class="data">
  293. <thead><tr><th>产品</th><th>计划数量</th><th>包装</th><th>送货方式</th></tr></thead>
  294. <tbody><tr><td>97% 精制硫酸</td><td class="num">30</td><td>槽罐</td><td>一票制</td></tr></tbody>
  295. </table>
  296. </div>
  297. <p class="section-title">装卸货信息</p>
  298. <div class="stops-split">
  299. <div class="stop-pane stop-pane--load">
  300. <div class="stop-pane__hd">装货信息</div>
  301. <div class="stop-pane__bd">
  302. <div class="party-row">
  303. <div class="field"><label>装货客户</label><select><option>XX 硫酸供应商</option></select></div>
  304. <div class="field"><label>装货合同</label><button class="btn ghost" style="width:100%">选合同</button></div>
  305. </div>
  306. <div class="highlight-box">
  307. <p class="layer-label" style="margin-top:4px"><span class="badge contract">合同层</span> 合同卡片 · 带产品表</p>
  308. <div class="contract-card">
  309. <div class="contract-card__hd">
  310. <span><span class="no">HT2026-001</span> · 采购合同 · 2 个产品</span>
  311. <span><button class="btn link">查看</button> <button class="btn link" style="color:var(--danger)">移除</button></span>
  312. </div>
  313. <div class="table-scroll">
  314. <table class="data wide">
  315. <thead>
  316. <tr><th>产品</th><th>别名</th><th>品牌</th><th>规格</th><th>数量</th><th>单位</th><th>包装</th><th>送货</th></tr>
  317. </thead>
  318. <tbody>
  319. <tr><td>硫酸</td><td>工业硫酸</td><td>不限</td><td>CP</td><td class="num">50</td><td>吨</td><td>槽罐</td><td>一票制</td></tr>
  320. </tbody>
  321. </table>
  322. </div>
  323. </div>
  324. </div>
  325. <div class="products-head" style="border-top:none;padding-top:0">
  326. <span class="products-head__title">装货产品</span>
  327. <button class="btn ghost">同步</button>
  328. </div>
  329. <p class="layer-label"><span class="badge stop">段层</span> 装货产品 · 紧凑表(又与上面重复)</p>
  330. <table class="data">
  331. <thead><tr><th>#</th><th>产品</th><th>计划数量</th><th>包装</th><th>送货方式</th></tr></thead>
  332. <tbody>
  333. <tr>
  334. <td class="center">1</td>
  335. <td>97% 精制硫酸<span class="subline">工业硫酸 · 不限 · CP · 吨</span></td>
  336. <td class="num"><input value="30" style="width:100%;height:26px" /></td>
  337. <td><select style="width:100%;height:26px"><option>槽罐</option></select></td>
  338. <td><select style="width:100%;height:26px"><option>一票制</option></select></td>
  339. </tr>
  340. </tbody>
  341. </table>
  342. </div>
  343. </div>
  344. <div class="stop-pane stop-pane--delivery">
  345. <div class="stop-pane__hd">送货信息(同理重复)</div>
  346. <div class="stop-pane__bd">
  347. <p style="font-size:12px;color:var(--text-muted);margin:20px 0">送货段同样:合同产品表 + 送货产品表 …</p>
  348. </div>
  349. </div>
  350. </div>
  351. </div>
  352. </div>
  353. <div class="pros-cons">
  354. <div><h4>为何混乱</h4><ul><li>两张表列字段几乎相同</li><li>用户不知道改哪张</li><li>窄栏 + 合同表横向滚动</li></ul></div>
  355. <div><h4>保留价值</h4><ul><li>合同表提供「合同约束数量」参照</li><li>需保留入口查看合同原文</li></ul></div>
  356. </div>
  357. </section>
  358. <!-- 方案 A -->
  359. <section class="scheme-panel" id="panel-chips">
  360. <p class="scheme-desc ok">
  361. <strong>推荐:</strong>段内<strong>不再展开合同产品表</strong>,合同区改为摘要 Chip(合同号 + 类型 + N 个产品 +「查看」弹窗)。
  362. 本 pane 内<strong>只保留一张「装货/送货产品」表</strong>作为唯一可操作清单。计划层「产品信息」仍是总量权威来源。
  363. </p>
  364. <div class="dialog-sim">
  365. <div class="dialog-sim__hd">编辑运输计划 · 方案 A</div>
  366. <div class="dialog-sim__bd">
  367. <div class="mini-plan">
  368. <p class="layer-label"><span class="badge plan">计划层</span> 产品信息 — 总量权威、添加/编辑产品</p>
  369. <table class="data">
  370. <thead><tr><th>产品</th><th>别名</th><th>品牌</th><th>计划数量</th><th>包装</th><th>送货方式</th></tr></thead>
  371. <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>
  372. </table>
  373. </div>
  374. <p class="section-title">装卸货信息</p>
  375. <div class="stops-split">
  376. <div class="stop-pane stop-pane--load">
  377. <div class="stop-pane__hd">装货信息</div>
  378. <div class="stop-pane__bd">
  379. <div class="party-row">
  380. <div class="field"><label>装货客户 *</label><select><option>XX 硫酸供应商</option></select></div>
  381. <div class="field"><label>装货合同 *</label><button class="btn ghost" style="width:100%">选合同</button></div>
  382. </div>
  383. <p class="layer-label"><span class="badge contract">合同层</span> 仅摘要,不展开产品表</p>
  384. <div class="contract-chips">
  385. <div class="contract-chip">
  386. <span class="contract-chip__no">HT2026-001</span>
  387. <span class="contract-chip__meta">采购 · 2 产品</span>
  388. <span class="contract-chip__actions">
  389. <button class="btn link">查看合同</button>
  390. <button class="btn link" style="color:var(--danger)">移除</button>
  391. </span>
  392. </div>
  393. </div>
  394. <p style="margin:0 0 8px;font-size:10px;color:var(--text-muted)">合同明细在「查看合同」弹窗中阅读,不占段内纵向空间</p>
  395. <div class="grid-2">
  396. <div class="field"><label>装货时间</label><input value="2026-08-26" /></div>
  397. <div class="field"><label>联系方式</label><input value="张工" /></div>
  398. <div class="field span-2"><label>装货地址</label><input value="安庆市 …" /></div>
  399. </div>
  400. <div class="products-head">
  401. <div>
  402. <span class="products-head__title">装货产品</span>
  403. <span class="products-head__hint"> · 本段唯一产品表</span>
  404. </div>
  405. <button class="btn ghost">从计划同步</button>
  406. </div>
  407. <div class="divider-role"><strong>段层</strong>:编辑本段计划数量 / 包装 / 送货方式 / 备注</div>
  408. <table class="data">
  409. <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>
  410. <tbody>
  411. <tr>
  412. <td class="center">1</td>
  413. <td>97% 精制硫酸 <span class="tag danger">毒</span><span class="subline">工业硫酸 · 不限 · CP · 吨</span></td>
  414. <td class="num"><input value="30" style="width:100%;height:26px" /></td>
  415. <td><select style="width:100%;height:26px"><option>槽罐</option></select></td>
  416. <td><select style="width:100%;height:26px"><option>一票制</option></select></td>
  417. </tr>
  418. </tbody>
  419. </table>
  420. </div>
  421. </div>
  422. <div class="stop-pane stop-pane--delivery">
  423. <div class="stop-pane__hd">送货信息 · #1 客户甲</div>
  424. <div class="stop-pane__bd">
  425. <div class="party-row">
  426. <div class="field"><label>送货客户</label><select><option>客户甲</option></select></div>
  427. <div class="field"><label>送货合同</label><button class="btn ghost" style="width:100%">选合同</button></div>
  428. </div>
  429. <div class="contract-chips">
  430. <div class="contract-chip" style="border-color:#bae6fd;background:#f0f9ff">
  431. <span class="contract-chip__no" style="color:#0369a1">HT2026-002</span>
  432. <span class="contract-chip__meta">销售 · 1 产品</span>
  433. <button class="btn link">查看</button>
  434. </div>
  435. </div>
  436. <div class="products-head">
  437. <span class="products-head__title">送货产品</span>
  438. <button class="btn ghost">同步</button>
  439. </div>
  440. <table class="data">
  441. <thead><tr><th>#</th><th>产品</th><th>计划数量</th><th>包装</th><th>送货方式</th></tr></thead>
  442. <tbody>
  443. <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>
  444. </tbody>
  445. </table>
  446. </div>
  447. </div>
  448. </div>
  449. </div>
  450. </div>
  451. <div class="pros-cons">
  452. <div><h4>优点</h4><ul><li>段内<strong>只有一张产品表</strong>,认知清晰</li><li>合同仍可选、可查看、可移除</li><li>实现:PlPlanContractMultiSelect 增加 <code>compact</code> 模式隐藏 card body</li></ul></div>
  453. <div><h4>注意</h4><ul><li>对照合同数量需点「查看合同」</li><li>内部客户免合同时 chips 区隐藏</li></ul></div>
  454. </div>
  455. </section>
  456. <!-- 方案 B -->
  457. <section class="scheme-panel" id="panel-collapse">
  458. <p class="scheme-desc">
  459. 合同卡片保留,但<strong>默认折叠</strong>只显示合同号摘要;用户需要对照时再「展开合同产品」。
  460. 段产品表始终可见。比现状省高度,但仍有两张表。
  461. </p>
  462. <div class="dialog-sim">
  463. <div class="dialog-sim__hd">方案 B · 合同默认折叠</div>
  464. <div class="dialog-sim__bd">
  465. <div class="stops-split" style="min-height:280px">
  466. <div class="stop-pane stop-pane--load">
  467. <div class="stop-pane__hd">装货信息</div>
  468. <div class="stop-pane__bd">
  469. <div class="party-row">
  470. <div class="field"><label>装货客户</label><select><option>XX 供应商</option></select></div>
  471. <div class="field"><label>装货合同</label><button class="btn ghost" style="width:100%">选合同</button></div>
  472. </div>
  473. <div class="contract-collapse" id="collapseDemo">
  474. <div class="contract-collapse__hd" onclick="toggleCollapse()">
  475. <span><strong>HT2026-001</strong> · 采购 · 2 产品</span>
  476. <span><button class="btn link">查看</button> <span class="contract-collapse__toggle">▼ 展开合同产品</span></span>
  477. </div>
  478. <div class="contract-collapse__bd">
  479. <table class="data" style="margin-top:6px">
  480. <thead><tr><th>产品</th><th>合同数量</th><th>单位</th></tr></thead>
  481. <tbody><tr><td>硫酸</td><td class="num">50</td><td>吨</td></tr></tbody>
  482. </table>
  483. </div>
  484. </div>
  485. <div class="products-head">
  486. <span class="products-head__title">装货产品(主表)</span>
  487. <button class="btn ghost">同步</button>
  488. </div>
  489. <table class="data">
  490. <thead><tr><th>#</th><th>产品</th><th>计划数量</th><th>包装</th></tr></thead>
  491. <tbody><tr><td>1</td><td>硫酸</td><td class="num"><input value="30" style="width:100%;height:26px" /></td><td>槽罐</td></tr></tbody>
  492. </table>
  493. </div>
  494. </div>
  495. <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>
  496. </div>
  497. </div>
  498. </div>
  499. <div class="pros-cons">
  500. <div><h4>优点</h4><ul><li>改动小,保留合同 inline 对照能力</li><li>默认界面更干净</li></ul></div>
  501. <div><h4>缺点</h4><ul><li>展开后仍重复</li><li>折叠状态用户可能找不到合同量</li></ul></div>
  502. </div>
  503. </section>
  504. <!-- 方案 C -->
  505. <section class="scheme-panel" id="panel-inline">
  506. <p class="scheme-desc">
  507. 取消合同卡片产品表;在<strong>段产品表增加「合同数量」只读列</strong>(选合同后自动匹配产品行带入)。
  508. 一张表同时看到约束与操作量。适合强约束「段数量 ≤ 合同余量」场景。
  509. </p>
  510. <div class="dialog-sim">
  511. <div class="dialog-sim__hd">方案 C · 合同量并入段表</div>
  512. <div class="dialog-sim__bd">
  513. <div class="stops-split" style="min-height:280px">
  514. <div class="stop-pane stop-pane--load">
  515. <div class="stop-pane__hd">装货信息</div>
  516. <div class="stop-pane__bd">
  517. <div class="party-row">
  518. <div class="field"><label>装货客户</label><select><option>XX 供应商</option></select></div>
  519. <div class="field"><label>装货合同</label><button class="btn ghost" style="width:100%">HT2026-001 ✓</button></div>
  520. </div>
  521. <div class="products-head" style="border-top:none;padding-top:0">
  522. <span class="products-head__title">装货产品(含合同参照)</span>
  523. <button class="btn ghost">同步</button>
  524. </div>
  525. <table class="data">
  526. <thead>
  527. <tr>
  528. <th style="width:8%">#</th>
  529. <th>产品</th>
  530. <th style="width:18%" class="ref-col">合同数量</th>
  531. <th style="width:18%">本段数量</th>
  532. <th style="width:18%">包装</th>
  533. </tr>
  534. </thead>
  535. <tbody>
  536. <tr>
  537. <td class="center">1</td>
  538. <td>97% 精制硫酸<span class="subline">工业硫酸 · CP · 吨</span></td>
  539. <td class="num ref-col">50</td>
  540. <td class="num"><input value="30" style="width:100%;height:26px" /></td>
  541. <td><select style="width:100%;height:26px"><option>槽罐</option></select></td>
  542. </tr>
  543. </tbody>
  544. </table>
  545. <p style="margin:6px 0 0;font-size:10px;color:var(--text-muted)">合同数量列只读;多合同合并时取汇总或分合同 Tab</p>
  546. </div>
  547. </div>
  548. <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>
  549. </div>
  550. </div>
  551. </div>
  552. <div class="pros-cons">
  553. <div><h4>优点</h4><ul><li>一表看清约束 vs 操作量</li><li>便于做超量校验提示</li></ul></div>
  554. <div><h4>缺点</h4><ul><li>窄栏多一列,仍可能挤</li><li>多合同多产品匹配逻辑复杂</li></ul></div>
  555. </div>
  556. </section>
  557. <!-- 三层职责总结 -->
  558. <section style="margin-top:20px;background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:16px 18px;box-shadow:var(--shadow)">
  559. <h2 style="margin:0 0 12px;font-size:16px">推荐信息架构(方案 A)</h2>
  560. <table class="data" style="font-size:12px">
  561. <thead>
  562. <tr><th style="width:18%">层级</th><th style="width:22%">区域</th><th>展示什么</th><th style="width:18%">是否产品表</th></tr>
  563. </thead>
  564. <tbody>
  565. <tr>
  566. <td><span class="badge plan">计划</span></td>
  567. <td>产品信息(全宽)</td>
  568. <td>计划总量、添加产品、别名品牌编辑</td>
  569. <td class="center">完整 10 列</td>
  570. </tr>
  571. <tr>
  572. <td><span class="badge contract">合同</span></td>
  573. <td>段内合同区</td>
  574. <td>Chip:合同号 + 类型 + 产品数 + 查看/移除</td>
  575. <td class="center"><strong>不展示</strong></td>
  576. </tr>
  577. <tr>
  578. <td><span class="badge stop">段</span></td>
  579. <td>装货/送货产品</td>
  580. <td>本段分装数量、包装、送货方式(从计划同步)</td>
  581. <td class="center">紧凑 5 列</td>
  582. </tr>
  583. </tbody>
  584. </table>
  585. </section>
  586. </div>
  587. <script>
  588. document.querySelectorAll('.scheme-tab').forEach((tab) => {
  589. tab.addEventListener('click', () => {
  590. const scheme = tab.dataset.scheme
  591. document.querySelectorAll('.scheme-tab').forEach((t) => t.classList.toggle('active', t === tab))
  592. document.querySelectorAll('.scheme-panel').forEach((p) => p.classList.toggle('active', p.id === `panel-${scheme}`))
  593. })
  594. })
  595. function toggleCollapse() {
  596. document.getElementById('collapseDemo')?.classList.toggle('is-open')
  597. }
  598. document.documentElement.style.setProperty('--dialog-max', '1280px')
  599. </script>
  600. </body>
  601. </html>