pl-plan-three-zone-merge-demo.html 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  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. --muted: #64748b;
  17. --border: #d9e8e2;
  18. --head: #f8fafc;
  19. --page: #eef2f6;
  20. --panel: #fff;
  21. --warn: #d97706;
  22. --danger: #dc2626;
  23. --alt: #fafafa;
  24. --load-bg: #ecfdf5;
  25. --delivery-bg: #f0f9ff;
  26. --base-bg: #f8fafc;
  27. --load-border: #a7f3d0;
  28. --delivery-border: #bae6fd;
  29. --base-border: #cbd5e1;
  30. }
  31. * { box-sizing: border-box; }
  32. body {
  33. margin: 0;
  34. padding: 24px 20px 80px;
  35. font-family: Inter, "PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
  36. font-size: 14px;
  37. line-height: 1.5;
  38. color: var(--text);
  39. background: var(--page);
  40. }
  41. .page { max-width: 1680px; margin: 0 auto; }
  42. .hero {
  43. background: linear-gradient(135deg, #ecfdf5 0%, #fff 55%, #f0f9ff 100%);
  44. border: 1px solid var(--border);
  45. border-radius: 10px;
  46. padding: 20px 22px;
  47. margin-bottom: 16px;
  48. }
  49. .hero h1 { margin: 0 0 8px; font-size: 22px; font-weight: 700; }
  50. .hero h1 em { font-style: normal; color: var(--primary-dark); }
  51. .hero p { margin: 0; color: var(--muted); max-width: 1100px; }
  52. .pills { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
  53. .pill {
  54. font-size: 12px; font-weight: 600; padding: 4px 10px; border-radius: 999px;
  55. background: var(--primary-bg); color: var(--primary-dark); border: 1px solid #a7f3d0;
  56. }
  57. .pill.muted { background: #f1f5f9; color: var(--muted); border-color: #e2e8f0; }
  58. .pill.warn { background: #fffbeb; color: var(--warn); border-color: #fde68a; }
  59. .pill.base { background: #f1f5f9; color: #334155; border-color: #cbd5e1; }
  60. .pill.load { background: var(--load-bg); color: var(--primary-dark); border-color: var(--load-border); }
  61. .pill.need { background: var(--delivery-bg); color: #0369a1; border-color: var(--delivery-border); }
  62. .tabs {
  63. display: flex; flex-wrap: wrap; gap: 6px;
  64. background: var(--panel); border: 1px solid var(--border);
  65. border-radius: 10px 10px 0 0; padding: 8px 10px 0;
  66. }
  67. .tab {
  68. border: none; background: transparent; cursor: pointer; font-family: inherit;
  69. padding: 10px 14px; font-size: 13px; font-weight: 600; color: var(--muted);
  70. border-bottom: 2px solid transparent;
  71. }
  72. .tab:hover { color: var(--primary-dark); }
  73. .tab.active { color: var(--primary-dark); border-bottom-color: var(--primary); }
  74. .tab .rec {
  75. margin-left: 6px; font-size: 10px; padding: 1px 6px; border-radius: 999px;
  76. background: var(--primary-bg); color: var(--primary-dark); border: 1px solid #a7f3d0;
  77. }
  78. .panel {
  79. display: none;
  80. background: var(--panel);
  81. border: 1px solid var(--border);
  82. border-top: none;
  83. border-radius: 0 0 10px 10px;
  84. padding: 16px 18px 22px;
  85. }
  86. .panel.active { display: block; }
  87. .desc {
  88. margin: 0 0 12px; padding: 12px 14px; border-radius: 8px;
  89. background: #f0f9ff; border: 1px solid #bae6fd; color: #0369a1; font-size: 13px;
  90. }
  91. .desc strong { color: var(--text); }
  92. .ok {
  93. margin: 0 0 14px; padding: 10px 12px; border-radius: 8px;
  94. background: #ecfdf5; border: 1px solid #a7f3d0; color: #065f46; font-size: 12.5px;
  95. }
  96. .pain {
  97. margin: 0 0 14px; padding: 10px 12px; border-radius: 8px;
  98. background: #fef2f2; border: 1px solid #fecaca; color: #991b1b; font-size: 12.5px;
  99. }
  100. .legend {
  101. display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 14px; font-size: 12px; color: var(--muted);
  102. }
  103. .legend span {
  104. display: inline-flex; align-items: center; gap: 6px;
  105. padding: 4px 8px; border-radius: 6px; border: 1px solid var(--border);
  106. }
  107. .swatch { width: 12px; height: 12px; border-radius: 3px; border: 1px solid rgba(0,0,0,.08); }
  108. .swatch.base { background: #e2e8f0; }
  109. .swatch.load { background: #a7f3d0; }
  110. .swatch.need { background: #7dd3fc; }
  111. .swatch.prod { background: #fde68a; }
  112. .table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 8px; }
  113. table.list {
  114. width: 100%;
  115. border-collapse: collapse;
  116. min-width: 1280px;
  117. background: #fff;
  118. }
  119. table.list th,
  120. table.list td {
  121. border-bottom: 1px solid var(--border);
  122. border-right: 1px solid #eef2f0;
  123. padding: 10px 12px;
  124. vertical-align: top;
  125. font-size: 13px;
  126. }
  127. table.list th:last-child,
  128. table.list td:last-child { border-right: none; }
  129. table.list thead th {
  130. position: sticky; top: 0; z-index: 2;
  131. background: var(--head);
  132. color: var(--muted);
  133. font-size: 12px;
  134. font-weight: 600;
  135. white-space: nowrap;
  136. text-align: left;
  137. }
  138. table.list thead tr.zone-row th {
  139. text-align: center;
  140. font-size: 12px;
  141. letter-spacing: 0.02em;
  142. border-bottom: 1px solid var(--border);
  143. }
  144. table.list thead th.zone-base {
  145. background: #e2e8f0 !important; color: #334155 !important;
  146. }
  147. table.list thead th.zone-load {
  148. background: #d1fae5 !important; color: var(--primary-dark) !important;
  149. }
  150. table.list thead th.zone-need {
  151. background: #bae6fd !important; color: #0369a1 !important;
  152. }
  153. table.list thead th.zone-prod {
  154. background: #fef3c7 !important; color: #92400e !important;
  155. }
  156. table.list thead th.col-base { background: #f1f5f9 !important; }
  157. table.list thead th.col-load { background: #ecfdf5 !important; color: var(--primary-dark) !important; }
  158. table.list thead th.col-need { background: #e0f2fe !important; color: #0369a1 !important; }
  159. table.list thead th.col-prod { background: #fffbeb !important; color: #92400e !important; }
  160. table.list tbody tr:hover td { background: #f8fafc; }
  161. table.list a { color: var(--primary-dark); font-weight: 500; text-decoration: none; }
  162. table.list a:hover { text-decoration: underline; }
  163. td.cell-base { background: rgba(241, 245, 249, 0.55); }
  164. td.cell-load { background: rgba(236, 253, 245, 0.55); }
  165. td.cell-need { background: rgba(240, 249, 255, 0.65); }
  166. td.cell-prod { background: #fff; }
  167. td.plan-end { border-bottom: 2px solid #94a3b8 !important; }
  168. .tag {
  169. display: inline-flex; align-items: center;
  170. padding: 1px 8px; border-radius: 6px;
  171. font-size: 12px; font-weight: 600; line-height: 1.45; white-space: nowrap;
  172. }
  173. .tag.success { background: #059669; color: #fff; }
  174. .tag.warn { background: #d97706; color: #fff; }
  175. .tag.danger { background: #dc2626; color: #fff; }
  176. .tag.side-load {
  177. background: var(--load-bg); color: var(--primary-dark);
  178. border: 1px solid var(--load-border);
  179. }
  180. .tag.side-need {
  181. background: var(--delivery-bg); color: #0369a1;
  182. border: 1px solid var(--delivery-border);
  183. }
  184. .muted { color: var(--muted); }
  185. .stack { display: flex; flex-direction: column; gap: 4px; }
  186. .stack .sub { color: var(--muted); font-size: 12px; }
  187. .name-with-mark {
  188. display: inline-flex; align-items: center; flex-wrap: wrap; gap: 4px;
  189. }
  190. .seg-divider {
  191. margin: 8px 0;
  192. border: 0;
  193. border-top: 1px dashed #cbd5e1;
  194. }
  195. .hint-row {
  196. font-size: 11px; color: var(--muted); margin-top: 4px;
  197. }
  198. .meta {
  199. margin-top: 14px; font-size: 12px; color: var(--muted);
  200. }
  201. .meta code {
  202. font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  203. background: #f1f5f9; padding: 1px 6px; border-radius: 4px;
  204. }
  205. </style>
  206. </head>
  207. <body>
  208. <div class="page">
  209. <header class="hero">
  210. <h1>运输计划列表 · <em>三区列</em>(基础 / 装货 / 送货)合并 Demo</h1>
  211. <p>
  212. 案例:<strong>PO20261009016</strong> —— 1 个装货段、2 个送货段;
  213. 展平后产品侧共 3 行(1 供产品 + 2 需产品)。
  214. 目标验证:列表分成<strong>基础信息列</strong>、<strong>装货段次列</strong>、<strong>送货段次列</strong>三块,并各自做合并单元格时的观感。
  215. </p>
  216. <div class="pills">
  217. <span class="pill">PO20261009016</span>
  218. <span class="pill warn">待安排</span>
  219. <span class="pill muted">皖R4B299/皖R8131挂</span>
  220. <span class="pill base">基础信息区</span>
  221. <span class="pill load">装货段次区</span>
  222. <span class="pill need">送货段次区</span>
  223. </div>
  224. </header>
  225. <div class="tabs" role="tablist">
  226. <button class="tab active" data-tab="a" type="button">
  227. 方案 A · 送货按段合并(跨产品行)<span class="rec">贴近你的描述</span>
  228. </button>
  229. <button class="tab" data-tab="b" type="button">方案 B · 送货整单合并(格内叠段)</button>
  230. <button class="tab" data-tab="c" type="button">对照 · 现状(供行出现 —)</button>
  231. </div>
  232. <!-- 方案 A -->
  233. <section class="panel active" id="panel-a">
  234. <p class="desc">
  235. <strong>方案 A:</strong>表头分三区。
  236. 行模型仍是「先 1 行供产品,再各送货段产品行」(本单共 3 行)。
  237. <strong>基础区 / 装货区</strong>整单合并(rowspan=3);
  238. <strong>送货区</strong>按送货段合并——第 1 个送货段 rowspan=2(盖住供产品行 + 该送货产品行),第 2 个送货段 rowspan=1。
  239. 送货列<strong>不再出现「—」占位行</strong>,但第 1 个送货客户会在视觉上与供产品行对齐(略高一截)。
  240. </p>
  241. <p class="ok">
  242. 可实现:三区列 + 合并单元格都成立;送货客户/地址恰好 2 段。
  243. 代价:多送货时,第一个送货段的合并格会「借」供侧产品行的高度,和产品行不是严格语义对齐。
  244. </p>
  245. <div class="legend">
  246. <span><i class="swatch base"></i>基础信息(整单合并)</span>
  247. <span><i class="swatch load"></i>装货段次(整单合并)</span>
  248. <span><i class="swatch need"></i>送货段次(按段合并)</span>
  249. <span><i class="swatch prod"></i>产品明细(不合并)</span>
  250. </div>
  251. <div class="table-wrap">
  252. <table class="list">
  253. <thead>
  254. <tr class="zone-row">
  255. <th class="zone-base" colspan="5">基础信息</th>
  256. <th class="zone-load" colspan="3">装货段次</th>
  257. <th class="zone-need" colspan="3">送货段次</th>
  258. <th class="zone-prod" colspan="4">产品明细(供/需)</th>
  259. </tr>
  260. <tr>
  261. <th class="col-base">计划编号</th>
  262. <th class="col-base">跟进状态</th>
  263. <th class="col-base">计划日期</th>
  264. <th class="col-base">车牌号</th>
  265. <th class="col-base">人员</th>
  266. <th class="col-load">装货客户</th>
  267. <th class="col-load">装货地址/时间</th>
  268. <th class="col-load">供合同</th>
  269. <th class="col-need">送货客户</th>
  270. <th class="col-need">送货地址/时间</th>
  271. <th class="col-need">需合同</th>
  272. <th class="col-prod">侧别</th>
  273. <th class="col-prod">产品名称</th>
  274. <th class="col-prod">单位</th>
  275. <th class="col-prod">计划量</th>
  276. </tr>
  277. </thead>
  278. <tbody>
  279. <tr>
  280. <td class="cell-base" rowspan="3">
  281. <a href="#">PO20261009016</a>
  282. </td>
  283. <td class="cell-base" rowspan="3"><span class="tag danger">待安排</span></td>
  284. <td class="cell-base" rowspan="3">2026-10-13</td>
  285. <td class="cell-base" rowspan="3">皖R4B299/皖R8131挂</td>
  286. <td class="cell-base" rowspan="3">彭双青(驾)、汪的霞(押)</td>
  287. <td class="cell-load" rowspan="3">铜陵华博精细化工有限公司</td>
  288. <td class="cell-load" rowspan="3">
  289. <div class="stack">
  290. <span>铜官大道南段3888号铜陵市华兴化工有限公司</span>
  291. <span class="sub">2026-10-13</span>
  292. </div>
  293. </td>
  294. <td class="cell-load" rowspan="3"><span class="muted">—</span></td>
  295. <td class="cell-need" rowspan="2">
  296. 合肥瞻宇环保科技有限公司
  297. <div class="hint-row">rowspan=2(含上方供产品行高度)</div>
  298. </td>
  299. <td class="cell-need" rowspan="2">
  300. <div class="stack">
  301. <span class="muted">—</span>
  302. <span class="sub">2026-10-13</span>
  303. </div>
  304. </td>
  305. <td class="cell-need" rowspan="2"><span class="muted">—</span></td>
  306. <td class="cell-prod"><span class="tag side-load">供</span></td>
  307. <td class="cell-prod">示例装货产品</td>
  308. <td class="cell-prod">吨</td>
  309. <td class="cell-prod">30</td>
  310. </tr>
  311. <tr>
  312. <td class="cell-prod"><span class="tag side-need">需</span></td>
  313. <td class="cell-prod">示例送货产品 A</td>
  314. <td class="cell-prod">吨</td>
  315. <td class="cell-prod">18</td>
  316. </tr>
  317. <tr>
  318. <td class="cell-need">
  319. <span class="name-with-mark">
  320. 安庆市山峡化工有限公司
  321. <span class="tag success">内部</span>
  322. </span>
  323. </td>
  324. <td class="cell-need">
  325. <div class="stack">
  326. <span>高新区震虹路5号安庆市山峡化工有限公司</span>
  327. <span class="sub">2026-10-13</span>
  328. </div>
  329. </td>
  330. <td class="cell-need"><span class="muted">—</span></td>
  331. <td class="cell-prod plan-end"><span class="tag side-need">需</span></td>
  332. <td class="cell-prod plan-end">示例送货产品 B</td>
  333. <td class="cell-prod plan-end">吨</td>
  334. <td class="cell-prod plan-end">12</td>
  335. </tr>
  336. </tbody>
  337. </table>
  338. </div>
  339. <p class="meta">
  340. 合并规则:基础/装货 <code>rowspan = 整单行数</code>;送货段
  341. <code>首段 rowspan = 供产品行数 + 本段产品行数</code>,后续段
  342. <code>rowspan = 本段产品行数</code>。
  343. </p>
  344. </section>
  345. <!-- 方案 B -->
  346. <section class="panel" id="panel-b">
  347. <p class="desc">
  348. <strong>方案 B:</strong>同样三区列表头。
  349. <strong>基础 / 装货 / 送货</strong>全部按整单合并(rowspan=3);
  350. 送货区在<strong>一个单元格内</strong>用虚线叠放 2 个送货段,不要求和右侧产品行一一对应。
  351. 产品明细仍 3 行。
  352. </p>
  353. <p class="ok">
  354. 实现最简单(送货列改成计划级合并 + 格内 v-for);送货客户/地址视觉上就是 2 行信息,不会出现第三行「—」。
  355. 代价:送货段与产品行不再纵向对齐。
  356. </p>
  357. <div class="legend">
  358. <span><i class="swatch base"></i>基础信息(整单合并)</span>
  359. <span><i class="swatch load"></i>装货段次(整单合并)</span>
  360. <span><i class="swatch need"></i>送货段次(整单合并,格内叠段)</span>
  361. <span><i class="swatch prod"></i>产品明细(不合并)</span>
  362. </div>
  363. <div class="table-wrap">
  364. <table class="list">
  365. <thead>
  366. <tr class="zone-row">
  367. <th class="zone-base" colspan="5">基础信息</th>
  368. <th class="zone-load" colspan="3">装货段次</th>
  369. <th class="zone-need" colspan="3">送货段次</th>
  370. <th class="zone-prod" colspan="4">产品明细(供/需)</th>
  371. </tr>
  372. <tr>
  373. <th class="col-base">计划编号</th>
  374. <th class="col-base">跟进状态</th>
  375. <th class="col-base">计划日期</th>
  376. <th class="col-base">车牌号</th>
  377. <th class="col-base">人员</th>
  378. <th class="col-load">装货客户</th>
  379. <th class="col-load">装货地址/时间</th>
  380. <th class="col-load">供合同</th>
  381. <th class="col-need">送货客户</th>
  382. <th class="col-need">送货地址/时间</th>
  383. <th class="col-need">需合同</th>
  384. <th class="col-prod">侧别</th>
  385. <th class="col-prod">产品名称</th>
  386. <th class="col-prod">单位</th>
  387. <th class="col-prod">计划量</th>
  388. </tr>
  389. </thead>
  390. <tbody>
  391. <tr>
  392. <td class="cell-base" rowspan="3"><a href="#">PO20261009016</a></td>
  393. <td class="cell-base" rowspan="3"><span class="tag danger">待安排</span></td>
  394. <td class="cell-base" rowspan="3">2026-10-13</td>
  395. <td class="cell-base" rowspan="3">皖R4B299/皖R8131挂</td>
  396. <td class="cell-base" rowspan="3">彭双青(驾)、汪的霞(押)</td>
  397. <td class="cell-load" rowspan="3">铜陵华博精细化工有限公司</td>
  398. <td class="cell-load" rowspan="3">
  399. <div class="stack">
  400. <span>铜官大道南段3888号铜陵市华兴化工有限公司</span>
  401. <span class="sub">2026-10-13</span>
  402. </div>
  403. </td>
  404. <td class="cell-load" rowspan="3"><span class="muted">—</span></td>
  405. <td class="cell-need" rowspan="3">
  406. <div class="stack">
  407. <span>合肥瞻宇环保科技有限公司</span>
  408. <hr class="seg-divider" />
  409. <span class="name-with-mark">
  410. 安庆市山峡化工有限公司
  411. <span class="tag success">内部</span>
  412. </span>
  413. </div>
  414. </td>
  415. <td class="cell-need" rowspan="3">
  416. <div class="stack">
  417. <div class="stack">
  418. <span class="muted">—</span>
  419. <span class="sub">2026-10-13</span>
  420. </div>
  421. <hr class="seg-divider" />
  422. <div class="stack">
  423. <span>高新区震虹路5号安庆市山峡化工有限公司</span>
  424. <span class="sub">2026-10-13</span>
  425. </div>
  426. </div>
  427. </td>
  428. <td class="cell-need" rowspan="3">
  429. <div class="stack">
  430. <span class="muted">—</span>
  431. <hr class="seg-divider" />
  432. <span class="muted">—</span>
  433. </div>
  434. </td>
  435. <td class="cell-prod"><span class="tag side-load">供</span></td>
  436. <td class="cell-prod">示例装货产品</td>
  437. <td class="cell-prod">吨</td>
  438. <td class="cell-prod">30</td>
  439. </tr>
  440. <tr>
  441. <td class="cell-prod"><span class="tag side-need">需</span></td>
  442. <td class="cell-prod">示例送货产品 A</td>
  443. <td class="cell-prod">吨</td>
  444. <td class="cell-prod">18</td>
  445. </tr>
  446. <tr>
  447. <td class="cell-prod plan-end"><span class="tag side-need">需</span></td>
  448. <td class="cell-prod plan-end">示例送货产品 B</td>
  449. <td class="cell-prod plan-end">吨</td>
  450. <td class="cell-prod plan-end">12</td>
  451. </tr>
  452. </tbody>
  453. </table>
  454. </div>
  455. <p class="meta">
  456. 合并规则:三区段信息列均为 <code>rowspan = 整单行数</code>;多送货在格内用分隔线叠放。
  457. 产品明细列不合并。
  458. </p>
  459. </section>
  460. <!-- 对照 C:现状 -->
  461. <section class="panel" id="panel-c">
  462. <p class="desc">
  463. <strong>对照 · 接近现状:</strong>同样三区列,但送货区按「展平行」各自出格——
  464. 供产品行没有可绑定的唯一送货客户时显示 <strong>—</strong>,再跟 2 个真实送货段,
  465. 于是送货客户/地址看起来像 <strong>3 行</strong>(你截图里的问题)。
  466. </p>
  467. <p class="pain">
  468. 问题:业务上只有 2 个送货段,列表却多出一行「—」占位,扫读时像第三个送货客户。
  469. </p>
  470. <div class="table-wrap">
  471. <table class="list">
  472. <thead>
  473. <tr class="zone-row">
  474. <th class="zone-base" colspan="5">基础信息</th>
  475. <th class="zone-load" colspan="2">装货段次</th>
  476. <th class="zone-need" colspan="2">送货段次</th>
  477. <th class="zone-prod" colspan="3">产品明细</th>
  478. </tr>
  479. <tr>
  480. <th class="col-base">计划编号</th>
  481. <th class="col-base">跟进状态</th>
  482. <th class="col-base">计划日期</th>
  483. <th class="col-base">车牌号</th>
  484. <th class="col-base">人员</th>
  485. <th class="col-load">装货客户</th>
  486. <th class="col-load">装货地址/时间</th>
  487. <th class="col-need">送货客户</th>
  488. <th class="col-need">送货地址/时间</th>
  489. <th class="col-prod">侧别</th>
  490. <th class="col-prod">产品名称</th>
  491. <th class="col-prod">计划量</th>
  492. </tr>
  493. </thead>
  494. <tbody>
  495. <tr>
  496. <td class="cell-base" rowspan="3"><a href="#">PO20261009016</a></td>
  497. <td class="cell-base" rowspan="3"><span class="tag danger">待安排</span></td>
  498. <td class="cell-base" rowspan="3">2026-10-13</td>
  499. <td class="cell-base" rowspan="3">皖R4B299/皖R8131挂</td>
  500. <td class="cell-base" rowspan="3">彭双青(驾)、汪的霞(押)</td>
  501. <td class="cell-load" rowspan="3">铜陵华博精细化工有限公司</td>
  502. <td class="cell-load" rowspan="3">
  503. <div class="stack">
  504. <span>铜官大道南段3888号…</span>
  505. <span class="sub">2026-10-13</span>
  506. </div>
  507. </td>
  508. <td class="cell-need"><span class="muted">—</span></td>
  509. <td class="cell-need">
  510. <div class="stack">
  511. <span class="muted">—</span>
  512. <span class="sub muted">—</span>
  513. </div>
  514. </td>
  515. <td class="cell-prod"><span class="tag side-load">供</span></td>
  516. <td class="cell-prod">示例装货产品</td>
  517. <td class="cell-prod">30</td>
  518. </tr>
  519. <tr>
  520. <td class="cell-need">合肥瞻宇环保科技有限公司</td>
  521. <td class="cell-need">
  522. <div class="stack">
  523. <span class="muted">—</span>
  524. <span class="sub">2026-10-13</span>
  525. </div>
  526. </td>
  527. <td class="cell-prod"><span class="tag side-need">需</span></td>
  528. <td class="cell-prod">示例送货产品 A</td>
  529. <td class="cell-prod">18</td>
  530. </tr>
  531. <tr>
  532. <td class="cell-need plan-end">
  533. <span class="name-with-mark">
  534. 安庆市山峡化工有限公司
  535. <span class="tag success">内部</span>
  536. </span>
  537. </td>
  538. <td class="cell-need plan-end">
  539. <div class="stack">
  540. <span>高新区震虹路5号…</span>
  541. <span class="sub">2026-10-13</span>
  542. </div>
  543. </td>
  544. <td class="cell-prod plan-end"><span class="tag side-need">需</span></td>
  545. <td class="cell-prod plan-end">示例送货产品 B</td>
  546. <td class="cell-prod plan-end">12</td>
  547. </tr>
  548. </tbody>
  549. </table>
  550. </div>
  551. <p class="meta">对照用:说明「三区列」本身可行,但若送货列仍跟供/需产品行一一出格,多送货时就会冒出「—」。</p>
  552. </section>
  553. </div>
  554. <script>
  555. const tabs = document.querySelectorAll('.tab')
  556. const panels = {
  557. a: document.getElementById('panel-a'),
  558. b: document.getElementById('panel-b'),
  559. c: document.getElementById('panel-c')
  560. }
  561. tabs.forEach((tab) => {
  562. tab.addEventListener('click', () => {
  563. const key = tab.getAttribute('data-tab')
  564. tabs.forEach((t) => t.classList.toggle('active', t === tab))
  565. Object.entries(panels).forEach(([k, el]) => {
  566. el.classList.toggle('active', k === key)
  567. })
  568. })
  569. })
  570. </script>
  571. </body>
  572. </html>