提交
This commit is contained in:
1 parent
e233269abf
commit
732c1b1dc9
17 files changed
+9607
-88132
No files matched your search
+1
-1
@@ -1 +1 @@
|
||||
19114
|
||||
26701
|
||||
@@ -0,0 +1,602 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Fresh Mint · 回传卡片 KV 重设计 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;
|
||||
--border-soft: #e2e8f0;
|
||||
--surface: #fff;
|
||||
--table-head: #f8fafc;
|
||||
--danger: #dc2626;
|
||||
--warn: #d97706;
|
||||
--radius: 10px;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: Inter, -apple-system, sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
color: var(--text);
|
||||
background: #eef2f6;
|
||||
}
|
||||
|
||||
.page { max-width: 1200px; margin: 0 auto; padding: 32px 20px 72px; }
|
||||
.head { margin-bottom: 28px; }
|
||||
.head h1 { margin: 0 0 8px; font-size: 24px; font-weight: 700; }
|
||||
.head h1 span { color: var(--primary-dark); }
|
||||
.head p { margin: 0; color: var(--text-muted); max-width: 760px; }
|
||||
|
||||
.block { margin-bottom: 36px; }
|
||||
.block > h2 {
|
||||
margin: 0 0 6px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.block > .desc {
|
||||
margin: 0 0 14px;
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.pick {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
padding: 1px 8px;
|
||||
border-radius: 999px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.pick-1 { background: #ecfdf5; color: var(--primary-dark); }
|
||||
.pick-2 { background: #eff6ff; color: #1d4ed8; }
|
||||
.pick-3 { background: #fff7ed; color: #c2410c; }
|
||||
|
||||
.row3 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 14px;
|
||||
}
|
||||
@media (max-width: 980px) {
|
||||
.row3 { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.panel {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border-soft);
|
||||
border-radius: var(--radius);
|
||||
padding: 14px;
|
||||
min-height: 300px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.panel-hd {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.panel-hd h3 {
|
||||
margin: 0;
|
||||
padding-left: 10px;
|
||||
border-left: 3px solid var(--primary);
|
||||
color: var(--primary-dark);
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.ops { display: flex; gap: 6px; }
|
||||
.btn {
|
||||
height: 28px;
|
||||
padding: 0 10px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--border-soft);
|
||||
background: #fff;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--text);
|
||||
}
|
||||
.btn-p { background: var(--primary); border-color: var(--primary); color: #fff; }
|
||||
|
||||
/* ========== 方案 1:单据表(系统原生 ViewKv 表格式) ========== */
|
||||
.kv-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
}
|
||||
.kv-table th,
|
||||
.kv-table td {
|
||||
padding: 9px 12px;
|
||||
border-bottom: 1px solid #eef2f6;
|
||||
border-right: 1px solid #eef2f6;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.kv-table tr:last-child th,
|
||||
.kv-table tr:last-child td { border-bottom: none; }
|
||||
.kv-table th {
|
||||
width: 78px;
|
||||
background: var(--table-head);
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.kv-table td {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
word-break: break-word;
|
||||
}
|
||||
.kv-table td.red { color: var(--danger); font-size: 15px; }
|
||||
.kv-table .tag {
|
||||
display: inline-block;
|
||||
padding: 1px 8px;
|
||||
border-radius: 4px;
|
||||
background: #059669;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.kv-table .thumbs {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.kv-table .thumb {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 6px;
|
||||
background: #ecfdf5;
|
||||
border: 1px solid #a7f3d0;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
font-size: 11px;
|
||||
color: var(--primary-dark);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ========== 方案 2:一句摘要 + 次要元信息 ========== */
|
||||
.summary-card { display: flex; flex-direction: column; gap: 12px; }
|
||||
.summary-hero {
|
||||
padding: 14px 14px 12px;
|
||||
border-radius: 8px;
|
||||
background: #0f172a;
|
||||
color: #f8fafc;
|
||||
}
|
||||
.summary-hero .kicker {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
color: #94a3b8;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.summary-hero .main {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.02em;
|
||||
line-height: 1.25;
|
||||
}
|
||||
.summary-hero .main strong { color: #fca5a5; font-weight: 700; }
|
||||
.summary-hero .sub {
|
||||
margin-top: 8px;
|
||||
font-size: 12px;
|
||||
color: #cbd5e1;
|
||||
line-height: 1.45;
|
||||
}
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
|
||||
.chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
max-width: 100%;
|
||||
padding: 6px 10px;
|
||||
border-radius: 999px;
|
||||
background: #f8fafc;
|
||||
border: 1px solid var(--border-soft);
|
||||
font-size: 12px;
|
||||
color: var(--text);
|
||||
}
|
||||
.chip b { color: var(--text-muted); font-weight: 500; }
|
||||
.chip .t { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 180px; }
|
||||
.media-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
.media-row .lab { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
|
||||
.media-row .thumb {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 8px;
|
||||
object-fit: cover;
|
||||
background: linear-gradient(135deg, #d1fae5, #a7f3d0);
|
||||
border: 1px solid #a7f3d0;
|
||||
}
|
||||
|
||||
/* ========== 方案 3:回执 / 小票式 ========== */
|
||||
.ticket {
|
||||
border: 1px solid var(--border-soft);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
}
|
||||
.ticket-band {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
padding: 10px 12px;
|
||||
background: linear-gradient(90deg, #ecfdf5 0%, #f0fdf4 60%, #fff 100%);
|
||||
border-bottom: 1px solid #d1fae5;
|
||||
}
|
||||
.ticket-band .who {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--primary-dark);
|
||||
}
|
||||
.ticket-band .when {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
font-variant-numeric: tabular-nums;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.ticket-qty {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0;
|
||||
border-bottom: 1px dashed #e2e8f0;
|
||||
}
|
||||
.ticket-qty > div {
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
.ticket-qty > div + div { border-left: 1px dashed #e2e8f0; }
|
||||
.ticket-qty .lab {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.ticket-qty .val {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: var(--danger);
|
||||
font-variant-numeric: tabular-nums;
|
||||
letter-spacing: -0.02em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
.ticket-qty .val.sm { font-size: 14px; line-height: 1.35; }
|
||||
.ticket-lines { padding: 4px 0; }
|
||||
.ticket-line {
|
||||
display: grid;
|
||||
grid-template-columns: 72px 1fr;
|
||||
gap: 8px;
|
||||
padding: 7px 12px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.ticket-line .lab { color: var(--text-muted); }
|
||||
.ticket-line .val { font-weight: 600; color: var(--text); word-break: break-word; }
|
||||
.ticket-foot {
|
||||
padding: 10px 12px;
|
||||
border-top: 1px dashed #e2e8f0;
|
||||
background: #f8fafc;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.ticket-foot .lab { font-size: 12px; color: var(--text-muted); }
|
||||
.ticket-foot .thumb {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 6px;
|
||||
background: #ecfdf5;
|
||||
border: 1px solid #a7f3d0;
|
||||
}
|
||||
|
||||
.footer-note {
|
||||
margin-top: 8px;
|
||||
padding: 14px 16px;
|
||||
background: #fff;
|
||||
border: 1px solid var(--border-soft);
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.footer-note strong { color: var(--text); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
<header class="head">
|
||||
<h1>回传卡片 · <span>重新设计</span></h1>
|
||||
<p>
|
||||
上一版三种「上下 KV / 指标卡 / 左右行」都不合适。本页换成三种完全不同的语言:
|
||||
<b>单据表</b>、<b>摘要优先</b>、<b>回执小票</b>。请直接点名要哪一种(或混搭)。
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<!-- 1 -->
|
||||
<section class="block">
|
||||
<h2>方案 1 · 单据表 <span class="pick pick-1">贴近现有 ViewKvTable</span></h2>
|
||||
<p class="desc">放弃「漂浮的上下摆」,改成管理端熟悉的「左标签右值」表格。数量单元格加大、红色。信息密度高、和系统其它查看弹窗一致。</p>
|
||||
<div class="row3">
|
||||
<article class="panel">
|
||||
<div class="panel-hd">
|
||||
<h3>司机回传信息</h3>
|
||||
<div class="ops"><button class="btn btn-p" type="button">编辑</button></div>
|
||||
</div>
|
||||
<table class="kv-table">
|
||||
<tr>
|
||||
<th>实际数量</th>
|
||||
<td class="red">28.5 吨</td>
|
||||
<th>品牌数量</th>
|
||||
<td class="red">云化 18.5 / 华谊 10</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>回传时间</th>
|
||||
<td>2026-07-31 14:22</td>
|
||||
<th>回传备注</th>
|
||||
<td>货已装完,现场确认无误</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>回传附件</th>
|
||||
<td colspan="3">
|
||||
<div class="thumbs"><span class="thumb">图1</span><span class="thumb">图2</span></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</article>
|
||||
|
||||
<article class="panel">
|
||||
<div class="panel-hd">
|
||||
<h3>出库单回传</h3>
|
||||
<div class="ops"><button class="btn btn-p" type="button">编辑</button></div>
|
||||
</div>
|
||||
<table class="kv-table">
|
||||
<tr>
|
||||
<th>单号</th>
|
||||
<td>CK20260731001</td>
|
||||
<th>状态</th>
|
||||
<td><span class="tag">已完成</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>计划号</th>
|
||||
<td>PL-202607-088</td>
|
||||
<th>车牌</th>
|
||||
<td>皖H·D1234</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>往来单位</th>
|
||||
<td colspan="3">安庆某某化工有限公司</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>实际数量</th>
|
||||
<td class="red">28.5 吨</td>
|
||||
<th>品牌数量</th>
|
||||
<td class="red">云化 18.5 / 华谊 10</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>现场备注</th>
|
||||
<td>过磅完成,单据已签</td>
|
||||
<th>现场附件</th>
|
||||
<td><div class="thumbs"><span class="thumb">图1</span></div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</article>
|
||||
|
||||
<article class="panel">
|
||||
<div class="panel-hd"><h3>地磅单信息(示意)</h3></div>
|
||||
<table class="kv-table">
|
||||
<tr>
|
||||
<th>出入库单号</th>
|
||||
<td>RK20260731008</td>
|
||||
<th>业务类型</th>
|
||||
<td><span class="tag">出库</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>毛重</th>
|
||||
<td>42580 kg</td>
|
||||
<th>皮重</th>
|
||||
<td>14200 kg</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>净重</th>
|
||||
<td class="red">28380 kg</td>
|
||||
<th>车牌</th>
|
||||
<td>皖H·D1234</td>
|
||||
</tr>
|
||||
</table>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 2 -->
|
||||
<section class="block">
|
||||
<h2>方案 2 · 摘要优先 <span class="pick pick-2">先看结论</span></h2>
|
||||
<p class="desc">卡片顶部用一句「结论句」把数量讲清楚,其余降级成胶囊标签。适合一眼扫量,弱化字段罗列感。</p>
|
||||
<div class="row3">
|
||||
<article class="panel">
|
||||
<div class="panel-hd">
|
||||
<h3>司机回传信息</h3>
|
||||
<div class="ops"><button class="btn btn-p" type="button">编辑</button></div>
|
||||
</div>
|
||||
<div class="summary-card">
|
||||
<div class="summary-hero">
|
||||
<div class="kicker">司机已回传</div>
|
||||
<div class="main">实际 <strong>28.5</strong> 吨</div>
|
||||
<div class="sub">品牌构成:云化 18.5 · 华谊 10</div>
|
||||
</div>
|
||||
<div class="chip-row">
|
||||
<span class="chip"><b>时间</b><span class="t">2026-07-31 14:22</span></span>
|
||||
<span class="chip"><b>备注</b><span class="t">货已装完,现场确认无误</span></span>
|
||||
</div>
|
||||
<div class="media-row">
|
||||
<span class="lab">附件</span>
|
||||
<span class="thumb"></span>
|
||||
<span class="thumb"></span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="panel">
|
||||
<div class="panel-hd">
|
||||
<h3>出库单回传</h3>
|
||||
<div class="ops"><button class="btn btn-p" type="button">编辑</button></div>
|
||||
</div>
|
||||
<div class="summary-card">
|
||||
<div class="summary-hero">
|
||||
<div class="kicker">出库单 · 已完成 · CK20260731001</div>
|
||||
<div class="main">实际 <strong>28.5</strong> 吨</div>
|
||||
<div class="sub">云化 18.5 · 华谊 10 | 皖H·D1234</div>
|
||||
</div>
|
||||
<div class="chip-row">
|
||||
<span class="chip"><b>计划</b><span class="t">PL-202607-088</span></span>
|
||||
<span class="chip"><b>往来</b><span class="t">安庆某某化工有限公司</span></span>
|
||||
<span class="chip"><b>备注</b><span class="t">过磅完成,单据已签</span></span>
|
||||
</div>
|
||||
<div class="media-row">
|
||||
<span class="lab">附件</span>
|
||||
<span class="thumb"></span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="panel">
|
||||
<div class="panel-hd"><h3>地磅单信息(示意)</h3></div>
|
||||
<div class="summary-card">
|
||||
<div class="summary-hero">
|
||||
<div class="kicker">地磅 · 出库 · RK20260731008</div>
|
||||
<div class="main">净重 <strong>28.38</strong> 吨</div>
|
||||
<div class="sub">毛重 42.58 · 皮重 14.20 | 皖H·D1234</div>
|
||||
</div>
|
||||
<div class="chip-row">
|
||||
<span class="chip"><b>往来</b><span class="t">安庆某某化工</span></span>
|
||||
<span class="chip"><b>状态</b><span class="t">已过磅</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 3 -->
|
||||
<section class="block">
|
||||
<h2>方案 3 · 回执小票 <span class="pick pick-3">像一张回执</span></h2>
|
||||
<p class="desc">顶部条带写时间/身份,中间居中放大数量,下方清单式字段。结构像「装车回执」,不是普通表单字段堆叠。</p>
|
||||
<div class="row3">
|
||||
<article class="panel">
|
||||
<div class="panel-hd">
|
||||
<h3>司机回传信息</h3>
|
||||
<div class="ops"><button class="btn btn-p" type="button">编辑</button></div>
|
||||
</div>
|
||||
<div class="ticket">
|
||||
<div class="ticket-band">
|
||||
<span class="who">司机回传回执</span>
|
||||
<span class="when">2026-07-31 14:22</span>
|
||||
</div>
|
||||
<div class="ticket-qty">
|
||||
<div>
|
||||
<div class="lab">实际数量(吨)</div>
|
||||
<div class="val">28.5</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="lab">品牌数量</div>
|
||||
<div class="val sm">云化 18.5<br />华谊 10</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ticket-lines">
|
||||
<div class="ticket-line"><span class="lab">回传备注</span><span class="val">货已装完,现场确认无误</span></div>
|
||||
</div>
|
||||
<div class="ticket-foot">
|
||||
<span class="lab">附件</span>
|
||||
<span class="thumb"></span>
|
||||
<span class="thumb"></span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="panel">
|
||||
<div class="panel-hd">
|
||||
<h3>出库单回传</h3>
|
||||
<div class="ops"><button class="btn btn-p" type="button">编辑</button></div>
|
||||
</div>
|
||||
<div class="ticket">
|
||||
<div class="ticket-band">
|
||||
<span class="who">出库单 CK20260731001 · 已完成</span>
|
||||
<span class="when">PL-202607-088</span>
|
||||
</div>
|
||||
<div class="ticket-qty">
|
||||
<div>
|
||||
<div class="lab">实际数量(吨)</div>
|
||||
<div class="val">28.5</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="lab">品牌数量</div>
|
||||
<div class="val sm">云化 18.5 / 华谊 10</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ticket-lines">
|
||||
<div class="ticket-line"><span class="lab">车牌</span><span class="val">皖H·D1234</span></div>
|
||||
<div class="ticket-line"><span class="lab">往来单位</span><span class="val">安庆某某化工有限公司</span></div>
|
||||
<div class="ticket-line"><span class="lab">现场备注</span><span class="val">过磅完成,单据已签</span></div>
|
||||
</div>
|
||||
<div class="ticket-foot">
|
||||
<span class="lab">附件</span>
|
||||
<span class="thumb"></span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="panel">
|
||||
<div class="panel-hd"><h3>地磅单信息(示意)</h3></div>
|
||||
<div class="ticket">
|
||||
<div class="ticket-band">
|
||||
<span class="who">地磅回执 · 出库</span>
|
||||
<span class="when">RK20260731008</span>
|
||||
</div>
|
||||
<div class="ticket-qty">
|
||||
<div>
|
||||
<div class="lab">净重(吨)</div>
|
||||
<div class="val">28.38</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="lab">毛重 / 皮重</div>
|
||||
<div class="val sm">42.58 / 14.20</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ticket-lines">
|
||||
<div class="ticket-line"><span class="lab">车牌</span><span class="val">皖H·D1234</span></div>
|
||||
<div class="ticket-line"><span class="lab">往来单位</span><span class="val">安庆某某化工</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="footer-note">
|
||||
<strong>怎么选:</strong>
|
||||
要和系统其它查看页统一 → 选 <strong>方案 1</strong>;
|
||||
归档时最关心「装了多少」→ 选 <strong>方案 2</strong>;
|
||||
想强调「这是一份回传凭证」→ 选 <strong>方案 3</strong>。
|
||||
也可以说「1 的表格 + 2 的顶部结论」这类混搭。文件:
|
||||
<code>docs/fresh-mint-pl-feedback-kv-polish-demo.html</code>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+1059
-1059
File diff suppressed because it is too large.
Load diff
@@ -16,7 +16,7 @@
|
||||
"14": "Community 14",
|
||||
"15": "Community 15",
|
||||
"16": "Community 16",
|
||||
"17": "Community 17",
|
||||
"17": "Ha",
|
||||
"18": "Community 18",
|
||||
"19": "Community 19",
|
||||
"20": "Community 20",
|
||||
@@ -25,22 +25,32 @@
|
||||
"23": "Community 23",
|
||||
"24": "Community 24",
|
||||
"25": "Community 25",
|
||||
"26": "Community 26",
|
||||
"26": "theme.min.js",
|
||||
"27": "Community 27",
|
||||
"28": "Community 28",
|
||||
"28": "useCommon",
|
||||
"29": "Community 29",
|
||||
"30": "loader.ts",
|
||||
"31": "RenewDialog.vue",
|
||||
"32": "index.vue",
|
||||
"33": "Community 33",
|
||||
"34": "main.ts",
|
||||
"35": "Community 35",
|
||||
"36": "VoidDialog.vue",
|
||||
"37": "pl-batch-print.ts",
|
||||
"38": "view-fields.ts",
|
||||
"39": "Community 39",
|
||||
"40": "Community 40",
|
||||
"41": "colors.ts",
|
||||
"42": "Community 42",
|
||||
"43": "Community 43",
|
||||
"44": "Community 44",
|
||||
"45": "Community 45",
|
||||
"46": "Community 46",
|
||||
"47": "fetchCustomerDetail",
|
||||
"48": "Community 48",
|
||||
"49": "Community 49",
|
||||
"50": "Community 50",
|
||||
"51": "price-letter-template.ts",
|
||||
"52": "Community 52",
|
||||
"53": "Community 53",
|
||||
"54": "Community 54",
|
||||
@@ -48,8 +58,13 @@
|
||||
"56": "Community 56",
|
||||
"57": "Community 57",
|
||||
"58": "Community 58",
|
||||
"59": "fetchData",
|
||||
"60": "index.vue",
|
||||
"61": "Community 61",
|
||||
"62": "highlight.ts",
|
||||
"63": "price-letter.ts",
|
||||
"64": "Community 64",
|
||||
"65": "detail.vue",
|
||||
"66": "Community 66",
|
||||
"67": "index.vue",
|
||||
"68": "Community 68",
|
||||
@@ -59,17 +74,27 @@
|
||||
"72": "Community 72",
|
||||
"73": "Community 73",
|
||||
"74": "Community 74",
|
||||
"75": "openEdit",
|
||||
"76": "handleSearch",
|
||||
"77": "loadUserOptions",
|
||||
"78": "customerPool.ts",
|
||||
"79": "Community 79",
|
||||
"80": "product.ts",
|
||||
"81": "Community 81",
|
||||
"82": "Community 82",
|
||||
"83": "StorageKeyManager",
|
||||
"84": "Community 84",
|
||||
"85": "handleEdit",
|
||||
"86": "Community 86",
|
||||
"87": "canDeleteByCreator",
|
||||
"88": "index.vue",
|
||||
"90": "Community 90",
|
||||
"91": "Community 91",
|
||||
"92": "Community 92",
|
||||
"93": "loadUserOptions",
|
||||
"94": "loadUserOptions",
|
||||
"95": "Community 95",
|
||||
"96": "Community 96",
|
||||
"104": "Community 104",
|
||||
"106": "Community 106",
|
||||
"107": "Community 107",
|
||||
"108": "Community 108",
|
||||
@@ -83,7 +108,6 @@
|
||||
"120": "Community 120",
|
||||
"125": "Community 125",
|
||||
"126": "Community 126",
|
||||
"127": "Community 127",
|
||||
"128": "Community 128",
|
||||
"129": "Community 129",
|
||||
"132": "Community 132",
|
||||
@@ -117,13 +141,11 @@
|
||||
"188": "Community 188",
|
||||
"189": "Community 189",
|
||||
"190": "Community 190",
|
||||
"191": "Community 191",
|
||||
"194": "Community 194",
|
||||
"195": "Community 195",
|
||||
"196": "Community 196",
|
||||
"197": "Community 197",
|
||||
"202": "Community 202",
|
||||
"203": "Community 203",
|
||||
"207": "Community 207",
|
||||
"208": "Community 208",
|
||||
"209": "Community 209",
|
||||
@@ -135,23 +157,19 @@
|
||||
"222": "types.ts",
|
||||
"223": "Community 223",
|
||||
"224": "Community 224",
|
||||
"225": "ContactFormDialog.vue",
|
||||
"227": "Community 227",
|
||||
"228": "Community 228",
|
||||
"233": "Community 233",
|
||||
"234": "Community 234",
|
||||
"235": "index.vue",
|
||||
"236": "Community 236",
|
||||
"237": "index.vue",
|
||||
"239": "Community 239",
|
||||
"241": "SettingActions.vue",
|
||||
"242": "Community 242",
|
||||
"243": "Community 243",
|
||||
"244": "index.vue",
|
||||
"246": "price-letter-template.ts",
|
||||
"247": "Community 247",
|
||||
"248": "Community 248",
|
||||
"249": "main.ts",
|
||||
"251": "handleDisburse",
|
||||
"253": "Community 253",
|
||||
"254": "Community 254",
|
||||
@@ -159,14 +177,10 @@
|
||||
"259": "Community 259",
|
||||
"260": "Community 260",
|
||||
"261": "Community 261",
|
||||
"263": "Community 263",
|
||||
"264": "Community 264",
|
||||
"265": "Community 265",
|
||||
"269": "Community 269",
|
||||
"270": "Community 270",
|
||||
"274": "Community 274",
|
||||
"276": "Community 276",
|
||||
"278": "Ha",
|
||||
"280": "Community 280",
|
||||
"283": "Community 283",
|
||||
"284": "Community 284",
|
||||
@@ -186,7 +200,6 @@
|
||||
"308": "Community 308",
|
||||
"309": "Community 309",
|
||||
"310": "Community 310",
|
||||
"314": "detail.vue",
|
||||
"315": "Community 315",
|
||||
"316": "Community 316",
|
||||
"317": "Community 317",
|
||||
@@ -216,27 +229,17 @@
|
||||
"341": "Community 341",
|
||||
"342": "error-handle.ts",
|
||||
"344": "ArtException.vue",
|
||||
"345": "Community 345",
|
||||
"346": "Community 346",
|
||||
"347": "Community 347",
|
||||
"348": "canPreview",
|
||||
"349": "Community 349",
|
||||
"350": "Community 350",
|
||||
"353": "index.vue",
|
||||
"354": "Community 354",
|
||||
"355": "Community 355",
|
||||
"356": "handleDisburse",
|
||||
"362": "Community 362",
|
||||
"364": "Community 364",
|
||||
"365": "Community 365",
|
||||
"366": "highlight.ts",
|
||||
"367": "Community 367",
|
||||
"370": "loader.ts",
|
||||
"371": "fetchData",
|
||||
"372": "detail.vue",
|
||||
"376": "index.vue",
|
||||
"377": "Community 377",
|
||||
"378": "index.vue",
|
||||
"379": "Community 379",
|
||||
"380": "Community 380",
|
||||
"381": "Community 381",
|
||||
@@ -246,7 +249,6 @@
|
||||
"392": "Community 392",
|
||||
"393": "Community 393",
|
||||
"394": "Community 394",
|
||||
"401": "fetchPriceLetterDetail",
|
||||
"405": "zh_CN.js",
|
||||
"406": "Community 406",
|
||||
"407": "index.vue",
|
||||
@@ -256,7 +258,6 @@
|
||||
"412": "Community 412",
|
||||
"416": "Community 416",
|
||||
"417": "Community 417",
|
||||
"418": "SettledPanel.vue",
|
||||
"422": "Community 422",
|
||||
"423": "Community 423",
|
||||
"424": "Community 424",
|
||||
@@ -269,20 +270,15 @@
|
||||
"443": "index.vue",
|
||||
"444": "index.vue",
|
||||
"445": "Community 445",
|
||||
"446": "Community 446",
|
||||
"447": "crm-product-display.ts",
|
||||
"448": "theme.min.js",
|
||||
"453": "ViewKvTableCell.vue",
|
||||
"454": "zh_CN.js",
|
||||
"455": "zh_CN.js",
|
||||
"457": "pl-batch-print.ts",
|
||||
"458": "Community 458",
|
||||
"459": "Community 459",
|
||||
"460": "Community 460",
|
||||
"461": "loading.ts",
|
||||
"462": "Community 462",
|
||||
"463": "index.vue",
|
||||
"464": "zh_CN.js",
|
||||
"465": "index.vue",
|
||||
"470": "Ta",
|
||||
"471": "Community 471",
|
||||
@@ -294,11 +290,8 @@
|
||||
"483": "crm-product-display.ts",
|
||||
"487": "Community 487",
|
||||
"488": "Community 488",
|
||||
"493": "SettingActions.vue",
|
||||
"495": "colors.ts",
|
||||
"496": "Community 496",
|
||||
"499": "Community 499",
|
||||
"506": "loading.ts",
|
||||
"521": "Community 521",
|
||||
"522": "Community 522",
|
||||
"528": "Community 528",
|
||||
@@ -373,7 +366,6 @@
|
||||
"653": "Community 653",
|
||||
"654": "Community 654",
|
||||
"655": "Community 655",
|
||||
"656": "Community 656",
|
||||
"657": "Community 657",
|
||||
"658": "Community 658",
|
||||
"659": "Community 659",
|
||||
|
||||
@@ -1 +1 @@
|
||||
web-admin
|
||||
/Users/wuzilong/work/00code/shanxia2.0/web-admin
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+2985
-73159
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+2980
-2531
File diff suppressed because it is too large.
Load diff
@@ -14,115 +14,121 @@
|
||||
@closed="handleClosed"
|
||||
@opened="handleOpened"
|
||||
>
|
||||
<div class="pl-arrange-layout">
|
||||
<section class="pl-arrange-form-panel">
|
||||
<div v-loading="loading" class="pl-arrange-form-scroll">
|
||||
<div ref="feedbackMirrorEl" class="pl-archive-feedback-mirror" />
|
||||
<div v-loading="loading" class="pl-archive-layout">
|
||||
<el-tabs v-model="activeTab" class="pl-archive-tabs">
|
||||
<el-tab-pane label="归档填写" name="archive" />
|
||||
<el-tab-pane label="计划概况" name="overview" />
|
||||
<el-tab-pane label="运输信息" name="transport" />
|
||||
<el-tab-pane label="合同信息" name="contract" />
|
||||
</el-tabs>
|
||||
|
||||
<section class="pl-plan-form-section">
|
||||
<h4 class="pl-plan-subtitle">产品实际数量</h4>
|
||||
<PlPlanFormProductTable
|
||||
:products="productRows"
|
||||
show-actual-qty
|
||||
editable-actual-qty-only
|
||||
<div v-show="activeTab === 'archive'" class="pl-archive-tab-panel pl-arrange-form-scroll">
|
||||
<div ref="feedbackMirrorEl" class="pl-archive-feedback-mirror" />
|
||||
|
||||
<section class="pl-plan-form-section">
|
||||
<h3 class="pl-plan-form-section-title">产品实际数量</h3>
|
||||
<PlPlanFormProductTable
|
||||
:products="productRows"
|
||||
show-actual-qty
|
||||
editable-actual-qty-only
|
||||
/>
|
||||
<div
|
||||
v-for="row in brandedProductRows"
|
||||
:key="row.id || row.productId"
|
||||
class="pl-archive-brand-qty-block"
|
||||
>
|
||||
<div class="pl-archive-brand-qty-head">
|
||||
<span class="pl-archive-brand-qty-title">{{ row.productName }} · 按品牌填量</span>
|
||||
<el-tag v-if="row.brandMode === 'required'" size="small" type="warning"
|
||||
>指定品牌</el-tag
|
||||
>
|
||||
<el-tag v-else size="small" type="info">不限品牌</el-tag>
|
||||
</div>
|
||||
<BrandQtyChipsField
|
||||
v-model="row.brandQtyRows"
|
||||
:brand-mode="archiveBrandMode(row)"
|
||||
:required-brand-id="row.brandId"
|
||||
:brand-options="row.brandOptions || []"
|
||||
:unit="resolveProductUnitLabel(row.unit)"
|
||||
variant="admin"
|
||||
:actual-qty="Number(row.actualQty ?? 0)"
|
||||
@update:actual-qty="(val) => onArchiveBrandActualQty(row, val)"
|
||||
/>
|
||||
<div
|
||||
v-for="row in brandedProductRows"
|
||||
:key="row.id || row.productId"
|
||||
class="pl-archive-brand-qty-block"
|
||||
>
|
||||
<div class="pl-archive-brand-qty-head">
|
||||
<span class="pl-archive-brand-qty-title">{{ row.productName }} · 按品牌填量</span>
|
||||
<el-tag v-if="row.brandMode === 'required'" size="small" type="warning"
|
||||
>指定品牌</el-tag
|
||||
>
|
||||
<el-tag v-else size="small" type="info">不限品牌</el-tag>
|
||||
</div>
|
||||
<BrandQtyChipsField
|
||||
v-model="row.brandQtyRows"
|
||||
:brand-mode="archiveBrandMode(row)"
|
||||
:required-brand-id="row.brandId"
|
||||
:brand-options="row.brandOptions || []"
|
||||
:unit="resolveProductUnitLabel(row.unit)"
|
||||
variant="admin"
|
||||
:actual-qty="Number(row.actualQty ?? 0)"
|
||||
@update:actual-qty="(val) => onArchiveBrandActualQty(row, val)"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="pl-plan-form-section pl-plan-freight-section">
|
||||
<div class="pl-plan-freight-section-head">
|
||||
<h4 class="pl-plan-subtitle">运费信息</h4>
|
||||
<label class="pl-plan-freight-switch">
|
||||
<span class="pl-plan-freight-switch-label">是否有运输费用</span>
|
||||
<el-switch v-model="formData.hasFreight" :active-value="1" :inactive-value="0" />
|
||||
</label>
|
||||
<section class="pl-plan-form-section pl-plan-freight-section">
|
||||
<div class="pl-plan-freight-section-head">
|
||||
<h3 class="pl-plan-form-section-title">运费信息</h3>
|
||||
<label class="pl-plan-freight-switch">
|
||||
<span class="pl-plan-freight-switch-label">是否有运输费用</span>
|
||||
<el-switch v-model="formData.hasFreight" :active-value="1" :inactive-value="0" />
|
||||
</label>
|
||||
</div>
|
||||
<el-form
|
||||
v-if="formData.hasFreight === 1"
|
||||
:model="formData"
|
||||
label-position="top"
|
||||
class="pl-plan-freight-form"
|
||||
>
|
||||
<div class="form-grid-5 pl-plan-archive-freight-grid">
|
||||
<el-form-item label="运费计算方式">
|
||||
<el-select v-model="formData.freightType">
|
||||
<el-option label="按重量" value="by_weight" />
|
||||
<el-option label="按趟" value="by_trip" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="运输公里数">
|
||||
<el-input-number v-model="formData.distanceKm" :min="0" :precision="2" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="formData.freightType === 'by_weight'"
|
||||
:label="`运输量(${freightUnitLabel})`"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="freightCalc.transportQty.value"
|
||||
:min="0"
|
||||
:precision="3"
|
||||
@change="freightCalc.markTransportQtyTouched()"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="formData.freightType === 'by_weight'"
|
||||
:label="`运输单价(元/${freightUnitLabel})`"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="freightCalc.freightPrice.value"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="运费金额(元)">
|
||||
<el-input-number
|
||||
v-model="freightCalc.freightAmount.value"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
@change="freightCalc.markFreightAmountTouched()"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form
|
||||
v-if="formData.hasFreight === 1"
|
||||
:model="formData"
|
||||
label-position="top"
|
||||
class="pl-plan-freight-form"
|
||||
>
|
||||
<div class="form-grid-5 pl-plan-archive-freight-grid">
|
||||
<el-form-item label="运费计算方式">
|
||||
<el-select v-model="formData.freightType">
|
||||
<el-option label="按重量" value="by_weight" />
|
||||
<el-option label="按趟" value="by_trip" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="运输公里数">
|
||||
<el-input-number v-model="formData.distanceKm" :min="0" :precision="2" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="formData.freightType === 'by_weight'"
|
||||
:label="`运输量(${freightUnitLabel})`"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="freightCalc.transportQty.value"
|
||||
:min="0"
|
||||
:precision="3"
|
||||
@change="freightCalc.markTransportQtyTouched()"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="formData.freightType === 'by_weight'"
|
||||
:label="`运输单价(元/${freightUnitLabel})`"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="freightCalc.freightPrice.value"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="运费金额(元)">
|
||||
<el-input-number
|
||||
v-model="freightCalc.freightAmount.value"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
@change="freightCalc.markFreightAmountTouched()"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</el-form>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section class="pl-arrange-view-panel">
|
||||
<h3 class="pl-arrange-view-title">计划单查看</h3>
|
||||
<div v-show="activeTab !== 'archive'" class="pl-archive-tab-panel pl-arrange-view-panel">
|
||||
<PlPlanViewTabs
|
||||
v-if="planId && feedbackMirrorTarget"
|
||||
ref="tabsRef"
|
||||
:plan-id="planId"
|
||||
embedded
|
||||
hide-nav
|
||||
:tab="viewTab"
|
||||
feedback-editable
|
||||
:arrange-driver-url="driverUrl"
|
||||
:arrange-site-records="siteRecords"
|
||||
:feedback-mirror-to="feedbackMirrorTarget"
|
||||
:feedback-mirror-to="archiveFeedbackMirrorTo"
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
@@ -183,11 +189,19 @@
|
||||
|
||||
const loading = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const activeTab = ref<'archive' | 'overview' | 'transport' | 'contract'>('archive')
|
||||
const tabsRef = ref<InstanceType<typeof PlPlanViewTabs> | null>(null)
|
||||
const plan = ref<Partial<Plan>>({})
|
||||
const feedbackMirrorEl = ref<HTMLElement | null>(null)
|
||||
/** 仅在弹窗 opened 且镜像节点已挂载后传入,避免 Teleport 目标为空导致 Vue patch 崩溃 */
|
||||
const feedbackMirrorTarget = ref<HTMLElement | null>(null)
|
||||
/** 归档填写 Tab 时把回传区镜像过去;其他 Tab 时留在运输信息区内 */
|
||||
const archiveFeedbackMirrorTo = computed(() =>
|
||||
activeTab.value === 'archive' ? feedbackMirrorTarget.value : null
|
||||
)
|
||||
const viewTab = computed(() =>
|
||||
activeTab.value === 'archive' ? 'overview' : activeTab.value
|
||||
)
|
||||
|
||||
const { driverUrl, siteRecords, resetArrangeActions, loadArrangeActions } =
|
||||
usePlPlanArrangeActions()
|
||||
@@ -378,6 +392,7 @@
|
||||
}
|
||||
|
||||
function resetState() {
|
||||
activeTab.value = 'archive'
|
||||
plan.value = {}
|
||||
productRows.value = []
|
||||
Object.assign(formData, {
|
||||
@@ -578,16 +593,23 @@
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pl-arrange-layout {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
.pl-archive-layout {
|
||||
min-height: 480px;
|
||||
}
|
||||
|
||||
.pl-arrange-form-panel {
|
||||
flex: 0 0 auto;
|
||||
overflow: visible;
|
||||
.pl-archive-tabs {
|
||||
:deep(> .el-tabs__header) {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/* 仅用顶部导航,内容区由下方面板接管 */
|
||||
:deep(> .el-tabs__content) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.pl-archive-tab-panel {
|
||||
min-height: 360px;
|
||||
}
|
||||
|
||||
.pl-arrange-form-scroll {
|
||||
@@ -608,30 +630,28 @@
|
||||
}
|
||||
|
||||
.pl-arrange-view-panel {
|
||||
flex: 0 0 auto;
|
||||
min-height: 280px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.pl-arrange-view-title {
|
||||
margin: 0 0 12px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--section-bar-title-color, var(--primary-dark, #059669));
|
||||
}
|
||||
|
||||
.pl-plan-form-section {
|
||||
flex: 0 0 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.pl-plan-subtitle {
|
||||
margin: 0 0 10px;
|
||||
font-size: 13px;
|
||||
.pl-plan-form-section-title {
|
||||
margin: 0 0 12px;
|
||||
padding-left: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #475569;
|
||||
color: var(--section-bar-title-color, var(--primary-dark, #059669));
|
||||
border-left: 3px solid var(--section-bar-border-color, var(--primary, #10b981));
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.pl-plan-freight-section-head .pl-plan-form-section-title {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.pl-archive-brand-qty-block {
|
||||
@@ -657,11 +677,6 @@
|
||||
}
|
||||
|
||||
.pl-plan-freight-section {
|
||||
.pl-plan-subtitle {
|
||||
margin-top: 4px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
:deep(.el-form-item__label) {
|
||||
width: 140px !important;
|
||||
max-width: 140px;
|
||||
|
||||
@@ -31,21 +31,28 @@
|
||||
<el-tag v-if="item.isExplosive" type="danger" size="small">易制爆</el-tag>
|
||||
<el-tag v-if="item.isToxic" type="warning" size="small">易制毒</el-tag>
|
||||
</div>
|
||||
<div class="form-grid-2 product-cert-grid">
|
||||
<el-form-item
|
||||
v-for="slot in getRequiredCertSlots(item)"
|
||||
:key="slot.key"
|
||||
:label="slot.label"
|
||||
:class="{ 'product-cert-grid__span-all': getRequiredCertSlots(item).length === 1 }"
|
||||
>
|
||||
<AttachmentUploadField
|
||||
v-model="item[slot.key]"
|
||||
folder="pl/plan-cert"
|
||||
:limit="1"
|
||||
:hint="`支持图片、PDF 等,上传${slot.label}`"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form
|
||||
label-position="left"
|
||||
label-width="72px"
|
||||
class="product-cert-form"
|
||||
@submit.prevent
|
||||
>
|
||||
<div class="form-grid-2 product-cert-grid">
|
||||
<el-form-item
|
||||
v-for="slot in getRequiredCertSlots(item)"
|
||||
:key="slot.key"
|
||||
:label="slot.label"
|
||||
:class="{ 'product-cert-grid__span-all': getRequiredCertSlots(item).length === 1 }"
|
||||
>
|
||||
<AttachmentUploadField
|
||||
v-model="item[slot.key]"
|
||||
folder="pl/plan-cert"
|
||||
:limit="1"
|
||||
:hint="`支持图片、PDF 等,上传${slot.label}`"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -200,10 +207,27 @@ function handleClosed() {
|
||||
color: var(--text, #1e293b);
|
||||
}
|
||||
|
||||
.product-cert-grid {
|
||||
.product-cert-form {
|
||||
:deep(.el-form-item) {
|
||||
align-items: flex-start;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 购买证 / 运输证 / 合法证明 统一标题宽度,四字不换行,附件上传区左对齐 */
|
||||
:deep(.el-form-item__label) {
|
||||
flex-shrink: 0;
|
||||
width: 72px !important;
|
||||
justify-content: flex-start;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
line-height: 1.4 !important;
|
||||
height: auto !important;
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
:deep(.el-form-item__content) {
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.product-cert-grid__span-all {
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,6 +1,10 @@
|
||||
<!-- eslint-disable vue/no-v-model-argument -->
|
||||
<template>
|
||||
<div v-loading="loading" class="pl-plan-view-tabs" :class="{ 'is-embedded': embedded }">
|
||||
<div
|
||||
v-loading="loading"
|
||||
class="pl-plan-view-tabs"
|
||||
:class="{ 'is-embedded': embedded, 'is-hide-nav': hideNav }"
|
||||
>
|
||||
<el-tabs v-model="activeTab" class="pl-plan-view-tabs__nav">
|
||||
<el-tab-pane label="计划概况" name="overview">
|
||||
<section class="pl-plan-form-section pl-plan-form-section--plain">
|
||||
@@ -80,8 +84,8 @@
|
||||
<section class="pl-plan-form-section pl-plan-form-section--plain">
|
||||
<h3 class="pl-plan-form-section-title">物流节点</h3>
|
||||
<div class="parties-row">
|
||||
<div class="party-panel party-panel--plain">
|
||||
<ViewKvTable :fields="pickupViewFields" mode="quad" />
|
||||
<div class="party-panel party-panel--plain pl-plan-logistics-panel">
|
||||
<ViewKvTable :fields="pickupViewFields" mode="dual" />
|
||||
</div>
|
||||
|
||||
<div class="party-flow-bridge">
|
||||
@@ -105,8 +109,8 @@
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="party-panel party-panel--plain">
|
||||
<ViewKvTable :fields="deliveryViewFields" mode="quad" />
|
||||
<div class="party-panel party-panel--plain pl-plan-logistics-panel">
|
||||
<ViewKvTable :fields="deliveryViewFields" mode="dual" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -347,7 +351,6 @@
|
||||
import PlVehicleViewDialog from '@/components/business/pl-vehicle-view-dialog/index.vue'
|
||||
import ViewKvTable from '@/components/business/system-view-dialog/ViewKvTable.vue'
|
||||
import type { ViewField } from '@/components/business/system-view-dialog/types'
|
||||
import { businessTypeTagType } from '@/components/business/db/db-related-view'
|
||||
import type { ContractVO } from '@/api/crm/contract/types'
|
||||
import { inventoryApi } from '@/api/db/inventory'
|
||||
import {
|
||||
@@ -362,7 +365,7 @@
|
||||
mapContractProducts,
|
||||
type PlanFormProductRow
|
||||
} from '@/composables/usePlContractToPlan'
|
||||
import { mapPlanProductToFormRow, usePlPlanViewDetail, type PlPlanTransportDibangRow, type PlPlanTransportSiteRow } from '@/composables/usePlPlanViewDetail'
|
||||
import { mapPlanProductToFormRow, usePlPlanViewDetail, type PlPlanTransportSiteRow } from '@/composables/usePlPlanViewDetail'
|
||||
import { resolveFreightUnitLabel } from '@/composables/usePlFreightCalc'
|
||||
import { isHazardProduct } from '@/composables/usePlToxicProductCertCheck'
|
||||
import { useDictStore } from '@/store/modules/dict'
|
||||
@@ -400,6 +403,10 @@
|
||||
feedbackEditable?: boolean
|
||||
/** 将司机/现场/地磅回传区块镜像渲染到归档左侧等目标节点 */
|
||||
feedbackMirrorTo?: string | HTMLElement | null
|
||||
/** 隐藏内部 Tab 导航(由外层统一控制 Tab) */
|
||||
hideNav?: boolean
|
||||
/** 受控当前 Tab:overview / transport / contract */
|
||||
tab?: string
|
||||
}>(),
|
||||
{
|
||||
embedded: false,
|
||||
@@ -407,11 +414,33 @@
|
||||
arrangeDriverUrl: '',
|
||||
arrangeSiteRecords: () => [],
|
||||
feedbackEditable: false,
|
||||
feedbackMirrorTo: null
|
||||
feedbackMirrorTo: null,
|
||||
hideNav: false,
|
||||
tab: undefined
|
||||
}
|
||||
)
|
||||
|
||||
const activeTab = ref('overview')
|
||||
const emit = defineEmits<{
|
||||
'update:tab': [value: string]
|
||||
}>()
|
||||
|
||||
const innerActiveTab = ref(props.tab || 'overview')
|
||||
const activeTab = computed({
|
||||
get: () => props.tab || innerActiveTab.value,
|
||||
set: (value: string) => {
|
||||
innerActiveTab.value = value
|
||||
emit('update:tab', value)
|
||||
}
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.tab,
|
||||
(value) => {
|
||||
if (value && value !== innerActiveTab.value) {
|
||||
innerActiveTab.value = value
|
||||
}
|
||||
}
|
||||
)
|
||||
const contractDetailDialogActive = ref(false)
|
||||
const contractDetailRef = ref<InstanceType<typeof ContractDetailDialog>>()
|
||||
const vehicleViewVisible = ref(false)
|
||||
@@ -899,28 +928,6 @@
|
||||
}))
|
||||
)
|
||||
|
||||
function dibangBasicViewFields(row: PlPlanTransportDibangRow): ViewField[] {
|
||||
const businessType = row.inventory?.businessType
|
||||
// long: false — 强制六字段同一行展示,避免往来单位等长文案自动折行
|
||||
return [
|
||||
{ label: '出入库单号', value: row.inventory?.batchNo || row.link.batchNo, long: false },
|
||||
{
|
||||
label: '业务类型',
|
||||
value: businessType,
|
||||
tagType: businessType ? businessTypeTagType(businessType) : undefined,
|
||||
long: false
|
||||
},
|
||||
{ label: '往来单位', value: row.inventory?.partnerCompany, long: false },
|
||||
{
|
||||
label: '车牌号',
|
||||
value: row.inventory?.vehicleNo || plan.value?.licensePlate || transport.value?.licensePlate,
|
||||
long: false
|
||||
},
|
||||
{ label: '产品', value: row.inventory?.product || row.link.productName, long: false },
|
||||
{ label: '数量(吨)', value: row.inventory?.quantity, long: false }
|
||||
]
|
||||
}
|
||||
|
||||
const dibangPlanRows = computed(() =>
|
||||
dibangRows.value.filter(row => Boolean(row.link.dbPurchasePlanId?.trim()))
|
||||
)
|
||||
@@ -1048,8 +1055,7 @@
|
||||
ioOrderViewFields: ioOrderViewFields.value,
|
||||
ioOrderImageCsv: ioOrderImageCsv.value,
|
||||
siteFeedbackTableRows: siteFeedbackTableRows.value,
|
||||
dibangPlanRows: dibangPlanRows.value,
|
||||
dibangBasicViewFields
|
||||
dibangPlanRows: dibangPlanRows.value
|
||||
}))
|
||||
|
||||
const feedbackBlocksOn = {
|
||||
@@ -1284,6 +1290,16 @@
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-hide-nav {
|
||||
.pl-plan-view-tabs__nav :deep(> .el-tabs__header) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pl-plan-view-tabs__nav :deep(> .el-tabs__content) {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pl-plan-view-tabs__nav :deep(.el-tabs__content) {
|
||||
@@ -1449,6 +1465,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
.pl-plan-logistics-panel {
|
||||
:deep(.view-kv-table--dual th) {
|
||||
width: 88px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
:deep(.view-kv-table--dual td) {
|
||||
width: auto;
|
||||
min-width: 7.5em;
|
||||
}
|
||||
|
||||
/* 取货/送达时间所在值列禁止换行,避免 2026-07-31 被拆开 */
|
||||
:deep(.view-kv-table--dual tr:not(.row-long) td:first-of-type) {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.party-panel__title {
|
||||
margin-bottom: 12px;
|
||||
padding-left: 10px;
|
||||
|
||||
@@ -15,9 +15,13 @@
|
||||
<li v-for="(item, idx) in field.items" :key="idx">{{ item }}</li>
|
||||
</ul>
|
||||
<template v-else>
|
||||
<span :class="{ 'money-display': field.money }">{{
|
||||
formatViewValue(field.value)
|
||||
}}</span>
|
||||
<span
|
||||
:class="{
|
||||
'money-display': field.money,
|
||||
'danger-display': field.danger
|
||||
}"
|
||||
>{{ formatViewValue(field.value) }}</span
|
||||
>
|
||||
</template>
|
||||
</dd>
|
||||
</div>
|
||||
@@ -60,6 +64,22 @@
|
||||
&--cols-5 {
|
||||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
&--cols-6 {
|
||||
grid-template-columns: repeat(6, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
&--cols-7 {
|
||||
grid-template-columns: repeat(7, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
&--cols-8 {
|
||||
grid-template-columns: repeat(8, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
&--cols-9 {
|
||||
grid-template-columns: repeat(9, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
.view-kv {
|
||||
@@ -85,6 +105,11 @@
|
||||
word-break: break-word;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.danger-display {
|
||||
color: #dc2626;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.view-kv-span-2 {
|
||||
@@ -105,9 +130,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1400px) {
|
||||
.view-kv-grid--cols-8,
|
||||
.view-kv-grid--cols-9 {
|
||||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
.view-kv-grid--cols-4,
|
||||
.view-kv-grid--cols-5 {
|
||||
.view-kv-grid--cols-5,
|
||||
.view-kv-grid--cols-6,
|
||||
.view-kv-grid--cols-7,
|
||||
.view-kv-grid--cols-8,
|
||||
.view-kv-grid--cols-9 {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
@@ -115,7 +151,11 @@
|
||||
@media (max-width: 900px) {
|
||||
.view-kv-grid--cols-3,
|
||||
.view-kv-grid--cols-4,
|
||||
.view-kv-grid--cols-5 {
|
||||
.view-kv-grid--cols-5,
|
||||
.view-kv-grid--cols-6,
|
||||
.view-kv-grid--cols-7,
|
||||
.view-kv-grid--cols-8,
|
||||
.view-kv-grid--cols-9 {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
@@ -124,7 +164,11 @@
|
||||
.view-kv-grid,
|
||||
.view-kv-grid--cols-3,
|
||||
.view-kv-grid--cols-4,
|
||||
.view-kv-grid--cols-5 {
|
||||
.view-kv-grid--cols-5,
|
||||
.view-kv-grid--cols-6,
|
||||
.view-kv-grid--cols-7,
|
||||
.view-kv-grid--cols-8,
|
||||
.view-kv-grid--cols-9 {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
|
||||
@@ -351,7 +351,11 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="往来单位" prop="customerName">
|
||||
<DbCrmCustomerSelect v-model="formData.customerName" placeholder="请输入往来单位搜索" />
|
||||
<DbCrmCustomerSelect
|
||||
v-model="formData.customerName"
|
||||
:allow-create="false"
|
||||
placeholder="请从客户管理中搜索选择"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="产品" prop="productId">
|
||||
<DbCrmProductSelect
|
||||
|
||||
@@ -371,7 +371,11 @@
|
||||
<el-input :value="currentQuantityInTons" placeholder="本次量(吨)" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item label="供货单位" prop="supplier">
|
||||
<DbCrmCustomerSelect v-model="formData.supplier" placeholder="请输入供货单位搜索" />
|
||||
<DbCrmCustomerSelect
|
||||
v-model="formData.supplier"
|
||||
:allow-create="false"
|
||||
placeholder="请从客户管理中搜索选择"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="扣杂(kg)" prop="deduction">
|
||||
<el-input-number
|
||||
@@ -385,7 +389,11 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="收货单位" prop="consignee">
|
||||
<DbCrmCustomerSelect v-model="formData.consignee" placeholder="请输入收货单位搜索" />
|
||||
<DbCrmCustomerSelect
|
||||
v-model="formData.consignee"
|
||||
:allow-create="false"
|
||||
placeholder="请从客户管理中搜索选择"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="毛重(kg)" prop="grossWeight">
|
||||
<el-input-number
|
||||
@@ -631,8 +639,8 @@
|
||||
const formRules = {
|
||||
vehicleNo: [{ required: true, message: '请选择车牌号', trigger: 'change' }],
|
||||
productId: [{ required: true, message: '请选择 CRM 产品', trigger: 'change' }],
|
||||
supplier: [{ required: true, message: '请输入供货单位', trigger: 'blur' }],
|
||||
consignee: [{ required: true, message: '请输入收货单位', trigger: 'blur' }]
|
||||
supplier: [{ required: true, message: '请选择供货单位', trigger: 'change' }],
|
||||
consignee: [{ required: true, message: '请选择收货单位', trigger: 'change' }]
|
||||
}
|
||||
|
||||
const netWeight = computed(() => {
|
||||
|
||||
Reference in new issue
Block a user