Files
jiu/docs/review/stockorder-empty-fields-stats.html
T

144 lines
13 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>出入库明细空字段 × 库存可补 数据统计 — 酒库管理系统</title>
<style>
:root{
--primary:#2563AC; --primary-dark:#154072; --danger:#D14343; --danger-bg:#FDECEC;
--success:#2E8B57; --success-bg:#E6F3EC; --warn:#B45309; --warn-bg:#FFF4E5; --accent:#8B2331;
--ink:#232934; --muted:#6E7888; --border:#DCE2EB; --paper:#F5F7FA; --head:#F0F4FF;
}
*{box-sizing:border-box;font-family:-apple-system,"PingFang SC","Microsoft YaHei",sans-serif;}
body{margin:0;background:var(--paper);color:var(--ink);padding:28px;line-height:1.65;max-width:1000px;margin:0 auto;}
h1{font-size:22px;margin:0 0 4px;}
h2{font-size:17px;margin:30px 0 10px;color:var(--primary-dark);border-bottom:2px solid var(--head);padding-bottom:6px;}
h3{font-size:14px;margin:18px 0 6px;color:var(--accent);}
.sub{color:var(--muted);font-size:13px;margin-bottom:8px;}
.stats{display:flex;gap:22px;flex-wrap:wrap;font-size:12.5px;color:var(--muted);margin:10px 0;}
.stats b{color:var(--ink);font-size:16px;}
.card{background:#fff;border:1px solid var(--border);border-radius:10px;padding:14px 18px;margin:12px 0;}
table{width:100%;border-collapse:collapse;font-size:13px;margin:6px 0;}
th{background:var(--head);color:var(--primary-dark);font-weight:600;font-size:12px;text-align:left;padding:8px 10px;border-bottom:1px solid var(--border);}
td{padding:7px 10px;border-bottom:1px solid #EEF1F6;}
tr:last-child td{border-bottom:0;}
td.n{text-align:right;font-family:ui-monospace,Menlo,monospace;}
.mono{font-family:ui-monospace,Menlo,monospace;font-size:12px;}
code{font-family:ui-monospace,Menlo,monospace;font-size:12px;background:#EEF2F8;padding:1px 5px;border-radius:4px;color:var(--primary-dark);}
.hi{color:var(--danger);font-weight:700;}
.ok{color:var(--success);font-weight:700;}
.callout{border-left:4px solid var(--primary);background:#F0F6FF;padding:10px 14px;border-radius:4px;margin:12px 0;font-size:13px;}
.callout.danger{border-color:var(--danger);background:var(--danger-bg);}
.callout.warn{border-color:var(--warn);background:var(--warn-bg);}
.callout.ok{border-color:var(--success);background:var(--success-bg);}
ul{margin:6px 0;padding-left:20px;} li{margin:4px 0;font-size:13px;}
.tag{display:inline-block;font-size:10px;padding:1px 7px;border-radius:9px;font-weight:600;}
.tag.fix{background:var(--success-bg);color:var(--success);}
.tag.no{background:#EEE;color:var(--muted);}
</style>
</head>
<body>
<h1>出入库明细 空字段 × 库存可补 · 数据统计</h1>
<div class="sub">数据源:生产库每日备份 <code>jiu_db_20260626_020210.sql.gz</code>2026-06-26 02:02)· 单租户(鼎晟酒行)</div>
<div class="stats">
<div>出库明细 <b>26,693</b></div>
<div>入库明细 <b>28,443</b></div>
<div>库存批次 <b>13,120</b></div>
<div>商品 <b>9,525</b></div>
</div>
<div class="callout">
<b>口径说明:</b>「库存能找到值」= 该字段在库存表的<b>显示值</b>非空,即 <code>COALESCE(NULLIF(sii.batch_no,''), inv.batch_no)</code>(用户在库存页看到的值)。出库明细按 <code>product_id</code> 匹配库存;入库明细按 <code>stock_in_item_id</code> 直连。<br>
「打印必空白」= 明细行快照为空 <b></b> 该行 <code>product</code> 主记录也为空(两者都空,打印才会留白)。
</div>
<h2>一、核心结论</h2>
<div class="card">
<ul>
<li><b>出库单打印空白、且能从库存补回的,只有约 <span class="hi">18~20 行</span>(集中在 <span class="hi">13 张单</span></b>,全部是 <b>2026-06-20 ~ 06-24</b> 的近期 App 新建单(含截图 <code>CK20260623000007</code>)。这正是「出库单显示对齐库存口径」能解决的部分。</li>
<li>出库明细批次号为空共 <b>5,528 行</b>,但其中 <span class="hi">99.7% 在库存里也查不到值</span>(商品已售罄无在库批次 / 源数据本就没录批次)——属源数据缺失,<b>非显示 bug,无法从库存补</b></li>
<li><b>入库单批次/生产日期可补数 = <span class="hi">0</span></b>(库存、product 主记录都补不出)。因为<b>入库是数据录入源头</b>,源头空则下游全空,无上游可回填——与出库不同,<b>不是显示 bug,"显示对齐库存口径"对入库无意义</b>。空批次跨 2023-04~2026-06 整段历史。</li>
<li>根因复述:批次/生产日期的值真实落在 <code>inventories</code><b>自身的快照列</b>上(不是 stock_in_item、也不是 product 主记录);出库打印却回退读 <code>product</code> 主记录,对不上。详见 <a href="../db-schema.html#inventories">db-schema</a></li>
</ul>
</div>
<h2>二、出库明细 stock_out_items</h2>
<p class="sub">product_id 全部有值(无占位行)。</p>
<h3>① 宽口径:明细字段为空 ÷ 其中库存能找到值</h3>
<div class="card"><table>
<thead><tr><th>字段</th><th>明细为空</th><th>占比</th><th>其中库存有值</th></tr></thead>
<tbody>
<tr><td><code>batch_no</code> 批次号</td><td class="n">5,557</td><td class="n">20.8%</td><td class="n">46</td></tr>
<tr><td><code>production_date</code> 生产日期</td><td class="n">66</td><td class="n">0.25%</td><td class="n">48</td></tr>
<tr><td><code>product_code</code> 商品编号</td><td class="n">62</td><td class="n">0.23%</td><td class="n">48</td></tr>
<tr><td><code>series</code> 系列</td><td class="n">63</td><td class="n">0.24%</td><td class="n">48</td></tr>
<tr><td><code>spec</code> 规格</td><td class="n">63</td><td class="n">0.24%</td><td class="n">48</td></tr>
</tbody>
</table></div>
<h3>② 打印口径:明细空 且 product 主记录也空(= 打印必空白)÷ 库存可补</h3>
<div class="card"><table>
<thead><tr><th>字段</th><th>打印空白行</th><th><span class="tag fix">库存可补</span></th><th>涉及出库单</th></tr></thead>
<tbody>
<tr><td><code>batch_no</code> 批次号</td><td class="n">5,528</td><td class="n ok">18</td><td class="n">1,207</td></tr>
<tr><td><code>production_date</code> 生产日期</td><td class="n">37</td><td class="n ok">20</td><td class="n">22</td></tr>
</tbody>
</table></div>
<h2>三、入库明细 stock_in_items</h2>
<p class="sub">与出库<b>完全同口径</b>:库存按 <code>product_id</code> 匹配;并额外列出能否从 <code>product</code> 主记录补值。</p>
<div class="card"><table>
<thead><tr><th>字段</th><th>明细为空</th><th><span class="tag fix">库存可补</span></th><th>product 主记录可补</th></tr></thead>
<tbody>
<tr><td><code>batch_no</code> 批次号</td><td class="n">6,876</td><td class="n hi">0</td><td class="n hi">0</td></tr>
<tr><td><code>production_date</code> 生产日期</td><td class="n">16</td><td class="n hi">0</td><td class="n hi">0</td></tr>
<tr><td><code>product_code</code> 商品编号</td><td class="n">25</td><td class="n">10</td><td class="n">25</td></tr>
<tr><td><code>series</code> 系列</td><td class="n">27</td><td class="n">12</td><td class="n">26</td></tr>
<tr><td><code>spec</code> 规格</td><td class="n">27</td><td class="n">12</td><td class="n">25</td></tr>
</tbody>
</table></div>
<div class="callout warn">
<b>入库单批次号/生产日期:可补数 = 0(库存、product 主记录都补不出)。</b>这是结构性的——<b>入库是数据录入的源头</b>:批次若在入库时就空着,由它建的 product 也空、由它生成的库存批次同样空,没有任何上游能反过来填。出库之所以能补,是因为出库引用的是「别的、已录过批次的库存批次」。<br>
入库空批次跨度 <b>2023-04 ~ 2026-06</b>(整段历史都有,非 App 期专属),属源头从未录入,<b>不是显示 bug,与出库的「显示对齐库存口径」无关</b>。商品编号/系列/规格少量空行(25~27)可从 product 主记录补,但属商品身份字段、与本次批次问题无关。</div>
<h2>四、受影响(打印空白但库存可补)出库单清单</h2>
<p class="sub">20 个明细行,13 张单,全部为近期 App 新建单。这些单据打印时批次/生产日期留白,但库存里有值。</p>
<div class="card"><table>
<thead><tr><th>出库单号</th><th>日期</th><th>product_id</th><th>库存批次</th><th>库存生产日期</th></tr></thead>
<tbody>
<tr><td class="mono">CK20260624000021</td><td>2026-06-24</td><td class="mono">4779</td><td class="mono">2015674600</td><td class="mono">2009-04-16</td></tr>
<tr><td class="mono">CK20260623000001</td><td>2026-06-23</td><td class="mono">9448</td><td class="mono">2023-003/AI013453</td><td class="mono">2025-02-27</td></tr>
<tr><td class="mono">CK20260623000001</td><td>2026-06-23</td><td class="mono">4430</td><td class="mono">1</td><td class="mono">2012-01-01</td></tr>
<tr><td class="mono">CK20260623000001</td><td>2026-06-23</td><td class="mono">9449</td><td class="mono">2023-003/AI013441</td><td class="mono">2025-02-27</td></tr>
<tr><td class="mono">CK20260623000001</td><td>2026-06-23</td><td class="mono">9486</td><td class="mono">2006-01/03008</td><td class="mono">2006-12-01</td></tr>
<tr><td class="mono">CK20260623000003</td><td>2026-06-23</td><td class="mono">4617</td><td class="mono">2026-001/YC025400</td><td class="mono">2026-03-19</td></tr>
<tr><td class="mono">CK20260623000004</td><td>2026-06-23</td><td class="mono">9477</td><td class="mono">2025-023/AA007333</td><td class="mono">2025-12-18</td></tr>
<tr><td class="mono">CK20260623000004</td><td>2026-06-23</td><td class="mono">9478</td><td class="mono">2025-023/AA007191</td><td class="mono">2025-12-18</td></tr>
<tr><td class="mono">CK20260623000004</td><td>2026-06-23</td><td class="mono">4722</td><td class="mono">2025-127/441066145489</td><td class="mono">2026-03-14</td></tr>
<tr><td class="mono"><b>CK20260623000007</b> <span class="tag fix">截图</span></td><td>2026-06-23</td><td class="mono">4382</td><td class="mono">2022-001/AH000108</td><td class="mono">2023-12-28</td></tr>
<tr><td class="mono">CK20260623000009</td><td>2026-06-23</td><td class="mono">4247</td><td class="mono">(批次空)</td><td class="mono">2024-08-21</td></tr>
<tr><td class="mono">CK20260623000010</td><td>2026-06-23</td><td class="mono">4717</td><td class="mono">2022-014/664667600053</td><td class="mono">2024-01-31</td></tr>
<tr><td class="mono">CK20260623000010</td><td>2026-06-23</td><td class="mono">9503</td><td class="mono">2023-004/654105250904</td><td class="mono">2024-07-11</td></tr>
<tr><td class="mono">CK20260623000013</td><td>2026-06-23</td><td class="mono">4026</td><td class="mono">2022-091/AA019835</td><td class="mono">2023-07-25</td></tr>
<tr><td class="mono">CK20260623000014</td><td>2026-06-23</td><td class="mono">9499</td><td class="mono">2022-006/AI008438</td><td class="mono">2024-05-11</td></tr>
<tr><td class="mono">CK20260623000014</td><td>2026-06-23</td><td class="mono">9500</td><td class="mono">2022-005/AH003630</td><td class="mono">2024-03-28</td></tr>
<tr><td class="mono">CK20260623000015</td><td>2026-06-23</td><td class="mono">4645</td><td class="mono">(批次空)</td><td class="mono">2026-01-19</td></tr>
<tr><td class="mono">CK20260623000016</td><td>2026-06-23</td><td class="mono">4732</td><td class="mono">2022-030/799689408820</td><td class="mono">2023-02-14</td></tr>
<tr><td class="mono">CK20260623000017</td><td>2026-06-23</td><td class="mono">4757</td><td class="mono">2025-102/006679240592</td><td class="mono">2026-02-13</td></tr>
<tr><td class="mono">CK20260620000001</td><td>2026-06-20</td><td class="mono">3510</td><td class="mono">RK20260613000004-01</td><td class="mono">2026-06-09</td></tr>
</tbody>
</table></div>
<h2>五、对修复方案的指向</h2>
<div class="callout ok">
<b>「出库单显示对齐库存口径」(已选方案)足以覆盖真实问题:</b>对近期 App 出库单(上表 13 张)打印时按 <code>product → inventory</code> 取批次/生产日期即可即时补全,无需动数据、无需重发。<br>
<b>历史海量空批次(5,500+ 行)不在修复范围:</b>它们在 product / 库存 / 入库明细中均无值,属源数据从未录入,任何「显示口径」都补不出来。<br>
<b>入库单方向收益≈0</b>入库明细与库存几乎无可用关联,且入库明细空批次同样源数据缺失。
</div>
<p class="sub" style="margin-top:24px;">统计方法:将备份导入临时库 <code>jiu_analyze</code>,按上述口径 SQL 聚合,完成后删除临时库。生成时间 2026-06-26。</p>
</body>
</html>